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:
committed by
Kubernetes Prow Robot
parent
1d874b911c
commit
0f7cb401ee
@@ -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,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 %}}
|
||||
+5
-4
@@ -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를 통한 파드-레벨 수준의 동작 지원
|
||||
* 부트스트랩과 같이 컨트롤러의 생에와 파드의 생애 분리
|
||||
* 컨트롤러와 서비스의 분리 — 파드를 감시하는 엔드 포인트 컨트롤러
|
||||
* 클러스터 레벨과 kubelet 레벨 기능의 깔끔한 구성 — 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 %}}
|
||||
Reference in New Issue
Block a user