본 내용은 CloudNet 주말 스터디 내용을 참고로 작성되었습니다.
계속 테스트하며 내용과 설명이 업데이트 됩니다.
목표
Istio 이해
Istio는 유튜브를 통해 우선 공부를 하고 실습하자.
<1> 서비스 매시(Service Mesh)
<2> Envoy 소개
<3> ingressgateway 인입 구성 방안
<4> 샘플 어플리케이션 배포
<5> istio 삭제
<6> core dns
<1> 서비스 매시(Service Mesh)
1
기본 동작 : 파드 간 통신 경로에 프록시를 놓고 트래픽 모니터링이나 트래픽 컨트롤 → 기존 애플리케이션 코드에 수정 없이 구성 가능
트래픽 모니터링 : 요청의 '에러율, 레이턴시, 커넥션 개수, 요청 개수' 등 메트릭 모니터링, 특정 서비스간 혹은 특정 요청 경로로 필터링 → 원인 파악 용이!
트래픽 컨트롤 : 트래픽 시프팅(Traffic shifting), 서킷 브레이커(Circuit Breaker), 폴트 인젝션(Fault Injection), 속도 제한(Rate Limit)
2
아키텍처
<2> Envoy 소개
1
L7 Proxy , Istio 의 Sidecar proxy 로 사용
2
용어
3
작업용 ec2에 envoy 설치
#
sudo rpm --import 'https://rpm.dl.getenvoy.io/public/gpg.CF716AF503183491.key'
curl -sL 'https://rpm.dl.getenvoy.io/public/config.rpm.txt?distro=el&codename=7' > /tmp/tetrate-getenvoy-rpm-stable.repo
sudo yum-config-manager --add-repo '/tmp/tetrate-getenvoy-rpm-stable.repo'
sudo yum makecache --disablerepo='*' --enablerepo='tetrate-getenvoy-rpm-stable' -y
sudo yum install getenvoy-envoy -y
# 확인
envoy --version
envoy version: d362e791eb9e4efa8d87f6d878740e72dc8330ac/1.18.2/clean-getenvoy-76c310e-envoy/RELEASE/BoringSSL
# 도움말
envoy --help
4
Envoy proxy 실습
# 데모 config 적용하여 실행
curl -O https://www.envoyproxy.io/docs/envoy/latest/_downloads/92dcb9714fb6bc288d042029b34c0de4/envoy-demo.yaml
envoy -c envoy-demo.yaml
# 에러 출력되면서 실행 실패
error initializing configuration 'envoy-demo.yaml': Field 'connect_timeout' is missing in: name: "service_envoyproxy_io"
# (터미널1) connect_timeout 추가 후 다시 실행
sed -i'' -r -e "/dns_lookup_family/a\ connect_timeout: 5s" envoy-demo.yaml
envoy -c envoy-demo.yaml
## 출력 로그
[2021-12-13T12:20:25.981Z] "GET / HTTP/1.1" 200 - 0 4472 1140 1080 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36" "a6999dc1-5e5e-4029-89b7-331b081fca27" "www.envoyproxy.io" "52.220.193.16:443"
[2021-12-13T12:22:21.634Z] "GET / HTTP/1.1" 200 - 0 17228 247 121 "-" "curl/7.74.0" "39b7b07d-3f79-4e61-81b4-2944bd041535" "www.envoyproxy.io" "167.99.78.230:443"
# (터미널2) 정보 확인
ss -tnlp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 0.0.0.0:10000 0.0.0.0:* users:(("envoy",pid=8007,fd=18),("envoy",pid=8007,fd=16))
# 접속 테스트
curl -s http://127.0.0.1:10000 | grep -o "<title>.*</title>"
<title>Envoy Proxy - Home</title>
# 자신의PC(웹브라우저)에서 작업용EC2 접속 확인 >> 어느 사이트로 접속이 되는가?
echo -e "Envoy Proxy Demo = http://$(curl -s ipinfo.io/ip):10000"
# 연결 정보 확인
ss -tnp
# (터미널1) envoy 실행 취소(CTRL+C) 후 (관리자페이지) 설정 덮어쓰기 - 링크
cat <<EOT> envoy-override.yaml
admin:
address:
socket_address:
address: 0.0.0.0
port_value: 9902
EOT
envoy -c envoy-demo.yaml --config-yaml "$(cat envoy-override.yaml)"
# 웹브라우저에서 http://192.168.10.254:9902 접속 확인!
# 자신의PC(웹브라우저)에서 작업용EC2 접속 확인 >> 어느 사이트로 접속이 되는가?
echo -e "Envoy Proxy Demo = http://$(curl -s ipinfo.io/ip):9902"
<3> ingressgateway 인입 구성 방안
1
NLB → istio-ingressgateway
ALB → istio-ingressgateway
NLB(IP mode) → istio-ingressgateway : 파드 IP로 직접 연결, Client IP 수집 시 PPv2 활성화 및 envoy 옵션 수정 필요 - 링크
*ALB(Instance mode) → (NodePort) istio-ingressgateway : 노드의 NodePort로 연결(약간 비효율적인 연결 가능), Client IP는 XFF로 수집
ALB(IP mode) → istio-ingressgateway : 가능 할 것으로 보임, 테스트 해 볼 것
아래 Istio 실습 전 사전 준비 사항 : AWS LoadBalancer Controller, ExternanDNS
2
설치 : k8s 1.23~1.26은 istio 1.17 지원됨
버전
설치
운영
workshop
3
# istioctl 설치
ISTIOV=1.17.2
curl -s -L https://istio.io/downloadIstio | ISTIO_VERSION=$ISTIOV TARGET_ARCH=x86_64 sh -
tree istio-$ISTIOV -L 2
cp istio-$ISTIOV/bin/istioctl /usr/local/bin/istioctl
istioctl version --remote=false
1.17.2
4
# (default 프로파일) 컨트롤 플레인 배포 - 링크 Customizing
istioctl profile list
Istio configuration profiles:
ambient
default
demo
empty
external
minimal
openshift
preview
remote
istioctl profile dump default | yh
istioctl profile dump --config-path components.ingressGateways
istioctl profile dump --config-path values.gateways.istio-ingressgateway
istioctl install --set profile=default -y
5
# 설치 확인
kubectl get-all -n istio-system
kubectl get all -n istio-system
kubectl get crd | grep istio.io | sort
authorizationpolicies.security.istio.io 2023-05-02T12:22:17Z
destinationrules.networking.istio.io 2023-05-02T12:22:17Z
envoyfilters.networking.istio.io 2023-05-02T12:22:17Z
gateways.networking.istio.io 2023-05-02T12:22:17Z
istiooperators.install.istio.io 2023-05-02T12:22:17Z
peerauthentications.security.istio.io 2023-05-02T12:22:17Z
proxyconfigs.networking.istio.io 2023-05-02T12:22:17Z
requestauthentications.security.istio.io 2023-05-02T12:22:17Z
serviceentries.networking.istio.io 2023-05-02T12:22:17Z
sidecars.networking.istio.io 2023-05-02T12:22:17Z
telemetries.telemetry.istio.io 2023-05-02T12:22:17Z
virtualservices.networking.istio.io 2023-05-02T12:22:17Z
wasmplugins.extensions.istio.io 2023-05-02T12:22:17Z
workloadentries.networking.istio.io 2023-05-02T12:22:17Z
workloadgroups.networking.istio.io 2023-05-02T12:22:17Z
6
# NodePort로 변경
kubectl patch svc -n istio-system istio-ingressgateway -p '{"spec":{"type":"NodePort"}}'
7
# 확인
kubectl get svc,ep -n istio-system istio-ingressgateway
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway NodePort 10.100.247.44 <none> 15021:32609/TCP,80:30479/TCP,443:31783/TCP 92m
NAME ENDPOINTS AGE
endpoints/istio-ingressgateway 192.168.2.15:15021,192.168.2.15:8080,192.168.2.15:8443 99m
8
# istio-ingressgateway 의 envoy 버전 확인
kubectl exec -it deploy/istio-ingressgateway -n istio-system -c istio-proxy -- envoy --version
envoy version: d799381810ae54f1cccb2a9ae79d9c6191ca2c83/1.25.4-dev/Clean/RELEASE/BoringSSL
envoy version: d799381810ae54f1cccb2a9ae79d9c6191ca2c83/1.25.4-dev/Clean/RELEASE/BoringSSL
envoy version: d799381810ae54f1cccb2a9ae79d9c6191ca2c83/1.25.4-dev/Clean/RELEASE/BoringSSL
9
kubectl get svc -n istio-system istio-ingressgateway -o jsonpath={.spec.ports[*]} | jq
{
"name": "status-port",
"nodePort": 30159,
"port": 15021,
"protocol": "TCP",
"targetPort": 15021
}
{
"name": "http2",
"nodePort": 31215,
"port": 80,
"protocol": "TCP",
"targetPort": 8080
}
{
"name": "https",
"nodePort": 30431,
"port": 443,
"protocol": "TCP",
"targetPort": 8443
}
10
kubectl get deploy/istio-ingressgateway -n istio-system -o jsonpath={.spec.template.spec.containers[0].ports[*]} | jq
{
"containerPort": 15021,
"protocol": "TCP"
}
{
"containerPort": 8080,
"protocol": "TCP"
}
{
"containerPort": 8443,
"protocol": "TCP"
}
{
"containerPort": 15090,
"name": "http-envoy-prom",
"protocol": "TCP"
}
11
kubectl get deploy/istio-ingressgateway -n istio-system -o jsonpath={.spec.template.spec.containers[0].readinessProbe} | jq
{
"failureThreshold": 30,
"httpGet": {
"path": "/healthz/ready",
"port": 15021,
"scheme": "HTTP"
},
"initialDelaySeconds": 1,
"periodSeconds": 2,
"successThreshold": 1,
"timeoutSeconds": 1
}
12
#
HPORT=$(kubectl get service istio-ingressgateway -n istio-system -o jsonpath='{.spec.ports[?(@.name=="status-port")].nodePort}')
# 사용 리전의 인증서 ARN 확인
aws acm list-certificates --query 'CertificateSummaryList[].CertificateArn[]' --output text
CERT_ARN=$(aws acm list-certificates --query 'CertificateSummaryList[].CertificateArn[]' --output text)
echo $CERT_ARN
13
# 배포
curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/aews/istioingress.yaml
MyDomain=$MyDomain HPORT=$HPORT CERT_ARN=$CERT_ARN envsubst < istioingress.yaml | kubectl apply -f -
14
# 확인
kubectl get pod,svc,ingress -n istio-system
15
# istioingress 접속 시도
echo "https://istio.${MyDomain}"
https://istio.taeho11.co.kr
# Auto Injection with namespace label : 해당 네임스페이스에 생성되는 모든 파드들은 istio 사이드카가 자동으로 winjection 됨
# mutating Webhook admisstion controller 사용
kubectl label namespace default istio-injection=enabled
namespace/default labeled
kubectl get ns -L istio-injection
NAME STATUS AGE ISTIO-INJECTION
amazon-cloudwatch Active 53m
default Active 4h37m enabled
istio-system Active 8m57s
kube-node-lease Active 4h37m
kube-public Active 4h37m
kube-system Active 4h37m
monitoring Active 34m
...
<4> 샘플 어플리케이션 배포
1
2
모니터링
3
4개의 마이크로서비스로 구성 : Productpage, reviews, ratings, details
Reviews 서비스는 v1, v2, v3 세 개의 버전이 있고 v2, v3 버전의 경우 Ratings 서비스에 접소갛여 도서에 대한 5단계 평가를 가져옴.
Reviews 서비스의 차이는, v1은 Rating 이 없고, v2는 검은색 별로 Ratings 가 표시되며, v3는 색깔이 있는 별로 Ratings 가 표시됨.
4
구성
5
설치
# 설치
tree istio-$ISTIOV/samples/bookinfo/platform/kube/
cat istio-$ISTIOV/samples/bookinfo/platform/kube/bookinfo.yaml | yh
kubectl apply -f istio-$ISTIOV/samples/bookinfo/platform/kube/bookinfo.yaml
6
# 설치 확인
kubectl get pod,svc
# ratings 파드에서 exec(curl)로 productpage 접속하여 정상 동작 확인
# kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}'
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>"
<title>Simple Bookstore App</title>
7
# 실제 요청을 받기 위해 Gateway, VirtualService 생성
# Istio Gateway(=gw)/VirtualService(=vs) 설정 정보를 확인
# virtual service 는 다른 네임스페이스의 서비스(ex. svc-nn.<ns>)도 참조할 수 있다
cat istio-$ISTIOV/samples/bookinfo/networking/bookinfo-gateway.yaml | yh
kubectl apply -f istio-$ISTIOV/samples/bookinfo/networking/bookinfo-gateway.yaml
kubectl get gateway,virtualservices
NAME AGE
gateway.networking.istio.io/bookinfo-gateway 9s
NAME GATEWAYS HOSTS AGE
virtualservice.networking.istio.io/bookinfo ["bookinfo-gateway"] ["*"] 9s
8
# 외부 접속 주소 확인
echo "https://istio.${MyDomain}/productpage"
https://istio.taeho11.co.kr/productpage
9
# 접속 확인 >> 웹 브라우저 접속 후 새로고침으로 별점 부분 확인!
curl -I https://istio.${MyDomain}/productpage
curl -s https://istio.${MyDomain}/productpage | grep -o "<title>.*</title>"
<title>Simple Bookstore App</title>
10
# productpage 파드의 istio-proxy 로그 확인 : Access log 가 나오지 않는다!
kubectl logs -l app=productpage -c istio-proxy -f
11
# Using Telemetry API : envoy 에 access log 활성화
kubectl apply -f - <<EOF
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
name: mesh-default
namespace: istio-system
spec:
accessLogging:
- providers:
- name: envoy
EOF
# 확인
kubectl get telemetries -n istio-system
NAME AGE
mesh-default 9s
12
# productpage 파드의 istio-proxy 로그 확인 : Access log 가 출력된다! : Default access log format - 링크
kubectl logs -l app=productpage -c istio-proxy -f
[2022-02-16T17:56:20.030Z] "GET /reviews/0 HTTP/1.1" 200 - via_upstream - "-" 0 375 11 11 "-" "curl/7.68.0" "c1921f78-c8de-4445-a026-360b5dd6f51d" "reviews:9080" "172.16.184.6:9080" outbound|9080||reviews.default.svc.cluster.local 172.16.158.7:55410 10.101.97.213:9080 172.16.158.7:34590 - default
[2022-02-16T17:56:20.020Z] "GET /productpage HTTP/1.1" 200 - via_upstream - "-" 0 5179 23 23 "192.168.10.254" "curl/7.68.0" "c1921f78-c8de-4445-a026-360b5dd6f51d" "www.gasida.dev:30858" "172.16.158.7:9080" inbound|9080|| 127.0.0.6:55471 172.16.158.7:9080 192.168.10.254:0 outbound_.9080_._.productpage.default.svc.cluster.local default
<5> istio 삭제
1
# addon 제거
kubectl delete -f istio-$ISTIOV/samples/addons
2
# 북인포와 vs/gw 제거
kubectl delete -f istio-$ISTIOV/samples/bookinfo/networking/bookinfo-gateway.yaml
kubectl delete -f istio-$ISTIOV/samples/bookinfo/platform/kube/bookinfo.yaml
3
# istio 제거
kubectl delete -f istioingress.yaml
istioctl uninstall -y --purge
kubectl delete namespace istio-system
kubectl label namespace default istio-injection-
<6> core dns
감사합니다.