[Docker] Kubernetes
1. Kubernetes
1) Kubernetes 기능
Kubernetes는 여러 개의 호스트를 하나로 묶어 도커를 이용하기 위한 오케스트레이션 툴로 분산 환경에서 한 대의 컴퓨터처럼 투과적으로 컨테이너에 액세스할 수 있다. 더욱이 시스템 이용자로부터 오는 부하의급증에 대해서도 유연하게 스케일하는 장치나 여러 개의 컨테이너를 효율적으로 통합 관리하는 장치도 있다.
- 여러 서버들에서의 컨테이너 관리
- 컨테이너 간 네트워크 관리
- 컨테이너의 부하분산
- 컨테이너의 감시
- 무정지로 업데이트
2) Kubernetes Master 서버
Kubernetes 클러스터 안의 컨테이너를 조작하기 위한 서버이다. kubect1 명령을 사용하여 클러스터를 구성하거나 리소스를 조작할 때는 마스터 서버가 커맨드로부터 리퀘스트를 받아 처리를 수행한다. 여러 대로 구성된 Kubernetes 클러스터 안에 있는 노드의 리소스 사용 상황을 확인하고 컨테이너를 시작할 노드를 자동으로 선택한다. Kubernetes가 오케스트레이션 툴이라 불리는 이유도 이 마스터 서버가 여러 대로 분산 구성된 노드를 모아 관리함으로 사용자가 봤을 때 마치 한 대의 서버인 것처럼 행동할 수 있기 때문이다.
3) 백엔드 데이터베이스 (etcd)
etcd라 부르는 분산 키 벨류 스토어를 사용하여 클러스터의 구성 정보를 관리한다. 클러스터를 구축하기 위한 설정 정보가 들어 있다. 시스템 구성에 따라서는 백엔드 데이터베이스를 마스터 서버 상에 구축하는 경우도 있다. 또한 마스터 서버와 마찬가지로 다중화를 검토할 필요가 있다.
4) 노드
실제로 도커 컨테이너를 작동시키는 서버이다. 노드를 여러 개 마련하여 클러스터를 구성한다. 노드의 관리는 마스터 서버가 하며 노드를 몇대 마련할지는 시스템의 규모나 부하에 따라 달라진다. 클라우드에서는 가상 머신의 인스턴스가 노드가 된다.
2. 애플리케이션 구성 관리
1) Pod
Kubernetes에서는 여러 개의 컨테이너를 모아 Pod로 관리한다. 예를 들어, 애플리케이션 서버용 도커 컨테이너와 프록시 서버용 컨테이너 등 관련된 것을 Pod로 모은다. 그리고 Kubernetes에서 Pod가 애플리케이션의 전개 단위가 되며, Pod 단위로 컨테이너 작성, 시작, 정지, 삭제와 같은 조작을 수행한다. 따라서 웹 프론트 서버와 데이터베이스 서버와 같이 역할이 다른 기능을 하나의 Pod에 저장하면 안된다. 즉, Pod 단위로 애플리케이션을 관리하며 여러 개의 노드에 걸치는 경우는 없다.
Pod는 반드시 동일한 노드 상에 동시에 전개되는 특징이 있어 Pod 안의 여러 컨테이너가 가상 NIC를 공유하는 구성을 취하기 때문에 컨테이너끼리 localhost 경유로 통신을 할 수 있다. 또한 공유 디렉토리를 통해 로그 정보를 주고 받을 수 있으며 노드 안에는 여러 개의 Pod이 배치된다.
2) ReplicaSet
ReplicaSet은 Kubernetes 클러스터 상에서 미리 지정된 Pod를 작성하여 실행시켜 두는 장치이다. 간단히 생각하면 클러스터 상에 정해진 수의 Pod를 반드시 실행시켜둔다는 뜻이다. ReplicaSet은 실행중인 Pod를 감시하여 장애와 같은 이유로 정지된 경우에 해당 Pod를 삭제하고 새로운 Pod를 실행시킨다. 즉, 필요한 Pod 수 만큼 실행시킨 상태를 클라우드 안에 항상 만들어 두는 역할을 한다. 클라우드 안에 Pod를 얼마나 실행시켜 둘지를 리플리카 수라고 한다.
예를 들어 5개의 노드에서 7개의 Pod를 실행시킨 상태를 ReplicaSet으로 구성하고 있을 때, 어떤 이유로 Pod가 이상 종료된 경우는 새로은 Pod를 실행시켜 클러스터 전체에서 항상 7개의 Pod가 실행된 상태를 유지한다.
또한 Pod의 수를 동적으로 변경하여 오토스케일을 구현할 수 있다. ReplicaSet를 이용하면 애플리케이션 개발자는 전개한 Pod가 어떤 상태인지를 신경을 쓸 필요 없이 항상 지정한 개수 만큼 Pod가 실행된 상태를 Kubernetes가 유지해준다.
3) Deployment
Deployment는 Pod와 ReplicaSet를 모은 것으로 ReplicaSet의 이력을 관리한다. Deployment는 ReplicaSet의 템플릿을 가지고 거기서 Pod의 구성을 정의하여 해당 템플릿을 따르는 ReplicaSet를 만든다. 이력을 관리할 수 있기 때문에 예를 들어 Pod 안의 컨테이너의 버전업을 하고 싶을 때 시스템을 정지시키지 않고 롤링 업데이트를 할 수 있거나 이력을 바탕으로 하나 이전 세대로 롤백할 수 있다.
즉, 정의된 리플리카의 수를 유지하는 역할을 갖고 있는 것이 ReplicaSet이고 ReplicaSet의 작성이나 갱신을 정의하는 것이 Deployment이다. 그 외에도 노드별로 감시 에이전트와 같은 특정 Pod를 반드시 배치하고 싶을 때에 이용하는 'DaemonSet'이나 웹 서버와 같은 상주 서비스가 아닌 수치 연산 처리와 같이 프로그램의 시작부터 종료까지 완료되는 프로그램을 Pod에서 실행시키는 'Jobs' 등이 있다. 더불어 'CronJob'을 사용하면 Linux의 Cron과 같이 Pod를 실행시킬 타이밍도 지정할 수 있다.
3. 네트워크 관리 (Service)
Kubernetes 클러스터 안에서 실행되는 Pod에 대해 외부로부터 액세스할 때는 서비스를 정의한다. 서비스는 Kubernetes 네트워크를 관리하는 것으로 종류가 다양하다. 그 중 Load Balancer와 같이 서비스에 대응하는 IP주소 + 포트번호에 액세스하면 여러 Pod에 대한 레이어 4 레벨의 부하분산이 일어난다.
서비스에 의해 할당되는 IP 주소에는 클러스터 IP와 외부 IP가 있다. 클러스터 IP는 클러스터 안의 Pod끼리 통신을 하기 위한 프라이빗 IP 주소이며, 외부 IP는 외부 클라이언트가 연결하기 위한 퍼블릭 IP이다.
4. Label 리소스 식별
Kubernetes에서는 리소스를 식별하기 위해 내부에서 자동으로 랜덤한 이름이 부여된다. 하지만 이것으로는 리소스를 적절히 관리하기 힘들기 때문에 알기 쉬운 Label을 붙여 관리한다. Label은 키-값 형태로된 임의의 문자열로, 이 Label을 식별자로 하여 리소스를 일괄적으로 처리할 수 있다. Label이 붙은 리소스를 참조하려면 'selector'로 지정한다.
Label은 하나의 리소스에 대해 여러 개 설정할 수 있기 때문에 Pod의 역할별로 임의의 이름을 붙이거나 관련 있는 Pod별로 모아서 유연하게 관리하고 싶을 때 임의의 Label을 설정한다. 또한 Label은 Kubernetes의 정의 파일인 매니페스트 파일을 참조할 때도 사용된다. 대규모 웹 시스템에서는 수많은 Pod나 버전이 다른 Pod를 관리해야한다. Label을 사용하여 논리적인 그룹핑을 함으로써 운용 부담을 줄일 수 있다.
labels:
app: v1.0
selector:
type: webserver
app: v1.0
5. Kubernetes 구조
1) 전체적인 구조
Kubernetes는 마스터, 데이터 스토어, 노드가 서로 협력하면서 컨테이너의 실행 환경을 관리하며, 그 안에서 몇가지 컴포넌트가 동작한다.
2) 마스터
API Server는 Kubernets의 리소스 정보를 관리하기 위한 프론트엔드 REST API로, 각 컴포넌트로부터 리소스 정보를 받아 데이터 스토어에 저장한다. 다른 컴포넌트는 API Server를 통해 etcd의 정보에 액세스한다. 개발자가 API Server에 액세스하려면 웹의 GUI 툴이나 kubectl 명령을 사용한다. 또한 애플리케이션안에서 API Server를 호출할 수 있다. API Server는 인증 및 인가 기능을 가지고 있다. (테스트나 작동 확인 시에는 kubectl 명령의 인수로 클러스터를 조작할 수 있다.)
Scehduler는 Pod의 어떤 노드에서 작동시킬지를 제어하는 백엔드 컴포넌트이다. Scheduler는 노드에 할당되어 있지 않은 Pod에 대해 Kubernetes 클러스터의 상태를 확인하고 빈 영역을 가진 노드를 찾아 Pod를 실행시키는 스케줄링을 수행한다.
Controller Manager는 Kubernetes 클러스터의 상태를 항상 감시하는 백엔드 컴포넌트이다. 정의 파일에서 정의한 것과 실제 노드나 컨테이너에서 움직이고 있는 상태를 모아서 관리한다.
3) 데이터 스토어 (etcd)
Kubernets 클러스터 구성을 유지 관리하는 KVS이다. 키-값 형태로 데이터를 관리하며 어떤 Pod를 어떻게 배치할지와 같은 구성 정보를 가지고 있으며 API Server가 참조한다.
4) 노드
노드에서는 kubelet이라는 에이전트가 작동된다. Pod의 정의 파일에 따라 도커 컨테이너를 실행하거나 스토리지를 마운트하는 기능을 가지고 있다. 또한 kubelet은 노드의 상태를 정기적으로 감시하는 기능을 가지고 있어 상태가 변경되면 API Server에 통지해준다.
5) Manifest
Kubernetes에서는 클러스터의 구성 정보를 YAML 또는 JSON 형식으로 관리할 수 있다. 이 정의 파일은 매니패스트파일이라고 하며 선언 기반으로 구성을 관리한다. 매니패스트 파일은 텍스트 파일로 Jenkins와 같은 소프트웨어의 버전 관리 시스템과 연계할 수 있다.
apiVersion: extension/v1beta1
kind: Deployment
metadata:
name: webserver-blue
spec:
replicas: 3 # 실행시킬 Pod 수
template :
...
spec:
containers:
- image: imagerec:blue # 도커 이미지 지정
name: webserver-container
...
ports:
- containerPort: 80 # 전송 포트 지정
name: http-server
[참고] 완벽한 IT 인프라 구축을 위한 Docker (2판)