개요
쿠버네티스를 빠르게 정확하게 익히기 위해 필요한 컨셉적인 내용을 공식문서를 찾아보고 핵심만 요약해둔다.
이 글은 기본적으로 Docker에 대한 이해가 있다는 가정에서 기술한다. 왜냐하면 Docker 자체를 모르고 있다면 쿠버네티스를 이해하기 힘들기 때문이다.
Pod
기본컨셉 이해
- Pod은 쿠버네티스에서 가장 작고 단순한 객체 모델로써 생성하고 배포가 가능
- Pod은 어플리케이션 컨테이너임
- Docker는 Pod의 컨테이너로 가장 널리 쓰이지만 다른 컨테이너도 가능
- Pod은 아래의 2가지 주요한 패턴으로 동작 가능
- Pod이 Single 컨테이너를 실행 : 가장 일반적인 케이스로 Pod이 단순히 컨테이너를 Wrapping하는 역할을 함
- Pod이 Multi 컨테이너를 실행 : Pod이 서로 연관된 컨테이너들을 집합을 캡슐화하고 있음
큐버네이트 블로그에 소개된 2개의 정보를 참고
– The Distributed System Toolkit: Patterns for Composite Containers
– Container Design Patterns
만약 어플리케이션을 scale-out 하고싶으면 Pod의 replica 갯수를 늘인다.
어떻게 Pod이 여러개의 컨테이너를 관리하는가?
- Pod은 여러개의 관련된 컨테이너들이 연결된 단위를 지원함
- Pod은 서로 연관된 컨테이너를 알아서 같은 물리장비나 VM에 올려줌
- 컨테이너들은 리소스나 의존성을 서로 공유하고 서로 통신할 수 있음, 또한 장애시 coordination 가능
- Single Pod에 여러개의 컨테이너를 Grouping하는 것은 Advanced 사용임을 유의
- 예를 들어 아래와 같이 WAS가 항상 공유 volume을 사용할 때의 Multi 컨테이너 구성은 아래와 같음
Networking
- 각 Pod은 고유한 IP주소를 가짐
- 각 Pod의 컨테이너는 network namespace을 공유함
- Pod안의 컨테이너들은 localhost로 서로 통신 가능함
- Pod안의 컨테이너가 외부로 통신할 때 포트 export정보 등을 지정해야함
(Docker와 동일한 개념이라 봐도 무방할 듯)
Storage
- Pod은 shared storage volume을 명시할 수 있음
- Pod 안의 모든 컨테이너는 이 shared volume에 접근 가능함
- volume은 일부 컨테이너가 재시작 되더라도 Data를 Persistent하게 해줌
Pod의 동작
- 쿠버네티스를 다루며 Pod를 직접 생성하는것은 매우 드묾(singleton pod이라고 할지라도)
이유는 Pod은 폐기가능한 엔티티로 설계되었기 때문 - 즉 Pod은 스스로 재기동 되거나 스케쥴링되거나 회복되거나 하지 않고 컨트롤러가 Pod을 관리함
- 따라서 유저는 Pod을 직접 사용하지 않고 쿠버네티스의 컨트롤러를 통해 Pod을 관리하는게 일반적임
- Controller는 Pod을 scaling하고 healing하는 역할을 함
Pods, 컨트롤
- 컨트롤러는 여러개의 Pod을 생성하거나 관리하게 해줌
(replication, self-healing 등을 명시하면서) - 예를 들어 컨트롤러는 노드가 장애나면 자동으로 Pod의 배치를 다른 노드로 옮겨줌
하나 이상의 Pod을 가지고 Controller에 대해 설명한 예제는 아래와 같음
– Deployment
– StatefulSet
– DaemonSet
Pod 템플릿
- 아래의 Pod Specification 예제는 Replication Controller, Jobs, DaemonSet을 포함한 내용임
내용은 아래와 같다.
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox
command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']
- 현재의 원하는 replica state를 기술하는 것이라기 보다 pod 템플릿은 찍어내는 틀 같은것임
- 템플릿을 바꾼다고 해도 기존에 생성된 pod에 영향을 끼치지 않음
- 핵심은 pod 인스턴스 마다 달리 설정되어야 할 state는 pod 인스턴스가 관리하고 템플릿은 pod생성 정의만 담당하므로 전체 시스템을 유연하고 단순하게 만듦
서비스
- Pod으로만 네트워크를 구성했을때의 문제점
- 쿠버네티스 Pod은 유한함(클라우드 환경에서 폐기, 재배치 등이 모두 가능)
- Pod이 모두 개별 IP를 가지고 있으면 서비스 중인 상황에서 stable하게 관리하기 힘듦
(예를 들어 1.1.1.1로 할당된 pod이 갑자기 죽으면?) - Pod 끼리는 또 어떻게 통신해야 할까?
- 서비스
- 쿠버네티스 서비스는 Pod의 논리적 집합과 엑세스 정책을 관리함
- 이 부분을 Label Selector로 관리함
- 서비스가 Pod으로의 Routing을 관리
- 쿠버네티스에서 Endpoints API를 통해 서비스 안의 Pod의 구성을 업데이트 할 수 있음
서비스 정의
아래는 서비스의 예제 코드이다.
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
위 예제에 대한 설명은 아래와 같다.
- 서비스 이름이 my-service임
- 서비스는 IP가 할당됨(cluster IP라고도 부름), 이게 proxy역할
- port는 외부에 노출될 포트
- targetPort는 Pod과 연결될 포트
큐버네티스는 TCP, UDP, SCTP를 모두지원하고 기본은 TCP이다.