Merge pull request #30412 from kubernetes/dev-1.22-ko.2

[ko] 2nd Korean localization work for v1.22
This commit is contained in:
Kubernetes Prow Robot
2021-11-09 05:39:47 -08:00
committed by GitHub
82 changed files with 2255 additions and 503 deletions
@@ -0,0 +1,319 @@
---
title: NGINX 인그레스(Ingress) 컨트롤러로 Minikube에서 인그레스 설정하기
content_type: task
weight: 100
---
<!-- overview -->
[인그레스](/ko/docs/concepts/services-networking/ingress/)는 클러스터의 서비스에 대한 외부 액세스를 허용하는 규칙을 정의하는
API 객체이다. [인그레스 컨트롤러](/ko/docs/concepts/services-networking/ingress-controllers/)는 인그레스에 설정된 규칙을 이행한다.
이 페이지에서는 HTTP URI에 따라 요청을 Service web 또는 web2로 라우팅하는 간단한 인그레스를 설정하는 방법을 보여준다.
## {{% heading "prerequisites" %}}
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
<!-- steps -->
## Minikube 클러스터 생성하기
1. **터미널 실행**을 클릭한다.
{{< kat-button >}}
1. (선택 사항) Minikube를 로컬로 설치한 경우 다음 명령을 실행한다.
```shell
minikube start
```
## 인그레스 컨트롤러 활성화
1. NGINX 인그레스 컨트롤러를 활성화하기 위해 다음 명령을 실행한다.
```shell
minikube addons enable ingress
```
1. NGINX 인그레스 컨트롤러가 실행 중인지 확인한다.
{{< tabs name="tab_with_md" >}}
{{% tab name="minikube v1.19 or later" %}}
```shell
kubectl get pods -n ingress-nginx
```
{{< note >}}이 작업은 1분 정도 소요될 수 있다.{{< /note >}}
Output:
```
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-g9g49 0/1 Completed 0 11m
ingress-nginx-admission-patch-rqp78 0/1 Completed 1 11m
ingress-nginx-controller-59b45fb494-26npt 1/1 Running 0 11m
```
{{% /tab %}}
{{% tab name="minikube v1.18.1 or earlier" %}}
```shell
kubectl get pods -n kube-system
```
{{< note >}}이 작업은 1분 정도 소요될 수 있다.{{< /note >}}
Output:
```
NAME READY STATUS RESTARTS AGE
default-http-backend-59868b7dd6-xb8tq 1/1 Running 0 1m
kube-addon-manager-minikube 1/1 Running 0 3m
kube-dns-6dcb57bcc8-n4xd4 3/3 Running 0 2m
kubernetes-dashboard-5498ccf677-b8p5h 1/1 Running 0 2m
nginx-ingress-controller-5984b97644-rnkrg 1/1 Running 0 1m
storage-provisioner 1/1 Running 0 2m
```
{{% /tab %}}
{{< /tabs >}}
```shell
kubectl get pods -n ingress-nginx
```
{{< note >}}이 작업은 1분 정도 소요될 수 있다.{{< /note >}}
Output:
```shell
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-2tgrf 0/1 Completed 0 3m28s
ingress-nginx-admission-patch-68b98 0/1 Completed 0 3m28s
ingress-nginx-controller-59b45fb494-lzmw2 1/1 Running 0 3m28s
```
## hello, world 앱 배포하기
1. 다음 명령을 사용하여 디플로이먼트(Deployment)를 생성한다.
```shell
kubectl create deployment web --image=gcr.io/google-samples/hello-app:1.0
```
Output:
```shell
deployment.apps/web created
```
1. 디플로이먼트를 노출시킨다.
```shell
kubectl expose deployment web --type=NodePort --port=8080
```
Output:
```shell
service/web exposed
```
1. 서비스(Service)가 생성되고 노드 포트에서 사용할 수 있는지 확인한다.
```shell
kubectl get service web
```
Output:
```shell
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
web NodePort 10.104.133.249 <none> 8080:31637/TCP 12m
```
1. 노드포트(NodePort)를 통해 서비스에 접속한다.
```shell
minikube service web --url
```
Output:
```shell
http://172.17.0.15:31637
```
{{< note >}}Katacoda 환경만 해당: 터미널 패널 상단에서 더하기 기호를 클릭한 다음 **Select port to view on Host 1**을 클릭한다. 노드포트(이 경우 '31637')를 입력한 다음 **Display Port**를 클릭한다.{{< /note >}}
Output:
```shell
Hello, world!
Version: 1.0.0
Hostname: web-55b8c6998d-8k564
```
이제 Minikube IP 주소와 노드포트를 통해 샘플 앱에 액세스할 수 있다. 다음 단계에서는
인그레스 리소스를 사용하여 앱에 액세스할 수 있다.
## 인그레스 리소스 생성하기
다음 파일은 hello-world.info를 통해 서비스로 트래픽을 보내는 인그레스 리소스다.
1. 다음 파일을 통해 `example-ingress.yaml`을 만든다.
{{< codenew file="service/networking/example-ingress.yaml" >}}
1. 다음 명령어를 실행하여 인그레스 리소스를 생성한다.
```shell
kubectl apply -f https://k8s.io/examples/service/networking/example-ingress.yaml
```
Output:
```shell
ingress.networking.k8s.io/example-ingress created
```
1. IP 주소가 설정되었는지 확인한다.
```shell
kubectl get ingress
```
{{< note >}}이 작업은 몇 분 정도 소요될 수 있다.{{< /note >}}
```shell
NAME CLASS HOSTS ADDRESS PORTS AGE
example-ingress <none> hello-world.info 172.17.0.15 80 38s
```
1. `/etc/hosts` 파일의 맨 아래에 다음 행을 추가한다.
{{< note >}}Minikube를 로컬에서 실행하는 경우 'minikube ip'를 사용하여 외부 IP를 가져온다. 인그레스 목록에 표시되는 IP 주소는 내부 IP가 된다.{{< /note >}}
```
172.17.0.15 hello-world.info
```
이것은 hello-world.info에서 Minikube로 요청을 보낸다.
1. 인그레스 컨트롤러가 트래픽을 전달하는지 확인한다.
```shell
curl hello-world.info
```
Output:
```shell
Hello, world!
Version: 1.0.0
Hostname: web-55b8c6998d-8k564
```
{{< note >}}Minikube를 로컬에서 실행하는 경우 브라우저에서 hello-world.info에 접속할 수 있다.{{< /note >}}
## 두 번째 디플로이먼트 생성하기
1. 다음 명령을 사용하여 v2 디플로이먼트를 생성한다.
```shell
kubectl create deployment web2 --image=gcr.io/google-samples/hello-app:2.0
```
Output:
```shell
deployment.apps/web2 created
```
1. 디플로이먼트를 노출시킨다.
```shell
kubectl expose deployment web2 --port=8080 --type=NodePort
```
Output:
```shell
service/web2 exposed
```
## 인그레스 수정하기
1. 기존 `example-ingress.yaml`을 편집하여 다음 줄을 추가한다.
```yaml
- path: /v2
pathType: Prefix
backend:
service:
name: web2
port:
number: 8080
```
1. 변경 사항을 적용한다.
```shell
kubectl apply -f example-ingress.yaml
```
Output:
```shell
ingress.networking/example-ingress configured
```
## 인그레스 테스트하기
1. Hello World 앱의 첫 번째 버전에 액세스한다.
```shell
curl hello-world.info
```
Output:
```shell
Hello, world!
Version: 1.0.0
Hostname: web-55b8c6998d-8k564
```
1. Hello World 앱의 두 번째 버전에 액세스한다.
```shell
curl hello-world.info/v2
```
Output:
```shell
Hello, world!
Version: 2.0.0
Hostname: web2-75cd47646f-t8cjk
```
{{< note >}}Minikube를 로컬에서 실행하는 경우 브라우저에서 hello-world.info 및 hello-world.info/v2에 접속할 수 있다.{{< /note >}}
## {{% heading "whatsnext" %}}
* [인그레스](/ko/docs/concepts/services-networking/ingress/)에 대해 더 보기.
* [인그레스 컨트롤러](/ko/docs/concepts/services-networking/ingress-controllers/)에 대해 더 보기.
* [서비스](/ko/docs/concepts/services-networking/service/)에 대해 더 보기.
@@ -2,8 +2,9 @@
title: 웹 UI (대시보드)
title: 쿠버네티스 대시보드를 배포하고 접속하기
description: >-
웹 UI(쿠버네티스 대시보드)를 배포하고 접속한다.
content_type: concept
weight: 10
card:
@@ -31,36 +32,39 @@ card:
## 대시보드 UI 배포
대시보드 UI는 기본으로 배포되지 않는다. 배포하려면 다음 커맨드를 동작한다.
대시보드 UI는 기본으로 배포되지 않는다. 배포하려면 다음 커맨드를 실행한다.
```
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.2.0/aio/deploy/recommended.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.3.1/aio/deploy/recommended.yaml
```
## 대시보드 UI 접근
클러스터 데이터를 보호하기 위해, 대시보드는 기본적으로 최소한의 RBAC 설정을 제공한다.
현재, 대시보드는 Bearer 토큰으로 로그인 하는 방법을 제공한다.
현재, 대시보드는 Bearer 토큰으로 로그인하는 방법을 제공한다.
본 시연을 위한 토큰을 생성하기 위해서는,
[샘플 사용자 만들기](https://github.com/kubernetes/dashboard/blob/master/docs/user/access-control/creating-sample-user.md) 가이드를 따른다.
{{< warning >}}
시연 중 생성한 샘플 사용자는 어드민 권한이 부여되며, 이는 교육 목적으로만 사용한다.
시연 중 생성한 샘플 사용자에게는 관리자(admin) 권한이 부여되며, 이는 교육 목적으로만 사용한다.
{{< /warning >}}
### 커맨드 라인 프록시
kubectl 커맨드라인 도구를 이용해 다음 커맨드를 실행함으로써 대시보드를 사용할 수 있다.
`kubectl` 커맨드라인 도구를 이용해 다음 커맨드를 실행함으로써 대시보드로의
접속을 활성화할 수 있다.
```
kubectl proxy
```
kubectl은 [http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/](http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/) 대시보드를 사용하는 것을 가능하게 해줄 것이다.
kubectl은 [http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/](http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/)를 통해 대시보드에 접속할 수 있게 해줄 것이다.
UI는 커맨드가 실행된 머신에서 _오직_ 접근 가능하다. 상세 내용은 `kubectl proxy --help` 옵션을 확인한다.
UI는 _오직_ 커맨드가 실행된 머신에서 접근 가능하다. 상세 내용은 `kubectl proxy --help` 옵션을 확인한다.
{{< note >}}
Kubeconfig 인증 방법은 외부 아이덴티티 프로이더 또는 x509 인증서를 지원하지 않는다.
Kubeconfig 인증 방법은 외부 아이덴티티 프로이더
또는 X.509 인증서를 **지원하지 않는다**.
{{< /note >}}
## 웰컴 뷰
@@ -75,7 +79,7 @@ Kubeconfig 인증 방법은 외부 아이덴티티 프로파이더 또는 x509
## 컨테이너화 된 애플리케이션 배포
대시보드를 이용하여 컨테이너화 된 애플리케이션을 디플로이먼트와 간단한 마법사를 통한 선택적인 서비스로 생성하고 배포할 수 있다.
애플리케이션 세부 정보를 수동으로 지정할 수 있고, 또는 애플리케이션 구성을 포함한 YAML, JSON 파일을 업로드할 수 있다.
애플리케이션 세부 정보를 수동으로 지정할 수 있고, 또는 애플리케이션 구성을 포함한 YAML 또는 JSON _매니페스트(manifest)_ 파일을 업로드할 수 있다.
시작하는 페이지의 상위 오른쪽 코너에 있는 **CREATE** 버튼을 클릭한다.
@@ -186,13 +190,14 @@ Kubeconfig 인증 방법은 외부 아이덴티티 프로파이더 또는 x509
### YAML 또는 JSON 파일 업로드
쿠버네티스는 선언적인 설정을 제공한다.
이 방식으로 모든 설정은 쿠버네티스 [API](/ko/docs/concepts/overview/kubernetes-api/) 리소스 스키마를
이용하여 YAML 또는 JSON 설정 파일에 저장한다.
이 방식에서는 모든 설정이 매니페스트(YAML 또는 JSON 설정 파일)에 저장된다.
매니페스트는 쿠버네티스 [API](/ko/docs/concepts/overview/kubernetes-api/) 리소스 스키마를
사용한다.
배포 마법사를 통해 애플리케이션 세부사항들을 지정하는 대신,
애플리케이션을 YAML 또는 JSON 파일로 정의할 수 있고 대시보드를 이용해서 파일을 업로드할 수 있다.
배포 마법사를 통해 애플리케이션 세부 사항들을 지정하는 대신, 애플리케이션을 하나 이상의 매니페스트로 정의할 수 있고 대시보드를 이용해서 파일을 업로드할 수 있다.
## 대시보드 사용
다음 섹션들은 어떻게 제공하고 어떻게 사용할 수 있는지에 대한 쿠버네티스 대시보드 UI의 모습을 보여준다.
### 탐색
@@ -201,9 +206,10 @@ Kubeconfig 인증 방법은 외부 아이덴티티 프로파이더 또는 x509
기본적으로 _기본_ 네임스페이스의 오프젝트만이 보이는데,
이는 탐색 창에 위치한 네임스페이스 셀렉터를 이용해 변경할 수 있다.
대시보드는 몇가지 메뉴 카테고리 중에서 대부분의 쿠버네티스 오브젝트 종류와 그룹을 보여준다.
대시보드는 몇 가지 메뉴 카테고리 중에서 대부분의 쿠버네티스 오브젝트 종류와 그룹을 보여준다.
#### 어드민 개요
클러스터와 네임스페이스 관리자에게 대시보드는 노드, 네임스페이스 그리고 퍼시스턴트 볼륨과 세부사항들이 보여진다.
노드는 모든 노드를 통틀어 CPU와 메모리 사용량을 보여준다.
세부사항은 각 노드들에 대한 사용량, 사양, 상태,
@@ -212,7 +218,7 @@ Kubeconfig 인증 방법은 외부 아이덴티티 프로파이더 또는 x509
#### 워크로드
선택된 네임스페이스에서 구동되는 모든 애플리케이션을 보여준다.
애플리케이션의 워크로드 종류(예를 들어, 디플로이먼트, 레플리카셋(ReplicaSet), 스테이트풀셋(StatefulSet))를 보여주고
애플리케이션의 워크로드 종류(예시: 디플로이먼트, 레플리카셋(ReplicaSet), 스테이트풀셋(StatefulSet))를 보여주고
각각의 워크로드 종류는 따로 보여진다.
리스트는 예를 들어 레플리카셋에서 준비된 파드의 숫자 또는 파드의 현재 메모리 사용량과 같은
워크로드에 대한 실용적인 정보를 요약한다.
@@ -230,9 +236,9 @@ Kubeconfig 인증 방법은 외부 아이덴티티 프로파이더 또는 x509
#### 스토리지
스토리지는 애플리케이션이 데이터를 저장하기 위해 사용하는 퍼시턴트 볼륨 클레임 리소스들을 보여준다.
스토리지는 애플리케이션이 데이터를 저장하기 위해 사용하는 퍼시턴트볼륨클레임 리소스들을 보여준다.
#### 컨피그 맵과 시크릿
#### 컨피그맵과 시크릿 {#config-maps-and-secrets}
클러스터에서 동작 중인 애플리케이션의 라이브 설정을 사용하는 모든 쿠버네티스 리소스들을 보여준다.
컨피그 오브젝트들을 수정하고 관리할 수 있도록 허용하며, 기본적으로는 숨겨져 있는 시크릿들을 보여준다.
@@ -146,11 +146,10 @@ curl $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure
http 클라이언트가 루트 인증서를 사용하도록 하려면 특별한 구성이
필요할 수 있다.
일부 클러스터에서, API 서버는 인증이 필요하지 않다.
로컬 호스트에서 제공되거나, 방화벽으로 보호될 수 있다. 이에 대한 표준은
없다. [쿠버네티스 API에 대한 접근 제어](/ko/docs/concepts/security/controlling-access)
클러스터 관리자로서 이를 구성하는 방법에 대해 설명한다. 이러한 접근 방식은 향후
고 가용성 지원과 충돌할 수 있다.
일부 클러스터에서, API 서버는 인증이 필요하지 않다. 로컬 호스트에서 제공되거나,
방화벽으로 보호될 수 있다. 이에 대한 표준은 없다.
[쿠버네티스 API에 대한 접근 제어](/ko/docs/concepts/security/controlling-access)는 클러스터
관리자로서 이를 구성하는 방법에 대해 설명한다. 이러한 접근 방식은 향후 고 가용성 지원과 충돌할 수 있다.
### API에 프로그래밍 방식으로 접근
@@ -1,4 +1,7 @@
---
title: DNS 서비스 사용자 정의하기
content_type: task
min-kubernetes-server-version: v1.12
@@ -133,10 +133,18 @@ Etcd 데이터 디렉터리를 마이그레이션하여 속도를 높일 수 있
## 구현 지침
![ha-master-gce](/images/docs/ha-master-gce.png)
![ha-control-plane](/docs/images/ha-control-plane.svg)
### 개요
위의 그림은 3개의 컨트롤 플레인 노드와 컴포넌트를 고가용 클러스터로 구성한 형상을 보여준다. 해당 컨트롤 플레인 노드의 컴포넌트들은 다음의 방법을 차용하고 있다.
- etcd: 인스턴스는 합의(consensus)를 통해서 클러스터링되어 있다.
- 컨트롤러들, 스케줄러, 클러스터 오토-스케일러: 리스(lease) 메커니즘을 통해 클러스터에서 각각 단 하나의 인스턴스만 활성화될 것이다.
- 애드-온(add-on) 메니저: 애드-온들이 동기화를 유지하도록 각각 독립적으로 동작한다.
추가적으로, API 서버들 앞에서 동작하는 로드 밸런서는 내부와 외부 트래픽을 컨트롤 플레인 노드들로 연결(route)한다.
각 컨트롤 플레인 노드는 다음 모드에서 다음 구성 요소를 실행한다.
* Etcd 인스턴스: 모든 인스턴스는 합의를 사용하여 함께 클러스터화 한다.
@@ -9,17 +9,17 @@ weight: 20
<!-- overview -->
이 페이지는 kubeadm으로 생성된 쿠버네티스 클러스터를
{{< skew latestVersionAddMinor -1 >}}.x 버전에서 {{< skew latestVersion >}}.x 버전으로,
{{< skew latestVersion >}}.x 버전에서 {{< skew latestVersion >}}.y(여기서 `y > x`) 버전으로 업그레이드하는 방법을 설명한다. 업그레이드가 지원되지 않는 경우
{{< skew currentVersionAddMinor -1 >}}.x 버전에서 {{< skew currentVersion >}}.x 버전으로,
{{< skew currentVersion >}}.x 버전에서 {{< skew currentVersion >}}.y(여기서 `y > x`) 버전으로 업그레이드하는 방법을 설명한다. 업그레이드가 지원되지 않는 경우
마이너 버전을 건너뛴다.
이전 버전의 kubeadm을 사용하여 생성된 클러스터 업그레이드에 대한 정보를 보려면,
이 페이지 대신 다음의 페이지들을 참고한다.
- [kubeadm 클러스터를 {{< skew latestVersionAddMinor -2 >}}에서 {{< skew latestVersionAddMinor -1 >}}로 업그레이드](https://v{{< skew latestVersionAddMinor -1 "-" >}}.docs.kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/)
- [kubeadm 클러스터를 {{< skew latestVersionAddMinor -3 >}}에서 {{< skew latestVersionAddMinor -2 >}}로 업그레이드](https://v{{< skew latestVersionAddMinor -2 "-" >}}.docs.kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/)
- [kubeadm 클러스터를 {{< skew latestVersionAddMinor -4 >}}에서 {{< skew latestVersionAddMinor -3 >}}로 업그레이드](https://v{{< skew latestVersionAddMinor -3 "-" >}}.docs.kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/)
- [kubeadm 클러스터를 {{< skew latestVersionAddMinor -5 >}}에서 {{< skew latestVersionAddMinor -4 >}}으로 업그레이드](https://v{{< skew latestVersionAddMinor -4 "-" >}}.docs.kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/)
- [kubeadm 클러스터를 {{< skew currentVersionAddMinor -2 >}}에서 {{< skew currentVersionAddMinor -1 >}}로 업그레이드](https://v{{< skew currentVersionAddMinor -1 "-" >}}.docs.kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/)
- [kubeadm 클러스터를 {{< skew currentVersionAddMinor -3 >}}에서 {{< skew currentVersionAddMinor -2 >}}로 업그레이드](https://v{{< skew currentVersionAddMinor -2 "-" >}}.docs.kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/)
- [kubeadm 클러스터를 {{< skew currentVersionAddMinor -4 >}}에서 {{< skew currentVersionAddMinor -3 >}}로 업그레이드](https://v{{< skew currentVersionAddMinor -3 "-" >}}.docs.kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/)
- [kubeadm 클러스터를 {{< skew currentVersionAddMinor -5 >}}에서 {{< skew currentVersionAddMinor -4 >}}으로 업그레이드](https://v{{< skew currentVersionAddMinor -4 "-" >}}.docs.kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/)
추상적인 업그레이드 작업 절차는 다음과 같다.
@@ -45,19 +45,19 @@ weight: 20
## 업그레이드할 버전 결정
OS 패키지 관리자를 사용하여 최신의 안정 버전({{< skew latestVersion >}})을 찾는다.
OS 패키지 관리자를 사용하여 쿠버네티스의 최신 패치 릴리스 버전({{< skew currentVersion >}})을 찾는다.
{{< tabs name="k8s_install_versions" >}}
{{% tab name="Ubuntu, Debian 또는 HypriotOS" %}}
apt update
apt-cache madison kubeadm
# 목록에서 최신 버전({{< skew latestVersion >}})을 찾는다
# {{< skew latestVersion >}}.x-00과 같아야 한다. 여기서 x는 최신 패치이다.
# 목록에서 최신 버전({{< skew currentVersion >}})을 찾는다
# {{< skew currentVersion >}}.x-00과 같아야 한다. 여기서 x는 최신 패치이다.
{{% /tab %}}
{{% tab name="CentOS, RHEL 또는 Fedora" %}}
yum list --showduplicates kubeadm --disableexcludes=kubernetes
# 목록에서 최신 버전({{< skew latestVersion >}})을 찾는다
# {{< skew latestVersion >}}.x-0과 같아야 한다. 여기서 x는 최신 패치이다.
# 목록에서 최신 버전({{< skew currentVersion >}})을 찾는다
# {{< skew currentVersion >}}.x-0과 같아야 한다. 여기서 x는 최신 패치이다.
{{% /tab %}}
{{< /tabs >}}
@@ -74,20 +74,21 @@ OS 패키지 관리자를 사용하여 최신의 안정 버전({{< skew latestVe
{{< tabs name="k8s_install_kubeadm_first_cp" >}}
{{% tab name="Ubuntu, Debian 또는 HypriotOS" %}}
# {{< skew latestVersion >}}.x-00에서 x를 최신 패치 버전으로 바꾼다.
# {{< skew currentVersion >}}.x-00에서 x를 최신 패치 버전으로 바꾼다.
apt-mark unhold kubeadm && \
apt-get update && apt-get install -y kubeadm={{< skew latestVersion >}}.x-00 && \
apt-get update && apt-get install -y kubeadm={{< skew currentVersion >}}.x-00 && \
apt-mark hold kubeadm
-
# apt-get 버전 1.1부터 다음 방법을 사용할 수도 있다
apt-get update && \
apt-get install -y --allow-change-held-packages kubeadm={{< skew latestVersion >}}.x-00
apt-get install -y --allow-change-held-packages kubeadm={{< skew currentVersion >}}.x-00
{{% /tab %}}
{{% tab name="CentOS, RHEL 또는 Fedora" %}}
# {{< skew latestVersion >}}.x-0에서 x를 최신 패치 버전으로 바꾼다.
yum install -y kubeadm-{{< skew latestVersion >}}.x-0 --disableexcludes=kubernetes
# {{< skew currentVersion >}}.x-0에서 x를 최신 패치 버전으로 바꾼다.
yum install -y kubeadm-{{< skew currentVersion >}}.x-0 --disableexcludes=kubernetes
{{% /tab %}}
{{< /tabs >}}
<br />
- 다운로드하려는 버전이 잘 받아졌는지 확인한다.
@@ -120,13 +121,13 @@ OS 패키지 관리자를 사용하여 최신의 안정 버전({{< skew latestVe
```shell
# 이 업그레이드를 위해 선택한 패치 버전으로 x를 바꾼다.
sudo kubeadm upgrade apply v{{< skew latestVersion >}}.x
sudo kubeadm upgrade apply v{{< skew currentVersion >}}.x
```
명령이 완료되면 다음을 확인해야 한다.
```
[upgrade/successful] SUCCESS! Your cluster was upgraded to "v{{< skew latestVersion >}}.x". Enjoy!
[upgrade/successful] SUCCESS! Your cluster was upgraded to "v{{< skew currentVersion >}}.x". Enjoy!
[upgrade/kubelet] Now that your control plane is upgraded, please proceed with upgrading your kubelets if you haven't already done so.
```
@@ -169,25 +170,22 @@ sudo kubeadm upgrade apply
- 모든 컨트롤 플레인 노드에서 kubelet 및 kubectl을 업그레이드한다.
{{< tabs name="k8s_install_kubelet" >}}
{{< tab name="Ubuntu, Debian 또는 HypriotOS" >}}
<pre>>
# {{< skew latestVersion >}}.x-00의 x를 최신 패치 버전으로 바꾼다
{{% tab name="Ubuntu, Debian 또는 HypriotOS" %}}
# replace x in {{< skew currentVersion >}}.x-00의 x를 최신 패치 버전으로 바꾼다
apt-mark unhold kubelet kubectl && \
apt-get update && apt-get install -y kubelet={{< skew latestVersion >}}.x-00 kubectl={{< skew latestVersion >}}.x-00 && \
apt-get update && apt-get install -y kubelet={{< skew currentVersion >}}.x-00 kubectl={{< skew currentVersion >}}.x-00 && \
apt-mark hold kubelet kubectl
-
# apt-get 버전 1.1부터 다음 방법을 사용할 수도 있다
apt-get update && \
apt-get install -y --allow-change-held-packages kubelet={{< skew latestVersion >}}.x-00 kubectl={{< skew latestVersion >}}.x-00
</pre>
{{< /tab >}}
{{< tab name="CentOS, RHEL 또는 Fedora" >}}
<pre>
# {{< skew latestVersion >}}.x-0에서 x를 최신 패치 버전으로 바꾼다
yum install -y kubelet-{{< skew latestVersion >}}.x-0 kubectl-{{< skew latestVersion >}}.x-0 --disableexcludes=kubernetes
</pre>
{{< /tab >}}
apt-get install -y --allow-change-held-packages kubelet={{< skew currentVersion >}}.x-00 kubectl={{< skew currentVersion >}}.x-00
{{% /tab %}}
{{% tab name="CentOS, RHEL 또는 Fedora" %}}
# {{< skew currentVersion >}}.x-0에서 x를 최신 패치 버전으로 바꾼다
yum install -y kubelet-{{< skew currentVersion >}}.x-0 kubectl-{{< skew currentVersion >}}.x-0 --disableexcludes=kubernetes
{{% /tab %}}
{{< /tabs >}}
<br />
- kubelet을 다시 시작한다.
@@ -216,18 +214,18 @@ sudo systemctl restart kubelet
{{< tabs name="k8s_install_kubeadm_worker_nodes" >}}
{{% tab name="Ubuntu, Debian 또는 HypriotOS" %}}
# {{< skew latestVersion >}}.x-00의 x를 최신 패치 버전으로 바꾼다
# {{< skew currentVersion >}}.x-00의 x를 최신 패치 버전으로 바꾼다
apt-mark unhold kubeadm && \
apt-get update && apt-get install -y kubeadm={{< skew latestVersion >}}.x-00 && \
apt-get update && apt-get install -y kubeadm={{< skew currentVersion >}}.x-00 && \
apt-mark hold kubeadm
-
# apt-get 버전 1.1부터 다음 방법을 사용할 수도 있다
apt-get update && \
apt-get install -y --allow-change-held-packages kubeadm={{< skew latestVersion >}}.x-00
apt-get install -y --allow-change-held-packages kubeadm={{< skew currentVersion >}}.x-00
{{% /tab %}}
{{% tab name="CentOS, RHEL 또는 Fedora" %}}
# {{< skew latestVersion >}}.x-0에서 x를 최신 패치 버전으로 바꾼다
yum install -y kubeadm-{{< skew latestVersion >}}.x-0 --disableexcludes=kubernetes
# {{< skew currentVersion >}}.x-0에서 x를 최신 패치 버전으로 바꾼다
yum install -y kubeadm-{{< skew currentVersion >}}.x-0 --disableexcludes=kubernetes
{{% /tab %}}
{{< /tabs >}}
@@ -254,20 +252,21 @@ sudo systemctl restart kubelet
{{< tabs name="k8s_kubelet_and_kubectl" >}}
{{% tab name="Ubuntu, Debian 또는 HypriotOS" %}}
# {{< skew latestVersion >}}.x-00의 x를 최신 패치 버전으로 바꾼다
# {{< skew currentVersion >}}.x-00의 x를 최신 패치 버전으로 바꾼다
apt-mark unhold kubelet kubectl && \
apt-get update && apt-get install -y kubelet={{< skew latestVersion >}}.x-00 kubectl={{< skew latestVersion >}}.x-00 && \
apt-get update && apt-get install -y kubelet={{< skew currentVersion >}}.x-00 kubectl={{< skew currentVersion >}}.x-00 && \
apt-mark hold kubelet kubectl
-
# apt-get 버전 1.1부터 다음 방법을 사용할 수도 있다
apt-get update && \
apt-get install -y --allow-change-held-packages kubelet={{< skew latestVersion >}}.x-00 kubectl={{< skew latestVersion >}}.x-00
apt-get install -y --allow-change-held-packages kubelet={{< skew currentVersion >}}.x-00 kubectl={{< skew currentVersion >}}.x-00
{{% /tab %}}
{{% tab name="CentOS, RHEL 또는 Fedora" %}}
# {{< skew latestVersion >}}.x-0에서 x를 최신 패치 버전으로 바꾼다
yum install -y kubelet-{{< skew latestVersion >}}.x-0 kubectl-{{< skew latestVersion >}}.x-0 --disableexcludes=kubernetes
# {{< skew currentVersion >}}.x-0에서 x를 최신 패치 버전으로 바꾼다
yum install -y kubelet-{{< skew currentVersion >}}.x-0 kubectl-{{< skew currentVersion >}}.x-0 --disableexcludes=kubernetes
{{% /tab %}}
{{< /tabs >}}
<br />
- kubelet을 다시 시작한다.
@@ -0,0 +1,213 @@
---
title: 쿠버네티스 클러스터에서 sysctl 사용하기
content_type: task
---
<!-- overview -->
{{< feature-state for_k8s_version="v1.21" state="stable" >}}
이 문서는 쿠버네티스 클러스터에서 {{< glossary_tooltip term_id="sysctl" >}} 인터페이스를 사용하여
커널 파라미터를 어떻게 구성하고, 사용하는지를 설명한다.
## {{% heading "prerequisites" %}}
{{< include "task-tutorial-prereqs.md" >}}
일부 단계에서는 실행 중인 클러스터의 kubelet에서
커맨드 라인 옵션을 재구성할 필요가 있다.
<!-- steps -->
## 모든 sysctl 파라미터 나열
리눅스에서 sysctl 인터페이스는 관리자들이 런타임에 커널 파라미터를 수정할 수 있도록
허용한다. 파라미터는 `/proc/sys` 가상 파일 시스템을 통해 이용할 수 있다. 파라미터는
다음과 같은 다양한 서브 시스템을 포함한다.
- 커널 (공통 접두사: `kernel.`)
- 네트워크 (공통 접두사: `net.`)
- 가상 메모리 (공통 접두사: `vm.`)
- MDADM (공통 접두사: `dev.`)
- 더 많은 서브 시스템은 [커널 문서](https://www.kernel.org/doc/Documentation/sysctl/README)에 설명되어 있다.
모든 파라미터 리스트를 가져오려면 다음 명령을 실행한다.
```shell
sudo sysctl -a
```
## unsafe sysctl 활성화하기
sysctl은 _safe_ sysctl과 _unsafe_ sysctl로 구성되어 있다. _safe_ sysctl은
적절한 네임스페이스 뿐만 아니라 동일한 노드의 파드 사이에 _고립_ 되어야 한다. 즉, 하나의
파드에 _safe_ sysctl을 설정한다는 것은 다음을 의미한다.
- 노드의 다른 파드에 영향을 미치지 않아야 한다
- 노드의 상태를 손상시키지 않아야 한다
- CPU 또는 메모리 리소스가 파드의 리소스 제한에 벗어나는 것을
허용하지 않아야 한다
아직까지 대부분 _네임스페이스된_ sysctl은 _safe_ sysctl로 고려되지 않았다.
>>> 다음 sysctl은 _safe_ 명령을 지원한다.
- `kernel.shm_rmid_forced`,
- `net.ipv4.ip_local_port_range`,
- `net.ipv4.tcp_syncookies`,
- `net.ipv4.ping_group_range` (Kubernetes 1.18 이후).
{{< note >}}
`net.ipv4.tcp_syncookies` 예시는 리눅스 커널 버전 4.4 또는 이하에서 네임스페이스되지 않는다.
{{< /note >}}
kubelet이 더 고립된 방법을 지원하면 추후 쿠버네티스 버전에서
확장될 것이다.
모든 _safe_ sysctl은 기본적으로 활성화된다.
모든 _unsafe_ sysctl은 기본적으로 비활성화되고, 노드별 기본 클러스터 관리자에
의해 수동으로 메뉴얼로 허용되어야 한다.
unsafe sysctl이 비활성화된 파드는 스케줄링되지만, 시작에 실패한다.
위의 경고를 염두에 두고 클러스터 관리자는
고성능 또는 실시간 애플리케이션 조정과 같은
매우 특수한 상황에 대해 특정 _unsafe_ sysctl을 허용할 수 있다. _unsafe_ sysctl은
kubelet 플래그를 사용하여 노드별로 활성화된다. 예를 들면, 다음과 같다.
```shell
kubelet --allowed-unsafe-sysctls \
'kernel.msg*,net.core.somaxconn' ...
```
{{< glossary_tooltip term_id="minikube" >}}의 경우, `extra-config` 플래그를 통해 이 작업을 수행할 수 있다.
```shell
minikube start --extra-config="kubelet.allowed-unsafe-sysctls=kernel.msg*,net.core.somaxconn"...
```
_네임스페이스_ sysctl만 이 방법을 사용할 수 있다.
## 파드에 대한 sysctl 설정
수많은 sysctl은 최근 리눅스 커널에서 _네임스페이스_ 되어 있다. 이는 노드의 각 파드에
대해 개별적으로 설정할 수 있다는 것이다. 쿠버네티스의 파드 securityContext를 통해
네임스페이스 sysctl만 구성할 수 있다.
다음 sysctls는 네임스페이스로 알려져 있다.
이 목록은 이후 버전의 Linux 커널에서 변경될 수 있다.
- `kernel.shm*`,
- `kernel.msg*`,
- `kernel.sem`,
- `fs.mqueue.*`,
- `net.*` 아래의 파라미터는 컨테이너 네트워킹 네임스페이스에서 설정할 수 있다.
그러나 예외가 존재한다. (예, `net.netfilter.nf_conntrack_max``net.netfilter.nf_conntrack_expect_max`
컨테이너 네트워킹 네임스페이스에서 설정되지만,
네임스페이스가 없다.)
네임스페이스가 없는 sysctl은 _node-level_ sysctl이라고 부른다.
이를 설정해야 한다면, 각 노드의 OS에서 수동으로 구성하거나
특권있는 컨테이너의 데몬셋을 사용하여야 한다.
네임스페이스 sysctl을 구성하기 위해서 파드 securityContext를 사용한다. securityContext는 동일한 파드의 모든 컨테이너에 적용된다.
이 예시는 safe sysctl `kernel.shm_rmid_forced`와 두 개의 unsafe sysctl인
`net.core.somaxconn``kernel.msgmax` 를 설정하기 위해 파드 securityContext를 사용한다.
{{< warning >}}
파라미터의 영향을 파악한 후에만 운영체제가
불안정해지지 않도록 sysctl 파라미터를 수정한다.
{{< /warning >}}
```yaml
apiVersion: v1
kind: Pod
metadata:
name: sysctl-example
spec:
securityContext:
sysctls:
- name: kernel.shm_rmid_forced
value: "0"
- name: net.core.somaxconn
value: "1024"
- name: kernel.msgmax
value: "65536"
...
```
<!-- discussion -->
{{< warning >}}
_unsafe_의 특성으로 인해 _unsafe_sysctl는 위험 부담이 있으며
컨테이너의 잘못된 동작, 리소스 부족 혹은 노드 완전 파손과 같은
심각한 문제를 초래할 수 있다.
{{< /warning >}}
특별한 sysctl 설정이 있는 노드를 클러스터 내에서 _tainted_로 간주하고
sysctl 설정이 필요한 노드에만 파드를 예약하는 것이 좋다.
이를 구현하려면 쿠버네티스 [_테인트(taint)와 톨러레이션(toleration)_ 기능](/docs/reference/generated/kubectl/kubectl-commands/#taint) 을
사용하는 것이 좋다.
_unsafe_ sysctl을 명시적으로 활성화하지 않은 노드에서 _unsafe_ sysctl을 사용하는
파드가 시작되지 않는다. _node-level_ sysctl과 마찬가지로
[_테인트와 톨러레이션_ 특징](/docs/reference/generated/kubectl/kubectl-commands/#taint) 또는
[노드 테인트](/docs/concepts/scheduling-eviction/taint-and-toleration/)를
사용하여 해당 파드를 오른쪽 노드에
스케줄하는 것을 추천한다.
## 파드시큐리티폴리시(PodSecurityPolicy)
{{< feature-state for_k8s_version="v1.21" state="deprecated" >}}
또한 파드시큐리티폴리시의 `forbiddenSysctls` 및/또는 `allowedUnsafeSysctls` 필드에
sysctl 또는 sysctl 패턴 목록을 지정하여 파드에서 설정할
수 있는 sysctl를 제어할 수 있다. sysctl 패턴은 `kernel.*`과 같은 `*`
문자로 끝난다. `*` 문자 자체는
모든 sysctl와 일치한다.
기본적으로 모든 safe sysctl은 허용된다.
`forbiddenSysctls``allowedUnsafeSysctls`는 모두 단순한 sysctl 이름 또는
sysctl 패턴 목록이다(`*`로 끝남). `*` 문자는 모든 sysctl과 일치한다.
`forbiddenSysctls` 필드에는 특정 sysctl이 제외된다.
목록에서 safe sysctl과 unsafe sysctl의 조합을 금지할 수 있다.
sysctl 설정을 금지하기 위해서는 `*`를 사용한다.
`allowedUnsafeSysctls` 필드에 unsafe sysctl을 지정하고 `forbiddenSysctls` 필드가
존재하지 않는 경우, 파드시큐리티폴리시를 사용하여
sysctl을 파드에서 사용할 수 있다.
파드시큐리티폴리시의 모든 unsafe sysctl을 설정하려면 `*`를 사용한다.
이 두 필드를 겹치도록 구성하지 않는다.
이는 지정된 sysctl이 허용 및 금지됨을 의미한다.
{{< warning >}}
파드시큐리티폴리시의 'allowedUnsafeSysctls' 필드를 통해 unsafe sysctl을
허용하는 경우, 해당 노드에서 sysctl이
'--allowed-unsafe-sysctls' kubelet 플래그를 통해 허용되지 않으면,
sysctl을 사용하는 모든 파드가 시작에 실패한다.
{{< /warning >}}
이 예에서는 `kernel.msg` 접두사가 붙은 unsafe sysctl을 설정할 수 있으며,
`kernel.shm_rmid_forced` sysctl의 설정을 허용하지 않는다.
```yaml
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: sysctl-psp
spec:
allowedUnsafeSysctls:
- kernel.msg*
forbiddenSysctls:
- kernel.shm_rmid_forced
...
```
@@ -0,0 +1,310 @@
---
title: 윈도우 파드와 컨테이너용 GMSA 구성
content_type: task
weight: 20
---
<!-- overview -->
{{< feature-state for_k8s_version="v1.18" state="stable" >}}
이 페이지는 윈도우 노드에서 실행되는 파드와 컨테이너용으로 [그룹 관리 서비스 어카운트(Group Managed Service Accounts,](https://docs.microsoft.com/ko-kr/windows-server/security/group-managed-service-accounts/group-managed-service-accounts-overview) GMSA)를 구성하는 방법을 소개한다. 그룹 관리 서비스 어카운트는 자동 암호 관리, 단순화된 서비스 사용자 이름(service principal name, SPN) 관리, 여러 서버에 걸쳐 다른 관리자에게 관리를 위임하는 기능을 제공하는 특정한 유형의 액티브 디렉터리(Active Directory) 계정이다.
쿠버네티스에서 GMSA 자격 증명 사양은 쿠버네티스 클러스터 전체 범위에서 사용자 정의 리소스(Custom Resources)로 구성된다. 윈도우 파드 및 파드 내의 개별 컨테이너들은 다른 윈도우 서비스와 상호 작용할 때 도메인 기반 기능(예: Kerberos 인증)에 GMSA를 사용하도록 구성할 수 있다. v1.16부터 도커 런타임은 윈도우 워크로드용 GMSA를 지원한다.
## {{% heading "prerequisites" %}}
쿠버네티스 클러스터가 있어야 하며 클러스터와 통신하도록 `kubectl` 커맨드라인 툴을 구성해야 한다. 클러스터에는 윈도우 워커 노드가 있어야 한다. 이 섹션에서는 각 클러스터에 대해 한 번씩 필요한 일련의 초기 단계를 다룬다.
### GMSACredentialSpec CRD 설치
GMSA 자격 증명 사양 리소스에 대한 [커스텀리소스데피니션(CustomResourceDefinition,](/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/) CRD)을 클러스터에서 구성하여 사용자 정의 리소스 유형 `GMSACredentialSpec`을 정의해야 한다. GMSA CRD [YAML](https://github.com/kubernetes-sigs/windows-gmsa/blob/master/admission-webhook/deploy/gmsa-crd.yml)을 다운로드하고 gmsa-crd.yaml로 저장한다.
다음, `kubectl apply -f gmsa-crd.yaml` 로 CRD를 설치한다.
### GMSA 사용자를 검증하기 위해 웹훅 설치
쿠버네티스 클러스터에서 두 개의 웹훅을 구성하여 파드 또는 컨테이너 수준에서 GMSA 자격 증명 사양 참조를 채우고 검증한다.
1. 변형(mutating) 웹훅은 (파드 사양의 이름별로) GMSA에 대한 참조를 파드 사양 내 JSON 형식의 전체 자격 증명 사양으로 확장한다.
1. 검증(validating) 웹훅은 GMSA에 대한 모든 참조가 파드 서비스 어카운트에서 사용하도록 승인되었는지 확인한다.
위의 웹훅 및 관련 오브젝트를 설치하려면 다음 단계가 필요하다.
1. 인증서 키 쌍 생성 (웹훅 컨테이너가 클러스터와 통신할 수 있도록 하는데 사용됨)
1. 위의 인증서로 시크릿을 설치
1. 핵심 웹훅 로직에 대한 디플로이먼트(deployment)를 생성
1. 디플로이먼트를 참조하여 검증 및 변경 웹훅 구성을 생성
[스크립트](https://github.com/kubernetes-sigs/windows-gmsa/blob/master/admission-webhook/deploy/deploy-gmsa-webhook.sh)를 사용하여 GMSA 웹훅과 위에서 언급한 관련 오브젝트를 배포 및 구성할 수 있다. 스크립트는 ```--dry-run=server``` 옵션으로 실행되어 클러스터에 대한 변경 사항을 검토할 수 있다.
스크립트에서 사용하는 [YAML 템플릿](https://github.com/kubernetes-sigs/windows-gmsa/blob/master/admission-webhook/deploy/gmsa-webhook.yml.tpl)을 사용하여 웹훅 및 (파라미터를 적절히 대체하여) 관련 오브젝트를 수동으로 배포할 수도 있다.
<!-- steps -->
## 액티브 디렉터리에서 GMSA 및 윈도우 노드 구성
쿠버네티스의 파드가 GMSA를 사용하도록 구성되기 전에 [윈도우 GMSA 문서](https://docs.microsoft.com/ko-kr/windows-server/security/group-managed-service-accounts/getting-started-with-group-managed-service-accounts#BKMK_Step1)에 설명된 대로 액티브 디렉터리에서 원하는 GMSA를 프로비저닝해야 한다. [윈도우 GMSA 문서](https://docs.microsoft.com/ko-kr/windows-server/security/group-managed-service-accounts/getting-started-with-group-managed-service-accounts#to-add-member-hosts-using-the-set-adserviceaccount-cmdlet)에 설명된 대로 원하는 GMSA와 연결된 시크릿 자격 증명에 접근하려면 (쿠버네티스 클러스터의 일부인) 윈도우 워커 노드를 액티브 디렉터리에서 구성해야 한다.
## GMSA 자격 증명 사양 리소스 생성
(앞에서 설명한 대로) GMSACredentialSpec CRD를 설치하면 GMSA 자격 증명 사양이 포함된 사용자 정의 리소스를 구성할 수 있다. GMSA 자격 증명 사양에는 시크릿 또는 민감한 데이터가 포함되어 있지 않다. 이것은 컨테이너 런타임이 원하는 윈도우 컨테이너 GMSA를 설명하는 데 사용할 수 있는 정보이다. GMSA 자격 증명 사양은 [PowerShell 스크립트](https://github.com/kubernetes-sigs/windows-gmsa/tree/master/scripts/GenerateCredentialSpecResource.ps1) 유틸리티를 사용하여 YAML 형식으로 생성할 수 있다.
다음은 JSON 형식으로 GMSA 자격 증명 사양 YAML을 수동으로 생성한 다음 변환하는 단계이다.
1. CredentialSpec [모듈](https://github.com/MicrosoftDocs/Virtualization-Documentation/blob/live/windows-server-container-tools/ServiceAccounts/CredentialSpec.psm1) 가져오기(import): `ipmo CredentialSpec.psm1`
1. `New-CredentialSpec`을 사용하여 JSON 형식의 자격 증명 사양을 만든다. WebApp1이라는 GMSA 자격 증명 사양을 만들려면 `New-CredentialSpec -Name WebApp1 -AccountName WebApp1 -Domain $(Get-ADDomain -Current LocalComputer)`를 호출한다.
1. `Get-CredentialSpec`을 사용하여 JSON 파일의 경로를 표시한다.
1. credspec 파일을 JSON에서 YAML 형식으로 변환하고 필요한 헤더 필드 `apiVersion`, `kind`, `metadata`, `credspec`을 적용하여 쿠버네티스에서 구성할 수 있는 GMSACredentialSpec 사용자 정의 리소스로 만든다.
다음 YAML 구성은 `gmsa-WebApp1`이라는 GMSA 자격 증명 사양을 설명한다.
```yaml
apiVersion: windows.k8s.io/v1alpha1
kind: GMSACredentialSpec
metadata:
name: gmsa-WebApp1 #임의의 이름이지만 참조로 사용된다.
credspec:
ActiveDirectoryConfig:
GroupManagedServiceAccounts:
- Name: WebApp1 #GMSA 계정의 사용자 이름
Scope: CONTOSO #NETBIOS 도메인 명
- Name: WebApp1 #GMSA 계정의 사용자 이름
Scope: contoso.com #DNS 도메인 명
CmsPlugins:
- ActiveDirectory
DomainJoinConfig:
DnsName: contoso.com #DNS 도메인 명
DnsTreeName: contoso.com #DNS 도메인 명 루트
Guid: 244818ae-87ac-4fcd-92ec-e79e5252348a #GUID
MachineAccountName: WebApp1 #GMSA 계정의 사용자 이름
NetBiosName: CONTOSO #NETBIOS 도메인 명
Sid: S-1-5-21-2126449477-2524075714-3094792973 #SID of GMSA
```
위의 자격 증명 사양 리소스는 `gmsa-Webapp1-credspec.yaml`로 저장되고 `kubectl apply -f gmsa-Webapp1-credspec.yml`을 사용하여 클러스터에 적용될 수 있다.
## 특정 GMSA 자격 증명 사양에서 RBAC를 활성화하도록 cluster role 구성
각 GMSA 자격 증명 사양 리소스에 대해 cluster role을 정의해야 한다. 이것은 일반적으로 서비스 어카운트인 주체에 의해 특정 GMSA 리소스에 대한 `use` 동사를 승인한다. 다음 예는 위에서 `gmsa-WebApp1` 자격 증명 사양의 사용을 승인하는 클러스터 롤(cluster role)을 보여준다. 파일을 gmsa-webapp1-role.yaml로 저장하고 `kubectl apply -f gmsa-webapp1-role.yaml`을 사용하여 적용한다.
```yaml
#credspec을 읽을 Role 생성
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: webapp1-role
rules:
- apiGroups: ["windows.k8s.io"]
resources: ["gmsacredentialspecs"]
verbs: ["use"]
resourceNames: ["gmsa-WebApp1"]
```
## 특정 GMSA credspecs를 사용하도록 서비스 어카운트에 롤 할당
(파드가 사용하게 되는) 서비스 어카운트는 위에서 생성한 클러스터 롤에 바인딩되어야 한다. 이렇게 하면 서비스 어카운트가 원하는 GMSA 자격 증명 사양 리소스를 사용할 수 있다. 다음은 위에서 생성한 `gmsa-WebApp1` 자격 증명 사양 리소스를 사용하기 위해 `webapp1-role` 클러스터 롤에 바인딩되는 기본(default) 서비스 어카운트이다.
```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: allow-default-svc-account-read-on-gmsa-WebApp1
namespace: default
subjects:
- kind: ServiceAccount
name: default
namespace: default
roleRef:
kind: ClusterRole
name: webapp1-role
apiGroup: rbac.authorization.k8s.io
```
## 파드 사양에서 GMSA 자격 증명 사양 참조 구성
파드 사양 필드 `securityContext.windowsOptions.gmsaCredentialSpecName`은 파드 사양에서 원하는 GMSA 자격 증명 사양 사용자 정의 리소스에 대한 참조를 지정하는 데 사용된다. 이렇게 하면 지정된 GMSA를 사용하도록 파드 사양의 모든 컨테이너가 구성된다. 다음은 `gmsa-WebApp1`을 참조하도록 채워진 어노테이션이 있는 샘플 파드 사양이다.
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
run: with-creds
name: with-creds
namespace: default
spec:
replicas: 1
selector:
matchLabels:
run: with-creds
template:
metadata:
labels:
run: with-creds
spec:
securityContext:
windowsOptions:
gmsaCredentialSpecName: gmsa-webapp1
containers:
- image: mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2019
imagePullPolicy: Always
name: iis
nodeSelector:
kubernetes.io/os: windows
```
파드 사양의 개별 컨테이너는 컨테이너별 `securityContext.windowsOptions.gmsaCredentialSpecName` 필드를 사용하여 원하는 GMSA credspec을 지정할 수도 있다. 다음은 예이다.
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
run: with-creds
name: with-creds
namespace: default
spec:
replicas: 1
selector:
matchLabels:
run: with-creds
template:
metadata:
labels:
run: with-creds
spec:
containers:
- image: mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2019
imagePullPolicy: Always
name: iis
securityContext:
windowsOptions:
gmsaCredentialSpecName: gmsa-Webapp1
nodeSelector:
kubernetes.io/os: windows
```
(위에서 설명한 대로) GMSA 필드가 채워진 파드 사양이 클러스터에 적용되면 다음과 같은 일련의 이벤트가 발생한다.
1. 변형 웹훅은 GMSA 자격 증명 사양 리소스에 대한 모든 참조를 확인하고 GMSA 자격 증명 사양의 내용으로 확장한다.
1. 검증 웹훅은 파드와 연결된 서비스 어카운트가 지정된 GMSA 자격 증명 사양의 `use` 동사에 대해 승인되었는지 확인한다.
1. 컨테이너 런타임은 컨테이너가 액티브 디렉터리에서 GMSA의 ID를 가정하고 해당 ID를 사용하여 도메인의 서비스에 접근할 수 있도록 지정된 GMSA 자격 증명 사양으로 각 윈도우 컨테이너를 구성한다.
## Containerd
윈도우 서버 2019에서 containerd와 함께 GMSA를 사용하려면 패치 [KB5000822](https://support.microsoft.com/ko-kr/topic/2021년-3월-9일-kb5000822-os-빌드-17763-1817-2eb6197f-e3b1-4f42-ab51-84345e063564)된 OS Build 17763.1817 (또는 이후 버전)을 실행해야 한다.
또한 파드에서 SMB 공유에 연결하려고 할 때 발생하는 containerd와 관련된 알려진 문제가 있다. GMSA를 구성하면 파드가 hostname 또는 FQDN을 사용하여 공유에 연결할 수 없지만, IP 주소를 사용하여 공유에 연결하면 예상대로 작동한다.
```PowerShell
ping adserver.ad.local
```
hostname을 IPv4 주소로 올바르게 변환한다. 출력은 다음과 유사하다.
```
Pinging adserver.ad.local [192.168.111.18] with 32 bytes of data:
Reply from 192.168.111.18: bytes=32 time=6ms TTL=124
Reply from 192.168.111.18: bytes=32 time=5ms TTL=124
Reply from 192.168.111.18: bytes=32 time=5ms TTL=124
Reply from 192.168.111.18: bytes=32 time=5ms TTL=124
```
그러나 hostname을 사용하여 디렉터리를 탐색하려고 할 때
```PowerShell
cd \\adserver.ad.local\test
```
대상 공유가 존재하지 않음을 암시하는 오류가 표시된다.
```
cd : Cannot find path '\\adserver.ad.local\test' because it does not exist.
At line:1 char:1
+ cd \\adserver.ad.local\test
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (\\adserver.ad.local\test:String) [Set-Location], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.SetLocationCommand
```
그러나 IPv4 주소를 대신 사용하여 공유를 탐색하면 오류가 사라진다. 다음은 예시이다.
```PowerShell
cd \\192.168.111.18\test
```
공유 내의 디렉터리로 변경하면 다음과 유사한 프롬프트가 표시된다.
```
Microsoft.PowerShell.Core\FileSystem::\\192.168.111.18\test>
```
동작을 수정하려면 노드에서 `reg add "HKLM\SYSTEM\CurrentControlSet\Services\hns\State" /v EnableCompartmentNamespace /t REG_DWORD /d 1`을 실행하여 필요한 레지스트리 키를 추가해야 한다. 이 노드 변경 사항은 새로 생성된 파드에만 적용되는데, SMB 공유에 액세스해야 하는 실행 중인 파드를 다시 생성해야 하는 것을 의미한다.
## 문제 해결
GMSA가 사용자 환경에서 작동하도록 하는 데 어려움이 있는 경우 취할 수 있는 몇 가지 문제 해결 단계가 있다.
먼저 credspec이 파드에 전달되었는지 확인한다. 이렇게 하려면 파드 중 하나에서 `exec`를 실행하고 `nltest.exe /parentdomain` 명령의 출력을 확인해야 한다.
아래 예에서 파드는 credspec을 올바르게 가져오지 못했다.
```PowerShell
kubectl exec -it iis-auth-7776966999-n5nzr powershell.exe
```
`nltest.exe /parentdomain` 는 다음과 같은 오류를 발생시킨다.
```
Getting parent domain failed: Status = 1722 0x6ba RPC_S_SERVER_UNAVAILABLE
```
파드가 credspec을 올바르게 가져오면 다음으로 도메인과의 통신을 확인한다. 먼저 파드 내부에서 nslookup을 빠르게 수행하여 도메인의 루트를 찾는다.
이것은 다음의 세 가지를 의미한다.
1. 파드는 DC에 도달할 수 있다.
1. DC는 파드에 도달할 수 있다.
1. DNS가 올바르게 작동하고 있다.
DNS 및 통신 테스트를 통과하면 다음으로 파드가 도메인과 보안 채널 통신을 설정했는지 확인해야 한다. 이렇게 하려면 파드에서 다시 `exec`를 실행하고 `nltest.exe /query` 명령을 실행한다.
```PowerShell
nltest.exe /query
```
결과는 다음과 같다.
```
I_NetLogonControl failed: Status = 1722 0x6ba RPC_S_SERVER_UNAVAILABLE
```
이것은 어떤 이유로 파드가 credspec에 지정된 계정을 사용하여 도메인에 로그온할 수 없음을 알려준다. 다음을 실행하여 보안 채널 복구를 시도할 수 있다.
```PowerShell
nltest /sc_reset:domain.example
```
명령이 성공하면 다음과 유사한 출력이 표시된다.
```
Flags: 30 HAS_IP HAS_TIMESERV
Trusted DC Name \\dc10.domain.example
Trusted DC Connection Status Status = 0 0x0 NERR_Success
The command completed successfully
```
위의 방법으로 오류가 수정되면 다음 수명 주기 훅(hook)을 파드 사양에 추가하여 단계를 자동화할 수 있다. 오류가 수정되지 않은 경우 credspec을 다시 검사하여 정확하고 완전한지 확인해야 한다.
```yaml
image: registry.domain.example/iis-auth:1809v1
lifecycle:
postStart:
exec:
command: ["powershell.exe","-command","do { Restart-Service -Name netlogon } while ( $($Result = (nltest.exe /query); if ($Result -like '*0x0 NERR_Success*') {return $true} else {return $false}) -eq $false)"]
imagePullPolicy: IfNotPresent
```
위의 `lifecycle` 섹션을 파드 사양에 추가하면, 파드는 `nltest.exe /query` 명령이 오류 없이 종료될 때까지 나열된 명령을 실행하여 `netlogon` 서비스를 다시 시작한다.
@@ -102,7 +102,7 @@ kubectl create secret docker-registry regcred --docker-server=<your-registry-ser
아래의 각 항목에 대한 설명을 참고한다.
* `<your-registry-server>` 은 프라이빗 도커 저장소의 FQDN 주소이다.
도커허브(DockerHub)는 `https://index.docker.io/v2/` 를 사용한다.
도커허브(DockerHub)는 `https://index.docker.io/v1/` 를 사용한다.
* `<your-name>` 은 도커 사용자의 계정이다.
* `<your-pword>` 은 도커 사용자의 비밀번호이다.
* `<your-email>` 은 도커 사용자의 이메일 주소이다.
@@ -31,6 +31,13 @@ API 서버에서 제어될 수는 없다.
을 사용하는 것이 바람직하다.
{{< /note >}}
{{< note >}}
스태틱 파드의 `spec`은 다른 API 오브젝트(예를 들면,
{{< glossary_tooltip text="서비스어카운트" term_id="service-account" >}},
{{< glossary_tooltip text="컨피그맵" term_id="configmap" >}},
{{< glossary_tooltip text="시크릿" term_id="secret" >}}, 등)가 참조할 수 없다.
{{< /note >}}
## {{% heading "prerequisites" %}}
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
@@ -0,0 +1,43 @@
---
title: 스테이트풀셋 디버깅하기
content_type: task
---
<!-- overview -->
이 문서에서는 스테이트풀셋을 디버깅 방법에 대해 설명한다.
## {{% heading "prerequisites" %}}
* 쿠버네티스 클러스터가 준비되어 있어야 하고, kubectl 커맨드 라인 도구가 클러스터와 통신할 수 있게 사전에 설정되어 있어야 한다.
* 조사하고자 하는 스테이트풀셋이 사전에 준비되어 있어야 한다.
<!-- steps -->
## 스테이트풀셋 디버깅하기
레이블이 `app=myapp`으로 지정된 스테이트풀셋 파드를 전부 나열하기 위해서는
다음의 명령을 사용할 수 있다.
```shell
kubectl get pods -l app=myapp
```
만약 오랜 시간동안 `Unknown`이나 `Terminating` 상태에 있는
파드들을 발견하였다면, 이러한 파드들을 어떻게 다루는지 알아보기 위해
[스테이트풀셋 파드 삭제하기](/docs/tasks/run-application/delete-stateful-set/)를 참고하길 바란다.
스테이트풀셋에 포함된 개별 파드들을 디버깅하기 위해서는
[파드 디버그하기](/ko/docs/tasks/debug-application-cluster/debug-pod-replication-controller/) 가이드를 참고하길 바란다.
## {{% heading "whatsnext" %}}
[초기화 컨테이너(Init container) 디버그하기](/ko/docs/tasks/debug-application-cluster/debug-init-containers/)를 참고길 바란다.
@@ -0,0 +1,158 @@
---
title: 동작중인 컨테이너의 셸에 접근하기
content_type: task
---
<!-- overview -->
이 페이지는 동작중인 컨테이너에 접근하기 위해 `kubectl exec`을 사용하는
방법에 대해 설명한다.
## {{% heading "prerequisites" %}}
{{< include "task-tutorial-prereqs.md" >}}
<!-- steps -->
## 컨테이너의 셸에 접근하기
이 예시에서는 하나의 컨테이너를 가진 파드를 생성할 것이다. 이 컨테이너는
nginx 이미지를 실행한다. 해당 파드에 대한 설정 파일은 다음과 같다.
{{< codenew file="application/shell-demo.yaml" >}}
파드를 생성한다.
```shell
kubectl apply -f https://k8s.io/examples/application/shell-demo.yaml
```
다음을 통해 컨테이너가 동작하고 있는지 확인할 수 있다.
```shell
kubectl get pod shell-demo
```
동작중인 컨테이너의 셸에 접근한다.
```shell
kubectl exec --stdin --tty shell-demo -- /bin/bash
```
{{< note >}}
kubectl 명령어 인자와 사용하고자 하는 명령어의 인자를 구분하기 위해서는 이중 대시(`--`)를 사용할 수 있다.
{{< /note >}}
셸에 접근해서 다음처럼 루트 디렉토리를 확인해 볼 수 있다.
```shell
# Run this inside the container
ls /
```
접근한 셸에서 다른 명령어도 한번 실행해 보아라. 다음은 실행해 볼
명령의 예시이다.
```shell
# You can run these example commands inside the container
ls /
cat /proc/mounts
cat /proc/1/maps
apt-get update
apt-get install -y tcpdump
tcpdump
apt-get install -y lsof
lsof
apt-get install -y procps
ps aux
ps aux | grep nginx
```
## nginx의 최상단 페이지 작성하기
앞에서 생성한 파드에 대한 설정을 살펴보아라. 파드에는
`emptyDir` 볼륨이 사용되었고, 이 컨테이너는 해당 볼륨을
`/usr/share/nginx/html` 경로에 마운트하였다.
접근한 셸 환경에서 `/usr/share/nginx/html` 디렉터리에 `index.html` 파일을
생성해 보아라.
```shell
# Run this inside the container
echo 'Hello shell demo' > /usr/share/nginx/html/index.html
```
셸 환경에서 nginx 서버에 GET 요청을 시도해보면 다음과 같다.
```shell
# Run this in the shell inside your container
apt-get update
apt-get install curl
curl http://localhost/
```
출력 결과는 여러분이 `index.html` 파일에 작성한 텍스트를 출력할 것이다.
```
Hello shell demo
```
셸 사용이 모두 끝났다면 `exit`을 입력해 종료하라.
```shell
exit # To quit the shell in the container
```
## 컨테이너에서 개별 명령어 실행하기
셸이 아닌 일반적인 커맨드 환경에서 다음처럼 동작중인 컨테이너의
환경 변수를 출력할 수 있다.
```shell
kubectl exec shell-demo env
```
다른 명령어도 한번 실행해 보아라. 다음은 실행해 볼 명령의 예시이다.
```shell
kubectl exec shell-demo -- ps aux
kubectl exec shell-demo -- ls /
kubectl exec shell-demo -- cat /proc/1/mounts
```
<!-- discussion -->
## 파드에 한 개 이상의 컨테이너가 있을 경우 셸에 접근하기
만일 파드에 한 개 이상의 컨테이너가 있을 경우, `kubectl exec` 명령어에
`--container` 혹은 `-c` 옵션을 사용해서 컨테이너를 지정하라. 예를 들어,
여러분이 my-pod라는 이름의 파드가 있다고 가정해 보자. 이 파드에는 _main-app_
_helper-app_ 이라는 이름의 두 컨테이너가 있다. 다음 명령어는 _main-app_
컨테이너에 대한 셸에 접근할 것이다.
```shell
kubectl exec -i -t my-pod --container main-app -- /bin/bash
```
{{< note >}}
축약형 옵션인 `-i``-t` 는 각각 `--stdin``--tty` 옵션에 대응된다.
{{< /note >}}
## {{% heading "whatsnext" %}}
* [kubectl
* exec](/docs/reference/generated/kubectl/kubectl-commands/#exec)를참고한다.
@@ -0,0 +1,88 @@
---
title: Konnectivity 서비스 설정
content_type: task
weight: 70
---
<!-- overview -->
Konnectivity 서비스는 컨트롤 플레인에 클러스터 통신을 위한 TCP 수준 프록시를
제공한다.
## {{% heading "prerequisites" %}}
{{< include "task-tutorial-prereqs.md" >}}
<!-- steps -->
## Konnectivity 서비스 설정
다음 단계에는 송신(egress) 설정이 필요하다. 예를 들면 다음과 같다.
{{< codenew file="admin/konnectivity/egress-selector-configuration.yaml" >}}
Konnectivity 서비스를 사용하고 네트워크 트래픽을 클러스터 노드로 보내도록
API 서버를 구성해야 한다.
1. `ServiceAccountTokenVolumeProjection` [기능 게이트(feature gate)](/ko/docs/reference/command-line-tools-reference/feature-gates/)가
활성화되어 있는지
확인한다. kube-apiserver에 다음과 같은 플래그를 제공하여
[서비스 어카운트 토큰 볼륨 보호](/docs/tasks/configure-pod-container/configure-service-account/#service-account-token-volume-projection)를
활성화할 수 있다.
```
--service-account-issuer=api
--service-account-signing-key-file=/etc/kubernetes/pki/sa.key
--api-audiences=system:konnectivity-server
```
1. `admin/konnectivity/egress-selector-configuration.yaml`과 같은 송신 구성 파일을 생성한다.
1. API 서버의 `--egress-selector-config-file` 플래그를
API 서버 송신 구성 파일의 경로로 설정한다.
1. UDS 연결을 사용하는 경우 kube-apiserver에 볼륨 구성을 추가한다.
```yaml
spec:
containers:
volumeMounts:
- name: konnectivity-uds
mountPath: /etc/kubernetes/konnectivity-server
readOnly: false
volumes:
- name: konnectivity-uds
hostPath:
path: /etc/kubernetes/konnectivity-server
type: DirectoryOrCreate
```
konnectivity-server에 대한 인증서 및 kubeconfig를 생성하거나 얻는다.
예를 들어 OpenSSL 커맨드라인 툴을 사용하여 컨트롤 플레인 호스트에서
클러스터 CA 인증서 `/etc/kubernetes/pki/ca.crt`를 사용하여 X.509 인증서를 발급할 수 있다.
```bash
openssl req -subj "/CN=system:konnectivity-server" -new -newkey rsa:2048 -nodes -out konnectivity.csr -keyout konnectivity.key -out konnectivity.csr
openssl x509 -req -in konnectivity.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out konnectivity.crt -days 375 -sha256
SERVER=$(kubectl config view -o jsonpath='{.clusters..server}')
kubectl --kubeconfig /etc/kubernetes/konnectivity-server.conf config set-credentials system:konnectivity-server --client-certificate konnectivity.crt --client-key konnectivity.key --embed-certs=true
kubectl --kubeconfig /etc/kubernetes/konnectivity-server.conf config set-cluster kubernetes --server "$SERVER" --certificate-authority /etc/kubernetes/pki/ca.crt --embed-certs=true
kubectl --kubeconfig /etc/kubernetes/konnectivity-server.conf config set-context system:konnectivity-server@kubernetes --cluster kubernetes --user system:konnectivity-server
kubectl --kubeconfig /etc/kubernetes/konnectivity-server.conf config use-context system:konnectivity-server@kubernetes
rm -f konnectivity.crt konnectivity.key konnectivity.csr
```
다음으로 Konnectivity 서버와 에이전트를 배포해야 한다.
[kubernetes-sigs/apiserver-network-proxy](https://github.com/kubernetes-sigs/apiserver-network-proxy)에서
구현을 참조할 수 있다.
컨트롤 플레인 노드에 Konnectivity 서버를 배포한다. 제공된
`konnectivity-server.yaml` 매니페스트는
쿠버네티스 구성 요소가 클러스터에 {{< glossary_tooltip text="스태틱 파드(static Pod)"
term_id="static-pod" >}}로 배포되었다고 가정한다. 그렇지 않은 경우에는 Konnectivity
서버를 데몬셋(DaemonSet)으로 배포할 수 있다.
{{< codenew file="admin/konnectivity/konnectivity-server.yaml" >}}
그런 다음 클러스터에 Konnectivity 에이전트를 배포한다.
{{< codenew file="admin/konnectivity/konnectivity-agent.yaml" >}}
마지막으로 클러스터에서 RBAC가 활성화된 경우 관련 RBAC 규칙을 생성한다.
{{< codenew file="admin/konnectivity/konnectivity-rbac.yaml" >}}
@@ -0,0 +1,96 @@
---
title: 스테이트풀셋(StatefulSet) 파드 강제 삭제하기
content_type: task
weight: 70
---
<!-- overview -->
이 페이지에서는 {{< glossary_tooltip text="스테이트풀셋" term_id="StatefulSet" >}}의 일부인 파드를 삭제하는 방법을 보여주고
이 과정에서 고려해야 할 사항을 설명한다.
## {{% heading "prerequisites" %}}
* 이것은 상당히 고급 태스크이며 스테이트풀셋 고유의 속성 중 일부를 위반할 가능성이 있다.
* 계속하기 전에 아래 나열된 고려 사항을 숙지하도록 한다.
<!-- steps -->
## 스테이트풀셋 고려 사항
정상적인 스테이트풀셋의 작동에서는 스테이트풀셋 파드를 강제로 삭제할 필요가 **절대** 없다. [스테이트풀셋 컨트롤러](/ko/docs/concepts/workloads/controllers/statefulset/)는 스테이트풀셋의 멤버 생성, 스케일링, 삭제를 담당한다. 서수 0부터 N-1까지 지정된 수의 파드가 활성 상태이고 준비되었는지 확인한다. 스테이트풀셋은 언제든지 클러스터에서 실행 중인 지정된 신원을 가진 최대 하나의 파드가 있는지 확인한다. 이를 스테이트풀셋에서 제공하는 *최대 하나* 의미론이라고 한다.
수동 강제 삭제는 스테이트풀셋 고유의 최대 하나 의미론을 위반할 가능성이 있으므로 주의해서 수행해야 한다. 스테이트풀셋은 안정적인 네트워크 신원과 안정적인 스토리지가 필요한 분산 클러스터 애플리케이션을 실행하는 데 사용할 수 있다. 이러한 애플리케이션은 종종 고정된 신원을 가진 고정된 수의 구성원 앙상블에 의존하는 구성을 가진다. 여러 구성원이 동일한 신원을 갖는 것은 재앙이 될 수 있으며 데이터 손실로 이어질 수 있다(예: 쿼럼 기반 시스템의 스플릿 브레인(split-brain) 시나리오).
## 파드 삭제
다음 명령을 사용하여 파드를 단계적으로 삭제할 수 있다.
```shell
kubectl delete pods <pod>
```
위의 내용이 단계적인 종료로 이어지려면 파드가
`pod.Spec.TerminationGracePeriodSeconds`를 0으로 지정하지 **않아야 한다**.
`pod.Spec.TerminationGracePeriodSeconds`를 0초로 설정하는 관행은 안전하지 않으며
스테이트풀셋 파드에서 강력히 권장하지 않는다. 단계적 삭제는 안전하며 kubelet이 apiserver에서 이름을 삭제하기 전에 파드가
[정상적으로 종료](/ko/docs/concepts/workloads/pods/pod-lifecycle/#pod-termination)되도록 한다.
노드에 연결할 수 없는 경우 파드는 자동으로 삭제되지 않는다.
연결할 수 없는 노드에서 실행 중인 파드는 [타임아웃](/ko/docs/concepts/architecture/nodes/#condition) 후에
'Terminating'이나 'Unknown' 상태가 된다.
사용자가 연결할 수 없는 노드에서 파드를 단계적으로 삭제하려고 하면 파드가 이러한 상태에 들어갈 수도 있다.
이러한 상태의 파드를 apiserver에서 제거할 수 있는 유일한 방법은 다음과 같다.
* 노드 오브젝트가 삭제된다(사용자 또는 [노드 컨트롤러](/ko/docs/concepts/architecture/nodes/)에 의해).
* 응답하지 않는 노드의 kubelet이 응답을 시작하고 파드를 종료하여 apiserver에서 항목을 제거한다.
* 사용자가 파드를 강제로 삭제한다.
권장되는 모범 사례는 첫 번째 또는 두 번째 방법을 사용하는 것이다. 노드가 죽은 것으로 확인되면(예: 네트워크에서 영구적으로 연결이 끊기거나 전원이 꺼진 경우 등) 노드 오브젝트를 삭제한다. 노드에 네트워크 파티션이 있는 경우 이를 해결하거나 해결될 때까지 기다린다. 파티션이 복구되면 kubelet은 파드 삭제를 완료하고 apiserver에서 해당 이름을 해제한다.
일반적으로 시스템은 파드가 노드에서 더 이상 실행되지 않거나 노드가 관리자에 의해 삭제되면 삭제를 완료한다. 파드를 강제로 삭제하여 이를 재정의할 수 있다.
### 강제 삭제
강제 삭제는 파드가 종료되었다는 kubelet의 확인을 기다리지 **않는다**. 강제 삭제가 파드를 죽이는 데 성공했는지 여부와 관계없이 즉시 apiserver에서 이름을 해제한다. 이렇게 하면 스테이트풀셋 컨트롤러가 동일한 신원으로 대체 파드를 생성할 수 있다. 이것은 여전히 실행 중인 파드와 중복될 수 있으며, 해당 파드가 여전히 스테이트풀셋의 다른 멤버와 통신할 수 있다면 스테이트풀셋이 보장하도록 설계된 최대 하나 의미론을 위반할 것이다.
스테이트풀셋 파드를 강제로 삭제하는 것은 문제의 파드가 스테이트풀셋의 다른 파드와 다시는 접촉하지 않으며 대체 생성을 위해 해당 이름을 안전하게 해제할 수 있다고 주장하는 것이다.
kubectl 버전 >= 1.5를 사용하여 파드를 강제로 삭제하려면, 다음을 수행한다.
```shell
kubectl delete pods <pod> --grace-period=0 --force
```
kubectl <= 1.4 버전을 사용하는 경우, `--force` 옵션을 생략하고 다음을 사용해야 한다.
```shell
kubectl delete pods <pod> --grace-period=0
```
이러한 명령 후에도 파드가 `Unknown` 상태에서 멈추면, 다음 명령을 사용하여 클러스터에서 파드를 제거한다.
```shell
kubectl patch pod <pod> -p '{"metadata":{"finalizers":null}}'
```
항상 관련된 위험에 대해 완전히 이해한 상태에서 주의 깊게 스테이트풀셋 파드의 강제 삭제를 수행한다.
## {{% heading "whatsnext" %}}
[스테이트풀셋 디버깅하기](/docs/tasks/debug-application-cluster/debug-stateful-set/)에 대해 더 알아보기.
@@ -1,4 +1,9 @@
---
title: Horizontal Pod Autoscaler 연습
content_type: task
weight: 100
@@ -100,7 +105,8 @@ NAME REFERENCE TARGET MINPODS MAXPODS REPLICA
php-apache Deployment/php-apache/scale 0% / 50% 1 10 1 18s
```
아직 서버로 어떠한 요청도 하지 않았기 때문에, 현재 CPU 소비는 0%임을 확인할 수 있다 (``TARGET``은 디플로이먼트에 의해 제어되는 파드들의 평균을 나타낸다).
아직 서버로 어떠한 요청도 하지 않았기 때문에, 현재 CPU 소비는 0%임을 확인할 수 있다.
(``TARGET``은 디플로이먼트에 의해 제어되는 파드들의 평균을 나타낸다)
## 부하 증가
@@ -236,15 +242,11 @@ CPU 외에 다른 메트릭을 지정할 수 있는데, 기본적으로 지원
더 고급화된 클러스터 모니터링 설정이 필요하다.
이러한 대체 메트릭 타입중 첫 번째는 *파드 메트릭* 이다.
이 메트릭은 파드들을 설명하고, 파드들간의 평균을 내며,
대상 값과 비교하여 레플리카 개수를 결정한다.
이것들은 `AverageValue``target`만을 지원한다는 것을 제외하면,
자원 메트릭과 매우 유사하게 동작한다.
이 메트릭은 파드들을 설명하고, 파드들 간의 평균을 내며, 대상 값과 비교하여 레플리카 개수를 결정한다.
이것들은 `AverageValue``target`만을 지원한다는 것을 제외하면, 자원 메트릭과 매우 유사하게 동작한다.
파드 메트릭은 이처럼 메트릭 블록을 사용하여 정의된다.
```yaml
type: Pods
pods:
@@ -395,7 +397,9 @@ object:
external:
metric:
name: queue_messages_ready
selector: "queue=worker_tasks"
selector:
matchLabels:
queue: "worker_tasks"
target:
type: AverageValue
averageValue: 30
@@ -68,14 +68,7 @@ Horizontal Pod Autoscaler는 컨트롤러
HorizontalPodAutoscaler는 보통 일련의 API 집합(`metrics.k8s.io`,
`custom.metrics.k8s.io`, `external.metrics.k8s.io`)에서 메트릭을 가져온다. `metrics.k8s.io` API는 대개 별도로
시작해야 하는 메트릭-서버에 의해 제공된다. 가이드는
[메트릭-서버](/ko/docs/tasks/debug-application-cluster/resource-metrics-pipeline/#메트릭-서버)를
참조한다. HorizontalPodAutoscaler는 힙스터(Heapster)에서 직접 메트릭을 가져올 수도 있다.
{{< note >}}
{{< feature-state state="deprecated" for_k8s_version="v1.11" >}}
힙스터에서 메트릭 가져오기는 Kubernetes 1.11에서 사용 중단(deprecated)됨.
{{< /note >}}
시작해야 하는 메트릭-서버에 의해 제공된다. 더 자세한 정보는 [메트릭-서버](/ko/docs/tasks/debug-application-cluster/resource-metrics-pipeline/#메트릭-서버)를 참조한다.
자세한 사항은 [메트릭 API를 위한 지원](#메트릭-api를-위한-지원)을 참조한다.
@@ -225,8 +218,7 @@ v1.12부터는 새로운 알고리즘 업데이트가 업스케일 지연에 대
- `--horizontal-pod-autoscaler-downscale-delay` : 다운스케일이
안정화되기까지의 시간 간격을 지정한다.
Horizontal Pod Autoscaler는 이전의 권장하는 크기를 기억하고,
이 시간 간격에서의 가장 큰 크기에서만 작동한다.
기본값은 5분(`5m0s`)이다.
이 시간 간격에서의 가장 큰 크기에서만 작동한다. 기본값은 5분(`5m0s`)이다.
{{< note >}}
이러한 파라미터 값을 조정할 때 클러스터 운영자는 가능한 결과를 알아야
@@ -345,8 +337,6 @@ API에 접속하려면 클러스터 관리자는 다음을 확인해야 한다.
* 외부 메트릭의 경우, 이것은 `external.metrics.k8s.io` API이다. 위에 제공된 사용자 정의 메트릭 어댑터에서 제공될 수 있다.
* `--horizontal-pod-autoscaler-use-rest-clients``true`이거나 설정되지 않음. 이것을 false로 설정하면 더 이상 사용되지 않는 힙스터 기반 오토스케일링으로 전환된다.
이런 다양한 메트릭 경로와 각각의 다른 점에 대한 상세 내용은 관련 디자인 제안서인
[HPA V2](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/autoscaling/hpa-v2.md),
[custom.metrics.k8s.io](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/instrumentation/custom-metrics-api.md),