Fourth Korean l10n work for release 1.18
- Translate docs/reference/issues-security/_index.md into Korean (#21145) - Translate tasks/administer-cluster/kubeadm/adding-windows-nodes.md into Korean (#21003) - Translate manage-resources/memory-default-namespace.md into Korean (#21089) - Translate tasks/configure-pod-container/pull-image-private-registry in Korean (#21036) - Translate contribute/advanced.md into Korean (#21002) - Update to Outdated files in the dev-1.18-ko.4 branch. (#21102) - Translate manage-resources/cpu-constraint-namespace.md into Korean (#21048) - Translate manage-resources/memory-constraint-namespace.md into Korean (#21091) - Translate setup/release/notes.md in Korean (#21158) - Translate manage-resources/quota-pod-namespace.md into Korean (#21087) - Translate tasks/administer-cluster/kubeadm/upgrading-windows-nodes.md into Korean (#20999) - Translate tasks/administer-cluster/kubeadm/kubeadm-certs.md into Korean (#21000) - Translate manage-resources/quota-memory-cpu-namespace.md into Korean (#21088) - Translate manage-resources/cpu-default-namespace.md into Korean (#21090) - Translate contribute/suggesting-improvements.md into Korean (#21001) - Translate quality-service-pod in Korean (#21081) Co-authored-by: Jerry Park <jaehwa@gmail.com> Co-authored-by: Jesang Myung <jesang.myung@gmail.com> Co-authored-by: DongMoon Kim <dmoons.kim@gmail.com> Co-authored-by: Jesang Myung <jesang.myung@gmail.com> Co-authored-by: Yuk, Yongsu <ysyukr@gmail.com> Co-authored-by: bluefriday <bluefriday86@gmail.com>
This commit is contained in:
@@ -1,120 +0,0 @@
|
||||
---
|
||||
title: 마스터-노드 커뮤니케이션
|
||||
content_template: templates/concept
|
||||
weight: 20
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
이 문서는 마스터(실제 apiserver)와 쿠버네티스 클러스터 사이의
|
||||
커뮤니케이션 경로를 나열해 본다. 그 목적은 신뢰할 수 없는 네트워크
|
||||
(또는 클라우드 제공자의 공인 IP만으로 구성된 네트워크)에서도 동작될 수 있는
|
||||
클러스터 구축을 위해, 네트워크의 구성을 강화하는 사용자
|
||||
맞춤형 설치를 허용하기 위함이다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
## 클러스터에서 마스터로
|
||||
|
||||
클러스터에서 마스터로의 모든 커뮤니케이션 경로는 apiserver에서 끝난다
|
||||
(어떤 다른 마스터 컴포넌트도 원격 서비스를 노출하기 위해 설계되지 않는다).
|
||||
전형적인 배포에서, apiserver는 하나 또는 그 이상의 클라이언트
|
||||
[인증](/docs/reference/access-authn-authz/authentication/) 형태가
|
||||
사용가능토록 하여 안전한 HTTPS 포트(443)를 통해 원격 연결에 대해 서비스 리슨하도록 구성된다.
|
||||
특히 [익명의 요청](/docs/reference/access-authn-authz/authentication/#anonymous-requests)
|
||||
또는 [서비스 계정 토큰](/docs/reference/access-authn-authz/authentication/#service-account-tokens)이
|
||||
허용된 경우에는 하나 또는 그 이상의
|
||||
[인가](/docs/reference/access-authn-authz/authorization/) 형태가 사용 가능해야만 한다.
|
||||
|
||||
노드는 유효한 클라이언트 자격증명과 함께 apiserver에 안전하게 접속할 수 있는
|
||||
그런 클러스터용 공인 루트 인증서를 가지고 제공되어야 한다.
|
||||
예를 들어, 기본 GKE 배포의 경우, kubelet에 제공되는 클라이언트 자격증명은
|
||||
클라이언트 인증서의 형태로 존재한다. kubelet 클라이언트 인증서에
|
||||
대한 자동화 프로비저닝에 대해서는
|
||||
[kubelet TLS bootstrapping](/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/)을 참고한다.
|
||||
|
||||
apiserver에 접속하려는 파드는 서비스 계정에 영향력을 발휘함으로써 안전하게
|
||||
그리 행할 수 있으며 따라서 쿠버네티스는 인스턴스화 될 때 공인 루트 인증서와
|
||||
유효한 베어러 토큰을 파드 속으로 자동 주입할 수 있게 된다.
|
||||
(모든 네임스페이스 내) `kubernetes` 서비스는 apiserver 상의 HTTPS 엔드포인트로
|
||||
(kube-proxy를 통해) 리다이렉트 되는 가상 IP 주소를
|
||||
가지고 구성된다.
|
||||
|
||||
마스터 컴포넌트는 또한 신뢰할 수 있는 포트를 통해 클러스터 apiserver와 소통한다.
|
||||
|
||||
결과적으로, 클러스터 (노드 그리고 노드에서 동작하는 파드)에서
|
||||
마스터로의 기본 동작 모드는 기본적으로 안전하며
|
||||
신뢰할 수 없는그리고/또는 공인 네트워크 상에서 동작할 수 있다.
|
||||
|
||||
## 마스터에서 클러스터로
|
||||
|
||||
마스터(apiserver)에서 클러스터로의 두 가지 주된 커뮤니케이션 경로가 존재한다.
|
||||
첫 번째는 클러스터 내 각 노드를 동작시키는 apiserver에서 kubelet 프로세스로의
|
||||
경로이다. 두 번째는 apiserver에서 apiserver의 프록시 기능을 통한 임의의 노드,
|
||||
파드 또는 서비스로의 경로이다.
|
||||
|
||||
### apiserver에서 kubelet으로
|
||||
|
||||
apiserver에서 kubelet으로의 연결은 다음을 위해 이용된다.
|
||||
|
||||
* 파드에 대한 로그 가져오기
|
||||
* 동작중인 파드에 (kubectl을 통해) 연관짓기
|
||||
* kubelet의 포트 포워딩 기능 제공하기
|
||||
|
||||
이 연결은 kubelet의 HTTPS 엔드포인트에서 끝난다. 기본적으로,
|
||||
apiserver는 kubelet의 제공 인증서를 확인하지 않는데,
|
||||
이는 연결에 대한 중간자 공격을 당하게 하고, 신뢰할 수 없는
|
||||
그리고/또는 공인 네트워크에서 운영하기에는 **불안** 하게 만든다.
|
||||
|
||||
이 연결을 확인하려면, apiserver에 kubelet의 제공 인증서 확인을
|
||||
위해 사용하는 루트 인증서 번들로 `--kubelet-certificate-authority`
|
||||
플래그를 이용한다
|
||||
|
||||
그것이 불가능한 경우, 신뢰할 수 없는 또는 공인 네트워크에 대한 연결을 피하고 싶다면,
|
||||
apiserver와 kubelet 사이에 [SSH 터널링](/ko/docs/concepts/architecture/master-node-communication/#ssh-터널)을
|
||||
사용한다.
|
||||
|
||||
마지막으로, kubelet API를 안전하게 하기 위해
|
||||
[Kubelet 인증 그리고/또는 인가](/docs/admin/kubelet-authentication-authorization/)가 활성화 되어야만 한다.
|
||||
|
||||
### apiserver에서 노드, 파드, 그리고 서비스로
|
||||
|
||||
apiserver에서 노드, 파드, 또는 서비스로의 연결은 보통 HTTP 연결을
|
||||
기본으로 하므로 인증도 암호화도 되지 않는다. API URL 내 노드, 파드, 또는 서비스 이름에
|
||||
`https:` 프리픽스를 붙임으로써 안전한 HTTPS 연결로 동작될 수 있지만,
|
||||
HTTPS 엔드포인트에 의해 제공되는 인증서를 확인하지 않으며
|
||||
클라이언트 자격증명 또한 제공하지 않는다.
|
||||
그래서 연결이 암호화될 동안, 어떠한 무결성도 제공되지 않을 것이다.
|
||||
이러한 연결들은 신뢰할 수 없는 그리고/또는 공인 네트워크에서 동작하기에
|
||||
**현재로서는 안전하지 않다**.
|
||||
|
||||
### SSH 터널
|
||||
|
||||
쿠버네티스는 마스터 → 클러스터 통신 경로를 보호하는 SSH 터널을
|
||||
지원한다. 이 구성에서 apiserver는 클러스터의 각 노드에서 SSH 터널을
|
||||
시작하고(포트 22번으로 수신 대기하는 ssh 서버에 연결), 터널을 통해
|
||||
kubelet, 노드, 파드 또는 서비스로 향하는 모든 트래픽을 전달한다.
|
||||
이 터널은 실행중인 노드의 트래픽이 외부로 노출되지
|
||||
않도록 보장한다.
|
||||
|
||||
SSH 터널은 현재 사용 중단(deprecated)되었으므로, 무엇을 하고 있는지 알지 못하는
|
||||
한 터널을 이용하지 말아야 한다. Konnectivity 서비스는 이 통신
|
||||
채널을 대체한다.
|
||||
|
||||
### Konnectivity 서비스
|
||||
{{< feature-state for_k8s_version="v1.18" state="beta" >}}
|
||||
|
||||
SSH 터널을 대체하는 Konnectivity 서비스는 마스터 → 클러스터 통신을
|
||||
위한 TCP 수준의 프록시를 제공한다. Konnectivity는 마스터
|
||||
네트워크와 클러스터 네트워크에서 실행되는 Konnectivity 서버와
|
||||
에이전트 두 부분으로 구성된다. Konnectivity 에이전트는
|
||||
Konnectivity 서버에 대한 연결을 시작하고, 유지한다.
|
||||
이 연결을 통해 모든 마스터 → 클러스터로의 트래픽이 통과하게 된다.
|
||||
|
||||
클러스터에서 설정하는 방법에 대해서는 [Konnectivity 서비스 구성](/docs/tasks/setup-konnectivity/)
|
||||
하기를 참고한다.
|
||||
|
||||
{{% /capture %}}
|
||||
@@ -6,18 +6,112 @@ weight: 10
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
하나의 노드는 쿠버네티스에서 하나의 워커 머신으로, 이전에는 `미니언`으로 알려졌다. 노드는
|
||||
클러스터에 따라, VM 또는 물리 머신이 될 수 있다. 각 노드는
|
||||
[파드](/ko/docs/concepts/workloads/pods/pod/)를 동작시키기 위해 필요한 서비스를 포함하며 마스터 컴포넌트에 의해 관리된다. 노드 상의 서비스는 [컨테이너 런타임](/ko/docs/concepts/overview/components/#컨테이너-런타임), kubelet 그리고 kube-proxy를 포함한다. 보다
|
||||
상세한 내용은 아키텍처 문서 내
|
||||
[쿠버네티스 노드](https://git.k8s.io/community/contributors/design-proposals/architecture/architecture.md#the-kubernetes-node)
|
||||
섹션을 확인한다.
|
||||
쿠버네티스는 컨테이너를 파드내에 배치하고 _노드_ 에서 실행함으로 워크로드를 구동한다.
|
||||
노드는 클러스터에 따라 가상 또는 물리적 머신일 수 있다. 각 노드에는
|
||||
{{< glossary_tooltip text="컨트롤 플레인" term_id="control-plane" >}}이라는
|
||||
{{< glossary_tooltip text="파드" term_id="pod" >}}를
|
||||
실행하는데 필요한 서비스가 포함되어 있다.
|
||||
|
||||
일반적으로 클러스터에는 여러개의 노드가 있으며, 학습 또는 리소스가 제한되는
|
||||
환경에서는 하나만 있을 수도 있다.
|
||||
|
||||
노드의 [컴포넌트](/ko/docs/concepts/overview/components/#노드-컴포넌트)에는
|
||||
{{< glossary_tooltip text="kubelet" term_id="kubelet" >}},
|
||||
{{< glossary_tooltip text="컨테이너 런타임" term_id="container-runtime" >}}
|
||||
그리고 {{< glossary_tooltip text="kube-proxy" term_id="kube-proxy" >}}가 포함된다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
## 관리
|
||||
|
||||
{{< glossary_tooltip text="API 서버" term_id="kube-apiserver" >}}에 노드를 추가하는 두가지 주요 방법이 있다.
|
||||
|
||||
1. 노드의 kubelet으로 컨트롤 플레인에 자체 등록
|
||||
2. 사용자 또는 다른 사용자가 노드 오브젝트를 수동으로 추가
|
||||
|
||||
노드 오브젝트 또는 노드의 kubelet으로 자체 등록한 후 컨트롤 플레인은 새 노드 오브젝트가 유효한지 확인한다.
|
||||
예를 들어 다음 JSON 매니페스트에서 노드를 만들려는 경우이다.
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": "Node",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "10.240.79.157",
|
||||
"labels": {
|
||||
"name": "my-first-k8s-node"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
쿠버네티스는 내부적으로 노드 오브젝트를 생성한다(표시한다). 쿠버네티스는
|
||||
kubelet이 노드의 `metadata.name` 필드와 일치하는 API 서버에 등록이 되어있는지 확인한다.
|
||||
노드가 정상이면(필요한 모든 서비스가 실행중인 경우) 파드를 실행할 수 있게 된다.
|
||||
그렇지 않으면, 해당 노드는 정상이 될때까지 모든 클러스터 활동에
|
||||
대해 무시된다.
|
||||
|
||||
{{< note >}}
|
||||
쿠버네티스는 유효하지 않은 노드 오브젝트를 유지하고, 노드가
|
||||
정상적인지 확인한다.
|
||||
|
||||
상태 확인을 중지하려면 사용자 또는 {{< glossary_tooltip term_id="controller" text="컨트롤러">}}에서
|
||||
노드 오브젝트를 명시적으로 삭제해야한다.
|
||||
{{< /note >}}
|
||||
|
||||
노드 오브젝트의 이름은 유효한 [DNS 서브도메인 이름](/ko/docs/concepts/overview/working-with-objects/names/#dns-서브도메인-이름들)이어야 한다.
|
||||
|
||||
### 노드에 대한 자체-등록
|
||||
|
||||
kubelet 플래그 `--register-node`는 참(기본값)일 경우, kubelet 은 API 서버에
|
||||
스스로 등록을 시도할 것이다. 이는 대부분의 배포판에 의해 이용되는, 선호하는 패턴이다.
|
||||
|
||||
자체-등록에 대해, kubelet은 다음 옵션과 함께 시작된다.
|
||||
|
||||
- `--kubeconfig` - apiserver에 스스로 인증하기 위한 자격증명에 대한 경로.
|
||||
- `--cloud-provider` - 자신에 대한 메터데이터를 읽기 위해 어떻게 {{< glossary_tooltip text="클라우드 제공자" term_id="cloud-provider" >}}와 소통할지에 대한 방법.
|
||||
- `--register-node` - 자동으로 API 서버에 등록.
|
||||
- `--register-with-taints` - 주어진 taint 리스트 (콤마로 분리된 `<key>=<value>:<effect>`)를 가진 노드 등록. `register-node`가 거짓이면 동작 안함.
|
||||
- `--node-ip` - 노드의 IP 주소.
|
||||
- `--node-labels` - 클러스터에 노드를 등록할 때 추가 할 {{< glossary_tooltip text="레이블" term_id="label" >}}([NodeRestriction admission plugin](/docs/reference/access-authn-authz/admission-controllers/#noderestriction)에 의해 적용되는 레이블 제한 사항 참고).
|
||||
- `--node-status-update-frequency` - 얼마나 자주 kubelet이 마스터에 노드 상태를 게시할 지 정의.
|
||||
|
||||
[Node authorization mode](/docs/reference/access-authn-authz/node/)와
|
||||
[NodeRestriction admission plugin](/docs/reference/access-authn-authz/admission-controllers/#noderestriction)이 활성화 되면,
|
||||
kubelets 은 자신의 노드 리소스를 생성/수정할 권한을 가진다.
|
||||
|
||||
#### 수동 노드 관리
|
||||
|
||||
{{< glossary_tooltip text="kubectl" term_id="kubectl" >}}을
|
||||
사용해서 노드 오브젝트를 생성하고 수정할 수 있다.
|
||||
|
||||
노드 오브젝트를 수동으로 생성하려면 kubelet 플래그를 `--register-node=false` 로 설정한다.
|
||||
|
||||
`--register-node` 설정과 관계 없이 노드 오브젝트를 수정할 수 있다.
|
||||
예를 들어 기존 노드에 레이블을 설정하거나, 스케줄 불가로 표시할 수 있다.
|
||||
|
||||
파드의 노드 셀렉터와 함께 노드의 레이블을 사용해서 스케줄링을 제어할 수 있다.
|
||||
예를 들어, 사용 가능한 노드의 하위 집합에서만 실행되도록
|
||||
파드를 제한할 수 있다.
|
||||
|
||||
노드를 스케줄 불가로 표시하면 스케줄러가 해당 노드에 새 파드를 배치할 수 없지만,
|
||||
노드에 있는 기존 파드에는 영향을 미치지 않는다.
|
||||
이는 노드 재부팅 또는 기타 유지보수 준비 단계에서 유용하다.
|
||||
|
||||
노드를 스케줄 불가로 표시하려면 다음을 실행한다.
|
||||
|
||||
```shell
|
||||
kubectl cordon $NODENAME
|
||||
```
|
||||
|
||||
{{< note >}}
|
||||
{{< glossary_tooltip term_id="daemonset" >}}에 포함되는 일부 파드는
|
||||
스케줄 불가 노드에서 실행될 수 있다. 일반적으로 데몬셋은 워크로드 애플리케이션을
|
||||
비우는 경우에도 노드에서 실행되어야 하는 노드 로컬 서비스를 제공한다.
|
||||
{{< /note >}}
|
||||
|
||||
## 노드 상태
|
||||
|
||||
노드의 상태는 다음의 정보를 포함한다.
|
||||
@@ -27,11 +121,13 @@ weight: 10
|
||||
* [용량과 할당가능](#capacity)
|
||||
* [정보](#info)
|
||||
|
||||
노드의 상태와 상세 정보는 다음 커맨드를 통해 확인할 수 있다.
|
||||
`kubectl` 을 사용해서 노드 상태와 기타 세부 정보를 볼수 있다.
|
||||
|
||||
```shell
|
||||
kubectl describe node <insert-node-name-here>
|
||||
```
|
||||
각 섹션은 아래 상세하게 기술되었다.
|
||||
|
||||
출력되는 각 섹션은 아래에 설명되어있다.
|
||||
|
||||
### 주소 {#addresses}
|
||||
|
||||
@@ -46,13 +142,21 @@ kubectl describe node <insert-node-name-here>
|
||||
|
||||
`conditions` 필드는 모든 `Running` 노드의 상태를 기술한다. 컨디션의 예로 다음을 포함한다.
|
||||
|
||||
| Node Condition | Description |
|
||||
{{< table caption = "노드 컨디션과 각 컨디션이 적용되는 시기에 대한 설명들이다." >}}
|
||||
| 노드 컨디션 | 설명 |
|
||||
|----------------|-------------|
|
||||
| `Ready` | 노드가 상태 양호하며 파드를 수용할 준비가 되어 있는 경우 `True`, 노드의 상태가 불량하여 파드를 수용하지 못할 경우 `False`, 그리고 노드 컨트롤러가 마지막 `node-monitor-grace-period` (기본값 40 기간 동안 노드로부터 응답을 받지 못한 경우) `Unknown` |
|
||||
| `DiskPressure` | 디스크 사이즈 상에 압박이 있는 경우, 즉 디스크 용량이 넉넉치 않은 경우 `True`, 반대의 경우 `False` |
|
||||
| `MemoryPressure` | 노드 메모리 상에 압박이 있는 경우, 즉 노드 메모리가 넉넉치 않은 경우 `True`, 반대의 경우 `False` |
|
||||
| `PIDPressure` | 프로세스 상에 압박이 있는 경우, 즉 노드 상에 많은 프로세스들이 존재하는 경우 `True`, 반대의 경우 `False` |
|
||||
| `DiskPressure` | 디스크 사이즈 상에 압박이 있는 경우, 즉 디스크 용량이 넉넉치 않은 경우 `True`, 반대의 경우 `False` |
|
||||
| `NetworkUnavailable` | 노드에 대해 네트워크가 올바르게 구성되지 않은 경우 `True`, 반대의 경우 `False` |
|
||||
{{< /table >}}
|
||||
|
||||
{{< note >}}
|
||||
커맨드 라인 도구를 사용해서 코드화된 노드의 세부 정보를 출력하는 경우 조건에는
|
||||
`SchedulingDisabled` 이 포함된다. `SchedulingDisabled` 은 쿠버네티스 API의 조건이 아니며,
|
||||
대신 코드화된 노드는 사양에 스케줄 불가로 표시된다.
|
||||
{{< /note >}}
|
||||
|
||||
노드 컨디션은 JSON 오브젝트로 표현된다. 예를 들어, 다음 응답은 상태 양호한 노드를 나타낸다.
|
||||
|
||||
@@ -69,17 +173,18 @@ kubectl describe node <insert-node-name-here>
|
||||
]
|
||||
```
|
||||
|
||||
ready 컨디션의 상태가 `pod-eviction-timeout` ([kube-controller-manager](/docs/admin/kube-controller-manager/)에 전달된 인수) 보다 더 길게 `Unknown` 또는 `False`로 유지되는 경우, 노드 상에 모든 파드는 노드 컨트롤러에 의해 삭제되도록 스케줄 된다. 기본 축출 타임아웃 기간은 **5분** 이다. 노드에 접근이 불가할 때와 같은 경우, apiserver는 노드 상의 kubelet과 통신이 불가하다. apiserver와의 통신이 재개될 때까지 파드 삭제에 대한 결정은 kubelet에 전해질 수 없다. 그 사이, 삭제되도록 스케줄 되어진 파드는 분할된 노드 상에서 계속 동작할 수도 있다.
|
||||
ready 컨디션의 상태가 `pod-eviction-timeout` ({{< glossary_tooltip text="kube-controller-manager" term_id="kube-controller-manager" >}}에 전달된 인수) 보다 더 길게 `Unknown` 또는 `False`로 유지되는 경우, 노드 상에 모든 파드는 노드 컨트롤러에 의해 삭제되도록 스케줄 된다. 기본 축출 타임아웃 기간은 **5분** 이다. 노드에 접근이 불가할 때와 같은 경우, apiserver는 노드 상의 kubelet과 통신이 불가하다. apiserver와의 통신이 재개될 때까지 파드 삭제에 대한 결정은 kubelet에 전해질 수 없다. 그 사이, 삭제되도록 스케줄 되어진 파드는 분할된 노드 상에서 계속 동작할 수도 있다.
|
||||
|
||||
1.5 이전의 쿠버네티스 버전에서는, 노드 컨트롤러가 apiserver로부터 접근 불가한 이러한 파드를 [강제 삭제](/ko/docs/concepts/workloads/pods/pod/#파드-강제-삭제)
|
||||
시킬 것이다. 그러나 1.5 이상에서는, 노드 컨트롤러가 클러스터 내 동작 중지된 것을 확신할 때까지는 파드를
|
||||
노드 컨트롤러가 클러스터 내 동작 중지된 것을 확신할 때까지는 파드를
|
||||
강제로 삭제하지 않는다. 파드가 `Terminating` 또는 `Unknown` 상태로 있을 때 접근 불가한 노드 상에서
|
||||
동작되고 있는 것을 보게 될 수도 있다. 노드가 영구적으로 클러스터에서 삭제되었는지에 대한 여부를 쿠버네티스가 기반 인프라로부터 유추할 수 없는 경우,
|
||||
노드가 클러스터를 영구적으로 탈퇴하게 되면, 클러스터 관리자는 손수 노드 오브젝트를 삭제해야 할 수도 있다. 쿠버네티스에서 노드 오브젝트를 삭제하면
|
||||
노드 상에서 동작중인 모든 파드 오브젝트가 apiserver로부터 삭제되어 그 이름을 사용할 수 있는 결과를 낳는다.
|
||||
동작되고 있는 것을 보게 될 수도 있다. 노드가 영구적으로 클러스터에서 삭제되었는지에
|
||||
대한 여부를 쿠버네티스가 기반 인프라로부터 유추할 수 없는 경우, 노드가 클러스터를 영구적으로
|
||||
탈퇴하게 되면, 클러스터 관리자는 손수 노드 오브젝트를 삭제해야 할 수도 있다.
|
||||
쿠버네티스에서 노드 오브젝트를 삭제하면 노드 상에서 동작중인 모든 파드 오브젝트가
|
||||
apiserver로부터 삭제되어 그 이름을 사용할 수 있는 결과를 낳는다.
|
||||
|
||||
노드 수명주기 컨트롤러는 자동으로 컨디션을 나타내는
|
||||
[테인트(taints)](/docs/concepts/configuration/taint-and-toleration/)를 생성한다.
|
||||
[테인트(taints)](/docs/concepts/scheduling-eviction/taint-and-toleration/)를 생성한다.
|
||||
스케줄러는 파드를 노드에 할당 할 때 노드의 테인트를 고려한다.
|
||||
또한 파드는 노드의 테인트를 극복(tolerate)할 수 있는 톨러레이션(toleration)을 가질 수 있다.
|
||||
|
||||
@@ -101,47 +206,10 @@ ready 컨디션의 상태가 `pod-eviction-timeout` ([kube-controller-manager](/
|
||||
커널 버전, 쿠버네티스 버전 (kubelet과 kube-proxy 버전), (사용하는 경우) Docker 버전, OS 이름과 같은노드에 대한 일반적인 정보를 보여준다.
|
||||
이 정보는 Kubelet에 의해 노드로부터 수집된다.
|
||||
|
||||
## 관리
|
||||
|
||||
[파드](/ko/docs/concepts/workloads/pods/pod/)와 [서비스](/ko/docs/concepts/services-networking/service/)와 달리,
|
||||
노드는 본래 쿠버네티스에 의해 생성되지 않는다. 구글 컴퓨트 엔진과 같은 클라우드 제공사업자에 의해
|
||||
외부로부터 생성 되거나, 물리적 또는 가상 머신의 풀 내에서 존재한다.
|
||||
그래서 쿠버네티스가 노드를 생성할 때,
|
||||
노드를 나타내는 오브젝트를 생성한다.
|
||||
생성 이후, 쿠버네티스는 노드의 유효성 여부를 검사한다. 예를 들어,
|
||||
다음 내용으로 노드를 생성하려 한다면,
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": "Node",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "10.240.79.157",
|
||||
"labels": {
|
||||
"name": "my-first-k8s-node"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
쿠버네티스는 내부적으로 (표현을) 노드 오브젝트를 생성하고,
|
||||
`metadata.name` 필드를 근거로 상태 체크를 수행하여 노드의 유효성을 확인한다. 노드가 유효하면, 즉
|
||||
모든 필요한 서비스가 동작 중이면, 파드를 동작시킬 자격이 된다. 그렇지 않으면,
|
||||
유효하게 될때까지 어떠한 클러스터 활동에 대해서도 무시된다.
|
||||
노드 오브젝트의 이름은 유효한 [DNS 서브도메인 이름](/ko/docs/concepts/overview/working-with-objects/names/#dns-서브도메인-이름들)이어야 한다.
|
||||
|
||||
{{< note >}}
|
||||
쿠버네티스는 유효하지 않은 노드로부터 오브젝트를 보호하고 유효한 상태로 이르는지 확인하기 위해 지속적으로 체크한다.
|
||||
이러한 프로세스를 중지시키기 위해는 명시적으로 노드 오브젝트를 삭제해야 한다.
|
||||
{{< /note >}}
|
||||
|
||||
현재, 쿠버네티스 노드 인터페이스와 상호작용 하는 3개의 컴포넌트가 존재하는데,
|
||||
노드 컨트롤러, kubelet, 그리고 kubectl 이다.
|
||||
|
||||
### 노드 컨트롤러
|
||||
|
||||
노드 컨트롤러는 노드의 다양한 측면을 관리하는 쿠버네티스
|
||||
마스터 컴포넌트다.
|
||||
노드 {{< glossary_tooltip text="컨트롤러" term_id="controller" >}}는
|
||||
노드의 다양한 측면을 관리하는 쿠버네티스 컨트롤 플레인 컴포넌트이다.
|
||||
|
||||
노드 컨트롤러는 노드가 생성되어 유지되는 동안 다양한 역할을 한다. 첫째는 등록 시점에
|
||||
(CIDR 할당이 사용토록 설정된 경우) 노드에 CIDR 블럭을 할당하는 것이다.
|
||||
@@ -164,6 +232,7 @@ NodeStatus의 NodeReady 컨디션을 ConditionUnknown으로 업데이트 하는
|
||||
#### 하트비트
|
||||
|
||||
쿠버네티스 노드에서 보내는 하트비트는 노드의 가용성을 결정하는데 도움이 된다.
|
||||
|
||||
하트비트의 두 가지 형태는 `NodeStatus` 와
|
||||
[리스(Lease) 오브젝트](/docs/reference/generated/kubernetes-api/{{< latest-version >}}/#lease-v1-coordination-k8s-io) 이다.
|
||||
각 노드에는 `kube-node-lease` 라는
|
||||
@@ -184,13 +253,7 @@ kubelet은 `NodeStatus` 와 리스 오브젝트를 생성하고 업데이트 할
|
||||
|
||||
#### 안정성
|
||||
|
||||
쿠버네티스 1.4에서, 대량의 노드들이 마스터 접근에
|
||||
문제를 지닐 경우 (예를 들어 마스터에 네트워크 문제들이 발생했기 때문에)
|
||||
더 개선된 문제 해결을 하도록 노드 컨트롤러의 로직을 업데이트 했다. 1.4를 시작으로,
|
||||
노드 컨트롤러는 파드 축출에 대한 결정을 내릴 경우 클러스터
|
||||
내 모든 노드를 살핀다.
|
||||
|
||||
대부분의 경우, 노드 컨트롤러는 초당 `--node-eviction-rate`(기본값 0.1)로
|
||||
대부분의 경우, 노드 컨트롤러는 초당 `--node-eviction-rate`(기본값 0.1)로
|
||||
축출 비율을 제한한다. 이 말은 10초당 1개의 노드를 초과하여
|
||||
파드 축출을 하지 않는다는 의미가 된다.
|
||||
|
||||
@@ -216,62 +279,11 @@ kubelet은 `NodeStatus` 와 리스 오브젝트를 생성하고 업데이트 할
|
||||
이러한 경우, 노드 컨트롤러는 마스터 연결에 문제가 있어 일부 연결이
|
||||
복원될 때까지 모든 축출을 중지하는 것으로 여긴다.
|
||||
|
||||
쿠버네티스 1.6을 시작으로 NodeController는 파드가 taint를 허용하지 않을 때,
|
||||
`NoExecute` taint 상태의 노드 상에 동작하는 파드 축출에 대한 책임 또한
|
||||
지고 있다. 추가로, 기본적으로 비활성화 된 알파 기능으로, NodeController는 노드 접근 불가
|
||||
또는 준비 부족과 같은 노드 문제에 상응하는 taint 추가에 대한 책임을 진다.
|
||||
`NoExecute` taints와 알파 기능에 대한 보다 상세한
|
||||
내용은 [이 문서](/docs/concepts/configuration/taint-and-toleration/)를 참고한다.
|
||||
|
||||
1.8 버전을 시작으로, 노드 컨트롤러는 노드 상태를 나타내는 taint 생성에 대한 책임을 지도록
|
||||
만들 수 있다. 이는 버전 1.8 의 알파 기능이다.
|
||||
|
||||
### 노드에 대한 자체-등록
|
||||
|
||||
kubelet 플래그 `--register-node`는 참(기본값)일 경우, kubelet 은 API 서버에
|
||||
스스로 등록을 시도할 것이다. 이는 대부분의 배포판에 의해 이용되는, 선호하는 패턴이다.
|
||||
|
||||
자체-등록에 대해, kubelet은 다음 옵션과 함께 시작된다.
|
||||
|
||||
- `--kubeconfig` - apiserver에 스스로 인증하기 위한 자격증명에 대한 경로.
|
||||
- `--cloud-provider` - 자신에 대한 메터데이터를 읽기 위해 어떻게 클라우드 제공사업자와 소통할지에 대한 방법.
|
||||
- `--register-node` - 자동으로 API 서버에 등록.
|
||||
- `--register-with-taints` - 주어진 taint 리스트 (콤마로 분리된 `<key>=<value>:<effect>`)를 가진 노드 등록. `register-node`가 거짓이면 동작 안함.
|
||||
- `--node-ip` - 노드의 IP 주소.
|
||||
- `--node-labels` - 클러스터 내 노드를 등록할 경우 추가되는 레이블 (1.13+ 에서 [NodeRestriction admission plugin](/docs/reference/access-authn-authz/admission-controllers/#noderestriction)에 의해 강제되는 레이블 제약사항 참고).
|
||||
- `--node-status-update-frequency` - 얼마나 자주 kubelet이 마스터에 노드 상태를 게시할 지 정의.
|
||||
|
||||
[Node authorization mode](/docs/reference/access-authn-authz/node/)와
|
||||
[NodeRestriction admission plugin](/docs/reference/access-authn-authz/admission-controllers/#noderestriction)이 활성화 되면,
|
||||
kubelets 은 자신의 노드 리소스를 생성/수정할 권한을 가진다.
|
||||
|
||||
#### 수동 노드 관리
|
||||
|
||||
클러스터 관리자는 노드 오브젝트를 생성하고 수정할 수 있다.
|
||||
|
||||
관리자가 수동으로 오브젝트를 생성하고자 한다면, kubelet 플래그를
|
||||
`--register-node=false`로 설정한다.
|
||||
|
||||
관리자는 노드 리소스를 수정할 수 있다(`--register-node`설정과 무관하게).
|
||||
수정은 노드 상에 레이블 설정과 스케줄 불가 마킹을 포함한다.
|
||||
|
||||
노드 상의 레이블은 스케줄링을 제어하기 위해,
|
||||
즉 하나의 파드가 오직 노드의 서브셋 상에 동작할 수 있도록 제한하기 위해 노드 셀렉터와 함께 이용될 수 있다.
|
||||
|
||||
노드를 스케줄 불가로 마킹하게 되면, 해당 노드에 새로운 파드가 스케줄되는 것을 막아주지만,
|
||||
노드 상의 임의의 기존 파드에 대해서는 영향을 미치치 않는다. 이는 노드 리부트
|
||||
전이나 기타 등의 준비 조치로 유용하다. 예를 들어, 노드를 스케줄 불가로
|
||||
마크하기 위해 다음 명령을 수행한다.
|
||||
|
||||
```shell
|
||||
kubectl cordon $NODENAME
|
||||
```
|
||||
|
||||
{{< note >}}
|
||||
DaemonSet 컨트롤러에 의해 생성된 파드는 쿠버네티스 스케줄러를
|
||||
우회하고 노드 상에 스케줄 불가 속성을 고려하지 않는다. 심지어 리부트를 준비하는 동안
|
||||
애플리케이션을 유출시키는 중이라 할지라도 머신 상에 속한 데몬으로 여긴다.
|
||||
{{< /note >}}
|
||||
또한, 노드 컨트롤러는 파드가 테인트를 허용하지 않을 때 `NoExecute` 테인트 상태의
|
||||
노드에서 동작하는 파드에 대한 축출 책임을 가지고 있다.
|
||||
추가로, 노드 컨틀로러는 연결할 수 없거나, 준비되지 않은 노드와 같은 노드 문제에 상응하는
|
||||
{{< glossary_tooltip text="테인트" term_id="taint" >}}를 추가한다.
|
||||
이는 스케줄러가 비정상적인 노드에 파드를 배치하지 않게 된다.
|
||||
|
||||
{{< caution >}}
|
||||
`kubectl cordon` 은 노드를 'unschedulable'로 표기하는데, 이는
|
||||
@@ -281,34 +293,41 @@ DaemonSet 컨트롤러에 의해 생성된 파드는 쿠버네티스 스케줄
|
||||
|
||||
### 노드 용량
|
||||
|
||||
노드의 용량 (cpu 수와 메모리 양) 은 노드 오브젝트의 한 부분이다.
|
||||
일반적으로, 노드는 스스로 등록하고 노드 오브젝트를 생성할 때 자신의 용량을 알린다. 만약
|
||||
[수동 노드 관리](#수동-노드-관리)를 수행 한다면, 노드를 추가할 때
|
||||
노드 용량을 설정해야 한다.
|
||||
노드 오브젝트는 노드 리소스 용량에 대한 정보(예: 사용 가능한 메모리의
|
||||
양과 CPU의 수)를 추적한다.
|
||||
노드의 [자체 등록](#노드에-대한-자체-등록)은 등록하는 중에 용량을 보고한다.
|
||||
[수동](#수동-노드-관리)으로 노드를 추가하는 경우 추가할 때
|
||||
노드의 용량 정보를 설정해야 한다.
|
||||
|
||||
쿠버네티스 스케줄러는 노드 상에 모든 노드에 대해 충분한 리소스가 존재하도록 보장한다.
|
||||
노드 상에 컨테이너에 대한 요청의 합이 노드 용량보다 더 크지 않도록 체크한다.
|
||||
kubelet에 의해 구동된 모든 컨테이너를 포함하지만, [컨테이너 런타임](/ko/docs/concepts/overview/components/#컨테이너-런타임)에 의해 직접 구동된 컨테이너 또는 컨테이너 외부에서 동작하는 임의의 프로세스는 해당되지 않는다.
|
||||
쿠버네티스 {{< glossary_tooltip text="스케줄러" term_id="kube-scheduler" >}}는
|
||||
노드 상에 모든 노드에 대해 충분한 리소스가 존재하도록 보장한다. 스케줄러는 노드 상에
|
||||
컨테이너에 대한 요청의 합이 노드 용량보다 더 크지 않도록 체크한다.
|
||||
요청의 합은 kubelet에서 관리하는 모든 컨테이너를 포함하지만, 컨테이너 런타임에
|
||||
의해 직접적으로 시작된 컨 테이너는 제외되고 kubelet의 컨트롤 범위
|
||||
밖에서 실행되는 모든 프로세스도 제외된다.
|
||||
|
||||
{{< note >}}
|
||||
파드 형태가 아닌 프로세스에 대해 명시적으로 리소스를 확보하려면,
|
||||
[reserve resources for system daemons](/docs/tasks/administer-cluster/reserve-compute-resources/#system-reserved) 튜토리얼을 따른다.
|
||||
[시스템 데몬에 사용할 리소스 예약하기](/docs/tasks/administer-cluster/reserve-compute-resources/#system-reserved)을 본다.
|
||||
{{< /note >}}
|
||||
|
||||
## 노드 토폴로지
|
||||
|
||||
{{< feature-state state="alpha" >}}
|
||||
{{< feature-state state="alpha" for_k8s_version="v1.16" >}}
|
||||
|
||||
`TopologyManager`
|
||||
[기능 게이트(feature gate)](/docs/reference/command-line-tools-reference/feature-gates/)를
|
||||
활성화 시켜두면, kubelet이 리소스 할당 결정을 할 때 토폴로지 힌트를 사용할 수 있다.
|
||||
|
||||
## API 오브젝트
|
||||
|
||||
노드는 쿠버네티스 REST API 내 탑-레벨 리소스 이다. API 오브젝트에 대한
|
||||
보다 자세한 내용은
|
||||
[노드 API 오브젝트](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#node-v1-core)에서 확인할 수 있다.
|
||||
자세한 내용은
|
||||
[노드의 컨트롤 토폴로지 관리 정책](/docs/tasks/administer-cluster/topology-manager/)을 본다.
|
||||
|
||||
{{% /capture %}}
|
||||
{{% capture whatsnext %}}
|
||||
* [노드 컴포넌트](/ko/docs/concepts/overview/components/#노드-컴포넌트)에 대해 읽기
|
||||
* 노드 수준 토폴로지에 대해 읽기: [노드의 토폴로지 정책 제어하기](/docs/tasks/administer-cluster/topology-manager/)
|
||||
* 노드를 구성하는 [컴포넌트](/ko/docs/concepts/overview/components/#노드-컴포넌트)에 대해 알아본다.
|
||||
* [노드에 대한 API 정의](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#node-v1-core)를 읽어본다.
|
||||
* 아키텍처 디자인 문서의 [노드](https://git.k8s.io/community/contributors/design-proposals/architecture/architecture.md#the-kubernetes-node)
|
||||
섹션을 읽어본다.
|
||||
* [테인트와 톨러레이션](/ko/docs/concepts/configuration/taint-and-toleration/)을 읽어본다.
|
||||
* [클러스터 오토스케일링](/ko/docs/tasks/administer-cluster/cluster-management/#클러스터-오토스케일링)을 읽어본다.
|
||||
{{% /capture %}}
|
||||
|
||||
@@ -30,6 +30,7 @@ content_template: templates/concept
|
||||
* [Flannel](https://github.com/coreos/flannel/blob/master/Documentation/kubernetes.md)은 쿠버네티스와 함께 사용할 수 있는 오버레이 네트워크 제공자이다.
|
||||
* [Knitter](https://github.com/ZTE/Knitter/)는 쿠버네티스 파드에서 여러 네트워크 인터페이스를 지원하는 플러그인이다.
|
||||
* [Multus](https://github.com/Intel-Corp/multus-cni)는 쿠버네티스에서 SRIOV, DPDK, OVS-DPDK 및 VPP 기반 워크로드 외에 모든 CNI 플러그인(예: Calico, Cilium, Contiv, Flannel)을 지원하기 위해 쿠버네티스에서 다중 네트워크 지원을 위한 멀티 플러그인이다.
|
||||
* [OVN4NFV-K8S-Plugin](https://github.com/opnfv/ovn4nfv-k8s-plugin)은 OVN 기반의 CNI 컨트롤러 플러그인으로 클라우드 네이티브 기반 서비스 기능 체인(Service function chaining(SFC)), 다중 OVN 오버레이 네트워킹, 동적 서브넷 생성, 동적 가상 네트워크 생성, VLAN 공급자 네트워크, 직접 공급자 네트워크와 멀티 클러스터 네트워킹의 엣지 기반 클라우드 등 네이티브 워크로드에 이상적인 멀티 네티워크 플러그인이다.
|
||||
* [NSX-T](https://docs.vmware.com/en/VMware-NSX-T/2.0/nsxt_20_ncp_kubernetes.pdf) 컨테이너 플러그인(NCP)은 VMware NSX-T와 쿠버네티스와 같은 컨테이너 오케스트레이터 간의 통합은 물론 NSX-T와 PKS(Pivotal 컨테이너 서비스) 및 OpenShift와 같은 컨테이너 기반 CaaS/PaaS 플랫폼 간의 통합을 제공한다.
|
||||
* [Nuage](https://github.com/nuagenetworks/nuage-kubernetes/blob/v5.1.1-1/docs/kubernetes-1-installation.rst)는 가시성과 보안 모니터링 기능을 통해 쿠버네티스 파드와 비-쿠버네티스 환경 간에 폴리시 기반 네트워킹을 제공하는 SDN 플랫폼이다.
|
||||
* [Romana](http://romana.io)는 [네트워크폴리시 API](/docs/concepts/services-networking/network-policies/)도 지원하는 파드 네트워크용 Layer 3 네트워킹 솔루션이다. Kubeadm 애드온 설치에 대한 세부 정보는 [여기](https://github.com/romana/romana/tree/master/containerize)에 있다.
|
||||
|
||||
@@ -134,6 +134,15 @@ CloudStack 클라우드 제공자는 쿠버네티스 노드 오브젝트의 이
|
||||
GCE 클라우드 제공자는 쿠버네티스 노드 오브젝트의 이름으로 노드의 (kubelet에 의해 결정되거나 `--hostname-override` 로 재정의된) 호스트 이름을 사용한다.
|
||||
참고로 쿠버네티스 노드 이름의 첫 번째 세그먼트는 GCE 인스턴스 이름과 일치해야 한다(예: `kubernetes-node-2.c.my-proj.internal` 이름이 지정된 노드는 `kubernetes-node-2` 이름이 지정된 인스턴스에 해당해야 함).
|
||||
|
||||
## HUAWEI 클라우드
|
||||
|
||||
외부 클라우드 제공자를 사용하려는 경우, 해당 리포지터리는 [kubernetes-sigs/cloud-provider-huaweicloud](https://github.com/kubernetes-sigs/cloud-provider-huaweicloud)이다.
|
||||
|
||||
### 노드 이름
|
||||
|
||||
HUAWEI 클라우드 제공자는 쿠버네티스 노드 오브젝트의 이름으로 노드의 프라이빗 IP 주소가 필요하다.
|
||||
노드에서 kubelet을 시작할 때 반드시 `--hostname-override=<node private IP>` 를 사용한다.
|
||||
|
||||
## OpenStack
|
||||
이 섹션에서는 쿠버네티스와 함께 OpenStack을 사용할 때 사용할 수 있는
|
||||
모든 구성에 대해 설명한다.
|
||||
@@ -412,3 +421,15 @@ Baidu 클라우드 제공자는 쿠버네티스 노드 오브젝트의 이름으
|
||||
|
||||
Tencent 클라우드 제공자는 쿠버네티스 노드 오브젝트의 이름으로 노드의 (kubelet에 의해 결정되거나 `--hostname-override` 로 재정의된) 호스트 이름을 사용한다.
|
||||
참고로 쿠버네티스 노드 이름은 Tencent VM 프라이빗 IP와 일치해야 한다.
|
||||
|
||||
## Alibaba 클라우드 쿠버네티스
|
||||
|
||||
이 외부 클라우드 제공자를 사용하려는 경우, 해당 리포지터리는 [kubernetes/cloud-provider-alibaba-cloud](https://github.com/kubernetes/cloud-provider-alibaba-cloud)이다.
|
||||
|
||||
### 노드 이름
|
||||
|
||||
Alibaba 클라우드는 노드 이름의 형식을 요구하지는 않지만, kubelet은 `--provider-id=${REGION_ID}.${INSTANCE_ID}` 를 추가해야만 한다. 파라미터 `${REGION_ID}` 는 쿠버네티스의 지역 ID에 해당하고, `${INSTANCE_ID}` 는 Alibaba ECS (Elastic Compute Service) ID를 의미한다.
|
||||
|
||||
### 로드 밸런서
|
||||
|
||||
[어노테이션](https://www.alibabacloud.com/help/en/doc-detail/86531.htm)을 구성해서 Alibaba 클라우드의 특정 기능을 사용하도록 외부 로드 밸런서를 설정할 수 있다.
|
||||
|
||||
@@ -260,6 +260,10 @@ Lars Kellogg-Stedman이 제공하는 [이 훌륭한
|
||||
|
||||
Multus는 CNI 명세를 구현하는 모든 [레퍼런스 플러그인](https://github.com/containernetworking/plugins)(예: [플라넬](https://github.com/containernetworking/plugins/tree/master/plugins/meta/flannel), [DHCP](https://github.com/containernetworking/plugins/tree/master/plugins/ipam/dhcp), [Macvlan](https://github.com/containernetworking/plugins/tree/master/plugins/main/macvlan)) 및 써드파티 플러그인(예: [캘리코](https://github.com/projectcalico/cni-plugin), [위브(Weave)](https://github.com/weaveworks/weave), [실리움](https://github.com/cilium/cilium), [콘티브](https://github.com/contiv/netplugin))을 지원한다. 또한, Multus는 쿠버네티스의 클라우드 네이티브 애플리케이션과 NFV 기반 애플리케이션을 통해 쿠버네티스의 [SRIOV](https://github.com/hustcat/sriov-cni), [DPDK](https://github.com/Intel-Corp/sriov-cni), [OVS-DPDK 및 VPP](https://github.com/intel/vhost-user-net-plugin) 워크로드를 지원한다.
|
||||
|
||||
### OVN4NFV-K8s-Plugin (OVN 기반의 CNI 컨트롤러 & 플러그인)
|
||||
|
||||
[OVN4NFV-K8S-Plugin](https://github.com/opnfv/ovn4nfv-k8s-plugin)은 OVN 기반의 CNI 컨트롤러 플러그인으로 클라우드 네이티브 기반 서비스 기능 체인(Service function chaining(SFC)), 다중 OVN 오버레이 네트워킹, 동적 서브넷 생성, 동적 가상 네트워크 생성, VLAN 공급자 네트워크, 직접 공급자 네트워크와 멀티 클러스터 네트워킹의 엣지 기반 클라우드 등 네이티브 워크로드에 이상적인 멀티 네티워크 플러그인이다.
|
||||
|
||||
### NSX-T
|
||||
|
||||
[VMware NSX-T](https://docs.vmware.com/en/VMware-NSX-T/index.html)는 네트워크 가상화 및 보안 플랫폼이다. NSX-T는 멀티 클라우드 및 멀티 하이퍼바이저 환경에 네트워크 가상화를 제공할 수 있으며 이기종 엔드포인트와 기술 스택이 있는 새로운 애플리케이션 프레임워크 및 아키텍처에 중점을 둔다. vSphere 하이퍼바이저 외에도, 이러한 환경에는 KVM, 컨테이너 및 베어메탈과 같은 다른 하이퍼바이저가 포함된다.
|
||||
|
||||
@@ -57,7 +57,7 @@ API [오브젝트](/ko/docs/concepts/overview/working-with-objects/kubernetes-ob
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
Name: game-demo
|
||||
name: game-demo
|
||||
data:
|
||||
# 속성과 비슷한 키; 각 키는 간단한 값으로 매핑됨
|
||||
player_initial_lives: 3
|
||||
|
||||
@@ -321,7 +321,7 @@ Ei, Pi, Ti, Gi, Mi, Ki와 같은 2의 거듭제곱을 사용할 수도 있다.
|
||||
128974848, 129e6, 129M, 123Mi
|
||||
```
|
||||
|
||||
다음 예에서, 파드에 두 개의 컨테이너가 있다. 각 컨테이너에는 2GiB의 로컬 임시 스토리지 요청이 있다. 각 컨테이너에는 4GiB의 로컬 임시 스토리지 제한이 있다. 따라서, 파드는 4GiB의 로컬 임시 스토리지 요청과 8GiB 스토리지 제한을 가진다.
|
||||
다음 예에서, 파드에 두 개의 컨테이너가 있다. 각 컨테이너에는 2GiB의 로컬 임시 스토리지 요청이 있다. 각 컨테이너에는 4GiB의 로컬 임시 스토리지 제한이 있다. 따라서, 파드는 4GiB의 로컬 임시 스토리지 요청과 8GiB 로컬 임시 스토리지 제한을 가진다.
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
|
||||
@@ -48,13 +48,6 @@ weight: 70
|
||||
이들은 일반적인 클래스이며 [중요한(critical) 컴포넌트가 항상 먼저 스케줄링이 되도록 하는 데](/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods/) 사용된다.
|
||||
{{< /note >}}
|
||||
|
||||
기능을 사용해 본 후 사용하지 않기로 했다면, PodPriority
|
||||
커맨드-라인 플래그를 제거하거나 `false` 로 설정한 후, API 서버와
|
||||
스케줄러를 다시 시작해야 한다. 기능이 비활성화된 후, 기존 파드는
|
||||
우선순위 필드를 유지하지만, 선점은 비활성화되며, 우선순위 필드는
|
||||
무시된다. 이 기능이 비활성화되면, 새로운 파드에서 `priorityClassName` 을 설정할 수
|
||||
없다.
|
||||
|
||||
## 선점을 비활성화하는 방법
|
||||
|
||||
{{< caution >}}
|
||||
@@ -117,7 +110,7 @@ disablePreemption: true
|
||||
|
||||
### PodPriority와 기존 클러스터에 대한 참고 사항
|
||||
|
||||
- 기존 클러스터를 업그레이드하고 이 기능을 활성화하면, 기존 파드의
|
||||
- 이 기능없이 기존 클러스터를 업그레이드 하는 경우, 기존 파드의
|
||||
우선순위는 사실상 0이다.
|
||||
|
||||
- `globalDefault` 가 `true` 로 설정된 프라이어리티클래스를 추가해도 기존 파드의
|
||||
|
||||
@@ -158,7 +158,7 @@ https://github.com/containerd/cri/blob/master/docs/config.md
|
||||
노드의 합집합을 취한다.
|
||||
|
||||
노드 셀렉터와 톨러레이션 설정에 대해 더 배우려면
|
||||
[노드에 파드 할당](/ko/docs/concepts/configuration/assign-pod-node/)을 참고한다.
|
||||
[노드에 파드 할당](/ko/docs/concepts/scheduling-eviction/assign-pod-node/)을 참고한다.
|
||||
|
||||
[런타임 클래스 어드미션 컨트롤러]: /docs/reference/access-authn-authz/admission-controllers/#runtimeclass
|
||||
|
||||
|
||||
@@ -223,6 +223,6 @@ selector:
|
||||
#### 노드 셋 선택
|
||||
|
||||
레이블을 통해 선택하는 사용 사례 중 하나는 파드를 스케줄 할 수 있는 노드 셋을 제한하는 것이다.
|
||||
자세한 내용은 [노드 선택](/ko/docs/concepts/configuration/assign-pod-node/) 문서를 참조한다.
|
||||
자세한 내용은 [노드 선택](/ko/docs/concepts/scheduling-eviction/assign-pod-node/) 문서를 참조한다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
@@ -490,7 +490,8 @@ kubectl create quota test --hard=count/deployments.extensions=2,count/replicaset
|
||||
```
|
||||
|
||||
```shell
|
||||
kubectl run nginx --image=nginx --replicas=2 --namespace=myspace
|
||||
kubectl create deployment nginx --image=nginx --namespace=myspace
|
||||
kubectl scale deployment nginx --replicas=2 --namespace=myspace
|
||||
```
|
||||
|
||||
```shell
|
||||
|
||||
+400
-400
@@ -1,400 +1,400 @@
|
||||
---
|
||||
title: 노드에 파드 할당하기
|
||||
content_template: templates/concept
|
||||
weight: 50
|
||||
---
|
||||
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
{{< glossary_tooltip text="파드" term_id="pod" >}}를 특정한 {{< glossary_tooltip text="노드(들)" term_id="node" >}}에서만 동작하도록 하거나,
|
||||
특정 노드들을 선호하도록 제한할 수 있다.
|
||||
이를 수행하는 방법에는 여러 가지가 있으며, 권장되는 접근 방식은 모두
|
||||
[레이블 셀렉터](/ko/docs/concepts/overview/working-with-objects/labels/)를 사용하여 선택한다.
|
||||
보통 스케줄러가 자동으로 합리적인 배치(예: 노드들에 걸쳐 파드를 분배하거나,
|
||||
자원이 부족한 노드에 파드를 배치하지 않는 등)를 수행하기에 이런 제약 조건은 필요하지 않지만
|
||||
간혹 파드가 배치되는 노드에 대해 더 많은 제어를 원할 수 있는 상황이 있다.
|
||||
예를 들어 SSD가 장착된 머신에 파드가 연결되도록 하거나 또는 동일한 가용성 영역(availability zone)에서
|
||||
많은 것을 통신하는 두 개의 서로 다른 서비스의 파드를 같이 배치할 수 있다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
## 노드 셀렉터(nodeSelector)
|
||||
|
||||
`nodeSelector` 는 가장 간단하고 권장되는 노드 선택 제약 조건의 형태이다.
|
||||
`nodeSelector` 는 PodSpec의 필드이다. 이는 키-값 쌍의 매핑으로 지정한다. 파드가 노드에서 동작할 수 있으려면,
|
||||
노드는 키-값의 쌍으로 표시되는 레이블을 각자 가지고 있어야 한다(이는 추가 레이블을 가지고 있을 수 있다).
|
||||
일반적으로 하나의 키-값 쌍이 사용된다.
|
||||
|
||||
`nodeSelector` 를 어떻게 사용하는지 예시를 통해 알아보도록 하자.
|
||||
|
||||
### 0 단계: 사전 준비
|
||||
|
||||
이 예시는 쿠버네티스 파드에 대한 기본적인 이해를 하고 있고 [쿠버네티스 클러스터가 설정](/ko/docs/setup/)되어 있다고 가정한다.
|
||||
|
||||
### 1 단계: 노드에 레이블 붙이기
|
||||
|
||||
`kubectl get nodes` 를 실행해서 클러스터 노드 이름을 가져온다. 이 중에 레이블을 추가하기 원하는 것 하나를 선택한 다음에 `kubectl label nodes <노드 이름> <레이블 키>=<레이블 값>` 을 실행해서 선택한 노드에 레이블을 추가한다. 예를 들어 노드의 이름이 'kubernetes-foo-node-1.c.a-robinson.internal' 이고, 원하는 레이블이 'disktype=ssd' 라면, `kubectl label nodes kubernetes-foo-node-1.c.a-robinson.internal disktype=ssd` 를 실행한다.
|
||||
|
||||
`kubectl get nodes --show-labels` 를 다시 실행해서 노드가 현재 가진 레이블을 확인하여, 이 작업을 검증할 수 있다. 또한 `kubectl describe node "노드 이름"` 을 사용해서 노드에 주어진 레이블의 전체 목록을 확인할 수 있다.
|
||||
|
||||
### 2 단계: 파드 설정에 nodeSelector 필드 추가하기
|
||||
|
||||
실행하고자 하는 파드의 설정 파일을 가져오고, 이처럼 nodeSelector 섹션을 추가한다. 예를 들어 이것이 파드 설정이라면,
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: nginx
|
||||
labels:
|
||||
env: test
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx
|
||||
```
|
||||
|
||||
이 다음에 nodeSelector 를 다음과 같이 추가한다.
|
||||
|
||||
{{< codenew file="pods/pod-nginx.yaml" >}}
|
||||
|
||||
그런 다음에 `kubectl apply -f https://k8s.io/examples/pods/pod-nginx.yaml` 을
|
||||
실행하면, 레이블이 붙여진 노드에 파드가 스케줄 된다.
|
||||
`kubectl get pods -o wide` 를 실행해서 파드가 할당된
|
||||
"NODE" 를 보면 작동하는지 검증할 수 있다.
|
||||
|
||||
## 넘어가기 전에: 내장 노드 레이블들 {#built-in-node-labels}
|
||||
|
||||
[붙인](#1-단계-노드에-레이블-붙이기) 레이블뿐만 아니라, 노드에는
|
||||
표준 레이블 셋이 미리 채워져 있다. 이 레이블들은 다음과 같다.
|
||||
|
||||
* [`kubernetes.io/hostname`](/docs/reference/kubernetes-api/labels-annotations-taints/#kubernetes-io-hostname)
|
||||
* [`failure-domain.beta.kubernetes.io/zone`](/docs/reference/kubernetes-api/labels-annotations-taints/#failure-domainbetakubernetesiozone)
|
||||
* [`failure-domain.beta.kubernetes.io/region`](/docs/reference/kubernetes-api/labels-annotations-taints/#failure-domainbetakubernetesioregion)
|
||||
* [`topology.kubernetes.io/zone`](/docs/reference/kubernetes-api/labels-annotations-taints/#topologykubernetesiozone)
|
||||
* [`topology.kubernetes.io/region`](/docs/reference/kubernetes-api/labels-annotations-taints/#topologykubernetesiozone)
|
||||
* [`beta.kubernetes.io/instance-type`](/docs/reference/kubernetes-api/labels-annotations-taints/#beta-kubernetes-io-instance-type)
|
||||
* [`node.kubernetes.io/instance-type`](/docs/reference/kubernetes-api/labels-annotations-taints/#nodekubernetesioinstance-type)
|
||||
* [`kubernetes.io/os`](/docs/reference/kubernetes-api/labels-annotations-taints/#kubernetes-io-os)
|
||||
* [`kubernetes.io/arch`](/docs/reference/kubernetes-api/labels-annotations-taints/#kubernetes-io-arch)
|
||||
|
||||
{{< note >}}
|
||||
이 레이블들의 값은 클라우드 공급자에 따라 다르고 신뢰성이 보장되지 않는다.
|
||||
예를 들어 `kubernetes.io/hostname` 은 어떤 환경에서는 노드 이름과 같지만,
|
||||
다른 환경에서는 다른 값일 수 있다.
|
||||
{{< /note >}}
|
||||
|
||||
## 노드 격리(isolation)/제한(restriction)
|
||||
|
||||
노드 오브젝트에 레이블을 추가하면 파드가 특정 노드 또는 노드 그룹을 목표 대상으로 할 수 있게 된다.
|
||||
이는 특정 파드가 어떤 격리, 보안, 또는 규제 속성이 있는 노드에서만 실행되도록 사용할 수 있다.
|
||||
이 목적으로 레이블을 사용하는 경우, 노드에서 kubelet 프로세스로 수정할 수 없는 레이블 키를 선택하는 것을 권장한다.
|
||||
이렇게 하면 손상된 노드가 해당 kubelet 자격 증명을 사용해서 해당 레이블을 자체 노드 오브젝트에 설정하고,
|
||||
스케줄러가 손상된 노드로 워크로드를 스케줄 하는 것을 방지할 수 있다.
|
||||
|
||||
`NodeRestriction` 어드미션 플러그인은 kubelet이 `node-restriction.kubernetes.io/` 접두사로 레이블을 설정 또는 수정하지 못하게 한다.
|
||||
노드 격리에 해당 레이블 접두사를 사용하려면 다음과 같이 한다.
|
||||
|
||||
1. [노드 권한부여자](/docs/reference/access-authn-authz/node/)를 사용하고 있고, [NodeRestriction 어드미션 플러그인](/docs/reference/access-authn-authz/admission-controllers/#noderestriction)을 _활성화_ 해야 한다.
|
||||
2. 노드 오브젝트의 `node-restriction.kubernetes.io/` 접두사 아래에 레이블을 추가하고, 해당 레이블을 노드 셀렉터에서 사용한다.
|
||||
예를 들어, `example.com.node-restriction.kubernetes.io/fips=true` 또는 `example.com.node-restriction.kubernetes.io/pci-dss=true` 이다.
|
||||
|
||||
## 어피니티(affinity)와 안티-어피니티(anti-affinity)
|
||||
|
||||
`nodeSelector` 는 파드를 특정 레이블이 있는 노드로 제한하는 매우 간단한 방법을 제공한다.
|
||||
어피니티/안티-어피니티 기능은 표현할 수 있는 제약 종류를 크게 확장한다. 주요 개선 사항은 다음과 같다.
|
||||
|
||||
1. 어피니티/안티-어피니티 언어가 더 표현적이다. 언어는 논리 연산자인 AND 연산으로 작성된
|
||||
정확한 매칭 항목 이외에 더 많은 매칭 규칙을 제공한다.
|
||||
2. 규칙이 엄격한 요구 사항이 아니라 "유연한(soft)"/"선호(preference)" 규칙을 나타낼 수 있기에 스케줄러가 규칙을 만족할 수 없더라도,
|
||||
파드가 계속 스케줄 되도록 한다.
|
||||
3. 노드 자체에 레이블을 붙이기보다는 노드(또는 다른 토폴로지 도메인)에서 실행 중인 다른 파드의 레이블을 제한할 수 있다.
|
||||
이를 통해 어떤 파드가 함께 위치할 수 있는지와 없는지에 대한 규칙을 적용할 수 있다.
|
||||
|
||||
어피니티 기능은 "노드 어피니티" 와 "파드 간 어피니티/안티-어피니티" 두 종류의 어피니티로 구성된다.
|
||||
노드 어피니티는 기존 `nodeSelector` 와 비슷하지만(그러나 위에서 나열된 첫째와 두 번째 이점이 있다.),
|
||||
파드 간 어피니티/안티-어피니티는 위에서 나열된 세번째 항목에 설명된 대로
|
||||
노드 레이블이 아닌 파드 레이블에 대해 제한되고 위에서 나열된 첫 번째와 두 번째 속성을 가진다.
|
||||
|
||||
### 노드 어피니티
|
||||
|
||||
노드 어피니티는 개념적으로 `nodeSelector` 와 비슷하다 -- 이는 노드의 레이블을 기반으로 파드를
|
||||
스케줄할 수 있는 노드를 제한할 수 있다.
|
||||
|
||||
여기에 현재 `requiredDuringSchedulingIgnoredDuringExecution` 와 `preferredDuringSchedulingIgnoredDuringExecution` 로 부르는
|
||||
두 가지 종류의 노드 어피니티가 있다. 전자는 파드가 노드에 스케줄 되도록 *반드시*
|
||||
규칙을 만족해야 하는 것(`nodeSelector` 와 같으나 보다 표현적인 구문을 사용해서)을 지정하고,
|
||||
후자는 스케줄러가 시도하려고는 하지만, 보증하지 않는 *선호(preferences)* 를 지정한다는 점에서
|
||||
이를 각각 "엄격함(hard)" 과 "유연함(soft)" 으로 생각할 수 있다.
|
||||
이름의 "IgnoredDuringExecution" 부분은 `nodeSelector` 작동 방식과 유사하게 노드의
|
||||
레이블이 런타임 중에 변경되어 파드의 어피니티 규칙이 더 이상 충족되지 않으면 파드가 여전히 그 노드에서
|
||||
동작한다는 의미이다. 향후에는 파드의 노드 어피니티 요구 사항을 충족하지 않는 노드에서 파드를 제거한다는
|
||||
점을 제외하고는 `preferredDuringSchedulingIgnoredDuringExecution` 와 같은 `requiredDuringSchedulingIgnoredDuringExecution` 를 제공할 계획이다.
|
||||
|
||||
따라서 `requiredDuringSchedulingIgnoredDuringExecution` 의 예로는 "인텔 CPU가 있는 노드에서만 파드 실행"이
|
||||
될 수 있고, `preferredDuringSchedulingIgnoredDuringExecution` 의 예로는 "장애 조치 영역 XYZ에 파드 집합을 실행하려고
|
||||
하지만, 불가능하다면 다른 곳에서 일부를 실행하도록 허용"이 있을 것이다.
|
||||
|
||||
노드 어피니티는 PodSpec의 `affinity` 필드의 `nodeAffinity` 필드에서 지정된다.
|
||||
|
||||
여기에 노드 어피니티를 사용하는 파드 예시가 있다.
|
||||
|
||||
{{< codenew file="pods/pod-with-node-affinity.yaml" >}}
|
||||
|
||||
이 노드 어피니티 규칙은 키가 `kubernetes.io/e2e-az-name` 이고 값이 `e2e-az1` 또는 `e2e-az2` 인
|
||||
레이블이 있는 노드에만 파드를 배치할 수 있다고 말한다. 또한, 이 기준을 충족하는 노드들
|
||||
중에서 키가 `another-node-label-key` 이고 값이 `another-node-label-value` 인 레이블이 있는 노드를
|
||||
선호하도록 한다.
|
||||
|
||||
예시에서 연산자 `In` 이 사용되고 있는 것을 볼 수 있다. 새로운 노드 어피니티 구문은 다음의 연산자들을 지원한다. `In`, `NotIn`, `Exists`, `DoesNotExist`, `Gt`, `Lt`.
|
||||
`NotIn` 과 `DoesNotExist` 를 사용해서 안티-어피니티를 수행하거나,
|
||||
특정 노드에서 파드를 쫓아내는 [노드 테인트(taint)](/docs/concepts/configuration/taint-and-toleration/)를 설정할 수 있다.
|
||||
|
||||
`nodeSelector` 와 `nodeAffinity` 를 모두 지정한다면 파드가 후보 노드에 스케줄 되기 위해서는
|
||||
*둘 다* 반드시 만족해야 한다.
|
||||
|
||||
`nodeAffinity` 유형과 연관된 `nodeSelectorTerms` 를 지정하면, 파드는 `nodeSelectorTerms` 를 **모두** 만족하는 노드에만 스케줄할 수 있다.
|
||||
|
||||
`nodeSelectorTerms` 와 연관된 여러 `matchExpressions` 를 지정하면, 파드는 `matchExpressions` 이 지정된 것 중 **한 가지**라도 만족하는 노드에만 스케줄할 수 있다.
|
||||
|
||||
파드가 스케줄 된 노드의 레이블을 지우거나 변경해도 파드는 제거되지 않는다. 다시 말해서 어피니티 선택은 파드를 스케줄링 하는 시점에만 작동한다.
|
||||
|
||||
`preferredDuringSchedulingIgnoredDuringExecution` 의 `weight` 필드의 범위는 1-100이다. 모든 스케줄링 요구 사항 (리소스 요청, RequiredDuringScheduling 어피니티 표현식 등)을 만족하는 각 노드들에 대해 스케줄러는 이 필드의 요소들을 반복해서 합계를 계산하고 노드가 MatchExpressions 에 일치하는 경우 합계에 "가중치(weight)"를 추가한다. 이후에 이 점수는 노드에 대한 다른 우선순위 함수의 점수와 합쳐진다. 전체 점수가 가장 높은 노드를 가장 선호한다.
|
||||
|
||||
### 파드간 어피니티와 안티-어피니티
|
||||
|
||||
파드간 어피니티와 안티-어피니티를 사용하면 노드의 레이블을 기반으로 하지 않고, *노드에서 이미 실행 중인 파드 레이블을 기반으로*
|
||||
파드가 스케줄될 수 있는 노드를 제한할 수 있다. 규칙은 "X가 규칙 Y를 충족하는 하나 이상의 파드를 이미 실행중인 경우
|
||||
이 파드는 X에서 실행해야 한다(또는 안티-어피니티가 없는 경우에는 동작하면 안된다)"는 형태이다. Y는
|
||||
선택적으로 연관된 네임스페이스 목록을 가진 LabelSelector로 표현된다. 노드와는 다르게 파드는 네임스페이스이기에
|
||||
(그리고 따라서 파드의 레이블은 암암리에 네임스페이스이다) 파드 레이블위의 레이블 셀렉터는 반드시
|
||||
셀렉터가 적용될 네임스페이스를 지정해야만 한다. 개념적으로 X는 노드, 랙,
|
||||
클라우드 공급자 영역, 클라우드 공급자 지역 등과 같은 토폴로지 도메인이다. 시스템이 이런 토폴로지
|
||||
도메인을 나타내는 데 사용하는 노드 레이블 키인 `topologyKey` 를 사용하여 이를 표현한다.
|
||||
예: [넘어가기 전에: 빌트인 노드 레이블](#built-in-node-labels) 섹션 위에 나열된 레이블 키를 본다.
|
||||
|
||||
{{< note >}}
|
||||
파드간 어피니티와 안티-어피니티에는 상당한 양의 프로세싱이 필요하기에
|
||||
대규모 클러스터에서는 스케줄링 속도가 크게 느려질 수 있다.
|
||||
수백 개의 노드를 넘어가는 클러스터에서 이를 사용하는 것은 추천하지 않는다.
|
||||
{{< /note >}}
|
||||
|
||||
{{< note >}}
|
||||
파드 안티-어피니티에서는 노드에 일관된 레이블을 지정해야 한다. 즉, 클러스터의 모든 노드는 `topologyKey` 와 매칭되는 적절한 레이블을 가지고 있어야 한다. 일부 또는 모든 노드에 지정된 `topologyKey` 레이블이 없는 경우에는 의도하지 않은 동작이 발생할 수 있다.
|
||||
{{< /note >}}
|
||||
|
||||
노드 어피니티와 마찬가지로 현재 파드 어피니티와 안티-어피니티로 부르는 "엄격함" 대 "유연함"의 요구사항을 나타내는 `requiredDuringSchedulingIgnoredDuringExecution` 와
|
||||
`preferredDuringSchedulingIgnoredDuringExecution` 두 가지 종류가 있다.
|
||||
앞의 노드 어피니티 섹션의 설명을 본다.
|
||||
`requiredDuringSchedulingIgnoredDuringExecution` 어피니티의 예시는
|
||||
"서로 많은 통신을 하기 때문에 서비스 A와 서비스 B를 같은 영역에 함께 위치시키는 것"이고,
|
||||
`preferredDuringSchedulingIgnoredDuringExecution` 안티-어피니티의 예시는 "서비스를 여러 영역에 걸쳐서 분배하는 것"이다
|
||||
(엄격한 요구사항은 영역보다 파드가 더 많을 수 있기 때문에 엄격한 요구사항은 의미가 없다).
|
||||
|
||||
파드간 어피니티는 PodSpec에서 `affinity` 필드 중 `podAffinity` 필드로 지정한다.
|
||||
그리고 파드간 안티-어피니티는 PodSpec에서 `affinity` 필드 중 `podAntiAffinity` 필드로 지정한다.
|
||||
|
||||
#### 파드 어피니티를 사용하는 파드의 예시
|
||||
|
||||
{{< codenew file="pods/pod-with-pod-affinity.yaml" >}}
|
||||
|
||||
이 파드의 어피니티는 하나의 파드 어피니티 규칙과 하나의 파드 안티-어피니티 규칙을 정의한다.
|
||||
이 예시에서 `podAffinity` 는 `requiredDuringSchedulingIgnoredDuringExecution` 이고 `podAntiAffinity` 는
|
||||
`preferredDuringSchedulingIgnoredDuringExecution` 이다. 파드 어피니티 규칙에 의하면 키 "security" 와 값
|
||||
"S1"인 레이블이 있는 하나 이상의 이미 실행 중인 파드와 동일한 영역에 있는 경우에만 파드를 노드에 스케줄할 수 있다.
|
||||
(보다 정확하게는, 클러스터에 키 "security"와 값 "S1"인 레이블을 가지고 있는 실행 중인 파드가 있는 키
|
||||
`failure-domain.beta.kubernetes.io/zone` 와 값 V인 노드가 최소 하나 이상 있고, 노드 N이 키
|
||||
`failure-domain.beta.kubernetes.io/zone` 와 일부 값이 V인 레이블을 가진다면 파드는 노드 N에서 실행할 수 있다.)
|
||||
파드 안티-어피니티 규칙에 의하면 노드가 이미 키 "security"와 값 "S2"인 레이블을 가진 파드를
|
||||
실행하고 있는 파드는 노드에 스케줄되는 것을 선호하지 않는다.
|
||||
(만약 `topologyKey` 가 `failure-domain.beta.kubernetes.io/zone` 라면 노드가 키
|
||||
"security"와 값 "S2"를 레이블로 가진 파드와
|
||||
동일한 영역에 있는 경우, 노드에 파드를 예약할 수 없음을 의미한다.)
|
||||
[디자인 문서](https://git.k8s.io/community/contributors/design-proposals/scheduling/podaffinity.md)를 통해
|
||||
`requiredDuringSchedulingIgnoredDuringExecution` 와 `preferredDuringSchedulingIgnoredDuringExecution` 의
|
||||
파드 어피니티와 안티-어피니티에 대한 많은 예시를 맛볼 수 있다.
|
||||
|
||||
파드 어피니티와 안티-어피니티의 적합한 연산자는 `In`, `NotIn`, `Exists`, `DoesNotExist` 이다.
|
||||
|
||||
원칙적으로, `topologyKey` 는 적법한 어느 레이블-키도 될 수 있다.
|
||||
하지만, 성능과 보안상의 이유로 topologyKey에는 몇 가지 제약조건이 있다.
|
||||
|
||||
1. 어피니티와 `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티는 대해
|
||||
`topologyKey` 가 비어있는 것을 허용하지 않는다.
|
||||
2. `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에서 `topologyKey` 를 `kubernetes.io/hostname` 로 제한하기 위해 어드미션 컨트롤러 `LimitPodHardAntiAffinityTopology` 가 도입되었다. 사용자 지정 토폴로지를에 사용할 수 있도록 하려면, 어드미션 컨트롤러를 수정하거나 간단히 이를 비활성화 할 수 있다.
|
||||
3. `preferredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티는 `topologyKey` 가 비어있는 것을 허용하지 않는다.
|
||||
4. 위의 경우를 제외하고, `topologyKey` 는 적법한 어느 레이블-키도 가능하다.
|
||||
|
||||
`labelSelector` 와 `topologyKey` 외에도 `labelSelector` 와 일치해야 하는 네임스페이스 목록 `namespaces` 를
|
||||
선택적으로 지정할 수 있다(이것은 `labelSelector` 와 `topologyKey` 와 같은 수준의 정의이다).
|
||||
생략되어있거나 비어있을 경우 어피니티/안티-어피니티 정의가 있는 파드의 네임스페이스가 기본 값이다.
|
||||
|
||||
파드를 노드에 스케줄하려면 `requiredDuringSchedulingIgnoredDuringExecution` 어피니티와 안티-어피니티와
|
||||
연관된 `matchExpressions` 가 모두 충족되어야 한다.
|
||||
|
||||
#### 더 실용적인 유스케이스
|
||||
|
||||
파드간 어피니티와 안티-어피니티는 레플리카셋, 스테이트풀셋, 디플로이먼트 등과 같은
|
||||
상위 레벨 모음과 함께 사용할 때 더욱 유용할 수 있다. 워크로드 집합이 동일한 노드와 같이
|
||||
동일하게 정의된 토폴로지와 같은 위치에 배치되도록 쉽게 구성할 수 있다.
|
||||
|
||||
##### 항상 같은 노드에 위치시키기
|
||||
|
||||
세 개의 노드가 있는 클러스터에서 웹 애플리케이션에는 redis와 같은 인-메모리 캐시가 있다. 웹 서버가 가능한 캐시와 함께 위치하기를 원한다.
|
||||
|
||||
다음은 세 개의 레플리카와 셀렉터 레이블이 `app=store` 가 있는 간단한 redis 디플로이먼트의 yaml 스니펫이다. 디플로이먼트에는 스케줄러가 단일 노드에서 레플리카를 함께 배치하지 않도록 `PodAntiAffinity` 가 구성되어 있다.
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: redis-cache
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: store
|
||||
replicas: 3
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: store
|
||||
spec:
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- labelSelector:
|
||||
matchExpressions:
|
||||
- key: app
|
||||
operator: In
|
||||
values:
|
||||
- store
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
containers:
|
||||
- name: redis-server
|
||||
image: redis:3.2-alpine
|
||||
```
|
||||
|
||||
아래 yaml 스니펫의 웹서버 디플로이먼트는 `podAntiAffinity` 와 `podAffinity` 설정을 가지고 있다. 이렇게 하면 스케줄러에 모든 레플리카는 셀렉터 레이블이 `app=store` 인 파드와 함께 위치해야 한다. 또한 각 웹 서버 레플리카가 단일 노드의 같은 위치에 있지 않도록 한다.
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: web-server
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: web-store
|
||||
replicas: 3
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: web-store
|
||||
spec:
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- labelSelector:
|
||||
matchExpressions:
|
||||
- key: app
|
||||
operator: In
|
||||
values:
|
||||
- web-store
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
podAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- labelSelector:
|
||||
matchExpressions:
|
||||
- key: app
|
||||
operator: In
|
||||
values:
|
||||
- store
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
containers:
|
||||
- name: web-app
|
||||
image: nginx:1.16-alpine
|
||||
```
|
||||
|
||||
만약 위의 두 디플로이먼트를 생성하면 세 개의 노드가 있는 클러스터는 다음과 같아야 한다.
|
||||
|
||||
| node-1 | node-2 | node-3 |
|
||||
|:--------------------:|:-------------------:|:------------------:|
|
||||
| *webserver-1* | *webserver-2* | *webserver-3* |
|
||||
| *cache-1* | *cache-2* | *cache-3* |
|
||||
|
||||
여기서 볼 수 있듯이 `web-server` 의 세 레플리카들이 기대했던 것처럼 자동으로 캐시와 함께 위치하게 된다.
|
||||
|
||||
```
|
||||
kubectl get pods -o wide
|
||||
```
|
||||
출력은 다음과 유사할 것이다.
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE IP NODE
|
||||
redis-cache-1450370735-6dzlj 1/1 Running 0 8m 10.192.4.2 kube-node-3
|
||||
redis-cache-1450370735-j2j96 1/1 Running 0 8m 10.192.2.2 kube-node-1
|
||||
redis-cache-1450370735-z73mh 1/1 Running 0 8m 10.192.3.1 kube-node-2
|
||||
web-server-1287567482-5d4dz 1/1 Running 0 7m 10.192.2.3 kube-node-1
|
||||
web-server-1287567482-6f7v5 1/1 Running 0 7m 10.192.4.3 kube-node-3
|
||||
web-server-1287567482-s330j 1/1 Running 0 7m 10.192.3.2 kube-node-2
|
||||
```
|
||||
|
||||
##### 절대 동일한 노드에 위치시키지 않게 하기
|
||||
|
||||
위의 예시에서 `topologyKey:"kubernetes.io/hostname"` 과 함께 `PodAntiAffinity` 규칙을 사용해서
|
||||
두 개의 인스터스가 동일한 호스트에 있지 않도록 redis 클러스터를 배포한다.
|
||||
같은 기술을 사용해서 고 가용성을 위해 안티-어피니티로 구성된 스테이트풀셋의 예시는
|
||||
[ZooKeeper 튜토리얼](/ko/docs/tutorials/stateful-application/zookeeper/#노드-실패-방지)을 본다.
|
||||
|
||||
## nodeName
|
||||
|
||||
`nodeName` 은 가장 간단한 형태의 노트 선택 제약 조건이지만,
|
||||
한계로 인해 일반적으로는 사용하지 않는다.
|
||||
`nodeName` 은 PodSpec의 필드이다. 만약 비어있지 않으면, 스케줄러는
|
||||
파드를 무시하고 명명된 노드에서 실행 중인 kubelet이
|
||||
파드를 실행하려고 한다. 따라서 만약 PodSpec에 `nodeName` 가
|
||||
제공된 경우, 노드 선텍을 위해 위의 방법보다 우선한다.
|
||||
|
||||
`nodeName` 을 사용해서 노드를 선택할 때의 몇 가지 제한은 다음과 같다.
|
||||
|
||||
- 만약 명명된 노드가 없으면, 파드가 실행되지 않고
|
||||
따라서 자동으로 삭제될 수 있다.
|
||||
- 만약 명명된 노드에 파드를 수용할 수 있는
|
||||
리소스가 없는 경우 파드가 실패하고, 그 이유는 다음과 같이 표시된다.
|
||||
예: OutOfmemory 또는 OutOfcpu.
|
||||
- 클라우드 환경의 노드 이름은 항상 예측 가능하거나
|
||||
안정적인 것은 아니다.
|
||||
|
||||
여기에 `nodeName` 필드를 사용하는 파드 설정 파일 예시가 있다.
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx
|
||||
nodeName: kube-01
|
||||
```
|
||||
|
||||
위 파드는 kube-01 노드에서 실행될 것이다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
|
||||
[테인트](/docs/concepts/configuration/taint-and-toleration/)는 노드가 특정 파드들을 *쫓아내게* 할 수 있다.
|
||||
|
||||
[노드 어피니티](https://git.k8s.io/community/contributors/design-proposals/scheduling/nodeaffinity.md)와
|
||||
[파드간 어피니티/안티-어피니티](https://git.k8s.io/community/contributors/design-proposals/scheduling/podaffinity.md)에 대한 디자인 문서에는
|
||||
이러한 기능에 대한 추가 배경 정보가 있다.
|
||||
|
||||
파드가 노드에 할당되면 kubelet은 파드를 실행하고 노드의 로컬 리소스를 할당한다.
|
||||
[토폴로지 매니저](/docs/tasks/administer-cluster/topology-manager/)는
|
||||
노드 수준의 리소스 할당 결정에 참여할 수 있다.
|
||||
|
||||
{{% /capture %}}
|
||||
---
|
||||
title: 노드에 파드 할당하기
|
||||
content_template: templates/concept
|
||||
weight: 50
|
||||
---
|
||||
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
{{< glossary_tooltip text="파드" term_id="pod" >}}를 특정한 {{< glossary_tooltip text="노드(들)" term_id="node" >}}에서만 동작하도록 하거나,
|
||||
특정 노드들을 선호하도록 제한할 수 있다.
|
||||
이를 수행하는 방법에는 여러 가지가 있으며, 권장되는 접근 방식은 모두
|
||||
[레이블 셀렉터](/ko/docs/concepts/overview/working-with-objects/labels/)를 사용하여 선택한다.
|
||||
보통 스케줄러가 자동으로 합리적인 배치(예: 노드들에 걸쳐 파드를 분배하거나,
|
||||
자원이 부족한 노드에 파드를 배치하지 않는 등)를 수행하기에 이런 제약 조건은 필요하지 않지만
|
||||
간혹 파드가 배치되는 노드에 대해 더 많은 제어를 원할 수 있는 상황이 있다.
|
||||
예를 들어 SSD가 장착된 머신에 파드가 연결되도록 하거나 또는 동일한 가용성 영역(availability zone)에서
|
||||
많은 것을 통신하는 두 개의 서로 다른 서비스의 파드를 같이 배치할 수 있다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
## 노드 셀렉터(nodeSelector)
|
||||
|
||||
`nodeSelector` 는 가장 간단하고 권장되는 노드 선택 제약 조건의 형태이다.
|
||||
`nodeSelector` 는 PodSpec의 필드이다. 이는 키-값 쌍의 매핑으로 지정한다. 파드가 노드에서 동작할 수 있으려면,
|
||||
노드는 키-값의 쌍으로 표시되는 레이블을 각자 가지고 있어야 한다(이는 추가 레이블을 가지고 있을 수 있다).
|
||||
일반적으로 하나의 키-값 쌍이 사용된다.
|
||||
|
||||
`nodeSelector` 를 어떻게 사용하는지 예시를 통해 알아보도록 하자.
|
||||
|
||||
### 0 단계: 사전 준비
|
||||
|
||||
이 예시는 쿠버네티스 파드에 대한 기본적인 이해를 하고 있고 [쿠버네티스 클러스터가 설정](/ko/docs/setup/)되어 있다고 가정한다.
|
||||
|
||||
### 1 단계: 노드에 레이블 붙이기
|
||||
|
||||
`kubectl get nodes` 를 실행해서 클러스터 노드 이름을 가져온다. 이 중에 레이블을 추가하기 원하는 것 하나를 선택한 다음에 `kubectl label nodes <노드 이름> <레이블 키>=<레이블 값>` 을 실행해서 선택한 노드에 레이블을 추가한다. 예를 들어 노드의 이름이 'kubernetes-foo-node-1.c.a-robinson.internal' 이고, 원하는 레이블이 'disktype=ssd' 라면, `kubectl label nodes kubernetes-foo-node-1.c.a-robinson.internal disktype=ssd` 를 실행한다.
|
||||
|
||||
`kubectl get nodes --show-labels` 를 다시 실행해서 노드가 현재 가진 레이블을 확인하여, 이 작업을 검증할 수 있다. 또한 `kubectl describe node "노드 이름"` 을 사용해서 노드에 주어진 레이블의 전체 목록을 확인할 수 있다.
|
||||
|
||||
### 2 단계: 파드 설정에 nodeSelector 필드 추가하기
|
||||
|
||||
실행하고자 하는 파드의 설정 파일을 가져오고, 이처럼 nodeSelector 섹션을 추가한다. 예를 들어 이것이 파드 설정이라면,
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: nginx
|
||||
labels:
|
||||
env: test
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx
|
||||
```
|
||||
|
||||
이 다음에 nodeSelector 를 다음과 같이 추가한다.
|
||||
|
||||
{{< codenew file="pods/pod-nginx.yaml" >}}
|
||||
|
||||
그런 다음에 `kubectl apply -f https://k8s.io/examples/pods/pod-nginx.yaml` 을
|
||||
실행하면, 레이블이 붙여진 노드에 파드가 스케줄 된다.
|
||||
`kubectl get pods -o wide` 를 실행해서 파드가 할당된
|
||||
"NODE" 를 보면 작동하는지 검증할 수 있다.
|
||||
|
||||
## 넘어가기 전에: 내장 노드 레이블들 {#built-in-node-labels}
|
||||
|
||||
[붙인](#1-단계-노드에-레이블-붙이기) 레이블뿐만 아니라, 노드에는
|
||||
표준 레이블 셋이 미리 채워져 있다. 이 레이블들은 다음과 같다.
|
||||
|
||||
* [`kubernetes.io/hostname`](/docs/reference/kubernetes-api/labels-annotations-taints/#kubernetes-io-hostname)
|
||||
* [`failure-domain.beta.kubernetes.io/zone`](/docs/reference/kubernetes-api/labels-annotations-taints/#failure-domainbetakubernetesiozone)
|
||||
* [`failure-domain.beta.kubernetes.io/region`](/docs/reference/kubernetes-api/labels-annotations-taints/#failure-domainbetakubernetesioregion)
|
||||
* [`topology.kubernetes.io/zone`](/docs/reference/kubernetes-api/labels-annotations-taints/#topologykubernetesiozone)
|
||||
* [`topology.kubernetes.io/region`](/docs/reference/kubernetes-api/labels-annotations-taints/#topologykubernetesiozone)
|
||||
* [`beta.kubernetes.io/instance-type`](/docs/reference/kubernetes-api/labels-annotations-taints/#beta-kubernetes-io-instance-type)
|
||||
* [`node.kubernetes.io/instance-type`](/docs/reference/kubernetes-api/labels-annotations-taints/#nodekubernetesioinstance-type)
|
||||
* [`kubernetes.io/os`](/docs/reference/kubernetes-api/labels-annotations-taints/#kubernetes-io-os)
|
||||
* [`kubernetes.io/arch`](/docs/reference/kubernetes-api/labels-annotations-taints/#kubernetes-io-arch)
|
||||
|
||||
{{< note >}}
|
||||
이 레이블들의 값은 클라우드 공급자에 따라 다르고 신뢰성이 보장되지 않는다.
|
||||
예를 들어 `kubernetes.io/hostname` 은 어떤 환경에서는 노드 이름과 같지만,
|
||||
다른 환경에서는 다른 값일 수 있다.
|
||||
{{< /note >}}
|
||||
|
||||
## 노드 격리(isolation)/제한(restriction)
|
||||
|
||||
노드 오브젝트에 레이블을 추가하면 파드가 특정 노드 또는 노드 그룹을 목표 대상으로 할 수 있게 된다.
|
||||
이는 특정 파드가 어떤 격리, 보안, 또는 규제 속성이 있는 노드에서만 실행되도록 사용할 수 있다.
|
||||
이 목적으로 레이블을 사용하는 경우, 노드에서 kubelet 프로세스로 수정할 수 없는 레이블 키를 선택하는 것을 권장한다.
|
||||
이렇게 하면 손상된 노드가 해당 kubelet 자격 증명을 사용해서 해당 레이블을 자체 노드 오브젝트에 설정하고,
|
||||
스케줄러가 손상된 노드로 워크로드를 스케줄 하는 것을 방지할 수 있다.
|
||||
|
||||
`NodeRestriction` 어드미션 플러그인은 kubelet이 `node-restriction.kubernetes.io/` 접두사로 레이블을 설정 또는 수정하지 못하게 한다.
|
||||
노드 격리에 해당 레이블 접두사를 사용하려면 다음과 같이 한다.
|
||||
|
||||
1. [노드 권한부여자](/docs/reference/access-authn-authz/node/)를 사용하고 있고, [NodeRestriction 어드미션 플러그인](/docs/reference/access-authn-authz/admission-controllers/#noderestriction)을 _활성화_ 해야 한다.
|
||||
2. 노드 오브젝트의 `node-restriction.kubernetes.io/` 접두사 아래에 레이블을 추가하고, 해당 레이블을 노드 셀렉터에서 사용한다.
|
||||
예를 들어, `example.com.node-restriction.kubernetes.io/fips=true` 또는 `example.com.node-restriction.kubernetes.io/pci-dss=true` 이다.
|
||||
|
||||
## 어피니티(affinity)와 안티-어피니티(anti-affinity)
|
||||
|
||||
`nodeSelector` 는 파드를 특정 레이블이 있는 노드로 제한하는 매우 간단한 방법을 제공한다.
|
||||
어피니티/안티-어피니티 기능은 표현할 수 있는 제약 종류를 크게 확장한다. 주요 개선 사항은 다음과 같다.
|
||||
|
||||
1. 어피니티/안티-어피니티 언어가 더 표현적이다. 언어는 논리 연산자인 AND 연산으로 작성된
|
||||
정확한 매칭 항목 이외에 더 많은 매칭 규칙을 제공한다.
|
||||
2. 규칙이 엄격한 요구 사항이 아니라 "유연한(soft)"/"선호(preference)" 규칙을 나타낼 수 있기에 스케줄러가 규칙을 만족할 수 없더라도,
|
||||
파드가 계속 스케줄 되도록 한다.
|
||||
3. 노드 자체에 레이블을 붙이기보다는 노드(또는 다른 토폴로지 도메인)에서 실행 중인 다른 파드의 레이블을 제한할 수 있다.
|
||||
이를 통해 어떤 파드가 함께 위치할 수 있는지와 없는지에 대한 규칙을 적용할 수 있다.
|
||||
|
||||
어피니티 기능은 "노드 어피니티" 와 "파드 간 어피니티/안티-어피니티" 두 종류의 어피니티로 구성된다.
|
||||
노드 어피니티는 기존 `nodeSelector` 와 비슷하지만(그러나 위에서 나열된 첫째와 두 번째 이점이 있다.),
|
||||
파드 간 어피니티/안티-어피니티는 위에서 나열된 세번째 항목에 설명된 대로
|
||||
노드 레이블이 아닌 파드 레이블에 대해 제한되고 위에서 나열된 첫 번째와 두 번째 속성을 가진다.
|
||||
|
||||
### 노드 어피니티
|
||||
|
||||
노드 어피니티는 개념적으로 `nodeSelector` 와 비슷하다 -- 이는 노드의 레이블을 기반으로 파드를
|
||||
스케줄할 수 있는 노드를 제한할 수 있다.
|
||||
|
||||
여기에 현재 `requiredDuringSchedulingIgnoredDuringExecution` 와 `preferredDuringSchedulingIgnoredDuringExecution` 로 부르는
|
||||
두 가지 종류의 노드 어피니티가 있다. 전자는 파드가 노드에 스케줄 되도록 *반드시*
|
||||
규칙을 만족해야 하는 것(`nodeSelector` 와 같으나 보다 표현적인 구문을 사용해서)을 지정하고,
|
||||
후자는 스케줄러가 시도하려고는 하지만, 보증하지 않는 *선호(preferences)* 를 지정한다는 점에서
|
||||
이를 각각 "엄격함(hard)" 과 "유연함(soft)" 으로 생각할 수 있다.
|
||||
이름의 "IgnoredDuringExecution" 부분은 `nodeSelector` 작동 방식과 유사하게 노드의
|
||||
레이블이 런타임 중에 변경되어 파드의 어피니티 규칙이 더 이상 충족되지 않으면 파드가 여전히 그 노드에서
|
||||
동작한다는 의미이다. 향후에는 파드의 노드 어피니티 요구 사항을 충족하지 않는 노드에서 파드를 제거한다는
|
||||
점을 제외하고는 `preferredDuringSchedulingIgnoredDuringExecution` 와 같은 `requiredDuringSchedulingIgnoredDuringExecution` 를 제공할 계획이다.
|
||||
|
||||
따라서 `requiredDuringSchedulingIgnoredDuringExecution` 의 예로는 "인텔 CPU가 있는 노드에서만 파드 실행"이
|
||||
될 수 있고, `preferredDuringSchedulingIgnoredDuringExecution` 의 예로는 "장애 조치 영역 XYZ에 파드 집합을 실행하려고
|
||||
하지만, 불가능하다면 다른 곳에서 일부를 실행하도록 허용"이 있을 것이다.
|
||||
|
||||
노드 어피니티는 PodSpec의 `affinity` 필드의 `nodeAffinity` 필드에서 지정된다.
|
||||
|
||||
여기에 노드 어피니티를 사용하는 파드 예시가 있다.
|
||||
|
||||
{{< codenew file="pods/pod-with-node-affinity.yaml" >}}
|
||||
|
||||
이 노드 어피니티 규칙은 키가 `kubernetes.io/e2e-az-name` 이고 값이 `e2e-az1` 또는 `e2e-az2` 인
|
||||
레이블이 있는 노드에만 파드를 배치할 수 있다고 말한다. 또한, 이 기준을 충족하는 노드들
|
||||
중에서 키가 `another-node-label-key` 이고 값이 `another-node-label-value` 인 레이블이 있는 노드를
|
||||
선호하도록 한다.
|
||||
|
||||
예시에서 연산자 `In` 이 사용되고 있는 것을 볼 수 있다. 새로운 노드 어피니티 구문은 다음의 연산자들을 지원한다. `In`, `NotIn`, `Exists`, `DoesNotExist`, `Gt`, `Lt`.
|
||||
`NotIn` 과 `DoesNotExist` 를 사용해서 안티-어피니티를 수행하거나,
|
||||
특정 노드에서 파드를 쫓아내는 [노드 테인트(taint)](/docs/concepts/configuration/taint-and-toleration/)를 설정할 수 있다.
|
||||
|
||||
`nodeSelector` 와 `nodeAffinity` 를 모두 지정한다면 파드가 후보 노드에 스케줄 되기 위해서는
|
||||
*둘 다* 반드시 만족해야 한다.
|
||||
|
||||
`nodeAffinity` 유형과 연관된 `nodeSelectorTerms` 를 지정하면, 파드는 `nodeSelectorTerms` 를 **모두** 만족하는 노드에만 스케줄할 수 있다.
|
||||
|
||||
`nodeSelectorTerms` 와 연관된 여러 `matchExpressions` 를 지정하면, 파드는 `matchExpressions` 이 지정된 것 중 **한 가지**라도 만족하는 노드에만 스케줄할 수 있다.
|
||||
|
||||
파드가 스케줄 된 노드의 레이블을 지우거나 변경해도 파드는 제거되지 않는다. 다시 말해서 어피니티 선택은 파드를 스케줄링 하는 시점에만 작동한다.
|
||||
|
||||
`preferredDuringSchedulingIgnoredDuringExecution` 의 `weight` 필드의 범위는 1-100이다. 모든 스케줄링 요구 사항 (리소스 요청, RequiredDuringScheduling 어피니티 표현식 등)을 만족하는 각 노드들에 대해 스케줄러는 이 필드의 요소들을 반복해서 합계를 계산하고 노드가 MatchExpressions 에 일치하는 경우 합계에 "가중치(weight)"를 추가한다. 이후에 이 점수는 노드에 대한 다른 우선순위 함수의 점수와 합쳐진다. 전체 점수가 가장 높은 노드를 가장 선호한다.
|
||||
|
||||
### 파드간 어피니티와 안티-어피니티
|
||||
|
||||
파드간 어피니티와 안티-어피니티를 사용하면 노드의 레이블을 기반으로 하지 않고, *노드에서 이미 실행 중인 파드 레이블을 기반으로*
|
||||
파드가 스케줄될 수 있는 노드를 제한할 수 있다. 규칙은 "X가 규칙 Y를 충족하는 하나 이상의 파드를 이미 실행중인 경우
|
||||
이 파드는 X에서 실행해야 한다(또는 안티-어피니티가 없는 경우에는 동작하면 안된다)"는 형태이다. Y는
|
||||
선택적으로 연관된 네임스페이스 목록을 가진 LabelSelector로 표현된다. 노드와는 다르게 파드는 네임스페이스이기에
|
||||
(그리고 따라서 파드의 레이블은 암암리에 네임스페이스이다) 파드 레이블위의 레이블 셀렉터는 반드시
|
||||
셀렉터가 적용될 네임스페이스를 지정해야만 한다. 개념적으로 X는 노드, 랙,
|
||||
클라우드 공급자 영역, 클라우드 공급자 지역 등과 같은 토폴로지 도메인이다. 시스템이 이런 토폴로지
|
||||
도메인을 나타내는 데 사용하는 노드 레이블 키인 `topologyKey` 를 사용하여 이를 표현한다.
|
||||
예: [넘어가기 전에: 빌트인 노드 레이블](#built-in-node-labels) 섹션 위에 나열된 레이블 키를 본다.
|
||||
|
||||
{{< note >}}
|
||||
파드간 어피니티와 안티-어피니티에는 상당한 양의 프로세싱이 필요하기에
|
||||
대규모 클러스터에서는 스케줄링 속도가 크게 느려질 수 있다.
|
||||
수백 개의 노드를 넘어가는 클러스터에서 이를 사용하는 것은 추천하지 않는다.
|
||||
{{< /note >}}
|
||||
|
||||
{{< note >}}
|
||||
파드 안티-어피니티에서는 노드에 일관된 레이블을 지정해야 한다. 즉, 클러스터의 모든 노드는 `topologyKey` 와 매칭되는 적절한 레이블을 가지고 있어야 한다. 일부 또는 모든 노드에 지정된 `topologyKey` 레이블이 없는 경우에는 의도하지 않은 동작이 발생할 수 있다.
|
||||
{{< /note >}}
|
||||
|
||||
노드 어피니티와 마찬가지로 현재 파드 어피니티와 안티-어피니티로 부르는 "엄격함" 대 "유연함"의 요구사항을 나타내는 `requiredDuringSchedulingIgnoredDuringExecution` 와
|
||||
`preferredDuringSchedulingIgnoredDuringExecution` 두 가지 종류가 있다.
|
||||
앞의 노드 어피니티 섹션의 설명을 본다.
|
||||
`requiredDuringSchedulingIgnoredDuringExecution` 어피니티의 예시는
|
||||
"서로 많은 통신을 하기 때문에 서비스 A와 서비스 B를 같은 영역에 함께 위치시키는 것"이고,
|
||||
`preferredDuringSchedulingIgnoredDuringExecution` 안티-어피니티의 예시는 "서비스를 여러 영역에 걸쳐서 분배하는 것"이다
|
||||
(엄격한 요구사항은 영역보다 파드가 더 많을 수 있기 때문에 엄격한 요구사항은 의미가 없다).
|
||||
|
||||
파드간 어피니티는 PodSpec에서 `affinity` 필드 중 `podAffinity` 필드로 지정한다.
|
||||
그리고 파드간 안티-어피니티는 PodSpec에서 `affinity` 필드 중 `podAntiAffinity` 필드로 지정한다.
|
||||
|
||||
#### 파드 어피니티를 사용하는 파드의 예시
|
||||
|
||||
{{< codenew file="pods/pod-with-pod-affinity.yaml" >}}
|
||||
|
||||
이 파드의 어피니티는 하나의 파드 어피니티 규칙과 하나의 파드 안티-어피니티 규칙을 정의한다.
|
||||
이 예시에서 `podAffinity` 는 `requiredDuringSchedulingIgnoredDuringExecution` 이고 `podAntiAffinity` 는
|
||||
`preferredDuringSchedulingIgnoredDuringExecution` 이다. 파드 어피니티 규칙에 의하면 키 "security" 와 값
|
||||
"S1"인 레이블이 있는 하나 이상의 이미 실행 중인 파드와 동일한 영역에 있는 경우에만 파드를 노드에 스케줄할 수 있다.
|
||||
(보다 정확하게는, 클러스터에 키 "security"와 값 "S1"인 레이블을 가지고 있는 실행 중인 파드가 있는 키
|
||||
`failure-domain.beta.kubernetes.io/zone` 와 값 V인 노드가 최소 하나 이상 있고, 노드 N이 키
|
||||
`failure-domain.beta.kubernetes.io/zone` 와 일부 값이 V인 레이블을 가진다면 파드는 노드 N에서 실행할 수 있다.)
|
||||
파드 안티-어피니티 규칙에 의하면 노드가 이미 키 "security"와 값 "S2"인 레이블을 가진 파드를
|
||||
실행하고 있는 파드는 노드에 스케줄되는 것을 선호하지 않는다.
|
||||
(만약 `topologyKey` 가 `failure-domain.beta.kubernetes.io/zone` 라면 노드가 키
|
||||
"security"와 값 "S2"를 레이블로 가진 파드와
|
||||
동일한 영역에 있는 경우, 노드에 파드를 예약할 수 없음을 의미한다.)
|
||||
[디자인 문서](https://git.k8s.io/community/contributors/design-proposals/scheduling/podaffinity.md)를 통해
|
||||
`requiredDuringSchedulingIgnoredDuringExecution` 와 `preferredDuringSchedulingIgnoredDuringExecution` 의
|
||||
파드 어피니티와 안티-어피니티에 대한 많은 예시를 맛볼 수 있다.
|
||||
|
||||
파드 어피니티와 안티-어피니티의 적합한 연산자는 `In`, `NotIn`, `Exists`, `DoesNotExist` 이다.
|
||||
|
||||
원칙적으로, `topologyKey` 는 적법한 어느 레이블-키도 될 수 있다.
|
||||
하지만, 성능과 보안상의 이유로 topologyKey에는 몇 가지 제약조건이 있다.
|
||||
|
||||
1. 어피니티와 `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티는 대해
|
||||
`topologyKey` 가 비어있는 것을 허용하지 않는다.
|
||||
2. `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에서 `topologyKey` 를 `kubernetes.io/hostname` 로 제한하기 위해 어드미션 컨트롤러 `LimitPodHardAntiAffinityTopology` 가 도입되었다. 사용자 지정 토폴로지를에 사용할 수 있도록 하려면, 어드미션 컨트롤러를 수정하거나 간단히 이를 비활성화 할 수 있다.
|
||||
3. `preferredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티는 `topologyKey` 가 비어있는 것을 허용하지 않는다.
|
||||
4. 위의 경우를 제외하고, `topologyKey` 는 적법한 어느 레이블-키도 가능하다.
|
||||
|
||||
`labelSelector` 와 `topologyKey` 외에도 `labelSelector` 와 일치해야 하는 네임스페이스 목록 `namespaces` 를
|
||||
선택적으로 지정할 수 있다(이것은 `labelSelector` 와 `topologyKey` 와 같은 수준의 정의이다).
|
||||
생략되어있거나 비어있을 경우 어피니티/안티-어피니티 정의가 있는 파드의 네임스페이스가 기본 값이다.
|
||||
|
||||
파드를 노드에 스케줄하려면 `requiredDuringSchedulingIgnoredDuringExecution` 어피니티와 안티-어피니티와
|
||||
연관된 `matchExpressions` 가 모두 충족되어야 한다.
|
||||
|
||||
#### 더 실용적인 유스케이스
|
||||
|
||||
파드간 어피니티와 안티-어피니티는 레플리카셋, 스테이트풀셋, 디플로이먼트 등과 같은
|
||||
상위 레벨 모음과 함께 사용할 때 더욱 유용할 수 있다. 워크로드 집합이 동일한 노드와 같이
|
||||
동일하게 정의된 토폴로지와 같은 위치에 배치되도록 쉽게 구성할 수 있다.
|
||||
|
||||
##### 항상 같은 노드에 위치시키기
|
||||
|
||||
세 개의 노드가 있는 클러스터에서 웹 애플리케이션에는 redis와 같은 인-메모리 캐시가 있다. 웹 서버가 가능한 캐시와 함께 위치하기를 원한다.
|
||||
|
||||
다음은 세 개의 레플리카와 셀렉터 레이블이 `app=store` 가 있는 간단한 redis 디플로이먼트의 yaml 스니펫이다. 디플로이먼트에는 스케줄러가 단일 노드에서 레플리카를 함께 배치하지 않도록 `PodAntiAffinity` 가 구성되어 있다.
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: redis-cache
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: store
|
||||
replicas: 3
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: store
|
||||
spec:
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- labelSelector:
|
||||
matchExpressions:
|
||||
- key: app
|
||||
operator: In
|
||||
values:
|
||||
- store
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
containers:
|
||||
- name: redis-server
|
||||
image: redis:3.2-alpine
|
||||
```
|
||||
|
||||
아래 yaml 스니펫의 웹서버 디플로이먼트는 `podAntiAffinity` 와 `podAffinity` 설정을 가지고 있다. 이렇게 하면 스케줄러에 모든 레플리카는 셀렉터 레이블이 `app=store` 인 파드와 함께 위치해야 한다. 또한 각 웹 서버 레플리카가 단일 노드의 같은 위치에 있지 않도록 한다.
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: web-server
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: web-store
|
||||
replicas: 3
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: web-store
|
||||
spec:
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- labelSelector:
|
||||
matchExpressions:
|
||||
- key: app
|
||||
operator: In
|
||||
values:
|
||||
- web-store
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
podAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- labelSelector:
|
||||
matchExpressions:
|
||||
- key: app
|
||||
operator: In
|
||||
values:
|
||||
- store
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
containers:
|
||||
- name: web-app
|
||||
image: nginx:1.16-alpine
|
||||
```
|
||||
|
||||
만약 위의 두 디플로이먼트를 생성하면 세 개의 노드가 있는 클러스터는 다음과 같아야 한다.
|
||||
|
||||
| node-1 | node-2 | node-3 |
|
||||
|:--------------------:|:-------------------:|:------------------:|
|
||||
| *webserver-1* | *webserver-2* | *webserver-3* |
|
||||
| *cache-1* | *cache-2* | *cache-3* |
|
||||
|
||||
여기서 볼 수 있듯이 `web-server` 의 세 레플리카들이 기대했던 것처럼 자동으로 캐시와 함께 위치하게 된다.
|
||||
|
||||
```
|
||||
kubectl get pods -o wide
|
||||
```
|
||||
출력은 다음과 유사할 것이다.
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE IP NODE
|
||||
redis-cache-1450370735-6dzlj 1/1 Running 0 8m 10.192.4.2 kube-node-3
|
||||
redis-cache-1450370735-j2j96 1/1 Running 0 8m 10.192.2.2 kube-node-1
|
||||
redis-cache-1450370735-z73mh 1/1 Running 0 8m 10.192.3.1 kube-node-2
|
||||
web-server-1287567482-5d4dz 1/1 Running 0 7m 10.192.2.3 kube-node-1
|
||||
web-server-1287567482-6f7v5 1/1 Running 0 7m 10.192.4.3 kube-node-3
|
||||
web-server-1287567482-s330j 1/1 Running 0 7m 10.192.3.2 kube-node-2
|
||||
```
|
||||
|
||||
##### 절대 동일한 노드에 위치시키지 않게 하기
|
||||
|
||||
위의 예시에서 `topologyKey:"kubernetes.io/hostname"` 과 함께 `PodAntiAffinity` 규칙을 사용해서
|
||||
두 개의 인스터스가 동일한 호스트에 있지 않도록 redis 클러스터를 배포한다.
|
||||
같은 기술을 사용해서 고 가용성을 위해 안티-어피니티로 구성된 스테이트풀셋의 예시는
|
||||
[ZooKeeper 튜토리얼](/ko/docs/tutorials/stateful-application/zookeeper/#노드-실패-방지)을 본다.
|
||||
|
||||
## nodeName
|
||||
|
||||
`nodeName` 은 가장 간단한 형태의 노트 선택 제약 조건이지만,
|
||||
한계로 인해 일반적으로는 사용하지 않는다.
|
||||
`nodeName` 은 PodSpec의 필드이다. 만약 비어있지 않으면, 스케줄러는
|
||||
파드를 무시하고 명명된 노드에서 실행 중인 kubelet이
|
||||
파드를 실행하려고 한다. 따라서 만약 PodSpec에 `nodeName` 가
|
||||
제공된 경우, 노드 선텍을 위해 위의 방법보다 우선한다.
|
||||
|
||||
`nodeName` 을 사용해서 노드를 선택할 때의 몇 가지 제한은 다음과 같다.
|
||||
|
||||
- 만약 명명된 노드가 없으면, 파드가 실행되지 않고
|
||||
따라서 자동으로 삭제될 수 있다.
|
||||
- 만약 명명된 노드에 파드를 수용할 수 있는
|
||||
리소스가 없는 경우 파드가 실패하고, 그 이유는 다음과 같이 표시된다.
|
||||
예: OutOfmemory 또는 OutOfcpu.
|
||||
- 클라우드 환경의 노드 이름은 항상 예측 가능하거나
|
||||
안정적인 것은 아니다.
|
||||
|
||||
여기에 `nodeName` 필드를 사용하는 파드 설정 파일 예시가 있다.
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx
|
||||
nodeName: kube-01
|
||||
```
|
||||
|
||||
위 파드는 kube-01 노드에서 실행될 것이다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
|
||||
[테인트](/docs/concepts/configuration/taint-and-toleration/)는 노드가 특정 파드들을 *쫓아내게* 할 수 있다.
|
||||
|
||||
[노드 어피니티](https://git.k8s.io/community/contributors/design-proposals/scheduling/nodeaffinity.md)와
|
||||
[파드간 어피니티/안티-어피니티](https://git.k8s.io/community/contributors/design-proposals/scheduling/podaffinity.md)에 대한 디자인 문서에는
|
||||
이러한 기능에 대한 추가 배경 정보가 있다.
|
||||
|
||||
파드가 노드에 할당되면 kubelet은 파드를 실행하고 노드의 로컬 리소스를 할당한다.
|
||||
[토폴로지 매니저](/docs/tasks/administer-cluster/topology-manager/)는
|
||||
노드 수준의 리소스 할당 결정에 참여할 수 있다.
|
||||
|
||||
{{% /capture %}}
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
title: 쿠버네티스 스케줄러
|
||||
content_template: templates/concept
|
||||
weight: 50
|
||||
weight: 10
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
+1
-1
@@ -91,7 +91,7 @@ hostaliases-pod 0/1 Completed 0 6s 10.200
|
||||
`hosts` 파일 내용은 아래와 같을 것이다.
|
||||
|
||||
```shell
|
||||
kubectl logs hostaliases-pod
|
||||
kubectl exec hostaliases-pod -- cat /etc/hosts
|
||||
```
|
||||
|
||||
```none
|
||||
|
||||
@@ -171,7 +171,7 @@ DNS 정책은 파드별로 설정할 수 있다. 현재 쿠버네티스는 다
|
||||
- "`None`": 이 정책은 파드가 쿠버네티스 환경의 DNS 설정을 무시하도록 한다.
|
||||
모든 DNS 설정은 파드 스펙 내에 `dnsConfig`필드를 사용하여 제공해야 한다.
|
||||
아래 절인
|
||||
[파드의 DNS 설정](#파드의-dns-설정)
|
||||
[파드의 DNS 설정](#pod-dns-config)
|
||||
에서 자세한 내용을 확인할 수 있다.
|
||||
|
||||
{{< note >}}
|
||||
@@ -202,7 +202,7 @@ spec:
|
||||
dnsPolicy: ClusterFirstWithHostNet
|
||||
```
|
||||
|
||||
### 파드의 DNS 설정
|
||||
### 파드의 DNS 설정 {#pod-dns-config}
|
||||
|
||||
사용자들은 파드의 DNS 설정을 통해서 직접 파드의 DNS를 세팅할 수 있다.
|
||||
|
||||
@@ -272,4 +272,3 @@ DNS 구성 관리에 대한 지침은
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
|
||||
@@ -36,27 +36,30 @@ IPv4/IPv6 이중 스택 쿠버네티스 클러스터를 활용하려면 다음
|
||||
* 쿠버네티스 1.16 또는 이후 버전
|
||||
* 이중 스택 네트워킹을 위한 공급자의 지원(클라우드 공급자 또는 다른 방식으로 쿠버네티스 노드에 라우팅 가능한 IPv4/IPv6 네트워크 인터페이스를 제공할 수 있어야 한다.)
|
||||
* 이중 스택(예: Kubenet 또는 Calico)을 지원하는 네트워크 플러그인
|
||||
* IPVS 모드에서 구동 중인 Kube-Proxy
|
||||
|
||||
## IPv4/IPv6 이중 스택 활성화
|
||||
|
||||
IPv4/IPv6 이중 스택을 활성화 하려면, 클러스터의 관련 구성요소에 대해 `IPv6DualStack` [기능 게이트](/docs/reference/command-line-tools-reference/feature-gates/) 를 활성화 하고, 이중 스택 클러스터 네트워크 할당을 설정한다.
|
||||
|
||||
* kube-apiserver:
|
||||
* `--feature-gates="IPv6DualStack=true"`
|
||||
* kube-controller-manager:
|
||||
* `--feature-gates="IPv6DualStack=true"`
|
||||
* `--cluster-cidr=<IPv4 CIDR>,<IPv6 CIDR>` 예: `--cluster-cidr=10.244.0.0/16,fc00::/24`
|
||||
* `--cluster-cidr=<IPv4 CIDR>,<IPv6 CIDR>`
|
||||
* `--service-cluster-ip-range=<IPv4 CIDR>,<IPv6 CIDR>`
|
||||
* `--node-cidr-mask-size-ipv4|--node-cidr-mask-size-ipv6` IPv4의 기본값은 /24 이고 IPv6의 기본값은 /64이다.
|
||||
* kubelet:
|
||||
* `--feature-gates="IPv6DualStack=true"`
|
||||
* kube-proxy:
|
||||
* `--proxy-mode=ipvs`
|
||||
* `--cluster-cidr=<IPv4 CIDR>,<IPv6 CIDR>`
|
||||
* `--feature-gates="IPv6DualStack=true"`
|
||||
|
||||
{{< caution >}}
|
||||
명령줄에서 `--cluster-cidr` 를 통해 /24보다 큰 IPv6 주소 블럭을 지정하면 할당이 실패한다.
|
||||
{{< /caution >}}
|
||||
{{< note >}}
|
||||
IPv4 CIDR의 예: `10.244.0.0/16` (자신의 주소 범위를 제공하더라도)
|
||||
|
||||
IPv6 CIDR의 예: `fdXY:IJKL:MNOP:15::/64` (이 형식으로 표시되지만, 유효한 주소는 아니다 - [RFC 4193](https://tools.ietf.org/html/rfc4193)을 본다.)
|
||||
|
||||
{{< /note >}}
|
||||
|
||||
## 서비스
|
||||
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
---
|
||||
title: 엔드포인트슬라이스
|
||||
feature:
|
||||
title: 엔드포인트슬라이스
|
||||
description: >
|
||||
쿠버네티스 클러스터에서 확장 가능한 네트워크 엔드포인트 추적.
|
||||
|
||||
content_template: templates/concept
|
||||
weight: 15
|
||||
---
|
||||
|
||||
@@ -132,11 +132,11 @@ spec:
|
||||
요소별로 경로 요소에 대해 수행한다.
|
||||
모든 _p_ 가 요청 경로의 요소별 접두사가 _p_ 인 경우
|
||||
요청은 _p_ 경로에 일치한다.
|
||||
{{< note >}}
|
||||
경로의 마지막 요소가 요청 경로에 있는 마지막 요소의
|
||||
하위 문자열인 경우에는 일치하지 않는다(예시:
|
||||
`/foo/bar` 와 `/foo/bar/baz` 와 일치하지만, `/foo/barbaz` 는 일치하지 않는다).
|
||||
{{< /note >}}
|
||||
|
||||
{{< note >}}
|
||||
경로의 마지막 요소가 요청 경로에 있는 마지막 요소의 하위 문자열인 경우에는 일치하지 않는다(예시:
|
||||
`/foo/bar` 와 `/foo/bar/baz` 와 일치하지만, `/foo/barbaz` 는 일치하지 않는다).
|
||||
{{< /note >}}
|
||||
|
||||
#### 다중 일치
|
||||
경우에 따라 인그레스의 여러 경로가 요청과 일치할 수 있다.
|
||||
@@ -400,16 +400,16 @@ metadata:
|
||||
spec:
|
||||
tls:
|
||||
- hosts:
|
||||
- sslexample.foo.com
|
||||
- sslexample.foo.com
|
||||
secretName: testsecret-tls
|
||||
rules:
|
||||
- host: sslexample.foo.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: service1
|
||||
servicePort: 80
|
||||
- host: sslexample.foo.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: service1
|
||||
servicePort: 80
|
||||
```
|
||||
|
||||
{{< note >}}
|
||||
|
||||
@@ -310,7 +310,7 @@ IPVS는 트래픽을 백엔드 파드로 밸런싱하기 위한 추가 옵션을
|
||||
- `nq`: 큐 미사용 (never queue)
|
||||
|
||||
{{< note >}}
|
||||
IPVS 모드에서 kube-proxy를 실행하려면, kube-proxy를 시작하기 전에 노드에서 IPVS Linux를
|
||||
IPVS 모드에서 kube-proxy를 실행하려면, kube-proxy를 시작하기 전에 노드에서 IPVS를
|
||||
사용 가능하도록 해야한다.
|
||||
|
||||
kube-proxy가 IPVS 프록시 모드에서 시작될 때, IPVS 커널 모듈을
|
||||
@@ -691,6 +691,15 @@ metadata:
|
||||
[...]
|
||||
```
|
||||
{{% /tab %}}
|
||||
{{% tab name="Alibaba Cloud" %}}
|
||||
```yaml
|
||||
[...]
|
||||
metadata:
|
||||
annotations:
|
||||
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-address-type: "intranet"
|
||||
[...]
|
||||
```
|
||||
{{% /tab %}}
|
||||
{{< /tabs >}}
|
||||
|
||||
|
||||
@@ -895,7 +904,7 @@ NLB는 특정 인스턴스 클래스에서만 작동한다. 지원되는 인스
|
||||
헬스 체크에 실패하고 트래픽을 수신하지 못하게 된다.
|
||||
|
||||
트래픽을 균일하게 하려면, DaemonSet을 사용하거나,
|
||||
[파드 안티어피니티(pod anti-affinity)](/ko/docs/concepts/configuration/assign-pod-node/#어피니티-affinity-와-안티-어피니티-anti-affinity)
|
||||
[파드 안티어피니티(pod anti-affinity)](/ko/docs/concepts/scheduling-eviction/assign-pod-node/#어피니티-affinity-와-안티-어피니티-anti-affinity)
|
||||
를 지정하여 동일한 노드에 위치하지 않도록 한다.
|
||||
|
||||
[내부 로드 밸런서](/ko/docs/concepts/services-networking/service/#internal-load-balancer) 어노테이션과 함께 NLB 서비스를
|
||||
|
||||
@@ -329,7 +329,7 @@ spec:
|
||||
가장 빠른 방법을 파드에 제공하는 데 유용하다. 반면에 파드에서 실행되는 애플리케이션은
|
||||
원시 블록 장치를 처리하는 방법을 알아야 한다.
|
||||
파드에서 `volumeMode: Block`으로 볼륨을 사용하는 방법에 대한 예는
|
||||
[원시 블록 볼륨 지원](/ko/docs/concepts/storage/persistent-volumes/#원시-블록-볼륨-지원)를 참조하십시오.
|
||||
[원시 블록 볼륨 지원](#원시-블록-볼륨-지원)를 참조하십시오.
|
||||
|
||||
### 접근 모드
|
||||
|
||||
|
||||
@@ -164,9 +164,9 @@ CSI | 1.14 (alpha), 1.16 (beta)
|
||||
퍼시스턴트볼륨은 파드의 스케줄링 제약 조건에 의해 지정된 토폴로지에
|
||||
따라 선택되거나 프로비전된다. 여기에는 [리소스
|
||||
요구 사항](/docs/concepts/configuration/manage-compute-resources-container/),
|
||||
[노드 셀렉터](/ko/docs/concepts/configuration/assign-pod-node/#노드-셀렉터-nodeselector),
|
||||
[노드 셀렉터](/ko/docs/concepts/scheduling-eviction/assign-pod-node/#노드-셀렉터-nodeselector),
|
||||
[파드 어피니티(affinity)와
|
||||
안티-어피니티(anti-affinity)](/ko/docs/concepts/configuration/assign-pod-node/#어피니티-affinity-와-안티-어피니티-anti-affinity)
|
||||
안티-어피니티(anti-affinity)](/ko/docs/concepts/scheduling-eviction/assign-pod-node/#어피니티-affinity-와-안티-어피니티-anti-affinity)
|
||||
그리고 [테인트(taint)와 톨러레이션(toleration)](/docs/concepts/configuration/taint-and-toleration/)이 포함된다.
|
||||
|
||||
다음 플러그인은 동적 프로비저닝과 `WaitForFirstConsumer` 를 지원한다.
|
||||
|
||||
@@ -243,14 +243,14 @@ spec:
|
||||
|
||||
#### CSI 마이그레이션
|
||||
|
||||
{{< feature-state for_k8s_version="v1.14" state="alpha" >}}
|
||||
{{< feature-state for_k8s_version="v1.18" state="beta" >}}
|
||||
|
||||
Cinder의 CSI 마이그레이션 기능이 활성화된 경우, 기존 트리 내 플러그인에서
|
||||
`cinder.csi.openstack.org` 컨테이너 스토리지 인터페이스(CSI)
|
||||
드라이버로 모든 플러그인 작업을 수행한다. 이 기능을 사용하려면, 클러스터에 [오픈스택 Cinder CSI
|
||||
드라이버](https://github.com/kubernetes/cloud-provider-openstack/blob/master/docs/using-cinder-csi-plugin.md)
|
||||
를 설치하고 `CSIMigration` 과 `CSIMigrationOpenStack`
|
||||
알파 기능을 활성화해야 한다.
|
||||
베타 기능을 활성화해야 한다.
|
||||
|
||||
### configMap {#configmap}
|
||||
|
||||
@@ -300,6 +300,11 @@ ConfigMap을 [subPath](#subpath-사용하기) 볼륨 마운트로 사용하는
|
||||
업데이트를 수신하지 않는다.
|
||||
{{< /note >}}
|
||||
|
||||
{{< note >}}
|
||||
텍스트 데이터는 UTF-8 문자 인코딩을 사용하는 파일로 노출된다. 다른 문자 인코딩을 사용하려면, binaryData를 사용한다.
|
||||
{{< /note >}}
|
||||
|
||||
|
||||
### downwardAPI {#downwardapi}
|
||||
|
||||
`downwardAPI` 볼륨은 애플리케이션에서 다운워드(downward) API 데이터를 사용할 수 있도록 하는데 사용된다.
|
||||
|
||||
@@ -91,9 +91,9 @@ kubectl apply -f https://k8s.io/examples/controllers/daemonset.yaml
|
||||
### 오직 일부 노드에서만 파드 실행
|
||||
|
||||
만약 `.spec.template.spec.nodeSelector` 를 명시하면 데몬셋 컨트롤러는
|
||||
[노드 셀렉터](/ko/docs/concepts/configuration/assign-pod-node/#노드-셀렉터-nodeselector)와
|
||||
[노드 셀렉터](/ko/docs/concepts/scheduling-eviction/assign-pod-node/#노드-셀렉터-nodeselector)와
|
||||
일치하는 노드에 파드를 생성한다. 마찬가지로 `.spec.template.spec.affinity` 를 명시하면
|
||||
데몬셋 컨트롤러는 [노트 어피니티](/ko/docs/concepts/configuration/assign-pod-node/#노드-어피니티)와 일치하는 노드에 파드를 생성한다.
|
||||
데몬셋 컨트롤러는 [노트 어피니티](/ko/docs/concepts/scheduling-eviction/assign-pod-node/#노드-어피니티)와 일치하는 노드에 파드를 생성한다.
|
||||
만약 둘 중 하나를 명시하지 않으면 데몬셋 컨트롤러는 모든 노드에서 파드를 생성한다.
|
||||
|
||||
## 데몬 파드가 스케줄 되는 방법
|
||||
|
||||
@@ -51,12 +51,13 @@ _디플로이먼트_ 는 [파드](/ko/docs/concepts/workloads/pods/pod/)와
|
||||
이 사례에서는 간단하게 파드 템플릿에 정의된 레이블(`app: nginx`)을 선택한다.
|
||||
그러나 파드 템플릿 자체의 규칙이 만족되는 한,
|
||||
보다 정교한 선택 규칙의 적용이 가능하다.
|
||||
{{< note >}}
|
||||
`.spec.selector.matchLabels` 필드는 {key,value}의 쌍으로 매핑되어있다. `matchLabels` 에 매핑된
|
||||
단일 {key,value}은 `matchExpressions` 의 요소에 해당하며, 키 필드는 "key"에 그리고 연산자는 "In"에 대응되며
|
||||
값 배열은 "value"만 포함한다.
|
||||
매칭을 위해서는 `matchLabels` 와 `matchExpressions` 의 모든 요건이 충족되어야 한다.
|
||||
{{< /note >}}
|
||||
|
||||
{{< note >}}
|
||||
`.spec.selector.matchLabels` 필드는 {key,value}의 쌍으로 매핑되어있다. `matchLabels` 에 매핑된
|
||||
단일 {key,value}은 `matchExpressions` 의 요소에 해당하며, 키 필드는 "key"에 그리고 연산자는 "In"에 대응되며
|
||||
값 배열은 "value"만 포함한다.
|
||||
매칭을 위해서는 `matchLabels` 와 `matchExpressions` 의 모든 요건이 충족되어야 한다.
|
||||
{{< /note >}}
|
||||
|
||||
* `template` 필드에는 다음 하위 필드가 포함되어있다.
|
||||
* 파드는 `.metadata.labels` 필드를 사용해서 `app: nginx` 라는 레이블을 붙인다.
|
||||
@@ -65,86 +66,95 @@ _디플로이먼트_ 는 [파드](/ko/docs/concepts/workloads/pods/pod/)와
|
||||
`nginx` 컨테이너 1개를 실행하는 것을 나타낸다.
|
||||
* 컨테이너 1개를 생성하고, `.spec.template.spec.containers[0].name` 필드를 사용해서 `nginx` 이름을 붙인다.
|
||||
|
||||
위의 디플로이먼트를 생성하려면 다음 단계를 따른다.
|
||||
시작하기 전에, 쿠버네티스 클러스터가 시작되고 실행 중인지 확인한다.
|
||||
위의 디플로이먼트를 생성하려면 다음 단계를 따른다.
|
||||
|
||||
시작하기 전에, 쿠버네티스 클러스터가 시작되고 실행 중인지 확인한다.
|
||||
|
||||
1. 다음 명령어를 실행해서 디플로이먼트를 생성한다.
|
||||
1. 다음 명령어를 실행해서 디플로이먼트를 생성한다.
|
||||
|
||||
{{< note >}}
|
||||
`--record` 플래그를 지정해서 실행된 명령을 `kubernetes.io/change-cause` 리소스 어노테이션에 작성할 수 있다. 이것은 향후 인트로스펙션(introspection)에 유용하다.
|
||||
예를 들면, 디플로이먼트의 각 수정 버전에서 실행된 명령을 볼 수 있다.
|
||||
{{< /note >}}
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml
|
||||
```
|
||||
|
||||
2. `kubectl get deployments` 을 실행해서 디플로이먼트가 생성되었는지 확인한다. 만약 디플로이먼트가 여전히 생성중이면 다음과 유사하게 출력된다.
|
||||
```shell
|
||||
NAME READY UP-TO-DATE AVAILABLE AGE
|
||||
nginx-deployment 0/3 0 0 1s
|
||||
```
|
||||
클러스터에서 디플로이먼트를 점검할 때 다음 필드가 표시된다.
|
||||
|
||||
* `NAME` 은 네임스페이스에 있는 디플로이먼트 이름의 목록이다.
|
||||
* `READY` 는 사용자가 사용할 수 있는 애플리케이션의 레플리카의 수를 표시한다. ready/desired 패턴을 따른다.
|
||||
* `UP-TO-DATE` 는 의도한 상태를 얻기위해 업데이트 된 레플리카의 수를 표시한다.
|
||||
* `AVAILABLE` 은 사용자가 사용 가능한 애플리케이션 레플리카의 수를 표시한다.
|
||||
* `AGE` 는 애플리케이션의 실행 된 시간을 표시한다.
|
||||
|
||||
`.spec.replicas` 필드에 따라 의도한 레플리카의 수가 3개인지 알 수 있다.
|
||||
|
||||
3. 디플로이먼트의 롤아웃 상태를 보려면 `kubectl rollout status deployment.v1.apps/nginx-deployment` 를 실행한다. 다음과 유사하게 출력된다.
|
||||
```shell
|
||||
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
|
||||
deployment.apps/nginx-deployment successfully rolled out
|
||||
```
|
||||
|
||||
4. 몇 초 후 `kubectl get deployments` 를 다시 실행한다. 다음과 유사하게 출력된다.
|
||||
```shell
|
||||
NAME READY UP-TO-DATE AVAILABLE AGE
|
||||
nginx-deployment 3/3 3 3 18s
|
||||
```
|
||||
디플로이먼트에서 3개의 레플리카가 생성되었고, 모든 레플리카는 최신 상태(최신 파드 템플릿을 포함)이며 사용 가능한 것을 알 수 있다.
|
||||
|
||||
5. 디플로이먼트로 생성된 레플리카셋(`rs`)을 보려면 `kubectl get rs` 를 실행한다. 다음과 유사하게 출력된다.
|
||||
```shell
|
||||
NAME DESIRED CURRENT READY AGE
|
||||
nginx-deployment-75675f5897 3 3 3 18s
|
||||
```
|
||||
레플리카셋의 출력에는 다음 필드가 표시된다.
|
||||
|
||||
* `NAME` 은 네임스페이스에 있는 레플리카셋 이름의 목록이다.
|
||||
* `DESIRED` 는 디플로이먼트의 생성 시 정의된 의도한 애플리케이션 _레플리카_ 의 수를 표시한다. 이것이 _의도한 상태_ 이다.
|
||||
* `CURRENT` 는 현재 실행 중인 레플리카의 수를 표시한다.
|
||||
* `READY` 는 사용자가 사용할 수 있는 애플리케이션의 레플리카의 수를 표시한다.
|
||||
* `AGE` 는 애플리케이션의 실행된 시간을 표시한다.
|
||||
|
||||
레플리카셋의 이름은 항상 `[DEPLOYMENT-NAME]-[RANDOM-STRING]` 형식으로 된 것을 알 수 있다. 무작위 문자열은
|
||||
무작위로 생성되며, `pod-template-hash` 를 시드(seed)로 사용한다.
|
||||
|
||||
6. 각 파드에 자동으로 생성된 레이블을 보려면 `kubectl get pods --show-labels` 를 실행한다. 다음과 유사하게 출력된다.
|
||||
```shell
|
||||
NAME READY STATUS RESTARTS AGE LABELS
|
||||
nginx-deployment-75675f5897-7ci7o 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453
|
||||
nginx-deployment-75675f5897-kzszj 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453
|
||||
nginx-deployment-75675f5897-qqcnn 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453
|
||||
```
|
||||
만들어진 레플리카셋은 3개의 `nginx` 파드가 있는 것을 보장한다.
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml
|
||||
```
|
||||
|
||||
{{< note >}}
|
||||
디플로이먼트에는 파드 템플릿 레이블과 적절한 셀렉터를 반드시 명시해야 한다(이 예시에서는 `app: nginx`).
|
||||
레이블 또는 셀렉터는 다른 컨트롤러(다른 디플로이먼트와 스테이트풀 셋 포함)와 겹치지 않아야 한다. 쿠버네티스는 겹치는 것을 막지 않으며, 만약 다중 컨트롤러가 겹치는 셀렉터를 가지는 경우 해당 컨트롤러의 충돌 또는 예기치 않은 동작을 야기할 수 있다.
|
||||
`--record` 플래그를 지정해서 실행된 명령을 `kubernetes.io/change-cause` 리소스 어노테이션에 작성할 수 있다.
|
||||
기록된 변경사항은 향후 인트로스펙션(introspection)에 유용하다. 예를 들면, 디플로이먼트의 각 수정 버전에서 실행된 명령을 볼 수 있다.
|
||||
{{< /note >}}
|
||||
|
||||
|
||||
2. `kubectl get deployments` 을 실행해서 디플로이먼트가 생성되었는지 확인한다.
|
||||
|
||||
만약 디플로이먼트가 여전히 생성 중이면, 다음과 유사하게 출력된다.
|
||||
```shell
|
||||
NAME READY UP-TO-DATE AVAILABLE AGE
|
||||
nginx-deployment 0/3 0 0 1s
|
||||
```
|
||||
클러스터에서 디플로이먼트를 점검할 때, 다음 필드가 표시된다.
|
||||
* `NAME` 은 네임스페이스에 있는 디플로이먼트 이름의 목록이다.
|
||||
* `READY` 는 사용자가 사용할 수 있는 애플리케이션의 레플리카의 수를 표시한다. ready/desired 패턴을 따른다.
|
||||
* `UP-TO-DATE` 는 의도한 상태를 얻기 위해 업데이트된 레플리카의 수를 표시한다.
|
||||
* `AVAILABLE` 은 사용자가 사용할 수 있는 애플리케이션 레플리카의 수를 표시한다.
|
||||
* `AGE` 는 애플리케이션의 실행된 시간을 표시한다.
|
||||
|
||||
`.spec.replicas` 필드에 따라 의도한 레플리카의 수가 3개인지 알 수 있다.
|
||||
|
||||
3. 디플로이먼트의 롤아웃 상태를 보려면, `kubectl rollout status deployment.v1.apps/nginx-deployment` 를 실행한다.
|
||||
|
||||
다음과 유사하게 출력된다.
|
||||
```shell
|
||||
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
|
||||
deployment.apps/nginx-deployment successfully rolled out
|
||||
```
|
||||
|
||||
4. 몇 초 후 `kubectl get deployments` 를 다시 실행한다.
|
||||
다음과 유사하게 출력된다.
|
||||
```shell
|
||||
NAME READY UP-TO-DATE AVAILABLE AGE
|
||||
nginx-deployment 3/3 3 3 18s
|
||||
```
|
||||
디플로이먼트에서 3개의 레플리카가 생성되었고, 모든 레플리카는 최신 상태(최신 파드 템플릿을 포함)이며 사용 가능한 것을 알 수 있다.
|
||||
|
||||
5. 디플로이먼트로 생성된 레플리카셋(`rs`)을 보려면, `kubectl get rs` 를 실행한다. 다음과 유사하게 출력된다.
|
||||
```shell
|
||||
NAME DESIRED CURRENT READY AGE
|
||||
nginx-deployment-75675f5897 3 3 3 18s
|
||||
```
|
||||
레플리카셋의 출력에는 다음 필드가 표시된다.
|
||||
|
||||
* `NAME` 은 네임스페이스에 있는 레플리카셋 이름의 목록이다.
|
||||
* `DESIRED` 는 디플로이먼트의 생성 시 정의된 의도한 애플리케이션 _레플리카_ 의 수를 표시한다. 이것이 _의도한 상태_ 이다.
|
||||
* `CURRENT` 는 현재 실행 중인 레플리카의 수를 표시한다.
|
||||
* `READY` 는 사용자가 사용할 수 있는 애플리케이션의 레플리카의 수를 표시한다.
|
||||
* `AGE` 는 애플리케이션의 실행된 시간을 표시한다.
|
||||
|
||||
레플리카셋의 이름은 항상 `[DEPLOYMENT-NAME]-[RANDOM-STRING]` 형식으로 된 것을 알 수 있다. 무작위 문자열은
|
||||
무작위로 생성되며, `pod-template-hash` 를 시드(seed)로 사용한다.
|
||||
|
||||
6. 각 파드에 자동으로 생성된 레이블을 보려면, `kubectl get pods --show-labels` 를 실행한다.
|
||||
다음과 유사하게 출력된다.
|
||||
```shell
|
||||
NAME READY STATUS RESTARTS AGE LABELS
|
||||
nginx-deployment-75675f5897-7ci7o 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453
|
||||
nginx-deployment-75675f5897-kzszj 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453
|
||||
nginx-deployment-75675f5897-qqcnn 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453
|
||||
```
|
||||
만들어진 레플리카셋은 실행 중인 3개의 `nginx` 파드를 보장한다.
|
||||
|
||||
{{< note >}}
|
||||
디플로이먼트에는 파드 템플릿 레이블과 적절한 셀렉터를 반드시 명시해야 한다
|
||||
(이 예시에서는 `app: nginx`).
|
||||
|
||||
레이블 또는 셀렉터는 다른 컨트롤러(다른 디플로이먼트와 스테이트풀 셋 포함)와 겹치지 않아야 한다. 쿠버네티스는 겹치는 것을 막지 않으며, 만약 다중 컨트롤러가 겹치는 셀렉터를 가지는 경우 해당 컨트롤러의 충돌 또는 예기치 않은 동작을 야기할 수 있다.
|
||||
{{< /note >}}
|
||||
|
||||
### Pod-template-hash 레이블
|
||||
|
||||
{{< note >}}
|
||||
{{< caution >}}
|
||||
이 레이블은 변경하면 안 된다.
|
||||
{{< /note >}}
|
||||
{{< /caution >}}
|
||||
|
||||
`pod-template-hash` 레이블은 디플로이먼트 컨트롤러에 의해서 디플로이먼트가 생성 또는 채택한 모든 레플리케셋에 추가된다.
|
||||
`pod-template-hash` 레이블은 디플로이먼트 컨트롤러에 의해서 디플로이먼트가 생성 또는 채택한 모든 레플리카셋에 추가된다.
|
||||
|
||||
이 레이블은 디플로이먼트의 자식 레플리카셋이 겹치지 않도록 보장한다. 레플리카셋의 `PodTemplate` 을 해싱하고, 해시 결과를 레플리카셋 셀렉터,
|
||||
파드 템플릿 레이블 및 레플리카셋 이 가질 수 있는 기존의 모든 파드에 레이블 값으로 추가해서 사용하도록 생성한다.
|
||||
@@ -407,9 +417,7 @@ API 버전 `apps/v1` 에서 디플로이먼트의 레이블 셀렉터는 생성
|
||||
```
|
||||
|
||||
{{< note >}}
|
||||
디플로이먼트 컨트롤러가 잘못된 롤아웃을 자동으로 중지하고, 새로운 레플리카셋의 스케일 업을 중지한다.
|
||||
이는 지정한 롤링 업데이트의 파라미터(구체적으로 `maxUnavailable`)에 따라 달라진다.
|
||||
쿠버네티스는 기본값으로 25%를 설정한다.
|
||||
디플로이먼트 컨트롤러가 잘못된 롤아웃을 자동으로 중지하고, 새로운 레플리카셋의 스케일 업을 중지한다. 이는 지정한 롤링 업데이트의 파라미터(구체적으로 `maxUnavailable`)에 따라 달라진다. 쿠버네티스는 기본값으로 25%를 설정한다.
|
||||
{{< /note >}}
|
||||
|
||||
* 디플로이먼트에 대한 설명 보기
|
||||
@@ -1080,6 +1088,15 @@ API 버전 `apps/v1` 에서는 `.spec.selector` 와 `.metadata.labels` 이 설
|
||||
|
||||
기존의 모든 파드는 `.spec.strategy.type==Recreate` 이면 새 파드가 생성되기 전에 죽는다.
|
||||
|
||||
{{< note >}}
|
||||
이렇게 하면 업그레이드를 생성하기 전에 파드 종료를 보장할 수 있다. 디플로이먼트를 업그레이드하면,
|
||||
이전 버전의 모든 파드가 즉시 종료된다. 신규 버전의 파드가 생성되기 전에 성공적으로 제거가
|
||||
완료되기를 대기한다. 파드를 수동으로 삭제하면, 라이프사이클은 레플리카셋에 의해
|
||||
제어되며(이전 파드가 여전히 종료 상태에 있는 경우에도) 교체용 파드가 즉시 생성된다. 파드에
|
||||
대해 "최대" 보장이 필요한 경우
|
||||
[스테이트풀셋](/ko/docs/concepts/workloads/controllers/statefulset/)의 사용을 고려해야 한다.
|
||||
{{< /note >}}
|
||||
|
||||
#### 디플로이먼트 롤링 업데이트
|
||||
|
||||
디플로이먼트는 `.spec.strategy.type==RollingUpdate` 이면 파드를 롤링 업데이트
|
||||
@@ -1114,7 +1131,7 @@ API 버전 `apps/v1` 에서는 `.spec.selector` 와 `.metadata.labels` 이 설
|
||||
`.spec.progressDeadlineSeconds` 는 디플로어먼트가 표면적으로 `Type=Progressing`, `Status=False`의
|
||||
상태 그리고 리소스가 `Reason=ProgressDeadlineExceeded` 상태로 [진행 실패](#디플로이먼트-실패)를 보고하기 전에
|
||||
디플로이먼트가 진행되는 것을 대기시키는 시간(초)를 명시하는 선택적 필드이다.
|
||||
디플로이먼트 컨트롤러는 디플로이먼트를 계속 재시도 한다.
|
||||
디플로이먼트 컨트롤러는 디플로이먼트를 계속 재시도 한다. 기본값은 600(초)이다.
|
||||
미래에 자동화된 롤백이 구현된다면 디플로이먼트 컨트롤러는 상태를 관찰하고,
|
||||
그 즉시 디플로이먼트를 롤백할 것이다.
|
||||
|
||||
|
||||
@@ -326,7 +326,7 @@ kubectl apply -f https://k8s.io/examples/controllers/hpa-rs.yaml
|
||||
(그리고 더 쉽다!)
|
||||
|
||||
```shell
|
||||
kubectl autoscale rs frontend --max=10
|
||||
kubectl autoscale rs frontend --max=10 --min=3 --cpu-percent=50
|
||||
```
|
||||
|
||||
## 레플리카셋의 대안
|
||||
|
||||
@@ -83,6 +83,8 @@ weight: 60
|
||||
|
||||
## Disruption Budgets의 작동 방식
|
||||
|
||||
{{< feature-state for_k8s_version="v1.5" state="beta" >}}
|
||||
|
||||
애플리케이션 소유자는 각 애플리케이션에 대해 `PodDisruptionBudget` 오브젝트(PDB)를 만들 수 있다.
|
||||
PDB는 자발적 중단으로 일시에 중지되는 복제된 애플리케이션 파드의 수를 제한한다.
|
||||
예를 들어 정족수 기반의 애플리케이션이
|
||||
@@ -192,7 +194,7 @@ drain 커멘드는 `pod-b`를 축출하는데 성공했다.
|
||||
|
||||
| node-1 *drained* | node-2 | node-3 | *no node* |
|
||||
|:--------------------:|:-------------------:|:------------------:|:------------------:|
|
||||
| | pod-b *available* | pod-c *available* | pod-e *pending* |
|
||||
| | pod-b *terminating* | pod-c *available* | pod-e *pending* |
|
||||
| | pod-d *available* | pod-y | |
|
||||
|
||||
이 시점에서 클러스터 관리자는
|
||||
|
||||
@@ -44,8 +44,8 @@ weight: 40
|
||||
그러나, 초기화 컨테이너를 위한 리소스 요청량과 상한은
|
||||
[리소스](#리소스)에 문서화된 것처럼 다르게 처리된다.
|
||||
|
||||
또한, 초기화 컨테이너는 준비성 프로브(readiness probe)를 지원하지 않는다. 왜냐하면 초기화 컨테이너는
|
||||
파드가 준비 상태가 되기 전에 완료를 목표로 실행되어야 하기 때문이다.
|
||||
또한, 초기화 컨테이너는 `lifecycle`, `livenessProbe`, `readinessProbe` 또는 `startupProbe` 를 지원하지 않는다.
|
||||
왜냐하면 초기화 컨테이너는 파드가 준비 상태가 되기 전에 완료를 목표로 실행되어야 하기 때문이다.
|
||||
|
||||
만약 다수의 초기화 컨테이너가 파드에 지정되어 있다면, Kubelet은 해당 초기화 컨테이너들을
|
||||
한 번에 하나씩 실행한다. 각 초기화 컨테이너는 다음 컨테이너를 실행하기 전에 꼭 성공해야 한다.
|
||||
@@ -239,7 +239,7 @@ myapp-pod 1/1 Running 0 9m
|
||||
```
|
||||
|
||||
이 간단한 예제는 사용자만의 초기화 컨테이너를 생성하는데
|
||||
영감을 줄 것이다. [다음 순서](#what-s-next)에는 더 자세한 예제의 링크가 있다.
|
||||
영감을 줄 것이다. [다음 순서](#다음-내용)에는 더 자세한 예제의 링크가 있다.
|
||||
|
||||
## 자세한 동작
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ node4 Ready <none> 2m43s v1.16.0 node=node4,zone=zoneB
|
||||
|
||||
`pod.spec.topologySpreadConstraints` 필드는 1.16에서 다음과 같이 도입되었다.
|
||||
|
||||
```yaml
|
||||
```
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
@@ -97,7 +97,7 @@ spec:
|
||||
|
||||
{{< codenew file="pods/topology-spread-constraints/one-constraint.yaml" >}}
|
||||
|
||||
`topologyKey: zone` 는 "zone:<any value>" 레이블 쌍을 가지는 노드에 대해서만 균등한 분배를 적용하는 것을 의미한다. `whenUnsatisfiable: DoNotSchedule` 은 만약 들어오는 파드가 제약 조건을 만족시키지 못하면 스케줄러에게 pending 상태를 유지하도록 지시한다.
|
||||
`topologyKey: zone` 는 "zone:<any value>" 레이블 쌍을 가지는 노드에 대해서만 균등한 분배를 적용하는 것을 의미한다. `whenUnsatisfiable: DoNotSchedule` 은 만약 들어오는 파드가 제약 조건을 만족시키지 못하면 스케줄러에게 pending 상태를 유지하도록 지시한다.
|
||||
|
||||
만약 스케줄러가 이 신규 파드를 "zoneA"에 배치하면 파드 분포는 [3, 1]이 되며, 따라서 실제 차이(skew)는 2 (3 - 1)가 되어 `maxSkew: 1` 를 위반하게 된다. 이 예시에서는 들어오는 파드는 오직 "zoneB"에만 배치할 수 있다.
|
||||
|
||||
|
||||
@@ -5,7 +5,9 @@ weight: 50
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
이 페이지는 파드 프리셋에 대한 개요를 제공한다. 파드 프리셋은 파드 생성 시간에 파드에
|
||||
{{< feature-state for_k8s_version="v1.6" state="alpha" >}}
|
||||
|
||||
이 페이지는 파드프리셋(PodPreset)에 대한 개요를 제공한다. 파드프리셋은 파드 생성 시간에 파드에
|
||||
특정 정보를 주입하기 위한 오브젝트이다. 해당 정보에는
|
||||
시크릿, 볼륨, 볼륨 마운트, 환경 변수가 포함될 수 있다.
|
||||
{{% /capture %}}
|
||||
@@ -14,16 +16,33 @@ weight: 50
|
||||
{{% capture body %}}
|
||||
## 파드 프리셋 이해하기
|
||||
|
||||
`Pod Preset`은 파드 생성 시간에 파드에 추가적인 런타임 요구사항을
|
||||
파드프리셋은 파드 생성 시간에 파드에 추가적인 런타임 요구사항을
|
||||
주입하기 위한 API 리소스이다.
|
||||
주어진 파드 프리셋이 적용되도록 파드에 명시하기 위해서는
|
||||
주어진 파드프리셋이 적용되도록 파드에 명시하기 위해서는
|
||||
[레이블 셀렉터](/ko/docs/concepts/overview/working-with-objects/labels/#레이블-셀렉터)를 사용한다.
|
||||
|
||||
파드 프리셋을 사용하는 것은 파드 템플릿 작성자에게 모든 파드를 위한 모든 정보를 명시적으로
|
||||
파드프리셋을 사용하는 것은 파드 템플릿 작성자에게 모든 파드를 위한 모든 정보를 명시적으로
|
||||
제공하지는 않아도 되도록 한다. 이렇게 하면, 어떤 특정 서비스를 사용할 파드의 파드
|
||||
템플릿 작성자는 해당 서비스에 대한 모든 세부 사항을 알 필요가 없다.
|
||||
|
||||
그 배경에 대한 자세한 정보를 위해서는, [파드 프리셋을 위한 디자인 제안](https://git.k8s.io/community/contributors/design-proposals/service-catalog/pod-preset.md)을 참고한다.
|
||||
## 클러스터에서 파드프리셋 활성화하기 {#enable-pod-preset}
|
||||
|
||||
클러스터에서 파드 프리셋을 사용하기 위해서는 다음 사항이 반드시 이행되어야 한다.
|
||||
|
||||
1. API 타입 `settings.k8s.io/v1alpha1/podpreset`을 활성화하였다.
|
||||
예를 들면, 이것은 API 서버의 `--runtime-config` 옵션에 `settings.k8s.io/v1alpha1=true`을 포함하여 완료할 수 있다.
|
||||
minikube에서는 클러스터가 시작할 때
|
||||
`--extra-config=apiserver.runtime-config=settings.k8s.io/v1alpha1=true`
|
||||
플래그를 추가한다.
|
||||
1. 어드미션 컨트롤러 `PodPreset`을 활성화하였다. 이것을 이루는 방법 중 하나는
|
||||
API 서버를 위해서 명시된 `--enable-admission-plugins` 옵션에 `PodPreset`을 포함하는 것이다.
|
||||
minikube에서는 클러스터가 시작할 때
|
||||
|
||||
```shell
|
||||
--extra-config=apiserver.enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota,PodPreset
|
||||
```
|
||||
|
||||
플래그를 추가한다.
|
||||
|
||||
## 어떻게 동작하는가
|
||||
|
||||
@@ -60,31 +79,12 @@ weight: 50
|
||||
있을 것이다. 이 경우에는, 다음과 같은 양식으로 어노테이션을 파드 스펙에
|
||||
추가한다. `podpreset.admission.kubernetes.io/exclude: "true"`.
|
||||
|
||||
## 파드 프리셋 활성화하기
|
||||
|
||||
클러스터에서 파드 프리셋을 사용하기 위해서는 다음 사항이 반드시 이행되어야 한다.
|
||||
|
||||
1. API 타입 `settings.k8s.io/v1alpha1/podpreset`을 활성화하였다.
|
||||
예를 들면, 이것은 API 서버의 `--runtime-config` 옵션에 `settings.k8s.io/v1alpha1=true`을 포함하여 완료할 수 있다.
|
||||
minikube에서는 클러스터가 시작할 때
|
||||
`--extra-config=apiserver.runtime-config=settings.k8s.io/v1alpha1=true`
|
||||
플래그를 추가한다.
|
||||
1. 어드미션 컨트롤러 `PodPreset`을 활성화하였다. 이것을 이루는 방법 중 하나는
|
||||
API 서버를 위해서 명시된 `--enable-admission-plugins` 옵션에 `PodPreset`을 포함하는 것이다.
|
||||
minikube에서는 클러스터가 시작할 때
|
||||
|
||||
```shell
|
||||
--extra-config=apiserver.enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota,PodPreset
|
||||
```
|
||||
|
||||
플래그를 추가한다.
|
||||
1. 사용할 네임스페이스 안에서 `PodPreset` 오브젝트를 생성하여
|
||||
파드 프리셋을 정의하였다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
|
||||
* [파드 프리셋을 사용하여 파드에 데이터 주입하기](/docs/tasks/inject-data-application/podpreset/)
|
||||
[파드프리셋을 사용하여 파드에 데이터 주입하기](/docs/tasks/inject-data-application/podpreset/)를 본다.
|
||||
|
||||
배경에 대한 자세한 정보를 위해서는, [파드프리셋을 위한 디자인 제안](https://git.k8s.io/community/contributors/design-proposals/service-catalog/pod-preset.md)을 본다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
Reference in New Issue
Block a user