지난 포스팅에서는 k8s의 전체적인 그림을 살펴보고 간단한 개념에 대해 알아보았다.
(https://timewizhan.tistory.com/entry/Kubernetes-Overview?category=1035066)
이번 포스팅에서는 기본 리소스에 대해 하나씩 알아보려고 한다.
Pods
그림 1. Pods
그림 1에서 볼 수 있듯이 k8s의 작업 단위로 한개 또는 그 이상의 컨테이너의 그룹화를 의미한다. (그룹화된 컨테이너를 추상화한 표현)
일반적으로 강한 결합을 필요로하는 여러개의 컨테이너들을 하나의 Pod로 묶는다. (물론 하나의 컨테이너를 Pod로 묶기도 한다.)
그림 2. Pod Layout
그래서 그림 2를 확인하면 Pod를 어떤 식으로 묶어서 사용하는지 확인 할 수 있다. 그런데 주의할 사항은 Pod는 여러 노드에 배치할 수는 있지만 같은 노드에만 배치해야 한다. (그림 2의 아래 그림처럼 Pod를 여러 개의 노드에 걸쳐서 배치 할 수는 없다.)
그렇다면 그림 2에서 컨테이너 그림 크기로도 확인 할 수 있듯이 Pod의 적절한 크기는 어느 정도 일까. 일반적으로는 Pod에 묶이는 강한 결합성을 띈 애플리케이션의 구성에 달려 있다. (물론 결합된 컨테이너의 크기가 너무 크다면 노드의 물리적 한계 또한 따져봐야 한다.)
그림 3. Pod Manifest (yaml)
k8s에서는 Pod를 생성할 때 kubectl을 직접 사용해서 만들어도 되지만 메니페스트* 파일을 만들어서 관리하는 것을 추천한다.
* k8s의 여러 리소스를 정의하는 파일로 버전 관리가 가능하다.
그림 3에서는 매니페스트 파일로 Pod를 nginx와 echo (애플리케이션)을 Pod로 묶어서 사용한다는 것을 알 수 있다.
apiVersion: v1 kind: Pod // 매니페이스 파일이 Pod 생성용이기 떄문에 (다른 리소스를 사용해도 된다) metadata: // 해당 Pod에 사용되는 메타데이터 name: simple-echo spec: // 리소스를 정의하기 위한 속성 (리소스마다 내부 구성요소가 다르다) containers: - name: nginx // 컨테이너 이름 image: ... // 도커 이미지 env: // 환경 변수 - name: BACKEND_HOST value: localhost:8080 ports: - containerPort: 80 // 컨테이너가 expose하는 포트 ... |
해당 파일을 바탕으로 Pod를 생성해보면 아래와 같이 Pod가 동작하는 것을 확인 할 수 있다.
그림 4. Running Pod
그림 5. Pod Network
그림 1에서도 잠깐 등장했지만 Pod는 각각 고유의 가상 IP 주소를 할당받는다. 때문에 Pod 안에 있는 모든 컨테이너는 동일한 가상 IP 주소를 공유해서 사용한다.
그림 5를 보면 10.244.1.8의 IP 주소를 가진 Pod는 4개의 컨테이너를 가지는데 Pod 내부적으로 컨테이너간에 네트워크 통신은 Localhost:Port로 이루어진다.
이는 Pod 안에 있는 모든 컨테이너가 동일한 IP를 가지기 때문이다.
그림 3에서 만들었던 예시를 다시 들어보면 nginx는 포트를 80, echo는 포트를 8080을 가지고 있다. nginx가 echo를 호출하기 위해서는 localhost:8080과 같은 방식으로 호출하면 된다. Pod 내부 통신 뿐만 아니라 Pod 간의 통신은 각 할당된 IP 및 포트를 가지고 하면된다. (Localhost는 Pod 내부 통신만)
ReplicaSet
ReplicaSet은 똑같은 Pod를 여러개 만들 때 사용하는 리소스이다. Pod 부분에서 언급했듯이 버전 관리를 위해 매니페스트(manifest) 파일을 만들어서 Pod를 생성한다. 그런데 매니페이스 파일로는 Pod를 한 번 밖에 만들 수 없기 때문에 ReplicaSet을 사용하여 여러개를 만든다.
apiVersion: apps/v1 kind: ReplicaSet metadata: name: echo labels: app: echo spec: replicas: 3 // 복제본의 갯수 selector: matchLabels: app: echo template: // Pod의 manifest 정의와 같음 metadata: labels: app: echo spec: containers: ... |
해당 파일을 정의하고 실행하면 아래과 같이 동일한 Pod가 여러개 생성된 것을 확인 할 수 있다.
그림 6. Running ReplicaSet
이와 같은 ReplicaSet은 파일에 정의한 Pod의 수가 항상 유지될 수 있게 한다. 때문에 임의로 Pod를 종료하면 Replication Contoller 및 ReplicaSet에 의해 종료된 갯수만큼 Pod를 다시 만든다.
그림 7. Deployment Vs ReplicaSet
k8s에서 배포의 기본 단위이다. 보통 ReplicaSet의 상위에 해당하는 리소스를 의미한다. 그림 7을 보면 확인 할 수 있듯이 Deployment는 ReplicaSet을 관리하고 실제 Pod 생성은 ReplicaSet이 담당한다. 때문에 실제 운영에서는 ReplicaSet을 통해 다루기 보다는 Deployment을 통해 다루는 경우가 많다.
apiVersion: apps/v1 kind: Deployment metadata: name: echo labels: app: echo spec: replicas: 4 selector: matchLabels: app: echo template: metadata: labels: app: echo spec: containers: ... |
또한 실제 Deployment 매니페스트 파일을 확인하면 바뀐 것이 Deployment 리소스 밖에 없다. (위의 코드 참조)
그럼 한 번 Deployment가 얼마나 효율적인지 확인해 보도록 하자.
그림 8. Running Deployment
그림 8은 Deployment를 매니페스트를 실행한 후 현재 Deployment의 리비전이다. Deployment는 실행 이후 스스로 리비전을 갖게 되는데 최초는 리비전 1이다.
그런데 Deployment를 통해 Pod를 생성하고 동작하고 있는 상황에서 새로이 Deployment 매니페스트 파일을 수정하고 배포하면 아래와 같이 된다.
그림 9. New Running Deployment
그림 9에서 확인 할 수 있듯이 기존의 Pod는 단계별로 종료되고 수정된 버전의 Pod가 생성된다.
그림 10. New Revision
또한 Deployment의 리비전을 확인하면 어떤 내용으로 (자세히는 나오진 않지만) 변경이 되었는지 확인 할 수 있다. 더욱이 Deployment의 장점 중 하나는 이러한 리비전을 이용해서 특정 버전으로 Pod를 재배포 할 수 있다는 것이다. 때문에 Pod의 관리 측면에서 Deployment가 효율적이다.
Reference
- https://kubernetes.io/docs/tutorials/kubernetes-basics/
- http://www.joseluisgomez.com/containers/hands-on-kubernetes-pods/
'IT > Kubernetes' 카테고리의 다른 글
[Kubernetes] Job & CronJob (1) | 2019.04.06 |
---|---|
[Kubernetes] Ingress (0) | 2019.03.31 |
[Kubernetes] Basic Resource - Part 2 (0) | 2019.03.30 |
[Kubernetes] Design Pattern (1) | 2019.03.27 |
[Kubernetes] Overview (0) | 2019.03.26 |
댓글