Post
KO

쿠버네티스

쿠버네티스는 컨테이너화된 워크로드와 서비스를 관리하기 위한 이식성이 있고, 확장가능한 오픈소스 플랫폼이다. 쿠버네티스는 선언적 구성과 자동화를 모두 용이하게 해준다. 쿠버네티스는 크고, 빠르게 성장하는 생태계를 가지고 있다. 쿠버네티스 서비스, 기술 지원 및 도구는 어디서나 쉽게 이용할 수 있다.

쿠버네티스란 명칭은 키잡이(helmsman)나 파일럿을 뜻하는 그리스어에서 유래했다. K8s라는 표기는 “K”와 “s”와 그 사이에 있는 8글자를 나타내는 약식 표기이다. 구글이 2014년에 쿠버네티스 프로젝트를 오픈소스화했다. 쿠버네티스는 프로덕션 워크로드를 대규모로 운영하는 15년 이상의 구글 경험과 커뮤니티의 최고의 아이디어와 적용 사례가 결합되어 있다.

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

서비스 디스커버리와 로드 밸런싱

쿠버네티스는 DNS 이름을 사용하거나 자체 IP 주소를 사용하여 컨테이너를 노출할 수 있다. 컨테이너에 대한 트래픽이 많으면, 쿠버네티스는 네트워크 트래픽을 로드밸런싱하고 배포하여 배포가 안정적으로 이루어질 수 있다.

스토리지 오케스트레이션

쿠버네티스를 사용하면 로컬 저장소, 공용 클라우드 공급자 등과 같이 원하는 저장소 시스템을 자동으로 탑재 할 수 있다.

자동화된 롤아웃과 롤백

쿠버네티스를 사용하여 배포된 컨테이너의 원하는 상태를 서술할 수 있으며 현재 상태를 원하는 상태로 설정한 속도에 따라 변경할 수 있다. 예를 들어 쿠버네티스를 자동화해서 배포용 새 컨테이너를 만들고, 기존 컨테이너를 제거하고, 모든 리소스를 새 컨테이너에 적용할 수 있다.

자동화된 빈 패킹(bin packing)

컨테이너화된 작업을 실행하는데 사용할 수 있는 쿠버네티스 클러스터 노드를 제공한다. 각 컨테이너가 필요로 하는 CPU와 메모리(RAM)를 쿠버네티스에게 지시한다. 쿠버네티스는 컨테이너를 노드에 맞추어서 리소스를 가장 잘 사용할 수 있도록 해준다.

자동화된 복구(self-healing)

쿠버네티스는 실패한 컨테이너를 다시 시작하고, 컨테이너를 교체하며, ‘사용자 정의 상태 검사’에 응답하지 않는 컨테이너를 죽이고, 서비스 준비가 끝날 때까지 그러한 과정을 클라이언트에 보여주지 않는다.

시크릿과 구성 관리

쿠버네티스를 사용하면 암호, OAuth 토큰 및 SSH 키와 같은 중요한 정보를 저장하고 관리 할 수 있다. 컨테이너 이미지를 재구성하지 않고 스택 구성에 시크릿을 노출하지 않고도 시크릿 및 애플리케이션 구성을 배포 및 업데이트 할 수 있다.

구성요소

*

노드

쿠버네티스는 컨테이너를 파드내에 배치하고 노드* 에서 실행함으로 워크로드를 구동한다. 노드는 클러스터에 따라 가상 또는 물리적 머신일 수 있다. 각 노드는 컨트롤 플레인에 의해 관리되며 파드를 실행하는 데 필요한 서비스를 포함한다.

일반적으로 클러스터에는 여러 개의 노드가 있으며, 학습 또는 리소스가 제한되는 환경에서는 하나만 있을 수도 있다.

노드의 컴포넌트에는 kubelet, 컨테이너 런타임 그리고 kube-proxy가 포함된다.

컨트롤 플레인(Control Plane)

컨테이너의 라이프사이클을 정의, 배포, 관리하기 위한 API와 인터페이스들을 노출하는 컨테이너 오케스트레이션 레이어.

파드

파드(Pod) 는 쿠버네티스에서 생성하고 관리할 수 있는 배포 가능한 가장 작은 컴퓨팅 단위이다.

파드 (고래 떼(pod of whales)나 콩꼬투리(pea pod)와 마찬가지로)는 하나 이상의 컨테이너의 그룹이다. 이 그룹은 스토리지 및 네트워크를 공유하고, 해당 컨테이너를 구동하는 방식에 대한 명세를 갖는다. 파드의 콘텐츠는 항상 함께 배치되고, 함께 스케줄되며, 공유 콘텍스트에서 실행된다. 파드는 애플리케이션 별 “논리 호스트”를 모델링한다. 여기에는 상대적으로 밀접하게 결합된 하나 이상의 애플리케이션 컨테이너가 포함된다. 클라우드가 아닌 콘텍스트에서, 동일한 물리 또는 가상 머신에서 실행되는 애플리케이션은 동일한 논리 호스트에서 실행되는 클라우드 애플리케이션과 비슷하다.

애플리케이션 컨테이너와 마찬가지로, 파드에는 파드 시작 중에 실행되는 초기화 컨테이너가 포함될 수 있다. 클러스터가 제공하는 경우, 디버깅을 위해 임시 컨테이너를 삽입할 수도 있다.

파드를 사용하려면 yaml 파일로 템플릿을 작성하는 것 같다.

![](/assets/images/posts/222972462803/af3182ac1039.png?type=w580)

적용은 cli를 통해서 작성하는 것으로 보인다.

![](/assets/images/posts/222972462803/844c1cd309b6.png?type=w580)

단일 컨테이너 실행하는 파드

“파드 당 하나의 컨테이너” 모델은 가장 일반적인 형태. 쿠버네티스는 컨테이너를 직접 관리하는 대신 파드를 관리함.

함께 작동해야 하는 여러 컨테이너를 실행하는 파드

파드는 밀접하게 연결되어 있는 여러 개의 컨테이너로 구성된 애플리케이션을 캡슐화 할 수 있다.

배치된 컨테이너는 하나의 결합된 서비스 단위를 설정할 수 있다.

함께 관리되는 여러 컨테니러를 그룹화하는 것은 비교적 고급 유즈 케이스이다. 이 패턴은 컨테이너가 밀접하게 결합된 특정 인스턴스에서만 사용해야 한다.

각 파드는 특정 애플리케이션의 단일 인스턴스를 실행하기 위한 것이다. 더 많은 인스턴스를 실행하여 더 많은 전체 리소스를 제공하기 위해 애플리케이션을 수평적으로 확장하려면, **각 인스턴스에 하나씩, 여러 파드를 사용해야 한다. -> **쿠버네티스에서는 이를 레플리케이션 이라고 한다.

복제된 파드는 일반적으로 워크로드 리소스와 해당 컨트롤러에 의해 그룹으로 생성되고 관리된다.

컨트롤러 로보틱스와 자동화에서 컨트롤 루프 는 시스템 상태를 조절하는 종료되지 않는 루프이다. 컨트롤 루프의 예시: 실내 온도 조절기 사용자는 온도를 설정해서, 사용자가 의도한 상태 를 온도 조절기에 알려준다. 현재 상태 이다. 온도 조절기는 장비를 켜거나 꺼서 현재 상태를 의도한 상태에 가깝게 만든다. 쿠버네티스에서 컨트롤러는 클러스터 의 상태를 관찰 한 다음, 필요한 경우에 생성 또는 변경을 요청하는 컨트롤 루프이다. 각 컨트롤러는 현재 클러스터 상태를 의도한 상태에 가깝게 이동한다.

파드가 여러 컨테이너를 관리하는 방법

응집력있는 서비스 단위를 형성하는 여러 협력 프로세스(컨테이너)를 지원하도록 설계되었다.

파드의 컨테이너는 클러스터의 동일한 물리 또는 가상머신에서 자동으로 같은 위치에 배치되고 함께 스케줄된다.

컨테이너는 리소스와 의존성을 공유하고, 서로 통신하고, 종료 시기와 방법을 조정할 수 있다.

일부 파드는** 앱 컨테이너 뿐만 아니라 초기화 컨테이너**를 갖고 있다. 초기화 컨테이너는 앱 컨테이너가 시작되기 전에 실행되고 완료된다.

* 앱 컨테이너(App Container)

애플리케이션 컨테이너(또는 앱 컨테이너)는 파드 내의 모든 초기화 컨테이너가 완료된 후 시작되는 컨테이너이다.

* 초기화 컨테이너(Init Container)

앱 컨테이너가 동작하기 전에 완료되기 위해 실행되는 하나 이상의 초기화 컨테이너.

파드는 기본적으로 파드에 속한 컨테이너에 네트워킹스토리지 라는 두가지 종류의 리소스를 제공한다.

파드 작업

사용자가 쿠버네티스에서 직접 개별 파드를 만드는 경우는 거의 없다. 싱글톤 파드도 마찬가지이다. 이는 파드가 상대적으로 일시적인, 일회용 엔티티로 설계되었기 때문이다. 파드가 생성될 때(사용자가 직접 또는 컨트롤러가 간접적으로), 새 파드는 클러스터의 노드에서 실행되도록 스케줄된다. 파드는 파드 실행이 완료되거나, 파드 오브젝트가 삭제되거나, 리소스 부족으로 인해 파드가 축출 되거나, 코드가 실패할 때까지 해당 노드에 남아있다.

  • 파드에서 컨테이너를 다시 시작하는 것과, 파드를 다시 시작하는 것을 혼동해서는 안된다. 파드는 프로세스가 아니라 컨테이너를 실행하기 위한 환경이다. 파드는 삭제될 때까지 유지된다.

파드 템플릿

워크로드 리소스에 대한 컨트롤러는 파드 템플릿에서 파드를 생성하고 사용자 대신 파드를 관리한다.

파드템플릿(PodTemplate)은 파드를 생성하기 위한 명세서이고, 디플로이먼트, 잡 및 데몬셋과 같은 워크로드 리소스에 포함 된다.

워크로드 리소스의 각 컨트롤러는 워크로드 오브젝트 내부의 PodTemplate을 사용하여 실제 파드를 생성한다. PodTempate은 앱을 실행하는 데 사용되는 워크로드 리소스가 무엇이든지 원하는 상태의 일부이다.

템플레이트 양식

apiVersion: batch/v1 kind: Job metadata: name: hello spec: template: # 여기서부터 파드 템플릿이다 spec: containers: - name: hello image: busybox command: ['sh', '-c', 'echo "Hello, Kubernetes!" && sleep 3600'] restartPolicy: OnFailure # 여기까지 파드 템플릿이다

파드 템플릿을 수정하거나 새로운 파드 템플릿으로 바꿔도 이미 존재하는 파드에는 직접적인 영향을 주지 않는다.

워크로드 리소스의 파드 템플릿을 변경하는 경우, 해당 리소스는 수정된 템플릿을 사용하는 대체 파드를 생성해야 한다.

예를 들어, 스테이트풀셋 컨트롤러는 실행 중인 파드가 각 스테이트풀셋 오브젝트에 대한 현재 파드 템플릿과 일치하는지 확인한다. 스테이트풀셋 기본 튜토리얼에서 업데이트 전략을 봐야 한다.

업데이트 전략

롤링 업데이트

쿠버네티스 1.7 이상에서 스테이트 풀셋 컨트롤러는 자동 업데이트를 지원한다. 전략은 스테이트 풀셋 API 오브젝트 ‘spec.updateStrategy’ 필드로 결정된다.

이 기능은 컨테이너 이미지, 스테이트 풀셋의 리소스 요청이나 혹은 한계와 레이블과 파드의 어노테이션을 업그레이드하기 위해 사용될 수 있다.

RollingUpdate, OnDelete 2개의 유효한 업데이트 전략이 있다.

> 롤링 업데이트

RollingUpdate 업데이트 전략은 스테이트풀셋을 보장하면서 스테이트풀셋 내에 파드를 역순으로 업데이트 합니다.

스테이트풀셋 web의 업데이트 전략을 RollingUpdate로 패치하는 방법은 아래와 같습니다.

kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate"}}}'
statefulset.apps/web patched

터미널 창에서 스테이트 풀셋 web의 컨테이너 이미지를 바꾸도록 또 패치하면 다음과 같습니다.

kubectl patch statefulset web --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"gcr.io/google_containers/nginx-slim:0.8"}]'
statefulset.apps/web patched

터미널창에서 스테이트풀셋의 파드를 감시해보는 방법은 아래와 같다.

kubectl get pod -l app=nginx -w

스테이트풀셋은 아래와 같이 보일 것이다.

NAME READY STATUS RESTARTS AGE web-0 1/1 Running 0 7m web-1 1/1 Running 0 7m web-2 1/1 Running 0 8m web-2 1/1 Terminating 0 8m web-2 1/1 Terminating 0 8m web-2 0/1 Terminating 0 8m web-2 0/1 Terminating 0 8m web-2 0/1 Terminating 0 8m web-2 0/1 Terminating 0 8m web-2 0/1 Pending 0 0s web-2 0/1 Pending 0 0s web-2 0/1 ContainerCreating 0 0s web-2 1/1 Running 0 19s web-1 1/1 Terminating 0 8m web-1 0/1 Terminating 0 8m web-1 0/1 Terminating 0 8m web-1 0/1 Terminating 0 8m web-1 0/1 Pending 0 0s web-1 0/1 Pending 0 0s web-1 0/1 ContainerCreating 0 0s web-1 1/1 Running 0 6s web-0 1/1 Terminating 0 7m web-0 1/1 Terminating 0 7m web-0 0/1 Terminating 0 7m web-0 0/1 Terminating 0 7m web-0 0/1 Terminating 0 7m web-0 0/1 Terminating 0 7m web-0 0/1 Pending 0 0s web-0 0/1 Pending 0 0s web-0 0/1 ContainerCreating 0 0s web-0 1/1 Running 0 10s

스테이트풀셋 내에 파드는 순번의 역순으로 업데이트가 된다.

(순번의 역순으로 업데이트 된다면 0,1,2 면 2,1,0 으로 업데이트 된다는 것인듯?)

스테이트풀셋 컨트롤러는 각 파드를 종료시키고 다음 파드를 업데이트하기 전에 Running과 Ready 상태로 전환될 때까지 기다린다. 알아둘 것은 이전 파드가 Running과 Ready상태가 되기까지 다음 파드를 업데이트 하지 않아도 현재 버전으로 파드 업데이트하다 실패하면 복원한다는 것이다.

컨테이너 이미지를 살펴보기 위해 파드를 가져와보자.

for p in 0 1 2; do kubectl get pod "web-$p" --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'; echo; done
k8s.gcr.io/nginx-slim:0.8 k8s.gcr.io/nginx-slim:0.8 k8s.gcr.io/nginx-slim:0.8

스테이트풀셋의 모든 파드가 지금은 이전 컨테이너 이미지를 실행 중이다.

참고: 스테이트풀셋의 롤링 업데이트 상황을 살펴보기 위해 kubectl rollout status sts/ 명령어도 사용할 수 있다.

> 단계적으로 업데이트 하기

RollingUpdate 업데이트 전략의 파라미터인 partition을 이용하여 스테이트풀셋의 단계적으로 업데이트할 수 있다. 단계적 업데이트는 스테이트풀셋의 모든 파드를 현재 버전으로 유지하면서 스테이트풀셋의 **.spec.template **에 변경을 허용한다.

web의 updateStrategy 필드에 partition을 추가하자.

kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate","rollingUpdate":{"partition":3}}}}'
statefulset.apps/web patched

컨테이너의 이미지를 바꾸도록 스테이트풀셋을 또 패치하자.

kubectl patch statefulset web --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"k8s.gcr.io/nginx-slim:0.7"}]'
statefulset.apps/web patched

스테이트풀셋의 파드를 삭제하자.

kubectl delete pod web-2
pod "web-2" deleted

파드가 Running과 Ready 상태가 되기까지 기다리자.

출처 : https://kubernetes.io/ko/docs/concepts/overview/what-is-kubernetes/

This article is licensed under CC BY 4.0 by the author.