kubernetes 정리

kubernetes는 배포, 확장 및 운영을 자동화하는 컨테이너 관리툴이다.


kubernetes가 왜 필요한지에 대해서 알아보자.

kubernetes없이 Docker를 이용하여 애플리케이션을 서버에 배포하고 운영 하려면 shell script를 작성하거나 별도의 툴을 사용해야 한다.

shell script를 이용한 배포를 예로 들면 docker image registry에서 애플리케이션이 포함되어 있는 custom docker image를 다운로드 받고 이를 각 서버에 배포하고 실행하는 수준이 될 것이다.

이와 같은 배포는 최초 환경 구성 시 빡시게 하면 된다.

단, 서비스 운영을 하면서 과도한 사용자 요청이 있을 경우 성능 저하가 발생하게 되는데 그때서야 부랴부랴 서버를 확장하고 애플리케이션을 각 서버에 적절히 배포해야 하는 수고로움이 또 발생하게 된다.


kubernetes는 이와 같은 반복적인 애플리케이션의 배포 및 확장 그리고 운영을 자동화 하는 매우 좋은 툴이다.

구글에서 만들었고, 2014년에 오픈 소스로 공개하였다.


kubernetes에는 다음과 같은 기본 용어들이 있다.

  • cluster
  • master
  • node
  • deployment 
  • pod
  • service


[cluster]

kubernetes 클러스터를 실행하면 컨테이너화된 애플리케이션을 배치할 수 있다.

master, node를 아우루는 개념이라고 생각하면 된다.

cluster에는 최소한 3개의 node를 가지고 있어야 한다. 

node가 3개 이하로 운영 되어도 kubernetes 시스템 자체의 문제는 발생하지 않지만 

컨테이너의 롤링 업데이트 시 애플리케이션의 down time이 발생하기 때문에 최소 3개의 node를 권장하는 것으로 파악된다.



[master]

클러스터 관리를 담당한다.

클러스터 노드에 컨테이너 구동을 위한 스케줄링 작업을 진행 (스케줄링이라 함은 적절한 node(물리머신 or VM)에 배포를 의미)

master가 설치되어 있는 서버에서 kubernetes관련 프로세스를 확인해 보면 다음과 같이 5개의 프로세스가 동작하는 것을 확인할 수 있다.

마스터 서버의 자동 스케줄링은 각 노드에서 사용 가능한 리소스를 고려한다.


etcd

/opt/bin/etcd -name infra --listen-client-urls=http://127.0.0.1:4001,http://192.168.50.11:4001 -advertise-client-url

분산 코디네이터 overlay network를 지원한다.


etcdctl

etcd 분산 코디네이터를 실행하는 command 명령어


kube-apiserver

kube-controller-manager

kube-scheduler



[node]

node는 VM 또는 물리적 장비들이다.

각 노드에는 kubelet이 존재하며 kubernetes master와 통신(using kubernetes API)하며 노드를 관리한다. (kubelet을 agent라고도 부른다.)

컨테이너의 애플리케이션을 kubernetes에 배포할 때 마스터 서버에게 애플리케이션 컨테이너를 시작한다고 알린다.

각 Node는 Master의 관리를 받는다.



[deployment]

kubernetes Deployment는 애플리케이션 인스턴스들의 생성과 업데이트를 책임진다.

Deployment를 생성하면 쿠버네티스 마스터는 클러스터에 존재하는 각각의 노드위에 애플리케이션 인스턴스를 스케줄링 한다.

애플리케이션 인스턴스들이 생성되면 쿠버네티스 Deployment 컨트롤러는 이러한 인스턴스들을 지속적으로 모니터링 한다.

Deployment 컨트롤러는 노드 호스팅이 다운되거나 삭제가 된다면 인스턴스를 바꿔치기 한다. 이는 기계 고장 또는 장비 유지 보수에 대한 자가치유 메커니즘을 제공한다.

Deployment의 생성과 관리는 쿠버네티스 command line interface로 사용한다. (kubectl)

kubectl은 kubernetes API를 사용하여 cluster와 통신한다.

Deployment를 생성할 때 애플리케이션을 구동하기 위한 복제 숫자 및 명시적인 컨테이너 이미지가 필요하다.

Deployment Scaling up은 가용한 자원의 노드에 pods을 생성하고 스케줄링 하는 것을 보장한다.

쿠버네티스는 autoscaling을 제공한다.

 


[pod]

Deployment를 생성하면 쿠버네티스는 당신의 애플리케이션을 호스트 장비의 pod으로 생성한다.

pod에는 한개 또는 여러 개의 애플리케이션 컨테이너가 존재한다. 그리고 각 컨테이너들이 리소스를 공유할 수 있다.

pod은 항상 Node위에서 동작한다. Node는 쿠버네티스 안에서 동작하는 머신이다.

Node는 여러 개의 pod을 가질 수 있다.

쿠버네티스 마스터는 클러스터의 노드에서 pod을 자동으로 스케줄링 처리한다.



[service]

서비스는 pods에 포함된 컨테이너의 트래픽 로드 밸런싱을 지원한다.

# kubectl expose deployment kubernetes-bootcamp --type="NodePort" --port 8080


기본적으로 모든 pod들은 클러스터 내부에서만 볼 수 있다. 쿠버네티스 외부에서 애플리케이션에 접속하기 위해서는 우리의 머신과 클러스터 머신 사이에 proxy를 생성해야 한다.

# kubectl proxy

외부에서 http://localhost:8001/api/v1/proxy/namespaces/default/pods/<POD_NAME>/ 입력하면 된다.


기본적인 용어를 알아보았으니 이제 컨테이너 이미지를 쿠버네티스 환경에 배포, 실행, 운영하는 방법에 대해서 알아보자.


1.

쿠버네티스 환경 구성

설치 URL : http://lng1982.tistory.com/269



2.

pod 생성

# kubectl run kubernetes-bootcamp --image=jocatalin/kubernetes-bootcamp:v1 --replicas=2 --port=8080

kubernetes-bootcamp은 pod 이름의 prefix 가 된다. 예를 들어 2개의 pod이 생성되면 pod의 이름은 다음처럼 생성된다.

kubernetes-bootcamp-2019480069-7rhvb

kubernetes-bootcamp-2019480069-c6pxk

--image 뒤에 붙는 jocatalin/kubernetes-bootcamp:v1 은 이미지 주소이다.

도커 이미지 레지스트리는 기본적으로 https://hub.docker.com 를 바라본다.



3.

Service 생성

# kubectl expose deployment kubernetes-bootcamp --target-port=8080 --type=NodePort


Service 생성 후 # kubectl get svc 명령을 실행하면 다음과 같은 정보가 출력된다.

CLUSTER-IP : 클러스터 아이피 (kubernetes에서 생성하는 아이피)

EXTERNAL-IP : <nodes>의 의미는 노드의 아이피이다. 즉, 물리 머신의 아이피

PORT : <내부포트>:<NODE_PORT>/TCP


쿠버네티스 클러스터 내부에서는 curl 192.168.3.22:8080 을 통해 애플리케이션 호출이 가능하고 클러스터 외부에서는 curl <NODE_IP>:30958 과 같이 호출 가능하다.



4.

컨테이너 내부 접속

# kubectl exec kubernetes-bootcamp-390780338-178wd -ti bash



5.

컨테이너 로그 스트리밍

# kubectl logs -f kubernetes-bootcamp-390780338-178wd



6.

복제 확장

# kubectl scale deployments/kubernetes-bootcamp --replicas=4

auto scaling 관련 : http://kubernetes.io/docs/user-guide/horizontal-pod-autoscaling/



7.

쿠버네티스는 롤링 업데이트를 허용한다.

롤링 업데이트 시 새로운 pod이 가용한 노드에 생성된다.

롤링 업데이트 하는 동안에 Service는 요청 트래픽을 사용 가능한 pod으로 로드 밸런싱 한다.

# kubectl set image deployment kubernetes-bootcamp kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2



8.

롤백

# kubectl rollout history deployment kubernetes-bootcamp

위의 명령어를 통해 history 정보 확인 후 롤백하고 싶은 revision 을 아래 명령어 실행 시 추가하면 된다.

# kubectl rollout undo deployment kubernetes-bootcamp --to-revision=1



[기타 정보]

[deployment 상태 정보]

DESIRED상태는 복제 숫자 설정을 보여주고 있다.

CURRENT상태는 몇 개의 복제가 동작하고 있는지 보여준다.

The UP-TO-DATE is the number of replicas that were updated to match the desired (configured) state

The AVAILABLE state shows how many replicas are actually AVAILABLE to the users



[yaml 파일로 pod 생성]

nginx-deployment.yaml

apiVersion: extensions/v1beta1

kind: Deployment

metadata:

  name: nginx-deployment

spec:

  replicas: 2

  template:

    metadata:

      labels:

        app: nginx

    spec:

      containers:

      - name: nginx

        image: nginx:1.8

        ports:

        - containerPort: 80


pod 생성은 다음의 명령어를 이용한다.

# kubectl create -f nginx-deployment.yaml


pod 정보 업데이트를 하고자 할 때에는 yaml 파일 변경 후 다음의 명령어를 이용한다.

# kubectl apply -f nginx-deployment.yaml