Fifth Korean l10n work for release 1.18

- Update to Outdated files in the dev-1.18-ko.5 branch. (#21450)
- Translate tasks/run-application/run-single-instance-stateful-application in Korean (#21174)
- Translate tasks/debug-application-cluster/determine-reason-pod-failure in Korean (#21515)
- Translate tasks/manage-hugepages/scheduling-hugepages.md into Korean (#21337)
- Translate tasks/extend-kubectl/kubectl-plugins.md into Korean (#21454)
- Translate tasks/manage-daemon/rollback-daemon-set.md into Korean (#21376)
- Translate contribute/generate-ref-docs/overview in Korean (#21466)
- Translate reference/kubectl/overview.md into Korean (#21552)
- Translate configure-pod-initialization in Korean (#21600)
- Translate tasks/manage-daemon/update-daemon-set.md into Korean (#21378)

Co-authored-by: Jerry Park <jaehwa@gmail.com>
Co-authored-by: Yoon <learder@gmail.com>
Co-authored-by: Yuk, Yongsu <ysyukr@gmail.com>
Co-authored-by: Seokho Son <shsongist@gmail.com>
Co-authored-by: guslcho <jamie14@naver.com>
Co-authored-by: DongMoon Kim <dmoons.kim@gmail.com>
Co-authored-by: bluefriday <bluefriday86@gmail.com>
This commit is contained in:
June Yi
2020-06-12 00:00:46 +09:00
parent 75c7b7c62a
commit 6c1edf3c1f
42 changed files with 1983 additions and 58 deletions
@@ -115,7 +115,7 @@ track=stable
- **CPU 요구 사항 (cores)** 와 **메모리 요구 사항 (MiB)**: 컨테이너를 위한 최소 [리소스 상한](/docs/tasks/configure-pod-container/limit-range/)을 정의할 수 있다. 기본적으로, 파드는 CPU와 메모리 상한을 두지 않고 동작한다.
- **커맨드 실행** 와 **커맨드 인수 실행**: 기본적으로, 컨테이너는 선택된 도커 이미지의 [기본 엔트리포인트 커맨드](/docs/user-guide/containers/#containers-and-commands)를 실행한다. 커맨드 옵션과 인자를 기본 옵션에 우선 적용하여 사용할 수 있다.
- **커맨드 실행** 와 **커맨드 인수 실행**: 기본적으로, 컨테이너는 선택된 도커 이미지의 [기본 엔트리포인트 커맨드](/docs/tasks/inject-data-application/define-command-argument-container/)를 실행한다. 커맨드 옵션과 인자를 기본 옵션에 우선 적용하여 사용할 수 있다.
- **특권을 가진(privileged) 상태로 실행**: 다음 세팅은 호스트에서 루트 권한을 가진 프로세스들이 [특권을 가진 컨테이너](/docs/user-guide/pods/#privileged-mode-for-pod-containers)의 프로세스들과 동등한 지 아닌지 정의한다. 특권을 가진(privileged) 컨테이너는 네트워크 스택과 디바이스에 접근하는 것을 조작하도록 활용할 수 있다.
@@ -0,0 +1,91 @@
---
title: 초기화 컨테이너에 대한 구성
content_template: templates/task
weight: 130
---
{{% capture overview %}}
이 페이지는 애플리케이션 실행 전에 파드를 초기화하기 위해 어떻게 초기화 컨테이너를
구성해야 하는지 보여준다.
{{% /capture %}}
{{% capture prerequisites %}}
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
{{% /capture %}}
{{% capture steps %}}
## 초기화 컨테이너를 갖는 파드 생성
이 연습에서 하나의 애플리케이션 컨테이너와 하나의 초기화 컨테이너를 갖는
파드를 생성한다. 초기화 컨테이너는 애플리케이션 시작
전에 실행을 종료한다.
아래는 해당 파드의 구성 파일이다.
{{< codenew file="pods/init-containers.yaml" >}}
이 구성 파일에서, 파드가 가진 볼륨을 초기화
컨테이너와 애플리케이션 컨테이너가 공유하는 것을 볼 수 있다.
초기화 컨테이너는 공유된 볼륨을
`/work-dir` 에 마운트하고, 애플리케이션 컨테이너는 공유된 볼륨을
`/usr/share/nginx/html` 에 마운트한다. 초기화 컨테이너는 다음 명령을 실행 후
종료한다.
wget -O /work-dir/index.html http://kubernetes.io
초기화 컨테이너는 nginx 서버의 루트 디렉터리 내 `index.html` 파일을
저장한다.
파드를 생성한다.
kubectl apply -f https://k8s.io/examples/pods/init-containers.yaml
nginx 컨테이너가 실행 중인지 확인한다.
kubectl get pod init-demo
출력 결과는 nginx 컨테이너가 실행 중임을 보여준다.
NAME READY STATUS RESTARTS AGE
init-demo 1/1 Running 0 1m
init-demo 파드 내 실행 중인 nginx 컨테이너의 셸을 실행한다.
kubectl exec -it init-demo -- /bin/bash
셸에서 GET 요청을 nginx 서버로 전송한다.
root@nginx:~# apt-get update
root@nginx:~# apt-get install curl
root@nginx:~# curl localhost
출력 결과는 nginx가 초기화 컨테이너에 의해 저장된 웹 페이지를 제공하고 있음을 보여준다.
<!Doctype html>
<html id="home">
<head>
...
"url": "http://kubernetes.io/"}</script>
</head>
<body>
...
<p>Kubernetes is open source giving you the freedom to take advantage ...</p>
...
{{% /capture %}}
{{% capture whatsnext %}}
* [같은 파드 내 실행 중인 컨테이너들간 통신](/ko/docs/tasks/access-application-cluster/communicate-containers-same-pod-shared-volume/)에
대해 배우기.
* [초기화 컨테이너](/ko/docs/concepts/workloads/pods/init-containers/)에 대해 배우기.
* [볼륨](/ko/docs/concepts/storage/volumes/)에 대해 배우기.
* [초기화 컨테이너 디버깅](/docs/tasks/debug-application-cluster/debug-init-containers/)에 대해 배우기.
{{% /capture %}}
@@ -0,0 +1,117 @@
---
title: 파드 실패의 원인 검증하기
content_template: templates/task
---
{{% capture overview %}}
이 페이지는 컨테이너 종료 메시지를 읽고 쓰는
방법을 보여준다.
종료 메시지는 컨테이너가 치명적인 이벤트에 대한 정보를,
대시보드나 모니터링 소프트웨어 도구와 같이
쉽게 조회 및 표시할 수 있는 위치에
기록하는 방법을 제공한다.
대부분의 경우에 종료 메시지에 넣는 정보는
일반
[쿠버네티스 로그](/ko/docs/concepts/cluster-administration/logging/)에도 쓰여져야 한다.
{{% /capture %}}
{{% capture prerequisites %}}
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
{{% /capture %}}
{{% capture steps %}}
## 종료 메시지 읽기 및 쓰기
이 예제에서는, 하나의 컨테이너를 실행하는 파드를 생성한다.
하단의 설정 파일은 컨테이너가 시작될 때 수행하는
명령어를 지정한다.
{{< codenew file="debug/termination.yaml" >}}
1. 다음의 YAML 설정 파일에 기반한 파드를 생성한다.
kubectl apply -f https://k8s.io/examples/debug/termination.yaml
YAML 파일에 있는 `cmd``args` 필드에서 컨테이너가 10초 간 잠든 뒤에
"Sleep expired" 문자열을 `/dev/termination-log` 파일에 기록하는
것을 확인할 수 있다. 컨테이너는 "Sleep expired" 메시지를
기록한 후에 종료된다.
1. 파드와 관련된 정보를 출력한다.
kubectl get pod termination-demo
파드가 더 이상 실행되지 않을 때까지 앞선 명령어를 반복한다.
1. 파드에 관한 상세 정보를 출력한다.
kubectl get pod termination-demo --output=yaml
결과는 "Sleep expired" 메시지를 포함한다.
apiVersion: v1
kind: Pod
...
lastState:
terminated:
containerID: ...
exitCode: 0
finishedAt: ...
message: |
Sleep expired
...
1. 종료 메시지만을 포함하는 출력 결과를 보기
위해서는 Go 템플릿을 사용한다.
kubectl get pod termination-demo -o go-template="{{range .status.containerStatuses}}{{.lastState.terminated.message}}{{end}}"
## 종료 메시지 사용자 정의하기
쿠버네티스는 컨테이너의 `terminationMessagePath` 필드에 지정된
종료 메시지 파일에서 종료 메시지를 검색하며, 이 필드의 기본값은
`/dev/termination-log` 이다. 이 필드를 사용자 정의 함으로써
쿠버네티스가 종료 메시지를 검색할 때 다른 파일을 사용하도록 조정할 수 있다.
쿠버네티스는 지정된 파일의 내용을 사용하여 컨테이너의 성공 및 실패에 대한 상태 메시지를 채운다.
다음의 예제에서 컨테이너는, 쿠버네티스가 조회할 수 있도록
`/tmp/my-log` 파일에 종료 메시지를 기록한다.
```yaml
apiVersion: v1
kind: Pod
metadata:
name: msg-path-demo
spec:
containers:
- name: msg-path-demo-container
image: debian
terminationMessagePath: "/tmp/my-log"
```
또한 사용자는 추가적인 사용자 정의를 위해 컨테이너의 `terminationMessagePolicy`
필드를 설정할 수 있다. 이 필드의 기본 값은 `File` 이며,
이는 오직 종료 메시지 파일에서만 종료 메시지가 조회되는 것을 의미한다.
`terminationMessagePolicy` 필드의 값을 "`FallbackToLogsOnError` 으로
설정함으로써, 종료 메시지 파일이 비어 있고 컨테이너가 오류와 함께 종료 되었을 경우
쿠버네티스가 컨테이너 로그 출력의 마지막 청크를 사용하도록 지시할 수 있다.
로그 출력은 2048 바이트나 80 행 중 더 작은 값으로 제한된다.
{{% /capture %}}
{{% capture whatsnext %}}
* [컨테이너](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#container-v1-core)
에 있는 `terminationMessagePath` 에 대해 읽어보기.
* [로그 검색](/docs/concepts/cluster-administration/logging/)에 대해 배워보기.
* [Go 템플릿](https://golang.org/pkg/text/template/)에 대해 배워보기.
{{% /capture %}}
@@ -0,0 +1,386 @@
---
title: 플러그인으로 kubectl 확장
description: kubectl 플러그인을 사용하면, 새로운 하위 명령을 추가하여 kubectl 명령의 기능을 확장할 수 있다.
content_template: templates/task
---
{{% capture overview %}}
이 가이드는 [kubectl](/docs/reference/kubectl/kubectl/) 확장을 설치하고 작성하는 방법을 보여준다. 핵심 `kubectl` 명령을 쿠버네티스 클러스터와 상호 작용하기 위한 필수 구성 요소로 생각함으로써, 클러스터 관리자는
플러그인을 이러한 구성 요소를 활용하여 보다 복잡한 동작을 만드는 수단으로 생각할 수 있다. 플러그인은 새로운 하위 명령으로 `kubectl` 을 확장하고, 주요 배포판에 포함되지 않은 `kubectl` 의 새로운 사용자 정의 기능을 허용한다.
{{% /capture %}}
{{% capture prerequisites %}}
동작하는 `kubectl` 바이너리가 설치되어 있어야 한다.
{{% /capture %}}
{{% capture steps %}}
## kubectl 플러그인 설치
플러그인은 이름이 `kubectl-` 로 시작되는 독립형 실행 파일이다. 플러그인을 설치하려면, 간단히 실행 파일을 `PATH` 에 지정된 디렉터리로 옮기면 된다.
[Krew](https://krew.dev/)를 사용하여 오픈소스에서 사용 가능한
kubectl 플러그인을 검색하고 설치할 수도 있다. Krew는 쿠버네티스 SIG CLI 커뮤니티에서 관리하는
플러그인 관리자이다.
{{< caution >}}
Krew [플러그인 인덱스](https://index.krew.dev/)를 통해 사용할 수 있는 kubectl 플러그인은
보안 감사를 받지 않는다. 써드파티 플러그인은 시스템에서 실행되는 임의의
프로그램이므로, 사용자는 이를 인지한 상태에서 설치하고 실행해야 한다.
{{< /caution >}}
### 플러그인 디스커버리
`kubectl` 은 유효한 플러그인 실행 파일을 `PATH` 에서 검색하는 `kubectl plugin list` 명령을 제공한다.
이 명령을 실행하면 `PATH` 에 있는 모든 파일을 탐색한다. 실행 가능하고, `kubectl-` 로 시작하는 모든 파일은 이 명령의 출력 결과에 *`PATH` 에 있는 순서대로* 표시된다.
실행 파일이 *아닌* 파일이 `kubectl-` 시작하는 경우 경고가 포함된다.
서로의 이름과 겹치는 유효한 플러그인 파일에 대한 경고도 포함된다.
[Krew](https://krew.dev/)를 사용하여 커뮤니티가 관리하는
[플러그인 인덱스](https://index.krew.dev/)에서 `kubectl`
플러그인을 검색하고 설치할 수 있다.
#### 제한 사항
현재 기존 `kubectl` 명령을 덮어 쓰는 플러그인을 생성할 수 없다. 예를 들어, 플러그인 `kubectl-version` 을 만들면 기존의 `kubectl version` 명령이 항상 우선하므로, 플러그인이 실행되지 않는다. 이 제한으로 인해, 플러그인을 사용하여 기존 `kubectl` 명령에 새로운 하위 명령을 추가할 수도 *없다*. 예를 들어, 플러그인 이름을 `kubectl-create-foo` 로 지정하여 `kubectl create foo` 하위 명령을 추가하면 해당 플러그인이 무시된다.
`kubectl plugin list` 는 이를 시도하는 유효한 플러그인에 대한 경고를 표시한다.
## kubectl 플러그인 작성
커맨드-라인 명령을 작성할 수 있는 프로그래밍 언어나 스크립트로 플러그인을 작성할 수 있다.
플러그인 설치 또는 사전 로딩이 필요하지 않다. 플러그인 실행 파일은
`kubectl` 바이너리에서 상속된 환경을 받는다.
플러그인은 이름을 기반으로 구현할 명령 경로를 결정한다. 예를
들어, 새로운 명령인 `kubectl foo` 를 제공하려는 플러그인은 단순히 이름이
`kubectl-foo` 이고, `PATH` 의 어딘가에 있다.
### 플러그인 예제
```bash
#!/bin/bash
# 선택적 인수 처리
if [[ "$1" == "version" ]]
then
echo "1.0.0"
exit 0
fi
# 선택적 인수 처리
if [[ "$1" == "config" ]]
then
echo "$KUBECONFIG"
exit 0
fi
echo "I am a plugin named kubectl-foo"
```
### 플러그인 사용
위의 플러그인을 사용하려면, 간단히 실행 가능하게 만든다.
```
sudo chmod +x ./kubectl-foo
```
그리고 `PATH` 의 어느 곳에나 옮겨 놓는다.
```
sudo mv ./kubectl-foo /usr/local/bin
```
이제 플러그인을 `kubectl` 명령으로 호출할 수 있다.
```
kubectl foo
```
```
I am a plugin named kubectl-foo
```
모든 인수와 플래그는 그대로 실행 파일로 전달된다.
```
kubectl foo version
```
```
1.0.0
```
모든 환경 변수도 실행 파일로 그대로 전달된다.
```bash
export KUBECONFIG=~/.kube/config
kubectl foo config
```
```
/home/<user>/.kube/config
```
```shell
KUBECONFIG=/etc/kube/config kubectl foo config
```
```
/etc/kube/config
```
또한, 플러그인으로 전달되는 첫 번째 인수는 항상 호출된 위치의 전체 경로이다(위의 예에서 `$0``/usr/local/bin/kubectl-foo` 와 동일하다).
### 플러그인 이름 지정
위 예제에서 볼 수 있듯이, 플러그인은 파일명을 기반으로 구현할 명령 경로를 결정한다. 플러그인이 대상으로 하는 명령 경로의 모든 하위 명령은 대시(`-`)로 구분된다.
예를 들어, 사용자가 `kubectl foo bar baz` 명령을 호출할 때마다 호출되는 플러그인은 파일명이 `kubectl-foo-bar-baz` 이다.
#### 플래그와 인수 처리
{{< note >}}
플러그인 메커니즘은 플러그인 프로세스에 대한 사용자 정의, 플러그인 특정 값 또는 환경 변수를 생성하지 *않는다*.
이전 kubectl 플러그인 메커니즘은 `KUBECTL_PLUGINS_CURRENT_NAMESPACE` 와 같이 더이상 사용하지 않는 환경 변수를 제공했다.
{{< /note >}}
kubectl 플러그인은 전달된 모든 인수를 파싱하고 유효성을 검사해야 한다.
플러그인 작성자를 대상으로 하는 Go 라이브러리에 대한 자세한 내용은 [커맨드 라인 런타임 패키지 사용](#커맨드-라인-런타임-패키지-사용)을 참고한다.
다음은 사용자가 추가 플래그와 인수를 제공하면서 플러그인을 호출하는 추가 사례이다. 이것은 위 시나리오의 `kubectl-foo-bar-baz` 플러그인을 기반으로한다.
`kubectl foo bar baz arg1 --flag=value arg2` 를 실행하면, kubectl의 플러그인 메커니즘은 먼저 가장 긴 가능한 이름을 가진 플러그인을 찾으려고 시도한다. 여기서는
`kubectl-foo-bar-baz-arg1` 이다. 해당 플러그인을 찾지 못하면, kubectl은 대시로 구분된 마지막 값을 인수(여기서는 `arg1`)로 취급하고, 다음으로 가장 긴 가능한 이름인 `kubectl-foo-bar-baz` 를 찾는다.
이 이름의 플러그인을 찾으면, kubectl은 해당 플러그인을 호출하여, 플러그인 이름 뒤에 모든 인수와 플래그를 플러그인 프로세스의 인수로 전달한다.
예:
```bash
# 플러그인 생성
echo -e '#!/bin/bash\n\necho "My first command-line argument was $1"' > kubectl-foo-bar-baz
sudo chmod +x ./kubectl-foo-bar-baz
# $PATH에 있는 디렉터리로 옮겨 플러그인을 "설치"
sudo mv ./kubectl-foo-bar-baz /usr/local/bin
# 플러그인을 kubectl이 인식하는지 확인
kubectl plugin list
```
```
The following kubectl-compatible plugins are available:
/usr/local/bin/kubectl-foo-bar-baz
```
```
# test that calling your plugin via a "kubectl" command works
# even when additional arguments and flags are passed to your
# plugin executable by the user.
kubectl foo bar baz arg1 --meaningless-flag=true
```
```
My first command-line argument was arg1
```
보시다시피, 사용자가 지정한 `kubectl` 명령을 기반으로 플러그인을 찾았으며, 모든 추가 인수와 플래그는 플러그인 실행 파일이 발견되면 그대로 전달된다.
#### 대시와 언더스코어가 있는 이름
`kubectl` 플러그인 메커니즘은 플러그인 파일명에 대시(`-`)를 사용하여 플러그인이 처리하는 하위 명령 시퀀스를 분리하지만, 파일명에
언더스코어(`_`)를 사용하여 커맨드 라인 호출에 대시를 포함하는 플러그인 명령을 생성할 수 있다.
예:
```bash
# 파일명에 언더스코어(_)가 있는 플러그인 생성
echo -e '#!/bin/bash\n\necho "I am a plugin with a dash in my name"' > ./kubectl-foo_bar
sudo chmod +x ./kubectl-foo_bar
# $PATH에 플러그인을 옮긴다
sudo mv ./kubectl-foo_bar /usr/local/bin
# 이제 kubectl을 통해 플러그인을 사용할 수 있다
kubectl foo-bar
```
```
I am a plugin with a dash in my name
```
참고로 플러그인 파일명에 언더스코어를 추가해도 `kubectl foo_bar` 와 같은 명령을 사용할 수 있다.
위 예에서 명령은 대시(`-`) 또는 언더스코어(`_`)을 사용하여 호출할 수 있다.
```bash
# 대시를 포함한 사용자 정의 명령을 사용할 수 있다
kubectl foo-bar
```
```
I am a plugin with a dash in my name
```
```bash
# 언더스코어를 포함한 사용자 정의 명령을 사용할 수도 있다
kubectl foo_bar
```
```
I am a plugin with a dash in my name
```
#### 이름 충돌과 오버셰도잉(overshadowing)
`PATH` 의 다른 위치에 동일한 파일명을 가진 여러 플러그인이 있을 수 있다.
예를 들어, `PATH` 값이 `PATH=/usr/local/bin/plugins:/usr/local/bin/moreplugins` 로 주어지고, `kubectl-foo` 플러그인을 복사한 파일이 `/usr/local/bin/plugins``/usr/local/bin/moreplugins` 에 있을 수 있다.
`kubectl plugin list` 명령의 출력 결과는 다음과 같다.
```bash
PATH=/usr/local/bin/plugins:/usr/local/bin/moreplugins kubectl plugin list
```
```
The following kubectl-compatible plugins are available:
/usr/local/bin/plugins/kubectl-foo
/usr/local/bin/moreplugins/kubectl-foo
- warning: /usr/local/bin/moreplugins/kubectl-foo is overshadowed by a similarly named plugin: /usr/local/bin/plugins/kubectl-foo
error: one plugin warning was found
```
위 시나리오에서, `/usr/local/bin/moreplugins/kubectl-foo` 아래의 경고는 이 플러그인이 실행되지 않을 것임을 알려준다. 대신, `PATH` 에 먼저 나타나는 실행 파일인 `/usr/local/bin/plugins/kubectl-foo` 는 항상 발견되고 `kubectl` 플러그인 메카니즘에 의해 먼저 실행된다.
이 문제를 해결하는 방법은 `kubectl` 와 함께 사용하려는 플러그인의 위치가 `PATH` 에 항상에서 먼저 오도록 하는 것이다. 예를 들어, `kubectl` 명령 `kubectl foo` 가 호출될 때마다 항상 `/usr/local/bin/moreplugins/kubectl-foo` 를 사용하려면, `PATH` 의 값을 `/usr/local/bin/moreplugins:/usr/local/bin/plugins` 로 변경한다.
#### 가장 긴 실행 파일명의 호출
플러그인 파일명으로 발생할 수 있는 또 다른 종류의 오버셰도잉이 있다. 사용자의 `PATH``kubectl-foo-bar``kubectl-foo-bar-baz` 라는 두 개의 플러그인이 있다면, `kubectl` 플러그인 메커니즘은 항상 주어진 사용자의 명령에 대해 가장 긴 가능한 플러그인 이름을 선택한다. 아래에 몇 가지 예가 있다.
```bash
# 주어진 kubectl 명령의 경우, 가장 긴 가능한 파일명을 가진 플러그인이 항상 선호된다
kubectl foo bar baz
```
```
Plugin kubectl-foo-bar-baz is executed
```
```bash
kubectl foo bar
```
```
Plugin kubectl-foo-bar is executed
```
```bash
kubectl foo bar baz buz
```
```
Plugin kubectl-foo-bar-baz is executed, with "buz" as its first argument
```
```bash
kubectl foo bar buz
```
```
Plugin kubectl-foo-bar is executed, with "buz" as its first argument
```
이 디자인 선택은 필요한 경우 여러 파일에 플러그인 하위 명령을 구현할 수 있도록 하고 이러한 하위 명령을 "부모" 플러그인 명령 아래에 중첩할 수 있도록 한다.
```bash
ls ./plugin_command_tree
```
```
kubectl-parent
kubectl-parent-subcommand
kubectl-parent-subcommand-subsubcommand
```
### 플러그인 경고 확인
위에서 언급한 `kubectl plugin list` 명령을 사용하여 `kubectl` 에 의해 플러그인이 표시되는지 확인하고, `kubectl` 명령으로 호출되지 못하게 하는 경고가 없는지 확인할 수 있다.
```bash
kubectl plugin list
```
```
The following kubectl-compatible plugins are available:
test/fixtures/pkg/kubectl/plugins/kubectl-foo
/usr/local/bin/kubectl-foo
- warning: /usr/local/bin/kubectl-foo is overshadowed by a similarly named plugin: test/fixtures/pkg/kubectl/plugins/kubectl-foo
plugins/kubectl-invalid
- warning: plugins/kubectl-invalid identified as a kubectl plugin, but it is not executable
error: 2 plugin warnings were found
```
### 커맨드 라인 런타임 패키지 사용
kubectl 용 플러그인을 작성하고 있고 Go를 사용한다면,
[cli-runtime](https://github.com/kubernetes/cli-runtime) 유틸리티 라이브러리를
사용할 수 있다.
이 라이브러리는 사용자의
[kubeconfig](/ko/docs/concepts/configuration/organize-cluster-access-kubeconfig/)
파일을 파싱이나 업데이트하거나, REST 스타일의 요청을 API 서버에 작성하거나, 구성 및 출력과
관련된 플래그를 바인딩하기 위한 헬퍼를 제공한다.
CLI 런타임 리포지터리에 제공된 도구 사용법의 예제는
[샘플 CLI 플러그인](https://github.com/kubernetes/sample-cli-plugin)을 참고한다.
## kubectl 플러그인 배포
다른 사람이 사용할 수 있는 플러그인을 개발한 경우, 이를 패키징하고, 배포하고
사용자에게 업데이트를 제공하는 방법을 고려해야 한다.
### Krew {#distributing-krew}
[Krew](https://krew.dev/)는 플러그인을 패키징하고 배포하는 크로스-플랫폼
방식을 제공한다. 이렇게 하면, 모든 대상 플랫폼(리눅스, 윈도우, macOS 등)에
단일 패키징 형식을 사용하고 사용자에게 업데이트를 제공한다.
Krew는 또한 다른 사람들이 여러분의 플러그인을 검색하고 설치할 수 있도록
[플러그인 인덱스](https://index.krew.dev/)를
유지 관리한다.
### 네이티브 / 플랫폼 별 패키지 관리 {#distributing-native}
다른 방법으로는, 리눅스의 `apt``yum`,
윈도우의 Chocolatey, macOS의 Homebrew와 같은 전통적인 패키지 관리자를 사용할 수 있다.
새 실행 파일을 사용자의 `PATH` 어딘가에 배치할 수 있는 패키지 관리자라면
어떤 패키지 관리자도 괜찮다.
플러그인 작성자로서, 이 옵션을 선택하면 각 릴리스의 여러 플랫폼에서
kubectl 플러그인의 배포 패키지를
업데이트해야 한다.
### 소스 코드 {#distributing-source-code}
소스 코드를 게시(예를 들어, Git 리포지터리)할 수 있다. 이
옵션을 선택하면, 해당 플러그인을 사용하려는 사람이 코드를 가져와서,
빌드 환경을 설정하고(컴파일이 필요한 경우), 플러그인을 배포해야 한다.
컴파일된 패키지를 사용 가능하게 하거나, Krew를 사용하면 설치가
더 쉬워진다.
{{% /capture %}}
{{% capture whatsnext %}}
* Go로 작성된 플러그인의
[자세한 예제](https://github.com/kubernetes/sample-cli-plugin)에 대해서는
샘플 CLI 플러그인 리포지터리를 확인한다.
궁금한 사항이 있으면,
[SIG CLI 팀](https://github.com/kubernetes/community/tree/master/sig-cli)에 문의한다.
* kubectl 플러그인 패키지 관리자인 [Krew](https://krew.dev/)에 대해 읽어본다.
{{% /capture %}}
@@ -0,0 +1,4 @@
---
title: "클러스터 데몬 관리"
weight: 130
---
@@ -0,0 +1,155 @@
---
title: 데몬셋(DaemonSet)에서 롤백 수행
content_template: templates/task
weight: 20
---
{{% capture overview %}}
이 페이지는 데몬셋에서 롤백을 수행하는 방법을 보여준다.
{{% /capture %}}
{{% capture prerequisites %}}
* 데몬셋 롤아웃 기록과 데몬셋 롤백 기능은
쿠버네티스 버전 1.7 이상의 `kubectl` 에서만 지원된다.
* [데몬셋에서 롤링 업데이트를
수행](/ko/docs/tasks/manage-daemon/update-daemon-set/)하는 방법을 알고 있어야 한다.
{{% /capture %}}
{{% capture steps %}}
## 데몬셋에서 롤백 수행
### 1단계: 롤백할 데몬셋 리비전 찾기
마지막 리비전으로 롤백하려는 경우 이 단계를 건너뛸 수 있다.
데몬셋의 모든 리비전을 나열한다.
```shell
kubectl rollout history daemonset <daemonset-name>
```
이 명령은 데몬셋 리비전 목록을 반환한다.
```shell
daemonsets "<daemonset-name>"
REVISION CHANGE-CAUSE
1 ...
2 ...
...
```
* 변경 원인은 데몬셋 어노테이션 `kubernetes.io/change-cause` 에서
생성 시의 리비전으로 복사된다. 변경 원인 어노테이션에서 실행된 명령을 기록하도록
`kubectl``--record=true` 를 지정할 수 있다.
특정 리비전의 세부 사항을 보려면 다음을 수행한다.
```shell
kubectl rollout history daemonset <daemonset-name> --revision=1
```
이 명령은 해당 리비전의 세부 사항을 반환한다.
```shell
daemonsets "<daemonset-name>" with revision #1
Pod Template:
Labels: foo=bar
Containers:
app:
Image: ...
Port: ...
Environment: ...
Mounts: ...
Volumes: ...
```
### 2단계: 특정 리비전으로 롤백
```shell
# --to-revision에 1단계에서 얻는 리비전 번호를 지정한다
kubectl rollout undo daemonset <daemonset-name> --to-revision=<revision>
```
성공하면, 명령은 다음을 반환한다.
```shell
daemonset "<daemonset-name>" rolled back
```
`--to-revision` 플래그를 지정하지 않은 경우, 마지막 리비전이 선택된다.
### 3단계: 데몬셋 롤백 진행 상황 확인
`kubectl rollout undo daemonset` 은 서버에 데몬셋 롤백을 시작하도록
지시한다. 실제 롤백은 서버 측에서 비동기적으로 수행된다.
롤백 진행 상황을 보려면 다음의 명령을 수행한다.
```shell
kubectl rollout status ds/<daemonset-name>
```
롤백이 완료되면, 출력 결과는 다음과 비슷하다.
```shell
daemonset "<daemonset-name>" successfully rolled out
```
{{% /capture %}}
{{% capture discussion %}}
## 데몬셋 리비전의 이해
이전 `kubectl rollout history` 단계에서, 데몬셋 리비전 목록을
얻었다. 각 리비전은 `ControllerRevision` 이라는 리소스에 저장된다.
`ControllerRevision` 은 쿠버네티스 릴리스 1.7 이상에서만 사용할 수 있는
리소스이다.
각 리비전에 저장된 내용을 보려면, 데몬셋 리비전 원시 리소스를
찾는다.
```shell
kubectl get controllerrevision -l <daemonset-selector-key>=<daemonset-selector-value>
```
이 명령은 `ControllerRevisions` 의 목록을 반환한다.
```shell
NAME CONTROLLER REVISION AGE
<daemonset-name>-<revision-hash> DaemonSet/<daemonset-name> 1 1h
<daemonset-name>-<revision-hash> DaemonSet/<daemonset-name> 2 1h
```
`ControllerRevision` 은 데몬셋 리비전의 어노테이션과 템플릿을
저장한다. ControllerRevision 오브젝트의 이름은 유효한
[DNS 서브도메인 이름](/ko/docs/concepts/overview/working-with-objects/names/#dns-서브도메인-이름)이어야 한다.
`kubectl rollout undo` 는 특정 `ControllerRevision` 을 가져와 데몬셋
템플릿을 `ControllerRevision` 에 저장된 템플릿으로 바꾼다.
`kubectl rollout undo``kubectl edit` 또는 `kubectl apply` 와 같은 다른 명령을 통해
데몬셋 템플릿을 이전 리비전으로 업데이트하는 것과
같다.
{{< note >}}
데몬셋 리비전은 롤 포워드만 한다. 즉, 롤백이
완료된 후, 롤백될 `ControllerRevision`
리비전 번호(`.revision` 필드)가 증가한다. 예를 들어,
시스템에 리비전 1과 2가 있고, 리비전 2에서 리비전 1으로 롤백하면,
`ControllerRevision``.revision: 1` 에서 `.revision: 3` 이 된다.
{{< /note >}}
## 문제 해결
* [데몬셋 롤링 업데이트
문제 해결](/ko/docs/tasks/manage-daemon/update-daemon-set/#문제-해결)을 참고한다.
{{% /capture %}}
@@ -0,0 +1,200 @@
---
title: 데몬셋(DaemonSet)에서 롤링 업데이트 수행
content_template: templates/task
weight: 10
---
{{% capture overview %}}
이 페이지는 데몬셋에서 롤링 업데이트를 수행하는 방법을 보여준다.
{{% /capture %}}
{{% capture prerequisites %}}
* 데몬셋 롤링 업데이트 기능은 쿠버네티스 버전 1.6 이상에서만 지원된다.
{{% /capture %}}
{{% capture steps %}}
## 데몬셋 업데이트 전략
데몬셋에는 두 가지 업데이트 전략 유형이 있다.
* OnDelete: `OnDelete` 업데이트 전략을 사용하여, 데몬셋 템플릿을 업데이트한 후,
이전 데몬셋 파드를 수동으로 삭제할 때 ** 새 데몬셋 파드가
생성된다. 이것은 쿠버네티스 버전 1.5 이하에서의 데몬셋의 동작과
동일하다.
* RollingUpdate: 기본 업데이트 전략이다.
`RollingUpdate` 업데이트 전략을 사용하여, 데몬셋 템플릿을
업데이트한 후, 오래된 데몬셋 파드가 종료되고, 새로운 데몬셋 파드는
제어 방식으로 자동 생성된다. 전체 업데이트 프로세스 동안 데몬셋의 최대 하나의 파드가 각 노드에서 실행된다.
## 롤링 업데이트 수행
데몬셋의 롤링 업데이트 기능을 사용하려면,
`.spec.updateStrategy.type``RollingUpdate` 를 설정해야 한다.
[`.spec.updateStrategy.rollingUpdate.maxUnavailable`](/ko/docs/concepts/workloads/controllers/deployment/#최대-불가max-unavailable)(기본값은 1)과
[`.spec.minReadySeconds`](/ko/docs/concepts/workloads/controllers/deployment/#최소-대기-시간초)(기본값은 0)으로 설정할 수도 있다.
### `RollingUpdate` 업데이트 전략으로 데몬셋 생성
이 YAML 파일은 'RollingUpdate'를 업데이트 전략으로 사용하여 데몬셋을 명시한다.
{{< codenew file="controllers/fluentd-daemonset.yaml" >}}
데몬셋 매니페스트의 업데이트 전략을 확인한 후, 데몬셋을 생성한다.
```shell
kubectl create -f https://k8s.io/examples/controllers/fluentd-daemonset.yaml
```
또는, `kubectl apply` 로 데몬셋을 업데이트하려는 경우, 동일한 데몬셋을
생성하는 데 `kubectl apply` 를 사용한다.
```shell
kubectl apply -f https://k8s.io/examples/controllers/fluentd-daemonset.yaml
```
### 데몬셋 `RollingUpdate` 업데이트 전략 확인
데몬셋의 업데이트 전략을 확인하고, `RollingUpdate` 로 설정되어 있는지
확인한다.
```shell
kubectl get ds/fluentd-elasticsearch -o go-template='{{.spec.updateStrategy.type}}{{"\n"}}' -n kube-system
```
시스템에서 데몬셋을 생성하지 않은 경우, 대신 다음의 명령으로
데몬셋 매니페스트를 확인한다.
```shell
kubectl apply -f https://k8s.io/examples/controllers/fluentd-daemonset.yaml --dry-run=client -o go-template='{{.spec.updateStrategy.type}}{{"\n"}}'
```
두 명령의 출력 결과는 다음과 같아야 한다.
```shell
RollingUpdate
```
출력 결과가 `RollingUpdate` 가 아닌 경우, 이전 단계로 돌아가서 데몬셋 오브젝트나 매니페스트를
적절히 수정한다.
### 데몬셋 템플릿 업데이트
`RollingUpdate` 데몬셋 `.spec.template` 에 대한 업데이트는 롤링 업데이트를
트리거한다. 새 YAML 파일을 적용하여 데몬셋을 업데이트한다. 이것은 여러 가지 다른 `kubectl` 명령으로 수행할 수 있다.
{{< codenew file="controllers/fluentd-daemonset-update.yaml" >}}
#### 선언적 커맨드
[구성 파일](/ko/docs/tasks/manage-kubernetes-objects/declarative-config/)을
사용하여 데몬셋을 업데이트하는 경우,
`kubectl apply` 를 사용한다.
```shell
kubectl apply -f https://k8s.io/examples/controllers/fluentd-daemonset-update.yaml
```
#### 명령형 커맨드
[명령형 커맨드](/ko/docs/tasks/manage-kubernetes-objects/imperative-command/)를
사용하여 데몬셋을 업데이트하는 경우,
`kubectl edit` 를 사용한다.
```shell
kubectl edit ds/fluentd-elasticsearch -n kube-system
```
##### 컨테이너 이미지만 업데이트
데몬셋 템플릿에서 컨테이너 이미지를 업데이트해야 하는
경우(예: `.spec.template.spec.containers[*].image`), `kubectl set image` 를 사용한다.
```shell
kubectl set image ds/fluentd-elasticsearch fluentd-elasticsearch=quay.io/fluentd_elasticsearch/fluentd:v2.6.0 -n kube-system
```
### 롤링 업데이트 상태 관찰
마지막으로, 최신 데몬셋 롤링 업데이트의 롤아웃 상태를 관찰한다.
```shell
kubectl rollout status ds/fluentd-elasticsearch -n kube-system
```
롤아웃이 완료되면, 출력 결과는 다음과 비슷하다.
```shell
daemonset "fluentd-elasticsearch" successfully rolled out
```
## 문제 해결
### 데몬셋 롤링 업데이트가 더 이상 진행되지 않는다(stuck)
가끔씩, 데몬셋 롤링 업데이트가 더 이상 진행되지 않을 수 있다. 이와 같은 상황이 발생할 수 있는 원인은
다음과 같다.
#### 일부 노드에 리소스가 부족하다
적어도 하나의 노드에서 새 데몬셋 파드를 스케줄링할 수 없어서 롤아웃이
중단되었다. 노드에 [리소스가 부족](/docs/tasks/administer-cluster/out-of-resource/)할 때
발생할 수 있다.
이 경우, `kubectl get nodes` 의 출력 결과와 다음의 출력 결과를 비교하여
데몬셋 파드가 스케줄링되지 않은 노드를 찾는다.
```shell
kubectl get pods -l name=fluentd-elasticsearch -o wide -n kube-system
```
해당 노드를 찾으면, 데몬셋이 아닌 파드를 노드에서 삭제하여
새 데몬셋 파드를 위한 공간을 생성한다.
{{< note >}}
삭제된 파드가 컨트롤러에 의해 제어되지 않거나 파드가 복제되지 않은 경우 서비스 중단이
발생한다. 이 때 [PodDisruptionBudget](/docs/tasks/configure-pod-container/configure-pod-disruption-budget/)정책도 적용되지
않는다.
{{< /note >}}
#### 롤아웃 실패
최근 데몬셋 템플릿 업데이트가 중단된 경우(예를 들어, 컨테이너가
계속 크래시되거나, 컨테이너 이미지가 존재하지 않는 경우(종종 오타로 인해)),
데몬셋 롤아웃이 진행되지 않는다.
이 문제를 해결하려면, 데몬셋 템플릿을 다시 업데이트한다. 이전의 비정상 롤아웃으로 인해
새로운 롤아웃이 차단되지 않는다.
#### 클럭 차이(skew)
데몬셋에 `.spec.minReadySeconds` 가 명시된 경우, 마스터와 노드 사이의
클럭 차이로 인해 데몬셋이 올바른 롤아웃 진행 상황을 감지할 수
없다.
## 정리
네임스페이스에서 데몬셋을 삭제한다.
```shell
kubectl delete ds fluentd-elasticsearch -n kube-system
```
{{% /capture %}}
{{% capture whatsnext %}}
* [태스크: 데몬셋에서 롤백
수행](/ko/docs/tasks/manage-daemon/rollback-daemon-set/)을 참고한다.
* [개념: 기존 데몬셋 파드를 채택하기 위한 데몬셋 생성](/ko/docs/concepts/workloads/controllers/daemonset/)을 참고한다.
{{% /capture %}}
@@ -0,0 +1,126 @@
---
title: HugePages 관리
content_template: templates/task
---
{{% capture overview %}}
{{< feature-state state="stable" >}}
쿠버네티스는 **GA** 기능으로 파드의 애플리케이션에 미리 할당된
huge page의 할당과 사용을 지원한다. 이 페이지에서는 사용자가
huge page를 사용하는 방법과 현재의 제약 사항에 대해 설명한다.
{{% /capture %}}
{{% capture prerequisites %}}
1. 쿠버네티스 노드는 노드에 대한 huge page 용량을 보고하기 위해
huge page를 미리 할당해야 한다. 노드는 여러 크기의 huge page를 미리 할당할 수
있다.
노드는 모든 huge page 리소스를 스케줄 가능한 리소스로 자동 검색하고
보고한다.
{{% /capture %}}
{{% capture steps %}}
## API
리소스 이름 `hugepages-<size>` (`<size>` 는 특정 노드에서 지원되는 정수값을
사용하는 가장 간단한 2진 표기법)를 사용하여 컨테이너 레벨의 리소스
요구 사항을 통해 huge page를 사용할 수 있다. 예를 들어,
노드가 2048KiB 및 1048576KiB 페이지 크기를 지원하는 경우, 스케줄 가능한
리소스인 `hugepages-2Mi``hugepages-1Gi` 를 노출한다. CPU나 메모리와 달리,
huge page는 오버커밋을 지원하지 않는다. 참고로 hugepage 리소스를 요청하는 경우,
메모리 또는 CPU 리소스도 요청해야 한다.
파드는 단일 파드 스펙에 여러 개의 huge page 크기를 사용할 수 있다. 이 경우
모든 볼륨 마운트에 대해 `medium: HugePages-<hugepagesize>` 표기법을 사용해야 한다.
```yaml
apiVersion: v1
kind: Pod
metadata:
name: huge-pages-example
spec:
containers:
- name: example
image: fedora:latest
command:
- sleep
- inf
volumeMounts:
- mountPath: /hugepages-2Mi
name: hugepage-2mi
- mountPath: /hugepages-1Gi
name: hugepage-1gi
resources:
limits:
hugepages-2Mi: 100Mi
hugepages-1Gi: 2Gi
memory: 100Mi
requests:
memory: 100Mi
volumes:
- name: hugepage-2mi
emptyDir:
medium: HugePages-2Mi
- name: hugepage-1gi
emptyDir:
medium: HugePages-1Gi
```
파드는 동일한 크기의 huge page들을 요청하는 경우에만 `medium: HugePages` 를 사용할 수 있다.
```yaml
apiVersion: v1
kind: Pod
metadata:
name: huge-pages-example
spec:
containers:
- name: example
image: fedora:latest
command:
- sleep
- inf
volumeMounts:
- mountPath: /hugepages
name: hugepage
resources:
limits:
hugepages-2Mi: 100Mi
memory: 100Mi
requests:
memory: 100Mi
volumes:
- name: hugepage
emptyDir:
medium: HugePages
```
- Huge page 요청(requests)은 제한(limits)과 같아야 한다. 제한이 지정되었지만, 요청은 지정되지 않은 경우
이것이 기본값이다.
- Huge page는 컨테이너 범위에서 격리되므로, 각 컨테이너에는 컨테이너 사양에서 요청한대로 cgroup 샌드박스에 대한 제한이 있다.
- Huge page가 지원하는 EmptyDir 볼륨은 파드 요청보다 더 많은 huge page 메모리를
사용하지 말아야 한다.
- `shmget()``SHM_HUGETLB` 를 통해 huge page를 사용하는 애플리케이션은
`proc/sys/vm/hugetlb_shm_group` 과 일치하는 보충 그룹(supplemental group)으로 실행해야 한다.
- 네임스페이스에서의 huge page 사용은 `hugepages-<size>` 토큰을 사용하는 `cpu` 또는 `memory` 와 같은
다른 컴퓨트 리소스와 비슷한 리소스쿼터(ResourceQuota)를 통해 제어할 수
있다.
- 다양한 크기의 huge page 지원이 기능 게이트로 제공된다. {{<
glossary_tooltip text="kubelet" term_id="kubelet" >}} 및 {{<
glossary_tooltip text="kube-apiserver"
term_id="kube-apiserver" >}} (`--feature-gates=HugePageStorageMediumSize=true`)의
`HugePageStorageMediumSize` [기능
게이트](/docs/reference/command-line-tools-reference/feature-gates/)를 사용하여 활성화할 수 있다.
## 향후 버전
- NUMA 지역성(locality)은 서비스 품질(QoS)의 기능으로 보장할 예정이다.
- 리밋레인지(LimitRange)를 지원할 예정이다.
{{% /capture %}}
@@ -48,12 +48,12 @@ Kustomize는 쿠버네티스 구성을 사용자 정의화하는 도구이다.
### 리소스 생성
컨피그 맵과 시크릿은 파드같은 다른 쿠버네티스 오브젝트에서 사용되는 설정이나 민감한 데이터를 가지고 있다.
컨피그 맵이나 시크릿의 실질적인 소스는 일반적으로 `.properties` 파일이나 ssh key 파일같이 다른 곳에서 가져온다.
컨피그 맵이나 시크릿의 실질적인 소스는 일반적으로 `.properties` 파일이나 ssh key 파일과 같은 것들은 클러스터 외부에 있다.
Kustomize는 시크릿과 컨피그 맵을 파일이나 문자열에서 생성하는 `secretGenerator``configMapGenerator`를 가지고 있다.
#### configMapGenerator
파일에서 컨피그 맵을 생성하려면 `configMapGenerator` 내의 `files` 리스트에 항목을 추가한다. 다음은 하나의 파일 콘텐츠에서 데이터 항목으로 컨피그 맵을 생성하는 예제이다.
파일에서 컨피그 맵을 생성하려면 `configMapGenerator` 내의 `files` 리스트에 항목을 추가한다. 다음은 하나의 `.properties` 파일에서 데이터 항목으로 컨피그 맵을 생성하는 예제이다.
```shell
# application.properties 파일을 생성
@@ -69,7 +69,7 @@ configMapGenerator:
EOF
```
생성된 컨피그 맵은 다음 명령어를 통해 확인할 수 있다.
생성된 컨피그 맵은 다음 명령어로 검사할 수 있다.
```shell
kubectl kustomize ./
@@ -173,7 +173,7 @@ type: Opaque
#### generatorOptions
생성된 컨피그 맵과 시크릿은 콘텐츠쉬화하여 덧붙이는 접미사를 가진다. 이는 콘텐츠가 변경될 때 새로운 컨피그 맵 이나 시크릿이 생성되는 것을 보장한다. 접미사를 추가하는 동작을 비활성화하는 방법으로 `generatorOptions`를 사용할 수 있다. 그밖에, 생성된 컨피그 맵과 시크릿에 교차 편집 옵션들을 지정해주는 것도 가능하다.
생성된 컨피그 맵과 시크릿은 콘텐츠 해시 접미사가 추가된다. 이는 콘텐츠가 변경될 때 새로운 컨피그 맵 이나 시크릿이 생성되는 것을 보장한다. 접미사를 추가하는 동작을 비활성화하는 방법으로 `generatorOptions`를 사용할 수 있다. 그밖에, 생성된 컨피그 맵과 시크릿에 교차 편집 옵션들을 지정해주는 것도 가능하다.
```shell
cat <<EOF >./kustomization.yaml
@@ -290,7 +290,7 @@ Kustomize는 서로 다른 파일들로 리소스를 구성하고 패치나 다
#### 구성
Kustomize는 서로 다른 리소스들의 구성을 지원한다. `kustomization.yaml` 파일 내 `resources` 필드는 구성 내에 포함하려는 리소스들의 리스트를 정의한다. `resources` 리스트 내에 리소스의 구성 파일의 경로를 설정한다.
다음 예제는 디플로이먼트와 서비스를 가지는 nginx 애플리케이션이다.
다음 예제는 디플로이먼트와 서비스로 구성된 NGINX 애플리케이션이다.
```shell
# deployment.yaml 파일 생성
@@ -340,11 +340,11 @@ resources:
EOF
```
`kubectl kustomize ./`의 리소스는 디플로이먼트와 서비스 오브젝트 모두 포함다.
`kubectl kustomize ./`의 리소스는 디플로이먼트와 서비스 오브젝트 모두 포함되어 있다.
#### 사용자 정의
리소스 위에 패치를 적용하는 것으로 서로 다른 사용자 정의들을 적용할 수 있다. Kustomize는
패치는 리소스에 다른 사용자 정의를 적용하는 데 사용할 수 있다. Kustomize는
`patchesStrategicMerge``patchesJson6902`를 통해 서로 다른 패치 메커니즘을 지원한다. `patchesStrategicMerge`는 파일 경로들의 리스트이다. 각각의 파일은 [전략적 병합 패치](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-api-machinery/strategic-merge-patch.md)로 분석될 수 있어야 한다. 패치 내부의 네임은 반드시 이미 읽혀진 리소스 네임과 일치해야 한다. 한 가지 일을 하는 작은 패치가 권장된다. 예를 들기 위해 디플로이먼트 레플리카 숫자를 증가시키는 하나의 패치와 메모리 상한을 설정하는 다른 패치를 생성한다.
```shell
@@ -0,0 +1,196 @@
---
title: 단일 인스턴스 스테이트풀 애플리케이션 실행하기
content_template: templates/tutorial
weight: 20
---
{{% capture overview %}}
이 페이지에서는 쿠버네티스 클러스터에서 퍼시스턴트볼륨(PersistentVolume)과 디플로이먼트(Deployment)를
사용하여, 단일 인스턴스 스테이트풀 애플리케이션을 실행하는 방법을 보인다.
해당 애플리케이션은 MySQL이다.
{{% /capture %}}
{{% capture objectives %}}
* 사용자 환경의 디스크를 참조하는 퍼시스턴트볼륨 생성하기
* MySQL 디플로이먼트 생성하기
* 알려진 DNS 이름으로 클러스터의 다른 파드에 MySQL 서비스 노출하기
{{% /capture %}}
{{% capture prerequisites %}}
* {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
* {{< include "default-storage-class-prereqs.md" >}}
{{% /capture %}}
{{% capture lessoncontent %}}
## MySQL 배포하기
쿠버네티스 디플로이먼트를 생성하고 퍼시스턴트볼륨클레임(PersistentVolumeClaim)을
사용하는 기존 퍼시스턴트볼륨에 연결하여 스테이트풀
애플리케이션을 실행할 수 있다. 예를 들어, 다음 YAML 파일은
MySQL을 실행하고 퍼시스턴트볼륨클레임을 참조하는 디플로이먼트를 기술한다.
이 파일은 /var/lib/mysql에 대한 볼륨 마운트를 정의한 후에,
20G의 볼륨을 요청하는 퍼시트턴트볼륨클레임을 생성한다.
이 클레임은 요구 사항에 적합한 기존 볼륨이나
동적 프로비저너에 의해서 충족된다.
참고: config yaml 파일에 정의된 비밀번호는 안전하지 않다. 더 안전한 해결방법을 위해
[쿠버네티스 시크릿](/docs/concepts/configuration/secret/)
을 보자
{{< codenew file="application/mysql/mysql-deployment.yaml" >}}
{{< codenew file="application/mysql/mysql-pv.yaml" >}}
1. YAML 파일의 PV와 PVC를 배포한다.
kubectl apply -f https://k8s.io/examples/application/mysql/mysql-pv.yaml
1. YAML 파일의 다른 오브젝트들을 배포한다.
kubectl apply -f https://k8s.io/examples/application/mysql/mysql-deployment.yaml
1. 디플로이먼트에 관한 정보를 확인한다.
kubectl describe deployment mysql
Name: mysql
Namespace: default
CreationTimestamp: Tue, 01 Nov 2016 11:18:45 -0700
Labels: app=mysql
Annotations: deployment.kubernetes.io/revision=1
Selector: app=mysql
Replicas: 1 desired | 1 updated | 1 total | 0 available | 1 unavailable
StrategyType: Recreate
MinReadySeconds: 0
Pod Template:
Labels: app=mysql
Containers:
mysql:
Image: mysql:5.6
Port: 3306/TCP
Environment:
MYSQL_ROOT_PASSWORD: password
Mounts:
/var/lib/mysql from mysql-persistent-storage (rw)
Volumes:
mysql-persistent-storage:
Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
ClaimName: mysql-pv-claim
ReadOnly: false
Conditions:
Type Status Reason
---- ------ ------
Available False MinimumReplicasUnavailable
Progressing True ReplicaSetUpdated
OldReplicaSets: <none>
NewReplicaSet: mysql-63082529 (1/1 replicas created)
Events:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
33s 33s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set mysql-63082529 to 1
1. 디플로이먼트로 생성된 파드를 나열한다.
kubectl get pods -l app=mysql
NAME READY STATUS RESTARTS AGE
mysql-63082529-2z3ki 1/1 Running 0 3m
1. 퍼시스턴트볼륨클레임을 살펴본다.
kubectl describe pvc mysql-pv-claim
Name: mysql-pv-claim
Namespace: default
StorageClass:
Status: Bound
Volume: mysql-pv-volume
Labels: <none>
Annotations: pv.kubernetes.io/bind-completed=yes
pv.kubernetes.io/bound-by-controller=yes
Capacity: 20Gi
Access Modes: RWO
Events: <none>
## MySQL 인스턴스 접근하기
이전의 YAML 파일은 클러스터의 다른 파드가 데이터베이스에
접근할 수 있는 서비스를 생성한다. `clusterIP: None`
서비스 옵션을 사용하면 서비스의 DNS 이름을 직접 파드의 IP 주소로
해석하도록 처리한다. 이 방법은 서비스에서 연결되는 파드가 오직 하나 뿐이고,
파드의 수를 더 늘릴 필요가 없는 경우에 가장 적합하다.
서버에 접속하기 위하여 MySQL 클라이언트를 실행한다.
```
kubectl run -it --rm --image=mysql:5.6 --restart=Never mysql-client -- mysql -h mysql -ppassword
```
이 명령어는 MySQL 클라이언트를 실행하는 파드를 클러스터에 생성하고,
서비스를 통하여 서버에 연결한다. 연결된다면, 스테이트풀
MySQL 데이터베이스가 실행 중임을 알 수 있다.
```
Waiting for pod default/mysql-client-274442439-zyp6i to be running, status is Pending, pod ready: false
If you don't see a command prompt, try pressing enter.
mysql>
```
## 업데이트하기
`kubectl apply` 명령을 사용하여 기존과 동일한 방식으로 디플로이먼트의
이미지나 다른 부분을 변경할 수 있다. 스테이트풀 애플리케이션과 관련하여 몇 가지
주의 사항이 있다.
* 애플리케이션을 스케일링하지 않는다. 이 설정은 단일 인스턴스 애플리케이션 전용이다.
기본적인 퍼시스턴트볼륨은 하나의 파드에서만 마운트할 수 있다.
클러스터 형태의 스테이트풀 애플리케이션에 대해서는
[스테이트풀셋](/ko/docs/concepts/workloads/controllers/statefulset/)을 보자.
* 디플로이먼트 구성 YAML 파일에서 `strategy:`
`type: Recreate` 를 사용한다. 이는 쿠버네티스가
롤링 업데이트를 사용하지 _않도록_ 지시한다. 동시에 두 개 이상의 파드를 생성할
수 없으므로, 롤링 업데이트는 일어나지 않게 된다. `Recreate` 전략을 사용하면
변경된 구성으로 새로운 파드를 생성하기에 앞서 기존의 파드를 중단한다.
## 디플로이먼트 삭제하기
이름으로 배포된 오브젝트를 삭제한다.
```
kubectl delete deployment,svc mysql
kubectl delete pvc mysql-pv-claim
kubectl delete pv mysql-pv-volume
```
퍼시스턴트볼륨을 수동으로 프로비저닝한 경우라면,
동일하게 수동으로 삭제하고 기본 리소스도 해제해야 한다.
동적 프로비저너를 사용한 경우, 퍼시스턴트볼륨클레임이
삭제되었을 때에 퍼시스턴트볼륨 또한 자동으로 삭제된다.
일부 동적 프로비저너(EBS 와 PD와 같은)는
퍼시스턴트볼륨을 삭제할 때에 기본 리소스도 해제한다.
{{% /capture %}}
{{% capture whatsnext %}}
* [디플로이먼트 오브젝트](/ko/docs/concepts/workloads/controllers/deployment/)에 대해 더 배워 보기
* [애플리케이션 배포하기](/docs/tasks/run-application/run-stateless-application-deployment/)에 대해 더 배워보기
* [kubectl run 문서](/docs/reference/generated/kubectl/kubectl-commands/#run)
* [볼륨](/ko/docs/concepts/storage/volumes/)과 [퍼시스턴트 볼륨](/ko/docs/concepts/storage/persistent-volumes/)
{{% /capture %}}
@@ -9,7 +9,7 @@ card:
---
<!-- overview -->
쿠버네티스 커맨드 라인 도구인 [kubectl](/docs/user-guide/kubectl/)을 사용하면, 쿠버네티스 클러스터에 대해 명령을 실행할 수 있다. kubectl을 사용하여 애플리케이션을 배포하고, 클러스터 리소스를 검사 및 관리하며 로그를 볼 수 있다. kubectl 작업의 전체 목록에 대해서는, [kubectl 개요](/docs/reference/kubectl/overview/)를 참고한다.
쿠버네티스 커맨드 라인 도구인 [kubectl](/docs/user-guide/kubectl/)을 사용하면, 쿠버네티스 클러스터에 대해 명령을 실행할 수 있다. kubectl을 사용하여 애플리케이션을 배포하고, 클러스터 리소스를 검사 및 관리하며 로그를 볼 수 있다. kubectl 작업의 전체 목록에 대해서는, [kubectl 개요](/ko/docs/reference/kubectl/overview/)를 참고한다.
## {{% heading "prerequisites" %}}