Merge pull request #20986 from kubernetes/dev-1.18-ko.3

Third Korean l10n work for release 1.18
pull/21001/head
Kubernetes Prow Robot 2020-05-14 23:56:58 -07:00 committed by GitHub
commit 3dee902b75
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
67 changed files with 4827 additions and 313 deletions

View File

@ -1,20 +1,21 @@
---
title: 클라우트 컨트롤러 매니저 기반에 관한 개념
title: 클라우드 컨트롤러 매니저
content_template: templates/concept
weight: 40
---
{{% capture overview %}}
클라우드 컨트롤러 매니저(CCM) 개념(바이너리와 혼동하지 말 것)은 본래 클라우드 벤더에 특화된 코드와 쿠버네티스 코어가 상호 독립적으로 진화할 수 있도록 해주기 위해 생성되었다. 클라우드 컨트롤러 매니저는 쿠버네티스 컨트롤러 매니저, API 서버, 그리고 스케줄러와 같은 다른 마스터 컴포넌트와 함께 동작된다. 또한 쿠버네티스 위에서 동작하는 경우에는, 쿠버네티스 애드온으로서 구동된다.
{{< feature-state state="beta" for_k8s_version="v1.11" >}}
클라우드 컨트롤러 매니저의 디자인은 새로운 클라우드 제공사업자가 플러그인을 이용하여 쉽게 쿠버네티스와 함께 통합하도록 허용해 주는 플러그인 메커니즘을 토대로 한다. 쿠버네티스에 새로운 클라우드 제공사업자를 적응시키기 위한 그리고 기존 모델에서 새로운 CCM 모델로 클라우드 제공사업자들이 전환을 이루기 위한 준비된 계획들이 있다.
클라우드 인프라스트럭쳐 기술을 통해 퍼블릭, 프라이빗 그리고 하이브리드 클라우드에서 쿠버네티스를 실행할 수 있다.
쿠버네티스는 컴포넌트간의 긴밀한 결합 없이 자동화된 API 기반의 인프라스트럭쳐를
신뢰한다.
이 문서는 클라우드 컨트롤러 매니저 이면상의 개념들을 논의하고 그것과 연관된 기능들에 대한 세부적인 사항들을 제시한다.
{{< glossary_definition term_id="cloud-controller-manager" length="all" prepend="클라우드 컨트롤러 매니저는">}}
다음은 클라우드 컨트롤러 매니저가 존재하지 않는 형태의 쿠버네티스 클러스터 아키텍처이다.
![Pre CCM Kube Arch](/images/docs/pre-ccm-arch.png)
클라우드 컨트롤러 매니저는 다양한 클라우드 공급자가 자신의
플랫폼에 쿠버네티스를 통합할 수 있도록 하는 플러그인 메커니즘을 사용해서 구성된다.
{{% /capture %}}
@ -23,91 +24,69 @@ weight: 40
## 디자인
이전 다이어그램에서, 쿠버네티스와 클라우드 제공사업자는 여러 상이한 컴포넌트들을 통해 통합되었다.
![쿠버네티스 컴포넌트](/images/docs/components-of-kubernetes.png)
* Kubelet
* 쿠버네티스 컨트롤러 매니저
* 쿠버네티스 API 서버
CCM은 앞의 세 컴포넌트가 가진 클라우드 의존적인 로직을 한 곳에 모아서 클라우드 통합을 위한 단일 포인트를 만들었다. CCM을 활용한 새로운 아키텍처는 다음과 같다.
![CCM Kube Arch](/images/docs/post-ccm-arch.png)
## CCM의 컴포넌트
CCM은 쿠버네티스 컨트롤러 매니저(KCM)의 기능 일부를 독립시키고 분리된 프로세스로서 그것을 작동시킨다. 특히, 클라우드 종속적인 KCM 내 컨트롤러들을 독립시킨다. KCM은 다음과 같은 클라우드 종속적인 컨트롤러 루프를 가진다.
* 노드 컨트롤러
* 볼륨 컨트롤러
* 라우트 컨트롤러
* 서비스 컨트롤러
버전 1.9 에서, CCM은 이전 리스트로부터 다음의 컨트롤러를 작동시킨다.
* 노드 컨트롤러
* 라우트 컨트롤러
* 서비스 컨트롤러
클라우드 컨트롤러 매니저는 컨트롤 플레인에서 복제된 프로세스의 집합으로 실행된다(일반적으로,
파드의 컨테이너). 각 클라우드 컨트롤러 매니저는 단일
프로세스에 여러 {{< glossary_tooltip text="컨트롤러" term_id="controller" >}}를
구현한다.
{{< note >}}
볼륨 컨트롤러는 의도적으로 CCM의 일부가 되지 않도록 선택되었다. 연관된 복잡성 때문에 그리고 벤더 특유의 볼륨 로직 개념을 일반화 하기 위한 기존의 노력때문에, 볼륨 컨트롤러는 CCM으로 이전되지 않도록 결정되었다.
또한 사용자는 클라우드 컨트롤러 매니저를 컨트롤 플레인의 일부가 아닌 쿠버네티스
{{< glossary_tooltip text="애드온" term_id="addons" >}}으로
실행할 수도 있다.
{{< /note >}}
CCM을 이용하는 볼륨을 지원하기 위한 원래 계획은 플러그형 볼륨을 지원하기 위한 [Flex](/ko/docs/concepts/storage/volumes/#flexVolume) 볼륨을 사용하기 위한 것이었다. 그러나, [CSI](/ko/docs/concepts/storage/volumes/#csi)라 알려진 경쟁적인 노력이 Flex를 대체하도록 계획되고 있다.
## 클라우드 컨트롤러 매니저의 기능 {#functions-of-the-ccm}
이러한 역동성을 고려하여, CSI가 준비될 때까지 차이점에 대한 측정은 도중에 중지하기로 결정하였다.
## CCM의 기능
CCM은 클라우드 제공사업자에 종속적인 쿠버네티스 컴포넌트로부터 그 속성을 상속받는다. 이번 섹션은 그러한 컴포넌트를 근거로 구성되었다.
### 1. 쿠버네티스 컨트롤러 매니저
CCM의 주요 기능은 KCM으로부터 파생된다. 이전 섹션에서 언급한 바와 같이, CCM은 다음의 컨트롤러 루프를 작동시킨다.
* 노드 컨트롤러
* 라우트 컨트롤러
* 서비스 컨트롤러
#### 노드 컨트롤러
노드 컨트롤러는 클라우드 제공사업자의 클러스터에서 동작중인 노드에 대한 정보를 얻음으로써 노드를 초기화할 책임을 가진다. 노드 컨트롤러는 다음 기능을 수행한다.
1. 클라우드 특유의 영역/지역 레이블을 이용한 노드를 초기화한다.
2. 클라우드 특유의 인스턴스 세부사항, 예를 들어, 타입 그리고 크기 등을 이용한 노드를 초기화한다.
3. 노드의 네트워크 주소와 호스트네임을 취득한다.
4. 노드가 무응답일 경우, 클라우드로부터 해당 노드가 삭제된 것인지 확인한다. 클라우드로부터 삭제된 것이라면, 쿠버네티스 노드 오브젝트를 삭제한다.
#### 라우트 컨트롤러
라우트 컨트롤러는 클라우드에서 적합하게 경로를 구성하는 책임을 가지며 쿠버네티스 클러스터 내 상이한 노드 상의 컨테이너들이 상호 소통할 수 있도록 해준다. 라우트 컨트롤러는 오직 Google Compute Engine 클러스터에서만 적용가능 하다.
#### 서비스 컨트롤러
서비스 컨트롤러는 서비스 생성, 업데이트, 그리고 이벤트 삭제에 대한 책임을 가진다. 쿠버네티스 내 서비스의 현재 상태를 근거로, 쿠버네티스 내 서비스의 상태를 나타내기 위해 클라우드 로드 밸런서(ELB, Google LB, Oracle Cloud Infrastrucuture LB와 같은)를 구성해준다. 추가적으로, 클라우드 로드 밸런서를 위한 서비스 백엔드가 최신화 되도록 보장해 준다.
### 2. Kubelet
노드 컨트롤러는 kubelet의 클라우드 종속적인 기능을 포함한다. CCM이 도입되기 이전에는, kubelet 이 IP 주소, 지역/영역 레이블 그리고 인스턴스 타입 정보와 같은 클라우드 특유의 세부사항으로 노드를 초기화하는 책임을 가졌다. CCM의 도입으로 kubelet에서 CCM으로 이 초기화 작업이 이전되었다.
이 새로운 모델에서, kubelet은 클라우드 특유의 정보 없이 노드를 초기화 해준다. 그러나, kubelet은 새로 생성된 노드에 taint를 추가해서 CCM이 클라우드에 대한 정보를 가지고 노드를 초기화하기 전까지는 스케줄되지 않도록 한다. 그러고 나서 이 taint를 제거한다.
## 플러그인 메커니즘
클라우드 컨트롤러 매니저는 어떠한 클라우드에서든지 플러그 인 되어 구현될 수 있도록 Go 인터페이스를 이용한다. 구체적으로, [여기](https://github.com/kubernetes/cloud-provider/blob/9b77dc1c384685cb732b3025ed5689dd597a5971/cloud.go#L42-L62)에 정의된 CloudProvider 인터페이스를 이용한다.
위에서 강조되었던 4개의 공유 컨트롤러의 구현, 그리고 공유 cloudprovider 인터페이스와 더불어 일부 골격은 쿠버네티스 코어 내에 유지될 것이다. 클라우드 제공사업자 특유의 구현은 코어의 외부에 탑재되어 코어 내에 정의된 인터페이스를 구현할 것이다.
개발 중인 플러그인에 대한 보다 자세한 정보는, [클라우드 컨트롤러 매니저 개발하기](/docs/tasks/administer-cluster/developing-cloud-controller-manager/)를 참고한다.
## 인가
이 섹션은 CCM에 의해 작업을 수행하기 위해 다양한 API 오브젝트에서 요구되는 접근에 대해 구분해 본다.
클라우드 컨틀롤러 매니저의 내부 컨트롤러에는 다음 컨트롤러들이 포함된다.
### 노드 컨트롤러
노드 컨트롤러는 오직 노드 오브젝트와 동작한다. 노드 오브젝트를 get, list, create, update, patch, watch, 그리고 delete 하기 위한 모든 접근을 요한다.
노드 컨트롤러는 클라우드 인프라스트럭처에 새 서버가 생성될 때 {{< glossary_tooltip text="노드" term_id="node" >}}
오브젝트를 생성하는 역할을 한다. 노드 컨트롤러는 클라우드 공급자의 사용자
테넌시 내에서 실행되는 호스트에 대한 정보를 가져온다. 노드 컨트롤러는 다음 기능들을 수행한다.
v1/Node:
1. 컨트롤러가 클라우드 공급자 API를 통해 찾아내는 각 서버에 대해 노드 오브젝트를 초기화한다.
2. 클라우드 관련 정보(예를 들어, 노드가 배포되는 지역과 사용 가능한 리소스(CPU, 메모리 등))를
사용해서 노드 오브젝트에 어노테이션과 레이블을 작성한다.
3. 노드의 호스트 이름과 네트워크 주소를 가져온다.
4. 노드의 상태를 확인한다. 노드가 응답하지 않는 경우, 이 컨트롤러는 사용자가
이용하는 클라우드 공급자의 API를 통해 서버가 비활성화됨 / 삭제됨 / 종료됨인지 확인한다.
노드가 클라우드에서 삭제된 경우, 컨트롤러는 사용자의 쿠버네티스 클러스터에서 노드
오브젝트를 삭제한다.
일부 클라우드 공급자의 구현에서는 이를 노드 컨트롤러와 별도의 노드
라이프사이클 컨트롤러로 분리한다.
### 라우트 컨트롤러
라우트 컨트롤러는 사용자의 쿠버네티스 클러스터의 다른 노드에
있는 각각의 컨테이너가 서로 통신할 수 있도록 클라우드에서
라우트를 적절히 구성해야 한다.
클라우드 공급자에 따라 라우트 컨트롤러는 파드 네트워크
IP 주소 블록을 할당할 수도 있다.
### 서비스 컨트롤러
{{< glossary_tooltip text="서비스" term_id="service" >}} 는 관리형 로드 밸런서,
IP 주소, 네트워크 패킷 필터링 그리고 대상 상태 확인과 같은
클라우드 인프라스트럭처 컴포넌트와 통합된다. 서비스 컨트롤러는 사용자의 클라우드
공급자 API와 상호 작용해서 필요한 서비스 리소스를 선언할 때
로드 밸런서와 기타 인프라스트럭처 컴포넌트를 설정한다.
## 인가
이 섹션에서는 클라우드 컨트롤러 매니저가 작업을 수행하기 위해
다양한 API 오브젝트에 필요한 접근 권한을 세분화한다.
### 노드 컨트롤러 {#authorization-node-controller}
노드 컨트롤러는 노드 오브젝트에서만 작동한다. 노드 오브젝트를 읽고,
수정하려면 전체 접근 권한이 필요하다.
`v1/Node`:
- Get
- List
@ -117,23 +96,24 @@ v1/Node:
- Watch
- Delete
### 라우트 컨트롤러
### 라우트 컨트롤러 {#authorization-route-controller}
라우트 컨트롤러는 노드 오브젝트 생성에 대해 귀기울이고 적절하게 라우트를 구성한다. 노드 오브젝트에 대한 get 접근을 요한다.
라우트 컨트롤러가 노드 오브젝트의 생성을 수신하고 적절하게
라우트를 구성한다. 노드 오브젝트에 대한 접근 권한이 필요하다.
v1/Node:
`v1/Node`:
- Get
### 서비스 컨트롤러
### 서비스 컨트롤러 {#authorization-service-controller}
서비스 컨트롤러는 서비스 오브젝트 create, update 그리고 delete에 대해 귀기울이고, 서비스를 위해 적절하게 엔드포인트를 구성한다.
서비스 컨트롤러는 서비스 오브젝트 생성, 업데이트 그리고 삭제 이벤트를 수신한 다음 해당 서비스에 대한 엔드포인트를 적절하게 구성한다.
서비스에 접근하기 위해, list, 그리고 watch 접근을 요한다. 서비스 update를 위해 patch와 update 접근을 요한다.
서비스에 접근하려면, 목록과 감시 접근 권한이 필요하다. 서비스를 업데이트하려면, 패치와 업데이트 접근 권한이 필요하다.
서비스에 대한 엔드포인트 설정을 위해, create, list, get, watch, 그리고 update를 하기위한 접근을 요한다.
서비스에 대한 엔드포인트 리소스를 설정하려면 생성, 목록, 가져오기, 감시 그리고 업데이트에 대한 접근 권한이 필요하다.
v1/Service:
`v1/Service`:
- List
- Get
@ -141,21 +121,22 @@ v1/Service:
- Patch
- Update
### 그 외의 것들
### 그 외의 것들 {#authorization-miscellaneous}
CCM의 코어에 대한 구현은 이벤트를 create 하고, 보안 작업을 보장하기 위한 접근을 요하며, ServiceAccount를 create 하기 위한 접근을 요한다.
클라우드 컨트롤러 매니저의 핵심 구현을 위해 이벤트 오브젝트를 생성하고, 안전한 작동을 보장하기 위해 서비스어카운트(ServiceAccounts)를 생성해야 한다.
v1/Event:
`v1/Event`:
- Create
- Patch
- Update
v1/ServiceAccount:
`v1/ServiceAccount`:
- Create
CCM에 대한 RBAC ClusterRole은 다음과 같다.
클라우드 컨트롤러 매니저의 {{< glossary_tooltip term_id="rbac" text="RBAC" >}}
클러스터롤(ClusterRole)은 다음과 같다.
```yaml
apiVersion: rbac.authorization.k8s.io/v1
@ -219,24 +200,16 @@ rules:
- update
```
## 벤더 구현사항
다음은 클라우드 제공사업자들이 구현한 CCM들이다.
* [Alibaba Cloud](https://github.com/kubernetes/cloud-provider-alibaba-cloud)
* [AWS](https://github.com/kubernetes/cloud-provider-aws)
* [Azure](https://github.com/kubernetes/cloud-provider-azure)
* [BaiduCloud](https://github.com/baidu/cloud-provider-baiducloud)
* [DigitalOcean](https://github.com/digitalocean/digitalocean-cloud-controller-manager)
* [GCP](https://github.com/kubernetes/cloud-provider-gcp)
* [Hetzner](https://github.com/hetznercloud/hcloud-cloud-controller-manager)
* [Linode](https://github.com/linode/linode-cloud-controller-manager)
* [OpenStack](https://github.com/kubernetes/cloud-provider-openstack)
* [Oracle](https://github.com/oracle/oci-cloud-controller-manager)
* [TencentCloud](https://github.com/TencentCloud/tencentcloud-cloud-controller-manager)
## 클러스터 관리
CCM을 구성하고 작동하기 위한 전체 안내는 [여기](/docs/tasks/administer-cluster/running-cloud-controller/#cloud-controller-manager)에서 제공된다.
{{% /capture %}}
{{% capture whatsnext %}}
[클라우드 컨트롤러 매니저 관리](/docs/tasks/administer-cluster/running-cloud-controller/#cloud-controller-manager)에는
클라우드 컨트롤러 매니저의 실행과 관리에 대한 지침이 있다.
자체 클라우드 컨트롤러 매니저를 구현하거나 기존 프로젝트를 확장하는 방법을 알고 싶은가?
클라우드 컨트롤러 매니저는 Go 인터페이스를 사용해서 모든 클라우드 플러그인을 구현할 수 있다. 구체적으로, [kubernetes/cloud-provider](https://github.com/kubernetes/cloud-provider)의 [`cloud.go`](https://github.com/kubernetes/cloud-provider/blob/release-1.17/cloud.go#L42-L62)에 정의된 `CloudProvider` 인터페이스를 사용한다.
이 문서(노드, 라우트와 서비스)에서 강조된 공유 컨트롤러의 구현과 공유 cloudprovider 인터페이스와 함께 일부 스캐폴딩(scaffolding)은 쿠버네티스 핵심의 일부이다. 클라우드 공급자 전용 구현은 쿠버네티스의 핵심 바깥에 있으며 `CloudProvider` 인터페이스를 구현한다.
플러그인 개발에 대한 자세한 내용은 [클라우드 컨트롤러 매니저 개발하기](/docs/tasks/administer-cluster/developing-cloud-controller-manager/)를 참조한다.
{{% /capture %}}

View File

@ -0,0 +1,66 @@
---
title: 컨트롤 플레인-노드 간 통신
content_template: templates/concept
weight: 20
aliases:
- master-node-communication
---
{{% capture overview %}}
이 문서는 컨트롤 플레인(실제로는 API 서버)과 쿠버네티스 클러스터 사이에 대한 통신 경로의 목록을 작성한다. 이는 사용자가 신뢰할 수 없는 네트워크(또는 클라우드 공급자의 완전한 퍼블릭 IP)에서 클러스터를 실행할 수 있도록 네트워크 구성을 강화하기 위한 맞춤 설치를 할 수 있도록 한다.
{{% /capture %}}
{{% capture body %}}
## 노드에서 컨트롤 플레인으로의 통신
노드에서 컨트롤 플레인까지의 모든 통신 경로는 API 서버에서 종료된다(다른 마스터 컴포넌트 중 어느 것도 원격 서비스를 노출하도록 설계되지 않았다). 일반적인 배포에서 API 서버는 하나 이상의 클라이언트 [인증](/docs/reference/access-authn-authz/authentication/) 형식이 활성화된 보안 HTTPS 포트(443)에서 원격 연결을 수신하도록 구성된다.
특히 [익명의 요청](/docs/reference/access-authn-authz/authentication/#anonymous-requests) 또는 [서비스 어카운트 토큰](/docs/reference/access-authn-authz/authentication/#service-account-tokens)이 허용되는 경우, 하나 이상의 [권한 부여](/docs/reference/access-authn-authz/authorization/) 형식을 사용해야 한다.
노드는 유효한 클라이언트 자격 증명과 함께 API 서버에 안전하게 연결할 수 있도록 클러스터에 대한 공개 루트 인증서로 프로비전해야 한다. 예를 들어, 기본 GKE 배포에서, kubelet에 제공되는 클라이언트 자격 증명은 클라이언트 인증서 형식이다. kubelet 클라이언트 인증서의 자동 프로비저닝은 [kubelet TLS 부트스트랩](/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/)을 참고한다.
API 서버에 연결하려는 파드는 쿠버네티스가 공개 루트 인증서와 유효한 베어러 토큰(bearer token)을 파드가 인스턴스화될 때 파드에 자동으로 주입하도록 서비스 어카운트를 활용하여 안전하게 연결할 수 있다.
`kubernetes` 서비스(모든 네임스페이스의)는 API 서버의 HTTPS 엔드포인트로 리디렉션되는 가상 IP 주소(kube-proxy를 통해)로 구성되어 있다.
컨트롤 플레인 컴포넌트는 보안 포트를 통해 클러스터 API 서버와도 통신한다.
결과적으로, 노드 및 노드에서 실행되는 파드에서 컨트롤 플레인으로 연결하기 위한 기본 작동 모드는 기본적으로 보호되며 신뢰할 수 없는 네트워크 및/또는 공용 네트워크에서 실행될 수 있다.
## 컨트롤 플레인에서 노드로의 통신
컨트롤 플레인(API 서버)에서 노드로는 두 가지 기본 통신 경로가 있다. 첫 번째는 API 서버에서 클러스터의 각 노드에서 실행되는 kubelet 프로세스이다. 두 번째는 API 서버의 프록시 기능을 통해 API 서버에서 모든 노드, 파드 또는 서비스에 이르는 것이다.
### API 서버에서 kubelet으로의 통신
API 서버에서 kubelet으로의 연결은 다음의 용도로 사용된다.
* 파드에 대한 로그를 가져온다.
* 실행 중인 파드에 (kubectl을 통해) 연결한다.
* kubelet의 포트-포워딩 기능을 제공한다.
이 연결은 kubelet의 HTTPS 엔드포인트에서 종료된다. 기본적으로, API 서버는 kubelet의 서빙(serving) 인증서를 확인하지 않으므로, 연결이 중간자(man-in-the-middle) 공격의 대상이 되며, 신뢰할 수 없는 네트워크 및/또는 공용 네트워크에서 실행하기에 **안전하지 않다** .
이 연결을 확인하려면, `--kubelet-certificate-authority` 플래그를 사용하여 API 서버에 kubelet의 서빙 인증서를 확인하는 데 사용할 루트 인증서 번들을 제공한다.
이것이 가능하지 않은 경우, 신뢰할 수 없는 네트워크 또는 공용 네트워크를 통한 연결을 피하기 위해 필요한 경우 API 서버와 kubelet 사이에 [SSH 터널링](/ko/docs/concepts/architecture/control-plane-node-communication/#ssh-터널)을
사용한다.
마지막으로, kubelet API를 보호하려면 [Kubelet 인증 및/또는 권한 부여](/docs/admin/kubelet-authentication-authorization/)를 활성화해야 한다.
### API 서버에서 노드, 파드 및 서비스로의 통신
API 서버에서 노드, 파드 또는 서비스로의 연결은 기본적으로 일반 HTTP 연결로 연결되므로 인증되거나 암호화되지 않는다. API URL에서 노드, 파드 또는 서비스 이름을 접두어 `https:` 로 사용하여 보안 HTTPS 연결을 통해 실행될 수 있지만, HTTPS 엔드포인트가 제공한 인증서의 유효성을 검증하지 않거나 클라이언트 자격 증명을 제공하지 않으므로 연결이 암호화되는 동안 무결성을 보장하지 않는다. 이러한 연결은 신뢰할 수 없는 네트워크 및/또는 공용 네트워크에서 실행하기에 **현재는 안전하지 않다** .
### SSH 터널
쿠버네티스는 SSH 터널을 지원하여 컨트롤 플레인에서 노드로의 통신 경로를 보호한다. 이 구성에서, API 서버는 클러스터의 각 노드에 SSH 터널을 시작하고(포트 22에서 수신 대기하는 ssh 서버에 연결) 터널을 통해 kubelet, 노드, 파드 또는 서비스로 향하는 모든 트래픽을 전달한다.
이 터널은 트래픽이 노드가 실행 중인 네트워크 외부에 노출되지 않도록 한다.
SSH 터널은 현재 더 이상 사용되지 않으므로 수행 중인 작업이 어떤 것인지 모른다면 사용하면 안된다. Konnectivity 서비스는 이 통신 채널을 대체한다.
### Konnectivity 서비스
{{< feature-state for_k8s_version="v1.18" state="beta" >}}
SSH 터널을 대체하는 Konnectivity 서비스는 컨트롤 플레인에서 클러스터 통신에 TCP 레벨 프록시를 제공한다. Konnectivity는 컨트롤 플레인 네트워크와 노드 네트워크에서 각각 실행되는 Konnectivity 서버와 Konnectivity 에이전트의 두 부분으로 구성된다. Konnectivity 에이전트는 Konnectivity 서버에 대한 연결을 시작하고 연결을 유지한다.
그런 다음 컨트롤 플레인에서 노드로의 모든 트래픽은 이 연결을 통과한다.
클러스터에서 설정하는 방법에 대해서는 [Konnectivity 서비스 설정](/docs/tasks/setup-konnectivity/)을 참조한다.

View File

@ -52,7 +52,7 @@ weight: 30
작업을 수행한 다음 중지하는
쿠버네티스 리소스 이다.
(일단 [스케줄되면](/ko/docs/concepts/scheduling/), 파드 오브젝트는 kubelet
(일단 [스케줄되면](/ko/docs/concepts/scheduling-eviction/), 파드 오브젝트는 kubelet
의 의도한 상태 중 일부가 된다.)
잡 컨트롤러가 새로운 작업을 확인하면, 클러스터 어딘가에서

View File

@ -0,0 +1,57 @@
---
title: 애드온 설치
content_template: templates/concept
---
{{% capture overview %}}
애드온은 쿠버네티스의 기능을 확장한다.
이 페이지는 사용 가능한 일부 애드온과 관련 설치 지침 링크를 나열한다.
각 섹션의 애드온은 알파벳 순으로 정렬되어 있다. 순서는 우선 순위와는 상관없다.
{{% /capture %}}
{{% capture body %}}
## 네트워킹과 네트워크 폴리시
* [ACI](https://www.github.com/noironetworks/aci-containers)는 Cisco ACI로 통합 컨테이너 네트워킹 및 네트워크 보안을 제공한다.
* [Calico](https://docs.projectcalico.org/latest/introduction/)는 네트워킹 및 네트워크 폴리시 제공자이다. Calico는 유연한 네트워킹 옵션을 지원하므로 BGP 유무에 관계없이 비-오버레이 및 오버레이 네트워크를 포함하여 가장 상황에 맞는 옵션을 선택할 수 있다. Calico는 동일한 엔진을 사용하여 서비스 메시 계층(service mesh layer)에서 호스트, 파드 및 (이스티오(istio)와 Envoy를 사용하는 경우) 애플리케이션에 대한 네트워크 폴리시를 적용한다.
* [Canal](https://github.com/tigera/canal/tree/master/k8s-install)은 Flannel과 Calico를 통합하여 네트워킹 및 네트워크 폴리시를 제공한다.
* [Cilium](https://github.com/cilium/cilium)은 L3 네트워크 및 네트워크 폴리시 플러그인으로 HTTP/API/L7 폴리시를 투명하게 시행할 수 있다. 라우팅 및 오버레이/캡슐화 모드를 모두 지원하며, 다른 CNI 플러그인 위에서 작동할 수 있다.
* [CNI-Genie](https://github.com/Huawei-PaaS/CNI-Genie)를 사용하면 쿠버네티스는 Calico, Canal, Flannel, Romana 또는 Weave와 같은 CNI 플러그인을 완벽하게 연결할 수 있다.
* [Contiv](http://contiv.github.io)는 다양한 유스케이스와 풍부한 폴리시 프레임워크를 위해 구성 가능한 네트워킹(BGP를 사용하는 네이티브 L3, vxlan을 사용하는 오버레이, 클래식 L2 그리고 Cisco-SDN/ACI)을 제공한다. Contiv 프로젝트는 완전히 [오픈소스](http://github.com/contiv)이다. [인스톨러](http://github.com/contiv/install)는 kubeadm을 이용하거나, 그렇지 않은 경우에 대해서도 설치 옵션을 모두 제공한다.
* [Contrail](http://www.juniper.net/us/en/products-services/sdn/contrail/contrail-networking/)은 [Tungsten Fabric](https://tungsten.io)을 기반으로 하며, 오픈소스이고, 멀티 클라우드 네트워크 가상화 및 폴리시 관리 플랫폼이다. Contrail과 Tungsten Fabric은 쿠버네티스, OpenShift, OpenStack 및 Mesos와 같은 오케스트레이션 시스템과 통합되어 있으며, 가상 머신, 컨테이너/파드 및 베어 메탈 워크로드에 대한 격리 모드를 제공한다.
* [Flannel](https://github.com/coreos/flannel/blob/master/Documentation/kubernetes.md)은 쿠버네티스와 함께 사용할 수 있는 오버레이 네트워크 제공자이다.
* [Knitter](https://github.com/ZTE/Knitter/)는 쿠버네티스 파드에서 여러 네트워크 인터페이스를 지원하는 플러그인이다.
* [Multus](https://github.com/Intel-Corp/multus-cni)는 쿠버네티스에서 SRIOV, DPDK, OVS-DPDK 및 VPP 기반 워크로드 외에 모든 CNI 플러그인(예: Calico, Cilium, Contiv, Flannel)을 지원하기 위해 쿠버네티스에서 다중 네트워크 지원을 위한 멀티 플러그인이다.
* [NSX-T](https://docs.vmware.com/en/VMware-NSX-T/2.0/nsxt_20_ncp_kubernetes.pdf) 컨테이너 플러그인(NCP)은 VMware NSX-T와 쿠버네티스와 같은 컨테이너 오케스트레이터 간의 통합은 물론 NSX-T와 PKS(Pivotal 컨테이너 서비스) 및 OpenShift와 같은 컨테이너 기반 CaaS/PaaS 플랫폼 간의 통합을 제공한다.
* [Nuage](https://github.com/nuagenetworks/nuage-kubernetes/blob/v5.1.1-1/docs/kubernetes-1-installation.rst)는 가시성과 보안 모니터링 기능을 통해 쿠버네티스 파드와 비-쿠버네티스 환경 간에 폴리시 기반 네트워킹을 제공하는 SDN 플랫폼이다.
* [Romana](http://romana.io)는 [네트워크폴리시 API](/docs/concepts/services-networking/network-policies/)도 지원하는 파드 네트워크용 Layer 3 네트워킹 솔루션이다. Kubeadm 애드온 설치에 대한 세부 정보는 [여기](https://github.com/romana/romana/tree/master/containerize)에 있다.
* [Weave Net](https://www.weave.works/docs/net/latest/kube-addon/)은 네트워킹 및 네트워크 폴리시를 제공하고, 네트워크 파티션의 양면에서 작업을 수행하며, 외부 데이터베이스는 필요하지 않다.
## 서비스 검색
* [CoreDNS](https://coredns.io)는 유연하고 확장 가능한 DNS 서버로, 파드를 위한 클러스터 내 DNS로 [설치](https://github.com/coredns/deployment/tree/master/kubernetes)할 수 있다.
## 시각화 &amp; 제어
* [대시보드](https://github.com/kubernetes/dashboard#kubernetes-dashboard)는 쿠버네티스를 위한 대시보드 웹 인터페이스이다.
* [Weave Scope](https://www.weave.works/documentation/scope-latest-installing/#k8s)는 컨테이너, 파드, 서비스 등을 그래픽으로 시각화하는 도구이다. [Weave Cloud 어카운트](https://cloud.weave.works/)와 함께 사용하거나 UI를 직접 호스팅한다.
## 인프라스트럭처
* [KubeVirt](https://kubevirt.io/user-guide/#/installation/installation)는 쿠버네티스에서 가상 머신을 실행하기 위한 애드온이다. 일반적으로 베어 메탈 클러스터에서 실행한다.
## 레거시 애드온
더 이상 사용되지 않는 [cluster/addons](https://git.k8s.io/kubernetes/cluster/addons) 디렉터리에 다른 여러 애드온이 문서화되어 있다.
잘 관리된 것들이 여기에 연결되어 있어야 한다. PR을 환영한다!
{{% /capture %}}

View File

@ -0,0 +1,414 @@
---
title: 클라우드 제공자
content_template: templates/concept
weight: 30
---
{{% capture overview %}}
이 페이지에서는 특정 클라우드 제공자에서 실행 중인 쿠버네티스를 관리하는 방법에
대해 설명한다.
{{% /capture %}}
{{% capture body %}}
### kubeadm
[kubeadm](/docs/reference/setup-tools/kubeadm/kubeadm/)은 쿠버네티스 클러스터를 생성하는 데 많이 사용하는 옵션이다.
kubeadm에는 클라우드 제공자에 대한 구성 정보를 지정하는 구성 옵션이 있다. 예를 들어
kubeadm을 사용하여 일반적인 인-트리(in-tree) 클라우드 제공자를 아래와 같이 구성할 수 있다.
```yaml
apiVersion: kubeadm.k8s.io/v1beta2
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
cloud-provider: "openstack"
cloud-config: "/etc/kubernetes/cloud.conf"
---
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v1.13.0
apiServer:
extraArgs:
cloud-provider: "openstack"
cloud-config: "/etc/kubernetes/cloud.conf"
extraVolumes:
- name: cloud
hostPath: "/etc/kubernetes/cloud.conf"
mountPath: "/etc/kubernetes/cloud.conf"
controllerManager:
extraArgs:
cloud-provider: "openstack"
cloud-config: "/etc/kubernetes/cloud.conf"
extraVolumes:
- name: cloud
hostPath: "/etc/kubernetes/cloud.conf"
mountPath: "/etc/kubernetes/cloud.conf"
```
인-트리 클라우드 제공자는 일반적으로 [kube-apiserver](/docs/admin/kube-apiserver/), [kube-controller-manager](/docs/admin/kube-controller-manager/)
및 [kubelet](/docs/admin/kubelet/)의 커맨드 라인에 지정된 `--cloud-provider``--cloud-config` 가 모두 필요하다.
각 제공자에 대해 `--cloud-config` 에 지정된 파일의 내용도 아래에 설명되어 있다.
모든 외부 클라우드 제공자의 경우, 아래 제공자에 대한 제목 아래에 있는 개별 리포지터리의 지침을 따르거나,
[모든 리포지터리 목록](https://github.com/kubernetes?q=cloud-provider-&type=&language=)을 볼 수 있다
## AWS
이 섹션에서는 Amazon Web Services에서 쿠버네티스를 실행할 때 사용할 수 있는
모든 구성에 대해 설명한다.
이 외부 클라우드 제공자를 사용하려는 경우, 해당 리포지터리는 [kubernetes/cloud-provider-aws](https://github.com/kubernetes/cloud-provider-aws#readme)이다.
### 노드 이름
AWS 클라우드 제공자는 AWS 인스턴스의 프라이빗 DNS 이름을 쿠버네티스 노드 오브젝트의 이름으로 사용한다.
### 로드 밸런서
아래와 같이 어노테이션을 구성하여 AWS의 특정 기능을 사용하도록
[외부 로드 밸런서](/docs/tasks/access-application-cluster/create-external-load-balancer/)를 설정할 수 있다.
```yaml
apiVersion: v1
kind: Service
metadata:
name: example
namespace: kube-system
labels:
run: example
annotations:
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:xx-xxxx-x:xxxxxxxxx:xxxxxxx/xxxxx-xxxx-xxxx-xxxx-xxxxxxxxx #이 값을 교체한다
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http
spec:
type: LoadBalancer
ports:
- port: 443
targetPort: 5556
protocol: TCP
selector:
app: example
```
_어노테이션_ 을 사용하여 AWS의 로드 밸런서 서비스에 다른 설정을 적용할 수 있다. 다음은 AWS ELB에서 지원하는 어노테이션에 대해 설명한다.
* `service.beta.kubernetes.io/aws-load-balancer-access-log-emit-interval`: 액세스 로그 방출 간격을 지정하는 데 사용된다.
* `service.beta.kubernetes.io/aws-load-balancer-access-log-enabled`: 서비스에서 액세스 로그를 활성화하거나 비활성화하는 데 사용된다.
* `service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-name`: 액세스 로그 s3 버킷 이름을 지정하는 데 사용된다.
* `service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-prefix`: 액세스 로그 s3 버킷 접두사를 지정하는 데 사용된다.
* `service.beta.kubernetes.io/aws-load-balancer-additional-resource-tags`: 서비스에서 쉼표로 구분된 키-값 쌍의 목록을 지정하여 ELB에 추가 태그로 기록된다. 예를 들면 다음과 같다. `"Key1=Val1,Key2=Val2,KeyNoVal1=,KeyNoVal2"`
* `service.beta.kubernetes.io/aws-load-balancer-backend-protocol`: 서비스에서 리스너 뒤의 백엔드(파드)가 언급한 프로토콜을 지정하는 데 사용된다. 만약 `http` (기본값) 또는 `https` 인 경우, 연결을 종료하고 헤더를 파싱하는 HTTPS 리스너가 생성된다. `ssl` 이나 `tcp` 로 설정된 경우, "원시(raw)" SSL 리스너가 사용된다. `http` 로 설정하고 `aws-load-balancer-ssl-cert` 를 사용하지 않았다면 HTTP 리스너가 사용된다.
* `service.beta.kubernetes.io/aws-load-balancer-ssl-cert`: 서비스에서 보안 리스너를 요청하는 데 사용된다. 값은 유효한 인증서 ARN이다. 자세한 내용은, [ELB 리스너 구성](https://docs.aws.amazon.com/ko_kr/elasticloadbalancing/latest/classic/elb-listener-config.html)을 참고한다. CertARN은 IAM 또는 CM 인증서 ARN이다(예: `arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012`).
* `service.beta.kubernetes.io/aws-load-balancer-connection-draining-enabled`: 서비스에서 연결 드레이닝(draining)을 활성화하거나 비활성화하는 데 사용된다.
* `service.beta.kubernetes.io/aws-load-balancer-connection-draining-timeout`: 서비스에서 연결 드레이닝 타임아웃 값을 지정하는 데 사용된다.
* `service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout`: 서비스에서 유휴 연결 타임아웃 값을 지정하는 데 사용된다.
* `service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled`: 서비스에서 교차 영역의 로드 밸런싱을 활성화하거나 비활성화하는 데 사용된다.
* `service.beta.kubernetes.io/aws-load-balancer-security-groups`: 생성된 ELB에 추가할 보안 그룹을 지정하는 데 사용된다. 이는 이전에 ELB에 할당된 다른 모든 보안 그룹을 대체한다.
* `service.beta.kubernetes.io/aws-load-balancer-extra-security-groups`: 서비스에서 생성된 ELB에 추가할 추가적인 보안 그룹을 지정하는 데 사용된다.
* `service.beta.kubernetes.io/aws-load-balancer-internal`: 서비스에서 내부 ELB 사용 희망을 표시하기 위해 사용된다.
* `service.beta.kubernetes.io/aws-load-balancer-proxy-protocol`: 서비스에서 ELB에서 프록시 프로토콜을 활성화하는 데 사용된다. 현재는 모든 ELB 백엔드에서 프록시 프로토콜을 사용하도록 설정하는 `*` 값만 허용한다. 향후에는 특정 백엔드에서만 프록시 프로토콜을 설정할 수 있도록 이를 조정할 수 있게 된다.
* `service.beta.kubernetes.io/aws-load-balancer-ssl-ports`: SSL/HTTPS 리스너를 사용할 쉼표로 구분된 포트의 목록을 지정하기 위해 서비스에서 사용된다. 기본값은 `*`(모두)이다.
AWS 어노테이션에 대한 정보 출처는 [aws.go](https://github.com/kubernetes/legacy-cloud-providers/blob/master/aws/aws.go)의 코멘트이다.
## Azure
이 외부 클라우드 제공자를 사용하려는 경우, 해당 리포지터리는 [kubernetes/cloud-provider-azure](https://github.com/kubernetes/cloud-provider-azure#readme)이다.
### 노드 이름
Azure 클라우드 제공자는 쿠버네티스 노드 오브젝트의 이름으로 노드의 (kubelet에 의해 결정되거나 `--hostname-override` 로 재정의된) 호스트 이름(hostname)을 사용한다.
참고로 쿠버네티스 노드 이름은 Azure VM 이름과 일치해야 한다.
## CloudStack
이 외부 클라우드 제공자를 사용하려는 경우, 해당 리포지터리는 [apache/cloudstack-kubernetes-provider](https://github.com/apache/cloudstack-kubernetes-provider)이다.
### 노드 이름
CloudStack 클라우드 제공자는 쿠버네티스 노드 오브젝트의 이름으로 노드의 (kubelet에 의해 결정되거나 `--hostname-override` 로 재정의된) 호스트 이름을 사용한다.
참고로 쿠버네티스 노드 이름은 CloudStack VM 이름과 일치해야 한다.
## GCE
이 외부 클라우드 제공자를 사용하려는 경우, 해당 리포지터리는 [kubernetes/cloud-provider-gcp](https://github.com/kubernetes/cloud-provider-gcp#readme)이다.
### 노드 이름
GCE 클라우드 제공자는 쿠버네티스 노드 오브젝트의 이름으로 노드의 (kubelet에 의해 결정되거나 `--hostname-override` 로 재정의된) 호스트 이름을 사용한다.
참고로 쿠버네티스 노드 이름의 첫 번째 세그먼트는 GCE 인스턴스 이름과 일치해야 한다(예: `kubernetes-node-2.c.my-proj.internal` 이름이 지정된 노드는 `kubernetes-node-2` 이름이 지정된 인스턴스에 해당해야 함).
## OpenStack
이 섹션에서는 쿠버네티스와 함께 OpenStack을 사용할 때 사용할 수 있는
모든 구성에 대해 설명한다.
이 외부 클라우드 제공자를 사용하려는 경우, 해당 리포지터리는 [kubernetes/cloud-provider-openstack](https://github.com/kubernetes/cloud-provider-openstack#readme)이다.
### 노드 이름
OpenStack 클라우드 제공자는 (OpenStack 메타데이터에서 결정한) 인스턴스 이름을 쿠버네티스 노드 오브젝트의 이름으로 사용한다.
참고로 kubelet이 노드 오브젝트를 성공적으로 등록하려면 인스턴스 이름이 유효한 쿠버네티스 노드 이름이어야 한다.
### 서비스
쿠버네티스에 대한
OpenStack 클라우드 제공자 구현은 사용 가능한 경우 기본 클라우드에서
이러한 OpenStack 서비스 사용을 지원한다.
| 서비스 | API 버전 | 필수 |
|--------------------------|----------------|----------|
| 블록 스토리지 (Cinder) | V1†, V2, V3 | 아니오 |
| 컴퓨트 (Nova) | V2 | 아니오 |
| 아이덴티티(Identity) (Keystone) | V2‡, V3 | 예 |
| 로드 밸런싱 (Neutron) | V1§, V2 | 아니오 |
| 로드 밸런싱 (Octavia) | V2 | 아니오 |
† 블록 스토리지 V1 API 지원은 사용 중단(deprecated)되며, 쿠버네티스 1.9에서 블록 스토리지
V3 API 지원이 추가되었다.
‡ 아이덴티티 V2 API 지원은 사용 중단되며, 향후 릴리스에서는 제공자에서
제거될 예정이다. "Queens" 릴리스부터 OpenStack은 더 이상 아이덴티티 V2 API를
공개하지 않는다.
§ 로드 밸런싱 V1 API 지원이 쿠버네티스 1.9에서 제거되었다.
서비스 디스커버리는 제공자 구성에서 제공된 `auth-url` 을 사용하여
OpenStack 아이덴티티(Keystone)에서 관리하는 서비스 카탈로그를
나열하여 수행된다. Keystone 이외의 OpenStack 서비스를 사용할 수 없고
영향을 받는 기능에 대한 지원을 거부할 경우 제공자는 기능이
점진적으로 떨어진다. 기본 클라우드에서 Neutron이 게시한 확장 목록을 기반으로
특정 기능을 활성화하거나 비활성화할 수도 있다.
### cloud.conf
쿠버네티스는 cloud.conf 파일을 통해 OpenStack과 상호 작용하는 방법을 알고 있다. 쿠버네티스에
OpenStack 인증 엔드포인트의 자격 증명과 위치를 제공하는 파일이다.
다음의 세부 정보를 지정하여 cloud.conf 파일을 만들 수 있다.
#### 일반적인 구성
이것은 가장 자주 설정해야 하는 값에 대한 일반적인 구성의
예시이다. OpenStack 클라우드의 Keystone
엔드포인트에서, 제공자를 가리키고 이를 인증하는 방법에 대한 세부 사항을 제공하고,
로드 밸런서를 구성한다.
```yaml
[Global]
username=user
password=pass
auth-url=https://<keystone_ip>/identity/v3
tenant-id=c869168a828847f39f7f06edd7305637
domain-id=2a73b8f597c04551a0fdc8e95544be8a
[LoadBalancer]
subnet-id=6937f8fa-858d-4bc9-a3a5-18d2c957166a
```
##### 글로벌
OpenStack 제공자에 대한 다음의 구성 옵션은 글로벌
구성과 관련이 있으며 `cloud.conf` 파일의 `[Global]` 섹션에 있어야
한다.
* `auth-url` (필수): 인증에 사용되는 Keystone API의 URL이다.
OpenStack 제어판의 액세스 및 보안 > API 액세스 >
자격 증명에서 찾을 수 있다.
* `username` (필수): Keystone에 설정된 유효한 사용자의 username을 나타낸다.
* `password` (필수): Keystone에 설정된 유효한 사용자의 password를 나타낸다.
* `tenant-id` (필수): 리소스를 생성하려는 프로젝트의 id를 지정하는 데
사용된다.
* `tenant-name` (선택): 리소스를 생성하려는 프로젝트의 이름을
지정하는 데 사용된다.
* `trust-id` (선택): 권한 부여에 사용할 트러스트(trust)의 식별자를 지정하는 데
사용된다. 트러스트는 한 사용자(트러스터(trustor))의 권한을 다른 사용자(트러스티(trustee))에게 역할을
위임하고, 선택적으로 트러스티가 트러스터를 가장하도록
허용한다. 사용 가능한 트러스트는
Keystone API의 `/v3/OS-TRUST/trusts` 엔드포인트 아래에 있다.
* `domain-id` (선택): 사용자가 속한 도메인의 id를 지정하는 데
사용된다.
* `domain-name` (선택): 사용자가 속한 도메인의 이름을 지정하는 데
사용된다.
* `region` (선택): 멀티-리전(multi-region) OpenStack 클라우드에서
실행할 때 사용할 리전의 식별자를 지정하는 데 사용된다. 리전은 OpenStack 디플로이먼트의
일반 디비전(division)이다. 리전에 엄격한 지리적 의미는 없지만,
디플로이먼트 시 `us-east` 와 같은
리전의 식별자에 지리적 이름을 사용할 수 있다. 사용 가능한 지역은
Keystone API의 `/v3/regions` 엔드포인트 아래에 있다.
* `ca-file` (선택): 사용자 지정 CA 파일의 경로를 지정하는 데 사용된다.
테넌트를 프로젝트로 변경하는 Keystone V3을 사용하면 `tenant-id` 값이
API의 프로젝트 구성에 자동으로 매핑된다.
##### 로드 밸런서
OpenStack 제공자에 대한 다음의 구성 옵션은 로드 밸런서와 관련이 있으며
`cloud.conf` 파일의 `[LoadBalancer]` 섹션에 있어야
한다.
* `lb-version` (선택): 자동 버전 감지를 대체하는 데 사용된다. 유효한
값은 `v1` 또는 `v2` 이다. 값이 제공되지 않는 경우 자동 감지는
기본 OpenStack 클라우드에 의해 제공되는 가장 최신의 지원되는 버전을
선택한다.
* `use-octavia` (선택): Octavia LBaaS V2 서비스 카탈로그 엔드포인트를 찾고 사용할지의
여부를 결정하는 데 사용된다. 유효한 값은 `true` 또는 `false` 이다.
`true` 가 지정되고 Octaiva LBaaS V2 항목을 찾을 수 없는 경우,
제공자는 폴백(fall back)하고 대신 Neutron LBaaS V2 엔드포인트를 찾으려고
시도한다. 기본값은 `false` 이다.
* `subnet-id` (선택): 로드 밸런서를 생성하려는 서브넷의 id를
지정하는 데 사용된다. Network > Networks 에서 찾을 수 있다. 해당
네트워크를 클릭하여 서브넷을 가져온다.
* `floating-network-id` (선택): 지정된 경우, 로드 밸런서에 대한 유동 IP를
생성한다.
* `lb-method` (선택): 로드 밸런서 풀(pool)의 멤버 간에 부하가
분산되는 알고리즘을 지정하는 데 사용된다. 값은
`ROUND_ROBIN`, `LEAST_CONNECTIONS` 또는 `SOURCE_IP` 가 될 수 있다. 지정되지
않은 경우 기본 동작은 `ROUND_ROBIN` 이다.
* `lb-provider` (선택): 로드 밸런서의 제공자를 지정하는 데 사용된다.
지정하지 않으면, neutron에 구성된 기본 제공자 서비스가
사용된다.
* `create-monitor` (선택): Neutron 로드 밸런서에 대한 헬스 모니터를
생성할지의 여부를 나타낸다. 유효한 값은 `true``false` 이다.
기본값은 `false` 이다. `true` 가 지정되면 `monitor-delay`,
`monitor-timeout``monitor-max-retries` 도 설정해야 한다.
* `monitor-delay` (선택): 로드 밸런서의 멤버에게 프로브(probe)를
보내는 간격의 시간이다. 유효한 시간 단위를 지정해야 한다. 유효한 시간 단위는 "ns", "us"(또는 "µs"), "ms", "s", "m", "h"이다.
* `monitor-timeout` (선택): 모니터가 타임아웃 되기 전에 핑(ping) 응답을
기다리는 최대 시간이다. 값은 지연 값보다 작아야
한다. 유효한 시간 단위를 지정해야 한다. 유효한 시간 단위는 "ns", "us"(또는 "µs"), "ms", "s", "m", "h"이다.
* `monitor-max-retries` (선택): 로드 밸런서 멤버의 상태를 INACTIVE로
변경하기 전에 허용되는 핑 오류 수이다. 1에서 10 사이의
숫자여야 한다.
* `manage-security-groups` (선택): 로드 밸런서가 보안 그룹 규칙을
자동으로 관리해야 하는지의 여부를 결정한다. 유효한 값은
`true``false` 이다. 기본값은 `false` 이다. `true` 가 지정되면
`node-security-group` 도 제공해야 한다.
* `node-security-group` (선택): 관리할 보안 그룹의 ID이다.
##### 블록 스토리지
OpenStack 제공자에 대한 다음의 구성 옵션은 블록 스토리지와 관련이 있으며
`cloud.conf` 파일의 `[BlockStorage]` 섹션에 있어야 한다.
* `bs-version` (선택): 자동 버전 감지를 대체하는 데 사용된다. 유효한
값은 `v1`, `v2`, `v3``auto` 이다. `auto` 가 지정되면 자동
감지는 기본 OpenStack 클라우드에 의해 노출되는 가장 최신의 지원되는
버전을 선택한다. 제공되지 않은 경우 기본값은 `auto` 이다.
* `trust-device-path` (선택): 대부분의 시나리오에서 Cinder가 제공한
블록 장치 이름(예: `/dev/vda`)을 신뢰할 수 없다. 이 부울은
이 동작을 토글(toggle)한다. 이를 `true` 로 설정하면 Cinder에서 제공한
블록 장치 이름을 신뢰하게 된다. 기본값인 `false` 는 일련 번호와
`/dev/disk/by-id` 를 매핑하여 장치 경로를 검색하게 하며
권장하는 방법이다.
* `ignore-volume-az` (선택): Cinder 볼륨을 연결할 때 가용 영역(availability zone)
사용에 영향을 주기 위해 사용된다. Nova와 Cinder의 가용성
영역이 서로 다른 경우, 이 값을 `true` 로 설정해야 한다. 이는 가장 일반적인 상황으로 Nova 가용 영역은
많지만 Cinder는 하나의 가용 영역만 있는 경우이다.
이전 릴리스에서 사용된 동작을 유지하기 위해 기본값은 `false`
이지만, 나중에 변경될 수 있다.
* `node-volume-attach-limit` (선택): 노드에 연결할 수 있는
최대 볼륨 수이다. 기본값은 cinder의 경우 256이다.
포트가 아닌 경로를 사용하여 엔드포인트를 구별하는 OpenStack
디플로이먼트에서 1.8 이하의 쿠버네티스 버전을 배포하는 경우
명시적으로 `bs-version` 파라미터를 설정해야 한다. 경로 기반의 엔드포인트는
`http://foo.bar/volume` 형식이며 포트 기반의 엔드포인트는
`http://foo.bar:xxx` 형식이다.
경로 기반의 엔드포인트를 사용하고 쿠버네티스가 이전 자동 감지 로직을 사용하는 환경에서는
볼륨 분리 시도 시 `BS API version autodetection failed.` 오류가
리턴된다. 이 문제를 해결하려면 클라우드 제공자 구성에
다음을 추가하여 Cinder API 버전 2를 강제로
사용할 수 있다.
```yaml
[BlockStorage]
bs-version=v2
```
##### 메타데이터
OpenStack 제공자에 대한 다음의 구성 옵션은 메타데이터와 관련이 있으며
`cloud.conf` 파일의 `[Metadata]` 섹션에 있어야 한다.
* `search-order` (선택): 이 구성 키는 실행되는 인스턴스와
관련된 메타데이터를 제공자가 검색하는 방식에 영향을 준다. 기본값인
`configDrive,metadataService` 를 사용할 수 있는 경우에 제공자가
먼저 구성 드라이브에서 인스턴스와 관련된 메타데이터를
검색한 다음 메타데이터 서비스를 검색하게 한다. 대체할 수 있는 값은 다음과 같다.
* `configDrive` - 구성 드라이브에서 인스턴스 메타데이터만
검색한다.
* `metadataService` - 메타데이터 서비스에서 인스턴스 메타데이터만
검색한다.
* `metadataService,configDrive` - 사용할 수 있는 경우 먼저 메타데이터
서비스에서 인스턴스 메타데이터를 검색한 다음, 구성 드라이브를 검색한다.
구성 드라이브의 메타데이터는 시간이 지남에 따라
오래될 수 있지만, 메타데이터 서비스는 항상 최신 뷰를 제공하므로
이러한 설정은 바람직하다. 모든 OpenStack 클라우드가
구성 드라이브와 메타데이터 서비스를 모두 제공하는 것은 아니며 하나 또는 다른 하나만
사용할 수 있으므로 기본값은 둘 다를 확인하는 것이다.
##### 라우트
OpenStack 제공자에 대한 다음의 구성 옵션은 [kubenet]
쿠버네티스 네트워크 플러그인과 관련이 있으며 `cloud.conf` 파일의 `[Route]` 섹션에
있어야 한다.
* `router-id` (선택): 기본 클라우드의 Neutron 디플로이먼트가
`extraroutes` 확장을 지원하는 경우 경로를 추가할 라우터를 지정하는 데 `router-id`
를 사용한다. 선택한 라우터는 클러스터 노드를 포함하는 프라이빗 네트워크에
걸쳐 있어야 한다(일반적으로 하나의 노드 네트워크만 있으며, 이 값은
노드 네트워크의 기본 라우터여야 한다). 이 값은 OpenStack에서 [kubenet]을 사용하는 데
필요하다.
[kubenet]: /ko/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/#kubenet
{{% /capture %}}
## OVirt
### 노드 이름
OVirt 클라우드 제공자는 쿠버네티스 노드 오브젝트의 이름으로 노드의 (kubelet에 의해 결정되거나 `--hostname-override` 로 재정의된) 호스트 이름을 사용한다.
참고로 쿠버네티스 노드 이름은 VM FQDN(Ovirt의 `<vm><guest_info><fqdn>...</fqdn></guest_info></vm>` 아래에서 보고된)과 일치해야 한다.
## Photon
### 노드 이름
Photon 클라우드 제공자는 쿠버네티스 노드 오브젝트의 이름으로 노드의 (kubelet에 의해 결정되거나 `--hostname-override` 로 재정의된) 호스트 이름을 사용한다.
참고로 쿠버네티스 노드 이름은 Photon VM 이름(또는 `--cloud-config` 에서 `overrideIP` 가 true로 설정된 경우, 쿠버네티스 노드 이름은 Photon VM IP 주소와 일치해야 함)과 일치해야 한다.
## vSphere
{{< tabs name="vSphere cloud provider" >}}
{{% tab name="vSphere 6.7U3 이상" %}}
vSphere 6.7U3 이상의 모든 vSphere 디플로이먼트의 경우, [vSphere CSI 드라이버](https://github.com/kubernetes-sigs/vsphere-csi-driver)와 함께 [외부 vSphere 클라우드 제공자](https://github.com/kubernetes/cloud-provider-vsphere)를 권장한다. 퀵스타트 가이드는 [CSI와 CPI를 사용하여 vSphere에 쿠버네티스 클러스터 배포하기](https://cloud-provider-vsphere.sigs.k8s.io/tutorials/kubernetes-on-vsphere-with-kubeadm.html)를 참고한다.
{{% /tab %}}
{{% tab name="vSphere 6.7U3 미만" %}}
vSphere 6.7U3 미만을 사용할 경우, 인-트리 vSphere 클라우드 제공자를 권장한다. 퀵스타트 가이드는 [kubeadm을 사용하여 vSphere에 쿠버네티스 클러스터 실행하기](https://cloud-provider-vsphere.sigs.k8s.io/tutorials/k8s-vcp-on-vsphere-with-kubeadm.html)를 참고한다.
{{% /tab %}}
{{< /tabs >}}
vSphere 클라우드 제공자에 대한 자세한 문서를 보려면, [vSphere 클라우드 제공자 문서 사이트](https://cloud-provider-vsphere.sigs.k8s.io)를 방문한다.
## IBM 클라우드 쿠버네티스 서비스
### 컴퓨트 노드
IBM 클라우드 쿠버네티스 서비스 제공자를 사용하면, 단일 영역 또는 하나의 리전에서 여러 영역에 걸쳐 가상 노드와 물리(베어 메탈) 노드가 혼합된 클러스터를 생성할 수 있다. 자세한 정보는, [클러스터와 워커(worker) 노드 설정 계획](https://cloud.ibm.com/docs/containers?topic=containers-planning_worker_nodes)을 참고한다.
쿠버네티스 노드 오브젝트의 이름은 IBM 클라우드 쿠버네티스 서비스 워커 노드 인스턴스의 프라이빗 IP 주소이다.
### 네트워킹
IBM 클라우드 쿠버네티스 서비스 제공자는 노드의 네트워크 성능 품질과 네트워크 격리를 위한 VLAN을 제공한다. 사용자 정의 방화벽 및 Calico 네트워크 폴리시를 설정하여 클러스터에 추가적인 보안 계층을 추가하거나 VPN을 통해 온-프레미스 데이터센터에 클러스터를 연결할 수 있다. 자세한 내용은 [인-클러스터(in-cluster) 및 프라이빗 네트워킹 계획](https://cloud.ibm.com/docs/containers?topic=containers-cs_network_cluster#cs_network_cluster)을 참고한다.
퍼블릭 또는 클러스터 내에서 앱을 노출하기 위해 노드포트(NodePort), 로드밸런서 또는 인그레스 서비스를 활용할 수 있다. 어노테이션을 사용하여 인그레스 애플리케이션 로드 밸런서를 커스터마이징 할 수도 있다. 자세한 내용은 [외부 네트워킹으로 앱 노출 계획](https://cloud.ibm.com/docs/containers?topic=containers-cs_network_planning#cs_network_planning)을 참고한다.
### 스토리지
IBM 클라우드 쿠버네티스 서비스 제공자는 쿠버네티스-네이티브 퍼시스턴트 볼륨을 활용하여 사용자가 파일, 블록 및 클라우드 오브젝트 스토리지를 앱에 마운트할 수 있도록 한다. 데이터를 지속적으로 저장하기 위해 서비스로서의-데이터베이스(database-as-a-service)와 써드파티 애드온을 사용할 수도 있다. 자세한 정보는 [고가용성 퍼시스턴트 스토리지 계획](https://cloud.ibm.com/docs/containers?topic=containers-storage_planning#storage_planning)을 참고한다.
## Baidu 클라우드 컨테이너 엔진
### 노드 이름
Baidu 클라우드 제공자는 쿠버네티스 노드 오브젝트의 이름으로 노드의 (kubelet에 의해 결정되거나 `--hostname-override` 로 재정의된) 프라이빗 IP 주소를 사용한다.
참고로 쿠버네티스 노드 이름은 Baidu VM 프라이빗 IP와 일치해야 한다.
## Tencent 쿠버네티스 엔진
이 외부 클라우드 제공자를 사용하려는 경우, 해당 리포지터리는 [TencentCloud/tencentcloud-cloud-controller-manager](https://github.com/TencentCloud/tencentcloud-cloud-controller-manager)이다.
### 노드 이름
Tencent 클라우드 제공자는 쿠버네티스 노드 오브젝트의 이름으로 노드의 (kubelet에 의해 결정되거나 `--hostname-override` 로 재정의된) 호스트 이름을 사용한다.
참고로 쿠버네티스 노드 이름은 Tencent VM 프라이빗 IP와 일치해야 한다.

View File

@ -0,0 +1,317 @@
---
title: 클러스터 네트워킹
content_template: templates/concept
weight: 50
---
{{% capture overview %}}
네트워킹은 쿠버네티스의 중심적인 부분이지만, 어떻게 작동하는지 정확하게
이해하기가 어려울 수 있다. 쿠버네티스에는 4가지 대응해야 할 네트워킹
문제가 있다.
1. 고도로 결합된 컨테이너 간의 통신: 이 문제는
[파드](/ko/docs/concepts/workloads/pods/pod/)와 `localhost` 통신으로 해결된다.
2. 파드 간 통신: 이 문제가 이 문서의 주요 초점이다.
3. 파드와 서비스 간 통신: 이 문제는 [서비스](/ko/docs/concepts/services-networking/service/)에서 다룬다.
4. 외부와 서비스 간 통신: 이 문제는 [서비스](/ko/docs/concepts/services-networking/service/)에서 다룬다.
{{% /capture %}}
{{% capture body %}}
쿠버네티스는 애플리케이션 간에 머신을 공유하는 것이다. 일반적으로,
머신을 공유하려면 두 애플리케이션이 동일한 포트를 사용하지 않도록
해야 한다. 여러 개발자 간에 포트를 조정하는 것은 대규모로 실시하기가 매우 어렵고,
사용자가 통제할 수 없는 클러스터 수준의 문제에 노출된다.
동적 포트 할당은 시스템에 많은 복잡성을 야기한다. 모든
애플리케이션은 포트를 플래그로 가져와야 하며, API 서버는 동적 포트 번호를
구성 블록에 삽입하는 방법을 알아야 하고, 서비스는 서로를
찾는 방법 등을 알아야 한다. 쿠버네티스는 이런 것들을 다루는 대신
다른 접근법을 취한다.
## 쿠버네티스 네트워크 모델
모든 `Pod` 에는 고유의 IP 주소가 있다. 즉, `Pod` 간에 링크를 명시적으로
생성할 필요가 없으며 컨테이너 포트를 호스트 포트에 매핑할
필요가 거의 없다. 이렇게 하면 포트 할당, 이름 지정, 서비스 검색, 로드 밸런싱,
애플리케이션 구성 및 마이그레이션 관점에서 `Pod` 를 VM 또는
물리적 호스트처럼 취급할 수 있는 깔끔하고, 하위 호환성
있는 모델이 생성된다.
쿠버네티스는 모든 네트워크 구현에 다음과 같은
기본 요구 사항을 적용한다(의도적 네트워크 세분화 정책 제외).
* 노드의 파드는 NAT 없이 모든 노드의 모든 파드와 통신할 수 있다.
* 노드의 에이전트(예: 시스템 데몬, kubelet)는 해당 노드의 모든
파드와 통신할 수 있다.
참고: 호스트 네트워크에서 실행되는 `Pod` 를 지원하는 리눅스와 같은 플랫폼의 경우, 다음의 요구 사항을
적용한다.
* 노드의 호스트 네트워크에 있는 파드는 NAT 없이 모든 노드에 있는 모든
파드와 통신할 수 있다.
이 모델은 전체적으로 덜 복잡할 뿐만 아니라, 쿠버네티스를 위해 VM에서
컨테이너로 애플리케이션을 포팅할 때 충돌이 적게 구현하려는 요구와
주로 호환된다. 잡이 이전에 VM에서 실행된 경우, VM에 IP가 있고
프로젝트의 다른 VM과 통신할 수 있다. 이것은 동일한 기본 모델이다.
쿠버네티스의 IP 주소는 그것의 IP 주소를 포함하여 `Pod` 범위에 존재한다(`Pod` 내
컨테이너는 네트워크 네임스페이스를 공유함). 이것은 `Pod` 내 컨테이너가 모두
`localhost` 에서 서로의 포트에 도달할 수 있다는 것을 의미한다. 또한
`Pod` 내부의 컨테이너 포트의 사용을 조정해야하는 것을 의미하지만, 이것도
VM 내의 프로세스와 동일하다. 이것을 "IP-per-pod(파드별 IP)" 모델이라고 한다.
이것이 어떻게 구현되는 지는 사용 중인 특정 컨테이너 런타임의 세부 사항이다.
`Pod` 로 전달하는 `Node` 자체의 포트(호스트 포트라고 함)를
요청할 수 있지만, 이는 매우 틈새 작업이다. 전달이 구현되는 방법은
컨테이너 런타임의 세부 사항이기도 하다. `Pod` 자체는
호스트 포트의 존재 여부에 대해 인식하지 못한다.
## 쿠버네티스 네트워크 모델의 구현 방법
이 네트워크 모델을 구현할 수 있는 방법에는 여러 가지가 있다. 이
문서는 다양한 방법에 대한 철저한 연구는 아니지만, 다양한 기술에 대한
소개로 활용되며 도약하는 포인트로 사용되기를 바란다.
이 목록은 알파벳 순으로 정렬되어 있으며, 정렬된 순서가
우선 상태를 의미하는 것은 아니다.
### ACI
[Cisco 애플리케이션 센트릭 인프라스트럭처(Application Centric Infrastructure)](https://www.cisco.com/c/en/us/solutions/data-center-virtualization/application-centric-infrastructure/index.html)는 컨테이너, 가상 머신 및 베어메탈 서버를 지원하는 통합 오버레이 및 언더레이 SDN 솔루션을 제공한다. [ACI](https://www.github.com/noironetworks/aci-containers)는 ACI를 위한 컨테이너 네트워킹 통합을 제공한다. 통합의 개요는 [여기](https://www.cisco.com/c/dam/en/us/solutions/collateral/data-center-virtualization/application-centric-infrastructure/solution-overview-c22-739493.pdf)에서 제공된다.
### Antrea
프로젝트 [Antrea](https://github.com/vmware-tanzu/antrea)는 쿠버네티스 고유의 오픈소스 쿠버네티스 네트워킹 솔루션이다. 네트워킹 데이터 플레인으로 Open vSwitch를 활용한다. Open vSwitch는 리눅스와 윈도우를 모두 지원하는 고성능의 프로그래밍이 가능한 가상 스위치이다. Antrea는 Open vSwitch를 통해 쿠버네티스 네트워크 정책을 고성능의 효율적인 방식으로 구현할 수 있다.
Antrea는 Open vSwitch의 "프로그래밍이 가능한" 특성으로 인해 Open vSwitch 위에 광범위한 네트워킹 및 보안 기능과 서비스를 구현할 수 있다.
### Apstra의 AOS
[AOS](http://www.apstra.com/products/aos/)는 단순한 통합 플랫폼에서 복잡한 데이터센터 환경을 만들고 관리하는 의도기반(Intent-Based) 네트워킹 시스템이다. AOS는 확장성이 뛰어난 분산 설계를 활용하여 네트워크 중단을 제거하면서 비용을 최소화한다.
AOS 레퍼런스 디자인은 현재 레거시 Layer-2 스위칭 문제를 제거하는 Layer-3 연결 호스트를 지원한다. 이 Layer-3 호스트는 리눅스 서버(Debian, Ubuntu, CentOS)일 수 있으며 랙 상단 스위치(TOR)와 직접 BGP 인접 관계를 만든다. AOS는 라우팅 인접성을 자동화한 다음 쿠버네티스 디플로이먼트에서 일반적으로 사용되는 RHI(Route Health Injection)에 대한 세밀한 제어를 제공한다.
AOS는 쿠버네티스가 애플리케이션 요구 사항에 따라 네트워크 정책을 신속하게 변경할 수 있는 풍부한 REST API 엔드포인트 셋을 제공한다. 네트워크 설계에 사용된 AOS 그래프 모델을 워크로드 프로비저닝과 통합하여 프라이빗 클라우드와 퍼블릭 클라우드 모두에 대한 엔드-투-엔드 관리 시스템을 향상시킬 수 있다.
AOS는 Cisco, Arista, Dell, Mellanox, HPE 그리고 Microsoft SONiC, Dell OPX 및 Cumulus Linux와 같은 개방형 네트워크 운영체제와 수많은 화이트-박스 시스템을 포함한 제조업체의 일반적인 벤더 장비 사용을 지원한다.
AOS 시스템 작동 방식에 대한 자세한 내용은 다음을 참고한다. http://www.apstra.com/products/how-it-works/
### 쿠버네티스용 AWS VPC CNI
[AWS VPC CNI](https://github.com/aws/amazon-vpc-cni-k8s)는 쿠버네티스 클러스터를 위한 통합된 AWS 버추얼 프라이빗 클라우드(Virtual Private Cloud, VPC) 네트워킹을 제공한다. 이 CNI 플러그인은 높은 처리량과 가용성, 낮은 레이턴시(latency) 그리고 최소 네트워크 지터(jitter)를 제공한다. 또한, 사용자는 쿠버네티스 클러스터를 구축하기 위한 기존의 AWS VPC 네트워킹 및 보안 모범 사례를 적용할 수 있다. 여기에는 VPC 플로우 로그, VPC 라우팅 정책과 네트워크 트래픽 격리를 위한 보안 그룹을 사용하는 기능이 포함되어 있다.
이 CNI 플러그인을 사용하면 쿠버네티스 파드는 VPC 네트워크와 동일한 IP 주소를 파드 내부에 가질 수 있다. CNI는 각 쿠버네티스 노드에 AWS 엘라스틱 네트워킹 인터페이스(Elastic Networking Interfaces, ENI)를 할당하고 노드의 파드에 대해 각 ENI의 보조 IP 범위를 사용한다. CNI에는 파드를 빠르게 시작하기 위해 ENI와 IP 주소의 사전 할당 제어 기능이 포함되어 있으며 최대 2,000개의 노드로 구성된 대규모 클러스터가 가능하다.
또한, CNI는 [네트워크 폴리시 적용을 위해 캘리코(Calico)](https://docs.aws.amazon.com/eks/latest/userguide/calico.html)와 함께 실행할 수 있다. AWS VPC CNI 프로젝트는 [GitHub의 문서](https://github.com/aws/amazon-vpc-cni-k8s)와 함께 오픈소스로 공개되어 있다.
### 쿠버네티스용 Azure CNI
[Azure CNI](https://docs.microsoft.com/en-us/azure/virtual-network/container-networking-overview)는 VM과 동등한 네트워크 성능을 제공하는 Azure 버추얼 네트워크(VNet이라고도 알려진)와 쿠버네티스 파드를 통합하는 [오픈소스](https://github.com/Azure/azure-container-networking/blob/master/docs/cni.md) 플러그인이다. 파드는 피어링된 VNet과 Express Route 또는 사이트 간 VPN을 통해 온-프레미스에 연결할 수 있으며 이러한 네트워크에서 직접 연결할 수도 있다. 파드는 서비스 엔드포인트 또는 프라이빗 링크로 보호되는 스토리지와 SQL과 같은 Azure 서비스에 접근할 수 있다. VNet 보안 정책과 라우팅을 사용하여 파드 트래픽을 필터링할 수 있다. 플러그인은 쿠버네티스 노드의 네트워크 인터페이스에 사전 구성된 보조 IP 풀을 활용하여 VNet IP를 파드에 할당한다.
Azure CNI는 [Azure 쿠버네티스 서비스(Azure Kubernetes Service, AKS)](https://docs.microsoft.com/en-us/azure/aks/configure-azure-cni)에서 기본적으로 사용할 수 있다.
### Big Switch Networks의 빅 클라우드 패브릭(Big Cloud Fabric)
[빅 클라우드 패브릭](https://www.bigswitch.com/container-network-automation)은 클라우드 네이티브 네트워킹 아키텍처로, 프라이빗 클라우드/온-프레미스 환경에서 쿠버네티스를 실행하도록 디자인되었다. 통합된 물리 및 가상 SDN을 사용하여, 빅 클라우드 패브릭은 로드 밸런싱, 가시성, 문제 해결, 보안 정책 및 컨테이너 트래픽 모니터링과 같은 내재한 컨테이너 네트워킹 문제를 해결한다.
빅 클라우드 패브릭의 가상 파드 멀티 테넌트 아키텍처를 통해 쿠버네티스, RedHat OpenShift, Mesosphere DC/OS 및 Docker Swarm과 같은 컨테이너 오케스트레이션 시스템은 VMware, OpenStack 및 Nutanix와 같은 VM 오케스트레이션 시스템과 함께 네이티브로 통합된다. 고객은 원하는 수의 클러스터를 안전하게 상호 연결할 수 있으며 필요한 경우 이들 사이의 테넌트 간 통신을 활성화할 수 있다.
가트너는 최신의 [매직 쿼드런트(Magic Quadrant)](http://go.bigswitch.com/17GatedDocuments-MagicQuadrantforDataCenterNetworking_Reg.html)에서 BCF를 비저너리(Visionary)로 인정했다. BCF 쿠버네티스 온-프레미스 디플로이먼트 중 하나(지리적으로 다른 리전에 걸쳐 여러 DC에서 실행되는 쿠버네티스, DC/OS 및 VMware 포함)도 [여기](https://portworx.com/architects-corner-kubernetes-satya-komala-nio/)에서 사례로 참조된다.
### 실리움(Cilium)
[실리움](https://github.com/cilium/cilium)은 애플리케이션 컨테이너 간에
네트워크 연결을 제공하고 투명하게 보호하기 위한 오픈소스 소프트웨어이다.
실리움은 L7/HTTP를 인식하며 네트워크 주소 지정에서 분리된 ID 기반 보안 모델을 사용하여 L3-L7에서
네트워크 정책을 적용할 수 있으며,
다른 CNI 플러그인과 함께 사용할 수 있다.
### 화웨이의 CNI-Genie
[CNI-Genie](https://github.com/Huawei-PaaS/CNI-Genie)는 쿠버네티스가 런타임 시 [쿠버네티스 네트워크 모델](https://github.com/kubernetes/website/blob/master/content/en/docs/concepts/cluster-administration/networking.md#the-kubernetes-network-model)의 [서로 다른 구현에 동시에 접근](https://github.com/Huawei-PaaS/CNI-Genie/blob/master/docs/multiple-cni-plugins/README.md#what-cni-genie-feature-1-multiple-cni-plugins-enables)할 수 있는 CNI 플러그인이다. 여기에는 [플라넬(Flannel)](https://github.com/coreos/flannel#flannel), [캘리코](http://docs.projectcalico.org/), [로마나(Romana)](http://romana.io), [위브넷(Weave-net)](https://www.weave.works/products/weave-net/)과 같은 [CNI 플러그인](https://github.com/containernetworking/cni#3rd-party-plugins)으로 실행되는 모든 구현이 포함된다.
CNI-Genie는 각각 다른 CNI 플러그인에서 [하나의 파드에 여러 IP 주소를 할당](https://github.com/Huawei-PaaS/CNI-Genie/blob/master/docs/multiple-ips/README.md#feature-2-extension-cni-genie-multiple-ip-addresses-per-pod)하는 것도 지원한다.
### cni-ipvlan-vpc-k8s
[cni-ipvlan-vpc-k8s](https://github.com/lyft/cni-ipvlan-vpc-k8s)는
L2 모드에서 리눅스 커널의 IPvlan 드라이버를 사용하여 Amazon 엘라스틱 네트워크 인터페이스(ENI)를
사용하고 AWS 매니지드 IP를 파드에 바인딩하는
Amazon 버추얼 프라이빗 클라우드(VPC) 환경 내에서 쿠버네티스를 위한
간단하고, 호스트 로컬, 낮은 레이턴시, 높은 처리량 및 호환 네트워킹 스택을 제공하는
CNI와 IPAM 플러그인 셋을 포함한다.
플러그인은 VPC 내에서 구성하고 배포할 수 있도록 간단하게 설계되었다.
Kubelets는 오버레이 네트워크 관리, BGP 관리, 소스/대상 확인 비활성화 또는
VPC 라우팅 테이블을 조정하여 각 호스트에 인스턴스별 서브넷을
제공(VPC별 50-100개 항목으로 제한)하는 등의 자주 권장되는 복잡성을 요구하지 않고
부팅한 다음 필요에 따라 IP 사용량을 자체 구성하고 확장할
수 있다. 즉, cni-ipvlan-vpc-k8s는 AWS 내에서 쿠버네티스를
대규모로 배포하는 데 필요한 네트워크 복잡성을 크게 줄인다.
### 콘티브(Contiv)
[콘티브](https://github.com/contiv/netplugin)는 다양한 적용 사례에서 구성 가능한 네트워킹(BGP를 사용하는 네이티브 L3, vxlan을 사용하는 오버레이, 클래식 L2 또는 Cisco-SDN/ACI)을 제공한다. [콘티브](http://contiv.io)는 모두 오픈소스이다.
### 콘트레일(Contrail) / 텅스텐 패브릭(Tungsten Fabric)
[텅스텐 패브릭](https://tungsten.io)을 기반으로 하는 [콘트레일](http://www.juniper.net/us/en/products-services/sdn/contrail/contrail-networking/)은 진정한 개방형 멀티 클라우드 네트워크 가상화 및 정책 관리 플랫폼이다. 콘트레일 및 텅스텐 패브릭은 쿠버네티스, OpenShift, OpenStack 및 Mesos와 같은 다양한 오케스트레이션 시스템과 통합되어 있으며, 가상 머신, 컨테이너/파드 및 베어메탈 워크로드에 대해 서로 다른 격리 모드를 제공한다.
### DANM
[DANM](https://github.com/nokia/danm)은 쿠버네티스 클러스터에서 실행되는 통신사 워크로드를 위한 네트워킹 솔루션이다. 다음의 컴포넌트로 구성된다.
* 고급 기능들로 IPVLAN 인터페이스를 프로비저닝할 수 있는 CNI 플러그인
* 여러 클러스터 전체의 불연속 L3 네트워크를 관리하고 요청 시 동적, 정적 또는 IP를 할당하지 않는 방식을 제공하는 내장 IPAM 모듈
* 자체 CNI를 통해서, 또는 SRI-OV나 플라넬과 같은 널리 사용되는 CNI 솔루션에 잡을 동시에 위임하여 여러 네트워크 인터페이스를 컨테이너에 연결할 수 있는 CNI 메타플러그인
* 모든 쿠버네티스 호스트의 VxLAN 및 VLAN 인터페이스를 중앙에서 관리할 수 있는 쿠버네티스 컨트롤러
* 쿠버네티스의 서비스 기반의 서비스 검색 개념을 확장하여 파드의 모든 네트워크 인터페이스에서 작동하는 다른 쿠버네티스 컨트롤러
이 도구 셋을 통해 DANM은 여러 개의 분리된 네트워크 인터페이스를 제공할 수 있으며, 파드에 다른 네트워킹 백엔드 및 고급 IPAM 기능을 사용할 수 있다.
### 플라넬
[플라넬](https://github.com/coreos/flannel#flannel)은 쿠버네티스 요구 사항을
충족하는 매우 간단한 오버레이 네트워크이다. 많은
경우에 쿠버네티스와 플라넬은 성공적으로 적용이 가능하다.
### Google 컴퓨트 엔진(GCE)
Google 컴퓨트 엔진 클러스터 구성 스크립트의 경우, [고급
라우팅](https://cloud.google.com/vpc/docs/routes)을 사용하여
각 VM에 서브넷을 할당한다(기본값은 `/24` - 254개 IP). 해당 서브넷에 바인딩된
모든 트래픽은 GCE 네트워크 패브릭에 의해 VM으로 직접 라우팅된다. 이는
아웃 바운드 인터넷 접근을 위해 NAT로 구성된 VM에 할당된 "기본"
IP 주소에 추가된다. 리눅스 브릿지(`cbr0`)는 해당 서브넷에 존재하도록
구성되며, 도커의 `--bridge` 플래그로 전달된다.
도커는 다음의 설정으로 시작한다.
```shell
DOCKER_OPTS="--bridge=cbr0 --iptables=false --ip-masq=false"
```
이 브릿지는 노드의 `.spec.podCIDR`에 따라 Kubelet(`--network-plugin=kubenet`
플래그로 제어되는)에 의해 생성된다.
도커는 이제 `cbr-cidr` 블록에서 IP를 할당한다. 컨테이너는 `cbr0` 브릿지를
통해 서로 `Node` 에 도달할 수 있다. 이러한 IP는 모두 GCE 프로젝트 네트워크
내에서 라우팅할 수 있다.
그러나, GCE 자체는 이러한 IP에 대해 전혀 알지 못하므로, 아웃 바운드 인터넷 트래픽을 위해
IP를 NAT하지 않는다. 그것을 달성하기 위해 iptables 규칙을 사용하여
GCE 프로젝트 네트워크(10.0.0.0/8) 외부의 IP에 바인딩된 트래픽을
마스커레이드(일명 SNAT - 마치 패킷이 `Node` 자체에서 온 것처럼
보이게 함)한다.
```shell
iptables -t nat -A POSTROUTING ! -d 10.0.0.0/8 -o eth0 -j MASQUERADE
```
마지막으로 커널에서 IP 포워딩이 활성화되어 있으므로, 커널은 브릿지된 컨테이너에
대한 패킷을 처리한다.
```shell
sysctl net.ipv4.ip_forward=1
```
이 모든 것의 결과는 모든 `Pod` 가 서로에게 도달할 수 있고 인터넷으로 트래픽을
송신할 수 있다는 것이다.
### 재규어(Jaguar)
[재규어](https://gitlab.com/sdnlab/jaguar)는 OpenDaylight 기반의 쿠버네티스 네트워크를 위한 오픈소스 솔루션이다. 재규어는 vxlan을 사용하여 오버레이 네트워크를 제공하고 재규어 CNI 플러그인은 파드별로 하나의 IP 주소를 제공한다.
### k-vswitch
[k-vswitch](https://github.com/k-vswitch/k-vswitch)는 [Open vSwitch](https://www.openvswitch.org/) 기반의 간단한 쿠버네티스 네트워킹 플러그인이다. Open vSwitch의 기존 기능을 활용하여 운영하기 쉽고, 성능이 뛰어나고 안전한 강력한 네트워킹 플러그인을 제공한다.
### Knitter
[Knitter](https://github.com/ZTE/Knitter/)는 쿠버네티스에서 여러 네트워킹을 지원하는 네트워크 솔루션이다. 테넌트 관리 및 네트워크 관리 기능을 제공한다. Knitter에는 애플리케이션의 IP 주소 유지, IP 주소 마이그레이션 등과 같은 여러 네트워크 플레인 외에 엔드-투-엔드 NFV 컨테이너 네트워킹 솔루션 셋이 포함되어 있다.
### Kube-OVN
[Kube-OVN](https://github.com/alauda/kube-ovn)은 기업을 위한 OVN 기반 쿠버네티스 네트워크 패브릭이다. OVN/OVS의 도움으로, 서브넷, QoS, 고정 IP 할당, 트래픽 미러링, 게이트웨이, 오픈플로우 기반 네트워크 정책 및 서비스 프록시와 같은 고급 오버레이 네트워크 기능을 제공한다.
### Kube-router
[kube-router](https://github.com/cloudnativelabs/kube-router)는 쿠버네티스를 위한 특수 목적의 네트워킹 솔루션으로 고성능 및 운영 단순성을 제공한다. 큐브 라우터는 리눅스 [LVS/IPVS](http://www.linuxvirtualserver.org/software/ipvs.html) 기반 서비스 프록시, 오버레이가 없는 리눅스 커널 포워딩 기반의 파드 간 네트워킹 솔루션 그리고 iptables/ipset 기반 네트워크 정책 집행도구를 제공한다.
### L2 네트워크 및 리눅스 브릿지
"베어메탈" 환경의 간단한 스위치와 같은 "더미(dumb)" L2 네트워크가 있는 경우,
위의 GCE 설정과 비슷한 작업을 수행할 수 있어야 한다.
이 방법은 매우 우연히 시도되었고 작동하는 것으로 보이지만
철저히 테스트되지 않았다. 이 기술을 사용하여
프로세스를 완료한 경우, 알려주길 바란다.
Lars Kellogg-Stedman이 제공하는 [이 훌륭한
튜토리얼](http://blog.oddbit.com/2014/08/11/four-ways-to-connect-a-docker/)의
"With Linux Bridge devices" 섹션을 참고한다.
### Multus(멀티 네트워크 플러그인)
[Multus](https://github.com/Intel-Corp/multus-cni)는 쿠버네티스의 CRD 기반 네트워크 오브젝트를 사용하여 쿠버네티스에서 멀티 네트워킹 기능을 지원하는 멀티 CNI 플러그인이다.
Multus는 CNI 명세를 구현하는 모든 [레퍼런스 플러그인](https://github.com/containernetworking/plugins)(예: [플라넬](https://github.com/containernetworking/plugins/tree/master/plugins/meta/flannel), [DHCP](https://github.com/containernetworking/plugins/tree/master/plugins/ipam/dhcp), [Macvlan](https://github.com/containernetworking/plugins/tree/master/plugins/main/macvlan)) 및 써드파티 플러그인(예: [캘리코](https://github.com/projectcalico/cni-plugin), [위브(Weave)](https://github.com/weaveworks/weave), [실리움](https://github.com/cilium/cilium), [콘티브](https://github.com/contiv/netplugin))을 지원한다. 또한, Multus는 쿠버네티스의 클라우드 네이티브 애플리케이션과 NFV 기반 애플리케이션을 통해 쿠버네티스의 [SRIOV](https://github.com/hustcat/sriov-cni), [DPDK](https://github.com/Intel-Corp/sriov-cni), [OVS-DPDK 및 VPP](https://github.com/intel/vhost-user-net-plugin) 워크로드를 지원한다.
### NSX-T
[VMware NSX-T](https://docs.vmware.com/en/VMware-NSX-T/index.html)는 네트워크 가상화 및 보안 플랫폼이다. NSX-T는 멀티 클라우드 및 멀티 하이퍼바이저 환경에 네트워크 가상화를 제공할 수 있으며 이기종 엔드포인트와 기술 스택이 있는 새로운 애플리케이션 프레임워크 및 아키텍처에 중점을 둔다. vSphere 하이퍼바이저 외에도, 이러한 환경에는 KVM, 컨테이너 및 베어메탈과 같은 다른 하이퍼바이저가 포함된다.
[NSX-T 컨테이너 플러그인(NCP)](https://docs.vmware.com/en/VMware-NSX-T/2.0/nsxt_20_ncp_kubernetes.pdf)은 NSX-T와 쿠버네티스와 같은 컨테이너 오케스트레이터 사이의 통합은 물론, NSX-T와 Pivotal 컨테이너 서비스(PKS) 및 OpenShift와 같은 컨테이너 기반 CaaS/PaaS 플랫폼 간의 통합을 제공한다.
### Nuage Networks VCS(가상 클라우드 서비스)
[Nuage](http://www.nuagenetworks.net)는 확장성이 뛰어난 정책 기반의 소프트웨어 정의 네트워킹(SDN) 플랫폼을 제공한다. Nuage는 개방형 표준을 기반으로 구축된 풍부한 기능의 SDN 컨트롤러와 함께 데이터 플레인용 오픈소스 Open vSwitch를 사용한다.
Nuage 플랫폼은 오버레이를 사용하여 쿠버네티스 파드와 쿠버네티스가 아닌 환경(VM 및 베어메탈 서버) 간에 완벽한 정책 기반의 네트워킹을 제공한다. Nuage의 정책 추상화 모델은 애플리케이션을 염두에 두고 설계되었으며 애플리케이션에 대한 세분화된 정책을 쉽게 선언할 수 있도록 한다. 플랫폼의 실시간 분석 엔진을 통해 쿠버네티스 애플리케이션에 대한 가시성과 보안 모니터링이 가능하다.
### OpenVSwitch
[OpenVSwitch](https://www.openvswitch.org/)는 다소 성숙하지만
오버레이 네트워크를 구축하는 복잡한 방법이다. 이것은 네트워킹 분야의 몇몇
"대형 벤더"에 의해 승인되었다.
### OVN(오픈 버추얼 네트워킹)
OVN은 Open vSwitch 커뮤니티에서 개발한 오픈소스 네트워크
가상화 솔루션이다. 논리적 스위치, 논리적 라우터, 스테이트풀 ACL, 로드 밸런서 등을 생성하여
서로 다른 가상 네트워킹 토폴로지를 구축할 수 있다. 이 프로젝트에는
[ovn-kubernetes](https://github.com/openvswitch/ovn-kubernetes)에
특정 쿠버네티스 플러그인 및 문서가 있다.
### 프로젝트 캘리코
[프로젝트 캘리코](http://docs.projectcalico.org/)는 오픈소스 컨테이너 네트워킹 공급자 및 네트워크 정책 엔진이다.
캘리코는 리눅스(오픈소스)와 윈도우(독점 - [Tigera](https://www.tigera.io/essentials/)에서 사용 가능) 모두에서 인터넷과 동일한 IP 네트워킹 원칙을 기반으로 쿠버네티스 파드를 연결하기 위한 확장성이 뛰어난 네트워킹 및 네트워크 정책 솔루션을 제공한다. 캘리코는 캡슐화나 오버레이 없이 구축되어 고성능의 대규모 데이터센터 네트워킹을 제공할 수 있다. 또한 캘리코는 분산 방화벽을 통해 쿠버네티스 파드에 대해 세분화된 의도기반의 네트워크 보안 정책을 제공한다.
캘리코는 플라넬, 일명 [canal](https://github.com/tigera/canal) 또는 네이티브 GCE, AWS나 Azure 네트워킹과 같은 다른 네트워킹 솔루션과 함께 정책 적용 모드로 실행될 수도 있다.
### 로마나
[로마나](http://romana.io)는 오버레이 네트워크 없이 쿠버네티스를 배포할 수 있는 오픈소스 네트워크 및 보안 자동화 솔루션이다. 로마나는 쿠버네티스 [네트워크 폴리시](/ko/docs/concepts/services-networking/network-policies/)를 지원하여 네트워크 네임스페이스에서 격리를 제공한다.
### Weaveworks의 위브넷
[위브넷](https://www.weave.works/products/weave-net/)은
쿠버네티스 및 호스팅된 애플리케이션을 위한 탄력적이고 사용하기 쉬운 네트워크이다.
위브넷은 [CNI 플러그인](https://www.weave.works/docs/net/latest/cni-plugin/) 또는
독립형으로 실행된다. 두 버전에서, 실행하기 위해 구성이나 추가 코드가 필요하지 않으며,
두 경우 모두, 쿠버네티스의 표준과 같이 네트워크에서 파드별로 하나의 IP 주소를 제공한다.
{{% /capture %}}
{{% capture whatsnext %}}
네트워크 모델의 초기 설계와 그 근거 및 미래의 계획은
[네트워킹 디자인 문서](https://git.k8s.io/community/contributors/design-proposals/network/networking.md)에
자세히 설명되어 있다.
{{% /capture %}}

View File

@ -1,7 +1,7 @@
---
title: 노드에 파드 할당하기
content_template: templates/concept
weight: 30
weight: 50
---

View File

@ -0,0 +1,169 @@
---
title: 컨피그맵(ConfigMap)
content_template: templates/concept
weight: 20
---
{{% capture overview %}}
{{< glossary_definition term_id="configmap" prepend="컨피그맵은" length="all" >}}
{{< caution >}}
컨피그맵은 보안 또는 암호화를 제공하지 않는다.
저장하려는 데이터가 기밀인 경우, 컨피그맵
대신 {{< glossary_tooltip text="시크릿(Secret)" term_id="secret" >}} 또는 추가(써드파티) 도구를
사용하여 데이터를 비공개로 유지하자.
{{< /caution >}}
{{% /capture %}}
{{% capture body %}}
## 사용 동기
애플리케이션 코드와 별도로 구성 데이터를 설정하려면 컨피그맵을 사용하자.
예를 들어, 자신의 컴퓨터(개발용)와 클라우드(실제 트래픽 처리)에서
실행할 수 있는 애플리케이션을 개발한다고 가정해보자.
`DATABASE_HOST` 라는
환경 변수를 찾기 위해 코드를 작성한다. 로컬에서는 해당 변수를
`localhost` 로 설정한다. 클라우드에서는, 데이터베이스
컴포넌트를 클러스터에 노출하는 쿠버네티스 {{< glossary_tooltip text="서비스" term_id="service" >}}를 참조하도록
설정한다.
이를 통해 클라우드에서 실행 중인 컨테이너 이미지를 가져와
필요한 경우 정확히 동일한 코드를 로컬에서 디버깅할 수 있다.
## 컨피그맵 오브젝트
컨피그맵은 다른 오브젝트가 사용할 구성을 저장할 수 있는
API [오브젝트](/ko/docs/concepts/overview/working-with-objects/kubernetes-objects/)이다.
`spec` 이 있는 대부분의 쿠버네티스 오브젝트와 달리,
컨피그맵에는 항목(키)과 해당 값을 저장하는 `data` 섹션이 있다.
컨피그맵의 이름은 유효한
[DNS 서브도메인 이름](/ko/docs/concepts/overview/working-with-objects/names/#dns-서브도메인-이름)이어야 한다.
## 컨피그맵과 파드(Pod)
컨피그맵을 참조하는 파드 `spec` 을 작성하고 컨피그맵의 데이터를
기반으로 해당 파드의 컨테이너를 구성할 수 있다. 파드와 컨피그맵은
동일한 {{< glossary_tooltip text="네임스페이스" term_id="namespace" >}}에 있어야 한다.
다음은 단일 값을 가진 키와,
값이 구성 형식의 일부처럼 보이는 키를 가진 컨피그맵의
예시이다.
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
Name: game-demo
data:
# 속성과 비슷한 키; 각 키는 간단한 값으로 매핑됨
player_initial_lives: 3
ui_properties_file_name: "user-interface.properties"
#
# 파일과 비슷한 키
game.properties: |
enemy.types=aliens,monsters
player.maximum-lives=5
user-interface.properties: |
color.good=purple
color.bad=yellow
allow.textmode=true
```
컨피그맵을 사용하여 파드 내부에 컨테이너를 구성할 수 있는
네 가지 방법이 있다.
1. 컨테이너의 엔트리포인트에 대한 커맨드 라인 인수
1. 컨테이너에 대한 환경 변수
1. 애플리케이션이 읽을 수 있도록 읽기 전용 볼륨에 파일 추가
1. 쿠버네티스 API를 사용하여 컨피그맵을 읽는 파드 내에서 실행할 코드 작성
이러한 방법들은 소비되는 데이터를 모델링하는
방식에 따라 다르게 쓰인다.
처음 세 가지 방법의 경우,
{{< glossary_tooltip text="kubelet" term_id="kubelet" >}}은 파드의 컨테이너를 시작할 때
시크릿의 데이터를 사용한다.
네 번째 방법은 시크릿과 데이터를 읽기 위해 코드를 작성해야 한다는 것을 의미한다.
그러나, 쿠버네티스 API를 직접 사용하기 때문에, 애플리케이션은
컨피그맵이 변경될 때마다 업데이트를 받기 위해 구독할 수 있고, 업데이트가
있으면 반응한다. 쿠버네티스 API에 직접 접근하면, 이
기술을 사용하여 다른 네임스페이스의 컨피그맵에 접근할 수도 있다.
다음은 `game-demo` 의 값을 사용하여 파드를 구성하는 파드 예시이다.
```yaml
apiVersion: v1
kind: Pod
metadata:
name: configmap-demo-pod
spec:
containers:
- name: demo
image: game.example/demo-game
env:
# 환경 변수 정의
- name: PLAYER_INITIAL_LIVES # 참고로 여기서는 컨피그맵의 키 이름과
# 대소문자가 다르다.
valueFrom:
configMapKeyRef:
name: game-demo # 이 값의 컨피그맵.
key: player_initial_lives # 가져올 키.
- name: UI_PROPERTIES_FILE_NAME
valueFrom:
configMapKeyRef:
name: game-demo
key: ui_properties_file_name
volumeMounts:
- name: config
mountPath: "/config"
readOnly: true
volumes:
# 파드 레벨에서 볼륨을 설정한 다음, 해당 파드 내의 컨테이너에 마운트한다.
- name: config
configMap:
# 마운트하려는 컨피그맵의 이름을 제공한다.
name: game-demo
```
컨피그맵은 단일 라인 속성(single line property) 값과 멀티 라인의 파일과 비슷한(multi-line file-like) 값을
구분하지 않는다.
더 중요한 것은 파드와 다른 오브젝트가 이러한 값을 소비하는 방식이다.
이 예제에서, 볼륨을 정의하고 `demo` 컨테이너에
`/config` 로 마운트하면 4개의 파일이 생성된다.
- `/config/player_initial_lives`
- `/config/ui_properties_file_name`
- `/config/game.properties`
- `/config/user-interface.properties`
`/config``.properties` 확장자를 가진 파일만
포함시키려면, 두 개의 다른 컨피그맵을 사용하고, 파드에
대해서는 `spec` 의 두 컨피그맵을 참조한다. 첫 번째 컨피그맵은
`player_initial_lives``ui_properties_file_name` 을 정의한다. 두 번째
컨피그맵은 kubelet이 `/config` 에 넣는 파일을 정의한다.
{{< note >}}
컨피그맵을 사용하는 가장 일반적인 방법은 동일한 네임스페이스의
파드에서 실행되는 컨테이너에 대한 설정을 구성하는 것이다. 컨피그맵을
별도로 사용할 수도 있다.
예를 들어,
컨피그맵에 기반한 동작을 조정하는 {{< glossary_tooltip text="애드온" term_id="addons" >}}이나
{{< glossary_tooltip text="오퍼레이터" term_id="operator-pattern" >}}를
사용할 수도 있다.
{{< /note >}}
{{% /capture %}}
{{% capture whatsnext %}}
* [시크릿](/docs/concepts/configuration/secret/)에 대해 읽어본다.
* [컨피그맵을 사용하도록 파드 구성하기](/docs/tasks/configure-pod-container/configure-pod-configmap/)를 읽어본다.
* 코드를 구성에서 분리하려는 동기를 이해하려면
[Twelve-Factor 앱](https://12factor.net/ko/)을 읽어본다.
{{% /capture %}}

View File

@ -0,0 +1,761 @@
---
title: 컨테이너 리소스 관리
content_template: templates/concept
weight: 40
feature:
title: 자동 빈 패킹(bin packing)
description: >
리소스 요구 사항과 기타 제약 조건에 따라 컨테이너를 자동으로 배치하지만, 가용성은 그대로 유지한다. 활용도를 높이고 더 많은 리소스를 절약하기 위해 중요한(critical) 워크로드와 최선의(best-effort) 워크로드를 혼합한다.
---
{{% capture overview %}}
{{< glossary_tooltip text="파드" term_id="pod" >}}를 지정할 때,
{{< glossary_tooltip text="컨테이너" term_id="container" >}}에 필요한 각 리소스의 양을 선택적으로 지정할 수 있다.
지정할 가장 일반적인 리소스는 CPU와 메모리(RAM) 그리고 다른 것들이 있다.
파드에서 컨테이너에 대한 리소스 _요청(request)_ 을 지정하면, 스케줄러는 이 정보를
사용하여 파드가 배치될 노드를 결정한다. 컨테이너에 대한 리소스 _제한(limit)_
지정하면, kubelet은 실행 중인 컨테이너가 설정한 제한보다 많은 리소스를
사용할 수 없도록 해당 제한을 적용한다. 또한 kubelet은
컨테이너가 사용할 수 있도록 해당 시스템 리소스의 최소 _요청_ 량을
예약한다.
{{% /capture %}}
{{% capture body %}}
## 요청 및 제한
파드가 실행 중인 노드에 사용 가능한 리소스가 충분하면, 컨테이너가 해당
리소스에 지정한 `request` 보다 더 많은 리소스를 사용할 수 있도록 허용된다.
그러나, 컨테이너는 리소스 `limit` 보다 더 많은 리소스를 사용할 수는 없다.
예를 들어, 컨테이너에 대해 256MiB의 `memory` 요청을 설정하고, 해당 컨테이너가
8GiB의 메모리를 가진 노드로 스케줄된 파드에 있고 다른 파드는 없는 경우, 컨테이너는 더 많은 RAM을
사용할 수 있다.
해당 컨테이너에 대해 4GiB의 `memory` 제한을 설정하면, kubelet(그리고
{{< glossary_tooltip text="컨테이너 런타임" term_id="container-runtime" >}})이 제한을 적용한다.
런타임은 컨테이너가 구성된 리소스 제한을 초과하여 사용하지 못하게 한다. 예를 들어,
컨테이너의 프로세스가 허용된 양보다 많은 메모리를 사용하려고 하면,
시스템 커널은 메모리 부족(out of memory, OOM) 오류와 함께 할당을 시도한 프로세스를
종료한다.
제한은 반응적(시스템이 위반을 감지한 후에 개입)으로
또는 강제적(시스템이 컨테이너가 제한을 초과하지 않도록 방지)으로 구현할 수 있다. 런타임마다
다른 방식으로 동일한 제약을 구현할 수 있다.
## 리소스 타입
*CPU* 와 *메모리* 는 각각 *리소스 타입* 이다. 리소스 타입에는 기본 단위가 있다.
CPU는 컴퓨팅 처리를 나타내며 [쿠버네티스 CPU](#cpu의-의미) 단위로 지정된다.
메모리는 바이트 단위로 지정된다.
쿠버네티스 v1.14 이상을 사용하는 경우, _huge page_ 리소스를 지정할 수 있다.
Huge page는 노드 커널이 기본 페이지 크기보다 훨씬 큰 메모리
블록을 할당하는 리눅스 관련 기능이다.
예를 들어, 기본 페이지 크기가 4KiB인 시스템에서, `hugepages-2Mi: 80Mi` 제한을
지정할 수 있다. 컨테이너가 40개 이상의 2MiB huge page(총 80MiB)를
할당하려고 하면 해당 할당이 실패한다.
{{< note >}}
`hugepages-*` 리소스를 오버커밋할 수 없다.
이것은 `memory``cpu` 리소스와는 다르다.
{{< /note >}}
CPU와 메모리를 통칭하여 *컴퓨트 리소스* 또는 그냥 *리소스* 라고 한다. 컴퓨트
리소스는 요청, 할당 및 소비될 수 있는 측정 가능한
수량이다. 이것은
[API 리소스](/ko/docs/concepts/overview/kubernetes-api/)와는 다르다. 파드 및
[서비스](/ko/docs/concepts/services-networking/service/)와 같은 API 리소스는
쿠버네티스 API 서버를 통해 읽고 수정할 수
있는 오브젝트이다.
## 파드와 컨테이너의 리소스 요청 및 제한
파드의 각 컨테이너는 다음 중 하나 이상을 지정할 수 있다.
* `spec.containers[].resources.limits.cpu`
* `spec.containers[].resources.limits.memory`
* `spec.containers[].resources.limits.hugepages-<size>`
* `spec.containers[].resources.requests.cpu`
* `spec.containers[].resources.requests.memory`
* `spec.containers[].resources.requests.hugepages-<size>`
요청과 제한은 개별 컨테이너에서만 지정할 수 있지만,
파드 리소스 요청 및 제한에 대해 이야기하는 것이 편리하다.
특정 리소스 타입에 대한 *파드 리소스 요청/제한* 은 파드의 각 컨테이너에 대한
해당 타입의 리소스 요청/제한의 합이다.
## 쿠버네티스의 리소스 단위
### CPU의 의미
CPU 리소스에 대한 제한 및 요청은 *cpu* 단위로 측정된다.
쿠버네티스의 CPU 1개는 클라우드 공급자용 **vCPU/Core 1개** 와 베어메탈 인텔 프로세서에서의 **1개 하이퍼스레드** 에 해당한다.
분수의 요청이 허용된다.
`0.5``spec.containers[].resources.requests.cpu` 요청을 가진
컨테이너는 CPU 1개를 요구하는 컨테이너의 절반만큼 CPU를 보장한다. `0.1` 이라는 표현은
"백 밀리cpu"로 읽을 수 있는 `100m` 표현과 동일하다. 어떤 사람들은
"백 밀리코어"라고 말하는데, 같은 것을 의미하는 것으로 이해된다.
`0.1` 과 같이 소수점이 있는 요청은 API에 의해 `100m` 로 변환되며,
`1m` 도 허용되지 않게 정밀하다. 이러한 이유로, `100m` 형식이
선호될 수 있다.
CPU는 항상 절대 수량으로 요청되며, 상대적 수량은 아니다.
0.1은 단일 코어, 이중 코어 또는 48코어 시스템에서 동일한 양의 CPU이다.
### 메모리의 의미
`memory` 에 대한 제한 및 요청은 바이트 단위로 측정된다.
E, P, T, G, M, K와 같은 접미사 중 하나를 사용하여 메모리를
일반 정수 또는 고정 소수점 정수로 표현할 수 있다. Ei, Pi, Ti, Gi, Mi, Ki와
같은 2의 거듭제곱을 사용할 수도 있다. 예를 들어, 다음은 대략 동일한 값을 나타낸다.
```shell
128974848, 129e6, 129M, 123Mi
```
다음은 예제이다.
다음 파드에는 두 개의 컨테이너가 있다. 각 컨테이너에는 0.25 cpu와
64MiB(2<sup>26</sup> 바이트)의 메모리 요청이 있다. 각 컨테이너는 0.5
cpu와 128MiB 메모리로 제한된다. 파드에 0.5 cpu와 128 MiB
메모리, 1 cpu와 256MiB 메모리 제한이 있다고 말할 수 있다.
```yaml
apiVersion: v1
kind: Pod
metadata:
name: frontend
spec:
containers:
- name: db
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "password"
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
- name: wp
image: wordpress
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
```
## 리소스 요청이 포함된 파드를 스케줄링하는 방법
파드를 생성할 때, 쿠버네티스 스케줄러는 파드를 실행할 노드를
선택한다. 각 노드는 파드에 제공할 수 있는 CPU와 메모리 양과 같은 각 리소스 타입에 대해
최대 용량을 갖는다. 스케줄러는 각 리소스 타입마다
스케줄된 컨테이너의 리소스 요청 합계가
노드 용량보다 작도록 한다. 참고로 노드의 실제 메모리나
CPU 리소스 사용량은 매우 적지만, 용량 확인에 실패한 경우
스케줄러는 여전히 노드에 파드를 배치하지 않는다. 이는 리소스 사용량이
나중에 증가할 때, 예를 들어, 일일 요청 비율이
최대일 때 노드의 리소스 부족을 방지한다.
## 리소스 제한이 있는 파드가 실행되는 방법
kubelet은 파드의 컨테이너를 시작할 때, CPU와 메모리 제한을
컨테이너 런타임으로 전달한다.
도커를 사용하는 경우에는 다음과 같다.
- `spec.containers[].resources.requests.cpu` 는 잠재적인 분수이며,
1024를 곱한 값인 코어 값으로 변환된다. 이 숫자 또는 2보다
큰 값은 `docker run` 명령에서
[`--cpu-shares`](https://docs.docker.com/engine/reference/run/#cpu-share-constraint)
플래그의 값으로 사용된다.
- 이 `spec.containers[].resources.limits.cpu` 값은 밀리코어 값으로 변환되고
100을 곱한 값이다. 그 결과 값은 컨테이너가 100ms마다 사용할 수 있는 총 CPU
시간이다. 이 간격 동안 컨테이너는 CPU 시간을 초과하여 사용할 수 없다.
{{< note >}}
기본 쿼터 기간은 100ms이다. 최소 CPU 쿼터는 1ms이다.
{{</ note >}}
- `spec.containers[].resources.limits.memory` 는 정수로 변환되어,
`docker run` 명령에서
[`--memory`](https://docs.docker.com/engine/reference/run/#/user-memory-constraints)
플래그의 값으로 사용된다.
컨테이너가 메모리 제한을 초과하면, 컨테이너는 종료될 수 있다. 다시
시작할 수 있으면, 다른 타입의 런타임 오류와 마찬가지로, kubelet이 다시
시작한다.
컨테이너가 메모리 요청을 초과하면, 노드에 메모리가
부족할 때마다 파드가 축출될 수 있다.
컨테이너가 오랫동안 CPU 제한을 초과하는 것은 허용되거나 허용되지
않을 수 있다. 그러나, 과도한 CPU 사용으로 인해 종료되지는 않는다.
리소스 제한으로 인해 컨테이너를 스케줄할 수 없는지 또는
종료 중인지 확인하려면,
[문제 해결](#문제-해결) 섹션을 참조한다.
### 컴퓨트 및 메모리 리소스 사용량 모니터링
파드의 리소스 사용량은 파드 상태의 일부로 보고된다.
클러스터에서 선택적인 모니터링 도구를
사용할 수 있다면, [메트릭 API](/ko/docs/tasks/debug-application-cluster/resource-metrics-pipeline/#메트릭-api)에서
직접 또는 모니터링 도구에서 파드 리소스
사용량을 검색할 수 있다.
## 로컬 임시(ephemeral) 스토리지
<!-- feature gate LocalStorageCapacityIsolation -->
{{< feature-state for_k8s_version="v1.10" state="beta" >}}
노드에는 로컬에 연결된 쓰기 가능 장치 또는, 때로는 RAM에 의해
지원되는 로컬 임시 스토리지가 있다.
"임시"는 내구성에 대한 장기간의 보증이 없음을 의미한다.
파드는 스크래치 공간, 캐싱 및 로그에 대해 임시 로컬 스토리지를 사용한다.
kubelet은 로컬 임시 스토리지를 사용하여 컨테이너에
[`emptyDir`](https://kubernetes.io/docs/concepts/storage/volumes/#emptydir)
{{< glossary_tooltip term_id="volume" text="볼륨" >}}을 마운트하기 위해 파드에 스크래치 공간을 제공할 수 있다.
kubelet은 이러한 종류의 스토리지를 사용하여
[노드-레벨 컨테이너 로그](/ko/docs/concepts/cluster-administration/logging/#노드-레벨에서의-로깅),
컨테이너 이미지 및 실행 중인 컨테이너의 쓰기 가능 계층을 보유한다.
{{< caution >}}
노드가 실패하면, 임시 스토리지의 데이터가 손실될 수 있다.
애플리케이션은 로컬 임시 스토리지에서 성능에 대한 SLA(예: 디스크 IOPS)를
기대할 수 없다.
{{< /caution >}}
베타 기능에서, 쿠버네티스는 파드가 사용할 수 있는 임시 로컬 스토리지의 양을
추적, 예약 및 제한할 수 있도록 해준다.
### 로컬 임시 스토리지 구성
쿠버네티스는 노드에서 로컬 임시 스토리지를 구성하는 두 가지 방법을 지원한다.
{{< tabs name="local_storage_configurations" >}}
{{% tab name="단일 파일시스템" %}}
이 구성에서, 모든 종류의 임시 로컬 데이터(`emptyDir` 볼륨,
쓰기 가능 계층, 컨테이너 이미지, 로그)를 하나의 파일시스템에 배치한다.
kubelet을 구성하는 가장 효과적인 방법은 이 파일시스템을 쿠버네티스(kubelet) 데이터 전용으로
하는 것이다.
kubelet은 또한
[노드-레벨 컨테이너 로그](/ko/docs/concepts/cluster-administration/logging/#노드-레벨에서의-로깅)를
작성하고 임시 로컬 스토리지와 유사하게 처리한다.
kubelet은 구성된 로그 디렉터리 내의 파일에 로그를 기록한다(기본적으로
`/var/log`). 그리고 로컬에 저장된 다른 데이터에 대한 기본 디렉터리가 있다(기본적으로
`/var/lib/kubelet`).
일반적으로, `/var/lib/kubelet``/var/log` 모두 시스템 루트 파일시스템에 위치하고,
그리고 kubelet은 이런 레이아웃을 염두에 두고 설계되었다.
노드는 쿠버네티스에서 사용하지 않는 다른 많은 파일시스템을
가질 수 있다.
{{% /tab %}}
{{% tab name="두 개의 파일시스템" %}}
사용하고 있는 노드에 실행 중인 파드에서 발생하는 임시 데이터를
위한 파일시스템을 가진다(로그와 `emptyDir` 볼륨). 이 파일시스템을
다른 데이터(예를 들어, 쿠버네티스와 관련없는 시스템 로그)를 위해 사용할 수 있다. 이 파일시스템은
루트 파일시스템일 수도 있다.
kubelet은 또한
[노드-레벨 컨테이너 로그](/ko/docs/concepts/cluster-administration/logging/#노드-레벨에서의-로깅)를
첫 번째 파일시스템에 기록하고, 임시 로컬 스토리지와 유사하게 처리한다.
또한 다른 논리 스토리지 장치가 지원하는 별도의 파일시스템을 사용한다.
이 구성에서, 컨테이너 이미지 계층과 쓰기 가능한 계층을 배치하도록
kubelet에 지시하는 디렉터리는 이 두 번째 파일시스템에 있다.
첫 번째 파일시스템에는 이미지 계층이나 쓰기 가능한 계층이 없다.
노드는 쿠버네티스에서 사용하지 않는 다른 많은 파일시스템을
가질 수 있다.
{{% /tab %}}
{{< /tabs >}}
kubelet은 사용 중인 로컬 스토리지 양을 측정할 수 있다. 이것은 다음을
제공한다.
- `LocalStorageCapacityIsolation`
[기능 게이트](/docs/reference/command-line-tools-reference/feature-gates/)(이
기능이 기본적으로 설정되어 있음)를 활성화하고,
- 로컬 임시 스토리지에 대한 지원되는 구성 중 하나를
사용하여 노드를 설정한다.
다른 구성을 사용하는 경우, kubelet은 임시 로컬 스토리지에 대한 리소스
제한을 적용하지 않는다.
{{< note >}}
kubelet은 로컬 임시 스토리지가 아닌 컨테이너 메모리 사용으로
`tmpfs` emptyDir 볼륨을 추적한다.
{{< /note >}}
### 로컬 임시 스토리지에 대한 요청 및 제한 설정
_임시-스토리지_ 를 사용하여 로컬 임시 저장소를 관리할 수 있다. 파드의 각 컨테이너는 다음 중 하나 이상을 지정할 수 있다.
* `spec.containers[].resources.limits.ephemeral-storage`
* `spec.containers[].resources.requests.ephemeral-storage`
`ephemeral-storage` 에 대한 제한 및 요청은 바이트 단위로 측정된다. E, P, T, G, M, K와
같은 접미사 중 하나를 사용하여 스토리지를 일반 정수 또는 고정 소수점 정수로 표현할 수 있다.
Ei, Pi, Ti, Gi, Mi, Ki와 같은 2의 거듭제곱을 사용할 수도 있다.
예를 들어, 다음은 대략 동일한 값을 나타낸다.
```shell
128974848, 129e6, 129M, 123Mi
```
다음 예에서, 파드에 두 개의 컨테이너가 있다. 각 컨테이너에는 2GiB의 로컬 임시 스토리지 요청이 있다. 각 컨테이너에는 4GiB의 로컬 임시 스토리지 제한이 있다. 따라서, 파드는 4GiB의 로컬 임시 스토리지 요청과 8GiB 스토리지 제한을 가진다.
```yaml
apiVersion: v1
kind: Pod
metadata:
name: frontend
spec:
containers:
- name: db
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "password"
resources:
requests:
ephemeral-storage: "2Gi"
limits:
ephemeral-storage: "4Gi"
- name: wp
image: wordpress
resources:
requests:
ephemeral-storage: "2Gi"
limits:
ephemeral-storage: "4Gi"
```
### 임시-스토리지 요청이 있는 파드의 스케줄링 방법
파드를 생성할 때, 쿠버네티스 스케줄러는 파드를 실행할 노드를
선택한다. 각 노드에는 파드에 제공할 수 있는 최대 임시 스토리지 공간이 있다. 자세한 정보는, [노드 할당 가능](/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable)을 참조한다.
스케줄러는 스케줄된 컨테이너의 리소스 요청 합계가 노드 용량보다 작도록 한다.
### 임시 스토리지 소비 관리 {#resource-emphemeralstorage-consumption}
kubelet이 로컬 임시 스토리지를 리소스로 관리하는 경우,
kubelet은 다음에서 스토리지 사용을 측정한다.
- _tmpfs_ `emptyDir` 볼륨을 제외한 `emptyDir` 볼륨
- 노드-레벨 로그가 있는 디렉터리
- 쓰기 가능한 컨테이너 계층
허용하는 것보다 더 많은 임시 스토리지를 파드가 사용하는 경우, kubelet은
파드 축출을 트리거하는 축출 신호를 설정한다.
컨테이너-레벨 격리의 경우, 컨테이너의 쓰기 가능한 계층과 로그
사용량이 스토리지 제한을 초과하면, kubelet은 파드를 축출하도록 표시한다.
파드-레벨 격리에 대해 kubelet은 해당 파드의 컨테이너에 대한 제한을 합하여
전체 파드 스토리지 제한을 해결한다. 이 경우, 모든
컨테이너와 파드의 `emptyDir` 볼륨의 로컬 임시 스토리지 사용량 합계가
전체 파드 스토리지 제한을 초과하면, kubelet은 파드를 축출 대상으로
표시한다.
{{< caution >}}
kubelet이 로컬 임시 스토리지를 측정하지 않는 경우,
로컬 스토리지 제한을 초과하는 파드는 로컬 스토리지 리소스 제한을
위반해도 축출되지 않는다.
그러나, 쓰기 가능한 컨테이너 계층, 노드-레벨 로그
또는 `emptyDir` 볼륨의 파일 시스템 공간이 부족하면, 로컬
스토리지가 부족하다고 노드 자체에 {{< glossary_tooltip text="테인트" term_id="taint" >}}되고
이로인해 특별히 이 테인트를 허용하지 않는 모든 파드를 축출하도록 트리거한다.
임시 로컬 스토리지에 대해 지원되는 [구성](#로컬-임시-스토리지-구성)을
참조한다.
{{< /caution >}}
kubelet은 파드 스토리지 사용을 측정하는 다양한 방법을 지원한다.
{{< tabs name="resource-emphemeralstorage-measurement" >}}
{{% tab name="주기적 스캐닝" %}}
kubelet은 각 `emptyDir` 볼륨, 컨테이너 로그 디렉터리 및 쓰기 가능한 컨테이너 계층을
스캔하는 정기적인 스케줄 검사를 수행한다.
스캔은 사용된 공간의 양을 측정한다.
{{< note >}}
이 모드에서, kubelet은 삭제된 파일의 열린 파일 디스크립터를
추적하지 않는다.
여러분(또는 컨테이너)이 `emptyDir` 볼륨 안에 파일을 생성하면,
그 파일이 열리고, 파일이 열려있는 동안 파일을
삭제하면, 삭제된 파일의 inode는 해당 파일을 닫을 때까지
유지되지만 kubelet은 사용 중인 공간으로 분류하지 않는다.
{{< /note >}}
{{% /tab %}}
{{% tab name="파일시스템 프로젝트 쿼터" %}}
{{< feature-state for_k8s_version="v1.15" state="alpha" >}}
프로젝트 쿼터는 파일시스템에서 스토리지 사용을 관리하기 위한
운영체제 레벨의 기능이다. 쿠버네티스를 사용하면, 스토리지 사용을
모니터링하기 위해 프로젝트 쿼터를 사용할 수 있다. 노드에서 'emptyDir' 볼륨을
지원하는 파일시스템이 프로젝트 쿼터 지원을 제공하는지 확인한다.
예를 들어, XFS와 ext4fs는 프로젝트 쿼터를 지원한다.
{{< note >}}
프로젝트 쿼터를 통해 스토리지 사용을 모니터링할 수 있다. 이는 제한을 강제하지 않는다.
{{< /note >}}
쿠버네티스는 `1048576` 부터 프로젝트 ID를 사용한다. 사용 중인 ID는
`/etc/projects``/etc/projid` 에 등록되어 있다. 이 범위의 프로젝트 ID가
시스템에서 다른 목적으로 사용되는 경우, 쿠버네티스가
이를 사용하지 않도록 해당 프로젝트 ID를 `/etc/projects``/etc/projid`
등록해야 한다.
쿼터는 디렉터리 검색보다 빠르고 정확하다. 디렉터리가
프로젝트에 할당되면, 디렉터리 아래에 생성된
모든 파일이 해당 프로젝트에 생성되며, 커널은 해당 프로젝트의
파일에서 사용 중인 블록 수를 추적하기만 하면 된다.
파일이 생성되고 삭제되었지만, 열린 파일 디스크립터가 있으면,
계속 공간을 소비한다. 쿼터 추적은 공간을 정확하게 기록하는 반면
디렉터리 스캔은 삭제된 파일이 사용한 스토리지를 간과한다.
프로젝트 쿼터를 사용하려면, 다음을 수행해야 한다.
* kubelet 구성에서 `LocalStorageCapacityIsolationFSQuotaMonitoring=true`
[기능 게이트](/docs/reference/command-line-tools-reference/feature-gates/)를
활성화한다.
* 루트 파일시스템(또는 선택적인 런타임 파일시스템)에
프로젝트 쿼터가 활성화되어 있는지 확인한다. 모든 XFS 파일시스템은 프로젝트 쿼터를 지원한다.
ext4 파일시스템의 경우, 파일시스템이 마운트되지 않은 상태에서 프로젝트 쿼터
추적 기능을 활성화해야 한다.
```bash
# ext4인 /dev/block-device가 마운트되지 않은 경우
sudo tune2fs -O project -Q prjquota /dev/block-device
```
* 루트 파일시스템(또는 선택적인 런타임 파일시스템)은 프로젝트 쿼터를
활성화한 상태에서 마운트해야 힌다. XFS와 ext4fs 모두에서,
마운트 옵션의 이름은 `prjquota` 이다.
{{% /tab %}}
{{< /tabs >}}
## 확장된 리소스
확장된 리소스는 `kubernetes.io` 도메인 외부의 전체 주소(fully-qualified)
리소스 이름이다. 쿠버네티스에 내장되지 않은 리소스를 클러스터 운영자가 알리고
사용자는 사용할 수 있다.
확장된 리소스를 사용하려면 두 단계가 필요한다. 먼저, 클러스터
운영자는 확장된 리소스를 알려야 한다. 둘째, 사용자는 파드의
확장된 리소스를 요청해야 한다.
### 확장된 리소스 관리
#### 노드-레벨의 확장된 리소스
노드-레벨의 확장된 리소스는 노드에 연결된다.
##### 장치 플러그인 관리 리소스
각 노드에서
장치 플러그인 관리 리소스를 알리는 방법은
[장치 플러그인](/ko/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/)을 참조한다.
##### 기타 리소스
새로운 노드-레벨의 확장된 리소스를 알리기 위해, 클러스터 운영자는
API 서버에 `PATCH` HTTP 요청을 제출하여 클러스터의
노드에 대해 `status.capacity` 에서 사용할 수 있는 수량을 지정할 수 있다. 이 작업
후에는, 노드의 `status.capacity` 에 새로운 리소스가 포함된다. 이
`status.allocatable` 필드는 kubelet에 의해 비동기적으로 새로운
리소스로 자동 업데이트된다. 참고로 스케줄러가 파드 적합성을 평가할 때 노드
`status.allocatable` 값을 사용하므로, 노드 용량을
새 리소스로 패치하는 것과 해당 노드에서 리소스를 스케줄하도록 요청하는 첫 번째 파드
사이에 약간의 지연이 있을 수 있다.
**예제:**
다음은 `curl` 을 사용하여 마스터가 `k8s-master` 인 노드 `k8s-node-1`
5개의 "example.com/foo" 리소스를 알리는 HTTP 요청을 구성하는 방법을
보여주는 예이다.
```shell
curl --header "Content-Type: application/json-patch+json" \
--request PATCH \
--data '[{"op": "add", "path": "/status/capacity/example.com~1foo", "value": "5"}]' \
http://k8s-master:8080/api/v1/nodes/k8s-node-1/status
```
{{< note >}}
앞의 요청에서, `~1` 은 패치 경로에서 문자 `/`
인코딩이다. JSON-Patch의 작업 경로 값은
JSON-Pointer로 해석된다. 더 자세한 내용은,
[IETF RFC 6901, 섹션 3](https://tools.ietf.org/html/rfc6901#section-3)을 참조한다.
{{< /note >}}
#### 클러스터-레벨의 확장된 리소스
클러스터-레벨의 확장된 리소스는 노드에 연결되지 않는다. 이들은 일반적으로
리소스 소비와 리소스 쿼터를 처리하는 스케줄러 익스텐더(extender)에 의해 관리된다.
[스케줄러 정책 구성](https://github.com/kubernetes/kubernetes/blob/release-1.10/pkg/scheduler/api/v1/types.go#L31)에서
스케줄러 익스텐더가
처리하는 확장된 리소스를 지정할 수 있다.
**예제:**
스케줄러 정책에 대한 다음의 구성은 클러스터-레벨의 확장된 리소스
"example.com/foo"가 스케줄러 익스텐더에 의해 처리됨을
나타낸다.
- 파드가 "example.com/foo"를 요청하는 경우에만 스케줄러가 파드를 스케줄러
익스텐더로 보낸다.
- 이 `ignoredByScheduler` 필드는 스케줄러가 `PodFitsResources` 속성에서
"example.com/foo" 리소스를 확인하지 않도록 지정한다.
```json
{
"kind": "Policy",
"apiVersion": "v1",
"extenders": [
{
"urlPrefix":"<extender-endpoint>",
"bindVerb": "bind",
"managedResources": [
{
"name": "example.com/foo",
"ignoredByScheduler": true
}
]
}
]
}
```
### 확장된 리소스 소비
사용자는 CPU와 메모리 같은 파드 스펙의 확장된 리소스를 사용할 수 있다.
스케줄러는 리소스 어카운팅(resource accounting)을 관리하여 사용 가능한 양보다
많은 양의 리소스가 여러 파드에 동시에 할당되지 않도록 한다.
API 서버는 확장된 리소스의 수량을 정수로 제한한다.
_유효한_ 수량의 예로는 `3`, `3000m` 그리고 `3Ki` 를 들 수 있다. _유효하지 않은_
수량의 예는 `0.5``1500m` 이다.
{{< note >}}
확장된 리소스는 불명확한 정수 리소스를 대체한다.
사용자는 예약된 `kubernetes.io` 이외의 모든 도메인 이름 접두사를 사용할 수 있다.
{{< /note >}}
파드에서 확장된 리소스를 사용하려면, 컨테이너 사양에서 `spec.containers[].resources.limits`
맵에 리소스 이름을 키로 포함한다.
{{< note >}}
확장된 리소스는 오버커밋할 수 없으므로, 컨테이너 사양에
둘 다 있으면 요청과 제한이 동일해야 한다.
{{< /note >}}
파드는 CPU, 메모리 및 확장된 리소스를 포함하여 모든 리소스 요청이
충족되는 경우에만 예약된다. 리소스 요청을 충족할 수 없다면
파드는 `PENDING` 상태를 유지한다.
**예제:**
아래의 파드는 2개의 CPU와 1개의 "example.com/foo"(확장된 리소스)를 요청한다.
```yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: myimage
resources:
requests:
cpu: 2
example.com/foo: 1
limits:
example.com/foo: 1
```
## 문제 해결
### 내 파드가 failedScheduling 이벤트 메시지로 보류 중이다
파드가 배치될 수 있는 노드를 스케줄러가 찾을 수 없으면, 노드를
찾을 수 있을 때까지 파드는 스케줄되지 않은 상태로 유지한다. 스케줄러가 다음과 같이
파드의 위치를 ​​찾지 못하면 이벤트가 생성된다.
```shell
kubectl describe pod frontend | grep -A 3 Events
```
```
Events:
FirstSeen LastSeen Count From Subobject PathReason Message
36s 5s 6 {scheduler } FailedScheduling Failed for reason PodExceedsFreeCPU and possibly others
```
위의 예에서, 노드의 CPU 리소스가 충분하지 않아 이름이
"frontend"인 파드를 스케줄하지 못했다. 비슷한 메시지로
메모리 부족(PodExceedsFreeMemory)으로 인한 장애도 알릴 수 있다. 일반적으로, 파드가
이 타입의 메시지로 보류 중인 경우, 몇 가지 시도해 볼 것들이 있다.
- 클러스터에 더 많은 노드를 추가한다.
- 불필요한 파드를 종료하여 보류 중인 파드를 위한 공간을 확보한다.
- 파드가 모든 노드보다 크지 않은지 확인한다. 예를 들어, 모든
노드의 용량이 `cpu: 1` 인 경우, `cpu: 1.1` 요청이 있는 파드는
절대 스케줄되지 않는다.
`kubectl describe nodes` 명령으로 노드 용량과 할당된 양을
확인할 수 있다. 예를 들면, 다음과 같다.
```shell
kubectl describe nodes e2e-test-node-pool-4lw4
```
```
Name: e2e-test-node-pool-4lw4
[ ... 명확하게 하기 위해 라인들을 제거함 ...]
Capacity:
cpu: 2
memory: 7679792Ki
pods: 110
Allocatable:
cpu: 1800m
memory: 7474992Ki
pods: 110
[ ... 명확하게 하기 위해 라인들을 제거함 ...]
Non-terminated Pods: (5 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits
--------- ---- ------------ ---------- --------------- -------------
kube-system fluentd-gcp-v1.38-28bv1 100m (5%) 0 (0%) 200Mi (2%) 200Mi (2%)
kube-system kube-dns-3297075139-61lj3 260m (13%) 0 (0%) 100Mi (1%) 170Mi (2%)
kube-system kube-proxy-e2e-test-... 100m (5%) 0 (0%) 0 (0%) 0 (0%)
kube-system monitoring-influxdb-grafana-v4-z1m12 200m (10%) 200m (10%) 600Mi (8%) 600Mi (8%)
kube-system node-problem-detector-v0.1-fj7m3 20m (1%) 200m (10%) 20Mi (0%) 100Mi (1%)
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
CPU Requests CPU Limits Memory Requests Memory Limits
------------ ---------- --------------- -------------
680m (34%) 400m (20%) 920Mi (12%) 1070Mi (14%)
```
위의 출력에서, ​파드가 1120m 이상의 CPU 또는 6.23Gi의 메모리를
요청하는 것은 노드에 맞지 않음을 알 수 있다.
`Pods` 섹션을 살펴보면, 파드가 노드에서 공간을 차지하는 것을
볼 수 있다.
시스템 데몬이 사용 가능한 리소스의 일부를 사용하기 때문에, 파드에
사용 가능한 리소스의 양이 노드 용량보다 적다. `allocatable` 필드
[NodeStatus](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#nodestatus-v1-core)는
파드가 사용할 수 있는 리소스의 양을 제공한다. 자세한 정보는
[노드 할당 가능 리소스](https://git.k8s.io/community/contributors/design-proposals/node/node-allocatable.md)를 참조한다.
[리소스 쿼터](/ko/docs/concepts/policy/resource-quotas/) 기능은
소비될 수 있는 리소스의 총량을 제한하도록 구성할 수 있다. 네임스페이스와
함께 사용하면, 한 팀이 모든 리소스를 사용하는 경우를 방지할 수 있다.
### 내 컨테이너가 종료되었다
리소스가 부족하여 컨테이너가 종료될 수 있다. 리소스
제한에 도달하여 컨테이너가 종료되고 있는지 확인하려면,
관심있는 파드에 대해 `kubectl describe pod` 를 호출한다.
```shell
kubectl describe pod simmemleak-hra99
```
```
Name: simmemleak-hra99
Namespace: default
Image(s): saadali/simmemleak
Node: kubernetes-node-tf0f/10.240.216.66
Labels: name=simmemleak
Status: Running
Reason:
Message:
IP: 10.244.2.75
Replication Controllers: simmemleak (1/1 replicas created)
Containers:
simmemleak:
Image: saadali/simmemleak
Limits:
cpu: 100m
memory: 50Mi
State: Running
Started: Tue, 07 Jul 2015 12:54:41 -0700
Last Termination State: Terminated
Exit Code: 1
Started: Fri, 07 Jul 2015 12:54:30 -0700
Finished: Fri, 07 Jul 2015 12:54:33 -0700
Ready: False
Restart Count: 5
Conditions:
Type Status
Ready False
Events:
FirstSeen LastSeen Count From SubobjectPath Reason Message
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {scheduler } scheduled Successfully assigned simmemleak-hra99 to kubernetes-node-tf0f
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD pulled Pod container image "k8s.gcr.io/pause:0.8.0" already present on machine
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD created Created with docker id 6a41280f516d
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD started Started with docker id 6a41280f516d
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} spec.containers{simmemleak} created Created with docker id 87348f12526a
```
앞의 예제에서, `Restart Count: 5` 표시는 파드의 `simmemleak`
컨테이너가 종료되고 5번 다시 시작되었음을 나타낸다.
이전에 종료된 컨테이너의 상태를 가져오기 위해 `-o go-template=...` 옵션을 사용해서
`kubectl get pod` 를 호출할 수 있다.
```shell
kubectl get pod -o go-template='{{range.status.containerStatuses}}{{"Container Name: "}}{{.name}}{{"\r\nLastState: "}}{{.lastState}}{{end}}' simmemleak-hra99
```
```
Container Name: simmemleak
LastState: map[terminated:map[exitCode:137 reason:OOM Killed startedAt:2015-07-07T20:58:43Z finishedAt:2015-07-07T20:58:43Z containerID:docker://0e4095bba1feccdfe7ef9fb6ebffe972b4b14285d5acdec6f0d3ae8a22fad8b2]]
```
컨테이너가 `reason:OOM Killed`(`OOM` 은 메모리 부족(Out Of Memory)의 약자) 때문에 종료된 것을 알 수 있다.
{{% /capture %}}
{{% capture whatsnext %}}
* [컨테이너와 파드에 메모리 리소스를 할당](/ko/docs/tasks/configure-pod-container/assign-memory-resource/)하는 핸즈온 경험을 해보자.
* [컨테이너와 파드에 CPU 리소스를 할당](/docs/tasks/configure-pod-container/assign-cpu-resource/)하는 핸즈온 경험을 해보자.
* 요청과 제한의 차이점에 대한 자세한 내용은,
[리소스 QoS](https://git.k8s.io/community/contributors/design-proposals/node/resource-qos.md)를 참조한다.
* [컨테이너](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#container-v1-core) API 레퍼런스 읽어보기
* [ResourceRequirements](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#resourcerequirements-v1-core) API 레퍼런스 읽어보기
* XFS의 [프로젝트 쿼터](http://xfs.org/docs/xfsdocs-xml-dev/XFS_User_Guide/tmp/en-US/html/xfs-quotas.html)에 대해 읽어보기
{{% /capture %}}

View File

@ -0,0 +1,193 @@
---
title: 파드 오버헤드
content_template: templates/concept
weight: 20
---
{{% capture overview %}}
{{< feature-state for_k8s_version="v1.18" state="beta" >}}
노드 위에서 파드를 구동할 때, 파드는 그 자체적으로 많은 시스템 리소스를 사용한다.
이러한 리소스는 파드 내의 컨테이너들을 구동하기 위한 리소스 이외에 추가적으로 필요한 것이다.
_파드 오버헤드_ 는 컨테이너 리소스 요청과 상한 위에서 파드의 인프라에 의해
소비되는 리소스를 계산하는 기능이다.
{{% /capture %}}
{{% capture body %}}
쿠버네티스에서 파드의 오버헤드는 파드의
[런타임클래스](/ko/docs/concepts/containers/runtime-class/) 와 관련된 오버헤드에 따라
[어드미션](/docs/reference/access-authn-authz/extensible-admission-controllers/#what-are-admission-webhooks)
이 수행될 때 지정된다.
파드 오버헤드가 활성화 되면, 파드를 노드에 스케줄링 할 때 컨테이너 리소스 요청의 합에
파드의 오버헤드를 추가해서 스케줄링을 고려한다. 마찬가지로, Kubelet은 파드의 cgroups 크기를 변경하거나
파드의 축출 등급을 부여할 때에도 파드의 오버헤드를 포함하여 고려한다.
## 파드 오버헤드 활성화하기 {#set-up}
기능 활성화를 위해 클러스터에서
`PodOverhead` [기능 게이트](/docs/reference/command-line-tools-reference/feature-gates/) 가 활성화 되어 있고 (1.18 버전에서는 기본적으로 활성화),
`overhead` 필드를 정의하는 `RuntimeClass` 가 사용되고 있는지 확인해야 한다.
## 사용 예제
파드 오버헤드 기능을 사용하기 위하여, `overhead` 필드를 정의하는 런타임클래스가 필요하다.
예를 들어, 가상 머신 및 게스트 OS에 대하여 파드 당 120 MiB를 사용하는
가상화 컨테이너 런타임의 런타임클래스의 경우 다음과 같이 정의 할 수 있다.
```yaml
---
kind: RuntimeClass
apiVersion: node.k8s.io/v1beta1
metadata:
name: kata-fc
handler: kata-fc
overhead:
podFixed:
memory: "120Mi"
cpu: "250m"
```
`kata-fc` 런타임클래스 핸들러를 지정하는 워크로드는 리소스 쿼터 계산,
노드 스케줄링 및 파드 cgroup 크기 조정을 위하여 메모리와 CPU 오버헤드를 고려한다.
주어진 예제 워크로드 test-pod의 구동을 고려해보자.
```yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
runtimeClassName: kata-fc
containers:
- name: busybox-ctr
image: busybox
stdin: true
tty: true
resources:
limits:
cpu: 500m
memory: 100Mi
- name: nginx-ctr
image: nginx
resources:
limits:
cpu: 1500m
memory: 100Mi
```
어드미션 수행 시에, [어드미션 컨트롤러](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/)는
런타임클래스에 기술된 `overhead` 를 포함하기 위하여 워크로드의 PodSpec 항목을 갱신한다. 만약 PodSpec이 이미 해당 필드에 정의되어 있으면,
파드는 거부된다. 주어진 예제에서, 오직 런타임클래스의 이름만이 정의되어 있기 때문에, 어드미션 컨트롤러는 파드가
`overhead` 를 포함하도록 변경한다.
런타임클래스의 어드미션 수행 후에, 파드의 스펙이 갱신된 것을 확인할 수 있다.
```bash
kubectl get pod test-pod -o jsonpath='{.spec.overhead}'
```
명령 실행 결과는 다음과 같다.
```
map[cpu:250m memory:120Mi]
```
만약 리소스쿼터 항목이 정의되어 있다면, 컨테이너의 리소스 요청의 합에는
`overhead` 필드도 추가된다.
kube-scheduler 는 어떤 노드에 파드가 기동 되어야 할지를 정할 때, 파드의 `overhead`
해당 파드에 대한 컨테이너의 리소스 요청의 합을 고려한다. 이 예제에서, 스케줄러는
리소스 요청과 파드의 오버헤드를 더하고, 2.25 CPU와 320 MiB 메모리가 사용 가능한 노드를 찾는다.
일단 파드가 특정 노드에 스케줄링 되면, 해당 노드에 있는 kubelet 은 파드에 대한 새로운 {{< glossary_tooltip text="cgroup" term_id="cgroup" >}}을 생성한다.
기본 컨테이너 런타임이 만들어내는 컨테이너들은 이 파드 안에 존재한다.
만약 각 컨테이너에 대하여 QoS가 보장되었거나 향상이 가능하도록 QoS 의 리소스 상한 제한이 걸려있으면,
kubelet 은 해당 리소스(CPU의 경우 cpu.cfs_quota_us, 메모리의 경우 memory.limit_in_bytes)와 연관된 파드의
cgroup 의 상한선을 설정한다. 이 상한선은 컨테이너 리소스 상한과 PodSpec에
정의된 `overhead` 의 합에 기반한다.
CPU의 경우, 만약 파드가 보장형 또는 버스트형 QoS로 설정되었으면, kubelet은 PodSpec에 정의된 `overhead` 에 컨테이너의
리소스 요청의 합을 더한 값을 `cpu.shares` 로 설정한다.
다음의 예제를 참고하여, 워크로드에 대하여 컨테이너의 리소스 요청을 확인하자.
```bash
kubectl get pod test-pod -o jsonpath='{.spec.containers[*].resources.limits}'
```
컨테이너 리소스 요청의 합은 각각 CPU 2000m 와 메모리 200MiB 이다.
```
map[cpu: 500m memory:100Mi] map[cpu:1500m memory:100Mi]
```
노드에서 측정된 내용과 비교하여 확인해보자.
```bash
kubectl describe node | grep test-pod -B2
```
CPU 2250m와 메모리 320MiB 가 리소스로 요청되었으며, 이 결과는 파드의 오버헤드를 포함한다.
```
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits AGE
--------- ---- ------------ ---------- --------------- ------------- ---
default test-pod 2250m (56%) 2250m (56%) 320Mi (1%) 320Mi (1%) 36m
```
## 파드 cgroup 상한 확인하기
워크로드가 실행 중인 노드에서 파드의 메모리 cgroup들을 확인 해보자. 다음의 예제에서, [`crictl`](https://github.com/kubernetes-sigs/cri-tools/blob/master/docs/crictl.md)은 노드에서 사용되며,
CRI-호환 컨테이너 런타임을 위해서 노드에서 사용할 수 있는 CLI 를 제공한다.
파드의 오버헤드 동작을 보여주는 좋은 예이며,
사용자가 노드에서 직접 cgroup들을 확인하지 않아도 된다.
먼저 특정 노드에서 파드의 식별자를 확인해 보자.
```bash
# 파드가 스케줄 된 노드에서 이것을 실행
POD_ID="$(sudo crictl pods --name test-pod -q)"
```
여기에서, 파드의 cgroup 경로를 확인할 수 있다.
```bash
# 파드가 스케줄 된 노드에서 이것을 실행
sudo crictl inspectp -o=json $POD_ID | grep cgroupsPath
```
명령의 결과로 나온 cgroup 경로는 파드의 `pause` 컨테이너를 포함한다. 파드 레벨의 cgroup은 하나의 디렉터리이다.
```
"cgroupsPath": "/kubepods/podd7f4b509-cf94-4951-9417-d1087c92a5b2/7ccf55aee35dd16aca4189c952d83487297f3cd760f1bbf09620e206e7d0c27a"
```
아래의 특정한 경우에, 파드 cgroup 경로는 `kubepods/podd7f4b509-cf94-4951-9417-d1087c92a5b2` 이다. 메모리의 파드 레벨 cgroup 설정을 확인하자.
```bash
# 파드가 스케줄 된 노드에서 이것을 실행.
# 또한 사용자의 파드에 할당된 cgroup 이름에 맞춰 해당 이름을 수정.
cat /sys/fs/cgroup/memory/kubepods/podd7f4b509-cf94-4951-9417-d1087c92a5b2/memory.limit_in_bytes
```
예상대로 320 MiB 이다.
```
335544320
```
### 관찰성
`kube_pod_overhead` 항목은 [kube-state-metrics](https://github.com/kubernetes/kube-state-metrics)
에서 사용할 수 있어, 파드 오버헤드가 사용되는 시기를 식별하고,
정의된 오버헤드로 실행되는 워크로드의 안정성을 관찰할 수 있다.
이 기능은 kube-state-metrics 의 1.9 릴리스에서는 사용할 수 없지만, 다음 릴리스에서는 가능할 예정이다.
그 전까지는 소스로부터 kube-state-metric 을 빌드해야 한다.
{{% /capture %}}
{{% capture whatsnext %}}
* [런타임클래스](/ko/docs/concepts/containers/runtime-class/)
* [파드오버헤드 디자인](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/20190226-pod-overhead.md)
{{% /capture %}}

View File

@ -0,0 +1,417 @@
---
title: 파드 우선순위(priority)와 선점(preemption)
content_template: templates/concept
weight: 70
---
{{% capture overview %}}
{{< feature-state for_k8s_version="v1.14" state="stable" >}}
[파드](/ko/docs/concepts/workloads/pods/pod/)는 _우선순위_ 를 가질 수 있다. 우선순위는
다른 파드에 대한 상대적인 파드의 중요성을 나타낸다. 파드를 스케줄링할 수 없는 경우,
스케줄러는 우선순위가 낮은 파드를 선점(축출)하여 보류 중인 파드를
스케줄링할 수 있게 한다.
{{% /capture %}}
{{% capture body %}}
{{< warning >}}
모든 사용자를 신뢰할 수 없는 클러스터에서, 악의적인 사용자가 우선순위가
가장 높은 파드를 생성하여 다른 파드가 축출되거나 스케줄링되지
않을 수 있다.
관리자는 리소스쿼터를 사용하여 사용자가 우선순위가 높은 파드를 생성하지
못하게 할 수 있다.
자세한 내용은 [기본적으로 프라이어리티 클래스(Priority Class) 소비 제한](/ko/docs/concepts/policy/resource-quotas/#기본적으로-우선-순위-클래스-소비-제한)을
참고한다.
{{< /warning >}}
## 우선순위와 선점을 사용하는 방법
우선순위와 선점을 사용하려면 다음을 참고한다.
1. 하나 이상의 [프라이어리티클래스](#프라이어리티클래스)를 추가한다.
1. 추가된 프라이어리티클래스 중 하나에 [`priorityClassName`](#파드-우선순위)이 설정된
파드를 생성한다. 물론 파드를 직접 생성할 필요는 없다.
일반적으로 디플로이먼트와 같은 컬렉션 오브젝트의 파드 템플릿에 `priorityClassName`
을 추가한다.
이 단계에 대한 자세한 내용은 계속 읽어보자.
{{< note >}}
쿠버네티스는 이미 `system-cluster-critical``system-node-critical`,
두 개의 프라이어리티클래스를 제공한다.
이들은 일반적인 클래스이며 [중요한(critical) 컴포넌트가 항상 먼저 스케줄링이 되도록 하는 데](/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods/) 사용된다.
{{< /note >}}
기능을 사용해 본 후 사용하지 않기로 했다면, PodPriority
커맨드-라인 플래그를 제거하거나 `false` 로 설정한 후, API 서버와
스케줄러를 다시 시작해야 한다. 기능이 비활성화된 후, 기존 파드는
우선순위 필드를 유지하지만, 선점은 비활성화되며, 우선순위 필드는
무시된다. 이 기능이 비활성화되면, 새로운 파드에서 `priorityClassName` 을 설정할 수
없다.
## 선점을 비활성화하는 방법
{{< caution >}}
중요 파드는 클러스터에 리소스 압박(resource pressure)이 가해지면
스케줄러 선점에 따라 스케줄링된다. 이런 이유로, 선점을 비활성화하지
않는 것을 권장한다.
{{< /caution >}}
{{< note >}}
쿠버네티스 1.15 이상에서, `NonPreemptingPriority` 기능이 활성화된 경우,
프라이어리티클래스는 옵션을 `preemptionPolicy: Never` 로 설정할 수 있다.
이렇게 하면 해당 프라이어리티클래스의 파드가 다른 파드를 축출할 수 없다.
{{< /note >}}
선점은 기본값이 `false`로 설정된 `disablePreemption` kube-scheduler
플래그에 의해 제어된다.
위의 주의에도 불구하고 선점을 비활성화하려는 경우,
`disablePreemption``true` 로 설정할 수 있다.
이 옵션은 컴포넌트 구성에서만 사용할 수 있으며
이전 스타일의 커맨드 라인 옵션에서는 사용할 수 없다. 다음은 선점을 비활성화하는 샘플 컴포넌트
구성이다.
```yaml
apiVersion: kubescheduler.config.k8s.io/v1alpha1
kind: KubeSchedulerConfiguration
algorithmSource:
provider: DefaultProvider
...
disablePreemption: true
```
## 프라이어리티클래스
프라이어리티클래스는 프라이어리티 클래스 이름에서 우선순위의 정수 값으로의 매핑을
정의하는 네임스페이스가 아닌(non-namespaced) 오브젝트이다. 이름은
프라이어리티클래스 오브젝트의 메타데이터의 `name` 필드에 지정된다. 값은
필수 `value` 필드에 지정되어 있다. 값이 클수록, 우선순위가
높다.
프라이어리티클래스 오브젝트의 이름은 유효한
[DNS 서브 도메인 이름](/ko/docs/concepts/overview/working-with-objects/names/#dns-서브도메인-이름)이어야 하며,
`system-` 접두사를 붙일 수 없다.
프라이어리티클래스 오브젝트는 10억 이하의 32비트 정수 값을 가질
수 있다. 일반적으로 선점하거나 축출해서는 안되는 중요한 시스템 파드에는 더 큰 숫자가
예약되어 있다. 클러스터 관리자는 원하는 각 매핑에 대해 프라이어리티클래스 오브젝트를
하나씩 생성해야 한다.
프라이어리티클래스에는 `globalDefault``description` 두 개의 선택적인 필드도 있다.
`globalDefault` 필드는 이 프라이어리티클래스의 값을 `priorityClassName` 이 없는
파드에 사용해야 함을 나타낸다. 시스템에서 `globalDefault``true` 로 설정된
프라이어리티클래스는 하나만 존재할 수 있다. `globalDefault` 가 설정된
프라이어리티클래스가 없을 경우, `priorityClassName` 이 없는 파드의
우선순위는 0이다.
`description` 필드는 임의의 문자열이다. 이 필드는 이 프라이어리티클래스를 언제
사용해야 하는지를 클러스터 사용자에게 알려주기 위한 것이다.
### PodPriority와 기존 클러스터에 대한 참고 사항
- 기존 클러스터를 업그레이드하고 이 기능을 활성화하면, 기존 파드의
우선순위는 사실상 0이다.
- `globalDefault``true` 로 설정된 프라이어리티클래스를 추가해도 기존 파드의
우선순위는 변경되지 않는다. 이러한 프라이어리티클래스의 값은
프라이어리티클래스를 추가한 후 생성된 파드에만 사용된다.
- 프라이어리티클래스를 삭제하면, 삭제된 프라이어리티클래스의 이름을 사용하는
기존 파드는 변경되지 않고 남아있지만, 삭제된 프라이어리티클래스의 이름을
사용하는 파드는 더 이상 생성할 수 없다.
### 프라이어리티클래스 예제
```yaml
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority
value: 1000000
globalDefault: false
description: "이 프라이어리티 클래스는 XYZ 서비스 파드에만 사용해야 한다."
```
## 비-선점 프라이어리티클래스 {#non-preempting-priority-class}
{{< feature-state for_k8s_version="v1.15" state="alpha" >}}
`PreemptionPolicy: Never` 를 가진 파드는 낮은 우선순위 파드의 스케줄링 대기열의
앞쪽에 배치되지만,
그 파드는 다른 파드를 축출할 수 없다.
스케줄링 대기 중인 비-선점 파드는 충분한 리소스가 확보되고
스케줄링될 수 있을 때까지
스케줄링 대기열에 대기한다.
다른 파드와 마찬가지로,
비-선점 파드는
스케줄러 백오프(back-off)에 종속된다.
이는 스케줄러가 이러한 파드를 스케줄링하려고 시도하고 스케줄링할 수 없는 경우,
더 적은 횟수로 재시도하여,
우선순위가 낮은 다른 파드를 미리 스케줄링할 수 있음을 의미한다.
비-선점 파드는 다른 우선순위가 높은 파드에 의해
축출될 수 있다.
`PreemptionPolicy` 는 기본값으로 `PreemptLowerPriority` 로 설정되어,
해당 프라이어리티클래스의 파드가 우선순위가 낮은 파드를 축출할 수
있다(기존의 기본 동작과 동일).
`PreemptionPolicy``Never` 로 설정된 경우,
해당 프라이어리티클래스의 파드는 비-선점될 것이다.
`PreemptionPolicy` 필드를 사용하려면 `NonPreemptingPriority`
[기능 게이트](/docs/reference/command-line-tools-reference/feature-gates/)가
활성화되어야 한다.
예제 유스케이스는 데이터 과학 관련 워크로드이다.
사용자는 다른 워크로드보다 우선순위가 높은 잡(job)을 제출할 수 있지만,
실행 중인 파드를 축출하여 기존의 작업을 삭제하지는 않을 것이다.
클러스터 리소스가 "자연스럽게" 충분히 사용할 수 있게 되면,
`PreemptionPolicy: Never` 의 우선순위가 높은 잡이
다른 대기 중인 파드보다 먼저 스케줄링된다.
### 비-선점 프라이어리티클래스 예제
```yaml
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority-nonpreempting
value: 1000000
preemptionPolicy: Never
globalDefault: false
description: "이 프라이어리티 클래스는 다른 파드를 축출하지 않는다."
```
## 파드 우선순위
프라이어리티클래스가 하나 이상 있으면, 그것의 명세에서 이들 프라이어리티클래스 이름 중 하나를
지정하는 파드를 생성할 수 있다. 우선순위 어드미션
컨트롤러는 `priorityClassName` 필드를 사용하고 우선순위의 정수 값을
채운다. 프라이어리티 클래스를 찾을 수 없으면, 파드가 거부된다.
다음의 YAML은 이전 예제에서 생성된 프라이어리티클래스를
사용하는 파드 구성의 예이다. 우선순위 어드미션 컨트롤러는
명세를 확인하고 파드의 우선순위를 1000000으로
해석한다.
```yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
priorityClassName: high-priority
```
### 스케줄링 순서에 대한 파드 우선순위의 영향
파드 우선순위가 활성화되면, 스케줄러가 우선순위에 따라 보류 중인
파드를 주문하고 보류 중인 파드는 스케줄링 대기열에서
우선순위가 낮은 다른 보류 중인 파드보다 우선한다. 결과적으로, 스케줄링
요구 사항이 충족되는 경우 우선순위가 더 낮은 파드보다 우선순위가 높은 파드가
더 빨리 스케줄링될 수 있다. 이러한 파드를 스케줄링할 수 없는 경우,
스케줄러는 계속 진행하고 우선순위가 낮은 다른 파드를 스케줄링하려고 한다.
## 선점
파드가 생성되면, 대기열로 이동하여 스케줄링을 기다린다.
스케줄러가 대기열에서 파드를 선택하여 노드에 스케줄링하려고 한다.
파드의 지정된 모든 요구 사항을 충족하는 노드가 없으면,
보류 중인 파드에 대해 선점 로직이 트리거된다. 보류 중인 파드를 P라 하자.
선점 로직은 P보다 우선순위가 낮은 하나 이상의 파드를 제거하면
해당 노드에서 P를 스케줄링할 수 있는 노드를 찾는다. 이러한
노드가 발견되면, 하나 이상의 우선순위가 낮은 파드가 노드에서 축출된다.
파드가 축출된 후, P는 노드에 스케줄링될 수 있다.
### 사용자 노출 정보
파드 P가 노드 N에서 하나 이상의 파드를 축출할 경우, 파드 P의 상태 `nominatedNodeName`
필드는 노드 N의 이름으로 설정된다. 이 필드는 스케줄러가 파드 P에
예약된 리소스를 추적하는 데 도움이 되고 사용자에게 클러스터의 선점에 대한
정보를 제공한다.
파드 P는 반드시 "지정된 노드"로 스케줄링되지는 않는다.
피해자 파드가 축출된 후, 그것은 정상적(graceful)으로 종료되는 기간을 갖는다.
스케줄러가 종료될 피해자 파드를 기다리는 동안 다른 노드를 사용할 수
있게 되면, 스케줄러는 파드 P를 스케줄링하기 위해 다른 노드를 사용한다. 그 결과,
파드 스펙의 `nominatedNodeName``nodeName` 은 항상 동일하지 않다. 또한,
스케줄러가 노드 N에서 파드를 축출했지만, 파드 P보다 우선순위가 높은 파드가
도착하면, 스케줄러가 노드 N에 새로운 우선순위가 높은 파드를 제공할 수 있다. 이러한
경우, 스케줄러는 파드 P의 `nominatedNodeName` 을 지운다. 이렇게하면, 스케줄러는
파드 P가 다른 노드에서 파드를 축출할 수 있도록 한다.
### 선점의 한계
#### 선점 피해자의 정상적인 종료
파드가 축출되면, 축출된 피해자 파드는
[정상적인 종료 기간](/ko/docs/concepts/workloads/pods/pod/#파드의-종료)을 가진다.
피해자 파드는 작업을 종료하고 빠져나가는 데(exit) 많은 시간을 가진다. 그렇지 않으면,
파드는 강제종료(kill) 된다. 이 정상적인 종료 기간은 스케줄러가 파드를 축출하는
지점과 보류 중인 파드(P)를 노드(N)에서 스케줄링할 수 있는 시점 사이의
시간 간격을 만든다. 그 동안, 스케줄러는 보류 중인 다른 파드를
계속 스케줄링한다. 피해자 파드가 빠져나가거나 종료되면, 스케줄러는 보류 대기열에서
파드를 스케줄하려고 한다. 따라서, 일반적으로 스케줄러가 피해자 파드를 축출하는 시점과
파드 P가 스케줄링된 시점 사이에 시간 간격이 있다.
이러한 차이를 최소화하기 위해, 우선순위가 낮은 파드의 정상적인 종료 기간을 0 또는
작은 수로 설정할 수 있다.
#### PodDisruptionBudget을 지원하지만, 보장하지 않음
[Pod Disruption Budget(PDB)](/ko/docs/concepts/workloads/pods/disruptions/)은
애플리케이션 소유자가 자발적 중단에서 동시에 다운된 복제된
애플리케이션의 파드 수를 제한할 수 있다. 쿠버네티스는 파드를
선점할 때 PDB를 지원하지만, PDB를 따르는 것이 최선의 노력이다. 스케줄러는
선점에 의해 PDB를 위반하지 않은 피해자 파드를 찾으려고 하지만, 그러한 피해자 파드가
발견되지 않으면, 선점은 여전히 발생하며, PDB를 위반하더라도 우선순위가
낮은 파드는 제거된다.
#### 우선순위가 낮은 파드에 대한 파드-간 어피니티
이 질문에 대한 답변이 '예'인 경우에만 노드가 선점 대상으로 간주된다.
"대기 중인 파드보다 우선순위가 낮은 모든 파드가 노드에서
제거되면, 보류 중인 파드를 노드에 스케줄링할 수 있습니까?"
{{< note >}}
선점으로 우선순위가 낮은 모든 파드를 반드시 제거할 필요는
없다. 우선순위가 낮은 모든 파드보다 적은 수를 제거하여 보류 중인 파드를
스케줄링할 수 있는 경우, 우선순위가 낮은 파드의 일부만 제거된다.
그럼에도 불구하고, 앞의 질문에 대한 대답은 '예'여야 한다. 답변이 '아니오'인 경우,
노드가 선점 대상으로 간주되지 않는다.
{{< /note >}}
보류 중인 파드가 노드에 있는 하나 이상의 우선순위가 낮은 파드에 대한 파드-간 어피니티를
가진 경우에, 우선순위가 낮은 파드가 없을 때 파드-간 어피니티 규칙을
충족할 수 없다. 이 경우, 스케줄러는 노드의 파드를 축출하지
않는다. 대신, 다른 노드를 찾는다. 스케줄러가
적합한 노드를 찾거나 찾지 못할 수 있다. 보류 중인 파드를 스케줄링할 수 있다는
보장은 없다.
이 문제에 대한 권장 솔루션은 우선순위가 같거나 높은 파드에 대해서만 파드-간 어피니티를
생성하는 것이다.
#### 교차 노드 선점
보류 중인 파드 P가 노드 N에 스케줄링될 수 있도록 노드 N이 선점 대상으로 고려되고
있다고 가정한다. 다른 노드의 파드가 축출된 경우에만 P가 N에서 실행 가능해질 수
있다. 예를 들면 다음과 같다.
* 파드 P는 노드 N에 대해 고려된다.
* 파드 Q는 노드 N과 동일한 영역의 다른 노드에서 실행 중이다.
* 파드 P는 파드 Q(`topologyKey:
failure-domain.beta.kubernetes.io/zone`)와 영역(zone) 전체의 안티-어피니티를 갖는다.
* 영역에서 파드 P와 다른 파드 간의 안티-어피니티에 대한 다른 경우는
없다.
* 노드 N에서 파드 P를 스케줄링하기 위해, 파드 Q를 축출할 수 있지만, 스케줄러는
교차-노드 선점을 수행하지 않는다. 따라서, 파드 P가 노드 N에서
스케줄링할 수 없는 것으로 간주된다.
파드 Q가 노드에서 제거되면, 파드 안티-어피니티 위반이
사라지고, 파드 P는 노드 N에서 스케줄링될 수 있다.
수요가 충분하고 합리적인 성능의 알고리즘을 찾을 경우
향후 버전에서 교차 노드 선점의 추가를 고려할 수 있다.
## 문제 해결
파드 우선순위와 선점은 원하지 않는 부작용을 가질 수 있다. 다음은
잠재적 문제의 예시와 이를 해결하는 방법이다.
### 파드가 불필요하게 선점(축출)됨
선점은 우선순위가 높은 보류 중인 파드를 위한 공간을 만들기 위해 리소스 압박을 받고 있는
클러스터에서 기존 파드를 제거한다. 실수로 특정 파드에 높은 우선순위를
부여하면, 의도하지 않은 높은 우선순위 파드가 클러스터에서
선점을 유발할 수 있다. 파드 우선순위는 파드 명세에서
`priorityClassName` 필드를 설정하여 지정한다. 그런 다음
우선순위의 정수 값이 분석되어 `podSpec``priority` 필드에 채워진다.
문제를 해결하기 위해, 해당 파드가 우선순위가 낮은 클래스를 사용하도록 `priorityClassName`
변경하거나, 해당 필드를 비워둘 수 있다. 빈
`priorityClassName` 은 기본값이 0으로 해석된다.
파드가 축출되면, 축출된 파드에 대한 이벤트가 기록된다.
선점은 클러스터가 파드에 대한 리소스를 충분히 가지지 못한 경우에만
발생한다. 이러한 경우, 선점은 보류 중인 파드(선점자)의 우선순위가
피해자 파드보다 높은 경우에만 발생한다. 보류 중인 파드가 없거나,
보류 중인 파드의 우선순위가 피해자 파드와 같거나 낮은 경우
선점이 발생하지 않아야 한다. 그러한 시나리오에서 선점이 발생하면, 이슈를 올리기 바란다.
### 파드가 축출되었지만, 선점자는 스케줄링되지 않음
파드가 축출되면, 요청된 정상적인 종료
기간(기본적으로 30초)이 주어진다. 이 기간 내에 대상 파드가
종료되지 않으면, 강제 종료된다. 모든 피해자 파드가 사라지면,
선점자 파드를 스케줄링할 수 있다.
선점자 파드가 피해자 파드가 없어지기를 기다리는 동안, 동일한 노드에
적합한 우선순위가 높은 파드가 생성될 수 있다. 이 경우, 스케줄러는
선점자 대신 우선순위가 높은 파드를 스케줄링한다.
이것은 예상된 동작이다. 우선순위가 높은 파드는 우선순위가 낮은 파드를
대체해야 한다. [클러스터 오토스케일링](/ko/docs/tasks/administer-cluster/cluster-management/#클러스터-오토스케일링)과
같은 다른 컨트롤러 작업은,
결국 보류 중인 파드를 스케줄링할 수 있는 용량을 제공할 수 있다.
### 우선순위가 높은 파드는 우선순위가 낮은 파드보다 우선함
스케줄러가 보류 중인 파드를 실행할 수 있는 노드를 찾으려고 한다. 노드를 찾지
못하면, 스케줄러는 임의의 노드에서 우선순위가 낮은 파드를 제거하여
보류 중인 파드를 위한 공간을 만든다.
우선순위가 낮은 파드가 있는 노드가 보류 중인 파드를 실행할 수 없는 경우, 스케줄러는
선점을 위해 우선순위가 높은 다른 노드(다른 노드의 파드와 비교)를
선택할 수 있다. 피해자 파드는 여전히 선점자 파드보다 우선순위가
낮아야 한다.
선점할 수 있는 여러 노드가 있는 경우, 스케줄러는
우선순위가 가장 낮은 파드 세트를 가진 노드를 선택하려고 한다. 그러나,
이러한 파드가 위반될 PodDisruptionBudget을 가지고 있고 축출된 경우
스케줄러는 우선순위가 높은 파드를 가진 다른 노드를 선택할 수 있다.
선점을 위해 여러 개의 노드가 존재하고 위의 시나리오 중 어느 것도 적용되지 않는 경우,
스케줄러는 우선순위가 가장 낮은 노드를 선택한다.
## 파드 우선순위와 서비스 품질 간의 상호 작용 {#interactions-of-pod-priority-and-qos}
파드 우선순위와 {{< glossary_tooltip text="QoS 클래스" term_id="qos-class" >}}는
상호 작용이 거의 없고 QoS 클래스를 기반으로 파드 우선순위를 설정하는 데 대한
기본 제한이 없는 두 개의 직교(orthogonal) 기능이다. 스케줄러의
선점 로직은 선점 대상을 선택할 때 QoS를 고려하지 않는다.
선점은 파드 우선순위를 고려하고 우선순위가 가장 낮은 대상 세트를
선택하려고 한다. 우선순위가 가장 높은 파드는 스케줄러가
선점자 파드를 스케줄링할 수 없거나 우선순위가 가장 낮은 파드가
`PodDisruptionBudget` 으로 보호되는 경우에만, 우선순위가 가장 낮은 파드를
축출 대상으로 고려한다.
QoS와 파드 우선순위를 모두 고려하는 유일한 컴포넌트는
[kubelet 리소스 부족 축출](/docs/tasks/administer-cluster/out-of-resource/)이다.
kubelet은 부족한 리소스의 사용이 요청을 초과하는지 여부에 따라, 그런 다음 우선순위에 따라,
파드의 스케줄링 요청에 대한 부족한 컴퓨팅 리소스의 소비에 의해
먼저 축출 대상 파드의 순위를 매긴다.
더 자세한 내용은
[엔드유저 파드 축출](/docs/tasks/administer-cluster/out-of-resource/#evicting-end-user-pods)을
참조한다.
kubelet 리소스 부족 축출은 사용량이 요청을 초과하지 않는 경우
파드를 축출하지 않는다. 우선순위가 낮은 파드가 요청을
초과하지 않으면, 축출되지 않는다. 요청을 초과하는 우선순위가
더 높은 다른 파드가 축출될 수 있다.
{{% /capture %}}
{{% capture whatsnext %}}
* 프라이어리티클래스와 관련하여 리소스쿼터 사용에 대해 [기본적으로 프라이어리티 클래스 소비 제한](/ko/docs/concepts/policy/resource-quotas/#기본적으로-우선-순위-클래스-소비-제한)을 읽어보자.
{{% /capture %}}

View File

@ -1,7 +1,7 @@
---
title: 확장된 리소스를 위한 리소스 빈 패킹(bin packing)
content_template: templates/concept
weight: 10
weight: 50
---
{{% capture overview %}}

View File

@ -198,7 +198,7 @@ tolerations:
## 테인트 기반 축출
{{< feature-state for_k8s_version="1.18" state="stable" >}}
{{< feature-state for_k8s_version="v1.18" state="stable" >}}
앞에서 우리는 노드에서 이미 실행 중인 파드에 영향을 주는 `NoExecute` 테인트 이펙트를
다음과 같이 언급했다.

View File

@ -78,7 +78,7 @@ _선언_ 하거나 지정할 수 있게 해주며 쿠버네티스 오브젝트
- 클라이언트는 "이 작업을 수행한다"라고 말하고 완료되면 동기(synchronous) 응답을 받는다.
- 클라이언트는 "이 작업을 수행한다"라고 말한 다음 작업 ID를 다시 가져오고 별도의 오퍼레이션(operation) 오브젝트를 확인하여 요청의 완료 여부를 결정해야 한다.
- RPC(원격 프로시저 호출)에 대해 얘기한다.
- 대량의 데이터를 직접 저장한다(예: > 오브젝트별 몇 kB 또는 >1000개의 오브젝트).
- 대량의 데이터를 직접 저장한다. 예: > 오브젝트별 몇 kB 또는 > 1000개의 오브젝트.
- 높은 대역폭 접근(초당 10개의 지속적인 요청)이 필요하다.
- 최종 사용자 데이터(예: 이미지, PII 등) 또는 애플리케이션에서 처리한 기타 대규모 데이터를 저장한다.
- 오브젝트에 대한 자연스러운 조작은 CRUD-y가 아니다.
@ -102,7 +102,7 @@ _선언_ 하거나 지정할 수 있게 해주며 쿠버네티스 오브젝트
다음 중 대부분이 적용되는 경우 커스텀 리소스(CRD 또는 애그리게이트 API(aggregated API))를 사용하자.
* 쿠버네티스 클라이언트 라이브러리 및 CLI를 사용하여 새 리소스를 만들고 업데이트하려고 한다.
* kubectl의 최상위 지원을 원한다(예: `kubectl get my-object object-name`).
* `kubectl` 의 최상위 지원을 원한다. 예: `kubectl get my-object object-name`.
* 새 오브젝트에 대한 업데이트를 감시한 다음 다른 오브젝트를 CRUD하거나 그 반대로 하는 새로운 자동화를 구축하려고 한다.
* 오브젝트의 업데이트를 처리하는 자동화를 작성하려고 한다.
* `.spec`, `.status``.metadata`와 같은 쿠버네티스 API 규칙을 사용하려고 한다.
@ -214,7 +214,7 @@ CRD 또는 AA를 통해 커스텀 리소스를 생성하면 쿠버네티스 플
### 써드파티 코드 및 새로운 장애 포인트
CRD를 생성해도 새로운 장애 포인트(예를 들어, API 서버에서 장애를 유발하는 써드파티 코드가 실행됨)가 자동으로 추가되지는 않지만, 패키지(예: 차트(Charts)) 또는 기타 설치 번들에는 CRD 및 새로운 커스텀 리소스에 대한 비즈니스 로직을 구현하는 써드파티 코드의 디플로이먼트가 포함되는 경우가 종종 있다.
CRD를 생성해도 새로운 장애 포인트(예를 들어, API 서버에서 장애를 유발하는 써드파티 코드가 실행됨)가 자동으로 추가되지는 않지만, 패키지(예: 차트(Charts)) 또는 기타 설치 번들에는 CRD 및 새로운 커스텀 리소스에 대한 비즈니스 로직을 구현하는 써드파티 코드의 디플로이먼트가 포함되는 경우가 종종 있다.
애그리게이트 API 서버를 설치하려면 항상 새 디플로이먼트를 실행해야 한다.
@ -234,11 +234,11 @@ CRD는 항상 API 서버의 빌트인 리소스와 동일한 인증, 권한 부
## 커스텀 리소스에 접근
쿠버네티스 [클라이언트 라이브러리](/docs/reference/using-api/client-libraries/)를 사용하여 커스텀 리소스에 접근할 수 있다. 모든 클라이언트 라이브러리가 커스텀 리소스를 지원하는 것은 아니다. Go와 python 클라이언트 라이브러리가 지원한다.
쿠버네티스 [클라이언트 라이브러리](/docs/reference/using-api/client-libraries/)를 사용하여 커스텀 리소스에 접근할 수 있다. 모든 클라이언트 라이브러리가 커스텀 리소스를 지원하는 것은 아니다. _Go_ _python_ 클라이언트 라이브러리가 지원한다.
커스텀 리소스를 추가하면 다음을 사용하여 접근할 수 있다.
- kubectl
- `kubectl`
- 쿠버네티스 동적 클라이언트
- 작성한 REST 클라이언트
- [쿠버네티스 클라이언트 생성 도구](https://github.com/kubernetes/code-generator)를 사용하여 생성된 클라이언트(하나를 생성하는 것은 고급 기능이지만, 일부 프로젝트는 CRD 또는 AA와 함께 클라이언트를 제공할 수 있다).

View File

@ -56,18 +56,19 @@ card:
### cloud-controller-manager
[cloud-controller-manager](/docs/tasks/administer-cluster/running-cloud-controller/)는 바탕을 이루는 클라우드 제공사업자와 상호작용하는 컨트롤러를 작동시킨다. cloud-controller-manager 바이너리는 쿠버네티스 릴리스 1.6에서 도입된 알파 기능이다.
cloud-controller-manager는 클라우드 제공자 전용 컨트롤러만 실행한다.
자신의 사내 또는 PC 내부의 학습 환경에서 쿠버네티스를 실행 중인 경우
클러스터에는 클라우드 컨트롤러 매니저가 없다.
cloud-controller-manager는 클라우드-제공사업자-특유 컨트롤러 루프만을 동작시킨다. 이 컨트롤러 루프는 kube-controller-manager에서 비활성 시켜야만 한다. kube-controller-manager를 구동시킬 때 `--cloud-provider` 플래그를 `external`로 설정함으로써 이 컨트롤러 루프를 비활성 시킬 수 있다.
kube-controller-manager와 마찬가지로 cloud-controller-manager는 논리적으로
독립적인 여러 컨트롤 루프를 단일 프로세스로 실행하는 단일 바이너리로 결합한다.
수평으로 확장(두 개 이상의 복제 실행)해서 성능을 향상시키거나 장애를 견딜 수 있다.
cloud-controller-manager는 클라우드 벤더 코드와 쿠버네티스 코드가 서로 독립적으로 발전시켜 나갈 수 있도록 해준다. 이전 릴리스에서는 코어 쿠버네티스 코드가 기능상으로 클라우드-제공사업자-특유 코드에 대해 의존적이었다. 향후 릴리스에서 클라우드 벤더만의 코드는 클라우드 벤더가 유지해야 하며, 쿠버네티스가 동작하는 동안 cloud-controller-manager에 연계되도록 해야 한다.
다음 컨트롤러들은 클라우드 제공 사업자의 의존성을 가질 수 있다.
다음 컨트롤러들은 클라우드 제공사업자의 의존성을 갖는다.
* 노드 컨트롤러: 노드가 응답을 멈춘 후 클라우드 상에서 삭제되었는지 판별하기 위해 클라우드 제공사업자에게 확인하는 것
* 노드 컨트롤러: 노드가 응답을 멈춘 후 클라우드 상에서 삭제되었는지 판별하기 위해 클라우드 제공 사업자에게 확인하는 것
* 라우트 컨트롤러: 기본 클라우드 인프라에 경로를 구성하는 것
* 서비스 컨트롤러: 클라우드 제공사업자 로드밸런서를 생성, 업데이트 그리고 삭제하는 것
* 볼륨 컨트롤러: 볼륨의 생성, 연결 그리고 마운트 하는 것과 오케스트레이션하기 위해 클라우드 제공사업자와 상호작용하는 것
* 서비스 컨트롤러: 클라우드 제공 사업자 로드밸런서를 생성, 업데이트 그리고 삭제하는 것
## 노드 컴포넌트
@ -121,6 +122,6 @@ cloud-controller-manager는 클라우드 벤더 코드와 쿠버네티스 코드
{{% capture whatsnext %}}
* [노드](/ko/docs/concepts/architecture/nodes/)에 대해 더 배우기
* [컨트롤러](/ko/docs/concepts/architecture/controller/)에 대해 더 배우기
* [kube-scheduler](/ko/docs/concepts/scheduling/kube-scheduler/)에 대해 더 배우기
* [kube-scheduler](/ko/docs/concepts/scheduling-eviction/kube-scheduler/)에 대해 더 배우기
* etcd의 공식 [문서](https://etcd.io/docs/) 읽기
{{% /capture %}}

View File

@ -32,8 +32,8 @@ card:
원하는 특징(_의도한 상태_)에 대한 설명을
제공해서 설정한다.
`status`는 오브젝트의 _현재 상태_ 를 기술하고, 쿠버네티스
컴포넌트에 의해 제공되고 업데이트 된다. 쿠버네티스
`status` 는 쿠버네티스 시스템과 컴포넌트에 의해 제공되고
업데이트된 오브젝트의 _현재 상태_ 를 설명한다. 쿠버네티스
{{< glossary_tooltip text="컨트롤 플레인" term_id="control-plane" >}}은 모든 오브젝트의
실제 상태를 사용자가 의도한 상태와 일치시키기 위해 끊임없이 그리고
능동적으로 관리한다.
@ -93,4 +93,3 @@ deployment.apps/nginx-deployment created
* [파드(Pod)](/ko/docs/concepts/workloads/pods/pod-overview/)와 같이, 가장 중요하고 기본적인 쿠버네티스 오브젝트에 대해 배운다.
* 쿠버네티스의 [컨트롤러](/ko/docs/concepts/architecture/controller/)에 대해 배운다.
{{% /capture %}}

View File

@ -7,7 +7,7 @@ weight: 10
{{% capture overview %}}
기본적으로 컨테이너는 쿠버네티스 클러스터에서 무제한 [컴퓨팅 리소스](/docs/user-guide/compute-resources)로 실행된다.
리소스 쿼터을 사용하면 클러스터 관리자는 네임스페이스별로 리소스 사용과 생성을 제한할 수 있다.
리소스 쿼터을 사용하면 클러스터 관리자는 {{< glossary_tooltip text="네임스페이스" term_id="namespace" >}}별로 리소스 사용과 생성을 제한할 수 있다.
네임스페이스 내에서 파드나 컨테이너는 네임스페이스의 리소스 쿼터에 정의된 만큼의 CPU와 메모리를 사용할 수 있다. 하나의 파드 또는 컨테이너가 사용 가능한 모든 리소스를 독점할 수 있다는 우려가 있다. 리밋레인지는 네임스페이스에서 리소스 할당(파드 또는 컨테이너)을 제한하는 정책이다.
{{% /capture %}}
@ -30,16 +30,16 @@ _리밋레인지_ 는 다음과 같은 제약 조건을 제공한다.
리밋레인지 오브젝트의 이름은 유효한 [DNS 서브도메인 이름](/ko/docs/concepts/overview/working-with-objects/names/#dns-서브도메인-이름)이어야한다.
### 범위 제한의 개요
### 리밋 레인지 개요
- 관리자는 하나의 네임스페이스에 하나의 `LimitRange`를 만든다.
- 관리자는 하나의 네임스페이스에 하나의 리밋레인지를 만든다.
- 사용자는 네임스페이스에서 파드, 컨테이너 및 퍼시스턴트볼륨클레임과 같은 리소스를 생성한다.
- `LimitRanger` 어드미션 컨트롤러는 컴퓨팅 리소스 요청 사항을 설정하지 않은 모든 파드와 컨테이너에 대한 기본값과 제한을 지정하고 네임스페이스의 리밋레인지에 정의된 리소스의 최소, 최대 및 비율을 초과하지 않도록 사용량을 추적한다.
- 리밋레인지 제약 조건을 위반하는 리소스(파드, 컨테이너, 퍼시스턴트볼륨클레임)를 생성하거나 업데이트하는 경우 HTTP 상태 코드 `403 FORBIDDEN` 및 위반된 제약 조건을 설명하는 메시지와 함께 API 서버에 대한 요청이 실패한다.
- `cpu`, `memory`와 같은 컴퓨팅 리소스의 네임스페이스에서 리밋레인지가 활성화된 경우 사용자는 해당 값에 대한 요청 또는 제한을 지정해야 한다. 그렇지 않으면 시스템에서 파드 생성이 거부될 수 있다.
- 리밋레인지 유효성 검사는 파드 실행 단계가 아닌 파드 어드미션 단계에서만 발생한다.
범위 제한을 사용하여 생성할 수 있는 정책의 예는 다음과 같다.
리밋 레인지를 사용하여 생성할 수 있는 정책의 예는 다음과 같다.
- 용량이 8GiB RAM과 16 코어인 2 노드 클러스터에서 네임스페이스의 파드를 제한하여 CPU의 최대 제한이 500m인 CPU 100m를 요청하고 메모리의 최대 제한이 600M인 메모리 200Mi를 요청하라.
- 스펙에 CPU 및 메모리 요청없이 시작된 컨테이너에 대해 기본 CPU 제한 및 요청을 150m로, 메모리 기본 요청을 300Mi로 정의하라.
@ -49,19 +49,20 @@ _리밋레인지_ 는 다음과 같은 제약 조건을 제공한다.
경합이나 리밋레인지 변경은 이미 생성된 리소스에 영향을 미치지 않는다.
## 예제
- [네임스페이스당 최소 및 최대 CPU 제약 조건을 설정하는 방법](/docs/tasks/administer-cluster/manage-resources/cpu-constraint-namespace/)을 본다.
- [네임스페이스당 최소 및 최대 메모리 제약 조건을 설정하는 방법](/docs/tasks/administer-cluster/manage-resources/memory-constraint-namespace/)을 본다.
- [네임스페이스당 기본 CPU 요청과 제한을 설정하는 방법](/docs/tasks/administer-cluster/manage-resources/cpu-default-namespace/)을 본다.
- [네임스페이스당 기본 메모리 요청과 제한을 설정하는 방법](/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/)을 본다.
- [네임스페이스당 최소 및 최대 스토리지 사용량을 설정하는 방법](/docs/tasks/administer-cluster/limit-storage-consumption/#limitrange-to-limit-requests-for-storage)을 확인한다.
- [네임스페이스당 할당량을 설정하는 자세한 예시](/docs/tasks/administer-cluster/quota-memory-cpu-namespace/)를 본다.
{{% /capture %}}
{{% capture whatsnext %}}
보다 자세한 내용은 [LimitRanger 설계 문서](https://git.k8s.io/community/contributors/design-proposals/resource-management/admission_control_limit_range.md)를 참고하길 바란다.
자세한 내용은 [LimitRanger 디자인 문서](https://git.k8s.io/community/contributors/design-proposals/resource-management/admission_control_limit_range.md)를 참조한다.
제한의 사용에 대한 예시는 다음을 참조한다.
- [네임스페이스당 최소 및 최대 CPU 제약 조건을 설정하는 방법](/docs/tasks/administer-cluster/manage-resources/cpu-constraint-namespace/).
- [네임스페이스당 최소 및 최대 메모리 제약 조건을 설정하는 방법](/docs/tasks/administer-cluster/manage-resources/memory-constraint-namespace/).
- [네임스페이스당 기본 CPU 요청과 제한을 설정하는 방법](/docs/tasks/administer-cluster/manage-resources/cpu-default-namespace/).
- [네임스페이스당 기본 메모리 요청과 제한을 설정하는 방법](/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/).
- [네임스페이스당 최소 및 최대 스토리지 사용량을 설정하는 방법](/docs/tasks/administer-cluster/limit-storage-consumption/#limitrange-to-limit-requests-for-storage).
- [네임스페이스당 할당량을 설정하는 자세한 예시](/docs/tasks/administer-cluster/quota-memory-cpu-namespace/).
{{% /capture %}}

View File

@ -193,7 +193,7 @@ GPU 리소스를 다음과 같이 쿼터를 정의할 수 있다.
### PriorityClass별 리소스 쿼터
{{< feature-state for_k8s_version="1.12" state="beta" >}}
{{< feature-state for_k8s_version="v1.12" state="beta" >}}
특정 [우선 순위](/docs/concepts/configuration/pod-priority-preemption/#pod-priority)로 파드를 생성할 수 있다.
쿼터 스펙의 `scopeSelector` 필드를 사용하여 파드의 우선 순위에 따라 파드의 시스템 리소스 사용을

View File

@ -0,0 +1,4 @@
---
title: "스케줄링과 축출(eviction)"
weight: 90
---

View File

@ -1,5 +0,0 @@
---
title: "스케줄링"
weight: 90
---

View File

@ -140,8 +140,8 @@ RBAC 인증(쿠버네티스 API에 대한 접근) | https://kubernetes.io/docs/r
TLS를 통한 접근 | 코드가 TCP를 통해 통신해야 한다면, 클라이언트와 먼저 TLS 핸드 셰이크를 수행하는 것이 이상적이다. 몇 가지 경우를 제외하고, 기본 동작은 전송 중인 모든 것을 암호화하는 것이다. 한걸음 더 나아가, VPC의 "방화벽 뒤"에서도 서비스 간 네트워크 트래픽을 암호화하는 것이 좋다. 이것은 인증서를 가지고 있는 두 서비스의 양방향 검증을 [mTLS](https://en.wikipedia.org/wiki/Mutual_authentication)를 통해 수행할 수 있다. 이것을 수행하기 위해 쿠버네티스에는 [Linkerd](https://linkerd.io/) 및 [Istio](https://istio.io/)와 같은 수많은 도구가 있다. |
통신 포트 범위 제한 | 이 권장사항은 당연할 수도 있지만, 가능하면 통신이나 메트릭 수집에 꼭 필요한 서비스의 포트만 노출시켜야 한다. |
타사 종속성 보안 | 애플리케이션은 자체 코드베이스의 외부에 종속적인 경향이 있기 때문에, 코드의 종속성을 정기적으로 스캔하여 현재 알려진 취약점이 없는지 확인하는 것이 좋다. 각 언어에는 이런 검사를 자동으로 수행하는 도구를 가지고 있다. |
정적 코드 분석 | 대부분 언어에는 잠재적으로 안전하지 않은 코딩 방법에 대해 코드 스니펫을 분석할 수 있는 방법을 제공한다. 가능한 언제든지 일반적인 보안 오류에 대해 코드베이스를 스캔할 수 있는 자동화된 도구를 사용하여 검사를 한다. 도구는 다음에서 찾을 수 있다: https://www.owasp.org/index.php/Source_Code_Analysis_Tools |
동적 탐지 공격 | 일반적으로 서비스에서 발생할 수 있는 잘 알려진 공격 중 일부를 서비스에 테스트할 수 있는 자동화된 몇 가지 도구가 있다. 이런 잘 알려진 공격에는 SQL 인젝션, CSRF 및 XSS가 포함된다. 가장 널리 사용되는 동적 분석 도구는 OWASP Zed Attack 프록시다. https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project |
정적 코드 분석 | 대부분 언어에는 잠재적으로 안전하지 않은 코딩 방법에 대해 코드 스니펫을 분석할 수 있는 방법을 제공한다. 가능한 언제든지 일반적인 보안 오류에 대해 코드베이스를 스캔할 수 있는 자동화된 도구를 사용하여 검사를 한다. 도구는 다음에서 찾을 수 있다. https://owasp.org/www-community/Source_Code_Analysis_Tools |
동적 탐지 공격 | 일반적으로 서비스에서 발생할 수 있는 잘 알려진 공격 중 일부를 서비스에 테스트할 수 있는 자동화된 몇 가지 도구가 있다. 이런 잘 알려진 공격에는 SQL 인젝션, CSRF 및 XSS가 포함된다. 가장 널리 사용되는 동적 분석 도구는 OWASP Zed Attack 프록시다. https://owasp.org/www-project-zap/ |
## 강력한(robust) 자동화

View File

@ -164,7 +164,7 @@ DNS 정책은 파드별로 설정할 수 있다. 현재 쿠버네티스는 다
일치하지 않는 DNS 쿼리는 노드에서 상속된 업스트림 네임서버로 전달된다.
클러스터 관리자는 추가 스텁-도메인(stub-domain)과 업스트림 DNS 서버를 구축할 수 있다.
그러한 경우 DNS 쿼리를 어떻게 처리하는지에 대한 자세한 내용은
[관련 논의](/docs/tasks/administer-cluster/dns-custom-nameservers/#impacts-on-pods)
[관련 논의](/docs/tasks/administer-cluster/dns-custom-nameservers/#effects-on-pods)
에서 확인할 수 있다.
- "`ClusterFirstWithHostNet`": hostNetwork에서 running 상태인 파드의 경우 DNS 정책인
"`ClusterFirstWithHostNet`"을 명시적으로 설정해야 한다.

View File

@ -652,6 +652,16 @@ metadata:
[...]
```
{{% /tab %}}
{{% tab name="IBM Cloud" %}}
```yaml
[...]
metadata:
name: my-service
annotations:
service.kubernetes.io/ibm-load-balancer-cloud-provider-ip-type: "private"
[...]
```
{{% /tab %}}
{{% tab name="OpenStack" %}}
```yaml
[...]

View File

@ -296,12 +296,13 @@ parameters:
`replication-type``regional-pd` 로 설정되면,
[지역 퍼시스턴트 디스크](https://cloud.google.com/compute/docs/disks/#repds)
가 프로비전된다. 이 경우, 사용자는 `zone` 대신 `zones` 를 사용해서 원하는
복제 영역을 지정해야 한다. 정확히 두 개의 영역이 지정된 경우, 해당
영역에서 지역 PD가 프로비전된다. 둘 이상의 영역이 지정되면
쿠버네티스는 지정된 영역 중에서 임의로 선택한다. `zones` 파라미터가 생략되면,
쿠버네티스는 클러스터가 관리하는 영역 중에서
임의로 선택한다.
가 프로비전된다. 이는 퍼시스턴트볼륨클레임과 스토리지클래스를 소모하는 파드를
생성할 때 지역 퍼시스턴트 디스크는 두개의 영역으로
프로비전되기에 `volumeBindingMode: WaitForFirstConsumer`
설정하는 것을 강력히 권장한다. 하나의 영역은 파드가 스케줄된
영역과 동일하다. 다른 영역은 클러스터에서 사용할 수
있는 영역에서 임의로 선택된다. 디스크 영역은 `allowedTopologies`
사용하면 더 제한할 수 있다.
{{< note >}}
`zone``zones` 파라미터는 사용 중단 되었으며,

View File

@ -6,7 +6,7 @@ weight: 20
{{% capture overview %}}
{{< feature-state for_k8s_version="1.17" state="beta" >}}
{{< feature-state for_k8s_version="v1.17" state="beta" >}}
쿠버네티스에서 스토리지 시스템 볼륨 스냅샷은 _VolumeSnapshot_ 을 나타낸다. 이 문서는 이미 쿠버네티스 [퍼시스턴트 볼륨](/docs/concepts/storage/persistent-volumes/)에 대해 잘 알고 있다고 가정한다.
{{% /capture %}}
@ -55,7 +55,9 @@ API 리소스 `PersistentVolume` 및 `PersistentVolumeClaim` 가 사용자 및
### 스냅샷 소스 보호로서의 퍼시스턴트 볼륨 클레임
이 보호의 목적은 스냅샷이 생성되는 동안 사용 중인 퍼시스턴트볼륨클레임 API 오브젝트가 시스템에서 지워지지 않게 하는 것이다(데이터 손실이 발생할 수 있기 때문에).
이 보호의 목적은 스냅샷이 생성되는 동안 사용 중인
{{< glossary_tooltip text="퍼시스턴트볼륨클레임" term_id="persistent-volume-claim" >}}
API 오브젝트가 시스템에서 지워지지 않게 하는 것이다(데이터 손실이 발생할 수 있기 때문에).
퍼시스턴트볼륨클레임이 스냅샷을 생성할 동안에는 해당 퍼시스턴트볼륨클레임은 사용중인 상태이다. 스냅샷 소스로 사용 중인 퍼시스턴트볼륨클레임 API 객체를 삭제한다면, 퍼시스턴트볼륨클레임 객체는 즉시 삭제되지 않는다. 대신, 퍼시스턴트볼륨클레임 객체 삭제는 스냅샷이 준비(readyTouse) 혹은 중단(aborted) 상태가 될 때까지 연기된다.

View File

@ -9,7 +9,7 @@ weight: 10
컨테이너 내의 디스크에 있는 파일은 임시적이며, 컨테이너에서 실행될 때
애플리케이션에 적지 않은 몇 가지 문제가 발생한다. 첫째, 컨테이너가 충돌되면,
kubelet은 컨테이너를 재시작시키지만, 컨테이너는 깨끗한 상태로
시작되기 때문에 기존 파일이 유실된다. 둘째, `파드` 에서 컨테이너를 함께 실행할 때
시작되기 때문에 기존 파일이 유실된다. 둘째, `파드` 에서 컨테이너를 함께 실행할 때
컨테이너 사이에 파일을 공유해야 하는 경우가 자주 발생한다. 쿠버네티스의
`볼륨` 추상화는 이 두 가지 문제를 모두 해결한다.
@ -22,7 +22,7 @@ kubelet은 컨테이너를 재시작시키지만, 컨테이너는 깨끗한 상
## 배경
도커는 다소 느슨하고, 덜 관리되지만
도커는 다소 느슨하고, 덜 관리되지만
[볼륨](https://docs.docker.com/engine/admin/volumes/)이라는
개념을 가지고 있다. 도커에서 볼륨은 단순한 디스크 내 디렉터리 또는
다른 컨테이너에 있는 디렉터리다. 수명은 관리되지 않으며 최근까지는
@ -70,7 +70,7 @@ kubelet은 컨테이너를 재시작시키지만, 컨테이너는 깨끗한 상
* [csi](#csi)
* [downwardAPI](#downwardapi)
* [emptyDir](#emptydir)
* [fc (파이버 채널))](#fc)
* [fc (파이버 채널)](#fc)
* [flexVolume](#flexVolume)
* [flocker](#flocker)
* [gcePersistentDisk](#gcepersistentdisk)
@ -496,7 +496,7 @@ gitRepo 볼륨 유형은 사용 중단(deprecated)되었다. git repo가 있는
`gitRepo` 볼륨은 볼륨 플러그인으로 할 수 있는 예시이다. 빈
디렉터리를 마운트하고 파드가 사용할 수 있도록 해당 디렉터리에 git 리포지트리를
복제한다. 미래에는 모든 이용 사례에 대해 쿠버네티스 API를 확장하는 대신에
복제한다. 미래에는 모든 이용 사례에 대해 쿠버네티스 API를 확장하는 대신에
이런 볼륨은 훨씬 더 분리된 모델로 이동될 수 있다.
여기 gitRepo 볼륨의 예시가 있다.
@ -1031,7 +1031,7 @@ tmpfs(RAM 기반 파일시스템)로 지원되기 때문에 비 휘발성 스토
### storageOS {#storageos}
`storageos` 볼륨을 사용하면 기존 [StorageOS](https://www.storageos.com)
`storageos` 볼륨을 사용하면 기존 [StorageOS](https://www.storageos.com)
볼륨을 파드에 마운트할 수 있다.
StorageOS 는 쿠버네티스 환경에서 컨테이너로 실행되므로

View File

@ -8,13 +8,17 @@ weight: 80
{{< feature-state for_k8s_version="v1.8" state="beta" >}}
_크론 잡은_ 시간 기반의 일정에 따라 [](/ko/docs/concepts/workloads/controllers/jobs-run-to-completion/)을 만든다.
_크론잡은_ 반복 일정에 따라 {{< glossary_tooltip term_id="job" text="잡" >}}을 만든다.
하나의 크론잡 객체는 _크론탭_ (크론 테이블) 파일의 한 줄과 같다. 크론잡은 잡을 [크론](https://en.wikipedia.org/wiki/Cron)형식으로 쓰여진 주어진 일정에 따라 주기적으로 동작시킨다.
{{< caution >}}
모든 **크론잡** `일정:` 시간은 UTC로 표시된다.
모든 **크론잡** `일정:` 시간은
{{< glossary_tooltip term_id="kube-controller-manager" text="kube-controller-manager" >}}의 시간대를 기준으로 한다.
컨트롤 플레인이 파드 또는 베어 컨테이너에서 kube-controller-manager를 실행하는 경우,
kube-controller-manager 컨테이너에 설정된 시간대는 크론잡 컨트롤러가 사용하는 시간대로 결정한다.
{{< /caution >}}
크론잡 리소스에 대한 매니페스트를 생성할때에는 제공하는 이름이
@ -23,14 +27,26 @@ _크론 잡은_ 시간 기반의 일정에 따라 [잡](/ko/docs/concepts/worklo
11자를 자동으로 추가하고, 작업 이름의 최대 길이는
63자라는 제약 조건이 있기 때문이다.
크론 잡을 생성하고 작동하는 방법은 크론 잡의 스펙 파일을 확안한다. 내용은 [크론 잡으로 자동 작업 실행하기](/docs/tasks/job/automated-tasks-with-cron-jobs)를 참조한다.
{{% /capture %}}
{{% capture body %}}
## 크론 잡의 한계
## 크론잡
크론잡은 백업 실행 또는 이메일 전송과 같은 정기적이고 반복적인
작업을 만드는데 유용하다. 또한 크론잡은 클러스터가 유휴 상태일 때 잡을
스케줄링하는 것과 같이 특정 시간 동안의 개별 작업을 스케줄할 수 있다.
### 예제
이 크론잡 매니페스트 예제는 현재 시간과 hello 메시지를 1분마다 출력한다.
{{< codenew file="application/job/cronjob.yaml" >}}
([크론잡으로 자동화된 작업 실행하기](/docs/tasks/job/automated-tasks-with-cron-jobs/)는
이 예시를 더 자세히 설명한다.)
## 크론 잡의 한계 {#cron-job-limitations}
크론 잡은 일정의 실행시간 마다 _약_ 한 번의 잡을 생성한다. "약" 이라고 하는 이유는
특정 환경에서는 두 개의 잡이 만들어지거나, 잡이 생성되지 않기도 하기 때문이다. 보통 이렇게 하지
@ -62,3 +78,11 @@ Cannot determine if job needs to be started. Too many missed start time (> 100).
잡은 그 잡이 대표하는 파드 관리에 책임이 있다.
{{% /capture %}}
{{% capture whatsnext %}}
[크론 표현 포맷](https://pkg.go.dev/github.com/robfig/cron?tab=doc#hdr-CRON_Expression_Format)은
크론잡 `schedule` 필드의 포맷을 문서화 한다.
크론 잡 생성과 작업에 대한 지침과 크론잡 매니페스트의
예는 [크론 잡으로 자동화된 작업 실행하기](/docs/tasks/job/automated-tasks-with-cron-jobs/)를 참조한다.
{{% /capture %}}

View File

@ -46,24 +46,24 @@ _디플로이먼트_ 는 [파드](/ko/docs/concepts/workloads/pods/pod/)와
이 예시에 대한 설명은 다음과 같다.
* `.metadata.name` 필드에 따라 `nginx-deployment` 이름으로 디플로이먼트가 생성된다.
* `replicas` 필드에 따라 디플로이먼트는 3개의 레플리카 파드를 생성한다.
* `selector` 필드는 디플로이먼트가 관리할 파드를 찾는 방법을 정의한다.
* `.spec.replicas` 필드에 따라 디플로이먼트는 3개의 레플리카 파드를 생성한다.
* `.spec.selector` 필드는 디플로이먼트가 관리할 파드를 찾는 방법을 정의한다.
이 사례에서는 간단하게 파드 템플릿에 정의된 레이블(`app: nginx`)을 선택한다.
그러나 파드 템플릿 자체의 규칙이 만족되는 한,
보다 정교한 선택 규칙의 적용이 가능하다.
{{< note >}}
`matchLabels` 필드는 {key,value}의 쌍으로 매핑되어있다. `matchLabels` 에 매핑된
`.spec.selector.matchLabels` 필드는 {key,value}의 쌍으로 매핑되어있다. `matchLabels` 에 매핑된
단일 {key,value}은 `matchExpressions` 의 요소에 해당하며, 키 필드는 "key"에 그리고 연산자는 "In"에 대응되며
값 배열은 "value"만 포함한다.
매칭을 위해서는 `matchLabels``matchExpressions` 의 모든 요건이 충족되어야 한다.
{{< /note >}}
* `template` 필드에는 다음 하위 필드가 포함되어있다.
* 파드는 `labels` 필드를 사용해서 `app: nginx` 라는 레이블을 붙인다.
* 파드는 `.metadata.labels` 필드를 사용해서 `app: nginx` 라는 레이블을 붙인다.
* 파드 템플릿의 사양 또는 `.template.spec` 필드는
파드가 [도커 허브](https://hub.docker.com/)의 `nginx` 1.14.2 버전 이미지를 실행하는
`nginx` 컨테이너 1개를 실행하는 것을 나타낸다.
* 컨테이너 1개를 생성하고, `name` 필드를 사용해서 `nginx` 이름을 붙인다.
* 컨테이너 1개를 생성하고, `.spec.template.spec.containers[0].name` 필드를 사용해서 `nginx` 이름을 붙인다.
위의 디플로이먼트를 생성하려면 다음 단계를 따른다.
@ -87,9 +87,8 @@ _디플로이먼트_ 는 [파드](/ko/docs/concepts/workloads/pods/pod/)와
```
클러스터에서 디플로이먼트를 점검할 때 다음 필드가 표시된다.
* `NAME` 은 클러스터에 있는 디플로이먼트 이름의 목록이다.
* `DESIRED` 는 디플로이먼트의 생성시 정의된 의도한 애플리케이션 _레플리카_ 의 수를 표시한다. 이것이 _의도한 상태_ 이다.
* `CURRENT` 는 현재 실행 중인 레플리카의 수를 표시한다.
* `NAME` 은 네임스페이스에 있는 디플로이먼트 이름의 목록이다.
* `READY` 는 사용자가 사용할 수 있는 애플리케이션의 레플리카의 수를 표시한다. ready/desired 패턴을 따른다.
* `UP-TO-DATE` 는 의도한 상태를 얻기위해 업데이트 된 레플리카의 수를 표시한다.
* `AVAILABLE` 은 사용자가 사용 가능한 애플리케이션 레플리카의 수를 표시한다.
* `AGE` 는 애플리케이션의 실행 된 시간을 표시한다.
@ -114,8 +113,16 @@ _디플로이먼트_ 는 [파드](/ko/docs/concepts/workloads/pods/pod/)와
NAME DESIRED CURRENT READY AGE
nginx-deployment-75675f5897 3 3 3 18s
```
레플리카셋의 출력에는 다음 필드가 표시된다.
* `NAME` 은 네임스페이스에 있는 레플리카셋 이름의 목록이다.
* `DESIRED` 는 디플로이먼트의 생성 시 정의된 의도한 애플리케이션 _레플리카_ 의 수를 표시한다. 이것이 _의도한 상태_ 이다.
* `CURRENT` 는 현재 실행 중인 레플리카의 수를 표시한다.
* `READY` 는 사용자가 사용할 수 있는 애플리케이션의 레플리카의 수를 표시한다.
* `AGE` 는 애플리케이션의 실행된 시간을 표시한다.
레플리카셋의 이름은 항상 `[DEPLOYMENT-NAME]-[RANDOM-STRING]` 형식으로 된 것을 알 수 있다. 무작위 문자열은
무작위로 생성되며, Pod-template-hash를 시드(seed)로 사용한다.
무작위로 생성되며, `pod-template-hash` 를 시드(seed)로 사용한다.
6. 각 파드에 자동으로 생성된 레이블을 보려면 `kubectl get pods --show-labels` 를 실행한다. 다음과 유사하게 출력된다.
```shell
@ -508,7 +515,7 @@ API 버전 `apps/v1` 에서 디플로이먼트의 레이블 셀렉터는 생성
이와 유사하게 출력된다.
```
deployment.apps/nginx-deployment
deployment.apps/nginx-deployment rolled back
```
Alternatively, you can rollback to a specific revision by specifying it with `--to-revision`:
@ -518,7 +525,7 @@ API 버전 `apps/v1` 에서 디플로이먼트의 레이블 셀렉터는 생성
이와 유사하게 출력된다.
```
deployment.apps/nginx-deployment
deployment.apps/nginx-deployment rolled back
```
롤아웃 관련 명령에 대한 자세한 내용은 [`kubectl rollout`](/docs/reference/generated/kubectl/kubectl-commands#rollout)을 참조한다.
@ -1015,7 +1022,7 @@ $ echo $?
## 디플로이먼트 사양 작성
다른 모든 쿠버네티스 설정과 마찬가지로 디플로이먼트에는 `apiVersion`, `kind` 그리고 `metadata` 필드가 필요하다.
다른 모든 쿠버네티스 설정과 마찬가지로 디플로이먼트에는 `.apiVersion`, `.kind` 그리고 `.metadata` 필드가 필요하다.
설정 파일 작업에 대한 일반적인 내용은 [애플리케이션 배포하기](/docs/tutorials/stateless-application/run-stateless-application-deployment/),
컨테이너 구성하기 그리고 [kubectl을 사용해서 리소스 관리하기](/ko/docs/concepts/overview/working-with-objects/object-management/) 문서를 참조한다.
디플로이먼트 오브젝트의 이름은 유효한

View File

@ -181,7 +181,7 @@ kubelet은 실행 중인 컨테이너들에 대해서 선택적으로 세 가지
...
State: Waiting
Reason: ErrImagePull
...
...
```
* `Running`: 컨테이너가 이슈 없이 구동된다는 뜻이다. `postStart` 훅(있는 경우)은 컨테이너가 Running 상태가 되기 전에 실행된다. 이 상태는 컨테이너가 언제 Running 상태에 돌입한 시간도 함께 출력된다.
@ -206,31 +206,34 @@ kubelet은 실행 중인 컨테이너들에 대해서 선택적으로 세 가지
...
```
## 파드의 준비성 게이트(readiness gate)
## 파드의 준비성(readiness) {#pod-readiness-gate}
{{< feature-state for_k8s_version="v1.14" state="stable" >}}
파드의 준비성에 대한 확장성을 추가하기 위해서
추가적인 피드백이나 신호를 `PodStatus`에 주입하는 방법인,
[파드 준비++](https://github.com/kubernetes/enhancements/blob/master/keps/sig-network/0007-pod-ready%2B%2B.md)라는 특징이 쿠버네티스 1.11에서 소개되었다.
파드의 준비성을 평가하기 위한 추가적인 조건들을 `PodSpec` 내의 새로운 `ReadinessGate` 필드를
통해서 지정할 수 있다. 만약 쿠버네티스가 `status.conditions` 필드에서 해당하는
애플리케이션은 추가 피드백 또는 신호를 PodStatus: _Pod readiness_
와 같이 주입할 수 있다. 이를 사용하기 위해, 파드의 준비성을 평가하기
위한 추가적인 조건들을 `PodSpec` 내의 `ReadinessGate` 필드를 통해서 지정할 수 있다.
준비성 게이트는 파드에 대한 `status.condition` 필드의 현재
상태에 따라 결정된다. 만약 쿠버네티스가 `status.conditions` 필드에서 해당하는
조건을 찾지 못한다면, 그 조건의 상태는
기본 값인 "`False`"가 된다. 아래는 한 예제를 보여준다.
여기 예제가 있다.
```yaml
Kind: Pod
kind: Pod
...
spec:
readinessGates:
- conditionType: "www.example.com/feature-1"
status:
conditions:
- type: Ready # 이것은 내장된 PodCondition이다
- type: Ready # 내장된 PodCondition이다
status: "False"
lastProbeTime: null
lastTransitionTime: 2018-01-01T00:00:00Z
- type: "www.example.com/feature-1" # 추가적인 PodCondition
- type: "www.example.com/feature-1" # 추가적인 PodCondition
status: "False"
lastProbeTime: null
lastTransitionTime: 2018-01-01T00:00:00Z
@ -240,19 +243,23 @@ status:
...
```
파드의 새로운 조건들은
쿠버네티스의 [레이블 키 포멧](/ko/docs/concepts/overview/working-with-objects/labels/#구문과-캐릭터-셋)을 준수해야 한다.
`kubectl patch` 명령어가 오브젝트 상태 패치(patching)를 아직 제공하지 않기 때문에,
새로운 파드 조건들은 [KubeClient 라이브러리](/ko/docs/reference/using-api/client-libraries/)를 통한 `PATCH` 액션을 통해서 주입되어야 한다.
추가하는 파드 상태에는 쿠버네티스 [레이블 키 포맷](/ko/docs/concepts/overview/working-with-objects/labels/#구문과-캐릭터-셋)을 충족하는 이름이 있어야 한다.
새로운 파드 조건들이 적용된 경우, 파드는 **오직**
다음 두 문장이 모두 참일 때만 준비 상태로 평가된다.
### 파드 준비성 상태 {#pod-readiness-status}
`kubectl patch` 명령어는 아직 오브젝트 상태 패치(patching)를 지원하지 않는다.
이러한 `status.conditions` 을 파드에 설정하려면 애플리케이션과
{{< glossary_tooltip term_id="operator-pattern" text="오퍼레이터">}}의
`PATCH` 액션을 필요로 한다.
[쿠버네티스 클라이언트 라이브러리](/ko/docs/reference/using-api/client-libraries/)를
사용해서 파드 준비성에 대한 사용자 지정 파드 조건을 설정하는 코드를 작성할 수 있다.
사용자 지정 조건을 사용하는 파드의 경우, 다음 두 조건이 모두 적용되는
경우에 **만** 해당 파드가 준비된 것으로 평가된다.
* 파드 내의 모든 컨테이너들이 준비 상태이다.
* `ReadinessGates`에 지정된 모든 조건들이 "`True`"이다.
파드 준비성 평가에 대한 변경을 촉진하기 위해서,
이전 파드 조건인 `Ready`를 포착하기 위한 새로운 파드 조건 `ContainersReady`가 소개되었다.
* `ReadinessGates`에 지정된 모든 조건들이 `True` 이다.
## 재시작 정책
@ -269,32 +276,31 @@ kubelet에 의해서 재시작되는 종료된 컨테이너는
## 파드의 일생(lifetime)
일반적으로, 파드는 사람 혹은 컨트롤러의 프로세스가 명시적으로 파드를 삭제할 때까지 남아 있다.
일반적으로, 파드는 사람 혹은
{{< glossary_tooltip term_id="controller" text="컨트롤러" >}}의
프로세스가 명시적으로 파드를 삭제할 때까지 남아 있다.
컨트롤 플레인은 파드의 수가 설정된 임계치(kube-controller-manager에서
`terminated-pod-gc-threshold`에 의해 결정)를 초과할 때,
종료된 파드들(`Succeeded` 또는 `Failed` 단계)을 정리한다.
이로써 시간이 지남에 따라 파드들이 생성 및 종료되며 발생하는 리소스 누수를 피할 수 있다.
세 가지 유형의 컨트롤러를 사용할 수 있다.
파드에는 다음과 같은 다양한 종류의 리소스가 있다.
- 배치 연산과 같이, 종료가 예상되는 파드를 위해서는 [](/docs/concepts/jobs/run-to-completion-finite-workloads/)을
- 예를 들어 웹 서버와 같이 종료되지 않을 것으로 예상되는 파드용
{{< glossary_tooltip term_id="deployment" >}}, {{< glossary_tooltip term_id="replica-set" >}} 또는
{{< glossary_tooltip term_id="statefulset" >}}을 사용한다.
- 배치 연산과 같이, 종료가 예상되는 파드를 위해서는
{{< glossary_tooltip term_id="job" >}}을
사용하길 바란다. 잡은 `restartPolicy`가 실패 시(OnFailure) 또는 절대 안 함(Never)으로
지정된 경우에 적합하다.
- 웹 서버와 같이, 종료가 예상되지 않는 파드에 대해서는
[레플리케이션 컨트롤러](/ko/docs/concepts/workloads/controllers/replicationcontroller/),
[레플리카 셋](/ko/docs/concepts/workloads/controllers/replicaset/), 또는
[디플로이먼트](/ko/docs/concepts/workloads/controllers/deployment/)를 사용하길 바란다.
레플리케이션 컨트롤러는 `restartPolicy`가 항상(Always)으로 지정된
경우에만 적합하다.
- 적합한 노드 당 하나씩 실행해야 하는 파드에는
{{< glossary_tooltip term_id="daemonset" >}}을 사용한다.
- 머신 당 하나씩 실행해야하는 파드를 위해서는 [데몬 셋](/ko/docs/concepts/workloads/controllers/daemonset/)을 사용하길
바란다. 왜냐하면 데몬 셋은 특정 머신 전용 시스템 서비스(machine-specific system service)를 제공하기 때문이다.
세 가지 모든 컨트롤러 유형은 PodTemplate을 가지고 있다. 파드를
직접적으로 생성하는 것 보다는, 적절한 컨트롤러를 생성하고 컨트롤러가 파드를
생성하도록 하는 것이 추천된다. 그 이유는 파드
혼자서는 머신의 실패에 탄력적(resilient)이지 않지만, 컨트롤러는 탄력적이기 때문이다.
모든 워크로드 리소스에는 파드명세가 포함된다. 사용자가 직접적으로 파드를 생성하는
것보다 적절한 워크로드 리소스를 생성하고 리소스 컨트롤러가
사용자를 위한 파드를 생성하도록 하는 것을 권장한다.
만약 노드가 죽거나 다른 클러스터의 다른 노드들로부터 연결이 끊기면, 쿠버네티스는
잃어버린 노드에 있는 모든 파드의 `phase`를 실패된(Failed)으로 설정하는 정책을 적용한다.
@ -398,4 +404,3 @@ spec:
{{% /capture %}}

View File

@ -15,9 +15,9 @@ card:
{{% capture body %}}
## 파드에 대해 이해하기
*파드* 는 쿠버네티스 애플리케이션의 기본 실행 단위이다. 쿠버네티스 객체 모델 중 만들고 배포할 수 있는 가장 작고 간단한 단위이다. 파드는 {{< glossary_tooltip term_id="cluster" >}} 에서의 Running 프로세스를 나타낸다.
*파드* 는 쿠버네티스 애플리케이션의 기본 실행 단위이다. 쿠버네티스 객체 모델 중 만들고 배포할 수 있는 가장 작고 간단한 단위이다. 파드는 {{< glossary_tooltip term_id="cluster" text="클러스터" >}} 에서의 Running 프로세스를 나타낸다.
파드는 애플리케이션 컨테이너(또는, 몇몇의 경우, 다중 컨테이너), 저장소 리소스, 특정 네트워크 IP 그리고, {{< glossary_tooltip text="container" term_id="container" >}} 가 동작하기 위해 만들어진 옵션들을 캡슐화 한다. 파드는 배포의 단위를 말한다. 아마 단일 컨테이너로 구성되어 있거나, 강하게 결합되어 리소스를 공유하는 소수의 컨테이너로 구성되어 있는 *쿠버네티스에서의 애플리케이션 단일 인스턴스* 를 의미.
파드는 애플리케이션 컨테이너(또는, 몇몇의 경우, 다중 컨테이너), 저장소 리소스, 특정 네트워크 정체성(IP 주소) 및 컨테이너가 동작하기 위해 만들어진 옵션들을 캡슐화 한다. 파드는 배포의 단위를 말한다. 아마 단일 {{< glossary_tooltip text="컨테이너" term_id="container" >}}로 구성되어 있거나, 강하게 결합되어 리소스를 공유하는 소수의 컨테이너로 구성되어 있는 *쿠버네티스에서의 애플리케이션 단일 인스턴스* 를 의미한다.
[도커](https://www.docker.com)는 쿠버네티스 파드에서 사용되는 가장 대표적인 컨테이너 런타임이지만, 파드는 다른 [컨테이너 런타임](/ko/docs/setup/production-environment/container-runtimes/) 역시 지원한다.
@ -26,12 +26,9 @@ card:
* **단일 컨테이너만 동작하는 파드**. "단일 컨테이너 당 한 개의 파드" 모델은 쿠버네티스 사용 사례 중 가장 흔하다. 이 경우, 한 개의 파드가 단일 컨테이너를 감싸고 있다고 생각할 수 있으며, 쿠버네티스는 컨테이너가 아닌 파드를 직접 관리한다고 볼 수 있다.
* **함께 동작하는 작업이 필요한 다중 컨테이너가 동작하는 파드**. 아마 파드는 강하게 결합되어 있고 리소스 공유가 필요한 다중으로 함께 배치된 컨테이너로 구성되어 있을 것이다. 이렇게 함께 배치되어 설치된 컨테이너는 단일 결합 서비스 단위일 것이다. 한 컨테이너는 공유 볼륨에서 퍼블릭으로 파일들을 옮기고, 동시에 분리되어 있는 "사이드카" 컨테이너는 그 파일들을 업데이트 하거나 복구한다. 파드는 이 컨테이너와 저장소 리소스들을 한 개의 관리 가능한 요소로 묶는다.
[쿠버네티스 블로그](https://kubernetes.io/blog)에는 파드 사용 사례의 몇 가지 추가적인 정보가 있다. 더 많은 정보를 위해서 아래 내용을 참조하길 바란다.
* [분산 시스템 툴킷: 복합 컨테이너를 위한 패턴](https://kubernetes.io/blog/2015/06/the-distributed-system-toolkit-patterns)
* [컨테이너 디자인 패턴](https://kubernetes.io/blog/2016/06/container-design-patterns)
각각의 파드는 주어진 애플리케이션에서 단일 인스턴스로 동작을 하는 것을 말한다. 만약 애플리케이션을 수평적으로 스케일하기를 원하면(예를 들면, 다중 인스턴스 동작하는 것), 각 인스턴스 당 한 개씩 다중 파드를 사용해야 한다. 쿠버네티스에서는, 일반적으로 이것을 _복제_ 라고 한다. 복제된 파드는 주로 컨트롤러라고 하는 추상화 개념의 그룹에 의해 만들어지고 관리된다. 더 많은 정보는 [파드와 컨트롤러](#파드와-컨트롤러)를 참고하길 바란다.
각각의 파드는 주어진 애플리케이션에서 단일 인스턴스로 동작하는 것을 말한다. 만약 애플리케이션을 수평적으로 스케일하기를 원하면(더 많은 인스턴스를 실행해서 더 많은 전체 리소스를 제공하는 것), 각 인스턴스 당 한 개씩 다중 파드를 사용해야 한다. 쿠버네티스에서는, 일반적으로 이것을 _복제_ 라고 한다.
복제된 파드는 일반적으로 워크로드 리소스와 해당 {{< glossary_tooltip text="_컨트롤러_" term_id="controller" >}}에 의해 그룹으로 생성과 관리된다.
쿠버네티스가 컨트롤러를 사용해서 워크로드의 확장과 복구를 구현하는 방법에 대한 자세한 내용은 [파드와 컨트롤러](#파드와-컨트롤러)를 참고한다.
## 어떻게 파드가 다중 컨테이너를 관리하는가
@ -47,7 +44,7 @@ card:
#### 네트워킹
각각의 파드는 유한 IP주소를 할당 받는다. 한 파드 내부의 모든 컨테이너는 네트워크 네임스페이스와 IP주소 및 네트워크 포트를 공유한다. *파드 안에 있는* 컨테이너는 다른 컨테이너와 `localhost`를 통해서 통신할 수 있다. 특정 파드 안에 있는 컨테이너가 *파드 밖의* 요소들과 통신하기 위해서는, 네트워크 리소스를 어떻게 쓰고 있는지 공유 해야 한다(예를 들어 포트 등).
각각의 파드는 각 주소 패밀리의 고유한 IP 주소를 할당 받는다. 한 파드 내부의 모든 컨테이너는 네트워크 네임스페이스와 IP주소 및 네트워크 포트를 공유한다. *파드 안에 있는* 컨테이너는 다른 컨테이너와 `localhost` 를 통해서 통신할 수 있다. 특정 파드 안에 있는 컨테이너가 *파드 밖의* 요소들과 통신하기 위해서는, 네트워크 리소스를 어떻게 쓰고 있는지 공유해야 한다(예를 들어 포트 등).
#### 저장소
@ -55,54 +52,63 @@ card:
## 파드 작업
직접 쿠버네티스에서 싱글톤 파드이더라도 개별 파드를 만들일이 거의 없을 것이다. 그 이유는 파드가 상대적으로 수명이 짧고 일시적이기 때문이다. 파드가 만들어지면(직접 만들거나, 컨트롤러에 의해서 간접적으로 만들어지거나), 그것은 클러스터의 {{< glossary_tooltip term_id="node" >}} 에서 동작할 것이다. 파드는 프로세스가 종료되거나, 파드 객체가 삭제되거나, 파드가 리소스의 부족으로 인해 *제거되거나*, 노드에 장애가 생기지 않는 한 노드에 남아있다.
직접 쿠버네티스에서 싱글톤 파드이더라도 개별 파드를 만들 일이 거의 없을 것이다. 그 이유는 파드가 상대적으로 수명이 짧고 일시적이기 때문이다. 파드가 만들어지면(직접 만들거나, {{< glossary_tooltip text="_컨트롤러_" term_id="controller" >}}에 의해서 간접적으로 만들어지거나), 그것은 클러스터의 {{< glossary_tooltip term_id="node" >}}에서 동작할 것이다. 파드는 프로세스가 종료되거나, 파드 오브젝트가 삭제되거나, 파드가 리소스의 부족으로 인해 *축출되거나*, 노드에 장애가 생기지 않는 한 노드에 남아있다.
{{< note >}}
파드 내부에서 재시작되는 컨테이너를 파드와 함께 재시작되는 컨테이너로 혼동해서는 안된다. 파드는 자기 스스로 동작하지 않는다. 하지만 컨테이너 환경은 그것이 삭제될 때까지 계속 동작한다.
파드 내부에서 재시작되는 컨테이너를 파드와 함께 재시작되는 컨테이너로 혼동해서는 안된다. 파드는 프로세스가 아니라, 컨테이너를 실행하는 환경이다. 파드는 삭제될 때까지 유지된다.
{{< /note >}}
파드는 스스로 자신을 치료하지 않는다. 만약 파드가 스케줄링된 노드에 장애가 생기거나, 스케쥴링 동작이 스스로 실패할 경우 파드는 삭제된다. 그와 비슷하게, 파드는 리소스나 노드의 유지 부족으로 인해 제거되는 상황에서 살아남지 못할 것이다. 쿠버네티스는 상대적으로 일시적인 파드 인스턴스를 관리하는 작업을 처리하는 *컨트롤러* 라고 하는 고수준의 추상적 개념을 사용한다. 즉, 파드를 직접적으로 사용가능 하지만, 컨트롤러를 사용하여 파드를 관리하는 것이 쿠버네티스에서 훨씬 더 보편적이다. 쿠버네티스가 어떻게 파드 스케일링과 치료하는지 보려면 [파드와 컨트롤러](#파드와-컨트롤러)를 참고하길 바란다.
파드는 스스로 자신을 치료하지 않는다. 만약 파드가 스케줄링된 노드에 장애가 생기거나, 스케쥴링 동작이 스스로 실패할 경우 파드는 삭제된다. 그와 비슷하게, 파드는 리소스나 노드의 유지 부족으로 인해 축출되는 상황에서 살아남지 못할 것이다. 쿠버네티스는 상대적으로 일시적인 파드 인스턴스를 관리하는 작업을 처리하는 *컨트롤러* 라고 하는 고수준의 추상적 개념을 사용한다. 즉, 파드를 직접적으로 사용할 수 있지만, 컨트롤러를 사용하여 파드를 관리하는 것이 쿠버네티스에서 훨씬 더 보편적이다.
### 파드와 컨트롤러
컨트롤러는 다중 파드를 생성하고 관리해 주는데, 클러스터 범위 내에서의 레플리케이션 핸들링, 롤아웃 그리고 셀프힐링 기능 제공을 한다. 예를 들어, 만약 노드가 고장났을 때, 컨트롤러는 다른 노드에 파드를 스케줄링 함으로써 자동으로 교체할 것이다.
워크로드 리소스를 사용해서 여러 파드를 생성하고 관리할 수 있다. 리소스 컨트롤러는 파드 장애 발생 시 복제, 롤아웃, 자동 복구를 처리한다. 예를 들어, 노드에 장애가 발생하면, 컨트롤러는 해당 노드의 파드는 작동을 멈추고 교체용 파드를 생성한다는 것을 알게 된다. 스케줄러는 교체용 파드를 정상적인 노드에 배치하게 된다.
한 가지 또는 그 이상의 파드를 보유한 컨트롤러의 몇 가지 예시.
* [디플로이먼트](/ko/docs/concepts/workloads/controllers/deployment/)
* [스테이트풀 셋](/ko/docs/concepts/workloads/controllers/statefulset/)
* [데몬 셋](/ko/docs/concepts/workloads/controllers/daemonset/)
일반적으로, 컨트롤러는 책임을 지고 제공한 파드 템플릿을 사용한다.
* {{< glossary_tooltip text="디플로이먼트" term_id="deployment" >}}
* {{< glossary_tooltip text="스테이트풀셋" term_id="statefulset" >}}
* {{< glossary_tooltip text="데몬셋" term_id="daemonset" >}}
## 파드 템플릿
파드 템플릿은 [레플리케이션 컨트롤러](/ko/docs/concepts/workloads/controllers/replicationcontroller/),
[](/docs/concepts/jobs/run-to-completion-finite-workloads/),
[데몬 셋](/ko/docs/concepts/workloads/controllers/daemonset/)과 같은 다른 객체를 포함하는 파드 명세서이다.
컨트롤러는 파드 템플릿을 사용하여 실제 파드를 만든다.
아래 예시는 메시지를 출력하는 컨테이너를 포함하는 파드에 대한 간단한 매니페스트이다.
워크로드 리소스에 대한 컨트롤러는 파드 템플릿으로 파드를 생성하고
사용자를 대신해서 이러한 파드를 관리한다.
파드템플릿은 파드를 생성하기 위한 명세이며
[디플로이먼트](/ko/docs/concepts/workloads/controllers/deployment/),
[](/ko/docs/concepts/jobs/run-to-completion-finite-workloads/) 그리고
[데몬셋](/ko/docs/concepts/workloads/controllers/daemonset/)과 같은 워크로드 리소스에 포함되어 있다.
워크로드 리소스의 각 컨트롤러는 워크로드 오브젝트 내부의 파드템플릿을 사용해서 실제 파드를 만든다. 파드템플릿은 앱을 실행하는 데 사용되는 모든 워크로드 리소스의 의도하는 상태의 일부이다.
아래 샘플은 하나의 컨테이너를 시작하는 `template` 이 있는 간단한 잡에 대한 매니페스트이다. 파드의 컨테이너가 메시지를 출력한 후 일시 중지하게 된다.
```yaml
apiVersion: v1
kind: Pod
apiVersion: batch/v1
kind: Job
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox
command: ['sh', '-c', 'echo 안녕하세요 쿠버네티스! && sleep 3600']
name: hello
template:
# 이것이 파드 템플릿이다.
spec:
containers:
- name: hello
image: busybox
command: ['sh', '-c', 'echo "Hello, Kubernetes!" && sleep 3600']
restartPolicy: OnFailure
# 여기가 파드 템플릿의 끝이다.
```
모든 레플리카의 현재 원하는 상태를 지정하는 대신, 파드 템플릿은 쿠키 틀과 같다. 쿠키가 한 번 잘리면, 그 쿠키는 쿠키 틀과 더이상 관련이 없다. 양자 얽힘이 없는 것이다. 그 이후 템플릿을 변경하거나 새로운 템플릿으로 바꿔도 이미 만들어진 파드에는 직접적인 영향이 없다. 마찬가지로, 레플리케이션 컨트롤러에 의해 만들어진 파드는 아마 그 이후 직접 업데이트될 수 있다. 이것은 모든 컨테이너가 속해있는 파드에서 현재 원하는 상태를 명시하는 것과 의도적으로 대비가 된다. 이러한 접근은 시스템의 의미를 철저히 단순화하고 유연성을 증가시킨다.
파드 템플릿을 수정하거나 새 파드 템플릿으로 전환해도 이미 존재하는 파드에는 영향을 미치지 않는다. 파드는 템플릿 업데이트를 직접 수신하지 않지만, 대신에 수정된 파드 템플릿과 일치하는 새 파드가 생성된다.
예를 들어, 디플로이먼트 컨트롤러는 실행 중인 파드가 현재 파드 템플릿과 일치하는지 확인한다. 템플릿이 업데이트되면, 컨트롤러는 업데이트된 템플릿을 기반으로 기존 파드를 제거하고 새 파드를 생성한다. 각 워크로드 컨트롤러는 파드 템플릿의 변경사항을 처리하기 위해 자체 규칙을 구현한다.
노드에서 "kubelet"이 파드 템플릿과 업데이트에 관련된 세부 정보를 직접 관찰하거나 관리하지 않으며, 이러한 세부 정보는 추상화되지 않는다. 이러한 추상화와 분리는 시스템 시맨틱을 단순화하며, 기존 코드를 변경하지 않고 클러스터의 동작을 확장할 수 있도록 한다.
{{% /capture %}}
{{% capture whatsnext %}}
* [파드](/ko/docs/concepts/workloads/pods/pod/)에 대해 더 배워보자.
* [분산 시스템 툴킷: 복합 컨테이너의 패턴](https://kubernetes.io/blog/2015/06/the-distributed-system-toolkit-patterns)은 둘 이상의 컨테이너가 있는 파드의 공통 레이아웃에 대해 설명한다.
* 파드의 동작에 대해 더 알아보자.
* [파드 종료](/ko/docs/concepts/workloads/pods/pod/#파드의-종료)
* [파드 라이프사이클](/ko/docs/concepts/workloads/pods/pod-lifecycle/)

View File

@ -62,10 +62,10 @@ metadata:
name: mypod
spec:
topologySpreadConstraints:
- maxSkew: <integer>
topologyKey: <string>
whenUnsatisfiable: <string>
labelSelector: <object>
- maxSkew: <integer>
topologyKey: <string>
whenUnsatisfiable: <string>
labelSelector: <object>
```
사용자는 하나 또는 다중 `topologySpreadConstraint` 를 정의해서 kube-scheduler 에게 클러스터에 걸쳐 있는 기존 파드와 시작하는 각각의 파드와 연관하여 배치하는 방법을 명령할 수 있다. 필드는 다음과 같다.
@ -73,8 +73,8 @@ spec:
- **maxSkew** 는 파드가 균등하지 않게 분산될 수 있는 정도를 나타낸다. 이것은 주어진 토폴로지 유형의 임의의 두 토폴로지 도메인에 일치하는 파드의 수 사이에서 허용되는 차이의 최댓값이다. 이것은 0보다는 커야 한다.
- **topologyKey** 는 노드 레이블의 키다. 만약 두 노드가 이 키로 레이블이 지정되고, 레이블이 동일한 값을 가진다면 스케줄러는 두 노드를 같은 토폴로지에 있는것으로 여기게 된다. 스케줄러는 각 토폴로지 도메인에 균형잡힌 수의 파드를 배치하려고 시도한다.
- **whenUnsatisfiable** 는 분산 제약 조건을 만족하지 않을 경우에 처리하는 방법을 나타낸다.
- `DoNotSchedule` (기본값)은 스케줄러에 스케줄을 하지 말라고 알려준다.
- `ScheduleAnyway` 는 스케줄러에게 차이(skew)를 최소화하는 노드에 높은 우선순위를 부여하면서, 스케줄을 계속하도록 지시한다.
- `DoNotSchedule` (기본값)은 스케줄러에 스케줄을 하지 말라고 알려준다.
- `ScheduleAnyway` 는 스케줄러에게 차이(skew)를 최소화하는 노드에 높은 우선 순위를 부여하면서, 스케줄을 계속하도록 지시한다.
- **labelSelector** 는 일치하는 파드를 찾는데 사용된다. 이 레이블 셀렉터와 일치하는 파드의 수를 계산하여 해당 토폴로지 도메인에 속할 파드의 수를 결정한다. 자세한 내용은 [레이블 셀렉터](/ko/docs/concepts/overview/working-with-objects/labels/#레이블-셀렉터)를 참조한다.
사용자는 `kubectl explain Pod.spec.topologySpreadConstraints` 를 실행해서 이 필드에 대한 자세한 내용을 알 수 있다.
@ -160,8 +160,8 @@ spec:
- 신규 파드와 같은 네임스페이스를 갖는 파드만이 매칭의 후보가 된다.
- `topologySpreadConstraints[*].topologyKey` 가 없는 노드는 무시된다. 이것은 다음을 의미한다.
1. 이러한 노드에 위치한 파드는 "maxSkew" 계산에 영향을 미치지 않는다. - 위의 예시에서, "node1"은 "zone"레이블을 가지고 있지 않다고 가정하면, 파드 2개는 무시될 것이고, 이런 이유로 신규 파드는 "zoneA"로 스케줄된다.
2. 신규 파드는 이런 종류의 노드에 스케줄 될 기회가 없다. - 위의 예시에서, 레이블로 `{zone-typo: zoneC}` 를 가지는 "node5"가 클러스터에 편입한다고 가정하면, 레이블 키에 "zone"이 없기 때문에 무시하게 된다.
1. 이러한 노드에 위치한 파드는 "maxSkew" 계산에 영향을 미치지 않는다. - 위의 예시에서, "node1"은 "zone" 레이블을 가지고 있지 않다고 가정하면, 파드 2개는 무시될 것이고, 이런 이유로 신규 파드는 "zoneA"로 스케줄된다.
2. 신규 파드는 이런 종류의 노드에 스케줄 될 기회가 없다. - 위의 예시에서, 레이블로 `{zone-typo: zoneC}` 를 가지는 "node5"가 클러스터에 편입한다고 가정하면, 레이블 키에 "zone"이 없기 때문에 무시하게 된다.
- 들어오는 파드의 `topologySpreadConstraints[*].labelSelector` 와 자체 레이블과 일치하지 않을 경우 어떻게 되는지 알고 있어야 한다. 위의 예시에서, 만약 들어오는 파드의 레이블을 제거하더라도 여전히 제약 조건이 충족하기 때문에 "zoneB"에 배치할 수 있다. 그러나, 배치 이후에도 클러스터의 불균형 정도는 변경되지 않는다. - 여전히 zoneA는 {foo:bar} 레이블을 가지고 있는 2개의 파드를 가지고 있고, zoneB 도 {foo:bar}를 레이블로 가지는 파드 1개를 가지고 있다. 따라서 만약 예상과 다르면, 워크로드의 `topologySpreadConstraints[*].labelSelector` 가 자체 레이블과 일치하도록 하는 것을 권장한다.
@ -207,12 +207,12 @@ kind: KubeSchedulerConfiguration
profiles:
pluginConfig:
- name: PodTopologySpread
args:
defaultConstraints:
- maxSkew: 1
topologyKey: failure-domain.beta.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
- name: PodTopologySpread
args:
defaultConstraints:
- maxSkew: 1
topologyKey: failure-domain.beta.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
```
{{< note >}}
@ -229,14 +229,14 @@ profiles:
더 많이 채워지거나 더 많이 분산되는 방식으로 스케줄 되는 방법을 제어한다.
- `PodAffinity` 는, 사용자가 자격이 충족되는 토폴로지 도메인에
원하는 수의 파드를 얼마든지 채울 수 있다.
원하는 수의 파드를 얼마든지 채울 수 있다.
- `PodAntiAffinity` 로는, 단일 토폴로지 도메인에
단 하나의 파드만 스케줄 될 수 있다.
단 하나의 파드만 스케줄 될 수 있다.
"EvenPodsSpread" 기능은 다양한 토폴로지 도메인에 파드를 균등하게 분배해서
고 가용성 또는 비용 절감을 달성할 수 있는 유연한 옵션을 제공한다. 또한 워크로드의 롤링 업데이트와
레플리카의 원활한 스케일링 아웃에 도움이 될 수 있다.
더 자세한 내용은 [모티베이션(Motivation)](https://github.com/kubernetes/enhancements/blob/master/keps/sig-scheduling/20190221-even-pods-spreading.md#motivation)를 참조한다.
더 자세한 내용은 [모티베이션(Motivation)](https://github.com/kubernetes/enhancements/blob/master/keps/sig-scheduling/20190221-pod-topology-spread.md#motivation)를 참조한다.
## 알려진 제한사항

View File

@ -35,7 +35,7 @@ card:
1. CNCF [Contributor License Agreement](https://github.com/kubernetes/community/blob/master/CLA.md)에 서명합니다.
2. [문서 리포지터리](https://github.com/kubernetes/website) 와 웹사이트의 [정적 사이트 생성기](https://gohugo.io)를 숙지합니다.
3. [풀 리퀘스트 열기](/docs/contribute/new-content/open-a-pr/)와 [변경 검토](/docs/contribute/review/reviewing-prs/)의 기본 프로세스를 이해하도록 합니다.
3. [풀 리퀘스트 열기](/docs/contribute/new-content/new-content/)와 [변경 검토](/docs/contribute/review/reviewing-prs/)의 기본 프로세스를 이해하도록 합니다.
일부 작업에는 쿠버네티스 조직에서 더 많은 신뢰와 더 많은 접근이 필요할 수 있습니다.
역할과 권한에 대한 자세한 내용은
@ -44,6 +44,7 @@ card:
## 첫 번째 기여
- [기여 개요](/docs/contribute/new-content/overview/)를 읽고 기여할 수 있는 다양한 방법에 대해 알아봅니다.
- [kubernetes/website에 기여하기](https://github.com/kubernetes/website/contribute)를 참조하여 좋은 진입점이 되는 이슈를 찾을 수 있습니다.
- 기존 문서에 대해 [GitHub을 사용해서 풀 리퀘스트 열거나](/docs/contribute/new-content/new-content/#changes-using-github) GitHub에서의 이슈 제기에 대해 자세히 알아봅니다.
- 정확성과 언어에 대해 다른 쿠버네티스 커뮤니티 맴버의 [풀 리퀘스트 검토](/docs/contribute/review/reviewing-prs/)를 합니다.
- 쿠버네티스 [컨텐츠](/docs/contribute/style/content-guide/)와 [스타일 가이드](/docs/contribute/style/style-guide/)를 읽고 정보에 대한 코멘트를 남길 수 있습니다.

View File

@ -209,6 +209,8 @@ egress | 이그레스, 송신(egress) |
Endpoint | 엔드포인트 |
entry point | 진입점 |
Event | 이벤트 |
evict | 축출하다 |
eviction | 축출 |
Exec | Exec |
expose | 노출시키다 |
extension | 익스텐션(extension) |
@ -277,7 +279,7 @@ Persistent Volume | 퍼시스턴트 볼륨 |
Persistent Volume Claim | 퍼시스턴트 볼륨 클레임 |
pipeline | 파이프라인 |
placeholder pod | 플레이스홀더(placeholder) 파드 |
Pod(파드) | 파드 |
Pod | 파드 |
Pod Preset | 파드 프리셋 |
PodAntiAffinity | 파드안티어피니티(PodAntiAffinity) |
PodDisruptionBudget | PodDisruptionBudget |
@ -330,6 +332,7 @@ Shell | 셸 |
Sign In | 로그인 |
Sign Out | 로그아웃 |
skew | 차이(skew) |
snippet | 스니펫(snippet) |
spec | 명세, 스펙, 사양 |
specification | 명세 |
Stateful Set | 스테이트풀 셋 |

View File

@ -0,0 +1,4 @@
---
title: 새로운 콘텐츠 기여하기
weight: 20
---

View File

@ -0,0 +1,484 @@
---
title: 풀 리퀘스트 열기
slug: new-content
content_template: templates/concept
weight: 10
card:
name: contribute
weight: 40
---
{{% capture overview %}}
{{< note >}}
**코드 개발자**: 향후 쿠버네티스 릴리스의
새로운 기능을 문서화하는 경우,
[새 기능 문서화](/docs/contribute/new-content/new-features/)를 참고한다.
{{< /note >}}
새 콘텐츠 페이지를 기여하거나 기존 콘텐츠 페이지를 개선하려면, 풀 리퀘스트(PR)를 연다. [시작하기 전에](/ko/docs/contribute/new-content/overview/#before-you-begin) 섹션의 모든 요구 사항을 준수해야 한다.
변경 사항이 작거나, git에 익숙하지 않은 경우, [GitHub을 사용하여 변경하기](#github을-사용하여-변경하기)를 읽고 페이지를 편집하는 방법을 알아보자.
변경 사항이 많으면, [로컬 포크에서 작업하기](#fork-the-repo)를 읽고 컴퓨터에서 로컬로 변경하는 방법을 배운다.
{{% /capture %}}
{{% capture body %}}
## GitHub을 사용하여 변경하기
git 워크플로에 익숙하지 않은 경우, 풀 리퀘스트를
여는 쉬운 방법이 있다.
1. 이슈가 있는 페이지에서, 오른쪽 상단에 있는 연필 아이콘을 선택한다.
페이지 하단으로 스크롤 하여 **페이지 편집하기** 를 선택할 수도 있다.
2. GitHub 마크다운 편집기에서 수정한다.
3. 편집기 아래에서, **Propose file change** 양식을
작성한다. 첫 번째 필드에서, 커밋 메시지 제목을 지정한다.
두 번째 필드에는, 설명을 제공한다.
{{< note >}}
커밋 메시지에 [GitHub 키워드](https://help.github.com/en/github/managing-your-work-on-github/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword)를 사용하지 않는다. 나중에 풀 리퀘스트 설명에
추가할 수 있다.
{{< /note >}}
4. **Propose file change** 를 선택한다.
5. **Create pull requests** 를 선택한다.
6. **Open a pull request** 화면이 나타난다. 양식을 작성한다.
- 풀 리퀘스트의 **Subject** 필드는 기본적으로 커밋의 요약으로 설정한다.
필요한 경우 변경할 수 있다.
- **Body** 는 만약 내용이 있다면, 확장된 커밋 메시지를 포함한다.
그리고 일부 템플릿 텍스트를 포함한다.
템플릿 텍스트에 필요한 세부 정보를 추가한 다음, 추가 템플릿 텍스트를 삭제한다.
- **Allow edits from maintainers** 체크박스는 선택된 상태로 둔다.
{{< note >}}
PR 설명은 리뷰어가 변경 사항을 이해하는 데 유용한 방법이다. 자세한 내용은 [PR 열기](#open-a-pr)를 참고한다.
{{</ note >}}
7. **Create pull request** 를 선택한다.
### GitHub에서 피드백 해결
풀 리퀘스트를 병합하기 전에, 쿠버네티스 커뮤니티 회원은 이를 리뷰하고
승인한다. `k8s-ci-robot` 은 이 페이지에 나와있는 가까운
멤버에게 리뷰를 제안한다. 특정한 사람을 염두에 두고 있다면,
GitHub 사용자 이름을 코멘트로 남긴다.
리뷰어가 변경을 요청하는 경우, 다음과 같이 한다.
1. **Files changed** 탭으로 이동 한다.
2. 풀 리퀘스트에 의해 변경된 파일에서 연필(편집) 아이콘을
선택한다.
3. 요청된 변경에 대한 수정을 한다.
4. 변경 사항을 커밋한다.
리뷰어를 기다리고 있는 경우, 7일마다 한 번씩 연락한다. 슬랙 채널 `#sig-docs` 에 메시지를 게시할 수도 있다.
리뷰가 완료되면, 리뷰어가 PR을 병합하고 몇 분 후에 변경 사항이 적용된다.
## 로컬 포크에서 작업하기 {#fork-the-repo}
git에 익숙하거나, 변경 사항이 몇 줄보다 클 경우,
로컬 포크로 작업한다.
컴퓨터에 [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)이 설치되어 있는지 확인한다. git UI 애플리케이션을 사용할 수도 있다.
### kubernetes/website 리포지터리 포크하기
1. [`kubernetes/website`](https://github.com/kubernetes/website/) 리포지터리로 이동한다.
2. **Fork** 를 선택한다.
### 로컬 클론 생성 및 업스트림 설정
3. 터미널 창에서, 포크를 클론한다.
```bash
git clone git@github.com/<github_username>/website
```
4. 새 `website` 디렉터리로 이동한다. `kubernetes/website` 리포지터리를 `upstream` 원격으로 설정한다.
```bash
cd website
git remote add upstream https://github.com/kubernetes/website.git
```
5. `origin``upstream` 리포지터리를 확인한다.
```bash
git remote -v
```
출력은 다음과 비슷하다.
```bash
origin git@github.com:<github_username>/website.git (fetch)
origin git@github.com:<github_username>/website.git (push)
upstream https://github.com/kubernetes/website (fetch)
upstream https://github.com/kubernetes/website (push)
```
6. 포크의 `origin/master``kubernetes/website``upstream/master` 에서 커밋을 가져온다.
```bash
git fetch origin
git fetch upstream
```
이를 통해 변경을 시작하기 전에 로컬 리포지터리가 최신 상태인지 확인한다.
{{< note >}}
이 워크플로는 [쿠버네티스 커뮤니티 GitHub 워크플로](https://github.com/kubernetes/community/blob/master/contributors/guide/github-workflow.md)와 다르다. 포크에 업데이트를 푸시하기 전에 로컬의 `master` 복사본을 `upstream/master` 와 병합할 필요가 없다.
{{< /note >}}
### 브랜치 만들기
1. 작업할 브랜치 기반을 결정한다.
- 기존 콘텐츠를 개선하려면, `upstream/master` 를 사용한다.
- 기존 기능에 대한 새로운 콘텐츠를 작성하려면, `upstream/master` 를 사용한다.
- 현지화된 콘텐츠의 경우, 현지화 규칙을 사용한다. 자세한 내용은 [쿠버네티스 문서 현지화](/ko/docs/contribute/localization_ko/)를 참고한다.
- 다가오는 쿠버네티스 릴리스의 새로운 기능에 대해서는 기능 브랜치(feature branch)를 사용한다. 자세한 정보는 [릴리스 문서화](/docs/contribute/new-content/new-features/)를 참고한다.
- 콘텐츠 재구성과 같이 여러 SIG Docs 기여자들이 협업하는 장기적인 작업에는,
해당 작업을 위해 작성된 특정 기능 브랜치를
사용한다.
브랜치 선택에 도움이 필요하면, 슬랙 채널 `#sig-docs` 에 문의한다.
2. 1단계에서 식별된 브랜치를 기반으로 새 브랜치를 작성한다. 이 예에서는 기본 브랜치가 `upstream/master` 라고 가정한다.
```bash
git checkout -b <my_new_branch> upstream/master
```
3. 텍스트 편집기를 사용하여 변경한다.
언제든지, `git status` 명령을 사용하여 변경한 파일을 본다.
### 변경 사항 커밋
풀 리퀘스트를 제출할 준비가 되면, 변경 사항을 커밋한다.
1. 로컬 리포지터리에서 커밋해야 할 파일을 확인한다.
```bash
git status
```
출력은 다음과 비슷하다.
```bash
On branch <my_new_branch>
Your branch is up to date with 'origin/<my_new_branch>'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: content/en/docs/contribute/new-content/contributing-content.md
no changes added to commit (use "git add" and/or "git commit -a")
```
2. **Changes not staged for commit** 에 나열된 파일을 커밋에 추가한다.
```bash
git add <your_file_name>
```
각 파일에 대해 이 작업을 반복한다.
3. 모든 파일을 추가한 후, 커밋을 생성한다.
```bash
git commit -m "Your commit message"
```
{{< note >}}
커밋 메시지에 [GitHub 키워드](https://help.github.com/en/github/managing-your-work-on-github/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword)를 사용하지 말자. 나중에 풀 리퀘스트 설명에 추가할
수 있다.
{{< /note >}}
4. 로컬 브랜치와 새로운 커밋을 원격 포크로 푸시한다.
```bash
git push origin <my_new_branch>
```
### 로컬에서 변경 사항 미리보기 {#preview-locally}
변경 사항을 푸시하거나 풀 리퀘스트를 열기 전에 변경 사항을 로컬에서 미리 보는 것이 좋다. 미리보기를 사용하면 빌드 오류나 마크다운 형식 문제를 알아낼 수 있다.
website의 도커 이미지를 만들거나 Hugo를 로컬에서 실행할 수 있다. 도커 이미지 빌드는 느리지만 [Hugo 단축코드](/docs/contribute/style/hugo-shortcodes/)를 표시하므로, 디버깅에 유용할 수 있다.
{{< tabs name="tab_with_hugo" >}}
{{% tab name="Hugo 컨테이너" %}}
1. 로컬에서 이미지를 빌드한다.
```bash
make docker-image
```
2. 로컬에서 `kubernetes-hugo` 이미지를 빌드한 후, 사이트를 빌드하고 서비스한다.
```bash
make docker-serve
```
3. 웹 브라우저에서 `https://localhost:1313` 로 이동한다. Hugo는
변경 사항을 보고 필요에 따라 사이트를 다시 구축한다.
4. 로컬의 Hugo 인스턴스를 중지하려면, 터미널로 돌아가서 `Ctrl+C` 를 입력하거나,
터미널 창을 닫는다.
{{% /tab %}}
{{% tab name="Hugo 커맨드 라인" %}}
또는, 컴퓨터에 `hugo` 명령을 설치하여 사용한다.
5. [`website/netlify.toml`](https://raw.githubusercontent.com/kubernetes/website/master/netlify.toml)에 지정된 [Hugo](https://gohugo.io/getting-started/installing/) 버전을 설치한다.
6. 터미널에서, 쿠버네티스 website 리포지터리로 이동하여 Hugo 서버를 시작한다.
```bash
cd <path_to_your_repo>/website
hugo server
```
7. 브라우저의 주소 표시줄에 `https://localhost:1313` 을 입력한다.
8. 로컬의 Hugo 인스턴스를 중지하려면, 터미널로 돌아가서 `Ctrl+C` 를 입력하거나,
    터미널 창을 닫는다.
{{% /tab %}}
{{< /tabs >}}
### 포크에서 kubernetes/website로 풀 리퀘스트 열기 {#open-a-pr}
1. 웹 브라우저에서 [`kubernetes/website`](https://github.com/kubernetes/website/) 리포지터리로 이동한다.
2. **New Pull Request** 를 선택한다.
3. **compare across forks** 를 선택한다.
4. **head repository** 드롭다운 메뉴에서, 포크를 선택한다.
5. **compare** 드롭다운 메뉴에서, 브랜치를 선택한다.
6. **Create Pull Request** 를 선택한다.
7. 풀 리퀘스트에 대한 설명을 추가한다.
- **Title**(50자 이하): 변경 사항에 대한 의도를 요약한다.
- **Description**: 변경 사항을 자세히 설명한다.
- 관련된 GitHub 이슈가 있는 경우, `Fixes #12345` 또는 `Closes #12345` 를 설명에 포함한다. 이렇게 하면 GitHub의 자동화 기능이 PR을 병합한 후 언급된 이슈를 닫는다. 다른 관련된 PR이 있는 경우, 이들 PR도 연결한다.
- 구체적인 내용에 대한 조언이 필요한 경우, 원하는 질문을 리뷰어가 생각해볼 수 있도록 설명에 포함한다.
8. **Create pull request** 버튼을 선택한다.
축하한다! 여러분의 풀 리퀘스트가 [풀 리퀘스트](https://github.com/kubernetes/website/pulls)에 열렸다.
PR을 연 후, GitHub는 자동 테스트를 실행하고 [Netlify](https://www.netlify.com/)를 사용하여 미리보기를 배포하려고 시도한다.
- Netlify 빌드가 실패하면, 자세한 정보를 위해 **Details** 를 선택한다.
- Netlify 빌드가 성공하면, **Details** 를 선택하면 변경 사항이 적용된 쿠버네티스 website의 커밋하기 직전의 버전(staged version)이 열린다. 리뷰어가 변경 사항을 확인하는 방법이다.
또한 GitHub는 리뷰어에게 도움을 주기 위해 PR에 레이블을 자동으로 할당한다. 필요한 경우 직접 추가할 수도 있다. 자세한 내용은 [이슈 레이블 추가와 제거](/docs/contribute/review/for-approvers/#adding-and-removing-issue-labels)를 참고한다.
### 로컬에서 피드백 해결
1. 변경한 후, 이전 커밋을 수정한다.
```bash
git commit -a --amend
```
- `-a`: 모든 변경 사항을 커밋
- `--amend`: 새로운 커밋을 만들지 않고, 이전 커밋을 수정한다.
2. 필요한 경우 커밋 메시지를 업데이트한다.
3. `git push origin <my_new_branch>` 를 사용해서 변경 사항을 푸시하고 Netlify 테스트를 다시 실행한다.
{{< note >}}
수정하는 대신 `git commit -m` 을 사용하는 경우, 병합하기 전에 [커밋을 스쿼시](#커밋-스쿼시하기)해야 한다.
{{< /note >}}
#### 리뷰어의 변경
때때로 리뷰어가 여러분의 풀 리퀘스트를 커밋한다. 다른 변경을 하기 전에, 커밋을 가져온다.
1. 원격 포크에서 커밋을 가져오고 작업 브랜치를 리베이스한다.
```bash
git fetch origin
git rebase origin/<your-branch-name>
```
2. 리베이스한 후, 포크에 새로운 변경 사항을 강제로 푸시한다.
```bash
git push --force-with-lease origin <your-branch-name>
```
#### 충돌 병합 및 리베이스
{{< note >}}
자세한 내용은 [Git 브랜치 - 기본 브랜치와 병합](https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging#_basic_merge_conflicts), [고급 병합](https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging)을 참조하거나, 슬랙 채널 `#sig-docs` 에서 도움을 요청한다.
{{< /note >}}
다른 기여자가 다른 PR에서 동일한 파일에 대한 변경 사항을 커밋하면, 병합 충돌이 발생할 수 있다. PR의 모든 병합 충돌을 해결해야 한다.
1. 포크를 업데이트하고 로컬 브랜치를 리베이스한다.
```bash
git fetch origin
git rebase origin/<your-branch-name>
```
그런 다음 포크에 변경 사항을 강제로 푸시한다.
```bash
git push --force-with-lease origin <your-branch-name>
```
2. `kubernetes/website``upstream/master` 에 대한 변경 사항을 가져오고 브랜치를 리베이스한다.
```bash
git fetch upstream
git rebase upstream/master
```
3. 리베이스의 결과를 검사한다.
```bash
git status
```
이 명령의 결과에 여러 파일이 충돌된 것으로 표시된다.
4. 충돌하는 각 파일을 열고 충돌 마커(`>>>`,`<<<` 그리고 `===`)를 찾는다. 충돌을 해결하고 충돌 마커를 삭제한다.
{{< note >}}
자세한 내용은 [충돌이 표시되는 방법](https://git-scm.com/docs/git-merge#_how_conflicts_are_presented)을 참고한다.
{{< /note >}}
5. 변경 세트에 파일을 추가한다.
```bash
git add <filename>
```
6. 리베이스를 계속한다.
```bash
git rebase --continue
```
7. 필요에 따라 2단계에서 5단계를 반복한다.
모든 커밋을 적용한 후, `git status` 명령은 리베이스가 완료되었음을 나타낸다.
8. 브랜치를 포크에 강제로 푸시한다.
```bash
git push --force-with-lease origin <your-branch-name>
```
풀 리퀘스트에 더 이상 충돌이 표시되지 않는다.
### 커밋 스쿼시하기
{{< note >}}
자세한 내용은 [Git 도구 - 히스토리 다시 쓰기](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History)를 참고하거나, 슬랙 채널 `#sig-docs` 에서 도움을 요청한다.
{{< /note >}}
PR에 여러 커밋이 있는 경우, PR을 병합하기 전에 해당 커밋을 단일 커밋으로 스쿼시해야 한다. PR의 **Commits** 탭에서 또는 `git log` 명령을 로컬에서 실행하여 커밋 수를 확인할 수 있다.
{{< note >}}
여기서는 `vim` 을 커맨드 라인 텍스트 편집기로 사용하는 것을 가정한다.
{{< /note >}}
1. 대화식 리베이스를 시작한다.
```bash
git rebase -i HEAD~<number_of_commits_in_branch>
```
커밋을 스쿼시하는 것은 일종의 리베이스이다. git의 `-i` 스위치는 리베이스를 대화형으로 할 수 있게 한다. `HEAD~<number_of_commits_in_branch` 는 리베이스를 위해 살펴볼 커밋 수를 나타낸다.
출력은 다음과 비슷하다.
```bash
pick d875112ca Original commit
pick 4fa167b80 Address feedback 1
pick 7d54e15ee Address feedback 2
# 3d18sf680..7d54e15ee 를 3d183f680 으로 리베이스한다 (3개 명령)
...
# 이 행들은 순서를 바꿀 수 있다. 이들은 위에서 아래로 실행된다.
```
출력의 첫 번째 섹션에는 리베이스의 커밋이 나열된다. 두 번째 섹션에는 각 커밋에 대한 옵션이 나열되어 있다. `pick` 단어를 바꾸면 리베이스가 완료되었을 때 커밋 상태가 변경된다.
리베이스를 하는 목적인 `squash``pick` 에 집중한다.
{{< note >}}
자세한 내용은 [대화식 모드](https://git-scm.com/docs/git-rebase#_interactive_mode)를 참고한다.
{{< /note >}}
2. 파일 편집을 시작한다.
다음의 원본 텍스트를 변경한다.
```bash
pick d875112ca Original commit
pick 4fa167b80 Address feedback 1
pick 7d54e15ee Address feedback 2
```
아래와 같이 변경한다.
```bash
pick d875112ca Original commit
squash 4fa167b80 Address feedback 1
squash 7d54e15ee Address feedback 2
```
이것은 커밋 `4fa167b80 Address feedback 1``7d54e15ee Address feedback 2``d875112ca Original commit` 으로 스쿼시한다. 타임라인의 일부로 `d875112ca Original commit` 만 남긴다.
3. 파일을 저장하고 종료한다.
4. 스쿼시된 커밋을 푸시한다.
```bash
git push --force-with-lease origin <branch_name>
```
## 다른 리포지터리에 기여하기
[쿠버네티스 프로젝트](https://github.com/kubernetes)에는 50개 이상의 리포지터리가 포함되어 있다. 이러한 리포지터리에는 사용자용 도움말 텍스트, 오류 메시지, API 레퍼런스 또는 코드 주석과 같은 문서가 포함되어 있다.
개선하려는 텍스트가 보이면, GitHub을 사용하여 쿠버네티스 조직의 모든 리포지터리를 검색한다.
이를 통해 어디에 이슈나 PR을 제출할지를 파악할 수 있다.
각 리포지터리에는 고유한 프로세스와 절차가 있다. 여러분이 이슈를
제기하거나 PR을 제출하기 전에, 그 리포지터리의 `README.md`, `CONTRIBUTING.md` 그리고
`code-of-conduct.md`(만약 이들 문서가 있다면)를 읽어본다.
대부분의 리포지터리에는 이슈와 PR 템플릿이 사용된다. 팀의 프로세스에 대한
느낌을 얻으려면 열린 이슈와 PR을 살펴보자. 이슈나 PR을 제출할 때
가능한 한 상세하게 템플릿의 내용을 작성한다.
{{% /capture %}}
{{% capture whatsnext %}}
- 리뷰 프로세스에 대한 자세한 내용은 [리뷰하기](/ko/docs/contribute/reviewing/revewing-prs)를 읽어본다.
{{% /capture %}}

View File

@ -0,0 +1,58 @@
---
title: 새로운 콘텐츠 기여하기에 대한 개요
linktitle: 개요
content_template: templates/concept
main_menu: true
weight: 5
---
{{% capture overview %}}
이 섹션에는 새로운 콘텐츠를 기여하기 전에 알아야 할 정보가 있다.
{{% /capture %}}
{{% capture body %}}
## 기여하기에 대한 기본
- 마크다운(Markdown)으로 쿠버네티스 문서를 작성하고 [Hugo](https://gohugo.io/)를 사용하여 쿠버네티스 사이트를 구축한다.
- 소스는 [GitHub](https://github.com/kubernetes/website)에 있다. 쿠버네티스 문서는 `/content/ko/docs/` 에서 찾을 수 있다. 일부 참조 문서는 `update-imported-docs/` 디렉터리의 스크립트에서 자동으로 생성된다.
- [페이지 템플릿](/docs/contribute/style/page-templates/)은 Hugo에서 문서 콘텐츠의 프리젠테이션을 제어한다.
- 표준 Hugo 단축코드(shortcode) 이외에도 설명서에서 여러 [사용자 정의 Hugo 단축코드](/docs/contribute/style/hugo-shortcodes/)를 사용하여 콘텐츠 표시를 제어한다.
- 문서 소스는 `/content/` 에서 여러 언어로 제공된다. 각 언어는 [ISO 639-1 표준](https://www.loc.gov/standards/iso639-2/php/code_list.php)에 의해 결정된 2문자 코드가 있는 자체 폴더가 있다. 예를 들어, 한글 문서의 소스는 `/content/ko/docs/` 에 저장된다.
- 여러 언어로 문서화에 기여하거나 새로운 번역을 시작하는 방법에 대한 자세한 내용은 [현지화](/ko/docs/contribute/localization_ko/)를 참고한다.
## 시작하기 전에 {#before-you-begin}
### CNCF CLA 서명 {#sign-the-cla}
모든 쿠버네티스 기여자는 **반드시** [기여자 가이드](https://github.com/kubernetes/community/blob/master/contributors/guide/README.md)를 읽고 [기여자 라이선스 계약(CLA)에 서명](https://github.com/kubernetes/community/blob/master/CLA.md)해야 한다.
CLA에 서명하지 않은 기여자의 풀 리퀘스트(pull request)는 자동 테스트에 실패한다. 제공한 이름과 이메일은 `git config` 에 있는 것과 일치해야 하며, git 이름과 이메일은 CNCF CLA에 사용된 것과 일치해야 한다.
### 사용할 Git 브랜치를 선택한다
풀 리퀘스트를 열 때는, 작업의 기반이 되는 브랜치를 미리 알아야 한다.
시나리오 | 브랜치
:---------|:------------
현재 릴리스의 기존 또는 새로운 영어 콘텐츠 | `master`
기능 변경 릴리스의 콘텐츠 | `dev-release-<version>` 패턴을 사용하여 기능 변경이 있는 주 버전과 부 버전에 해당하는 브랜치. 예를 들어, `{{< latest-version >}}` 에서 기능이 변경된 경우, ``dev-{{< release-branch >}}`` 에 문서 변경을 추가한다.
다른 언어로된 콘텐츠(현지화) | 현지화 규칙을 사용. 자세한 내용은 [현지화 브랜치 전략](/docs/contribute/localization/#branching-strategy)을 참고한다.
어떤 브랜치를 선택해야 할지 잘 모르는 경우 슬랙의 `#sig-docs` 에 문의한다.
{{< note >}}
풀 리퀘스트를 이미 제출했는데 기본 브랜치가 잘못되었다는 것을 알게 되면,
제출자(제출자인 여러분만)가 이를 변경할 수 있다.
{{< /note >}}
### PR 당 언어
PR 당 하나의 언어로 풀 리퀘스트를 제한한다. 여러 언어로 동일한 코드 샘플을 동일하게 변경해야 하는 경우 각 언어마다 별도의 PR을 연다.
{{% /capture %}}

View File

@ -0,0 +1,14 @@
---
title: 변경 사항 리뷰하기
weight: 30
---
{{% capture overview %}}
이 섹션은 콘텐츠를 리뷰하는 방법에 대해 설명한다.
{{% /capture %}}
{{% capture body %}}
{{% /capture %}}

View File

@ -0,0 +1,228 @@
---
title: 승인자와 리뷰어의 리뷰
linktitle: 승인자와 리뷰어용
slug: for-approvers
content_template: templates/concept
weight: 20
---
{{% capture overview %}}
SIG Docs [리뷰어](/ko/docs/contribute/participating/#리뷰어)와 [승인자](/ko/docs/contribute/participating/#승인자)는 변경 사항을 리뷰할 때 몇 가지 추가 작업을 수행한다.
매주 특정 문서 승인자 역할의 지원자가
풀 리퀘스트를 심사하고 리뷰한다. 이
사람은 일주일 동안 "PR 랭글러(Wrangler)"이다. 자세한
정보는 [PR 랭글러 스케줄러](https://github.com/kubernetes/website/wiki/PR-Wranglers)를 참고한다. PR 랭글러가 되려면, 매주 SIG Docs 회의에 참석하고 자원한다. 이번 주에 해당 일정이 없는 경우에도, 아직 리뷰 중이 아닌
풀 리퀘스트(PR)를 여전히 리뷰할 수 있다.
로테이션 외에도, 봇은 영향을 받는 파일의 소유자를 기반으로
PR에 대한 리뷰어와 승인자를 할당한다.
{{% /capture %}}
{{% capture body %}}
## PR 리뷰
쿠버네티스의 문서는 [쿠버네티스의 코드 리뷰 프로세스](https://github.com/kubernetes/community/blob/master/contributors/guide/owners.md#the-code-review-process)를 따른다.
[풀 리퀘스트 리뷰](/ko/docs/contribute/review/reviewing-prs)에 설명된 모든 내용이 적용되지만, 리뷰어와 승인자도 다음을 수행해야 한다.
- `/assign` Prow 명령을 사용하여 필요에 따라 특정 리뷰어를 PR에 할당한다. 이는 코드 기여자에게
기술 리뷰를 요청할 때 특히 중요하다.
{{< note >}}
마크다운 파일 맨 위에 있는 헤더의 `reviewers` 필드를 보고 기술 리뷰를
제공할 수 있는 사람을 확인한다.
{{< /note >}}
- PR이 [콘텐츠](/docs/contribute/style/content-guide/)와 [스타일](/docs/contribute/style/style-guide/) 가이드를 따르는 지 확인한다. 그렇지 않은 경우 가이드의 관련 부분에 작성자를 연결한다.
- 적용이 가능한 경우 GitHub **Request Changes** 옵션을 사용하여 PR 작성자에게 변경을 제안한다.
- 제안한 사항이 구현된 경우, `/approve` 또는 `/lgtm` Prow 명령을 사용하여 GitHub에서 리뷰 상태를 변경한다.
## 다른 사람의 PR에 커밋
PR 코멘트를 남기는 것이 도움이 되지만, 대신 다른 사람의 PR에 커밋을
해야 하는 경우가 있다.
다른 사람이 명시적으로 요청하거나, 오랫동안
중단된 PR을 재개하려는 경우가 아니라면 다른 사람에게서 "가져오지" 마라. 단기적으로는
작업이 빠를 수 있지만, 그 사람이 기여할 기회를 박탈하게 된다.
사용할 프로세스는 이미 PR의 범위에 있는 파일을 편집해야
하는지, 또는 PR이 아직 다루지 않은 파일을 편집해야 하는지에 따라 다르다.
다음 중 하나에 해당하면 다른 사람의 PR에 커밋할 수
없다.
- PR 작성자가 브랜치를
[https://github.com/kubernetes/website/](https://github.com/kubernetes/website/)
리포지터리로 직접 푸시한 경우, 푸시 접근 권한이 있는 리뷰어만 다른 사용자의 PR에 커밋할 수 있다.
{{< note >}}
다음 번부터는 PR을 열기 전에 작성자가 브랜치를 자신의 포크로
푸시하도록 권장한다.
{{< /note >}}
- PR 작성자가 승인자의 수정을 명시적으로 허용하지 않는다.
## 리뷰를 위한 Prow 명령
[Prow](https://github.com/kubernetes/test-infra/blob/master/prow/README.md)는
풀 리퀘스트 (PR)에 대한 작업을 실행하는 쿠버네티스 기반 CI/CD 시스템이다. Prow는
챗봇 스타일 명령으로 쿠버네티스
조직 전체에서 [레이블 추가와
제거](#이슈-레이블-추가와-제거), 이슈 종료 및 승인자 할당과 같은 GitHub 작업을 처리할 수 ​​있다. `/<command-name>` 형식을 사용하여 Prow 명령을 GitHub 코멘트로 입력한다.
리뷰어와 승인자가 사용하는 가장 일반적인 Prow 명령은 다음과 같다.
{{< table caption="리뷰를 위한 Prow 명령" >}}
Prow 명령 | 역할 제한 | 설명
:------------|:------------------|:-----------
`/lgtm` | 누구나, 리뷰어나 승인자가 사용한다면 자동화를 트리거한다. | PR 리뷰를 마치고 변경 사항에 만족했음을 나타낸다.
`/approve` | 승인자 | PR을 병합(merge)하기 위해 승인한다.
`/assign` | 리뷰어 또는 승인자 | PR을 리뷰하거나 승인할 사람을 지정한다.
`/close` | 리뷰어 또는 승인자 | 이슈 또는 PR을 닫는다.
`/hold` | 누구나 | 자동으로 병합할 수 없음을 나타내는 `do-not-merge/hold` 레이블을 추가한다.
`/hold cancel` | 누구나 | `do-not-merge/hold` 레이블을 제거한다.
{{< /table >}}
PR에서 사용할 수 있는 명령의 전체 목록을 보려면
[Prow 명령 레퍼런스](https://prow.k8s.io/command-help)를 참고한다.
## 이슈 심사와 분류
일반적으로, SIG Docs는 [쿠버네티스 이슈 심사](https://github.com/kubernetes/community/blob/master/contributors/guide/issue-triage.md) 프로세스를 따르며 동일한 레이블을 사용한다.
이 GitHub 이슈 [필터](https://github.com/kubernetes/website/issues?q=is%3Aissue+is%3Aopen+-label%3Apriority%2Fbacklog+-label%3Apriority%2Fimportant-longterm+-label%3Apriority%2Fimportant-soon+-label%3Atriage%2Fneeds-information+-label%3Atriage%2Fsupport+sort%3Acreated-asc)는
심사가 필요한 이슈를 찾는다.
### 이슈 심사
1. 이슈 확인
- 이슈가 website 문서에 관한 것인지 확인한다. 질문에 답하거나
리소스에 리포터를 지정하면 일부 이슈를 신속하게 종결할 수 있다. 자세한 내용은
[지원 요청 또는 코드 버그 리포트](#지원-요청-또는-코드-버그-리포트) 섹션을 참고한다.
- 이슈가 가치가 있는지 평가한다.
- 이슈의 내용에 실행할 수 있는 세부 사항이 충분하지 않거나 템플릿의 내용이
제대로 작성되지 않은 경우 `triage/needs-information` 레이블을 추가한다.
- `lifecycle/stale``triage/needs-information` 레이블이 모두 있으면 이슈를 닫는다.
2. 우선순위 레이블을
추가한다([이슈 심사 가이드라인](https://github.com/kubernetes/community/blob/master/contributors/guide/issue-triage.md#define-priority)은 우선순위 레이블을 자세히 정의함).
{{< table caption="이슈 레이블" >}}
레이블 | 설명
:------------|:------------------
`priority/critical-urgent` | 이 작업을 지금 즉시 수행한다.
`priority/important-soon` | 3개월 이내에 이 작업을 수행한다.
`priority/important-longterm` | 6개월 이내에 이 작업을 수행한다.
`priority/backlog` | 무기한 연기할 수 있다. 자원이 있을 때 수행한다.
`priority/awaiting-more-evidence` | 잠재적으로 좋은 이슈에 대해 잊지 않도록 표시한다.
`help` 또는 `good first issue` | 쿠버네티스나 SIG Docs 경험이 거의 없는 사람에게 적합하다. 자세한 내용은 [도움이 필요함 및 좋은 첫 번째 이슈 레이블](https://github.com/kubernetes/community/blob/master/contributors/guide/help-wanted.md)을 참고한다.
{{< /table >}}
재량에 따라, 이슈의 소유권을 가져와서 PR을
제출한다(특히, 이미 수행 중인 작업과 관련이 있거나 빠르다면).
이슈 심사에 대해 질문이 있다면, 슬랙의 `#sig-docs` 채널이나
[kubernetes-sig-docs 메일링리스트](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)에 문의한다.
## 이슈 레이블 추가와 제거
레이블을 추가하려면, 다음의 형식 중 하나로 코멘트를 남긴다.
- `/<label-to-add>` (예: `/good-first-issue`)
- `/<label-category> <label-to-add>` (예: `/triage needs-information` 또는 `/language ko`)
레이블을 제거하려면, 다음의 형식 중 하나로 코멘트를 남긴다.
- `/remove-<label-to-remove>` (예: `/remove-help`)
- `/remove-<label-category> <label-to-remove>` (예: `/remove-triage needs-information`)
두 경우 모두, 사용하려는 레이블은 이미 존재하는 레이블이어야 한다. 존재하지 않는 레이블을 추가하려고 하면, 명령이
자동으로 무시된다.
모든 레이블 목록에 대해서는 [website 리포지터리의 레이블 섹션](https://github.com/kubernetes/website/labels)을 참고한다. SIG Docs에서 모든 레이블을 사용하는 것은 아니다.
### 이슈의 lifecycle 레이블
이슈는 일반적으로 신속하게 열리고 닫힌다.
그러나, 가끔씩은 이슈가 열린 후 비활성 상태로 있다.
어떤 경우에는 이슈가 90일 이상 열려 있을 수도 있다.
{{< table caption="이슈의 lifecycle 레이블" >}}
레이블 | 설명
:------------|:------------------
`lifecycle/stale` | 90일이 지나도 아무런 활동이 없는 이슈는 자동으로 오래된 것(stale)으로 표시된다. `/remove-lifecycle stale` 명령을 사용하여 라이프사이클을 수동으로 되돌리지 않으면 이슈가 자동으로 닫힌다.
`lifecycle/frozen` | 90일 동안 활동이 없어도 이 레이블의 이슈는 오래된 것(stale)으로 바뀌지 않는다. 사용자는 `priority/important-longterm` 레이블이 있는 이슈처럼 90일보다 훨씬 오래 열려 있어야 하는 이슈에 이 레이블을 수동으로 추가한다.
{{< /table >}}
## 특별한 이슈 유형의 처리
SIG Docs가 처리 방법을 문서화할 정도로 다음과 같은 유형의 이슈를
자주 경험하게 된다.
### 중복된 이슈
단일 문제에 대해 하나 이상의 이슈가 열려 있으면, 이를 단일 이슈로 합친다.
열린 상태를 유지할 이슈를 결정한 다음(또는
새로운 이슈를 열어야 함), 모든 관련 정보로 이동하여 관련 이슈를 연결해야 한다.
마지막으로, 동일한 문제를 설명하는 다른 모든 이슈에
`triage/duplicate` 레이블을 지정하고 닫는다. 하나의 이슈만 해결하는 것으로 혼동을 줄이고
같은 문제에 대한 중복 작업을 피할 수 있다.
### 깨진 링크 이슈
깨진 링크 이슈가 API 문서나 `kubectl` 문서에 있는 경우, 문제가 완전히 이해될 때까지 `/priority critical-urgent` 레이블을 할당한다. 다른 모든 깨진 링크 이슈는 수동으로 수정해야하므로, `/priority important-longterm` 를 할당한다.
### 블로그 이슈
[쿠버네티스 블로그](https://kubernetes.io/blog/) 항목은 시간이 지남에 따라
구식이 될 것으로 예상한다. 따라서, 1년 미만의 블로그 항목만 유지 관리한다.
1년이 지난 블로그 항목과 관련된 이슈일 경우,
수정하지 않고 이슈를 닫는다.
### 지원 요청 또는 코드 버그 리포트
문서에 대한 일부 이슈는 실제로 기본 코드와 관련된 이슈이거나, 튜토리얼과
같은 무언가가 작동하지 않을 때 도움을 요청하는 것이다.
문서와 관련이 없는 이슈의 경우, `triage/support` 레이블과 함께 요청자에게 지원받을 수 있는 곳(슬랙, Stack Overflow)을
알려주며 이슈를 닫고, 기능 관련 버그에 대한 이슈인 경우,
관련 리포지터리를 코멘트로 남긴다(`kubernetes/kubernetes` 는
시작하기 좋은 곳이다).
지원 요청에 대한 샘플 응답은 다음과 같다.
```none
이 이슈는 지원 요청과 비슷하지만
문서 관련 이슈와는 관련이 없는 것 같습니다.
[쿠버네티스 슬랙](http://slack.k8s.io/)의
`#kubernetes-users` 채널에서 질문을 하시기 바랍니다. 또한,
[Stack Overflow](http://stackoverflow.com/questions/tagged/kubernetes)와
같은 리소스를 검색하여 유사한 질문에 대한 답변을
얻을 수도 있습니다.
https://github.com/kubernetes/kubernetes 에서
쿠버네티스 기능 관련 이슈를 열 수도 있습니다.
문서에 대한 이슈인 경우 이 이슈를 다시 여십시오.
```
샘플 코드 버그 리포트 응답은 다음과 같다.
```none
이 이슈는 문서에 대한 이슈보다 코드에 대한 이슈와
비슷합니다. https://github.com/kubernetes/kubernetes/issues 에서
이슈를 여십시오.
문서에 대한 이슈인 경우 이 이슈를 다시 여십시오.
```
{{% /capture %}}

View File

@ -0,0 +1,98 @@
---
title: 풀 리퀘스트 리뷰
content_template: templates/concept
main_menu: true
weight: 10
---
{{% capture overview %}}
누구나 문서화에 대한 풀 리퀘스트를 리뷰할 수 있다. 쿠버네티스 website 리포지터리의 [풀 리퀘스트](https://github.com/kubernetes/website/pulls) 섹션을 방문하여 열린(open) 풀 리퀘스트를 확인한다.
문서화에 대한 풀 리퀘스트를 리뷰하는 것은
쿠버네티스 커뮤니티에 자신을 소개하는 훌륭한 방법이다.
아울러, 코드 베이스(code base)를 배우고 다른 기여자와 신뢰를 구축하는 데 도움이 된다.
리뷰하기 전에, 다음을 수행하는 것이 좋다.
- 적합한 코멘트를 남길 수 있도록 [콘텐츠 가이드](/docs/contribute/style/content-guide/)와
[스타일 가이드](/docs/contribute/style/style-guide/)를 읽는다.
- 쿠버네티스 문서화 커뮤니티의 다양한 [역할과 책임](/docs/contribute/participating/#roles-and-responsibilities)을 이해한다.
{{% /capture %}}
{{% capture body %}}
## 시작하기 전에
리뷰를 시작하기 전에 다음을 명심하자.
- [CNCF 행동 강령](https://github.com/cncf/foundation/blob/master/code-of-conduct-languages/ko.md)을 읽고 항상 준수한다.
- 정중하고, 사려 깊고, 도움이 되자.
- PR의 긍정적인 측면과 변화에 대한 의견을 남긴다.
- 당신의 리뷰를 어떻게 받아들일지에 대해 공감하고 주의한다.
- 좋은 의도를 가지고 명확한 질문을 한다.
- 숙련된 기여자인 경우, 작업에 광범위한 변경이 필요한 새 기여자와 쌍을 이루어 리뷰해 본다.
## 리뷰 과정
일반적으로, 영어로 콘텐츠와 스타일에 대한 풀 리퀘스트를 리뷰한다.
1. [https://github.com/kubernetes/website/pulls](https://github.com/kubernetes/website/pulls)로
이동한다.
쿠버네티스 website와 문서에 대한 모든 열린 풀 리퀘스트 목록이
표시된다.
2. 다음 레이블 중 하나 또는 모두를 사용하여 열린 PR을 필터링한다.
- `cncf-cla: yes`(권장): CLA에 서명하지 않은 기여자가 제출한 PR은 병합할 수 없다. 자세한 내용은 [CLA 서명](/docs/contribute/new-content/overview/#sign-the-cla)을 참고한다.
- `language/en`(권장): 영어 문서에 대한 PR 전용 필터이다.
- `size/<size>`: 특정 크기의 PR을 필터링한다. 새로 시작하는 사람이라면, 더 작은 PR로 시작한다.
또한, PR이 진행 중인 작업으로 표시되지 않았는지 확인한다. `work in progress` 레이블을 사용하는 PR은 아직 리뷰할 준비가 되지 않은 PR이다.
3. 리뷰할 PR을 선택한 후, 다음을 통해 변경 사항을 이해한다.
- PR 설명을 통해 변경 사항을 이해하고, 연결된 이슈 읽기
- 다른 리뷰어의 의견 읽기
- **Files changed** 탭을 클릭하여 변경된 파일과 행 보기
- **Conversation** 탭의 맨 아래에 있는 PR의 빌드 확인 섹션으로 스크롤하여 **deploy/netlify** 행의 **Details** 링크를 클릭하고 Netlify 미리보기 빌드의 변경 사항을 확인
4. **Files changed** 탭으로 이동하여 리뷰를 시작한다.
1. 코멘트을 달려는 줄 옆에 있는 `+` 기호를 클릭한다.
2. 행에 대한 의견을 작성하고 **Add single comments**(작성할 의견이 하나만 있는 경우) 또는 **Start a review**(작성할 의견이 여러 개인 경우)를 클릭한다.
3. 완료되면, 페이지 상단에서 **Review changes** 를 클릭한다. 여기에서
리뷰에 대한 요약을 추가하고(기여자에게 긍정적인 의견을 남겨주기 바란다!),
PR을 승인하거나, 의견을 보내거나 필요에 따라 변경을 요청할 수 있다. 새로운 기여자는
항상 **Comment** 를 선택해야 한다.
## 리뷰 체크리스트
리뷰할 때, 다음을 시작점으로 사용한다.
### 언어와 문법
- 언어나 문법에 명백한 오류가 있는가? 무언가를 표현하는 더 좋은 방법이 있는가?
- 더 간단한 단어로 대체될 수 있는 복잡하거나 오래된 단어가 있는가?
- 비 차별적 대안으로 대체될 수 있는 단어, 용어 또는 문구가 있는가?
- 단어 선택과 대소문자는 [스타일 가이드](/docs/contribute/style/style-guide/)를 따르는가?
- 더 짧고 간결하게 만들 수 있는 긴 문장이 있는가?
- 목록이나 표로 더 잘 표현할 수 있는 긴 단락이 있는가?
### 콘텐츠
- 쿠버네티스 사이트의 다른 곳에도 비슷한 콘텐츠가 있는가?
- 콘텐츠가 오프-사이트, 개별 업체, 또는 공개되지 않은 소스 문서에 과도하게 링크되는가?
### 웹 사이트
- 이 PR이 페이지 제목, slug/alias 또는 앵커(anchor) 링크를 변경 또는 제거하는가? 그렇다면, 이 PR의 결과로 끊어진 링크가 있는가? slug를 변경 없이 페이지 제목을 변경하는 등의 다른 옵션이 있는가?
- PR이 새로운 페이지를 소개하는가? 그렇다면,
- 페이지가 올바른 [페이지 템플릿](/docs/contribute/style/page-templates/)과 연관된 Hugo 단축 코드를 사용하는가?
- 섹션의 측면 탐색에 페이지가 올바르게 나타나는가?
- 페이지가 [문서 홈](/ko/docs/home/) 목록에 나타나야 하는가?
- 변경 사항이 Netlify 미리보기에 표시되는가? 목록, 코드 블록, 표, 메모 및 이미지에 특히 주의한다.
### 기타
오타나 공백과 같은 작은 이슈의 PR인 경우, 코멘트 앞에 `nit:` 를 추가한다. 이를 통해 문서의 저자는 이슈가 긴급하지 않다는 것을 알 수 있다.
{{% /capture %}}

View File

@ -0,0 +1,9 @@
---
title: 문서 스타일 개요
main_menu: true
weight: 80
---
이 섹션의 주제는 문서 작성 스타일, 컨텐츠 형식과
구성, 쿠버네티스 문서화에 적합하게 사용자 정의된 Hugo 사용 방법에 대한
가이드를 제공한다.

View File

@ -0,0 +1,23 @@
---
title: 클라우드 컨트롤 매니저
id: cloud-controller-manager
date: 2018-04-12
full_link: /ko/docs/concepts/architecture/cloud-controller/
short_description: >
쿠버네티스를 타사 클라우드 공급자와 통합하는 컨트롤 플레인 컴포넌트.
aka:
tags:
- core-object
- architecture
- operation
---
클라우드별 컨트롤 로직을 포함하는 쿠버네티스
{{< glossary_tooltip text="컨트롤 플레인" term_id="control-plane" >}} 컴포넌트이다.
클라우트 컨트롤러 매니저를 통해 클러스터를 클라우드 공급자의 API에 연결하고,
해당 클라우드 플랫폼과 상호 작용하는 컴포넌트와 클러스터와 상호 작용하는 컴포넌트를 분리할 수 있다.
<!--more-->
쿠버네티스와 기본 클라우드 인프라스터럭처 간의 상호 운용성 로직을
분리함으로써, cloud-controller-manager 컴포넌트는 클라우드 공급자가
주요 쿠버네티스 프로젝트와 다른 속도로 기능들을 릴리스할 수 있도록 한다.

View File

@ -0,0 +1,20 @@
---
title: 컨피그맵(ConfigMap)
id: configmap
date: 2018-04-12
full_link: /docs/concepts/configuration/configmap/
short_description: >
키-값 쌍으로 기밀이 아닌 데이터를 저장하는 데 사용하는 API 오브젝트이다. 볼륨에서 환경 변수, 커맨드-라인 인수 또는 구성 파일로 사용될 수 있다.
aka:
tags:
- core-object
---
키-값 쌍으로 기밀이 아닌 데이터를 저장하는 데 사용하는 API 오브젝트이다.
{{< glossary_tooltip text="파드" term_id="pod" >}}는
{{< glossary_tooltip text="볼륨" term_id="volume" >}}에서
환경 변수, 커맨드-라인 인수 또는 구성 파일로 컨피그맵을 사용할 수 있다.
<!--more-->
컨피그맵을 사용하면 {{< glossary_tooltip text="컨테이너 이미지" term_id="image" >}}에서 환경별 구성을 분리하여, 애플리케이션을 쉽게 이식할 수 있다.

View File

@ -11,3 +11,15 @@ tags:
- fundamental
---
컨테이너의 라이프사이클을 정의, 배포, 관리하기 위한 API와 인터페이스들을 노출하는 컨테이너 오케스트레이션 레이어.
<!--more-->
이 계층은 다음과 같은 다양한 컴포넌트로 구성된다(그러나 제한되지는 않는다).
* {{< glossary_tooltip text="etcd" term_id="etcd" >}}
* {{< glossary_tooltip text="API 서버" term_id="kube-apiserver" >}}
* {{< glossary_tooltip text="스케줄러" term_id="kube-scheduler" >}}
* {{< glossary_tooltip text="컨트롤러 매니저" term_id="kube-controller-manager" >}}
* {{< glossary_tooltip text="클라우드 컨트롤러 매니저" term_id="cloud-controller-manager" >}}
이러한 컴포넌트는 기존 운영체제 서비스(데몬) 또는 컨테이너로 실행할 수 있다. 이러한 컴포넌트를 실행하는 호스트를 {{< glossary_tooltip text="마스터" term_id="master" >}}라 한다.

View File

@ -4,7 +4,7 @@ id: cronjob
date: 2018-04-12
full_link: /ko/docs/concepts/workloads/controllers/cron-jobs/
short_description: >
주기적인 일정에 따라 실행되는 [](/ko/docs/concepts/workloads/controllers/jobs-run-to-completion/)을 관리.
정기적인 일정으로 실행되는 반복 작업(잡).
aka:
tags:

View File

@ -4,7 +4,7 @@ id: deployment
date: 2018-04-12
full_link: /ko/docs/concepts/workloads/controllers/deployment/
short_description: >
복제된(replicated) 애플리케이션을 관리하는 API 오브젝트.
클러스터에서 복제된 애플리케이션을 관리한다.
aka:
tags:
@ -12,9 +12,10 @@ tags:
- core-object
- workload
---
복제된 애플리케이션을 관리하는 API 오브젝트.
일반적으로 로컬 상태가 없는 파드를 실행하여 복제된 애플리케이션을 관리하는 API 오브젝트.
<!--more-->
각 레플리카는 {{< glossary_tooltip text="파드" term_id="pod" >}}로 표현되며, 파드는 클러스터의 {{< glossary_tooltip text="노드" term_id="node" >}}에 분산된다.
각 레플리카는 {{< glossary_tooltip text="파드" term_id="pod" >}}로 표현되며,
파드는 클러스터의 {{< glossary_tooltip text="노드" term_id="node" >}}에 분산된다.
로컬 상태가 필요한 워크로드의 경우 {{< glossary_tooltip term_id="StatefulSet" >}}의 사용을 고려한다.

View File

@ -4,7 +4,7 @@ id: pod
date: 2018-04-12
full_link: /ko/docs/concepts/workloads/pods/pod-overview/
short_description: >
가장 작고 단순한 쿠버네티스 오브젝트. 파드는 사용자 클러스터에서 동작하는 컨테이너의 집합을 나타낸다.
파드는 클러스터에서 실행 중인 컨테이너의 집합을 나타낸다.
aka:
tags:

View File

@ -1,5 +1,5 @@
---
title: 서비스 어카운트(ServiceAccount)
title: 서비스어카운트(ServiceAccount)
id: service-account
date: 2018-04-12
full_link: /docs/tasks/configure-pod-container/configure-service-account/

View File

@ -4,7 +4,7 @@ id: statefulset
date: 2018-04-12
full_link: /ko/docs/concepts/workloads/controllers/statefulset/
short_description: >
파드 집합의 디플로이먼트와 스케일링을 관리하며, 파드들의 *순서 및 고유성을 보장한다* .
내구성이 있는 스토리지와 파드별로 지속성 식별자를 사용해서 파드 집합의 디플로이먼트와 스케일링을 관리한다.
aka:
tags:
@ -17,4 +17,6 @@ tags:
<!--more-->
{{< glossary_tooltip text="디플로이먼트" term_id="deployment" >}}와 유사하게, 스테이트풀 셋은 동일한 컨테이너 스펙을 기반으로 둔 파드들을 관리한다. 디플로이먼트와는 다르게, 스테이트풀 셋은 각 파드의 독자성을 유지한다. 이 파드들은 동일한 스팩으로 생성되었지만, 서로 교체는 불가능하다. 다시 말해, 각각은 재스케줄링 간에도 지속적으로 유지되는 식별자를 가진다.
{{< glossary_tooltip text="디플로이먼트" term_id="deployment" >}}와 유사하게, 스테이트풀셋은 동일한 컨테이너 스펙을 기반으로 둔 파드들을 관리한다. 디플로이먼트와는 다르게, 스테이트풀셋은 각 파드의 독자성을 유지한다. 이 파드들은 동일한 스팩으로 생성되었지만, 서로 교체는 불가능하다. 다시 말해, 각각은 재스케줄링 간에도 지속적으로 유지되는 식별자를 가진다.
스토리지 볼륨을 사용해서 워크로드에 지속성을 제공하려는 경우, 솔루션의 일부로 스테이트풀셋을 사용할 수 있다. 스테이트풀셋의 개별 파드는 장애에 취약하지만, 퍼시스턴트 파드 식별자는 기존 볼륨을 실패한 볼륨을 대체하는 새 파드에 더 쉽게 일치시킬 수 있다.

View File

@ -64,7 +64,7 @@ kubectl config get-contexts # 컨텍스트 리스트
kubectl config current-context # 현재 컨텍스트 출력
kubectl config use-context my-cluster-name # my-cluster-name를 기본 컨텍스트로 설정
# 기본 인증을 지원하는 새로운 클러스터를 kubeconf에 추가한다
# 기본 인증을 지원하는 새로운 사용자를 kubeconf에 추가한다
kubectl config set-credentials kubeuser/foo.kubernetes.com --username=kubeuser --password=kubepassword
# 해당 컨텍스트에서 모든 후속 kubectl 커맨드에 대한 네임스페이스를 영구적으로 저장한다
@ -342,6 +342,21 @@ kubectl api-resources --api-group=extensions # "extensions" API 그룹의 모든
`-o=wide` | 추가 정보가 포함된 일반-텍스트 형식으로 출력하고, 파드의 경우 노드 명이 포함
`-o=yaml` | YAML 형식의 API 오브젝트 출력
`-o=custom-columns` 의 사용 예시:
```bash
# 클러스터에서 실행 중인 모든 이미지
kubectl get pods -A -o=custom-columns='DATA:spec.containers[*].image'
# "k8s.gcr.io/coredns:1.6.2" 를 제외한 모든 이미지
kubectl get pods -A -o=custom-columns='DATA:spec.containers[?(@.image!="k8s.gcr.io/coredns:1.6.2")].image'
# 이름에 관계없이 메타데이터 아래의 모든 필드
kubectl get pods -A -o=custom-columns='DATA:metadata.*'
```
More examples in the kubectl [reference documentation](/docs/reference/kubectl/overview/#custom-columns).
### Kubectl 출력 로그 상세 레벨(verbosity)과 디버깅
Kubectl 로그 상세 레벨(verbosity)은 `-v` 또는`--v` 플래그와 로그 레벨을 나타내는 정수로 제어된다. 일반적인 쿠버네티스 로깅 규칙과 관련 로그 레벨이 [여기](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/logging.md)에 설명되어 있다.

View File

@ -50,28 +50,28 @@ Machinery](https://github.com/kubernetes/community/tree/master/sig-api-machinery
| Lisp | [github.com/brendandburns/cl-k8s](https://github.com/brendandburns/cl-k8s) |
| Lisp | [github.com/xh4/cube](https://github.com/xh4/cube) |
| Node.js (TypeScript) | [github.com/Goyoo/node-k8s-client](https://github.com/Goyoo/node-k8s-client) |
| Node.js | [github.com/tenxcloud/node-kubernetes-client](https://github.com/tenxcloud/node-kubernetes-client) |
| Node.js | [github.com/godaddy/kubernetes-client](https://github.com/godaddy/kubernetes-client) |
| Node.js | [github.com/ajpauwels/easy-k8s](https://github.com/ajpauwels/easy-k8s)
| Node.js | [github.com/godaddy/kubernetes-client](https://github.com/godaddy/kubernetes-client) |
| Node.js | [github.com/tenxcloud/node-kubernetes-client](https://github.com/tenxcloud/node-kubernetes-client) |
| Perl | [metacpan.org/pod/Net::Kubernetes](https://metacpan.org/pod/Net::Kubernetes) |
| PHP | [github.com/maclof/kubernetes-client](https://github.com/maclof/kubernetes-client) |
| PHP | [github.com/allansun/kubernetes-php-client](https://github.com/allansun/kubernetes-php-client) |
| PHP | [github.com/maclof/kubernetes-client](https://github.com/maclof/kubernetes-client) |
| PHP | [github.com/travisghansen/kubernetes-client-php](https://github.com/travisghansen/kubernetes-client-php) |
| Python | [github.com/eldarion-gondor/pykube](https://github.com/eldarion-gondor/pykube) |
| Python | [github.com/fiaas/k8s](https://github.com/fiaas/k8s) |
| Python | [github.com/mnubo/kubernetes-py](https://github.com/mnubo/kubernetes-py) |
| Python | [github.com/tomplus/kubernetes_asyncio](https://github.com/tomplus/kubernetes_asyncio) |
| Ruby | [github.com/Ch00k/kuber](https://github.com/Ch00k/kuber) |
| Ruby | [github.com/abonas/kubeclient](https://github.com/abonas/kubeclient) |
| Ruby | [github.com/Ch00k/kuber](https://github.com/Ch00k/kuber) |
| Ruby | [github.com/kontena/k8s-client](https://github.com/kontena/k8s-client) |
| Rust | [github.com/clux/kube-rs](https://github.com/clux/kube-rs) |
| Rust | [github.com/ynqa/kubernetes-rust](https://github.com/ynqa/kubernetes-rust) |
| Scala | [github.com/doriordan/skuber](https://github.com/doriordan/skuber) |
| dotNet | [github.com/tonnyeremin/kubernetes_gen](https://github.com/tonnyeremin/kubernetes_gen) |
| Scala | [github.com/joan38/kubernetes-client](https://github.com/joan38/kubernetes-client) |
| DotNet | [github.com/tonnyeremin/kubernetes_gen](https://github.com/tonnyeremin/kubernetes_gen) |
| DotNet (RestSharp) | [github.com/masroorhasan/Kubernetes.DotNet](https://github.com/masroorhasan/Kubernetes.DotNet) |
| Elixir | [github.com/obmarg/kazan](https://github.com/obmarg/kazan/) |
| Elixir | [github.com/coryodaniel/k8s](https://github.com/coryodaniel/k8s) |
| Haskell | [github.com/kubernetes-client/haskell](https://github.com/kubernetes-client/haskell) |
{{% /capture %}}

View File

@ -195,7 +195,7 @@ minikube start --driver=<driver_name>
* virtualbox
* vmwarefusion
* docker (EXPERIMENTAL)
* docker ([드라이버 설치](https://minikube.sigs.k8s.io/docs/drivers/docker/)
* kvm2 ([드라이버 설치](https://minikube.sigs.k8s.io/docs/reference/drivers/kvm2/))
* hyperkit ([드라이버 설치](https://minikube.sigs.k8s.io/docs/reference/drivers/hyperkit/))
* hyperv ([드라이버 설치](https://minikube.sigs.k8s.io/docs/reference/drivers/hyperv/))
@ -457,11 +457,11 @@ Minikube에 대한 더 자세한 정보는, [제안](https://git.k8s.io/communit
## 추가적인 링크:
* **목표와 비목표**: Minikube 프로젝트의 목표와 비목표에 대해서는 [로드맵](https://git.k8s.io/minikube/docs/contributors/roadmap.md)을 살펴보자.
* **개발 가이드**: 풀 리퀘스트를 보내는 방법에 대한 개요는 [참여 가이드](https://git.k8s.io/minikube/CONTRIBUTING.md)를 살펴보자.
* **Minikube 빌드**: Minikube를 소스에서 빌드/테스트하는 방법은 [빌드 가이드](https://git.k8s.io/minikube/docs/contributors/build_guide.md)를 살펴보자.
* **새 의존성 추가하기**: Minikube에 새 의존성을 추가하는 방법에 대해서는, [의존성 추가 가이드](https://git.k8s.io/minikube/docs/contributors/adding_a_dependency.md)를 보자.
* **새 애드온 추가하기**: Minikube에 새 애드온을 추가하는 방법에 대해서는, [애드온 추가 가이드](https://git.k8s.io/minikube/docs/contributors/adding_an_addon.md)를 보자.
* **목표와 비목표**: Minikube 프로젝트의 목표와 비목표에 대해서는 [로드맵](https://minikube.sigs.k8s.io/docs/contrib/roadmap/)을 살펴보자.
* **개발 가이드**: 풀 리퀘스트를 보내는 방법에 대한 개요는 [기여하기](https://minikube.sigs.k8s.io/docs/contrib/)를 살펴보자.
* **Minikube 빌드**: Minikube를 소스에서 빌드/테스트하는 방법은 [빌드 가이드](https://minikube.sigs.k8s.io/docs/contrib/building/)를 살펴보자.
* **새 의존성 추가하기**: Minikube에 새 의존성을 추가하는 방법에 대해서는, [의존성 추가 가이드](https://minikube.sigs.k8s.io/docs/contrib/drivers/)를 보자.
* **새 애드온 추가하기**: Minikube에 새 애드온을 추가하는 방법에 대해서는, [애드온 추가 가이드](https://minikube.sigs.k8s.io/docs/contrib/addons/)를 보자.
* **MicroK8s**: 가상 머신을 사용하지 않으려는 Linux 사용자는 대안으로 [MicroK8s](https://microk8s.io/)를 고려할 수 있다.
## 커뮤니티

View File

@ -7,7 +7,7 @@ weight: 40
{{% capture overview %}}
{{< feature-state for_k8s_version="1.12" state="stable" >}}
{{< feature-state for_k8s_version="v1.12" state="stable" >}}
kubeadm의 `ClusterConfiguration` 오브젝트는 API 서버, 컨트롤러매니저, 스케줄러와 같은 컨트롤 플레인 구성요소에 전달되는 기본 플래그 `extraArgs` 필드를 노출한다. 이 구성요소는 다음 필드를 사용하도록 정의되어 있다.

View File

@ -6,7 +6,7 @@ content_template: templates/task
{{% capture overview %}}
{{< feature-state for_k8s_version="1.5" state="alpha" >}}
{{< feature-state for_k8s_version="v1.5" state="alpha" >}}
구글 컴퓨트 엔진(Google Compute Engine, 이하 GCE)의 `kube-up`이나 `kube-down` 스크립트에 쿠버네티스 마스터를 복제할 수 있다.
이 문서는 kube-up/down 스크립트를 사용하여 고가용(HA) 마스터를 관리하는 방법과 GCE와 함께 사용하기 위해 HA 마스터를 구현하는 방법에 관해 설명한다.

View File

@ -0,0 +1,4 @@
---
title: "kubeadm으로 관리하기"
weight: 10
---

View File

@ -0,0 +1,443 @@
---
title: kubeadm 클러스터 업그레이드
content_template: templates/task
weight: 20
min-kubernetes-server-version: 1.18
---
{{% capture overview %}}
이 페이지는 kubeadm으로 생성된 쿠버네티스 클러스터를
1.17.x 버전에서 1.18.x 버전으로, 1.18.x 버전에서 1.18.y(여기서 `y > x`) 버전으로 업그레이드하는 방법을 설명한다.
이전 버전의 kubeadm을 사용하여 생성된 클러스터 업그레이드에 대한 정보를 보려면,
이 페이지 대신 다음의 페이지들을 참고한다.
- [kubeadm 클러스터를 1.16에서 1.17로 업그레이드](https://v1-17.docs.kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/)
- [kubeadm 클러스터를 1.15에서 1.16으로 업그레이드](https://v1-16.docs.kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/)
- [kubeadm 클러스터를 1.14에서 1.15로 업그레이드](https://v1-15.docs.kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-1-15/)
- [kubeadm 클러스터를 1.13에서 1.14로 업그레이드](https://v1-15.docs.kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-1-14/)
추상적인 업그레이드 작업 절차는 다음과 같다.
1. 기본 컨트롤 플레인 노드를 업그레이드한다.
1. 추가 컨트롤 플레인 노드를 업그레이드한다.
1. 워커(worker) 노드를 업그레이드한다.
{{% /capture %}}
{{% capture prerequisites %}}
- 1.17.0 버전 이상을 실행하는 kubeadm 쿠버네티스 클러스터가 있어야 한다.
- [스왑을 비활성화해야 한다](https://serverfault.com/questions/684771/best-way-to-disable-swap-in-linux).
- 클러스터는 정적 컨트롤 플레인 및 etcd 파드 또는 외부 etcd를 사용해야 한다.
- [릴리스 노트]({{< latest-release-notes >}})를 주의 깊게 읽어야 한다.
- 데이터베이스에 저장된 앱-레벨 상태와 같은 중요한 컴포넌트를 반드시 백업한다.
`kubeadm upgrade` 는 워크로드에 영향을 미치지 않고, 쿠버네티스 내부의 컴포넌트만 다루지만, 백업은 항상 모범 사례일 정도로 중요하다.
### 추가 정보
- 컨테이너 사양 해시 값이 변경되므로, 업그레이드 후 모든 컨테이너가 다시 시작된다.
- 하나의 MINOR 버전에서 다음 MINOR 버전으로,
또는 동일한 MINOR의 PATCH 버전 사이에서만 업그레이드할 수 있다. 즉, 업그레이드할 때 MINOR 버전을 건너 뛸 수 없다.
예를 들어, 1.y에서 1.y+1로 업그레이드할 수 있지만, 1.y에서 1.y+2로 업그레이드할 수는 없다.
{{% /capture %}}
{{% capture steps %}}
## 업그레이드할 버전 결정
1. 최신의 안정 버전인 1.18을 찾는다.
{{< tabs name="k8s_install_versions" >}}
{{% tab name="Ubuntu, Debian 또는 HypriotOS" %}}
apt update
apt-cache madison kubeadm
# 목록에서 최신 버전 1.18을 찾는다
# 1.18.x-00과 같아야 한다. 여기서 x는 최신 패치이다.
{{% /tab %}}
{{% tab name="CentOS, RHEL 또는 Fedora" %}}
yum list --showduplicates kubeadm --disableexcludes=kubernetes
# 목록에서 최신 버전 1.18을 찾는다
# 1.18.x-0과 같아야 한다. 여기서 x는 최신 패치이다.
{{% /tab %}}
{{< /tabs >}}
## 컨트롤 플레인 노드 업그레이드
### 첫 번째 컨트롤 플레인 노드 업그레이드
1. 첫 번째 컨트롤 플레인 노드에서 kubeadm을 업그레이드한다.
{{< tabs name="k8s_install_kubeadm_first_cp" >}}
{{% tab name="Ubuntu, Debian 또는 HypriotOS" %}}
# 1.18.x-00에서 x를 최신 패치 버전으로 바꾼다.
apt-mark unhold kubeadm && \
apt-get update && apt-get install -y kubeadm=1.18.x-00 && \
apt-mark hold kubeadm
# apt-get 버전 1.1부터 다음 방법을 사용할 수도 있다
apt-get update && \
apt-get install -y --allow-change-held-packages kubeadm=1.18.x-00
{{% /tab %}}
{{% tab name="CentOS, RHEL 또는 Fedora" %}}
# 1.18.x-0에서 x를 최신 패치 버전으로 바꾼다.
yum install -y kubeadm-1.18.x-0 --disableexcludes=kubernetes
{{% /tab %}}
{{< /tabs >}}
1. 다운로드하려는 버전이 잘 받아졌는지 확인한다.
```shell
kubeadm version
```
1. 컨트롤 플레인 노드를 드레인(drain)한다.
```shell
# <cp-node-name>을 컨트롤 플레인 노드 이름으로 바꾼다.
kubectl drain <cp-node-name> --ignore-daemonsets
```
1. 컨트롤 플레인 노드에서 다음을 실행한다.
```shell
sudo kubeadm upgrade plan
```
다음과 비슷한 출력이 표시되어야 한다.
```
[upgrade/config] Making sure the configuration is correct:
[upgrade/config] Reading configuration from the cluster...
[upgrade/config] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'
[preflight] Running pre-flight checks.
[upgrade] Running cluster health checks
[upgrade] Fetching available versions to upgrade to
[upgrade/versions] Cluster version: v1.17.3
[upgrade/versions] kubeadm version: v1.18.0
[upgrade/versions] Latest stable version: v1.18.0
[upgrade/versions] Latest version in the v1.17 series: v1.18.0
Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply':
COMPONENT CURRENT AVAILABLE
Kubelet 1 x v1.17.3 v1.18.0
Upgrade to the latest version in the v1.17 series:
COMPONENT CURRENT AVAILABLE
API Server v1.17.3 v1.18.0
Controller Manager v1.17.3 v1.18.0
Scheduler v1.17.3 v1.18.0
Kube Proxy v1.17.3 v1.18.0
CoreDNS 1.6.5 1.6.7
Etcd 3.4.3 3.4.3-0
You can now apply the upgrade by executing the following command:
kubeadm upgrade apply v1.18.0
_____________________________________________________________________
```
이 명령은 클러스터를 업그레이드할 수 있는지를 확인하고, 업그레이드할 수 있는 버전을 가져온다.
{{< note >}}
또한 `kubeadm upgrade` 는 이 노드에서 관리하는 인증서를 자동으로 갱신한다.
인증서 갱신을 하지 않으려면 `--certificate-renewal=false` 플래그를 사용할 수 있다.
자세한 내용은 [인증서 관리 가이드](/docs/tasks/administer-cluster/kubeadm/kubeadm-certs)를 참고한다.
{{</ note >}}
1. 업그레이드할 버전을 선택하고, 적절한 명령을 실행한다. 예를 들면 다음과 같다.
```shell
# 이 업그레이드를 위해 선택한 패치 버전으로 x를 바꾼다.
sudo kubeadm upgrade apply v1.18.x
```
다음과 비슷한 출력이 표시되어야 한다.
```
[upgrade/config] Making sure the configuration is correct:
[upgrade/config] Reading configuration from the cluster...
[upgrade/config] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'
[preflight] Running pre-flight checks.
[upgrade] Running cluster health checks
[upgrade/version] You have chosen to change the cluster version to "v1.18.0"
[upgrade/versions] Cluster version: v1.17.3
[upgrade/versions] kubeadm version: v1.18.0
[upgrade/confirm] Are you sure you want to proceed with the upgrade? [y/N]: y
[upgrade/prepull] Will prepull images for components [kube-apiserver kube-controller-manager kube-scheduler etcd]
[upgrade/prepull] Prepulling image for component etcd.
[upgrade/prepull] Prepulling image for component kube-apiserver.
[upgrade/prepull] Prepulling image for component kube-controller-manager.
[upgrade/prepull] Prepulling image for component kube-scheduler.
[apiclient] Found 1 Pods for label selector k8s-app=upgrade-prepull-kube-controller-manager
[apiclient] Found 0 Pods for label selector k8s-app=upgrade-prepull-etcd
[apiclient] Found 0 Pods for label selector k8s-app=upgrade-prepull-kube-scheduler
[apiclient] Found 1 Pods for label selector k8s-app=upgrade-prepull-kube-apiserver
[apiclient] Found 1 Pods for label selector k8s-app=upgrade-prepull-etcd
[apiclient] Found 1 Pods for label selector k8s-app=upgrade-prepull-kube-scheduler
[upgrade/prepull] Prepulled image for component etcd.
[upgrade/prepull] Prepulled image for component kube-apiserver.
[upgrade/prepull] Prepulled image for component kube-controller-manager.
[upgrade/prepull] Prepulled image for component kube-scheduler.
[upgrade/prepull] Successfully prepulled the images for all the control plane components
[upgrade/apply] Upgrading your Static Pod-hosted control plane to version "v1.18.0"...
Static pod: kube-apiserver-myhost hash: 2cc222e1a577b40a8c2832320db54b46
Static pod: kube-controller-manager-myhost hash: f7ce4bc35cb6e646161578ac69910f18
Static pod: kube-scheduler-myhost hash: e3025acd90e7465e66fa19c71b916366
[upgrade/etcd] Upgrading to TLS for etcd
[upgrade/etcd] Non fatal issue encountered during upgrade: the desired etcd version for this Kubernetes version "v1.18.0" is "3.4.3-0", but the current etcd version is "3.4.3". Won't downgrade etcd, instead just continue
[upgrade/staticpods] Writing new Static Pod manifests to "/etc/kubernetes/tmp/kubeadm-upgraded-manifests308527012"
W0308 18:48:14.535122 3082 manifests.go:225] the default kube-apiserver authorization-mode is "Node,RBAC"; using "Node,RBAC"
[upgrade/staticpods] Preparing for "kube-apiserver" upgrade
[upgrade/staticpods] Renewing apiserver certificate
[upgrade/staticpods] Renewing apiserver-kubelet-client certificate
[upgrade/staticpods] Renewing front-proxy-client certificate
[upgrade/staticpods] Renewing apiserver-etcd-client certificate
[upgrade/staticpods] Moved new manifest to "/etc/kubernetes/manifests/kube-apiserver.yaml" and backed up old manifest to "/etc/kubernetes/tmp/kubeadm-backup-manifests-2020-03-08-18-48-14/kube-apiserver.yaml"
[upgrade/staticpods] Waiting for the kubelet to restart the component
[upgrade/staticpods] This might take a minute or longer depending on the component/version gap (timeout 5m0s)
Static pod: kube-apiserver-myhost hash: 2cc222e1a577b40a8c2832320db54b46
Static pod: kube-apiserver-myhost hash: 609429acb0d71dce6725836dd97d8bf4
[apiclient] Found 1 Pods for label selector component=kube-apiserver
[upgrade/staticpods] Component "kube-apiserver" upgraded successfully!
[upgrade/staticpods] Preparing for "kube-controller-manager" upgrade
[upgrade/staticpods] Renewing controller-manager.conf certificate
[upgrade/staticpods] Moved new manifest to "/etc/kubernetes/manifests/kube-controller-manager.yaml" and backed up old manifest to "/etc/kubernetes/tmp/kubeadm-backup-manifests-2020-03-08-18-48-14/kube-controller-manager.yaml"
[upgrade/staticpods] Waiting for the kubelet to restart the component
[upgrade/staticpods] This might take a minute or longer depending on the component/version gap (timeout 5m0s)
Static pod: kube-controller-manager-myhost hash: f7ce4bc35cb6e646161578ac69910f18
Static pod: kube-controller-manager-myhost hash: c7a1232ba2c5dc15641c392662fe5156
[apiclient] Found 1 Pods for label selector component=kube-controller-manager
[upgrade/staticpods] Component "kube-controller-manager" upgraded successfully!
[upgrade/staticpods] Preparing for "kube-scheduler" upgrade
[upgrade/staticpods] Renewing scheduler.conf certificate
[upgrade/staticpods] Moved new manifest to "/etc/kubernetes/manifests/kube-scheduler.yaml" and backed up old manifest to "/etc/kubernetes/tmp/kubeadm-backup-manifests-2020-03-08-18-48-14/kube-scheduler.yaml"
[upgrade/staticpods] Waiting for the kubelet to restart the component
[upgrade/staticpods] This might take a minute or longer depending on the component/version gap (timeout 5m0s)
Static pod: kube-scheduler-myhost hash: e3025acd90e7465e66fa19c71b916366
Static pod: kube-scheduler-myhost hash: b1b721486ae0ac504c160dcdc457ab0d
[apiclient] Found 1 Pods for label selector component=kube-scheduler
[upgrade/staticpods] Component "kube-scheduler" upgraded successfully!
[upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[kubelet] Creating a ConfigMap "kubelet-config-1.18" in namespace kube-system with the configuration for the kubelets in the cluster
[kubelet-start] Downloading configuration for the kubelet from the "kubelet-config-1.18" ConfigMap in the kube-system namespace
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstrap-token] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstrap-token] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy
[upgrade/successful] SUCCESS! Your cluster was upgraded to "v1.18.0". Enjoy!
[upgrade/kubelet] Now that your control plane is upgraded, please proceed with upgrading your kubelets if you haven't already done so.
```
1. CNI 제공자 플러그인을 수동으로 업그레이드한다.
CNI(컨테이너 네트워크 인터페이스) 제공자는 자체 업그레이드 지침을 따를 수 있다.
[애드온](/docs/concepts/cluster-administration/addons/) 페이지에서
사용하는 CNI 제공자를 찾고 추가 업그레이드 단계가 필요한지 여부를 확인한다.
CNI 제공자가 데몬셋(DaemonSet)으로 실행되는 경우 추가 컨트롤 플레인 노드에는 이 단계가 필요하지 않다.
1. 컨트롤 플레인 노드에 적용된 cordon을 해제한다.
```shell
# <cp-node-name>을 컨트롤 플레인 노드 이름으로 바꾼다.
kubectl uncordon <cp-node-name>
```
### 추가 컨트롤 플레인 노드 업그레이드
1. 첫 번째 컨트롤 플레인 노드와 동일하지만 다음을 사용한다.
```
sudo kubeadm upgrade node
```
아래 명령 대신 위의 명령을 사용한다.
```
sudo kubeadm upgrade apply
```
또한 `sudo kubeadm upgrade plan` 은 필요하지 않다.
### kubelet과 kubectl 업그레이드
1. 모든 컨트롤 플레인 노드에서 kubelet 및 kubectl을 업그레이드한다.
{{< tabs name="k8s_install_kubelet" >}}
{{% tab name="Ubuntu, Debian 또는 HypriotOS" %}}
# 1.18.x-00의 x를 최신 패치 버전으로 바꾼다
apt-mark unhold kubelet kubectl && \
apt-get update && apt-get install -y kubelet=1.18.x-00 kubectl=1.18.x-00 && \
apt-mark hold kubelet kubectl
# apt-get 버전 1.1부터 다음 방법을 사용할 수도 있다
apt-get update && \
apt-get install -y --allow-change-held-packages kubelet=1.18.x-00 kubectl=1.18.x-00
{{% /tab %}}
{{% tab name="CentOS, RHEL 또는 Fedora" %}}
# 1.18.x-0에서 x를 최신 패치 버전으로 바꾼다
yum install -y kubelet-1.18.x-0 kubectl-1.18.x-0 --disableexcludes=kubernetes
{{% /tab %}}
{{< /tabs >}}
1. kubelet을 다시 시작한다.
```shell
sudo systemctl restart kubelet
```
## 워커 노드 업그레이드
워커 노드의 업그레이드 절차는 워크로드를 실행하는 데 필요한 최소 용량을 보장하면서,
한 번에 하나의 노드 또는 한 번에 몇 개의 노드로 실행해야 한다.
### kubeadm 업그레이드
1. 모든 워커 노드에서 kubeadm을 업그레이드한다.
{{< tabs name="k8s_install_kubeadm_worker_nodes" >}}
{{% tab name="Ubuntu, Debian 또는 HypriotOS" %}}
# 1.18.x-00의 x를 최신 패치 버전으로 바꾼다
apt-mark unhold kubeadm && \
apt-get update && apt-get install -y kubeadm=1.18.x-00 && \
apt-mark hold kubeadm
# apt-get 버전 1.1부터 다음 방법을 사용할 수도 있다
apt-get update && \
apt-get install -y --allow-change-held-packages kubeadm=1.18.x-00
{{% /tab %}}
{{% tab name="CentOS, RHEL 또는 Fedora" %}}
# 1.18.x-0에서 x를 최신 패치 버전으로 바꾼다
yum install -y kubeadm-1.18.x-0 --disableexcludes=kubernetes
{{% /tab %}}
{{< /tabs >}}
### 노드 드레인
1. 스케줄 불가능(unschedulable)으로 표시하고 워크로드를 축출하여 유지 보수할 노드를 준비한다.
```shell
# <node-to-drain>을 드레이닝하려는 노드 이름으로 바꾼다.
kubectl drain <node-to-drain> --ignore-daemonsets
```
다음과 비슷한 출력이 표시되어야 한다.
```
node/ip-172-31-85-18 cordoned
WARNING: ignoring DaemonSet-managed Pods: kube-system/kube-proxy-dj7d7, kube-system/weave-net-z65qx
node/ip-172-31-85-18 drained
```
### kubelet 구성 업그레이드
1. 다음의 명령을 호출한다.
```shell
sudo kubeadm upgrade node
```
### kubelet과 kubectl 업그레이드
1. 모든 워커 노드에서 kubelet 및 kubectl을 업그레이드한다.
{{< tabs name="k8s_kubelet_and_kubectl" >}}
{{% tab name="Ubuntu, Debian 또는 HypriotOS" %}}
# 1.18.x-00의 x를 최신 패치 버전으로 바꾼다
apt-mark unhold kubelet kubectl && \
apt-get update && apt-get install -y kubelet=1.18.x-00 kubectl=1.18.x-00 && \
apt-mark hold kubelet kubectl
# apt-get 버전 1.1부터 다음 방법을 사용할 수도 있다
apt-get update && \
apt-get install -y --allow-change-held-packages kubelet=1.18.x-00 kubectl=1.18.x-00
{{% /tab %}}
{{% tab name="CentOS, RHEL 또는 Fedora" %}}
# 1.18.x-0에서 x를 최신 패치 버전으로 바꾼다
yum install -y kubelet-1.18.x-0 kubectl-1.18.x-0 --disableexcludes=kubernetes
{{% /tab %}}
{{< /tabs >}}
1. kubelet을 다시 시작한다.
```shell
sudo systemctl restart kubelet
```
### 노드에 적용된 cordon 해제
1. 스케줄 가능(schedulable)으로 표시하여 노드를 다시 온라인 상태로 만든다.
```shell
# <node-to-drain>을 노드의 이름으로 바꾼다.
kubectl uncordon <node-to-drain>
```
## 클러스터 상태 확인
모든 노드에서 kubelet을 업그레이드 한 후 kubectl이 클러스터에 접근할 수 있는 곳에서 다음의 명령을 실행하여 모든 노드를 다시 사용할 수 있는지 확인한다.
```shell
kubectl get nodes
```
모든 노드에 대해 `STATUS` 열에 `Ready` 가 표시되어야 하고, 버전 번호가 업데이트되어 있어야 한다.
{{% /capture %}}
## 장애 상태에서의 복구
예를 들어 `kubeadm upgrade` 를 실행하는 중에 예기치 못한 종료로 인해 업그레이드가 실패하고 롤백하지 않는다면, `kubeadm upgrade` 를 다시 실행할 수 있다.
이 명령은 멱등성을 보장하며 결국 실제 상태가 선언한 의도한 상태인지 확인한다.
잘못된 상태에서 복구하기 위해, 클러스터가 실행 중인 버전을 변경하지 않고 `kubeadm upgrade apply --force` 를 실행할 수도 있다.
업그레이드하는 동안 kubeadm은 `/etc/kubernetes/tmp` 아래에 다음과 같은 백업 폴더를 작성한다.
- `kubeadm-backup-etcd-<date>-<time>`
- `kubeadm-backup-manifests-<date>-<time>`
`kubeadm-backup-etcd` 는 컨트롤 플레인 노드에 대한 로컬 etcd 멤버 데이터의 백업을 포함한다.
etcd 업그레이드가 실패하고 자동 롤백이 작동하지 않으면, 이 폴더의 내용을
`/var/lib/etcd` 에서 수동으로 복원할 수 있다. 외부 etcd를 사용하는 경우 이 백업 폴더는 비어있다.
`kubeadm-backup-manifests` 는 컨트롤 플레인 노드에 대한 정적 파드 매니페스트 파일의 백업을 포함한다.
업그레이드가 실패하고 자동 롤백이 작동하지 않으면, 이 폴더의 내용을
`/etc/kubernetes/manifests` 에서 수동으로 복원할 수 있다. 어떤 이유로 특정 컴포넌트의 업그레이드 전
매니페스트 파일과 업그레이드 후 매니페스트 파일 간에 차이가 없는 경우, 백업 파일은 기록되지 않는다.
## 작동 원리
`kubeadm upgrade apply` 는 다음을 수행한다.
- 클러스터가 업그레이드 가능한 상태인지 확인한다.
- API 서버에 접근할 수 있다
- 모든 노드가 `Ready` 상태에 있다
- 컨트롤 플레인이 정상적으로 동작한다
- 버전 차이(skew) 정책을 적용한다.
- 컨트롤 플레인 이미지가 사용 가능한지 또는 머신으로 가져올 수 있는지 확인한다.
- 컨트롤 플레인 컴포넌트 또는 롤백 중 하나라도 나타나지 않으면 업그레이드한다.
- 새로운 `kube-dns``kube-proxy` 매니페스트를 적용하고 필요한 모든 RBAC 규칙이 생성되도록 한다.
- API 서버의 새 인증서와 키 파일을 작성하고 180일 후에 만료될 경우 이전 파일을 백업한다.
`kubeadm upgrade node` 는 추가 컨트롤 플레인 노드에서 다음을 수행한다.
- 클러스터에서 kubeadm `ClusterConfiguration` 을 가져온다.
- 선택적으로 kube-apiserver 인증서를 백업한다.
- 컨트롤 플레인 컴포넌트에 대한 정적 파드 매니페스트를 업그레이드한다.
- 이 노드의 kubelet 구성을 업그레이드한다.
`kubeadm upgrade node` 는 워커 노드에서 다음을 수행한다.
- 클러스터에서 kubeadm `ClusterConfiguration` 을 가져온다.
- 이 노드의 kubelet 구성을 업그레이드한다.

View File

@ -0,0 +1,145 @@
---
title: 스토리지의 볼륨을 사용하는 파드 구성
content_template: templates/task
weight: 50
---
{{% capture overview %}}
이 페이지는 스토리지의 볼륨을 사용하는 파드를 구성하는 방법을 설명한다.
컨테이너 파일 시스템은 컨테이너가 살아있는 동안만 존재한다. 따라서
컨테이너가 종료되고 재시작할 때, 파일 시스템 변경사항이 손실된다. 컨테이너와
독립적이며 보다 일관된 스토리지를 위해 사용자는 [볼륨](/ko/docs/concepts/storage/volumes/)을
사용할 수 있다. 이것은 레디스(Redis)와 같은 키-값 저장소나
데이터베이스와 같은 스테이트풀 애플리케이션에 매우 중요하다.
{{% /capture %}}
{{% capture prerequisites %}}
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
{{% /capture %}}
{{% capture steps %}}
## 파드에 볼륨 구성
이 연습에서는 하나의 컨테이너를 실행하는 파드를 생성한다. 이 파드는
컨테이너가
종료되고, 재시작 하더라도 파드의 수명동안 지속되는 [emptyDir](/ko/docs/concepts/storage/volumes/#emptydir)
유형의 볼륨이 있다.
파드의 구성 파일은 다음과 같다.
{{< codenew file="pods/storage/redis.yaml" >}}
1. 파드 생성
```shell
kubectl apply -f https://k8s.io/examples/pods/storage/redis.yaml
```
1. 파드의 컨테이너가 Running 중인지 확인하고, 파드의 변경사항을
지켜본다.
```shell
kubectl get pod redis --watch
```
출력은 이와 유사하다.
```shell
NAME READY STATUS RESTARTS AGE
redis 1/1 Running 0 13s
```
1. 다른 터미널에서 실행 중인 컨테이너의 셸을 획득한다.
```shell
kubectl exec -it redis -- /bin/bash
```
1. 셸에서 `/data/redis` 로 이동하고, 파일을 생성한다.
```shell
root@redis:/data# cd /data/redis/
root@redis:/data/redis# echo Hello > test-file
```
1. 셸에서 실행 중인 프로세스 목록을 확인한다.
```shell
root@redis:/data/redis# apt-get update
root@redis:/data/redis# apt-get install procps
root@redis:/data/redis# ps aux
```
출력은 이와 유사하다.
```shell
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
redis 1 0.1 0.1 33308 3828 ? Ssl 00:46 0:00 redis-server *:6379
root 12 0.0 0.0 20228 3020 ? Ss 00:47 0:00 /bin/bash
root 15 0.0 0.0 17500 2072 ? R+ 00:48 0:00 ps aux
```
1. 셸에서 Redis 프로세스를 강제종료(kill)한다.
```shell
root@redis:/data/redis# kill <pid>
```
여기서 `<pid>`는 Redis 프로세스 ID(PID) 이다.
1. 원래 터미널에서, Redis 파드의 변경을 지켜본다. 결국,
다음과 유사한 것을 보게 될 것이다.
```shell
NAME READY STATUS RESTARTS AGE
redis 1/1 Running 0 13s
redis 0/1 Completed 0 6m
redis 1/1 Running 1 6m
```
이때, 컨테이너는 종료되고 재시작된다. 이는
Redis 파드의
[restartPolicy](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podspec-v1-core)는
`Always` 이기 때문이다.
1. 재시작된 컨테이너의 셸을 획득한다.
```shell
kubectl exec -it redis -- /bin/bash
```
1. 셸에서 `/data/redis` 로 이동하고, `test-file` 이 여전히 존재하는지 확인한다.
```shell
root@redis:/data/redis# cd /data/redis/
root@redis:/data/redis# ls
test-file
```
1. 이 연습을 위해 생성한 파드를 삭제한다.
```shell
kubectl delete pod redis
```
{{% /capture %}}
{{% capture whatsnext %}}
* [볼륨](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#volume-v1-core)을 참고한다.
* [파드](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#pod-v1-core)을 참고한다.
* 쿠버네티스는 `emptyDir` 이 제공하는 로컬 디스크 스토리지 뿐만 아니라,
중요한 데이터에 선호하는 GCE의 PD, EC2의 EBS를 포함해서
네트워크 연결 스토리지(NAS) 솔루션을 지원하며,
노드의 디바이스 마운트, 언마운트와 같은 세부사항을 처리한다.
자세한 내용은 [볼륨](/ko/docs/concepts/storage/volumes/)을 참고한다.
{{% /capture %}}

View File

@ -7,7 +7,7 @@ title: GPU 스케줄링
{{% capture overview %}}
{{< feature-state state="beta" for_k8s_version="1.10" >}}
{{< feature-state state="beta" for_k8s_version="v1.10" >}}
쿠버네티스는 AMD 및 NVIDIA GPU(그래픽 프로세싱 유닛)를 노드들에 걸쳐 관리하기 위한 **실험적인**
지원을 포함한다.

View File

@ -231,7 +231,7 @@ CPU 외에 다른 메트릭을 지정할 수 있는데, 기본적으로 지원
이 자원들은 한 클러스터에서 다른 클러스터로 이름을 변경할 수 없으며,
`metrics.k8s.io` API가 가용한 경우 언제든지 사용할 수 있어야 한다.
또한, `AverageUtilization` 대신 `AverageValue``target` 타입을,
또한, `Utilization` 대신 `AverageValue``target` 타입을,
그리고 `target.averageUtilization` 대신 `target.averageValue`로 설정하여
자원 메트릭을 퍼센트 대신 값으로 명시할 수 있다.

View File

@ -71,7 +71,7 @@ HorizontalPodAutoscaler는 보통 일련의 API 집합(`metrics.k8s.io`,
참조한다. HorizontalPodAutoscaler는 힙스터(Heapster)에서 직접 메트릭을 가져올 수도 있다.
{{< note >}}
{{< feature-state state="deprecated" for_k8s_version="1.11" >}}
{{< feature-state state="deprecated" for_k8s_version="v1.11" >}}
힙스터에서 메트릭 가져오기는 Kubernetes 1.11에서 사용 중단(deprecated)됨.
{{< /note >}}

View File

@ -0,0 +1,496 @@
---
title: kubectl 설치 및 설정
content_template: templates/task
weight: 10
card:
name: tasks
weight: 20
title: kubectl 설치
---
{{% capture overview %}}
쿠버네티스 커맨드 라인 도구인 [kubectl](/docs/user-guide/kubectl/)을 사용하면, 쿠버네티스 클러스터에 대해 명령을 실행할 수 있다. kubectl을 사용하여 애플리케이션을 배포하고, 클러스터 리소스를 검사 및 관리하며 로그를 볼 수 있다. kubectl 작업의 전체 목록에 대해서는, [kubectl 개요](/docs/reference/kubectl/overview/)를 참고한다.
{{% /capture %}}
{{% capture prerequisites %}}
클러스터의 마이너(minor) 버전 차이 내에 있는 kubectl 버전을 사용해야 한다. 예를 들어, v1.2 클라이언트는 v1.1, v1.2 및 v1.3의 마스터와 함께 작동해야 한다. 최신 버전의 kubectl을 사용하면 예기치 않은 문제를 피할 수 있다.
{{% /capture %}}
{{% capture steps %}}
## 리눅스에 kubectl 설치
### 리눅스에서 curl을 사용하여 kubectl 바이너리 설치
1. 다음 명령으로 최신 릴리스를 다운로드한다.
```
curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl
```
특정 버전을 다운로드하려면, `$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)` 명령 부분을 특정 버전으로 바꾼다.
예를 들어, 리눅스에서 버전 {{< param "fullversion" >}}을 다운로드하려면, 다음을 입력한다.
```
curl -LO https://storage.googleapis.com/kubernetes-release/release/{{< param "fullversion" >}}/bin/linux/amd64/kubectl
```
2. kubectl 바이너리를 실행 가능하게 만든다.
```
chmod +x ./kubectl
```
3. 바이너리를 PATH가 설정된 디렉터리로 옮긴다.
```
sudo mv ./kubectl /usr/local/bin/kubectl
```
4. 설치한 버전이 최신 버전인지 확인한다.
```
kubectl version --client
```
### 기본 패키지 관리 도구를 사용하여 설치
{{< tabs name="kubectl_install" >}}
{{< tab name="Ubuntu, Debian 또는 HypriotOS" codelang="bash" >}}
sudo apt-get update && sudo apt-get install -y apt-transport-https gnupg2
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee -a /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubectl
{{< /tab >}}
{{< tab name="CentOS, RHEL 또는 Fedora" codelang="bash" >}}cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF
yum install -y kubectl
{{< /tab >}}
{{< /tabs >}}
### 다른 패키지 관리 도구를 사용하여 설치
{{< tabs name="other_kubectl_install" >}}
{{% tab name="Snap" %}}
[snap](https://snapcraft.io/docs/core/install) 패키지 관리자를 지원하는 Ubuntu 또는 다른 리눅스 배포판을 사용하는 경우, kubectl을 [snap](https://snapcraft.io/) 애플리케이션으로 설치할 수 있다.
```shell
snap install kubectl --classic
kubectl version --client
```
{{% /tab %}}
{{% tab name="Homebrew" %}}
리눅스 상에서 [Homebrew](https://docs.brew.sh/Homebrew-on-Linux) 패키지 관리자를 사용한다면, [설치](https://docs.brew.sh/Homebrew-on-Linux#install)를 통해 kubectl을 사용할 수 있다.
```shell
brew install kubectl
kubectl version --client
```
{{% /tab %}}
{{< /tabs >}}
## macOS에 kubectl 설치
### macOS에서 curl을 사용하여 kubectl 바이너리 설치
1. 최신 릴리스를 다운로드한다.
```
curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/darwin/amd64/kubectl"
```
특정 버전을 다운로드하려면, `$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)` 명령 부분을 특정 버전으로 바꾼다.
예를 들어, macOS에서 버전 {{< param "fullversion" >}}을 다운로드하려면, 다음을 입력한다.
```
curl -LO https://storage.googleapis.com/kubernetes-release/release/{{< param "fullversion" >}}/bin/darwin/amd64/kubectl
```
2. kubectl 바이너리를 실행 가능하게 만든다.
```
chmod +x ./kubectl
```
3. 바이너리를 PATH가 설정된 디렉터리로 옮긴다.
```
sudo mv ./kubectl /usr/local/bin/kubectl
```
4. 설치한 버전이 최신 버전인지 확인한다.
```
kubectl version --client
```
### macOS에서 Homebrew를 사용하여 설치
macOS에서 [Homebrew](https://brew.sh/) 패키지 관리자를 사용하는 경우, Homebrew로 kubectl을 설치할 수 있다.
1. 설치 명령을 실행한다.
```
brew install kubectl
```
또는
```
brew install kubernetes-cli
```
2. 설치한 버전이 최신 버전인지 확인한다.
```
kubectl version --client
```
### macOS에서 Macports를 사용하여 설치
macOS에서 [Macports](https://macports.org/) 패키지 관리자를 사용하는 경우, Macports로 kubectl을 설치할 수 있다.
1. 설치 명령을 실행한다.
```
sudo port selfupdate
sudo port install kubectl
```
2. 설치한 버전이 최신 버전인지 확인한다.
```
kubectl version --client
```
## Windows에 kubectl 설치
### Windows에서 curl을 사용하여 kubectl 바이너리 설치
1. [이 링크](https://storage.googleapis.com/kubernetes-release/release/{{< param "fullversion" >}}/bin/windows/amd64/kubectl.exe)에서 최신 릴리스 {{< param "fullversion" >}}을 다운로드한다.
또는 `curl` 을 설치한 경우, 다음 명령을 사용한다.
```
curl -LO https://storage.googleapis.com/kubernetes-release/release/{{< param "fullversion" >}}/bin/windows/amd64/kubectl.exe
```
최신의 안정 버전(예: 스크립팅을 위한)을 찾으려면, [https://storage.googleapis.com/kubernetes-release/release/stable.txt](https://storage.googleapis.com/kubernetes-release/release/stable.txt)를 참고한다.
2. 바이너리를 PATH가 설정된 디렉터리에 추가한다.
3. `kubectl` 의 버전이 다운로드한 버전과 같은지 확인한다.
```
kubectl version --client
```
{{< note >}}
[Windows용 도커 데스크톱](https://docs.docker.com/docker-for-windows/#kubernetes)은 자체 버전의 `kubectl` 을 PATH에 추가한다.
도커 데스크톱을 이전에 설치한 경우, 도커 데스크톱 설치 프로그램에서 추가한 PATH 항목 앞에 PATH 항목을 배치하거나 도커 데스크톱의 `kubectl` 을 제거해야 할 수도 있다.
{{< /note >}}
### PSGallery에서 Powershell로 설치
Windows에서 [Powershell Gallery](https://www.powershellgallery.com/) 패키지 관리자를 사용하는 경우, Powershell로 kubectl을 설치하고 업데이트할 수 있다.
1. 설치 명령을 실행한다(`DownloadLocation` 을 지정해야 한다).
```
Install-Script -Name install-kubectl -Scope CurrentUser -Force
install-kubectl.ps1 [-DownloadLocation <path>]
```
{{< note >}}`DownloadLocation` 을 지정하지 않으면, `kubectl` 은 사용자의 임시 디렉터리에 설치된다.{{< /note >}}
설치 프로그램은 `$HOME/.kube` 를 생성하고 구성 파일을 작성하도록 지시한다.
2. 설치한 버전이 최신 버전인지 확인한다.
```
kubectl version --client
```
{{< note >}}설치 업데이트는 1 단계에서 나열한 두 명령을 다시 실행하여 수행한다.{{< /note >}}
### Chocolatey 또는 Scoop을 사용하여 Windows에 설치
Windows에 kubectl을 설치하기 위해서 [Chocolatey](https://chocolatey.org) 패키지 관리자나 [Scoop](https://scoop.sh) 커맨드 라인 설치 프로그램을 사용할 수 있다.
{{< tabs name="kubectl_win_install" >}}
{{% tab name="choco" %}}
choco install kubernetes-cli
{{% /tab %}}
{{% tab name="scoop" %}}
scoop install kubectl
{{% /tab %}}
{{< /tabs >}}
2. 설치한 버전이 최신 버전인지 확인한다.
```
kubectl version --client
```
3. 홈 디렉토리로 이동한다.
```
cd %USERPROFILE%
```
4. `.kube` 디렉터리를 생성한다.
```
mkdir .kube
```
5. 금방 생성한 `.kube` 디렉터리로 이동한다.
```
cd .kube
```
6. 원격 쿠버네티스 클러스터를 사용하도록 kubectl을 구성한다.
```
New-Item config -type file
```
{{< note >}}메모장과 같은 텍스트 편집기를 선택하여 구성 파일을 편집한다.{{< /note >}}
## Google Cloud SDK의 일부로 다운로드
kubectl을 Google Cloud SDK의 일부로 설치할 수 있다.
1. [Google Cloud SDK](https://cloud.google.com/sdk/)를 설치한다.
2. `kubectl` 설치 명령을 실행한다.
```
gcloud components install kubectl
```
3. 설치한 버전이 최신 버전인지 확인한다.
```
kubectl version --client
```
## kubectl 구성 확인
kubectl이 쿠버네티스 클러스터를 찾아 접근하려면, [kube-up.sh](https://github.com/kubernetes/kubernetes/blob/master/cluster/kube-up.sh)를 사용하여 클러스터를 생성하거나 Minikube 클러스터를 성공적으로 배포할 때 자동으로 생성되는 [kubeconfig 파일](/ko/docs/tasks/access-application-cluster/configure-access-multiple-clusters/)이 필요하다. 기본적으로, kubectl 구성은 `~/.kube/config` 에 있다.
클러스터 상태를 가져와서 kubectl이 올바르게 구성되어 있는지 확인한다.
```shell
kubectl cluster-info
```
URL 응답이 표시되면, kubectl이 클러스터에 접근하도록 올바르게 구성된 것이다.
다음과 비슷한 메시지가 표시되면, kubectl이 올바르게 구성되지 않았거나 쿠버네티스 클러스터에 연결할 수 없다.
```shell
The connection to the server <server-name:port> was refused - did you specify the right host or port?
```
예를 들어, 랩톱에서 로컬로 쿠버네티스 클러스터를 실행하려면, Minikube와 같은 도구를 먼저 설치한 다음 위에서 언급한 명령을 다시 실행해야 한다.
kubectl cluster-info가 URL 응답을 반환하지만 클러스터에 접근할 수 없는 경우, 올바르게 구성되었는지 확인하려면 다음을 사용한다.
```shell
kubectl cluster-info dump
```
## 선택적 kubectl 구성
### 셸 자동 완성 활성화
kubectl은 Bash 및 Zsh에 대한 자동 완성 지원을 제공하므로 입력을 위한 타이핑을 많이 절약할 수 있다.
다음은 Bash(리눅스와 macOS의 다른 점 포함) 및 Zsh에 대한 자동 완성을 설정하는 절차이다.
{{< tabs name="kubectl_autocompletion" >}}
{{% tab name="리눅스에서의 Bash" %}}
### 소개
Bash의 kubectl 완성 스크립트는 `kubectl completion bash` 명령으로 생성할 수 있다. 셸에서 완성 스크립트를 소싱(sourcing)하면 kubectl 자동 완성 기능이 활성화된다.
그러나, 완성 스크립트는 [**bash-completion**](https://github.com/scop/bash-completion)에 의존하고 있으며, 이 소프트웨어를 먼저 설치해야 한다(`type _init_completion` 을 실행하여 bash-completion이 이미 설치되어 있는지 확인할 수 있음).
### bash-completion 설치
bash-completion은 많은 패키지 관리자에 의해 제공된다([여기](https://github.com/scop/bash-completion#installation) 참고). `apt-get install bash-completion` 또는 `yum install bash-completion` 등으로 설치할 수 있다.
위의 명령은 bash-completion의 기본 스크립트인 `/usr/share/bash-completion/bash_completion` 을 생성한다. 패키지 관리자에 따라, `~/.bashrc` 파일에서 이 파일을 수동으로 소스(source)해야 한다.
확인하려면, 셸을 다시 로드하고 `type _init_completion` 을 실행한다. 명령이 성공하면, 이미 설정된 상태이고, 그렇지 않으면 `~/.bashrc` 파일에 다음을 추가한다.
```shell
source /usr/share/bash-completion/bash_completion
```
셸을 다시 로드하고 `type _init_completion` 을 입력하여 bash-completion이 올바르게 설치되었는지 확인한다.
### kubectl 자동 완성 활성화
이제 kubectl 완성 스크립트가 모든 셸 세션에서 제공되도록 해야 한다. 이를 수행할 수 있는 두 가지 방법이 있다.
- `~/.bashrc` 파일에서 완성 스크립트를 소싱한다.
```shell
echo 'source <(kubectl completion bash)' >>~/.bashrc
```
- 완성 스크립트를 `/etc/bash_completion.d` 디렉터리에 추가한다.
```shell
kubectl completion bash >/etc/bash_completion.d/kubectl
```
- kubectl에 대한 앨리어스(alias)가 있는 경우, 해당 앨리어스로 작업하도록 셸 완성을 확장할 수 있다.
```shell
echo 'alias k=kubectl' >>~/.bashrc
echo 'complete -F __start_kubectl k' >>~/.bashrc
```
{{< note >}}
bash-completion은 `/etc/bash_completion.d` 에 있는 모든 완성 스크립트를 소싱한다.
{{< /note >}}
두 방법 모두 동일하다. 셸을 다시 로드한 후, kubectl 자동 완성 기능이 작동해야 한다.
{{% /tab %}}
{{% tab name="macOS에서의 Bash" %}}
### 소개
Bash의 kubectl 완성 스크립트는 `kubectl completion bash` 로 생성할 수 있다. 이 스크립트를 셸에 소싱하면 kubectl 완성이 가능하다.
그러나 kubectl 완성 스크립트는 미리 [**bash-completion**](https://github.com/scop/bash-completion)을 설치해야 동작한다.
{{< warning>}}
bash-completion에는 v1과 v2 두 가지 버전이 있다. v1은 Bash 3.2(macOS의 기본 설치 버전) 버전용이고, v2는 Bash 4.1 이상 버전용이다. kubectl 완성 스크립트는 bash-completion v1과 Bash 3.2 버전에서는 **작동하지 않는다**. **bash-completion v2****Bash 4.1 이상 버전** 이 필요하다. 따라서, macOS에서 kubectl 완성 기능을 올바르게 사용하려면, Bash 4.1 이상을 설치하고 사용해야한다([*지침*](https://itnext.io/upgrading-bash-on-macos-7138bd1066ba)). 다음의 내용에서는 Bash 4.1 이상(즉, 모든 Bash 버전 4.1 이상)을 사용한다고 가정한다.
{{< /warning >}}
### Bash 업그레이드
여기의 지침에서는 Bash 4.1 이상을 사용한다고 가정한다. 다음을 실행하여 Bash 버전을 확인할 수 있다.
```shell
echo $BASH_VERSION
```
너무 오래된 버전인 경우, Homebrew를 사용하여 설치/업그레이드할 수 있다.
```shell
brew install bash
```
셸을 다시 로드하고 원하는 버전을 사용 중인지 확인한다.
```shell
echo $BASH_VERSION $SHELL
```
Homebrew는 보통 `/usr/local/bin/bash` 에 설치한다.
### bash-completion 설치
{{< note >}}
언급한 바와 같이, 이 지침에서는 Bash 4.1 이상을 사용한다고 가정한다. 이는 bash-completion v2를 설치한다는 것을 의미한다(Bash 3.2 및 bash-completion v1의 경우, kubectl 완성이 작동하지 않음).
{{< /note >}}
bash-completion v2가 이미 설치되어 있는지 `type_init_completion` 으로 확인할 수 있다. 그렇지 않은 경우, Homebrew로 설치할 수 있다.
```shell
brew install bash-completion@2
```
이 명령의 출력에 명시된 바와 같이, `~/.bash_profile` 파일에 다음을 추가한다.
```shell
export BASH_COMPLETION_COMPAT_DIR="/usr/local/etc/bash_completion.d"
[[ -r "/usr/local/etc/profile.d/bash_completion.sh" ]] && . "/usr/local/etc/profile.d/bash_completion.sh"
```
셸을 다시 로드하고 bash-completion v2가 올바르게 설치되었는지 `type _init_completion` 으로 확인한다.
### kubectl 자동 완성 활성화
이제 kubectl 완성 스크립트가 모든 셸 세션에서 제공되도록 해야 한다. 이를 수행하는 방법에는 여러 가지가 있다.
- 완성 스크립트를 `~/.bash_profile` 파일에서 소싱한다.
```shell
echo 'source <(kubectl completion bash)' >>~/.bash_profile
```
- 완성 스크립트를 `/usr/local/etc/bash_completion.d` 디렉터리에 추가한다.
```shell
kubectl completion bash >/usr/local/etc/bash_completion.d/kubectl
```
- kubectl에 대한 앨리어스가 있는 경우, 해당 앨리어스로 작업하기 위해 셸 완성을 확장할 수 있다.
```shell
echo 'alias k=kubectl' >>~/.bash_profile
echo 'complete -F __start_kubectl k' >>~/.bash_profile
```
- Homebrew로 kubectl을 설치한 경우([위](#macos에서-homebrew를-사용하여-설치)의 설명을 참고), kubectl 완성 스크립트는 이미 `/usr/local/etc/bash_completion.d/kubectl` 에 있어야 한다. 이 경우, 아무 것도 할 필요가 없다.
{{< note >}}
bash-completion v2의 Homebrew 설치는 `BASH_COMPLETION_COMPAT_DIR` 디렉터리의 모든 파일을 소싱하므로, 후자의 두 가지 방법이 적용된다.
{{< /note >}}
어쨌든, 셸을 다시 로드 한 후에, kubectl 완성이 작동해야 한다.
{{% /tab %}}
{{% tab name="Zsh" %}}
Zsh용 kubectl 완성 스크립트는 `kubectl completion zsh` 명령으로 생성할 수 있다. 셸에서 완성 스크립트를 소싱하면 kubectl 자동 완성 기능이 활성화된다.
모든 셸 세션에서 사용하려면, `~/.zshrc` 파일에 다음을 추가한다.
```shell
source <(kubectl completion zsh)
```
kubectl에 대한 앨리어스가 있는 경우, 해당 앨리어스로 작업하도록 셸 완성을 확장할 수 있다.
```shell
echo 'alias k=kubectl' >>~/.zshrc
echo 'complete -F __start_kubectl k' >>~/.zshrc
```
셸을 다시 로드 한 후, kubectl 자동 완성 기능이 작동해야 한다.
`complete:13: command not found: compdef` 와 같은 오류가 발생하면, `~/.zshrc` 파일의 시작 부분에 다음을 추가한다.
```shell
autoload -Uz compinit
compinit
```
{{% /tab %}}
{{< /tabs >}}
{{% /capture %}}
{{% capture whatsnext %}}
* [Minikube 설치](/ko/docs/tasks/tools/install-minikube/)
* 클러스터 생성에 대한 자세한 내용은 [시작하기](/ko/docs/setup/)를 참고한다.
* [애플리케이션을 시작하고 노출하는 방법에 대해 배운다.](/docs/tasks/access-application-cluster/service-access-application-cluster/)
* 직접 생성하지 않은 클러스터에 접근해야하는 경우, [클러스터 접근 공유 문서](/ko/docs/tasks/access-application-cluster/configure-access-multiple-clusters/)를 참고한다.
* [kubectl 레퍼런스 문서](/docs/reference/kubectl/kubectl/) 읽기
{{% /capture %}}

View File

@ -19,7 +19,7 @@ weight: 20
<div class="katacoda">
<div class="katacoda__alert">
터미널로 상호 작용하기 위해서, 데스크탑/태블릿 버전을 사용해주세요
화면이 너무 좁아 터미널과 상호작용할 수 없습니다. 데스크톱/태블릿을 사용해주세요.
</div>
<div class="katacoda__box" id="inline-terminal-1" data-katacoda-id="kubernetes-bootcamp/1"
data-katacoda-color="326de6" data-katacoda-secondary="273d6d" data-katacoda-hideintro="false"

View File

@ -86,7 +86,7 @@ weight: 10
<p>디플로이먼트를 생성할 때, 애플리케이션에 대한 컨테이너 이미지와 구동시키고자 하는 복제 수를 지정해야
한다. 디플로이먼트를 업데이트해서 이런 정보를 나중에 변경할 수 있다. 모듈
<a href="/ko/docs/tutorials/kubernetes-basics/scale-intro/">5</a><a href="/ko/docs/tutorials/kubernetes-basics/update-intro/">6</a>의 부트캠프에서 어떻게
<a href="/ko/docs/tutorials/kubernetes-basics/scale/scale-intro/">5</a><a href="/ko/docs/tutorials/kubernetes-basics/update/update-intro/">6</a>의 부트캠프에서 어떻게
스케일하고 업데이트하는지에 대해 다룬다.</p>

View File

@ -29,7 +29,7 @@ weight: 10
<div class="col-md-8">
<h2>쿠버네티스 파드</h2>
<p>모듈 <a href="/ko/docs/tutorials/kubernetes-basics/deploy-intro/">2</a>에서 배포를 생성했을 때, 쿠버네티스는 여러분의 애플리케이션 인스턴스에 <b>파드</b>를 생성했다. 파드는 하나 또는 그 이상의 애플리케이션 컨테이너 (도커 또는 rkt와 같은)들의 그룹을 나타내는 쿠버네티스의 추상적 개념으로 일부는 컨테이너에 대한 자원을 공유한다. 그 자원은 다음을 포함한다:</p>
<p>모듈 <a href="/ko/docs/tutorials/kubernetes-basics/deploy-app/deploy-intro/">2</a>에서 배포를 생성했을 때, 쿠버네티스는 여러분의 애플리케이션 인스턴스에 <b>파드</b>를 생성했다. 파드는 하나 또는 그 이상의 애플리케이션 컨테이너 (도커 또는 rkt와 같은)들의 그룹을 나타내는 쿠버네티스의 추상적 개념으로 일부는 컨테이너에 대한 자원을 공유한다. 그 자원은 다음을 포함한다:</p>
<ul>
<li>볼륨과 같은, 공유 스토리지</li>
<li>클러스터 IP 주소와 같은, 네트워킹</li>
@ -108,7 +108,7 @@ weight: 10
<div class="row">
<div class="col-md-8">
<h2>kubectl로 문제해결하기</h2>
<p>모듈 <a href="/ko/docs/tutorials/kubernetes-basics/deploy/deploy-intro/">2</a>에서, Kubectl 커맨드-라인 인터페이스를 사용했다. 배포된 애플리케이션과 그 환경에 대한 정보를 얻기 위해 모듈3에서도 계속 그것을 사용할 것이다. 가장 보편적인 운용업무는 다음 kubectl 명령어를 이용하여 처리할 수 있다:</p>
<p>모듈 <a href="/ko/docs/tutorials/kubernetes-basics/deploy-app/deploy-intro/">2</a>에서, Kubectl 커맨드-라인 인터페이스를 사용했다. 배포된 애플리케이션과 그 환경에 대한 정보를 얻기 위해 모듈3에서도 계속 그것을 사용할 것이다. 가장 보편적인 운용업무는 다음 kubectl 명령어를 이용하여 처리할 수 있다:</p>
<ul>
<li><b>kubectl get</b> - 자원을 나열한다</li>
<li><b>kubectl describe</b> - 자원에 대해 상세한 정보를 보여준다.</li>

View File

@ -0,0 +1,18 @@
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure

View File

@ -0,0 +1,14 @@
apiVersion: v1
kind: Pod
metadata:
name: redis
spec:
containers:
- name: redis
image: redis
volumeMounts:
- name: redis-storage
mountPath: /data/redis
volumes:
- name: redis-storage
emptyDir: {}