Notice
Recent Posts
Recent Comments
Today
Total
04-16 07:26
Archives
관리 메뉴

Jeongchul Kim

Google Cloud with Kubernetes 본문

Google Cloud Platform

Google Cloud with Kubernetes

김 정출 2018. 3. 9. 16:53


Google Cloud with Kubernetes


Overview

여기서의 목표는 우리가 개발한 코드를 Kubernetes Engine 에서 실행되는 Kubernetes에서 실행되는 복제된(replicated) application으로 만드는 것입니다. 여기서는 간단한 node-js 앱을 개발할 것입니다.


여기서 사용되는 다양한 Google Cloud Platform의 다양한 컴포넌트를 볼 수 있습니다.



Kubernetes는 오픈 소스 프로젝트로 (kubernetes.io) 고 가용성을 가진 다중의 노드 클러스터에 이르기까지 다양한 환경에서 실행할 수 있습니다. 공개의 Cloud나 on-premise 배포서부터, VM(Virtual Machine)에서 실제 machine(bare metal)까지 실행 가능합니다.


여기서는 Kubernetes Engine(Compute Engine에서 실행되는 Kubernetes의 Google 호스팅 버전)과 같은 관리 환경을 사용하여 기본 infrastructure를 설정하는 대신, Kubernetes에 많은 경험을 할 수 있습니다.


WHAT YOU’LL DO

  • node-js 서버를 생성합니다.

  • Docker container image를 생성합니다.

  • container 클러스터(cluster)를 생성합니다.

  • Kubernetes pod를 생성합니다.

  • service를 scale-up 해봅니다.


Google Cloud Platform

https://cloud.google.com/?hl=ko

로그인을 진행하고 콘솔로 이동합니다.


콘솔로 이동하면 다음의 사이트로 보입니다.


ACTIVATE GOOGLE CLOUD SHELL

GCP(Google Cloud Platform)에서 오른쪽 상단 툴바의 Cloud Shell 아이콘을 클릭합니다.




"Start Cloud Shell" 버튼을 클릭합니다.



환경을 제공하고 연결하는 데 몇 분이 걸립니다.



Create your Node.js application

Cloud Shell을 사용하여 Kubernetes Engine에 배포할 application을 작성합니다. 다음은 간단한 Node.js 서버를 만드는 코드입니다.

$ vi server.js


다음의 코드를 채워 놓습니다.

var http = require('http');
var handleRequest = function(request, response) {
 response.writeHead(200);
 response.end("Hello World!");
}
var server = http.createServer(handleRequest);
server.listen(8080);



server.js를 저장하고 나옵니다.


Cloud Shell에는 node를 실행할 수 있도록 설치되어 있습니다. node를 실행해봅시다.

$ node server.js


Cloud Shell의 기본적으로 제공하는 ‘웹 미리보기 기능'을 사용하여 새 브라우저 탭을 열고 방금 시작된 port 8080에서 요청을 하도록 프록시(proxy)합니다.


파란색 동그라미의 ‘웹 미리 보기’를 클릭하고 포트에서 미리 보기 8080을 클릭합니다.



새로운 tab에서 다음과 같은 결과가 나옵니다.


실행중인 node server를 멈추기 위해서는 Ctrl+C를 입력합니다.



이제 중요한 것은 Docker Container에 application을 패키지(package)하는 것입니다.


Create a Docker container image

다음으로는, 빌드(build)할 image를 설명하는 Dockerfile을 생성합니다. Docker Container image는 기존의 image에서 확장될 수 있습니다. 여기의 image는 기존의 node image에서 확장됩니다.


$ vi Dockerfile


Edit를 시작합니다. 내용을 추가합니다.

FROM node:6.9.2
EXPOSE 8080
COPY server.js .
CMD node server.js


여기서의 code에서는

- Docker Hub에 있는 node image에서 시작합니다.

- port 8080을 Expose 합니다.

- server.js 파일을 image로 복사합니다.

- node server.js 명령어를 수행합니다.


다음의 image를 빌드(build)합니다. PROJECT_ID를 본인의 project ID로 수정합니다.


$ docker build -t gcr.io/PROJECT_ID/hello-node:v1 .


모든 것을 다운로드하고, 압축하는데 다소의 시간이 걸리며, image가 빌드됨에 따라 진행 막대가 표시됩니다. 완료되면 새롭게 Docker Container 생성됩니다. 이 Container image를 daemon으로 실행되는 port 8080에서 테스트해봅시다.

$ docker run -d -p 8080:8080 gcr.io/PROJECT_ID/hello-node:v1

결과는 다음과 같습니다.

d26f28906671f12c87cf7f35c3c09243078b44fe31aa1b0500984bebca6a9572


Cloud Shell에서 제공하는 ‘웹 미리보기’ 기능으로 결과를 확인해봅시다.



또는 curl이나 wget 명령어를 사용해봅시다.

$ curl http://localhost:8080

결과는 다음과 같습니다.

Hello World!


Docker run 명령에 대한 설명서는 다음의 사이트에서 찾을 수 있습니다.

https://docs.docker.com/engine/reference/run/


Now let's stop the running container.

이제 실행중인 container를 정지합니다.


Docker container ID를 찾아봅시다.


$ docker ps

결과는 다음과 같습니다.



container ID를 이용해 정지합니다.

$ docker stop heurstic_nobel

결과는 다음과 같습니다.

heuristic_nobel


image가 의도하는 대로 작동되므로, Docker image의 비공개 저장소인 GCR(Google Container Registry) push 해봅시다.

$ gcloud docker -- push gcr.io/PROJECT_ID/hello-node:v1

초기 push를 완료하는데 시간이 소요됩니다. build되는 동안 프로그레스 바(progress bar)로 확인할 수 있습니다.


결과는 다음과 같습니다.

The push refers to a repository [gcr.io/qwiklabs-gcp-6h281a111f098/hello-node]
ba6ca48af64e: Pushed
381c97ba7dc3: Pushed
604c78617f34: Pushed
fa18e5ffd316: Pushed
0a5e2b2ddeaa: Pushed
53c779688d06: Pushed
60a0858edcd5: Pushed
b6ca02dfe5e6: Pushed
v1: digest: sha256:8a9349a355c8e06a48a1e8906652b9259bba6d594097f115060acca8e3e941a2 size: 2002


container image는 Tools > Container Registry에서 리스트로 확인할 수 있습니다. 이제 Kubernetes가 접근하고 orchestrate 할 수 있는 Docker image를 사용할 수 있습니다.



Create your cluster

이제 Container Engine 클러스터(cluster)를 만들 준비가 되었습니다. cluster는 Google에서 호스팅하는 Kubernetes Master API 서버와 일련의 Worker node로 구성됩니다. Worker node는 Computer Engine의 VM(Virtual Machine)입니다.


Console의 Kubernetes cluster 섹션으로 이동하여 시스템이 초기화될 때까지 기다립니다.



gcloud에 PROJECT_ID의 설정을 확실하기 위해 Console에 있는 project id로 진행합니다.


$ gcloud config set project PROJECT_ID

클러스터를 구성하기 전에 앞서 GCP의 Instance에 대해서 알아봅시다.

https://cloud.google.com/kubernetes-engine/


인스턴스 가격에 따르면 f1-micro VM은 매달마다 무료로 사용 가능합니다.


다른 인스턴스 가격정보는 다음과 같습니다.

https://cloud.google.com/compute/pricing?hl=ko


클러스터를 구성하기 위해서는 VM의 개수가 3대 이상이 필요합니다.


Kubernetes Engine 사이트에서도 클러스터를 만들 수 있지만 명령어로 직접 만들어 봅시다.



3 개의 f1-micro 노드로 구성된 cluster를 다음의 명령어로 만듭니다. 완료하는데 몇 분 정도 소요됩니다.

$ gcloud container clusters create hello-world  \
              --num-nodes 3 \
              --machine-type f1-micro \
              --zone us-central1-f

결과는 다음과 같습니다.

Creating cluster hello-world...done.
Created [https://container.googleapis.com/v1/projects/PROJECT_ID/zones/us-central1-f/clusters/hello-world].
kubeconfig entry generated for hello-world.
NAME         ZONE  MASTER_VERSION MASTER_IP       MACHINE_TYPE STATUS
hello-world  us-central1-f  1.5.7           146.148.46.124  n1-standard-1  RUNNING


container registry에서 사용하는 저장소 bucket과 동일한 영역에 cluster를 생성하는 것이 좋습니다.


Kubernetes Engine에 의해 구동되는 Kubernetes 클러스터는 완벽하게 작동합니다.




자 이제 우리의 컨테이너화된 application을 Kubernetes 클러스터에 배포할 차례입니다. 이제부터는 kubectl(Cloud Shell 환경에 설정되어 있음)을 사용합니다.

Create your pod

Kubernetes 포드(pod)는 관리와 네트워킹 목적으로 함께 묶인 container 그룹입니다. 단일 또는 다중의 container를 포함할 수 있습니다. 여기서는 private container registry에 있는 Node.js image로 빌드된 하나의 container를 사용합니다. 여기서는 port 8080에서 내용을 제공합니다.


kubectl run의 명령어로 pod를 생성해봅시다.


$ kubectl run hello-node \
   --image=gcr.io/PROJECT_ID/hello-node:v1 \
   --port=8080

결과는 다음과 같습니다.

deployment "hello-node" created


보다시피, 우리는 deployment 객체를 생성했습니다. pod를 만들고, 크기를 조정하는데 deployment가 권장됩니다. 새로운 deployment는 hello-node:v1 image를 실행하는 단일 pod 복제본을 관리합니다.


방금 작성한 deployment를 확인하려면 다음의 명령어를 실행합니다.

$ kubectl get deployments

결과는 다음과 같습니다.

NAME         DESIRED CURRENT   UP-TO-DATE AVAILABLE   AGE
hello-node   1         1         1            1           2m


deployment로 만든 pod를 보려면 다음의 명령어를 실행합니다.

$ kubectl get pods

결과는 다음과 같습니다.

NAME                         READY STATUS RESTARTS  AGE
hello-node-714049816-ztzrb   1/1       Running   0          6m


다음은 kubectl로 클러스터 상태를 확인할 수 있습니다.


$ kubectl cluster-info


$ kubectl config view


$ kubectl get events


$ kubectl logs <pod-name>


Allow external traffic

기본적으로 pod는 클러스터(cluster)내의 내부 IP로만 액세스할 수 있습니다. hello-node container를 가상의 네트워크 외부에서 액세스를 가능하게 하려면, pod를 kubernetes service로 expose를 해야 합니다.


Cloud Shell에서 --type 옵션을 이용해 LoadBalancer와 kubectl expose 결합된 명령어를 통해 pod를 공개 인터넷에 expose할 수 있습니다. 이 옵션은 외부에서 액세스할 수 있는 IP를 생성하는데 필요합니다.


Load Balancing

https://cloud.google.com/compute/docs/load-balancing/network/


Network Load Balancing을 사용하면 주소(address), 포트(port) 및 프로토콜(protocol) 타입과 같은 들어는 IP 프로토콜 데이터를 기반으로 시스템 부하를 분산시킬 수 있습니다.


Network Load Balancing은 forwarding rules를 통해 target pool을 가리킵니다.  이 rules는 load balancing에서 사용할 수 있는 instances를 나열하고, 이러한 instances에서 수행하는 상태 검사 유형을 정의합니다.


$ kubectl expose deployment hello-node --type="LoadBalancer"


이 명령에 사용된 flag는 Computer Engine load balancer를 사용하도록 지정합니다. pod로 직접 expose 않고, deployment를 expose 합니다. 이로 인해 서비스의 결과가 deployment에 의해 모든 pod에 트래픽(traffic)을 load balancing 하게 됩니다. 이 경우에는 1개의 pod이지만, 나중에는 더 많은 복제본(replicas)을 추가합니다.


Kubernetes master는 load balancer 그리고 Compute engine forwarding rules 그리고 target pool을 만들어 Google cloud Platform 외부에서 서비스에 완벽하게 액세스 할 수 있습니다.


공개적으로 접근 가능한 서비스(public access IP)에 IP 주소를 찾으려면, kubectl get services 명령어를 입력합니다.


$ kubectl get services

결과는 다음과 같습니다.


NAME         CLUSTER-IP  EXTERNAL-IP  PORT(S) AGE
hello-node   10.3.250.149   104.154.90.147   8080/TCP   1m
kubernetes   10.3.240.1     <none>           443/TCP    5m


목록에서 port 8080을 2개의 IP 주소가 있습니다. 하나(CLUSTER-IP)는 내부 가상 사설망의 IP이며, 다른 하나(EXTERNAL-IP)는 외부 load balancing IP입니다.


EXTERNAL-IP는 사용 가능하고 보이기 까지는 몇 분이 걸릴 수 있습니다.


이제 브라우저에서 이 주소로 이동하여 서비스에 연결할 수 있습니다.


http://<EXTERNAL_IP>:8080


이 시점에서 우리는 container 그리고 Kubernetes로 이동하여 몇 가지 특징을 얻었습니다. load balancing를 실행할 호스트를 지정할 필요가 없으며, service 모니터링 및 재시작의 이점도 있습니다. 새로운


Scale up your service

Kubernetes가 제공하는 강력한 특징 중 하나는 application을 확장하는 것이 얼마나 쉬운 지입니다. application에 갑자기 많은 용량이 필요하다고 가정을 해봅시다. 그 경우에는 pod에 대한 복제본(replicas)의 새로운 수를 관리하도록 replicaiton controller에 지시할 수 있습니다.


$ kubectl get deployment


$ kubectl scale deployment hello-node --replicas=5


업데이트된 deployment를 살펴봅시다.

$ kubectl get deployment


모든 pod의 리스트를 봅시다.

$ kubectl get pods


여기서는 선언적(declarative) 접근법을 사용하고 있습니다. 새로운 instance를 시작하거나 중지하는 대신 항상 실행해야 하는 instance 수를 선언해야 합니다. Kubernetes reconciliation 루프는 사용자가 요청한 것과 일치하는지 확인하고 필요한 경우 액션을 취합니다.


다음은 Kubernetes 클러스터의 상태를 요약한 다이어그램입니다.




Roll out an upgrade to your service

어떤 시점에서 개발 환경에서 배포한 application의 bug를 수정하거나 기능 추가가 필요합니다. Kubernetes에는 사용자에게 영향을 주지 않고 새로운 버전으로 배포할 수 있도록 도와줍니다.


먼저 application을 수정해봅시다. server.js를 편집합니다.


$ vi server.js

response의 message를 수정합니다.

response.end("Hello Kubernetes World!");


이제 우리는 업그레이드 버전(v2)로 registry에 새로운 container image를 빌드하고 게시(publish)할 수 있습니다.


$ docker build -t gcr.io/kmu-bigdata/hello-node:v2 .


$ gcloud docker -- push gcr.io/kmu-bigdata/hello-node:v2


caching을 최대한 활용하면 업데이트된 image를 만들고 push하는 것이 더 빠를 것입니다.


Kubernetes는 replication controller를 새로운 버전의 application으로 원활하게 업데이트할 것입니다. 실행중인 container의 image의 label을 변경하려면 기존 hello-node 배포를 편집하고 image를 gcr.io/PROJECT_ID/hello-node:v1에서 gcr.io/PROJECT_ID/hello-node:v2로 변경해야 합니다.


변경을 위해서 kubectl edit 명령을 사용해서 전체 deployment의 yaml 구성(configuration)을 텍스트 편집기로 열립니다. 전체 yaml 구성을 이해할 필요는 없습니다. pod를 새 image로 업데이트 하도록 spec.template.spec.containers.image 필드를 업데이트하면 됩니다.


$ kubectl edit deployment hello-node

# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
 annotations:
   deployment.kubernetes.io/revision: "1"
 creationTimestamp: 2018-03-06T07:05:28Z
 generation: 3
 labels:
   run: hello-node
 name: hello-node
 namespace: default
 resourceVersion: "151017"
 selfLink: /apis/extensions/v1beta1/namespaces/default/deployments/hello-node
 uid: d05c8fad-210c-11e8-9a78-42010af00005
spec:
 replicas: 5
 selector:
   matchLabels:
     run: hello-node
 strategy:
   rollingUpdate:
     maxSurge: 1
     maxUnavailable: 1
   type: RollingUpdate
 template:
   metadata:
     creationTimestamp: null
     labels:
       run: hello-node
   spec:
     containers:
     - image: gcr.io/PROJECT_ID/hello-node:v2 ## Update this line ##
       imagePullPolicy: IfNotPresent
       name: hello-node
       ports:
       - containerPort: 8080
         protocol: TCP
       resources: {}
       terminationMessagePath: /dev/termination-log
     dnsPolicy: ClusterFirst
     restartPolicy: Always
     securityContext: {}
     terminationGracePeriodSeconds: 30

image를 gcr.io/kmu-bigdata/hello-node:v2 로 변경합니다.


변경을 마치고, file을 저장합니다.



deployment를 새 image로 업데이트하려면 다음의 명령어를 실행합니다. 기존의 pod는 삭제되고, 새로운 image로 생성된 새로운 pod가 생성됩니다.


$ kubectl get deployments


위의 일이 발생되는 동안 사용자가 사용하는 서비스는 중단을 하지 않아야 합니다. 조금 후에 application의 새로운 버전에 액세스하기 시작합니다. rolling updates에 대해서 다음의 사이트에서 확인할 수 있습니다.

https://cloud.google.com/container-engine/docs/rolling-updates


결과를 확인해봅시다.



Kubernetes graphical dashboard

그래픽 웹 사용자 인터페이스(dashboard)는 최근 버전의  Kubernetes에서 소개되었습니다. dashboard를 사용하면 신속하게 시작할 수 있으며, CLI에 있는 일부 기능을 시스템에서 보다 쉽게 접근할 수 있습니다.


Kubernetes 클러스터 dashboard에 대한 액세스를 구성하려면, Cloud Shell 에서 다음의 명령어를 실행합니다.



$ gcloud container clusters get-credentials hello-world --zone us-central1-f --project <PROJECT_ID>
$ gcloud container clusters get-credentials hello-world --zone us-central1-f --project kmu-bigdata


$ kubectl proxy --port 8081


Cloud Shell 웹 미리 보기에서 포트 변경을 하여 8081로 변경합니다.



포트 번호를 8081로 입력합니다.


그러면 API의 endpoint로 연결됩니다.


dashboard로 이동하려면 ?authuser=0을 제거하고 “/ui”와 함께 URL을 추가합니다.

https://8081-dot-3604478-dot-devshell.appspot.com/ui


~/.kube/config 를 열어 access-token: 키값을 복사합니다.

다음의 사이트가 열립니다.

$ cat ~/.kube/config


Token을 선택하여 토큰키값을 붙여넣고 SIGN IN 버튼을 클릭합니다.


로그인이 완료되었습니다



Kubernetes 그래픽 dashboard를 사용하여 container application을 배포하고, 클러스터 모니터링 및 관리에 사용할 수 있습니다.








Comments