Fifth Korean localization work for release-1.14 (#14578) (#14874)

Change List
* ko: add tutorials/clusters/apparmor #12455 (#14613)
* ko: add tasks/access-application-cluster/configure-dns-cluster (#14628)
* ko: add tasks/access-application-cluster/communicate-containers-same-… (#14627)
* ko: Update outdated files of setup and tasks in dev-1.14-ko.5 partly (#14683)
* translate to content/ko/docs/concepts/cluster-administration/cluster-… (#14237)
* Update renamed or deleted files in dev-1.14-ko.5 (#14710)
* Create pod.md (#13927)

Co-Authored-By:    Yoon <learder@gmail.com>
Co-Authored-By:    Woojin Na(Eddie) <kimchigood1130@gmail.com>
Co-Authored-By:    Claudia J. Kang <claudiajkang@gmail.com>
This commit is contained in:
June Yi
2019-06-15 21:16:10 -07:00
committed by Kubernetes Prow Robot
parent 1d874b911c
commit 0f7cb401ee
30 changed files with 1101 additions and 414 deletions
+1 -1
View File
@@ -53,7 +53,7 @@ weight: 40
클러스터에 대해 바라는 상태를 유지할 책임은 쿠버네티스 마스터에 있다. `kubectl` 커맨드라인 인터페이스와 같은 것을 사용해서 쿠버네티스로 상호 작용할 때에는 쿠버네티스 마스터와 통신하고 있는 셈이다.
> "마스터"는 클러스터 상태를 관리하는 프로세스의 묶음이다. 주로 프로세스는 클러스터 내 단일 노드에서 구동되며, 이 노드가 바로 마스터이다. 마스터는 가용성과 중복을 위해 복제될 수도 있다.
> "마스터"는 클러스터 상태를 관리하는 프로세스의 묶음이다. 주로 모든 프로세스는 클러스터 내 단일 노드에서 구동되며, 이 노드가 바로 마스터이다. 마스터는 가용성과 중복을 위해 복제될 수도 있다.
### 쿠버네티스 노드
@@ -225,9 +225,9 @@ rules:
* [Digital Ocean](https://github.com/digitalocean/digitalocean-cloud-controller-manager)
* [Oracle](https://github.com/oracle/oci-cloud-controller-manager)
* [Azure](https://github.com/kubernetes/kubernetes/tree/master/pkg/cloudprovider/providers/azure)
* [GCE](https://github.com/kubernetes/kubernetes/tree/master/pkg/cloudprovider/providers/gce)
* [AWS](https://github.com/kubernetes/kubernetes/tree/master/pkg/cloudprovider/providers/aws)
* [Azure](https://github.com/kubernetes/cloud-provider-azure)
* [GCP](https://github.com/kubernetes/cloud-provider-gcp)
* [AWS](https://github.com/kubernetes/cloud-provider-aws)
* [BaiduCloud](https://github.com/baidu/cloud-provider-baiducloud)
* [Linode](https://github.com/linode/linode-cloud-controller-manager)
@@ -0,0 +1,69 @@
---
title: 클러스터 관리 개요
content_template: templates/concept
weight: 10
---
{{% capture overview %}}
클러스터 관리 개요는 쿠버네티스 클러스터를 만들거나 관리하는 모든 사람들을 위한 것이다.
여기서는 쿠버네티스의 핵심 [개념](/ko/docs/concepts/)에 대해 잘 알고 있다고 가정한다.
{{% /capture %}}
{{% capture body %}}
## 클러스터 계획
[올바른 솔루션 고르기](/ko/docs/setup/pick-right-solution/)에서 쿠버네티스 클러스터를 어떻게 계획하고, 셋업하고, 구성하는 지에 대한 예시를 참조하자. 이 글에 쓰여진 솔루션들은 *배포판* 이라고 부른다.
가이드를 고르기 전에, 몇 가지 고려사항이 있다.
- 단지 자신의 컴퓨터에 쿠버네티스를 테스트를 하는지, 또는 고가용성의 멀티 노드 클러스터를 만들려고 하는지에 따라 니즈에 가장 적절한 배포판을 고르자.
- **만약 고가용성을 만들려고 한다면**, [여러 영역에서의 클러스터](/ko/docs/concepts/cluster-administration/federation/) 설정에 대해 배우자.
- [구글 쿠버네티스 엔진](https://cloud.google.com/kubernetes-engine/)과 같은 **호스팅된 쿠버네티스 클러스터** 를 사용할 것인지, **자신의 클러스터에 호스팅할 것인지**?
- 클러스터가 **온프레미스** 인지, 또는 **클라우드(IaaS)** 인지? 쿠버네티스는 하이브리드 클러스터를 직접적으로 지원하지는 않는다. 대신에, 사용자는 여러 클러스터를 구성할 수 있다.
- **만약 온프레미스에서 쿠버네티스를 구성한다면**, 어떤 [네트워킹 모델](/docs/concepts/cluster-administration/networking/)이 가장 적합한지 고려한다.
- 쿠버네티스 실행을 **"베어메탈" 하드웨어** 또는, **가상 머신 (VMs)** 중 어디에서 할 것 인지?
- **단지 클러스터 동작** 만 할 것인지, 아니면 **쿠버네티스 프로젝트 코드의 적극적인 개발** 을 원하는지? 만약 후자의 경우라면,
적극적으로 개발된 배포판을 선택한다. 몇몇 배포판은 바이너리 릴리스 밖에 없지만,
매우 다양한 선택권을 제공한다.
- 스스로 클러스터 구동에 필요한 [구성요소](/docs/admin/cluster-components/)에 익숙해지자.
참고: 모든 배포판이 적극적으로 유지되는 것은 아니다. 최근 버전의 쿠버네티스로 테스트 된 배포판을 선택하자.
## 클러스터 관리
* [클러스터 관리](/docs/tasks/administer-cluster/cluster-management/)는 클러스터의 라이프사이클과 관련된 몇 가지 주제를 설명한다. 이는 새 클러스터 생성, 마스터와 워커노드 업그레이드, 노드 유지보수 실행 (예: 커널 업그레이드), 그리고 동작 중인 클러스터의 쿠버네티스 API 버전 업그레이드 등을 포함한다.
* 어떻게 [노드 관리](/ko/docs/concepts/architecture/nodes/)를 하는지 배워보자.
* 공유된 클러스터의 [자원 할당량](/docs/concepts/policy/resource-quotas/)을 어떻게 셋업하고 관리할 것인지 배워보자.
## 클러스터 보안
* [인증서](/docs/concepts/cluster-administration/certificates/)는 다른 툴 체인을 이용하여 인증서를 생성하는 방법을 설명한다.
* [쿠버네티스 컨테이너 환경](/docs/concepts/containers/container-environment-variables/)은 쿠버네티스 노드에서 Kubelet에 의해 관리되는 컨테이너 환경에 대해 설명한다.
* [쿠버네티스 API에 대한 접근 제어](/docs/reference/access-authn-authz/controlling-access/)는 사용자와 서비스 계정에 어떻게 권한 설정을 하는지 설명한다.
* [인증](/docs/reference/access-authn-authz/authentication/)은 다양한 인증 옵션을 포함한 쿠버네티스에서의 인증을 설명한다.
* [인가](/docs/reference/access-authn-authz/authorization/)은 인증과 다르며, HTTP 호출이 처리되는 방법을 제어한다.
* [어드미션 컨트롤러 사용](/docs/reference/access-authn-authz/admission-controllers/)은 쿠버네티스 API 서버에서 인증과 인가 후 요청을 가로채는 플러그인을 설명한다.
* [쿠버네티스 클러스터에서 Sysctls 사용](/docs/concepts/cluster-administration/sysctl-cluster/)는 관리자가 `sysctl` 커맨드라인 툴을 사용하여 커널 파라미터를 설정하는 방법을 설명한다.
* [감시](/docs/tasks/debug-application-cluster/audit/)는 쿠버네티스 감시 로그가 상호작용 하는 방법을 설명한다.
### kubelet 보안
* [마스터노드 커뮤니케이션](/ko/docs/concepts/architecture/master-node-communication/)
* [TLS 부트스트래핑](/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/)
* [Kubelet 인증/인가](/docs/admin/kubelet-authentication-authorization/)
## 선택적 클러스터 서비스
* [DNS 통합](/docs/concepts/services-networking/dns-pod-service/)은 DNS 이름이 쿠버네티스 서비스에 바로 연결되도록 변환하는 방법을 설명한다.
* [클러스터 활동 로깅과 모니터링](/docs/concepts/cluster-administration/logging/)은 쿠버네티스 로깅이 로깅의 작동 방법과 로깅을 어떻게 구현하는지 설명한다.
{{% /capture %}}
+1 -2
View File
@@ -1,5 +1,4 @@
---
title: "개요"
weight: 20
---
---
@@ -1,4 +0,0 @@
---
title: "kubectl을 이용한 오브젝트 관리"
weight: 50
---
@@ -1,990 +0,0 @@
---
title: 구성 파일을 이용한 쿠버네티스 오브젝트의 선언형 관리
content_template: templates/concept
weight: 40
---
{{% capture overview %}}
쿠버네티스 오브젝트는 여러 개의 오브젝트 구성 파일을
디렉터리에 저장하고 필요에 따라 `kubectl apply`
사용하여 재귀적으로 오브젝트를 생성하고 업데이트함으로써 생성, 업데이트 및 삭제할 수 있다.
이 방식은 변경사항을 되돌려 오브젝트 구성 파일에 병합하지 않고
활성 오브젝트에 가해진 기록을 유지한다. `kubectl diff`는 또한
`apply`가 어떠한 변경사항을 이루어질지에 대한 프리뷰를 제공한다.
{{% /capture %}}
{{% capture body %}}
## 트레이드 오프
`kubectl` 툴은 세 가지 방식의 오브젝트 관리를 지원한다.
* 명령형 커맨드
* 명령형 오브젝트 구성
* 선언형 오브젝트 구성
오브젝트 관리 방식의 종류별 장단점에 대한 논의는 [Kubernetes Object Management](/docs/concepts/overview/object-management-kubectl/overview/)를
참고한다.
## 시작하기 전에
선언형 오브젝트 구성은 쿠버네티스 오브젝트 정의와
구성에 대한 확실한 이해가 필요하다. 아직 그렇지 못하다면,
먼저 다음 문서를 읽고 이해한다.
- [명령형 커맨드를 사용한 쿠버네티스 오브젝트 관리하기](/ko/docs/concepts/overview/object-management-kubectl/imperative-command/)
- [구성 파일을 사용한 쿠버네티스 오브젝트 명령형 관리](/ko/docs/concepts/overview/object-management-kubectl/imperative-config/)
다음은 이 문서에서 사용되는 용어에 대한 정의이다.
- *오브젝트 구성 파일 / 구성 파일*: 쿠버네티스 오브젝트에 대한
구성을 정의하는 하나의 파일. 이 주제는 어떻게
`kubectl apply`에 구성 파일을 전달하는지에 대해 보여준다. 구성 파일은 일반적으로 Git과 같은, 소스 컨트롤에 저장된다.
- *활성 오브젝트 구성 / 활성 구성*: 쿠버네티스 클러스터에 의해 관측된
오브젝트에 대한 활성 구성 값. 이것들은 쿠버네티스 클러스터 저장소에 유지된다.
일반적으로 etcd가 사용된다.
- *선언형 구성 작성자 / 선언형 작성자*: 활성 오브젝트를 업데이트해 주는
사람이나 소프트웨어. 이 주제에서 언급하는 활성 작성자는 오브젝트 구성 파일에 변경을 가하고
`kubectl apply`를 실행하여 변경사항을 기록한다.
## 오브젝트 생성 방법
기존에 존재하는 것을 제외한, 지정한 디렉터리 내 구성 파일에 의해 정의된 모든 오브젝트를 생성하기 위해 `kubectl apply`
사용한다.
```shell
kubectl apply -f <디렉터리>/
```
이것은  각 오브젝트에 대해 `kubectl.kubernetes.io/last-applied-configuration: '{...}'`
어노테이션을 설정한다. 해당 어노테이션은 오브젝트를 생성하기 위해 사용했던
오브젝트 구성 파일의 내용을 포함한다. 
{{< note >}}
재귀적으로 디렉터리를 처리하기 위해서 `-R` 플래그를 추가한다. 
{{< /note >}}
다음은 오브젝트 구성 파일에 대한 예시이다.
{{< codenew file="application/simple_deployment.yaml" >}}
생성될 오브젝트를 출력하려면 `kubectl diff`를 실행한다. 
```shell
kubectl diff -f https://k8s.io/examples/application/simple_deployment.yaml
```
{{< note >}}
`diff``kube-apiserver`의 활성화가 필요한 [서버사이드 dry-run](/docs/reference/using-api/api-concepts/#dry-run)을 사용한다.
{{< /note >}}
`kubectl apply`를 사용하여 오브젝트를 생성한다.
```shell
kubectl apply -f https://k8s.io/examples/application/simple_deployment.yaml
```
`kubectl get`을 사용하여 활성 구성을 출력한다.
```shell
kubectl get -f https://k8s.io/examples/application/simple_deployment.yaml -o yaml
```
출력은 `kubectl.kubernetes.io/last-applied-configuration` 어노테이션이
활성 구성에 기록된 것을 보여주며, 그것은 구성 파일과 일치한다.
```yaml
kind: Deployment
metadata:
annotations:
# ...
# This is the json representation of simple_deployment.yaml
# It was written by kubectl apply when the object was created
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"apps/v1","kind":"Deployment",
"metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"},
"spec":{"minReadySeconds":5,"selector":{"matchLabels":{"app":nginx}},"template":{"metadata":{"labels":{"app":"nginx"}},
"spec":{"containers":[{"image":"nginx:1.7.9","name":"nginx",
"ports":[{"containerPort":80}]}]}}}}
# ...
spec:
# ...
minReadySeconds: 5
selector:
matchLabels:
# ...
app: nginx
template:
metadata:
# ...
labels:
app: nginx
spec:
containers:
- image: nginx:1.7.9
# ...
name: nginx
ports:
- containerPort: 80
# ...
# ...
# ...
# ...
```
## How to update objects
또한 오브젝트가 기존에 존재하더라도 디렉터리 내 정의된 모든 오브젝트를 업데이트하기 위해 `kubectl apply`
사용할 수 있다. 이러한 접근방식은 다음을 수행할 수 있게 해준다.
1. 활성 구성 내 구성 파일에 나타나는 필드 설정
2. 활성 구성 내 구성 파일로부터 제거된 필드 정리
```shell
kubectl diff -f <디렉터리>/
kubectl apply -f <디렉터리>/
```
{{< note >}}
재귀적으로 디렉터리를 처리하기 위해서 `-R`플래그를 추가한다.
{{< /note >}}
다음은 구성 파일의 예시이다.
{{< codenew file="application/simple_deployment.yaml" >}}
`kubectl apply`를 사용하여 오브젝트를 생성한다.
```shell
kubectl apply -f https://k8s.io/examples/application/simple_deployment.yaml
```
{{< note >}}
설명을 위해, 앞선 명령은 디렉터리 대신
하나의 구성 파일을 참조한다.
{{< /note >}}
`kubectl get`을 사용하여 활성 구성을 출력한다.
```shell
kubectl get -f https://k8s.io/examples/application/simple_deployment.yaml -o yaml
```
출력은 `kubectl.kubernetes.io/last-applied-configuration` 어노테이션이
활성 구성에 기록된 것을 보여주며, 그것은 구성 파일과 일치한다.
```yaml
kind: Deployment
metadata:
annotations:
# ...
# This is the json representation of simple_deployment.yaml
# It was written by kubectl apply when the object was created
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"apps/v1","kind":"Deployment",
"metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"},
"spec":{"minReadySeconds":5,"selector":{"matchLabels":{"app":nginx}},"template":{"metadata":{"labels":{"app":"nginx"}},
"spec":{"containers":[{"image":"nginx:1.7.9","name":"nginx",
"ports":[{"containerPort":80}]}]}}}}
# ...
spec:
# ...
minReadySeconds: 5
selector:
matchLabels:
# ...
app: nginx
template:
metadata:
# ...
labels:
app: nginx
spec:
containers:
- image: nginx:1.7.9
# ...
name: nginx
ports:
- containerPort: 80
# ...
# ...
# ...
# ...
```
`kubectl scale`을 사용하여 활성 구성 내 `replicas` 필드를 직접 업데이트한다.
이는 `kubectl apply`를 사용하지 않는다.
```shell
kubectl scale deployment/nginx-deployment --replicas=2
```
`kubectl get`을 사용하여 활성 구성을 출력한다.
```shell
kubectl get -f https://k8s.io/examples/application/simple_deployment.yaml -o yaml
```
출력은 `replicas` 필드가 2로 설정된 것을 보여주며, `last-applied-configuration`
어노테이션은 `replicas` 필드를 포함하지 않는다.
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
# ...
# note that the annotation does not contain replicas
# because it was not updated through apply
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"apps/v1","kind":"Deployment",
"metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"},
"spec":{"minReadySeconds":5,"selector":{"matchLabels":{"app":nginx}},"template":{"metadata":{"labels":{"app":"nginx"}},
"spec":{"containers":[{"image":"nginx:1.7.9","name":"nginx",
"ports":[{"containerPort":80}]}]}}}}
# ...
spec:
replicas: 2 # written by scale
# ...
minReadySeconds: 5
selector:
matchLabels:
# ...
app: nginx
template:
metadata:
# ...
labels:
app: nginx
spec:
containers:
- image: nginx:1.7.9
# ...
name: nginx
ports:
- containerPort: 80
# ...
```
`nginx:1.7.9`에서 `nginx:1.11.9`로 이미지를 변경하기 위해 `simple_deployment.yaml`
구성 파일을 업데이트 하고, `minReadySeconds` 필드를 삭제한다.
{{< codenew file="application/update_deployment.yaml" >}}
구성 파일에 이루어진 변경사항을 적용한다.
```shell
kubectl diff -f https://k8s.io/examples/application/update_deployment.yaml
kubectl apply -f https://k8s.io/examples/application/update_deployment.yaml
```
`kubectl get`을 사용하여 활성 구성을 출력한다.
```
kubectl get -f https://k8s.io/examples/application/simple_deployment.yaml -o yaml
```
출력은 활성 구성에 다음의 변경사항을 보여준다.
- `replicas` 필드는 `kubectl scale`에 의해 설정된 값 2를 유지한다.
이는 구성 파일에서 생략되었기 때문에 가능하다.
- `image` 필드는 `nginx:1.7.9`에서 `nginx:1.11.9`로 업데이트되었다.
- `last-applied-configuration` 어노테이션은 새로운 이미지로 업데이트되었다.
- `minReadySeconds` 필드는 지워졌다.
- `last-applied-configuration` 어노테이션은 더 이상 `minReadySeconds` 필드를 포함하지 않는다.
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
# ...
# The annotation contains the updated image to nginx 1.11.9,
# but does not contain the updated replicas to 2
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"apps/v1","kind":"Deployment",
"metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"},
"spec":{"selector":{"matchLabels":{"app":nginx}},"template":{"metadata":{"labels":{"app":"nginx"}},
"spec":{"containers":[{"image":"nginx:1.11.9","name":"nginx",
"ports":[{"containerPort":80}]}]}}}}
# ...
spec:
replicas: 2 # Set by `kubectl scale`. Ignored by `kubectl apply`.
# minReadySeconds cleared by `kubectl apply`
# ...
selector:
matchLabels:
# ...
app: nginx
template:
metadata:
# ...
labels:
app: nginx
spec:
containers:
- image: nginx:1.11.9 # Set by `kubectl apply`
# ...
name: nginx
ports:
- containerPort: 80
# ...
# ...
# ...
# ...
```
{{< warning >}}
명령형 오브젝트 구성 커맨드 `create``replace`와 함께 `kubectl apply`
혼합하는 것은 지원하지 않는다. 이는 `kubectl apply`가 업데이트 사항을 계산하는데 사용하는
`kubectl.kubernetes.io/last-applied-configuration``create``replace`
유지하지 하지 않기 때문이다.
{{< /warning >}}
## 오브젝트 삭제 방법
`kubectl apply`에 의해 관리되는 오브젝트를 삭제하는데 2가지 접근 방법이 있다.
### 권장 방법: `kubectl delete -f <파일명>`
명령형 커맨드를 사용하여 오브젝트를 수동으로 삭제하는 것이 권장되는 방식인데,
무엇이 삭제되는지에 대해 더 명확하게 나타내므로 사용자가 의도하지 않게
무언가를 삭제할 가능성이 작아지기 때문이다.
```shell
kubectl delete -f <파일명>
```
### 대안: `kubectl apply -f <디렉터리/> --prune -l your=레이블`
무엇을 하는지 파악하는 경우에만 이를 사용한다.
{{< warning >}}
`kubectl apply --prune`은 알파 상태이며, 후속 릴리스에서는
하위 호환되지 않는 변경 사항이 도입될 수 있다.
{{< /warning >}}
{{< warning >}}
이 명령을 사용할 때는 의도하지 않게 오브젝트를 삭제하지 않도록
주의해야만 한다.
{{< /warning >}}
`kubectl delete`에 대한 대안으로, 디렉터리로부터 구성 파일이 삭제된 후에 삭제될 오브젝트를 식별하기 위해 `kubectl apply`를 사용할 수 있다.
`--prune`을 사용하여 적용하면 일련의 레이블의 집합과 일치하는
모든 오브젝트에 대해API 서버에 쿼리하고, 반환된 활성 오브젝트
구성을 오브젝트 구성 파일에 일치시키려고 시도한다.
오브젝트가 쿼리에 일치하고, 해당 디렉터리 내 구성 파일이 없고
`last-applied-configuration`어노테이션이 있는 경우,
삭제된다.
{{< comment >}}
TODO(pwittrock): We need to change the behavior to prevent the user from running apply on subdirectories unintentionally.
{{< /comment >}}
```shell
kubectl apply -f <디렉터리/> --prune -l <레이블>
```
{{< warning >}}
prune을 사용하여 적용하는 것은 오브젝트 구성 파일을
포함하는 루트 디렉터리에 대해서만 실행해야 한다.
하위 디렉터리에 대해 실행하게 되면,
`-l <레이블>`로 지정된 레이블 셀렉터에 의해 반환되고 하위 디렉터리에 나타나지 않는 경우,
오브젝트가 의도하지 않게 삭제될 수 있다.
{{< /warning >}}
## 오브젝트 확인 방법
활성 오브젝트의 구성을 확인하기 위해 `-o yaml`과 함께 `kubectl get`을 사용할 수 있다.
```shell
kubectl get -f <파일명|url> -o yaml
```
## 어떻게 apply가 차이를 계산하고 변경을 병합하는가
{{< caution >}}
*patch* 는 전체 오브젝트 대신 오브젝트의 특정 필드 범위의 오퍼레이션을 업데이트한다.
이는 먼저 오브젝트를 읽지 않고도 오브젝트의 특정 필드 집합만을
업데이트할 수 있도록 해준다.
{{< /caution >}}
`kubectl apply`가 하나의 오브젝트에 대한 활성 구성을 업데이트할 때,
API 서버에 패치 요청을 보냄으로써 그것을 수행한다.
그 패치는 활성 오브젝트 구성의 특정 필드에 대한 범위의
업데이트로 한정한다. `kubectl apply` 커맨드는
구성 파일, 활성 구성, 그리고 활성 구성에 저장된
`last-applied-configuration`어노테이션을 사용하여 이 패치 요청을 계산한다.
### 패치 계산 병합
`kubectl apply` 명령은
`kubectl.kubernetes.io/last-applied-configuration` 어노테이션에 구성 파일의 내용을 기록한다.
이것은 구성 파일로부터 제거되었고 활성 구성으로부터 지워질 필요가 있는
필드를 확인하는 데 사용된다. 다음은 어떤 필드가 삭제 또는 설정돼야 하는지
계산하기 위해 사용되는 단계이다.
1. 삭제할 필드를 계산한다. 이것은 `last-applied-configuration` 내 존재하고 구성 파일로부터 유실된 필드이다.
2. 추가 또는 설정되어야 할 필드를 계산한다. 이것은 활성 구성과 불일치하는 값을 가지는 구성 파일 내 존재하는 필드이다.
다음은 예시이다. 디플로이먼트 오브젝트에 대한 구성 파일이라고 가정한다.
{{< codenew file="application/update_deployment.yaml" >}}
또한, 이것은 동일한 디플로이먼트 오브젝트에 대한 활성 구성이라고 가정한다.
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
# ...
# note that the annotation does not contain replicas
# because it was not updated through apply
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"apps/v1","kind":"Deployment",
"metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"},
"spec":{"minReadySeconds":5,"selector":{"matchLabels":{"app":nginx}},"template":{"metadata":{"labels":{"app":"nginx"}},
"spec":{"containers":[{"image":"nginx:1.7.9","name":"nginx",
"ports":[{"containerPort":80}]}]}}}}
# ...
spec:
replicas: 2 # written by scale
# ...
minReadySeconds: 5
selector:
matchLabels:
# ...
app: nginx
template:
metadata:
# ...
labels:
app: nginx
spec:
containers:
- image: nginx:1.7.9
# ...
name: nginx
ports:
- containerPort: 80
# ...
```
다음은 `kubectl apply`에 의해 수행될 병합 계산이다.
1. `last-applied-configuration`으로부터 값을 읽어
구성 파일의 값과 비교하여 삭제할 필드를
계산한다.
`last-applied-configuration`에 보이는 것과는 무관하게
로컬의 오브젝트 구성 파일 내 null이라고 명시적으로 설정된 필드를 지운다.
이 예시에서, `minReadySeconds`
`last-applied-configuration` 어노테이션 내 나타나지만, 구성 파일 내에는 보여지지 않는다.
**조치:** 활성 구성으로부터 `minReadySeconds`을 지운다.
2. 구성 파일로부터 값을 읽어 활성 구성 내 값과
비교하여 설정할 필드를 계산한다. 이 예시에서,
구성 파일 내 `image` 값은 활성 구성 내 값과 불일치한다.
**조치:** 활성 구성 내 `image` 값을 설정한다.
3. 구성 파일의 값과 일치시키기 위해 `last-applied-configuration`
어노테이션을 설정한다.
4. 1, 2, 3으로부터의 결과를 API 서버에 단일 패치 요청으로 병합한다.
다음은 병합의 결과인 활성 구성이다.
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
# ...
# The annotation contains the updated image to nginx 1.11.9,
# but does not contain the updated replicas to 2
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"apps/v1","kind":"Deployment",
"metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"},
"spec":{"selector":{"matchLabels":{"app":nginx}},"template":{"metadata":{"labels":{"app":"nginx"}},
"spec":{"containers":[{"image":"nginx:1.11.9","name":"nginx",
"ports":[{"containerPort":80}]}]}}}}
# ...
spec:
selector:
matchLabels:
# ...
app: nginx
replicas: 2 # Set by `kubectl scale`. Ignored by `kubectl apply`.
# minReadySeconds cleared by `kubectl apply`
# ...
template:
metadata:
# ...
labels:
app: nginx
spec:
containers:
- image: nginx:1.11.9 # Set by `kubectl apply`
# ...
name: nginx
ports:
- containerPort: 80
# ...
# ...
# ...
# ...
```
### 어떻게 상이한 필드 타입이 병합되는가
구성 파일 내 특정 필드가 필드의 타입에 따라
어떻게 활성 구성과 함께 병합되는가.
여러 가지 필드 타입이 있다.
- *기본(primitives)*: 문자열, 숫자 또는 불리언 타입의 필드.
예를 들어, `image``replicas`는 기본 필드다. **조치:** 교체.
- *맵*, 또한 *오브젝트* 라 칭함: 맵 타입 또는 서브필드를 포함하는 복합 타입의 필드. 예를 들어, `레이블`,
`어노테이션`,`스펙``메타데이터`는 모두 맵이다. **조치:** 구성요소 또는 서브필드 병합.
- *리스트*: 기본타입 또는 맵이 될 수 있는 아이템의 리스트를 포함하는 필드.
예를 들어, `컨테이너`, `포트`, 그리고 `args`는 리스트다. **조치:** 다양함.
`kubectl apply`가 맵 또는 리스트 필드를 업데이트하는 경우,
일반적으로 전체 필드를 교체하는 대신, 개별 부 구성요소를 업데이트한다,
예를 들어, 디플로이먼트에 대한 `spec`을 병합할 경우, 전체 `spec`
교체되지 않는다. 대신 `replicas`와 같은 `spec`의 서브필드가
비교되고 병합된다.
### 기본 필드에 대한 변경사항 병합하기
기본 필드는 교체되거나 지워진다.
{{< note >}}
`-` 는 값이 사용되지 않기 때문에 "해당 없음"으로 사용된다.
{{< /note >}}
| Field in object configuration file | Field in live object configuration | Field in last-applied-configuration | Action |
|-------------------------------------|------------------------------------|-------------------------------------|-------------------------------------------|
| Yes | Yes | - | 구성 파일 값 활성으로 설정. |
| Yes | No | - | 활성을 로컬 구성으로 설정. |
| No | - | Yes | 활성 구성으로부터 지움. |
| No | - | No | 아무것도 안함. 활성값 유지. |
### 맵 필드에 변경사항 병합하기
맵을 요청하는 필드는 서브필드의 각각 또는 맵의 구성요소를 비교함으로써 병합된다.
{{< note >}}
`-` 는 값이 사용되지 않기 때문에 "해당 없음"으로 사용된다.
{{< /note >}}
| Key in object configuration file | Key in live object configuration | Field in last-applied-configuration | Action |
|-------------------------------------|------------------------------------|-------------------------------------|----------------------------------|
| Yes | Yes | - | 서브필드 값 비교. |
| Yes | No | - | 활성을 로컬 구성으로 설정. |
| No | - | Yes | 활성 구성으로부터 삭제. |
| No | - | No | 아무것도 안함. 활성값 유지. |
### 타입 리스트의 필드에 대한 변경사항 병합하기
리스트에 대한 변경사항을 병합하는 것은 세 가지 전략 중 하나를 사용한다.
* 구성요소가 모두 기본형인 경우 리스트를 교체한다.
* 복합 구성요소의 리스트에서 개별 구성요소를 병합한다.
* 기초 구성요소의 리스트를 병합한다.
전략에 대한 선택은 필드별로 이루어진다.
#### 구성요소가 모두 기본형인 경우 리스트 교체
기초 필드와 동일한 리스트로 취급한다. 전체 리스트를 교체 또는 삭제한다.
이것은 순서를 유지한다.
**예시:** 파드 내 컨테이너의 `args` 필드를 업데이트하기 위해 `kubectl apply`를 사용한다.
이것은 활성 구성 내 `args`의 값을 구성 파일 내 값으로 설정한다.
활성 구성에 추가했던 이전의 모든 `args`구성요소들은 유실된다.
구성 파일 내 정의한 `args` 구성요소의 순서는
활성 구성 내 유지된다.
```yaml
# last-applied-configuration value
args: ["a", "b"]
# configuration file value
args: ["a", "c"]
# live configuration
args: ["a", "b", "d"]
# result after merge
args: ["a", "c"]
```
**설명:** 병합은 새로운 리스트 값으로 구성 파일 값을 사용했다.
#### 복합 구성요소 리스트에 대한 개별 구성요소 병합
리스트를 맵으로 취급하고 각 구성요소의 특정 필드를 키로 취급한다.
개별 구성요소를 추가, 삭제, 또는 업데이트 한다. 이것은 순서를 보존하지 않는다.
이 병합 전략은 각 필드에 `patchMergeKey`라 칭하는 특별한 태그를 사용한다.
`patchMergeKey`는 쿠버네티스 소스 코드:
[types.go](https://github.com/kubernetes/api/blob/d04500c8c3dda9c980b668c57abc2ca61efcf5c4/core/v1/types.go#L2747)
의 각 필드에 대해 정의한다. 맵 리스트를 병합할 때, 주어진 구성요소에 대한 `patchMergeKey`
지정한 필드는 해당 구성요소에 대한 맵키와 같이 사용된다.
**예시:** `kubectl apply`를 사용하여 PodSpec에 대한 `containers`필드를 업데이트한다.
이렇게 하면 각 구성요소가
`name`별로 키로 되어 있는 맵인 것처럼 리스트를 병합한다.
```yaml
# last-applied-configuration value
containers:
- name: nginx
image: nginx:1.10
- name: nginx-helper-a # key: nginx-helper-a; will be deleted in result
image: helper:1.3
- name: nginx-helper-b # key: nginx-helper-b; will be retained
image: helper:1.3
# configuration file value
containers:
- name: nginx
image: nginx:1.10
- name: nginx-helper-b
image: helper:1.3
- name: nginx-helper-c # key: nginx-helper-c; will be added in result
image: helper:1.3
# live configuration
containers:
- name: nginx
image: nginx:1.10
- name: nginx-helper-a
image: helper:1.3
- name: nginx-helper-b
image: helper:1.3
args: ["run"] # Field will be retained
- name: nginx-helper-d # key: nginx-helper-d; will be retained
image: helper:1.3
# result after merge
containers:
- name: nginx
image: nginx:1.10
# Element nginx-helper-a was deleted
- name: nginx-helper-b
image: helper:1.3
args: ["run"] # Field was retained
- name: nginx-helper-c # Element was added
image: helper:1.3
- name: nginx-helper-d # Element was ignored
image: helper:1.3
```
**설명:**
- 구성 파일에 "nginx-helper-a"라는 이름을 가진 컨테이너가 나타나지 않았기 때문에
"nginx-helper-a"라는 컨테이너는 삭제되었다.
- "nginx-helper-b"라는 컨테이너는 활성 구성에 `args`
대한 변경사항을 유지했다. `kubectl apply`
필드 값이 다름에도 불구하고(구성 파일에 `args`가 없음) 활성 구성에
"nginx-helper-b"가 구성 파일과 동일한
"nginx-helper-b"임을 식별할 수 있었다. 이것은
`patchMergeKey` 필드 값(이름)이 둘 다 같았기 때문이다..
- "nginx-helper-c"라는 이름의 컨테이너가 활성 구성에 나타나지
않았지만, 구성 파일에 그 이름을 가진 컨테이너가 나타났기 때문에
추가되었다.
- last-applied-configuration에 그 이름을 가진 구성요소가 없었기 때문에
"nginx-helper-d"라는 이름의 컨테이너는 유지되었다.
#### 기초 구성요소 리스트 병합
쿠버네티스 1.5로부터 기초 구성요소 병합하기는 지원되지 않는다.
{{< note >}}
주어진 필드에 대해 위 전략 중 어떤 것을 선택할지에 대해서는
[types.go](https://github.com/kubernetes/api/blob/d04500c8c3dda9c980b668c57abc2ca61efcf5c4/core/v1/types.go#L2748)의 `patchStrategy` 태그에 의해 제어된다.
타입 필드에 대해 `patchStrategy`가 지정되지 않으면,
리스트는 대체된다.
{{< /note >}}
{{< comment >}}
TODO(pwittrock): Uncomment this for 1.6
- Treat the list as a set of primitives. Replace or delete individual
elements. Does not preserve ordering. Does not preserve duplicates.
**Example:** Using apply to update the `finalizers` field of ObjectMeta
keeps elements added to the live configuration. Ordering of finalizers
is lost.
{{< /comment >}}
## 기본 필드값
오브젝트가 생성될 때 값이 지정되지 않는 경우, API 서버는 활성 구성 내
특정 필드를 기본값으로 설정한다.
다음은 디플로이먼트에 대한 구성 파일이다. 파일에는 `strategy`가 지정되지 않았다.
{{< codenew file="application/simple_deployment.yaml" >}}
`kubectl apply`를 사용하여 오브젝트를 생성한다.
```shell
kubectl apply -f https://k8s.io/examples/application/simple_deployment.yaml
```
`kubectl get`을 사용하여 활성 구성을 출력한다.
```shell
kubectl get -f https://k8s.io/examples/application/simple_deployment.yaml -o yaml
```
출력은 API 서버가 활성 구성 내 여러 필드를 기본값으로 설정한 것을 보여준다.
이 필드들은 구성 파일에 지정되지 않았다.
```yaml
apiVersion: apps/v1
kind: Deployment
# ...
spec:
selector:
matchLabels:
app: nginx
minReadySeconds: 5
replicas: 1 # defaulted by apiserver
strategy:
rollingUpdate: # defaulted by apiserver - derived from strategy.type
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate # defaulted apiserver
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx:1.7.9
imagePullPolicy: IfNotPresent # defaulted by apiserver
name: nginx
ports:
- containerPort: 80
protocol: TCP # defaulted by apiserver
resources: {} # defaulted by apiserver
terminationMessagePath: /dev/termination-log # defaulted by apiserver
dnsPolicy: ClusterFirst # defaulted by apiserver
restartPolicy: Always # defaulted by apiserver
securityContext: {} # defaulted by apiserver
terminationGracePeriodSeconds: 30 # defaulted by apiserver
# ...
```
패치 요청에서, 패치 요청의 부분으로서 명시적으로 지워지지 않은 경우
기본 처리된 필드는 다시 기본으로 설정되지 않는다.
이것은 다른 필드에 대한 값에 따라 기본 처리된 필드에 대해
예상하지 못한 동작을 유발할 수 있다. 다른 필드가 나중에 변경되면,
그로부터 기본 처리된 것이 명시적으로 지워지지 않은 한
업데이트되지 않을 것이다.
이러한 사유로, 의도한 값이 서버의 기본값과 일치하더라도,
서버에 의해 기본 처리된 특정 필드는 구성 파일 내
명시적으로 정의할 것을 권고한다. 이렇게 하면
서버에 의해 다시 기본 처리되지 않게 될 충돌하는 값을 보다 쉽게
인식할 수 있도록 해준다.
**Example:**
```yaml
# last-applied-configuration
spec:
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
# configuration file
spec:
strategy:
type: Recreate # updated value
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
# live configuration
spec:
strategy:
type: RollingUpdate # defaulted value
rollingUpdate: # defaulted value derived from type
maxSurge : 1
maxUnavailable: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
# result after merge - ERROR!
spec:
strategy:
type: Recreate # updated value: incompatible with rollingUpdate
rollingUpdate: # defaulted value: incompatible with "type: Recreate"
maxSurge : 1
maxUnavailable: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
```
**설명:**
1. 사용자가 `strategy.type`을 정의하지 않고 디플로이먼트를 생성한다.
2. 서버는 `strategy.type``RollingUpdate`로 기본 설정하고
`strategy.rollingUpdate`값을 기본 값으로 처리한다.
3. 사용자가 `strategy.type``Recreate`로 변경한다.
서버에서 해당 값이 삭제될 거라 예상하지만 `strategy.rollingUpdate`값은 기본값으로 남아 있다.
`strategy.rollingUpdate`값이 처음에 구성 파일에서 지정되었다면,
이것을 삭제해야 한다는 것이 더 분명했을 것이다.
4. `strategy.rollingUpdate`가 지워지지 않았기 때문에 적용은 실패한다.
`strategy.rollingupdate` 필드는 `Recreate``strategy.type`으로 정의될 수 없다.
권고: 이들 필드는 오브젝트 구성 파일 내 명시적으로 정의돼야 한다.
- 디플로이먼트, 스테이트풀셋, 잡, 데몬셋, 레플리카셋 및 레플리케이션컨트롤러와 같은
워크로드에 대한 셀렉터와 파드템플릿 레이블
- 디플로이먼트 롤아웃 전략
### 서버 기본 필드 또는 다른 작성자에 의해 설정된 필드 지우는 방법
구성 파일 내 나타나지 않는 필드는 그 값을
`null`로 설정하고 나서 구성 파일을 적용함으로써 지워질 수 있다.
서버가 기본 값을 할당했던 필드에 대해서, 이는 다시 기본 값을
할당하도록 한다.
## 구성 파일과 직접 명령형 작성자 간의 필드 소유권을 변경시키는 방법
개별 오브젝트 필드를 변경시키는 데 사용해야 하는 유일한 방법은 다음과 같다.
- `kubectl apply`를 사용한다.
- 구성 파일을 수정하지 않고 활성 구성을 직접 작성한다.
예를 들어, `kubectl scale`을 사용한다.
### 직접 명령형 작성자에서 구성 파일로 소유자 변경하기
구성 파일에 필드를 추가한다. 해당 필드의 경우
`kubectl apply`를 거치지 않는 활성 구성에 대해 직접 업데이트를 적용하지 않는다.
### 구성 파일에서 직접 명령형 작성자로 소유자 변경하기
쿠버네티스 1.5로부터 구성 파일에서 명령형 작성자로 소유권을 변경하는데
수동 단계 필요하다.
- 구성 파일에서 필드를 제거한다.
- 활성 오브젝트 상의 `kubectl.kubernetes.io/last-applied-configuration` 어노테이션에서 필드를 제거한다.
## 관리 방법 변경하기
쿠버네티스 오브젝트는 한 번에 오직 하나의 방법을 사용하여 관리돼야 한다.
하나의 방법에서 다른 방법으로 전환하는 것은 가능하나, 수동 프로세스이다.
{{< note >}}
선언형 관리와 함께 명령형 삭제를 사용하는 것은 괜찮다.
{{< /note >}}
{{< comment >}}
TODO(pwittrock): We need to make using imperative commands with
declarative object configuration work so that it doesn't write the
fields to the annotation, and instead. Then add this bullet point.
- using imperative commands with declarative configuration to manage where each manages different fields.
{{< /comment >}}
### 명령형 커맨드 관리에서 오브젝트 구성으로 이전하기
명령형 커맨드 관리에서 오브젝트 구성으로 이전하는 것은
여러 수동 단계를 포함한다.
1. 활성 오브젝트를 로컬 구성 파일로 내보낸다.
```shell
kubectl get <종류>/<이름> -o yaml --export > <종류>_<이름>.yaml
```
1. 구성 파일에서 수동으로 `status` 필드를 제거한다.
{{< note >}}
`kubectl apply` 구성 파일에 존재한다고 하더라도 상태 필드가 업데이트되지 않기 때문에,
이 단계는 선택적이다.
{{< /note >}}
1. 오브젝트의 `kubectl.kubernetes.io/last-applied-configuration` 어노테이션을 설정한다.
```shell
kubectl replace --save-config -f <종류>_<이름>.yaml
```
1. 오직 오브젝트를 관리하기 위해 `kubectl apply`를 사용하도록 프로세스를 변경한다.
{{< comment >}}
TODO(pwittrock): Why doesn't export remove the status field? Seems like it should.
{{< /comment >}}
### 명령형 오브젝트 구성에서 선언형 오브젝트 구성으로 이전하기
1. 오브젝트의 `kubectl.kubernetes.io/last-applied-configuration` 어노테이션을 설정한다.
```shell
kubectl replace --save-config -f <종류>_<이름>.yaml
```
1. 오직 오브젝트를 관리하기 위해 `kubectl apply`를 사용하도록 프로세스를 변경한다.
## 컨트롤러 셀렉터와 파드템플릿 레이블 정의하기
{{< warning >}}
컨트롤러에서 셀렉터를 업데이트하는 것은 추천되지 않는다.
{{< /warning >}}
권고되는 접근 방법은 다른 의미론적 의미를 가지지 않고 컨트롤러에 의해서만 사용되는
단일, 불변의 파드템플릿 레이블을 정의하는 것이다.
**예시:**
```yaml
selector:
matchLabels:
controller-selector: "extensions/v1beta1/deployment/nginx"
template:
metadata:
labels:
controller-selector: "extensions/v1beta1/deployment/nginx"
```
{{% capture whatsnext %}}
- [명령형 커맨드 사용하여 쿠버네티스 오브젝트 관리하기](/ko/docs/concepts/overview/object-management-kubectl/imperative-command/)
- [구성 파일 사용하여 쿠버네티스 오브젝트 관리하기](/ko/docs/concepts/overview/object-management-kubectl/imperative-config/)
- [Kubectl 명령어 참조](/docs/reference/generated/kubectl/kubectl/)
- [쿠버네티스 API 참조](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/)
{{% /capture %}}
@@ -1,162 +0,0 @@
---
title: 명령형 커맨드를 이용한 쿠버네티스 오브젝트 관리하기
content_template: templates/concept
weight: 20
---
{{% capture overview %}}
쿠버네티스 오브젝트는 `kubectl` 커맨드 라인 툴 속에 내장된 명령형 커맨드를 이용함으로써
바로 신속하게 생성, 업데이트 및 삭제할 수 있다. 이 문서는 어떻게 커맨드가 구성되어 있으며,
이를 사용하여 활성 오브젝트를 어떻게 관리하는 지에 대해 설명한다.
{{% /capture %}}
{{% capture body %}}
## 트레이드 오프
`kubectl`툴은 3가지 종류의 오브젝트 관리를 지원한다.
* 명령형 커맨드
* 명령형 오브젝트 구성
* 선언형 오브젝트 구성
각 종류별 오브젝트 관리의 장점과 단점에 대한 논의는 [쿠버네티스 오브젝트 관리](/ko/docs/concepts/overview/object-management-kubectl/overview/)
를 참고한다.
## 오브젝트 생성 방법
`kubectl` 툴은 가장 일반적인 오브젝트 타입을 생성하는데 동사 형태 기반의 커맨드를
지원한다. 쿠버네티스 오브젝트 타입에 익숙하지 않은 사용자가 인지할 수 있도록 커맨드
이름이 지어졌다.
- `run`: 하나 이상의 파드 내 컨테이너를 실행하도록 새로운 디플로이먼트 오브젝트를 생성한다.
- `expose`: 파드에 걸쳐 트래픽을 로드 밸런스하도록 새로운 서비스 오브젝트를 생성한다.
- `autoscale`: 디플로이먼트와 같이, 하나의 컨트롤러에 대해 자동으로 수평적 스케일이 이루어 지도록 새로운 Autoscaler 오브젝트를 생성한다.
또한 `kubectl` 툴은 오브젝트 타입에 의해 구동되는 생성 커맨드를 지원한다.
이러한 커맨드는 더 많은 오브젝트 타입을 지원해주며 그 의도하는 바에 대해
보다 명확하게 해주지만, 사용자가 생성하고자 하는 오브젝트 타입에 대해
알 수 있도록 해야 한다.
- `create <오브젝트 타입> [<서브 타입>] <인스턴스명>`
일부 오브젝트 타입은 `create` 커맨드 내 정의할 수 있는 서브 타입을 가진다.
예를 들어, 서비스 오브젝트는 ClusterIP, LoadBalancer 및 NodePort 등을
포함하는 여러 서브 타입을 가진다, 다음은 NodePort 서브 타입을 통해 서비스를
생성하는 예제이다.
```shell
kubectl create service nodeport <사용자 서비스 명칭>
```
이전 예제에서, `create service nodeport` 커맨드는
`create service` 커맨드의 서브 커맨드라고 칭한다.
`-h` 플래그를 사용하여 서브 커맨드에 의해 지원되는 인수 및 플래그를
찾아 볼 수 있다.
```shell
kubectl create service nodeport -h
```
## 오브젝트 업데이트 방법
`kubectl` 커맨드는 일반적인 몇몇의 업데이트 작업을 위해 동사 형태 기반의 커맨드를 지원한다.
이 커맨드는 쿠버네티스 오브젝트에 익숙하지 않은 사용자가 설정되어야
하는 특정 필드를 모르는 상태에서도 업데이트를 수행할 수 있도록
이름 지어졌다.
- `scale`: 컨트롤러의 레플리카 수를 업데이트 함으로써 파드를 추가 또는 제거하는 컨트롤러를 수평적으로 스케일한다.
- `annotate`: 오브젝트로부터 어노테이션을 추가 또는 제거한다.
- `label`: 오브젝트에서 레이블을 추가 또는 제거한다.
`kubectl` 커맨드는 또한 오브젝트 측면에서 구동되는 업데이트 커맨드를 지원한다.
이 측면의 설정은 다른 오브젝트 타입에 대한 다른 필드를 설정 할 수도 있다.
- `set` `<field>`: 오브젝트의 측면을 설정한다.
{{< note >}}
쿠버네티스 1.5 버전에서는 모든 동사 형태 기반의 커맨드가 관련된 측면 중심의 커맨드를 가지는 것은 아니다.
{{< /note >}}
`kubectl` 툴은 활성 오브젝트를 직접 업데이트하기 위해 추가적인 방법을 지원하지만,
쿠버네티스 오브젝트 스키마에 대한 추가적인 이해를 요구한다.
- `edit`: 편집기에서 구성을 열어 활성 오브젝트에 대한 원래 그대로의 구성을 바로 편집한다.
- `patch`: 패치 문자열를 사용하여 활성 오브젝트를 바로 편집한다.
패치 문자열에 대한 보다 자세한 정보를 보려면
[API 규정](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#patch-operations)에서 패치 섹션을 참고한다.
## 오브젝트 삭제 방법
클러스터에서 오브젝트를 삭제하기 위해 `delete` 커맨드을 사용할 수 있다.
- `delete <타입>/<이름>`
{{< note >}}
명령형 커맨드와 명령형 오브젝트 구성 모두 `kubectl delete`를 사용할 수
있다. 차이점은 커맨드에 전해지는 인수에 있다. 명령형 커맨드로
`kubectl delete`을 사용하기 위해, 삭제할 오브젝트를 인수로 전한다.
다음은 nginx라는 디플로이먼트 오브젝트를 전하는 예제이다.
{{< /note >}}
```shell
kubectl delete deployment/nginx
```
## 오브젝트 확인 방법
{{< comment >}}
TODO(pwittrock): 구현이 이루어지면 주석을 해제한다.
오브젝트의 특정 필드를 출력하기 위해 `kubectl view`를 사용할 수 있다.
- `view`: 오브젝트의 특정 필드의 값을 출력한다.
{{< /comment >}}
오브젝트에 대한 정보를 출력하는 몇 가지 커맨드가 있다.
- `get`: 일치하는 오브젝트에 대한 기본 정보를 출력한다. 옵션 리스트를 확인하기 위해 `get -h`를 사용한다.
- `describe`: 일치하는 오브젝트에 대해 수집한 상세한 정보를 출력한다.
- `logs`: 파드에서 실행 중인 컨테이너에 대한 stdout과 stderr를 출력한다.
## 생성 전 오브젝트 수정을 위해 `set` 커맨드 사용하기
`create` 커맨드에 사용할 수 있는 플래그가 없는 몇 가지 오브젝트
필드가 있다. 이러한 경우, 오브젝트 생성 전에 필드에 대한 값을
정의하기 위해 `set``create`을 조합해서 사용할 수 있다.
이는 `set` 커맨드에 `create` 커맨드의 출력을 파이프 함으로써 수행할 수 있다.
다음은 관련 예제이다.
```sh
kubectl create service clusterip my-svc --clusterip="None" -o yaml --dry-run | kubectl set selector --local -f - 'environment=qa' -o yaml | kubectl create -f -
```
1. `kubectl create service -o yaml --dry-run` 커맨드는 서비스에 대한 구성을 생성하지만, 이를 쿠버네티스 API 서버에 전송하는 대신 YAML 형식으로 stdout에 출력한다.
1. `kubectl set selector --local -f - -o yaml` 커맨드는 stdin으로부터 구성을 읽어, YAML 형식으로 stdout에 업데이트된 구성을 기록한다.
1. `kubectl create -f -` 커맨드는 stdin을 통해 제공된 구성을 사용하여 오브젝트를 생성한다.
## 생성 전 오브젝트 수정을 위해 `--edit` 사용하기
생성 전에 오브젝트에 임의의 변경을 가하기 위해 `kubectl create --edit` 을 사용할 수 있다.
다음은 관련 예제이다.
```sh
kubectl create service clusterip my-svc --clusterip="None" -o yaml --dry-run > /tmp/srv.yaml
kubectl create --edit -f /tmp/srv.yaml
```
1. `kubectl create service` 커맨드는 서비스에 대한 구성을 생성하고 이를 `/tmp/srv.yaml`에 저장한다.
1. `kubectl create --edit` 커맨드는 오브젝트를 생성하기 전에 편집을 위해 구성파일을 열어준다.
{{% /capture %}}
{{% capture whatsnext %}}
- [오브젝트 구성을 이용하여 쿠베네티스 관리하기(명령형)](/docs/concepts/overview/object-management-kubectl/imperative-config/)
- [오브젝트 구성을 이용하여 쿠버네티스 관리하기(선언형)](/docs/concepts/overview/object-management-kubectl/declarative-config/)
- [Kubectl 커맨드 참조](/docs/reference/generated/kubectl/kubectl/)
- [쿠버네티스 API 참조](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/)
{{% /capture %}}
@@ -1,143 +0,0 @@
---
title: 구성파일을 이용한 명령형 쿠버네티스 오브젝트 관리
content_template: templates/concept
weight: 30
---
{{% capture overview %}}
쿠버네티스 오브젝트는 YAML 또는 JSON으로 작성된 오프젝트 구성파일과 함께 `kubectl`
커맨드 라인 툴을 이용하여 생성, 업데이트 및 삭제할 수 있다.
이 문서는 구성파일을 이용하여 어떻게 오브젝트를 정의하고 관리할 수 있는지에 대해 설명한다.
{{% /capture %}}
{{% capture body %}}
## 트레이드 오프
`kubectl` 툴은 3가지 종류의 오브젝트 관리를 지원한다.
* 명령형 커맨드
* 명령형 오브젝트 구성
* 선언형 오브젝트 구성
각 종류별 오브젝트 관리의 장점과 단점에 대한 논의는
[쿠버네티스 오브젝트 관리](/ko/docs/concepts/overview/object-management-kubectl/overview/)를 참고한다.
## 오브젝트 생성 방법
구성파일로부터 오브젝트를 생성하기 위해 `kubectl create -f`를 사용할 수 있다.
보다 상세한 정보는 [쿠버네티스 API 참조](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/)를
참조한다.
- `kubectl create -f <파일명|url>`
## 오브젝트 업데이트 방법
{{< warning >}}
`replace` 커맨드로 오브젝트를 업데이트 하게되면,
구성파일에 정의되지 않은 스펙의 모든 부분이 삭제된다. 이는
`externalIPs`필드가 구성파일로부터 독립적으로 관리되는
`LoadBalancer`타입의 서비스와 같이, 클러스터 의해 부분적으로
관리되는 스펙의 오브젝트와 함께 사용되어서는 안된다.
독립적으로 관리되는 필드는 `replace`로 삭제되는 것을 방지하기 위해
구성파일에 복사되어져야만 한다.
{{< /warning >}}
구성파일에 따라 활성 오브젝트를 업데이트하기 위해 `kubectl replace -f`
를 사용할 수 있다.
- `kubectl replace -f <파일명|url>`
## 오브젝트 삭제 방법
구성파일에 정의한 오브젝트를 삭제하기 위해 `kubectl delete -f`
사용할 수 있다.
- `kubectl delete -f <파일명|url>`
## 오브젝트 삭제 방법
구성파일에 정의한 오브젝트에 관한 정보 확인을 위해 `kubectl get -f`
명령을 사용할 수 있다.
- `kubectl get -f <파일명|url> -o yaml`
`-o yaml` 플래그는 전체 오브젝트 구성이 출력되도록 정의한다. 옵션의 리스트를 확인하기
위해서는 `kubectl get -h`를 사용한다.
## 제약사항
`create`, `replace`, 그리고 `delete` 명령은 각 오브젝트의 구성이
그 구성파일 내에 완전하게 정의되고 기록되어질 경우 잘 동작한다.
그러나 활성 오브젝트가 업데이트 되고, 구성파일 안에 병합되지 않으면,
업데이트 내용은 다음번 `replace`가 실행될 때 삭제될 것이다.
이는 HorizontalPodAutoscaler와 같은 컨트롤러가
활성 오브젝트를 직접적으로 업데이트하도록 할 경우 발생한다.
여기 예시가 있다.
1. 구성파일로부터 오브젝트를 생성할 경우
1. 또 다른 소스가 일부 필드를 변경함으로써 오브젝트가 업데이트 되는 경우
1. 구성파일로부터 오브젝트를 대체할 경우. 스텝 2에서의
다른 소스에 의해 이루어진 변경은 유실된다.
동일 오브젝트에 대해 여러 명의 작성자들로부터의 지원이 필요한 경우, 오브젝트를 관리하기 위해
`kubectl apply`를 사용할 수 있다.
## 구성 저장 없이 URL로부터 오브젝트 생성과 편집하기
구성파일에 대한 URL을 가진다고 가정해보자.
`kubectl create --edit`을 사용하여 오브젝트가 생성되기 전에
구성을 변경할 수 있다. 이는 독자가 수정할 수 있는 구성파일을
가르키는 튜토리얼과 작업에 특히 유용하다.
```sh
kubectl create -f <url> --edit
```
## 명령형 커맨드에서 명령형 오브젝트 구성으로 전환하기
령형 커맨드에서 명령형 오브젝트 구성으로 전환하기 위해
몇 가지 수동 단계를 포함한다.
1. 다음과 같이 활성 오브젝트를 로컬 오브젝트 구성파일로 내보낸다.
```sh
kubectl get <종류>/<이름> -o yaml --export > <종류>_<이름>.yaml
```
1. 수동으로 오브젝트 구성파일에서 상태 필드를 제거한다.
1. 이후 오브젝트 관리를 위해, `replace`만 사용한다.
```sh
kubectl replace -f <종류>_<이름>.yaml
```
## 컨트롤러 셀렉터와 PodTemplate 레이블 삭제하기
{{< warning >}}
컨트롤러에서 셀렉터를 업데이트하지 않도록 강력하게 권고한다.
{{< /warning >}}
권고되는 접근방법은 다른 의미론적 의미가 없는 컨트롤러 셀렉터의 의해서만
사용되는 단일, 불변의 PodTemplate 레이블로 정의하는 것이다.
레이블 예시:
```yaml
selector:
matchLabels:
controller-selector: "extensions/v1beta1/deployment/nginx"
template:
metadata:
labels:
controller-selector: "extensions/v1beta1/deployment/nginx"
```
{{% /capture %}}
{{% capture whatsnext %}}
- [명령형 커맨드를 이용한 쿠버네티스 오브젝트 관리하기](/ko/docs/concepts/overview/object-management-kubectl/imperative-command/)
- [오브젝트 구성을 이용하여 쿠버네티스 오브젝트 관리하기 (선언형)](/docs/concepts/overview/object-management-kubectl/declarative-config/)
- [Kubectl 커멘드 참조](/docs/reference/generated/kubectl/kubectl/)
- [쿠버네티스 API 참조](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/)
{{% /capture %}}
@@ -1,7 +1,7 @@
---
title: 쿠버네티스 오브젝트 관리
content_template: templates/concept
weight: 10
weight: 15
---
{{% capture overview %}}
@@ -176,9 +176,10 @@ kubectl apply -R -f configs/
{{% /capture %}}
{{% capture whatsnext %}}
- [명령형 명령어를 이용한 쿠버네티스 오브젝트 관리하기](/docs/concepts/overview/object-management-kubectl/imperative-command/)
- [오브젝트 구성을 이용한 쿠버네티스 오브젝트 관리하기 (명령형)](/docs/concepts/overview/object-management-kubectl/imperative-config/)
- [오브젝트 구성을 이용한 쿠버네티스 오브젝트 관리하기 (선언형)](/docs/concepts/overview/object-management-kubectl/declarative-config/)
- [명령형 커맨드를 이용한 쿠버네티스 오브젝트 관리하기](/ko/docs/tasks/manage-kubernetes-objects/imperative-command/)
- [오브젝트 구성을 이용한 쿠버네티스 오브젝트 관리하기 (명령형)](/ko/docs/tasks/manage-kubernetes-objects/imperative-config/)
- [오브젝트 구성을 이용한 쿠버네티스 오브젝트 관리하기 (선언형)](/ko/docs/tasks/manage-kubernetes-objects/declarative-config/)
- [Kustomize를 사용한 쿠버네티스 오브젝트 관리하기 (선언형)](/docs/tasks/manage-kubernetes-objects/kustomization/)
- [Kubectl 명령어 참조](/docs/reference/generated/kubectl/kubectl-commands/)
- [Kubectl 서적](https://kubectl.docs.kubernetes.io)
- [쿠버네티스 API 참조](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/)
@@ -152,8 +152,8 @@ spec:
아래의 yaml file은 `mydb``myservice` 서비스의 개요를 보여준다.
```yaml
kind: Service
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
@@ -162,8 +162,8 @@ spec:
port: 80
targetPort: 9376
---
kind: Service
apiVersion: v1
kind: Service
metadata:
name: mydb
spec:
@@ -313,7 +313,8 @@ myapp-pod 1/1 Running 0 9m
있다.
* 사용자가 초기화 컨테이너 이미지의 변경을 일으키는 파드 스펙 업데이트를 수행했다.
앱 컨테이너 이미지 변경은 앱 컨테이너만 재시작시킨다.
Init Container 이미지 변경하면 파드가 다시 시작된다. 앱 컨테이너
이미지의 변경은 앱 컨테이너만 재시작시킨다.
* 파드 인프라스트럭처 컨테이너가 재시작되었다. 이는 일반적인 상황이 아니며 노드에
대해서 root 접근 권한을 가진 누군가에 의해서 수행됐을 것이다.
* 파드 내의 모든 컨테이너들이, 재시작을 강제하는 `restartPolicy`이 항상으로 설정되어 있는,
@@ -15,25 +15,25 @@ card:
{{% capture body %}}
## 파드에 대해 이해하기
*파드* 는 쿠버네티스의 기본 구성 요소이다. 쿠버네티스 객체 모델 중 만들고 배포할 수 있는 가장 작고 간단한 단위이다. 파드는 클러스터에서의 Running 프로세스를 나타낸다.
*파드* 는 쿠버네티스의 기본 구성 요소이다. 쿠버네티스 객체 모델 중 만들고 배포할 수 있는 가장 작고 간단한 단위이다. 파드는 {{< glossary_tooltip term_id="cluster" >}} 에서의 Running 프로세스를 나타낸다.
파드는 애플리케이션 컨테이너(또는, 몇몇의 경우, 다중 컨테이너), 저장소 리소스, 특정 네트워크 IP 그리고, 컨테이너가 동작하기 위해 만들어진 옵션들을 캡슐화 한다.
파드는 애플리케이션 컨테이너(또는, 몇몇의 경우, 다중 컨테이너), 저장소 리소스, 특정 네트워크 IP 그리고, {{< glossary_tooltip text="container" term_id="container" >}} 가 동작하기 위해 만들어진 옵션들을 캡슐화 한다.
파드는 배포의 단위를 말한다. 아마 단일 컨테이너로 구성되어 있거나, 강하게 결합되어 리소스를 공유하는 소수의 컨테이너로 구성되어 있는 *쿠버네티스에서의 애플리케이션 단일 인스턴스* 를 의미함.
> [Docker](https://www.docker.com)는 쿠버네티스 파드에서 사용되는 가장 대표적인 컨테이너 런타임이지만, 파드는 다른 컨테이너 런타임 역시 지원한다.
[도커](https://www.docker.com)는 쿠버네티스 파드에서 사용되는 가장 대표적인 컨테이너 런타임이지만, 파드는 다른 컨테이너 런타임 역시 지원한다.
쿠버네티스 클러스터 내부의 파드는 주로 두 가지 방법으로 사용된다.
* **단일 컨테이너만 동작하는 파드**. "단일 컨테이너 당 한 개의 파드" 모델은 쿠버네티스 사용 사례 중 가장 흔하다. 이 경우, 한 개의 파드가 단일 컨테이너를 감싸고 있다고 생각할 수 있으며, 쿠버네티스는 컨테이너가 아닌 파드를 직접 관리한다고 볼 수 있다.
* **함께 동작하는 작업이 필요한 다중 컨테이너가 동작하는 파드**. 아마 파드는 강하게 결합되어 있고 리소스 공유가 필요한 다중으로 함께 배치된 컨테이너로 구성되어 있을 것이다. 이렇게 함께 배치되어 설치된 컨테이너는 단일 결합 서비스 단위일 것이다. 한 컨테이너는 공유 볼륨에서 퍼블릭으로 파일들을 옮기고, 동시에 분리되어 있는 "사이드카" 컨테이너는 그 파일들을 업데이트 하거나 복구한다. 파드는 이 컨테이너와 저장소 리소스들을 한 개의 관리 가능한 요소로 묶는다.
[쿠버네티스 블로그](http://kubernetes.io/blog)에는 파드 사용 사례의 몇 가지 추가적인 정보가 있다. 더 많은 정보를 위해서 아래 내용을 참조하길 바란다.
* [분산 시스템 툴킷: 복합 컨테이너를 위한 패턴](https://kubernetes.io/blog/2015/06/the-distributed-system-toolkit-patterns)
* [컨테이너 디자인 패턴](https://kubernetes.io/blog/2016/06/container-design-patterns)
* [분산 시스템 툴킷: 복합 컨테이너를 위한 패턴](https://kubernetes.io/blog/2015/06/the-distributed-system-toolkit-patterns)
* [컨테이너 디자인 패턴](https://kubernetes.io/blog/2016/06/container-design-patterns)
각각의 파드는 주어진 애플리케이션에서 단일 인스턴스로 동작을 하는 것을 말한다. 만약 애플리케이션을 수평적으로 스케일하기를 원하면(예를 들면, 다중 인스턴스 동작하는 것), 각 인스턴스 당 한 개씩 다중 파드를 사용해야 한다. 쿠버네티스에서는, 일반적으로 이것을 _복제_ 라고 한다. 복제된 파드는 주로 컨트롤러라고 하는 추상화 개념의 그룹에 의해 만들어지고 관리된다. 더 많은 정보는 [파드와 컨트롤러](#pods-and-controllers)를 참고하길 바란다.
@@ -46,7 +46,9 @@ card:
단일 파드 내부에서 함께 배치되고 관리되는 컨테이너 그룹은 상대적으로 심화된 사용 예시임에 유의하자. 컨테이너가 강하게 결합된 특별한 인스턴스의 경우에만 이 패턴을 사용하는게 좋다. 예를 들어, 공유 볼륨 내부 파일의 웹 서버 역할을 하는 컨테이너와 원격 소스로부터 그 파일들을 업데이트하는 분리된 "사이드카" 컨테이너가 있는 경우 아래 다이어그램의 모습일 것이다.
{{< figure src="/images/docs/pod.svg" title="pod diagram" width="50%" >}}
{{< figure src="/images/docs/pod.svg" alt="example pod diagram" width="50%" >}}
몇몇의 파드는 {{< glossary_tooltip text="init containers" term_id="init-container" >}} 뿐만 아니라 {{< glossary_tooltip text="app containers" term_id="app-container" >}} 도 가진다. 초기 컨테이너는 앱 컨테이너 시작이 완료되기 전에 동작한다.
파드는 같은 파드 안에 속한 컨테이너에게 두 가지 공유 리소스를 제공한다. *네트워킹**저장소*.
@@ -56,11 +58,11 @@ card:
#### 저장소
파드는 공유 저장소 집합인 *볼륨* 을 명시할 수 있다. 파드 내부의 모든 컨테이너는 공유 볼륨에 접근할 수 있고, 그 컨테이너끼리 데이터를 공유하는 것을 허용한다. 또한 볼륨은 컨테이너가 재시작되어야 하는 상황에도 파드 안의 데이터가 영구적으로 유지될 수 있게 한다. 쿠버네티스가 어떻게 파드 안의 공유 저장소를 사용하는지 보려면 [볼륨](/docs/concepts/storage/volumes/)를 참고하길 바란다.
파드는 공유 저장소 집합인 {{< glossary_tooltip text="Volumes" term_id="volume" >}} 을 명시할 수 있다. 파드 내부의 모든 컨테이너는 공유 볼륨에 접근할 수 있고, 그 컨테이너끼리 데이터를 공유하는 것을 허용한다. 또한 볼륨은 컨테이너가 재시작되어야 하는 상황에도 파드 안의 데이터가 영구적으로 유지될 수 있게 한다. 쿠버네티스가 어떻게 파드 안의 공유 저장소를 사용하는지 보려면 [볼륨](/docs/concepts/storage/volumes/)를 참고하길 바란다.
## 파드 작업
직접 쿠버네티스에서 싱글톤 파드이더라도 개별 파드를 만들일이 거의 없을 것이다. 그 이유는 파드가 상대적으로 수명이 짧고 일시적이기 때문이다. 파드가 만들어지면(직접 만들거나, 컨트롤러에 의해서 간접적으로 만들어지거나), 그것은 클러스터의 노드에서 동작할 것이다. 파드는 프로세스가 종료되거나, 파드 객체가 삭제되거나, 파드가 리소스의 부족으로 인해 *제거되거나*, 노드에 장애가 생기지 않는 한 노드에 남아있는다.
직접 쿠버네티스에서 싱글톤 파드이더라도 개별 파드를 만들일이 거의 없을 것이다. 그 이유는 파드가 상대적으로 수명이 짧고 일시적이기 때문이다. 파드가 만들어지면(직접 만들거나, 컨트롤러에 의해서 간접적으로 만들어지거나), 그것은 클러스터의 {{< glossary_tooltip term_id="node" >}} 에서 동작할 것이다. 파드는 프로세스가 종료되거나, 파드 객체가 삭제되거나, 파드가 리소스의 부족으로 인해 *제거되거나*, 노드에 장애가 생기지 않는 한 노드에 남아있는다.
{{< note >}}
파드 내부에서 재시작되는 컨테이너를 파드와 함께 재시작되는 컨테이너로 혼동해서는 안된다. 파드는 자기 스스로 동작하지 않는다. 하지만 컨테이너 환경은 그것이 삭제될 때까지 계속 동작한다.
@@ -104,7 +106,7 @@ spec:
{{% /capture %}}
{{% capture whatsnext %}}
* 파드의 다른 동작들을 더 배워보자.
* [파드](/docs/concepts/workloads/pods/pod/)의 다른 동작들을 더 배워보자.
* [파드 종료](/docs/concepts/workloads/pods/pod/#termination-of-pods)
* [파드 라이프사이클](/ko/docs/concepts/workloads/pods/pod-lifecycle/)
{{% /capture %}}
@@ -0,0 +1,205 @@
---
title: 파드
content_template: templates/concept
weight: 20
---
{{% capture overview %}}
_파드_ 는 쿠버네티스에서 생성되고 관리될 수 있는 배포 가능한 최소 컴퓨팅 단위이다.
{{% /capture %}}
{{% capture body %}}
## 파드는 무엇인가?
_파드_ 는 (고래 떼(pod of whales)나 콩꼬투리(pea pod)와 마찬가지로) 하나 이상의(도커 컨테이너 같은) 컨테이너 그룹이다.
이 그룹은 스토리지/네트워크를 공유하고, 해당 컨테이너를 구동하는 방식에 대한 명세를 갖는다.
파드의 콘텐츠들은 항상 함께 배치되고 같이 스케줄되며, 공유 컨텍스트 내에서 구동된다.
파드는 애플리케이션에 특화된 "논리 호스트"를 모델로 하고 있다.
이것은 하나 또는 강하게 서로 결합되어 있는 여러 애플리케이션 컨테이너를 포함한다.
컨테이너 이전의 세상에서 같은 물리적 또는 가상의 머신에서 실행되는 것은
같은 논리적 호스트에서 실행되고 있는 것을 의미한다.
쿠버네티스는는 도커 이외에도 많은 컨테이너 런타임을 지원하지만,
도커는 가장 일반적으로 알려진 런타임이므로 도커 용어로 파드를 설명하는 것이 도움이 된다.
파드의 공유 컨텍스트는 Linux 네임 스페이스, 컨트롤 그룹(cgroup) 및
도커 컨테이너를 격리하는 것과 같이 잠재적으로 다른 격리 요소들이다.
파드의 컨텍스트 내에서 개별 응용 프로그램은
추가적으로 하위 격리가 적용된다.
컨테이너들 안의 파드는 IP주소와 포트 공간을 공유하고,
서로를 `localhost` 를 통해 찾을 수 있다.
그들은 또한 SystemV 세마포어나, POSIX 공유 메모리와 같은 표준 프로세스 간 통신 방식으로
서로 통신할 수 있다.
다른 파드의 컨테이너에는 고유한 IP 주소가 있고,
[특별한 구성](/docs/concepts/policy/pod-security-policy/) 없이는 IPC에 의해서 통신 할 수 없다.
컨테이너는 주로 서로의 IP 주소를 통해 소통한다.
또한 파드 안의 애플리케이션은 파드의 일부로 정의되어,
각각의 애플리케이션의 파일시스템에 마운트 할 수 있도록 만들어진
공유 볼륨에 엑세스 할 수 있다.
[도커](https://www.docker.com/)의 구조 관점에서 보면
파드는 공유 네임스페이스와 공유 [볼륨](/docs/concepts/storage/volumes/)을 가진
도커 컨테이너 그룹으로 모델링 된다.
개별 애플리케이션 컨테이너와 같이, 파드는 상대적으로 수명이 짧은 엔터티로 간주된다.
[파드의 생애](/docs/concepts/workloads/pods/pod-lifecycle/)에서 논의된 것과 같이,
파드가 만들어지고 고유한 ID(UID)가 할당되고,
재시작 정책에 따라서 종료 또는 삭제될 때 까지 노드에 스케줄된다.
노드가 종료되면 해당 노드로 스케줄 된 파드는 제한시간이 지나면 삭제되도록 스케줄된다.
해당 파드(UID로 정의된)는 새로운 노드에 "리스케줄(reschedule)" 되지 않는다. 대신, 동일한 파드로,
원한다면 이름도 동일하게, 교체될 수 있지만, 새로운 UID가 부여된다.
더 자세한 내용은 [레플리케이션 컨트롤러](/docs/concepts/workloads/controllers/replicationcontroller/)를 참조한다.
볼륨과 같이 파드와 동일한 수명이 있다고 하면,
UID를 포함한 해당 파드가 존재하는 한 그것도 존재한다는 것을 의미한다.
어떤 이유로든 해당 파드가 삭제 된 경우,
동일한 대체품이 만들어 지더라도 관련된 것(예 : 볼륨) 또한 삭제되고 새로 만들어진다.
{{< figure src="/images/docs/pod.svg" title="파드 다이어그램" width="50%" >}}
*파일 풀러(Puller)와 컨테이너 간 공유 스토리지로 퍼시스턴트 볼륨을 사용하는
웹 서버를 포함하는 멀티 컨테이너 파드.*
## 파드의 의의
### 관리
파드는 응집력 있는 서비스 단위를 형성하는 여러 개의 협력 프로세스를 모델로 한다.
파드는 그 구성 요소 집합보다 높은 수준의 추상화를 제공함으로써
애플리케이션 배포 및 관리를 단순화한다.
파드는 전개 단위, 수평 확장 및 복제를 한다.
공동 스케줄링, 공유 된 생애주기 (예 : 종료), 조정 된 복제, 자원 공유 및 종속성 관리는
파드의 컨테이너에 대해 자동으로 처리된다.
### 리소스 공유 및 통신
파드는 그 구성 요소 간에 데이터 공유 및 통신이 가능하다.
파드의 모든 애플리케이션은 동일한 네트워크 네임스페이스(동일한 IP 및 포트 공간)를 사용하므로
서로를 찾고 통신하는데 `localhost`를 사용할 수 있다.
이 때문에 파드의 애플리케이션은 포트 사용을 조정 해야한다.
각 파드에는 다른 물리적 컴퓨터 및 파드들과 네트워크를 통해 통신할 수 있는 공유 네트워크 공간의 IP 주소가 있다.
호스트 이름은 파드 안에있는 애플리케이션 컨테이너의 파드 이름으로 설정된다.
더 자세한 내용은 [네트워킹의 더 자세한 내용](/docs/concepts/cluster-administration/networking/)을 참조한다.
파드는 파드 안의 애플리케이션 컨테이너를 정의하는 것 이외에도 공유 저장 볼륨의 집합을 지정한다.
볼륨은 컨테이너가 재시작되어도 데이터가 생존할 수 있도록 하고,
파드 안의 애플리케이션들끼리 데이터를 공유할 수 있게 해준다.
## 파드의 사용
파드는 수직으로 통합 된 애플리케이션 스택(예 : LAMP)을 호스팅하는 데 사용할 수 있다.
하지만, 주요 동기는 공동 배치 및 공동 관리되는 헬퍼(helper) 프로그램을 지원하는 것이다.
예를 들면,
* 컨텐츠 관리 시스템, 파일과 데이터 로더, 로컬 캐시 관리 등.
* 로그와 백업 체크포인트, 압축, 로테이션, 스냅샷 등.
* 데이터 변동 감시자, 로그 추적자, 로깅 및 모니터링 어댑터, 이벤트 관리 등.
* 프록시, 브릿지, 어댑터
* 컨트롤러, 매니저, 설정, 업데이트
일반적으로 하나의 파드는
동일한 애플리케이션의 여러 인스턴스를 실행하도록 사용하지 않는다.
더 자세한 설명을 보려면 [분산 시스템 툴킷: 복합 컨테이너를 위한 패턴] (https://kubernetes.io/blog/2015/06/the-distributed-system-toolkit-patterns)을 참조한다.
## 고려된 대안
_싱글 (도커)컨테이너에서 다중 프로그램을 실행하지 않는 이유는 무엇인가?_
1. 투명도. 인프라에 파드 내의 컨테이너를 표시하면,
인프라에서 프로세스 관리와 리소스 모니터링과 같은 기능을 제공할 수 있다.
이 기능들은 사용자에게 편의를 제공한다.
1. 소프트웨어 의존성 분리. 각각의 컨테이너는 독립적으로 버전 관리,
재빌드, 재배포될 수 있다.
언젠가는 쿠버네티스에서 개별 컨테이너의 실시간 업데이트도 할 수 있을 것이다.
1. 사용의 편의성. 사용자는 자신의 프로세스 매니저를 따로 실행 할 필요가 없고,
시그널이나 종료 코드(exit-code) 전파 등에 대해 걱정할 필요가 없다.
1. 효율성. 인프라측에서 많은 책임을 가지고 있으므로,
컨테이너는 더 가벼워 질 수 있다.
_컨테이너의 어피니티(affinity) 기반 공동 스케줄링을 지원하지 않는 이유는 무엇인가?_
이와 같은 접근은 공동위치를 제공하지만,
리소스 공유, IPC, 보장된 생애 공유, 관리의 단순화와 같은
파드가 가진 대부분의 장점을 제공하지 못한다.
## 파드의 내구성 (또는 결핍)
파드는 내구성이 강한 엔터티로 취급하지는 않는다. 파드는 스케줄링 실패,
노드 장애 또는 그 밖에 리소스가 부족해서, 또는 노드 정비를 위한 경우와 같이 축출(eviction)되는 상황에서는 살아남을 수 없을 것이다.
일반적으로 사용자는 파드를 직접 만들 필요가 없다.
싱글톤이라도 대부분 [디플로이먼트](/docs/concepts/workloads/controllers/deployment/)와 같은 컨트롤러를 사용한다.
컨트롤러는 클러스터 범위에서
복제와 롤아웃 관리 뿐 만 아니라 자가치료 기능도 제공한다.
[StatefulSet](/docs/concepts/workloads/controllers/statefulset.md)과 같은 컨트롤러는 상태를 저장하는 파드에도
위와 같은 기능 제공을 할 수 있다.
사용자 지향적으로 선정된 API를 사용하는 것은 [Borg](https://research.google.com/pubs/pub43438.html), [Marathon](https://mesosphere.github.io/marathon/docs/rest-api.html), [Aurora](http://aurora.apache.org/documentation/latest/reference/configuration/#job-schema)와 [Tupperware](http://www.slideshare.net/Docker/aravindnarayanan-facebook140613153626phpapp02-37588997)를 비롯한 클러스터 스케줄링 시스템에서 비교적 일반적이다.
파드는 아래와 같은 사항들을 용이하게 하기 위해 노출이 된다:
* 스케줄러 및 컨트롤러 연결 가능
* "프록시" 없이 컨트롤러 API를 통한 파드-레벨 수준의 동작 지원
* 부트스트랩과 같이 컨트롤러의 생에와 파드의 생애 분리
* 컨트롤러와 서비스의 분리 &mdash; 파드를 감시하는 엔드 포인트 컨트롤러
* 클러스터 레벨과 kubelet 레벨 기능의 깔끔한 구성 &mdash; Kubelet은 효과적인 "파드 컨트롤러" 이다.
* 계획된 삭제 또는 이미지 프리페칭과 같이 파드가 종료되기 전에 교체가 될 것이고,
삭제 전에는 확실히 교체되는 고가용성 애플리케이션.
## 파드의 종료
파드는 클러스터의 노드에서 실행 중인 프로세스를 나타내므로 이러한 프로세스가 더 이상 필요하지 않을 때 (KILL 시그널로 강제로 죽여서 정리할 기회를 주지 않는 것과 대조적으로) 정상적으로 종료 되도록 허용하는 것이 중요하다.
사용자는 삭제를 요청할 수 있어야 하며, 프로세스가 종료 될 때 알 수 있어야 할 뿐 만 아니라, 삭제가 결국 완료되는 것을 확인 할 수 있어야 한다.
사용자가 파드를 삭제하도록 요청하면 시스템은 파드가 강제로 종료되기 전에 예정된 유예 기간을 기록하고 TERM 시그널이 각 컨테이너의 주 프로세스로 전송된다.
유예 기간이 만료되면 KILL 신호가 해당 프로세스로 전송되고 파드가 API 서버에서 삭제된다. 프로세스가 종료되기를 기다리는 동안 Kubelet 또는 컨테이너 관리자가 다시 시작되면 종료가 전체 유예 기간과 함께 재시도된다.
흐름 예시:
1. 사용자가 파드 삭제 명령을 내린다. (기본 유예 기간 30초)
1. API 서버 안의 파드는 유예 기간에 따라, 시간을 넘은 것(죽은)것으로 간주되는 파드가 업데이트 된다.
1. 클라이언트 명령에서 파드는 "Terminating" 이라는 문구를 나타낸다.
1. (3번 단계와 동시에) Kubelet은 파드가 2번 단계에서 설정된 시간으로 인해 Terminating으로 표시되는 것을 확인하면 파드 종료 단계를 시작한다.
1. 파드의 컨테이너 중 하나에 [preStop hook](/docs/concepts/containers/container-lifecycle-hooks/#hook-details)이 정의된 경우, 해당 컨테이너 내부에서 실행된다. 유예 기간이 만료된 후에도 `preStop` 훅이 계속 실행 중이면, 유예 기간을 짧게(2초) 연장해서 2번 단계를 실행한다.
1. 파드의 프로세스에 TERM 시그널이 전달된다. 파드의 모든 컨테이너가 TERM 시그널을 동시에 받기 때문에 컨테이너의 종료 순서가 중요한 경우에는 `preStop` 훅이 각각 필요할 수 있음을 알아두자.
1. (3번 단계와 동시에) 파드는 서비스를 위해 엔드포인트 목록에서 제거되며, 더 이상 레플리케이션 컨트롤러가 실행중인 파드로 고려하지 않는다.
느리게 종료되는 파드는 로드밸런서(서비스 프록시와 같은)의 로테이션에서 지워지기 때문에 트래픽을 계속 처리할 수 없다.
1. 유예 기간이 만료되면, 파드에서 실행중이던 모든 프로세스가 SIGKILL로 종료된다.
1. Kubelet은 유예기간 0(즉시 삭제)을 세팅하여 API 서버에서 파드 삭제를 끝낼 것이다. API 서버에서 사라진 파드는 클라이언트에게서 더 이상 보이지 않는다.
기본적으로 모든 삭제는 30초 이내에 끝이난다. `kubectl delete` 명령은 사용자가 기본 설정을 오버라이드 하고 자신이 원하는 값을 설정할 수 있게 해주는 `--grace-period=<seconds>` 옵션을 지원한다. `0`값은 파드를 [강제로 삭제한다](/ko/docs/concepts/workloads/pods/pod/#파드-강제-삭제). kubectl 버전 >= 1.5 에서는, 강제 삭제 수행을 위해서 반드시 `--grace-period=0`와 함께 추가 플래그인 `--force`를 지정해야 한다.
### 파드 강제 삭제
파드 강제 삭제는 클러스터 및 etcd에서 즉시 삭제하는 것으로 정의된다. 강제 삭제가 수행되면, apiserver는 kubelet에서 실행중이던 노드에서 파드가 종료되었다는 확인을 기다리지 않는다.
API에서 파드를 즉시 제거하므로 동일한 이름으로 새 파드를 만들 수 있다.
노드에서 즉시 종결되도록 설정된 파드에는 강제 삭제되기 전에 짧은 유예 기간이 주어진다.
강제 삭제는 일부 파드의 경우 잠재적으로 위험 할 수 있으므로 주의해서 수행해야 한다.
스테이트풀셋 파드의 경우 [스테이트풀셋 파드 삭제](/docs/tasks/run-application/force-delete-stateful-set-pod/)에 대한 작업문서를 참조한다.
## 파드 컨테이너의 특권(Privileged) 모드
Kubernetes v1.1부터, 파드의 모든 컨테이너는 컨테이너 스펙의 `SecurityContext``privileged` 플래그를 사용하여 특권 모드를 사용할 수 있다. 이것은 네트워크 스택을 조작하고 장치에 액세스하는 것과 같은 Linux 기능을 사용하려는 컨테이너에 유용하다. 컨테이너 내의 프로세스는 컨테이너 외부의 프로세스에서 사용할 수 있는 거의 동일한 권한을 갖는다. 특권 모드를 사용하면 네트워크 및 볼륨 플러그인을 kubelet에 컴파일 할 필요가 없는 별도의 파드로 쉽게 만들 수 있다.
마스터가 Kubernetes v1.1 이상에서 실행 중이고, 노드가 v1.1 보다 낮은 버전을 실행중인 경우 새 권한이 부여 된 파드는 api-server에 의해 승인되지만 시작되지는 않는다. 이것들은 pending 상태가 될 것이다.
사용자가 `kubectl describe pod FooPodName` 을 호출하면 사용자는 파드가 사용자가 `kubectl describe pod FooPodName` 을 호출하면 사용자는 파드가 pending 상태에 있는 이유를 볼 수 있다. describe 명령 출력의 이벤트 테이블은 다음과 같다.
`Error validating pod "FooPodName"."FooPodNamespace" from api, ignoring: spec.containers[0].securityContext.privileged: forbidden '<*>(0xc2089d3248)true'`
마스터가 v1.1보다 낮은 버전에서 실행중인 경우 특권을 갖는 파드를 만들 수 없다. 유저가 특권을 갖는 컨테이너가 있는 파드를 만들려고 하면 다음과 같은 오류가 발생한다.
`The Pod "FooPodName" is invalid.
spec.containers[0].securityContext.privileged: forbidden '<*>(0xc20b222db0)true'`
## API 오브젝트
파드는 쿠버네티스 REST API에서 최상위 리소스이다. API 오브젝트에 더 자세한 정보는 아래 내용을 참조한다:
[파드 API 오브젝트](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#pod-v1-core).
{{% /capture %}}