From 7b707b1d814c2fd4b96cbbaf5bc307851e00d0cd Mon Sep 17 00:00:00 2001 From: Sungchan Yi Date: Wed, 12 Jul 2023 10:25:26 +0900 Subject: [PATCH] feat: recovery part 2 of kubernetes in action (#34) * [PUBLISHER] upload files #29 * PUSH NOTE : 04. Replication and Other Controllers - Deploying Managed Pods.md * PUSH ATTACHMENT : k8s-04.jpeg * PUSH NOTE : 03. Pods - Running Containers in Kubernetes.md * PUSH ATTACHMENT : k8s-03.jpeg * [PUBLISHER] upload files #30 * PUSH NOTE : 06. Volumes - Attaching Disk Storage to Containers.md * PUSH ATTACHMENT : k8s-06.jpeg * PUSH NOTE : 05. Services - Enabling Clients to Discover and Talk to Pods.md * PUSH ATTACHMENT : k8s-05.jpeg * [PUBLISHER] upload files #31 * PUSH NOTE : 08. Accessing Pod Metadata and Other Resources from Applications.md * PUSH ATTACHMENT : k8s-08.jpeg * PUSH NOTE : 07. ConfigMaps and Secrets - Configuring Applications.md * PUSH ATTACHMENT : k8s-07.jpeg * [PUBLISHER] upload files #32 * PUSH NOTE : 07. ConfigMaps and Secrets - Configuring Applications.md * PUSH ATTACHMENT : k8s-07.jpeg * [PUBLISHER] upload files #33 * PUSH NOTE : 10. StatefulSets - Deploying Replicated Stateful Applications.md * PUSH ATTACHMENT : k8s-10.jpeg * PUSH NOTE : 09. Deployments - Updating Applications Declaratively.md * PUSH ATTACHMENT : k8s-09.jpeg --- .../Kubernetes/2021-03-17-03-pods.md | 447 +++++++++++++++ ...21-04-replication-and-other-controllers.md | 454 +++++++++++++++ .../Kubernetes/2021-04-07-05-services.md | 470 ++++++++++++++++ .../Kubernetes/2021-04-07-06-volumes.md | 372 +++++++++++++ .../2021-04-18-07-configmaps-and-secrets.md | 474 ++++++++++++++++ ...a-and-other-resources-from-applications.md | 518 +++++++++++++++++ .../Kubernetes/2021-04-30-09-deployments.md | 490 +++++++++++++++++ .../Kubernetes/2021-05-17-10-statefulsets.md | 519 ++++++++++++++++++ assets/img/posts/k8s-03.jpeg | Bin 0 -> 47648 bytes assets/img/posts/k8s-04.jpeg | Bin 0 -> 25032 bytes assets/img/posts/k8s-05.jpeg | Bin 0 -> 37186 bytes assets/img/posts/k8s-06.jpeg | Bin 0 -> 44356 bytes assets/img/posts/k8s-07.jpeg | Bin 0 -> 58138 bytes assets/img/posts/k8s-08.jpeg | Bin 0 -> 26382 bytes assets/img/posts/k8s-09.jpeg | Bin 0 -> 37914 bytes assets/img/posts/k8s-10.jpeg | Bin 0 -> 25284 bytes 16 files changed, 3744 insertions(+) create mode 100644 _posts/Development/Kubernetes/2021-03-17-03-pods.md create mode 100644 _posts/Development/Kubernetes/2021-03-21-04-replication-and-other-controllers.md create mode 100644 _posts/Development/Kubernetes/2021-04-07-05-services.md create mode 100644 _posts/Development/Kubernetes/2021-04-07-06-volumes.md create mode 100644 _posts/Development/Kubernetes/2021-04-18-07-configmaps-and-secrets.md create mode 100644 _posts/Development/Kubernetes/2021-04-18-08-accessing-pod-metadata-and-other-resources-from-applications.md create mode 100644 _posts/Development/Kubernetes/2021-04-30-09-deployments.md create mode 100644 _posts/Development/Kubernetes/2021-05-17-10-statefulsets.md create mode 100644 assets/img/posts/k8s-03.jpeg create mode 100644 assets/img/posts/k8s-04.jpeg create mode 100644 assets/img/posts/k8s-05.jpeg create mode 100644 assets/img/posts/k8s-06.jpeg create mode 100644 assets/img/posts/k8s-07.jpeg create mode 100644 assets/img/posts/k8s-08.jpeg create mode 100644 assets/img/posts/k8s-09.jpeg create mode 100644 assets/img/posts/k8s-10.jpeg diff --git a/_posts/Development/Kubernetes/2021-03-17-03-pods.md b/_posts/Development/Kubernetes/2021-03-17-03-pods.md new file mode 100644 index 0000000..d4bed63 --- /dev/null +++ b/_posts/Development/Kubernetes/2021-03-17-03-pods.md @@ -0,0 +1,447 @@ +--- +share: true +toc: true +categories: [Development, Kubernetes] +tags: [kubernetes, sre, devops] +title: "03. Pods: Running Containers in Kubernetes" +date: "2021-03-17" +github_title: "2021-03-17-03-pods" +image: + path: /assets/img/posts/k8s-03.jpeg +--- + +![k8s-03.jpeg](../../../assets/img/posts/k8s-03.jpeg) _A container shouldn’t run multiple processes. (출처: https://livebook.manning.com/book/kubernetes-in-action/chapter-3)_ + +다양한 쿠버네티스 오브젝트 (resources) 를 살펴보는 단원이다. 가장 기본이 되는 Pod 부터 시작한다. 이외의 모든 것들은 pod 를 관리하거나, pod 를 노출하거나, pod 에 의해 사용된다. + +## 3.1 Introducing Pods + +**Pod**는 컨테이너의 모임이며, 쿠버네티스의 기본적인 building block 이 된다. 하나 기억할 사실은, 하나의 pod 는 하나의 노드 위에 있게 되므로, pod 내부의 모든 컨테이너는 같은 노드에 존재하게 된다. + +### 3.1.1 왜 Pod 를 사용하는가? + +그냥 하나의 컨테이너 안에서 모든 것을 실행하면 안 되는 것인가? + +하나의 프로세스라면 하나의 컨테이너 안에서 실행해도 괜찮지만, 여러 프로세스가 한꺼번에 동작하는 앱의 경우 한 컨테이너 안에서 돌아가게 되면 관리가 어렵다. + +모든 프로세스가 정상적으로 돌아가고 있는지 개발자가 직접 확인해야 하고, 프로세스가 죽으면 직접 다시 시작해줘야 하며, 실제 서비스에서 특정 프로세스가 지나친 병목을 일으키는 경우에는 scale out 을 적용하여 해당 프로세스만 여러 개 실행하여 throughput 을 늘릴 수도 있을 것이다. + +그러므로 컨테이너를 여러 개 쓰는 것이 보다 바람직하다. + +### 3.1.2 Pod 에 대한 이해 + +컨테이너 하나에서 여러 프로세스를 실행하는 것은 바람직하지 않으므로, 컨테이너 여러 개를 하나로 묶어서 관리해줄 상위 레벨의 개념이 필요하다. 그래서 Pod 가 등장하게 된 것이다. + +#### Pod 내의 partial isolation + +Pod 를 사용하면 서로 연관된 프로세스를 실행하는 컨테이너들을 함께 실행할 수 있게 되며, 마치 하나의 머신/컨테이너 안에서 실행되는 것처럼 환경을 제공할 수 있게 된다. + +물론 각 컨테이너도 서로 어느 정도 독립적으로 동작하지만, 같은 pod 내의 container 는 같은 namespace 를 가지고 있고, 또 쿠버네티스 *volume* 을 사용해서 컨테이너들 끼리 파일을 공유하도록 설정할 수도 있다. + +#### Shared IP and port space + +같은 pod 내의 컨테이너들은 IP 를 공유하므로, 하나의 포트에는 하나의 서비스만 할당되어야 한다. 또 같은 *loopback network interface* 를 사용하므로 localhost 를 사용해 컨테이너들 끼리 통신할 수 있다. + +#### Flat inter-pod nework + +Pod 마다 IP 가 할당되어 있고, 모든 pod 들은 하나의 flat (network topology 말하는 듯), 공유된 네트워크 주소 공간을 사용한다. 그러므로 pod 들 끼리 서로의 IP 주소를 이용해 통신할 수 있으며, NAT(Network Address Translation) gateway 가 사이에 존재하지 않는다. 이는 pod 가 서로 다른 노드에 배치되더라도 상관없다. + +이렇게 동작하기 위해서는 SDN(Software Defined Network) 레이어를 하나 만들어서 사용한다. + +#### 요약 + +Pod 는 논리적인 호스트이며, 컨테이너를 사용하지 않는다면 물리적인 호스트나 VM과 다를바 없다. 한 pod 내의 프로세스들은 같은 머신에서 동작하는 프로세스들이며, 차이점은 각 프로세스가 컨테이너 안에서 돌아간다는 점이다. + +### 3.1.3 Pod 내의 컨테이너 배치 + +Pod 는 개별적인 머신이지만 한 머신이 하나의 앱을 실행한다고 이해해야한다. + +Pod 는 가벼우므로 거의 오버헤드 없이 여러 개를 실행할 수 있으므로, 하나의 pod 에 모든 것을 꾸겨 넣기 보다는 여러 개의 pod 를 사용해서 한 pod 내에는 관련이 깊은 작업만 있또록 관리하는 것이 좋다. + +#### 하나의 앱을 여러 컨테이너로 분리 + +백엔드, 프론트엔드가 있는 서비스를 생각해보면, 각각을 하나의 pod 내에 넣지 말라는 법은 없지만 바람직한 방법은 아니다. + +만약 쿠버네티스 클러스터에 여러 개의 노드가 있다면, 차라리 두 개의 pod 로 분리해서 CPU 등 하드웨어 자원을 더 효율적으로 사용할 수 있을 것이다. + +더불어 쿠버네티스에서 scaling 의 단위는 pod 이다. 컨테이너 단위로는 복제할 수 없다. (정말? - 확인 필요) + +(+ 왜 스케일링의 단위가 컨테이너가 아닌 pod 로 설계했을까? 관련이 깊은 작업들은 묶어서 한꺼번에 스케일링 하기 위해? 각각을 복제하고 묶는 것보다는 나을 것 같긴 하다.) + +또한 각 애플리케이션 마다 scaling 을 위한 조건이 다를 수 있다. 프론트/백 모두 한 pod 내에 있었다면 스케일링 했을 경우 프론트/백 모두 2개씩 존재하게 된다. 한편 백엔드의 경우 DB가 있다면 scale out 이 어려울 수 있으며, 경우에 따라서 프론트/백 중 어느 하나만 부하가 심해 하나만 scale out 해야하는 상황이 올 수도 있다. + +차라리 이들을 분리하여 각각 하나의 pod 에서 실행되도록 하는 것이 바람직한 방법이다. + +#### 어떤 컨테이너들을 한 pod 내에 묶을 것인가 + +Pod 내에 여러 컨테이너를 넣는다면 그에 합당한 이유가 있어야 한다. 컨테이너가 서로 긴밀하게 연관되어 있어야 한다. Main 컨테이너가 하나 있고 나머지가 해당 컨테이너를 support 한다던가 (sidecar), 혹은 컨테이너들이 하나의 volume 을 공유해야 하는 상황이라던가. + +대표적으로 로깅을 담당하는 컨테이너의 경우 (logrotate, 단순 수집, 수집 후 어딘가로 전송) 애플리케이션과 함께 같은 pod 내에 존재하는 것이 나을 것이다. + +한 pod 내에 여러 컨테이너를 묶는다면 아래 3가지 질문을 해보면 된다. + +- 같이 실행 되어야 하는가? 아니면 다른 호스트에서 실행되어도 괜찮은가? +- 여러 컨테이너가 하나처럼 동작하는가? 아니면 독립적인 컴포넌트인가? +- 함께 스케일링 되어야 하는가? 아니면 따로 스케일링 되어야 하는가? + +기본적으로는 pod 를 분리하는 쪽으로 결정하는 것이 바람직하다. 특별한 이유가 없다면! + +## 3.2 YAML/JSON 파일로부터 pod 만들기 + +보통 pod 를 비롯한 쿠버네티스 리소스를 만들 때는 YAML/JSON 파일을 Kubernetes API 에 POST 해서 만든다. + +물론 `kubectl run ...` 을 사용할 수 있긴 하지만 모든 옵션을 다 지원하지는 않으며, 매번 명령을 입력하기 보다는 파일로 저장하고 관리하여 버전 관리도 할 수 있게 된다. + +### 3.2.1 YAML descriptor + +```bash +$ kubectl get po -o yaml +``` + +- Pod 의 정보를 yaml 형태로 출력하고 싶을 때 사용하는 명령어 +- 뒤에 `yaml` 대신에 `json` 을 붙이면 JSON 파일로 출력 결과를 볼 수 있다. + +복잡하지만 크게 구성은 다음과 같다. + +- 쿠버네티스 API 버전 +- 쿠버네티스 object type +- Pod metadata + - 이름, namespace, 레이블을 비롯한 기타 정보 +- Pod specification/contents + - Pod 내에 존재하는 내용으로 컨테이너, 볼륨과 같은 정보 +- Pod status + - 현재 실행중인 pod 의 상세 정보, 내부 IP 등 + +### 3.2.2 Pod 을 위한 YAML descriptor 만들기 + +대략 다음과 같은 내용으로 구성하면 된다. + +```yaml +apiVersion: # 쿠버네티스 API 버전 +kind: Pod # Pod 임을 명시 +metadata: + name: # Pod 이름 +spec: + container: + - image: # 컨테이너를 실행할 이미지 + name: # 컨테이너의 이름 + ports: # 컨테이너가 listen 할 포트 + - containerPort: + protocol: TCP +``` + +### 3.2.3 `kubectl` 로 pod 생성하기 + +```bash +$ kubectl create -f +``` + +(`kubectl apply -f` 가 생각나는데 무슨 차이가 있는지 확인해보기) + +- Argument 로 넘겨준 파일의 설정으로부터 pod 를 생성한다. + +생성 후 잘 돌아가는지 확인하려면 `kubectl get pods` 로 확인하면 된다. + + +### 3.2.4 로그 확인하기 + +컨테이너 내의 앱은 파일에 로그를 떨구기보다는 보통은 stdout, stderr 로 로그를 내보낸다. 이렇게 하면 다양한 컨테이너들에서 다양한 애플리케이션을 실행할 때 통일된 방법으로 로그를 확인할 수 있다. + +```bash +$ docker logs +``` + +- 컨테이너 내의 로그 (stdout/stderr)를 파일로 redirection 해준다. +- 하지만 `docker` 명령어를 실행하는 것이므로 pod 내에 ssh 로 접근해서 해야한다. + +쿠버네티스에서는 더 간편한 방법을 제공해준다. + +```bash +$ kubectl logs +``` + +- 해당 pod 의 로그를 확인할 수 있게 된다. +- Pod 내의 특정 컨테이너 로그를 확인하려면 `-c ` 을 붙여주면 된다. +- 컨테이너 로그는 10MB 마다, 매일 rotation 된다. + +물론 컨테이너가 삭제되면 로그가 함께 삭제되므로, 클러스터 전체의 로그를 수집하는 부분이 따로 필요하다. (centralized logging) 이는 나중에 17장에서 다룬다. + +### 3.2.5 Pod 에 요청 보내기 + +2장에서 한 것처럼 `kubectl expose` 를 사용하는 방법도 있지만 Service object 에 대해서는 나중에 알아보기로 하고, 포트포워딩으로 하는 방법을 소개한다. + +```bash +$ kubectl port-forward : +``` + +- 로컬의 포트를 pod 의 포트로 포워딩해준다. + +## 3.3 레이블을 이용한 pod 구성 + +Pod 의 개수가 많아질수록 관리가 힘들어지고, 한 서비스에 pod 가 여러 개 존재하게 되므로 (복제본) pod 를 묶어서 관리할 방법이 필요하다. 쿠버네티스는 pod 뿐만 아니라 다른 object 들도 **레이블**을 이용해서 관리한다. + +### 3.3.1 레이블 + +레이블은 key-value pair 로, 쿠버네티스 리소스에 붙일 수 있으며, label selector 를 이용해 리소스를 필터링할 때 사용된다. + +한 리소스에 레이블은 여러 개 붙을 수 있으며 key 가 유일하기만 하면 된다. + +보통 리소스를 생성할 때 레이블을 붙이지만, 리소스를 다시 생성할 필요 없이 레이블을 붙일 수도 있다. + +### 3.3.2 Pod 생성 시 레이블 붙이기 + +당연히 yaml 파일에 레이블을 추가해주면 된다. `metadata` 아래에 추가하면 된다. + +```yaml +metadata: + name: ... + labels: + key_1: value_1 + key_2: value_2 + ... +``` + +이렇게 하고 pod 를 실행한 뒤, `kubectl get pods` 를 해보면 레이블이 보이지 않는다. + +`--show-labels` 옵션을 설정해야 레이블이 같이 출력된다. 대신 모든 레이블이 출력되므로 보기 불편할 수 있다. `-L ` 옵션을 주면 해당 key 에 대한 레이블만 보여준다. Key 가 여러 개인 경우 `,` 로 구분한다. + +### 3.3.3 레이블 수정하기 + +```bash +$ kubectl label po = +``` + +- Pod 에 새롭게 레이블을 붙인다. +- 해당 key 가 존재하지 않아야 한다. 만약 덮어쓰고 싶다면 `--overwrite` 를 붙여야 한다. + +## 3.4 Label selector 를 사용하여 pod 목록 출력하기 + +레이블에 따라 검색하는 기능을 제공한다. + +- 특정 key 를 갖거나 갖지 않는지 +- 특정 key-value 를 갖는지 +- 특정 key 를 갖지만 해당 value 가 아닌 값을 갖는지 + +### 3.4.1 Listing pods using a label selector + +```bash +$ kubectl get po -l [CONDITION] +``` + +- `-l` 옵션을 이용해서 label selector 를 사용할 수 있다. + +`CONDITION` 내에는 다음과 같은 구문을 넣을 수 있다. + +- `=`: 해당 key-value pair 를 갖는 pod 출력 +- ``: 해당 key 를 갖는 pod 출력 +- `!`: 해당 key 를 갖지 않는 pod 출력 + - `'!'` 와 같이 `'...'` 로 감싸주어야 shell 이 `!` 를 계산하지 않는다. +- `!=`: 해당 key 를 갖지만 value 가 아닌 pod 출력 +- ` in (, , ...)`: key 의 값이 value 목록에 포함되는 pod 를 출력 +- ` notin (, , ...)`: key 의 값이 value 목록에 포함되지 않는 pod 를 출력 + +### 3.4.2 Label selector 에서 여러 조건을 이용하기 + +조건을 여러 개 적용하고 싶다면 `,` 로 구분하면 된다. + +이 section 에서는 pod 목록을 가져오는 용도로 레이블을 사용했지만, 여러 개의 pod 를 한꺼번에 삭제할 때도 사용할 수 있는 등 특정 명령을 pod 의 부분집합에 적용할 수 있게 된다. + +## 3.5 Pod 스케쥴링 제한 + +일반적으로는 worker node 들에 pod 들이 적당히 배치되어 돌아간다. 그리고 밖에서 볼 때는 어떤 pod 가 어느 노드에 있는지는 보통 상관 없다. 하지만 pod 가 특정 하드웨어가 필요한 경우에는 pod 가 어느 노드로 스케쥴링 되어야 하는지 제한할 필요가 있다. (GPU가 필요하다던가...) + +한편 특정 노드에 이 pod 를 스케쥴링 해주라고 요청하게 되면 쿠버네티스를 사용할 이유가 없어진다. 앱과 인프라를 분리하지 못하게 된다. 그러므로 특정 노드에 스케쥴링 해야한다고 명시하지는 않고, 이 pod 를 실행할 노드가 갖춰야 할 요구사항을 적는다. 이를 위해 노드 레이블과 노드 label selector 를 사용한다. + +### 3.5.1 Categorizing worker nodes + +레이블은 다양한 리소스에 붙일 수 있다. 명령어도 거의 비슷하다. + +```bash +$ kubectl label node = +``` + +### 3.5.2 특정 노드들로 pod 스케쥴링 + +Pod 의 yaml 파일을 수정하면 된다. + +노드에 `gpu=true` 라는 레이블이 있다고 하면, GPU 가 필요한 pod 의 yaml 파일에 다음을 추가한다. + +```yaml +spec: + nodeSelector: + gpu: "true" +``` + +그러면 이 레이블을 가진 노드에만 pod 가 스케쥴링 되게 된다. + +### 3.5.3 특정 노드 하나로 pod 스케쥴링 + +가능한데 하지마! + +각 노드는 기본적으로 레이블 `kubernetes.io/hostname=` 을 가지므로 이를 이용하면 특정 노드에 pod 를 스케쥴링 할 수 있다. + +하지만 이 노드가 죽어있으면 pod 가 실행되지 못한다. + +개별적인 하나의 노드가 아니라 node label selector 를 이용해 특정 성질을 가진 노드의 집합을 고려하는 것이 쿠버네티스의 사고방식이다. + +## 3.6 Annotating Pods + +쿠버네티스 리소스들은 레이블 뿐만 아니라 어노테이션도 가질 수 있는데, 얘도 key-value pair 이다. 레이블과 비슷하지만 selector 가 따로 존재하지는 않아서 이를 이용해 리소스를 분류할 수는 없다. + +(다른 툴들이 annotation 을 사용한다고 하는데 어떤 툴들이 쓰는지 알아보기) + +### 3.6.1 Object 의 어노테이션 확인하기 + +Object 의 yaml 파일을 확인해 보면 `metadata` 아래에 있다. + +### 3.6.2 어노테이션 추가 및 수정 + +```bash +$ kubectl annotate pod = +``` + +어노테이션 추가시 key 충돌을 막기 위해 unique prefix 를 사용하는 것이 좋다. + +`kubectl describe pod ` 으로 추가된 어노테이션을 확인할 수 있다. + +## 3.7 Namespace 를 이용한 리소스 그룹화 + +`kubectl get pods` 를 했을 때, 매번 레이블을 이용해서 필터링하지 않으면 모든 pod 가 다 목록에 출력된다. 또한 레이블은 한 집합 내에서 부분집합으로 구분하기 위해서 사용했다. 부분집합들은 서로 겹치기도 한다. + +만약 아예 다른 집합을 만들어 겹치지 않도록 분리하고 싶은 경우도 있을 것이다. (다른 이유가 더 있지만 - 뭐지?) 쿠버네티스에서는 namespace 를 이용해서 object 를 그룹화 할 수 있다. + +linux namespace 와는 다르다! + +### 3.7.1 Namespace 의 필요성 + +Namespace 를 사용하면 많은 컴포넌트를 가진 복잡한 시스템을 작고 분리된 그룹으로 나누어 관리할 수 있다. 컴퓨팅 리소스를 개발, 배포, QA 환경 용으로 각각 분리할 수 있게 되며, namespace 안에서만 리소스 이름이 유일하면 된다. + +만약 여러 사용자가 한 클러스터에 접근하여 작업하는 경우 각 사용자마다 독립적으로 리소스를 관리하고 싶다면 namespace 를 사용하여 사용자별로 분리하면 될 것이다. 의도치 않게 다른 사용자들의 리소스를 건드리거나, 이름이 충돌하는 일이 생기지 않게 된다. + +더불어 namespace 에 따라 접근 제한을 할 수 있는데 12~14장에서 더 알아본다. + +거의 대부분의 리소스들이 namespace 로 관리할 수 있지만, 몇 개는 그렇지 않으며 대표적으로 노드의 경우 namespace 에 구애받지 않는다. + +(아마 다른 cluster 레벨의 리소스도 구애받지 않을 것 같다) + +### 3.7.2 Namespace 확인 + +```bash +$ kubectl get namespace +$ kubectl get ns # short +``` + +처음에는 `default` namespace 에서 작업하게 된다. `kubectl get` 명령을 할 때에도 namespace 를 지정하지 않아서 `default` namespace 에 대해 명령을 실행하게 된다. + +`kubectl get` 명령에 `-n` (`--namespace`) 옵션을 주어 namespace 를 제한할 수 있다. + +### 3.7.3 Namespace 만들기 + +Namespace 또한 쿠버네티스 리소스이므로, yaml 파일을 이용해 만들 수 있다. + +```yaml +apiVersion: ... +kind: Namespace +metadata: + name: ... +``` + +파일을 만드는 것은 번거로울 수 있으므로 명령어를 사용하는 방법도 있다. + +```bash +$ kubectl create namespace +``` + +### 3.7.4 다른 namespace 의 object 관리 + +특정 namespace 에 리소스를 만들고 싶다면, yaml 파일에서 `metadata` 섹션 아래에 `namespace: ` 엔트리를 넣어주면 된다. 다만 같은 리소스를 여러 namespace 에 만들고 싶을 수 있으므로 다음과 같이 할 수도 있다. + +```bash +$ kubectl create -f -n +``` + +- `-n` 옵션으로 namespace 를 넘겨주면 된다. + +즉 `-n` 옵션을 이용하면 다른 namespace 에 있는 리소스도 관리할 수 있게 되며, `-n` 옵션이 없으면 현재 설정된 kubectl context 의 namespace 에서 동작하게 된다. + +### 3.7.5 Namespace 가 제공하는 환경 분리 이해하기 + +Namespace 를 사용하면 object 들을 분리하여 그룹화 한 후, 특정 그룹에 대해서만 작업을 할 수 있지만, object 자체를 격리하는 것은 아니다. + +예를 들어 두 pod 가 다른 namespace 에 있다고 해서 반드시 통신이 불가능한 것은 아니다. + +## 3.8 Pod 중지 및 삭제 + +### 3.8.1 이름으로 삭제 + +```bash +$ kubectl delete pod +``` + +### 3.8.2 Label selector 로 삭제 + +```bash +$ kubectl delete pod -l = +``` + +(왠지 label selector 에서 제공하는 필터링 기능을 다 사용할 수 있을 것 같다.) + +### 3.8.3 Pod 이 속한 namespace 삭제 + +```bash +$ kubectl delete ns +``` + +### 3.8.4 Namespace 는 남기고 pod 만 삭제 + +```bash +$ kubectl delete pod --all +``` + +### 3.8.5 거의 모든 리소스 삭제 + +```bash +$ kubectl delete all --all +``` + +몇몇 object 들은 사용자가 직접 삭제해줘야 해서 `all` 로 지워도 지워지지 않는다. + +(안 쓰는게 좋을 것 같다.) + +--- + +## Discussion & Additional Topics + +### `kubectl apply` 와 `kubectl create` 의 차이점 + +- Imperative vs Declarative +- https://kubernetes.io/docs/concepts/overview/working-with-objects/object-management/ +- https://stackoverflow.com/questions/47369351/kubectl-apply-vs-kubectl-create + +### Kubernetes object 와 Kubernetes resource 의 차이점 +- https://stackoverflow.com/a/59952807/7788730 + +### Namespace 의 올바른 사용법 + +### JSON vs YAML +- https://stackoverflow.com/questions/1726802/what-is-the-difference-between-yaml-and-json + +### Label 과 namespace 의 차이 +- Label selector 를 이용하면 namespace 처럼 분리가 가능 +- 하지만 namespace 는 label 보다 상위 개념 +- Namespace 를 이용하면 resource quota 를 이용해서 하드웨어 리소스 분배가 가능 +- Namespace 를 이용하면 접근 제한 가능 + +### Annotation 의 올바른 사용법 + +### Linux 에 존재하는 namespace 들의 종류 +- UTS namespace 란? + +### Pod 에 각각 IP 주소가 부여되는 원리 +- https://ronaknathani.com/blog/2020/08/how-a-kubernetes-pod-gets-an-ip-address/ + +### MSA vs Microservice 간 통신으로 인한 오버헤드 +- MSA 를 사용하면 + - 책임이 분배되어 프로젝트 관리가 용이하고 + - 개발하기 편하고 확장이 쉬워짐 (microservice 별로 확장) +- 다만 통신으로 인한 오버헤드는 증가하는 것이 맞을 것이다. diff --git a/_posts/Development/Kubernetes/2021-03-21-04-replication-and-other-controllers.md b/_posts/Development/Kubernetes/2021-03-21-04-replication-and-other-controllers.md new file mode 100644 index 0000000..fef7c21 --- /dev/null +++ b/_posts/Development/Kubernetes/2021-03-21-04-replication-and-other-controllers.md @@ -0,0 +1,454 @@ +--- +share: true +toc: true +categories: [Development, Kubernetes] +tags: [kubernetes, sre, devops] +title: "04. Replication and Other Controllers: Deploying Managed Pods" +date: "2021-03-21" +github_title: "2021-03-21-04-replication-and-other-controllers" +image: + path: /assets/img/posts/k8s-04.jpeg +--- + +![k8s-04.jpeg](../../../assets/img/posts/k8s-04.jpeg) _ReplicationController recreating pods. (출처: https://livebook.manning.com/book/kubernetes-in-action/chapter-4)_ + +[3장](./2021-03-17-03-pods.md)에서는 pod 를 직접 관리하는 방법에 대해 살펴봤다. 하지만 실무에서는 pod 의 관리가 자동으로 되길 원한다. 이를 위해 ReplicationController 나 Deployment 를 사용한다. + +## 4.1 Keeping pods healthy + +Pod 내의 컨테이너가 (오류로 인해) 죽으면, Kubelet 이 자동으로 해당 컨테이너를 재시작한다. 하지만 컨테이너의 프로세스가 종료되지 않았는데 애플리케이션이 동작하지 않는 경우가 있고, (JVM OOM 에러) 애플리케이션이 deadlock 이나 무한 루프에 빠져서 동작하지 않는 경우가 생길 수도 있다. 이런 경우에도 컨테이너가 자동으로 재시작되게 해야한다. 물론 앱이 자체적으로 에러를 감지해서 프로세스를 종료할 수도 있겠지만, 내부적으로 에러를 감지하기 보다는 **컨테이너 밖에서** 컨테이너의 상태를 확인해야 한다. + +(앱이 자체적으로 에러를 감지해서 프로세스를 죽인다면, 에러를 감지하는 로직을 추가로 구현해야 하며, 이는 쿠버네티스에 올린 앱 종류 별로 달라진다. 앱 자체에 의존적인 로직을 구현하고 사용하는 것보다 컨테이너의 밖에서 정해진 방식으로 에러를 감지하는 편이 나을 것 같다.) + +### 4.1.1 Liveness probes + +쿠버네티스는 *liveness probe* 를 이용해서 컨테이너가 동작 중인지 확인한다. Pod 설정에서 컨테이너 별로 이를 지정할 수 있으며, 지정하면 쿠버네티스가 주기적으로 컨테이너의 상태를 확인하게 된다. + +#### 컨테이너 상태 확인하는 3가지 방법 + +- **HTTP GET probe**: 컨테이너 IP 주소에 GET 요청 보내보기 + - 응답 코드가 2xx, 3xx 이면 OK + - 이외의 에러 코드나 응답이 없으면 실패로 간주하고 컨테이너 재시작 +- **TCP socket probe**: 컨테이너의 정해진 포트에 TCP 연결을 시도해서 실패하면 컨테이너 재시작 +- **Exec probe**: 컨테이너 안에서 임의의 명령을 실행하고 exit code 가 0 이 아니면 컨테이너 재시작 + +### 4.1.2 HTTP-based liveness probe 만들기 + +```yaml +spec: + containers: + - image: luksa/kubia-unhealthy + name: sung + livenessProbe: + httpGet: + path: / + port: 8080 +``` + +`livenessProbe` 에 설정해주면 된다. `httpGet`, `tcpSocket`, `exec` 으로 그 종류를 설정할 수 있다. + +### 4.1.3 Seeing a liveness probe in action + +`kubectl get pods ` 을 한 뒤 `RESTARTS` column 을 보면 재시작 된 횟수를 알 수 있다. + +재시작 사유는 `kubectl describe` 를 이용해 확인할 수 있다. `Last State` 를 보면 된다. + +컨테이너가 종료될 때는 완전히 새로운 컨테이너가 생성된다. 같은 컨테이너가 재시작 되는 것이 아니다. + +(그러면 사실 `restart` 라는 단어가 조금 애매해지는데... 사실은 다른 컨테이너지만 겉에서 보기에는 같다 정도로 이해하면 될 것 같다.) + +### 4.1.4 Liveness probe 추가 설정 + +#### Liveness probe 추가 옵션 + +- `initialDelaySeconds`: 컨테이너가 시작된 직후 첫 liveness 를 체크를 얼마나 미룰 것인지 + - 기본값 0s +- `timeoutSeconds`: liveness probe 가 실행된 후 몇 초만에 응답이 와야 하는지 + - 기본값 1s +- `periodSeconds`: liveness probe 를 실행할 주기 + - 기본값 10s +- `successThreshold`: 컨테이너가 정상적으로 동작한다고 판단할 연속된 liveness probe success 개수 + - 기본값 1 +- `failureThreshold`: 컨테이너가 동작하지 않고 있다고 판단할 연속된 liveness probe failure 개수 + - 기본값 3 + +앱이 시작되는 시간이 존재하므로 `initialDelaySeconds` 를 잘 설정해야 한다. 무거운 애플리케이션의 경우 실행되는데 오래 걸릴 수도 있다. + +#### Exit code + +보통 `128 + x` 로 계산된다. 여기서 `x` 는 프로세스를 죽인 signal 의 번호이다. + +- 137: SIGKILL (128 + 9) +- 143: SIGTERM (128 + 15) + +### 4.1.5 효과적인 liveness probe 만들기 + +배포할 때 필수! 설정하지 않으면 쿠버네티스는 컨테이너의 프로세스가 실행 중인지만 확인하여 컨테이너의 상태를 확인한다. + +- 앱에 health check API 를 만들어서 이를 호출하도록 할 수도 있다. + - 이 경우 앱 자신에 대한 health check 만 하도록 한다. 프론트 서버에서 DB 가 접속이 안된다는 이유로 실패했다고 하면 안된다. 이건 프론트 서버가 아닌 DB 의 문제일 수도 있다. +- Liveness probe 는 가벼워야 한다. + - 자원을 너무 많이 소모해서도 안되고, 지나치게 오래 걸려도 안된다. +- Liveness probe 구현 시 재시도 횟수를 포함하여 구현할 필요 없다. + - `failureThreshold` 옵션을 이용한다. + +## 4.2 ReplicationControllers + +컨테이너가 죽으면 liveness probe 등을 이용하여 다시 재시작하면 된다. 이 작업은 pod 가 존재하고 있는 노드의 Kubelet 이 해준다. 그런데 만약 노드가 죽으면? Control Plane 이 직접 나서서 죽어버린 pod 를 다시 살려야 한다. + +다만 직접 만든 pod 에 대해서는 다시 살릴 수 없다. 직접 만든 pod 에는 Control Plane 이 관여하지 않고, 노드에 있는 Kubelet 혼자서 관리하고 있기 때문에, 노드가 죽어서 Kubelet 이 사라지면 되살릴 방법이 없어진다. + +노드가 죽은 경우에도 다른 노드에서 pod 가 시작되게 하려면, ReplicationController 와 같은 쿠버네티스 리소스를 사용해야 한다. + +**근데 docs 보면 다음과 같은 내용이 있다!!!** + +> Note: A Deployment that configures a ReplicaSet is now the recommended way to set up replication. + +**ReplicationController** 는 pod 가 동작하고 있는지 확인하고, pod 의 복제본 개수를 정확하게 관리해준다. + +### 4.2.1 The operation of a ReplicationController + +ReplicationController 는 현재 실행 중인 (정상 작동 중인) pod 의 목록을 확인하여 특정 'type' 의 pod 개수가 일정하도록 관리해준다. 만약 pod 개수가 너무 적으면 pod 를 더 띄우고, 너무 많으면 pod 를 삭제한다. + +#### Pod 의 개수가 안 맞는 경우 + +- `kubectl` 등 커맨드로 직접 같은 pod 를 하나 더 생성하는 경우 +- 존재하는 pod 에서 'type' 을 변경하는 경우 +- ReplicationController 에서 필요한 pod 개수를 변경하는 경우 + +여기서 'type' 이라 함은 pod 들의 부분집합을 말하는데, label selector 를 사용하여 얻은 부분집합이다. + +동작 방식은 간단하다. 정해진 label selector 에 맞는 pod 의 개수를 확인하여 정해진 만큼 있으면 아무 것도 하지 않는다. Pod 개수가 적거나 많으면 더 만들거나 삭제한다. + +#### Three parts of a ReplicationController + +- *label selector*: ReplicationController 의 scope (관리할 pod 들) 를 결정할 label +- *replica count*: 필요한 pod 의 개수를 정함 +- *pod template*: 새로운 pod 를 만들 때 사용할 template + +이 세 가지는 ReplicationController 가 실행된 이후에도 수정이 가능하지만, replica count 를 수정하면 현재 실행 중인 pod 에 영향을 미치게 된다. + +Label selector 를 고치게 되면 ReplicationController 의 scope 에서 pod 이 빠지게 된다. (근데 그러면 변경된 label selector 에 따라서 새로운 pod 들이 scope 에 들어오게 되면 existing pod 에 영향을 주는 것 아닌가?) + +#### 궁금해서 테스트 해봤다. + +- 우선 `app=kubia` label 이 달린 pod 3개를 생성하고, ReplicationController 를 만들어 `app=kubia2` label 을 가진 pod 를 2개 생성 +- ReplicationController 에서 `template` 의 `label` 을 `app=kubia` 로 변경 +- `kubectl apply -f` 를 이용해서 존재하는 object 를 수정 (`create` 쓰면 삭제되고 다시 만드니까) +- 에러가 뜨며 수정이 불가능 +- 한번 ReplicationController 를 생성할 때 `selector` 가 정해졌는데, `template` 의 `label` 을 바꾸면 `selector` 와 값이 달라지게 되므로 에러 +- 그럼 ReplicationController YAML 에서 `selector` 도 `app=kubia` 로 명시적으로 적기 (앞에서는 안적었음) +- 다시 `kubectl apply -f` 를 하니 적용이 됐고, `app=kubia` 가 달려있던 pod 3개 중 하나가 `Terminating` 으로 변경됨 +- 그러면 existing pod 에 영향을 주는 것 같으니 책의 의도는 "기존 scope 에 있던 existing pod" 에 영향을 주지 않는 다는 말인 듯 (;;) + +그리고 ReplicationController 는 pod 를 생성하고 나면 pod 의 내용 (컨테이너 이미지, 환경 변수 등) 은 신경쓰지 않기 때문에 pod template 을 수정해도 기존 pod 에는 영향을 주지 않는다. + +#### ReplicationController 의 장점 + +- 실행 중인 pod 의 개수를 일정하게 유지해준다. +- 클러스터 노드가 죽는 경우, 노드 안에 있던 pod 중 ReplicationController 의 scope 안에 있는 pod 를 살려내 준다. +- Scale out 을 쉽게 해준다. + +### 4.2.2 ReplicationController 만들기 + +```yaml +apiVersion: v1 +kind: ReplicationController +metadata: + name: sung-rc +spec: + replicas: 3 # 복제본 3개 + selector: # label selector + app: kubia + template: # pod template + metadata: + labels: + app: kubia + spec: + containers: + - name: sung + image: luksa/kubia + ports: + - containerPort: 8080 +``` + +`selector` 를 명시할 필요는 없다. `template` 의 `label` 을 보고 자동으로 뽑아준다. (`selector` 의 label 이 `spec` 의 `label` 과 달라서 컨테이너가 무한히 생성되는 문제를 막기 위해서 이를 검사한다) + +### 4.2.3 Seeing the ReplicationController in action + +컨테이너를 하나 삭제해 보면 즉시 새로운 컨테이너가 하나 생기는 모습을 확인할 수 있다. + +**동작 방식**: ReplicationController 는 scope 내의 pod 가 삭제되면 삭제된 사실을 알게 된다. 그러면 ReplicationController 는 pod 의 개수가 적절한지 확인하게 되고, 만약 적절하지 않으면 적당한 행동을 취해 pod 수를 조정한다. + +`kubectl get rc` 를 하면 ReplicationController 별로 `DESIRED`, `CURRENT`, `READY` 컨테이너 수를 확인할 수 있다. + +(노드를 죽이는 실습은 생략) + +### 4.2.4 ReplicationController 의 scope 조절하기 + +ReplicationController 가 생성한 pod 은 ReplicationController 와 직접 연결되어 있지 않다. 단지 ReplicationController 는 label selector 에 맞는 pod 들을 관리할 뿐이다. 그러므로 pod 의 label 을 변경하게 되면 scope 에 들어가거나 나갈 수 있다. + +Label 을 변경해서 scope 에서 나가게 되면 ReplicationController 를 사용하지 않고 만들어진 pod 과 다를 바가 없게 된다. 노드가 죽으면 끝이다. 또한 pod 를 관리하고 있던 ReplicationController 를 삭제하면 scope 를 벗어난 pod 는 제거되지 않는다. + +#### ReplicationController 의 label selector 수정하기 + +(아 혼자 테스트 해봤는데 내용이 책에 있었네) + +ReplicationController 의 label selector 를 수정하게 되면 기존 scope 에 있던 pod 들은 모두 scope 에 포함되지 않게 되며, 새로운 label selector 를 이용해 조회한 pod 목록을 보고 ReplicationController 는 적절한 동작을 취한다. + +### 4.2.5 Pod template 수정하기 + +Template 이 바뀐다고 해서 기존에 scope 에 있던 pod 들이 갑자기 사라지거나 하지는 않으므로, 기존 pod 를 하나 지우게 되면 ReplicationController 가 새로 pod 생성할 때 변경된 template 으로 생성한다. + +### 4.2.6 Horizontal scaling + +```bash +$ kubectl scale rc --replicas= +``` + +혹은 + +```bash +$ kubectl edit rc +``` + +으로 YAML 파일을 직접 수정하여 scaling 을 할 수 있다. 개수만 바꿔주면 나머지는 ReplicationController 가 알아서 한다. + +### 4.2.7 ReplicationController 삭제하기 + +`kubectl delete` 를 사용하면 scope 내의 pod 도 같이 지워진다! 단 `--cascade=false` 옵션을 주면 ReplicationController 만 지워지고 pod 는 남아있게 된다. + +Pod 가 관리되지 않은 채로 남아있다고 하더라도, 다시 ReplicationController 를 생성해서 얼마든지 다시 관리할 수 있다. + +## 4.3 ReplicaSet + +ReplicationControllers will eventually be deprecated! + +보통 ReplicaSet 은 Deployment 를 생성할 때 자동으로 만들어진다. + +### 4.3.1 ReplicaSet 과 ReplicationController 비교 + +ReplicaSet 의 pod selector 가 표현력이 훨씬 강하다. ReplicationController 는 특정 label 을 포함하는지만 검사가 가능하지만, ReplicaSet 의 경우 label 이 없는지, 혹은 특정 label key 를 갖는지 검사할 수 있다. + +### 4.3.2 ReplicaSet 정의하기 + +```yaml +apiVersion: apps/v1 # apps API group 에 있다 +kind: ReplicaSet +metadata: + name: sung +spec: + replicas: 3 + selector: # 이 부분만 다르다 + matchLabels: + app: sung + template: # ReplicationController 와 동일 + metadata: + labels: + app: sung + spec: + containers: + - name: sung + image: luksa/kubia +``` + +### 4.3.3 Creating and examining a ReplicaSet + +`kubectl get rs` 로 ReplicaSet 의 목록을 확인할 수 있다. + +### 4.3.4 More expressive label selectors + +`matchLabels` 는 ReplicationController 의 label selector 와 동일하다. + +`matchExpressions` property 를 이용해서 더욱 복잡한 label selector 를 이용할 수 있다. + +```yaml +selector: + matchExpressions: + - key: app + operator: In + values: + - sung +``` + +각 expression 에는 세 가지 값이 필요하다. `key`, `operator`, `values` (optional). + +- `key`: label 의 key 값 +- `operator`: 네 개가 있다. + - `In`: label 의 value 가 `values` 안에 있는지 검사 + - `NotIn`: label 의 value 가 `values` 안에 없는지 검사 + - `Exists`: `key` 를 갖고 있는지 검사 (`values` 옵션 불필요) + - `DoesNotExist`: `key` 를 갖고 있지 않은지 검사 (`values` 옵션 불필요) + +여러 개의 expression 을 사용하면 모든 expression 을 만족해야 pod 가 선택된다. + +### 4.3.5 ReplicaSet 정리 + +항상 ReplicationController 대신 ReplicaSet 을 사용해라! + +## 4.4 DaemonSet 을 이용하여 한 노드에 pod 하나씩 실행하기 + +ReplicationController 나 ReplicaSet 을 사용하면 클러스터 내의 임의의 노드에서 실행하게 되는데, 각 노드마다 하나씩 존재해야 하는 앱이 있을 수도 있다. (한 노드가 여유롭다고 몰리면 안된다) 대표적으로 노드의 리소스를 확인하거나 노드의 로그를 확인하고 싶은 경우가 그렇다. + +쿠버네티스를 사용하지 않는다면 system init script 나 systemd 를 사용할 것이고, 노드에서 이것들을 사용할 수 있긴 하지만, 쿠버네티스의 장점은 누릴 수 없게 된다. + +### 4.4.1 DaemonSet 으로 모든 노드에 pod 띄우기 + +ReplicaSet 과 거의 비슷하지만 DaemonSet 을 사용하면 Kubernetes Scheduler 의 통제를 받지 않게된다. DaemonSet 은 노드 개수 만큼 pod 을 만들며, 각 노드마다 pod 를 하나씩 올린다. + +DaemonSet 은 replica count 의 개념이 없으며, 단지 모든 노드에 pod 가 하나씩 동작하고 있는지만 관리한다. 그러므로 노드가 죽으면 아무 일도 하지 않고, 노드가 새로 생길 때는 바로 pod 를 하나 더 띄워준다. + +### 4.4.2 DaemonSet 으로 특정 노드에 pod 띄우기 + +Node selector property 를 이용하면 모든 노드가 아니라 특정 노드에만 pod 를 띄울 수 있게 된다. + +주의사항: 노드는 unschedulable 상태로 만들 수 있는데, DaemonSet 은 이런 상태를 무시하고 pod 를 띄운다. 이 unschedulable property 는 scheduler 가 이용하는데, DaemonSet 은 scheduler 의 영향을 받지 않기 때문이다. 더불어 이 동작은 의도된 것이다. DaemonSet 은 시스템과 관련된 서비스를 운영할 때 사용하므로 unschedulable node 에도 pod 를 띄워야 한다. + +YAML 파일은 ReplicaSet 과 거의 동일한데, node selector 를 사용한다는 차이점이 있다. + +```yaml +template: + ... + spec: + nodeSelctor: # node selector 를 사용한다. + disk: ssd +``` + +## 4.5 Running pods that perform a single completable task + +여기서 single completable task 란, 동작을 모두 마치면 종료하는 작업을 말하는 것이다. (기존에는 서버와 같이 계속 실행 중이어야 하는 프로세스를 다뤄왔다. 이 프로세스들은 완료 - 'completed' 의 개념이 없다) + +### 4.5.1 Job 리소스 + +Job 리소스를 사용하면 작업이 완료된 뒤에 재시작 되지 않는 pod 를 만들 수 있게 된다. + +만약 노드가 죽는 경우에는 다른 노드로 다시 스케줄링 되며, 만약 컨테이너의 프로세스가 문제가 생긴 경우 컨테이너를 재시작할지 그냥 종료할지 선택할 수 있다. + +Job 은 정상적으로 종료되어야 하는 task 에 사용하는 것이 좋다. 쿠버네티스나 Job 을 사용하지 않고도 작업을 할 수 있겠지만, 쿠버네티스를 사용하면 노드가 죽거나 에러가 생기는 경우에 쿠버네티스의 기능을 활용하여 작업이 정상적으로 완료될 때까지 다시 실행할 수 있게 된다. + +### 4.5.2 Job 리소스 정의하기 + +```yaml +apiVersion: batch/v1 +kind: Job +metadata: + name: batch-job +spec: + template: + metadata: + labels: + app: batch-job + spec: + restartPolicy: OnFailure # 문제가 생겼을 때 어떻게 할지 + containers: + - name: main + image: luksa/batch-job +``` + +`restartPolicy` 는 일반적으로 `Always` 이다. 하지만 Job 리소스를 만들 때 이 값을 사용할 수는 없고, `OnFailure` 혹은 `Never` 를 사용하게 된다. (계속 실행할 거면 Job 을 쓰지 말자) 이 옵션 값을 사용하므로 작업이 완료된 뒤 컨테이너가 재시작되지 않는다. + +### 4.5.3 Seeing a Job run a pod + +Job 을 생성한 뒤 완료되면 pod 의 상태가 `Completed` 로 변경되고, 삭제되지 않은 채로 남아있다. 실행 결과 로그를 확인할 수 있게 하기 위해서이다. 단, Job 을 삭제하면 pod 도 같이 삭제된다. + +### 4.5.4 Running multiple pod instances in a job + +Job 은 꼭 하나의 pod 만 생성해야 하는 것은 아니다. 순차적 실행, 병렬 실행도 가능하다. + +#### 순차적 실행 + +```yaml +... +spec: + completions: 5 # 5번 완료되어야 Job 이 완전히 끝난다 +``` + +`completions` 옵션을 사용하면 지정된 횟수만큼 pod 을 만들어서 작업을 수행한다. 한 번에 pod 하나씩 만들어서 작업을 수행하지만 중간에 작업이 실패하는 경우가 있을 수도 있으므로 총 생성하는 pod 개수는 지정된 값보다 많을 수 있다. + +(연속으로 성공해야 하는지? 2개 완료하고 죽으면 처음부터 다시하나? 맥락 상 처음부터 다시 하지는 않을 것 같은데 - 찾아보기) + +#### 병렬 실행 + +```yaml +... +spec: + completions: 5 + parallelism: 2 # 한 번에 만들 pod 개수 +``` + +`parallelism` 옵션을 사용하면 작업을 동시에 실행할 pod 개수를 설정할 수 있다. 여러 개 중 어느 하나라도 완료되면 바로 다음 pod 를 생성하여 `completions` 횟수만큼 작업을 완료한다. 이 값은 Job 이 실행 중일 때도 변경 가능하다. + +```bash +$ kubectl scale job --replicas +``` + +### 4.5.5 Job pod 에 제한 시간 걸기 + +작업이 끝날 때까지 얼마나 기다려야 할지 정할 수 있다. 중간에 무한 루프에 빠지는 등 멈출 수도 있다. + +`.spec.activeDeadlineSeconds` 옵션을 이용하면 지정된 시간 만큼 작업을 실행해보고, 시간이 지나도 완료되지 않으면 실패 처리한다. + +더불어 `.spec.backoffLimit` 옵션을 사용하면 최대 몇 번까지 작업을 재시도할지 설정할 수 있다. 다만 `activeDeadlineSeconds` 가 더 우선 순위가 높아 시간이 초과되면 재시도 횟수가 남아도 그냥 실패 처리한다. + +## 4.6 Scheduling Jobs to run periodically or once in the future + +### 4.6.1 CronJob 만들기 + +(얘는 아직 API가 beta 네...) + +```yaml +apiVersion: batch/v1beta1 +kind: CronJob +metadata: + name: batch-job-15m +spec: + schedule: "0,15,30,45 * * * *" # 15분마다 실행하기 + jobTemplate: + spec: + template: + metadata: + labels: + app: periodic-batch-job + spec: + restartPolicy: OnFailure + containers: + - name: main + image: luksa/batch-job +``` + +### 4.6.2 Understanding how scheduled jobs are run + +대략 Job 을 실행할 시간대가 되면 CronJob 이 Job 리소스를 생성하고, Job 이 pod 를 만들어서 작업을 실행한다. +이 생성 작업이 조금 걸릴 수도 있으므로, `.spec.startingDeadlineSeconds` 옵션을 설정하여 정해진 시간으로부터 늦어도 몇 초 이내에 작업이 실행되어야 하는지 설정할 수 있다. + +만약에 정해진 시간이 지나도 실행하지 못했다면 자동으로 실패처리 된다. + +CronJob 은 보통 1회 실행 시 Job 를 하나 만들지만, 2개 이상이 생성될 수도 있으므로, idempotency 를 가지고 있어야 한다. 여러 번 실행해도 같은 결과를 보장해야 한다. 또한 직전에 실패한 경우가 있다면 다음 Job 은 직전에 실패한 것까지 고려해야할 수도 있다. + +--- + +## Discussion & Additional Topics + +### Actual examples on usage of DaemonSets + +### More about unix signals + +- https://jhnyang.tistory.com/143 + +### More about exit codes + +### Docker also has restart policy + +- https://docs.docker.com/config/containers/start-containers-automatically/ + +### What happens when the Kubernetes master plane fails? + +- https://stackoverflow.com/questions/39172131/what-happens-when-the-kubernetes-master-fails + +### Can a single pod be controlled by two ReplicaSets? + +- 만약 레이블이 2개인 pod 이 하나가 있고 그 이후에 ReplicaSet 을 만든다면...? + +### Pod garbage collector? + +- https://kubernetes.io/ko/docs/concepts/workloads/controllers/garbage-collection/ diff --git a/_posts/Development/Kubernetes/2021-04-07-05-services.md b/_posts/Development/Kubernetes/2021-04-07-05-services.md new file mode 100644 index 0000000..e700683 --- /dev/null +++ b/_posts/Development/Kubernetes/2021-04-07-05-services.md @@ -0,0 +1,470 @@ +--- +share: true +toc: true +categories: [Development, Kubernetes] +tags: [kubernetes, sre, devops] +title: "05. Services: Enabling Clients to Discover and Talk to Pods" +date: "2021-04-07" +github_title: "2021-04-07-05-services" +image: + path: /assets/img/posts/k8s-05.jpeg +--- + +![k8s-05.jpeg](../../../assets/img/posts/k8s-05.jpeg) _Using `kubectl exec` to test out a connection to the service by running curl in one of the pods. (출처: https://livebook.manning.com/book/kubernetes-in-action/chapter-5)_ + +많은 앱들이 request (요청) 을 받아 서비스를 제공하는 형태인데, 이런 요청을 보내려면 IP 주소를 알아야 한다. 한편 Kubernetes 를 사용하게 되면 pod 의 IP 주소를 알아야 하는데, Kubernetes 의 pod 들은 굉장히 동적이므로 이들의 IP 주소를 알아낼 방법이 필요하다. + +Pod 들은 스케쥴링 되고 스케일링 되기 때문에 IP 주소가 자주 바뀔 수 있으며, pod 가 시작된 후 IP 주소가 할당될 뿐만 아니라, 하나의 서비스를 위해 pod 를 여러 개 사용하는 경우 하나의 IP 를 사용하여 여러 개의 pod 에 접근할 방법이 필요하다. (쿠버네티스를 사용하지 않으면 고정 IP 등을 사용하거나 따로 설정된 주소로 요청이 가도록 했을 것이다) + +## 5.1 Services 소개 + +Service 를 이용하면 같은 일을 하는 여러 개의 pod 에 하나의 entrypoint 를 제공할 수 있다. + +Service 는 IP 와 포트가 설정되어 있고 (service 가 살아있는 동안) 고정되어 있다. 자신의 주소로 요청이 들어오면 연결된 pod 중 하나로 요청을 보내준다. (로드 밸런싱도 가능) + +### 5.1.1 Service 만들기 + +Service 에 포함되는 pod 를 정의하기 위해서는 **label selector** 를 사용한다. + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: sung +spec: + ports: + - port: 80 + targetPort: 8080 + selector: + app: kubia +``` + +Service 가 실행했을 때 할당되는 IP 주소의 80 포트로 들어오는 요청은 `app=kubia` label 을 가진 pod 의 8080 포트로 요청이 전달된다. + +`kubectl create` 로 service 를 생성한 후, `kubectl get svc` 를 하면 service 목록을 확인할 수 있다. Column 중에 `CLUSTER-IP` 가 있는데 이는 클러스터 내부에서 사용하는 IP 주소이다. (`EXTERNAL-IP` 는 외부에서 사용하는 주소인데 일단은 `` 이다.) + +원래 service 의 주 목적은 클러스터 내의 pod 들을 다른 pod 들에게 보여주는 것이므로 cluster IP 가 존재한다. (프론트, 백 각각 service 로 만들어 두면 프론트에서 백엔드 service 에 접근할 수 있어야 한다) 하지만 주로 클러스터 외부로 expose 하는 경우가 더 많을 것이다. + +#### Session affinity + +4장에서 사용한 ReplicationController 를 생성하고 service 를 만든 뒤 service 의 주소로 `curl` 을 날려보면 항상 같은 pod 가 요청을 처리하지는 않는다는 것을 확인할 수 있다. 만약에 같은 client 의 요청은 같은 pod 에서 처리하고 싶다면 `.spec.sessionAffinity` 를 설정하면 된다. + +Service 의 `sessionAffinity` 는 `None` 과 `ClientIP` 만 지정할 수 있다. `ClientIP` 로 지정하게 되면 같은 client 의 요청은 하나의 pod 에서 무조건 처리하게 된다. + +Cookie 를 사용한 affinity 설정은 불가능하다. Service 가 애초에 TCP/UDP 레벨 (transport layer)에 있어서 Cookie 가 있는 HTTP 레벨 (application layer) 과 다르다. + +#### 여러 개의 포트 개방 + +여러 개의 포트를 개방하여 pod 의 포트로 redirect 시킬 수 있다. 다만 각 포트에 해당하는 이름을 설정해줘야 한다. + +```yaml +... +spec: + ports: + - name: http # 이름을 지정해줘야 한다 + port: 80 + targetPort: 8080 + - name: https + port: 443 + targetPort: 8443 + selector: + app: kubia +``` + +또한 label selector 는 포트마다 다르게 설정할 수 없다. 포트마다 다른 label selector 를 사용하고 싶다면 service 를 여러 개 만들어야 한다. + +#### 포트에 이름 붙이기 + +애플리케이션이 복잡해지면 포트를 변경할 일이 생길 수도 있다. 포트 번호를 단순히 숫자로 관리하면 나중에 pod 레벨에서 port 가 변경되었을 때 이를 참조하는 모든 쿠버네티스 오브젝트의 spec 에서 포트 번호를 변경해야 할 수도 있다. 그래서 pod 정의시 포트에 이름을 붙일 수 있다. + +```yaml +kind: Pod +spec: + containers: + - name: kubia + ports: + - name: http # 포트에 이름 붙이기 + containerPort: 8080 + - name: https + containerPort: 8443 +``` + +Service 의 YAML 파일에서는 아래와 같이 사용하면 된다. + +```yaml +kind: Service +spec: + ports: + - name: http + port: 80 + targetPort: http + - name: https + port: 443 + targetPort: https +``` + +Service 는 label selector 에 match 된 pod 중 임의의 한 pod 에 요청을 보낼텐데, 그 pod 의 정의에 포트 이름이 정의되어 있으면 그 포트 번호로 요청을 보내는 듯하다. + +그러므로 이런 것도 가능하다. 예전에 만든 pod 에는 8080 포트에 이름 `http` 가 있었는데, 새로 만든 pod 에는 80 포트에 `http` 를 붙여놓았다면, (같은 일을 하는 pod 라고 하자) service 에서는 `http` 라는 이름만 이용해서 pod 에게 요청을 전달하므로 실제 포트 번호는 다르게 설정할 수도 있다. + +### 5.1.2 Discovering services + +Service 또한 pod 처럼 생성이 되어야 IP 주소가 할당되므로, pod 와 같은 문제를 갖고있다. Service 를 생성하고 그 IP 를 pod 에 하드코딩 하는 것도 바람직하지는 않아 보인다. + +특정 service 가 필요한 pod 들에게 service 의 IP 주소를 알려줄 방법이 필요하다. + +#### 환경 변수 사용 + +쿠버네티스는 pod 가 생성될 때 현재 존재하고 있는 각 service 를 가리키는 환경 변수를 설정한다. + +그래서 service 를 먼저 만들고 이를 필요로 하는 pod 를 생성하면 환경 변수에서 service 의 IP 주소를 알 수 있다. + +단, 이렇게 하면 의존성이 생기고, 쿠버네티스 리소스를 띄워야 하는 순서가 생겨버린다. + +#### DNS, FQDN + +쿠버네티스에도 DNS 서버가 있어서, 각 service 는 내부 DNS 서버에 등록된다. 그래서 pod 가 만약 service 의 이름을 알면 FQDN 을 이용해서 접근할 수 있게 된다. + +FQDN 은 대략 이런 모양이다. + +``` +..svc.cluster.local +``` + +단, 이렇게 하더라도 service 가 listen 하고있는 포트는 알아야 한다. (이건 IP 주소 알아내는 것보다는 쉬울 듯) + +만약 namespace 가 같다면, service 의 이름만 가지고서도 접근이 가능하다! + +#### Service IP 로 `ping` 이 불가능한 이유 + +`curl` 은 되지만 `ping` 은 안되는 이유는 cluster IP 가 virtual IP 라서 포트와 결합되었을 때 의미를 갖기 때문이다. + +정확히는, `ping` 명령어는 ICMP 위에서 동작한다. 그런데 service 의 클러스터 내부에서 특정 포트만 사용하기 때문에 ICMP request 에 응답하지 않으므로 `ping` 이 불가능하다. + +## 5.2 클러스터 외부의 service 에 접속하기 + +### 5.2.1 Service endpoints + +Service 와 pod 은 직접 연결되지 않고 사이에 endpoints 라는 리소스가 있다. `kubectl describe svc ` 을 실행해보면 `Endpoints: ...` 라면서 IP 주소와 포트가 나열되어있는 것을 확인할 수 있다. + +Pod selector 가 YAML 파일에 정의되어 있기는 하지만, 실제로 service 가 요청을 처리할 때는 pod selector 를 사용하지 않고 이 endpoints 에 있는 값들을 사용한다. Selector 는 endpoints 의 값들을 만들 때 사용한다. + +그럼 endpoints 의 값들은 언제 갱신하는데? Pod 이 생길 때마다? -> 계속 읽어보니 readiness probe 가 성공했을 때 추가된다고 한다. + +### 5.2.2 Service endpoints 직접 설정하기 + +Pod selector 가 없는 service 를 만들면 endpoints 가 설정되지 않는다. + +Endpoints 리소스를 직접 만들어서 service 에 갖다 붙일 수 있다. 다만 만들어진 endpoints 리소스의 이름은 service 의 이름과 동일해야 한다. + +이 방법을 이용하면 외부의 서버 등에 연결할 수 있는 service 를 하나 만들어두고 pod 들이 외부 서버에 접속할 때 해당 service 로 요청을 보내도록 할 수 있다. (로드 밸런싱은 덤) + +Label selector 를 지정하면 endpoints 가 자동으로 관리되고, label selector 를 제거하면 endpoints 의 갱신은 멈춘다. + +### 5.2.3 외부의 서비스 alias 설정 + +외부 서비스의 FQDN 을 이용해서 접근할 수 있다. Service 오브젝트를 생성할 때 `.spec.type` 를 `ExternalName` 으로 설정하면 된다. 이렇게 하면 외부 서비스의 FQDN 을 직접 이용하지 않고 service 를 경유하여 사용할 수 있게 된다. 나중에 외부 서비스를 교체할 일이 생길 때 훨씬 수월하게 교체할 수 있게 된다. + +`ExternalName` service 들은 DNS 레벨에서 구현되어 있어서 `CNAME` record 가 생성된다. 이 service 에 접속을 시도하는 client 들은 외부 서비스에 직접 접속하며, service 에는 IP 가 할당 되지 않는다. + +## 5.3 Service 를 외부에 공개하기 + +프론트엔드의 경우 외부로 공개할 필요가 있다. 공개하는 방법에는 세 가지 방법이 있다. + +- Service 타입 `NodePort` 로 설정하기: 클러스터의 *각* 노드가 한 포트를 개방한다. 개방된 포트로 들어오는 요청은 해당 service 로 redirect 된다. 특정 노드에 구애받지 않고, 모든 노드의 해당 포트로 들어오는 요청이 redirect 된다. +- Service 타입 `LoadBalancer` 로 설정하기: 해당 service 를 위한 load balancer 의 IP 주소를 통해서 service 에 접근할 수 있도록 한다. (Cloud infrastructure 에서 관리) +- Ingress 리소스 만들기: HTTP level 에서 동작한다. 5.4 에서 설명한다. + +### 5.3.1 NodePort service + +`NodePort` service 를 생성하면 모든 노드의 한 포트가 reserve 된다. 해당 포트로 들어오는 요청은 모두 service 로 연결된다. + +일반적인 service 와 크게 다르지 않지만, cluster IP 뿐만 아니라 임의의 노드 IP 와 포트를 통해서도 접근이 가능하다. + +#### NodePort service 생성 + +```yaml +... +spec: + type: NodePort + ports: + - port: 80 + targetPort: 8080 + nodePort: 30123 # 노드의 포트를 개방하도록 설정 +``` + +개방할 포트를 안적으면 random 하게 선택되며, GKE 의 경우 방화벽 설정을 해야한다. + +모든 노드의 IP 주소로부터 접근이 가능하지만, 만약 어떤 client 가 무조건 한 노드의 IP 로만 접근하는데 해당 노드가 죽는 경우에는 접근이 불가능해진다. 따라서 load balancer 를 사용하는 방법이 더 바람직하다. + +### 5.3.2 Exposing a service through an external load balancer + +Service 타입을 `LoadBalancer` 로 설정하면 된다. 다만 cloud infrastructure 단에서 load balancer 를 지원해줘야 한다. 만약 지원해주지 않는다면 `NodePort` service 와 동일하게 동작한다. (extension 이기 때문) + +`LoadBalancer` service 를 생성하게 되면 해당 service 에 external IP 가 설정되며, 해당 주소로 접근할 수 있다. + +`LoadBalancer` service 를 생성할 때도 `NodePort` service 가 그랬듯이 모든 노드에서 한 포트를 개방하게 되며, 로드 밸런싱을 거쳐 적절한 노드로 요청을 redirect 해준다. 또한 노드에서 한 포트가 개방되는 셈이므로, `kubectl describe` 를 이용하여 개방된 포트를 확인하고 방화벽 설정을 고쳐주면 `NodePort` service 처럼 노드의 IP 주소와 포트를 이용해 접근할 수 있다. + +### 5.3.3 Understanding the peculiarities of external connections + +#### Avoiding additional network hops + +`NodePort` service 를 이용하게 되면 요청을 받은 노드에 요청을 처리해줄 pod 이 존재하지 않을 수도 있다. 혹은 임의로 선택된 pod 가 해당 노드에 존재하지 않을 수도 있다. 이 때 해당 pod 이 존재하는 노드로 가야하기 때문에 추가 delay 가 생긴다. + +`.spec.externalTrafficPolicy` 를 `local` 로 설정하면 요청을 받은 노드 안에 있는 pod 로만 redirect 된다. 만약에 그런 pod 가 없으면 대기한다. 그러므로 쓰기 전에 노드에 pod 가 있음을 확신할 수 있어야 한다. + +위 옵션을 사용하면 더 이상 요청이 pod 별로 균등하게 분배되지 않는다. + +#### Non-preservation of the client's IP + +`NodePort` service 를 통해 외부에서 접근하게 되면 SNAT 로 인해 source IP 가 변경된다. (내부에서는 무관) 그런데 만약 애플리케이션이 source IP 를 필요로 한다면 문제가 될 수도 있다. + +## 5.4 Ingress resource + +### Ingress 가 필요한 이유 + +`LoadBalancer` service 는 각 service 마다 load balancer 를 생성하고, 공개 IP 주소가 필요하지만, Ingress 는 여러 개의 service 를 관리하는데도 하나의 IP 주소만 있어도 된다. HTTP 요청을 받을 때, host 와 path 를 보고 어느 service 로 redirect 해야하는지 알 수 있다. + +또한 application layer 에서 동작하기 때문에 service 가 제공하지 않는 기능들을 사용할 수 있다. + +(IP 주소 하나 쓰는 것만으로는 조금 부족해 보이는데 어떤 기능들이 있는지 확인해 봐야겠다.) + +더불어 Ingress 가 동작하려면 Ingress controller 가 동작하고 있어야 한다. + +### 5.4.1 Ingress 리소스 생성 + +```yaml +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: sung +spec: + rules: + - host: sung.example.com # 이 주소로 들어오는 요청은 서비스로 redirect + http: + paths: + - path: / + backend: + serviceName: sung + servicePort: 80 +``` + +Note. 위 처럼 생성하면 warning 이 발생한다. + +``` +Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress +``` + +### 5.4.2 Ingress 를 이용하여 service 접속 + +Domain name resolution 이 잘 되어야 한다! `kubectl get ingresses` 로 IP 를 확인할 수 있다. Ingress 에 입력한 `host` 값이 해당 IP 로 resolve 될 수 있도록 직접 설정해줘야 한다. `/etc/hosts` 를 쓰거나, DNS 서버를 직접 사용하거나... + +#### How does it work? + +1. Client 가 `sung.example.com` 의 IP 주소를 DNS 에서 찾아본다. +2. 받은 IP 주소에 HTTP 요청을 보낼 때 `Host: sung.example.com` 헤더를 넣어서 보낸다. +3. Ingress controller 는 어느 service 에 대한 요청인지 파악한다. +4. 해당 서비스의 endpoints 중 하나의 주소로 요청을 보낸다. + +유의하여 볼 점은 service 에게 요청을 전달하지 않고 직접 pod 를 선택했다는 점이다. + +### 5.4.3 하나의 Ingress 에 여러 service 연결하기 + +#### Mulitple paths + +```yaml +... +- host: sung.example.com + http: + paths: + - path: /sung # sung.example.com/sung + backend: + serviceName: sung + servicePort: 80 + - path: /foo # sung.example.com/foo + backend: + serviceName: bar + servicePort: 80 +``` + +각 path 별로 다른 service 를 사용하도록 설정할 수 있다. + +#### Multiple hosts + +`host` 를 여러 개 등록하면 `Host: ...` 헤더 값에 따라 다른 service 에 접근할 수 있다. DNS 에 `host` 값을 등록하는 것을 잊으면 안 된다. + +### 5.4.4 Configuring Ingress to handle TLS traffic + +HTTPS 요청을 처리하는 방법에 대해서 알아본다. + +#### TLS certificate for the Ingress + +Client 와 controller 사이의 통신은 암호화 되어있지만, controller 와 pod 사이의 통신은 암호화 되어있지 않다. 그러므로 pod 에서 돌아가는 앱은 TLS 를 지원할 필요는 없다. + +인증서와 private key 를 생성하여 Ingress 에 넣어주어야 한다. 원래는 Secret 이라는 쿠버네티스 리소스에 저장되지만 7장에서 자세히 살펴본다. + +```bash +$ openssl genrsa -out tls.key 2048 +$ openssl req -new -x509 -key tls.key -out tls.cert -days 360 -subj CN=sung.example.com + +# Create Secret +$ kubectl create secret tls tls-secret --cert=tls.cert --key=tls.key +``` + +이제 YAML 파일을 수정한다. + +```yaml +... +spec: + tls: + - hosts: + - sung.example.com + secretName: tls-secret + rules: +... +``` + +## 5.5 연결을 받을 준비가 되었을 때 신호 보내기 + +Service 나 Ingress 를 사용하면 pod 가 생성되자마자 요청이 전달될 수 있다. (label 만 검사하므로) 한편 startup 이 오래걸리는 애플리케이션의 경우 아직 pod 는 준비가 안되었는데 요청을 받게 되어 요청을 정상적으로 처리 못하게 될 수 있다. + +Pod 가 요청을 처리할 준비가 되었음을 확인할 방법이 필요하다. + +### 5.5.1 Readiness probes + +Readiness probe 는 주기적으로 실행되며, pod 가 client request 를 받을 준비가 되었는지 확인한다. + +종류는 liveness probe 와 마찬가지로 세 종류가 있다. + +- **HTTP GET probe**: 컨테이너 IP 주소에 GET 요청 보내보기 + - 응답 코드가 2xx, 3xx 이면 OK + - 이외의 에러 코드나 응답이 없으면 실패로 간주 +- **TCP socket probe**: 컨테이너의 정해진 포트에 TCP 연결을 시도해서 성공하면 준비된 것으로 판단 +- **Exec probe**: 컨테이너 안에서 임의의 명령을 실행하고 exit code 가 0 이면 준비된 것으로 판단 + +#### Understanding the operation of readiness probes + +- 첫 readiness probe 를 실행하기 전 얼만큼 기다릴지 미리 설정할 수 있다. 그 이후에는 주기적으로 실행한다. +- Ready 상태가 아니면 service 의 endpoints 에서 제거되고, 준비가 되면 추가된다. +- Liveness probe 는 실패하면 컨테이너를 재시작하지만, readiness probe 는 그렇지 않다. + +Pod 이 죽을 때 어떤 방식으로 endpoints 를 업데이트 하는지? -> 이게 아니고 readiness probe 가 실패해서 endpoints 가 업데이트 되는 듯 하다. + 삭제시 쿠버네티스가 알아서 업데이트 해준다. + +아무튼, readiness probe 는 client 들이 healthy pod 에만 요청을 할 수 있도록 관리해준다. + +### 5.5.2 Pod 에 readiness probe 추가하기 + +ReplicationController's pod template 를 수정하여 readiness probe 를 추가한다. 컨테이너별로 readiness probe 의 동작을 다르게 정할 수 있다. + +ReplicationController 의 pod template 을 수정하면 현재 존재하는 pod 에는 영향이 없으므로, 존재하는 pod 들은 삭제하고 새롭게 pod 를 띄우거나, ready 상태가 될 수 있도록 적절한 동작을 취해줘야 할 수도 있다. + +### 5.5.3 Readiness probe 가 해야할 일 + +- 항상 readiness probe 를 사용할 것 + +사용하지 않으면, pod 의 시작과 동시에 service endpoints 에 추가되므로, 요청을 처리하지 못할 것이다. + +- Don't include pod shutdown logic + +Shutdown 이 시작되었음을 감지하고 readiness probe 가 실패하도록 로직을 짤 필요는 없다. Pod 가 삭제되면 쿠버네티스가 자동으로 service endpoints 에서 제거한다. + +## 5.6 Headless service for discovering individual pods + +Client 가 모든 pod 에 접근해야 한다면? (어떤 경우에 이러한가? - 아래 Discussion 참고) + +DNS lookup 을 이용할 수 있다! 보통 service 를 위해 DNS lookup 을 하면 하나의 IP (service IP) 를 돌려주지만, service 에 cluster IP 가 필요없다고 설정하면, endpoints 에 있는 IP 들을 DNS `A` 레코드로 돌려준다. + +### 5.6.1 Headless service 생성 + +`.spec.clusterIP: None` 으로 설정하면 된다. + +### 5.6.2 Discovering pods through DNS + +`nslookup` 명령어로 확인하면 된다! + +#### YAML 없이 pod 띄우기 + +```bash +$ kubectl run --image= --generator=run-pod/v1 +``` + +진짜로 pod 만 만들어준다. ReplicationController, service 이런거 없이 만들어 준다. + +### 5.6.3 Discovering all pods - even those that aren't ready + +Service 에서 `publishNotReadyAddresses=True` 로 설정하면 된다. + +## 5.7 Troubleshooting + +순서대로 해보면 좋을 것이다! + +- Service cluster IP 를 사용하는 경우 클러스터 내에서 접속하고 있는지 확인하자. +- Service IP 에는 `ping` 이 동작하지 않는다. +- Readiness probe 를 설정했다면 성공하는지 꼭 확인해야 한다. 그렇지 않으면 pod 가 service 의 endpoints 에 등록되지 않는다. +- Pod 가 service 의 endpoints 에 등록되었는지 확인하려면 `kubectl get endpoints`. +- FQDN 으로 접속이 안되면, cluster IP 를 사용해서 되는지 확인해본다. +- Service 의 타겟 포트가 아니고 expose 한 포트로 접속하고 있는지 확인한다. +- Pod IP, 포트로 직접 접속하여 요청을 받는지 확인한다. +- 마지막으로, 앱이 localhost 에 바인딩 하지 않았는지 확인한다. + +11장에서 service 가 어떻게 구현되었는지 공부하면 디버깅이 더 쉬울 것이라고 한다 ... + +--- + +## Discussion & Additional Topics + +### When would you want to set sessionAffinity to `ClientIP` ? + +- 좋은 방법은 아니겠지만, session 정보를 저장해야 하는 경우가 그럴 것이다. 예를 들면 pod A, B 가 실행 중인데 처음에 A 로 접속해서 로그인했다고 하자. 그러면 다음 요청을 보낼 때 A 로 가게 되면 로그인 된 것으로 처리하지만, pod B 로 요청이 가게 되면 로그인하지 않은 상태일 것이다. +- 위와 같은 경우 로그인 상태를 캐싱하고 있는 서버를 별도로 두는 것이 좋다. Pod B 에서 캐싱 서버로 요청을 보내 사용자의 로그인 여부를 판단할 수 있게 될 것이다. + +### Current Ingress resource example + +- https://kubernetes.io/docs/concepts/services-networking/ingress/#the-ingress-resource + +### Why does Ingress controller select pods directly, and not pass the request to the service? + +### Pod 가 이미 에러나서 요청을 처리하지 못하지만 죽지는 않은 상태이다. 한편 readiness probe 가 아직 실행되지 않았으면 그 사이에 도착한 요청들은 다 망한건가? ㅋㅋ + +- 예. + +### 왜 pod 의 YAML 에서 설정하는 것이 아니고 rc 에서 하는 것일까? 현실에서는 어차피 복제될 pod 라 괜찮겠지만... + +- Pod 를 실제로 복제할 때 readiness probe 에 대한 정보도 필요하므로 rc 의 template 에 넣어야 맞을 것이다. + +### When would we actually use `publishNotReadyAddresses=True` ? + +- https://stackoverflow.com/questions/51098498/keep-a-kubernetes-pod-in-service-when-in-a-state-of-not-ready +- 뭔지 잘 모르겠다. + +### FQDN 사용 시 `cluster.local` 이 아닌 곳으로도 접근이 가능한 경우가 있을까? + +### FQDN + +- https://en.wikipedia.org/wiki/Fully_qualified_domain_name + +### DNS Records + +- https://en.wikipedia.org/wiki/List_of_DNS_record_types +- `dig` 명령어로 DNS record 조회 가능하다. + +#### 대표적인 records +- A record: 도메인에 IP 를 할당한다. +- CNAME record: Canonical NAME record 으로, 특정 도메인을 다른 도메인 이름으로 매핑한다. + +### Load Balancer 이야기 + +- https://d2.naver.com/helloworld/605418 + +### Client 가 여러 pod 에 동시에 연결하는 상황의 예시 + +- 동영상 스트리밍 할 때, 자연스럽게 화질을 전환하는 경우! +- 고화질, 중화질, 저화질 서버를 각각 pod 으로 만들어 둔 뒤, client 는 모든 pod 에 연결하고, 네트워크 상황에 따라 pod 을 바꿔가며 동영상을 스트리밍 하면 된다. + +### Can a single K8s pod host 2 or more K8s services? + +- https://stackoverflow.com/questions/46981184/kubernetes-can-a-single-k8s-pod-host-2-or-more-k8s-services/46984384#46984384 + +### JSONPath / XPath + +- https://kubernetes.io/docs/reference/kubectl/jsonpath/ diff --git a/_posts/Development/Kubernetes/2021-04-07-06-volumes.md b/_posts/Development/Kubernetes/2021-04-07-06-volumes.md new file mode 100644 index 0000000..721eeb2 --- /dev/null +++ b/_posts/Development/Kubernetes/2021-04-07-06-volumes.md @@ -0,0 +1,372 @@ +--- +share: true +toc: true +categories: [Development, Kubernetes] +tags: [kubernetes, sre, devops] +title: "06. Volumes: Attaching Disk Storage to Containers" +date: "2021-04-07" +github_title: "2021-04-07-06-volumes" +image: + path: /assets/img/posts/k8s-06.jpeg +--- + +![k8s-06.jpeg](../../../assets/img/posts/k8s-06.jpeg) _The complete picture of dynamic provisioning of PersistentVolumes. (출처: https://livebook.manning.com/book/kubernetes-in-action/chapter-6)_ + +컨테이너가 재시작되면 기존 작업 내역이 모두 사라지게 될 수 있으므로, 컨테이너의 작업 내역을 저장하고 같은 pod 내의 다른 컨테이너가 함께 사용하는 저장 공간이다. + +## 6.1 Introducing volumes + +Pod 의 한 구성 부분으로 pod spec 에 정의되어 있다. 또 standalone Kubernetes object 가 아니라서 독립적으로 생성되거나 삭제될 수 없다. + +Pod 내의 모든 컨테이너로부터 접근이 가능하지만, 그렇게 하려면 mount 해줘야 한다. + +### 6.1.1 Volume 예시 + +### 6.1.2 Available volume types + +종류가 굉장히 많은데, 다 알지는 않아도 괜찮다고 한다. + +#### Volume types + +- `emptyDir`: 빈 폴더로 일시적인 데이터 저장에 사용 +- `hostPath`: 노드의 파일 시스템에 있는 디렉토리를 사용할 때 +- `gitRepo`: Git repository 를 checkout 하여 사용 +- `nfs`: NFS share +- `gcePersistentDisk`, `awsElasticBlockStore`, `azureDisk`: 클라우드가 제공하는 스토리지 +- `configMap`, `secret` `downwardAPI`: 리소스나 클러스터 정보를 pod 에게 알려주기 위해 사용하는 volume +- `persistentVolumeClaim`: pre- or dynamically provisioned persistent storage + +## 6.2 Volume 을 이용한 컨테이너간 데이터 공유 + +### 6.2.1 `emptyDir` volume + +`emptyDir` volume 을 사용하면 빈 디렉토리로 시작한다. Pod 안의 컨테이너는 해당 디렉토리에 자유롭게 쓸 (write) 수 있다. 대신 pod 이 지워지면 volume 도 함께 지워지므로, 썼던 내용은 모두 사라진다. + +주로 컨테이너들 간에 파일을 공유할 때 유용한데, 한 컨테이너만 사용하는 경우에도 컨테이너가 일시적으로 디스크에 파일을 저장해야하는 경우에도 유용하게 사용할 수 있다. (sort operation on a large dataset that doesn't fit into memory) 더불어 어떤 경우에는 컨테이너의 파일시스템을 사용할 수 없는 (not writable) 경우도 있다. + +#### 생성하기 + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: fortune +spec: + containers: + - image: luksa/fortune + name: html-generator + volumeMounts: + - name: html + mountPath: /var/htdocs # 컨테이너 내의 /var/htdocs 에 mount + - image: nginx:alpine + name: web-server + volumeMounts: + - name: html + mountPath: /usr/share/nginx/html # 컨테이너 내의 해당 디렉토리에 mount + readOnly: true + ports: + - containerPort: 80 + protocol: TCP + volumes: + - name: html # 이 volume 을 두 컨테이너가 공유한다 + emptyDir: {} +``` + +`html-generator` 에서 생성한 파일을 volume 에 쓰면 `web-server` 가 내용을 읽고 서빙해준다. + +`emptyDir` 를 사용하면 실제 노드의 디스크에 volume 이 생성된다. 그래서 노드의 디스크 타입에 따라 성능이 달라질 수 있다. `.volumes.emptyDir` 에 `medium` 을 설정하게 되면 tmpfs 파일시스템 (메모리 위의 파일시스템) 을 사용할 수도 있다. + +```yaml +volumes: +- name: html + emptyDir: + medium: Memory +``` + +### 6.2.2 Git 레포를 사용하기 + +`gitRepo` volume 은 `emptyDir` volume 인데 시작할 때 git repository 의 내용이 채워진다. (컨테이너가 생성되기 전에) + +Git repository 가 업데이트 되더라도, volume 은 업데이트 되지 않는다. 단 pod 이 재시작 되는 등 volume 이 다시 생성되게 되면 repo 의 변경사항이 반영된다. 단점이 있다면, repo 에 push 해서 변경사항이 생길 때마다 restart 해야한다. + +#### 생성하기 + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: gitrepo-pod +spec: + containers: + - image: nginx:alpine + name: web-server + volumeMounts: + - name: html + mountPath: /usr/share/nginx/html + readOnly: true + ports: + - containerPort: 80 + protocol: TCP + volumes: + - name: html + gitRepo: + repository: https://github.com/luksa/kubia-website-example.git # 어떤 repo 를 사용할지 + revision: master # master branch 사용 + directory: . # volume 의 root 디렉토리에 clone +``` + +#### 자동 업데이트 + +Sidecar container 를 사용해서 자동으로 repo 와 동기화시킬 수 있다. + +> Sidecar container: Container that augments the operation of the main container of the pod + +Docker Hub 에서 `git sync` 를 검색하면 많은 이미지들이 나올 것이다. 해당 이미지를 YAML 에 추가해서 자동으로 sync 하도록 설정하고 pod 를 만들어주면 될 것이다. + +#### Private repository + +현재 private repository 는 clone 이 안 된다. `gitRepo` 옵션을 간단하게 유지하고 싶다고 한다. + +> Warning: The `gitRepo` volume type is deprecated. To provision a container with a git repo, mount an EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir into the Pod's container. + +(어쩐지, 위 예시 코드 작동 안하더라.) + +## 6.3 노드의 파일 시스템에 접근하기 + +보통 pod 들은 자신이 어떤 노드 위에서 돌아가고 있는지 알 필요가 없기 때문에 노드의 파일 시스템에 접근할 일이 없다. 하지만 시스템 레벨의 pod 들은 (DaemonSet 이라던가) 노드의 파일을 읽어야 하는 경우가 생길 수도 있다. 이런 경우에는 `hostPath` 볼륨을 사용한다. + +### 6.3.1 `hostPath` volume + +노드의 파일 시스템에 있는 한 파일이나 디렉토리를 매핑해준다. 같은 노드에 있는 pod 들이 같은 경로의 `hostPath` volume 을 사용하고 있다면 같은 파일을 보게 된다. + +`hostPath` volume 은 앞서 살펴본 `emptyDir`, `gitRepo` 와는 다르게 pod 이 지워진다고 해서 삭제되지는 않는다. (컨테이너가 디렉토리에 뭔가 write 했다면 그것이 노드에 남아있는 듯 하다. 다른 pod 이 같은 노드로 스케쥴링 되고 같은 경로로 mount 하면 작업하고 남은 것들을 확인할 수 있는 듯) + +그렇다고 해서 pod 들 간에 파일을 공유하는 목적으로 사용해서는 안 된다. 어느 노드에 스케쥴링 될지 알 수 없다. + +### 6.3.2 System pods that use `hostPath` volumes + +`kube-system` namespace 의 몇 pod 들에 대해 `kubectl describe` 를 해보면 `hostPath` volume 을 사용중인 것을 알 수 있다. 다른 pod 도 사용하고 있을 수도 있는데, 주로 자신의 데이터를 디렉토리에 쓰기보다는 노드의 정보를 가져와서 사용하기 위해 `hostPath` volume 을 사용한다. + +Single-node 클러스터에서는 `hostPath` volume 을 persistent storage 로 사용할 수 있다. (Minikube) 아무튼 multi-node 클러스터에서는 여러 pod 들 간에 데이터를 공유하거나 persistent storage 로 사용해서는 안된다. + +## 6.4 Persistent storage + +Pod 들 간에 데이터를 공유해야 한다면, 위에서 언급한 volume type 들은 사용할 수 없다. 클러스터 내의 임의의 노드에서 접근이 가능해야하기 때문에 NAS (network attached storage) 급의 저장장치가 필요하다. + +### 6.4.1 GCE Persistent Disk in a pod volume + +생략. + +GCE Persistent Disk 를 생성하고, 이를 mount 한 pod 에서 DB 에 뭔가 write 한 뒤, pod 를 삭제하고 재생성하여 find 해보면 존재한다는 내용이다. + +### 6.4.2 Other types of volumes with underlying persistent storage + +- AWS: `awsElasticBlockStore` +- Azure: `azureFile`, `azureDisk` + +굉장히 다양한 종류의 volume type 을 지원하긴 하는데, 이걸 모두 알 필요는 당연히 없다. 또한 infrastructure 와 관련된 저장소 타입에 대한 정보를 개발자가 알아야할 이유도 없다. Kubernetes 는 이런 정보를 추상화시키는 것이 목적이다. 특정 저장소 정보를 YAML 파일에 기록하게 되면 해당 클러스터의 하드웨어 인프라와 지나치게 연결되어, 다른 클러스터에서 돌아가지 않게 된다. 위에서 제시한 persistent volume 들은 하나의 방법이긴 하지만 최선은 아니다. + + +## 6.5 스토리지 기술과 pod 를 분리하기 + +개발자는 물리적 저장소에 대한 정보를 몰라야 한다! 그것은 클러스터 관리자가 할 일이다. + +### 6.5.1 PersistentVolumes and PersistentVolumeClaims + +개발자는 그저 저장소를 달라고 요청을 하고, 요청을 받았을 때 어떤 저장소를 줄지는 클러스터 관리자가 설정한다. + +이를 위해 PersistentVolume (PV) 과 PersistentVolumeClaim (PVC) 이라는 리소스가 생겨났다. + +개발자가 직접 저장소를 pod 에 mount 하는 것이 아니라, 클러스터 관리자가 실제 저장소를 만들어두고 쿠버네티스에 PersistentVolume 이라는 리소스로 등록해 두는 것이다. (이때 저장소의 크기와 권한을 설정할 수 있다) + +이제 클러스터의 사용자가 저장소가 필요하다면, PVC manifest 를 만들어서 최소 용량과 필요한 권한을 명시한다. 이 정보를 이용하여 쿠버네티스 API 에 요청하면 해당 정보에 맞는 PV 를 찾아 PVC 를 연결시켜준다. 이제 PVC 는 마치 pod 안에 mount 된 volume 처럼 사용할 수 있다. 그리고 PVC 가 지워지기 전까지 연결된 해당 PV 는 다른 PVC 가 사용할 수 없다. + +### 6.5.2 PersistentVolume 생성 + +```yaml +apiVersion: v1 +kind: PersistentVolume +metadata: + name: mongodb-pv +spec: + capacity: # 크기 + storage: 1Gi + accessModes: + - ReadWriteOnce # 하나의 PVC 만 읽거나 쓴다 + - ReadOnlyMany # 여러 PVC 가 읽기만 한다 + persistentVolumeReclaimPolicy: Retain # PVC 와 연결이 해제되면 지우거나 삭제하지 않고 유지한다 + hostPath: + path: /tmp/mongodb +``` + +크기와, 접근 방식, 그리고 reclaim 될 때의 동작, 그리고 실제 물리적인 저장소 정보 (위 예시에서는 `hostPath`) 를 명시해줘야 한다. + +참고로 PV 는 namespace 를 갖지 않는다. Cluster-level 리소스이다. 반면 PVC 는 namespace 를 갖는다. + +### 6.5.3 PersistentVolumeClaim 을 생성하여 PersistentVolume 연결하기 + +Pod 에서 직접 접속해서는 안되고, (혹시 가능할까 ㅋㅋ) claim 을 먼저 해야한다. 그런데 claim 은 pod 생성과 독립적인 과정이다. Pod 에 종속적인 작업이 된다면 pod 이 re-스케쥴링 되거나 재시작될 때 또 claim 을 해야한다. 애초에 목적이 *persistent* volume 을 만드는 것이므로 pod 생성과는 독립적인 것이 자연스럽다. 재시작 되어도 저장소는 그대로 있어야지! + +```yaml +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: mongodb-pvc +spec: + resources: + requests: + storage: 1Gi # 1GB 를 요청한다 + accessModes: # 연결할 PV 는 아래 옵션으로 접근이 가능해야 한다 + - ReadWriteOnce + storageClassName: "" # 추후 dynamic provisioning 에서 설명 +``` + +PVC 를 생성하면 적합한 PV 를 찾아 bind 해준다. PVC 에서 요청한 공간보다 PV 의 용량이 커야 하고, PVC 에서 요구한 `accessModes` 를 PV 또한 지원해야 한다. + +#### Access Modes + +- `RWO`: `ReadWriteOnce` +- `ROX`: `ReadOnlyMany` +- `RWX`: `ReadWriteMany` + +추가로, `Once` 와 `Many` 를 구분하는 기준은 *노드* 이다. Pod 의 개수가 아니다. + +### 6.5.4 Pod 안에서 PersistentVolumeClaim 사용하기 + +PV 를 직접 연결하지 말고, PVC 를 reference 하도록 한다. + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: mongodb +spec: + containers: + - image: mongo + name: mongodb + volumeMounts: + - name: mongodb-data + mountPath: /data/db + ports: + - containerPort: 27017 + protocol: TCP + volumes: + - name: mongodb-data + persistentVolumeClaim: + claimName: mongodb-pvc # PVC 의 이름 +``` + +### 6.5.5 PersistentVolume, PersistentVolumeClaim 의 장점 + +일단 개발자 입장에서는 개발자가 클러스터 환경에 대해 이해하고 있지 않아도 돼서 간편하다. 또한 PVC 를 만들기 위해 사용한 YAML 파일은 클러스터 환경과 관계없이 동작하게 되었다. 단지 PV 가 어떤 요구사항을 충족해야 하는지만 설명하면 된다. + +(PV 는 여전히 클러스터 환경에 영향을 받는 것 같은데 이는 어쩔 수 없는 것인가...) + +### 6.5.6 PersistentVolume 정리하고 재사용하기 + +Pod 과 PVC 를 지우고 `kubectl get pv` 를 해보면 `Released` 상태로 바뀐 것을 확인할 수 있다. 다시 PVC 를 생성하고 `kubectl get pv` 를 해보면 상태가 변하지 않았다. `kubectl get pvc` 를 해보면 `Pending` 상태인 것도 확인할 수 있다. + +이는 PV 를 한 번 사용한 뒤 클러스터 관리자가 해당 PV 를 정리할 기회를 주기 위해서이다. PV 는 namespace 에 종속되지 않기 때문에 다른 namespace 의 PVC 에서도 bind 요청을 보낼 수 있다. 하지만 PV 를 정리하지 않고 그냥 연결해주게 되면 전에 연결되었던 다른 namespace 의 pod 에서 작업했던 내용이 그대로 남아있을 것이다. (다른 namespace 면 분리하고 싶은 것이니 작업 내용이 보이지 않아야 한다) + +#### 수동으로 reclaim 하기 + +위와 같은 현상은 `persistentVolumeReclaimPolicy: Retain` 으로 설정했기 때문에 일어났다. 수동으로 reclaim 하려면 PV 를 지우고 다시 생성하는 방법밖에 없다고 한다. PV 안에 있던 파일은 꺼내올 수 있다. + +#### 자동으로 reclaim 하기 + +다른 reclaim policy 로는 `Recycle`, `Delete` 가 있다. `Recycle` 은 지우고 새로 만들어서 다른 PVC 가 사용할 수 있도록 한다. `Delete` 는 그냥 지워버린다. + +## 6.6 Dynamic provisioning of PersistentVolumes + +위에서 살펴본 방식대로 PVC 를 사용하는 것도 편하지만, 여전히 클러스터 관리자가 PV 를 생성해야한다는 점에서 불편하다. 쿠버네티스는 PV 의 dynamic provisioning 을 제공하여 스토리지를 자동으로 만들어준다. + +클러스터 관리자는 PV 를 만들지 않고 PV provisioner 를 만들어 두고, StorageClass object 를 여러 개 정의해둘 수 있다. 그러면 사용자는 어떤 타입의 PV 를 원하는지 설정할 수 있다. + +> StorageClass objects aren't namespaced! + +그러므로 관리자가 PV 를 여러 개 만들어 두지 않아도 되고, 한 두개 정도 StorageClass 를 정의해 두면 PVC 를 통해 요청이 들어올 때 쿠버네티스 시스템이 알아서 생성해준다. 이렇게 하면 PV 가 부족할 일은 없을 것이다. (하지만 저장 공간은 가득 찰 수도 있다) + +### 6.6.1 StorageClass 리소스로 이용 가능한 스토리지 종류 정의하기 + +```yaml +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: fast +provisioner: k8s.io/minikube-hostpath # volume plugin +parameters: + type: pd-ssd # provisioner 로 전달되는 parameter +``` + +PVC 가 StorageClass 에 요청을 할 때 어떤 provisioner 를 사용할지 설정할 수 있다. Provisioner plugin 마다 parameter 가 조금씩 다를 수 있다. + +### 6.6.2 PersistentVolumeClaim 에서 StorageClass 요청하기 + +```yaml +... +spec: + storageClassName: fast # StorageClass 이름 + resources: + requests: + storage: 100Mi + accessModes: + - ReadWriteOnce +``` + +StorageClass 를 명시할 수 있다. PVC 를 생성하면 StorageClass 가 PV 를 만들어 준다. 만약 존재하지 않는 StorageClass 를 입력하면 `ProvisioningFailed` 에러가 발생한다. + +#### StorageClass 사용법 이해하기 + +클러스터 관리자가 다양한 StorageClass 를 만들어둘 수 있다. 개발자는 그 중 적절한 StorageClass 를 골라서 사용하면 된다. + +PVC 를 설정할 때 StorageClass 의 이름으로 하기 때문에 클라우드 환경과 무관하게 해당 StorageClass 이름이 있다면 동작하게 된다. (portable!) + +(아무튼 StorageClass 는 수동으로 만들어야 하는 것인가) + +### 6.6.3 Dynamic provisioning without specifying a storage class + +`kubectl get sc` 를 해보면 `standard` 라는 이름을 가진 StorageClass 가 있는 것을 확인할 수 있다. PVC 를 생성할 때 `storageClassName` 값을 주지 않고 생성하면 기본값인 `standard` 를 이용하게 된다. + +그래서 위에서 `storageClassName: ""` 로 설정한 이유는 이렇게 empty string 을 넣어주지 않으면 `standard` StorageClass 를 이용하여 새로운 PV 를 만들기 때문이다. Empty string 을 넣어주면 bind 할 PV 를 이미 존재하는 PV 중에서 찾는다. + +#### Complete picture of dynamic provisioning + +정리하면, pod 에 persistent storage 를 붙이는 최고의 방법은 PVC (with or without StorageClass) 만 생성하는 것이다. 나머지는 dynamic provisioner 가 해결해준다. + +1. 클러스터 관리자가 PV provisioner 를 설정한다. +2. 관리자가 StorageClass 를 만들어 둔다. 그리고 필요하다면 하나를 기본값으로 설정한다. +3. 사용자는 (StorageClass 를 이용하여) PVC 을 생성한다. +4. K8s 가 해당 StorageClass 의 provisioner 에게 새로운 PV 를 만들 것을 요청한다. 이 때 PVC 의 요구 사항 (용량, 접근 모드) 과 StorageClass 에 적은 parameter 가 함께 전달된다. +5. Provisioner 가 실제 저장소를 만들고 PV 를 만들어 PVC 에 bind 한다. +6. 사용자가 해당 PVC 를 이름으로 reference 하는 pod 를 생성한다. + +--- + +## Discussion & Additional Topics + +### What is NFS? + +- Network File System +- https://en.wikipedia.org/wiki/Network_File_System + +### Why do PersistentVolum(Claim) access modes pertain to the number of worker nodes, not to the number of pods? + +- 왜 이렇게 했지? +- (추정) 클라우드에서 volume 이라는 시스템 자체가 노드 단위로 컨트롤 되기 때문에? + +### 올바른 PersistentVolume 의 사용법? + +- Reclaim policy 가 `Retain`, `Recycle`, `Delete` 뿐이면 재사용이 안된다는 것인데, 그렇다면 PVC 를 생성해서 작업을 하는 동안 계속 연결해야 하고 pod 들의 작업이 끝나야지만 지우라는 건가? +- PVC 를 지워서 연결은 끊었지만 나중에 다시 필요하다면...? 애초에 그런 상황을 만들지 말고 PVC 를 계속 유지? +- 그런 듯 하다. + +### `hostPath` use case + +- GPU 가 필요한 노드에서 DaemonSet 으로 노드에 Nvidia driver 를 설치하고 driver path 를 `hostPath` 로 잡는 경우가 있다. + +### Storage vs Disk vs Volume vs Filesystem + +- 스토리지: 추상화된 저장소 +- 디스크: 저장소의 물리적 구현체 (HDD, SSD) +- 볼륨: 디스크의 한 구획 (파티션, C:, D;) +- 파일시스템: 디스크에 파일을 저장하는 소프트웨어 (ext, NTFS etc.) diff --git a/_posts/Development/Kubernetes/2021-04-18-07-configmaps-and-secrets.md b/_posts/Development/Kubernetes/2021-04-18-07-configmaps-and-secrets.md new file mode 100644 index 0000000..310d683 --- /dev/null +++ b/_posts/Development/Kubernetes/2021-04-18-07-configmaps-and-secrets.md @@ -0,0 +1,474 @@ +--- +share: true +toc: true +categories: [Development, Kubernetes] +tags: [kubernetes, sre, devops] +title: "07. ConfigMaps and Secrets: Configuring Applications" +date: "2021-04-18" +github_title: "2021-04-18-07-configmaps-and-secrets" +image: + path: /assets/img/posts/k8s-07.jpeg +--- + +![k8s-07.jpeg](../../../assets/img/posts/k8s-07.jpeg) _Combining a ConfigMap and a Secret to run your fortune-https pod (출처: https://livebook.manning.com/book/kubernetes-in-action/chapter-7)_ + +거의 대부분의 앱은 설정(configuration)이 필요하다. 개발 서버, 배포 서버의 설정 사항 (접속하려는 DB 서버 주소 등)이 다를 수도 있고, 클라우드 등에 접속하기 위한 access key 가 필요하거나, 데이터를 암호화하는 encryption key 도 설정해야하는 경우가 있다. 이러한 경우에 해당 값들을 도커 이미지 자체에 넣어버리면 보안 상 취약하고, 또 설정 사항을 변경하는 경우 이미지를 다시 빌드해야하는 등 불편함이 따른다. + +이번 장에서는 Kubernetes 에서 돌아가는 애플리케이션에 설정 사항을 넘겨주는 방법을 알아본다. + +## 7.1 컨테이너화 된 애플리케이션 설정하기 +--- + +보통 애플리케이션의 설정 사항을 관리할 때에는 configuration file 이 존재하게 된다. (`.properties`, `.env` 등) + +그런데 Docker 를 사용하면, config file 을 컨테이너로 옮기는 명령이 Dockerfile 에 필요하게 되고, config file 을 수정하면 이미지를 다시 빌드해야하기 때문에 보통은 컨테이너에 환경 변수(environment variables)를 전달하는 방식으로 사용한다. 그리고 애플리케이션은 환경 변수를 조회하여 사용할 수 있다. + +또는 6장에서 배운 volume 을 사용할 수도 있을 것이다. + +애플리케이션 설정 사항을 전달하는 방법에는 크게 3가지가 있다. +- 컨테이너에 command line argument 전달하기 +- 컨테이너마다 환경 변수 설정하기 +- Volume 을 이용해서 config file mount 하기 + +## 7.2 컨테이너에 command line argument 전달하기 +--- + +보통은 컨테이너 이미지에 정의된 기본 명령으로 이미지를 실행하지만, Kubernetes 에서는 해당 명령을 override 하여 다른 명령을 실행하도록 할 수 있다. 그래서 실행할 때 추가로 argument 를 전달할 수 있게 된다. + +### 7.2.1 Defining the command and arguments in Docker + +우선, 컨테이너에서 실행되는 명령은 두 부분: **command**, **arguments** 으로 나뉜다. + +#### `ENTRYPOINT`, `CMD` 이해하기 + +Dockerfile 에서 다음 명령을 사용할 수 있다. + +- `ENTRYPOINT`: 컨테이너가 시작할 때 실행할 파일 +- `CMD`: `ENTRYPOINT` 를 실행할 때 전달할 argument + +> **Note.** Dockerfile reference 를 보면 `CMD` 의 용법은 3가지가 있다고 한다. +> - `CMD ["executable","param1","param2"]` (*exec* form, this is the preferred form) +> - `CMD ["param1","param2"]` (as *default parameters to ENTRYPOINT*) +> - `CMD command param1 param2` (*shell* form) +> +> Dockerfile 에는 하나의 `CMD` 만 존재할 수 있으며, **The main purpose of a CMD is to provide defaults for an executing container.** 라고 한다. +> *provide default* 라고 했기 때문에 이는 overriding 이 가능하다는 것이다. +> +> `ENTRYPOINT` 를 사용하면 컨테이너가 실행될 때 `ENTRYPOINT` 에서 지정한 명령을 수행하고, `CMD` 도 마찬가지지만 `CMD` 의 경우 컨테이너 실행시 인자값을 주면 Dockerfile 의 `CMD` 를 override 하여 실행한다. +> +> Reference 에서도 이 둘의 사용법을 설명해줬다. +> +> Both `CMD` and `ENTRYPOINT` instructions define what command gets executed when running a container. There are few rules that describe their co-operation. +> - Dockerfile should specify at least one of `CMD` or `ENTRYPOINT` commands. +> - `ENTRYPOINT` should be defined when using the container as an executable. +> - `CMD` should be used as a way of defining default arguments for an `ENTRYPOINT` command or for executing an ad-hoc command in a container. +> - `CMD` will be overridden when running the container with alternative arguments. + +#### shell form & exec form + +`ENTRYPOINT`, `CMD` 를 사용할 때는 2가지 형태가 있다. + +- `shell` form: `ENTRYPOINT node app.js` +- `exec` form: `ENTRYPOINT ["node", "app.js"]` + +`shell` form 의 경우에는 컨테이너가 시작하면 shell 을 띄워서 안에서 명령을 실행한다. 반면 `exec` form 은 해당 명령이 바로 컨테이너의 프로세스가 된다. + +그러므로 전자는 `shell` 프로세스를 별도로 실행하기 때문에, `exec` form 을 사용하는 것이 좋다. + +#### 이미지에서 argument 설정하기 + +```dockerfile +ENTRYPOINT ["/bin/fortuneloop.sh"] +CMD ["10"] +``` + +위와 같이 설정하면 쉘 스크립트의 argument 로 `10` 을 전달할 수 있다. + +또 `docker run` 할 때 override 할 수 있다. + +```bash +$ docker run -it 15 +``` + +위와 같이 넘기면 `15` 를 argument 로 전달할 수 있다. + +### 7.2.2 Kubernetes 에서 command, argument overriding + +YAML 파일에서 override 할 수 있다. + +```yaml +spec: + containers: + - image: some/image + command: ["/bin/command"] + args: ["arg1", "arg2", "arg3"] +``` + +`command`, `args` 필드는 컨테이너가 시작되면 수정할 수 없다. + +## 7.3 컨테이너 환경 변수 설정하기 +--- + +Pod 레벨에서 환경 변수를 설정하고 컨테이너가 이를 상속하게 하는 옵션은 존재하지 않는다. + +### 7.3.1 컨데이너 정의에 환경 변수 설정하기 + +```yaml +spec: + containers: + - image: luksa/fortune:env + env: + - name: INTERVAL + value: "30" + name: html-generator +``` + +위와 같이 `env` 필드 안에 환경 변수의 이름과 값을 설정할 수 있다. 확인해 보면 pod 레벨에서 환경 변수를 설정하는 것이 아니라 컨테이너 별로 환경 변수를 설정해야 한다. + +### 7.3.2 환경 변수 참조하기 + +이전에 정의된 환경 변수를 재사용할 수도 있다. + +```yaml +env: +- name: FIRST_VAR + value: "foo" +- name: SECOND_VAR + value: "$(FIRST_VAR)bar" +``` + +더불어 `command`, `args` 필드의 값에서도 환경 변수를 참조하여 사용할 수 있다. + +### 7.3.3 환경 변수 하드코딩의 단점 + +위와 같은 방법으로 하면 환경 변수를 하나씩 하드코딩하는 것인데, 그렇다면 개발용/배포용 pod 설정을 따로 해줘야 하는 불편함이 있다. Pod 설정을 재사용하지 못하는 것이다. + +만약 pod 설정을 재사용하고 싶다면 config 와 pod 설정을 분리해야 하므로, 쿠버네티스에서는 ConfigMap 리소스를 제공한다. + +## 7.4 ConfigMap 으로 설정 분리하기 +--- + +앱 설정 사항을 만들 때 가장 많이 고려하는 부분은 자주 바뀌는 설정을 코드와 분리하는 것이다. (그래서 config file 도 만들고, 환경 변수도 쓰고...) + +### 7.4.1 ConfigMap + +ConfigMap 는 환경 변수를 key/value pair 로 저장하는 리소스이다. Value 에는 짧은 string 뿐만 아니라 config file 자체가 들어갈 수도 있다. + +애플리케이션 입장에서는 ConfigMap 을 읽어올 필요도 없고 존재하는지 알 필요도 없다. 대신 ConfigMap 리소스의 정보는 volume 이 되어서 환경 변수나 파일로 컨테이너에 전달된다. + +또한 pod 들이 ConfigMap 을 레퍼런스 할 때 이름으로 레퍼런스 하기 때문에, ConfigMap 을 같은 이름으로 여러 개 만들고 각각 다른 namespace 에 만들게 되면 pod YAML 파일을 하나만 만들어서 여러 namespace 에 재사용할 수 있게 된다. + +(namespace 별로 이름은 같지만 다른 설정을 할 수 있다는 의미) + +### 7.4.2 ConfigMap 만들기 + +`kubectl create configmap` 으로 만들면 된다. + +#### Literal 으로부터 만들기 + +```bash +$ kubectl create configmap --from-literal== +``` + +위 명령을 실행하면 ConfigMap 을 만들고 `=` 로 설정이 생긴다. 여러 개를 만들고 싶다면 `--from-literal` 을 여러 개 입력해야한다. (불편) + +만약 YAML 로 만들게 된다면 `.metadata.name` 에 ConfigMap 이름을 설정해 주고, 나머지는 `data` 에 key-value pair 로 넣어주면 된다. + +#### 파일로부터 만들기 + +```bash +$ kubectl create configmap --from-file= +``` + +주의할 점은 `kubectl` 을 실행하는 경로 내에서 `` (파일)을 찾는다는 점이다. 실행하게 되면 파일 이름을 key 로 해서 파일의 내용을 저장하게 된다. (key 도 임의로 설정할 수 있다) + +여러 파일을 추가하는 경우에도 `--from-file` 을 여러 번 적어야 한다. + +#### 디렉토리 내의 모든 파일 추가 + +`--from-file` 옵션을 이용할 때 디렉토리 경로를 넣어주면 된다. 대신 파일 이름이 유효한 key 값이어야 한다. (valid DNS subdomain) + +#### 옵션 조합하기 + +ConfigMap 을 만들 때 위 옵션들을 조합해서 전부 사용할 수 있다. + +### 7.4.3 ConfigMap entry 를 컨테이너의 환경 변수로 사용하기 + +`valueFrom` 을 사용한다. + +```yaml +spec: + containers: + - image: luksa/fortune:env + env: + - name: INTERVAL # 환경 변수를 만든다 + valueFrom: + configMapKeyRef: + name: fortune-config # fortune-config 라는 ConfigMap 에서 + key: sleep-interval # sleep-interval 의 값을 가져온다 +``` + +만약 한 컨테이너가 존재하지 않는 ConfigMap 을 reference 한다면 해당 컨테이너는 시작되지 않는다. + +### 7.4.4 ConfigMap 의 모든 entry 를 환경 변수로 넘기기 + +`envFrom` 을 사용한다. (버전 1.6 이후) + +```yaml +spec: + containers: + - image: some-image + envFrom: + - prefix: CONFIG_ # 모든 환경 변수가 CONFIG_ 라는 prefix 를 갖는다 + configMapRef: + name: my-config-map +``` + +올바르지 않은 key 값이 있다면 무시된다. + +### 7.4.5 ConfigMap entry 를 command-line argument 로 넘기기 + +ConfigMap 의 entry 를 직접 reference 해서 argument 로 사용할 수는 없고 (`args` 필드), 환경 변수를 생성한 뒤 해당 값을 reference 하는 방식으로 해야한다. + +(생성하고 reference 하기!) + +### 7.4.6 `configMap` volume 을 사용하여 ConfigMap entry 를 file 로 사용하기 + +보통 환경 변수나 argument 로 넘길 때에는 짧은 값을 사용하는데, (그런가...) ConfigMap 의 경우 파일 전체가 들어갈 수도 있다. 이 파일을 컨테이너가 사용할 수 있도록 하려면 `configMap` volume 을 사용해야한다. + +`configMap` volume 을 사용하면 ConfigMap 의 모든 entry 가 파일로 공개된다. 컨테이너 내부의 프로세스는 해당 파일을 읽어와서 설정 값을 사용할 수 있다. + +#### Volume 에 ConfigMap entry 넣기 + +```yaml +spec: + containers: + - image: nginx:alpine + name: web-server + volumeMounts: + - name: config + mountPath: /etc/nginx/conf.d + readOnly: true + volumes: + - name: config + configMap: + name: fortune-config +``` + +위와 같이 해주면 `fortune-config` ConfigMap 에 있는 파일 전체를 `mountPath` 에 mount 해준다. + +더불어 파일 전체가 아니라 일부만 mount 할 수도 있다. (ConfigMap 을 두개 만들어서 따로 마운트 하는 것은 불편하지 않을까) + +```yaml +volumes: + - name: config + configMap: + name: fortune-config + items: + - key: + path: +``` + +위와 같이 하면 `` 에 해당되는 값을 volume 의 `` 에 저장한다. 주의할 점은 `path` 를 각각 입력해야한다는 점이다. + +추가로, volume 을 사용할 때 디렉토리로 mount 하게 되면 컨테이너의 해당 디렉토리에 아무 파일도 없을 경우 문제가 되지 않지만, 파일이 존재했다면 해당 파일은 더 이상 사용할 수 없고 mount 한 볼륨의 내용으로 대체된다. 그래서 만약 `/etc` 와 같은 경로에 파일을 mount 하고 싶다면 컨테이너 자체의 `/etc` 가 날아가버리기 때문에 mount 하기 어렵다. + +그래서 `subPath` 를 사용하면 volume 전체를 mount 하지 않고 한 디렉토리나 한 파일만을 mount 할 수 있다. 하지만 이렇게 하나의 파일만을 mount 하는 경우에는 파일이 업데이트 될 때 문제가 발생하는데 다음 섹션에서 알아본다. + +#### `configMap` volume 의 파일 권한 + +Default 644. `defaultMode` 값을 수정하여 변경할 수 있다. + +### 7.4.7 앱 재시작 없이 설정 업데이트하기 + +환경 변수나 command line argument 를 사용하면, 설정 값을 바꿀 때 앱을 재시작해야 한다. 반면 ConfigMap 을 사용하면 그럴 필요가 없어진다. + +ConfigMap 을 수정하게 되면 ConfigMap 을 참조하고 있는 모든 volume 에서 파일이 수정된다. 그러면 앱이 파일의 변경을 감지하고 reload 하면 된다. (다만 오래 걸릴 수 있으니 주의) + +#### ConfigMap 수정하기 + +`kubectl edit` 으로 수정하면 된다. + +#### 파일의 업데이트는 atomic + +쿠버네티스가 파일을 모두 업데이트 하기 전에 앱이 이를 감지하고 reload 하는 일은 일어나지 않는다. 쿠버네티스에서 파일의 업데이트는 atomic 하게 되어서, 업데이트가 한 번에 되고, 이는 symbolic link 를 사용해서 한다. + +파일이 수정되면 수정 사항이 반영된 파일들을 만들어 한 디렉토리에 집어넣은 뒤 symbolic link 를 수정하여 해당 디렉토리 안을 참조하도록 한다. + +#### 파일 하나만 mount 하면 업데이트 안 됨 + +(책이 집필될 시점에서는) Volume 전체가 아니라 한 파일만 mount 하는 경우 업데이트가 되지 않는다. 그래서 대안으로는 volume 전체를 다른 디렉토리에 마운트 한 뒤 필요한 위치의 파일에서 참조하도록 symbolic link 를 만들어주는 방법이 있다. + +#### ConfigMap 업데이트시 주의할 점 + +ConfigMap 을 업데이트하는데 앱이 만약 설정이 변경된 것을 reload 하지 않는다면, pod 은 얼마든지 재시작 될 수 있으므로 일부 pod 는 수정되기 전의 설정을 그대로 가지고 있을 수도 있다. + +그러므로 앱 자체에 reload 기능이 없다면, ConfigMap 을 수정하는 것은 좋은 방법이 아닐 수 있다. + +만약 reload 기능이 있다면 ConfigMap 을 수정해도 괜찮으나 존재하는 instance 들 상에서 파일이 동시에 업데이트 되지 않을 수도 있으므로 잠시 sync 가 맞지 않을 수 있다는 점에 유의해야 한다. + +(??? atomic 하게 된다고 했던 것 같은데...) + +## 7.5 Secrets for sensitive data +--- + +Credential 의 경우 안전하게 전달되어야 한다. + +### 7.5.1 Secrets + +ConfigMap 과 비슷하다. 컨테이너에 환경 변수를 전달할 수도 있고, volume 을 통해 Secret 의 파일을 사용할 수도 있다. + +쿠버네티스는 Secret 에 접근할 필요가 있는 pod 가 실행 중인 노드에서만 Secret 이 접근 가능하도록 한다. 그리고 Secret 은 메모리 상에만 존재하여 절대 물리적 저장소에 저장되지 않는다. + +Secret 과 ConfigMap 중 고민이 될 때에는 다음 기준을 고려해본다. + +- Non-sensitive, plain configuration data 이면 ConfigMap +- Sensitive, 특별한 관리가 필요한 정보가 존재한다면 Secret + +### 7.5.2 Default token Secret + +모든 pod 에는 기본적으로 `secret` volume 이 존재한다. `describe` 를 이용해서 내부 정보를 보면 `ca.crt`, `namespace`, `token` 이 있는데 이 정보를 이용하면 Kubernetes API server 에 요청을 직접 보낼 수 있다. (필요하다면) + +### 7.5.3 Secret 생성 + +`kubectl create secret generic --from-file=` + +설정 방법 자체는 ConfigMap 과 유사하다. + +### 7.5.4 ConfigMap 과 Secret 차이 + +각 리소스를 생성하고 YAML output 을 비교해 보면 다르다. Secret 의 entry 들은 Base64 로 인코딩된 문자열이다. 반면 ConfigMap 의 경우 평문이 그대로 출력된다. + +추가로 Secrets 의 경우에는 binary data 를 갖고 있을 수 있다. Base64 로 binary data 를 인코딩해서 넣을 수 있는 것이다. + +만약 non-binary data 라면 `stringData` 필드를 이용해서 평문을 그대로 저장할 수도 있다. + +Secret 을 컨테이너에서 읽게 되면 entry 는 복호화되어서 원본 값 그대로 파일에 쓰이게 된다. 환경 변수로 넘겨주는 경우에도 동일하다. 앱 자체에서 복호화 할 필요는 없다. + +### 7.5.5 Pod 에서 Secret 사용하기 + +(생략) + +`secret` volume 은 in-memory filesystem (tmpfs) 을 사용하여 Secret 의 파일들을 서장한다. 디스크에 직접 쓰지 않는다. + +#### 환경 변수로 내보내기 + +환경 변수로 내보낼 때는 `valueFrom` 을 사용하고, ConfigMap 에서는 `configMapKeyRef` 를 사용했던 것과는 달리, `secretKeyRef` 를 사용하면 된다. + +환경 변수로 내보내는 것이 가능은 하지만 추천되지는 않는다. 환경 변수는 다른 어딘가 로그나 에러 리포트에 의도치 않게 저장될 수도 있다. 또 child process 가 환경 변수를 모두 상속받게 되는데 child process 가 third-party app 이면 secret data 에 무슨 일이 생길지 알 수 없다. + +Volume 사용이 추천된다. + +### 7.5.6 Understanding image pull Secrets + +때로 쿠버네티스 자체에서 credential 을 요구하는 경우가 있다. + +책의 예시는 private image registry 에서 pull 받는 경우인데, `docker-registry` Secret 을 만들면 `.dockercfg` 파일이 생긴다 (`docker login` 명령을 실행하면 생성되는 파일과 동일) Secret 의 이름을 이용해 `.spec.imagePullSecrets.name` 에 이름을 전달해 주면 private repo 에서 pull 받을 수 있게 된다. + +매번 이렇게 설정해 주기는 번거로우므로 12장에서 ServiceAccount 를 이용해 자동으로 추가하는 방법을 배운다. + +--- + +## Discussion & Additional Topics + +### What is a valid DNS subdomain? + +- Alphanumeric characters, dashes, underscores and dots only. May contain optional leading dot. + +아래는 쿠버네티스 공식 문서에서 가져온 내용: + +#### DNS Subdomain Names + +Most resource types require a name that can be used as a DNS subdomain name as defined in RFC 1123. This means the name must: + +- contain no more than 253 characters +- contain only lowercase alphanumeric characters, '-' or '.' +- start with an alphanumeric character +- end with an alphanumeric character + + +### Resolution of key collisions when creating ConfigMaps? + +- 그냥 애초에 생성이 안 되는 듯 하다. + +``` +$ kubectl create configmap test --from-literal=some=thing2 --from-literal=some=thing +error: cannot add key "some", another key by that name already exists in Data for ConfigMap "test" +``` + +### YAML 파일로 ConfigMap 을 만든다면 literal 을 제외한 다른 옵션은 어떻게 사용하는지? + +- Literal 옵션의 경우 `key: value` 로 등록하면 되는 것이고, +- 파일 entry 를 넣는다면 `|` 를 이용해서 아래와 같이 하면 된다. + +```yaml +data: + some-key: | + property1=value1 + property2=value2 + property3=value3 + property4=value4 +``` + +### ConfigMap 에서 파일을 사용하는 경우??? + +- ConfigMap 에서 파일을 entry 로 넣는 경우 mount 해서 사용하는게 맞을 것 같아 보인다. + - 안 그러면 불러왔는데 multi-line 일테니 직접 파싱 해서 사용 (??) +- Mount 를 잘 하면 `.properties` 나 `.env` 가 들어갈 위치에 config file 을 넣어줄 수 있지 않을까? + - 그러면 애플리케이션은 해당 설정 파일을 읽으며 자연스럽게 동작! + +### Mounted ConfigMaps are updated automatically + +(공식 문서 발췌) + +When a ConfigMap already being consumed in a volume is updated, *projected keys are eventually updated as well*. **Kubelet is checking whether the mounted ConfigMap is fresh on every periodic sync**. + +However, it is using its *local ttl-based cache* for getting the current value of the ConfigMap. As a result, the total delay [from the moment when the ConfigMap is updated to the moment when new keys are projected to the pod] can be as long as kubelet sync period (1 minute by default) + ttl of ConfigMaps cache (1 minute by default) in kubelet. + +You can trigger an immediate refresh by updating one of the pod's annotations. + +> Note: A container using a ConfigMap as a `subPath` volume will not receive ConfigMap updates. + +### Secret 종류에 generic, docker-registry 말고 뭐가 더 있나? + +- [공식 문서](https://kubernetes.io/docs/concepts/configuration/secret/)에 자료가 많다! + +| Builtin Type | Usage | +|--------------|-------| +| `Opaque` | arbitrary user-defined data | +| `kubernetes.io/service-account-token` | service account token | +| `kubernetes.io/dockercfg` | serialized `~/.dockercfg` file | +| `kubernetes.io/dockerconfigjson` | serialized `~/.docker/config.json` file | +| `kubernetes.io/basic-auth` | credentials for basic authentication | +| `kubernetes.io/ssh-auth` | credentials for SSH authentication | +| `kubernetes.io/tls` | data for a TLS client or server | +| `bootstrap.kubernetes.io/token` | bootstrap token data | + +### Restrictions of Secrets + +- Pod 생성 전에 Secret 를 만들어야 함 + - 없는 값을 참조하면 pod 가 시작하지 않는다 +- Secret 은 namespace 를 가지므로, 같은 namespace 안에 있어야 참조할 수 있음 +- 각 Secret 의 최대 용량은 1MB 이다. + - API server, Kubelet 의 자원 낭비를 막기 위한 장치 + - 물론 작은 Secret 여러 개 만들 수 있는데 이것 까지도 통합적으로 용량 제한하는 기능은 계획 중 + +### More use cases of Secret + +- https://kubernetes.io/docs/concepts/configuration/secret/#use-cases + +### Hard link vs Symbolic link + +- Hard link + - 원본 파일과 동일한 `inode` 를 사용한다. 즉, **원본 파일을 가르키는** 링크이다. 그러므로 원본 파일이 삭제되어도 사용 가능하다. +- Symbolic link + - 원본 파일의 **이름을 가르키는** 링크로, 원본 파일이 삭제되면 사용이 불가능하다. + +### Where does ConfigMap data get stored? + +- `etcd` +- https://stackoverflow.com/questions/53935597/where-does-configmap-data-gets-stored/53936061#53936061 + +--- + +후기: 이해는 되지만 잘 와닿지가 않는 느낌인데, 나중에 다시 읽어보겠습니다... diff --git a/_posts/Development/Kubernetes/2021-04-18-08-accessing-pod-metadata-and-other-resources-from-applications.md b/_posts/Development/Kubernetes/2021-04-18-08-accessing-pod-metadata-and-other-resources-from-applications.md new file mode 100644 index 0000000..8d56b4c --- /dev/null +++ b/_posts/Development/Kubernetes/2021-04-18-08-accessing-pod-metadata-and-other-resources-from-applications.md @@ -0,0 +1,518 @@ +--- +share: true +toc: true +categories: [Development, Kubernetes] +tags: [kubernetes, sre, devops] +title: "08. Accessing Pod Metadata and Other Resources from Applications" +date: "2021-04-18" +github_title: "2021-04-18-08-accessing-pod-metadata-and-other-resources-from-applications" +image: + path: /assets/img/posts/k8s-08.jpeg +--- + +![k8s-08.jpeg](../../../assets/img/posts/k8s-08.jpeg) _Using the files from the default-token Secret to talk to the API server (출처: https://livebook.manning.com/book/kubernetes-in-action/chapter-8)_ + +### 주요 내용 + +- Pod 나 컨테이너의 metadata 를 전달하는 방법 +- 컨테이너 안의 앱이 Kubernetes API 와 통신하고 클러스터의 리소스를 생성/수정하는 방법 + +## 8.1 Passing metadata through the Downward API +--- + +앱의 config data 는 pod 생성 전에 결정되기 때문에 환경 변수나 configMap, secret volume 을 이용해 전달할 수 있었다. + +하지만 pod 가 시작 되어야 알 수 있는 정보들도 있다. (Pod IP, 실행 중인 노드의 이름, pod 자체의 이름 등) 이런 정보를 얻기 위해서 **Downward API** 가 존재하며, 이 API 를 호출하면 pod 나 실행 환경과 관련된 정보를 얻을 수 있다. 얻은 정보는 환경 변수로 전달되거나, `downwardAPI` 볼륨을 이용하면 파일로 전달된다. + +### 8.1.1 사용 가능한 metadata + +Downward API 를 이용하면 pod 의 metadata 를 pod 내부의 프로세스(컨테이너에도)에 전달할 수 있다. + +현재 다음 정보들을 컨테이너에게 넘겨줄 수 있다. + +- Pod 의 이름, IP, namespace, 노드 이름, label, annotation +- The name of the [service account](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) the pod is running under +- 각 컨테이너의 CPU, 메모리 자원 요청과 최대 할당량 + +> service account 는 pod 가 API server 와 통신할 때 authentication 을 위해 활용하는 계정이다. + +위 항목들 중에서 pod labels, annotation 은 volume 을 통해서만 전달될 수 있다. + +### 8.1.2 환경 변수를 이용해 metadata 가져오기 + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: downward +spec: + containers: + - name: main + image: busybox + command: ["sleep", "9999999"] + resources: + requests: + cpu: 15m + memory: 100Ki + limits: + cpu: 100m + memory: 6Mi # 책은 4Mi 인데 limit 의 최솟값이 6Mi 여야 한다고 해서 수정 + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name # yaml 파일의 값에서 가져오기 + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: CONTAINER_CPU_REQUEST_MILLICORES + valueFrom: + resourceFieldRef: # CPU, 메모리의 경우 resourceFieldRef 를 사용 + resource: requests.cpu + divisor: 1m # divisor 를 정의해서 원하는 단위로 값을 얻을 수 있다 + - name: CONTAINER_MEMORY_LIMIT_KIBIBYTES + valueFrom: + resourceFieldRef: + resource: limits.memory + divisor: 1Ki +``` + +위와 같이 `.spec.containers.env` 아래에 환경 변수를 설정할 수 있다. + +> `1m` 은 1 milli-core 를 의미한다. 1/1000 core. 또한 Ki 는 키비바이트로, 1024KiB = 1MiB 이다. (binary byte 라고 생각하면 된다. Prefix 간의 간격이 1000이 아닌 1024배이다.) + +Pod 를 실행하고 나서 `kubectl exec downward -- env` 를 통해 환경변수를 확인할 수 있다. + +> `kubectl exec [POD] [COMMAND]` 는 deprecated 되었다고 한다. `kubectl exec [POD] -- [COMMAND]` 를 사용하라고 한다. + +### 8.1.3 Passing metadata through files in a downward API volume + +만약 metadata 를 파일로 얻고 싶다면 `downwardAPI` volume 을 정의하고 컨테이너에 마운트해야 한다. + +환경 변수와 마찬가지로 metadata field 를 명시적으로 지정해줘야 컨테이너 안의 프로세스가 사용할 수 있다. + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: downward + labels: + foo: bar + annotations: + key1: value1 + key2: | + multi + line + value +spec: + containers: + - name: main + image: busybox + command: ["sleep", "9999999"] + resources: + requests: + cpu: 15m + memory: 100Ki + limits: + cpu: 100m + memory: 4Mi + volumeMounts: # downwardAPI volume 마운트하기 + - name: downward + mountPath: /etc/downward + volumes: + - name: downward + downwardAPI: + items: # 설정한 경로의 파일에 필요한 정보가 저장된다 + - path: "podName" + fieldRef: + fieldPath: metadata.name + - path: "podNamespace" + fieldRef: + fieldPath: metadata.namespace + - path: "labels" + fieldRef: + fieldPath: metadata.labels + - path: "annotations" + fieldRef: + fieldPath: metadata.annotations + - path: "containerCpuRequestMilliCores" + resourceFieldRef: + containerName: main + resource: requests.cpu + divisor: 1m + - path: "containerMemoryLimitBytes" + resourceFieldRef: + containerName: main # volume 을 사용할 땐 containerName 이 들어간다 + resource: limits.memory + divisor: 1 +``` + +Pod 를 만들어서 마운트가 잘 되었는지 확인해 본다. + +``` +$ kubectl exec downward -- ls -lL /etc/downward +total 24 +-rw-r--r-- 1 root root 134 Apr 17 06:31 annotations +-rw-r--r-- 1 root root 2 Apr 17 06:31 containerCpuRequestMilliCores +-rw-r--r-- 1 root root 7 Apr 17 06:31 containerMemoryLimitBytes +-rw-r--r-- 1 root root 9 Apr 17 06:31 labels +-rw-r--r-- 1 root root 8 Apr 17 06:31 podName +-rw-r--r-- 1 root root 7 Apr 17 06:31 podNamespace +``` + +> `-L` (`--dereference`) 옵션: when showing file information for a symbolic link, show information for the file the link references rather than for the link itself + +#### label 과 annotation 은 volume 으로만 expose 가능한 이유 + +더불어 label 과 annotation 은 pod 이 생성되고 변경이 가능하기 때문에, 환경 변수로 expose 하게 되면 값이 변경됐을 때 업데이트할 방법이 없다. 반면 volume 을 사용하게 되면 변경시 파일은 업데이트 된다. (그러므로 환경 변수로 내보내는 것을 막아둔 듯) + +#### Volume 사용시 컨테이너 이름 명시 + +추가로 환경 변수 때와는 달리 volume 을 사용하는 경우에는 `resourceFieldRef.containerName` 필드가 있어야 하는데, volume 은 pod 레벨에서 사용하는 리소스이므로 어떤 컨테이너의 metadata 를 가져오는 것인지 명시해야 값을 가져올 수 있다. + +#### Volume 사용시 얻는 장점 + +같은 pod 내에서 한 컨테이너의 metadata 를 다른 컨테이너에게 보여줄 수 있다는 장점이 있다. + +#### Downward API 를 사용해야할 때 + +Downward API 를 사용하는 것은 간단하다. Shell script 로 환경 변수를 설정하는 등의 수고로움을 덜어줄 것며, 애플리케이션이 Kubernetes 에 의존하지 않게 할 수 있다. 만약 환경 변수 값을 이용해서 동작하는 앱이라면 Downward API 가 유용할 것이다. + +## 8.2 Talking to the Kubernetes API server +--- + +Downward API 도 다양한 정보를 제공하지만 이로는 부족할 수 있다. (다른 pod/클러스터의 정보가 필요하거나) 그렇다면 Kubernetes API server 와 직접 통신하여 원하는 값을 얻어야 한다. + +### 8.2.1 Exploring the Kubernetes REST API + +우선 API 서버의 URL 을 알아보려면 `kubectl cluster-info` 를 입력하면 된다. + +``` +$ kubectl cluster-info +Kubernetes control plane is running at https://192.168.49.2:8443 +KubeDNS is running at https://192.168.49.2:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy +``` + +API 서버는 HTTPS 를 사용하므로, 인증 없이는 직접 요청을 보낼 수 없다. + +#### kubectl proxy 를 이용하여 요청하기 + +`kubectl proxy` 를 이용하면 로컬에서 HTTP 요청을 받아서 Kubernetes API 서버로 요청을 전달해 주고, 인증도 알아서 처리해준다. 더불어 매 요청마다 서버의 인증서를 확인하여 MITM attack 을 막고 실제 서버와 통신할 수 있도록 해준다. + +``` +$ kubectl proxy +Starting to serve on 127.0.0.1:8001 +``` + +이제 `http://localhost:8001` 에 접속해보면 `paths` 가 잔뜩 있는 것을 확인할 수 있다. 각 `paths` 는 리소스를 만들때 사용했던 `apiVersion` 나 API group 에 대응된다. + +#### batch API group + +Job 리소스의 API group 은 `/apis/batch` 이다. + +``` +$ curl http://localhost:8001/apis/batch +{ + "kind": "APIGroup", + "apiVersion": "v1", + "name": "batch", + "versions": [ + { + "groupVersion": "batch/v1", + "version": "v1" + }, + { + "groupVersion": "batch/v1beta1", + "version": "v1beta1" + } + ], + "preferredVersion": { + "groupVersion": "batch/v1", + "version": "v1" + } +} +``` + +`curl` 을 해보면, API 버전이 2개가 있고, 이 중 `batch/v1` 이 선호된다는 것을 알 수 있다. + +``` +$ curl http://localhost:8001/apis/batch/v1 +{ + "kind": "APIResourceList", + "apiVersion": "v1", + "groupVersion": "batch/v1", + "resources": [ + { + "name": "jobs", + "singularName": "", + "namespaced": true, + "kind": "Job", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ], + "categories": [ + "all" + ], + "storageVersionHash": "mudhfqk/qZY=" + }, + { + "name": "jobs/status", + "singularName": "", + "namespaced": true, + "kind": "Job", + "verbs": [ + "get", + "patch", + "update" + ] + } + ] +} +``` + +`batch/v1` 으로 `curl` 을 해보면 해당 API group 에 있는 리소스 종류의 목록과 REST 엔드포인트를 돌려준다. 여기에 Job 이 있다. (`resources` 안에 이 그룹의 리소스 종류가 배열의 원소로 들어있다) + +자세히 살펴보면 리소스의 이름과 관련된 `name`, `kind` 가 있고, `namespaced` 에서 namespace 의 적용 여부와 `verbs` 에서 수행할 수 있는 동작을 (생성, 삭제 등) 확인할 수 있다. + +#### 클러스터 내 모든 Job 인스턴스 가져오기 + +`/apis/batch/v1/jobs` 에 GET 요청을 보내면 될 것이다. + +#### 이름으로 특정 Job 인스턴스 가져오기 + +만약 `default` namespace 의 `my-job` 이란 이름의 Job 리소스에 대해 정보를 확인하고 싶다면 `/apis/batch/v1/namespaces/default/jobs/my-job` 으로 GET 요청을 보내면 된다. (이거 매우 불편해보입니다;) + +결과를 보면 `kubectl get job my-job -o json` 과 동일함을 확인할 수 있다. + +### 8.2.2 Pod 내부에서 API 서버에 요청하기 + +Pod 내부에서는 `kubectl` 이 없을 것이므로, `kubectl proxy` 를 사용할 수 없다. 그러므로 API 서버와 통신하기 위해서는 다음 3가지를 고려해야 한다. + +- API 서버의 URL +- API 서버의 authenticity (MITM 아닌지 확인) +- API 서버에 인증하기 + +#### 서버와 통신할 pod 생성 + +우선 테스트를 위해 아무것도 안하는 pod 를 생성하고, 안에서 shell 을 실행해본다. Pod 내부에서 `curl` 이 가능해야 하므로, `curl` binary 가 있는 이미지로 컨테이너를 만든다. + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: curl +spec: + containers: + - name: main + image: tutum/curl + command: ["sleep", "9999999"] # 자라... +``` + +```bash +$ kubectl exec -it curl bash +``` + +로 shell 을 실행한다. + +#### API 서버의 주소 알아내기 + +`kubernetes` 라는 이름으로 service 가 돌아가고 있으므로, 해당 IP 로 요청을 보내면 될 것이다. Service 의 주소는 환경 변수로 들어가므로, `env` 를 이용해 확인해주면 간단하게 해결된다. + +``` +root@curl:/# env | grep KUBERNETES_SERVICE +KUBERNETES_SERVICE_PORT=443 +KUBERNETES_SERVICE_HOST=10.96.0.1 +KUBERNETES_SERVICE_PORT_HTTPS=443 +``` + +사실 이렇게 하지 않아도 되고, 내부 DNS 서버에 entry 가 생성되므로, 그냥 `https://kubernetes` 로 요청을 보내도 된다. 하지만 이 경우에는 포트 번호를 알아야하긴 하므로 환경 변수에서 직접 찾아보거나, [DNS SRV record](https://en.wikipedia.org/wiki/SRV_record) 를 찾아보면 될 것이다. + +> SRV record: specification of data in the DNS defining the location of servers for specified services. 여기서 location 이라 함은 hostname 과 port number 정도로 생각해도 괜찮을 것 같다. + +한 번 `https://kubernetes` 로 요청을 보내보면 인증서가 없어서 실패한다. + +``` +root@curl:/# curl https://kubernetes +curl: (60) SSL certificate problem: unable to get local issuer certificate +More details here: http://curl.haxx.se/docs/sslcerts.html + +curl performs SSL certificate verification by default, using a "bundle" + of Certificate Authority (CA) public keys (CA certs). If the default + bundle file isn't adequate, you can specify an alternate file + using the --cacert option. +If this HTTPS server uses a certificate signed by a CA represented in + the bundle, the certificate verification probably failed due to a + problem with the certificate (it might be expired, or the name might + not match the domain name in the URL). +If you'd like to turn off curl's verification of the certificate, use + the -k (or --insecure) option. +``` + +`-k` (`--insecure`) 옵션을 사용하면 이를 무시할 수 있지만 그래도 API 서버 측에서 막는다. + +``` +root@curl:/# curl https://kubernetes -k +{ + "kind": "Status", + "apiVersion": "v1", + "metadata": { + + }, + "status": "Failure", + "message": "forbidden: User \"system:anonymous\" cannot get path \"/\"", + "reason": "Forbidden", + "details": { + + }, + "code": 403 +} +``` + +#### 서버가 진짜인지 확인하기 + +`default-token-*****` 라는 Secret 이 모든 컨테이너에 생성되므로, `/var/run/secrets/kubernetes.io/serviceaccount` 에 들어가서 확인해 본다. `ca.crt`, `namespace`, `token` 이렇게 총 3개의 파일이 있는데, `ca.crt` 파일을 이용할 것이다. 이 파일에는 서버의 인증서를 sign 한 CA 의 정보가 들어있다. + +`curl` 의 `--cacert` 옵션을 이용해 `ca.crt` 를 CA 인증서로 넘겨주고 다시 `curl` 을 때려본다. + +``` +root@curl:/# curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt https://kubernetes +{ + "kind": "Status", + "apiVersion": "v1", + "metadata": { + + }, + "status": "Failure", + "message": "forbidden: User \"system:anonymous\" cannot get path \"/\"", + "reason": "Forbidden", + "details": { + + }, + "code": 403 +} +``` + +`-k` 를 이용해서 인증서 체크를 건너뛰었을 때와 같은 결과가 나오는 것을 확인할 수 있다. 이제 서버에 인증을 하면 될 것이다. + +그 전에 매번 `--cacert` 를 입력하기 귀찮으므로 `CURL_CA_BUNDLE` 환경 변수를 `ca.crt` 파일의 경로로 설정해주면 입력하지 않고도 요청을 보낼 수 있다. + +```bash +$ export CURL_CA_BUNDLE=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt +``` + +#### API 서버에 인증하기 + +인증을 위해서는 authentication token 이 필요하다. 이 token 은 `token` 파일에 있다. 우선 환경 변수로 token 값을 빼온 뒤, `curl` 을 때려본다. + +```bash +$ TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) +$ curl -H "Authorization: Bearer $TOKEN" https://kubernetes +``` + +> Role-based access control ([RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/)) 이 실행되고 있는 클러스터에서는 위 `curl` 에서 에러가 난다. 일단 테스트를 위해서 임시적으로 +> ```bash +> kubectl create clusterrolebinding permissive-binding \ +> --clusterrole=cluster-admin \ +> --group=system:serviceaccounts +> ``` +> 를 입력하여 모든 serviceaccounts 에 admin 권한을 줄 수 있다 ㅋㅋㅋ; + +#### 현재 pod 의 namespace 가져오기 + +조금 전에 `default-token` secret 에 `ls` 했을 때 `namespace` 파일이 있었다. 해당 파일의 내용을 읽어오면 된다. + +```bash +$ NS=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace) +$ curl -H "Authorization: Bearer $TOKEN" https://kubernetes/api/v1/namespaces/$NS/pods +``` + +비슷한 방법으로 다른 API 를 이용해 `PUT` 등 요청을 보내 오브젝트 정보를 가져오거나 수정할 수 있다. + +#### Pod 안에서 API 서버와 통신하기 요약 + +1. 앱은 API 서버의 인증서가 CA 에 의해 확인되었는지 확인해야한다. CA 의 인증서는 `ca.crt` 에 있다. +2. 앱은 요청을 보낼 때 header 에 `Authorization: Bearer $TOKEN` 을 추가해야 한다. +3. `namespace` 파일을 이용해 namespace 를 확인하고 CRUD 요청을 할 수 있다. + +### 8.2.3 Ambassador container 를 이용해 API 서버 통신 간소화 + +HTTPS 는 너무 번거로울 수도 있으므로, 요청을 처리해줄 컨테이너를 하나 만들면 되지 않을까? + +#### Ambassador 패턴 + +컨테이너가 직접 API 서버와 통신하지 않고, ambassador 컨테이너로 요청을 보내며, ambassador 는 proxy 역할을 해준다. + +Ambassador 컨테이너는 secret 을 이용해서 인증을 처리하고 proxy 역할을 해준다. 더불어 pod 내의 컨테이너들은 네트워크 인터페이스를 공유하므로 localhost 의 한 포트로 접근할 수 있다. + +#### curl pod with ambassador + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: curl-with-ambassador +spec: + containers: + - name: main + image: tutum/curl + command: ["sleep", "9999999"] + - name: ambassador + image: luksa/kubectl-proxy:1.6.2 # proxy 를 담당할 이미지 +``` + +Pod 를 생성한 뒤 `kubectl exec -it curl-with-ambassador -c main -- bash` 를 이용해 접근한다. + +> `-c` 는 pod 내의 어느 컨테이너에서 명령을 실행할지 정하는 옵션이다. + +#### Ambassador 를 이용해 API 서버에 요청하기 + +`kubectl proxy` 는 8001 포트에 bind 되므로 `localhost:8001` 로 요청을 보내보면 잘 작동하는 것을 확인할 수 있다. + +모든 인증 과정은 ambassador 컨테이너가 담당한다. + +### 8.2.4 Client 라이브러리를 이용해서 API 서버에 요청하기 + +간단한 요청은 ambassador 컨테이너와 HTTP client 라이브러리를 이용해서 해결할 수 있겠지만, 복잡한 요청을 하게 된다면 Kubernetes API client 라이브러리를 사용하는 것이 좋다. + +#### 존재하는 라이브러리 + +Supported by the API Machinery special interest group (SIG) + +- Golang client, Python + +User contributed client libraries + +- Java. Node.js, PHP, Ruby, Clojure, Scala, Perl + +당연히 라이브러리들은 HTTPS 인증도 처리해준다. + +--- + +## Discussion & Additional Topics + +### Mili-core 단위로 CPU 자원 할당을 어떻게 하는 것인지? + +### Ambassador 컨테이너가 `kubectl proxy` 를 실행하는게 과연 맞는 방법일지? + +- 컨테이너 안에 `kubectl` 설치해야 하는 것 같던데... +- [소스 링크](https://github.com/luksa/kubernetes-in-action/tree/master/Chapter08/kubectl-proxy) diff --git a/_posts/Development/Kubernetes/2021-04-30-09-deployments.md b/_posts/Development/Kubernetes/2021-04-30-09-deployments.md new file mode 100644 index 0000000..91643c0 --- /dev/null +++ b/_posts/Development/Kubernetes/2021-04-30-09-deployments.md @@ -0,0 +1,490 @@ +--- +share: true +toc: true +categories: [Development, Kubernetes] +tags: [kubernetes, sre, devops] +title: "09. Deployments: Updating Applications Declaratively" +date: "2021-04-30" +github_title: "2021-04-30-09-deployments" +image: + path: /assets/img/posts/k8s-09.jpeg +--- + +![k8s-09.jpeg](../../../assets/img/posts/k8s-09.jpeg) _Rolling update of Deployments (출처: livebook.manning.com/book/kubernetes-in-action/chapter-9)_ + +### 주요 내용 + +- Deployment 를 사용하여... + - 무중단 배포를 하는 방법 + - 롤백하는 방법 + +## 9.1 Updating applications running in pods +--- + +만약 서비스/앱을 업데이트하고 싶다면 2가지 방법이 있다. + +1. Pod 를 모두 지운 후, 업데이트 된 pod 로 새롭게 시작 +2. 새로운 pod 를 시작한 뒤 새로운 pod 가 요청을 처리할 준비가 되면 기존 pod 를 지운다. + +두 방법 모두 장단이 있다. 1번의 경우 잠시 서비스가 중단된다는 문제가 있고, 2번의 경우 배포 중에 2가지 버전의 서비스가 동시에 존재하게 되므로 이를 잘 처리하기 위해서 서비스/앱 단에서 처리해줘야 한다. (하위 호환성) + +### 9.1.1 삭제 후 새롭게 생성 + +ReplicationController / ReplicaSet 의 경우 pod template 을 수정할 수 있었다. + +- Pod template 변경 (`kubectl apply -f ...`) +- Old pod 모두 삭제 +- ReplicationController / ReplicaSet 이 삭제를 감지하고 새로운 pod template 으로 생성 + +당연히, rc/rs 가 삭제를 감지하고 pod 이 요청을 처리할 준비가 될 때까지 서비스가 중단된다. + +### 9.1.2 새로운 pod 생성 후 기존 pod 삭제 + +#### 한 번에 새로운 pod 로 교체하기 + +이 방법을 사용할 때 고려해야할 점이 있다면, 새로운 pod 를 생성한 뒤 삭제하는 것이므로 평소보다 2배 많은 pod 가 존재하게 되어 리소스를 많이 사용하게 된다. (이를 버틸 수 있는 리소스가 있어야 한다) + +이 방법도 간단하다. Pod 앞에 Service 가 붙어있을 것이므로, Service 의 label selector 롤 고쳐주면 된다. + +- 새로운 pod template 을 사용하는 ReplicaSet 생성 +- ReplicaSet 이 만든 pod 들이 모두 준비되었는지 확인 +- Service 의 label selector 를 교체 (`kubectl set selector ...`) + +이 방법은 *blue-green deployment* 라고 한다. + +#### 롤링 업데이트 + +Rolling update 방식에서는 pod 를 조금씩 교체한다. + +이를 수동으로 하는 경우에는 rc/rs 의 replica 수를 조절해야한다. 기존의 rc/rs 에서는 replica 수를 줄이고, 새로운 rc/rs 에서는 replica 수를 늘려야 한다. 이 때 Service 의 pod selector 가 새롭게 생성되는 pod 들도 포함할 수 있어야 한다. + +롤링 업데이트는 수동으로 하면 실수할 확률이 매우 높으므로, 자동화하는 것이 좋다. + +## 9.2 Performing an automatic rolling update with a ReplicationController +--- + +> 아래에 소개되는 방법은 이제는 사용하지 않는 방법이다! + +### 9.2.1 Initial version 실행하기 + +```yaml +apiVersion: v1 +kind: ReplicationController +metadata: + name: kubia-v1 +spec: + replicas: 3 + template: + metadata: + name: kubia + labels: + app: kubia + spec: + containers: + - image: luksa/kubia:v1 + name: nodejs +--- +apiVersion: v1 +kind: Service +metadata: + name: kubia +spec: + type: NodePort # minikube 인 관계로 NodePort Service 이용 + selector: + app: kubia + ports: + - port: 80 + targetPort: 8080 + nodePort: 30123 +``` + +ReplicationController 는 3개의 pod 를 생성할 것이고, Service 가 해당 pod 들을 관리할 것이다. + +> minikube 를 사용해 NodePort Service 를 생성하게 되면 minikube 의 IP 주소로 요청을 보내야 한다. `minikube ip` 로 확인하면 된다. 혹은 `minikube service list` 를 입력하면 포트까지 포함된 URL 이 출력된다. + +### 9.2.2 `kubectl` 로 rolling update 하기 + +> Note. 현재 `kubectl` 에 존재하지 않는 명령어이다. + +```bash +$ kubectl rolling-update kubia-v1 kubia-v2 --image=luksa/kubia:v2 +``` + +ReplicationController `kubia-v1` 을 `kubia-v2` 로 업데이트하고, 이미지를 `luksa/kubia:v2` 를 사용하겠다는 의미이다. 명령을 실행하면 ReplicationController `kubia-v2` 가 생성되고 롤링 업데이트가 진행된다. + +#### 동작 과정 + +`kubectl` 은 `kubia-v1` ReplicationController 의 pod template 을 그대로 가져와서 image 만 바꿔치기한 후 `kubia-v2` 를 만든다. + +또한 label 에 `deployment=...` 이 추가된 것을 확인할 수 있다. 만약 label 이 변경되지 않는다면 같은 label selector 를 갖는 ReplicationController 가 2개 존재하게 될 것이므로 문제가 생긴다. (새로 생긴 rc 가 동작할 필요가 없어진다) + +그래서 `kubectl` 은 ReplicationController 에 label selector 를 추가하고, rc 가 관리하고 있던 pod 의 label 에 `deployment=...` 을 추가해준다. + +Label 변경이 끝나면 본격적으로 scaling 이 시작되고, pod 는 하나씩 교체된다. (rc 의 replica 수를 하나씩 감소/증가 시키는 것이다) + +모든 pod 의 업데이트가 끝나면 기존의 rc 는 삭제된다. + +> label 도 원래대로 돌아오나 조금 궁금하긴 한데, 존재하지 않는 명령이라 확인이 불가능하다. + +### 9.2.3 `kubectl rolling-update` is now obsolete + +- 사용자가 생성한 object 들을 Kubernetes 가 직접 수정하는 것이 좋지 않다. + - 위에서 `deployment=...` label 이 추가되는 것처럼 +- `kubectl` *client* 가 모든 작업을 수행한다. + - `kubectl rolling-update ... --v 6` 을 하면 로그를 볼 수 있다. + - 로그를 보면 `kubectl` 이 API 서버에 보내는 요청을 하나씩 확인할 수 있다. + - Client 가 작업을 수행하게 되면 중간에 네트워크 연결이 유실되면 업데이트가 멈춰버린다. +- 이 방법은 imperative 하다. + - **Kubernetes 를 사용할 때는 어떤 목표 도달 상태에 대해서 알려만 주고, 그것을 Kubernetes 가 알아서 수행하도록 해야한다.** + - 반면 `rolling-update` 과정에서는 replica 수를 하나씩 조절한다. (좋지 않음) + +> `--v 6` 하면 로깅 레벨을 높여서 `kubectl` 이 API 서버에 보내는 요청을 볼 수 있다. + +## 9.3 Using Deployments for updating apps declaratively +--- + +> Declarative 와 imperative 가 서로 상반되는 개념인듯 하다. + +앱 배포 및 업데이트 위해 사용하는 object 이다. Deployment 를 생성하게 되면 내부적으로 ReplicaSet 을 자동으로 생성하며, ReplicaSet 이 pod 들을 관리해주게 된다. + +> ReplicationController 는 쓰지 말라고 공식 문서에 나와있다. + +Deployment 를 사용하면 rc/rs 와 같은 lower-level construct 들을 사용하지 않고도 업데이트를 쉽게 할 수 있게 된다. Deployment 에 목표 도달 상태를 정해주기만 하면 나머지는 Kubernetes 가 알아서 한다. + +### 9.3.1 Deployment 생성 + +ReplicationController 와 상당히 비슷하다. Deployment 에도 label selector, replica count, pod template 가 있으며, 추가로 배포 전략을 정해주는 strategy 필드를 갖고있다. + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: kubia # 이름에 버전 정보가 들어갈 필요없다! +spec: + replicas: 3 + template: + metadata: + name: kubia + labels: + app: kubia + spec: + containers: + - image: luksa/kubia:v1 + name: nodejs + selector: + matchLabels: + app: kubia +``` + +생성할 때 `--record` 옵션을 줘서 revision history 에 명령을 저장할 수 있도록 한다. + +#### Deployment rollout + +`kubectl get deployment`, `kubectl describe deployment` 로 Deployment 의 상태를 확인할 수도 있지만, `rollout` 을 사용해서 확인하는 방법이 있다. (이 목적으로 만들어졌다) + +``` +$ kubectl rollout status deployment kubia +deployment "kubia" successfully rolled out +``` + +#### 생성된 pod, ReplicaSet 확인 + +`kubectl get po` 로 만들어진 pod 들을 확인할 수 있고, `kubectl get rs` 를 해보면 ReplicaSet 이 생겼다는 것을 알 수 있다. + +그리고 ReplicaSet 의 이름에는 pod template 의 hash 값이 들어가 있는데, 이렇게 하는 이유는 Deployment 가 직접 pod 를 제어하지 않고 ReplicaSet 이 하기 때문이다. Deployment 는 ReplicaSet 을 여러 개 만들기도 하는데, 이때 이미 존재하는 ReplicaSet 을 추가로 만들지 않고 그대로 사용할 수 있게 된다. (pod template 이 같다면 hash 값이 일치하므로 재사용이 가능하다.) + +> 앞에서 `kubectl rolling-update` 를 사용할 때는 ReplicationController 에 label 이 추가되는 부분이 있었는데, 이는 같은 label selector 를 사용하는 여러 개의 ReplicationController 생성을 막기 위한 것이었다. +> +> ReplicaSet 도 이 문제에서 자유롭지는 못할 것 같아서 확인해보니, label selector 에 `pod-template-hash` 가 있는 것을 확인할 수 있었다. +> ``` +> $ kubectl get po --show-labels +> NAME READY STATUS RESTARTS AGE LABELS +> kubia-74967b5695-bpqfm 1/1 Running 0 17s app=kubia, pod-template-hash=74967b5695 +> kubia-74967b5695-djsfb 1/1 Running 0 17s app=kubia,pod-template-hash=74967b5695 +> kubia-74967b5695-h7d2b 1/1 Running 0 17s app=kubia,pod-template-hash=74967b5695 +> ``` +> 실제로 pod template hash 값을 사용하나보다. + +#### Service 생성 + +Service 를 생성하여 Deployment 가 생성한 pod 에 연결할 수 있도록 해준다. + +> Service 랑 Deployment 는 따로 띄워야 하나보다. + +### 9.3.2 Updating a Deployment + +ReplicationController 를 사용할 때보다 훨씬 간단해졌다. YAML 에서 pod template 만 고쳐주면 나머지는 Kubernetes 가 알아서 해준다! + +> ReplicationController 를 사용할 때는 새로운 rc 의 이름을 정해줘야 하고, 중간에 문제가 생기지는 않았는지 `kubectl rolling-update` 명령이 끝날 때까지 기다려야 했다. + +#### Deployment strategies + +배포 전략에는 2가지가 있다. 하나는 rolling update 방식이고 이 값이 기본값이다. 나머지 하나는 `Recreate` 로, 9.1.1 에서 다룬 것과 같이 pod 를 모두 삭제한 뒤 새로운 pod 를 띄우는 방식이다. + +> 만약 다른 버전의 앱이 여러 개 동작하고 있는 것이 서비스 구조상 불가능하다면 `Recreate` 를 사용할 수 있을 것이다. 서비스가 잠시 중단되는 것은 마찬가지이다. + +#### 실습을 위해 rolling update 천천히 하도록 설정 + +'Rolling' 이 잘 되고있는지 확인하기 위해 `minReadySeconds` 필드를 Deployment 에 추가한다. 필드 하나를 추가하는 것이므로 `kubectl patch` 를 사용한다. + +```bash +$ kubectl patch deployment kubia -p '{"spec": {"minReadySeconds": 10}}' +``` + +> `minReadySeconds` 는 해당 pod 가 available 상태라고 판단하기 위한 최소한의 `READY` 시간이다. 이 때, 설정한 시간만큼 해당 pod 의 어떠한 컨테이너도 crash 하지 않고 살아있어야 한다. + +#### Rolling update + +이제 pod 에서 사용하는 이미지를 `luksa/kubia:v2` 로 변경하면 된다. `kubectl patch` 로도 할 수 있지만, `kubectl set image` 를 사용할 것이다. + +```bash +$ kubectl set image deployment kubia nodejs=luksa/kubia:v2 +``` + +`kubia` 이름을 가진 Deployment 의 `nodejs` 컨테이너가 사용하는 이미지를 `luksa/kubia:v2` 로 변경하라는 의미이다. 실행하면 Deployment 의 pod template 이 변경된다. + +변경을 감지한 Kubernetes 가 rolling update 를 알아서 해준다. + +#### Deployment 의 편리함 + +필드 하나를 바꿨는데 rolling update 가 된다! 이 작업은 `kubectl` client 가 한것이 아니고 Kubernetes control plane 에서 처리한 것이다. + +기존 pod 를 하나씩 지우고 새로운 pod 를 하나씩 생성하는 전체적인 과정은 `rolling-update` 명령과 동일하다. 반면 업데이트가 끝난 다음에도 ReplicaSet 이 남아있게 되는데, 사용자는 Deployment 를 생성했지 ReplicaSet 을 직접 생성한 것이 아니므로 일단 고려하지 않아도 된다. + +오히려 ReplicaSet 이 남아있기 때문에 이를 활용할 수 있게 된다. + +### 9.3.3 Deployment 롤백하기 + +의도적으로 버그가 있는 버전을 배포해본다. Pod template 의 이미지를 변경한 후, `kubectl rollout` 명령을 이용해 rolling update 과정을 확인할 수 있다. + +``` +kubectl rollout status deployment kubia +Waiting for deployment "kubia" rollout to finish: 1 out of 3 new replicas have been updated... +Waiting for deployment "kubia" rollout to finish: 2 out of 3 new replicas have been updated... +Waiting for deployment "kubia" rollout to finish: 1 old replicas are pending termination... +deployment "kubia" successfully rolled out +``` + +`curl` 을 때려보면 에러가 발생하는 것을 확인할 수 있다. + +롤백을 위해서는 다음과 같이 마지막 rollout 을 취소하면 된다. + +``` +$ kubectl rollout undo deployment kubia +deployment.apps/kubia rolled back +``` + +> `undo` 명령은 rollout 이 진행 중인 경우에도 사용할 수 있다. 새로 생성된 pod 들은 삭제되고 삭제되었던 pod 들은 다시 생성된다. + +#### Rollout history 확인하기 + +롤백이 가능한 이유는 history 가 저장되고 있기 때문이다. ReplicaSet 안에 revision history 가 저장되고 있다. Rollout 이 완료되었을 때 ReplicaSet 이 삭제되지 않으므로, 임의의 revision 으로 롤백할 수 있게 된다. + +History 확인은 `kubectl rollout history deployment ` 으로 한다. + +``` +$ kubectl rollout history deployment kubia +deployment.apps/kubia +REVISION CHANGE-CAUSE +1 kubectl create --filename=kubia-deployment-v1.yaml --record=true +3 kubectl create --filename=kubia-deployment-v1.yaml --record=true +4 kubectl create --filename=kubia-deployment-v1.yaml --record=true +``` + +특정 revision 으로 롤백하고 싶다면, + +```bash +$ kubectl rollout undo deployment kubia --to-revision=1 +``` + +과 같이 `--to-revision` 옵션을 사용하면 된다. + +위에서 Deployment 생성시 `--record` 명령을 사용했기 때문에 `CHANGE-CAUSE` 에 revision history 가 상세하게 남게 된다. + +> `--record` 를 사용하지 않고 Deployment 를 생성하면 history 에서 `CHANGE-CAUSE` 열이 `` 으로 표시된다. +> +> ``` +> $ kubectl rollout history deployment kubia +> deployment.apps/kubia +> REVISION CHANGE-CAUSE +> 1 \ +> 2 \ +> ``` +> +> 또한, ReplicaSet 을 강제로 삭제하게 되면 그와 관련된 revision 도 함께 삭제된다. +> ``` +> $ kubectl rollout history deployment kubia +> deployment.apps/kubia +> REVISION CHANGE-CAUSE +> 2 \ +> ``` +> +> 그러므로 `kubectl rollout undo` 도 사용이 불가능하다. +> ``` +> $ kubectl rollout undo deployment kubia +> error: no rollout history found for deployment "kubia" +> ``` +> 그냥 궁금해서 테스트했는데 뒤에 나와있다. ㅋㅋ + +그렇다면 revision 이 생길 때마다 ReplicaSet 이 남아있게 되므로 이는 작업할 때 매우 불편할 것이다. 그래서 `revisionHistoryLimit` 옵션을 Deployment 에 주게 되면 해당 개수 만큼만 revision history 가 남는다. + +> `revisionHistoryLimit` 을 0으로 설정하게 되면 ReplicaSet 이 자동으로 정리된다. 하지만 이 경우 롤백이 불가능하며, rollout 을 취소할 수 없게 된다. + +> Deployment 를 수정하면서 과거의 ReplicaSet 을 다시 이용하게 되면 해당 ReplicaSet 에 있던 revision 기록은 삭제된다. + +### 9.3.4 Controlling the rate of the rollout + +앞에서 rolling update 를 할 때는 pod 를 하나씩 교체했다. 하지만 이것도 (rate) 설정할 수 있다. + +#### `maxSurge` and `maxUnavailable` + +- `maxSurge`: Replica count 보다 추가로 존재할 수 있는 pod 의 개수의 최댓값이다. 기본값은 25% (replica count 의 최대 25% 만 더 생성할 수 있다) 이다. 계산시 소수점은 올린다. +- `maxUnavailable`: Replica count 중 동작이 중지된 pod 의 개수의 최댓값이다. 기본값은 25% (replica count 의 최대 25% 만 unavailable 일 수 있다) 이다. 계산시 소수점은 버린다. + +두 값 모두 백분율 값이 아닌 정수로도 설정할 수 있다. + +> 테스트 할 때 replica count 는 3이었으므로, `maxSurge` 는 ceil(3 * 0.25) = 1 이었고, `maxUnavailable` 은 floor(3 * 0.25) = 0 이었기 때문에 rolling update 시 pod 를 최대 한 개 추가로 생성할 수 있었던 것이며, 3개의 pod 는 항상 동작하고 있어야 하므로 새로운 pod 가 생성된 다음에서야 기존 pod 를 삭제할 수 있었던 것이다. + +`maxUnavailable` 이 1일 때 반드시 최대 1개만 unavailable 이라는 의미는 아니다. `Replica count - 1` 개가 available 해야한다는 의미이다. 그래서 만약 `maxSurge` 가 2 이고 replica count 가 3이라면, 최소 2개만 available 이면 되므로 rollout 시 기존 pod 를 즉시 하나 삭제하여 2개를 available 로 남기고, 새로운 pod 3개를 생성하게 된다. 생성한 즉시에는 당연히 unavailable 이므로 이 순간에는 unavailable pod 개수는 3이다. + +> `maxSurge`, `maxUnavailable` 은 replica count 에서 더하거나 빼는 값임을 기억하면 될 듯 하다. + +### 9.3.5 Rollout 일시정지하기 + +Rollout 하는 도중 일부 pod 에만 업데이트를 적용하고 조금 지켜본 다음 정상 작동한다면 나머지에도 적용하고 싶을 수 있다. (canary release) 이런 경우 업데이트된 내용으로 pod 를 새로 띄우거나 할 필요 없이 rollout 과정을 잠시 중단하면 된다. + +``` +$ kubectl set image deployment kubia nodejs=luksa/kubia:v4 +deployment.apps/kubia image updated + +$ kubectl rollout pause deployment kubia +deployment.apps/kubia paused + +$ kubectl rollout status deployment kubia +Waiting for deployment "kubia" rollout to finish: 1 out of 3 new replicas have been updated... +``` + +하나만 교체하고 나머지는 그대로인 상태에서 rollout 을 중지했다. `curl` 을 때려 확인해 보면 일부 요청은 새로운 버전의 pod 가 처리하고 있는 것을 확인할 수 있다. + +새로운 버전을 그대로 배포해도 괜찮겠다면, rollout 을 재개한다. + +``` +$ kubectl rollout resume deployment kubia +deployment.apps/kubia resumed +``` + +#### 일시정지의 단점 + +새롭게 생성된 pod 가 어떤 비율이 되었을 때 자동으로 pause 해주는 기능은 없다. 사실 그래서 canary release 를 하는 올바른 방법은 새로운 Deployment 를 생성하여 적당히 scaling 하는 것이다. + +#### Pause deployment + +Deployment 를 일시정지 할 수 있다. Deployment 를 일시정지한 후 필요한 설정 변경을 한 뒤에 Deployment 를 resume 하면 rollout 이 진행된다. + +> 왜 필요할까 생각해 보니, 여러 개의 설정을 변경하는 경우 설정을 변경할 때마다 rollout 이 trigger 될 수 있다는 문제가 있다. 이를 막기 위해 Deployment 를 pause 해둔 뒤 여러 설정을 변경하고 resume 하면 rollout 을 한 번만 수행하여 변경된 설정을 모두 반영할 수 있게 된다. + +### 9.3.6 Blocking rollouts of bad versions + +`minReadySeconds` 는 비정상적인 버전을 배포하는 것을 막기 위해 사용하는 옵션이다. + +새로 생성된 pod 는 `READY` 상태로 `minReadySeconds` 만큼의 시간이 지나야 available 상태로 취급된다. 이 옵션이 유의미한 이유는 `maxUnavailable` 때문인데, available pod 가 일정 개수 이상 있어야 rolling update 를 할 수 있게 된다. Available pod 개수가 충족되지 않으면 rollout 이 진행될 수 없다. + +> Pod 가 `READY` 상태가 되려면 모든 컨테이너에서 readiness probe 가 성공해야 한다. + +실제로는 `minReadySeconds` 를 큰 값으로 설정해서, pod 가 `READY` 상태가 되어 실제 서비스 요청을 받고 나서도 오랜 시간동안 문제가 없는지 확인한 뒤 available pod 로 처리한다. + +> 큰 값으로 설정하면 규모가 큰 서비스는 rolling 엄청 오래 걸리겠다. + +#### 버그가 있는 버전에 readiness probe 적용하여 rollout + +이번에는 컨테이너에 `readinessProbe` 를 설정할 것이다. + +```yaml +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + name: kubia +spec: + replicas: 3 + minReadySeconds: 10 # READY 상태로 10초 있어야 한다 + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 # 3개는 항상 동작 중이도록 한다 + type: RollingUpdate + template: + metadata: + name: kubia + labels: + app: kubia + spec: + containers: + - image: luksa/kubia:v3 + name: nodejs + readinessProbe: + periodSeconds: 1 # 1초마다 GET 요청을 보낸다 + httpGet: + path: / + port: 8080 +``` + +`kubectl apply -f ...` 으로 Deployment 를 업데이트한다. 그리고 rollout status 를 확인해본다. + +``` +$ kubectl rollout status deployment kubia +Waiting for deployment "kubia" rollout to finish: 1 out of 3 new replicas have been updated... +``` + +더 이상 출력이 되지 않는다. `kubectl get po` 로 확인해 보면 pod 하나가 `READY` 상태가 아닌 것을 볼 수 있다. + +``` +$ kubectl get po +NAME READY STATUS RESTARTS AGE +kubia-86499d4c5f-pdfgt 0/1 Running 0 13s +kubia-bcf9bb974-9425g 1/1 Running 0 7m10s +kubia-bcf9bb974-9cq7f 1/1 Running 0 7m12s +kubia-bcf9bb974-k7cxf 1/1 Running 0 7m14s +``` + +`describe po` 로 확인해 보면 readiness probe 가 실패했다고 나와있으며, `curl` 로 확인해보면 과거 버전 pod 로만 요청이 가고있음을 확인할 수 있다. + +당연히, available 상태가 되지 않았으므로 rollout 은 더 이상 진행될 수 없으며 (`maxUnavailable`) `READY` 상태가 아닌 pod 들은 Service Endpoints 에서 제거되기 때문에 과거 버전 pod 로만 요청이 가게 된다. + +> Service Endpoint 에서 추가/제거 되는 기준은 pod 가 `READY` 인지 아닌지 이다. 우선 `curl` 로 요청을 계속 보내고 있는 상태에서 버그가 있는 버전으로 rolling update 를 해보니 중간에 에러가 난 요청들이 보이긴 했다. +> +> 4번째 요청까지는 OK 응답이 돌아오므로, readiness probe 가 이 pod 는 `READY` 라고 했을 것이다. 그러면서 Service Endpoints 에 이 pod 의 IP 가 추가된 것이며, 내가 보낸 `curl` 요청을 받을 수 있었던 것이다. +> +> Readiness probe 는 주기적으로 실행되므로, 어느 시점부터 실패했을 것이므로 `READY` 상태가 아니게 되고 unavailable 상태가 지속되면서 rollout 은 중단된 것이다. +> +> 결국 중간에 요청이 비정상적으로 처리되는 경우가 있었다는 것은 실제 서비스에서 일부 사용자들은 오류를 겪을 수도 있다는 것인데 이것이 불가피한 것인지 아닌지는 상황에 따라 다를 것 같다. 책에서는 모든 pod 가 잘못된 pod 로 교체되는 것에 비하면 낫다고 하는데, 이렇게 생각해도 과연 괜찮을련지 ㅋㅋ + +#### Rollout deadline + +Rollout 이 10분간 진전이 없으면 failed 처리된다. `kubectl describe` 로 확인해 보면 `ProgressDeadlineExceeded` condition 이 발생해있다. + +> `kubectl rollout status` 에서는 다음과 같이 에러가 발생한다. +> ``` +> $ kubectl rollout status deployment kubia +> error: deployment "kubia" exceeded its progress deadline +> ``` + +이 값 또한 `progressDeadlineSeconds` 로 설정할 수 있다. + +#### Bad rollout 중단하기 + +`kubectl rollout undo` 를 이용해서 중단하면 된다. + +> Note 에는 future version 들에서 자동으로 중단될거라고 하는데, 나는 자동으로 중단되지 않았다. Unavailable pod 가 1시간 넘게 남아있었다. 수동으로 `undo` 해주니 그제서야 `Terminating` 으로 변경되었다. + +--- + +## Discussion & Additional Topics + +### BlueGreenDeployment + +- https://martinfowler.com/bliki/BlueGreenDeployment.html + +### Canary Release + +- https://martinfowler.com/bliki/CanaryRelease.html + - 일부 사용자들에게만 new version 으로 서비스 하는 것 \ No newline at end of file diff --git a/_posts/Development/Kubernetes/2021-05-17-10-statefulsets.md b/_posts/Development/Kubernetes/2021-05-17-10-statefulsets.md new file mode 100644 index 0000000..186f5ad --- /dev/null +++ b/_posts/Development/Kubernetes/2021-05-17-10-statefulsets.md @@ -0,0 +1,519 @@ +--- +share: true +toc: true +categories: [Development, Kubernetes] +tags: [kubernetes, sre, devops] +title: "10. StatefulSets: Deploying Replicated Stateful Applications" +date: "2021-05-17" +github_title: "2021-05-17-10-statefulsets" +image: + path: /assets/img/posts/k8s-10.jpeg +--- + +![k8s-10.jpeg](../../../assets/img/posts/k8s-10.jpeg) _A stateful pod may be rescheduled to a different node, but it retains the name, hostname, and storage. (출처: https://livebook.manning.com/book/kubernetes-in-action/chapter-10)_ + +### 주요 내용 + +- StatefulSet 에 대한 이해 +- Stateful application 배포하기 +- DNS SRV record 를 이용한 peer discovery + +## 10.1 Replicating stateful pods +--- + +도입 질문: 각 pod replica 가 하나씩 PV 를 갖게 할 수는 없을까? + +ReplicaSet 의 pod template 에서 PVC (PersistentVolumeClaim) 를 사용하게 되면, 모든 replica 가 하나의 PV (PersistentVolume) 을 참조하게 된다. + +그래서 *하나의* ReplicaSet 으로는 distributed data store 를 만들 수 없다. 지금까지 살펴본 API object 만으로는 조금 복잡하다. + +### 10.1.1 Running multiple replicas with separate storage for each + +Pod 의 replica 들을 만들고 싶은데 각각이 자신만의 storage volume 을 갖게 하려면 어떻게 해야하는가? + +#### Pod 직접 만들어서 띄우기 + +Kubernetes 의 철학에 어긋난다. + +#### One ReplicaSet per pod instance + +각 ReplicaSet 의 replica count 를 1로 설정하고, 각 ReplicaSet 이 PVC 를 사용하도록 하면 여러 개의 pod 가 생성되며 각각이 자신만의 volume 을 갖도록 구성할 수 있다. + +직접 pod 를 만들어 띄우는 것과 비교하면 automatic scheduling 이 지원되므로 좀 더 낫지만, scaling 을 수동으로 해야한다는 점에서 불편하다. + +#### Multiple directories in the same volume + +또 하나의 방법으로는, pod 들이 하나의 PV 를 사용하되, PV 내의 서로 다른 폴더를 사용하도록 하는 방법이 있다. + +한편 이렇게 하면 ReplicaSet 이 알아서 pod 를 생성하므로, 각 pod 에게 PV 내의 어떤 폴더를 저장 공간으로 사용하라고 임의로 지정할 수 없다. (물론 앱 내부적으로 폴더를 선택하는 로직을 추가 구현할 수 있긴 하겠지만...) + +### 10.1.2 Providing a stable identity for each pod + +저장 공간 뿐만 아니라, 어떤 애플리케이션의 경우 장기간 안정적으로 유지되는 state 가 필요할 수 있다. 특히 IP 와 hostname 같은 네트워크 정보의 경우 pod 이 rescheduling 되면 바뀌게 된다. 대표적으로 distributed stateful applications 의 경우 이러한 네트워크 정보가 바뀌면 클러스터 내의 정보를 수시로 업데이트 해줘야 하는 오버헤드가 발생한다. + +#### Dedicated service for each pod instance + +위 문제를 회피하는 방법으로는 service 를 생성하여 IP 를 할당하고 각 pod 가 service endpoints 에 추가되도록 하면 된다. + +이 방법도 그리 깔끔하지 않다. 각 pod 들은 자신이 어떤 service 를 통해 expose 되어있는지 알 수 없고 (자신의 stable IP 를 모른다), 다른 pod 들에게 자신의 IP 를 알릴 수 없다. + +Kubernetes 에서는 이러한 문제를 **StatefulSet** 으로 해결한다. + +## 10.2 Understanding StatefulSets +--- + +이런 경우, ReplicaSet 보다는 StatefulSet 을 사용하여 각 pod 들이 stable 한 이름과 상태를 갖도록 한다. + +### 10.2.1 StatefulSets vs ReplicaSets + +#### Pets vs Cattle 비유 + +우리는 앱 인스턴스를 pet 처럼 대하려는 경향이 있다. 이름을 부여하고, 각 인스턴스를 개별적으로 고려한다. 하지만, 보통 인스턴스를 cattle 로 대하고 개별적인 인스턴스에는 특별히 관심을 주지 않는 것이 나을 때가 많다. 이렇게 하면 문제가 있는 인스턴스를 고민 없이 교체할 수 있다. + +상태가 없는 앱의 경우 cattle 과 같다. 인스턴스 하나에 문제가 생겨도, 새로 만들어서 교체해버리면 겉으로는 차이가 보이지 않는다. 반면, 상태가 있는 앱의 경우 pet 과 같다. 인스턴스에 문제가 생기면, 마치 pet 이 사라졌다고 티나지 않게 대체가 불가능하듯, 인스턴스도 대체가 불가능하다. 대체하려면 기존의 인스턴스와 정확히 똑같은 상태를 가지고 있어야 한다. + +#### StatefulSets vs ReplicaSets / ReplicationControllers + +그래서 ReplicaSet 이나 ReplicationController 에 의해 관리되는 replica 들은 cattle 에 가깝다. 상태를 가지고 있지 않으므로 언제든 교체될 수 있다. + +반면 상태를 갖는 (stateful) 앱의 경우 pod 인스턴스 가 죽으면 새로운 인스턴스 를 생성할 때 전의 인스턴스와 동일한 이름, 네트워크 정보와 상태를 가져야 한다. *StatefulSet 을 사용하면 이런 일이 가능해진다.* + +StatefulSet 은 pod 들이 자신의 정보와 상태를 유지하면서 reschedule 될 수 있도록 보장해준다. 이뿐만 아니라 ReplicaSet 때처럼 replica count 를 지정할 수 있어 scaling 이 가능하며, pod template 을 지정할 수도 있다. + +ReplicaSet 과 다른 점은 StatefulSet 이 생성한 pod 들은 서로의 exact copy 가 아니라는 점이다. 각 pod 마다 자신만의 volume 을 가질 수도 있고, 생성될 때마다 예측하기 쉬운 (그리고 안정적인) 정보를 갖는다. + +> 여기서 예측하기 쉽다는게...? + +### 10.2.2 Providing a stable network identity + +StatefulSet 을 이용해서 pod 를 생성하면 zero-based index 를 기반으로 번호가 주어진다. 그 번호를 이용해 pod 의 이름과 hostname 을 가져오고, 각 pod 에 storage 를 붙일 수 있게 된다. + +이름에 번호가 주어지기 때문에 이름은 예측하기 쉬우며, 랜덤한 이름이 부여될 때보다 잘 정리되어 있다. + +#### Governing service + +상태를 갖는 (stateful) pod 의 경우, 서로 통신할 때 특정 상태를 갖는 특정 pod 에서 작업을 요청하게 되므로 hostname 으로 reference 가 가능해야한다. + +그래서 StatefulSet 을 사용하면 StatefulSet 에 대응하는 governing headless service 를 생성하여 각 pod 에 네트워크 정보를 부여할 것이 강제된다. 이렇게 하면 service 를 통해 각 pod 는 DNS entry 를 갖게 되며, 클러스터 내의 다른 리소스에서 hostname 을 확인할 수 있게 된다. (FQDN 사용) + +#### Replacing lost pets + +StatefulSet 으로 관리되는 pod 중 하나가 사라지면, StatefulSet 이 자동으로 reschedule 해준다. 이 때 ReplicaSet 과는 달리, 새로 생긴 pod 는 사라진 pod 와 동일한 이름과 hostname 을 갖도록 생성된다. + +#### Scaling a StatefulSet + +Scale up 하는 경우, replica count 에 맞게 index 값이 이름에 부여된다. 반면 scale down 하는 경우 index 가 가장 큰 pod 부터 삭제하므로, 어떤 pod 가 삭제될지 사전에 알 수 있다. + +몇몇 stateful 애플리케이션은 빠른 scale down 을 잘 처리하지 못하는 경우가 있어 StatefulSet 에서는 한 번에 하나씩만 scale down 할 수 있다. + +> Distributed data store 의 경우 여러 개의 pod 가 한꺼번에 삭제되면, 데이터가 유실될 수 있다. 하나씩만 scale down 을 지원하게 되면 데이터의 copy 가 추가로 없는 경우 다른 곳에 백업을 해둘 수 있게 된다. + +이러한 이유로 만약 임의의 인스턴스가 정상이 아니면, StatefulSet 의 scale down 은 불가능하다. + +> Scalue up 할 때도 1개씩 하는 것 같다! + +### 10.2.3 Providing stable dedicated storage to each stateful instance + +위에서 pod 의 정보를 안정적으로 유지하는 방법을 살펴봤는데, 저장공간은 어떻게 하는가? 특히 rescheduling 되는 경우에도 잘 처리해줘야 한다. + +당연히 stateful pod 와 연결된 storage 는 persistent 해야 하고 pod 에 종속적이지 않아야한다. + +한편 PVC 의 경우 PV 와 일대일로 대응되기 때문에 StatefulSet 의 pod 들은 각각 다른 PVC 를 reference 해야 하는 상황이 된다. StatefulSet 은 이 문제도 해결해준다. + +#### Volume claim template + +StatefulSet 이 PVC 도 만들어 주는데, volume claim template 을 사용하면 pod 를 새로 띄울 때 자연스럽게 PVC 를 pod 에 연결해준다. + +#### PVC 의 생성과 삭제 이해 + +StatefulSet 을 scale up 하는 경우 pod 와 PVC 가 새롭게 생기지만, scale down 하는 경우 pod 만 삭제하고 PVC 는 그대로 둔다. 만약 PVC 를 지워버리면 PV 는 recycle 되거나 삭제되어 내용이 유실된다. + +StatefulSet 을 사용하는 경우는 말 그대로 state 가 중요하므로, pod 가 지워졌더라도 PV 안의 데이터는 중요하다. 그래서 PV 를 free 하려면 PVC 를 수동으로 지워줘야 한다. + +#### PVC reattach + +또한 scale down 이후 PVC 가 유지되기 때문에, 다시 scale up 하는 경우 같은 PVC 를 새로운 pod 에 연결하여 예전 pod 가 삭제되기 전 PV 의 상태를 그대로 사용할 수 있게 된다. 실수로 scale down 해도 원상 복구가 가능하다. + +### 10.2.4 Understanding StatefulSet guarantees + +StatefulSet 들이 무엇을 보장해주는지 살펴본다. + +#### Implications of stable identity and storage + +만약 Kubernetes 가 새로운 pod 를 생성했는데 기존 pod 가 사실 삭제되지 않았다면, 같은 정보를 가진 2개의 pod 가 동시에 존재하는 상황이 생길 수도 있다. 같은 저장소를 사용하므로 각 pod 내의 프로세스가 같은 파일에 write 할 수도 있다. + +#### StatefulSet's at-most-one semantics + +따라서 Kubernetes 에서는 같은 정보를 가지고 같은 PVC 에 bind 된 stateful pod 가 동시에 2개 이상 존재하지 않도록 특별히 주의한다. 즉 StatefulSet 은 stateful pod 가 최대 1개만 존재하도록 보장해야 하며, 이를 *at-most-one* semantics 라고 한다. + +따라서 StatefulSet 의 입장에서는 새로운 pod 를 생성하기 전에 생성할 pod 의 정보와 같은 정보를 가진 pod 가 없음을 **확신**할 수 있어야 한다. 이 때문에 노드에 문제가 생기는 경우 처리 방법이 크게 달라진다. + +뒤에서 더 자세히 살펴보고, 우선 StatefulSet 을 생성하는 방법부터 살펴본다. + +## 10.3 Using a StatefulSet +--- + +### 10.3.1 Creating the app and container image + +실습에 사용할 앱은 POST 요청을 받으면 request body 를 `/var/data/kubia.txt` 에 저장하고, GET 요청을 받으면 hostname 과 `/var/data/kubia.txt` 의 내용을 돌려준다. + +### 10.3.2 Deploying the app through a StatefulSet + +StatefulSet 을 이용해 앱을 배포하기 위해서는 PV 와 governing service 를 만들어줘야 한다. + +#### PV 생성하기 (Without dynamic provisioning) + +실습에서는 replica 를 3개 만들 것이므로 PV 를 3개 만들어야 한다. + +```yaml +kind: List +apiVersion: v1 +items: +- apiVersion: v1 + kind: PersistentVolume + metadata: + name: pv-a + spec: + capacity: + storage: 1Mi + accessModes: + - ReadWriteOnce + persistentVolumeReclaimPolicy: Recycle + hostPath: + path: /tmp/pv-a +- apiVersion: v1 + kind: PersistentVolume + metadata: + name: pv-b + spec: + capacity: + storage: 1Mi + accessModes: + - ReadWriteOnce + persistentVolumeReclaimPolicy: Recycle + hostPath: + path: /tmp/pv-b +- apiVersion: v1 + kind: PersistentVolume + metadata: + name: pv-c + spec: + capacity: + storage: 1Mi + accessModes: + - ReadWriteOnce + persistentVolumeReclaimPolicy: Recycle + hostPath: + path: /tmp/pv-c +``` + +`List` 로 만들어서 여러 object 를 한꺼번에 생성할 수 있다. + +#### Governing service + +Headless service 도 하나 생성한다. + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: kubia +spec: + clusterIP: None # headless + selector: + app: kubia + ports: + - name: http + port: 80 +``` + +#### StatefulSet 생성 + +```yaml +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: kubia +spec: + serviceName: kubia + replicas: 2 + selector: + matchLabels: + app: kubia # app=kubia label 이 있어야 선택 + template: + metadata: + labels: + app: kubia + spec: + containers: + - name: kubia + image: luksa/kubia-pet + ports: + - name: http + containerPort: 8080 + volumeMounts: + - name: data + mountPath: /var/data # volume mount 위치 + volumeClaimTemplates: # PVC template + - metadata: + name: data + spec: + resources: + requests: + storage: 1Mi + accessModes: + - ReadWriteOnce +``` + +ReplicaSet, Deployment 와 다른 점은 `volumeClaimTemplate` 가 있다는 점이다. `data` 라는 이름의 volume claim template 을 만들어서 pod 이 생길 때마다 PVC 를 하나씩 생성하고 pod 에 연결해준다. + +Replica 수를 2로 설정했는데, pod 은 하나씩 생성된다. 이는 race condition 을 방지하기 위해서이다. + +``` +$ kubectl get pod +NAME READY STATUS RESTARTS AGE +kubia-0 1/1 Running 0 3m37s +kubia-1 1/1 Running 0 3m29s +``` + +Pod 이름 뒤에 zero-based index 가 추가되어있는 것도 확인 가능하다. + +``` +$ kubectl get pvc +NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE +data-kubia-0 Bound pvc-9ea59858-ecc9-4549-ba87-4db46e8f1f79 1Mi RWO standard 98s +data-kubia-1 Bound pvc-7a58e057-beb9-40a8-adc2-8c46043fbce2 1Mi RWO standard 92s +``` + +또 PVC 가 생성된 것도 확인할 수 있다. + +> 분명 앞에서 PV 생성해 뒀는데 그걸 안 쓰고 minikube 가 알아서 PV 를 새로 만들어서 사용해 버린다. + +### 10.3.3 Playing with your pods + +Pod 에 접속을 해보자. 단 service 가 headless 하므로 각 pod 에 직접 접속해야한다. + +보통은 pod 안에 들어가서 `curl` 을 때려보거나 포트 포워딩을 하겠지만 이번에는 API server 를 사용하여 pod 로 proxy 해본다. + +#### Communicating with pods through the API server + +다음 URL 로 보내면 특정 pod 로 요청을 보낼 수 있게 된다. + +``` +:/api/v1/namespaces/default/pods//proxy/ +``` + +한편 API server 에 요청을 보내는 것은 인증 절차 등이 필요해 복잡하다는 것을 알고 있다. 그래서 `kubectl proxy` 를 이용해서 요청을 보낸다. 이제 아래와 같이 하면 `kubia-0` pod 에 요청을 보낼 수 있다. + +``` +$ curl localhost:8001/api/v1/namespaces/default/pods/kubia-0/proxy/ +You've hit kubia-0 +Data stored on this pod: No data posted yet +``` + +이제 POST 요청을 보내본다. + +``` +$ curl -X POST localhost:8001/api/v1/namespaces/default/pods/kubia-0/proxy/ \ + -d "This is a request for kubia-0 pod." +Data stored on pod kubia-0 +``` + +다시 GET 요청을 보내보면 응답이 정상적으로 온다. + +``` +$ curl localhost:8001/api/v1/namespaces/default/pods/kubia-0/proxy/ +You've hit kubia-0 +Data stored on this pod: This is a request for kubia-0 pod. +``` + +한편, `kubia-1` pod 에는 아무것도 저장되어 있지 않다. + +``` +$ curl localhost:8001/api/v1/namespaces/default/pods/kubia-1/proxy/ +You've hit kubia-1 +Data stored on this pod: No data posted yet +``` + +확실히 각 pod 가 state 를 갖는다는 사실을 확인할 수 있다. + +#### Deleting a stateful pod + +이제 pod 를 한 번 지워보고 rescheduling 될 때 같은 storage 에 연결되는지 확인할 것이다. + +먼저 `kubectl delete pod kubia-0` 를 입력한 뒤 pod 가 삭제될 때까지 대기한다. 조금 기다리면 StatefulSet 이 새로 pod 를 생성하는 것을 확인할 수 있다. + +> Pod 삭제 명령을 입력했는데 엄청 오래걸리는 것은 기분 탓인가, 아니면 stateful pod 라서 오래걸리는 건가... 1분 20초 정도 걸렸다. + +같은 storage 에 연결되었는지 확인하기 위해 GET 요청을 보내본다. + +``` +$ curl localhost:8001/api/v1/namespaces/default/pods/kubia-0/proxy/ +You've hit kubia-0 +Data stored on this pod: This is a request for kubia-0 pod. +``` + +이전과 같은 정보를 저장하고 있는 것을 확인했다. + +#### Exposing stateful pods through a non-headless service + +Service 를 만들어서 expose 해본다. + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: kubia-public +spec: + selector: + app: kubia + ports: + - port: 80 + targetPort: 8080 +``` + +이 service 는 `ClientIP` service 이므로 클러스터 안에서만 접근이 가능하다. 앞에서와 마찬가지로 API server 를 proxy 로 이용해 접속할 수 있다. + +``` +$ curl localhost:8001/api/v1/namespaces/default/services/kubia-public/proxy/ +You've hit kubia-3 +Data stored on this pod: No data posted yet +``` + +다만 random 한 pod 에서 응답을 보내준다. + +## 10.4 Discovering peers in a StatefulSet +--- + +마지막으로 살펴볼 내용은 peer discovery 이다. StatefulSet 의 pod 이 다른 pod 를 발견할 수 있어야 한다. 물론 API server 를 사용할수도 있겠지만, 애플리케이션이 직접 요청을 보내게 되기 때문에 Kubernetes 에 종속되게 된다. 다른 방법이 필요하며, 여기서는 SRV record 를 사용할 것이다. + +#### SRV records + +특정 서비스를 제공하는 hostname 과 port 를 알려주기 위한 record 이다. + +실행한 pod 들의 SRV record 를 확인하기 위해 `dig` 를 사용할 것이다. + +``` +$ kubectl run -it srvlookup --image=tutum/dnsutils --rm \ + --restart=Never -- dig SRV kubia.default.svc.cluster.local +``` + +조금 기다리면 다음과 같이 결과가 나온다. + +``` +;; ANSWER SECTION: +kubia.default.svc.cluster.local. 30 IN SRV 0 25 80 kubia-0.kubia.default.svc.cluster.local. +kubia.default.svc.cluster.local. 30 IN SRV 0 25 80 kubia-1.kubia.default.svc.cluster.local. + +;; ADDITIONAL SECTION: +kubia-0.kubia.default.svc.cluster.local. 30 IN A 172.17.0.3 +kubia-2.kubia.default.svc.cluster.local. 30 IN A 172.17.0.6 +``` + +`ANSWER SECTION` 을 보면 service 뒤에 있는 2개의 pod 에 대한 record 가 나온다. 각 pod 는 A record 도 가지고 있으며, `ADDITIONAL SECTION` 에 적혀있다. + +그러므로 pod 가 StatefulSet 내의 다른 pod 정보를 얻고 싶다면, SRV DNS lookup 한 번을 해주면 된다. + +> 참고로 결과에 있는 SRV record 의 순서는 임의로 변경될 수 있다. + +### 10.4.1 Implementing peer discovery through DNS + +이제 pod 들이 서로 통신하도록 하려고 한다. + +이제 client 는 `kubia-public` service 를 이용해서 요청을 보낼 것인데, 그러면 요청이 임의의 pod 로 전달될 수 있다. 클러스터에 pod 가 여러 개 있으므로 데이터를 여러 개 저장할 수 있으나, 요청이 모든 pod 에 한 번씩 도달할 때까지 요청을 계속 반복해야 한다. + +따라서 pod 가 요청을 받으면 다른 pod 로부터 정보를 모두 받아 데이터를 돌려주도록 할 것이다. 이를 위해 SRV DNS lookup 을 하고, 각 record 에 요청을 보내 데이터를 받아온 다음 돌려주면 된다. + +(구현체는 생략) + +### 10.4.2 Updating a StatefulSet + +`kubectl edit statefulset ` 을 이용하면 된다. 실습을 위해 replica count 는 3으로, container 도 새롭게 구현한 container 로 교체해줄 것이다. + +수정이 완료되면 자동으로 rollout 이 진행된다. + +``` +$ kubectl rollout status statefulset kubia +Waiting for 1 pods to be ready... +Waiting for partitioned roll out to finish: 2 out of 3 new pods have been updated... +Waiting for 1 pods to be ready... +partitioned roll out complete: 3 new pods have been updated... +``` + +### 10.4.3 Trying out your clustered data store + +이제 테스트를 해본다. 먼저 데이터를 POST 한다. 요청은 *service* 로 보내야 한다. + +``` +$ curl -X POST localhost:8001/api/v1/namespaces/default/services/kubia-public/proxy/ \ + -d "Good morning" +Data stored on pod kubia-1 + +$ curl -X POST localhost:8001/api/v1/namespaces/default/services/kubia-public/proxy/ \ + -d "Good afternoon" +Data stored on pod kubia-0 + +$ curl -X POST localhost:8001/api/v1/namespaces/default/services/kubia-public/proxy/ \ + -d "Some random data" +Data stored on pod kubia-2 +``` + +이제 데이터를 읽어온다. + +``` +$ curl localhost:8001/api/v1/namespaces/default/services/kubia-public/proxy/ +You've hit kubia-2 +Data stored in the cluster: +- kubia-2.kubia.default.svc.cluster.local: Some random data +- kubia-0.kubia.default.svc.cluster.local: Good afternoon +- kubia-1.kubia.default.svc.cluster.local: Good evening +``` + +Pod 가 직접 peer discovery 를 진행하므로 scaling 에도 유연하게 대처할 수 있다. + +## 10.5 Understanding how StatefulSets deal with node failures +--- + +10.2.4 에서 *at-most-one* semantics 를 설명하면서 StatefulSet 은 같은 상태를 가진 pod 를 2개 만들어서는 안된다고 했었다. 한편 노드가 작동을 중단하는 경우 Kubernetes 는 그 노드에 있던 리소스의 정보를 알 수 없게 된다. Pod 가 실제로 작동을 중지한 것인지, 아니면 접근이 가능한데 그냥 Kubelet 이 노드의 상태를 master 에 보고하는 것을 중단했을 수도 있다. + +그래서 StatefulSet 은 클러스터 관리자가 알려주기 전까지는 대체 pod 를 생성하지 않게된다. 클러스터 관리자는 pod 를 완전히 삭제하거나, 노드를 삭제할 수도 있다. + +마지막으로 한 노드의 네트워크가 유실되는 상황에서 StatefulSet 의 동작을 살펴볼 것이다. + +### 10.5.1 Simulating a node's disconnection from the network + +minikube 에서는 안된다! GKE 의 이야기이다. + +노드에 ssh 로 접속해서 `sudo ifconfig eth0 down` 을 입력하면 네트워크를 죽일 수 있다! + +이제 노드의 네트워크 인터페이스가 꺼졌기 때문에 노드의 Kubelet 은 Kubernetes API server 와 연결할 수 없다. Pod 들이 잘 동작하고 있다고 보고할 수 없게 되는 것이다. + +조금 기다린 뒤 `kubectl get nodes` 를 해보면 노드가 `NotReady` 상태로 변경된다. 그래서 `kubectl get pod` 를 하면 `STATUS` 가 `Unknown` 으로 변경된다. + +#### Status 가 Unknown 이면 어떤 일이 일어나는가 + +만약 노드의 네트워크가 금방 다시 연결되면 pod 상태를 다시 보고할 것이므로 `Ready` 상태가 된다. 반면 오랜 시간동안 (이 시간은 설정 가능하다) `Unknown` 상태이면 Kubernetes control plane 에서 pod 를 자동으로 삭제한다. + +Kubelet 이 pod 이 삭제 명령을 받으면 삭제를 시작하여 `Terminating` 으로 변경되는데, 지금 상황에서는 네트워크가 유실되었으므로 Kubelet 이 pod 삭제 명령을 알 수 없다. 그래서 pod 는 게속 실행 중이게 된다. + +`kubectl describe pod ` 으로 유실된 노드의 pod 를 살펴보면 `Terminating` 으로 변경되어있고, `Reason: NodeLost` 라고 적혀있다. 단, 이는 어디까지나 control plane 의 관점이며, 실제로 노드 안에서 pod 는 정상적으로 돌아가고 있다. + +### 10.5.2 Deleting the pod manually + +Rescheduling 을 하려면 수동으로 삭제해줘야 한다. 한편 `kubectl delete pod` 명령으로는 삭제가 불가능하다. 네트워크가 유실되었기 때문에 이 명령이 전달되지 않는다. 강제 삭제해야한다. + +**이 명령은 노드가 더 이상 동작하지 않는 다는 것을 확신할 때만 입력해야 한다.** + +```bash +$ kubectl delete pod --force --grace-period 0 +``` + +이렇게 `--force`, `--grace-period 0` 옵션을 모두 줘서 삭제해야 한다. 원래는 Kubelet 이 컨테이너가 모두 중단되었고, 삭제가 완료되었다고 알려줘야 하지만 이 옵션을 주게 되면 기다리지 않고 즉시 삭제한 것으로 처리한다. + +--- + +## Discussion & Additional Topics + +### Pets vs Cattle Analogy + +- http://cloudscaling.com/blog/cloud-computing/the-history-of-pets-vs-cattle/ diff --git a/assets/img/posts/k8s-03.jpeg b/assets/img/posts/k8s-03.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..20310dfa7bc6cc84aa03420cc37ed53deb5a454d GIT binary patch literal 47648 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 O7chU)3OK(%Xa67Y!1bR1 literal 0 HcmV?d00001 diff --git a/assets/img/posts/k8s-04.jpeg b/assets/img/posts/k8s-04.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..1c78f9df9385191d28af583fcb5301652f72fd9b GIT binary patch literal 25032 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 SZ#PcI-`hXM0pQzb6aNEX$H4Lc literal 0 HcmV?d00001 diff --git a/assets/img/posts/k8s-05.jpeg b/assets/img/posts/k8s-05.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..9201398f6da7f0a2fba5218adaaa03752a50d225 GIT binary patch literal 37186 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%0A*VZbx2z&OlP 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 literal 0 HcmV?d00001 diff --git a/assets/img/posts/k8s-06.jpeg b/assets/img/posts/k8s-06.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..f3f1f1318d993b294b292e353f590c4f0265e742 GIT binary patch literal 44356 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 VCD_v1X!&J9#p;}IZeRRa`VZ$@p&S4J literal 0 HcmV?d00001 diff --git a/assets/img/posts/k8s-07.jpeg b/assets/img/posts/k8s-07.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..499a308e88f01e9e9eefea075950a533e08f7d13 GIT binary patch literal 58138 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 H{yFh~Hv{an literal 0 HcmV?d00001 diff --git a/assets/img/posts/k8s-10.jpeg b/assets/img/posts/k8s-10.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..91adb3634f148e1ea055d12ed4d3b29cc73f2d5d GIT binary patch literal 25284 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