티스토리 뷰
20 CI/CD Pipeline - Run and Scale a Distributed Crossword Puzzle App with CI/CD on Kubernetes (Part 3)
zerobig-k8s 2018. 9. 11. 21:38<출처>
시리즈의 3회차에서는, Kr8sswordz Puzzle 애플리케이션을 동작시키는 메인 이벤트를 시작해 본다.
시리즈 중 Part 2에서, K8S 클러스터 안으로 Jenkins 파드를 배포했고, 이것을 이용하여 K8S 안에 컨테이너로 만든 Hello-Kenzan 애플리케이션을 자동으로 빌드하고 배포하는 CI/CI 파이프라인을 설치했다. 대단한 성과였지만, 여기서 멈추지 않는다.
Part 3에서는, Hello-Kenzan 애플리케이션은 잠시 치워두고 주요 이벤트인 Kr8sswordz Puzzle 애플리케이션 구동하기로 넘어가 보겠다. MongoDB 내 Etcd 캐싱과 퍼시스턴스 같은 다양한 컴포넌트를 공개할 것이다. 또한 K8S API를 이용하여 백엔드 서비스 파드를 스케일 업, 다운하기 위하여 내장형 UI 기능을 집중적으로 조명해보고 부하테스트를 시뮬레이션 해본다.
시리즈의 모든 글을 읽어보자.
Set Up a CI/CD Pipeline with Kubernetes Part 1: Overview
Set Up a CI/CD Pipeline with a Jenkins Pod in Kubernetes (Part 2)
Run and Scale a Distributed Crossword Puzzle App with CI/CD on Kubernetes (Part 3)
Set Up CI/CD for a Distributed Crossword Puzzle App on Kubernetes (Part 4)
설치를 시작하기 전에, Kr8sswordz Puzzle 앱의 일부로서 동작하게 될 파드를 살펴보는 것이 도움이 된다.
kr8sswordz - Node.js 프론트 UI를 갖는 하나의 React 컨테이너
puzzle - MongoDB내 퍼시스턴스와 etcd 내 캐싱을 통해 크로스 퍼즐에 응답을 제출하고 처리해주는 주요 백엔드 서비스
mongo - 크로스워드 응답에 대한 지속성을 제공해주는 MongoDB 컨테이너
etcd - 크로스워드 응답을 캐싱하기 위한 etcd 클라이언트
monitor-scale - puzzle 서비스의 스케일 업, 다운에 대한 기능을 처리해 주는 백엔드 서비스. 이 서비스는 또한 웹소켓 메시지를 브로트캐스팅하여 UI와 함게 상호작용 한다.
애플리케이션을 구동한 후에 보다 상세하게 메인 서비스 엔드포인트와 그 구조 속으로 들어가 보자, 그럼 출발해보자!
중요: 이 실습을 완성시키기 위해, 최신 버전의 리눅스, macOS가 동작하는 컴퓨터가 필요하다. 최적의 성능을 내기위해, 컴퓨터는 16GB의 RAM을 보유해야만 하며, 컴퓨터를 리부팅하고 현재 동작 중인 앱의 갯수를 최소로 유지한다. (그만큼 부하를 유발시킬 거라는 이야기지만 필자는 나름 사양이 빵빵?해서 리부팅과 앱 최소 유지는 생략했다^. 진행해 보고 버벅거리면 그때 조치하는 것으로 해도 무방할 듯...)
Exercise 1: Running the Kr8sswordz Puzzle App
먼저 Part 1과 Part 2 실습 단계를 거치면서 수행했던 것을 확인하고 싶을 것이다. 이미지 레파지토리와 Jenkins 파드를 설치했다–Part 3 진행을 위해 필요하다. 앞서 Minikube를 중지시켰다면, 다시 구동시켜야 한다. 다음 터미널 명령을 입력하고 클러스터가 구동되는 것을 기다린다.
1 2 3 4 5 6 7 8 9 10 11 | root@zerobig-vm-u:~# minikube start --memory 8000 --cpus 2 --kubernetes-version v1.10.0 Starting local Kubernetes v1.10.0 cluster... Starting VM... Getting VM IP address... Moving files into cluster... Setting up certs... Connecting to cluster... Setting up kubeconfig... Starting cluster components... Kubectl is now configured to use the cluster. Loading cached images from config file. | cs |
클러스터 상태를 확인하고 모든 파드를 확인해 보고 싶으면, 다음 명령을 수행해본다.
1 2 3 4 5 | root@zerobig-vm-u:~# kubectl cluster-info Kubernetes master is running at https://192.168.99.100:8443 KubeDNS is running at https://192.168.99.100:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'. | cs |
다음 터미널 명령으로 Part 3를 위한 대화형 튜토리얼을 시작해보자.
1 | root@zerobig-vm-u:~# cd /home/study/k8s/kubernetes-ci-cd/ | cs |
1 2 3 4 5 6 7 | root@zerobig-vm-u:/home/study/k8s/kubernetes-ci-cd# npm run part3 > kubernetes-ci-cd@1.0.0 part3 /home/study/k8s/kubernetes-ci-cd > node start.js part3.yml ? Welcome to the Linux.com interactive Kubernetes tutorial by Kenzan. Press enter to begin Yes | cs |
아래 명령을 타이핑 할 필요가 없음을 상기하자. -- 각 단계에서 엔터만 치면 스크립트가 그 명령을 대신 입력해 줄 것이다!
1. 먼저, etcd에 의해 이용되는 한 쌍의 컴포넌트를 설치해 줄 etcd.sh 스크립트를 실행할 것이다. 이 컴포넌트는 etcd 클러스터 관리를 돕는 operator, 그리고 키 밸류를 저장하고 검색하기 위한 cluster service를 말한다. cluster 서비스는 이중화를 위해 3개의 파드 인스턴스로 동작한다.
클러스터에 etcd operator와 service를 구동한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | Part 3 Step: 1 Start the etcd operator and service on the cluster. You may notice errors showing up as it is waiting to start up the cluster. This is normal until it starts. scripts/etcd.sh Press enter to run the above command for the step. Yes installing etcd operator deployment.extensions/etcd-operator created Waiting for deployment "etcd-operator" rollout to finish: 0 out of 1 new replicas have been updated... Waiting for deployment "etcd-operator" rollout to finish: 0 of 1 updated replicas are available... deployment "etcd-operator" successfully rolled out pausing for 10 seconds for operator to settle etcdcluster.etcd.database.coreos.com/example-etcd-cluster created installing etcd cluster service service/example-etcd-cluster-client-service created waiting for etcd cluster to turnup | cs |
클러스터가 구동되는 것을 대기하고 있는 중이므로 안내 에러가 뜰지도 모른다. 구동을 마칠때가지 이것은 정상이다.
원한다면, 새로 터미널 창을 하나 띄워 "kubectl get pods"를 입력하여 새로운 파드를 확인해 볼 수 있다.
2. 이제 etcd 서비스가 생겼으니, etcd 클라이언트가 필요한다. 다음 명령은 키-밸류 쌍을 저장하기 위해 etcd 이내에 디렉토리를 설치해 준다. 그리고나서 etcd 클라이언트를 동작시켜 준다.
1 2 3 4 5 6 7 8 | Part 3 Step: 2 Now that we have an etcd service, we need an etcd client. The following command will set up a directory within etcd for storing key-value pairs, and th en run the etcd client. kubectl create -f manifests/etcd-job.yml Press enter to run the above command for the step. Yes job.batch/etcd-job created | cs |
3. step 2에서 배포한 것을 확인하기 위해 job의 상태를 체크해 본다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | Part 3 Step: 3 Check the status of the job in step 2 to make sure it deployed. kubectl describe jobs/etcd-job Press enter to run the above command for the step. Yes Name: etcd-job Namespace: default Selector: controller-uid=7d5e10c2-b348-11e8-91d0-08002737e655 Labels: controller-uid=7d5e10c2-b348-11e8-91d0-08002737e655 job-name=etcd-job Annotations: <none> Parallelism: 1 Completions: 1 Start Time: Sat, 08 Sep 2018 18:20:55 +0900 Pods Statuses: 1 Running / 0 Succeeded / 0 Failed Pod Template: Labels: controller-uid=7d5e10c2-b348-11e8-91d0-08002737e655 job-name=etcd-job Containers: etcd-job: Image: tenstartups/etcdctl Port: <none> Host Port: <none> Command: etcdctl mkdir pod-list Environment: ETCDCTL_ENDPOINT: http://example-etcd-cluster-client-service:2379 Mounts: <none> Volumes: <none> Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SuccessfulCreate 16s job-controller Created pod: etcd-job-fxb55 | cs |
4. 크로스워드 애플리케이션은 multi-tier 애플리케이션으로 서로 의존관계를 갖는다. 배포가 그것들을 감지할 수 있도록 예상보다 빨리 K8S에 3개의 서비스를 생성할 것이다.
1 2 3 4 5 6 7 8 9 10 | Part 3 Step: 4 The crossword application is a multi-tier application whose services depend on each other. We will create three services in Kubernetes ahead of time, s o that the deployments are aware of them. kubectl apply -f manifests/all-services.yml Press enter to run the above command for the step. Yes service/monitor-scale created service/puzzle created service/kr8sswordz created | cs |
5. 이제, monitor-scale 서비스에 대한 첫 빌드를 진행해 보일 것이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | Part 3 Step: 5 Now we're going to walk through an initial build of the monitor-scale service. docker build -t 127.0.0.1:30400/monitor-scale:`git rev-parse --short HEAD` -f applications/monitor-scale/Dockerfile applications/monitor-scale Press enter to run the above command for the step. Yes Sending build context to Docker daemon 50.69kB Step 1/9 : FROM node:boron boron: Pulling from library/node f189db1b88b3: Pull complete 3d06cf2f1b5e: Pull complete 687ebdda822c: Pull complete 99119ca3f34e: Pull complete e771d6006054: Pull complete b0cc28d0be2c: Pull complete 3d5d4cf85147: Pull complete 68fe23dc978d: Pull complete Digest: sha256:68d8ca89524a21200e6a3ec0948893f3fe2c9e807ecc2a74319fbee59a13d2c4 Status: Downloaded newer image for node:boron ---> f64a15ead359 Step 2/9 : RUN mkdir -p /usr/src/app ---> Running in 8ea1be367e6f Removing intermediate container 8ea1be367e6f ---> e853d34d41a0 Step 3/9 : WORKDIR /usr/src/app ---> Running in a6a6d61aed2f Removing intermediate container a6a6d61aed2f ---> b2146d1f15fa Step 4/9 : COPY package.json yarn.lock /usr/src/app/ ---> 8180ed089bb6 Step 5/9 : RUN yarn --pure-lockfile ---> Running in c44dbea0b1a6 yarn install v1.6.0 [1/4] Resolving packages... [2/4] Fetching packages... [3/4] Linking dependencies... [4/4] Building fresh packages... Done in 9.87s. Removing intermediate container c44dbea0b1a6 ---> 65a1029094b4 Step 6/9 : COPY . /usr/src/app ---> 43beda09b176 Step 7/9 : EXPOSE 3001 ---> Running in 6996ac8ac17d Removing intermediate container 6996ac8ac17d ---> a436a756e72b Step 8/9 : EXPOSE 8080 ---> Running in 5432e522dd74 Removing intermediate container 5432e522dd74 ---> e152ed6018e2 Step 9/9 : CMD ["node", "index.js"] ---> Running in d1e7faf46bca Removing intermediate container d1e7faf46bca ---> 4e14638d30e9 Successfully built 4e14638d30e9 Successfully tagged 127.0.0.1:30400/monitor-scale:fca8c7e | cs |
6. 클러스터 레지스트리에 방금 빌드한 monitor-scale Docker 이미지를 푸쉬할 수 있도록 프록시를 설정한다.
1 2 3 4 5 6 7 8 9 10 | Part 3 Step: 6 Set up a proxy so we can push the monitor-scale Docker image we just built to our cluster's registry. docker stop socat-registry; docker rm socat-registry; docker run -d -e "REGIP=`minikube ip`" --name socat-registry -p 30400:5000 chadmoon/socat:latest bash -c "socat TCP4-LISTEN:5000,fork,reuseaddr TCP4:`minikube ip`:30400" Press enter to run the above command for the step. Yes socat-registry socat-registry 25ba287b9549ab09562a3e6416e275b1c23d0855c5500e5c96f041ee236ccf32 | cs |
7. monitor-scale image를 레지스트리에 푸쉬한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | Part 3 Step: 7 Push the monitor-scale image to the registry. docker push 127.0.0.1:30400/monitor-scale:`git rev-parse --short HEAD` Press enter to run the above command for the step. Yes The push refers to repository [127.0.0.1:30400/monitor-scale] dd3da674d396: Pushed 980460ceef91: Pushed 22a27089262b: Pushed 3a8cc781d563: Pushed 6c9a1bc6b767: Pushed f059848e1802: Pushed 2793dc0607dd: Pushed 74800c25aa8c: Pushed ba504a540674: Pushed 81101ce649d5: Pushed daf45b2cad9a: Pushed 8c466bf4ca6f: Pushed fca8c7e: digest: sha256:6f1b7873b8550a5f864cc8304a7b08a7a84b40029980f1b066210cd443a587c6 size: 2844 | cs |
8. proxy의 동작이 끝나면, 계속 진행하기 위해 그것을 멈춘다.
1 2 3 4 5 6 7 | Part 3 Step: 8 The proxy’s work is done, so go ahead and stop it. docker stop socat-registry Press enter to run the above command for the step. Yes socat-registry | cs |
9. 레지스트리 UI를 열어 로컬 레지스트리에 monitor-scale 이미지가 존재하는지 검증한다.
1 2 3 4 5 6 7 8 | Part 3 Step: 9 Open the registry UI and verify that the monitor-scale image is in our local registry. minikube service registry-ui Press enter to run the above command for the step. Yes Opening kubernetes service default/registry-ui in default browser... | cs |
10. monitor-scale 디플로이먼트와 서비스를 생성한다.
1 2 3 4 5 6 7 8 9 10 | Part 3 Step: 10 Create the monitor-scale deployment and service. sed 's#127.0.0.1:30400/monitor-scale:latest#127.0.0.1:30400/monitor-scale:'`git rev-parse --short HEAD`'#' applications/monitor-scale/k8s/deployment.ya ml | kubectl apply -f - Press enter to run the above command for the step. Yes service/monitor-scale unchanged deployment.extensions/monitor-scale created ingress.extensions/monitor-scale created | cs |
11. monitor-scale 디플로이먼트가 마치기를 기다린다.
1 2 3 4 5 6 7 | Part 3 Step: 11 Wait for the monitor-scale deployment to finish. kubectl rollout status deployment/monitor-scale Press enter to run the above command for the step. Yes deployment "monitor-scale" successfully rolled out | cs |
12. monitor-scale 파드가 동작하는지 알아보기 위해 파드를 확인한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | Part 3 Step: 12 View pods to see the monitor-scale pod running. kubectl get pods Press enter to run the above command for the step. Yes NAME READY STATUS RESTARTS AGE etcd-job-fxb55 0/1 Completed 0 27m etcd-operator-69b559656f-zw4hq 1/1 Running 0 38m example-etcd-cluster-2stvm2j6d9 1/1 Running 0 36m example-etcd-cluster-kkf67n5tvj 1/1 Running 0 37m example-etcd-cluster-xvj82zxrhf 1/1 Running 0 37m hello-kenzan-55bcf94b6b-rdr7f 1/1 Running 0 4h jenkins-c5d9b4944-mb6pk 1/1 Running 0 7h monitor-scale-6bb95b75b7-lf72x 2/2 Running 0 3m nginx-768979984b-p6hl2 1/1 Running 1 1d registry-95c457bdb-hcvsd 2/2 Running 2 1d | cs |
13. monitor-scale 서비스를 보기 위해 서비스들을 확인한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | Part 3 Step: 13 View services to see the monitor-scale service. kubectl get services Press enter to run the above command for the step. Yes NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE example-etcd-cluster ClusterIP None <none> 2379/TCP,2380/TCP 39m example-etcd-cluster-client ClusterIP 10.96.204.181 <none> 2379/TCP 39m example-etcd-cluster-client-service NodePort 10.104.147.176 <none> 2379:32379/TCP 39m hello-kenzan NodePort 10.110.223.146 <none> 80:31740/TCP 1d jenkins NodePort 10.103.62.123 <none> 80:32282/TCP 7h kr8sswordz NodePort 10.101.77.76 <none> 80:30704/TCP 21m kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1d monitor-scale NodePort 10.99.214.19 <none> 3001:30696/TCP 21m nginx NodePort 10.107.167.30 <none> 80:32367/TCP 1d puzzle NodePort 10.111.211.216 <none> 3000:31261/TCP 21m registry NodePort 10.96.190.0 <none> 5000:30400/TCP 1d registry-ui NodePort 10.100.22.114 <none> 8080:30588/TCP 1d | cs |
14. monitor-scale 인그레스 룰을 보기 위해 인그레스 룰을 확인한다.
1 2 3 4 5 6 7 8 | Part 3 Step: 14 View ingress rules to see the monitor-scale ingress rule. kubectl get ingress Press enter to run the above command for the step. Yes NAME HOSTS ADDRESS PORTS AGE monitor-scale monitor-scale.192.168.99.100.xip.io 10.0.2.15 80 5m | cs |
15. monitor-scale 디플로이먼트를 보기 위해 디플로이먼트를 확인한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 | Part 3 Step: 15 View deployments to see the monitor-scale deployment. kubectl get deployments Press enter to run the above command for the step. Yes NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE etcd-operator 1 1 1 1 43m hello-kenzan 1 1 1 1 1d jenkins 1 1 1 1 7h monitor-scale 1 1 1 1 8m nginx 1 1 1 1 1d registry 1 1 1 1 1d | cs |
16. Docker 이미지를 생성하여 로컬 레지스트리에 저장해주는 puzzle 과 mongo 서비스를 부트스트랩 하기 위해 스크립트를 수행할 것이다. 두 서비스에 대해 수동으로 빠르게 살펴보았다. 동일한 빌드, 프록시, 푸쉬 그리고 배포 단계를 거치는 puzzle.sh 스크립트가 수행된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | Part 3 Step: 16 We will run a script to bootstrap the puzzle and mongo services, creating Docker images and storing them in the local registry. The puzzle.sh script ru ns through the same build, proxy, push, and deploy steps we just ran through manually for both services. scripts/puzzle.sh Press enter to run the above command for the step. Yes Sending build context to Docker daemon 130.6kB Step 1/10 : FROM node:boron ---> f64a15ead359 Step 2/10 : RUN mkdir -p /usr/src/app ---> Using cache ---> e853d34d41a0 Step 3/10 : WORKDIR /usr/src/app ---> Using cache ---> b2146d1f15fa Step 4/10 : COPY package.json yarn.lock /usr/src/app/ ---> 0351daec0c57 Step 5/10 : RUN yarn --pure-lockfile ---> Running in 53970257e305 yarn install v1.6.0 [1/4] Resolving packages... [2/4] Fetching packages... [3/4] Linking dependencies... [4/4] Building fresh packages... Done in 20.44s. Removing intermediate container 53970257e305 ---> 3b17d5a2d7ed Step 6/10 : COPY . /usr/src/app ---> 448cd158bcb1 Step 7/10 : COPY up.sh /up.sh ---> 7cfcadb3bc84 Step 8/10 : COPY down.sh /down.sh ---> 5ab4d0796e37 Step 9/10 : EXPOSE 3000 ---> Running in 3f00cade6190 Removing intermediate container 3f00cade6190 ---> 61fc829e3dfd Step 10/10 : CMD [ "node", "." ] ---> Running in cd8f6271611b Removing intermediate container cd8f6271611b ---> f7a8f85d9e0a Successfully built f7a8f85d9e0a Successfully tagged 127.0.0.1:30400/puzzle:fca8c7e socat-registry socat-registry b5c7e40061633e48f897d5e57495412bf5f0501e7304f527d527804a0539a7eb 5 second sleep to make sure the registry is ready The push refers to repository [127.0.0.1:30400/puzzle] f184f60e7c70: Pushed c81845d674dd: Pushed 823e03d1ce09: Pushed 7bcd60aa8629: Pushed 04994985fde9: Pushed 3a8cc781d563: Mounted from monitor-scale 6c9a1bc6b767: Mounted from monitor-scale f059848e1802: Mounted from monitor-scale 2793dc0607dd: Mounted from monitor-scale 74800c25aa8c: Mounted from monitor-scale ba504a540674: Mounted from monitor-scale 81101ce649d5: Mounted from monitor-scale daf45b2cad9a: Mounted from monitor-scale 8c466bf4ca6f: Mounted from monitor-scale fca8c7e: digest: sha256:20c196296f75252f8c426324d4619ad09a34a75c81ebb4b6aad9f86f316b799a size: 3258 socat-registry deployment.extensions/puzzle created service/puzzle unchanged deployment.extensions/mongo created service/mongo created ingress.extensions/puzzle created | cs |
17. puzzle 과 mongo 서비스가 배포 되었는지 확인한다.
1 2 3 4 5 6 7 | Part 3 Step: 17 Check to see if the puzzle and mongo services have been deployed. kubectl rollout status deployment/puzzle Press enter to run the above command for the step. Yes deployment "puzzle" successfully rolled out | cs |
18. Bootstrap the kr8sswordz 프론트엔드 웹 애플리케이션을 부트스트랩한다. 이 스크립트는 다른 서비스들이 따랐던 동일한 빌드, 프록시, 푸쉬 그리고 배포 단계를 따른다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | Part 3 Step: 18 Bootstrap the kr8sswordz frontend web application. This script follows the same build proxy, push, and deploy steps that the other services followed. scripts/kr8sswordz-pages.sh Press enter to run the above command for the step. Yes Sending build context to Docker daemon 1.871MB Step 1/8 : FROM node:7 7: Pulling from library/node ad74af05f5a2: Pull complete 2b032b8bbe8b: Pull complete a9a5b35f6ead: Pull complete 3245b5a1c52c: Pull complete afa075743392: Pull complete 9fb9f21641cd: Pull complete 3f40ad2666bc: Pull complete 49c0ed396b49: Pull complete Digest: sha256:af5c2c6ac8bc3fa372ac031ef60c45a285eeba7bce9ee9ed66dad3a01e29ab8d Status: Downloaded newer image for node:7 ---> d9aed20b68a4 Step 2/8 : RUN mkdir -p /usr/src/app ---> Running in 7ed095f5c478 Removing intermediate container 7ed095f5c478 ---> b49176530d4d Step 3/8 : WORKDIR /usr/src/app ---> Running in e1c1f5ebde2c Removing intermediate container e1c1f5ebde2c ---> 42777117b4c4 Step 4/8 : COPY package.json gulpfile.js yarn.lock /usr/src/app/ ---> 734670c25f13 Step 5/8 : RUN yarn --pure-lockfile ---> Running in 97b7f44a3ea4 yarn install v0.24.4 [1/4] Resolving packages... [2/4] Fetching packages... warning fsevents@1.1.1: The platform "linux" is incompatible with this module. info "fsevents@1.1.1" is an optional dependency and failed compatibility check. Excluding it from installation. [3/4] Linking dependencies... warning "react-tap-event-plugin@2.0.1" has incorrect peer dependency "react@^15.4.0-0". warning "react-tap-event-plugin@2.0.1" has incorrect peer dependency "react-dom@^15.4.0-0". [4/4] Building fresh packages... Done in 114.39s. Removing intermediate container 97b7f44a3ea4 ---> 2ef3da4707a4 Step 6/8 : COPY . /usr/src/app ---> c0a8153e596e Step 7/8 : EXPOSE 3002 ---> Running in 2a0f5406de23 Removing intermediate container 2a0f5406de23 ---> 686307e9077a Step 8/8 : CMD [ "npm", "run", "start" ] ---> Running in 73c9f05f8222 Removing intermediate container 73c9f05f8222 ---> 83fe8ff1e8ff Successfully built 83fe8ff1e8ff Successfully tagged 127.0.0.1:30400/kr8sswordz:fca8c7e socat-registry socat-registry 856517fc76b97959bd7af4fb47600004d4b5df5e2fcc937377a9dd8a6e426aae 5 second sleep to make sure the registry is ready The push refers to repository [127.0.0.1:30400/kr8sswordz] 368e94db4e17: Pushed 747a2d498a0c: Pushed 55fc9da8b6f1: Pushed 40749ae91044: Pushed ab90d83fa34a: Pushed 8ee318e54723: Pushed e6695624484e: Pushed da59b99bbd3b: Pushed 5616a6292c16: Pushed f3ed6cb59ab0: Pushed 654f45ecb7e3: Pushed 2c40c66f7667: Pushed fca8c7e: digest: sha256:74a88348bf789a1691c032ce1caa1b9f31c0bcb7fc038e1e5da32f10fc63959a size: 2845 socat-registry service/kr8sswordz unchanged deployment.extensions/kr8sswordz created ingress.extensions/kr8sswordz created | cs |
19. 프론트엔드가 배포 되었는지 확인해 본다.
1 2 3 4 5 6 7 8 | Part 3 Step: 19 Check to see if the frontend has been deployed. kubectl rollout status deployment/kr8sswordz Press enter to run the above command for the step. Yes Waiting for deployment "kr8sswordz" rollout to finish: 0 of 1 updated replicas are available... deployment "kr8sswordz" successfully rolled out | cs |
20. 모든 파드가 동작 중에 있는지 확인해 본다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | Part 3 Step: 20 Check out all the pods that are running. kubectl get pods Press enter to run the above command for the step. Yes NAME READY STATUS RESTARTS AGE etcd-job-fxb55 0/1 Completed 0 58m etcd-operator-69b559656f-zw4hq 1/1 Running 0 1h example-etcd-cluster-2stvm2j6d9 1/1 Running 0 1h example-etcd-cluster-kkf67n5tvj 1/1 Running 0 1h example-etcd-cluster-xvj82zxrhf 1/1 Running 0 1h hello-kenzan-55bcf94b6b-rdr7f 1/1 Running 0 4h jenkins-c5d9b4944-mb6pk 1/1 Running 0 7h kr8sswordz-85b9fd8fb4-tmm8n 1/1 Running 0 2m mongo-79fbd6bc6-q4pqn 1/1 Running 0 12m monitor-scale-6bb95b75b7-lf72x 2/2 Running 0 33m nginx-768979984b-p6hl2 1/1 Running 1 1d puzzle-686c87976d-wk7wd 1/1 Running 0 12m registry-95c457bdb-hcvsd 2/2 Running 2 1d | cs |
21. 기본 브라우져에서 웹 애플리케이션을 구동 시킨다.
1 2 3 4 5 6 7 8 | Part 3 Step: 21 Start the web application in your default browser. You may have to refresh your browser so that the puzzle appears properly. minikube service kr8sswordz Press enter to run the above command for the step. Yes Opening kubernetes service default/kr8sswordz in default browser... complete | cs |
Exercise 2: Giving the Kr8sswordz Puzzle a Spin
이제 구동되어 동작중이다. Kr8sswordz 퍼즐을 시험해 보자. 또한 몇개의 백엔드 서비스를 구동시켜 K8S 가 어떻게 자동으로 부하를 분배하는지 살펴보기 위해 강한 부하를 유발시킬 것이다.
1. 퍼블에 몇 개의 응답을 채워본다. 잘못된 응답은 글자가 채워질 때 자동으로 빨간색으로 보이는 것을 확인할 수 있을 것이다.
2. Submit.을 클릭하면, 퍼즐에 대한 현재 응답은 MongoDB 내 저장된다.
3. 몇 개의 퍼즐을 좀 더 채운 다음, Reload 를 한번 클릭한다. 이는 MongoDB에 최종적으로 보내진 퍼즐 응답을 되돌려 주는 GET을 수행할 것이다.
Reload를 클릭했을 때 우측에 녹새의 화살표를 인지했는가? 그 화살표는 애플리케이션이 MongoDB로부터 데이터를 가져오는 것을 나타내준다. GET 또한 30초 TTL (time to live)값을 가지며 etcd에 같은 응답을 캐시한다. 즉시 Reload 를 다시 누르면, TTL값이 만료될 때가지는 etcd로부터 응답을 불러올 것이다. 그 시점에 응답은 MongoDB로부터 다시 불러들여지고 다시 캐시된다. 한번 시험해 보고 화살표를 지켜본다.
4. 위쪽 슬라이더을 우측 끝까지 드래그한 다음, Scale 을 클릭하여 Kr8sswordz puzzle 서비스의 인스턴스 갯수를 16까지 스케일 한다. puzzle 서비스의 수가 증가한 것을 주목한다.
터미널에서, 새로운 replicas를 보기 위해 "kubectl get pods"를 수행한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | root@zerobig-vm-u:/home/study/k8s/kubernetes-ci-cd# kubectl get pods NAME READY STATUS RESTARTS AGE etcd-job-fxb55 0/1 Completed 0 5h etcd-operator-69b559656f-zw4hq 1/1 Running 0 5h example-etcd-cluster-2stvm2j6d9 1/1 Running 0 5h example-etcd-cluster-kkf67n5tvj 1/1 Running 0 5h example-etcd-cluster-xvj82zxrhf 1/1 Running 0 5h hello-kenzan-55bcf94b6b-rdr7f 1/1 Running 0 9h jenkins-c5d9b4944-mb6pk 1/1 Running 0 12h kr8sswordz-85b9fd8fb4-tmm8n 1/1 Running 0 4h mongo-79fbd6bc6-q4pqn 1/1 Running 0 5h monitor-scale-6bb95b75b7-lf72x 2/2 Running 0 5h nginx-768979984b-p6hl2 1/1 Running 1 1d puzzle-686c87976d-4j4pt 1/1 Running 0 3m puzzle-686c87976d-4tz6g 1/1 Running 0 3m puzzle-686c87976d-8tkjd 1/1 Running 0 3m puzzle-686c87976d-dk7zz 1/1 Running 1 3m puzzle-686c87976d-dwb2x 1/1 Running 0 3m puzzle-686c87976d-fb78s 1/1 Running 0 3m puzzle-686c87976d-fnxz8 1/1 Running 0 3m puzzle-686c87976d-g88d7 1/1 Running 0 3m puzzle-686c87976d-gjgbk 1/1 Running 0 3m puzzle-686c87976d-k8rd6 1/1 Running 0 3m puzzle-686c87976d-k92tf 1/1 Running 0 3m puzzle-686c87976d-rr7x8 1/1 Running 0 3m puzzle-686c87976d-td4gl 1/1 Running 0 3m puzzle-686c87976d-tz7vt 1/1 Running 0 3m puzzle-686c87976d-vqk79 1/1 Running 0 3m puzzle-686c87976d-wk7wd 1/1 Running 0 5h registry-95c457bdb-hcvsd 2/2 Running 2 1d | cs |
5. 이제 부하 테스트를 시행해본다. 아래 쪽 슬라이더를 우측으로 250 요청까지 드래그하고 Load Test를 클릭한다. 방대한 요청들을 처리하기 위해 얼마나 매우 빠르게 여러 개의 퍼즐 서비스를 (녹색 빛 플래쉬) hit 하는지 주목한다. K8S는 모든 이용가능한 파드 인스턴스들을 대상으로 부하를 자동 분배하고 있다. 고맙다. K8S!
6. 중간 슬라이더를 다시 1로 내리도록 드래그하고 Scale 을 클릭한다. 터미널에서 퍼즐 서비스가 종료되는 것을 보기 위해 "kubectl get pods"를 수행한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | root@zerobig-vm-u:/home/study/k8s/kubernetes-ci-cd# kubectl get pods NAME READY STATUS RESTARTS AGE etcd-job-fxb55 0/1 Completed 0 6h etcd-operator-69b559656f-zw4hq 1/1 Running 0 6h example-etcd-cluster-2stvm2j6d9 1/1 Running 0 6h example-etcd-cluster-kkf67n5tvj 1/1 Running 0 6h example-etcd-cluster-xvj82zxrhf 1/1 Running 0 6h hello-kenzan-55bcf94b6b-rdr7f 1/1 Running 0 9h jenkins-c5d9b4944-mb6pk 1/1 Running 0 12h kr8sswordz-85b9fd8fb4-tmm8n 1/1 Running 0 5h mongo-79fbd6bc6-q4pqn 1/1 Running 0 5h monitor-scale-6bb95b75b7-lf72x 2/2 Running 0 5h nginx-768979984b-p6hl2 1/1 Running 1 1d puzzle-686c87976d-4j4pt 1/1 Terminating 0 15m puzzle-686c87976d-4tz6g 1/1 Terminating 0 15m puzzle-686c87976d-8tkjd 1/1 Terminating 0 15m puzzle-686c87976d-dk7zz 1/1 Terminating 1 15m puzzle-686c87976d-dwb2x 1/1 Terminating 0 15m puzzle-686c87976d-fb78s 1/1 Terminating 0 15m puzzle-686c87976d-fnxz8 1/1 Terminating 0 15m puzzle-686c87976d-g88d7 1/1 Terminating 0 15m puzzle-686c87976d-gjgbk 1/1 Terminating 0 15m puzzle-686c87976d-k8rd6 1/1 Terminating 0 15m puzzle-686c87976d-k92tf 1/1 Terminating 0 15m puzzle-686c87976d-rr7x8 1/1 Terminating 0 15m puzzle-686c87976d-td4gl 1/1 Terminating 0 15m puzzle-686c87976d-tz7vt 1/1 Terminating 0 15m puzzle-686c87976d-vqk79 1/1 Terminating 0 15m puzzle-686c87976d-wk7wd 1/1 Running 0 5h registry-95c457bdb-hcvsd 2/2 Running 2 1d | cs |
7. 이제 K8S가 자동으로 다운된 파드를 치유해주는 능력을 이용하여 파드를 재구동해주는 것을 보기 위해 퍼즐 파드가 삭제되도록 한다.
a. 모든 파드를 보기 위해 터미널에서 "kubectl get pods"를 입력한다. 퍼즐 파드 이름을 복사한다. (위 그림에서 보여지는 것과 유사하다.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | root@zerobig-vm-u:/home/study/k8s/kubernetes-ci-cd# kubectl get pods NAME READY STATUS RESTARTS AGE etcd-job-fxb55 0/1 Completed 0 6h etcd-operator-69b559656f-zw4hq 1/1 Running 0 6h example-etcd-cluster-2stvm2j6d9 1/1 Running 0 6h example-etcd-cluster-kkf67n5tvj 1/1 Running 0 6h example-etcd-cluster-xvj82zxrhf 1/1 Running 0 6h hello-kenzan-55bcf94b6b-rdr7f 1/1 Running 0 9h jenkins-c5d9b4944-mb6pk 1/1 Running 0 12h kr8sswordz-85b9fd8fb4-tmm8n 1/1 Running 0 5h mongo-79fbd6bc6-q4pqn 1/1 Running 0 5h monitor-scale-6bb95b75b7-lf72x 2/2 Running 0 5h nginx-768979984b-p6hl2 1/1 Running 1 1d puzzle-686c87976d-wk7wd 1/1 Running 0 5h registry-95c457bdb-hcvsd 2/2 Running 2 1d | cs |
b. 남겨진 퍼즐 파드를 삭제하기 위해 다음 명령을 입력한다.
1 2 | root@zerobig-vm-u:/home/study/k8s/kubernetes-ci-cd# kubectl delete pod puzzle-686c87976d-wk7wd pod "puzzle-686c87976d-wk7wd" deleted | cs |
c. 이전 파드를 종료하고 새로운 파드를 구동하는 것을 보기 위해 "kubectl get pods"를 입력한다. Kr8sswordz Puzzle 앱에 새로운 퍼즐 파드가 나타남을 볼 수 있을 것이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | root@zerobig-vm-u:/home/study/k8s/kubernetes-ci-cd# kubectl get pods NAME READY STATUS RESTARTS AGE etcd-job-fxb55 0/1 Completed 0 6h etcd-operator-69b559656f-zw4hq 1/1 Running 0 6h example-etcd-cluster-2stvm2j6d9 1/1 Running 0 6h example-etcd-cluster-kkf67n5tvj 1/1 Running 0 6h example-etcd-cluster-xvj82zxrhf 1/1 Running 0 6h hello-kenzan-55bcf94b6b-rdr7f 1/1 Running 0 9h jenkins-c5d9b4944-mb6pk 1/1 Running 0 12h kr8sswordz-85b9fd8fb4-tmm8n 1/1 Running 0 5h mongo-79fbd6bc6-q4pqn 1/1 Running 0 5h monitor-scale-6bb95b75b7-lf72x 2/2 Running 0 5h nginx-768979984b-p6hl2 1/1 Running 1 1d puzzle-686c87976d-dl7sj 1/1 Running 0 35s registry-95c457bdb-hcvsd 2/2 Running 2 1d | cs |
What’s Happening on the Backend
K8S의 신비함을 조금 알게되었다. 부하에 대해 어떻게 파드가 스케일 되어지는 지를 보고, 요청에 대한 부하 분배를 어떻게 자동으로 처리하는지도 보았다, 게다가 파드가 다운될 경우 어떻게 자동으로 치유하는지도 보았다. 이 기능을 명백하게 확인하기 위해 Kr8sswordz Puzzle 앱에 무슨 일이 일어나고 있는지 보다 가까이 들여다 보도록 하자.
Submit 버튼을 누르면, 하나의 PUT 요청이 kr8sswordz UI로부터 puzzle 서비스에 대한 파드 인스턴스로 보내진다. 퍼즐 서비스는 MongoDB 내 응답을 저장하기 위해 루프백(LoopBack) 데이터 서비스를 이용한다. Reload 버튼이 눌러지면, 응답은 MongoDB에서 GET 요청과 함께 되찾아 진다. 그리고 etcd 클라이언트는 30초 TTL 값을 갖고 응답을 캐시하는데 이용되어 진다.
monitor-scale 파드는 스케일과 앱에 대한 부하 테스트 기능을 통제한다. Scale 버튼이 눌러지면, monitor-scale 파드는 K8S상의 puzzle 파드의 수를 스케일 업, 다운 하기 위해 Kubectl API를 이용한다.
Load Test 버튼이 눌러지면, monitor-scale pod는 프론트엔드로부터 전송된 카운트를 근거로 하여 서비스 파드에 다수의 GET 응답을 전송하여 loadtest 를 통제한다.
puzzle 파드 인스턴스가 증가하거나 감소할 때, 퍼즐 파드는 monitor-scale 파드에 이에 관한 정보를 전송한다. 증가와 감소 상태는 퍼즐 파드 k8s 디플로이먼트 내 lifecycle 인용부호로 (lifecycle hook) 구성되는데, monitor-scale에 대한 동일 엔드포인트로 curl 한다.( hooks를 확인해 보려면 kubernetes-ci-cd/applications/puzzle/k8s/deployment.yml 내용을 본다.) Monitor-scale 은 set, delete 그리고 get 파드 요청으로 etcd 내 이용가능한 퍼즐 파드의 리스트를 지속시켜 준다.
123456789101112131415161718192021222324252627282930root@zerobig-vm-u:/home/study/k8s/kubernetes-ci-cd/applications/puzzle/k8s# cat deployment.yamlapiVersion: extensions/v1beta1kind: Deploymentmetadata:name: puzzlelabels:app: puzzlespec:strategy:type: Recreatetemplate:metadata:labels:app: puzzletier: puzzlespec:containers:- image: 127.0.0.1:30400/puzzle:latestname: puzzleimagePullPolicy: Alwayslifecycle:postStart:exec:command: ["/up.sh"]preStop:exec:command: ["/down.sh"]ports:- containerPort: 3000name: puzzlecs
현재 Minikube에서 작업을 수행해왔다면, 다음 명령을 입력하여 클러스터를 계속 동작시킬 수도 있고 중지시킬 수도 있다.
1 2 3 | root@zerobig-vm-u:/home/study/k8s/kubernetes-ci-cd# minikube stop Stopping local Kubernetes cluster... Machine stopped. | cs |
Up Next
이제 Kr8sswordz Puzzle 앱이 동작하게 되었으니, 다음 단계는 앱에 대한 CI/CD 체계를 수립하는 것이다. Hello-Kenzan 앱에 대해 행했던 내용과 유사하다. Part 4는 하나의 버튼 터치로 Kr8sswordz Puzzle 앱이 빌드될 수 있도록 이 앱을 위한 Jenkins 파이프라인 생성에 관해 다룰 것이다. 또한 애플리케이션 품질을 높이기 위해 약간의 코드 수정과 Submit 버튼을 누르면, UI 내 퍼즐 서비스 인스턴스 상에 녹색 hit가 보일 수 있도록 해볼 것이다. 채널 고정!