Service Mesh 전략 by 윤종연 차장님
About Istio
Istio는 Kubernetes에서 마이크로서비스 아키텍처에서 서비스 간 통신과 관리를 담당하는 서비스 메시 플랫폼입니다. Istio는 사이드카 프록시를 사용하여 네트워크 트래픽을 제어하고 보안 기능을 제공하며, 트래픽 라우팅, 부하 분산, 장애 복구, 트래픽 모니터링 등의 기능을 수행합니다. 이를 통해 개발자는 서비스 간 통신을 표준화하고 중앙에서 관리할 수 있으며, 애플리케이션의 안정성과 보안을 강화할 수 있습니다.
Unterstand Istio Architecture
배포된 모든 Application과 함께 Proxy “SideCar”를 추가함으로써 Istio를 사용하면 App의 인식, 트래팩 관리, 놀라운 관찰 가능성 및 강력한 보안 기능을 네트워크에 프로그래밍 할 수 있습니다.
Istio 사용 전
Istio 사용 후
Istio에는 데이터 평면과 제어 평면이라는 두 가지 구성 요소가 있습니다. 데이터 플레인은 서비스 간의 통신입니다. 서비스 메시가 없으면 네트워크는 전송되는 트래픽을 이해하지 못하며 트래픽의 유형이나 발신자 또는 수신자를 기반으로 결정을 내릴 수 없습니다. 서비스 메시는 프록시를 사용하여 모든 네트워크 트래픽을 가로채서 설정한 구성을 기반으로 광범위한 애플리케이션 인식 기능을 허용합니다. Envoy 프록시는 클러스터에서 시작하는 각 서비스와 함께 배포되거나 VM에서 실행되는 서비스와 함께 실행됩니다. 컨트롤 플레인은 원하는 구성과 서비스 보기를 가져와서 프록시 서버를 동적으로 프로그래밍 하여 규칙이나 환경이 변경되면 업데이트합니다.
목차
Install
Istio
Add-Ons
Demo Update Strategy BlueGreen
Demo Update Strategy Canary
Install Istio
Requirement
Istio 1.18.0 버전(현재 최신버전) 은 Kubernetes(1.24, 1.25, 1.26, 1.27) 버전에서 동작 한다.
How to Deployment
Istio 설치에서 다양하 모델로 설치 할 수 있는데 (single or multiple cluster, single or multiple network, single or multiple control plane, single or multiple mesh) 여기서는 Single Cluster, Network, Control plane, mesh 모두 싱글로 구성 하였다. 추 후 멀티로 구성 하는 것들도 진행을 해보는 것이 좋을 것같다 자세한 정보 참고 https://istio.io/latest/docs/ops/deployment/deployment-models/
구성
Component | Version |
istiod | v1.18.0 |
Egress | v1.18.0 |
Ingress | v1.18.0 |
Deploy Istio Components
Dowload CLI & Pre-Check
# Istio 다운로드 버전을 명시하여 다운로드
curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.18.0 TARGET_ARCH=x86_64 sh -
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 102 100 102 0 0 347 0 --:--:-- --:--:-- --:--:-- 346
100 4856 100 4856 0 0 10609 0 --:--:-- --:--:-- --:--:-- 10609
Downloading istio-1.18.0 from https://github.com/istio/istio/releases/download/1.18.0/istio-1.18.0-linux-amd64.tar.gz ...
Istio 1.18.0 Download Complete!
Istio has been successfully downloaded into the istio-1.18.0 folder on your system.
Next Steps:
See https://istio.io/latest/docs/setup/install/ to add Istio to your Kubernetes cluster.
To configure the istioctl client tool for your workstation,
add the /root/istio-1.18.0/bin directory to your environment path variable with:
export PATH="$PATH:/root/istio-1.18.0/bin"
Begin the Istio pre-installation check by running:
istioctl x precheck
Need more information? Visit https://istio.io/latest/docs/setup/install/
# 환경변수에 Path 등록 또는 istioctl 파일을 복사한다.
cp ~/istio-1.18.0/bin/istioctl /usr/local/bin/
# 선행 체크 실행 No issues 확인
istioctl x precheck
✔ No issues found when checking the cluster. Istio is safe to install or upgrade!
To get started, check out https://istio.io/latest/docs/setup/getting-started/
Bash
복사
2.
Setup Istio Profile
설치 과정으로 Istio는 설치에 Profile이란 것이 존재하며 다양한 프로파일에 기본으로 설치되고 되지 않는 Component 들이있으니 확인을 하고 설치하자 참고로 Production 환경에서 Demo Profile을 사용하지 않도록 하자. 여기서는 Prodoction 환경에서 권장하는 default 프로파일에 egress gateway를 추가하는 방법으로 설치를 할 것이다. 참고 https://istio.io/latest/docs/setup/additional-setup/config-profiles/
아래 그림은 default(좌) 와 demo(우) 의 비교이다. demo경우 resource 부분에 CPU 와 Memory 를 제한 하고 있어서 사용하지 말아야 하며 default의 경우 egressGateways같은 것이 false 로 비활성화 되어있기 때문에 필요시 변경해야 한다.
# Istio 설치 프로파일 리스트이며 이중에 기본적으로 Production 환경에서는 default 를 사용한다.
istioctl profile list
Istio configuration profiles:
ambient
default
demo
empty
external
minimal
openshift
preview
remote
# 그냥 default 프로파일을 설정하면 아래와 같이 3개가 설치되는 것을 볼 수 있다. egress는 빠져있다.
istioctl install --set profile=default
This will install the Istio 1.18.0 default profile with ["Istio core" "Istiod" "Ingress gateways"] components into the cluster. Proceed? (y/N)
# default 프로파일에 추가로 egressgateway 활성화와 함께 하는 방법1
vi manifests/profiles/default.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
namespace: istio-system2
spec:
:
:
components:
egressGateways:
- name: istio-egressgateway
enabled: true # false를 true 로 바꿈
저장
# 수정한 파일로 지정하면 Egress 가 추가된것을 볼 수 있다.
istioctl install -f manifests/profiles/default.yaml
This will install the Istio 1.18.0 default profile with ["Istio core" "Istiod" "Ingress gateways" "Egress gateways"] components into the cluster. Proceed? (y/N) n
# default 프로파일에 추가로 egressgateway 활성화와 함께 하는 방법2
istioctl install --set profile=default --set components.egressGateways[0].name=istio-egressgateway --set components.egressGateways[0].enabled=true
This will install the Istio 1.18.0 default profile with ["Istio core" "Istiod" "Ingress gateways" "Egress gateways"] components into the cluster. Proceed? (y/N) n
Bash
복사
3.
Install Istio Components
# 위 yaml 파일 수정 버전으로 설치 Egress 추가된 것을 볼 수 있다.
istioctl install -f manifests/profiles/default.yaml
This will install the Istio 1.18.0 default profile with ["Istio core" "Istiod" "Ingress gateways" "Egress gateways"] components into the cluster. Proceed? (y/N) y
✔ Istio core installed
✔ Istiod installed
✔ Egress gateways installed
✔ Ingress gateways installed
✔ Installation complete
Making this installation the default for injection and validation.
# istioctl 명령 확인
istioctl version
client version: 1.18.0
control plane version: 1.18.0
data plane version: 1.18.0 (2 proxies)
# kubectl 명령 확인 여기서 ingressgateway 가 EXTERNAL-IP 를 받은 이유는 Metallb에서 자동으로 받아온 것이다. IP를 못받아오면 저기는 따로 구성을 해주어야 한다.
kubectl get all -n istio-system
NAME READY STATUS RESTARTS AGE
pod/istio-egressgateway-6964995f45-dbkr2 1/1 Running 0 7m32s
pod/istio-ingressgateway-56ffb9b986-vkftj 1/1 Running 0 7m32s
pod/istiod-66ff7c9bfd-ckbrx 1/1 Running 0 7m36s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/authservice ClusterIP 10.233.53.168 <none> 8080/TCP 8d
service/istio-egressgateway ClusterIP 10.233.34.190 <none> 80/TCP,443/TCP 7m32s
service/istio-ingressgateway LoadBalancer 10.233.14.90 172.30.10.121 15021:31900/TCP,80:32141/TCP,443:31134/TCP 7m32s
service/istiod ClusterIP 10.233.6.197 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 7m36s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/istio-egressgateway 1/1 1 1 7m32s
deployment.apps/istio-ingressgateway 1/1 1 1 7m32s
deployment.apps/istiod 1/1 1 1 7m36s
NAME DESIRED CURRENT READY AGE
replicaset.apps/istio-egressgateway-6964995f45 1 1 1 7m32s
replicaset.apps/istio-ingressgateway-56ffb9b986 1 1 1 7m32s
replicaset.apps/istiod-66ff7c9bfd 1 1 1 7m36s
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
horizontalpodautoscaler.autoscaling/istio-egressgateway Deployment/istio-egressgateway 4%/80% 1 5 1 7m32s
horizontalpodautoscaler.autoscaling/istio-ingressgateway Deployment/istio-ingressgateway 5%/80% 1 5 1 7m32s
horizontalpodautoscaler.autoscaling/istiod Deployment/istiod 1%/80% 1 5 1 7m36s
Bash
복사
4.
Uninstall Istio
# 위 yaml 파일 수정 버전으로 설치 Egress 추가된 것을 볼 수 있다.
istioctl install -f manifests/profiles/default.yaml
This will install the Istio 1.18.0 default profile with ["Istio core" "Istiod" "Ingress gateways" "Egress gateways"] components into the cluster. Proceed? (y/N) y
✔ Istio core installed
✔ Istiod installed
✔ Egress gateways installed
✔ Ingress gateways installed
✔ Installation complete
Making this installation the default for injection and validation.
# istioctl 명령 확인
istioctl version
client version: 1.18.0
control plane version: 1.18.0
data plane version: 1.18.0 (2 proxies)
# kubectl 명령 확인 여기서 ingressgateway 가 EXTERNAL-IP 를 받은 이유는 Metallb에서 자동으로 받아온 것이다. IP를 못받아오면 저기는 따로 구성을 해주어야 한다.
kubectl get all -n istio-system
NAME READY STATUS RESTARTS AGE
pod/istio-egressgateway-6964995f45-dbkr2 1/1 Running 0 7m32s
pod/istio-ingressgateway-56ffb9b986-vkftj 1/1 Running 0 7m32s
pod/istiod-66ff7c9bfd-ckbrx 1/1 Running 0 7m36s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/authservice ClusterIP 10.233.53.168 <none> 8080/TCP 8d
service/istio-egressgateway ClusterIP 10.233.34.190 <none> 80/TCP,443/TCP 7m32s
service/istio-ingressgateway LoadBalancer 10.233.14.90 172.30.10.121 15021:31900/TCP,80:32141/TCP,443:31134/TCP 7m32s
service/istiod ClusterIP 10.233.6.197 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 7m36s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/istio-egressgateway 1/1 1 1 7m32s
deployment.apps/istio-ingressgateway 1/1 1 1 7m32s
deployment.apps/istiod 1/1 1 1 7m36s
NAME DESIRED CURRENT READY AGE
replicaset.apps/istio-egressgateway-6964995f45 1 1 1 7m32s
replicaset.apps/istio-ingressgateway-56ffb9b986 1 1 1 7m32s
replicaset.apps/istiod-66ff7c9bfd 1 1 1 7m36s
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
horizontalpodautoscaler.autoscaling/istio-egressgateway Deployment/istio-egressgateway 4%/80% 1 5 1 7m32s
horizontalpodautoscaler.autoscaling/istio-ingressgateway Deployment/istio-ingressgateway 5%/80% 1 5 1 7m32s
horizontalpodautoscaler.autoscaling/istiod Deployment/istiod 1%/80% 1 5 1 7m36s
Bash
복사
5.
Install Istio Add-Ons
What is Addons
Istio는 다양한 애드온(add-on)을 제공하여 서비스 메시를 보완하고 확장하는 기능을 제공합니다. 이러한 애드온들은 Istio의 기본 기능을 보완하거나 추가 기능을 제공하여 서비스 메시의 관리, 보안, 관찰 등을 강화합니다. 몇 가지 주요한 애드온은 다음과 같습니다
Kiali | Istio는 다양한 애드온(add-on)을 제공하여 서비스 메시를 보완하고 확장하는 기능을 제공합니다. 이러한 애드온들은 Istio의 기본 기능을 보완하거나 추가 기능을 제공하여 서비스 메시의 관리, 보안, 관찰 등을 강화합니다. 몇 가지 주요한 애드온은 다음과 같습니다 |
Prometheus | 시계열 데이터베이스로서 메트릭을 수집하고 저장하는 역할을 합니다. Istio에서 생성하는 다양한 메트릭을 수집하여 모니터링 및 경고 기능을 구현할 수 있습니다 |
Grafana | Prometheus로부터 수집된 메트릭 데이터를 시각화하여 대시보드로 표시합니다. 다양한 그래프와 시각화 도구를 사용하여 서비스 메시의 성능과 상태를 모니터링할 수 있습니다. |
Jaeger | 분산 추적 시스템으로서 서비스 간의 요청 추적을 지원합니다. 서비스 간의 호출 흐름과 지연 시간 등을 추적하여 복잡한 서비스 메시의 디버깅과 성능 개선에 도움을 줍니다. |
Zipkin | 마이크로서비스 아키텍처에서 발생하는 분산 추적 정보를 수집하고 시각화하는 데 사용됩니다. Zipkin을 사용하여 각 서비스 간의 호출 흐름을 추적하고 지연 시간을 확인할 수 있습니다. |
Install Add-Ons
# 노드 셀럭터로 특정 노드로 띄우고 Grafana 연결을 위해서 파일 수정을 해야한다.
vi samples/addons/jaeger kiali prometheus grafana loki 의 yaml 파일을 모두 열어 모두 monitor 노드로 가도록 해주었다.
sepc:
containers:
nodeSelector:
#kubernetes.io/os: linux
node-role.kubernetes.io/monitor: enable
저장
# Kiali 에서 AddOn 중에 Grafana 와 연결 하기 위해 kiali.yaml 파일은 추가로 넣어 주었다.
# 외부 Grafana 대시보드 연결은 문서 참고 https://kiali.io/docs/configuration/p8s-jaeger-grafana/grafana/
vi samples/addons/kiali.yaml
external_services:
custom_dashboards:
enabled: true
istio:
root_namespace: istio-system
grafana:
url: "http://grafana:3000"
# 제공된 addons 폴더에 모든 yaml 파일을 설치한다. 위에 언급한 툴이 모두 설치 된다. istio-system에 사용 하려고 namespace 를 붙여서 설치
kubectl apply -f samples/addons -n istio-system
serviceaccount/grafana created
configmap/grafana created
service/grafana created
deployment.apps/grafana created
configmap/istio-grafana-dashboards created
configmap/istio-services-grafana-dashboards created
deployment.apps/jaeger created
service/tracing created
service/zipkin created
service/jaeger-collector created
serviceaccount/kiali created
configmap/kiali created
clusterrole.rbac.authorization.k8s.io/kiali-viewer created
clusterrole.rbac.authorization.k8s.io/kiali created
clusterrolebinding.rbac.authorization.k8s.io/kiali created
role.rbac.authorization.k8s.io/kiali-controlplane created
rolebinding.rbac.authorization.k8s.io/kiali-controlplane created
service/kiali created
deployment.apps/kiali created
serviceaccount/loki created
configmap/loki created
configmap/loki-runtime created
service/loki-memberlist created
service/loki-headless created
service/loki created
statefulset.apps/loki created
serviceaccount/prometheus created
configmap/prometheus created
clusterrole.rbac.authorization.k8s.io/prometheus created
clusterrolebinding.rbac.authorization.k8s.io/prometheus created
service/prometheus created
deployment.apps/prometheus created
# kiali 설치가 되었는지 확인 해본다. 이런 식으로 다른 것도 확인 가능하다.
kubectl rollout status deployment/kiali -n istio-system
deployment "kiali" successfully rolled out
# 확인 AddOn 들은 모두 Monitor Node 로 띄우도록 nodeSelector 설정을 해주었다.
kubectl get pod -n istio-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
grafana-5f98b97b64-xwjkd 1/1 Running 0 67m 10.233.121.180 kubemonitor02 <none> <none>
istio-egressgateway-5f7cfc6776-spcxc 1/1 Running 0 4m5s 10.233.125.197 kubeinfra03 <none> <none>
istio-ingressgateway-8679bf9545-8x6lq 1/1 Running 0 4m5s 10.233.125.211 kubeinfra03 <none> <none>
istiod-66ff7c9bfd-d6gpl 1/1 Running 0 4m9s 10.233.125.221 kubeinfra03 <none> <none>
jaeger-76cd7c7566-xts78 1/1 Running 0 67m 10.233.121.179 kubemonitor02 <none> <none>
kiali-7799445c94-6ms7t 1/1 Running 0 67m 10.233.86.133 kubemonitor03 <none> <none>
loki-0 1/1 Running 0 67m 10.233.86.134 kubemonitor03 <none> <none>
prometheus-67599c8d5c-cwp5r 2/2 Running 0 67m 10.233.121.61 kubemonitor01 <none> <none>
Bash
복사
Add-On zipkin
# Zipkin사용으로 Zipkin을 추가로 배포 해보려고 extra 디렉토리의 zipkin을 설치했다.
cat samples/addons/extras/zipkin.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: zipkin
namespace: istio-system
labels:
app: zipkin
spec:
selector:
matchLabels:
app: zipkin
template:
metadata:
labels:
app: zipkin
sidecar.istio.io/inject: "false"
spec:
containers:
- name: zipkin
image: openzipkin/zipkin-slim:2.23.14
env:
- name: STORAGE_METHOD
value: "mem"
readinessProbe:
httpGet:
path: /health
port: 9411
initialDelaySeconds: 5
periodSeconds: 5
nodeSelector:
#kubernetes.io/os: linux
node-role.kubernetes.io/monitor: enable
---
apiVersion: v1
kind: Service
metadata:
name: tracing
namespace: istio-system
labels:
app: zipkin
spec:
type: ClusterIP
ports:
- name: http-query
port: 80
protocol: TCP
targetPort: 9411
selector:
app: zipkin
---
apiVersion: v1
kind: Service
metadata:
labels:
name: zipkin
name: zipkin
namespace: istio-system
spec:
ports:
- port: 9411
targetPort: 9411
name: http-query
selector:
app: zipkin
확인
kubectl apply -f samples/addons/extras/zipkin.yaml
deployment.apps/zipkin created
service/tracing configured
service/zipkin configured
kubectl get pod -n istio-system
NAME READY STATUS RESTARTS AGE
grafana-694697f484-zhlqd 1/1 Running 0 6d23h
istio-egressgateway-5f7cfc6776-spcxc 1/1 Running 0 6d23h
istio-ingressgateway-8679bf9545-8x6lq 1/1 Running 0 6d23h
istiod-66ff7c9bfd-d6gpl 1/1 Running 0 6d23h
jaeger-57cb5d5546-szbnn 1/1 Running 0 6d23h
kiali-855db86b7d-wwh97 1/1 Running 0 6d22h
loki-0 1/1 Running 0 7d
prometheus-79f95f68fc-g6f22 2/2 Running 0 6d23h
zipkin-977bc78bd-g26jh 1/1 Running 0 9s
Bash
복사
Kiali
Zipkin
Deployment Sample Application with Update Strategy BlueGreen
위에서 Istio Controller 의 설치는 마무리가 되었다. 이제 Isto를 적용할 Namespace와 거기에 보여줄 Application 셋팅을 진행 해본다. 파이프라인은 기존 파이프라인을 재사용 하면 될 것이고 여기서는 SideCar가 어떻게 적용이 되고 그것이 Kiali Dashboard에 어떻게 표현되는지를 중점으로 보는 것이다. 배포경우 ArgoCD 를 이용해서 배포를 할 것인데 Sample Application 은 기존에 ArgoCD를 통해서 Blue-Green을 했던 단순한 Nginx Web Pod를 기반으로 재사용해서 해보기로 하였다.
Copy Sample Application
ArgoCD에서 기존에 사용했던 rollout-nginx-test를 통째로 복사하여 istio blue-green 용도로 사용 하기로 했다 복재는 rollout-nginx-test-istio-blue-green 이라는 디렉토리에 했다.
Create & Modify Manifest Files
복사한 파일들중에 수정하고 생성된 파일들 있는데 생성한 파일은 gateway.yaml virtualservice.yaml 파일이다. 이며 kustomization.yaml 파일이 일부 수정이 되었고 나머지는 크게 바뀌지 않았다.
Gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: nginx-test-blue-green-gateway
spec:
# The selector matches the ingress gateway pod labels.
# If you installed Istio using Helm following the standard documentation, this would be "istio=ingress"
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "cloud-sre-istio-blue-green.icnp.******.co.kr"
Bash
복사
VirtualService.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: nginx-test-blue-green-virtualservice
spec:
hosts:
# 적용할 도메인 주소
- "cloud-sre-istio-blue-green.icnp.******.co.kr"
gateways:
# 통신할 게이트 웨이 개체명
- cloud-sre-istio-nginx-test-blue-green-gateway-prd
# 매치 조건 설정
http:
- match:
- uri:
exact: /v1
rewrite:
uri: /
route:
- destination:
# 실제 연결되는 Kubernetes의 service 명을 적어야 한다. 여기서는 Argo Rollout 의 Blue-Green에 사용하는 active service를 v1 에 매칭 시켰다.
host: cloud-sre-istio-nginx-test-blue-green-service-active-prd
#subset: v1
port:
number: 80
- match:
- uri:
exact: /v2
rewrite:
uri: /
route:
- destination:
# 실제 연결되는 Kubernetes의 service 명을 적어야 한다. 여기서는 Argo Rollout 의 Blue-Green에 사용하는 preview service를 v2 에 매칭 시켰다.
host: cloud-sre-istio-nginx-test-blue-green-service-preview-prd
port:
number: 80
Bash
복사
Rollout.yaml
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: nginx-test-istio-blue-green
spec:
replicas: 2
revisionHistoryLimit: 2
selector:
matchLabels:
app: cloud-sre-istio-nginx-test-blue-green-prd
template:
metadata:
labels:
app: cloud-sre-istio-nginx-test-blue-green-prd
#version: v1
spec:
containers:
- name: nginx-test
image: harbor.icnp.******.co.kr/cloud-sre/main/rollout-nginx-test-istio-blue-green
imagePullPolicy: Always
ports:
- containerPort: 80
imagePullSecrets:
- name: cloud-sre-istio-secret-harbor-nginx-test-prd
strategy:
blueGreen:
activeService: cloud-sre-istio-nginx-test-blue-green-service-active-prd
previewService: cloud-sre-istio-nginx-test-blue-green-service-preview-prd
autoPromotionEnabled: false
Bash
복사
Kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
#- loadbalancer.yaml
resources:
- rollout.yaml
- service-active.yaml
- service-preview.yaml
- secret.yaml
# 추가 된 파일
- gateway.yaml
- virtualservice.yaml
namePrefix: cloud-sre-istio-
nameSuffix: -prd
# 배포될 객체의 네임스페이스스
namespace: cloud-sre-istio
#patches:
#- target:
#kind: Rollout
#name: cloud-sre-istio-nginx-test-rollout-prd
#patch: |-
#- op: replace
#path: /spec/template/metadata/labels/version
#value: v2
# patch하여 base와 결합될 yaml 파일 리스트트
#patchesStrategicMerge:
#- deployment.yaml
#- service.yaml
#- rollout.yaml
# 공통 적으로 들어가는 라벨로 모든 객체 service or deployment 위 metadata.labels에 들어간다. prefix나 suffix 안붙는다는것을 참고해라 Deployment 에서는 이 값이 그냥 박히기만 하지만 Rollout 에서는 반드시 매칭이 되어야 한다.
commonLabels:
app: cloud-sre-istio-nginx-test-blue-green-prd
images:
- name: harbor.icnp.******.co.kr/cloud-sre/main/rollout-nginx-test-istio-blue-green
newTag: "3"
Bash
복사
Service-active.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-test-blue-green-service-active
spec:
#selector:
#version: v1
ports:
- port: 80
protocol: TCP
targetPort: 80
type: ClusterIP
Bash
복사
Service-preview.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-test-blue-green-service-preview
spec:
#selector:
#version: v2
ports:
- port: 80
protocol: TCP
targetPort: 80
type: ClusterIP
Bash
복사
App Sync ArgoCD
Connect Blue-Green Web Page
ArgoCD Rollout 에서 셋팅한 대로 Blue-Green 서비스로 접속 해본다. 현재(Active /v1)-미리보기(Preview /v2)는 모두 같은 Blue 페이지 인것을 확인 할 수 있다.
Test Update Strategy & Result (Blue-Green)
위에서 Istio Controller 의 설치는 마무리가 되었다. 이제 Isto를 적용할 Namespace와 거기에 보여줄 Application 셋팅을 진행 해본다. 파이프라인은 기존 파이프라인을 재사용 하면 될 것이고 여기서는 SideCar가 어떻게 적용이 되고 그것이 Kiali Dashboard에 어떻게 표현되는지를 중점으로 보는 것이다. 배포경우 ArgoCD 를 이용해서 배포를 할 것인데 Sample Application 은 기존에 ArgoCD를 통해서 Blue-Green을 했던 단순한 Nginx Web Pod를 기반으로 재사용해서 해보기로 하였다.
Edit & Build Sample Application Pipeline
Blue-Green 테스트를 위한 Pipeline 수정을 하였다. 특별 한 것 없이 기존 Blue 였던 배경과 글씨를 Green 으로 바꿔주고
ArgoCD에 새 이미지로 그린 배포 확인
Test Result Blue Green
Check Web Page
테스트 웹 화면 리프레쉬 하면 반영된 결과를 볼 수있다 Active /v1의 경우 그대로 유지하고 Preview 인 /v2 는 신규로 배포한 Green 으로 변경되었다.
Apply Promote Web Page
이제 최종적으로 Active 페이지인 /v1 페이지도 Green 페이지로 변경을 위해 Promote를 한다. Promote 하고 나면 다시 4개에서 2개로 줄어 들게 되고 v1마저 v2와 같은 이미지를 바라보게 된다.
Final Check Web Page
Promote 후 active(/v1) 페이지와 preview(/v2) 페이지 모두 새 이미지인 Green 으로 변경 된 것을 확인 할 수 있다.
Deployment Sample Application with Update Strategy Canary
위에서 Blue-Green 테스트는 잘 되었다 이번에는 Canary를 할 것인데 버전으로 하기보다 여기서는 Header로 컨트롤하는 것을 기준으로 했다. 분명 Istio에서 Label로 하여금 version 관리를 하는데 그것은 추후에 하는 것으로 생각을 하고 Nginx Ingress에서 Header 가지고 구성 한 것과 비슷한 방식으로 했다고 생각하면 쉽다. 거기에 Istio만의 Traffic Monitoring 이 추가되었다고 생각을 하고 보자.
Create Namespace Applied Istio Injection
샘플 Application 배포를 위한 Namespace 생성 이미 Blue-Green 에서 만들었다면 안해도 된다.
# 생성
kubectl create ns cloud-sre-istio
namespace/cloud-sre-istio created
# Istio 적용을 위해 Injention Enable
kubectl label namespace cloud-sre-istio istio-injection=enabled
namespace/cloud-sre-istio labeled
# 확인 enabled
kubectl get ns -L istio-injection cloud-sre-istio
NAME STATUS AGE ISTIO-INJECTION
cloud-sre-istio Active 53s enabled
# Injection 설정 삭제 방법
kubectl label namespace cloud-sre-istio istio-injection-
Bash
복사
Copy Sample Applicaiton
앞서 만들었던 Blue-Green 용을 그대로 복사해서 canary 라는 디렉토리로 만들었고 수정 후 Git에 그대로 업로드 했다.
Create & Modify Manifest Files
복사한 파일들중에 수정하고 생성된 파일들 있는데 생성한 파일은 gateway.yaml virtualservice.yaml 파일이다. 이며 kustomization.yaml 파일이 일부 수정이 되었고 나머지는 크게 바뀌지 않았다.
Gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: nginx-test-canary-gateway
spec:
# The selector matches the ingress gateway pod labels.
# If you installed Istio using Helm following the standard documentation, this would be "istio=ingress"
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "cloud-sre-istio-canary.icnp.******.co.kr"
Bash
복사
위에서 만든 gateway와 연결되어지는 virtualservice.yaml 파일 생성시 상당히 에를 먹었는데 우리가 원하는 것은 header가 없으면 canary 설정 비율 대로 랜덤하게 들어가도록 하고 header를 붙여서 들어오면 반드시 canary로 가도록 하고 싶었는데 아래 설정중에 - match 가 반드시 위에 있어야 동작을 한다. stable 밑으로 destination은 반드시 두개 stable 서비스와 canary 서비스가 있어야 오류가 없다. rollout.yaml 파일을 보면 stable이라는 이름을 사용하게된다.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: nginx-test-canary-virtualservice
spec:
hosts:
- "cloud-sre-istio-canary.icnp.******.co.kr"
gateways:
- cloud-sre-istio-nginx-test-canary-gateway-prd
http:
- match: # match 조건 설정
- headers: # 헤더 값 설정
header: # 헤더 값이 header: canary 인 경우에 아래 destination 인 preview 서비스로 간다. 가중치도 100%
exact: canary
route:
- destination:
host: cloud-sre-istio-nginx-test-canary-service-preview-prd
port:
number: 80
#weight: 100 # destination이 한개인 route인 경우 weight 생략이 가능하다 한곳으로 전부 연결되기 때문 하지만 아래 처럼 2개 이상인 경우 반드시 설정해야됨
# match에 안 맞는 경우 Stable로 들어오게되고 이 이름이 Rollout.yaml 파일에 기입 된다. 반드시 rollout에 canary와 stable 연결을 위해 destination이 두개가 있어야 한다.
- name: stable
route:
- destination:
host: cloud-sre-istio-nginx-test-canary-service-preview-prd
port:
number: 80
weight: 0 # 0% 라고 적었으나 Rollout.yaml에 의해 이 값은 무시 되기도 한다 그래서 ArgoCD 에서 보면 OutofSync 라고 나오나 무시해도된다.
- destination:
host: cloud-sre-istio-nginx-test-canary-service-active-prd
port:
number: 80
weight: 100 # 100% 라고 적었으나 Rollout.yaml에 의해 이 값은 무시 되기도 한다 그래서 ArgoCD 에서 보면 OutofSync 라고 나오나 무시해도된다.
Bash
복사
Rollout.yaml
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: nginx-test-istio-canary
spec:
replicas: 4
revisionHistoryLimit: 2
selector:
matchLabels:
app: cloud-sre-istio-nginx-test-canary-prd
template:
metadata:
labels:
app: cloud-sre-istio-nginx-test-canary-prd
spec:
containers:
- name: nginx-test
image: harbor.icnp.******.co.kr/cloud-sre/main/rollout-nginx-test-istio-canary
imagePullPolicy: Always
ports:
- containerPort: 80
imagePullSecrets:
- name: cloud-sre-istio-secret-harbor-nginx-test-prd
strategy:
canary:
canaryService: cloud-sre-istio-nginx-test-canary-service-preview-prd
stableService: cloud-sre-istio-nginx-test-canary-service-active-prd
# 하단의 steps영역은 argo rollout의 관리 영역으로 여기서 셋팅한 weight 값이 하단 istio virtualservice 에 셋팅되어 넘어가서 변경이 된다. 그럼과 동시에 out of sync가 나오지만 무시해도 상관없다.
steps:
- setWeight: 25
- pause:
{}
#duration: 1m
- setWeight: 50
- pause:
duration: 3m
- setWeight: 75
- pause:
duration: 5m
# istio canary 사용시 아래 부분이 반드시 설정되어야 한다.
trafficRouting:
istio:
virtualService:
name: cloud-sre-istio-nginx-test-canary-virtualservice-prd # 생성한 virtualservice 의 이름
routes:
- stable # 앞서 virtualservice 에 생성한 route의 이름 여기에 목적지가 두개 셋팅 된 것을 넣어야 한다.
Bash
복사
Kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- rollout.yaml
- service-active.yaml
- service-preview.yaml
- secret.yaml
- gateway.yaml
- virtualservice.yaml
#- loadbalancer.yaml
namePrefix: cloud-sre-istio-
nameSuffix: -prd
# 배포될 객체의 네임스페이스스
namespace: cloud-sre-istio
#patches:
#- target:
#kind: Rollout
#name: cloud-sre-istio-nginx-test-rollout-prd
#patch: |-
#- op: replace
#path: /spec/template/metadata/labels/version
#value: v2
# patch하여 base와 결합될 yaml 파일 리스트트
#patchesStrategicMerge:
# 공통 적으로 들어가는 라벨로 모든 객체 service or deployment 위 metadata.labels에 들어간다. prefix나 suffix 안붙는다는것을 참고해라
commonLabels:
app: cloud-sre-istio-nginx-test-canary-prd
images:
- name: harbor.icnp.******.co.kr/cloud-sre/main/rollout-nginx-test-istio-canary
newTag: "8"
Bash
복사
Service-active.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-test-canary-service-active
spec:
#selector:
# app:
ports:
- port: 80
protocol: TCP
targetPort: 80
type: ClusterIP
Bash
복사
Service-preview.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-test-canary-service-preview
spec:
#selector:
# app:
ports:
- port: 80
protocol: TCP
targetPort: 80
type: ClusterIP
Bash
복사
Add ArgoCD Application
Connect Web Page before Canary Test
Canary 배포 전 현재 페이지 접속은 계속해서 BLUE 로 접속을 하게 되어있다.
Test Update Strategy & Result (Canary)
위에서 셋팅한 것을 기반으로 Canary 테스트를 해본다.
Edit & Build Sample Application Pipeline
Canary 테스트를 위한 Pipeline 수정을 하였다. 특별 한 것 없이 기존 Blue 였던 배경과 글씨를 Green 으로 바꿔주고
ArgoCD에 새 이미지로 4개 에서 5개로 한개 늘어난 것을 볼 수있다 1개만 늘어 난 것은 100프로중에 canary로 25%를 지정했기에 1대만 늘어 나는 것이다.
Test Result Canary
Check Web Page without Header
Canary 배포 후 헤더가 없는 기본 접속 페이지로 접속 하면 75:25 비율로 Blue 와 Green 을 랜덤하게 접속 하게 되었다.
Check Web Page with Header
Canary 배포 후 미리 정의한 헤더를 입력해서 접속 하면 75:25 비율을 무시하고 Green 접속 페이지로 만 접속 하여 확인이 가능하게 되었다.
Apply Promote Web Page
이제 최종적으로 Active 페이지인 Blue 페이지도 Green 페이지로 변경을 위해 Promote를 한다. Promote 하고 나면 다시 5개에서 잠시 8개로 늘었다가 다시 4개로 줄어 들게 되고 모든 pod가 Green 이미지로 변경 되게 된다.
Final Check Web Page without Header
Promote 후 헤더가 없는 기본 접속 페이지로 접속 하면 이제는 Green 로만 접속 하게된다.
About Kiali and Zipkin
결국 위에서 무언가 한 것도 의미가 있지만 Istio 를 사용하면서 AddOn 으로 설치한 것들 중 Kiali Dashboard 로 Blue Green 테스트로 인한 트래픽의 변화를 아래와 같이 볼 수있고 어던 경로로 많이 연결이 되었는지도 확인이 가능하다.
윤종연 차장님