-
쿠버네티스 라벨을 이용한 카나리(canary) 배포Kubernetes 2018. 7. 31. 12:35라벨은 다양하게 활용할 수 있습니다. 그 중에서도 배포에 활용하는 방법을 알아보도록 하겠습니다. 일반적으로 배포를 이야기 할 때는 롤링업데이트, 블루/그린, 카나리등 여러가지 방법이 있습니다. 롤링업데이트는 전체 배포 되어 있는 포드들을 한꺼번에 교체하는 것이 아니라 일정 개수씩 바꿔치기하면서 배포하는 방법으로 디플로이먼트의 기본 배포 방법입니다. 블루/그린은 기존에 띄워져 있는 포드 개수와 동일한 개수 만큼의 신규포드를 모두 띄운 다음에 신규 포드가 이상없이 정상적으로 떴는지 확인한 다음에 들어오는 트래픽을 한번에 신규포드쪽으로 옮기는 방법입니다. 이것역시 디플로이먼트를 이용하면 가능합니다. 카나리 배포는 옛날 광부들이 광산에 유독가스가 있는지 확인하기 위해 가스에 민감한 카나리아를 광산에 가지고 들어간 거에서 아이디어를 얻은 배포 방법입니다. 신규 버전을 배포할 때 한꺼번에 앱의 전체를 교체하는게 아니라 기존 버전을 유지한 채로 일부 버전만 신규 버전으로 올려서 신규 버전에 버그나 이상은 없는지를 사용자 반응은 어떤지 확인하는데 유용하게 사용하는 방법입니다. 쿠버네티스의 기본 디플로이먼트로는 디플로이먼트에 속한 포드들을 하나씩이던 한꺼번에든 모두 교체하는 방식이기 때문에 이런 카나리 배포를 하기에는 어려움이 있습니다. 하지만 라벨을 이용하면 쿠버네티스에서도 카나리 배포를 할 수 있습니다.카나리 배포를 위해서 우선 2개의 디플로이먼트를 만듭니다.deployment-v1.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: k8s-testapplabels:app: myappversion: stablespec:replicas: 2selector:matchLabels:app: myappversion: stabletemplate:metadata:labels:app: myappversion: stablespec:containers:- name: testappimage: arisu1000/simple-container-app:v0.1ports:- containerPort: 8080deployment-v2.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: k8s-testapp-canarylabels:app: myappversion: canaryspec:replicas: 1selector:matchLabels:app: myappversion: canarytemplate:metadata:labels:app: myappversion: canaryspec:containers:- name: testappimage: arisu1000/simple-container-app:v0.2ports:- containerPort: 8080앞의 yaml파일을 이용해서 버전이 다른 2개의 포드를 실행합니다.kubectl apply -f deployment-v1.yamlkubectl apply -f deployment-v2.yamlv1과 v2에서 실행되는 컨테이너 이미지는 접속한 내역을 보여주는 간단한 앱입니다. 앞부분에 app version을 표시하는데 v1에서는 v0.1을 보여주고 v2에서는 v0.2를 보여줍니다. deployment파일의 내용중 deployment-v1.yaml은 app=myapp, version=stable 라는 라벨을 가지고 있고, deployment-v2.yaml은 app=myapp, version=canary라는 라벨을 가지고 있습니다. 같은 앱이지만 라벨을 이용해서 stable버전과 canary버전을 구분하기 위한 용도입니다. 그리고 v1은 포드를 2개 실행했고, v2는 canary용이기 때문에 1개만 실행했습니다.이제 이 2개의 디플로이먼트에 접근하는 하나의 서비스를 실행해 보겠습니다.myapp-svc.yamlapiVersion: v1kind: Servicemetadata:labels:app: myappname: myapp-svcnamespace: defaultspec:ports:- nodePort: 30880port: 8080protocol: TCPtargetPort: 8080selector:app: myapptype: NodePortkubectl apply -f myapp-svc.yaml로 실행하면 30880의 포트를 가진 노드포트로 서비스를 실행합니다.curl localhost:30880 로 여러번 접속해 보면 결과를 확인할 수 있습니다. app version이 v0.1과 v0.2를 번갈아 가면서 출력되는걸 확인할 수 있습니다. 여러개의 디플로이먼트를 하나의 접속 주소로 묶어서 서비스하고 있다는걸 확인할 수 있습니다.
보다 자세한 내용을 확인하려면 다음 명령으로 현재 pod정보와 svc가 어떻게 연결되어 있는지 확인할 수 있습니다.[wcjung@jeong-woncheon-ui-MacBook-Pro ~]$ kubectl get pods -o wideNAME READY STATUS RESTARTS AGE IP NODEk8s-testapp-86b5494dd4-2glc6 1/1 Running 0 27m 10.1.0.123 docker-for-desktopk8s-testapp-86b5494dd4-crm4p 1/1 Running 0 27m 10.1.0.124 docker-for-desktopk8s-testapp-canary-54fcdcfdbd-drh59 1/1 Running 0 27m 10.1.0.125 docker-for-desktop[wcjung@jeong-woncheon-ui-MacBook-Pro ~]$ kubectl describe svc myapp-svcName: myapp-svcNamespace: defaultLabels: app=myappAnnotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app":"myapp"},"name":"myapp-svc","namespace":"default"},"spec":{"ports":[{"...Selector: app=myappType: NodePortIP: 10.107.123.233LoadBalancer Ingress: localhostPort: <unset> 8080/TCPTargetPort: 8080/TCPNodePort: <unset> 30880/TCPEndpoints: 10.1.0.123:8080,10.1.0.124:8080,10.1.0.125:8080Session Affinity: NoneExternal Traffic Policy: ClusterEvents: <none>각 pod정보의 IP들이 service의 Endpoints부분에 보면 나와있는걸 확인할 수 있습니다. 이렇게 stable버전의 포드와 canary버전의 포드를 동시에 서비스할 수 있습니다. 이 상태에서 canary버전이 정상작동하는지 확인하고 만약 제대로 작동하지 않는다면 디플로이먼트를 지우거나 디플로이먼트의 replicas를 0으로 조정해서 서비스에서 제외할 수 있습니다. 좀 더 많은 사용자에게 테스트를 해보고 싶다면 canary버전의 replicas 개수를 늘려서 보다 많은 요청을 canary버전에서 받게할 수도 있습니다. 그리고 canary버전이 정상작동한다면 stable에 있는 컨테이너의 이미지를 업데이트해서 전체 서비스에 적용할 수 있습니다.'Kubernetes' 카테고리의 다른 글
쿠버네티스 시크릿(kubernetes secret) (0) 2018.08.03 쿠버네티스 컨피그맵(kubernetes configmap) (1) 2018.08.01 쿠버네티스 라벨과 애노테이션(kubernetes label, annotation) (1) 2018.07.26 쿠버네티스 인그레스(kubernetes ingress) (20) 2018.07.18 쿠버네티스 서비스(kubernetes services) (2) (3) 2018.07.13 댓글