[ko] Update outdated files in dev-1.22-ko.4 M43-55

This commit is contained in:
Jihoon Seo
2021-12-13 17:49:54 +09:00
parent 854318acaa
commit 7d020244e7
12 changed files with 56 additions and 349 deletions
@@ -91,6 +91,7 @@ kubectl [command] [TYPE] [NAME] [flags]
* `KUBERNETES_SERVICE_HOST` 환경 변수가 설정되어 있고,
* `KUBERNETES_SERVICE_PORT` 환경 변수가 설정되어 있고,
* kubectl 명령에 네임스페이스를 명시하지 않으면
kubectl은 자신이 클러스터 내부에서 실행되고 있다고 가정한다.
kubectl은 해당 서비스어카운트의 네임스페이스(파드의 네임스페이스와 동일하다)를 인식하고 해당 네임스페이스에 대해 동작한다.
이는 클러스터 외부에서 실행되었을 때와는 다른데,
@@ -36,10 +36,9 @@ Go에 의해 정의된 `runtime.GOOS` 값을 kubelet이 읽어서 이 레이블
적용 대상: 네임스페이스
`NamespaceDefaultLabelName` [기능 게이트](/ko/docs/reference/command-line-tools-reference/feature-gates/)가
활성화되어 있으면,
쿠버네티스 API 서버가 모든 네임스페이스에 이 레이블을 적용한다.
레이블의 값은 네임스페이스의 이름으로 적용된다.
({{< glossary_tooltip text="컨트롤 플레인" term_id="control-plane" >}}의 일부인)
쿠버네티스 API 서버가 이 레이블을 모든 네임스페이스에 설정한다.
레이블의 값은 네임스페이스의 이름으로 적용된다. 이 레이블의 값을 변경할 수는 없다.
레이블 {{< glossary_tooltip text="셀렉터" term_id="selector" >}}를 이용하여 특정 네임스페이스를 지정하고 싶다면
이 레이블이 유용할 수 있다.
@@ -63,6 +62,16 @@ kubelet이 호스트네임을 읽어서 이 레이블의 값으로 채운다. `k
이 레이블은 토폴로지 계층의 일부로도 사용된다. [`topology.kubernetes.io/zone`](#topologykubernetesiozone)에서 세부 사항을 확인한다.
## kubernetes.io/change-cause {#change-cause}
예시: `kubernetes.io/change-cause=kubectl edit --record deployment foo`
적용 대상: 모든 오브젝트
이 어노테이션은 어떤 오브젝트가 왜 변경되었는지 그 이유를 담는다.
어떤 오브젝트를 변경할 수도 있는 `kubectl` 명령에 `--record` 플래그를 사용하면 이 레이블이 추가된다.
## controller.kubernetes.io/pod-deletion-cost {#pod-deletion-cost}
예시: `controller.kubernetes.io/pod-deletion-cost=10`
+16
View File
@@ -49,3 +49,19 @@ Kompose의 용도
* 도커 컴포즈 파일을 쿠버네티스 오브젝트로 변환
* 로컬 도커 개발 환경에서 나의 애플리케이션을 쿠버네티스를 통해 관리하도록 이전
* V1 또는 V2 도커 컴포즈 `yaml` 파일 또는 [분산 애플리케이션 번들](https://docs.docker.com/compose/bundles/)을 변환
## Kui
[`Kui`](https://github.com/kubernetes-sigs/kui)는 입력으로 일반적인 `kubectl` 커맨드 라인 요청을 받고
출력으로 그래픽적인 응답을 제공하는 GUI 도구이다.
Kui는 입력으로 일반적인 `kubectl` 커맨드 라인 요청을 받고 출력으로 그래픽적인 응답을 제공한다.
Kui는 ASCII 표 대신 정렬 가능한 표를 GUI로 제공한다.
Kui를 사용하면 다음의 작업이 가능하다.
* 자동으로 생성되어 길이가 긴 리소스 이름을 클릭하여 복사할 수 있다.
* `kubectl` 명령을 입력하면 실행되는 모습을 볼 수 있으며, `kubectl` 보다 더 빠른 경우도 있다.
* {{< glossary_tooltip text="잡" term_id="job">}}을 조회하여
실행 형상을 워터폴 그림으로 확인한다.
* 탭이 있는 UI를 이용하여 클러스터의 자원을 클릭 동작으로 확인할 수 있다.
@@ -1,5 +1,7 @@
---
title: 클라이언트 라이브러리
content_type: concept
weight: 30
---
@@ -35,7 +37,6 @@ API 호출 또는 요청/응답 타입을 직접 구현할 필요는 없다.
| JavaScript | [github.com/kubernetes-client/javascript](https://github.com/kubernetes-client/javascript) | [둘러보기](https://github.com/kubernetes-client/javascript/tree/master/examples)
| Python | [github.com/kubernetes-client/python/](https://github.com/kubernetes-client/python/) | [둘러보기](https://github.com/kubernetes-client/python/tree/master/examples)
## 커뮤니티에 의해 관리되는 클라이언트 라이브러리
{{% thirdparty-content %}}
@@ -70,7 +71,6 @@ API 호출 또는 요청/응답 타입을 직접 구현할 필요는 없다.
| Python | [github.com/tomplus/kubernetes_asyncio](https://github.com/tomplus/kubernetes_asyncio) |
| Python | [github.com/Frankkkkk/pykorm](https://github.com/Frankkkkk/pykorm) |
| Ruby | [github.com/abonas/kubeclient](https://github.com/abonas/kubeclient) |
| Ruby | [github.com/Ch00k/kuber](https://github.com/Ch00k/kuber) |
| Ruby | [github.com/k8s-ruby/k8s-ruby](https://github.com/k8s-ruby/k8s-ruby) |
| Ruby | [github.com/kontena/k8s-client](https://github.com/kontena/k8s-client) |
| Rust | [github.com/clux/kube-rs](https://github.com/clux/kube-rs) |
@@ -1,5 +1,7 @@
---
title: 쿠버네티스 API 헬스(health) 엔드포인트
content_type: concept
weight: 50
---
@@ -18,11 +20,11 @@ weight: 50
`/readyz` 엔드포인트는 `--shutdown-delay-duration` [플래그](/docs/reference/command-line-tools-reference/kube-apiserver) 옵션을 사용하여 정상적(graceful)으로 셧다운할 수 있다.
API 서버의 `healthz`/`livez`/`readyz` 를 사용하는 머신은 HTTP 상태 코드에 의존해야 한다.
상태 코드 200은 호출된 엔드포인트에 따라 API 서버의 `healthy`/`live`/`ready` 상태를 나타낸다.
아래 표시된 더 자세한 옵션은 운영자가 클러스터나 특정 API 서버의 상태를 디버깅하는데 사용할 수 있다.
아래 표시된 더 자세한 옵션은 운영자가 클러스터를 디버깅하거나 특정 API 서버의 상태를 이해하는 데 사용할 수 있다.
다음의 예시는 헬스 API 엔드포인트와 상호 작용할 수 있는 방법을 보여준다.
모든 엔드포인트 `verbose` 파라미터를 사용하여 검사 항목과 상태를 출력할 수 있다.
모든 엔드포인트에 대해, `verbose` 파라미터를 사용하여 검사 항목과 상태를 출력할 수 있다.
이는 운영자가 머신 사용을 위한 것이 아닌, API 서버의 현재 상태를 디버깅하는데 유용하다.
```shell
@@ -79,7 +79,7 @@ systemd가 기본적으로 cgroup v2를 사용하지 않는 경우, 커널 명
# dnf install -y grubby && \
sudo grubby \
--update-kernel=ALL \
--args=systemd.unified_cgroup_hierarchy=1"
--args="systemd.unified_cgroup_hierarchy=1"
```
구성을 적용하려면 노드를 재부팅해야 한다.
@@ -243,7 +243,7 @@ sudo mkdir -p $DOWNLOAD_DIR
crictl 설치(kubeadm / Kubelet 컨테이너 런타임 인터페이스(CRI)에 필요)
```bash
CRICTL_VERSION="v1.17.0"
CRICTL_VERSION="v1.22.0"
ARCH="amd64"
curl -L "https://github.com/kubernetes-sigs/cri-tools/releases/download/${CRICTL_VERSION}/crictl-${CRICTL_VERSION}-linux-${ARCH}.tar.gz" | sudo tar -C $DOWNLOAD_DIR -xz
```
@@ -38,8 +38,8 @@ Kubespray는 [Ansible](https://docs.ansible.com/) 플레이북, [인벤토리](h
* 타겟 서버들은 docker 이미지를 풀(pull) 하기 위해 반드시 인터넷에 접속할 수 있어야 한다. 아니라면, 추가적인 설정을 해야 한다 ([오프라인 환경 확인하기](https://github.com/kubernetes-sigs/kubespray/blob/master/docs/offline-environment.md))
* 타겟 서버들의 **IPv4 포워딩**이 활성화되어야 한다
* **SSH 키**가 인벤토리의 모든 서버들에 복사되어야 한다
* **방화벽은 관리되지 않는다**. 사용자가 예전 방식대로 고유한 규칙을 구현해야 한다. 디플로이먼트 과정에서의 문제를 방지하려면 방화벽을 비활성화해야 한다
* 만약 kubespray가 루트가 아닌 사용자 계정에서 실행되었다면, 타겟 서버에서 알맞은 권한 확대 방법이 설정되어야 한다. 그 뒤 `ansible_become` 플래그나 커맨드 파라미터들, `--become` 또는 `-b` 가 명시되어야 한다
* **방화벽은 kubespray에 의해 관리되지 않는다**. 사용자는 필요에 따라 적절한 규칙을 구현해야 한다. 디플로이먼트 과정에서의 문제를 방지하려면 방화벽을 비활성화해야 한다
* 만약 kubespray가 루트가 아닌 사용자 계정에서 실행되었다면, 타겟 서버에서 알맞은 권한 확대 방법이 설정되어야 하며, `ansible_become` 플래그나 커맨드 파라미터들, `--become` 또는 `-b` 가 명시되어야 한다
Kubespray는 환경에 맞는 프로비저닝을 돕기 위해 아래와 같은 서비스를 제공한다:
@@ -214,117 +214,9 @@ apiserver의 인증서 제공을 검증하는데 사용되어야 한다.
## 클러스터에서 실행되는 서비스로 접근
이전 장은 쿠버네티스 API server 접속에 대한 내용을 다루었다. 이번 장은
쿠버네티스 클러스터 상에서 실행되는 다른 서비스로의 연결을 다룰 것이다.
이전 섹션에서는 쿠버네티스 API 서버에 연결하는 방법을 소개하였다. 쿠버네티스 클러스터에서 실행되는 다른 서비스에 연결하는 방법은 [클러스터 접근](/ko/docs/tasks/access-application-cluster/access-cluster/) 페이지를 참조한다.
쿠버네티스에서, [노드](/ko/docs/concepts/architecture/nodes/),
[파드](/ko/docs/concepts/workloads/pods/) 및 [서비스](/ko/docs/concepts/services-networking/service/)는 모두
고유한 IP를 가진다. 당신의 데스크탑 PC와 같은 클러스터 외부 장비에서는
클러스터 상의 노드 IP, 파드 IP, 서비스 IP로 라우팅되지 않아서 접근을
할 수 없을 것이다.
### 통신을 위한 방식들
클러스터 외부에서 노드, 파드 및 서비스에 접속하기 위한 몇 가지 옵션이 있다.
- 공인 IP를 통해 서비스에 접근.
- 클러스터 외부에서 접근할 수 있도록 `NodePort` 또는 `LoadBalancer` 타입의
서비스를 사용한다. [서비스](/ko/docs/concepts/services-networking/service/)와
[kubectl expose](/docs/reference/generated/kubectl/kubectl-commands/#expose) 문서를 참조한다.
- 클러스터 환경에 따라, 서비스는 회사 네트워크에만 노출되기도 하며,
인터넷에 노출되는 경우도 있다. 이 경우 노출되는 서비스의 보안 여부를 고려해야 한다.
해당 서비스는 자체적으로 인증을 수행하는가?
- 파드는 서비스 뒤에 위치시킨다. 레플리카들의 집합에서 특정 파드 하나에 debugging 같은 목적으로 접근하려면
해당 파드에 고유의 레이블을 붙이고 셀렉터에 해당 레이블을 선택하는 신규 서비스를 생성한다.
- 대부분의 경우에는 애플리케이션 개발자가 노드 IP를 통해 직접 노드에
접근할 필요는 없다.
- Proxy Verb를 사용하여 서비스, 노드, 파드에 접근.
- 원격 서비스에 접근하기에 앞서 apiserver의 인증과 인가를 받아야 한다.
서비스가 인터넷에 노출하기에 보안이 충분하지 않거나 노드 IP 상의 포트에
접근을 하려고 하거나 debugging을 하려면 이를 사용한다.
- 어떤 web 애플리케이션에서는 프록시가 문제를 일으킬 수 있다.
- HTTP/HTTPS에서만 동작한다.
- [여기](#수작업으로-apiserver-proxy-url들을-구축)에서 설명하고 있다.
- 클러스터 내 노드 또는 파드에서 접근.
- 파드를 실행한 다음, [kubectl exec](/docs/reference/generated/kubectl/kubectl-commands/#exec)를 사용하여 해당 파드의 셸로 접속한다.
해당 셸에서 다른 노드, 파드, 서비스에 연결한다.
- 어떤 클러스터는 클러스터 내의 노드에 ssh 접속을 허용하기도 한다. 이런 클러스터에서는
클러스터 서비스에 접근도 가능하다. 이는 비표준 방식으로 특정 클러스터에서는 동작하지만
다른 클러스터에서는 동작하지 않을 수 있다. 브라우저와 다른 도구들이 설치되지 않았거나 설치되었을 수 있다. 클러스터 DNS가 동작하지 않을 수도 있다.
### 빌트인 서비스 검색
일반적으로 kube-system에 의해 클러스터에 실행되는 몇 가지 서비스가 있다.
`kubectl cluster-info` 커맨드로 이 서비스의 리스트를 볼 수 있다.
```shell
kubectl cluster-info
```
결괏값은 다음과 같을 것이다.
```
Kubernetes master is running at https://104.197.5.247
elasticsearch-logging is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy
kibana-logging is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/kibana-logging/proxy
kube-dns is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/kube-dns/proxy
grafana is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/monitoring-grafana/proxy
heapster is running at https://104.197.5.247/api/v1/namespaces/kube-system/services/monitoring-heapster/proxy
```
이는 각 서비스에 접근하기 위한 proxy-verb URL을 보여준다.
예를 들어 위 클러스터는 클러스터 수준의 logging(Elasticsearch 사용)이 활성화되었으므로 적절한 인증을 통과하여
`https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/`로 접근할 수 있다. 예를 들어 kubectl proxy로
`http://localhost:8080/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/`를 통해 logging에 접근할 수도 있다.
(인증을 통과하는 방법이나 kubectl proxy를 사용하는 것은 [쿠버네티스 API를 사용해서 클러스터에 접근하기](/ko/docs/tasks/administer-cluster/access-cluster-api/)을 참조한다.)
#### 수작업으로 apiserver proxy URL을 구축
위에서 언급한 것처럼 서비스의 proxy URL을 검색하는 데 `kubectl cluster-info` 커맨드를 사용할 수 있다. 서비스 endpoint, 접미사, 매개변수를 포함하는 proxy URL을 생성하려면 해당 서비스에
`http://`*`kubernetes_master_address`*`/api/v1/namespaces/`*`namespace_name`*`/services/`*`service_name[:port_name]`*`/proxy` 형식의 proxy URL을 덧붙인다.
당신이 포트에 이름을 지정하지 않았다면 URL에 *port_name* 을 지정할 필요는 없다. 이름이 있는 포트와 이름이 없는 포트 모두에 대하여, *port_name* 이 들어갈 자리에 포트 번호를 기재할 수도 있다.
기본적으로 API server는 http를 사용하여 서비스를 프록시한다. https를 사용하려면 다음과 같이 서비스 네임의 접두사에 `https:`를 붙인다.
`http://`*`kubernetes_master_address`*`/api/v1/namespaces/`*`namespace_name`*`/services/`*`https:service_name:[port_name]`*`/proxy`
URL의 네임 부분에 지원되는 양식은 다음과 같다.
* `<service_name>` - http를 사용하여 기본값 또는 이름이 없는 포트로 프록시한다.
* `<service_name>:<port_name>` - http를 사용하여 지정된 포트 이름 또는 포트 번호로 프록시한다.
* `https:<service_name>:` - https를 사용하여 기본값 또는 이름이 없는 포트로 프록시한다. (마지막 콜론:에 주의)
* `https:<service_name>:<port_name>` - https를 사용하여 지정된 포트 이름 또는 포트 번호로 프록시한다.
##### 예제들
* Elasticsearch 서비스 endpoint `_search?q=user:kimchy`에 접근하려면 `http://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/_search?q=user:kimchy`를 사용할 수 있다.
* Elasticsearch 클러스터 상태 정보 `_cluster/health?pretty=true`에 접근하려면 `https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/_cluster/health?pretty=true`를 사용할 수 있다.
```json
{
"cluster_name" : "kubernetes_logging",
"status" : "yellow",
"timed_out" : false,
"number_of_nodes" : 1,
"number_of_data_nodes" : 1,
"active_primary_shards" : 5,
"active_shards" : 5,
"relocating_shards" : 0,
"initializing_shards" : 0,
"unassigned_shards" : 5
}
```
### 클러스터 상에서 실행되는 서비스에 웹브라우저를 사용하여 접근
브라우저의 주소창에 apiserver proxy url을 넣을 수도 있다. 하지만
- 웹브라우저는 일반적으로 토큰을 전달할 수 없으므로 basic (password) auth를 사용해야 할 것이다. basic auth를 수용할 수 있도록 apiserver를 구성할 수 있지만,
당신의 클러스터가 basic auth를 수용할 수 있도록 구성되어 있지 않을 수도 있다.
- 몇몇 web app은 동작하지 않을 수도 있다. 특히 proxy path prefix를 인식하지 않는 방식으로 url을
구성하는 client side javascript를 가진 web app은 동작하지 않을 수 있다.
## 요청 redirect
## redirect 요청하기
redirect 기능은 deprecated되고 제거 되었다. 대신 (아래의) 프록시를 사용하기를 바란다.
@@ -70,7 +70,7 @@ jsonpath에서 `.items[*]` 부분은 생략해야 하는데, 이는 명령어가
반복하여 출력할 수 있다.
```shell
kubectl get pods --all-namespaces -o=jsonpath='{range .items[*]}{"\n"}{.metadata.name}{":\t"}{range .spec.containers[*]}{.image}{", "}{end}{end}' |\
kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{"\n"}{.metadata.name}{":\t"}{range .spec.containers[*]}{.image}{", "}{end}{end}' |\
sort
```
@@ -80,7 +80,7 @@ sort
명령어 결과값은 `app=nginx` 레이블에 일치하는 파드만 출력한다.
```shell
kubectl get pods --all-namespaces -o=jsonpath="{.items[*].spec.containers[*].image}" -l app=nginx
kubectl get pods --all-namespaces -o jsonpath="{.items[*].spec.containers[*].image}" -l app=nginx
```
## 파드 네임스페이스로 필터링된 컨테이너 이미지 목록 보기
@@ -86,7 +86,18 @@ heapster is running at https://104.197.5.247/api/v1/namespaces/kube-system/servi
위에서 언급한 것처럼, `kubectl cluster-info` 명령을 사용하여 서비스의 프록시 URL을 검색한다. 서비스 엔드포인트, 접미사 및 매개 변수를 포함하는 프록시 URL을 작성하려면, 서비스의 프록시 URL에 추가하면 된다.
`http://`*`kubernetes_master_address`*`/api/v1/namespaces/`*`namespace_name`*`/services/`*`[https:]service_name[:port_name]`*`/proxy`
포트에 대한 이름을 지정하지 않은 경우, URL에 *port_name* 을 지정할 필요가 없다.
포트에 대한 이름을 지정하지 않은 경우, URL에 *port_name* 을 지정할 필요가 없다. 또한, 이름이 지정된 포트와 지정되지 않은 포트 모두에 대해, *port_name* 자리에 포트 번호를 기재할 수도 있다.
기본적으로, API 서버는 서비스로의 프록시를 HTTP로 제공한다. HTTPS를 사용하려면, 서비스 이름 앞에 `https:` 를 추가한다.
`http://<쿠버네티스_컨트롤_플레인_주소>/api/v1/namespaces/<네임스페이스_이름>/services/<서비스_이름>/proxy`
URL에서 `<서비스_이름>` 이 지원하는 형식은 다음과 같다.
* `<서비스_이름>` - 기본 포트 또는 이름이 지정되지 않은 포트로 http를 사용하여 프록시
* `<서비스_이름>:<포트_이름>` - 기재된 포트 이름 또는 포트 번호로 http를 사용하여 프록시
* `https:<서비스_이름>:` - 기본 포트 또는 이름이 지정되지 않은 포트로 https를 사용하여 프록시(맨 끝의 콜론에 유의)
* `https:<서비스_이름>:<포트_이름>` - 기재된 포트 이름 또는 포트 번호로 https를 사용하여 프록시
##### 예제
@@ -1,224 +0,0 @@
---
title: 고가용성 쿠버네티스 클러스터 컨트롤 플레인 설정하기
content_type: task
---
<!-- overview -->
{{< feature-state for_k8s_version="v1.5" state="alpha" >}}
구글 컴퓨트 엔진(Google Compute Engine, 이하 GCE)의 `kube-up`이나 `kube-down` 스크립트에 쿠버네티스 컨트롤 플레인 노드를 복제할 수 있다. 하지만 이러한 스크립트들은 프로덕션 용도로 사용하기에 적합하지 않으며, 프로젝트의 CI에서만 주로 사용된다.
이 문서는 kube-up/down 스크립트를 사용하여 고가용(HA) 컨트롤 플레인을 관리하는 방법과 GCE와 함께 사용하기 위해 HA 컨트롤 플레인을 구현하는 방법에 관해 설명한다.
## {{% heading "prerequisites" %}}
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
<!-- steps -->
## HA 호환 클러스터 시작
새 HA 호환 클러스터를 생성하려면, `kube-up` 스크립트에 다음 플래그를 설정해야 한다.
* `MULTIZONE=true` - 서버의 기본 영역(zone)과 다른 영역에서 컨트롤 플레인 kubelet이 제거되지 않도록 한다.
여러 영역에서 컨트롤 플레인 노드를 실행(권장됨)하려는 경우에 필요하다.
* `ENABLE_ETCD_QUORUM_READ=true` - 모든 API 서버에서 읽은 내용이 최신 데이터를 반환하도록 하기 위한 것이다.
true인 경우, Etcd의 리더 복제본에서 읽는다.
이 값을 true로 설정하는 것은 선택 사항이다. 읽기는 더 안정적이지만 느리게 된다.
선택적으로, 첫 번째 컨트롤 플레인 노드가 생성될 GCE 영역을 지정할 수 있다.
다음 플래그를 설정한다.
* `KUBE_GCE_ZONE=zone` - 첫 번째 컨트롤 플레인 노드가 실행될 영역.
다음 샘플 커맨드는 europe-west1-b GCE 영역에 HA 호환 클러스터를 구성한다.
```shell
MULTIZONE=true KUBE_GCE_ZONE=europe-west1-b ENABLE_ETCD_QUORUM_READS=true ./cluster/kube-up.sh
```
위의 커맨드는 하나의 컨트롤 플레인 노드를 포함하는 클러스터를 생성한다.
그러나 후속 커맨드로 새 컨트롤 플레인 노드를 추가할 수 있다.
## 새 컨트롤 플레인 노드 추가
HA 호환 클러스터를 생성했다면, 여기에 컨트롤 플레인 노드를 추가할 수 있다.
`kube-up` 스크립트에 다음 플래그를 사용하여 컨트롤 플레인 노드를 추가한다.
* `KUBE_REPLICATE_EXISTING_MASTER=true` - 기존 컨트롤 플레인 노드의 복제본을
만든다.
* `KUBE_GCE_ZONE=zone` - 컨트롤 플레인 노드가 실행될 영역.
반드시 다른 컨트롤 플레인 노드가 존재하는 영역과 동일한 지역(region)에 있어야 한다.
HA 호환 클러스터를 시작할 때, 상속되는 `MULTIZONE`이나 `ENABLE_ETCD_QUORUM_READS` 플래그를 따로
설정할 필요는 없다.
다음 샘플 커맨드는 기존 HA 호환 클러스터에서
컨트롤 플레인 노드를 복제한다.
```shell
KUBE_GCE_ZONE=europe-west1-c KUBE_REPLICATE_EXISTING_MASTER=true ./cluster/kube-up.sh
```
## 컨트롤 플레인 노드 제거
다음 플래그가 있는 `kube-down` 스크립트를 사용하여 HA 클러스터에서 컨트롤 플레인 노드를 제거할 수 있다.
* `KUBE_DELETE_NODES=false` - kubelet을 삭제하지 않기 위한 것이다.
* `KUBE_GCE_ZONE=zone` - 컨트롤 플레인 노드가 제거될 영역.
* `KUBE_REPLICA_NAME=replica_name` - (선택) 제거할 컨트롤 플레인 노드의 이름.
명시하지 않으면, 해당 영역의 모든 복제본이 제거된다.
다음 샘플 커맨드는 기존 HA 클러스터에서 컨트롤 플레인 노드를 제거한다.
```shell
KUBE_DELETE_NODES=false KUBE_GCE_ZONE=europe-west1-c ./cluster/kube-down.sh
```
## 동작에 실패한 컨트롤 플레인 노드 처리
HA 클러스터의 컨트롤 플레인 노드 중 하나가 동작에 실패하면,
클러스터에서 해당 노드를 제거하고 동일한 영역에 새 컨트롤 플레인
노드를 추가하는 것이 가장 좋다.
다음 샘플 커맨드로 이 과정을 시연한다.
1. 손상된 복제본을 제거한다.
```shell
KUBE_DELETE_NODES=false KUBE_GCE_ZONE=replica_zone KUBE_REPLICA_NAME=replica_name ./cluster/kube-down.sh
```
<ol start="2"><li>기존 복제본을 대신할 새 노드를 추가한다.</li></ol>
```shell
KUBE_GCE_ZONE=replica-zone KUBE_REPLICATE_EXISTING_MASTER=true ./cluster/kube-up.sh
```
## HA 클러스터에서 컨트롤 플레인 노드 복제에 관한 모범 사례
* 다른 영역에 컨트롤 플레인 노드를 배치하도록 한다. 한 영역이 동작에 실패하는 동안,
해당 영역에 있는 컨트롤 플레인 노드도 모두 동작에 실패할 것이다.
영역 장애를 극복하기 위해 노드를 여러 영역에 배치한다
(더 자세한 내용은 [멀티 영역](/ko/docs/setup/best-practices/multiple-zones/)를 참조한다).
* 두 개의 노드로 구성된 컨트롤 플레인은 사용하지 않는다. 두 개의 노드로 구성된
컨트롤 플레인에서의 합의를 위해서는 지속적 상태(persistent state) 변경 시 두 컨트롤 플레인 노드가 모두 정상적으로 동작 중이어야 한다.
결과적으로 두 컨트롤 플레인 노드 모두 필요하고, 둘 중 한 컨트롤 플레인 노드에만 장애가 발생해도
클러스터의 심각한 장애 상태를 초래한다.
따라서 HA 관점에서는 두 개의 노드로 구성된 컨트롤 플레인은
단일 노드로 구성된 컨트롤 플레인보다도 못하다.
* 컨트롤 플레인 노드를 추가하면, 클러스터의 상태(Etcd)도 새 인스턴스로 복사된다.
클러스터가 크면, 이 상태를 복제하는 시간이 오래 걸릴 수 있다.
이 작업은 [etcd 관리 가이드](https://etcd.io/docs/v2.3/admin_guide/#member-migration)에 기술한 대로
Etcd 데이터 디렉터리를 마이그레이션하여 속도를 높일 수 있다.
(향후에 Etcd 데이터 디렉터리 마이그레이션 지원 추가를 고려 중이다)
<!-- discussion -->
## 구현 지침
![ha-control-plane](/docs/images/ha-control-plane.svg)
### 개요
위의 그림은 3개의 컨트롤 플레인 노드와 컴포넌트를 고가용 클러스터로 구성한 형상을 보여준다. 해당 컨트롤 플레인 노드의 컴포넌트들은 다음의 방법을 차용하고 있다.
- etcd: 인스턴스는 합의(consensus)를 통해서 클러스터링되어 있다.
- 컨트롤러들, 스케줄러, 클러스터 오토-스케일러: 리스(lease) 메커니즘을 통해 클러스터에서 각각 단 하나의 인스턴스만 활성화될 것이다.
- 애드-온(add-on) 메니저: 애드-온들이 동기화를 유지하도록 각각 독립적으로 동작한다.
추가적으로, API 서버들 앞에서 동작하는 로드 밸런서는 내부와 외부 트래픽을 컨트롤 플레인 노드들로 연결(route)한다.
각 컨트롤 플레인 노드는 다음 모드에서 다음 구성 요소를 실행한다.
* Etcd 인스턴스: 모든 인스턴스는 합의를 사용하여 함께 클러스터화 한다.
* API 서버: 각 서버는 내부 Etcd와 통신한다. 클러스터의 모든 API 서버가 가용하게 된다.
* 컨트롤러, 스케줄러, 클러스터 오토스케일러: 임대 방식을 이용한다. 각 인스턴스 중 하나만이 클러스터에서 활성화된다.
* 애드온 매니저: 각 매니저는 애드온의 동기화를 유지하려고 독립적으로 작업한다.
또한 API 서버 앞단에 외부/내부 트래픽을 라우팅하는 로드 밸런서가 있을 것이다.
### 로드 밸런싱
두 번째 컨트롤 플레인 노드를 배치할 때, 두 개의 복제본에 대한 로드 밸런서가 생성될 것이고, 첫 번째 복제본의 IP 주소가 로드 밸런서의 IP 주소로 승격된다.
비슷하게 끝에서 두 번째의 컨트롤 플레인 노드를 제거한 후에는 로드 밸런서가 제거되고
해당 IP 주소는 마지막으로 남은 복제본에 할당된다.
로드 밸런서 생성 및 제거는 복잡한 작업이며, 이를 전파하는 데 시간(~20분)이 걸릴 수 있다.
### 컨트롤 플레인 서비스와 Kubelet
쿠버네티스 서비스에서 최신의 쿠버네티스 API 서버 목록을 유지하는 대신,
시스템은 모든 트래픽을 외부 IP 주소로 보낸다.
* 단일 노드 컨트롤 플레인의 경우, IP 주소는 단일 컨트롤 플레인 노드를 가리킨다.
* 고가용성 컨트롤 플레인의 경우, IP 주소는 컨트롤 플레인 노드 앞의 로드밸런서를 가리킨다.
마찬가지로 Kubelet은 외부 IP 주소를 사용하여 컨트롤 플레인과 통신한다.
### 컨트롤 플레인 노드 인증서
쿠버네티스는 각 컨트롤 플레인 노드의 외부 퍼블릭 IP 주소와 내부 IP 주소를 대상으로 TLS 인증서를 발급한다.
컨트롤 플레인 노드의 임시 퍼블릭 IP 주소에 대한 인증서는 없다.
임시 퍼블릭 IP 주소를 통해 컨트롤 플레인 노드에 접근하려면, TLS 검증을 건너뛰어야 한다.
### etcd 클러스터화
etcd를 클러스터로 구축하려면, etcd 인스턴스간 통신에 필요한 포트를 열어야 한다(클러스터 내부 통신용).
이러한 배포를 안전하게 하기 위해, etcd 인스턴스간의 통신은 SSL을 이용하여 승인한다.
### API 서버 신원
{{< feature-state state="alpha" for_k8s_version="v1.20" >}}
API 서버 식별 기능은
[기능 게이트](/ko/docs/reference/command-line-tools-reference/feature-gates/)에
의해 제어되며 기본적으로 활성화되지 않는다.
{{< glossary_tooltip text="API 서버" term_id="kube-apiserver" >}}
시작 시 `APIServerIdentity` 라는 기능 게이트를 활성화하여 API 서버 신원을 활성화할 수 있다.
```shell
kube-apiserver \
--feature-gates=APIServerIdentity=true \
# …다른 플래그는 평소와 같다.
```
부트스트랩 중에 각 kube-apiserver는 고유한 ID를 자신에게 할당한다. ID는
`kube-apiserver-{UUID}` 형식이다. 각 kube-apiserver는
_kube-system_ {{< glossary_tooltip text="네임스페이스" term_id="namespace">}}에
[임대](/docs/reference/generated/kubernetes-api/{{< param "version" >}}//#lease-v1-coordination-k8s-io)를 생성한다.
임대 이름은 kube-apiserver의 고유 ID이다. 임대에는
`k8s.io/component=kube-apiserver` 라는 레이블이 있다. 각 kube-apiserver는
`IdentityLeaseRenewIntervalSeconds` (기본값은 10초)마다 임대를 새로 갱신한다. 각
kube-apiserver는 `IdentityLeaseDurationSeconds` (기본값은 3600초)마다
모든 kube-apiserver 식별 ID 임대를 확인하고,
`IdentityLeaseDurationSeconds` 이상 갱신되지 않은 임대를 삭제한다.
`IdentityLeaseRenewIntervalSeconds``IdentityLeaseDurationSeconds`
kube-apiserver 플래그 `identity-lease-renew-interval-seconds`
`identity-lease-duration-seconds`로 구성된다.
이 기능을 활성화하는 것은 HA API 서버 조정과 관련된 기능을
사용하기 위한 전제조건이다(예: `StorageVersionAPI` 기능 게이트).
## 추가 자료
[자동화된 HA 마스터 배포 - 제안 문서](https://git.k8s.io/community/contributors/design-proposals/cluster-lifecycle/ha_master.md)