First Korean l10n Work For Release 1.18

* Update to Outdated files in the dev-1.18-ko.1 branch (#19886)
* Translate reference/glossary/service-catalog.md in Korean (#20055)
* Translate storage/dynamic-provisioning.md in Korean (#19952)
* Translate extend-kubernetes/extend-cluster.md in Korean (#20031)
* Translate storage/persistent-volumes.md in Korean (#19906)
* Translate partners/_index.html in Korean (#19967)
* Translate extend-kubernetes/operator.md in Korean (#20037)
* Translate assign-pods-nodes to Korean (#20035)
* Translate scheduling/kube-scheduler.md in Korean (#19879)
* Translate concepts/containers/overview in Korean (#19885)
* Translate policy/pod-security-policy.md in Korean (#19922)
* Translate policy/limit-range.md in Korean (#19912)
* Translate policy/resource-quotas.md in Korean (#19931)
* Translate extend-kubernetes/api-extension/custom-resources.md in Korean (#20093)
* Translate reference/glossary/managed-service.md in Korean (#20150)

Co-authored-by: Jerry Park <jaehwa@gmail.com>
Co-authored-by: heechang lee <bluefriday86@gmail.com>
Co-authored-by: Yuk, Yongsu <ysyukr@gmail.com>
Co-authored-by: Seokho Son <shsongist@gmail.com>
Co-authored-by: coolguyhong <podolsmith@naver.com>
Co-authored-by: santachopa <santachopa@naver.com>
Co-authored-by: Jesang Myung <jesang.myung@gmail.com>
Co-authored-by: June Yi <june.yi@samsung.com>
pull/19999/head
Yuk, Yongsu 2020-03-31 09:24:40 +09:00 committed by bryan
parent e5f4945dfa
commit 583c90add9
65 changed files with 4045 additions and 614 deletions

View File

@ -180,7 +180,7 @@ kubelet은 `NodeStatus` 와 리스 오브젝트를 생성하고 업데이트 할
보다 훨씬 길다).
- kubelet은 10초마다 리스 오브젝트를 생성하고 업데이트 한다(기본 업데이트 주기).
리스 업데이트는 `NodeStatus` 업데이트와는
독립적으로 발생한다.
독립적으로 발생한다. 리스 업데이트가 실패하면 kubelet에 의해 재시도하며 7초로 제한된 지수 백오프를 200 밀리초에서 부터 시작한다.
#### 안정성

View File

@ -41,7 +41,7 @@ weight: 10
* [인증서](/docs/concepts/cluster-administration/certificates/)는 다른 툴 체인을 이용하여 인증서를 생성하는 방법을 설명한다.
* [쿠버네티스 컨테이너 환경](/ko/docs/concepts/containers/container-environment-variables/)은 쿠버네티스 노드에서 Kubelet에 의해 관리되는 컨테이너 환경에 대해 설명한다.
* [쿠버네티스 컨테이너 환경](/ko/docs/concepts/containers/container-environment/)은 쿠버네티스 노드에서 Kubelet에 의해 관리되는 컨테이너 환경에 대해 설명한다.
* [쿠버네티스 API에 대한 접근 제어](/docs/reference/access-authn-authz/controlling-access/)는 사용자와 서비스 계정에 어떻게 권한 설정을 하는지 설명한다.

View File

@ -315,7 +315,7 @@ spec:
topologyKey: "kubernetes.io/hostname"
containers:
- name: web-app
image: nginx:1.12-alpine
image: nginx:1.16-alpine
```
만약 위의 두 디플로이먼트를 생성하면 세 개의 노드가 있는 클러스터는 다음과 같아야 한다.

View File

@ -113,7 +113,7 @@ Events:
{{% capture whatsnext %}}
* [컨테이너 환경](/ko/docs/concepts/containers/container-environment-variables/)에 대해 더 배우기.
* [컨테이너 환경](/ko/docs/concepts/containers/container-environment/)에 대해 더 배우기.
* [컨테이너 라이프사이클 이벤트에 핸들러 부착](/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/)
실습 경험하기.

View File

@ -0,0 +1,43 @@
---
title: 컨테이너 개요
content_template: templates/concept
weight: 10
---
{{% capture overview %}}
컨테이너는 런타임에 필요한 종속성과 애플리케이션의
컴파일 된 코드를 패키징 하는 기술이다. 실행되는 각각의
컨테이너는 반복해서 사용 가능하다. 종속성이 포함된 표준화를
통해 컨테이너가 실행되는 환경과 무관하게 항상 동일하게
동작한다.
컨테이너는 기본 호스트 인프라 환경에서 애플리케이션의 실행환경을 분리한다.
따라서 다양한 클라우드 환경이나 운영체제에서 쉽게 배포 할 수 있다.
{{% /capture %}}
{{% capture body %}}
## 컨테이너 이미지
[컨테이너 이미지](/ko/docs/concepts/containers/images/) 는 즉시 실행할 수 있는
소프트웨어 패키지이며, 애플리케이션을 실행하는데 필요한 모든 것
(필요한 코드와 런타임, 애플리케이션 및 시스템 라이브러리 등의 모든 필수 설정에 대한 기본값)
을 포함한다.
원칙적으로, 컨테이너는 변경되지 않는다. 이미 구동 중인 컨테이너의
코드를 변경할 수 없다. 컨테이너화 된 애플리케이션이 있고 그
애플리케이션을 변경하려는 경우, 변경사항을 포함하여 만든
새로운 이미지를 통해 컨테이너를 다시 생성해야 한다.
## 컨테이너 런타임
{{< glossary_definition term_id="container-runtime" length="all" >}}
{{% /capture %}}
{{% capture whatsnext %}}
* [컨테이너 이미지](/ko/docs/concepts/containers/images/)에 대해 읽어보기
* [파드](/ko/docs/concepts/workloads/pods/)에 대해 읽어보기
{{% /capture %}}

View File

@ -10,22 +10,14 @@ weight: 20
이 페이지는 런타임 클래스(RuntimeClass) 리소스와 런타임 선택 메커니즘에 대해서 설명한다.
{{< warning >}}
런타임클래스는 v1.14 베타 업그레이드에서 *중대한* 변화를 포함한다.
런타임클래스를 v1.14 이전부터 사용하고 있었다면,
[런타임 클래스를 알파에서 베타로 업그레이드하기](#upgrading-runtimeclass-from-alpha-to-beta)를 확인한다.
{{< /warning >}}
런타임클래스는 컨테이너 런타임을 구성을 선택하는 기능이다. 컨테이너 런타임
구성은 파드의 컨테이너를 실행하는데 사용된다.
{{% /capture %}}
{{% capture body %}}
## 런타임 클래스
런타임 클래스는 컨테이너 런타임 설정을 선택하는 기능이다.
이 컨테이너 런타임 설정은 파드의 컨테이너를 실행할 때에 이용한다.
## 동기
서로 다른 파드간에 런타임 클래스를 설정하여
@ -38,7 +30,7 @@ weight: 20
또한 런타임 클래스를 사용하여 컨테이너 런타임이 같으나 설정이 다른
여러 파드를 실행할 수 있다.
### 셋업
## 셋업
RuntimeClass 특징 게이트가 활성화(기본값)를 확인한다.
특징 게이트 활성화에 대한 설명은 [특징 게이트](/docs/reference/command-line-tools-reference/feature-gates/)를
@ -47,7 +39,7 @@ RuntimeClass 특징 게이트가 활성화(기본값)를 확인한다.
1. CRI 구현(implementation)을 노드에 설정(런타임에 따라서)
2. 상응하는 런타임 클래스 리소스 생성
#### 1. CRI 구현을 노드에 설정
### 1. CRI 구현을 노드에 설정
런타임 클래스를 통한 가능한 구성은 컨테이너 런타임 인터페이스(CRI) 구현에 의존적이다.
사용자의 CRI 구현에 따른 설정 방법은
@ -62,7 +54,7 @@ RuntimeClass 특징 게이트가 활성화(기본값)를 확인한다.
해당 설정은 상응하는 `handler` 이름을 가지며, 이는 런타임 클래스에 의해서 참조된다.
런타임 핸들러는 유효한 DNS 1123 서브도메인(알파-숫자 + `-``.`문자)을 가져야 한다.
#### 2. 상응하는 런타임 클래스 리소스 생성
### 2. 상응하는 런타임 클래스 리소스 생성
1단계에서 셋업 한 설정은 연관된 `handler` 이름을 가져야 하며, 이를 통해서 설정을 식별할 수 있다.
각 런타임 핸들러(그리고 선택적으로 비어있는 `""` 핸들러)에 대해서, 상응하는 런타임 클래스 오브젝트를 생성한다.
@ -88,7 +80,7 @@ handler: myconfiguration # 상응하는 CRI 설정의 이름임
더 자세한 정보는 [권한 개요](/docs/reference/access-authn-authz/authorization/)를 참고한다.
{{< /note >}}
### 사용
## 사용
클러스터를 위해서 런타임 클래스를 설정하고 나면, 그것을 사용하는 것은 매우 간단하다. 파드 스펙에
`runtimeClassName`를 명시한다. 예를 들면 다음과 같다.
@ -147,13 +139,13 @@ https://github.com/containerd/cri/blob/master/docs/config.md
[100]: https://raw.githubusercontent.com/cri-o/cri-o/9f11d1d/docs/crio.conf.5.md
### 스케줄
## 스케줄
{{< feature-state for_k8s_version="v1.16" state="beta" >}}
쿠버네티스 v1.16 부터, 런타임 클래스는 `scheduling` 필드를 통해 이종의 클러스터 지원을 포함한다.
이 필드를 사용하면, 이 런타임 클래스를 갖는 파드가 이를 지원하는 노드로 스케줄된다는 것을 보장할 수 있다.
이 스케줄링 기능을 사용하려면, 런타임 클래스 [어드미션(admission) 컨트롤러][]를 활성화(1.16 부터 기본 값)해야 한다.
이 스케줄링 기능을 사용하려면, [런타임 클래스 어드미션(admission) 컨트롤러][]를 활성화(1.16 부터 기본 값)해야 한다.
파드가 지정된 런타임 클래스를 지원하는 노드에 안착한다는 것을 보장하려면,
해당 노드들은 `runtimeClass.scheduling.nodeSelector` 필드에서 선택되는 공통 레이블을 가져야한다.
@ -168,50 +160,24 @@ https://github.com/containerd/cri/blob/master/docs/config.md
노드 셀렉터와 톨러레이션 설정에 대해 더 배우려면
[노드에 파드 할당](/ko/docs/concepts/configuration/assign-pod-node/)을 참고한다.
[어드미션 컨트롤러]: /docs/reference/access-authn-authz/admission-controllers/
[런타임 클래스 어드미션 컨트롤러]: /docs/reference/access-authn-authz/admission-controllers/#runtimeclass
### 파드 오버헤드
{{< feature-state for_k8s_version="v1.16" state="alpha" >}}
{{< feature-state for_k8s_version="v1.18" state="beta" >}}
쿠버네티스 v1.16 부터는, 런타임 클래스에는 구동 중인 파드와 관련된 오버헤드를
지정할 수 있는 기능이 [`PodOverhead`](/docs/concepts/configuration/pod-overhead) 기능을 통해 지원된다.
`PodOverhead`를 사용하려면, PodOverhead [기능 게이트](/docs/reference/command-line-tools-reference/feature-gates/)
활성화 시켜야 한다. (기본으로 활성화 되어 있다.)
파드 실행과 연관되는 _오버헤드_ 리소스를 지정할 수 있다. 오버헤드를 선언하면
클러스터(스케줄러 포함)가 파드와 리소스에 대한 결정을 내릴 때 처리를 할 수 있다.
PodOverhead를 사용하려면, PodOverhead [기능 게이트](/docs/reference/command-line-tools-reference/feature-gates/)
활성화 시켜야 한다. (기본으로 활성화 되어 있다.)
파드 오버헤드는 런타임 클래스에서 `Overhead` 필드를 통해 정의된다. 이 필드를 사용하면,
파드 오버헤드는 런타임 클래스에서 `overhead` 필드를 통해 정의된다. 이 필드를 사용하면,
해당 런타임 클래스를 사용해서 구동 중인 파드의 오버헤드를 특정할 수 있고 이 오버헤드가
쿠버네티스 내에서 처리된다는 것을 보장할 수 있다.
### 런타임 클래스를 알파에서 베타로 업그레이드 {#upgrading-runtimeclass-from-alpha-to-beta}
런타임 클래스 베타 기능은 다음의 변화를 포함한다.
- `node.k8s.io` API 그룹과 `runtimeclasses.node.k8s.io` 리소스는 CustomResourceDefinition에서
내장 API로 이전되었다.
- 런타임 클래스 정의에서 `spec`을 직접 사용할 수 있다.
(즉, 더 이상 RuntimeClassSpec는 없다).
- `runtimeHandler` 필드는 `handler`로 이름이 바뀌었다.
- `handler` 필드는 이제 모두 API 버전에서 요구된다. 이는 알파 API에서도 `runtimeHandler` 필드가
필요하다는 의미이다.
- `handler` 필드는 반드시 올바른 DNS 레이블([RFC 1123](https://tools.ietf.org/html/rfc1123))으로,
이는 더 이상 `.` 캐릭터(모든 버전에서)를 포함할 수 없다 의미이다. 올바른 핸들러는
다음의 정규 표현식을 따른다. `^[a-z0-9]([-a-z0-9]*[a-z0-9])?$`.
**작업 필요** 다음 작업은 알파 버전의 런타임 기능을
베타 버전으로 업그레이드하기 위해 진행되어야 한다.
- 런타임 클래스 리소스는 v1.14로 업그레이드 *후에* 반드시 재생성되어야 하고,
`runtimeclasses.node.k8s.io` CRD는 다음과 같이 수동으로 지워야 한다.
```
kubectl delete customresourcedefinitions.apiextensions.k8s.io runtimeclasses.node.k8s.io
```
- 지정되지 않았거나 비어 있는 `runtimeHandler` 이거나 핸들러 내에 `.` 캐릭터를 사용한 알파 런타임 클래스는
더 이상 올바르지 않으며, 반드시 올바른 핸들러 구성으로 이전헤야 한다
(위를 참조).
### 더 읽기
{{% /capture %}}
{{% capture whatsnext %}}
- [런타임 클래스 설계](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/runtime-class.md)
- [런타임 클래스 스케줄링 설계](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/runtime-class-scheduling.md)

View File

@ -0,0 +1,254 @@
---
title: 커스텀 리소스
content_template: templates/concept
weight: 10
---
{{% capture overview %}}
*커스텀 리소스* 는 쿠버네티스 API의 익스텐션이다. 이 페이지에서는 쿠버네티스 클러스터에
커스텀 리소스를 추가할 시기와 독립형 서비스를 사용하는 시기에 대해 설명한다. 커스텀 리소스를
추가하는 두 가지 방법과 이들 중에서 선택하는 방법에 대해 설명한다.
{{% /capture %}}
{{% capture body %}}
## 커스텀 리소스
*리소스* 는 [쿠버네티스 API](/ko/docs/reference/using-api/api-overview/)에서 특정 종류의
[API 오브젝트](/ko/docs/concepts/overview/working-with-objects/kubernetes-objects/) 모음을 저장하는 엔드포인트이다. 예를 들어 빌트인 *파드* 리소스에는 파드 오브젝트 모음이 포함되어 있다.
*커스텀 리소스* 는 쿠버네티스 API의 익스텐션으로, 기본 쿠버네티스 설치에서 반드시
사용할 수 있는 것은 아니다. 이는 특정 쿠버네티스 설치에 수정이 가해졌음을 나타낸다. 그러나
많은 핵심 쿠버네티스 기능은 이제 커스텀 리소스를 사용하여 구축되어, 쿠버네티스를 더욱 모듈화한다.
동적 등록을 통해 실행 중인 클러스터에서 커스텀 리소스가 나타나거나 사라질 수 있으며
클러스터 관리자는 클러스터 자체와 독립적으로 커스텀 리소스를 업데이트 할 수 있다.
커스텀 리소스가 설치되면 사용자는 *파드* 와 같은 빌트인 리소스와 마찬가지로
[kubectl](/docs/user-guide/kubectl-overview/)을 사용하여 해당 오브젝트를 생성하고
접근할 수 있다.
## 커스텀 컨트롤러
자체적으로 커스텀 리소스를 사용하면 구조화된 데이터를 저장하고 검색할 수 있다.
커스텀 리소스를 *커스텀 컨트롤러* 와 결합하면, 커스텀 리소스가 진정한
_선언적(declarative) API_ 를 제공하게 된다.
[선언적 API](/ko/docs/concepts/overview/kubernetes-api/)는 리소스의 의도한 상태를
_선언_ 하거나 지정할 수 있게 해주며 쿠버네티스 오브젝트의 현재 상태를 의도한 상태와
동기화 상태로 유지하려고 한다. 컨트롤러는 구조화된 데이터를 사용자가
원하는 상태의 레코드로 해석하고 지속적으로
이 상태를 유지한다.
클러스터 라이프사이클과 관계없이 실행 중인 클러스터에 커스텀 컨트롤러를 배포하고
업데이트할 수 있다. 커스텀 컨트롤러는 모든 종류의 리소스와 함께 작동할 수 있지만
커스텀 리소스와 결합할 때 특히 효과적이다.
[오퍼레이터 패턴](https://coreos.com/blog/introducing-operators.html)은 사용자 정의
리소스와 커스텀 컨트롤러를 결합한다. 커스텀 컨트롤러를 사용하여 특정 애플리케이션에 대한 도메인 지식을
쿠버네티스 API의 익스텐션으로 인코딩할 수 있다.
## 쿠버네티스 클러스터에 커스텀 리소스를 추가해야 하나?
새로운 API를 생성할 때 [쿠버네티스 클러스터 API와 생성한 API를 애그리게이트](/ko/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/)할 것인지 아니면 생성한 API를 독립적으로 유지할 것인지 고려하자.
| API 애그리게이트를 고려할 경우 | 독립 API를 고려할 경우 |
| ---------------------------- | ---------------------------- |
| API가 [선언적](#선언적-api)이다. | API가 [선언적](#선언적-api) 모델에 맞지 않다. |
| `kubectl`을 사용하여 새로운 타입을 읽고 쓸 수 있기를 원한다.| `kubectl` 지원이 필요하지 않다. |
| 쿠버네티스 UI(예: 대시보드)에서 빌트인 타입과 함께 새로운 타입을 보길 원한다. | 쿠버네티스 UI 지원이 필요하지 않다. |
| 새로운 API를 개발 중이다. | 생성한 API를 제공하는 프로그램이 이미 있고 잘 작동하고 있다. |
| API 그룹 및 네임스페이스와 같은 REST 리소스 경로에 적용하는 쿠버네티스의 형식 제한을 기꺼이 수용한다. ([API 개요](/ko/docs/concepts/overview/kubernetes-api/)를 참고한다.) | 이미 정의된 REST API와 호환되도록 특정 REST 경로가 있어야 한다. |
| 자체 리소스는 자연스럽게 클러스터 또는 클러스터의 네임스페이스로 범위가 지정된다. | 클러스터 또는 네임스페이스 범위의 리소스는 적합하지 않다. 특정 리소스 경로를 제어해야 한다. |
| [쿠버네티스 API 지원 기능](#일반적인-기능)을 재사용하려고 한다. | 이러한 기능이 필요하지 않다. |
### 선언적 API
선언적 API에서는 다음의 특성이 있다.
- API는 상대적으로 적은 수의 상대적으로 작은 오브젝트(리소스)로 구성된다.
- 오브젝트는 애플리케이션 또는 인프라의 구성을 정의한다.
- 오브젝트는 비교적 드물게 업데이트 된다.
- 사람이 종종 오브젝트를 읽고 쓸 필요가 있다.
- 오브젝트의 주요 작업은 CRUD-y(생성, 읽기, 업데이트 및 삭제)이다.
- 오브젝트 간 트랜잭션은 필요하지 않다. API는 정확한(exact) 상태가 아니라 의도한 상태를 나타낸다.
명령형 API는 선언적이지 않다.
자신의 API가 선언적이지 않을 수 있다는 징후는 다음과 같다.
- 클라이언트는 "이 작업을 수행한다"라고 말하고 완료되면 동기(synchronous) 응답을 받는다.
- 클라이언트는 "이 작업을 수행한다"라고 말한 다음 작업 ID를 다시 가져오고 별도의 오퍼레이션(operation) 오브젝트를 확인하여 요청의 완료 여부를 결정해야 한다.
- RPC(원격 프로시저 호출)에 대해 얘기한다.
- 대량의 데이터를 직접 저장한다(예: > 오브젝트별 몇 kB 또는 >1000개의 오브젝트).
- 높은 대역폭 접근(초당 10개의 지속적인 요청)이 필요하다.
- 최종 사용자 데이터(예: 이미지, PII 등) 또는 애플리케이션에서 처리한 기타 대규모 데이터를 저장한다.
- 오브젝트에 대한 자연스러운 조작은 CRUD-y가 아니다.
- API는 오브젝트로 쉽게 모델링되지 않는다.
- 작업 ID 또는 작업 오브젝트로 보류 중인 작업을 나타내도록 선택했다.
## 컨피그맵을 사용해야 하나, 커스텀 리소스를 사용해야 하나?
다음 중 하나에 해당하면 컨피그맵을 사용하자.
* `mysql.cnf` 또는 `pom.xml`과 같이 잘 문서화된 기존 구성 파일 형식이 있다.
* 전체 구성 파일을 컨피그맵의 하나의 키에 넣고 싶다.
* 구성 파일의 주요 용도는 클러스터의 파드에서 실행 중인 프로그램이 파일을 사용하여 자체 구성하는 것이다.
* 파일 사용자는 쿠버네티스 API가 아닌 파드의 환경 변수 또는 파드의 파일을 통해 사용하는 것을 선호한다.
* 파일이 업데이트될 때 디플로이먼트 등을 통해 롤링 업데이트를 수행하려고 한다.
{{< note >}}
민감한 데이터에는 [시크릿](/docs/concepts/configuration/secret/)을 사용하자. 이는 컨피그맵과 비슷하지만 더 안전한다.
{{< /note >}}
다음 중 대부분이 적용되는 경우 커스텀 리소스(CRD 또는 애그리게이트 API(aggregated API))를 사용하자.
* 쿠버네티스 클라이언트 라이브러리 및 CLI를 사용하여 새 리소스를 만들고 업데이트하려고 한다.
* kubectl의 최상위 지원을 원한다(예: `kubectl get my-object object-name`).
* 새 오브젝트에 대한 업데이트를 감시한 다음 다른 오브젝트를 CRUD하거나 그 반대로 하는 새로운 자동화를 구축하려고 한다.
* 오브젝트의 업데이트를 처리하는 자동화를 작성하려고 한다.
* `.spec`, `.status``.metadata`와 같은 쿠버네티스 API 규칙을 사용하려고 한다.
* 제어된 리소스의 콜렉션 또는 다른 리소스의 요약에 대한 오브젝트가 되기를 원한다.
## 커스텀 리소스 추가
쿠버네티스는 클러스터에 커스텀 리소스를 추가하는 두 가지 방법을 제공한다.
- CRD는 간단하며 프로그래밍 없이 만들 수 있다.
- [API 애그리게이션](/ko/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/)에는 프로그래밍이 필요하지만, 데이터 저장 방법 및 API 버전 간 변환과 같은 API 동작을 보다 강력하게 제어할 수 있다.
쿠버네티스는 다양한 사용자의 요구를 충족시키기 위해 이 두 가지 옵션을 제공하므로 사용의 용이성이나 유연성이 저하되지 않는다.
애그리게이트 API는 기본 API 서버 뒤에 있는 하위 API 서버이며 프록시 역할을 한다. 이 배치를 [API 애그리게이션](/ko/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/)(AA)이라고 한다. 사용자에게는 쿠버네티스 API가 확장된 것과 같다.
CRD를 사용하면 다른 API 서버를 추가하지 않고도 새로운 타입의 리소스를 생성할 수 있다. CRD를 사용하기 위해 API 애그리게이션을 이해할 필요는 없다.
설치 방법에 관계없이 새 리소스는 커스텀 리소스라고 하며 빌트인 쿠버네티스 리소스(파드 등)와 구별된다.
## 커스텀리소스데피니션
[커스텀리소스데피니션](/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/)
API 리소스를 사용하면 커스텀 리소스를 정의할 수 있다.
CRD 오브젝트를 정의하면 지정한 이름과 스키마를 사용하여 새 커스텀 리소스가 만들어진다.
쿠버네티스 API는 커스텀 리소스의 스토리지를 제공하고 처리한다.
CRD 오브젝트의 이름은 유효한
[DNS 서브도메인 이름](/ko/docs/concepts/overview/working-with-objects/names#dns-서브도메인-이름)이어야 한다.
따라서 커스텀 리소스를 처리하기 위해 자신의 API 서버를 작성할 수 없지만
구현의 일반적인 특성으로 인해
[API 서버 애그리게이션](#api-서버-애그리게이션)보다 유연성이 떨어진다.
새 커스텀 리소스를 등록하고 새 리소스 타입의 인스턴스에 대해 작업하고
컨트롤러를 사용하여 이벤트를 처리하는 방법에 대한 예제는
[커스텀 컨트롤러 예제](https://github.com/kubernetes/sample-controller)를 참고한다.
## API 서버 애그리게이션
일반적으로 쿠버네티스 API의 각 리소스에는 REST 요청을 처리하고 오브젝트의 퍼시스턴트 스토리지를 관리하는 코드가 필요하다. 주요 쿠버네티스 API 서버는 *파드**서비스* 와 같은 빌트인 리소스를 처리하고, 일반적으로 [CRD](#커스텀리소스데피니션)를 통해 커스텀 리소스를 처리할 수 ​​있다.
[애그리게이션 레이어](/ko/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/)를 사용하면 자체 독립형 API 서버를
작성하고 배포하여 커스텀 리소스에 대한 특수한 구현을 제공할 수 있다.
기본 API 서버는 처리하는 커스텀 리소스에 대한 요청을 사용자에게 위임하여
모든 클라이언트가 사용할 수 있게 한다.
## 커스텀 리소스를 추가할 방법 선택
CRD는 사용하기가 더 쉽다. 애그리게이트 API가 더 유연하다. 자신의 요구에 가장 잘 맞는 방법을 선택하자.
일반적으로 CRD는 다음과 같은 경우에 적합하다.
* 필드가 몇 개 되지 않는다
* 회사 내에서 또는 소규모 오픈소스 프로젝트의 일부인(상용 제품이 아닌) 리소스를 사용하고 있다.
### 사용 편의성 비교
CRD는 애그리게이트 API보다 생성하기가 쉽다.
| CRD | 애그리게이트 API |
| --------------------------- | -------------- |
| 프로그래밍이 필요하지 않다. 사용자는 CRD 컨트롤러에 대한 모든 언어를 선택할 수 있다. | Go로 프로그래밍하고 바이너리와 이미지를 빌드해야 한다. |
| 실행할 추가 서비스가 없다. CR은 API 서버에서 처리한다. | 추가 서비스를 생성하면 실패할 수 있다. |
| CRD가 생성된 후에는 지속적인 지원이 없다. 모든 버그 픽스는 일반적인 쿠버네티스 마스터 업그레이드의 일부로 선택된다. | 업스트림에서 버그 픽스를 주기적으로 선택하고 애그리게이트 API 서버를 다시 빌드하고 업데이트해야 할 수 있다. |
| 여러 버전의 API를 처리할 필요가 없다. 예를 들어, 이 리소스에 대한 클라이언트를 제어할 때 API와 동기화하여 업그레이드할 수 있다. | 인터넷에 공유할 익스텐션을 개발할 때와 같이 여러 버전의 API를 처리해야 한다. |
### 고급 기능 및 유연성
애그리게이트 API는 보다 고급 API 기능과 스토리지 레이어와 같은 다른 기능의 사용자 정의를 제공한다.
| 기능 | 설명 | CRD | 애그리게이트 API |
| ------- | ----------- | ---- | -------------- |
| 유효성 검사 | 사용자가 오류를 방지하고 클라이언트와 독립적으로 API를 발전시킬 수 있도록 도와준다. 이러한 기능은 동시에 많은 클라이언트를 모두 업데이트할 수 없는 경우에 아주 유용하다. | 예. [OpenAPI v3.0 유효성 검사](/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/#validation)를 사용하여 CRD에서 대부분의 유효성 검사를 지정할 수 있다. [웹훅 유효성 검사](/docs/reference/access-authn-authz/admission-controllers/#validatingadmissionwebhook-alpha-in-1-8-beta-in-1-9)를 추가해서 다른 모든 유효성 검사를 지원한다. | 예, 임의의 유효성 검사를 지원한다. |
| 기본 설정 | 위를 참고하자. | 예, [OpenAPI v3.0 유효성 검사](/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/#defaulting)의 `default` 키워드(1.17에서 GA) 또는 [웹훅 변형(mutating)](/docs/reference/access-authn-authz/admission-controllers/#mutatingadmissionwebhook)(이전 오브젝트의 etcd에서 읽을 때는 실행되지 않음)을 통해 지원한다. | 예 |
| 다중 버전 관리 | 두 가지 API 버전을 통해 동일한 오브젝트를 제공할 수 있다. 필드 이름 바꾸기와 같은 API 변경을 쉽게 할 수 있다. 클라이언트 버전을 제어하는 ​​경우는 덜 중요하다. | [](/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definition-versioning) | 예 |
| 사용자 정의 스토리지 | 다른 성능 모드(예를 들어, 키-값 저장소 대신 시계열 데이터베이스)나 보안에 대한 격리(예를 들어, 암호화된 시크릿이나 다른 암호화) 기능을 가진 스토리지가 필요한 경우 | 아니오 | 예 |
| 사용자 정의 비즈니스 로직 | 오브젝트를 생성, 읽기, 업데이트 또는 삭제를 할 때 임의의 점검 또는 조치를 수행한다. | 예, [웹훅](/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks)을 사용한다. | 예 |
| 서브리소스 크기 조정 | HorizontalPodAutoscaler 및 PodDisruptionBudget과 같은 시스템이 새로운 리소스와 상호 작용할 수 있다. | [](/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/#scale-subresource) | 예 |
| 서브리소스 상태 | 사용자가 스펙 섹션을 작성하고 컨트롤러가 상태 섹션을 작성하는 세분화된 접근 제어를 허용한다. 커스텀 리소스 데이터 변형 시 오브젝트 생성을 증가시킨다(리소스에서 별도의 스펙과 상태 섹션 필요). | [](/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/#status-subresource) | 예 |
| 기타 서브리소스 | "logs" 또는 "exec"과 같은 CRUD 이외의 작업을 추가한다. | 아니오 | 예 |
| strategic-merge-patch | 새로운 엔드포인트는 `Content-Type: application/strategic-merge-patch+json` 형식의 PATCH를 지원한다. 로컬 및 서버 양쪽에서 수정할 수도 있는 오브젝트를 업데이트하는 데 유용하다. 자세한 내용은 ["kubectl 패치를 사용한 API 오브젝트 업데이트"](/docs/tasks/run-application/update-api-object-kubectl-patch/)를 참고한다. | 아니오 | 예 |
| 프로토콜 버퍼 | 새로운 리소스는 프로토콜 버퍼를 사용하려는 클라이언트를 지원한다. | 아니오 | 예 |
| OpenAPI 스키마 | 서버에서 동적으로 가져올 수 있는 타입에 대한 OpenAPI(스웨거(swagger)) 스키마가 있는가? 허용된 필드만 설정하여 맞춤법이 틀린 필드 이름으로부터 사용자를 보호하는가? 타입이 적용되는가(즉, `string` 필드에 `int`를 넣지 않는가?) | 예, [OpenAPI v3.0 유효성 검사](/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/#validation)를 기반으로 하는 스키마(1.16에서 GA) | 예 |
### 일반적인 기능
CRD 또는 AA를 통해 커스텀 리소스를 생성하면 쿠버네티스 플랫폼 외부에서 구현하는 것과 비교하여 API에 대한 많은 기능이 제공된다.
| 기능 | 설명 |
| ------- | ------------ |
| CRUD | 새로운 엔드포인트는 HTTP 및 `kubectl`을 통해 CRUD 기본 작업을 지원한다. |
| 감시 | 새로운 엔드포인트는 HTTP를 통해 쿠버네티스 감시 작업을 지원한다. |
| 디스커버리 | kubectl 및 대시보드와 같은 클라이언트는 리소스에 대해 목록, 표시 및 필드 수정 작업을 자동으로 제공한다. |
| json-patch | 새로운 엔드포인트는 `Content-Type: application/json-patch+json` 형식의 PATCH를 지원한다. |
| merge-patch | 새로운 엔드포인트는 `Content-Type: application/merge-patch+json` 형식의 PATCH를 지원한다. |
| HTTPS | 새로운 엔드포인트는 HTTPS를 사용한다. |
| 빌트인 인증 | 익스텐션에 대한 접근은 인증을 위해 기본 API 서버(애그리게이션 레이어)를 사용한다. |
| 빌트인 권한 부여 | 익스텐션에 접근하면 기본 API 서버(예: RBAC)에서 사용하는 권한을 재사용할 수 있다. |
| Finalizer | 외부 정리가 발생할 때까지 익스텐션 리소스의 삭제를 차단한다. |
| 어드미션 웹훅 | 생성/업데이트/삭제 작업 중에 기본값을 설정하고 익스텐션 리소스의 유효성 검사를 한다. |
| UI/CLI 디스플레이 | Kubectl, 대시보드는 익스텐션 리소스를 표시할 수 있다. |
| 설정하지 않음(unset)과 비어있음(empty) | 클라이언트는 값이 없는 필드 중에서 설정되지 않은 필드를 구별할 수 있다. |
| 클라이언트 라이브러리 생성 | 쿠버네티스는 일반 클라이언트 라이브러리와 타입별 클라이언트 라이브러리를 생성하는 도구를 제공한다. |
| 레이블 및 어노테이션 | 공통 메타데이터는 핵심 및 커스텀 리소스를 수정하는 방법을 알고 있는 도구이다. |
## 커스텀 리소스 설치 준비
클러스터에 커스텀 리소스를 추가하기 전에 알아야 할 몇 가지 사항이 있다.
### 써드파티 코드 및 새로운 장애 포인트
CRD를 생성해도 새로운 장애 포인트(예를 들어, API 서버에서 장애를 유발하는 써드파티 코드가 실행됨)가 자동으로 추가되지는 않지만, 패키지(예: 차트(Charts)) 또는 기타 설치 번들에는 CRD 및 새로운 커스텀 리소스에 대한 비즈니스 로직을 구현하는 써드파티 코드의 디플로이먼트가 포함되는 경우가 종종 있다.
애그리게이트 API 서버를 설치하려면 항상 새 디플로이먼트를 실행해야 한다.
### 스토리지
커스텀 리소스는 컨피그맵과 동일한 방식으로 스토리지 공간을 사용한다. 너무 많은 커스텀 리소스를 생성하면 API 서버의 스토리지 공간이 과부하될 수 있다.
애그리게이트 API 서버는 기본 API 서버와 동일한 스토리지를 사용할 수 있으며 이 경우 동일한 경고가 적용된다.
### 인증, 권한 부여 및 감사
CRD는 항상 API 서버의 빌트인 리소스와 동일한 인증, 권한 부여 및 감사 로깅을 사용한다.
권한 부여에 RBAC를 사용하는 경우 대부분의 RBAC 역할은 새로운 리소스에 대한 접근 권한을 부여하지 않는다(클러스터 관리자 역할 또는 와일드 카드 규칙으로 생성된 역할 제외). 새로운 리소스에 대한 접근 권한을 명시적으로 부여해야 한다. CRD 및 애그리게이트 API는 종종 추가하는 타입에 대한 새로운 역할 정의와 함께 제공된다.
애그리게이트 API 서버는 기본 API 서버와 동일한 인증, 권한 부여 및 감사를 사용하거나 사용하지 않을 수 있다.
## 커스텀 리소스에 접근
쿠버네티스 [클라이언트 라이브러리](/docs/reference/using-api/client-libraries/)를 사용하여 커스텀 리소스에 접근할 수 있다. 모든 클라이언트 라이브러리가 커스텀 리소스를 지원하는 것은 아니다. Go와 python 클라이언트 라이브러리가 지원한다.
커스텀 리소스를 추가하면 다음을 사용하여 접근할 수 있다.
- kubectl
- 쿠버네티스 동적 클라이언트
- 작성한 REST 클라이언트
- [쿠버네티스 클라이언트 생성 도구](https://github.com/kubernetes/code-generator)를 사용하여 생성된 클라이언트(하나를 생성하는 것은 고급 기능이지만, 일부 프로젝트는 CRD 또는 AA와 함께 클라이언트를 제공할 수 있다).
{{% /capture %}}
{{% capture whatsnext %}}
* [애그리게이션 레이어(aggregation layer)로 쿠버네티스 API 확장](/ko/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/)하는 방법에 대해 배우기.
* [커스텀리소스데피니션으로 쿠버네티스 API 확장](/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/)하는 방법에 대해 배우기.
{{% /capture %}}

View File

@ -0,0 +1,205 @@
---
title: 쿠버네티스 클러스터 확장
content_template: templates/concept
weight: 10
---
{{% capture overview %}}
쿠버네티스는 매우 유연하게 구성할 수 있고 확장 가능하다. 결과적으로
쿠버네티스 프로젝트를 포크하거나 코드에 패치를 제출할 필요가
거의 없다.
이 가이드는 쿠버네티스 클러스터를 사용자 정의하기 위한 옵션을 설명한다.
쿠버네티스 클러스터를 업무 환경의 요구에 맞게
조정하는 방법을 이해하려는 {{< glossary_tooltip text="클러스터 운영자" term_id="cluster-operator" >}}를 대상으로 한다.
잠재적인 {{< glossary_tooltip text="플랫폼 개발자" term_id="platform-developer" >}} 또는 쿠버네티스 프로젝트 {{< glossary_tooltip text="컨트리뷰터" term_id="contributor" >}}인 개발자에게도
어떤 익스텐션 포인트와 패턴이 있는지,
그리고 그것들의 트레이드오프와 제약에 대한 소개 자료로 유용할 것이다.
{{% /capture %}}
{{% capture body %}}
## 개요
사용자 정의 방식은 크게 플래그, 로컬 구성 파일 또는 API 리소스 변경만 포함하는 *구성* 과 추가 프로그램이나 서비스 실행과 관련된 *익스텐션* 으로 나눌 수 있다. 이 문서는 주로 익스텐션에 관한 것이다.
## 구성
*구성 파일* 및 *플래그* 는 온라인 문서의 레퍼런스 섹션에 각 바이너리 별로 문서화되어 있다.
* [kubelet](/docs/admin/kubelet/)
* [kube-apiserver](/docs/admin/kube-apiserver/)
* [kube-controller-manager](/docs/admin/kube-controller-manager/)
* [kube-scheduler](/docs/admin/kube-scheduler/).
호스팅된 쿠버네티스 서비스 또는 매니지드 설치 환경의 배포판에서 플래그 및 구성 파일을 항상 변경할 수 있는 것은 아니다. 변경 가능한 경우 일반적으로 클러스터 관리자만 변경할 수 있다. 또한 향후 쿠버네티스 버전에서 변경될 수 있으며, 이를 설정하려면 프로세스를 다시 시작해야 할 수도 있다. 이러한 이유로 다른 옵션이 없는 경우에만 사용해야 한다.
[리소스쿼터](/ko/docs/concepts/policy/resource-quotas/), [PodSecurityPolicy](/ko/docs/concepts/policy/pod-security-policy/), [네트워크폴리시](/ko/docs/concepts/services-networking/network-policies/) 및 역할 기반 접근 제어([RBAC](/docs/reference/access-authn-authz/rbac/))와 같은 *빌트인 정책 API(built-in Policy API)* 는 기본적으로 제공되는 쿠버네티스 API이다. API는 일반적으로 호스팅된 쿠버네티스 서비스 및 매니지드 쿠버네티스 설치 환경과 함께 사용된다. 그것들은 선언적이며 파드와 같은 다른 쿠버네티스 리소스와 동일한 규칙을 사용하므로, 새로운 클러스터 구성을 반복할 수 있고 애플리케이션과 동일한 방식으로 관리할 수 ​​있다. 또한, 이들 API가 안정적인 경우, 다른 쿠버네티스 API와 같이 [정의된 지원 정책](/docs/reference/deprecation-policy/)을 사용할 수 있다. 이러한 이유로 인해 구성 파일과 플래그보다 선호된다.
## 익스텐션(Extension) {#익스텐션}
익스텐션은 쿠버네티스를 확장하고 쿠버네티스와 긴밀하게 통합되는 소프트웨어 컴포넌트이다.
이들 컴포넌트는 쿠버네티스가 새로운 유형과 새로운 종류의 하드웨어를 지원할 수 있게 해준다.
대부분의 클러스터 관리자는 쿠버네티스의 호스팅 또는 배포판 인스턴스를 사용한다.
결과적으로 대부분의 쿠버네티스 사용자는 익스텐션 기능을 설치할 필요가 있고
새로운 익스텐션 기능을 작성할 필요가 있는 사람은 더 적다.
## 익스텐션 패턴
쿠버네티스는 클라이언트 프로그램을 작성하여 자동화 되도록 설계되었다.
쿠버네티스 API를 읽고 쓰는 프로그램은 유용한 자동화를 제공할 수 있다.
*자동화* 는 클러스터 상에서 또는 클러스터 밖에서 실행할 수 있다. 이 문서의 지침에 따라
고가용성과 강력한 자동화를 작성할 수 있다.
자동화는 일반적으로 호스트 클러스터 및 매니지드 설치 환경을 포함한 모든
쿠버네티스 클러스터에서 작동한다.
쿠버네티스와 잘 작동하는 클라이언트 프로그램을 작성하기 위한 특정 패턴은 *컨트롤러* 패턴이라고 한다.
컨트롤러는 일반적으로 오브젝트의 `.spec`을 읽고, 가능한 경우 수행한 다음
오브젝트의 `.status`를 업데이트 한다.
컨트롤러는 쿠버네티스의 클라이언트이다. 쿠버네티스가 클라이언트이고
원격 서비스를 호출할 때 이를 *웹훅(Webhook)* 이라고 한다. 원격 서비스를
*웹훅 백엔드* 라고 한다. 컨트롤러와 마찬가지로 웹훅은 장애 지점을
추가한다.
웹훅 모델에서 쿠버네티스는 원격 서비스에 네트워크 요청을 한다.
*바이너리 플러그인* 모델에서 쿠버네티스는 바이너리(프로그램)를 실행한다.
바이너리 플러그인은 kubelet(예:
[Flex Volume 플러그인](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-storage/flexvolume.md)과
[네트워크 플러그인](/docs/concepts/cluster-administration/network-plugins/))과
kubectl에서
사용한다.
아래는 익스텐션 포인트가 쿠버네티스 컨트롤 플레인과 상호 작용하는 방법을
보여주는 다이어그램이다.
<img src="https://docs.google.com/drawings/d/e/2PACX-1vQBRWyXLVUlQPlp7BvxvV9S1mxyXSM6rAc_cbLANvKlu6kCCf-kGTporTMIeG5GZtUdxXz1xowN7RmL/pub?w=960&h=720">
<!-- image source drawing https://docs.google.com/drawings/d/1muJ7Oxuj_7Gtv7HV9-2zJbOnkQJnjxq-v1ym_kZfB-4/edit?ts=5a01e054 -->
## 익스텐션 포인트
이 다이어그램은 쿠버네티스 시스템의 익스텐션 포인트를 보여준다.
<img src="https://docs.google.com/drawings/d/e/2PACX-1vSH5ZWUO2jH9f34YHenhnCd14baEb4vT-pzfxeFC7NzdNqRDgdz4DDAVqArtH4onOGqh0bhwMX0zGBb/pub?w=425&h=809">
<!-- image source diagrams: https://docs.google.com/drawings/d/1k2YdJgNTtNfW7_A8moIIkij-DmVgEhNrn3y2OODwqQQ/view -->
1. 사용자는 종종 `kubectl`을 사용하여 쿠버네티스 API와 상호 작용한다. [Kubectl 플러그인](/docs/tasks/extend-kubectl/kubectl-plugins/)은 kubectl 바이너리를 확장한다. 개별 사용자의 로컬 환경에만 영향을 미치므로 사이트 전체 정책을 적용할 수는 없다.
2. apiserver는 모든 요청을 처리한다. apiserver의 여러 유형의 익스텐션 포인트는 요청을 인증하거나, 콘텐츠를 기반으로 요청을 차단하거나, 콘텐츠를 편집하고, 삭제 처리를 허용한다. 이 내용은 [API 접근 익스텐션](/ko/docs/concepts/extend-kubernetes/extend-cluster/#api-접근-익스텐션) 섹션에 설명되어 있다.
3. apiserver는 다양한 종류의 *리소스* 를 제공한다. `pods`와 같은 *빌트인 리소스 종류* 는 쿠버네티스 프로젝트에 의해 정의되며 변경할 수 없다. 직접 정의한 리소스를 추가할 수도 있고, [커스텀 리소스](/ko/docs/concepts/extend-kubernetes/extend-cluster/#사용자-정의-유형) 섹션에 설명된대로 *커스텀 리소스* 라고 부르는 다른 프로젝트에서 정의한 리소스를 추가할 수도 있다. 커스텀 리소스는 종종 API 접근 익스텐션과 함께 사용된다.
4. 쿠버네티스 스케줄러는 파드를 배치할 노드를 결정한다. 스케줄링을 확장하는 몇 가지 방법이 있다. 이들은 [스케줄러 익스텐션](/ko/docs/concepts/extend-kubernetes/extend-cluster/#스케줄러-익스텐션) 섹션에 설명되어 있다.
5. 쿠버네티스의 많은 동작은 API-Server의 클라이언트인 컨트롤러(Controller)라는 프로그램으로 구현된다. 컨트롤러는 종종 커스텀 리소스와 함께 사용된다.
6. kubelet은 서버에서 실행되며 파드가 클러스터 네트워크에서 자체 IP를 가진 가상 서버처럼 보이도록 한다. [네트워크 플러그인](/ko/docs/concepts/extend-kubernetes/extend-cluster/#네트워크-플러그인)을 사용하면 다양한 파드 네트워킹 구현이 가능하다.
7. kubelet은 컨테이너의 볼륨을 마운트 및 마운트 해제한다. 새로운 유형의 스토리지는 [스토리지 플러그인](/ko/docs/concepts/extend-kubernetes/extend-cluster/#스토리지-플러그인)을 통해 지원될 수 있다.
어디서부터 시작해야 할지 모르겠다면, 이 플로우 차트가 도움이 될 수 있다. 일부 솔루션에는 여러 유형의 익스텐션이 포함될 수 있다.
<img src="https://docs.google.com/drawings/d/e/2PACX-1vRWXNNIVWFDqzDY0CsKZJY3AR8sDeFDXItdc5awYxVH8s0OLherMlEPVUpxPIB1CSUu7GPk7B2fEnzM/pub?w=1440&h=1080">
<!-- image source drawing: https://docs.google.com/drawings/d/1sdviU6lDz4BpnzJNHfNpQrqI9F19QZ07KnhnxVrp2yg/edit -->
## API 익스텐션
### 사용자 정의 유형
새 컨트롤러, 애플리케이션 구성 오브젝트 또는 기타 선언적 API를 정의하고 `kubectl`과 같은 쿠버네티스 도구를 사용하여 관리하려면 쿠버네티스에 커스텀 리소스를 추가하자.
애플리케이션, 사용자 또는 모니터링 데이터의 데이터 저장소로 커스텀 리소스를 사용하지 않는다.
커스텀 리소스에 대한 자세한 내용은 [커스텀 리소스 개념 가이드](/docs/concepts/api-extension/custom-resources/)를 참고하길 바란다.
### 새로운 API와 자동화의 결합
사용자 정의 리소스 API와 컨트롤 루프의 조합을 [오퍼레이터(operator) 패턴](/docs/concepts/extend-kubernetes/operator/)이라고 한다. 오퍼레이터 패턴은 특정 애플리케이션, 일반적으로 스테이트풀(stateful) 애플리케이션을 관리하는 데 사용된다. 이러한 사용자 정의 API 및 컨트롤 루프를 사용하여 스토리지나 정책과 같은 다른 리소스를 제어할 수도 있다.
### 빌트인 리소스 변경
사용자 정의 리소스를 추가하여 쿠버네티스 API를 확장하면 추가된 리소스는 항상 새로운 API 그룹에 속한다. 기존 API 그룹을 바꾸거나 변경할 수 없다.
API를 추가해도 기존 API(예: 파드)의 동작에 직접 영향을 미치지는 않지만 API 접근 익스텐션은 영향을 준다.
### API 접근 익스텐션
요청이 쿠버네티스 API 서버에 도달하면 먼저 인증이 되고, 그런 다음 승인된 후 다양한 유형의 어드미션 컨트롤이 적용된다. 이 흐름에 대한 자세한 내용은 [쿠버네티스 API에 대한 접근 제어](/docs/reference/access-authn-authz/controlling-access/)를 참고하길 바란다.
이러한 각 단계는 익스텐션 포인트를 제공한다.
쿠버네티스에는 이를 지원하는 몇 가지 빌트인 인증 방법이 있다. 또한 인증 프록시 뒤에 있을 수 있으며 인증 헤더에서 원격 서비스로 토큰을 전송하여 확인할 수 있다(웹훅). 이러한 방법은 모두 [인증 설명서](/docs/reference/access-authn-authz/authentication/)에 설명되어 있다.
### 인증
[인증](/docs/reference/access-authn-authz/authentication/)은 모든 요청의 헤더 또는 인증서를 요청하는 클라이언트의 사용자 이름에 매핑한다.
쿠버네티스는 몇 가지 빌트인 인증 방법과 필요에 맞지 않는 경우 [인증 웹훅](/docs/reference/access-authn-authz/authentication/#webhook-token-authentication) 방법을 제공한다.
### 승인
[승인](/docs/reference/access-authn-authz/webhook/)은 특정 사용자가 API 리소스에서 읽고, 쓰고, 다른 작업을 수행할 수 있는지를 결정한다. 전체 리소스 레벨에서 작동하며 임의의 오브젝트 필드를 기준으로 구별하지 않는다. 빌트인 인증 옵션이 사용자의 요구를 충족시키지 못하면 [인증 웹훅](/docs/reference/access-authn-authz/webhook/)을 통해 사용자가 제공한 코드를 호출하여 인증 결정을 내릴 수 있다.
### 동적 어드미션 컨트롤
요청이 승인된 후, 쓰기 작업인 경우 [어드미션 컨트롤](/docs/reference/access-authn-authz/admission-controllers/) 단계도 수행된다. 빌트인 단계 외에도 몇 가지 익스텐션이 있다.
* [이미지 정책 웹훅](/docs/reference/access-authn-authz/admission-controllers/#imagepolicywebhook)은 컨테이너에서 실행할 수 있는 이미지를 제한한다.
* 임의의 어드미션 컨트롤 결정을 내리기 위해 일반적인 [어드미션 웹훅](/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks)을 사용할 수 있다. 어드미션 웹훅은 생성 또는 업데이트를 거부할 수 있다.
## 인프라스트럭처 익스텐션
### 스토리지 플러그인
[Flex Volumes](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/storage/flexvolume-deployment.md)을 사용하면
Kubelet이 바이너리 플러그인을 호출하여 볼륨을 마운트하도록 함으로써
빌트인 지원 없이 볼륨 유형을 마운트 할 수 있다.
### 장치 플러그인
장치 플러그인은 노드가 [장치 플러그인](/docs/concepts/cluster-administration/device-plugins/)을
통해 새로운 노드 리소스(CPU 및 메모리와 같은 빌트인 자원 외에)를
발견할 수 있게 해준다.
### 네트워크 플러그인
노드-레벨의 [네트워크 플러그인](/docs/admin/network-plugins/)을 통해 다양한 네트워킹 패브릭을 지원할 수 있다.
### 스케줄러 익스텐션
스케줄러는 파드를 감시하고 파드를 노드에 할당하는 특수한 유형의
컨트롤러이다. 다른 쿠버네티스 컴포넌트를 계속 사용하면서
기본 스케줄러를 완전히 교체하거나,
[여러 스케줄러](/docs/tasks/administer-cluster/configure-multiple-schedulers/)를
동시에 실행할 수 있다.
이것은 중요한 부분이며, 거의 모든 쿠버네티스 사용자는 스케줄러를 수정할
필요가 없다는 것을 알게 된다.
스케줄러는 또한 웹훅 백엔드(스케줄러 익스텐션)가
파드에 대해 선택된 노드를 필터링하고 우선 순위를 지정할 수 있도록 하는
[웹훅](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/scheduling/scheduler_extender.md)을
지원한다.
{{% /capture %}}
{{% capture whatsnext %}}
* [커스텀 리소스](/docs/concepts/api-extension/custom-resources/)에 대해 더 알아보기
* [동적 어드미션 컨트롤](/docs/reference/access-authn-authz/extensible-admission-controllers/)에 대해 알아보기
* 인프라스트럭처 익스텐션에 대해 더 알아보기
* [네트워크 플러그인](/docs/concepts/cluster-administration/network-plugins/)
* [장치 플러그인](/docs/concepts/cluster-administration/device-plugins/)
* [kubectl 플러그인](/docs/tasks/extend-kubectl/kubectl-plugins/)에 대해 알아보기
* [오퍼레이터 패턴](/docs/concepts/extend-kubernetes/operator/)에 대해 알아보기
{{% /capture %}}

View File

@ -0,0 +1,133 @@
---
title: 오퍼레이터(operator) 패턴
content_template: templates/concept
weight: 30
---
{{% capture overview %}}
오퍼레이터(Operator)는
[사용자 정의 리소스](/docs/concepts/extend-kubernetes/api-extension/custom-resources/)를
사용하여 애플리케이션 및 해당 컴포넌트를 관리하는 쿠버네티스의 소프트웨어 익스텐션이다. 오퍼레이터는
쿠버네티스 원칙, 특히 [컨트롤 루프](/ko/docs/concepts/#쿠버네티스-컨트롤-플레인)를 따른다.
{{% /capture %}}
{{% capture body %}}
## 동기 부여
오퍼레이터 패턴은 서비스 또는 서비스 셋을 관리하는 운영자의
주요 목표를 포착하는 것을 목표로 한다. 특정 애플리케이션 및
서비스를 돌보는 운영자는 시스템의 작동 방식, 배포 방법 및 문제가 있는 경우
대처 방법에 대해 깊이 알고 있다.
쿠버네티스에서 워크로드를 실행하는 사람들은 종종 반복 가능한 작업을 처리하기 위해
자동화를 사용하는 것을 좋아한다. 오퍼레이터 패턴은 쿠버네티스 자체가 제공하는 것 이상의
작업을 자동화하기 위해 코드를 작성하는 방법을 포착한다.
## 쿠버네티스의 오퍼레이터
쿠버네티스는 자동화를 위해 설계되었다. 기본적으로 쿠버네티스의 중추를 통해 많은
빌트인 자동화 기능을 사용할 수 있다. 쿠버네티스를 사용하여 워크로드 배포
및 실행을 자동화할 수 있고, *또한* 쿠버네티스가 수행하는 방식을
자동화할 수 있다.
쿠버네티스의 {{< glossary_tooltip text="컨트롤러" term_id="controller" >}}
개념을 통해 쿠버네티스 코드 자체를 수정하지 않고도 클러스터의 동작을
확장할 수 있다.
오퍼레이터는 [사용자 정의 리소스](/docs/concepts/api-extension/custom-resources/)의
컨트롤러 역할을 하는 쿠버네티스 API의 클라이언트이다.
## 오퍼레이터 예시 {#example}
오퍼레이터를 사용하여 자동화할 수 있는 몇 가지 사항은 다음과 같다.
* 주문형 애플리케이션 배포
* 해당 애플리케이션의 상태를 백업하고 복원
* 데이터베이스 스키마 또는 추가 구성 설정과 같은 관련 변경 사항에 따른
애플리케이션 코드 업그레이드 처리
* 쿠버네티스 API를 지원하지 않는 애플리케이션에 서비스를
게시하여 검색을 지원
* 클러스터의 전체 또는 일부에서 장애를 시뮬레이션하여 가용성 테스트
* 내부 멤버 선출 절차없이 분산 애플리케이션의
리더를 선택
오퍼레이터의 모습을 더 자세하게 볼 수 있는 방법은 무엇인가? 자세한 예는
다음과 같다.
1. 클러스터에 구성할 수 있는 SampleDB라는 사용자 정의 리소스.
2. 오퍼레이터의 컨트롤러 부분이 포함된 파드의 실행을
보장하는 디플로이먼트.
3. 오퍼레이터 코드의 컨테이너 이미지.
4. 컨트롤 플레인을 쿼리하여 어떤 SampleDB 리소스가 구성되어 있는지
알아내는 컨트롤러 코드.
5. 오퍼레이터의 핵심은 API 서버에 구성된 리소스와 현재 상태를
일치시키는 방법을 알려주는 코드이다.
* 새 SampleDB를 추가하면 오퍼레이터는 퍼시스턴트볼륨클레임을
설정하여 내구성있는 데이터베이스 스토리지, SampleDB를 실행하는 스테이트풀셋 및
초기 구성을 처리하는 잡을 제공한다.
* SampleDB를 삭제하면 오퍼레이터는 스냅샷을 생성한 다음 스테이트풀셋과 볼륨도
제거되었는지 확인한다.
6. 오퍼레이터는 정기적인 데이터베이스 백업도 관리한다. 오퍼레이터는 각 SampleDB
리소스에 대해 데이터베이스에 연결하고 백업을 수행할 수 있는 파드를 생성하는
시기를 결정한다. 이 파드는 데이터베이스 연결 세부 정보 및 자격 증명이 있는
컨피그맵 및 / 또는 시크릿에 의존한다.
7. 오퍼레이터는 관리하는 리소스에 견고한 자동화를 제공하는 것을 목표로 하기 때문에
추가 지원 코드가 있다. 이 예제에서 코드는 데이터베이스가 이전 버전을 실행 중인지
확인하고, 업그레이드된 경우 이를 업그레이드하는
잡 오브젝트를 생성한다.
## 오퍼레이터 배포
오퍼레이터를 배포하는 가장 일반적인 방법은
커스텀 리소스 데피니션의 정의 및 연관된 컨트롤러를 클러스터에 추가하는 것이다.
컨테이너화된 애플리케이션을 실행하는 것처럼
컨트롤러는 일반적으로 {{< glossary_tooltip text="컨트롤 플레인" term_id="control-plane" >}}
외부에서 실행된다.
예를 들어 클러스터에서 컨트롤러를 디플로이먼트로 실행할 수 있다.
## 오퍼레이터 사용 {#using-operators}
오퍼레이터가 배포되면 오퍼레이터가 사용하는 리소스의 종류를 추가, 수정 또는
삭제하여 사용한다. 위의 예에 따라 오퍼레이터 자체에 대한
디플로이먼트를 설정한 후 다음을 수행한다.
```shell
kubectl get SampleDB # 구성된 데이터베이스 찾기
kubectl edit SampleDB/example-database # 일부 설정을 수동으로 변경하기
```
&hellip;이것으로 끝이다! 오퍼레이터는 변경 사항을 적용하고 기존 서비스를
양호한 상태로 유지한다.
## 자신만의 오퍼레이터 작성 {#writing-operator}
에코시스템에 원하는 동작을 구현하는 오퍼레이터가 없다면 직접 코딩할 수 있다.
[다음 내용](#다음-내용)에서는 클라우드 네이티브 오퍼레이터를 작성하는 데
사용할 수 있는 라이브러리 및 도구에 대한 몇 가지 링크를
찾을 수 있다.
또한 [쿠버네티스 API의 클라이언트](/docs/reference/using-api/client-libraries/)
역할을 할 수 있는 모든 언어 / 런타임을 사용하여 오퍼레이터(즉, 컨트롤러)를 구현한다.
{{% /capture %}}
{{% capture whatsnext %}}
* [사용자 정의 리소스](/docs/concepts/extend-kubernetes/api-extension/custom-resources/)에 대해 더 알아보기
* [OperatorHub.io](https://operatorhub.io/)에서 유스케이스에 맞는 이미 만들어진 오퍼레이터 찾기
* 기존 도구를 사용하여 자신만의 오퍼레이터를 작성해보자. 다음은 예시이다.
* [KUDO](https://kudo.dev/) (Kubernetes Universal Declarative Operator) 사용하기
* [kubebuilder](https://book.kubebuilder.io/) 사용하기
* 웹훅(WebHook)과 함께 [Metacontroller](https://metacontroller.app/)를
사용하여 직접 구현하기
* [오퍼레이터 프레임워크](https://github.com/operator-framework/getting-started) 사용하기
* 다른 사람들이 사용할 수 있도록 자신의 오퍼레이터를 [게시](https://operatorhub.io/)하기
* 오퍼레이터 패턴을 소개한 [CoreOS 원본 기사](https://coreos.com/blog/introducing-operators.html) 읽기
* 오퍼레이터 구축을 위한 모범 사례에 대한 구글 클라우드(Google Cloud)의 [기사](https://cloud.google.com/blog/products/containers-kubernetes/best-practices-for-building-kubernetes-operators-and-stateful-apps) 읽기
{{% /capture %}}

View File

@ -82,7 +82,7 @@ metadata:
spec:
containers:
- name: nginx
image: nginx:1.7.9
image: nginx:1.14.2
ports:
- containerPort: 80

View File

@ -67,7 +67,7 @@ metadata:
spec:
containers:
- name: nginx
image: nginx:1.7.9
image: nginx:1.14.2
ports:
- containerPort: 80

View File

@ -62,7 +62,7 @@ metadata:
spec:
containers:
- name: nginx
image: nginx:1.7.9
image: nginx:1.14.2
ports:
- containerPort: 80
```

View File

@ -0,0 +1,4 @@
---
title: "정책"
weight: 90
---

View File

@ -0,0 +1,388 @@
---
title: 리밋 레인지(Limit Range)
content_template: templates/concept
weight: 10
---
{{% capture overview %}}
기본적으로 컨테이너는 쿠버네티스 클러스터에서 무제한 [컴퓨팅 리소스](/docs/user-guide/compute-resources)로 실행된다.
리소스 쿼터을 사용하면 클러스터 관리자는 네임스페이스별로 리소스 사용과 생성을 제한할 수 있다.
네임스페이스 내에서 파드나 컨테이너는 네임스페이스의 리소스 쿼터에 정의된 만큼의 CPU와 메모리를 사용할 수 있다. 하나의 파드 또는 컨테이너가 사용 가능한 모든 리소스를 독점할 수 있다는 우려가 있다. 리밋레인지는 네임스페이스에서 리소스 할당(파드 또는 컨테이너)을 제한하는 정책이다.
{{% /capture %}}
{{% capture body %}}
_리밋레인지_ 는 다음과 같은 제약 조건을 제공한다.
- 네임스페이스에서 파드 또는 컨테이너별 최소 및 최대 컴퓨팅 리소스 사용량을 지정한다.
- 네임스페이스에서 스토리지클래스별 최소 및 최대 스토리지 요청을 지정한다.
- 네임스페이스에서 리소스에 대한 요청과 제한 사이의 비율을 지정한다.
- 네임스페이스에서 컴퓨팅 리소스에 대한 기본 요청/제한을 설정하고 런타임에 있는 컨테이너에 자동으로 설정한다.
## 리밋레인지 활성화
많은 쿠버네티스 배포판에 리밋레인지 지원이 기본적으로 활성화되어 있다. apiserver `--enable-admission-plugins=` 플래그의 인수 중 하나로 `LimitRanger` 어드미션 컨트롤러가 있는 경우 활성화된다.
해당 네임스페이스에 리밋레인지 오브젝트가 있는 경우 특정 네임스페이스에 리밋레인지가 지정된다.
리밋레인지 오브젝트의 이름은 유효한 [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로 정의하라.
네임스페이스의 총 제한이 파드/컨테이너의 제한 합보다 작은 경우 리소스에 대한 경합이 있을 수 있다.
이 경우 컨테이너 또는 파드가 생성되지 않는다.
경합이나 리밋레인지 변경은 이미 생성된 리소스에 영향을 미치지 않는다.
## 컨테이너 컴퓨팅 리소스 제한
다음 절에서는 컨테이너 레벨에서 작동하는 리밋레인지 생성에 대해 설명한다.
4개의 컨테이너가 있는 파드가 먼저 생성된다. 파드 내의 각 컨테이너에는 특정 `spec.resource` 구성이 있다.
파드 내의 각 컨테이너는 `LimitRanger` 어드미션 컨트롤러에 의해 다르게 처리된다.
다음 kubectl 명령을 사용하여 네임스페이스 `limitrange-demo`를 생성한다.
```shell
kubectl create namespace limitrange-demo
```
kubectl 명령에서 네임스페이스 대상인 `limitrange-demo`를 빠트리지 않으려면 다음 명령으로 컨텍스트를 변경한다.
```shell
kubectl config set-context --current --namespace=limitrange-demo
```
다음은 리밋레인지 오브젝트의 구성 파일이다.
{{< codenew file="admin/resource/limit-mem-cpu-container.yaml" >}}
이 오브젝트는 컨테이너에 적용할 최소 및 최대 CPU/메모리 제한, 기본 CPU/메모리 요청과 CPU/메모리 리소스에 대한 기본 제한을 정의한다.
다음 kubectl 명령을 사용하여 `limit-mem-cpu-per-container` 리밋레인지를 생성한다.
```shell
kubectl create -f https://k8s.io/examples/admin/resource/limit-mem-cpu-container.yaml
```
```shell
kubectl describe limitrange/limit-mem-cpu-per-container
```
```shell
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Container cpu 100m 800m 110m 700m -
Container memory 99Mi 1Gi 111Mi 900Mi -
```
다음은 4개의 컨테이너가 포함된 파드의 구성 파일로 리밋레인지 기능을 보여준다.
{{< codenew file="admin/resource/limit-range-pod-1.yaml" >}}
`busybox1` 파드를 생성한다.
```shell
kubectl apply -f https://k8s.io/examples/admin/resource/limit-range-pod-1.yaml
```
### 유효한 CPU/메모리 요청과 제한이 있는 컨테이너 스펙
`busybox-cnt01`의 리소스 구성을 보자.
```shell
kubectl get po/busybox1 -o json | jq ".spec.containers[0].resources"
```
```json
{
"limits": {
"cpu": "500m",
"memory": "200Mi"
},
"requests": {
"cpu": "100m",
"memory": "100Mi"
}
}
```
- `busybox` 파드 내의 `busybox-cnt01` 컨테이너는 `requests.cpu=100m``requests.memory=100Mi`로 정의됐다.
- `100m <= 500m <= 800m`, 컨테이너 CPU 제한(500m)은 승인된 CPU 리밋레인지 내에 있다.
- `99Mi <= 200Mi <= 1Gi`, 컨테이너 메모리 제한(200Mi)은 승인된 메모리 리밋레인지 내에 있다.
- CPU/메모리에 대한 요청/제한 비율 검증이 없으므로 컨테이너가 유효하며 생성되었다.
### 유효한 CPU/메모리 요청은 있지만 제한이 없는 컨테이너 스펙
`busybox-cnt02`의 리소스 구성을 보자.
```shell
kubectl get po/busybox1 -o json | jq ".spec.containers[1].resources"
```
```json
{
"limits": {
"cpu": "700m",
"memory": "900Mi"
},
"requests": {
"cpu": "100m",
"memory": "100Mi"
}
}
```
- `busybox1` 파드 내의 `busybox-cnt02` 컨테이너는 `requests.cpu=100m``requests.memory=100Mi`를 정의했지만 CPU와 메모리에 대한 제한은 없다.
- 컨테이너에 제한 섹션이 없다. `limit-mem-cpu-per-container` 리밋레인지 오브젝트에 정의된 기본 제한은 `limits.cpu=700mi``limits.memory=900Mi`로 이 컨테이너에 설정된다.
- `100m <= 700m <= 800m`, 컨테이너 CPU 제한(700m)이 승인된 CPU 제한 범위 내에 있다.
- `99Mi <= 900Mi <= 1Gi`, 컨테이너 메모리 제한(900Mi)이 승인된 메모리 제한 범위 내에 있다.
- 요청/제한 비율이 설정되지 않았으므로 컨테이너가 유효하며 생성되었다.
### 유효한 CPU/메모리 제한은 있지만 요청은 없는 컨테이너 스펙
`busybox-cnt03`의 리소스 구성을 보자.
```shell
kubectl get po/busybox1 -o json | jq ".spec.containers[2].resources"
```
```json
{
"limits": {
"cpu": "500m",
"memory": "200Mi"
},
"requests": {
"cpu": "500m",
"memory": "200Mi"
}
}
```
- `busybox1` 파드 내의 `busybox-cnt03` 컨테이너는 `limits.cpu=500m``limits.memory=200Mi`를 정의했지만 CPU와 메모리에 대한 요청은 없다.
- 컨테이너에 요청 섹션이 정의되지 않았다. `limit-mem-cpu-per-container` 리밋레인지에 정의된 기본 요청은 제한 섹션을 채우는 데 사용되지 않지만 컨테이너에 의해 정의된 제한은 `limits.cpu=500m``limits.memory=200Mi`로 설정된다.
- `100m <= 500m <= 800m`, 컨테이너 CPU 제한(500m)은 승인된 CPU 제한 범위 내에 있다.
- `99Mi <= 200Mi <= 1Gi`, 컨테이너 메모리 제한(200Mi)은 승인된 메모리 제한 범위 내에 있다.
- 요청/제한 비율이 설정되지 않았으므로 컨테이너가 유효하며 생성되었다.
### CPU/메모리 요청/제한이 없는 컨테이너 스펙
`busybox-cnt04`의 리소스 구성을 보자.
```shell
kubectl get po/busybox1 -o json | jq ".spec.containers[3].resources"
```
```json
{
"limits": {
"cpu": "700m",
"memory": "900Mi"
},
"requests": {
"cpu": "110m",
"memory": "111Mi"
}
}
```
- `busybox1``busybox-cnt04` 컨테이너는 제한이나 요청을 정의하지 않았다.
- 컨테이너는 제한 섹션을 정의하지 않으며 `limit-mem-cpu-per-container` 리밋레인지에 정의된 기본 제한은 `limit.cpu=700m``limits.memory=900Mi`로 설정된다.
- 컨테이너는 요청 섹션을 정의하지 않으며 `limit-mem-cpu-per-container` 리밋레인지에 정의된 defaultRequest는 `requests.cpu=110m``requests.memory=111Mi`로 설정된다.
- `100m <= 700m <= 800m`, 컨테이너 CPU 제한(700m)은 승인된 CPU 제한 범위 내에 있다.
- `99Mi <= 900Mi <= 1Gi`, 컨테이너 메모리 제한(900Mi)은 승인된 메모리 제한 범위 내에 있다.
- 요청/제한 비율이 설정되지 않았으므로 컨테이너가 유효하며 생성되었다.
`busybox` 파드에 정의된 모든 컨테이너는 리밋레인지 유효성 검사를 통과했으므로 이 파드는 유효하며 네임스페이스에서 생성된다.
## 파드 컴퓨팅 리소스 제한
다음 절에서는 파드 레벨에서 리소스를 제한하는 방법에 대해 설명한다.
{{< codenew file="admin/resource/limit-mem-cpu-pod.yaml" >}}
`busybox1` 파드를 삭제하지 않고 `limitrange-demo` 네임스페이스에 `limit-mem-cpu-pod` 리밋레인지를 생성한다.
```shell
kubectl apply -f https://k8s.io/examples/admin/resource/limit-mem-cpu-pod.yaml
```
리밋레인지가 생성되고 파드별로 CPU가 2 코어로, 메모리가 2Gi로 제한된다.
```shell
limitrange/limit-mem-cpu-per-pod created
```
다음 kubectl 명령을 사용하여 `limit-mem-cpu-per-pod` 리밋레인지 오브젝트의 정보를 나타낸다.
```shell
kubectl describe limitrange/limit-mem-cpu-per-pod
```
```shell
Name: limit-mem-cpu-per-pod
Namespace: limitrange-demo
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Pod cpu - 2 - - -
Pod memory - 2Gi - - -
```
이제 `busybox2` 파드를 생성한다.
{{< codenew file="admin/resource/limit-range-pod-2.yaml" >}}
```shell
kubectl apply -f https://k8s.io/examples/admin/resource/limit-range-pod-2.yaml
```
`busybox2` 파드 정의는 `busybox1`과 동일하지만 이제 파드 리소스가 제한되어 있으므로 오류가 보고된다.
```shell
Error from server (Forbidden): error when creating "limit-range-pod-2.yaml": pods "busybox2" is forbidden: [maximum cpu usage per Pod is 2, but limit is 2400m., maximum memory usage per Pod is 2Gi, but limit is 2306867200.]
```
```shell
kubectl get po/busybox1 -o json | jq ".spec.containers[].resources.limits.memory"
"200Mi"
"900Mi"
"200Mi"
"900Mi"
```
해당 컨테이너의 총 메모리 제한이 리밋레인지에 정의된 제한보다 크므로 `busybox2` 파드는 클러스터에서 허용되지 않는다.
`busyRange1`은 리밋레인지를 생성하기 전에 클러스터에서 생성되고 허용되므로 제거되지 않는다.
## 스토리지 리소스 제한
리밋레인지를 사용하여 네임스페이스에서 각 퍼시스턴트볼륨클레임이 요청할 수 있는 [스토리지 리소스](/ko/docs/concepts/storage/persistent-volumes/)의 최소 및 최대 크기를 지정할 수 있다.
{{< codenew file="admin/resource/storagelimits.yaml" >}}
`kubectl create`를 사용하여 YAML을 적용한다.
```shell
kubectl create -f https://k8s.io/examples/admin/resource/storagelimits.yaml
```
```shell
limitrange/storagelimits created
```
생성된 오브젝트의 정보를 나타낸다.
```shell
kubectl describe limits/storagelimits
```
출력은 다음과 같다.
```shell
Name: storagelimits
Namespace: limitrange-demo
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
PersistentVolumeClaim storage 1Gi 2Gi - - -
```
{{< codenew file="admin/resource/pvc-limit-lower.yaml" >}}
```shell
kubectl create -f https://k8s.io/examples/admin/resource/pvc-limit-lower.yaml
```
`requests.storage`가 리밋레인지의 Min 값보다 낮은 PVC를 만드는 동안 서버에서 발생하는 오류는 다음과 같다.
```shell
Error from server (Forbidden): error when creating "pvc-limit-lower.yaml": persistentvolumeclaims "pvc-limit-lower" is forbidden: minimum storage usage per PersistentVolumeClaim is 1Gi, but request is 500Mi.
```
`requests.storage`가 리밋레인지의 Max 값보다 큰 경우에도 동일한 동작이 나타난다.
{{< codenew file="admin/resource/pvc-limit-greater.yaml" >}}
```shell
kubectl create -f https://k8s.io/examples/admin/resource/pvc-limit-greater.yaml
```
```shell
Error from server (Forbidden): error when creating "pvc-limit-greater.yaml": persistentvolumeclaims "pvc-limit-greater" is forbidden: maximum storage usage per PersistentVolumeClaim is 2Gi, but request is 5Gi.
```
## 제한/요청 비율
`LimitRangeSpec``LimitRangeItem.maxLimitRequestRatio`가 지정되어 있으면 명명된 리소스는 제한을 요청으로 나눈 값이 열거된 값보다 작거나 같은 0이 아닌 값을 요청과 제한 모두 가져야 한다.
다음의 리밋레인지는 메모리 제한이 네임스페이스의 모든 파드에 대한 메모리 요청 양의 최대 두 배가 되도록 한다.
{{< codenew file="admin/resource/limit-memory-ratio-pod.yaml" >}}
```shell
kubectl apply -f https://k8s.io/examples/admin/resource/limit-memory-ratio-pod.yaml
```
다음의 kubectl 명령으로 `limit-memory-ratio-pod` 리밋레인지의 정보를 나타낸다.
```shell
kubectl describe limitrange/limit-memory-ratio-pod
```
```shell
Name: limit-memory-ratio-pod
Namespace: limitrange-demo
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Pod memory - - - - 2
```
`requests.memory=100Mi``limits.memory=300Mi`로 파드를 생성한다.
{{< codenew file="admin/resource/limit-range-pod-3.yaml" >}}
```shell
kubectl apply -f https://k8s.io/examples/admin/resource/limit-range-pod-3.yaml
```
위 예에서 제한/요청 비율(`3`)이 `limit-memory-ratio-pod` 리밋레인지에 지정된 제한 비율(`2`)보다 커서 파드 생성에 실패했다.
```
Error from server (Forbidden): error when creating "limit-range-pod-3.yaml": pods "busybox3" is forbidden: memory max limit to request ratio per Pod is 2, but provided ratio is 3.000000.
```
## 정리
모든 리소스를 해제하려면 `limitrange-demo` 네임스페이스를 삭제한다.
```shell
kubectl delete ns limitrange-demo
```
다음 명령을 사용하여 컨텍스트를 `default` 네임스페이스로 변경한다.
```shell
kubectl config set-context --current --namespace=default
```
## 예제
- [네임스페이스별 컴퓨팅 리소스를 제한하는 방법에 대한 튜토리얼](/docs/tasks/administer-cluster/manage-resources/cpu-constraint-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)를 참고하길 바란다.
{{% /capture %}}

View File

@ -0,0 +1,635 @@
---
title: 파드 시큐리티 폴리시
content_template: templates/concept
weight: 20
---
{{% capture overview %}}
{{< feature-state state="beta" >}}
파드 시큐리티 폴리시를 사용하면 파드 생성 및 업데이트에 대한 세분화된 권한을
부여할 수 있다.
{{% /capture %}}
{{% capture body %}}
## 파드 시큐리티 폴리시란?
_Pod Security Policy_ 는 파드 명세의 보안 관련 측면을 제어하는 ​​클러스터-레벨의
리소스이다. [파드시큐리티폴리시](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podsecuritypolicy-v1beta1-policy) 오브젝트는
관련 필드에 대한 기본값뿐만 아니라 시스템에 적용하기 위해 파드가 실행해야만 하는
조건 셋을 정의한다. 관리자는
다음을 제어할 수 있다.
| 제어 측면 | 필드 이름 |
| ----------------------------------------------------| ------------------------------------------- |
| 특권을 가진(privileged) 컨테이너의 실행 | [`privileged`](#privileged) |
| 호스트 네임스페이스의 사용 | [`hostPID`, `hostIPC`](#host-namespaces) |
| 호스트 네트워킹과 포트의 사용 | [`hostNetwork`, `hostPorts`](#host-namespaces) |
| 볼륨 유형의 사용 | [`volumes`](#volumes-and-file-systems) |
| 호스트 파일시스템의 사용 | [`allowedHostPaths`](#volumes-and-file-systems) |
| FlexVolume 드라이버의 화이트리스트 | [`allowedFlexVolumes`](#flexvolume-drivers) |
| 파드 볼륨을 소유한 FSGroup 할당 | [`fsGroup`](#volumes-and-file-systems) |
| 읽기 전용 루트 파일시스템 사용 필요 | [`readOnlyRootFilesystem`](#volumes-and-file-systems) |
| 컨테이너의 사용자 및 그룹 ID | [`runAsUser`, `runAsGroup`, `supplementalGroups`](#users-and-groups) |
| 루트 특권으로의 에스컬레이션 제한 | [`allowPrivilegeEscalation`, `defaultAllowPrivilegeEscalation`](#privilege-escalation) |
| 리눅스 기능 | [`defaultAddCapabilities`, `requiredDropCapabilities`, `allowedCapabilities`](#capabilities) |
| 컨테이너의 SELinux 컨텍스트 | [`seLinux`](#selinux) |
| 컨테이너에 허용된 Proc 마운트 유형 | [`allowedProcMountTypes`](#allowedprocmounttypes) |
| 컨테이너가 사용하는 AppArmor 프로파일 | [어노테이션](#apparmor) |
| 컨테이너가 사용하는 seccomp 프로파일 | [어노테이션](#seccomp) |
| 컨테이너가 사용하는 sysctl 프로파일 | [`forbiddenSysctls`,`allowedUnsafeSysctls`](#sysctl) |
## 파드 시큐리티 폴리시 활성화
파드 시큐리티 폴리시 제어는 선택 사항(하지만 권장함)인
[어드미션
컨트롤러](/docs/reference/access-authn-authz/admission-controllers/#podsecuritypolicy)로
구현된다. [어드미션 컨트롤러 활성화](/docs/reference/access-authn-authz/admission-controllers/#how-do-i-turn-on-an-admission-control-plug-in)하면
파드시큐리티폴리시가 적용되지만,
정책을 승인하지 않고 활성화하면 클러스터에
**파드가 생성되지 않는다.**
파드 시큐리티 폴리시 API(`policy/v1beta1/podsecuritypolicy`)는
어드미션 컨트롤러와 독립적으로 활성화되므로 기존 클러스터의 경우
어드미션 컨트롤러를 활성화하기 전에 정책을 추가하고 권한을
부여하는 것이 좋다.
## 정책 승인
파드시큐리티폴리시 리소스가 생성되면 아무 것도 수행하지 않는다. 이를 사용하려면
요청 사용자 또는 대상 파드의
[서비스 어카운트](/docs/tasks/configure-pod-container/configure-service-account/)는
정책에서 `use` 동사를 허용하여 정책을 사용할 권한이 있어야 한다.
대부분의 쿠버네티스 파드는 사용자가 직접 만들지 않는다. 대신 일반적으로
컨트롤러 관리자를 통해
[디플로이먼트](/ko/docs/concepts/workloads/controllers/deployment/),
[레플리카셋](/ko/docs/concepts/workloads/controllers/replicaset/), 또는 기타
템플릿 컨트롤러의 일부로 간접적으로 생성된다. 컨트롤러에 정책에 대한 접근 권한을 부여하면
해당 컨트롤러에 의해 생성된 *모든* 파드에 대한 접근 권한이 부여되므로 정책을 승인하는
기본 방법은 파드의 서비스 어카운트에 대한 접근 권한을
부여하는 것이다([예](#다른-파드를-실행) 참고).
### RBAC을 통한 방법
[RBAC](/docs/reference/access-authn-authz/rbac/)은 표준 쿠버네티스 권한 부여 모드이며,
정책 사용 권한을 부여하는 데 쉽게 사용할 수 있다.
먼저, `Role` 또는 `ClusterRole`은 원하는 정책을 `use` 하려면 접근 권한을 부여해야 한다.
접근 권한을 부여하는 규칙은 다음과 같다.
```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: <role name>
rules:
- apiGroups: ['policy']
resources: ['podsecuritypolicies']
verbs: ['use']
resourceNames:
- <list of policies to authorize>
```
그런 다음 `(Cluster)Role`이 승인된 사용자에게 바인딩된다.
```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: <binding name>
roleRef:
kind: ClusterRole
name: <role name>
apiGroup: rbac.authorization.k8s.io
subjects:
# Authorize specific service accounts:
- kind: ServiceAccount
name: <authorized service account name>
namespace: <authorized pod namespace>
# Authorize specific users (not recommended):
- kind: User
apiGroup: rbac.authorization.k8s.io
name: <authorized user name>
```
`RoleBinding`(`ClusterRoleBinding` 아님)을 사용하는 경우, 바인딩과 동일한 네임스페이스에서
실행되는 파드에 대해서만 사용 권한을 부여한다. 네임스페이스에서 실행되는 모든 파드에 접근 권한을
부여하기 위해 시스템 그룹과 쌍을 이룰 수 있다.
```yaml
# Authorize all service accounts in a namespace:
- kind: Group
apiGroup: rbac.authorization.k8s.io
name: system:serviceaccounts
# Or equivalently, all authenticated users in a namespace:
- kind: Group
apiGroup: rbac.authorization.k8s.io
name: system:authenticated
```
RBAC 바인딩에 대한 자세한 예는,
[역할 바인딩 예제](/docs/reference/access-authn-authz/rbac#role-binding-examples)를 참고하길 바란다.
파드시큐리티폴리시 인증에 대한 전체 예제는
[아래](#예제)를 참고하길 바란다.
### 문제 해결
- [컨트롤러 관리자](/docs/admin/kube-controller-manager/)는
[보안 API 포트](/docs/reference/access-authn-authz/controlling-access/)에 대해 실행해야 하며,
슈퍼유저 권한이 없어야 한다. 그렇지 않으면 요청이 인증 및 권한 부여 모듈을 우회하고,
모든 파드시큐리티폴리시 오브젝트가 허용되며
사용자는 특권있는 컨테이너를 만들 수 있다. 컨트롤러 관리자 권한 구성에 대한 자세한
내용은 [컨트롤러 역할](/docs/reference/access-authn-authz/rbac/#controller-roles)을
참고하길 바란다.
## 정책 순서
파드 생성 및 업데이트를 제한할 뿐만 아니라 파드 시큐리티 폴리시를 사용하여
제어하는 ​​많은 필드에 기본값을 제공할 수도 있다. 여러 정책을
사용할 수 있는 경우 파드 시큐리티 폴리시 컨트롤러는
다음 기준에 따라 정책을 선택한다.
1. 기본 설정을 변경하거나 파드를 변경하지 않고 파드를 있는 그대로 허용하는 파드시큐리티폴리시가
선호된다. 이러한 비-변이(non-mutating) 파드시큐리티폴리시의
순서는 중요하지 않다.
2. 파드를 기본값으로 설정하거나 변경해야 하는 경우, 파드를 허용할 첫 번째 파드시큐리티폴리시
(이름순)가 선택된다.
{{< note >}}
업데이트 작업 중(파드 스펙에 대한 변경이 허용되지 않는 동안) 비-변이 파드시큐리티폴리시만
파드의 유효성을 검사하는 데 사용된다.
{{< /note >}}
## 예제
_이 예에서는 파드시큐리티폴리시 어드미션 컨트롤러가 활성화된 클러스터가 실행 중이고
클러스터 관리자 권한이 있다고 가정한다._
### 설정
이 예제와 같이 네임스페이스와 서비스 어카운트를 설정한다.
이 서비스 어카운트를 사용하여 관리자가 아닌 사용자를 조정한다.
```shell
kubectl create namespace psp-example
kubectl create serviceaccount -n psp-example fake-user
kubectl create rolebinding -n psp-example fake-editor --clusterrole=edit --serviceaccount=psp-example:fake-user
```
어떤 사용자로 활동하고 있는지 명확하게 하고 입력 내용을 저장하려면 2개의 별칭(alias)을
만든다.
```shell
alias kubectl-admin='kubectl -n psp-example'
alias kubectl-user='kubectl --as=system:serviceaccount:psp-example:fake-user -n psp-example'
```
### 정책과 파드 생성
파일에서 예제 파드시큐리티폴리시 오브젝트를 정의한다. 이는 특권있는 파드를
만들지 못하게 하는 정책이다.
파드시큐리티폴리시 오브젝트의 이름은 유효한
[DNS 서브도메인 이름](/ko/docs/concepts/overview/working-with-objects/names#dns-서브도메인-이름)이어야 한다.
{{< codenew file="policy/example-psp.yaml" >}}
그리고 kubectl로 생성한다.
```shell
kubectl-admin create -f example-psp.yaml
```
이제 권한이 없는 사용자로서 간단한 파드를 생성해보자.
```shell
kubectl-user create -f- <<EOF
apiVersion: v1
kind: Pod
metadata:
name: pause
spec:
containers:
- name: pause
image: k8s.gcr.io/pause
EOF
Error from server (Forbidden): error when creating "STDIN": pods "pause" is forbidden: unable to validate against any pod security policy: []
```
**무슨 일이 일어났나?** 파드시큐리티폴리시가 생성되었지만, 파드의 서비스 어카운트나 `fake-user`
새 정책을 사용할 권한이 없다.
```shell
kubectl-user auth can-i use podsecuritypolicy/example
no
```
예제 정책에서 `fake-user`에게 `use` 동사를 부여하는 rolebinding을
생성한다.
{{< note >}}
이 방법은 권장하지 않는다! 선호하는 방법은 [다음 절](#다른-파드를-실행)을
참고하길 바란다.
{{< /note >}}
```shell
kubectl-admin create role psp:unprivileged \
--verb=use \
--resource=podsecuritypolicy \
--resource-name=example
role "psp:unprivileged" created
kubectl-admin create rolebinding fake-user:psp:unprivileged \
--role=psp:unprivileged \
--serviceaccount=psp-example:fake-user
rolebinding "fake-user:psp:unprivileged" created
kubectl-user auth can-i use podsecuritypolicy/example
yes
```
이제 파드 생성을 다시 시도하자.
```shell
kubectl-user create -f- <<EOF
apiVersion: v1
kind: Pod
metadata:
name: pause
spec:
containers:
- name: pause
image: k8s.gcr.io/pause
EOF
pod "pause" created
```
예상대로 작동한다! 그러나 특권있는 파드를 만들려는 시도는 여전히
거부되어야 한다.
```shell
kubectl-user create -f- <<EOF
apiVersion: v1
kind: Pod
metadata:
name: privileged
spec:
containers:
- name: pause
image: k8s.gcr.io/pause
securityContext:
privileged: true
EOF
Error from server (Forbidden): error when creating "STDIN": pods "privileged" is forbidden: unable to validate against any pod security policy: [spec.containers[0].securityContext.privileged: Invalid value: true: Privileged containers are not allowed]
```
계속 진행하기 전에 파드를 삭제하자.
```shell
kubectl-user delete pod pause
```
### 다른 파드를 실행
약간 다르게 다시 시도해보자.
```shell
kubectl-user run pause --image=k8s.gcr.io/pause
deployment "pause" created
kubectl-user get pods
No resources found.
kubectl-user get events | head -n 2
LASTSEEN FIRSTSEEN COUNT NAME KIND SUBOBJECT TYPE REASON SOURCE MESSAGE
1m 2m 15 pause-7774d79b5 ReplicaSet Warning FailedCreate replicaset-controller Error creating: pods "pause-7774d79b5-" is forbidden: no providers available to validate pod request
```
**무슨 일이 일어났나?** 우리는 이미 `fake-user`에 대해 `psp:unprivileged` 역할을 바인딩했는데,
`Error creating: pods "pause-7774d79b5-" is
forbidden: no providers available to validate pod request` 오류가
발생하는 이유는 무엇인가? 그 답은 소스인 `replicaset-controller`에 있다. Fake-user가
디플로이먼트를 성공적으로 생성했지만(레플리카셋을 성공적으로 생성했음), 레플리카셋이
파드를 생성했을 때 podsecuritypolicy 예제를
사용할 권한이 없었다.
이 문제를 해결하려면 `psp:unprivileged` 역할을 파드의 서비스 어카운트에 대신
바인딩한다. 이 경우(지정하지 않았으므로) 서비스 어카운트는
`default`이다.
```shell
kubectl-admin create rolebinding default:psp:unprivileged \
--role=psp:unprivileged \
--serviceaccount=psp-example:default
rolebinding "default:psp:unprivileged" created
```
이제 다시 한번 해본다면 replicaset-controller가
파드를 성공적으로 생성할 것이다.
```shell
kubectl-user get pods --watch
NAME READY STATUS RESTARTS AGE
pause-7774d79b5-qrgcb 0/1 Pending 0 1s
pause-7774d79b5-qrgcb 0/1 Pending 0 1s
pause-7774d79b5-qrgcb 0/1 ContainerCreating 0 1s
pause-7774d79b5-qrgcb 1/1 Running 0 2s
```
### 정리
네임스페이스를 삭제하여 대부분의 예제 리소스를 정리한다.
```shell
kubectl-admin delete ns psp-example
namespace "psp-example" deleted
```
`PodSecurityPolicy` 리소스는 네임스페이스에 포함되지 않으므로 별도로
정리해야 한다.
```shell
kubectl-admin delete psp example
podsecuritypolicy "example" deleted
```
### 정책 예제
다음은 파드 시큐리티 폴리시 어드미션 컨트롤러를 사용하지 않는 것과 동일하게 만들 수 있는
최소한의 제한 정책이다.
{{< codenew file="policy/privileged-psp.yaml" >}}
다음은 권한이 없는 사용자로서의 실행을 필요로 하고, 루트로의 에스컬레이션(escalation) 가능성을 차단하고,
여러 보안 메커니즘을 사용을 필요로 하는 제한적
정책의 예제이다.
{{< codenew file="policy/restricted-psp.yaml" >}}
## 정책 레퍼런스
### 특권을 가진
**Privileged** - 파드의 컨테이너가 특권 모드를 사용할 수 있는지 여부를 결정한다.
기본적으로 컨테이너는 호스트의 모든 장치에 접근할 수 없지만
"특권을 가진" 컨테이너는 호스트의 모든 장치에 접근할 수 있다. 이것은
컨테이너가 호스트에서 실행되는 프로세스와 거의 동일한 접근을 허용한다.
이것은 네트워크 스택 조작 및 장치 접근과 같은
리눅스 기능을 사용하려는 컨테이너에 유용하다.
### 호스트 네임스페이스
**HostPID** - 파드 컨테이너가 호스트 프로세스 ID 네임스페이스를 공유할 수 있는지 여부를
제어한다. ptrace와 함께 사용하면 컨테이너 외부로 권한을 에스컬레이션하는 데 사용할 수
있다(ptrace는 기본적으로 금지되어 있음).
**HostIPC** - 파드 컨테이너가 호스트 IPC 네임스페이스를 공유할 수 있는지 여부를
제어한다.
**HostNetwork** - 파드가 노드 네트워크 네임스페이스를 사용할 수 있는지 여부를 제어한다.
이렇게 하면 파드에 루프백 장치에 접근 권한을 주고, 서비스는 로컬호스트(localhost)를 리스닝할 수 있으며,
동일한 노드에 있는 다른 파드의 네트워크 활동을 스누핑(snoop)하는 데
사용할 수 있다.
**HostPorts** - 호스트 네트워크 네임스페이스에 허용되는 포트 범위의 화이트리스트(whitelist)를
제공한다. `min``max`를 포함하여 `HostPortRange`의 목록으로 정의된다.
기본값은 허용하는 호스트 포트 없음(no allowed host ports)이다.
### 볼륨 및 파일시스템
**Volumes** - 허용되는 볼륨 유형의 화이트리스트를 제공한다. 허용 가능한 값은
볼륨을 생성할 때 정의된 볼륨 소스에 따른다. 볼륨 유형의 전체 목록은
[볼륨 유형들](/ko/docs/concepts/storage/volumes/#볼륨-유형들)에서 참고한다.
또한 `*`를 사용하여 모든 볼륨 유형을
허용할 수 있다.
새 PSP에 허용되는 볼륨의 **최소 권장 셋** 은 다음과 같다.
- 컨피그맵
- 다운워드API
- emptyDir
- 퍼시스턴트볼륨클레임
- 시크릿
- 프로젝티드(projected)
{{< warning >}}
파드시큐리티폴리시는 `PersistentVolumeClaim`이 참조할 수 있는 `PersistentVolume`
오브젝트의 유형을 제한하지 않으며 hostPath 유형
`PersistentVolumes`은 읽기-전용 접근 모드를 지원하지 않는다. 신뢰할 수 있는 사용자만
`PersistentVolume` 오브젝트를 생성할 수 있는 권한을 부여 받아야 한다.
{{< /warning >}}
**FSGroup** - 일부 볼륨에 적용되는 보충 그룹(supplemental group)을 제어한다.
- *MustRunAs* - 하나 이상의 `range`를 지정해야 한다. 첫 번째 범위의 최솟값을
기본값으로 사용한다. 모든 범위에 대해 검증한다.
- *MayRunAs* - 하나 이상의 `range`를 지정해야 한다. 기본값을 제공하지 않고
`FSGroups`을 설정하지 않은 상태로 둘 수 있다. `FSGroups`이 설정된 경우 모든 범위에 대해
유효성을 검사한다.
- *RunAsAny* - 기본값은 제공되지 않는다. 어떠한 `fsGroup` ID의 지정도 허용한다.
**AllowedHostPaths** - hostPath 볼륨에서 사용할 수 있는 호스트 경로의 화이트리스트를
지정한다. 빈 목록은 사용되는 호스트 경로에 제한이 없음을 의미한다.
이는 단일 `pathPrefix` 필드가 있는 오브젝트 목록으로 정의되며, hostPath 볼륨은
허용된 접두사로 시작하는 경로를 마운트할 수 있으며 `readOnly` 필드는
읽기-전용으로 마운트 되어야 함을 나타낸다.
예를 들면 다음과 같습니다.
```yaml
allowedHostPaths:
# 이 정책은 "/foo", "/foo/", "/foo/bar" 등을 허용하지만,
# "/fool", "/etc/foo" 등은 허용하지 않는다.
# "/foo/../" 는 절대 유효하지 않다.
- pathPrefix: "/foo"
readOnly: true # 읽기 전용 마운트만 허용
```
{{< warning >}}호스트 파일시스템에 제한없는 접근을 부여하며, 컨테이너가 특권을 에스컬레이션
(다른 컨테이너들에 있는 데이터를 읽고, 시스템 서비스의 자격 증명을 어뷰징(abusing)하는 등)할
수 있도록 만드는 다양한 방법이 있다. 예를 들면, Kubelet과 같다.
쓰기 가능한 hostPath 디렉토리 볼륨을 사용하면, 컨테이너가 `pathPrefix` 외부의
호스트 파일시스템에 대한 통행을 허용하는 방식으로 컨테이너의 파일시스템 쓰기(write)를 허용한다.
쿠버네티스 1.11 이상 버전에서 사용 가능한 `readOnly: true`는 지정된 `pathPrefix`에 대한
접근을 효과적으로 제한하기 위해 **모든** `allowedHostPaths`에서 사용해야 한다.
{{< /warning >}}
**ReadOnlyRootFilesystem** - 컨테이너는 읽기-전용 루트 파일시스템(즉, 쓰기 가능한 레이어 없음)으로
실행해야 한다.
### FlexVolume 드라이버
flexvolume에서 사용할 수 있는 FlexVolume 드라이버의 화이트리스트를 지정한다.
빈 목록 또는 nil은 드라이버에 제한이 없음을 의미한다.
[`volumes`](#볼륨-및-파일시스템) 필드에 `flexVolume` 볼륨 유형이 포함되어
있는지 확인한다. 그렇지 않으면 FlexVolume 드라이버가 허용되지 않는다.
예를 들면 다음과 같다.
```yaml
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: allow-flex-volumes
spec:
# ... 다른 스펙 필드
volumes:
- flexVolume
allowedFlexVolumes:
- driver: example/lvm
- driver: example/cifs
```
### 사용자 및 그룹
**RunAsUser** - 컨테이너를 실행할 사용자 ID를 제어힌다.
- *MustRunAs* - 하나 이상의 `range`를 지정해야 한다. 첫 번째 범위의 최솟값을
기본값으로 사용한다. 모든 범위에 대해 검증한다.
- *MustRunAsNonRoot* - 파드가 0이 아닌 `runAsUser`로 제출되거나
이미지에 `USER` 지시문이 정의되어 있어야 한다(숫자 UID 사용). `runAsNonRoot` 또는
`runAsUser` 설정을 지정하지 않은 파드는 `runAsNonRoot=true`를 설정하도록
변경되므로 컨테이너에 0이 아닌 숫자가 정의된 `USER` 지시문이
필요하다. 기본값은 제공되지 않는다.
이 전략에서는 `allowPrivilegeEscalation=false`를 설정하는 것이 좋다.
- *RunAsAny* - 기본값은 제공되지 않는다. 어떠한 `runAsUser`의 지정도 허용한다.
**RunAsGroup** - 컨테이너가 실행될 기본 그룹 ID를 제어한다.
- *MustRunAs* - 하나 이상의 `range`를 지정해야 한다. 첫 번째 범위의 최솟값을
기본값으로 사용한다. 모든 범위에 대해 검증한다.
- *MayRunAs* - `RunAsGroup`을 지정할 필요가 없다. 그러나 `RunAsGroup`을 지정하면
정의된 범위에 속해야 한다.
- *RunAsAny* - 기본값은 제공되지 않는다. 어떠한 `runAsGroup`의 지정도 허용한다.
**SupplementalGroups** - 컨테이너가 추가할 그룹 ID를 제어한다.
- *MustRunAs* - 하나 이상의 `range`를 지정해야 한다. 첫 번째 범위의 최솟값을
기본값으로 사용한다. 모든 범위에 대해 검증한다.
- *MayRunAs* - 하나 이상의 `range`를 지정해야 한다. `supplementalGroups`
기본값을 제공하지 않고 설정하지 않은 상태로 둘 수 있다.
`supplementalGroups`가 설정된 경우 모든 범위에 대해 유효성을 검증한다.
- *RunAsAny* - 기본값은 제공되지 않는다. 어떠한 `supplementalGroups`의 지정도
허용한다.
### 권한 에스컬레이션
이 옵션은 `allowPrivilegeEscalation` 컨테이너 옵션을 제어한다. 이 bool은
컨테이너 프로세스에서
[`no_new_privs`](https://www.kernel.org/doc/Documentation/prctl/no_new_privs.txt)
플래그가 설정되는지 여부를 직접 제어한다. 이 플래그는 `setuid` 바이너리가
유효 사용자 ID를 변경하지 못하게 하고 파일에 추가 기능을 활성화하지 못하게
한다(예: `ping` 도구 사용을 못하게 함). `MustRunAsNonRoot`를 효과적으로
강제하려면 이 동작이 필요하다.
**AllowPrivilegeEscalation** - 사용자가 컨테이너의 보안 컨텍스트를
`allowPrivilegeEscalation=true`로 설정할 수 있는지 여부를 게이트한다.
이 기본값은 setuid 바이너리를 중단하지 않도록 허용한다. 이를 `false`로 설정하면
컨테이너의 하위 프로세스가 상위 프로세스보다 더 많은 권한을 얻을 수 없다.
**DefaultAllowPrivilegeEscalation** - `allowPrivilegeEscalation` 옵션의
기본값을 설정한다. 이것이 없는 기본 동작은 setuid 바이너리를 중단하지 않도록
권한 에스컬레이션을 허용하는 것이다. 해당 동작이 필요하지 않은 경우 이 필드를 사용하여
기본적으로 허용하지 않도록 설정할 수 있지만 파드는 여전히 `allowPrivilegeEscalation`
명시적으로 요청할 수 있다.
### 기능
리눅스 기능은 전통적으로 슈퍼유저와 관련된 권한을 보다 세밀하게 분류한다.
이러한 기능 중 일부는 권한 에스컬레이션 또는 컨테이너 분류에 사용될 수 있으며
파드시큐리티폴리시에 의해 제한될 수 있다. 리눅스 기능에 대한 자세한 내용은
[기능(7)](http://man7.org/linux/man-pages/man7/capabilities.7.html)을
참고하길 바란다.
다음 필드는 대문자로 표기된 기능 이름 목록을
`CAP_` 접두사 없이 가져온다.
**AllowedCapabilities** - 컨테이너에 추가될 수 있는 기능의 화이트리스트를
제공한다. 기본적인 기능 셋은 암시적으로 허용된다. 비어있는 셋은
기본 셋을 넘어서는 추가 기능이 추가되지 않는 것을
의미한다. `*`는 모든 기능을 허용하는 데 사용할 수 있다.
**RequiredDropCapabilities** - 컨테이너에서 삭제해야 하는 기능이다.
이러한 기능은 기본 셋에서 제거되며 추가해서는 안된다.
`RequiredDropCapabilities`에 나열된 기능은 `AllowedCapabilities` 또는
`DefaultAddCapabilities`에 포함되지 않아야 한다.
**DefaultAddCapabilities** - 런타임 기본값 외에 기본적으로 컨테이너에 추가되는 기능이다.
도커 런타임을 사용할 때 기본 기능 목록은
[도커 문서](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities)를
참고하길 바란다.
### SELinux
- *MustRunAs* - `seLinuxOptions`을 구성해야 한다.
`seLinuxOptions`을 기본값으로 사용한다. `seLinuxOptions`에 대해 유효성을 검사한다.
- *RunAsAny* - 기본값은 제공되지 않는다. 어떠한 `seLinuxOptions`의 지정도
허용한다.
### AllowedProcMountTypes
`allowedProcMountTypes`는 허용된 ProcMountTypes의 화이트리스트이다.
비어 있거나 nil은 `DefaultProcMountType`만 사용할 수 있음을 나타낸다.
`DefaultProcMount`는 /proc의 읽기 전용 및 마스킹(masking)된 경로에 컨테이너 런타임
기본값을 사용한다. 대부분의 컨테이너 런타임은 특수 장치나 정보가 실수로 보안에
노출되지 않도록 /proc의 특정 경로를 마스킹한다. 이것은 문자열
`Default`로 표시된다.
유일하게 다른 ProcMountType은 `UnmaskedProcMount`로, 컨테이너 런타임의
기본 마스킹 동작을 무시하고 새로 작성된 /proc 컨테이너가 수정없이
그대로 유지되도록 한다. 이 문자열은
`Unmasked`로 표시된다.
### AppArmor
파드시큐리티폴리시의 어노테이션을 통해 제어된다. [AppArmor
문서](/docs/tutorials/clusters/apparmor/#podsecuritypolicy-annotations)를 참고하길 바란다.
### Seccomp
파드에서 seccomp 프로파일의 사용은 파드시큐리티폴리시의 어노테이션을 통해
제어할 수 있다. Seccomp는 쿠버네티스의 알파 기능이다.
**seccomp.security.alpha.kubernetes.io/defaultProfileName** - 컨테이너에
적용할 기본 seccomp 프로파일을 지정하는 어노테이션이다. 가능한 값은
다음과 같다.
- `unconfined` - 대안이 제공되지 않으면 Seccomp가 컨테이너 프로세스에 적용되지
않는다(쿠버네티스의 기본값임).
- `runtime/default` - 기본 컨테이너 런타임 프로파일이 사용된다.
- `docker/default` - 도커 기본 seccomp 프로파일이 사용된다. 쿠버네티스 1.11 부터 사용 중단(deprecated)
되었다. 대신 `runtime/default` 사용을 권장한다.
- `localhost/<path>` - `<seccomp_root>/<path>`에 있는 노드에서 파일을 프로파일로
지정한다. 여기서 `<seccomp_root>`는 Kubelet의 `--seccomp-profile-root` 플래그를
통해 정의된다.
**seccomp.security.alpha.kubernetes.io/allowedProfileNames** - 파드 seccomp
어노테이션에 허용되는 값을 지정하는 어노테이션. 쉼표로 구분된
허용된 값의 목록으로 지정된다. 가능한 값은 위에 나열된 값과
모든 프로파일을 허용하는 `*` 이다.
이 주석이 없으면 기본값을 변경할 수 없다.
### Sysctl
기본적으로 모든 안전한 sysctls가 허용된다.
- `forbiddenSysctls` - 특정 sysctls를 제외한다. 목록에서 안전한 것과 안전하지 않은 sysctls의 조합을 금지할 수 있다. 모든 sysctls 설정을 금지하려면 자체적으로 `*`를 사용한다.
- `allowedUnsafeSysctls` - `forbiddenSysctls`에 나열되지 않는 한 기본 목록에서 허용하지 않은 특정 sysctls를 허용한다.
[Sysctl 문서](
/docs/concepts/cluster-administration/sysctl-cluster/#podsecuritypolicy)를 참고하길 바란다.
{{% /capture %}}
{{% capture whatsnext %}}
API 세부 정보는 [파드 시큐리티 폴리시 레퍼런스](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podsecuritypolicy-v1beta1-policy) 참조
{{% /capture %}}

View File

@ -0,0 +1,600 @@
---
title: 리소스 쿼터
content_template: templates/concept
weight: 10
---
{{% capture overview %}}
여러 사용자나 팀이 정해진 수의 노드로 클러스터를 공유할 때
한 팀이 공정하게 분배된 리소스보다 많은 리소스를 사용할 수 있다는 우려가 있다.
리소스 쿼터는 관리자가 이 문제를 해결하기 위한 도구이다.
{{% /capture %}}
{{% capture body %}}
`ResourceQuota` 오브젝트로 정의된 리소스 쿼터는 네임스페이스별 총 리소스 사용을 제한하는
제약 조건을 제공한다. 유형별로 네임스페이스에서 만들 수 있는 오브젝트 수와
해당 프로젝트의 리소스가 사용할 수 있는 총 컴퓨트 리소스의 양을
제한할 수 있다.
리소스 쿼터는 다음과 같이 작동한다.
- 다른 팀은 다른 네임스페이스에서 작동한다. 현재 이것은 자발적이지만 ACL을 통해 이 필수 사항을
적용하기 위한 지원이 계획되어 있다.
- 관리자는 각 네임스페이스에 대해 하나의 `ResourceQuota`를 생성한다.
- 사용자는 네임스페이스에서 리소스(파드, 서비스 등)를 생성하고 쿼터 시스템은
사용량을 추적하여 `ResourceQuota`에 정의된 하드(hard) 리소스 제한을 초과하지 않도록 한다.
- 리소스를 생성하거나 업데이트할 때 쿼터 제약 조건을 위반하면 위반된 제약 조건을 설명하는
메시지와 함께 HTTP 상태 코드 `403 FORBIDDEN`으로 요청이 실패한다.
- `cpu`, `memory`와 같은 컴퓨트 리소스에 대해 네임스페이스에서 쿼터가 활성화된 경우
사용자는 해당값에 대한 요청 또는 제한을 지정해야 한다. 그렇지 않으면 쿼터 시스템이
파드 생성을 거부할 수 있다. 힌트: 컴퓨트 리소스 요구 사항이 없는 파드를 기본값으로 설정하려면 `LimitRanger` 어드미션 컨트롤러를 사용하자.
이 문제를 회피하는 방법에 대한 예제는 [연습](/docs/tasks/administer-cluster/quota-memory-cpu-namespace/)을 참고하길 바란다.
`ResourceQuota` 오브젝트의 이름은 유효한
[DNS 서브도메인 이름](/ko/docs/concepts/overview/working-with-objects/names#dns-서브도메인-이름)이어야 한다.
네임스페이스와 쿼터를 사용하여 만들 수 있는 정책의 예는 다음과 같다.
- 용량이 32GiB RAM, 16 코어인 클러스터에서 A 팀이 20GiB 및 10 코어를 사용하고
B 팀은 10GiB 및 4 코어를 사용하게 하고 2GiB 및 2 코어를 향후 할당을 위해 보유하도록 한다.
- "testing" 네임스페이스를 1 코어 및 1GiB RAM을 사용하도록 제한한다.
"production" 네임스페이스에는 원하는 양을 사용하도록 한다.
클러스터의 총 용량이 네임스페이스의 쿼터 합보다 작은 경우 리소스에 대한 경합이 있을 수 있다.
이것은 선착순으로 처리된다.
경합이나 쿼터 변경은 이미 생성된 리소스에 영향을 미치지 않는다.
## 리소스 쿼터 활성화
많은 쿠버네티스 배포판에 기본적으로 리소스 쿼터 지원이 활성화되어 있다.
API 서버 `--enable-admission-plugins=` 플래그의 인수 중 하나로
`ResourceQuota`가 있는 경우 활성화된다.
해당 네임스페이스에 `ResourceQuota`가 있는 경우 특정 네임스페이스에 리소스 쿼터가 적용된다.
## 컴퓨트 리소스 쿼터
지정된 네임스페이스에서 요청할 수 있는 총 [컴퓨트 리소스](/docs/user-guide/compute-resources) 합을 제한할 수 있다.
다음과 같은 리소스 유형이 지원된다.
| 리소스 이름 | 설명 |
| --------------------- | ----------------------------------------------------------- |
| `limits.cpu` | 터미널이 아닌 상태의 모든 파드에서 CPU 제한의 합은 이 값을 초과할 수 없음 |
| `limits.memory` | 터미널이 아닌 상태의 모든 파드에서 메모리 제한의 합은 이 값을 초과할 수 없음 |
| `requests.cpu` | 터미널이 아닌 상태의 모든 파드에서 CPU 요청의 합은 이 값을 초과할 수 없음 |
| `requests.memory` | 터미널이 아닌 상태의 모든 파드에서 메모리 요청의 합은 이 값을 초과할 수 없음 |
### 확장된 리소스에 대한 리소스 쿼터
위에서 언급한 리소스 외에도 릴리스 1.10에서는
[확장된 리소스](/docs/concepts/configuration/manage-compute-resources-container/#extended-resources)에 대한 쿼터 지원이 추가되었다.
확장된 리소스에는 오버커밋(overcommit)이 허용되지 않으므로 하나의 쿼터에서
동일한 확장된 리소스에 대한 `requests``limits`을 모두 지정하는 것은 의미가 없다. 따라서 확장된
리소스의 경우 지금은 접두사 `requests.`이 있는 쿼터 항목만 허용된다.
예를 들어, 리소스 이름이 `nvidia.com/gpu`이고 네임스페이스에서 요청된 총 GPU 수를 4개로 제한하려는 경우,
GPU 리소스를 다음과 같이 쿼터를 정의할 수 있다.
* `requests.nvidia.com/gpu: 4`
자세한 내용은 [쿼터 보기 및 설정](#쿼터-보기-및-설정)을 참고하길 바란다.
## 스토리지 리소스 쿼터
지정된 네임스페이스에서 요청할 수 있는 총 [스토리지 리소스](/ko/docs/concepts/storage/persistent-volumes/) 합을 제한할 수 있다.
또한 연관된 ​​스토리지 클래스를 기반으로 스토리지 리소스 사용을 제한할 수 있다.
| 리소스 이름 | 설명 |
| --------------------- | ----------------------------------------------------------- |
| `requests.storage` | 모든 퍼시스턴트 볼륨 클레임에서 스토리지 요청의 합은 이 값을 초과할 수 없음 |
| `persistentvolumeclaims` | 네임스페이스에 존재할 수 있는 총 [퍼시스턴트 볼륨 클레임](/ko/docs/concepts/storage/persistent-volumes/#퍼시스턴트볼륨클레임) 수 |
| `<storage-class-name>.storageclass.storage.k8s.io/requests.storage` | storage-class-name과 관련된 모든 퍼시스턴트 볼륨 클레임에서 스토리지 요청의 합은 이 값을 초과할 수 없음 |
| `<storage-class-name>.storageclass.storage.k8s.io/persistentvolumeclaims` | storage-class-name과 관련된 모든 퍼시스턴트 볼륨 클레임에서 네임스페이스에 존재할 수 있는 총 [퍼시스턴트 볼륨 클레임](/ko/docs/concepts/storage/persistent-volumes/#퍼시스턴트볼륨클레임) 수 |
예를 들어, 운영자가 `bronze` 스토리지 클래스와 별도로 `gold` 스토리지 클래스를 사용하여 스토리지에 쿼터를 지정하려는 경우 운영자는 다음과 같이
쿼터를 정의할 수 있다.
* `gold.storageclass.storage.k8s.io/requests.storage: 500Gi`
* `bronze.storageclass.storage.k8s.io/requests.storage: 100Gi`
릴리스 1.8에서는 로컬 임시 스토리지에 대한 쿼터 지원이 알파 기능으로 추가되었다.
| 리소스 이름 | 설명 |
| ------------------------------- |----------------------------------------------------------- |
| `requests.ephemeral-storage` | 네임스페이스의 모든 파드에서 로컬 임시 스토리지 요청의 합은 이 값을 초과할 수 없음 |
| `limits.ephemeral-storage` | 네임스페이스의 모든 파드에서 로컬 임시 스토리지 제한의 합은 이 값을 초과할 수 없음 |
## 오브젝트 수 쿼터
1.9 릴리스는 다음 구문을 사용하여 모든 표준 네임스페이스 리소스 유형에 쿼터를 지정하는 지원을 추가했다.
* `count/<resource>.<group>`
다음은 사용자가 오브젝트 수 쿼터 아래에 배치하려는 리소스 셋의 예이다.
* `count/persistentvolumeclaims`
* `count/services`
* `count/secrets`
* `count/configmaps`
* `count/replicationcontrollers`
* `count/deployments.apps`
* `count/replicasets.apps`
* `count/statefulsets.apps`
* `count/jobs.batch`
* `count/cronjobs.batch`
* `count/deployments.extensions`
1.15 릴리스는 동일한 구문을 사용하여 사용자 정의 리소스에 대한 지원을 추가했다.
예를 들어 `example.com` API 그룹에서 `widgets` 사용자 정의 리소스에 대한 쿼터를 생성하려면 `count/widgets.example.com`을 사용한다.
`count/*` 리소스 쿼터를 사용할 때 서버 스토리지 영역에 있다면 오브젝트는 쿼터에 대해 과금된다.
이러한 유형의 쿼터는 스토리지 리소스 고갈을 방지하는 데 유용하다. 예를 들어,
크기가 큰 서버에서 시크릿 수에 쿼터를 지정할 수 있다. 클러스터에 시크릿이 너무 많으면 실제로 서버와
컨트롤러가 시작되지 않을 수 있다! 네임스페이스에 너무 많은 작업을 생성하는
잘못 구성된 크론 잡으로 인해 서비스 거부를 유발하는 것으로부터 보호하기 위해 작업의 쿼터를 지정하도록 선택할 수 있다.
1.9 릴리스 이전에는 제한된 리소스 셋에서 일반 오브젝트 수 쿼터를 적용할 수 있었다.
또한, 특정 리소스에 대한 쿼터를 유형별로 추가로 제한할 수 있다.
다음 유형이 지원된다.
| 리소스 이름 | 설명 |
| ------------------------------- | ------------------------------------------------- |
| `configmaps` | 네임스페이스에 존재할 수 있는 총 구성 맵 수 |
| `persistentvolumeclaims` | 네임스페이스에 존재할 수 있는 총 [퍼시스턴트 볼륨 클레임](/ko/docs/concepts/storage/persistent-volumes/#퍼시스턴트볼륨클레임) 수 |
| `pods` | 네임스페이스에 존재할 수 있는 터미널이 아닌 상태의 파드의 총 수. `.status.phase in (Failed, Succeeded)`가 true인 경우 파드는 터미널 상태임 |
| `replicationcontrollers` | 네임스페이스에 존재할 수 있는 총 레플리케이션 컨트롤러 수 |
| `resourcequotas` | 네임스페이스에 존재할 수 있는 총 [리소스 쿼터](/docs/reference/access-authn-authz/admission-controllers/#resourcequota) 수 |
| `services` | 네임스페이스에 존재할 수 있는 총 서비스 수 |
| `services.loadbalancers` | 네임스페이스에 존재할 수 있는 로드 밸런서 유형의 총 서비스 수 |
| `services.nodeports` | 네임스페이스에 존재할 수 있는 노드 포트 유형의 총 서비스 수 |
| `secrets` | 네임스페이스에 존재할 수 있는 총 시크릿 수 |
예를 들어, `pods` 쿼터는 터미널이 아닌 단일 네임스페이스에서 생성된 `pods` 수를 계산하고 최대값을 적용한다.
사용자가 작은 파드를 많이 생성하여 클러스터의 파드 IP 공급이 고갈되는 경우를 피하기 위해
네임스페이스에 `pods` 쿼터를 설정할 수 있다.
## 쿼터 범위
각 쿼터에는 연결된 범위 셋이 있을 수 있다. 쿼터는 열거된 범위의 교차 부분과 일치하는 경우에만
리소스 사용량을 측정한다.
범위가 쿼터에 추가되면 해당 범위와 관련된 리소스를 지원하는 리소스 수가 제한된다.
허용된 셋 이외의 쿼터에 지정된 리소스는 유효성 검사 오류가 발생한다.
| 범위 | 설명 |
| ----- | ----------- |
| `Terminating` | `.spec.activeDeadlineSeconds >= 0`에 일치하는 파드 |
| `NotTerminating` | `.spec.activeDeadlineSeconds is nil`에 일치하는 파드 |
| `BestEffort` | 최상의 서비스 품질을 제공하는 파드 |
| `NotBestEffort` | 서비스 품질이 나쁜 파드 |
`BestEffort` 범위는 다음의 리소스(파드)를 추적하도록 쿼터를 제한한다.
`Terminating`, `NotTerminating``NotBestEffort` 범위는 쿼터를 제한하여 다음의 리소스를 추적한다.
* `cpu`
* `limits.cpu`
* `limits.memory`
* `memory`
* `pods`
* `requests.cpu`
* `requests.memory`
### PriorityClass별 리소스 쿼터
{{< feature-state for_k8s_version="1.12" state="beta" >}}
특정 [우선 순위](/docs/concepts/configuration/pod-priority-preemption/#pod-priority)로 파드를 생성할 수 있다.
쿼터 스펙의 `scopeSelector` 필드를 사용하여 파드의 우선 순위에 따라 파드의 시스템 리소스 사용을
제어할 수 있다.
쿼터 스펙의 `scopeSelector`가 파드를 선택한 경우에만 쿼터가 일치하고 사용된다.
이 예에서는 쿼터 오브젝트를 생성하여 특정 우선 순위의 파드와 일치시킨다.
예제는 다음과 같이 작동한다.
- 클러스터의 파드는 "low(낮음)", "medium(중간)", "high(높음)"의 세 가지 우선 순위 클래스 중 하나를 가진다.
- 각 우선 순위마다 하나의 쿼터 오브젝트가 생성된다.
다음 YAML을 `quota.yml` 파일에 저장한다.
```yaml
apiVersion: v1
kind: List
items:
- apiVersion: v1
kind: ResourceQuota
metadata:
name: pods-high
spec:
hard:
cpu: "1000"
memory: 200Gi
pods: "10"
scopeSelector:
matchExpressions:
- operator : In
scopeName: PriorityClass
values: ["high"]
- apiVersion: v1
kind: ResourceQuota
metadata:
name: pods-medium
spec:
hard:
cpu: "10"
memory: 20Gi
pods: "10"
scopeSelector:
matchExpressions:
- operator : In
scopeName: PriorityClass
values: ["medium"]
- apiVersion: v1
kind: ResourceQuota
metadata:
name: pods-low
spec:
hard:
cpu: "5"
memory: 10Gi
pods: "10"
scopeSelector:
matchExpressions:
- operator : In
scopeName: PriorityClass
values: ["low"]
```
`kubectl create`를 사용하여 YAML을 적용한다.
```shell
kubectl create -f ./quota.yml
```
```shell
resourcequota/pods-high created
resourcequota/pods-medium created
resourcequota/pods-low created
```
`kubectl describe quota`를 사용하여 `Used` 쿼터가 `0`인지 확인하자.
```shell
kubectl describe quota
```
```shell
Name: pods-high
Namespace: default
Resource Used Hard
-------- ---- ----
cpu 0 1k
memory 0 200Gi
pods 0 10
Name: pods-low
Namespace: default
Resource Used Hard
-------- ---- ----
cpu 0 5
memory 0 10Gi
pods 0 10
Name: pods-medium
Namespace: default
Resource Used Hard
-------- ---- ----
cpu 0 10
memory 0 20Gi
pods 0 10
```
우선 순위가 "high"인 파드를 생성한다. 다음 YAML을
`high-priority-pod.yml` 파일에 저장한다.
```yaml
apiVersion: v1
kind: Pod
metadata:
name: high-priority
spec:
containers:
- name: high-priority
image: ubuntu
command: ["/bin/sh"]
args: ["-c", "while true; do echo hello; sleep 10;done"]
resources:
requests:
memory: "10Gi"
cpu: "500m"
limits:
memory: "10Gi"
cpu: "500m"
priorityClassName: high
```
`kubectl create`로 적용하자.
```shell
kubectl create -f ./high-priority-pod.yml
```
"high" 우선 순위 쿼터가 적용된 `pods-high`에 대한 "Used" 통계가 변경되었고
다른 두 쿼터는 변경되지 않았는지 확인한다.
```shell
kubectl describe quota
```
```shell
Name: pods-high
Namespace: default
Resource Used Hard
-------- ---- ----
cpu 500m 1k
memory 10Gi 200Gi
pods 1 10
Name: pods-low
Namespace: default
Resource Used Hard
-------- ---- ----
cpu 0 5
memory 0 10Gi
pods 0 10
Name: pods-medium
Namespace: default
Resource Used Hard
-------- ---- ----
cpu 0 10
memory 0 20Gi
pods 0 10
```
`scopeSelector``operator` 필드에서 다음 값을 지원한다.
* `In`
* `NotIn`
* `Exist`
* `DoesNotExist`
## 요청과 제한의 비교 {#requests-vs-limits}
컴퓨트 리소스를 할당할 때 각 컨테이너는 CPU 또는 메모리에 대한 요청과 제한값을 지정할 수 있다.
쿼터는 값에 대한 쿼터를 지정하도록 구성할 수 있다.
쿼터에 `requests.cpu``requests.memory`에 지정된 값이 있으면 들어오는 모든
컨테이너가 해당 리소스에 대한 명시적인 요청을 지정해야 한다. 쿼터에 `limits.cpu`
`limits.memory`에 지정된 값이 있으면 들어오는 모든 컨테이너가 해당 리소스에 대한 명시적인 제한을 지정해야 한다.
## 쿼터 보기 및 설정
Kubectl은 쿼터 생성, 업데이트 및 보기를 지원한다.
```shell
kubectl create namespace myspace
```
```shell
cat <<EOF > compute-resources.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-resources
spec:
hard:
requests.cpu: "1"
requests.memory: 1Gi
limits.cpu: "2"
limits.memory: 2Gi
requests.nvidia.com/gpu: 4
EOF
```
```shell
kubectl create -f ./compute-resources.yaml --namespace=myspace
```
```shell
cat <<EOF > object-counts.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: object-counts
spec:
hard:
configmaps: "10"
persistentvolumeclaims: "4"
pods: "4"
replicationcontrollers: "20"
secrets: "10"
services: "10"
services.loadbalancers: "2"
EOF
```
```shell
kubectl create -f ./object-counts.yaml --namespace=myspace
```
```shell
kubectl get quota --namespace=myspace
```
```shell
NAME AGE
compute-resources 30s
object-counts 32s
```
```shell
kubectl describe quota compute-resources --namespace=myspace
```
```shell
Name: compute-resources
Namespace: myspace
Resource Used Hard
-------- ---- ----
limits.cpu 0 2
limits.memory 0 2Gi
requests.cpu 0 1
requests.memory 0 1Gi
requests.nvidia.com/gpu 0 4
```
```shell
kubectl describe quota object-counts --namespace=myspace
```
```shell
Name: object-counts
Namespace: myspace
Resource Used Hard
-------- ---- ----
configmaps 0 10
persistentvolumeclaims 0 4
pods 0 4
replicationcontrollers 0 20
secrets 1 10
services 0 10
services.loadbalancers 0 2
```
Kubectl은 `count/<resource>.<group>` 구문을 사용하여 모든 표준 네임스페이스 리소스에 대한
오브젝트 수 쿼터를 지원한다.
```shell
kubectl create namespace myspace
```
```shell
kubectl create quota test --hard=count/deployments.extensions=2,count/replicasets.extensions=4,count/pods=3,count/secrets=4 --namespace=myspace
```
```shell
kubectl run nginx --image=nginx --replicas=2 --namespace=myspace
```
```shell
kubectl describe quota --namespace=myspace
```
```shell
Name: test
Namespace: myspace
Resource Used Hard
-------- ---- ----
count/deployments.extensions 1 2
count/pods 2 3
count/replicasets.extensions 1 4
count/secrets 1 4
```
## 쿼터 및 클러스터 용량
`ResourceQuotas`는 클러스터 용량과 무관하다. 그것들은 절대 단위로 표현된다.
따라서 클러스터에 노드를 추가해도 각 네임스페이스에 더 많은 리소스를
사용할 수 있는 기능이 자동으로 부여되지는 *않는다*.
가끔 다음과 같은 보다 복잡한 정책이 필요할 수 있다.
- 여러 팀으로 전체 클러스터 리소스를 비례적으로 나눈다.
- 각 테넌트가 필요에 따라 리소스 사용량을 늘릴 수 있지만, 실수로 리소스가 고갈되는 것을
막기 위한 충분한 제한이 있다.
- 하나의 네임스페이스에서 요구를 감지하고 노드를 추가하며 쿼터를 늘린다.
이러한 정책은 쿼터 사용을 감시하고 다른 신호에 따라 각 네임스페이스의 쿼터 하드 제한을
조정하는 "컨트롤러"를 작성하여 `ResourceQuotas`를 구성 요소로
사용하여 구현할 수 있다.
리소스 쿼터는 통합된 클러스터 리소스를 분할하지만 노드에 대한 제한은 없다.
여러 네임스페이스의 파드가 동일한 노드에서 실행될 수 있다.
## 기본적으로 우선 순위 클래스 소비 제한
파드가 특정 우선 순위, 예를 들어 일치하는 쿼터 오브젝트가 존재하는 경우에만 "cluster-services"가 네임스페이스에 허용되어야 힌다.
이 메커니즘을 통해 운영자는 특정 우선 순위가 높은 클래스의 사용을 제한된 수의 네임스페이스로 제한할 수 있으며 모든 네임스페이스가 기본적으로 이러한 우선 순위 클래스를 사용할 수 있는 것은 아니다.
이를 적용하려면 kube-apiserver 플래그 `--admission-control-config-file`을 사용하여 다음 구성 파일의 경로를 전달해야 한다.
{{< tabs name="example1" >}}
{{% tab name="apiserver.config.k8s.io/v1" %}}
```yaml
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: "ResourceQuota"
configuration:
apiVersion: apiserver.config.k8s.io/v1
kind: ResourceQuotaConfiguration
limitedResources:
- resource: pods
matchScopes:
- scopeName: PriorityClass
operator: In
values: ["cluster-services"]
```
{{% /tab %}}
{{% tab name="apiserver.k8s.io/v1alpha1" %}}
```yaml
# Deprecated in v1.17 in favor of apiserver.config.k8s.io/v1
apiVersion: apiserver.k8s.io/v1alpha1
kind: AdmissionConfiguration
plugins:
- name: "ResourceQuota"
configuration:
# Deprecated in v1.17 in favor of apiserver.config.k8s.io/v1, ResourceQuotaConfiguration
apiVersion: resourcequota.admission.k8s.io/v1beta1
kind: Configuration
limitedResources:
- resource: pods
matchScopes:
- scopeName: PriorityClass
operator: In
values: ["cluster-services"]
```
{{% /tab %}}
{{< /tabs >}}
이제 "cluster-services" 파드는 `scopeSelector`와 일치하는 쿼터 오브젝트가 있는 네임스페이스에서만 허용된다.
예를 들면 다음과 같다.
```yaml
scopeSelector:
matchExpressions:
- scopeName: PriorityClass
operator: In
values: ["cluster-services"]
```
자세한 내용은 [LimitedResources](https://github.com/kubernetes/kubernetes/pull/36765)와 [우선 순위 클래스에 대한 쿼터 지원 디자인 문서](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/scheduling/pod-priority-resourcequota.md)를 참고하길 바란다.
## 예제
[리소스 쿼터를 사용하는 방법에 대한 자세한 예](/docs/tasks/administer-cluster/quota-api-object/)를 참고하길 바란다.
{{% /capture %}}
{{% capture whatsnext %}}
자세한 내용은 [리소스쿼터 디자인 문서](https://git.k8s.io/community/contributors/design-proposals/resource-management/admission_control_resource_quota.md)를 참고하길 바란다.
{{% /capture %}}

View File

@ -0,0 +1,97 @@
---
title: 쿠버네티스 스케줄러
content_template: templates/concept
weight: 50
---
{{% capture overview %}}
쿠버네티스에서 _스케줄링_ 은 {{< glossary_tooltip term_id="kubelet" >}}이
파드를 실행할 수 있도록 {{< glossary_tooltip text="파드" term_id="pod" >}}가
{{< glossary_tooltip text="노드" term_id="node" >}}에 적합한지 확인하는 것을 말한다.
{{% /capture %}}
{{% capture body %}}
## 스케줄링 개요 {#scheduling}
스케줄러는 노드가 할당되지 않은 새로 생성된 파드를 감시한다.
스케줄러가 발견한 모든 파드에 대해 스케줄러는 해당 파드가 실행될
최상의 노드를 찾는 책임을 진다. 스케줄러는
아래 설명된 스케줄링 원칙을 고려하여 이 배치 결정을
하게 된다.
파드가 특정 노드에 배치되는 이유를 이해하려고 하거나
사용자 정의된 스케줄러를 직접 구현하려는 경우 이
페이지를 통해서 스케줄링에 대해 배울 수 있을 것이다.
## kube-scheduler
[kube-scheduler](https://kubernetes.io/docs/reference/command-line-tools-reference/kube-scheduler/)는
쿠버네티스의 기본 스케줄러이며 {{< glossary_tooltip text="컨트롤 플레인" term_id="control-plane" >}}의
일부로 실행된다.
kube-scheduler는 원하거나 필요에 따라 자체 스케줄링 컴포넌트를
만들고 대신 사용할 수 있도록 설계되었다.
새로 생성된 모든 파드 또는 예약되지 않은 다른 파드에 대해 kube-scheduler는
실행할 최적의 노드를 선택한다. 그러나 파드의 모든 컨테이너에는
리소스에 대한 요구사항이 다르며 모든 파드에도
요구사항이 다르다. 따라서 기존 노드들은
특정 스케줄링 요구사항에 따라 필터링 되어야 한다.
클러스터에서 파드에 대한 스케줄링 요구사항을 충족하는 노드를
_실행 가능한(feasible)_ 노드라고 한다. 적합한 노드가 없으면 스케줄러가
배치할 수 있을 때까지 파드가 스케줄 되지 않은 상태로 유지된다.
스케줄러는 파드가 실행 가능한 노드를 찾은 다음 실행 가능한 노드의
점수를 측정하는 기능 셋을 수행하고 실행 가능한 노드 중에서 가장 높은 점수를
가진 노드를 선택하여 파드를 실행한다. 그런 다음 스케줄러는
_바인딩_ 이라는 프로세스에서 이 결정에 대해 API 서버에 알린다.
스케줄링 결정을 위해 고려해야 할 요소에는
개별 및 집단 리소스 요구사항, 하드웨어 / 소프트웨어 /
정책 제한조건, 어피니티 및 안티-어피니티 명세, 데이터
지역성(data locality), 워크로드 간 간섭 등이 포함된다.
### kube-scheduler에서 노드 선택 {#kube-scheduler-implementation}
kube-scheduler는 2단계 작업에서 파드에 대한 노드를 선택한다.
1. 필터링
1. 스코어링(scoring)
_필터링_ 단계는 파드를 스케줄링 할 수 있는 노드 셋을
찾는다. 예를 들어 PodFitsResources 필터는
후보 노드가 파드의 특정 리소스 요청을 충족시키기에 충분한 가용 리소스가
있는지 확인한다. 이 단계 다음에 노드 목록에는 적합한 노드들이
포함된다. 하나 이상의 노드가 포함된 경우가 종종 있을 것이다. 목록이 비어 있으면
해당 파드는 (아직) 스케줄링 될 수 없다.
_스코어링_ 단계에서 스케줄러는 목록에 남아있는 노드의 순위를 지정하여
가장 적합한 파드 배치를 선택한다. 스케줄러는 사용 중인 스코어링 규칙에 따라
이 점수를 기준으로 필터링에서 통과된 각 노드에 대해 점수를 지정한다.
마지막으로 kube-scheduler는 파드를 순위가 가장 높은 노드에 할당한다.
점수가 같은 노드가 두 개 이상인 경우 kube-scheduler는
이들 중 하나를 임의로 선택한다.
스케줄러의 필터링 및 스코어링 동작을 구성하는 데 지원되는 두 가지
방법이 있다.
1. [스케줄링 정책](/docs/reference/scheduling/policies)을 사용하면
필터링을 위한 _단정(Predicates)_ 및 스코어링을 위한 _우선순위(Priorities)_ 를 구성할 수 있다.
1. [스케줄링 프로파일](/docs/reference/scheduling/profiles)을 사용하면
`QueueSort`, `Filter`, `Score`, `Bind`, `Reserve`, `Permit` 등의
다른 스케줄링 단계를 구현하는 플러그인을 구성할 수 있다. 다른 프로파일을 실행하도록
kube-scheduler를 구성할 수도 있다.
{{% /capture %}}
{{% capture whatsnext %}}
* [스케줄러 성능 튜닝](/ko/docs/concepts/scheduling/scheduler-perf-tuning/)에 대해 읽기
* [파드 토폴로지 분배 제약 조건](/ko/docs/concepts/workloads/pods/pod-topology-spread-constraints/)에 대해 읽기
* kube-scheduler의 [레퍼런스 문서](/docs/reference/command-line-tools-reference/kube-scheduler/) 읽기
* [멀티 스케줄러 구성하기](/docs/tasks/administer-cluster/configure-multiple-schedulers/)에 대해 배우기
* [토폴로지 관리 정책](/docs/tasks/administer-cluster/topology-manager/)에 대해 배우기
* [파드 오버헤드](/docs/concepts/configuration/pod-overhead/)에 대해 배우기
{{% /capture %}}

View File

@ -71,6 +71,7 @@ spec:
- http:
paths:
- path: /testpath
pathType: Prefix
backend:
serviceName: test
servicePort: 80
@ -115,6 +116,84 @@ spec:
만약 인그레스 오브젝트의 HTTP 요청과 일치하는 호스트 또는 경로가 없으면, 트래픽은
기본 백엔드로 라우팅 된다.
### 경로(Path) 유형
인그레스의 각 경로에는 해당하는 경로 유형이 있다. 지원되는 세 가지의 경로
유형이 있다.
* _`ImplementationSpecific`_ (기본): 이 경로 유형의 일치 여부는 IngressClass에 따라
달라진다. 이를 구현할 때 별도 pathType으로 처리하거나, `Prefix` 또는 `Exact`
경로 유형과 같이 동일하게 처리할 수 있다.
* _`Exact`_: URL 경로의 대소문자를 엄격하게 일치시킨다.
* _`Prefix`_: URL 경로의 접두사를 `/` 를 기준으로 분리한 값과 일치시킨다.
일치는 대소문자를 구분하고,
요소별로 경로 요소에 대해 수행한다.
모든 _p_ 가 요청 경로의 요소별 접두사가 _p_ 인 경우
요청은 _p_ 경로에 일치한다.
{{< note >}}
경로의 마지막 요소가 요청 경로에 있는 마지막 요소의
하위 문자열인 경우에는 일치하지 않는다(예시:
`/foo/bar``/foo/bar/baz` 와 일치하지만, `/foo/barbaz` 는 일치하지 않는다).
{{< /note >}}
#### 다중 일치
경우에 따라 인그레스의 여러 경로가 요청과 일치할 수 있다.
이 경우 가장 긴 일치하는 경로가 우선하게 된다. 두 개의 경로가
여전히 동일하게 일치하는 경우 접두사(prefix) 경로 유형보다
정확한(exact) 경로 유형을 가진 경로가 사용 된다.
## 인그레스 클래스
인그레스는 서로 다른 컨트롤러에 의해 구현될 수 있으며, 종종 다른 구성으로
구현될 수 있다. 각 인그레스에서는 클래스를 구현해야하는 컨트롤러
이름을 포함하여 추가 구성이 포함된 IngressClass
리소스에 대한 참조 클래스를 지정해야 한다.
```yaml
apiVersion: networking.k8s.io/v1beta1
kind: IngressClass
metadata:
name: external-lb
spec:
controller: example.com/ingress-controller
parameters:
apiGroup: k8s.example.com/v1alpha
kind: IngressParameters
name: external-lb
```
IngressClass 리소스에는 선택적인 파라미터 필드가 있다. 이 클래스에 대한
추가 구성을 참조하는데 사용할 수 있다.
### 사용중단(Deprecated) 어노테이션
쿠버네티스 1.18에 IngressClass 리소스 및 `ingressClassName` 필드가 추가되기
전에 인그레스 클래스는 인그레스에서
`kubernetes.io/ingress.class` 어노테이션으로 지정되었다. 이 어노테이션은
공식적으로 정의된 것은 아니지만, 인그레스 컨트롤러에서 널리 지원되었었다.
인그레스의 최신 `ingressClassName` 필드는 해당 어노테이션을
대체하지만, 직접적으로 해당하는 것은 아니다. 어노테이션은 일반적으로
인그레스를 구현해야 하는 인그레스 컨트롤러의 이름을 참조하는 데 사용되었지만,
이 필드는 인그레스 컨트롤러의 이름을 포함하는 추가 인그레스 구성이
포함된 인그레스 클래스 리소스에 대한 참조이다.
### 기본 인그레스 클래스
특정 IngressClass를 클러스터의 기본 값으로 표시할 수 있다. IngressClass
리소스에서 `ingressclass.kubernetes.io/is-default-class``true`
설정하면 `ingressClassName` 필드가 지정되지 않은
새 인그레스에게 기본 IngressClass가 할당된다.
{{< caution >}}
클러스터의 기본값으로 표시된 IngressClass가 두 개 이상 있는 경우
어드미션 컨트롤러에서 `ingressClassName` 이 지정되지 않은
새 인그레스 오브젝트를 생성할 수 없다. 클러스터에서 최대 1개의 IngressClass가
기본값으로 표시하도록 해서 이 문제를 해결할 수 있다.
{{< /caution >}}
## 인그레스 유형들
### 단일 서비스 인그레스

View File

@ -202,6 +202,17 @@ API 리소스이다. 개념적으로 엔드포인트와 매우 유사하지만,
엔드포인트슬라이스는 [엔드포인트슬라이스](/ko/docs/concepts/services-networking/endpoint-slices/)에서
자세하게 설명된 추가적인 속성 및 기능을 제공한다.
### 애플리케이션 프로토콜
{{< feature-state for_k8s_version="v1.18" state="alpha" >}}
AppProtocol 필드는 각 서비스 포트에 사용될 애플리케이션 프로토콜을
지정하는 방법을 제공한다.
알파 기능으로 이 필드는 기본적으로 활성화되어 있지 않다. 이 필드를 사용하려면,
[기능 게이트](/docs/reference/command-line-tools-reference/feature-gates/)에서
`ServiceAppProtocol` 을 활성화해야 한다.
## 가상 IP와 서비스 프록시
쿠버네티스 클러스터의 모든 노드는 `kube-proxy`를 실행한다. `kube-proxy`

View File

@ -0,0 +1,131 @@
---
title: 동적 볼륨 프로비저닝
content_template: templates/concept
weight: 40
---
{{% capture overview %}}
동적 볼륨 프로비저닝을 통해 온-디맨드 방식으로 스토리지 볼륨을 생성할 수 있다.
동적 프로비저닝이 없으면 클러스터 관리자는 클라우드 또는 스토리지
공급자에게 수동으로 요청해서 새 스토리지 볼륨을 생성한 다음, 쿠버네티스에
표시하기 위해 [`PersistentVolume` 오브젝트](/ko/docs/concepts/storage/persistent-volumes/)를
생성해야 한다. 동적 프로비저닝 기능을 사용하면 클러스터 관리자가
스토리지를 사전 프로비저닝 할 필요가 없다. 대신 사용자가
스토리지를 요청하면 자동으로 프로비저닝 한다.
{{% /capture %}}
{{% capture body %}}
## 배경
동적 볼륨 프로비저닝의 구현은 `storage.k8s.io` API 그룹의 `StorageClass`
API 오브젝트를 기반으로 한다. 클러스터 관리자는 볼륨을 프로비전하는
*볼륨 플러그인* (프로비저너라고도 알려짐)과 프로비저닝시에 프로비저너에게
전달할 파라미터 집합을 지정하는 `StorageClass`
오브젝트를 필요한 만큼 정의할 수 있다.
클러스터 관리자는 클러스터 내에서 사용자 정의 파라미터 집합을
사용해서 여러 가지 유형의 스토리지 (같거나 다른 스토리지 시스템들)를
정의하고 노출시킬 수 있다. 또한 이 디자인을 통해 최종 사용자는
스토리지 프로비전 방식의 복잡성과 뉘앙스에 대해 걱정할 필요가 없다. 하지만,
여전히 여러 스토리지 옵션들을 선택할 수 있다.
스토리지 클래스에 대한 자세한 정보는
[여기](/docs/concepts/storage/storage-classes/)에서 찾을 수 있다.
## 동적 프로비저닝 활성화하기
동적 프로비저닝을 활성화하려면 클러스터 관리자가 사용자를 위해 하나 이상의 StorageClass
오브젝트를 사전 생성해야 한다.
StorageClass 오브젝트는 동적 프로비저닝이 호출될 때 사용할 프로비저너와
해당 프로비저너에게 전달할 파라미터를 정의한다.
StorageClass 오브젝트의 이름은 유효한
[DNS 서브도메인 이름](/ko/docs/concepts/overview/working-with-objects/names/#dns-서브도메인-이름)이어야 한다.
다음 매니페스트는 표준 디스크와 같은 퍼시스턴트 디스크를 프로비전하는
스토리지 클래스 "slow"를 만든다.
```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: slow
provisioner: kubernetes.io/gce-pd
parameters:
type: pd-standard
```
다음 매니페스트는 SSD와 같은 퍼시스턴트 디스크를 프로비전하는
스토리지 클래스 "fast"를 만든다.
```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast
provisioner: kubernetes.io/gce-pd
parameters:
type: pd-ssd
```
## 동적 프로비저닝 사용하기
사용자는 `PersistentVolumeClaim` 에 스토리지 클래스를 포함시켜 동적으로 프로비전된
스토리지를 요청한다. 쿠버네티스 v1.6 이전에는 `volume.beta.kubernetes.io/storage-class`
어노테이션을 통해 수행되었다. 그러나 이 어노테이션은
v1.6부터 더 이상 사용하지 않는다. 사용자는 이제 `PersistentVolumeClaim` 오브젝트의
`storageClassName` 필드를 사용할 수 있기에 대신하여 사용해야 한다. 이 필드의 값은
관리자가 구성한 `StorageClass` 의 이름과
일치해야 한다. ([아래](#동적-프로비저닝-활성화하기)를 참고)
예를 들어 “fast” 스토리지 클래스를 선택하려면 다음과
같은 `PersistentVolumeClaim` 을 생성한다.
```yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: claim1
spec:
accessModes:
- ReadWriteOnce
storageClassName: fast
resources:
requests:
storage: 30Gi
```
이 클레임의 결과로 SSD와 같은 퍼시스턴트 디스크가 자동으로
프로비전 된다. 클레임이 삭제되면 볼륨이 삭제된다.
## 기본 동작
스토리지 클래스가 지정되지 않은 경우 모든 클레임이 동적으로
프로비전이 되도록 클러스터에서 동적 프로비저닝을 활성화 할 수 있다. 클러스터 관리자는
이 방법으로 활성화 할 수 있다.
- 하나의 `StorageClass` 오브젝트를 *default* 로 표시한다.
- API 서버에서 [`DefaultStorageClass` 어드미션 컨트롤러](/docs/reference/access-authn-authz/admission-controllers/#defaultstorageclass)를
사용하도록 설정한다.
관리자는 `storageclass.kubernetes.io/is-default-class` 어노테이션을
추가해서 특정 `StorageClass` 를 기본으로 표시할 수 있다.
기본 `StorageClass` 가 클러스터에 존재하고 사용자가
`storageClassName` 를 지정하지 않은 `PersistentVolumeClaim`
작성하면, `DefaultStorageClass` 어드미션 컨트롤러가 디폴트
스토리지 클래스를 가리키는 `storageClassName` 필드를 자동으로 추가한다.
클러스터에는 최대 하나의 *default* 스토리지 클래스가 있을 수 있다. 그렇지 않은 경우
`storageClassName` 을 명시적으로 지정하지 않은 `PersistentVolumeClaim`
생성할 수 없다.
## 토폴로지 인식
[다중 영역](/ko/docs/setup/best-practices/multiple-zones/) 클러스터에서 파드는 한 지역 내
여러 영역에 걸쳐 분산될 수 있다. 파드가 예약된 영역에서 단일 영역 스토리지 백엔드를
프로비전 해야 한다. [볼륨 바인딩 모드](/docs/concepts/storage/storage-classes/#volume-binding-mode)를
설정해서 수행할 수 있다.
{{% /capture %}}

View File

@ -0,0 +1,757 @@
---
title: 퍼시스턴트 볼륨
feature:
title: 스토리지 오케스트레이션
description: >
로컬 스토리지, <a href="https://cloud.google.com/storage/">GCP</a><a href="https://aws.amazon.com/products/storage/">AWS</a>와 같은 퍼블릭 클라우드 공급자 또는 NFS, iSCSI, Gluster, Ceph, Cinder나 Flocker와 같은 네트워크 스토리지 시스템에서 원하는 스토리지 시스템을 자동으로 마운트한다.
content_template: templates/concept
weight: 20
---
{{% capture overview %}}
이 페이지는 쿠버네티스의 _퍼시스턴트 볼륨_ 의 현재 상태를 설명한다. [볼륨](/ko/docs/concepts/storage/volumes/)에 대해 익숙해지는 것을 추천한다.
{{% /capture %}}
{{% capture body %}}
## 소개
스토리지 관리는 컴퓨트 인스턴스 관리와는 별개의 문제다. 퍼시스턴트볼륨 서브시스템은 사용자 및 관리자에게 스토리지 사용 방법에서부터 스토리지가 제공되는 방법에 대한 세부 사항을 추상화하는 API를 제공한다. 이를 위해 퍼시스턴트볼륨 및 퍼시스턴트볼륨클레임이라는 두 가지 새로운 API 리소스를 소개한다.
퍼시스턴트볼륨(PV)은 관리자가 프로비저닝하거나 [스토리지 클래스](/docs/concepts/storage/storage-classes/)를 사용하여 동적으로 프로비저닝한 클러스터의 스토리지이다. 노드가 클러스터 리소스인 것처럼 PV는 클러스터 리소스이다. PV는 Volumes와 같은 볼륨 플러그인이지만, PV를 사용하는 개별 파드와는 별개의 라이프사이클을 가진다. 이 API 오브젝트는 NFS, iSCSI 또는 클라우드 공급자별 스토리지 시스템 등 스토리지 구현에 대한 세부 정보를 담아낸다.
퍼시스턴트볼륨클레임(PVC)은 사용자의 스토리지에 대한 요청이다. 파드와 비슷하다. 파드는 노드 리소스를 사용하고 PVC는 PV 리소스를 사용한다. 파드는 특정 수준의 리소스(CPU 및 메모리)를 요청할 수 있다. 클레임은 특정 크기 및 접근 모드를 요청할 수 있다(예: 한 번 읽기/쓰기 또는 여러 번 읽기 전용으로 마운트 할 수 있음).
퍼시스턴트볼륨클레임을 사용하면 사용자가 추상화된 스토리지 리소스를 사용할 수 있지만, 다른 문제들 때문에 성능과 같은 다양한 속성을 가진 퍼시스턴트볼륨이 필요한 경우가 일반적이다. 클러스터 관리자는 사용자에게 해당 볼륨의 구현 방법에 대한 세부 정보를 제공하지 않고 단순히 크기와 접근 모드와는 다른 방식으로 다양한 퍼시스턴트볼륨을 제공할 수 있어야 한다. 이러한 요구에는 _스토리지클래스_ 리소스가 있다.
[실습 예제와 함께 상세한 내용](/docs/tasks/configure-pod-container/configure-persistent-volume-storage/)을 참고하길 바란다.
## 볼륨과 클레임 라이프사이클
PV는 클러스터 리소스이다. PVC는 해당 리소스에 대한 요청이며 리소스에 대한 클레임 검사 역할을 한다. PV와 PVC 간의 상호 작용은 다음 라이프사이클을 따른다.
### 프로비저닝
PV를 프로비저닝 할 수 있는 두 가지 방법이 있다: 정적(static) 프로비저닝과 동적(dynamic) 프로비저닝
#### 정적 프로비저닝
클러스터 관리자는 여러 PV를 만든다. 클러스터 사용자가 사용할 수 있는 실제 스토리지의 세부 사항을 제공한다. 이 PV들은 쿠버네티스 API에 존재하며 사용할 수 있다.
#### 동적 프로비저닝
관리자가 생성한 정적 PV가 사용자의 퍼시스턴트볼륨클레임과 일치하지 않으면
클러스터는 PVC를 위해 특별히 볼륨을 동적으로 프로비저닝 하려고 시도할 수 있다.
이 프로비저닝은 스토리지클래스를 기반으로 한다. PVC는
[스토리지 클래스](/docs/concepts/storage/storage-classes/)를
요청해야 하며 관리자는 동적 프로비저닝이 발생하도록 해당 클래스를 생성하고 구성해야 한다.
`""` 클래스를 요청하는 클레임은 동적 프로비저닝을 효과적으로
비활성화한다.
스토리지 클래스를 기반으로 동적 스토리지 프로비저닝을 사용하려면 클러스터 관리자가 API 서버에서
`DefaultStorageClass` [어드미션 컨트롤러](/docs/reference/access-authn-authz/admission-controllers/#defaultstorageclass)를 사용하도록 설정해야 한다.
예를 들어 API 서버 컴포넌트의 `--enable-admission-plugins` 플래그에 대한 쉼표로 구분되어
정렬된 값들의 목록 중에 `DefaultStorageClass`가 포함되어 있는지 확인하여 설정할 수 있다.
API 서버 커맨드라인 플래그에 대한 자세한 정보는
[kube-apiserver](/docs/admin/kube-apiserver/) 문서를 확인하면 된다.
### 바인딩
사용자는 원하는 특정 용량의 스토리지와 특정 접근 모드로 퍼시스턴트볼륨클레임을 생성하거나 동적 프로비저닝의 경우 이미 생성한 상태다. 마스터의 컨트롤 루프는 새로운 PVC를 감시하고 일치하는 PV(가능한 경우)를 찾아 서로 바인딩한다. PV가 새 PVC에 대해 동적으로 프로비저닝된 경우 루프는 항상 해당 PV를 PVC에 바인딩한다. 그렇지 않으면 사용자는 항상 최소한 그들이 요청한 것을 얻지만 볼륨은 요청된 것을 초과할 수 있다. 일단 바인딩되면 퍼시스턴트볼륨클레임은 어떻게 바인딩되었는지 상관없이 배타적으로 바인딩된다. PVC 대 PV 바인딩은 일대일 매핑으로, 퍼시스턴트볼륨과 퍼시스턴트볼륨클레임 사이의 양방향 바인딩인 ClaimRef를 사용한다.
일치하는 볼륨이 없는 경우 클레임은 무한정 바인딩되지 않은 상태로 남아 있다. 일치하는 볼륨이 제공되면 클레임이 바인딩된다. 예를 들어 많은 수의 50Gi PV로 프로비저닝된 클러스터는 100Gi를 요청하는 PVC와 일치하지 않는다. 100Gi PV가 클러스터에 추가되면 PVC를 바인딩할 수 있다.
### 사용 중
파드는 클레임을 볼륨으로 사용한다. 클러스터는 클레임을 검사하여 바인딩된 볼륨을 찾고 해당 볼륨을 파드에 마운트한다. 여러 접근 모드를 지원하는 볼륨의 경우 사용자는 자신의 클레임을 파드에서 볼륨으로 사용할 때 원하는 접근 모드를 지정한다.
일단 사용자에게 클레임이 있고 그 클레임이 바인딩되면, 바인딩된 PV는 사용자가 필요로 하는 한 사용자에게 속한다. 사용자는 파드의 `volumes` 블록에 `persistentVolumeClaim`을 포함하여 파드를 스케줄링하고 클레임한 PV에 접근한다. 이에 대한 자세한 내용은 [볼륨으로 클레임하기](#볼륨으로-클레임하기)를 참고하길 바란다.
### 사용 중인 스토리지 오브젝트 ​​보호
사용 중인 스토리지 오브젝트 ​​보호 기능의 목적은 PVC에 바인딩된 파드와 퍼시스턴트볼륨(PV)이 사용 중인 퍼시스턴트볼륨클레임(PVC)을 시스템에서 삭제되지 않도록 하는 것이다. 삭제되면 이로 인해 데이터의 손실이 발생할 수 있기 때문이다.
{{< note >}}
PVC를 사용하는 파드 오브젝트가 존재하면 파드가 PVC를 사용하고 있는 상태이다.
{{< /note >}}
사용자가 파드에서 활발하게 사용 중인 PVC를 삭제하면 PVC는 즉시 삭제되지 않는다. PVC가 더 이상 파드에서 적극적으로 사용되지 않을 때까지 PVC 삭제가 연기된다. 또한 관리자가 PVC에 바인딩된 PV를 삭제하면 PV는 즉시 삭제되지 않는다. PV가 더 이상 PVC에 바인딩되지 않을 때까지 PV 삭제가 연기된다.
PVC의 상태가 `Terminating`이고 `Finalizers` 목록에 `kubernetes.io/pvc-protection`이 포함되어 있으면 PVC가 보호된 것으로 볼 수 있다.
```shell
kubectl describe pvc hostpath
Name: hostpath
Namespace: default
StorageClass: example-hostpath
Status: Terminating
Volume:
Labels: <none>
Annotations: volume.beta.kubernetes.io/storage-class=example-hostpath
volume.beta.kubernetes.io/storage-provisioner=example.com/hostpath
Finalizers: [kubernetes.io/pvc-protection]
...
```
마찬가지로 PV 상태가 `Terminating`이고 `Finalizers` 목록에 `kubernetes.io/pv-protection`이 포함되어 있으면 PV가 보호된 것으로 볼 수 있다.
```shell
kubectl describe pv task-pv-volume
Name: task-pv-volume
Labels: type=local
Annotations: <none>
Finalizers: [kubernetes.io/pv-protection]
StorageClass: standard
Status: Terminating
Claim:
Reclaim Policy: Delete
Access Modes: RWO
Capacity: 1Gi
Message:
Source:
Type: HostPath (bare host directory volume)
Path: /tmp/data
HostPathType:
Events: <none>
```
### 반환(Reclaiming)
사용자가 볼륨을 다 사용하고나면 리소스를 반환할 수 있는 API를 사용하여 PVC 오브젝트를 삭제할 수 있다. 퍼시스턴트볼륨의 반환 정책은 볼륨에서 클레임을 해제한 후 볼륨에 수행할 작업을 클러스터에 알려준다. 현재 볼륨에 대한 반환 정책은 Retain, Recycle, 그리고 Delete가 있다.
#### Retain(보존)
`Retain` 반환 정책은 리소스를 수동으로 반환할 수 있게 한다. 퍼시스턴트볼륨클레임이 삭제되면 퍼시스턴트볼륨은 여전히 존재하며 볼륨은 "릴리스 된" 것으로 간주된다. 그러나 이전 요청자의 데이터가 여전히 볼륨에 남아 있기 때문에 다른 요청에 대해서는 아직 사용할 수 없다. 관리자는 다음 단계에 따라 볼륨을 수동으로 반환할 수 있다.
1. 퍼시스턴트볼륨을 삭제한다. PV가 삭제된 후에도 외부 인프라(예: AWS EBS, GCE PD, Azure Disk 또는 Cinder 볼륨)의 관련 스토리지 자산이 존재한다.
1. 관련 스토리지 자산의 데이터를 수동으로 삭제한다.
1. 연결된 스토리지 자산을 수동으로 삭제하거나 동일한 스토리지 자산을 재사용하려는 경우 스토리지 자산 정의로 새 퍼시스턴트볼륨을 생성한다.
#### Delete(삭제)
`Delete` 반환 정책을 지원하는 볼륨 플러그인의 경우, 삭제는 쿠버네티스에서 퍼시스턴트볼륨 오브젝트와 외부 인프라(예: AWS EBS, GCE PD, Azure Disk 또는 Cinder 볼륨)의 관련 스토리지 자산을 모두 삭제한다. 동적으로 프로비저닝된 볼륨은 [스토리지클래스의 반환 정책](#반환-정책)을 상속하며 기본값은 `Delete`이다. 관리자는 사용자의 기대에 따라 스토리지클래스를 구성해야 한다. 그렇지 않으면 PV를 생성한 후 PV를 수정하거나 패치해야 한다. [퍼시스턴트볼륨의 반환 정책 변경](/docs/tasks/administer-cluster/change-pv-reclaim-policy/)을 참고하길 바란다.
#### Recycle(재활용)
{{< warning >}}
`Recycle` 반환 정책은 더 이상 사용하지 않는다. 대신 권장되는 방식은 동적 프로비저닝을 사용하는 것이다.
{{< /warning >}}
기본 볼륨 플러그인에서 지원하는 경우 `Recycle` 반환 정책은 볼륨에서 기본 스크럽(`rm -rf /thevolume/*`)을 수행하고 새 클레임에 다시 사용할 수 있도록 한다.
그러나 관리자는 [여기](/docs/admin/kube-controller-manager/)에 설명된대로 쿠버네티스 컨트롤러 관리자 커맨드라인 인자(command line arguments)를 사용하여 사용자 정의 재활용 파드 템플릿을 구성할 수 있다. 사용자 정의 재활용 파드 템플릿에는 아래 예와 같이 `volumes` 명세가 포함되어야 한다.
```yaml
apiVersion: v1
kind: Pod
metadata:
name: pv-recycler
namespace: default
spec:
restartPolicy: Never
volumes:
- name: vol
hostPath:
path: /any/path/it/will/be/replaced
containers:
- name: pv-recycler
image: "k8s.gcr.io/busybox"
command: ["/bin/sh", "-c", "test -e /scrub && rm -rf /scrub/..?* /scrub/.[!.]* /scrub/* && test -z \"$(ls -A /scrub)\" || exit 1"]
volumeMounts:
- name: vol
mountPath: /scrub
```
그러나 `volumes` 부분의 사용자 정의 재활용 파드 템플릿에 지정된 특정 경로는 재활용되는 볼륨의 특정 경로로 바뀐다.
### 퍼시스턴트 볼륨 클레임 확장
{{< feature-state for_k8s_version="v1.11" state="beta" >}}
이제 퍼시스턴트볼륨클레임(PVC) 확장 지원이 기본적으로 활성화되어 있다. 다음 유형의
볼륨을 확장할 수 있다.
* gcePersistentDisk
* awsElasticBlockStore
* Cinder
* glusterfs
* rbd
* Azure File
* Azure Disk
* Portworx
* FlexVolumes
* CSI
스토리지 클래스의 `allowVolumeExpansion` 필드가 true로 설정된 경우에만 PVC를 확장할 수 있다.
``` yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gluster-vol-default
provisioner: kubernetes.io/glusterfs
parameters:
resturl: "http://192.168.10.100:8080"
restuser: ""
secretNamespace: ""
secretName: ""
allowVolumeExpansion: true
```
PVC에 대해 더 큰 볼륨을 요청하려면 PVC 오브젝트를 수정하여 더 큰 용량을
지정한다. 이는 기본 퍼시스턴트볼륨을 지원하는 볼륨의 확장을 트리거한다. 클레임을 만족시키기 위해
새로운 퍼시스턴트볼륨이 생성되지 않고 기존 볼륨의 크기가 조정된다.
#### CSI 볼륨 확장
{{< feature-state for_k8s_version="v1.16" state="beta" >}}
CSI 볼륨 확장 지원은 기본적으로 활성화되어 있지만 볼륨 확장을 지원하려면 특정 CSI 드라이버도 필요하다. 자세한 내용은 특정 CSI 드라이버 문서를 참고한다.
#### 파일시스템을 포함하는 볼륨 크기 조정
파일시스템이 XFS, Ext3 또는 Ext4 인 경우에만 파일시스템을 포함하는 볼륨의 크기를 조정할 수 있다.
볼륨에 파일시스템이 포함된 경우 새 파드가 `ReadWrite` 모드에서 퍼시스턴트볼륨클레임을 사용하는
경우에만 파일시스템의 크기가 조정된다. 파일시스템 확장은 파드가 시작되거나
파드가 실행 중이고 기본 파일시스템이 온라인 확장을 지원할 때 수행된다.
FlexVolumes는 `RequiresFSResize` 기능으로 드라이버가 `true`로 설정된 경우 크기 조정을 허용한다.
FlexVolume은 파드 재시작 시 크기를 조정할 수 있다.
#### 사용 중인 퍼시스턴트볼륨클레임 크기 조정
{{< feature-state for_k8s_version="v1.15" state="beta" >}}
{{< note >}}
사용 중인 PVC 확장은 쿠버네티스 1.15 이후 버전에서는 베타로, 1.11 이후 버전에서는 알파로 제공된다. `ExpandInUsePersistentVolumes` 기능을 사용하도록 설정해야 한다. 베타 기능의 경우 여러 클러스터에서 자동으로 적용된다. 자세한 내용은 [기능 게이트](/docs/reference/command-line-tools-reference/feature-gates/) 문서를 참고한다.
{{< /note >}}
이 경우 기존 PVC를 사용하는 파드 또는 디플로이먼트를 삭제하고 다시 만들 필요가 없다.
파일시스템이 확장되자마자 사용 중인 PVC가 파드에서 자동으로 사용 가능하다.
이 기능은 파드나 디플로이먼트에서 사용하지 않는 PVC에는 영향을 미치지 않는다. 확장을 완료하기 전에
PVC를 사용하는 파드를 만들어야 한다.
다른 볼륨 유형과 비슷하게 FlexVolume 볼륨도 파드에서 사용 중인 경우 확장할 수 있다.
{{< note >}}
FlexVolume의 크기 조정은 기본 드라이버가 크기 조정을 지원하는 경우에만 가능하다.
{{< /note >}}
{{< note >}}
EBS 볼륨 확장은 시간이 많이 걸리는 작업이다. 또한 6시간마다 한 번의 수정을 할 수 있는 볼륨별 쿼터(quota)가 있다.
{{< /note >}}
## 퍼시스턴트 볼륨의 유형
퍼시스턴트볼륨 유형은 플러그인으로 구현된다. 쿠버네티스는 현재 다음의 플러그인을 지원한다.
* GCEPersistentDisk
* AWSElasticBlockStore
* AzureFile
* AzureDisk
* CSI
* FC (파이버 채널)
* FlexVolume
* Flocker
* NFS
* iSCSI
* RBD (Ceph Block Device)
* CephFS
* Cinder (OpenStack 블록 스토리지)
* Glusterfs
* VsphereVolume
* Quobyte Volumes
* HostPath (단일 노드 테스트 전용 로컬 스토리지는 어떤 방식으로도 지원되지 않으며 다중-노드 클러스터에서 작동하지 않음)
* Portworx Volumes
* ScaleIO Volumes
* StorageOS
## 퍼시스턴트 볼륨
각 PV에는 스펙과 상태(볼륨의 명세와 상태)가 포함된다.
퍼시스턴트볼륨 오브젝트의 이름은 유효한
[DNS 서브도메인 이름](/ko/docs/concepts/overview/working-with-objects/names/#dns-서브도메인-이름들)이어야 한다.
```yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0003
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: slow
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: /tmp
server: 172.17.0.2
```
{{< note >}}
클러스터 내에서 퍼시스턴트볼륨을 사용하려면 볼륨 유형과 관련된 헬퍼(Helper) 프로그램이 필요할 수 있다. 이 예에서 퍼시스턴트볼륨은 NFS 유형이며 NFS 파일시스템 마운트를 지원하려면 헬퍼 프로그램인 /sbin/mount.nfs가 필요하다.
{{< /note >}}
### 용량
일반적으로 PV는 특정 저장 용량을 가진다. 이것은 PV의 `capacity` 속성을 사용하여 설정된다. `capacity`가 사용하는 단위를 이해하려면 쿠버네티스 [리소스 모델](https://git.k8s.io/community/contributors/design-proposals/scheduling/resources.md)을 참고한다.
현재 스토리지 용량 크기는 설정하거나 요청할 수 있는 유일한 리소스이다. 향후 속성에 IOPS, 처리량 등이 포함될 수 있다.
### 볼륨 모드
{{< feature-state for_k8s_version="v1.18" state="stable" >}}
쿠버네티스는 퍼시스턴트볼륨의 두 가지 `volumeModes``Filesystem``Block`을 지원한다.
`volumeMode`는 선택적 API 파라미터이다.
`Filesystem``volumeMode` 파라미터가 생략될 때 사용되는 기본 모드이다.
`volumeMode: Filesystem`이 있는 볼륨은 파드의 디렉터리에 *마운트* 된다. 볼륨이 장치에
의해 지원되고 그 장치가 비어 있으면 쿠버네티스는 장치를
처음 마운트하기 전에 장치에 파일시스템을 만든다.
볼륨을 원시 블록 장치로 사용하려면 `volumeMode`의 값을 `Block`으로 설정할 수 있다.
이러한 볼륨은 파일시스템이 없는 블록 장치로 파드에 제공된다.
이 모드는 파드와 볼륨 사이에 파일시스템 계층 없이도 볼륨에 액세스하는
가장 빠른 방법을 파드에 제공하는 데 유용하다. 반면에 파드에서 실행되는 애플리케이션은
원시 블록 장치를 처리하는 방법을 알아야 한다.
파드에서 `volumeMode: Block`으로 볼륨을 사용하는 방법에 대한 예는
[원시 블록 볼륨 지원](/ko/docs/concepts/storage/persistent-volumes/#원시-블록-볼륨-지원)를 참조하십시오.
### 접근 모드
리소스 제공자가 지원하는 방식으로 호스트에 퍼시스턴트볼륨을 마운트할 수 있다. 아래 표에서 볼 수 있듯이 제공자들은 서로 다른 기능을 가지며 각 PV의 접근 모드는 해당 볼륨에서 지원하는 특정 모드로 설정된다. 예를 들어 NFS는 다중 읽기/쓰기 클라이언트를 지원할 수 있지만 특정 NFS PV는 서버에서 읽기 전용으로 export할 수 있다. 각 PV는 특정 PV의 기능을 설명하는 자체 접근 모드 셋을 갖는다.
접근 모드는 다음과 같다.
* ReadWriteOnce -- 하나의 노드에서 볼륨을 읽기-쓰기로 마운트할 수 있다
* ReadOnlyMany -- 여러 노드에서 볼륨을 읽기 전용으로 마운트할 수 있다
* ReadWriteMany -- 여러 노드에서 볼륨을 읽기-쓰기로 마운트할 수 있다
CLI에서 접근 모드는 다음과 같이 약어로 표시된다.
* RWO - ReadWriteOnce
* ROX - ReadOnlyMany
* RWX - ReadWriteMany
> __중요!__ 볼륨이 여러 접근 모드를 지원하더라도 한 번에 하나의 접근 모드를 사용하여 마운트할 수 있다. 예를 들어 GCEPersistentDisk는 하나의 노드가 ReadWriteOnce로 마운트하거나 여러 노드가 ReadOnlyMany로 마운트할 수 있지만 동시에는 불가능하다.
| Volume Plugin | ReadWriteOnce | ReadOnlyMany | ReadWriteMany|
| :--- | :---: | :---: | :---: |
| AWSElasticBlockStore | &#x2713; | - | - |
| AzureFile | &#x2713; | &#x2713; | &#x2713; |
| AzureDisk | &#x2713; | - | - |
| CephFS | &#x2713; | &#x2713; | &#x2713; |
| Cinder | &#x2713; | - | - |
| CSI | 드라이버에 따라 다름 | 드라이버에 따라 다름 | 드라이버에 따라 다름 |
| FC | &#x2713; | &#x2713; | - |
| FlexVolume | &#x2713; | &#x2713; | 드라이버에 따라 다름 |
| Flocker | &#x2713; | - | - |
| GCEPersistentDisk | &#x2713; | &#x2713; | - |
| Glusterfs | &#x2713; | &#x2713; | &#x2713; |
| HostPath | &#x2713; | - | - |
| iSCSI | &#x2713; | &#x2713; | - |
| Quobyte | &#x2713; | &#x2713; | &#x2713; |
| NFS | &#x2713; | &#x2713; | &#x2713; |
| RBD | &#x2713; | &#x2713; | - |
| VsphereVolume | &#x2713; | - | - (파드가 병치될(collocated) 때 작동) |
| PortworxVolume | &#x2713; | - | &#x2713; |
| ScaleIO | &#x2713; | &#x2713; | - |
| StorageOS | &#x2713; | - | - |
### 클래스
PV는 `storageClassName` 속성을
[스토리지클래스](/docs/concepts/storage/storage-classes/)의
이름으로 설정하여 지정하는 클래스를 가질 수 있다.
특정 클래스의 PV는 해당 클래스를 요청하는 PVC에만 바인딩될 수 있다.
`storageClassName`이 없는 PV에는 클래스가 없으며 특정 클래스를 요청하지 않는 PVC에만
바인딩할 수 있다.
이전에는 `volume.beta.kubernetes.io/storage-class` 어노테이션이
`storageClassName` 속성 대신 사용되었다. 이 어노테이션은 아직까지는 사용할 수 있지만,
향후 쿠버네티스 릴리스에서 완전히 사용 중단(deprecated)이 될 예정이다.
### 반환 정책
현재 반환 정책은 다음과 같다.
* Retain(보존) -- 수동 반환
* Recycle(재활용) -- 기본 스크럽 (`rm -rf /thevolume/*`)
* Delete(삭제) -- AWS EBS, GCE PD, Azure Disk 또는 OpenStack Cinder 볼륨과 같은 관련 스토리지 자산이 삭제됨
현재 NFS 및 HostPath만 재활용을 지원한다. AWS EBS, GCE PD, Azure Disk 및 Cinder 볼륨은 삭제를 지원한다.
### 마운트 옵션
쿠버네티스 관리자는 퍼시스턴트 볼륨이 노드에 마운트될 때 추가 마운트 옵션을 지정할 수 있다.
{{< note >}}
모든 퍼시스턴트 볼륨 유형이 마운트 옵션을 지원하는 것은 아니다.
{{< /note >}}
다음 볼륨 유형은 마운트 옵션을 지원한다.
* AWSElasticBlockStore
* AzureDisk
* AzureFile
* CephFS
* Cinder (OpenStack 블록 스토리지)
* GCEPersistentDisk
* Glusterfs
* NFS
* Quobyte Volumes
* RBD (Ceph Block Device)
* StorageOS
* VsphereVolume
* iSCSI
마운트 옵션의 유효성이 검사되지 않으므로 마운트 옵션이 유효하지 않으면 마운트가 실패한다.
이전에는 `mountOptions` 속성 대신 `volume.beta.kubernetes.io/mount-options` 어노테이션이
사용되었다. 이 어노테이션은 아직까지는 사용할 수 있지만,
향후 쿠버네티스 릴리스에서 완전히 사용 중단(deprecated)이 될 예정이다.
### 노드 어피니티(affinity)
{{< note >}}
대부분의 볼륨 유형의 경우 이 필드를 설정할 필요가 없다. [AWS EBS](/ko/docs/concepts/storage/volumes/#awselasticblockstore), [GCE PD](/ko/docs/concepts/storage/volumes/#gcepersistentdisk) 및 [Azure Disk](/ko/docs/concepts/storage/volumes/#azuredisk) 볼륨 블록 유형에 자동으로 채워진다. [로컬](/ko/docs/concepts/storage/volumes/#local) 볼륨에 대해서는 이를 명시적으로 설정해야 한다.
{{< /note >}}
PV는 [노드 어피니티](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#volumenodeaffinity-v1-core)를 지정하여 이 볼륨에 접근할 수 있는 노드를 제한하는 제약 조건을 정의할 수 있다. PV를 사용하는 파드는 노드 어피니티에 의해 선택된 노드로만 스케줄링된다.
### 단계(Phase)
볼륨은 다음 단계 중 하나이다.
* Available(사용 가능) - 아직 클레임에 바인딩되지 않은 사용할 수 있는 리소스
* Bound(바인딩) - 볼륨이 클레임에 바인딩됨
* Released(릴리스) - 클레임이 삭제되었지만 클러스터에서 아직 리소스를 반환하지 않음
* Failed(실패) - 볼륨이 자동 반환에 실패함
CLI는 PV에 바인딩된 PVC의 이름을 표시한다.
## 퍼시스턴트볼륨클레임
각 PVC에는 스펙과 상태(클레임의 명세와 상태)가 포함된다.
퍼시스턴트볼륨클레임 오브젝트의 이름은 유효한
[DNS 서브도메인 이름](/ko/docs/concepts/overview/working-with-objects/names/#dns-서브도메인-이름들)이어야
한다.
```yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 8Gi
storageClassName: slow
selector:
matchLabels:
release: "stable"
matchExpressions:
- {key: environment, operator: In, values: [dev]}
```
### 접근 모드
클레임은 특정 접근 모드로 저장소를 요청할 때 볼륨과 동일한 규칙을 사용한다.
### 볼륨 모드
클레임은 볼륨과 동일한 규칙을 사용하여 파일시스템 또는 블록 장치로 볼륨을 사용함을 나타낸다.
### 리소스
파드처럼 클레임은 특정 수량의 리소스를 요청할 수 있다. 이 경우는 스토리지에 대한 요청이다. 동일한 [리소스 모델](https://git.k8s.io/community/contributors/design-proposals/scheduling/resources.md)이 볼륨과 클레임 모두에 적용된다.
### 셀렉터
클레임은 볼륨 셋을 추가로 필터링하기 위해 [레이블 셀렉터](/ko/docs/concepts/overview/working-with-objects/labels/#레이블-셀렉터)를 지정할 수 있다. 레이블이 셀렉터와 일치하는 볼륨만 클레임에 바인딩할 수 있다. 셀렉터는 두 개의 필드로 구성될 수 있다.
* `matchLabels` - 볼륨에 이 값의 레이블이 있어야함
* `matchExpressions` - 키, 값의 목록, 그리고 키와 값에 관련된 연산자를 지정하여 만든 요구 사항 목록. 유효한 연산자에는 In, NotIn, Exists 및 DoesNotExist가 있다.
`matchLabels``matchExpressions`의 모든 요구 사항이 AND 조건이다. 일치하려면 모두 충족해야 한다.
### 클래스
클레임은 `storageClassName` 속성을 사용하여
[스토리지클래스](/docs/concepts/storage/storage-classes/)의 이름을 지정하여
특정 클래스를 요청할 수 있다.
요청된 클래스의 PV(PVC와 동일한 `storageClassName`을 갖는 PV)만 PVC에
바인딩될 수 있다.
PVC는 반드시 클래스를 요청할 필요는 없다. `storageClassName``""`로 설정된
PVC는 항상 클래스가 없는 PV를 요청하는 것으로 해석되므로
클래스가 없는 PV(어노테이션이 없거나 `""`와 같은 하나의 셋)에만 바인딩될 수
있다. `storageClassName`이 없는 PVC는
[`DefaultStorageClass` 어드미션 플러그인](/docs/reference/access-authn-authz/admission-controllers/#defaultstorageclass)이
켜져 있는지 여부에 따라 동일하지 않으며
클러스터에 따라 다르게 처리된다.
* 어드미션 플러그인이 켜져 있으면 관리자가 기본 스토리지클래스를 지정할 수 있다.
`storageClassName`이 없는 모든 PVC는 해당 기본값의 PV에만 바인딩할 수 있다. 기본
스토리지클래스 지정은 스토리지클래스 오브젝트에서 어노테이션
`storageclass.kubernetes.io/is-default-class``true`
설정하여 수행된다. 관리자가 기본값을 지정하지 않으면 어드미션 플러그인이 꺼져 있는 것처럼
클러스터가 PVC 생성에 응답한다. 둘 이상의 기본값이 지정된 경우 어드미션
플러그인은 모든 PVC 생성을
금지한다.
* 어드미션 플러그인이 꺼져 있으면 기본 스토리지클래스에 대한 기본값 자체가 없다.
`storageClassName`이 없는 모든 PVC는 클래스가 없는 PV에만 바인딩할 수 있다. 이 경우
`storageClassName`이 없는 PVC는 `storageClassName``""`로 설정된 PVC와
같은 방식으로 처리된다.
설치 방법에 따라 설치 중에 애드온 관리자가 기본 스토리지클래스를 쿠버네티스 클러스터에
배포할 수 있다.
PVC가 스토리지클래스를 요청하는 것 외에도 `selector`를 지정하면 요구 사항들이
AND 조건으로 동작한다. 요청된 클래스와 요청된 레이블이 있는 PV만 PVC에
바인딩될 수 있다.
{{< note >}}
현재 비어 있지 않은 `selector`가 있는 PVC에는 PV를 동적으로 프로비저닝할 수 없다.
{{< /note >}}
이전에는 `volume.beta.kubernetes.io/storage-class` 어노테이션이 `storageClassName`
속성 대신 사용되었다. 이 어노테이션은 아직까지는 사용할 수 있지만,
향후 쿠버네티스 릴리스에서는 지원되지 않는다.
## 볼륨으로 클레임하기
클레임을 볼륨으로 사용해서 파드가 스토리지에 접근한다. 클레임은 클레임을 사용하는 파드와 동일한 네임스페이스에 있어야 한다. 클러스터는 파드의 네임스페이스에서 클레임을 찾고 이를 사용하여 클레임과 관련된 퍼시스턴트볼륨을 얻는다. 그런 다음 볼륨이 호스트와 파드에 마운트된다.
```yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: myfrontend
image: nginx
volumeMounts:
- mountPath: "/var/www/html"
name: mypd
volumes:
- name: mypd
persistentVolumeClaim:
claimName: myclaim
```
### 네임스페이스에 대한 참고 사항
퍼시스턴트볼륨 바인딩은 배타적이며, 퍼시스턴트볼륨클레임은 네임스페이스 오브젝트이므로 "다중" 모드(`ROX`, `RWX`)를 사용한 클레임은 하나의 네임스페이스 내에서만 가능하다.
## 원시 블록 볼륨 지원
{{< feature-state for_k8s_version="v1.18" state="stable" >}}
다음 볼륨 플러그인에 해당되는 경우 동적 프로비저닝을 포함하여 원시 블록 볼륨을
지원한다.
* AWSElasticBlockStore
* AzureDisk
* CSI
* FC (파이버 채널)
* GCEPersistentDisk
* iSCSI
* Local volume
* OpenStack Cinder
* RBD (Ceph Block Device)
* VsphereVolume
### 원시 블록 볼륨을 사용하는 퍼시스턴트볼륨 {#persistent-volume-using-a-raw-block-volume}
```yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: block-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
volumeMode: Block
persistentVolumeReclaimPolicy: Retain
fc:
targetWWNs: ["50060e801049cfd1"]
lun: 0
readOnly: false
```
### 원시 블록 볼륨을 요청하는 퍼시스턴트볼륨클레임 {#persistent-volume-claim-requesting-a-raw-block-volume}
```yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: block-pvc
spec:
accessModes:
- ReadWriteOnce
volumeMode: Block
resources:
requests:
storage: 10Gi
```
### 컨테이너에 원시 블록 장치 경로를 추가하는 파드 명세
```yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-with-block-volume
spec:
containers:
- name: fc-container
image: fedora:26
command: ["/bin/sh", "-c"]
args: [ "tail -f /dev/null" ]
volumeDevices:
- name: data
devicePath: /dev/xvda
volumes:
- name: data
persistentVolumeClaim:
claimName: block-pvc
```
{{< note >}}
파드에 대한 원시 블록 장치를 추가할 때 마운트 경로 대신 컨테이너에 장치 경로를 지정한다.
{{< /note >}}
### 블록 볼륨 바인딩
사용자가 퍼시스턴트볼륨클레임 스펙에서 `volumeMode` 필드를 사용하여 이를 나타내는 원시 블록 볼륨을 요청하는 경우 바인딩 규칙은 스펙의 일부분으로 이 모드를 고려하지 않은 이전 릴리스에 비해 약간 다르다.
사용자와 관리자가 원시 블록 장치를 요청하기 위해 지정할 수 있는 가능한 조합의 표가 아래 나열되어 있다. 이 테이블은 볼륨이 바인딩되는지 여부를 나타낸다.
정적 프로비저닝된 볼륨에 대한 볼륨 바인딩 매트릭스이다.
| PV volumeMode | PVC volumeMode | Result |
| --------------|:---------------:| ----------------:|
| 지정되지 않음 | 지정되지 않음 | BIND |
| 지정되지 않음 | Block | NO BIND |
| 지정되지 않음 | Filesystem | BIND |
| Block | 지정되지 않음 | NO BIND |
| Block | Block | BIND |
| Block | Filesystem | NO BIND |
| Filesystem | Filesystem | BIND |
| Filesystem | Block | NO BIND |
| Filesystem | 지정되지 않음 | BIND |
{{< note >}}
알파 릴리스에서는 정적으로 프로비저닝된 볼륨만 지원된다. 관리자는 원시 블록 장치로 작업할 때 이러한 값을 고려해야 한다.
{{< /note >}}
## 볼륨 스냅샷 및 스냅샷 지원에서 볼륨 복원
{{< feature-state for_k8s_version="v1.17" state="beta" >}}
CSI 볼륨 플러그인만 지원하도록 볼륨 스냅샷 기능이 추가되었다. 자세한 내용은 [볼륨 스냅샷](/docs/concepts/storage/volume-snapshots/)을 참고한다.
볼륨 스냅샷 데이터 소스에서 볼륨 복원을 지원하려면 apiserver와 controller-manager에서
`VolumeSnapshotDataSource` 기능 게이트를 활성화한다.
### 볼륨 스냅샷에서 퍼시스턴트볼륨클레임 생성 {#create-persistent-volume-claim-from-volume-snapshot}
```yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: restore-pvc
spec:
storageClassName: csi-hostpath-sc
dataSource:
name: new-snapshot-test
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
```
## 볼륨 복제
[볼륨 복제](/docs/concepts/storage/volume-pvc-datasource/)는 CSI 볼륨 플러그인만 사용할 수 있다.
### 기존 pvc에서 퍼시스턴트볼륨클레임 생성 {#create-persistent-volume-claim-from-an-existing-pvc}
```yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: cloned-pvc
spec:
storageClassName: my-csi-plugin
dataSource:
name: existing-src-pvc-name
kind: PersistentVolumeClaim
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
```
## 포터블 구성 작성
광범위한 클러스터에서 실행되고 퍼시스턴트 스토리지가 필요한
구성 템플릿 또는 예제를 작성하는 경우 다음 패턴을 사용하는 것이 좋다.
- 구성 번들(디플로이먼트, 컨피그맵 등)에 퍼시스턴트볼륨클레임
오브젝트를 포함시킨다.
- 구성을 인스턴스화 하는 사용자에게 퍼시스턴트볼륨을 생성할 권한이 없을 수 있으므로
퍼시스턴트볼륨 오브젝트를 구성에 포함하지 않는다.
- 템플릿을 인스턴스화 할 때 스토리지 클래스 이름을 제공하는 옵션을
사용자에게 제공한다.
- 사용자가 스토리지 클래스 이름을 제공하는 경우 해당 값을
`permanentVolumeClaim.storageClassName` 필드에 입력한다.
클러스터에서 관리자가 스토리지클래스를 활성화한 경우
PVC가 올바른 스토리지 클래스와 일치하게 된다.
- 사용자가 스토리지 클래스 이름을 제공하지 않으면
`permanentVolumeClaim.storageClassName` 필드를 nil로 남겨둔다.
그러면 클러스터에 기본 스토리지클래스가 있는 사용자에 대해 PV가 자동으로 프로비저닝된다.
많은 클러스터 환경에 기본 스토리지클래스가 설치되어 있거나 관리자가
고유한 기본 스토리지클래스를 생성할 수 있다.
- 도구(tooling)에서 일정 시간이 지나도 바인딩되지 않는 PVC를 관찰하여 사용자에게
노출시킨다. 이는 클러스터가 동적 스토리지를 지원하지
않거나(이 경우 사용자가 일치하는 PV를 생성해야 함),
클러스터에 스토리지 시스템이 없음을 나타낸다(이 경우
사용자는 PVC가 필요한 구성을 배포할 수 없음).
{{% /capture %}}
{{% capture whatsnext %}}
* [퍼시스턴트볼륨 생성](/docs/tasks/configure-pod-container/configure-persistent-volume-storage/#create-a-persistentvolume)에 대해 자세히 알아보기
* [퍼시스턴트볼륨클레임 생성](/docs/tasks/configure-pod-container/configure-persistent-volume-storage/#create-a-persistentvolumeclaim)에 대해 자세히 알아보기
* [퍼시스턴트 스토리지 설계 문서](https://git.k8s.io/community/contributors/design-proposals/storage/persistent-storage.md) 읽기
### 참고
* [퍼시스턴트볼륨](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#persistentvolume-v1-core)
* [PersistentVolumeSpec](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#persistentvolumespec-v1-core)
* [퍼시스턴트볼륨클레임](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#persistentvolumeclaim-v1-core)
* [PersistentVolumeClaimSpec](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#persistentvolumeclaimspec-v1-core)
{{% /capture %}}

View File

@ -6,7 +6,6 @@ weight: 30
{{% capture overview %}}
{{< feature-state for_k8s_version="v1.16" state="beta" >}}
이 문서에서는 쿠버네티스의 기존 CSI 볼륨 복제의 개념을 설명한다. [볼륨]
(/ko/docs/concepts/storage/volumes)을 숙지하는 것을 추천한다.
@ -32,6 +31,7 @@ weight: 30
* 복제는 동일한 스토리지 클래스 내에서만 지원된다.
- 대상 볼륨은 소스와 동일한 스토리지 클래스여야 한다.
- 기본 스토리지 클래스를 사용할 수 있으며, 사양에 storageClassName을 생략할 수 있다.
* 동일한 VolumeMode 설정을 사용하는 두 볼륨에만 복제를 수행할 수 있다(블록 모드 볼륨을 요청하는 경우에는 반드시 소스도 블록 모드여야 한다).
## 프로비저닝

View File

@ -1327,19 +1327,13 @@ CSI 호환 볼륨 드라이버가 쿠버네티스 클러스터에 배포되면
#### CSI 원시(raw) 블록 볼륨 지원
{{< feature-state for_k8s_version="v1.14" state="beta" >}}
{{< feature-state for_k8s_version="v1.18" state="stable" >}}
1.11 버전부터 CSI는 이전 버전의 쿠버네티스에서 도입된 원시
블록 볼륨 기능에 의존하는 원시 블록 볼륨에 대한 지원을
도입했다. 이 기능을 사용하면 외부 CSI 드라이버가 있는 벤더들이 쿠버네티스
워크로드에서 원시 블록 볼륨 지원을 구현할 수 있다.
외부 CSI 드라이버가 있는 벤더들은 쿠버네티스 워크로드에서 원시(raw) 블록 볼륨
지원을 구현할 수 있다.
CSI 블록 볼륨은 기능 게이트로 지원하지만, 기본적으로 활성화되어있다. 이
기능을 위해 활성화 되어야하는 두개의 기능 게이트는 `BlockVolume`
`CSIBlockVolume` 이다.
[원시 블록 볼륨 지원으로 PV/PVC 설정](/docs/concepts/storage/persistent-volumes/#raw-block-volume-support)
방법을 알아본다.
CSI 설정 변경 없이 평소와 같이
[원시 블록 볼륨 지원으로 PV/PVC 설정](/docs/concepts/storage/persistent-volumes/#raw-block-volume-support)을 할 수 있다.
#### CSI 임시(ephemeral) 볼륨

View File

@ -14,12 +14,7 @@ _크론 잡은_ 시간 기반의 일정에 따라 [잡](/ko/docs/concepts/worklo
{{< caution >}}
모든 **크론잡** `일정:` 시간은 {{< glossary_tooltip term_id="kube-controller-manager" text="kube-controller-manager" >}}
의 시간대를 기준으로 한다.
컨트롤 플레인이 파드 또는 베어 컨테이너에서 kube-controller-manager를
실행하는 경우 kube-controller-manager 컨테이너의 설정된 시간대는 크론 잡 컨트롤러가
사용하는 시간대로 설정한다.
모든 **크론잡** `일정:` 시간은 UTC로 표시된다.
{{< /caution >}}
크론잡 리소스에 대한 매니페스트를 생성할때에는 제공하는 이름이

View File

@ -61,7 +61,7 @@ _디플로이먼트_ 는 [파드](/ko/docs/concepts/workloads/pods/pod/)와
* `template` 필드에는 다음 하위 필드가 포함되어있다.
* 파드는 `labels` 필드를 사용해서 `app: nginx` 이라는 레이블을 붙인다.
* 파드 템플릿의 사양 또는 `.template.spec` 필드는
파드가 [도커 허브](https://hub.docker.com/)의 `nginx` 1.7.9 버전 이미지를 실행하는
파드가 [도커 허브](https://hub.docker.com/)의 `nginx` 1.14.2 버전 이미지를 실행하는
`nginx` 컨테이너 1개를 실행하는 것을 나타낸다.
* 컨테이너 1개를 생성하고, `name` 필드를 사용해서 `nginx` 이름을 붙인다.
@ -151,15 +151,15 @@ _디플로이먼트_ 는 [파드](/ko/docs/concepts/workloads/pods/pod/)와
다음 단계에 따라 디플로이먼트를 업데이트한다.
1. `nginx:1.7.9` 이미지 대신 `nginx:1.9.1` 이미지를 사용하도록 nginx 파드를 업데이트 한다.
1. `nginx:1.14.2` 이미지 대신 `nginx:1.16.1` 이미지를 사용하도록 nginx 파드를 업데이트 한다.
```shell
kubectl --record deployment.apps/nginx-deployment set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1
kubectl --record deployment.apps/nginx-deployment set image deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1
```
또는 간단하게 다음의 명령어를 사용한다.
```shell
kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1 --record
kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1 --record
```
이와 유사하게 출력된다.
@ -167,7 +167,7 @@ _디플로이먼트_ 는 [파드](/ko/docs/concepts/workloads/pods/pod/)와
deployment.apps/nginx-deployment image updated
```
대안으로 디플로이먼트를 `edit` 해서 `.spec.template.spec.containers[0].image``nginx:1.7.9` 에서 `nginx:1.9.1` 로 변경한다.
대안으로 디플로이먼트를 `edit` 해서 `.spec.template.spec.containers[0].image``nginx:1.14.2` 에서 `nginx:1.16.1` 로 변경한다.
```shell
kubectl edit deployment.v1.apps/nginx-deployment
@ -263,7 +263,7 @@ _디플로이먼트_ 는 [파드](/ko/docs/concepts/workloads/pods/pod/)와
Labels: app=nginx
Containers:
nginx:
Image: nginx:1.9.1
Image: nginx:1.16.1
Port: 80/TCP
Environment: <none>
Mounts: <none>
@ -304,11 +304,11 @@ _디플로이먼트_ 는 [파드](/ko/docs/concepts/workloads/pods/pod/)와
스케일 업하기 시작한다. 그리고 이전에 스케일 업 하던 레플리카셋에 롤오버 한다.
--이것은 기존 레플리카셋 목록에 추가하고 스케일 다운을 할 것이다.
예를 들어 디플로이먼트로 `nginx:1.7.9` 레플리카를 5개 생성을 한다.
하지만 `nginx:1.7.9` 레플리카 3개가 생성되었을 때 디플로이먼트를 업데이트해서 `nginx:1.9.1`
예를 들어 디플로이먼트로 `nginx:1.14.2` 레플리카를 5개 생성을 한다.
하지만 `nginx:1.14.2` 레플리카 3개가 생성되었을 때 디플로이먼트를 업데이트해서 `nginx:1.16.1`
레플리카 5개를 생성성하도록 업데이트를 한다고 가정한다. 이 경우 디플로이먼트는 즉시 생성된 3개의
`nginx:1.7.9` 파드 3개를 죽이기 시작하고 `nginx:1.9.1` 파드를 생성하기 시작한다.
이것은 과정이 변경되기 전 `nginx:1.7.9` 레플리카 5개가
`nginx:1.14.2` 파드 3개를 죽이기 시작하고 `nginx:1.16.1` 파드를 생성하기 시작한다.
이것은 과정이 변경되기 전 `nginx:1.14.2` 레플리카 5개가
생성되는 것을 기다리지 않는다.
### 레이블 셀렉터 업데이트
@ -345,10 +345,10 @@ API 버전 `apps/v1` 에서 디플로이먼트의 레이블 셀렉터는 생성
롤백된다는 것을 의미한다.
{{< /note >}}
* 디플로이먼트를 업데이트하는 동안 이미지 이름을 `nginx:1.9.1` 이 아닌 `nginx:1.91` 로 입력해서 오타를 냈다고 가정한다.
* 디플로이먼트를 업데이트하는 동안 이미지 이름을 `nginx:1.16.1` 이 아닌 `nginx:1.161` 로 입력해서 오타를 냈다고 가정한다.
```shell
kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.91 --record=true
kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.161 --record=true
```
이와 유사하게 출력된다.
@ -425,7 +425,7 @@ API 버전 `apps/v1` 에서 디플로이먼트의 레이블 셀렉터는 생성
Labels: app=nginx
Containers:
nginx:
Image: nginx:1.91
Image: nginx:1.161
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
@ -466,13 +466,13 @@ API 버전 `apps/v1` 에서 디플로이먼트의 레이블 셀렉터는 생성
deployments "nginx-deployment"
REVISION CHANGE-CAUSE
1 kubectl apply --filename=https://k8s.io/examples/controllers/nginx-deployment.yaml --record=true
2 kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1 --record=true
3 kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.91 --record=true
2 kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1 --record=true
3 kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.161 --record=true
```
`CHANGE-CAUSE` 는 수정 생성시 디플로이먼트 주석인 `kubernetes.io/change-cause` 에서 복사한다. 다음에 대해 `CHANGE-CAUSE` 메시지를 지정할 수 있다.
* 디플로이먼트에 `kubectl annotate deployment.v1.apps/nginx-deployment kubernetes.io/change-cause="image updated to 1.9.1"` 로 주석을 단다.
* 디플로이먼트에 `kubectl annotate deployment.v1.apps/nginx-deployment kubernetes.io/change-cause="image updated to 1.16.1"` 로 주석을 단다.
* `kubectl` 명령어 이용시 `--record` 플래그를 추가해서 리소스 변경을 저장한다.
* 수동으로 리소스 매니페스트 편집.
@ -486,10 +486,10 @@ API 버전 `apps/v1` 에서 디플로이먼트의 레이블 셀렉터는 생성
deployments "nginx-deployment" revision 2
Labels: app=nginx
pod-template-hash=1159050644
Annotations: kubernetes.io/change-cause=kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1 --record=true
Annotations: kubernetes.io/change-cause=kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1 --record=true
Containers:
nginx:
Image: nginx:1.9.1
Image: nginx:1.16.1
Port: 80/TCP
QoS Tier:
cpu: BestEffort
@ -547,7 +547,7 @@ API 버전 `apps/v1` 에서 디플로이먼트의 레이블 셀렉터는 생성
CreationTimestamp: Sun, 02 Sep 2018 18:17:55 -0500
Labels: app=nginx
Annotations: deployment.kubernetes.io/revision=4
kubernetes.io/change-cause=kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1 --record=true
kubernetes.io/change-cause=kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1 --record=true
Selector: app=nginx
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
@ -557,7 +557,7 @@ API 버전 `apps/v1` 에서 디플로이먼트의 레이블 셀렉터는 생성
Labels: app=nginx
Containers:
nginx:
Image: nginx:1.9.1
Image: nginx:1.16.1
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
@ -720,7 +720,7 @@ nginx-deployment-618515232 11 11 11 7m
* 그런 다음 디플로이먼트의 이미지를 업데이트 한다.
```shell
kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1
kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1
```
이와 유사하게 출력된다.

View File

@ -15,10 +15,8 @@ weight: 80
{{< warning >}}
임시 컨테이너는 초기 알파 상태이며, 프로덕션 클러스터에는
적합하지 않다. 사용자는 컨테이너 네임스페이스를 대상으로 하는 경우와
같은 어떤 상황에서 기능이 작동하지 않을 것으로 예상해야 한다. [쿠버네티스
사용중단(deprecation) 정책](/docs/reference/using-api/deprecation-policy/)에 따라 이 알파
기능은 향후 크게 변경되거나, 완전히 제거될 수 있다.
적합하지 않다. [쿠버네티스 사용중단(deprecation) 정책](/docs/reference/using-api/deprecation-policy/)에 따라
이 알파 기능은 향후 크게 변경되거나, 완전히 제거될 수 있다.
{{< /warning >}}
{{% /capture %}}
@ -75,7 +73,11 @@ API에서 특별한 `ephemeralcontainers` 핸들러를 사용해서 만들어지
공유](/docs/tasks/configure-pod-container/share-process-namespace/)를
활성화하면 다른 컨테이너 안의 프로세스를 보는데 도움이 된다.
### 예시
임시 컨테이너를 사용해서 문제를 해결하는 예시는
[임시 디버깅 컨테이너로 디버깅하기]
(/docs/tasks/debug-application-cluster/debug-running-pod/#debugging-with-ephemeral-debug-container)를 참조한다.
## 임시 컨테이너 API
{{< note >}}
이 섹션의 예시는 `EphemeralContainers` [기능
@ -84,8 +86,9 @@ API에서 특별한 `ephemeralcontainers` 핸들러를 사용해서 만들어지
{{< /note >}}
이 섹션의 에시는 임시 컨테이너가 어떻게 API에 나타나는지
보여준다. 사용자는 일반적으로 자동화하는 단계의 문제 해결을 위해 `kubectl`
플러그인을 사용했을 것이다.
보여준다. 일반적으로 `kubectl alpha debug` 또는
다른 `kubectl` [플러그인](/docs/tasks/extend-kubectl/kubectl-plugins/)을
사용해서 API를 직접 호출하지 않고 이런 단계들을 자동화 한다.
임시 컨테이너는 파드의 `ephemeralcontainers` 하위 리소스를
사용해서 생성되며, `kubectl --raw` 를 사용해서 보여준다. 먼저
@ -177,35 +180,12 @@ Ephemeral Containers:
...
```
사용자는 `kubectl attach` 를 사용해서 새로운 임시 컨테이너에 붙을 수 있다.
예시와 같이 `kubectl attach`, `kubectl exec`, 그리고 `kubectl logs` 를 사용해서
다른 컨테이너와 같은 방식으로 새로운 임시 컨테이너와
상호작용할 수 있다.
```shell
kubectl attach -it example-pod -c debugger
```
만약 프로세스 네임스페이스를 공유를 활성화하면, 사용자는 해당 파드 안의 모든 컨테이너의 프로세스를 볼 수 있다.
예를 들어, 임시 컨테이너에 붙은 이후에 디버거 컨테이너에서 `ps` 를 실행한다.
```shell
# "디버거" 임시 컨테이너 내부 쉘에서 이것을 실행한다.
ps auxww
```
다음과 유사하게 출력된다.
```
PID USER TIME COMMAND
1 root 0:00 /pause
6 root 0:00 nginx: master process nginx -g daemon off;
11 101 0:00 nginx: worker process
12 101 0:00 nginx: worker process
13 101 0:00 nginx: worker process
14 101 0:00 nginx: worker process
15 101 0:00 nginx: worker process
16 101 0:00 nginx: worker process
17 101 0:00 nginx: worker process
18 101 0:00 nginx: worker process
19 root 0:00 /pause
24 root 0:00 sh
29 root 0:00 ps auxww
```
{{% /capture %}}

View File

@ -6,7 +6,7 @@ weight: 50
{{% capture overview %}}
{{< feature-state for_k8s_version="v1.16" state="alpha" >}}
{{< feature-state for_k8s_version="v1.18" state="beta" >}}
사용자는 _토폴로지 분배 제약 조건_ 을 사용해서 지역, 영역, 노드 그리고 기타 사용자-정의 토폴로지 도메인과 같이 장애-도메인으로 설정된 클러스터에 걸쳐 파드가 분산되는 방식을 제어할 수 있다. 이를 통해 고가용성뿐만 아니라, 효율적인 리소스 활용의 목적을 이루는 데 도움이 된다.
@ -18,11 +18,10 @@ weight: 50
### 기능 게이트 활성화
`EvenPodsSpread` 기능 게이트의 활성화가 되었는지 확인한다(기본적으로 1.16에서는
비활성화되어있다). 기능 게이트의 활성화에 대한 설명은 [기능 게이트](/docs/reference/command-line-tools-reference/feature-gates/)
를 참조한다. {{< glossary_tooltip text="API 서버" term_id="kube-apiserver" >}} **와**
{{< glossary_tooltip text="스케줄러" term_id="kube-scheduler" >}}에
대해 `EvenPodsSpread` 기능 게이트가 활성화되어야 한다.
대해 `EvenPodsSpread`
[기능 게이트](/docs/reference/command-line-tools-reference/feature-gates/)가 활성화되어야 한다.
### 노드 레이블
@ -184,6 +183,46 @@ spec:
{{< codenew file="pods/topology-spread-constraints/one-constraint-with-nodeaffinity.yaml" >}}
### 클러스터 수준의 기본 제약 조건
{{< feature-state for_k8s_version="v1.18" state="alpha" >}}
클러스터에 대한 기본 토폴로지 분배 제약 조건을 설정할 수 있다. 기본
토폴로지 분배 제약 조건은 다음과 같은 경우에만 파드에 적용된다.
- `.spec.topologySpreadConstraints` 에는 어떠한 제약도 정의되어 있지 않는 경우.
- 서비스, 레플리케이션 컨트롤러, 레플리카 셋 또는 스테이트풀 셋에 속해있는 경우.
기본 제약 조건은 [스케줄링 프로파일](/docs/reference/scheduling/profiles)에서
`PodTopologySpread` 플러그인의 일부로 설정할 수 있다.
제약 조건은 `labelSelector` 가 비어 있어야 한다는 점을 제외하고, [위와 동일한 API](#api)로
제약 조건을 지정한다. 셀렉터는 파드가 속한 서비스, 레플리케이션 컨트롤러,
레플리카 셋 또는 스테이트풀 셋에서 계산한다.
예시 구성은 다음과 같다.
```yaml
apiVersion: kubescheduler.config.k8s.io/v1alpha2
kind: KubeSchedulerConfiguration
profiles:
pluginConfig:
- name: PodTopologySpread
args:
defaultConstraints:
- maxSkew: 1
topologyKey: failure-domain.beta.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
```
{{< note >}}
기본 스케줄링 제약 조건에 의해 생성된 점수는
[`DefaultPodTopologySpread` 플러그인](/docs/reference/scheduling/profiles/#scheduling-plugins)에
의해 생성된 점수와 충돌 할 수 있다.
`PodTopologySpread` 에 대한 기본 제약 조건을 사용할 때 스케줄링 프로파일에서
이 플러그인을 비활성화 하는 것을 권장한다.
{{< /note >}}
## 파드어피니티(PodAffinity)/파드안티어피니티(PodAntiAffinity)와의 비교
쿠버네티스에서 "어피니티(Affinity)"와 관련된 지침은 파드가
@ -201,9 +240,9 @@ spec:
## 알려진 제한사항
1.16을 기준으로 이 기능은 알파(Alpha)이며, 몇 가지 알려진 제한사항이 있다.
1.18을 기준으로 이 기능은 베타(Beta)이며, 몇 가지 알려진 제한사항이 있다.
- `Deployment` 를 스케일링 다운하면 그 결과로 파드의 분포가 불균형이 될 수 있다.
- 디플로이먼트를 스케일링 다운하면 그 결과로 파드의 분포가 불균형이 될 수 있다.
- 파드와 일치하는 테인트(taint)가 된 노드가 존중된다. [이슈 80921](https://github.com/kubernetes/kubernetes/issues/80921)을 본다.
{{% /capture %}}

View File

@ -3,7 +3,7 @@ title: 쿠버네티스 문서
noedit: true
cid: docsHome
layout: docsportal_home
class: gridPage
class: gridPage gridPageHome
linkTitle: "홈"
main_menu: true
weight: 10
@ -40,7 +40,7 @@ cards:
button: "태스크 보기"
button_path: "/ko/docs/tasks"
- name: training
title: 교육"
title: "교육"
description: "공인 쿠버네티스 인증을 획득하고 클라우드 네이티브 프로젝트를 성공적으로 수행하세요!"
button: "교육 보기"
button_path: "/training"

View File

@ -36,13 +36,15 @@ content_template: templates/concept
* [JSONPath](/docs/reference/kubectl/jsonpath/) - kubectl에서 [JSONPath 표현](http://goessner.net/articles/JsonPath/)을 사용하기 위한 문법 가이드.
* [kubeadm](/docs/reference/setup-tools/kubeadm/kubeadm/) - 안정적인 쿠버네티스 클러스터를 쉽게 프로비전하기 위한 CLI 도구.
## 설정 레퍼런스
## 컴포넌트 레퍼런스
* [kubelet](/docs/reference/command-line-tools-reference/kubelet/) - 각 노드에서 구동되는 주요한 *노드 에이전트*. kubelet은 PodSpecs 집합을 가지며 기술된 컨테이너가 구동되고 있는지, 정상 작동하는지를 보장한다.
* [kube-apiserver](/docs/reference/command-line-tools-reference/kube-apiserver/) - 파드, 서비스, 레플리케이션 컨트롤러와 같은 API 오브젝트에 대한 검증과 구성을 수행하는 REST API.
* [kube-controller-manager](/docs/reference/command-line-tools-reference/kube-controller-manager/) - 쿠버네티스에 탑재된 핵심 제어 루프를 포함하는 데몬.
* [kube-proxy](/docs/reference/command-line-tools-reference/kube-proxy/) - 간단한 TCP/UDP 스트림 포워딩이나 백-엔드 집합에 걸쳐서 라운드-로빈 TCP/UDP 포워딩을 할 수 있다.
* [kube-scheduler](/docs/reference/command-line-tools-reference/kube-scheduler/) - 가용성, 성능 및 용량을 관리하는 스케줄러.
* [kube-scheduler 정책](/docs/reference/scheduling/policies)
* [kube-scheduler 프로파일](/docs/reference/scheduling/profiles)
## 설계 문서

View File

@ -0,0 +1,18 @@
---
title: 매니지드 서비스
id: managed-service
date: 2018-04-12
full_link:
short_description: >
타사 공급자가 유지보수하는 소프트웨어.
aka:
tags:
- extension
---
타사 공급자가 유지보수하는 소프트웨어.
<!--more-->
매니지드 서비스의 몇 가지 예시로 AWS EC2, Azure SQL Database 그리고 GCP Pub/Sub이 있으나, 애플리케이션에서 사용할 수 있는 모든 소프트웨어 제품이 될 수 있다. [서비스 카탈로그](/docs/concepts/service-catalog/)는 {{< glossary_tooltip text="서비스 브로커" term_id="service-broker" >}}가 제공하는 매니지드 서비스의 목록과 프로비전, 바인딩하는 방법을 제공한다.

View File

@ -4,16 +4,22 @@ id: replication-controller
date: 2018-04-12
full_link:
short_description: >
특정 수의 파드 인스턴스가 항상 동작하도록 보장하는 쿠버네티스 서비스.
(사용 중단된) 복제된 애플리케이션을 관리하는 API 오브젝트
aka:
tags:
- workload
- core-object
---
특정 수의 {{< glossary_tooltip text="파드" term_id="pod" >}} 인스턴스가 항상 동작하도록 보장하는 쿠버네티스 서비스.
특정한 수의 {{< glossary_tooltip text="파드" term_id="pod" >}} 인스턴스가
실행 중인지 확인하면서 복제된 애플리케이션을 관리하는 워크로드 리소스이다.
<!--more-->
레플리케이션 컨트롤러는 파드에 설정된 값에 따라서, 동작하는 파드의 인스턴스를 자동으로 추가하거나 제거할 것이다. 파드가 삭제되거나 실수로 너무 많은 수의 파드가 시작된 경우, 파드가 지정된 수의 인스턴스로 돌아갈 수 있게 허용한다.
컨트롤 플레인은 일부 파드에 장애가 발생하거나, 수동으로 파드를 삭제하거나,
실수로 너무 많은 수의 파드가 시작된 경우에도 정의된 수량의 파드가 실행되도록 한다.
{{< note >}}
레플리케이션컨트롤러는 사용 중단되었다. 유사한
것으로는 {{< glossary_tooltip text="디플로이먼트" term_id="deployment" >}}를 본다.
{{< /note >}}

View File

@ -0,0 +1,18 @@
---
title: 서비스 카탈로그(Service Catalog)
id: service-catalog
date: 2018-04-12
full_link:
short_description: >
쿠버네티스 클러스터 내에서 실행되는 응용 프로그램이 클라우드 공급자가 제공하는 데이터 저장소 서비스와 같은 외부 관리 소프트웨어 제품을 쉽게 사용할 수 있도록하는 확장 API이다.
aka:
tags:
- extension
---
쿠버네티스 클러스터 내에서 실행되는 응용 프로그램이 클라우드 공급자가 제공하는 데이터 저장소 서비스와 같은 외부 관리 소프트웨어 제품을 쉽게 사용할 수 있도록하는 확장 API이다.
<!--more-->
서비스 생성 또는 관리에 대한 자세한 지식 없이도 {{< glossary_tooltip text="서비스 브로커" term_id="service-broker" >}}를 통해 외부의 {{< glossary_tooltip text="매니지드 서비스" term_id="managed-service" >}}의 목록과 프로비전, 바인딩하는 방법을 제공한다.

View File

@ -49,63 +49,6 @@ card:
운영 환경을 위한 솔루션을 평가할 때에는, 쿠버네티스 클러스터 운영에 대한 어떤 측면(또는 _추상적인 개념_)을 스스로 관리하기를 원하는지, 제공자에게 넘기기를 원하는지 고려하자.
몇 가지 가능한 쿠버네티스 클러스터의 추상적인 개념은 {{< glossary_tooltip text="애플리케이션" term_id="applications" >}}, {{< glossary_tooltip text="데이터 플레인" term_id="data-plane" >}}, {{< glossary_tooltip text="컨트롤 플레인" term_id="control-plane" >}}, {{< glossary_tooltip text="클러스터 인프라스트럭처" term_id="cluster-infrastructure" >}}, 및 {{< glossary_tooltip text="클러스터 운영" term_id="cluster-operations" >}}이다.
다음의 다이어그램은 쿠버네티스 클러스터에 대해 가능한 추상적인 개념을 나열하고, 각 추상적인 개념을 사용자 스스로 관리하는지 제공자에 의해 관리되는지를 보여준다.
운영 환경 솔루션![운영 환경 솔루션](/images/docs/KubernetesSolutions.svg)
{{< table caption="제공자와 솔루션을 나열한 운영 환경 솔루션 표." >}}
다음 운영 환경 솔루션 표는 제공자와 솔루션을 나열한다.
|제공자 | 매니지드 | 턴키 클라우드 | 온-프렘(on-prem) 데이터센터 | 커스텀 (클라우드) | 커스텀 (온-프레미스 VMs)| 커스텀 (베어 메탈) |
| --------- | ------ | ------ | ------ | ------ | ------ | ----- |
| [Agile Stacks](https://www.agilestacks.com/products/kubernetes)| | &#x2714; | &#x2714; | | |
| [Alibaba Cloud](https://www.alibabacloud.com/product/kubernetes)| | &#x2714; | | | |
| [Amazon](https://aws.amazon.com) | [Amazon EKS](https://aws.amazon.com/eks/) |[Amazon EC2](https://aws.amazon.com/ec2/) | | | |
| [AppsCode](https://appscode.com/products/pharmer/) | &#x2714; | | | | |
| [APPUiO](https://appuio.ch/)  | &#x2714; | &#x2714; | &#x2714; | | | |
| [Banzai Cloud Pipeline Kubernetes Engine (PKE)](https://banzaicloud.com/products/pke/) | | &#x2714; | | &#x2714; | &#x2714; | &#x2714; |
| [CenturyLink Cloud](https://www.ctl.io/) | | &#x2714; | | | |
| [Cisco Container Platform](https://cisco.com/go/containers) | | | &#x2714; | | |
| [Cloud Foundry Container Runtime (CFCR)](https://docs-cfcr.cfapps.io/) | | | | &#x2714; |&#x2714; |
| [CloudStack](https://cloudstack.apache.org/) | | | | | &#x2714;|
| [Canonical](https://ubuntu.com/kubernetes) | &#x2714; | &#x2714; | &#x2714; | &#x2714; |&#x2714; | &#x2714;
| [Containership](https://containership.io) | &#x2714; |&#x2714; | | | |
| [D2iQ](https://d2iq.com/) | | [Kommander](https://docs.d2iq.com/ksphere/kommander/) | [Konvoy](https://d2iq.com/solutions/ksphere/konvoy) | [Konvoy](https://d2iq.com/solutions/ksphere/konvoy) | [Konvoy](https://d2iq.com/solutions/ksphere/konvoy) | [Konvoy](https://d2iq.com/solutions/ksphere/konvoy) |
| [Digital Rebar](https://provision.readthedocs.io/en/tip/README.html) | | | | | | &#x2714;
| [DigitalOcean](https://www.digitalocean.com/products/kubernetes/) | &#x2714; | | | | |
| [Docker Enterprise](https://www.docker.com/products/docker-enterprise) | |&#x2714; | &#x2714; | | | &#x2714;
| [Gardener](https://gardener.cloud/) | &#x2714; | &#x2714; | &#x2714; | &#x2714; | &#x2714; | [사용자 정의 확장](https://github.com/gardener/gardener/blob/master/docs/extensions/overview.md) |
| [Giant Swarm](https://www.giantswarm.io/) | &#x2714; | &#x2714; | &#x2714; | |
| [Google](https://cloud.google.com/) | [Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine/) | [Google Compute Engine (GCE)](https://cloud.google.com/compute/)|[GKE On-Prem](https://cloud.google.com/gke-on-prem/) | | | | | | | |
| [Hidora](https://hidora.com/) | &#x2714; | &#x2714;| &#x2714; | | | | | | | |
| [IBM](https://www.ibm.com/in-en/cloud) | [IBM Cloud Kubernetes Service](https://cloud.ibm.com/kubernetes/catalog/cluster)| |[IBM Cloud Private](https://www.ibm.com/in-en/cloud/private) | |
| [Ionos](https://www.ionos.com/enterprise-cloud) | [Ionos Managed Kubernetes](https://www.ionos.com/enterprise-cloud/managed-kubernetes) | [Ionos Enterprise Cloud](https://www.ionos.com/enterprise-cloud) | |
| [Kontena Pharos](https://www.kontena.io/pharos/) | |&#x2714;| &#x2714; | | |
| [KubeOne](https://kubeone.io/) | | &#x2714; | &#x2714; | &#x2714; | &#x2714; | &#x2714; |
| [Kubermatic](https://kubermatic.io/) | &#x2714; | &#x2714; | &#x2714; | &#x2714; | &#x2714; | &#x2714; |
| [KubeSail](https://kubesail.com/) | &#x2714; | | | | |
| [Kubespray](https://kubespray.io/#/) | | | |&#x2714; | &#x2714; | &#x2714; |
| [Kublr](https://kublr.com/) |&#x2714; | &#x2714; |&#x2714; |&#x2714; |&#x2714; |&#x2714; |
| [Microsoft Azure](https://azure.microsoft.com) | [Azure Kubernetes Service (AKS)](https://azure.microsoft.com/en-us/services/kubernetes-service/) | | | | |
| [Mirantis Cloud Platform](https://www.mirantis.com/software/kubernetes/) | | | &#x2714; | | |
| [NetApp Kubernetes Service (NKS)](https://cloud.netapp.com/kubernetes-service) | &#x2714; | &#x2714; | &#x2714; | | |
| [Nirmata](https://www.nirmata.com/) | | &#x2714; | &#x2714; | | |
| [Nutanix](https://www.nutanix.com/en) | [Nutanix Karbon](https://www.nutanix.com/products/karbon) | [Nutanix Karbon](https://www.nutanix.com/products/karbon) | | | [Nutanix AHV](https://www.nutanix.com/products/acropolis/virtualization) |
| [OpenNebula](https://www.opennebula.org) |[OpenNebula Kubernetes](https://marketplace.opennebula.systems/docs/service/kubernetes.html) | | | | |
| [OpenShift](https://www.openshift.com) |[OpenShift Dedicated](https://www.openshift.com/products/dedicated/) and [OpenShift Online](https://www.openshift.com/products/online/) | | [OpenShift Container Platform](https://www.openshift.com/products/container-platform/) | | [OpenShift Container Platform](https://www.openshift.com/products/container-platform/) |[OpenShift Container Platform](https://www.openshift.com/products/container-platform/)
| [Oracle Cloud Infrastructure Container Engine for Kubernetes (OKE)](https://docs.cloud.oracle.com/iaas/Content/ContEng/Concepts/contengoverview.htm) | &#x2714; | &#x2714; | | | |
| [oVirt](https://www.ovirt.org/) | | | | | &#x2714; |
| [Pivotal](https://pivotal.io/) | | [Enterprise Pivotal Container Service (PKS)](https://pivotal.io/platform/pivotal-container-service) | [Enterprise Pivotal Container Service (PKS)](https://pivotal.io/platform/pivotal-container-service) | | |
| [Platform9](https://platform9.com/) | [Platform9 Managed Kubernetes](https://platform9.com/managed-kubernetes/) | | [Platform9 Managed Kubernetes](https://platform9.com/managed-kubernetes/) | &#x2714; | &#x2714; | &#x2714;
| [Rancher](https://rancher.com/) | | [Rancher 2.x](https://rancher.com/docs/rancher/v2.x/en/) | | [Rancher Kubernetes Engine (RKE)](https://rancher.com/docs/rke/latest/en/) | | [k3s](https://k3s.io/)
| [Supergiant](https://supergiant.io/) | |&#x2714; | | | |
| [SUSE](https://www.suse.com/) | | &#x2714; | | | |
| [SysEleven](https://www.syseleven.io/) | &#x2714; | | | | |
| [Tencent Cloud](https://intl.cloud.tencent.com/) | [Tencent Kubernetes Engine](https://intl.cloud.tencent.com/product/tke) | &#x2714; | &#x2714; | | | &#x2714; |
| [VEXXHOST](https://vexxhost.com/) | &#x2714; | &#x2714; | | | |
| [VMware](https://cloud.vmware.com/) | [VMware Cloud PKS](https://cloud.vmware.com/vmware-cloud-pks) |[VMware Enterprise PKS](https://cloud.vmware.com/vmware-enterprise-pks) | [VMware Enterprise PKS](https://cloud.vmware.com/vmware-enterprise-pks) | [VMware Essential PKS](https://cloud.vmware.com/vmware-essential-pks) | |[VMware Essential PKS](https://cloud.vmware.com/vmware-essential-pks)
| [Z.A.R.V.I.S.](https://zarvis.ai/) | &#x2714; | | | | | |
[공인 쿠버네티스](https://github.com/cncf/k8s-conformance/#certified-kubernetes) 공급자의 목록과 "[파트너](https://kubernetes.io/partners/#conformance)"를 참조한다.
{{% /capture %}}

View File

@ -183,23 +183,25 @@ Minikube는 또한 "minikube" 컨텍스트를 생성하고 이를 kubectl의 기
minikube start --kubernetes-version {{< param "fullversion" >}}
```
#### VM 드라이버 지정하기
`minikube start` 코멘드에 `--vm-driver=<enter_driver_name>` 플래그를 추가해서 VM 드라이버를 변경할 수 있다.
`minikube start` 코멘드에 `--driver=<enter_driver_name>` 플래그를 추가해서 VM 드라이버를 변경할 수 있다.
코멘드를 예를 들면 다음과 같다.
```shell
minikube start --vm-driver=<driver_name>
minikube start --driver=<driver_name>
```
Minikube는 다음의 드라이버를 지원한다.
{{< note >}}
지원되는 드라이버와 플러그인 설치 방법에 대한 보다 상세한 정보는 [드라이버](https://git.k8s.io/minikube/docs/drivers.md)를 참조한다.
지원되는 드라이버와 플러그인 설치 방법에 대한 보다 상세한 정보는 [드라이버](https://minikube.sigs.k8s.io/docs/reference/drivers/)를 참조한다.
{{< /note >}}
* virtualbox
* vmwarefusion
* kvm2 ([드라이버 설치](https://git.k8s.io/minikube/docs/drivers.md#kvm2-driver))
* hyperkit ([드라이버 설치](https://git.k8s.io/minikube/docs/drivers.md#hyperkit-driver))
* hyperv ([드라이버 설치](https://github.com/kubernetes/minikube/blob/master/docs/drivers.md#hyperv-driver))
* docker (EXPERIMENTAL)
* 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/))
다음 IP는 동적이며 변경할 수 있다. `minikube ip`로 알아낼 수 있다.
* vmware ([드라이버 설치](https://github.com/kubernetes/minikube/blob/master/docs/drivers.md#vmware-unified-driver)) (VMware unified driver)
* vmware ([드라이버 설치](https://minikube.sigs.k8s.io/docs/reference/drivers/vmware/)) (VMware unified driver)
* parallels ([드라이버 설치](https://minikube.sigs.k8s.io/docs/reference/drivers/parallels/))
* none (쿠버네티스 컴포넌트를 가상 머신이 아닌 호스트 상에서 구동한다. 리눅스를 실행중이어야 하고, {{< glossary_tooltip term_id="docker" >}}가 설치되어야 한다.)
{{< caution >}}

View File

@ -62,7 +62,7 @@ kubelet을 재시작 하는 것은 에러를 해결할 수 없을 것이다.
## Docker
각 머신들에 대해서, Docker를 설치한다.
버전 19.03.4가 추천된다. 그러나 1.13.1, 17.03, 17.06, 17.09, 18.06 그리고 18.09도 동작하는 것으로 알려져 있다.
버전 19.03.8이 추천된다. 그러나 1.13.1, 17.03, 17.06, 17.09, 18.06 그리고 18.09도 동작하는 것으로 알려져 있다.
쿠버네티스 릴리스 노트를 통해서, 최신에 검증된 Docker 버전의 지속적인 파악이 필요하다.
시스템에 Docker를 설치하기 위해서 아래의 커맨드들을 사용한다.
@ -86,9 +86,9 @@ add-apt-repository \
## Docker CE 설치.
apt-get update && apt-get install -y \
containerd.io=1.2.10-3 \
docker-ce=5:19.03.4~3-0~ubuntu-$(lsb_release -cs) \
docker-ce-cli=5:19.03.4~3-0~ubuntu-$(lsb_release -cs)
containerd.io=1.2.13-1 \
docker-ce=5:19.03.8~3-0~ubuntu-$(lsb_release -cs) \
docker-ce-cli=5:19.03.8~3-0~ubuntu-$(lsb_release -cs)
# 데몬 설정.
cat > /etc/docker/daemon.json <<EOF
@ -121,9 +121,9 @@ yum-config-manager --add-repo \
## Docker CE 설치.
yum update -y && yum install -y \
containerd.io-1.2.10 \
docker-ce-19.03.4 \
docker-ce-cli-19.03.4
containerd.io-1.2.13 \
docker-ce-19.03.8 \
docker-ce-cli-19.03.8
## /etc/docker 디렉터리 생성.
mkdir /etc/docker
@ -182,27 +182,47 @@ sysctl --system
```
{{< tabs name="tab-cri-cri-o-installation" >}}
{{< tab name="Ubuntu 16.04" codelang="bash" >}}
{{< tab name="Debian" codelang="bash" >}}
# Debian 개발 배포본(Unstable/Sid)
echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_Unstable/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/Debian_Unstable/Release.key -O- | sudo apt-key add -
# 선행 조건 설치
apt-get update
apt-get install -y software-properties-common
# Debian Testing
echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_Testing/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/Debian_Testing/Release.key -O- | sudo apt-key add -
add-apt-repository ppa:projectatomic/ppa
apt-get update
# Debian 10
echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_10/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/Debian_10/Release.key -O- | sudo apt-key add -
# Raspbian 10
echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Raspbian_10/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/Raspbian_10/Release.key -O- | sudo apt-key add -
# CRI-O 설치
apt-get install -y cri-o-1.15
sudo apt-get install cri-o-1.17
{{< /tab >}}
{{< tab name="CentOS/RHEL 7.4+" codelang="bash" >}}
{{< tab name="Ubuntu 18.04, 19.04 and 19.10" codelang="bash" >}}
# 리포지터리 설치
. /etc/os-release
sudo sh -c "echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/x${NAME}_${VERSION_ID}/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list"
wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/x${NAME}_${VERSION_ID}/Release.key -O- | sudo apt-key add -
sudo apt-get update
# CRI-O 설치
sudo apt-get install cri-o-1.17
{{< /tab >}}
{{< tab name="CentOS/RHEL 7.4+" codelang="bash" >}}
# 선행 조건 설치
yum-config-manager --add-repo=https://cbs.centos.org/repos/paas7-crio-115-release/x86_64/os/
# CRI-O 설치
yum install --nogpgcheck -y cri-o
{{< tab name="openSUSE Tumbleweed" codelang="bash" >}}
sudo zypper install cri-o
{{< /tab >}}
{{< /tabs >}}
@ -304,4 +324,4 @@ kubeadm을 사용하는 경우에도 마찬가지로, 수동으로
자세한 정보는 [Frakti 빠른 시작 가이드](https://github.com/kubernetes/frakti#quickstart)를 참고한다.
{{% /capture %}}
{{% /capture %}}

View File

@ -19,7 +19,7 @@ weight: 75
## 시작하기 전에
* [윈도우 서버에서 운영하는 마스터와 워커 노드](../user-guide-windows-nodes)를 포함한 쿠버네티스 클러스터를 생성한다.
* [윈도우 서버에서 운영하는 마스터와 워커 노드](/docs/tasks/administer-cluster/kubeadm/adding-windows-nodes)를 포함한 쿠버네티스 클러스터를 생성한다.
* 쿠버네티스에서 서비스와 워크로드를 생성하고 배포하는 것은 리눅스나 윈도우 컨테이너 모두 비슷한 방식이라는 것이 중요하다. [Kubectl 커맨드](/docs/reference/kubectl/overview/)로 클러스터에 접속하는 것은 동일하다. 아래 단원의 예시는 윈도우 컨테이너를 경험하기 위해 제공한다.
## 시작하기: 윈도우 컨테이너 배포하기

View File

@ -1,354 +0,0 @@
---
reviewers:
title: 쿠버네티스에서 윈도우 노드 추가 가이드
min-kubernetes-server-version: v1.14
content_template: templates/tutorial
weight: 70
---
{{% capture overview %}}
쿠버네티스 플랫폼은 이제 리눅스와 윈도우 컨테이너 모두 운영할 수 있다. 윈도우 노드도 클러스터에 등록할 수 있다. 이 페이지에서는 어떻게 하나 또는 그 이상의 윈도우 노드를 클러스터에 등록할 수 있는지 보여준다.
{{% /capture %}}
{{% capture prerequisites %}}
* 윈도우 컨테이너를 호스트하는 윈도우 노드를 구성하려면 [윈도우 서버 2019 라이선스](https://www.microsoft.com/en-us/cloud-platform/windows-server-pricing)를 소유해야 한다. 클러스터를 위해서 소속 기관의 라이선스를 사용하거나, Microsoft, 리셀러로 부터 취득할 수 있으며, GCP, AWS, Azure와 같은 주요 클라우드 제공자의 마켓플레이스를 통해 윈도우 서버를 운영하는 가상머신을 프로비저닝하여 취득할 수도 있다. [사용시간이 제한된 시험판](https://www.microsoft.com/en-us/cloud-platform/windows-server-trial)도 활용 가능하다.
* 컨트롤 플레인에 접근할 수 있는 리눅스 기반의 쿠버네티스 클러스터를 구축한다.(몇 가지 예시는 [kubeadm으로 단일 컨트롤플레인 클러스터 만들기](/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/), [AKS Engine](/docs/setup/production-environment/turnkey/azure/), [GCE](/docs/setup/production-environment/turnkey/gce/), [AWS](/docs/setup/production-environment/turnkey/aws/)를 포함한다)
{{% /capture %}}
{{% capture objectives %}}
* 윈도우 노드를 클러스터에 등록하기
* 리눅스와 윈도우에서 동작하는 파드와 서비스가 상호 간에 통신할 수 있게 네트워크를 구성하기
{{% /capture %}}
{{% capture lessoncontent %}}
## 시작하기: 사용자 클러스터에 윈도우 노드 추가하기
### IP 주소 체계 설계하기
쿠버네티스 클러스터 관리를 위해 실수로 네트워크 충돌을 일으키지 않도록 IP 주소에 대해 신중히 설계해야 한다. 이 가이드는 [쿠버네티스 네트워킹 개념](/docs/concepts/cluster-administration/networking/)에 익숙하다 가정한다.
클러스터를 배포하려면 다음 주소 공간이 필요하다.
| 서브넷 / 주소 범위 | 비고 | 기본값 |
| --- | --- | --- |
| 서비스 서브넷 | 라우트 불가한 순수한 가상 서브넷으로 네트워크 토플로지에 관계없이 파드에서 서비스로 단일화된 접근을 제공하기 위해 사용한다. 서비스 서브넷은 노드에서 실행 중인 `kube-proxy`에 의해서 라우팅 가능한 주소 공간으로(또는 반대로) 번역된다. | 10.96.0.0/12 |
| 클러스터 서브넷 | 클러스터 내에 모든 파드에 사용되는 글로벌 서브넷이다. 각 노드에는 파드가 사용하기 위한 /24 보다 작거나 같은 서브넷을 할당한다. 서브넷은 클러스터 내에 모든 파드를 수용할 수 있을 정도로 충분히 큰 값이어야 한다. *최소 서브넷*의 크기를 계산하려면: `(노드의 개수) + (노드의 개수 * 구성하려는 노드 당 최대 파드 개수)`. 예: 노드 당 100개 파드인 5 노드짜리 클러스터 = `(5) + (5 * 100) = 505.` | 10.244.0.0/16 |
| 쿠버네티스 DNS 서비스 IP | DNS 확인 및 클러스터 서비스 검색에 사용되는 서비스인 `kube-dns`의 IP 주소이다. | 10.96.0.10 |
클러스터에 IP 주소를 얼마나 할당해야 할지 결정하기 위해 '쿠버네티스에서 윈도우 컨테이너: 지원되는 기능: 네트워킹'에서 소개한 네트워킹 선택 사항을 검토하자.
### 윈도우에서 실행되는 구성 요소
쿠버네티스 컨트롤 플레인이 리눅스 노드에서 운영되는 반면, 다음 요소는 윈도우 노드에서 구성되고 운영된다.
1. kubelet
2. kube-proxy
3. kubectl (선택적)
4. 컨테이너 런타임
v1.14 이후의 최신 바이너리를 [https://github.com/kubernetes/kubernetes/releases](https://github.com/kubernetes/kubernetes/releases)에서 받아온다. kubeadm, kubectl, kubelet, kube-proxy의 Windows-amd64 바이너리는 CHANGELOG 링크에서 찾아볼 수 있다.
### 네트워크 구성
리눅스 기반의 쿠버네티스 컨트롤 플레인("마스터") 노드를 가지고 있다면 네트워킹 솔루션을 선택할 준비가 된 것이다. 이 가이드는 단순화를 위해 VXLAN 방식의 플라넬(Flannel)을 사용하여 설명한다.
#### 리눅스 컨트롤 플레인에서 VXLAN 방식으로 플라넬 구성하기
1. 플라넬을 위해 쿠버네티스 마스터를 준비한다.
클러스터의 쿠버네티스 마스터에서 사소한 준비를 권장한다. 플라넬을 사용할 때에 iptables 체인으로 IPv4 트래픽을 브릿지할 수 있게 하는 것은 추천한다. 이는 다음 커맨드를 이용하여 수행할 수 있다.
```bash
sudo sysctl net.bridge.bridge-nf-call-iptables=1
```
1. 플라넬 다운로드 받고 구성하기
가장 최신의 플라넬 메니페스트를 다운로드한다.
```bash
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
```
VXLAN 네트워킹 벡엔드를 가능하게 하기 위해 수정할 곳은 두 곳이다.
아래 단계를 적용하면 `kube-flannel.yml``net-conf.json`부분을 다음과 같게 된다.
```json
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "vxlan",
"VNI" : 4096,
"Port": 4789
}
}
```
{{< note >}}리눅스의 플라넬과 윈도우의 플라넬이 상호운용하기 위해서 `VNI`는 반드시 4096이고, `Port`는 4789여야 한다. 다른 VNI는 곧 지원될 예정이다. [VXLAN 문서](https://github.com/coreos/flannel/blob/master/Documentation/backends.md#vxlan)에서
이 필드의 설명 부분을 보자.{{< /note >}}
1. `kube-flannel.yml``net-conf.json` 부분을 거듭 확인하자.
1. 클러스터 서브넷(예, "10.244.0.0/16")은 IP 주소 설계에 따라 설정되어야 한다.
* VNI 4096 은 벡엔드에 설정한다.
* Port 4789 는 벡엔드에 설정한다.
1. `kube-flannel.yml``cni-conf.json` 부분에서 네트워크 이름을 `vxlan0`로 바꾼다.
`cni-conf.json`는 다음과 같다.
```json
cni-conf.json: |
{
"name": "vxlan0",
"plugins": [
{
"type": "flannel",
"delegate": {
"hairpinMode": true,
"isDefaultGateway": true
}
},
{
"type": "portmap",
"capabilities": {
"portMappings": true
}
}
]
}
```
1. 플라넬 매니페스트를 적용하고 확인하기
플라넬 구성을 적용하자.
```bash
kubectl apply -f kube-flannel.yml
```
몇 분 뒤에 플라넬 파드 네트워크가 배포되었다면, 모든 파드에서 운영 중인 것을 확인할 수 있다.
```bash
kubectl get pods --all-namespaces
```
결과는 다음과 같다.
```
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system etcd-flannel-master 1/1 Running 0 1m
kube-system kube-apiserver-flannel-master 1/1 Running 0 1m
kube-system kube-controller-manager-flannel-master 1/1 Running 0 1m
kube-system kube-dns-86f4d74b45-hcx8x 3/3 Running 0 12m
kube-system kube-flannel-ds-54954 1/1 Running 0 1m
kube-system kube-proxy-Zjlxz 1/1 Running 0 1m
kube-system kube-scheduler-flannel-master 1/1 Running 0 1m
```
플라넬 데몬셋에 노드 셀렉터가 적용되었음을 확인한다.
```bash
kubectl get ds -n kube-system
```
결과는 다음과 같다. 노드 셀렉터 `beta.kubernetes.io/os=linux`가 적용되었다.
```
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
kube-flannel-ds 2 2 2 2 2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux 21d
kube-proxy 2 2 2 2 2 beta.kubernetes.io/os=linux 26d
```
### 윈도우 워커 노드 추가하기
이번 단원은 맨 땅에서부터 온프레미스 클러스터에 가입하기까지 윈도우 노드 구성을 다룬다. 클러스터가 클라우드상에 있다면, [퍼블릭 클라우드 제공자 단원](#퍼블릭-클라우드-제공자)에 있는 클라우드에 특정한 가이드를 따르도록 된다.
#### 윈도우 노드 준비하기
{{< note >}}
윈도우 단원에서 모든 코드 부분은 윈도우 워커 노드에서 높은 권한(Administrator)으로 파워쉘(PowerShell) 환경에서 구동한다.
{{< /note >}}
1. 설치 및 참여(join) 스크립트가 포함된 [SIG Windows tools](https://github.com/kubernetes-sigs/sig-windows-tools) 리포지터리를 내려받는다.
```PowerShell
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Start-BitsTransfer https://github.com/kubernetes-sigs/sig-windows-tools/archive/master.zip
tar -xvf .\master.zip --strip-components 3 sig-windows-tools-master/kubeadm/v1.15.0/*
Remove-Item .\master.zip
```
1. 쿠버네티스 [구성 파일](https://github.com/kubernetes-sigs/sig-windows-tools/blob/master/kubeadm/v1.15.0/Kubeclustervxlan.json)을 커스터마이즈한다.
```
{
"Cri" : { // Contains values for container runtime and base container setup
"Name" : "dockerd", // Container runtime name
"Images" : {
"Pause" : "mcr.microsoft.com/k8s/core/pause:1.2.0", // Infrastructure container image
"Nanoserver" : "mcr.microsoft.com/windows/nanoserver:1809", // Base Nanoserver container image
"ServerCore" : "mcr.microsoft.com/windows/servercore:ltsc2019" // Base ServerCore container image
}
},
"Cni" : { // Contains values for networking executables
"Name" : "flannel", // Name of network fabric
"Source" : [{ // Contains array of objects containing values for network daemon(s)
"Name" : "flanneld", // Name of network daemon
"Url" : "https://github.com/coreos/flannel/releases/download/v0.11.0/flanneld.exe" // Direct URL pointing to network daemon executable
}
],
"Plugin" : { // Contains values for CNI network plugin
"Name": "vxlan" // Backend network mechanism to use: ["vxlan" | "bridge"]
},
"InterfaceName" : "Ethernet" // Designated network interface name on Windows node to use as container network
},
"Kubernetes" : { // Contains values for Kubernetes node binaries
"Source" : { // Contains values for Kubernetes node binaries
"Release" : "1.15.0", // Version of Kubernetes node binaries
"Url" : "https://dl.k8s.io/v1.15.0/kubernetes-node-windows-amd64.tar.gz" // Direct URL pointing to Kubernetes node binaries tarball
},
"ControlPlane" : { // Contains values associated with Kubernetes control-plane ("Master") node
"IpAddress" : "kubemasterIP", // IP address of control-plane ("Master") node
"Username" : "localadmin", // Username on control-plane ("Master") node with remote SSH access
"KubeadmToken" : "token", // Kubeadm bootstrap token
"KubeadmCAHash" : "discovery-token-ca-cert-hash" // Kubeadm CA key hash
},
"KubeProxy" : { // Contains values for Kubernetes network proxy configuration
"Gates" : "WinOverlay=true" // Comma-separated key-value pairs passed to kube-proxy feature gate flag
},
"Network" : { // Contains values for IP ranges in CIDR notation for Kubernetes networking
"ServiceCidr" : "10.96.0.0/12", // Service IP subnet used by Services in CIDR notation
"ClusterCidr" : "10.244.0.0/16" // Cluster IP subnet used by Pods in CIDR notation
}
},
"Install" : { // Contains values and configurations for Windows node installation
"Destination" : "C:\\ProgramData\\Kubernetes" // Absolute DOS path where Kubernetes will be installed on the Windows node
}
}
```
{{< note >}}
사용자는 쿠버네티스 컨트롤 플레인("마스터") 노드에서 `kubeadm token create --print-join-command`를 실행해서 `ControlPlane.KubeadmToken``ControlPlane.KubeadmCAHash` 필드를 위한 값을 생성할 수 있다.
{{< /note >}}
1. 컨테이너와 쿠버네티스를 설치 (시스템 재시작 필요)
기존에 내려받은 [KubeCluster.ps1](https://github.com/kubernetes-sigs/sig-windows-tools/blob/master/kubeadm/KubeCluster.ps1) 스크립트를 사용해서 쿠버네티스를 윈도우 서버 컨테이너 호스트에 설치한다.
```PowerShell
.\KubeCluster.ps1 -ConfigFile .\Kubeclustervxlan.json -install
```
이 때 `-ConfigFile`는 쿠버네티스 구성 파일의 경로를 가리킨다.
{{< note >}}
아래 예제에서, 우리는 오버레이 네트워킹 모드를 사용한다. 이는 [KB4489899](https://support.microsoft.com/help/4489899)를 포함한 윈도우 서버 버전 2019와 최소 쿠버네티스 v1.14 이상이 필요하다. 이 요구사항을 만족시키기 어려운 사용자는 구성 파일의 [플러그인](https://github.com/kubernetes-sigs/sig-windows-tools/blob/master/kubeadm/v1.15.0/Kubeclusterbridge.json#L18)으로 `bridge`를 선택하지 말고 `L2bridge` 네트워킹을 사용해야만 한다.
{{< /note >}}
![alt_text](../kubecluster.ps1-install.gif "KubeCluster.ps1 install output")
대상으로 하는 윈도우 노드에서, 본 단계는
1. 윈도우 서버 컨테이너 역할을 활성화(및 재시작) 한다.
1. 선택된 컨테이너 런타임을 내려받아 설치한다.
1. 필요한 컨테이너 이미지를 모두 내려받는다.
1. 쿠버네티스 바이너리를 내려받아서 `$PATH` 환경 변수에 추가한다.
1. 쿠버네티스 구성 파일에서 선택한 내용을 기반으로 CNI 플러그인을 내려받는다.
1. (선택적으로) 참여(join) 중에 컨트롤 플레인("마스터") 노드에 접속하기 위한 새로운 SSH 키를 생성한다.
{{< note >}}또한, SSH 키 생성 단계에서 생성된 공개 SSH 키를 (리눅스) 컨트롤 플레인 노드의 `authorized_keys` 파일에 추가해야 한다. 이는 한 번만 수행하면 된다. 스크립트가 출력물의 마지막 부분에 이를 따라 할 수 있도록 단계를 출력해 준다.{{< /note >}}
일단 설치가 완료되면, 생성된 모든 구성 파일이나 바이너리는 윈도우 노드가 참여하기 전에 수정될 수 있다.
#### 윈도우 노드를 쿠버네티스 클러스터에 참여시키기
이 섹션에서는 클러스터를 구성하기 위해서 [쿠버네티스가 설치된 윈도우 노드](#윈도우-노드-준비하기)를 기존의 (리눅스) 컨트롤 플레인에 참여시키는 방법을 다룬다.
앞서 내려받은 [KubeCluster.ps1](https://github.com/kubernetes-sigs/sig-windows-tools/blob/master/kubeadm/KubeCluster.ps1) 스크립트를 사용해서 윈도우 노드를 클러스터에 참여시킨다.
```PowerShell
.\KubeCluster.ps1 -ConfigFile .\Kubeclustervxlan.json -join
```
이 때 `-ConfigFile` 쿠버네티스 구성 파일의 경로를 가리킨다.
![alt_text](../kubecluster.ps1-join.gif "KubeCluster.ps1 join output")
{{< note >}}
어떤 이유에서든 부트스트랩 동안이나 참여 과정에서 스크립트가 실패하면, 뒤따르는 참여 시도를 시작하기 전에 신규 PowerShell 세션을 시작해야한다.
{{< /note >}}
본 단계는 다음의 행위를 수행한다.
1. 컨트롤 플레인("마스터") 노드에 SSH로 접속해서 [Kubeconfig 파일](/ko/docs/concepts/configuration/organize-cluster-access-kubeconfig/)을 얻어온다.
1. kubelet을 윈도우 서비스로 등록한다.
1. CNI 네트워크 플러그인을 구성한다.
1. 선택된 네트워크 인터페이스 상에서 HNS 네트워크를 생성한다.
{{< note >}}
이는 vSwitch가 생성되는 동안 몇 초간의 네트워크 순단현상을 야기할 수 있다.
{{< /note >}}
1. (vxlan 플러그인을 선택한 경우) 오버레이 트래픽을 위해서 인바운드(inbound) 방화벽의 UDP 포트 4789를 열어준다.
1. flanneld를 윈도우 서비스로 등록한다.
1. kube-proxy를 윈도우 서비스로 등록한다.
이제 클러스터에서 다음의 명령을 실행해서 윈도우 노드를 볼 수 있다.
```bash
kubectl get nodes
```
#### 윈도우 노드를 쿠버네티스 클러스터에서 제거하기
이 섹션에서는 윈도우 노드를 쿠버네티스 클러스터에서 제거하는 방법을 다룬다.
앞서 내려받은 [KubeCluster.ps1](https://github.com/kubernetes-sigs/sig-windows-tools/blob/master/kubeadm/KubeCluster.ps1) 스크립트를 사용해서 클러스터에서 윈도우 노드를 제거한다.
```PowerShell
.\KubeCluster.ps1 -ConfigFile .\Kubeclustervxlan.json -reset
```
이 때 `-ConfigFile` 쿠버네티스 구성 파일의 경로를 가리킨다.
![alt_text](../kubecluster.ps1-reset.gif "KubeCluster.ps1 reset output")
본 단계는 다음의 행위를 대상이되는 윈도우 노드에서 수행한다.
1. 윈도우 노드를 쿠버네티스 클러스터에서 삭제한다.
1. 구동 중인 모든 컨테이너를 중지시킨다.
1. 모든 컨테이너 네트워킹(HNS) 자원을 삭제한다.
1. 등록된 모든 쿠버네티스 서비스(flanneld, kubelet, kube-proxy)를 해지한다.
1. 쿠버네티스 바이너리(kube-proxy.exe, kubelet.exe, flanneld.exe, kubeadm.exe)를 모두 삭제한다.
1. CNI 네트워크 플러그인 바이너리를 모두 삭제한다.
1. 쿠버네티스 클러스터에 접근하기 위한 [Kubeconfig 파일](/ko/docs/concepts/configuration/organize-cluster-access-kubeconfig/)을 삭제한다.
### 퍼블릭 클라우드 제공자
#### Azure
AKS-Engine은 완전하고, 맞춤 설정이 가능한 쿠버네티스 클러스터를 리눅스와 윈도우 노드에 배포할 수 있다. 단계별 안내가 [GitHub에 있는 문서](https://github.com/Azure/aks-engine/blob/master/docs/topics/windows.md)로 제공된다.
#### GCP
사용자가 [GitHub](https://github.com/kubernetes/kubernetes/blob/master/cluster/gce/windows/README-GCE-Windows-kube-up.md)에 있는 단계별 안내를 따라서 완전한 쿠버네티스 클러스터를 GCE 상에 쉽게 배포할 수 있다.
#### kubeadm과 클러스터 API로 배포하기
Kubeadm은 쿠버네티스 클러스터를 배포하는 사용자에게 산업 표준이 되었다. Kubeadm에서 윈도우 노드 지원은 쿠버네티스 v1.16 이후 부터 알파 기능이다. 또한 윈도우 노드가 올바르게 프로비저닝되도록 클러스터 API에 투자하고 있다. 보다 자세한 내용은, [Windows KEP를 위한 kubeadm](https://github.com/kubernetes/enhancements/blob/master/keps/sig-cluster-lifecycle/kubeadm/20190424-kubeadm-for-windows.md)을 통해 상담하도록 하자.
### 다음 단계
이제 클러스터 내에 윈도우 컨테이너를 실행하도록 윈도우 워커를 구성했으니, 리눅스 컨테이너를 실행할 리눅스 노드를 1개 이상 추가할 수 있다. 이제 윈도우 컨테이너를 클러스터에 스케줄링할 준비가 됬다.
{{% /capture %}}

View File

@ -21,7 +21,7 @@ content_template: templates/concept
## 클러스터 업그레이드
클러스터 업그레이드 상태의 현황은 제공자에 따라 달라지며, 몇몇 릴리스들은 업그레이드에 각별한 주의를 요하기도 한다. 관리자들에게는 클러스터 업그레이드에 앞서 [릴리스 노트](https://git.k8s.io/kubernetes/CHANGELOG.md)와 버전에 맞는 업그레이드 노트 모두를 검토하도록 권장하고 있다.
클러스터 업그레이드 상태의 현황은 제공자에 따라 달라지며, 몇몇 릴리스들은 업그레이드에 각별한 주의를 요하기도 한다. 관리자들에게는 클러스터 업그레이드에 앞서 [릴리스 노트](https://git.k8s.io/kubernetes/CHANGELOG/README.md)와 버전에 맞는 업그레이드 노트 모두를 검토하도록 권장하고 있다.
### Azure Kubernetes Service (AKS) 클러스터 업그레이드

View File

@ -0,0 +1,4 @@
---
title: "파드와 컨테이너 설정"
weight: 20
---

View File

@ -0,0 +1,104 @@
---
title: 노드에 파드 할당
content_template: templates/task
weight: 120
---
{{% capture overview %}}
이 문서는 쿠버네티스 클러스터의 특정 노드에 쿠버네티스 파드를 할당하는
방법을 설명한다.
{{% /capture %}}
{{% capture prerequisites %}}
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
{{% /capture %}}
{{% capture steps %}}
## 노드에 레이블 추가
1. 클러스터의 {{< glossary_tooltip term_id="node" text="노드" >}}를 레이블과 함께 나열하자.
```shell
kubectl get nodes --show-labels
```
결과는 아래와 같다.
```shell
NAME STATUS ROLES AGE VERSION LABELS
worker0 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker0
worker1 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker1
worker2 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker2
```
1. 노드 한 개를 선택하고, 레이블을 추가하자.
```shell
kubectl label nodes <your-node-name> disktype=ssd
```
`<your-node-name>`는 선택한 노드의 이름이다.
1. 선택한 노드가 `disktype=ssd` 레이블을 갖고 있는지 확인하자.
```shell
kubectl get nodes --show-labels
```
결과는 아래와 같다.
```shell
NAME STATUS ROLES AGE VERSION LABELS
worker0 Ready <none> 1d v1.13.0 ...,disktype=ssd,kubernetes.io/hostname=worker0
worker1 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker1
worker2 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker2
```
위의 결과에서, `worker0` 노드에 `disktype=ssd` 레이블이 있는 것을
확인할 수 있다.
## 선택한 노드에 스케줄되도록 파드 생성하기
이 파드 구성 파일은 `disktype: ssd`라는 선택하는 노드 셀렉터를 가진 파드를
설명한다.
즉, `disktype=ssd` 레이블이 있는 노드에 파드가 스케줄될 것이라는
것을 의미한다.
{{< codenew file="pods/pod-nginx.yaml" >}}
1. 구성 파일을 사용해서 선택한 노드로 스케줄되도록 파드를
생성하자.
```shell
kubectl apply -f https://k8s.io/examples/pods/pod-nginx.yaml
```
1. 파드가 선택한 노드에서 실행 중인지 확인하자.
```shell
kubectl get pods --output=wide
```
결과는 아래와 같다.
```shell
NAME READY STATUS RESTARTS AGE IP NODE
nginx 1/1 Running 0 13s 10.200.0.4 worker0
```
## 특정 노드에 스케줄되도록 파드 생성하기
`nodeName` 설정을 통해 특정 노드로 파드를 배포할 수 있다.
{{< codenew file="pods/pod-nginx-specific-node.yaml" >}}
설정 파일을 사용해 `foo-node` 노드에 파드를 스케줄되도록 만들어 보자.
{{% /capture %}}
{{% capture whatsnext %}}
* [레이블과 셀렉터](/ko/docs/concepts/overview/working-with-objects/labels/)에 대해 배우기.
* [노드](/ko/docs/concepts/architecture/nodes/)에 대해 배우기.
{{% /capture %}}

View File

@ -117,7 +117,7 @@ metadata:
{"apiVersion":"apps/v1","kind":"Deployment",
"metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"},
"spec":{"minReadySeconds":5,"selector":{"matchLabels":{"app":nginx}},"template":{"metadata":{"labels":{"app":"nginx"}},
"spec":{"containers":[{"image":"nginx:1.7.9","name":"nginx",
"spec":{"containers":[{"image":"nginx:1.14.2","name":"nginx",
"ports":[{"containerPort":80}]}]}}}}
# ...
spec:
@ -134,7 +134,7 @@ spec:
app: nginx
spec:
containers:
- image: nginx:1.7.9
- image: nginx:1.14.2
# ...
name: nginx
ports:
@ -197,7 +197,7 @@ metadata:
{"apiVersion":"apps/v1","kind":"Deployment",
"metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"},
"spec":{"minReadySeconds":5,"selector":{"matchLabels":{"app":nginx}},"template":{"metadata":{"labels":{"app":"nginx"}},
"spec":{"containers":[{"image":"nginx:1.7.9","name":"nginx",
"spec":{"containers":[{"image":"nginx:1.14.2","name":"nginx",
"ports":[{"containerPort":80}]}]}}}}
# ...
spec:
@ -214,7 +214,7 @@ spec:
app: nginx
spec:
containers:
- image: nginx:1.7.9
- image: nginx:1.14.2
# ...
name: nginx
ports:
@ -253,7 +253,7 @@ metadata:
{"apiVersion":"apps/v1","kind":"Deployment",
"metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"},
"spec":{"minReadySeconds":5,"selector":{"matchLabels":{"app":nginx}},"template":{"metadata":{"labels":{"app":"nginx"}},
"spec":{"containers":[{"image":"nginx:1.7.9","name":"nginx",
"spec":{"containers":[{"image":"nginx:1.14.2","name":"nginx",
"ports":[{"containerPort":80}]}]}}}}
# ...
spec:
@ -271,7 +271,7 @@ spec:
app: nginx
spec:
containers:
- image: nginx:1.7.9
- image: nginx:1.14.2
# ...
name: nginx
ports:
@ -279,7 +279,7 @@ spec:
# ...
```
`nginx:1.7.9`에서 `nginx:1.11.9`로 이미지를 변경하기 위해 `simple_deployment.yaml`
`nginx:1.14.2`에서 `nginx:1.16.1`로 이미지를 변경하기 위해 `simple_deployment.yaml`
구성 파일을 업데이트 하고, `minReadySeconds` 필드를 삭제한다.
{{< codenew file="application/update_deployment.yaml" >}}
@ -301,7 +301,7 @@ kubectl get -f https://k8s.io/examples/application/simple_deployment.yaml -o yam
* `replicas` 필드는 `kubectl scale`에 의해 설정된 값 2를 유지한다.
이는 구성 파일에서 생략되었기 때문에 가능하다.
* `image` 필드는 `nginx:1.7.9`에서 `nginx:1.11.9`로 업데이트되었다.
* `image` 필드는 `nginx:1.14.2`에서 `nginx:1.16.1`로 업데이트되었다.
* `last-applied-configuration` 어노테이션은 새로운 이미지로 업데이트되었다.
* `minReadySeconds` 필드는 지워졌다.
* `last-applied-configuration` 어노테이션은 더 이상 `minReadySeconds` 필드를 포함하지 않는다.
@ -318,7 +318,7 @@ metadata:
{"apiVersion":"apps/v1","kind":"Deployment",
"metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"},
"spec":{"selector":{"matchLabels":{"app":nginx}},"template":{"metadata":{"labels":{"app":"nginx"}},
"spec":{"containers":[{"image":"nginx:1.11.9","name":"nginx",
"spec":{"containers":[{"image":"nginx:1.16.1","name":"nginx",
"ports":[{"containerPort":80}]}]}}}}
# ...
spec:
@ -336,7 +336,7 @@ spec:
app: nginx
spec:
containers:
- image: nginx:1.11.9 # Set by `kubectl apply`
- image: nginx:1.16.1 # Set by `kubectl apply`
# ...
name: nginx
ports:
@ -458,7 +458,7 @@ metadata:
{"apiVersion":"apps/v1","kind":"Deployment",
"metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"},
"spec":{"minReadySeconds":5,"selector":{"matchLabels":{"app":nginx}},"template":{"metadata":{"labels":{"app":"nginx"}},
"spec":{"containers":[{"image":"nginx:1.7.9","name":"nginx",
"spec":{"containers":[{"image":"nginx:1.14.2","name":"nginx",
"ports":[{"containerPort":80}]}]}}}}
# ...
spec:
@ -476,7 +476,7 @@ spec:
app: nginx
spec:
containers:
- image: nginx:1.7.9
- image: nginx:1.14.2
# ...
name: nginx
ports:
@ -516,7 +516,7 @@ metadata:
{"apiVersion":"apps/v1","kind":"Deployment",
"metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"},
"spec":{"selector":{"matchLabels":{"app":nginx}},"template":{"metadata":{"labels":{"app":"nginx"}},
"spec":{"containers":[{"image":"nginx:1.11.9","name":"nginx",
"spec":{"containers":[{"image":"nginx:1.16.1","name":"nginx",
"ports":[{"containerPort":80}]}]}}}}
# ...
spec:
@ -534,7 +534,7 @@ spec:
app: nginx
spec:
containers:
- image: nginx:1.11.9 # Set by `kubectl apply`
- image: nginx:1.16.1 # Set by `kubectl apply`
# ...
name: nginx
ports:
@ -777,7 +777,7 @@ spec:
app: nginx
spec:
containers:
- image: nginx:1.7.9
- image: nginx:1.14.2
imagePullPolicy: IfNotPresent # defaulted by apiserver
name: nginx
ports:
@ -817,7 +817,7 @@ spec:
spec:
containers:
- name: nginx
image: nginx:1.7.9
image: nginx:1.14.2
ports:
- containerPort: 80
@ -832,7 +832,7 @@ spec:
spec:
containers:
- name: nginx
image: nginx:1.7.9
image: nginx:1.14.2
ports:
- containerPort: 80
@ -850,7 +850,7 @@ spec:
spec:
containers:
- name: nginx
image: nginx:1.7.9
image: nginx:1.14.2
ports:
- containerPort: 80
@ -868,7 +868,7 @@ spec:
spec:
containers:
- name: nginx
image: nginx:1.7.9
image: nginx:1.14.2
ports:
- containerPort: 80
```

View File

@ -139,10 +139,10 @@ TODO(pwittrock): 구현이 이루어지면 주석을 해제한다.
다음은 관련 예제이다.
```sh
kubectl create service clusterip my-svc --clusterip="None" -o yaml --dry-run | kubectl set selector --local -f - 'environment=qa' -o yaml | kubectl create -f -
kubectl create service clusterip my-svc --clusterip="None" -o yaml --dry-run=client | kubectl set selector --local -f - 'environment=qa' -o yaml | kubectl create -f -
```
1. `kubectl create service -o yaml --dry-run` 커맨드는 서비스에 대한 구성을 생성하지만, 이를 쿠버네티스 API 서버에 전송하는 대신 YAML 형식으로 stdout에 출력한다.
1. `kubectl create service -o yaml --dry-run=client` 커맨드는 서비스에 대한 구성을 생성하지만, 이를 쿠버네티스 API 서버에 전송하는 대신 YAML 형식으로 stdout에 출력한다.
1. `kubectl set selector --local -f - -o yaml` 커맨드는 stdin으로부터 구성을 읽어, YAML 형식으로 stdout에 업데이트된 구성을 기록한다.
1. `kubectl create -f -` 커맨드는 stdin을 통해 제공된 구성을 사용하여 오브젝트를 생성한다.
@ -152,7 +152,7 @@ kubectl create service clusterip my-svc --clusterip="None" -o yaml --dry-run | k
다음은 관련 예제이다.
```sh
kubectl create service clusterip my-svc --clusterip="None" -o yaml --dry-run > /tmp/srv.yaml
kubectl create service clusterip my-svc --clusterip="None" -o yaml --dry-run=client > /tmp/srv.yaml
kubectl create --edit -f /tmp/srv.yaml
```

View File

@ -791,6 +791,12 @@ kubectl get -k ./
kubectl describe -k ./
```
다음 명령을 실행해서 디플로이먼트 오브젝트 `dev-my-nginx` 를 매니페스트가 적용된 경우의 클러스터 상태와 비교한다.
```shell
kubectl diff -k ./
```
디플로이먼트 오브젝트 `dev-my-nginx`를 삭제하려면 다음 명령어를 실행한다.
```shell

View File

@ -291,7 +291,7 @@ API에 접속하려면 클러스터 관리자는 다음을 확인해야 한다.
## 구성가능한 스케일링 동작 지원
[v1.17](https://github.com/kubernetes/enhancements/blob/master/keps/sig-autoscaling/20190307-configurable-scale-velocity-for-hpa.md)
[v1.18](https://github.com/kubernetes/enhancements/blob/master/keps/sig-autoscaling/20190307-configurable-scale-velocity-for-hpa.md)
부터 `v2beta2` API는 HPA `behavior` 필드를 통해
스케일링 동작을 구성할 수 있다.
동작은 `behavior` 필드 아래의 `scaleUp` 또는 `scaleDown`

View File

@ -26,7 +26,7 @@ grep -E --color 'vmx|svm' /proc/cpuinfo
{{% tab name="맥OS" %}}
맥OS에서 가상화 지원 여부를 확인하려면, 아래 명령어를 터미널에서 실행한다.
```
sysctl -a | grep -E --color 'machdep.cpu.features|VMX'
sysctl -a | grep -E --color 'machdep.cpu.features|VMX'
```
만약 출력 중에 (색상으로 강조된) `VMX`를 볼 수 있다면, VT-x 기능이 머신에서 활성화된 것이다.
{{% /tab %}}
@ -74,7 +74,7 @@ kubectl이 설치되었는지 확인한다. kubectl은 [kubectl 설치하고 설
• [VirtualBox](https://www.virtualbox.org/wiki/Downloads)
Minikube는 쿠버네티스 컴포넌트를 VM이 아닌 호스트에서도 동작하도록 `--vm-driver=none` 옵션도 지원한다.
Minikube는 쿠버네티스 컴포넌트를 VM이 아닌 호스트에서도 동작하도록 `--driver=none` 옵션도 지원한다.
이 드라이버를 사용하려면 [도커](https://www.docker.com/products/docker-desktop) 와 Linux 환경이 필요하지만, 하이퍼바이저는 필요하지 않다.
데비안(Debian) 또는 파생된 배포판에서 `none` 드라이버를 사용하는 경우,
@ -83,7 +83,7 @@ Minikube에서는 동작하지 않는 스냅 패키지 대신 도커용 `.deb`
{{< caution >}}
`none` VM 드라이버는 보안과 데이터 손실 이슈를 일으킬 수 있다.
`--vm-driver=none` 을 사용하기 전에 [이 문서](https://minikube.sigs.k8s.io/docs/reference/drivers/none/)를 참조해서 더 자세한 내용을 본다.
`--driver=none` 을 사용하기 전에 [이 문서](https://minikube.sigs.k8s.io/docs/reference/drivers/none/)를 참조해서 더 자세한 내용을 본다.
{{< /caution >}}
Minikube는 도커 드라이브와 비슷한 `vm-driver=podman` 도 지원한다. 슈퍼사용자 권한(root 사용자)으로 실행되는 Podman은 컨테이너가 시스템에서 사용 가능한 모든 기능에 완전히 접근할 수 있는 가장 좋은 방법이다.
@ -214,12 +214,12 @@ Minikube 설치를 마친 후, 현재 CLI 세션을 닫고 재시작한다. Mini
{{< note >}}
`minikube start``--vm-driver` 를 설정하려면, 아래에 `<driver_name>` 로 소문자로 언급된 곳에 설치된 하이퍼바이저의 이름을 입력한다. `--vm-driver` 값의 전체 목록은 [VM driver 문서에서 지정하기](https://kubernetes.io/docs/setup/learning-environment/minikube/#specifying-the-vm-driver)에서 확인할 수 있다.
`minikube start``--driver` 를 설정하려면, 아래에 `<driver_name>` 로 소문자로 언급된 곳에 설치된 하이퍼바이저의 이름을 입력한다. `--driver` 값의 전체 목록은 [VM driver 문서에서 지정하기](https://kubernetes.io/docs/setup/learning-environment/minikube/#specifying-the-vm-driver)에서 확인할 수 있다.
{{< /note >}}
```shell
minikube start --vm-driver=<driver_name>
minikube start --driver=<driver_name>
```
`minikube start` 가 완료되면, 아래 명령을 실행해서 클러스터의 상태를 확인한다.

View File

@ -0,0 +1,19 @@
apiVersion: v1
kind: LimitRange
metadata:
name: limit-mem-cpu-per-container
spec:
limits:
- max:
cpu: "800m"
memory: "1Gi"
min:
cpu: "100m"
memory: "99Mi"
default:
cpu: "700m"
memory: "900Mi"
defaultRequest:
cpu: "110m"
memory: "111Mi"
type: Container

View File

@ -0,0 +1,10 @@
apiVersion: v1
kind: LimitRange
metadata:
name: limit-mem-cpu-per-pod
spec:
limits:
- max:
cpu: "2"
memory: "2Gi"
type: Pod

View File

@ -0,0 +1,9 @@
apiVersion: v1
kind: LimitRange
metadata:
name: limit-memory-ratio-pod
spec:
limits:
- maxLimitRequestRatio:
memory: 2
type: Pod

View File

@ -0,0 +1,37 @@
apiVersion: v1
kind: Pod
metadata:
name: busybox1
spec:
containers:
- name: busybox-cnt01
image: busybox
command: ["/bin/sh"]
args: ["-c", "while true; do echo hello from cnt01; sleep 10;done"]
resources:
requests:
memory: "100Mi"
cpu: "100m"
limits:
memory: "200Mi"
cpu: "500m"
- name: busybox-cnt02
image: busybox
command: ["/bin/sh"]
args: ["-c", "while true; do echo hello from cnt02; sleep 10;done"]
resources:
requests:
memory: "100Mi"
cpu: "100m"
- name: busybox-cnt03
image: busybox
command: ["/bin/sh"]
args: ["-c", "while true; do echo hello from cnt03; sleep 10;done"]
resources:
limits:
memory: "200Mi"
cpu: "500m"
- name: busybox-cnt04
image: busybox
command: ["/bin/sh"]
args: ["-c", "while true; do echo hello from cnt04; sleep 10;done"]

View File

@ -0,0 +1,37 @@
apiVersion: v1
kind: Pod
metadata:
name: busybox2
spec:
containers:
- name: busybox-cnt01
image: busybox
command: ["/bin/sh"]
args: ["-c", "while true; do echo hello from cnt01; sleep 10;done"]
resources:
requests:
memory: "100Mi"
cpu: "100m"
limits:
memory: "200Mi"
cpu: "500m"
- name: busybox-cnt02
image: busybox
command: ["/bin/sh"]
args: ["-c", "while true; do echo hello from cnt02; sleep 10;done"]
resources:
requests:
memory: "100Mi"
cpu: "100m"
- name: busybox-cnt03
image: busybox
command: ["/bin/sh"]
args: ["-c", "while true; do echo hello from cnt03; sleep 10;done"]
resources:
limits:
memory: "200Mi"
cpu: "500m"
- name: busybox-cnt04
image: busybox
command: ["/bin/sh"]
args: ["-c", "while true; do echo hello from cnt04; sleep 10;done"]

View File

@ -0,0 +1,13 @@
apiVersion: v1
kind: Pod
metadata:
name: busybox3
spec:
containers:
- name: busybox-cnt01
image: busybox
resources:
limits:
memory: "300Mi"
requests:
memory: "100Mi"

View File

@ -0,0 +1,10 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-limit-greater
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi

View File

@ -0,0 +1,10 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-limit-lower
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 500Mi

View File

@ -0,0 +1,11 @@
apiVersion: v1
kind: LimitRange
metadata:
name: storagelimits
spec:
limits:
- type: PersistentVolumeClaim
max:
storage: 2Gi
min:
storage: 1Gi

View File

@ -1,4 +1,4 @@
apiVersion: apps/v1 # apps/v1beta2를 사용하는 1.9.0보다 더 이전의 버전용
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: nginx-deployment
@ -6,7 +6,7 @@ spec:
selector:
matchLabels:
app: nginx
replicas: 2 # 템플릿에 매칭되는 파드 2개를 구동하는 디플로이먼트임
replicas: 2 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
@ -14,6 +14,6 @@ spec:
spec:
containers:
- name: nginx
image: nginx:1.7.9
image: nginx:1.14.2
ports:
- containerPort: 80

View File

@ -14,6 +14,6 @@ spec:
spec:
containers:
- name: nginx
image: nginx:1.7.9
image: nginx:1.14.2
ports:
- containerPort: 80

View File

@ -13,6 +13,6 @@ spec:
spec:
containers:
- name: nginx
image: nginx:1.11.9 # update the image
image: nginx:1.16.1 # update the image
ports:
- containerPort: 80

View File

@ -15,6 +15,8 @@ spec:
name: fluentd-elasticsearch
spec:
tolerations:
# this toleration is to have the daemonset runnable on master nodes
# remove it if your masters can't run pods
- key: node-role.kubernetes.io/master
effect: NoSchedule
containers:

View File

@ -16,6 +16,6 @@ spec:
spec:
containers:
- name: nginx
image: nginx:1.7.9
image: nginx:1.14.2
ports:
- containerPort: 80

View File

@ -0,0 +1,10 @@
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
nodeName: foo-node # 특정 노드에 파드 스케줄
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent

View File

@ -0,0 +1,17 @@
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: example
spec:
privileged: false # 특권을 가진 파드는 허용금지!
# 나머지는 일부 필수 필드를 채운다.
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
runAsUser:
rule: RunAsAny
fsGroup:
rule: RunAsAny
volumes:
- '*'

View File

@ -0,0 +1,27 @@
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: privileged
annotations:
seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*'
spec:
privileged: true
allowPrivilegeEscalation: true
allowedCapabilities:
- '*'
volumes:
- '*'
hostNetwork: true
hostPorts:
- min: 0
max: 65535
hostIPC: true
hostPID: true
runAsUser:
rule: 'RunAsAny'
seLinux:
rule: 'RunAsAny'
supplementalGroups:
rule: 'RunAsAny'
fsGroup:
rule: 'RunAsAny'

View File

@ -0,0 +1,48 @@
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: restricted
annotations:
seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default,runtime/default'
apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default'
seccomp.security.alpha.kubernetes.io/defaultProfileName: 'runtime/default'
apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default'
spec:
privileged: false
# 루트로의 에스컬레이션을 방지하는데 필요하다.
allowPrivilegeEscalation: false
# 이것은 루트가 아닌 사용자 + 권한 에스컬레이션을 허용하지 않는 것으로 중복이지만,
# 심층 방어를 위해 이를 제공한다.
requiredDropCapabilities:
- ALL
# 기본 볼륨 유형을 허용한다.
volumes:
- 'configMap'
- 'emptyDir'
- 'projected'
- 'secret'
- 'downwardAPI'
# 클러스터 관리자가 설정한 퍼시스턴트볼륨을 사용하는 것이 안전하다고 가정한다.
- 'persistentVolumeClaim'
hostNetwork: false
hostIPC: false
hostPID: false
runAsUser:
# 루트 권한없이 컨테이너를 실행해야 한다.
rule: 'MustRunAsNonRoot'
seLinux:
# 이 정책은 노드가 SELinux가 아닌 AppArmor를 사용한다고 가정한다.
rule: 'RunAsAny'
supplementalGroups:
rule: 'MustRunAs'
ranges:
# 루트 그룹을 추가하지 않는다.
- min: 1
max: 65535
fsGroup:
rule: 'MustRunAs'
ranges:
# 루트 그룹을 추가하지 않는다.
- min: 1
max: 65535
readOnlyRootFilesystem: false

View File

@ -0,0 +1,91 @@
---
title: 파트너
bigheader: 쿠버네티스 파트너
abstract: 쿠버네티스 생태계의 성장
class: gridPage
cid: partners
---
<section id="users">
<main class="main-section">
<h5>쿠버네티스는 파트너와 협력하여 다양하게 보완하는 플랫폼을 지원하는 강력하고 활기찬 코드베이스를 만들어갑니다.</h5>
<div class="col-container">
<div class="col-nav">
<center>
<h5>
<b>공인 쿠버네티스 서비스 공급자(Kubernetes Certified Service Providers, KCSP)</b>
</h5>
<br>기업들이 쿠버네티스를 성공적으로 채택하도록 도와주는 풍부한 경험을 가진 노련한 서비스 공급자입니다.
<br><br><br>
<button id="kcsp" class="button" onClick="updateSrc(this.id)">KCSP 파트너 보기</button>
<br><br><a href="https://www.cncf.io/certification/kcsp/">KCSP</a>에 관심이 있으신가요?
</center>
</div>
<div class="col-nav">
<center>
<h5>
<b>공인 쿠버네티스 배포, 호스트된 플랫폼 그리고 설치 프로그램</b>
</h5>소프트웨어 적합성은 모든 벤더의 쿠버네티스 버전이 필요한 API를 지원하도록 보장합니다.
<br><br><br>
<button id="conformance" class="button" onClick="updateSrc(this.id)">적합한 파트너 보기</button>
<br><br><a href="https://www.cncf.io/certification/software-conformance/">공인 쿠버네티스</a>에 관심이 있으신가요?
</center>
</div>
<div class="col-nav">
<center>
<h5><b>쿠버네티스 교육 파트너(Kubernetes Training Partners, KTP)</b></h5>
<br>클라우드 네이티브 기술 교육 경험이 풍부하고 노련한 교육 공급자입니다.
<br><br><br><br>
<button id="ktp" class="button" onClick="updateSrc(this.id)">KTP 파트너 보기</button>
<br><br><a href="https://www.cncf.io/certification/training/">KTP</a>에 관심이 있으신가요?
</center>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script type="text/javascript">
var defaultLink = "https://landscape.cncf.io/category=kubernetes-certified-service-provider&format=card-mode&grouping=category&embed=yes";
var firstLink = "https://landscape.cncf.io/category=certified-kubernetes-distribution,certified-kubernetes-hosted,certified-kubernetes-installer&format=card-mode&grouping=category&embed=yes";
var secondLink = "https://landscape.cncf.io/category=kubernetes-training-partner&format=card-mode&grouping=category&embed=yes";
function updateSrc(buttonId) {
if (buttonId == "kcsp") {
$("#landscape").attr("src",defaultLink);
window.location.hash = "#kcsp";
}
if (buttonId == "conformance") {
$("#landscape").attr("src",firstLink);
window.location.hash = "#conformance";
}
if (buttonId == "ktp") {
$("#landscape").attr("src",secondLink);
window.location.hash = "#ktp";
}
}
// Automatically load the correct iframe based on the URL fragment
document.addEventListener('DOMContentLoaded', function() {
var showContent = "kcsp";
if (window.location.hash) {
console.log('hash is:', window.location.hash.substring(1));
showContent = window.location.hash.substring(1);
}
updateSrc(showContent);
});
</script>
<body>
<div id="frameHolder">
<iframe id="landscape" title="CNCF Landscape" frameBorder="0" scrolling="no" style="width: 1px; min-width: 100%" src=""></iframe>
<script src="https://landscape.cncf.io/iframeResizer.js"></script>
</div>
</body>
</main>
</section>
<style>
{{< include "partner-style.css" >}}
</style>
<script>
{{< include "partner-script.js" >}}
</script>