kubernetes
istio 배포
misankim
2023. 3. 8. 23:33
istio 배포
공식 가이드
# 설치
## istioctl 로 설치
curl -L https://istio.io/downloadIstio | sh -
cd istio-*
export PATH=$PWD/bin:$PATH
istioctl install --set profile=demo -y
배포된 istio 관련 리소스 확인
kubectl get all -n istio-system
설치된 istio profile 확인
istioctl profile dump
앱 배포 시 envoy 사이드카 프록시를 자동으로 삽입하도록 앱을 배포할 네임스페이스에 레이블을 추가
-> envoy 사이드카 프록시가 정상적으로 배포되었다면 파드에 포함된 컨테이너가 1개(READY 1/1)가 아닌 2개(READY 2/2)로 보이는 것이 정상
kubectl label namespace default istio-injection=enabled
kubectl get ns --show-labels
(참고) istio 관련 리소스
❯ kubectl get all -n istio-system
NAME READY STATUS RESTARTS AGE
pod/istio-egressgateway-66fdd867f4-nhmmc 1/1 Running 0 3m53s
pod/istio-ingressgateway-77968dbd74-2sb8m 1/1 Running 0 3m53s
pod/istiod-699b647f8b-2zcnk 1/1 Running 0 4m9s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/istio-egressgateway ClusterIP 100.66.9.189 <none> 80/TCP,443/TCP 3m52s
service/istio-ingressgateway LoadBalancer 100.66.3.174 34.64.56.24 15021:32719/TCP,80:32147/TCP,443:32119/TCP,31400:31958/TCP,15443:31065/TCP 3m52s
service/istiod ClusterIP 100.66.3.216 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 4m9s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/istio-egressgateway 1/1 1 1 3m54s
deployment.apps/istio-ingressgateway 1/1 1 1 3m54s
deployment.apps/istiod 1/1 1 1 4m10s
NAME DESIRED CURRENT READY AGE
replicaset.apps/istio-egressgateway-66fdd867f4 1 1 1 3m54s
replicaset.apps/istio-ingressgateway-77968dbd74 1 1 1 3m54s
replicaset.apps/istiod-699b647f8b 1 1 1 4m10s
## istio operator 로 설치
IstioOperator 옵션 참고
istioctl operator init
-> istio-operator 네임스페이스에 istio-operator 관련 리소스가 생성됨
-> IstioOperator 리소스 작성하면 자동으로 istio 배포
-> istio 초기 배포 이후 IstioOperator 가 변경되면 변경되는 내용을 istio operator 가 실시간으로 istio 에 반영해줌
kubectl apply -f - <<EOF
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
namespace: istio-system
name: istiocontrolplane
spec:
profile: demo
meshConfig:
accessLogFile: /dev/stdout
values:
pilot:
enabled: true
autoscaleEnabled: true
autoscaleMin: 1
autoscaleMax: 5
resources:
requests:
cpu: 500m
memory: 2048Mi
limits:
cpu: 500m
memory: 2048Mi
gateways:
istio-ingressgateway:
autoscaleEnabled: true
type: ClusterIP
serviceAnnotations:
cloud.google.com/backend-config: '{"default": "istio-ingressgateway"}'
istio-egressgateway:
autoscaleEnabled: true
EOF
kubectl get IstioOperator -n istio-system
## istio operator 로 설치한 istio, operator 제거
kubectl delete istiooperators.install.istio.io -n istio-system istiocontrolplane
istioctl uninstall -y --purge
kubectl delete ns istio-system istio-operator --grace-period=0 --force
# 샘플 앱 배포
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
kubectl get all
배포된 앱 정상 작동 확인
kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -sS productpage:9080/productpage | grep -o "<title>.*</title>"
# 외부로 앱 노출
kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
구성 검증
istioctl analyze
로드밸런서 지원 여부 확인(EXTERNAL-IP)
kubectl get svc istio-ingressgateway -n istio-system
환경 변수 설정(복잡)
export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')
export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].port}')
export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
환경 변수 설정(간단)
export GATEWAY_URL=$(kubectl get svc istio-ingressgateway -n istio-system -o json | jq -r .status.loadBalancer.ingress[0].ip)
확인
echo "$GATEWAY_URL"
접속할 외부 주소
echo "http://${GATEWAY_URL}/productpage"
# 애드온 설치 및 접속
애드온 설치
kubectl apply -f samples/addons
prometheus 접속을 위한 포트포워드
kubectl -n istio-system port-forward \
$(kubectl -n istio-system get pod -l app=prometheus -o jsonpath='{.items[0].metadata.name}') 9090:9090
grafana 접속을 위한 포트포워드
kubectl -n istio-system port-forward \
$(kubectl -n istio-system get pod -l app=grafana -o jsonpath='{.items[0].metadata.name}') 3000:3000
jaeger 접속을 위한 포트포워드
kubectl -n istio-system port-forward \
$(kubectl -n istio-system get pod -l app=jaeger -o jsonpath='{.items[0].metadata.name}') 20001:16686
# kiali 대시보드 배포
kiali 배포
kubectl rollout status deployment/kiali -n istio-system
대시보드 프록시 실행(자동으로 브라우저로 연결됨)
istioctl dashboard kiali
혹은 포트포워드
kubectl -n istio-system port-forward \
$(kubectl -n istio-system get pod -l app=kiali -o jsonpath='{.items[0].metadata.name}') 20001:20001
좌측 메뉴에서 그래프 선택 후 네임스페이스 default 선택
샘플 데이터 생성
for i in $(seq 1 100); do curl -s -o /dev/null "http://$GATEWAY_URL/productpage"; done
샘플 데이터 생성 후 대시보드의 그래프가 정상적으로 보여지는지 확인
(참고) 애드온으로 배포된 prometheus 가 수집하는 메트릭
istio-telemetry.istio-system:42422: The istio-mesh job returns all Mixer-generated metrics.
istio-telemetry.istio-system:15014: The istio-telemetry job returns all Mixer-specific metrics. Use this endpoint to monitor Mixer itself.
istio-proxy:15090: The envoy-stats job returns raw stats generated by Envoy. Prometheus is configured to look for pods with the envoy-prom endpoint exposed. The add-on configuration filters out a large number of envoy metrics during collection in an attempt to limit the scale of data by the add-on processes.
istio-pilot.istio-system:15014: The pilot job returns the Pilot-generated metrics.
istio-galley.istio-system:15014: The galley job returns the Galley-generated metrics.
istio-policy.istio-system:15014: The istio-policy job returns all policy-related metrics.
istio-citadel.istio-system:15014: The istio-citadel job returns all Citadel-generated metrics.
# 제거
kubectl delete -f samples/addons
istioctl manifest generate --set profile=demo | kubectl delete --ignore-not-found=true -f -
istioctl tag remove default
kubectl delete namespace istio-system
kubectl label namespace default istio-injection-
(참고) nginx 로 리버스 프록시 파드 사용 시 404 에러가 찍히는 경우
-> envoy 프록시는 호스트 헤더와 경로를 기반으로 프록시할 대상을 인식하는데 nginx 설정에 의해 호스트 헤더가 덮어 씌어지면 envoy 에서 경로를 찾지 못해 404 에러 발생
-> nginx 의 default.conf 파일에 아래 옵션이 있다면 주석
proxy_set_header Host $host;
(참고) nginx 로 리버스 프록시 파드 사용 시 426 에러가 찍히는 경우
nginx 의 default.conf 파일에 아래 옵션 추가
proxy_http_version 1.1;
# gateway 에 ssl 인증서 적용
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./my-flask-app.example.com.key -out ./my-flask-app.example.com.crt -subj "/CN=my-flask-app.example.com/O=my-flask-app.example.com"
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./keycloak.example.com.key -out ./keycloak.example.com.crt -subj "/CN=keycloak.example.com/O=keycloak.example.com"
kubectl create -n istio-system secret tls my-flask-app-credential --key=my-flask-app.example.com.key --cert=my-flask-app.example.com.crt
kubectl create -n istio-system secret tls keycloak-credential --key=keycloak.example.com.key --cert=keycloak.example.com.crt
cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: istio-ingressgateway
namespace: istio-system
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
- port:
number: 443
name: https-my-flask-app
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: my-flask-app-credential
hosts:
- my-flask-app.example.com
- port:
number: 443
name: https-keycloak
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: keycloak-credential
hosts:
- keycloak.example.com
EOF
# 사이드카 프록시를 주입하지 않도록 label 추가
❯ cat rollout.yaml
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: my-flask-app
spec:
...
template:
metadata:
labels:
app: my-flask-app
sidecar.istio.io/inject: "false"
spec:
terminationGracePeriodSeconds: 30
serviceAccount: pubsub-ksa
containers:
...
# istio 업그레이드
설치 전 체크
istioctl x precheck
업그레이드
istioctl upgrade
버전 확인
istioctl version
프로파일 설정값 확인
istioctl profile dump
# static 응답(403, 404 등) 반환
-> directResponse 설정은 istio 버전 1.15 이상에서만 사용 가능
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: ratings-route
spec:
hosts:
- ratings.prod.svc.cluster.local
http:
- match:
- uri:
exact: /v1/getProductRatings
directResponse:
status: 503
body:
string: "unknown error"
...
# sticky session 설정
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: dr-my-flask-app
spec:
host: svc-my-flask-app.my-flask-app.svc.cluster.local
subsets:
- name: canary
labels:
app: my-flask-app
- name: stable
labels:
app: my-flask-app
trafficPolicy:
loadBalancer:
consistentHash:
httpCookie:
name: istio-session
ttl: 0s