From 7eafd6eaa9d44bdd93d492d9018b7719f7e25e62 Mon Sep 17 00:00:00 2001 From: "Yuk, Yongsu" Date: Tue, 14 Jan 2020 12:19:09 +0900 Subject: [PATCH 01/12] Changed some words in the IPv4/IPv6 dual-stack korean doc. (#18668) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `송신` -> `이그레스` `위장` -> `마스커레이딩` from #18666 /language ko --- .../ko/docs/concepts/services-networking/dual-stack.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/content/ko/docs/concepts/services-networking/dual-stack.md b/content/ko/docs/concepts/services-networking/dual-stack.md index cf4e03d0f7e26..2cdfb310284f1 100644 --- a/content/ko/docs/concepts/services-networking/dual-stack.md +++ b/content/ko/docs/concepts/services-networking/dual-stack.md @@ -28,7 +28,7 @@ weight: 70 * 이중 스택 파드 네트워킹(파드 당 단일 IPv4와 IPv6 주소 할당) * IPv4와 IPv6 지원 서비스(각 서비스는 단일 주소 패밀리이어야 한다.) * Kubenet 다중 주소 패밀리 지원(IPv4와 IPv6) - * IPv4와 IPv6 인터페이스를 통한 파드 오프(off) 클러스터 송신 라우팅(예: 인터넷) + * IPv4와 IPv6 인터페이스를 통한 파드 오프(off) 클러스터 이그레스 라우팅(예: 인터넷) ## 필수 구성 요소 @@ -62,7 +62,7 @@ IPv4/IPv6 이중 스택을 활성화 하려면, 클러스터의 관련 구성요 ## 서비스 만약 클러스터 IPv4/IPv6 이중 스택 네트워킹을 활성화한 경우, IPv4 또는 IPv6 주소로 {{< glossary_tooltip text="서비스" term_id="service" >}} 를 만들 수 있다. 해당 서비스에서 `.spec.ipFamily` 필드를 설정하면, 서비스 클러스터 IP의 주소 패밀리를 선택할 수 있다. -새 서비스를 생성할 때만 이 필드를 설정할 수 있다. `.spec.ipFamily` 필드는 선택 사항이며 클러스터에서 {{< glossary_tooltip text="서비스" term_id="service" >}} 와 {{< glossary_tooltip text="인그레스" term_id="ingress" >}} 를 IPv4와 IPv6로 사용하도록 설정할 경우에만 사용해야 한다. 이 필드의 구성은 [송신](#송신-트래픽)에 대한 요구사항이 아니다. +새 서비스를 생성할 때만 이 필드를 설정할 수 있다. `.spec.ipFamily` 필드는 선택 사항이며 클러스터에서 {{< glossary_tooltip text="서비스" term_id="service" >}} 와 {{< glossary_tooltip text="인그레스" term_id="ingress" >}} 를 IPv4와 IPv6로 사용하도록 설정할 경우에만 사용해야 한다. 이 필드의 구성은 [이그레스](#이그레스-트래픽)에 대한 요구사항이 아니다. {{< note >}} 클러스터의 기본 주소 패밀리는 `--service-cluster-ip-range` 플래그로 kube-controller-manager에 구성된 첫 번째 서비스 클러스터 IP 범위의 주소 패밀리이다. @@ -89,9 +89,9 @@ IPv4/IPv6 이중 스택을 활성화 하려면, 클러스터의 관련 구성요 IPv6가 활성화된 외부 로드 밸런서를 지원하는 클라우드 공급자들은 `type` 필드를 `LoadBalancer` 로 설정하고, 추가적으로 `ipFamily` 필드를 `IPv6` 로 설정하면 서비스에 대한 클라우드 로드 밸런서가 구축된다. -## 송신 트래픽 +## 이그레스 트래픽 -근본적으로 {{< glossary_tooltip text="CNI" term_id="cni" >}} 공급자가 전송을 구현할 수 있는 경우 공개적으로 라우팅 하거나 비공개 라우팅만 가능한 IPv6 주소 블록의 사용은 허용된다. 만약 비공개 라우팅만 가능한 IPv6를 사용하는 파드가 있고, 해당 파드가 오프 클러스터 목적지(예: 공용 인터넷)에 도달하기를 원하는 경우에는 송신 트래픽과 모든 응답을 위한 위장 IP를 설정해야 한다. [ip-masq-agent](https://github.com/kubernetes-incubator/ip-masq-agent) 는 이중 스택을 인식하기에, 이중 스택 클러스터에서 위장 IP에 ip-masq-agent 를 사용할 수 있다. +근본적으로 {{< glossary_tooltip text="CNI" term_id="cni" >}} 공급자가 전송을 구현할 수 있는 경우 공개적으로 라우팅 하거나 비공개 라우팅만 가능한 IPv6 주소 블록의 사용은 허용된다. 만약 비공개 라우팅만 가능한 IPv6를 사용하는 파드가 있고, 해당 파드가 오프 클러스터 목적지(예: 공용 인터넷)에 도달하기를 원하는 경우에는 이그레스 트래픽과 모든 응답을 위한 마스커레이딩 IP를 설정해야 한다. [ip-masq-agent](https://github.com/kubernetes-incubator/ip-masq-agent) 는 이중 스택을 인식하기에, 이중 스택 클러스터에서 마스커레이딩 IP에 ip-masq-agent 를 사용할 수 있다. ## 알려진 이슈들 From 8c0be8e9d86eddcb51a0120e2bf58c0c4ffb0ee4 Mon Sep 17 00:00:00 2001 From: "Yuk, Yongsu" Date: Wed, 15 Jan 2020 19:33:32 +0900 Subject: [PATCH 02/12] Update to Outdated files in dev-1.17-ko.3 branch. (#18580) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update to Outdated files in dev-1.17-ko.3 branch. ### 6 out of 9 files to be modified - [x] content/ko/docs/concepts/services-networking/connect-applications-service.md - [ ] content/ko/docs/concepts/services-networking/dual-stack.md > 오타 수정으로, 한글문서에서는 반영되어있음. - [ ] content/ko/docs/concepts/services-networking/service-topology.md > 오타 수정으로, 한글문서에서는 반영되어있음. - [x] content/ko/docs/concepts/workloads/controllers/cron-jobs.md - [x] content/ko/docs/concepts/workloads/pods/pod-overview.md - [x] content/ko/docs/reference/glossary/customresourcedefinition.md - [x] content/ko/docs/reference/kubectl/cheatsheet.md - [x] content/ko/docs/setup/_index.md - [ ] content/ko/docs/tasks/access-application-cluster/access-cluster.md > #18243 에서 반영됨. from #18577 /language ko * Update kubectl/cheatsheet.md in dev-1.17-ko.3 branch. Co-authored-by: Claudia J.Kang --- .../services-networking/connect-applications-service.md | 2 +- content/ko/docs/concepts/workloads/controllers/cron-jobs.md | 5 +++++ content/ko/docs/concepts/workloads/pods/pod-overview.md | 2 +- .../ko/docs/reference/glossary/customresourcedefinition.md | 2 +- content/ko/docs/reference/kubectl/cheatsheet.md | 5 +++-- content/ko/docs/setup/_index.md | 6 ++---- 6 files changed, 13 insertions(+), 9 deletions(-) diff --git a/content/ko/docs/concepts/services-networking/connect-applications-service.md b/content/ko/docs/concepts/services-networking/connect-applications-service.md index a0728564afe07..fce55dbf8e2fc 100644 --- a/content/ko/docs/concepts/services-networking/connect-applications-service.md +++ b/content/ko/docs/concepts/services-networking/connect-applications-service.md @@ -334,7 +334,7 @@ NAME READY STATUS RESTARTS AGE curl-deployment-1515033274-1410r 1/1 Running 0 1m ``` ```shell -kubectl exec curl-deployment-1515033274-1410r -- curl https://my-nginx --cacert /etc/nginx/ssl/nginx.crt +kubectl exec curl-deployment-1515033274-1410r -- curl https://my-nginx --cacert /etc/nginx/ssl/tls.crt ... Welcome to nginx! ... diff --git a/content/ko/docs/concepts/workloads/controllers/cron-jobs.md b/content/ko/docs/concepts/workloads/controllers/cron-jobs.md index d7c6f10739c69..ff76d12f868bf 100644 --- a/content/ko/docs/concepts/workloads/controllers/cron-jobs.md +++ b/content/ko/docs/concepts/workloads/controllers/cron-jobs.md @@ -17,6 +17,11 @@ _크론 잡은_ 시간 기반의 일정에 따라 [잡](/docs/concepts/workloads 모든 **크론잡** `일정:` 시간은 잡이 처음 시작된 마스터의 시간대를 기반으로 한다. {{< /note >}} +크론잡 리소스에 대한 매니페스트를 생성할때에는 제공하는 이름이 +52자 이하인지 확인해야 한다. 이는 크론잡 컨트롤러는 제공된 잡 이름에 +11자를 자동으로 추가하고, 작업 이름의 최대 길이는 +63자라는 제약 조건이 있기 때문이다. + 크론 잡을 생성하고 작동하는 방법은 크론 잡의 스펙 파일을 확안한다. 내용은 [크론 잡으로 자동 작업 실행하기](/docs/tasks/job/automated-tasks-with-cron-jobs)를 참조한다. {{% /capture %}} diff --git a/content/ko/docs/concepts/workloads/pods/pod-overview.md b/content/ko/docs/concepts/workloads/pods/pod-overview.md index ef0b0de7558f4..55126172feb7a 100644 --- a/content/ko/docs/concepts/workloads/pods/pod-overview.md +++ b/content/ko/docs/concepts/workloads/pods/pod-overview.md @@ -26,7 +26,7 @@ card: * **단일 컨테이너만 동작하는 파드**. "단일 컨테이너 당 한 개의 파드" 모델은 쿠버네티스 사용 사례 중 가장 흔하다. 이 경우, 한 개의 파드가 단일 컨테이너를 감싸고 있다고 생각할 수 있으며, 쿠버네티스는 컨테이너가 아닌 파드를 직접 관리한다고 볼 수 있다. * **함께 동작하는 작업이 필요한 다중 컨테이너가 동작하는 파드**. 아마 파드는 강하게 결합되어 있고 리소스 공유가 필요한 다중으로 함께 배치된 컨테이너로 구성되어 있을 것이다. 이렇게 함께 배치되어 설치된 컨테이너는 단일 결합 서비스 단위일 것이다. 한 컨테이너는 공유 볼륨에서 퍼블릭으로 파일들을 옮기고, 동시에 분리되어 있는 "사이드카" 컨테이너는 그 파일들을 업데이트 하거나 복구한다. 파드는 이 컨테이너와 저장소 리소스들을 한 개의 관리 가능한 요소로 묶는다. -[쿠버네티스 블로그](http://kubernetes.io/blog)에는 파드 사용 사례의 몇 가지 추가적인 정보가 있다. 더 많은 정보를 위해서 아래 내용을 참조하길 바란다. +[쿠버네티스 블로그](https://kubernetes.io/blog)에는 파드 사용 사례의 몇 가지 추가적인 정보가 있다. 더 많은 정보를 위해서 아래 내용을 참조하길 바란다. * [분산 시스템 툴킷: 복합 컨테이너를 위한 패턴](https://kubernetes.io/blog/2015/06/the-distributed-system-toolkit-patterns) * [컨테이너 디자인 패턴](https://kubernetes.io/blog/2016/06/container-design-patterns) diff --git a/content/ko/docs/reference/glossary/customresourcedefinition.md b/content/ko/docs/reference/glossary/customresourcedefinition.md index d21612e118370..3e680ca2bd822 100755 --- a/content/ko/docs/reference/glossary/customresourcedefinition.md +++ b/content/ko/docs/reference/glossary/customresourcedefinition.md @@ -2,7 +2,7 @@ title: 커스텀 리소스 데피니션(CustomResourceDefinition) id: CustomResourceDefinition date: 2018-04-12 -full_link: docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/ +full_link: /docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/ short_description: > 사용자 정의 서버를 완전히 새로 구축할 필요가 없도록 쿠버네티스 API 서버에 추가할 리소스를 정의하는 사용자 정의 코드. diff --git a/content/ko/docs/reference/kubectl/cheatsheet.md b/content/ko/docs/reference/kubectl/cheatsheet.md index a964a4a6d6e0b..8c6e54aabb41c 100644 --- a/content/ko/docs/reference/kubectl/cheatsheet.md +++ b/content/ko/docs/reference/kubectl/cheatsheet.md @@ -82,7 +82,7 @@ kubectl config unset users.foo # foo 사용자 삭제 ## 오브젝트 생성 -쿠버네티스 매니페스트는 json이나 yaml로 정의된다. 파일 확장자는 `.yaml` +쿠버네티스 매니페스트는 JSON이나 YAML로 정의된다. 파일 확장자는 `.yaml` , `.yml`, `.json` 이 사용된다. ```bash @@ -203,6 +203,7 @@ kubectl rollout history deployment/frontend # 현 리비전 kubectl rollout undo deployment/frontend # 이전 디플로이먼트로 롤백 kubectl rollout undo deployment/frontend --to-revision=2 # 특정 리비전으로 롤백 kubectl rollout status -w deployment/frontend # 완료될 때까지 "frontend" 디플로이먼트의 롤링 업데이트 상태를 감시 +kubectl rollout restart deployment/frontend # "frontend" 디플로이먼트의 롤링 재시작 # 버전 1.11 부터 사용 중단 @@ -330,7 +331,7 @@ kubectl api-resources --api-group=extensions # "extensions" API 그룹의 모든 ### 출력 형식 지정 -특정 형식으로 터미널 창에 세부 사항을 출력하려면, 지원되는 `kubectl` 명령에 `-o` 또는 `--output` 플래그를 추가하면 된다. +특정 형식으로 터미널 창에 세부 사항을 출력하려면, 지원되는 `kubectl` 명령에 `-o` (또는 `--output`) 플래그를 추가한다. 출력 형식 | 세부 사항 --------------| ----------- diff --git a/content/ko/docs/setup/_index.md b/content/ko/docs/setup/_index.md index d10d66cd204db..8e6bc5e66887a 100644 --- a/content/ko/docs/setup/_index.md +++ b/content/ko/docs/setup/_index.md @@ -43,7 +43,6 @@ card: | | [IBM Cloud Private-CE (Community Edition)](https://github.com/IBM/deploy-ibm-cloud-private) | | | [IBM Cloud Private-CE (Community Edition) on Linux Containers](https://github.com/HSBawa/icp-ce-on-linux-containers)| | | [k3s](https://k3s.io)| -| | [Ubuntu on LXD](/docs/getting-started-guides/ubuntu/)| ## 운영 환경 @@ -77,11 +76,10 @@ card: | [Digital Rebar](https://provision.readthedocs.io/en/tip/README.html) | | | | | | ✔ | [DigitalOcean](https://www.digitalocean.com/products/kubernetes/) | ✔ | | | | | | [Docker Enterprise](https://www.docker.com/products/docker-enterprise) | |✔ | ✔ | | | ✔ -| [Fedora (멀티 노드)](https://kubernetes.io/docs/getting-started-guides/fedora/flannel_multi_node_cluster/)  | | | | | ✔ | ✔ -| [Fedora (단일 노드)](https://kubernetes.io/docs/getting-started-guides/fedora/fedora_manual_config/)  | | | | | | ✔ | [Gardener](https://gardener.cloud/) | ✔ | ✔ | ✔ | ✔ | ✔ | [사용자 정의 확장](https://github.com/gardener/gardener/blob/master/docs/extensions/overview.md) | | [Giant Swarm](https://www.giantswarm.io/) | ✔ | ✔ | ✔ | | | [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/) | ✔ | ✔| ✔ | | | | | | | | | [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/) | |✔| ✔ | | | @@ -92,6 +90,7 @@ card: | [Kublr](https://kublr.com/) |✔ | ✔ |✔ |✔ |✔ |✔ | | [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/) | | | ✔ | | | +| [NetApp Kubernetes Service (NKS)](https://cloud.netapp.com/kubernetes-service) | ✔ | ✔ | ✔ | | | | [Nirmata](https://www.nirmata.com/) | | ✔ | ✔ | | | | [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) | | | | | @@ -101,7 +100,6 @@ card: | [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/) | ✔ | ✔ | ✔ | [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/) -| [StackPoint](https://stackpoint.io/)  | ✔ | ✔ | | | | | [Supergiant](https://supergiant.io/) | |✔ | | | | | [SUSE](https://www.suse.com/) | | ✔ | | | | | [SysEleven](https://www.syseleven.io/) | ✔ | | | | | From 1d756c8dfe9be01ef6170158ef3169466933a136 Mon Sep 17 00:00:00 2001 From: KimMJ Date: Fri, 24 Jan 2020 20:30:28 +0900 Subject: [PATCH 03/12] translate assign-pod-node.md --- .../concepts/configuration/assign-pod-node.md | 348 ++++++++++++++++++ content/ko/examples/pods/pod-nginx.yaml | 13 + .../examples/pods/pod-with-node-affinity.yaml | 26 ++ .../examples/pods/pod-with-pod-affinity.yaml | 29 ++ 4 files changed, 416 insertions(+) create mode 100644 content/ko/docs/concepts/configuration/assign-pod-node.md create mode 100644 content/ko/examples/pods/pod-nginx.yaml create mode 100644 content/ko/examples/pods/pod-with-node-affinity.yaml create mode 100644 content/ko/examples/pods/pod-with-pod-affinity.yaml diff --git a/content/ko/docs/concepts/configuration/assign-pod-node.md b/content/ko/docs/concepts/configuration/assign-pod-node.md new file mode 100644 index 0000000000000..4387e832345d6 --- /dev/null +++ b/content/ko/docs/concepts/configuration/assign-pod-node.md @@ -0,0 +1,348 @@ +--- +title: 노드에 파드 할당하기 +content_template: templates/concept +weight: 30 +--- + + +{{% capture overview %}} + +{{< glossary_tooltip text="파드" term_id="pod" >}}를 특정한 {{< glossary_tooltip text="노드" term_id="node" >}}에서만 동작하도록 하거나 특정 노드를 선호하도록 제한할 수 있다. +이를 위해서는 몇가지 방법이 있는데 그 중 하나는 선택 시 [레이블 셀렉터(label selector)](/ko/docs/concepts/overview/working-with-objects/labels/)를 사용하는 것이다. +스케쥴러가 알아서 합리적인 위치를 고르기 때문에 (예를 들어 파드를 노드에 퍼뜨리고, 리소스가 충분하지 않은 노드에는 파드를 위치시키지 않는 것 등) 일반적으로 이러한 제약은 불필요하지만 +파드가 SSD가 달려있는 머신에서 동작하도록 하거나 서로 통신을 많이 하는 두개의 각기 다른 서비스와 연결된 파드가 +동일한 가용성 영역(availability zone)에 위치시켜야 하는 것처럼 +파드가 위치할 노드에 대해 좀 더 제어가 필요한 몇가지 상황들이 있다. + +{{% /capture %}} + +{{% capture body %}} + +## 노드 셀렉터(nodeSelector) + +`nodeSelector`는 가장 간단하고 추천하는 형식의 노드 선택 제약이다. +`nodeSelector`는 파드 스펙의 필드이다. 이는 키-값 쌍의 맵을 지정한다. +파드가 노드에서 동작할 수 있도록 하려면 노드는 반드시 레이블(물론 이는 추가적인 레이블들을 가질 수도 있다)로 지정된 +키-값 쌍들을 모두 가지고 있어야 한다. 일반적인 사용법은 단일 키-값 쌍을 사용하는 것이다. + +`nodeSelector`를 어떻게 사용하는지 예시를 통해 알아보도록 하자. + +### 0 단계: 사전 준비 + +이 예시는 쿠버네티스에 대한 기본적인 이해를 하고 있고 [쿠버네티스 클러스터가 준비](/ko/docs/setup/)되어 있다고 가정한다. + +### 1 단계: 노드에 레이블 붙이기 {#step-one-attach-label-to-the-node} + +`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} + +노드에 [붙인](#step-one-attach-label-to-the-node) 레이블에 추가적으로 이미 만들어진 표준 레이블 모음이 있다. 이런 레이블들은 다음과 같다. + +* [`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) + +노드 오브젝트에 레이블을 추가하는 것은 파드가 특정한 노드들이나 노드 그룹들을 목표 대상으로 할 수 있도록 한다. +이는 특정한 파드가 어떤 격리, 보안, 규제 속성들을 가진 노드에서만 동작할 수 있도록 한다. +이는 compromised node들이 kubelet 자격증명(credential)을 사용하여 노드 오브젝트 자체에 레이블을 설정하지 않도록 하며 스케쥴러가 compromised node에 워크로드를 스케쥴하는 데 영향을 주지 않도록 한다. + +`NodeRestriction` 어드미션 플러그인은 kubelet이 레이블을 `node-restriction.kubernetes.io/` 접두사로 수정하거나 설정하는 것을 방지한다. 노드 격리를 위해 그 레이블 접두사를 사용하도록 하려면 다음과 같이 하면 된다: + +1. [Node authorizer](/docs/reference/access-authn-authz/node/)를 사용하고 있고 [NodeRestriction admission plugin](/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`와 비슷한 것(그러나 위의 리스트에서 말한 것 중 처음 두가지 이점을 가졌다)이고, +파드간 어피니티/안티-어피니티는 위 리스트의 3번째 리스트에서 설명한 것처럼 +노드 레이블이 아니라 파드의 레이블에 대해서 제약을 둘 수 있으면서 첫번째와 두번째 속성또한 가졌다. + +### 노드 어피니티 + +노드 어피니티는 개념적으로 `nodeSelector`와 비슷하다 -- 이는 노드에 달린 레이블을 기반으로 파드가 특정한 노드로 스케쥴이 가능하도록 제약을 줄 수 있다. + +`requiredDuringSchedulingIgnoredDuringExecution`과 `preferredDuringSchedulingIgnoredDuringExecution` 두가지 종류의 노드 어피니티가 있다. +전자는 파드가 노드에 스케쥴될 때 (`nodeSelector`와 비슷하지만 좀 더 표현이 풍부한 문법이다) 규칙을 *반드시* 만족해야 하는 것이고, 후자는 스케쥴러가 규칙을 지키려고 시도하겠지만 만족한다는 것을 보장하지는 않는, 규칙을 *선호*한다는 관점에서 이를 각각 "엄격한" 그리고 "유연한" 조건이라고 생각할 수 있다. +위의 이름에서 "IgnoredDuringExecution"라고 적혀있는 부분은 `nodeSelector`가 동작하는 방식과 비슷하게 노드의 레이블이 런타임에 변경될 경우 파드에 설정된 어피니티 규칙이 더이상 만족하지 않는 경우에도 파드가 여전히 그 노드에서 동작한다는 의미이다. +후에 `requiredDuringSchedulingRequiredDuringExecution` 설정을 제공하여 `requiredDuringSchedulingIgnoredDuringExecution` 처럼 동작하지만 파드가 동작하고 있는 노드가 더 이상 파드의 노드 어피니티 요구사항을 만족하지 않는 경우에 파드를 축출하는 것을 계획하고 있다. + +따라서 `requiredDuringSchedulingIgnoredDuringExecution`의 예시는 "인텔 CPU가 있는 노드에서만 파드를 동작시키겠다"가 될 수 있으며 +`preferredDuringSchedulingIgnoredDuringExecution`의 예시는 "XYZ 영역에 파드 세트를 동작시키려고 시도하지만 가능하지 않은 경우 다른곳에서 동작하는 것을 허용한다"가 되겠다. + +노드 어피니티는 파드 스펙에서 `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`를 사용하여 안티-어피니티 동작을 할 수 있고 [노드 테인트(node taints)](/docs/concepts/configuration/taint-and-toleration/) 사용하여 특정한 노드에서 파드를 쫓아낼 수 있다. + +`nodeSelector`와 `nodeAffinity`를 모두 지정한다면 파드가 후보 노드에 스케쥴 되기 위해서는 *둘 다* 반드시 만족해야한다. + +여러개의 `nodeAffinity` 타입과 관련하여 `nodeSelectorTerms`를 지정하면 파드는 `nodeSelectorTerms` 중에서 **하나라도 만족**하는 노드에 스케쥴될 수 있다. + +`nodeSelectorTerms`와 관련된 `matchExpressions`를 여러개 지정하면 파드는 `matchExpressions`가 **모두 만족**하는 노드에만 스케쥴될 수 있다. + +파드가 스케쥴된 노드의 레이블을 지우거나 변경해도 파드는 삭제되지 않는다. 다시 말해, 어피니티 선택은 파드가 스케쥴링 되는 시점에만 작동한다. + +`preferredDuringSchedulingIgnoredDuringExecution`에서 `weight` 필드는 1-100까지의 범위를 가진다. +모든 스케쥴링 요구사항 (리소스 요청, RequiredDuringScheduling 어피니티 표현식 등)을 만족하는 각 노드들에 대해서 스케쥴러는 이 필드를 순회하며 노드가 MatchExpressions에 적합할 때 "weight"를 누적 합계에 추가하여 총합을 계산할 것이다. +이 점수는 노드에 대해 다른 우선순위 함수의 점수들과 합쳐진다. 가장 높은 점수를 가진 노드를 가장 선호하게 된다. + +### 파드간 어피니티와 안티-어피니티 + +파드간 어피니티와 안티-어피니티는 파드를 노드의 레이블이 아니라 *노드에서 이미 동작 중인 파드들의 레이블을 기반으로* 동작할 수 있는 노드를 선택하게 할 수 있다. +이 규칙은 "이 파드는 반드시 Y 규칙을 만족하는 파드가 하나 이상 동작중인 X에서만 동작할 수 있도록(안티-어피니티의 경우, 동작할수 없도록) 한다"는 형태로 구성되어있다. +Y는 네임스페이스와 관련된 선택적 목록을 가진 LabelSelector로 표현된다; 노드와는 다르게 파드는 네임스페이스 기반(이는 파드의 레이블이 네임스페이스 기반임을 내포한다)이고 파트 레이블에 대한 레이블 셀렉터는 반드시 셀렉터가 어느 네임스페이스에 적용되어야 하는지 지정해 주어야 하기 때문이다. +개념적으로 X는 노드, 랙, 클라우드 제공자 영역, 클라우드 제공자 리젼 등과 같은 토폴로지 도메인이다. 시스템이 사용하는 토폴로지 도메인을 의미하는 노드 레이블의 키인 `topologyKey`를 사용하여 토폴로지 도메인을 표현할 수 있으며, 예시는 [넘어가기 전에: 빌트인 노드 레이블](#built-in-node-labels) 섹션에 나열된 레이블 키를 보면 된다. + +{{< note >}} +파드간 어피니티와 안티-어피니티는 상당한 양의 연산을 필요로 하여 큰 클러스터에서는 스케쥴링을 상당히 느리게 할 수 있다. +수백개의 노드가 넘는 클러스터에서 이를 사용하는 것은 추천하지 않는다. +{{< /note >}} + +{{< note >}} +파드 안티-어피니티는 노드가 일관적으로 레이블을 가지고 있어야 함을 전제로 한다. 예를들어 클러스터의 모든 노드는 `topologyKey`와 매칭되는 적절한 레이블을 가지고 있어야 한다. 일부 또는 모든 노드가 지정된 `topologyKey` 레이블이 없다면 이는 의도치 않은 동작을 일으킬 수 있다. +{{< /note >}} + +노드 어피니티처럼 현재 각각 "엄격한"과 "유연한" 제약사항을 나타내는 `requiredDuringSchedulingIgnoredDuringExecution`와 `preferredDuringSchedulingIgnoredDuringExecution`라고 하는 파드 어피니티와 안티 어피니티 두가지 종류가 있다. +앞선 노드 어피니티 섹션의 설명을 보면 된다. +`requiredDuringSchedulingIgnoredDuringExecution` 어피니티의 예시는 "서비스 A와 서비스 B는 서로 많은 통신을 하기 때문에 각 서비스의 파드들을 동일한 영역에 위치시킨다."이고 `preferredDuringSchedulingIgnoredDuringExecution` 안티 어피니티의 예시는 "서비스를 여러 영역에 걸처 퍼트린다"가 될 것이다 +(엄격한 제약조건은 파드가 영역의 수보다 많을 수 있기 때문에 말이 안된다). + +파드간 어피니티는 파드 스펙에서 `affinity` 필드의 `podAffinity` 필드에서 지정할 수 있다. 그리고 파드간 안티-어피니티는 파드 스펙에서 `affinity` 필드의 `podAntiAffinity` 필드에서 지정할 수 있다. + +#### 파드 어피니티를 사용하는 파드의 예시: + +{{< codenew file="pods/pod-with-pod-affinity.yaml" >}} + +이 파드에서의 어피니티는 하나의 파드 어피니티 규칙과 하나의 안티-어피니티 규칙을 정의한다. 이 예시에서 `podAffinity`는 `requiredDuringSchedulingIgnoredDuringExecution`이고 `podAntiAffinity`는 `preferredDuringSchedulingIgnoredDuringExecution`이다. +파드 어피니티 규칙은 "security"를 키로하고 "S1"을 값으로 하는 레이블을 가진 파드가 최소한 하나라도 동작 중인 한 노드에서만 스케쥴될 수 있다고 말하고 있다. +(더 정확하게는 파드가 `failure-domain.beta.kubernetes.io/zone`를 키로하고 V를 값으로 하는 클러스터의 노드가 "security"를 키로하고 "S1"을 값으로 하는 레이블을 가진 파드를 동작시키고 있는 것과 같이 노드 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`는 어느 규칙에 맞는 레이블-키도 될 수 있다. +하지만 성능과 보안상의 이유로 토폴로지 키에는 몇가지 제약사항이 있다. + +1. 어피니티와 `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 `topologyKey`가 비어있는 것은 허용하지 않는다. +2. `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 어드미션 컨트롤러의 `LimitPodHardAntiAffinityTopology`는 `topologyKey`를 `kubernetes.io/hostname`으로 제한하기 위해 도입되었다. 사용자 정의 토폴로지를 이용하고자 할 경우 어드미션 컨트롤러를 수정하거나 간단하게 이를 비활성화 하면 된다. +3. `preferredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 `topologyKey`가 비어있는 경우 이를 "모든 토폴로지"("모든 토폴로지"는 현재 `kubernetes.io/hostname`, `failure-domain.beta.kubernetes.io/zone`, `failure-domain.beta.kubernetes.io/region`로 제한된다)로 해석한다. +4. 위의 경우를 제외하면 `topologyKey`는 어느 규칙에 맞는 레이블-키도 가능하다. + +`labelSelector`와 `topologyKey`외에도 `labelSelector`가 매칭되어야 하는 네임스페이스의 `namespaces` 리스트를 선택적으로 지정할 수 있다(이는 `labelSelector`와 `topologyKey`와 같은 개위로 작성되어야 한다). +생략되어있거나 비어있을 경우 어피니티/안티-어피니티 정의가 있는 파드의 네임스페이스가 기본 값이다. + +파드가 노드에 스케쥴되려면 `requiredDuringSchedulingIgnoredDuringExecution` 어피니티 및 안티-어피니티와 관련된 모든 `matchExpressions`를 만족해야 한다. + +#### 더 실용적인 유스케이스 + +파드간 어피니티와 안티-어피니티는 레플리카셋, 스테이트풀셋, 디플로이먼트 등과 같은 상위 레벨의 컬렉션에 사용될 때 좀 더 유용할 수 있다. +이를 통해 같은 노드에 함께 위치시키는 것과 같이 정의된 토폴로지와 동일한 곳에 함께 위치시키는 워크로드를 쉽게 구성할 수 있다. + +##### 항상 같은 노드에 위치시키기 + +세개의 노드를 가진 클러스터가 있는 상황에서 웹 어플리케이션은 redis와 같은 인메모리 캐시를 가지고 있다. 웹 서버를 캐시가 있는 위치와 동일한 곳으로 최대한 많이 위치시키고 싶다. + +이 짧은 yaml은 세개의 레플리카를 가지고 `app=store`라는 셀렉터 레이블을 가진 간단한 redis 디플로이먼트이다. 디플로이먼트는 `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.12-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 +``` + +##### 절대 동일한 노드에 위치시키지 않게 하기 + +위의 예시는 `PodAntiAffinity` 규칙을 `topologyKey:"kubernetes.io/hostname"`과 함께 사용하여 redis 클러스터가 하나의 호스트에 두개 이상 위치하지 않도록 배포한다. +[ZooKeeper 튜토리얼](/docs/tutorials/stateful-application/zookeeper/#tolerating-node-failure)을 통해 같은 방법을 사용하여 스테이트풀셋을 고가용성을 위해 안티-어피니티 설정을 한 예시를 확인할 수 있다. + +## nodeName + +`nodeName` 노드 셀렉션을 하는 가장 간단한 형태이지만 자체의 한계때문에 일반적으로 사용하지는 않는다. +`nodeName`은 파드 스펙의 필드이다. 비어있지 않다면 스케쥴러는 이 파트를 무시하게 되고 해당되는 노드에서 동작중인 kubelet이 파드를 실행하려 할 것이다. +따라서 `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 %}} + +[테인트(Taints)](/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 %}} diff --git a/content/ko/examples/pods/pod-nginx.yaml b/content/ko/examples/pods/pod-nginx.yaml new file mode 100644 index 0000000000000..134ddae2aa1c8 --- /dev/null +++ b/content/ko/examples/pods/pod-nginx.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nginx + labels: + env: test +spec: + containers: + - name: nginx + image: nginx + imagePullPolicy: IfNotPresent + nodeSelector: + disktype: ssd diff --git a/content/ko/examples/pods/pod-with-node-affinity.yaml b/content/ko/examples/pods/pod-with-node-affinity.yaml new file mode 100644 index 0000000000000..253d2b21ea917 --- /dev/null +++ b/content/ko/examples/pods/pod-with-node-affinity.yaml @@ -0,0 +1,26 @@ +apiVersion: v1 +kind: Pod +metadata: + name: with-node-affinity +spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/e2e-az-name + operator: In + values: + - e2e-az1 + - e2e-az2 + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + preference: + matchExpressions: + - key: another-node-label-key + operator: In + values: + - another-node-label-value + containers: + - name: with-node-affinity + image: k8s.gcr.io/pause:2.0 \ No newline at end of file diff --git a/content/ko/examples/pods/pod-with-pod-affinity.yaml b/content/ko/examples/pods/pod-with-pod-affinity.yaml new file mode 100644 index 0000000000000..35e645ef1f376 --- /dev/null +++ b/content/ko/examples/pods/pod-with-pod-affinity.yaml @@ -0,0 +1,29 @@ +apiVersion: v1 +kind: Pod +metadata: + name: with-pod-affinity +spec: + affinity: + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: security + operator: In + values: + - S1 + topologyKey: failure-domain.beta.kubernetes.io/zone + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + - key: security + operator: In + values: + - S2 + topologyKey: failure-domain.beta.kubernetes.io/zone + containers: + - name: with-pod-affinity + image: k8s.gcr.io/pause:2.0 From e81689daf2debb85560f91b1525ccb878e061af1 Mon Sep 17 00:00:00 2001 From: KimMJ Date: Sun, 2 Feb 2020 03:43:01 +0900 Subject: [PATCH 04/12] =?UTF-8?q?comment=201=EC=B0=A8=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../concepts/configuration/assign-pod-node.md | 233 +++++++++++------- 1 file changed, 140 insertions(+), 93 deletions(-) diff --git a/content/ko/docs/concepts/configuration/assign-pod-node.md b/content/ko/docs/concepts/configuration/assign-pod-node.md index 4387e832345d6..32f25b8558d43 100644 --- a/content/ko/docs/concepts/configuration/assign-pod-node.md +++ b/content/ko/docs/concepts/configuration/assign-pod-node.md @@ -7,12 +7,15 @@ weight: 30 {{% capture overview %}} -{{< glossary_tooltip text="파드" term_id="pod" >}}를 특정한 {{< glossary_tooltip text="노드" term_id="node" >}}에서만 동작하도록 하거나 특정 노드를 선호하도록 제한할 수 있다. -이를 위해서는 몇가지 방법이 있는데 그 중 하나는 선택 시 [레이블 셀렉터(label selector)](/ko/docs/concepts/overview/working-with-objects/labels/)를 사용하는 것이다. -스케쥴러가 알아서 합리적인 위치를 고르기 때문에 (예를 들어 파드를 노드에 퍼뜨리고, 리소스가 충분하지 않은 노드에는 파드를 위치시키지 않는 것 등) 일반적으로 이러한 제약은 불필요하지만 -파드가 SSD가 달려있는 머신에서 동작하도록 하거나 서로 통신을 많이 하는 두개의 각기 다른 서비스와 연결된 파드가 -동일한 가용성 영역(availability zone)에 위치시켜야 하는 것처럼 -파드가 위치할 노드에 대해 좀 더 제어가 필요한 몇가지 상황들이 있다. +{{< glossary_tooltip text="파드" term_id="pod" >}}를 특정한 {{< glossary_tooltip text="노드(emf)" term_id="node" >}}에서만 동작하도록 하거나, +특정 노드들을 선호하도록 제한할 수 있다. +이를 수행하는 방법에는 여러가지가 있으며, 권장되는 접근 방식은 모두 +[레이블 셀렉터(label selector)](/ko/docs/concepts/overview/working-with-objects/labels/)를 사용하여 선택한다. +보통 스케줄러가 자동으로 합리적인 배치를 수행하기에 이런 제약 조건은 필요하지 않지만 +(예: 노드들에 걸쳐 파드를 분배하거나, 여유 자원이 부족한 노드에 파드를 배치하는 등) +간혹 파드가 착츅하는 노드에 대해 더 많은 제어를 원할 수 있는 상황이 있다. +예를 들어 SSD가 장착되어 있는 머신에 파드가 연결되도록 하거나 또는 동일한 가용성 영역(availability zone)에서 +많은 것을 통신하는 두 개의 서로 다른 서비스의 파드를 같이 배치할 수 있다. {{% /capture %}} @@ -20,29 +23,26 @@ weight: 30 ## 노드 셀렉터(nodeSelector) -`nodeSelector`는 가장 간단하고 추천하는 형식의 노드 선택 제약이다. -`nodeSelector`는 파드 스펙의 필드이다. 이는 키-값 쌍의 맵을 지정한다. -파드가 노드에서 동작할 수 있도록 하려면 노드는 반드시 레이블(물론 이는 추가적인 레이블들을 가질 수도 있다)로 지정된 -키-값 쌍들을 모두 가지고 있어야 한다. 일반적인 사용법은 단일 키-값 쌍을 사용하는 것이다. +`nodeSelector` 는 가장 간단하고 권장하는 노드 선택 제약 조건의 형태이다. +`nodeSelector` 는 PodSpec의 필드이다. 이는 키-값 쌍의 매핑으로 지정한다. 파드가 노드에서 동작할 수 있으려면, +노드는 키-값의 쌍으로 표시되는 레이블을 각자 가지고 있어야 한다(이는 추가 레이블을 가지고 있을 수 있다). +대부분의 일반적인 사용은 하나의 키-값 쌍이다. -`nodeSelector`를 어떻게 사용하는지 예시를 통해 알아보도록 하자. +`nodeSelector` 를 어떻게 사용하는지 예시를 통해 알아보도록 하자. ### 0 단계: 사전 준비 -이 예시는 쿠버네티스에 대한 기본적인 이해를 하고 있고 [쿠버네티스 클러스터가 준비](/ko/docs/setup/)되어 있다고 가정한다. +이 예시는 쿠버네티스 파드에에 대한 기본적인 이해를 하고 있고 [쿠버네티스 클러스터가 설정](/ko/docs/setup/)되어 있다고 가정한다. -### 1 단계: 노드에 레이블 붙이기 {#step-one-attach-label-to-the-node} +### 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` 를 실행해서 클러스터 노드 이름을 가져온다. 이 중에 레이블을 추가하기 원하는 것 하나를 선택한 다음에 `kubectl label nodes <노드 이름> <레이블 키>=<레이블 값>` 을 실행해서 선택한 노드에 레이블을 추가 한다. 예를 들어 노드의 이름이 'kubernetes-foo-node-1.c.a-robinson.internal' 이고, 원하는 레이블이 'disktype=ssd' 라면, `kubectl label nodes ubernetes-foo-node-1.c.a-robinson.internal disktype=ssd` 를 실행 한다. -`kubectl get nodes --show-labels`를 다시 실행시켜서 노드에 레이블이 있는지 확인하여 이 작업이 잘 되었는지 검증할 수 있다. -또한 `kubectl describe node "노드 이름"`을 이용하여 주어진 노드에 대한 모든 레이블들의 리스트를 확인할 수 있다. +`kubectl get nodes --show-labels` 를 다시 실행해서 노드가 현재 가진 레이블을 확인하여, 이 작업을 검증할 수 있다. 또한 `kubectl describe node "노드 이름"` 을 사용해서 노드에 주어진 레이블의 전체 목록을 확인할 수 있다. ### 2 단계: 파드 설정에 nodeSelector 필드 추가하기 -아래와 같이 실행하고 싶은 파드의 설정 파일에 nodeSelector을 추가한다. 만약 파드 설정 파일이 다음과 같다면: +실행하고자 하는 파드의 설정 파일을 가져오고, 이와 같이 nodeSelector 섹션을 추가한다. 예를 들어 이것이 파드 설정이라면: ```yaml apiVersion: v1 @@ -57,16 +57,19 @@ spec: image: nginx ``` -nodeSelector를 이처럼 추가한다: +이 다음에 nodeSelector 를 다음과 같이 추가한다: {{< codenew file="pods/pod-nginx.yaml" >}} -`kubectl apply -f https://k8s.io/examples/pods/pod-nginx.yaml`을 실행시키면 파드는 레이블을 붙인 노드에 스케쥴될 것이다. -`kubectl get pods -o wide`를 실행시켜 파드가 할당된 "NODE"를 확인하여 검증할 수 있다. +그런 다음에 `kubectl apply -f https://k8s.io/examples/pods/pod-nginx.yaml` 을 +실행하면, 레이블이 붙여진 노드에 파드가 스케줄 된다. +`kubectl get pods -o wide` 를 실행해서 파드가 할당된 +"NODE" 를 보면 작동하는지 검증할 수 있다. ## 넘어가기 전에: 내장 노드 레이블들 {#built-in-node-labels} -노드에 [붙인](#step-one-attach-label-to-the-node) 레이블에 추가적으로 이미 만들어진 표준 레이블 모음이 있다. 이런 레이블들은 다음과 같다. +[붙인](#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) @@ -79,82 +82,98 @@ nodeSelector를 이처럼 추가한다: * [`kubernetes.io/arch`](/docs/reference/kubernetes-api/labels-annotations-taints/#kubernetes-io-arch) {{< note >}} -이 레이블들의 값은 클라우드 제공자에 따라 다르고 신뢰성이 보장되지 않는다. -예를 들어 `kubernetes.io/hostname`은 어떤 환경에서는 노드의 이름과 같고 다른 환경에서는 다른 값이 될 수 있다. +이 레이블들의 값은 클라우드 공급자에 따라 다르고 신뢰성이 보장되지 않는다. +예를 들어 `kubernetes.io/hostname` 은 어떤 환경에서는 노드 이름과 같지만, +다른 환경에서는 다른 값일 수 있다. {{< /note >}} ## 노드 격리(isolation)/제한(restriction) -노드 오브젝트에 레이블을 추가하는 것은 파드가 특정한 노드들이나 노드 그룹들을 목표 대상으로 할 수 있도록 한다. -이는 특정한 파드가 어떤 격리, 보안, 규제 속성들을 가진 노드에서만 동작할 수 있도록 한다. -이는 compromised node들이 kubelet 자격증명(credential)을 사용하여 노드 오브젝트 자체에 레이블을 설정하지 않도록 하며 스케쥴러가 compromised node에 워크로드를 스케쥴하는 데 영향을 주지 않도록 한다. +노드 오브젝트에 레이블을 추가하면 특정 노드 또는 노드 그룹에 파드를 대상으로 할 수 있다. +이는 특정 파드가 어떤 격리, 보안, 또는 규제 속성이 있는 노드에서만 실행되도록 사용할 수 있다. +이 목적으로 레이블을 사용하는 경우, 노드에서 kubelet 프로세스로 수정할 수 없는 레이블 키를 선택하는 것을 권장한다. +이렇게 하면 손상된 노드가 해당 kubelet 자격 증명을 사용해서 해당 레이블을 자체 노드 오브젝트에 설정하고, 스케줄러가 손상된 노드로 워크로드를 스케줄 하는 것을 방지할 수 있다. -`NodeRestriction` 어드미션 플러그인은 kubelet이 레이블을 `node-restriction.kubernetes.io/` 접두사로 수정하거나 설정하는 것을 방지한다. 노드 격리를 위해 그 레이블 접두사를 사용하도록 하려면 다음과 같이 하면 된다: +`NodeRestriction` 어드미션 플러그인은 kubelet이 `node-restriction.kubernetes.io/` 접두사로 레이블을 설정 또는 수정하지 못하게 한다. +노드 격리에 해당 레이블 접두사를 사용하려면 다음과 같이 한다. -1. [Node authorizer](/docs/reference/access-authn-authz/node/)를 사용하고 있고 [NodeRestriction admission plugin](/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`와 같이 설정한다. +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`는 파드를 특정 레이블을 가진 노드에서 동작하도록 제한을 하는 가장 간단한 방법이다. -어피니티/안티-어피니티는 표현할 수 있는 제약의 종류를 폭 넓게 할 수 있다. 개선할 수 있는 사항들은 다음과 같다. +`nodeSelector` 는 파드를 특정 레이블이 있는 도느로 제한하는 매우 간단한 방법을 제공한다. +어피니티/안티-어피니티 기능은 표현할 수 있는 제약 종류를 크게 확장한다. 주요 개선 사항은 다음과 같다. -1. 언어가 더욱 표현력있게 된다. (단순히 정확한 일치를 의미하는 "AND"가 아니다) -2. 엄격한 요구사항 대신 "유연한(soft)"/"선호(preference)" 규칙을 나타낼 수 있어 스케쥴러가 만족하지 못할 경우에도 여전히 파드가 스케쥴될 수 있도록 할 수 있다. -3. 노드 자체(또는 다른 토폴로지 도메인)에 대한 레이블에 대해서만 제약을 걸 수 있는것이 아니라 노드에 떠있는 파드들이 가진 레이블에 대해서도 제약을 걸어 파드가 서로 함께 위치하도록 하거나 위치하지 못하도록 할 수 있다. +1. 언어가 보다 표현적이다("AND 또는 정확한 일치" 만이 아니다). +2. 규칙이 엄격한 요구사항이 아니라 "유연한(soft)"/"선호(preference)" 규칙을 나타낼 수 있기에 스케줄러가 규칙을 만족할 수 없다면, + 파드는 계속 스케줄 되도록 한다. +3. 노드 자체에 레이블을 붙이기 보다는 노드(또는 다른 토폴로지 도메인)에서 실행중인 다른 파드의 레이블을 제한할 수 있다. + 이를 통해 어떤 파드가 함께 위치할 수 있는지와 없는지에 대한 규칙을 적용할 수 있다. -어피니티 기능은 "노드 어피니티", "파드 간 어피니티/안티-어피니티" 두가지 종류의 어피니티로 구성되어있다. -노드 어피니티는 기존 `nodeSelector`와 비슷한 것(그러나 위의 리스트에서 말한 것 중 처음 두가지 이점을 가졌다)이고, -파드간 어피니티/안티-어피니티는 위 리스트의 3번째 리스트에서 설명한 것처럼 -노드 레이블이 아니라 파드의 레이블에 대해서 제약을 둘 수 있으면서 첫번째와 두번째 속성또한 가졌다. +어피니티 기능은 "노드 어피니티" 와 "파드 간 어피니티/안티-어피니티" 두 종류의 어피니티로 구성된다. +노드 어피니티는 기존 `nodeSelector` 와 비슷하지만(그러나 위에서 나열된 첫 째와 두번째 이점이 있다.), +파드 간 어피니티/안티-어피니티는 위에서 나열된 세번째 항목에 설명된 대로 +노드 레이블이 아닌 파드 레이블에 대해 제한되고 위에서 나열된 첫번째와 두번째 속성을 가진다. ### 노드 어피니티 -노드 어피니티는 개념적으로 `nodeSelector`와 비슷하다 -- 이는 노드에 달린 레이블을 기반으로 파드가 특정한 노드로 스케쥴이 가능하도록 제약을 줄 수 있다. +노드 어피니티는 개념적으로 `nodeSelector` 와 비슷하다 -- 이는 노드의 레이블을 기반으로 파드를 +스케줄할 수 있는 노드를 제한할 수 있다. -`requiredDuringSchedulingIgnoredDuringExecution`과 `preferredDuringSchedulingIgnoredDuringExecution` 두가지 종류의 노드 어피니티가 있다. -전자는 파드가 노드에 스케쥴될 때 (`nodeSelector`와 비슷하지만 좀 더 표현이 풍부한 문법이다) 규칙을 *반드시* 만족해야 하는 것이고, 후자는 스케쥴러가 규칙을 지키려고 시도하겠지만 만족한다는 것을 보장하지는 않는, 규칙을 *선호*한다는 관점에서 이를 각각 "엄격한" 그리고 "유연한" 조건이라고 생각할 수 있다. -위의 이름에서 "IgnoredDuringExecution"라고 적혀있는 부분은 `nodeSelector`가 동작하는 방식과 비슷하게 노드의 레이블이 런타임에 변경될 경우 파드에 설정된 어피니티 규칙이 더이상 만족하지 않는 경우에도 파드가 여전히 그 노드에서 동작한다는 의미이다. -후에 `requiredDuringSchedulingRequiredDuringExecution` 설정을 제공하여 `requiredDuringSchedulingIgnoredDuringExecution` 처럼 동작하지만 파드가 동작하고 있는 노드가 더 이상 파드의 노드 어피니티 요구사항을 만족하지 않는 경우에 파드를 축출하는 것을 계획하고 있다. +여기에 현재 `requiredDuringSchedulingIgnoredDuringExecution` 와 `preferredDuringSchedulingIgnoredDuringExecution` 로 부르는 +두 가지 종류의 노드 어피니티가 있다. 전자는 파드가 노드에 스케줄 되도록 *반드시* 규칙을 만족해야 하는 것(`nodeSelector` 와 같으나 보다 표현적인 구문을 사용해서)을 지정하고, +후자는 스케줄러가 시도하려고는 하지만, 보증하지 않는 *선호(preferences)*를 지정한다는 점에서 이를 각각 "엄격함(hard)" 과 "유연함(soft)" 하다고 생각할 수 있다. +이름의 "IgnoredDuringExecution" 부분은 `nodeSelector` 작동 방식과 유사하게 노드의 +레이블이 런타임 중에 변경되어 파드의 어피니티 규칙이 더 이상 충족되지 않으면 파드가 여전히 그 노드에서 +동작한다는 의미이다. 향후에는 파드의 노드 어피니티 요구 사항을 충족하지 않는 노드에서 파드를 제거한다는 점을 제외하고는 `preferredDuringSchedulingIgnoredDuringExecution` 와 같은 `requiredDuringSchedulingIgnoredDuringExecution` 를 제공할 계획이다. -따라서 `requiredDuringSchedulingIgnoredDuringExecution`의 예시는 "인텔 CPU가 있는 노드에서만 파드를 동작시키겠다"가 될 수 있으며 -`preferredDuringSchedulingIgnoredDuringExecution`의 예시는 "XYZ 영역에 파드 세트를 동작시키려고 시도하지만 가능하지 않은 경우 다른곳에서 동작하는 것을 허용한다"가 되겠다. +따라서 `requiredDuringSchedulingIgnoredDuringExecution` 의 예로는 "인텔 CPU가 있는 노드에서만 파드 실행"이 +될 수 있고, `preferredDuringSchedulingIgnoredDuringExecution` 의 예로는 "장애 조치 영역 XYZ에 파드 집합을 실행하려고 +하지만, 불가능하다면 다른 곳에서 일부를 실행하도록 허용"이 된다. -노드 어피니티는 파드 스펙에서 `affinity`필드 내의 `nodeAffinity` 필드에서 지정된다. +노드 어피니티는 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`인 레이블을 가진 노드를 선호하도록 되어있다. +이 노드 어피니티 규칙은 키가 `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`를 사용하여 안티-어피니티 동작을 할 수 있고 [노드 테인트(node taints)](/docs/concepts/configuration/taint-and-toleration/) 사용하여 특정한 노드에서 파드를 쫓아낼 수 있다. +예시에서 연산자 `In` 이 사용되고 있는 것을 볼 수 있다. 새로운 노드 어피니티 구문은 다음의 연산자들을 지원한다. `In`, `NotIn`, `Exists`, `DoesNotExist`, `Gt`, `Lt`. +`NotIn` 과 `DoesNotExist` 를 사용해서 안티-어피니티를 수행하거나, +특정 노드에서 파드를 쫓아내는 [노드 테인트(taint)](/docs/concepts/configuration/taint-and-toleration/)를 할 수 있다. -`nodeSelector`와 `nodeAffinity`를 모두 지정한다면 파드가 후보 노드에 스케쥴 되기 위해서는 *둘 다* 반드시 만족해야한다. +`nodeSelector` 와 `nodeAffinity` 를 모두 지정한다면 파드가 후보 노드에 스케줄 되기 위해서는 +*둘 다* 반드시 만족해야한다. -여러개의 `nodeAffinity` 타입과 관련하여 `nodeSelectorTerms`를 지정하면 파드는 `nodeSelectorTerms` 중에서 **하나라도 만족**하는 노드에 스케쥴될 수 있다. +`nodeAffinity` 유형과 연관된 `nodeSelectorTerms` 를 지정하면, 파드를 `nodeSelectorTerms` 가 지정된 것 중 **하 가지**라도 만족하는 노드에 스케줄 할 수 있다. -`nodeSelectorTerms`와 관련된 `matchExpressions`를 여러개 지정하면 파드는 `matchExpressions`가 **모두 만족**하는 노드에만 스케쥴될 수 있다. +`nodeSelectorTerms` 와 연관된 여러 `matchExpressions` 를 지정하면, 파드는 `matchExpressions` 를 **모두** 만족하는 노드에만 스케줄할 수 있다. -파드가 스케쥴된 노드의 레이블을 지우거나 변경해도 파드는 삭제되지 않는다. 다시 말해, 어피니티 선택은 파드가 스케쥴링 되는 시점에만 작동한다. +파드가 스케줄된 노드의 레이블을 지우거나 변경해도 파드는 제거되지 않는다. 다시 말해서 어피니티 선택은 파드를 스케줄링 하는 시점에만 작동한다. -`preferredDuringSchedulingIgnoredDuringExecution`에서 `weight` 필드는 1-100까지의 범위를 가진다. -모든 스케쥴링 요구사항 (리소스 요청, RequiredDuringScheduling 어피니티 표현식 등)을 만족하는 각 노드들에 대해서 스케쥴러는 이 필드를 순회하며 노드가 MatchExpressions에 적합할 때 "weight"를 누적 합계에 추가하여 총합을 계산할 것이다. -이 점수는 노드에 대해 다른 우선순위 함수의 점수들과 합쳐진다. 가장 높은 점수를 가진 노드를 가장 선호하게 된다. +`preferredDuringSchedulingIgnoredDuringExecution` 의 `weight` 필드의 범위는 1-100 이다. 모든 스케줄링 요구사항 (리소스 요청, RequiredDuringScheduling 어피니티 표현식 등)을 만족하는 각 노드들에 대해 스케줄러는 이 필드의 요소들을 반복해서 합계를 계산하고 노드가 MatchExpressions 에 일치하는 경우 합계에 "가중치(weight)"를 추가 한다. 이후에 이 점수는 노드에 대한 다른 우선순위 함수의 점수와 합쳐진다. 전체 점수가 가장 높은 노드를 가장 선호한다. ### 파드간 어피니티와 안티-어피니티 -파드간 어피니티와 안티-어피니티는 파드를 노드의 레이블이 아니라 *노드에서 이미 동작 중인 파드들의 레이블을 기반으로* 동작할 수 있는 노드를 선택하게 할 수 있다. -이 규칙은 "이 파드는 반드시 Y 규칙을 만족하는 파드가 하나 이상 동작중인 X에서만 동작할 수 있도록(안티-어피니티의 경우, 동작할수 없도록) 한다"는 형태로 구성되어있다. -Y는 네임스페이스와 관련된 선택적 목록을 가진 LabelSelector로 표현된다; 노드와는 다르게 파드는 네임스페이스 기반(이는 파드의 레이블이 네임스페이스 기반임을 내포한다)이고 파트 레이블에 대한 레이블 셀렉터는 반드시 셀렉터가 어느 네임스페이스에 적용되어야 하는지 지정해 주어야 하기 때문이다. -개념적으로 X는 노드, 랙, 클라우드 제공자 영역, 클라우드 제공자 리젼 등과 같은 토폴로지 도메인이다. 시스템이 사용하는 토폴로지 도메인을 의미하는 노드 레이블의 키인 `topologyKey`를 사용하여 토폴로지 도메인을 표현할 수 있으며, 예시는 [넘어가기 전에: 빌트인 노드 레이블](#built-in-node-labels) 섹션에 나열된 레이블 키를 보면 된다. +파드간 어피니티와 안티-어피니티는 파드를 노드의 레이블이 아니라 *노드에서 이미 동작 중인 파드들의 레이블을 기반으로* +동작할 수 있는 노드를 선택하게 할 수 있다. 이 규칙은 "이 파드는 반드시 Y 규칙을 만족하는 파드가 하나 이상 +동작중인 X에서만 동작할 수 있도록(안티-어피니티의 경우, 동작할수 없도록) 한다"는 형태로 구성되어있다. Y는 +네임스페이스와 관련된 선택적 목록을 가진 LabelSelector로 표현된다; 노드와는 다르게 파드는 네임스페이스 +기반(이는 파드의 레이블이 네임스페이스 기반임을 내포한다)이고 파트 레이블에 대한 레이블 셀렉터는 반드시 +셀렉터가 어느 네임스페이스에 적용되어야 하는지 지정해 주어야 하기 때문이다. 개념적으로 X는 노드, 랙, +클라우드 제공자 영역, 클라우드 제공자 리젼 등과 같은 토폴로지 도메인이다. 시스템이 사용하는 토폴로지 +도메인을 의미하는 노드 레이블의 키인 `topologyKey`를 사용하여 토폴로지 도메인을 표현할 수 있으며, +예시는 [넘어가기 전에: 빌트인 노드 레이블](#built-in-node-labels) 섹션에 나열된 레이블 키를 보면 된다. {{< note >}} -파드간 어피니티와 안티-어피니티는 상당한 양의 연산을 필요로 하여 큰 클러스터에서는 스케쥴링을 상당히 느리게 할 수 있다. +파드간 어피니티와 안티-어피니티는 상당한 양의 연산을 필요로 하여 +큰 클러스터에서는 스케쥴링을 상당히 느리게 할 수 있다. 수백개의 노드가 넘는 클러스터에서 이를 사용하는 것은 추천하지 않는다. {{< /note >}} @@ -162,43 +181,60 @@ Y는 네임스페이스와 관련된 선택적 목록을 가진 LabelSelector로 파드 안티-어피니티는 노드가 일관적으로 레이블을 가지고 있어야 함을 전제로 한다. 예를들어 클러스터의 모든 노드는 `topologyKey`와 매칭되는 적절한 레이블을 가지고 있어야 한다. 일부 또는 모든 노드가 지정된 `topologyKey` 레이블이 없다면 이는 의도치 않은 동작을 일으킬 수 있다. {{< /note >}} -노드 어피니티처럼 현재 각각 "엄격한"과 "유연한" 제약사항을 나타내는 `requiredDuringSchedulingIgnoredDuringExecution`와 `preferredDuringSchedulingIgnoredDuringExecution`라고 하는 파드 어피니티와 안티 어피니티 두가지 종류가 있다. +노드 어피니티처럼 현재 각각 "엄격한"과 "유연한" 제약사항을 나타내는 `requiredDuringSchedulingIgnoredDuringExecution`와 +`preferredDuringSchedulingIgnoredDuringExecution`라고 하는 파드 어피니티와 안티 어피니티 두가지 종류가 있다. 앞선 노드 어피니티 섹션의 설명을 보면 된다. -`requiredDuringSchedulingIgnoredDuringExecution` 어피니티의 예시는 "서비스 A와 서비스 B는 서로 많은 통신을 하기 때문에 각 서비스의 파드들을 동일한 영역에 위치시킨다."이고 `preferredDuringSchedulingIgnoredDuringExecution` 안티 어피니티의 예시는 "서비스를 여러 영역에 걸처 퍼트린다"가 될 것이다 +`requiredDuringSchedulingIgnoredDuringExecution` 어피니티의 예시는 +"서비스 A와 서비스 B는 서로 많은 통신을 하기 때문에 각 서비스의 파드들을 동일한 영역에 위치시킨다."이고 +`preferredDuringSchedulingIgnoredDuringExecution` 안티 어피니티의 예시는 "서비스를 여러 영역에 걸처 퍼트린다"가 될 것이다 (엄격한 제약조건은 파드가 영역의 수보다 많을 수 있기 때문에 말이 안된다). -파드간 어피니티는 파드 스펙에서 `affinity` 필드의 `podAffinity` 필드에서 지정할 수 있다. 그리고 파드간 안티-어피니티는 파드 스펙에서 `affinity` 필드의 `podAntiAffinity` 필드에서 지정할 수 있다. +파드간 어피니티는 파드 스펙에서 `affinity` 필드의 `podAffinity` 필드에서 지정할 수 있다. +그리고 파드간 안티-어피니티는 파드 스펙에서 `affinity` 필드의 `podAntiAffinity` 필드에서 지정할 수 있다. #### 파드 어피니티를 사용하는 파드의 예시: {{< codenew file="pods/pod-with-pod-affinity.yaml" >}} -이 파드에서의 어피니티는 하나의 파드 어피니티 규칙과 하나의 안티-어피니티 규칙을 정의한다. 이 예시에서 `podAffinity`는 `requiredDuringSchedulingIgnoredDuringExecution`이고 `podAntiAffinity`는 `preferredDuringSchedulingIgnoredDuringExecution`이다. -파드 어피니티 규칙은 "security"를 키로하고 "S1"을 값으로 하는 레이블을 가진 파드가 최소한 하나라도 동작 중인 한 노드에서만 스케쥴될 수 있다고 말하고 있다. -(더 정확하게는 파드가 `failure-domain.beta.kubernetes.io/zone`를 키로하고 V를 값으로 하는 클러스터의 노드가 "security"를 키로하고 "S1"을 값으로 하는 레이블을 가진 파드를 동작시키고 있는 것과 같이 노드 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`의 파드 어피니티와 안티-어피니티에 대한 많은 예시를 확인할 수 있다. +이 파드에서의 어피니티는 하나의 파드 어피니티 규칙과 하나의 안티-어피니티 규칙을 정의한다. +이 예시에서 `podAffinity`는 `requiredDuringSchedulingIgnoredDuringExecution`이고 `podAntiAffinity`는 +`preferredDuringSchedulingIgnoredDuringExecution`이다. 파드 어피니티 규칙은 "security"를 키로하고 + "S1"을 값으로 하는 레이블을 가진 파드가 최소한 하나라도 동작 중인 한 노드에서만 스케쥴될 수 있다고 말하고 있다. +(더 정확하게는 파드가 `failure-domain.beta.kubernetes.io/zone`를 키로하고 V를 값으로 하는 +클러스터의 노드가 "security"를 키로하고 "S1"을 값으로 하는 레이블을 가진 파드를 동작시키고 있는 것과 같이 +노드 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`는 어느 규칙에 맞는 레이블-키도 될 수 있다. -하지만 성능과 보안상의 이유로 토폴로지 키에는 몇가지 제약사항이 있다. +하지만 성능과 보안상의 이유로 토폴로지 키에는 몇가지 제약사항이 있다: -1. 어피니티와 `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 `topologyKey`가 비어있는 것은 허용하지 않는다. +1. 어피니티와 `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 +`topologyKey`가 비어있는 것은 허용하지 않는다. 2. `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 어드미션 컨트롤러의 `LimitPodHardAntiAffinityTopology`는 `topologyKey`를 `kubernetes.io/hostname`으로 제한하기 위해 도입되었다. 사용자 정의 토폴로지를 이용하고자 할 경우 어드미션 컨트롤러를 수정하거나 간단하게 이를 비활성화 하면 된다. 3. `preferredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 `topologyKey`가 비어있는 경우 이를 "모든 토폴로지"("모든 토폴로지"는 현재 `kubernetes.io/hostname`, `failure-domain.beta.kubernetes.io/zone`, `failure-domain.beta.kubernetes.io/region`로 제한된다)로 해석한다. 4. 위의 경우를 제외하면 `topologyKey`는 어느 규칙에 맞는 레이블-키도 가능하다. -`labelSelector`와 `topologyKey`외에도 `labelSelector`가 매칭되어야 하는 네임스페이스의 `namespaces` 리스트를 선택적으로 지정할 수 있다(이는 `labelSelector`와 `topologyKey`와 같은 개위로 작성되어야 한다). +`labelSelector`와 `topologyKey`외에도 `labelSelector`가 매칭되어야 하는 네임스페이스의 `namespaces` +리스트를 선택적으로 지정할 수 있다(이는 `labelSelector`와 `topologyKey`와 같은 개위로 작성되어야 한다). 생략되어있거나 비어있을 경우 어피니티/안티-어피니티 정의가 있는 파드의 네임스페이스가 기본 값이다. -파드가 노드에 스케쥴되려면 `requiredDuringSchedulingIgnoredDuringExecution` 어피니티 및 안티-어피니티와 관련된 모든 `matchExpressions`를 만족해야 한다. +파드가 노드에 스케쥴되려면 `requiredDuringSchedulingIgnoredDuringExecution` 어피니티 및 안티-어피니티와 +관련된 모든 `matchExpressions`를 만족해야 한다. #### 더 실용적인 유스케이스 -파드간 어피니티와 안티-어피니티는 레플리카셋, 스테이트풀셋, 디플로이먼트 등과 같은 상위 레벨의 컬렉션에 사용될 때 좀 더 유용할 수 있다. -이를 통해 같은 노드에 함께 위치시키는 것과 같이 정의된 토폴로지와 동일한 곳에 함께 위치시키는 워크로드를 쉽게 구성할 수 있다. +파드간 어피니티와 안티-어피니티는 레플리카셋, 스테이트풀셋, 디플로이먼트 등과 같은 +상위 레벨의 컬렉션에 사용될 때 좀 더 유용할 수 있다. 이를 통해 같은 노드에 함께 위치시키는 것과 같이 +정의된 토폴로지와 동일한 곳에 함께 위치시키는 워크로드를 쉽게 구성할 수 있다. ##### 항상 같은 노드에 위치시키기 @@ -279,7 +315,6 @@ spec: 위의 두 디플로이먼트를 생성하면 세개의 노드를 가진 클러스터는 다음과 같이 보일 것이다. - | node-1 | node-2 | node-3 | |:--------------------:|:-------------------:|:------------------:| | *webserver-1* | *webserver-2* | *webserver-3* | @@ -303,20 +338,29 @@ web-server-1287567482-s330j 1/1 Running 0 7m 10.192.3 ##### 절대 동일한 노드에 위치시키지 않게 하기 -위의 예시는 `PodAntiAffinity` 규칙을 `topologyKey:"kubernetes.io/hostname"`과 함께 사용하여 redis 클러스터가 하나의 호스트에 두개 이상 위치하지 않도록 배포한다. -[ZooKeeper 튜토리얼](/docs/tutorials/stateful-application/zookeeper/#tolerating-node-failure)을 통해 같은 방법을 사용하여 스테이트풀셋을 고가용성을 위해 안티-어피니티 설정을 한 예시를 확인할 수 있다. +위의 예시는 `PodAntiAffinity` 규칙을 `topologyKey:"kubernetes.io/hostname"`과 함께 사용하여 +redis 클러스터가 하나의 호스트에 두개 이상 위치하지 않도록 배포한다. +[ZooKeeper 튜토리얼](/docs/tutorials/stateful-application/zookeeper/#tolerating-node-failure)을 통해 +같은 방법을 사용하여 스테이트풀셋을 고가용성을 위해 안티-어피니티 설정을 한 예시를 확인할 수 있다. ## nodeName -`nodeName` 노드 셀렉션을 하는 가장 간단한 형태이지만 자체의 한계때문에 일반적으로 사용하지는 않는다. -`nodeName`은 파드 스펙의 필드이다. 비어있지 않다면 스케쥴러는 이 파트를 무시하게 되고 해당되는 노드에서 동작중인 kubelet이 파드를 실행하려 할 것이다. -따라서 `nodeName`이 파드 스펙에 제공되면 노드 셀렉션에 대한 위의 방법들 중 가장 우선시된다. +`nodeName` 노드 셀렉션을 하는 가장 간단한 형태이지만 +자체의 한계때문에 일반적으로 사용하지는 않는다. +`nodeName`은 파드 스펙의 필드이다. 비어있지 않다면 스케쥴러는 +이 파트를 무시하게 되고 해당되는 노드에서 동작중인 kubelet이 +파드를 실행하려 할 것이다. 따라서 `nodeName`이 파드 스펙에 +제공되면 노드 셀렉션에 대한 위의 방법들 중 가장 우선시된다. `nodeName`으로 노드를 선택하는 것의 제약사항이 몇가지 있다: -- 그 이름을 가진 노드가 없을 경우 파드는 실행되지 않을 것이고 몇몇 경우에는 자동으로 삭제된다. -- 그 이름을 가진 노드가 파드를 실행하기 위한 충분한 리소스가 없는 경우 파드의 실행은 실패하고 OutOfmemory 또는 OutOfcpu와 같은 이유를 나타낼 것이다. -- 클라우드 환경에서의 노드 이름은 항상 예측이 가능하거나 안정적인 것이 아니다. +- 그 이름을 가진 노드가 없을 경우 파드는 실행되지 않을 것이고 + 몇몇 경우에는 자동으로 삭제된다. +- 그 이름을 가진 노드가 파드를 실행하기 위한 + 충분한 리소스가 없는 경우 파드의 실행은 실패하고 + OutOfmemory 또는 OutOfcpu와 같은 이유를 나타낼 것이다. +- 클라우드 환경에서의 노드 이름은 항상 예측이 가능하거나 + 안정적인 것이 아니다. `nodeName` 필드를 사용한 파드 설정 파일의 예시이다: @@ -340,9 +384,12 @@ spec: [테인트(Taints)](/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)에 대한 디자인 문서는 이 기능들에 대한 추가적인 배경 정보를 포함한다. +[노드 어피니티](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/)는 노드 레벨의 리소스 할당 결정의 일부분이 될 수 있다. +[토폴로지 매니저](/docs/tasks/administer-cluster/topology-manager/)는 +노드 레벨의 리소스 할당 결정의 일부분이 될 수 있다. {{% /capture %}} From c3426bb663ecc173c88f9e2f271d17b9b0711286 Mon Sep 17 00:00:00 2001 From: KimMJ Date: Sun, 2 Feb 2020 04:11:07 +0900 Subject: [PATCH 05/12] =?UTF-8?q?=EB=9D=84=EC=96=B4=EC=93=B0=EA=B8=B0=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../concepts/configuration/assign-pod-node.md | 162 +++++++++--------- 1 file changed, 81 insertions(+), 81 deletions(-) diff --git a/content/ko/docs/concepts/configuration/assign-pod-node.md b/content/ko/docs/concepts/configuration/assign-pod-node.md index 32f25b8558d43..cbc07d76852c7 100644 --- a/content/ko/docs/concepts/configuration/assign-pod-node.md +++ b/content/ko/docs/concepts/configuration/assign-pod-node.md @@ -9,12 +9,12 @@ weight: 30 {{< glossary_tooltip text="파드" term_id="pod" >}}를 특정한 {{< glossary_tooltip text="노드(emf)" term_id="node" >}}에서만 동작하도록 하거나, 특정 노드들을 선호하도록 제한할 수 있다. -이를 수행하는 방법에는 여러가지가 있으며, 권장되는 접근 방식은 모두 +이를 수행하는 방법에는 여러 가지가 있으며, 권장되는 접근 방식은 모두 [레이블 셀렉터(label selector)](/ko/docs/concepts/overview/working-with-objects/labels/)를 사용하여 선택한다. 보통 스케줄러가 자동으로 합리적인 배치를 수행하기에 이런 제약 조건은 필요하지 않지만 (예: 노드들에 걸쳐 파드를 분배하거나, 여유 자원이 부족한 노드에 파드를 배치하는 등) -간혹 파드가 착츅하는 노드에 대해 더 많은 제어를 원할 수 있는 상황이 있다. -예를 들어 SSD가 장착되어 있는 머신에 파드가 연결되도록 하거나 또는 동일한 가용성 영역(availability zone)에서 +간혹 파드가 착륙하는 노드에 대해 더 많은 제어를 원할 수 있는 상황이 있다. +예를 들어 SSD가 장착된 머신에 파드가 연결되도록 하거나 또는 동일한 가용성 영역(availability zone)에서 많은 것을 통신하는 두 개의 서로 다른 서비스의 파드를 같이 배치할 수 있다. {{% /capture %}} @@ -36,13 +36,13 @@ weight: 30 ### 1 단계: 노드에 레이블 붙이기 -`kubectl get nodes` 를 실행해서 클러스터 노드 이름을 가져온다. 이 중에 레이블을 추가하기 원하는 것 하나를 선택한 다음에 `kubectl label nodes <노드 이름> <레이블 키>=<레이블 값>` 을 실행해서 선택한 노드에 레이블을 추가 한다. 예를 들어 노드의 이름이 'kubernetes-foo-node-1.c.a-robinson.internal' 이고, 원하는 레이블이 'disktype=ssd' 라면, `kubectl label nodes ubernetes-foo-node-1.c.a-robinson.internal disktype=ssd` 를 실행 한다. +`kubectl get nodes` 를 실행해서 클러스터 노드 이름을 가져온다. 이 중에 레이블을 추가하기 원하는 것 하나를 선택한 다음에 `kubectl label nodes <노드 이름> <레이블 키>=<레이블 값>` 을 실행해서 선택한 노드에 레이블을 추가한다. 예를 들어 노드의 이름이 'kubernetes-foo-node-1.c.a-robinson.internal' 이고, 원하는 레이블이 'disktype=ssd' 라면, `kubectl label nodes ubernetes-foo-node-1.c.a-robinson.internal disktype=ssd` 를 실행한다. `kubectl get nodes --show-labels` 를 다시 실행해서 노드가 현재 가진 레이블을 확인하여, 이 작업을 검증할 수 있다. 또한 `kubectl describe node "노드 이름"` 을 사용해서 노드에 주어진 레이블의 전체 목록을 확인할 수 있다. ### 2 단계: 파드 설정에 nodeSelector 필드 추가하기 -실행하고자 하는 파드의 설정 파일을 가져오고, 이와 같이 nodeSelector 섹션을 추가한다. 예를 들어 이것이 파드 설정이라면: +실행하고자 하는 파드의 설정 파일을 가져오고, 이처럼 nodeSelector 섹션을 추가한다. 예를 들어 이것이 파드 설정이라면: ```yaml apiVersion: v1 @@ -97,25 +97,25 @@ spec: `NodeRestriction` 어드미션 플러그인은 kubelet이 `node-restriction.kubernetes.io/` 접두사로 레이블을 설정 또는 수정하지 못하게 한다. 노드 격리에 해당 레이블 접두사를 사용하려면 다음과 같이 한다. -1. [노드 권한부여자](/docs/reference/access-authn-authz/node/)를 사용하고 있고, [NodeRestriction 어드미션 플러그인](/docs/reference/access-authn-authz/admission-controllers/#noderestriction)을 _활성화_ 해야한다. +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` 는 파드를 특정 레이블이 있는 도느로 제한하는 매우 간단한 방법을 제공한다. +`nodeSelector` 는 파드를 특정 레이블이 있는 노드로 제한하는 매우 간단한 방법을 제공한다. 어피니티/안티-어피니티 기능은 표현할 수 있는 제약 종류를 크게 확장한다. 주요 개선 사항은 다음과 같다. 1. 언어가 보다 표현적이다("AND 또는 정확한 일치" 만이 아니다). -2. 규칙이 엄격한 요구사항이 아니라 "유연한(soft)"/"선호(preference)" 규칙을 나타낼 수 있기에 스케줄러가 규칙을 만족할 수 없다면, +2. 규칙이 엄격한 요구 사항이 아니라 "유연한(soft)"/"선호(preference)" 규칙을 나타낼 수 있기에 스케줄러가 규칙을 만족할 수 없다면, 파드는 계속 스케줄 되도록 한다. -3. 노드 자체에 레이블을 붙이기 보다는 노드(또는 다른 토폴로지 도메인)에서 실행중인 다른 파드의 레이블을 제한할 수 있다. +3. 노드 자체에 레이블을 붙이기보다는 노드(또는 다른 토폴로지 도메인)에서 실행 중인 다른 파드의 레이블을 제한할 수 있다. 이를 통해 어떤 파드가 함께 위치할 수 있는지와 없는지에 대한 규칙을 적용할 수 있다. 어피니티 기능은 "노드 어피니티" 와 "파드 간 어피니티/안티-어피니티" 두 종류의 어피니티로 구성된다. -노드 어피니티는 기존 `nodeSelector` 와 비슷하지만(그러나 위에서 나열된 첫 째와 두번째 이점이 있다.), +노드 어피니티는 기존 `nodeSelector` 와 비슷하지만(그러나 위에서 나열된 첫째와 두 번째 이점이 있다.), 파드 간 어피니티/안티-어피니티는 위에서 나열된 세번째 항목에 설명된 대로 -노드 레이블이 아닌 파드 레이블에 대해 제한되고 위에서 나열된 첫번째와 두번째 속성을 가진다. +노드 레이블이 아닌 파드 레이블에 대해 제한되고 위에서 나열된 첫 번째와 두 번째 속성을 가진다. ### 노드 어피니티 @@ -149,98 +149,98 @@ spec: 특정 노드에서 파드를 쫓아내는 [노드 테인트(taint)](/docs/concepts/configuration/taint-and-toleration/)를 할 수 있다. `nodeSelector` 와 `nodeAffinity` 를 모두 지정한다면 파드가 후보 노드에 스케줄 되기 위해서는 -*둘 다* 반드시 만족해야한다. +*둘 다* 반드시 만족해야 한다. -`nodeAffinity` 유형과 연관된 `nodeSelectorTerms` 를 지정하면, 파드를 `nodeSelectorTerms` 가 지정된 것 중 **하 가지**라도 만족하는 노드에 스케줄 할 수 있다. +`nodeAffinity` 유형과 연관된 `nodeSelectorTerms` 를 지정하면, 파드를 `nodeSelectorTerms` 가 지정된 것 중 **한 가지**라도 만족하는 노드에 스케줄할 수 있다. `nodeSelectorTerms` 와 연관된 여러 `matchExpressions` 를 지정하면, 파드는 `matchExpressions` 를 **모두** 만족하는 노드에만 스케줄할 수 있다. -파드가 스케줄된 노드의 레이블을 지우거나 변경해도 파드는 제거되지 않는다. 다시 말해서 어피니티 선택은 파드를 스케줄링 하는 시점에만 작동한다. +파드가 스케줄 된 노드의 레이블을 지우거나 변경해도 파드는 제거되지 않는다. 다시 말해서 어피니티 선택은 파드를 스케줄링 하는 시점에만 작동한다. -`preferredDuringSchedulingIgnoredDuringExecution` 의 `weight` 필드의 범위는 1-100 이다. 모든 스케줄링 요구사항 (리소스 요청, RequiredDuringScheduling 어피니티 표현식 등)을 만족하는 각 노드들에 대해 스케줄러는 이 필드의 요소들을 반복해서 합계를 계산하고 노드가 MatchExpressions 에 일치하는 경우 합계에 "가중치(weight)"를 추가 한다. 이후에 이 점수는 노드에 대한 다른 우선순위 함수의 점수와 합쳐진다. 전체 점수가 가장 높은 노드를 가장 선호한다. +`preferredDuringSchedulingIgnoredDuringExecution` 의 `weight` 필드의 범위는 1-100이다. 모든 스케줄링 요구 사항 (리소스 요청, RequiredDuringScheduling 어피니티 표현식 등)을 만족하는 각 노드들에 대해 스케줄러는 이 필드의 요소들을 반복해서 합계를 계산하고 노드가 MatchExpressions 에 일치하는 경우 합계에 "가중치(weight)"를 추가한다. 이후에 이 점수는 노드에 대한 다른 우선순위 함수의 점수와 합쳐진다. 전체 점수가 가장 높은 노드를 가장 선호한다. ### 파드간 어피니티와 안티-어피니티 -파드간 어피니티와 안티-어피니티는 파드를 노드의 레이블이 아니라 *노드에서 이미 동작 중인 파드들의 레이블을 기반으로* -동작할 수 있는 노드를 선택하게 할 수 있다. 이 규칙은 "이 파드는 반드시 Y 규칙을 만족하는 파드가 하나 이상 -동작중인 X에서만 동작할 수 있도록(안티-어피니티의 경우, 동작할수 없도록) 한다"는 형태로 구성되어있다. Y는 -네임스페이스와 관련된 선택적 목록을 가진 LabelSelector로 표현된다; 노드와는 다르게 파드는 네임스페이스 -기반(이는 파드의 레이블이 네임스페이스 기반임을 내포한다)이고 파트 레이블에 대한 레이블 셀렉터는 반드시 -셀렉터가 어느 네임스페이스에 적용되어야 하는지 지정해 주어야 하기 때문이다. 개념적으로 X는 노드, 랙, -클라우드 제공자 영역, 클라우드 제공자 리젼 등과 같은 토폴로지 도메인이다. 시스템이 사용하는 토폴로지 -도메인을 의미하는 노드 레이블의 키인 `topologyKey`를 사용하여 토폴로지 도메인을 표현할 수 있으며, +파드간 어피니티와 안티-어피니티는 파드를 노드의 레이블이 아니라 *노드에서 이미 동작 중인 파드들의 레이블을 기반으로* +동작할 수 있는 노드를 선택하게 할 수 있다. 이 규칙은 "이 파드는 반드시 Y 규칙을 만족하는 파드가 하나 이상 +동작 중인 X에서만 동작할 수 있도록(안티-어피니티의 경우, 동작할 수 없도록) 한다"는 형태로 구성되어 있다. Y는 +네임스페이스와 관련된 선택적 목록을 가진 LabelSelector로 표현된다; 노드와는 다르게 파드는 네임스페이스 +기반(이는 파드의 레이블이 네임스페이스 기반임을 내포한다)이고 파트 레이블에 대한 레이블 셀렉터는 반드시 +셀렉터가 어느 네임스페이스에 적용되어야 하는지 지정해 주어야 하기 때문이다. 개념적으로 X는 노드, 랙, +클라우드 제공자 영역, 클라우드 제공자 리젼 등과 같은 토폴로지 도메인이다. 시스템이 사용하는 토폴로지 +도메인을 의미하는 노드 레이블의 키인 `topologyKey` 를 사용하여 토폴로지 도메인을 표현할 수 있으며, 예시는 [넘어가기 전에: 빌트인 노드 레이블](#built-in-node-labels) 섹션에 나열된 레이블 키를 보면 된다. {{< note >}} -파드간 어피니티와 안티-어피니티는 상당한 양의 연산을 필요로 하여 -큰 클러스터에서는 스케쥴링을 상당히 느리게 할 수 있다. -수백개의 노드가 넘는 클러스터에서 이를 사용하는 것은 추천하지 않는다. +파드간 어피니티와 안티-어피니티는 상당한 양의 연산을 필요로 하여 +큰 클러스터에서는 스케줄링을 상당히 느리게 할 수 있다. +수백 개의 노드가 넘는 클러스터에서 이를 사용하는 것은 추천하지 않는다. {{< /note >}} {{< note >}} -파드 안티-어피니티는 노드가 일관적으로 레이블을 가지고 있어야 함을 전제로 한다. 예를들어 클러스터의 모든 노드는 `topologyKey`와 매칭되는 적절한 레이블을 가지고 있어야 한다. 일부 또는 모든 노드가 지정된 `topologyKey` 레이블이 없다면 이는 의도치 않은 동작을 일으킬 수 있다. +파드 안티-어피니티는 노드가 일관적으로 레이블을 가지고 있어야 함을 전제로 한다. 예를 들어 클러스터의 모든 노드는 `topologyKey` 와 매칭되는 적절한 레이블을 가지고 있어야 한다. 일부 또는 모든 노드가 지정된 `topologyKey` 레이블이 없다면 이는 의도치 않은 동작을 일으킬 수 있다. {{< /note >}} -노드 어피니티처럼 현재 각각 "엄격한"과 "유연한" 제약사항을 나타내는 `requiredDuringSchedulingIgnoredDuringExecution`와 -`preferredDuringSchedulingIgnoredDuringExecution`라고 하는 파드 어피니티와 안티 어피니티 두가지 종류가 있다. -앞선 노드 어피니티 섹션의 설명을 보면 된다. -`requiredDuringSchedulingIgnoredDuringExecution` 어피니티의 예시는 -"서비스 A와 서비스 B는 서로 많은 통신을 하기 때문에 각 서비스의 파드들을 동일한 영역에 위치시킨다."이고 +노드 어피니티처럼 현재 각각 "엄격한"과 "유연한" 제약사항을 나타내는 `requiredDuringSchedulingIgnoredDuringExecution` 와 +`preferredDuringSchedulingIgnoredDuringExecution` 라고 하는 파드 어피니티와 안티 어피니티 두 가지 종류가 있다. +앞선 노드 어피니티 섹션의 설명을 보면 된다. +`requiredDuringSchedulingIgnoredDuringExecution` 어피니티의 예시는 +"서비스 A와 서비스 B는 서로 많은 통신을 하기 때문에 각 서비스의 파드들을 동일한 영역에 위치시킨다."이고 `preferredDuringSchedulingIgnoredDuringExecution` 안티 어피니티의 예시는 "서비스를 여러 영역에 걸처 퍼트린다"가 될 것이다 (엄격한 제약조건은 파드가 영역의 수보다 많을 수 있기 때문에 말이 안된다). -파드간 어피니티는 파드 스펙에서 `affinity` 필드의 `podAffinity` 필드에서 지정할 수 있다. +파드간 어피니티는 파드 스펙에서 `affinity` 필드의 `podAffinity` 필드에서 지정할 수 있다. 그리고 파드간 안티-어피니티는 파드 스펙에서 `affinity` 필드의 `podAntiAffinity` 필드에서 지정할 수 있다. -#### 파드 어피니티를 사용하는 파드의 예시: +#### 파드 어피니티를 사용하는 파드의 예시 {{< codenew file="pods/pod-with-pod-affinity.yaml" >}} -이 파드에서의 어피니티는 하나의 파드 어피니티 규칙과 하나의 안티-어피니티 규칙을 정의한다. -이 예시에서 `podAffinity`는 `requiredDuringSchedulingIgnoredDuringExecution`이고 `podAntiAffinity`는 -`preferredDuringSchedulingIgnoredDuringExecution`이다. 파드 어피니티 규칙은 "security"를 키로하고 - "S1"을 값으로 하는 레이블을 가진 파드가 최소한 하나라도 동작 중인 한 노드에서만 스케쥴될 수 있다고 말하고 있다. -(더 정확하게는 파드가 `failure-domain.beta.kubernetes.io/zone`를 키로하고 V를 값으로 하는 -클러스터의 노드가 "security"를 키로하고 "S1"을 값으로 하는 레이블을 가진 파드를 동작시키고 있는 것과 같이 -노드 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`의 +이 파드에서의 어피니티는 하나의 파드 어피니티 규칙과 하나의 안티-어피니티 규칙을 정의한다. +이 예시에서 `podAffinity` 는 `requiredDuringSchedulingIgnoredDuringExecution` 이고 `podAntiAffinity` 는 +`preferredDuringSchedulingIgnoredDuringExecution` 이다. 파드 어피니티 규칙은 "security"를 키로 하고 + "S1"을 값으로 하는 레이블을 가진 파드가 최소한 하나라도 동작 중인 한 노드에서만 스케줄 될 수 있다고 말하고 있다. +(더 정확하게는 파드가 `failure-domain.beta.kubernetes.io/zone` 를 키로 하고 V를 값으로 하는 +클러스터의 노드가 "security"를 키로하고 "S1"을 값으로 하는 레이블을 가진 파드를 동작시키고 있는 것과 같이 +노드 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`가 있다. +파드 어피니티와 안티-어피니티에 대해 허용된 연산자는 `In`, `NotIn`, `Exists`, `DoesNotExist` 가 있다. -원칙적으로 `topologyKey`는 어느 규칙에 맞는 레이블-키도 될 수 있다. -하지만 성능과 보안상의 이유로 토폴로지 키에는 몇가지 제약사항이 있다: +원칙적으로 `topologyKey` 는 어느 규칙에 맞는 레이블-키도 될 수 있다. +하지만 성능과 보안상의 이유로 토폴로지 키에는 몇 가지 제약사항이 있다: -1. 어피니티와 `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 -`topologyKey`가 비어있는 것은 허용하지 않는다. -2. `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 어드미션 컨트롤러의 `LimitPodHardAntiAffinityTopology`는 `topologyKey`를 `kubernetes.io/hostname`으로 제한하기 위해 도입되었다. 사용자 정의 토폴로지를 이용하고자 할 경우 어드미션 컨트롤러를 수정하거나 간단하게 이를 비활성화 하면 된다. -3. `preferredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 `topologyKey`가 비어있는 경우 이를 "모든 토폴로지"("모든 토폴로지"는 현재 `kubernetes.io/hostname`, `failure-domain.beta.kubernetes.io/zone`, `failure-domain.beta.kubernetes.io/region`로 제한된다)로 해석한다. -4. 위의 경우를 제외하면 `topologyKey`는 어느 규칙에 맞는 레이블-키도 가능하다. +1. 어피니티와 `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 +`topologyKey` 가 비어있는 것은 허용하지 않는다. +2. `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 어드미션 컨트롤러의 `LimitPodHardAntiAffinityTopology` 는 `topologyKey` 를 `kubernetes.io/hostname` 으로 제한하기 위해 도입되었다. 사용자 정의 토폴로지를 이용하고자 할 경우 어드미션 컨트롤러를 수정하거나 간단하게 이를 비활성화하면 된다. +3. `preferredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 `topologyKey` 가 비어있는 경우 이를 "모든 토폴로지"("모든 토폴로지"는 현재 `kubernetes.io/hostname`, `failure-domain.beta.kubernetes.io/zone`, `failure-domain.beta.kubernetes.io/region`로 제한된다)로 해석한다. +4. 위의 경우를 제외하면 `topologyKey` 는 어느 규칙에 맞는 레이블-키도 가능하다. -`labelSelector`와 `topologyKey`외에도 `labelSelector`가 매칭되어야 하는 네임스페이스의 `namespaces` -리스트를 선택적으로 지정할 수 있다(이는 `labelSelector`와 `topologyKey`와 같은 개위로 작성되어야 한다). +`labelSelector` 와 `topologyKey` 외에도 `labelSelector` 가 매칭되어야 하는 네임스페이스의 `namespaces` +리스트를 선택적으로 지정할 수 있다(이는 `labelSelector` 와 `topologyKey` 와 같은 개위로 작성되어야 한다). 생략되어있거나 비어있을 경우 어피니티/안티-어피니티 정의가 있는 파드의 네임스페이스가 기본 값이다. -파드가 노드에 스케쥴되려면 `requiredDuringSchedulingIgnoredDuringExecution` 어피니티 및 안티-어피니티와 -관련된 모든 `matchExpressions`를 만족해야 한다. +파드가 노드에 스케줄 되려면 `requiredDuringSchedulingIgnoredDuringExecution` 어피니티 및 안티-어피니티와 +관련된 모든 `matchExpressions` 를 만족해야 한다. #### 더 실용적인 유스케이스 -파드간 어피니티와 안티-어피니티는 레플리카셋, 스테이트풀셋, 디플로이먼트 등과 같은 -상위 레벨의 컬렉션에 사용될 때 좀 더 유용할 수 있다. 이를 통해 같은 노드에 함께 위치시키는 것과 같이 +파드간 어피니티와 안티-어피니티는 레플리카셋, 스테이트풀셋, 디플로이먼트 등과 같은 +상위 레벨의 컬렉션에 사용될 때 좀 더 유용할 수 있다. 이를 통해 같은 노드에 함께 위치시키는 것과 같이 정의된 토폴로지와 동일한 곳에 함께 위치시키는 워크로드를 쉽게 구성할 수 있다. ##### 항상 같은 노드에 위치시키기 -세개의 노드를 가진 클러스터가 있는 상황에서 웹 어플리케이션은 redis와 같은 인메모리 캐시를 가지고 있다. 웹 서버를 캐시가 있는 위치와 동일한 곳으로 최대한 많이 위치시키고 싶다. +세 개의 노드를 가진 클러스터가 있는 상황에서 웹 어플리케이션은 redis와 같은 인메모리 캐시를 가지고 있다. 웹 서버를 캐시가 있는 위치와 동일한 곳으로 최대한 많이 위치시키고 싶다. -이 짧은 yaml은 세개의 레플리카를 가지고 `app=store`라는 셀렉터 레이블을 가진 간단한 redis 디플로이먼트이다. 디플로이먼트는 `PodAntiAffinity` 설정이 있어 스케쥴러가 레플리카들을 하나의 노드에만 위치하지 않도록 한다. +이 짧은 yaml은 세 개의 레플리카를 가지고 `app=store` 라는 셀렉터 레이블을 가진 간단한 redis 디플로이먼트이다. 디플로이먼트는 `PodAntiAffinity` 설정이 있어 스케줄러가 레플리카들을 하나의 노드에만 위치하지 않도록 한다. ```yaml apiVersion: apps/v1 @@ -272,7 +272,7 @@ spec: image: redis:3.2-alpine ``` -아래의 짧은 yaml은 웹서버 디플로이먼트가 `podAntiAffinity`와 `podAffinity` 설정을 가진 것이다. 이는 스케쥴러에게 이 레플리카들이 `app=store`라는 셀렉터 레이블을 가진 파드와 함께 위치시키고 싶다는 것을 알려준다. 또한 웹서버 레플리카가 하나의 노드에만 위치하지 않도록 한다. +아래의 짧은 yaml은 웹서버 디플로이먼트가 `podAntiAffinity` 와 `podAffinity` 설정을 가진 것이다. 이는 스케줄러에게 이 레플리카들이 `app=store` 라는 셀렉터 레이블을 가진 파드와 함께 위치시키고 싶다는 것을 알려준다. 또한 웹서버 레플리카가 하나의 노드에만 위치하지 않도록 한다. ```yaml apiVersion: apps/v1 @@ -313,14 +313,14 @@ spec: image: nginx:1.12-alpine ``` -위의 두 디플로이먼트를 생성하면 세개의 노드를 가진 클러스터는 다음과 같이 보일 것이다. +위의 두 디플로이먼트를 생성하면 세 개의 노드를 가진 클러스터는 다음과 같이 보일 것이다. | node-1 | node-2 | node-3 | |:--------------------:|:-------------------:|:------------------:| | *webserver-1* | *webserver-2* | *webserver-3* | | *cache-1* | *cache-2* | *cache-3* | -여기서 볼 수 있듯이 `web-server`의 세 레플리카들이 기대했던 것처럼 알아서 캐시와 함께 위치하게 되었다. +여기서 볼 수 있듯이 `web-server` 의 세 레플리카들이 기대했던 것처럼 알아서 캐시와 함께 위치하게 되었다. ``` kubectl get pods -o wide @@ -338,22 +338,22 @@ web-server-1287567482-s330j 1/1 Running 0 7m 10.192.3 ##### 절대 동일한 노드에 위치시키지 않게 하기 -위의 예시는 `PodAntiAffinity` 규칙을 `topologyKey:"kubernetes.io/hostname"`과 함께 사용하여 -redis 클러스터가 하나의 호스트에 두개 이상 위치하지 않도록 배포한다. -[ZooKeeper 튜토리얼](/docs/tutorials/stateful-application/zookeeper/#tolerating-node-failure)을 통해 +위의 예시는 `PodAntiAffinity` 규칙을 `topologyKey:"kubernetes.io/hostname"` 과 함께 사용하여 +redis 클러스터가 하나의 호스트에 두 개 이상 위치하지 않도록 배포한다. +[ZooKeeper 튜토리얼](/docs/tutorials/stateful-application/zookeeper/#tolerating-node-failure)을 통해 같은 방법을 사용하여 스테이트풀셋을 고가용성을 위해 안티-어피니티 설정을 한 예시를 확인할 수 있다. ## nodeName -`nodeName` 노드 셀렉션을 하는 가장 간단한 형태이지만 -자체의 한계때문에 일반적으로 사용하지는 않는다. -`nodeName`은 파드 스펙의 필드이다. 비어있지 않다면 스케쥴러는 -이 파트를 무시하게 되고 해당되는 노드에서 동작중인 kubelet이 -파드를 실행하려 할 것이다. 따라서 `nodeName`이 파드 스펙에 +`nodeName` 노드 셀렉션을 하는 가장 간단한 형태이지만 +자체의 한계 때문에 일반적으로 사용하지는 않는다. +`nodeName` 은 파드 스펙의 필드이다. 비어있지 않다면 스케줄러는 +이 파트를 무시하게 되고 해당되는 노드에서 동작 중인 kubelet이 +파드를 실행하려 할 것이다. 따라서 `nodeName` 이 파드 스펙에 제공되면 노드 셀렉션에 대한 위의 방법들 중 가장 우선시된다. -`nodeName`으로 노드를 선택하는 것의 제약사항이 몇가지 있다: - +`nodeName` 으로 노드를 선택하는 것의 제약사항이 몇 가지 있다: + - 그 이름을 가진 노드가 없을 경우 파드는 실행되지 않을 것이고 몇몇 경우에는 자동으로 삭제된다. - 그 이름을 가진 노드가 파드를 실행하기 위한 @@ -384,12 +384,12 @@ spec: [테인트(Taints)](/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)에 대한 디자인 문서는 +[노드 어피니티](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/)는 +파드가 노드에 할당되고 나면 kubelet은 파드를 실행하고 노드의 로컬 리소스를 할당한다. +[토폴로지 매니저](/docs/tasks/administer-cluster/topology-manager/)는 노드 레벨의 리소스 할당 결정의 일부분이 될 수 있다. {{% /capture %}} From ff6b72c6c1f589417e93812dd0815e8f9763f3c6 Mon Sep 17 00:00:00 2001 From: KimMJ Date: Sun, 2 Feb 2020 04:28:36 +0900 Subject: [PATCH 06/12] =?UTF-8?q?=EB=9D=BC=EC=9D=B8=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../concepts/configuration/assign-pod-node.md | 48 ++++++++++--------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/content/ko/docs/concepts/configuration/assign-pod-node.md b/content/ko/docs/concepts/configuration/assign-pod-node.md index cbc07d76852c7..7088e8e3e36d3 100644 --- a/content/ko/docs/concepts/configuration/assign-pod-node.md +++ b/content/ko/docs/concepts/configuration/assign-pod-node.md @@ -92,7 +92,8 @@ spec: 노드 오브젝트에 레이블을 추가하면 특정 노드 또는 노드 그룹에 파드를 대상으로 할 수 있다. 이는 특정 파드가 어떤 격리, 보안, 또는 규제 속성이 있는 노드에서만 실행되도록 사용할 수 있다. 이 목적으로 레이블을 사용하는 경우, 노드에서 kubelet 프로세스로 수정할 수 없는 레이블 키를 선택하는 것을 권장한다. -이렇게 하면 손상된 노드가 해당 kubelet 자격 증명을 사용해서 해당 레이블을 자체 노드 오브젝트에 설정하고, 스케줄러가 손상된 노드로 워크로드를 스케줄 하는 것을 방지할 수 있다. +이렇게 하면 손상된 노드가 해당 kubelet 자격 증명을 사용해서 해당 레이블을 자체 노드 오브젝트에 설정하고, +스케줄러가 손상된 노드로 워크로드를 스케줄 하는 것을 방지할 수 있다. `NodeRestriction` 어드미션 플러그인은 kubelet이 `node-restriction.kubernetes.io/` 접두사로 레이블을 설정 또는 수정하지 못하게 한다. 노드 격리에 해당 레이블 접두사를 사용하려면 다음과 같이 한다. @@ -123,11 +124,14 @@ spec: 스케줄할 수 있는 노드를 제한할 수 있다. 여기에 현재 `requiredDuringSchedulingIgnoredDuringExecution` 와 `preferredDuringSchedulingIgnoredDuringExecution` 로 부르는 -두 가지 종류의 노드 어피니티가 있다. 전자는 파드가 노드에 스케줄 되도록 *반드시* 규칙을 만족해야 하는 것(`nodeSelector` 와 같으나 보다 표현적인 구문을 사용해서)을 지정하고, -후자는 스케줄러가 시도하려고는 하지만, 보증하지 않는 *선호(preferences)*를 지정한다는 점에서 이를 각각 "엄격함(hard)" 과 "유연함(soft)" 하다고 생각할 수 있다. +두 가지 종류의 노드 어피니티가 있다. 전자는 파드가 노드에 스케줄 되도록 *반드시* +규칙을 만족해야 하는 것(`nodeSelector` 와 같으나 보다 표현적인 구문을 사용해서)을 지정하고, +후자는 스케줄러가 시도하려고는 하지만, 보증하지 않는 *선호(preferences)*를 지정한다는 점에서 +이를 각각 "엄격함(hard)" 과 "유연함(soft)" 하다고 생각할 수 있다. 이름의 "IgnoredDuringExecution" 부분은 `nodeSelector` 작동 방식과 유사하게 노드의 레이블이 런타임 중에 변경되어 파드의 어피니티 규칙이 더 이상 충족되지 않으면 파드가 여전히 그 노드에서 -동작한다는 의미이다. 향후에는 파드의 노드 어피니티 요구 사항을 충족하지 않는 노드에서 파드를 제거한다는 점을 제외하고는 `preferredDuringSchedulingIgnoredDuringExecution` 와 같은 `requiredDuringSchedulingIgnoredDuringExecution` 를 제공할 계획이다. +동작한다는 의미이다. 향후에는 파드의 노드 어피니티 요구 사항을 충족하지 않는 노드에서 파드를 제거한다는 +점을 제외하고는 `preferredDuringSchedulingIgnoredDuringExecution` 와 같은 `requiredDuringSchedulingIgnoredDuringExecution` 를 제공할 계획이다. 따라서 `requiredDuringSchedulingIgnoredDuringExecution` 의 예로는 "인텔 CPU가 있는 노드에서만 파드 실행"이 될 수 있고, `preferredDuringSchedulingIgnoredDuringExecution` 의 예로는 "장애 조치 영역 XYZ에 파드 집합을 실행하려고 @@ -161,7 +165,7 @@ spec: ### 파드간 어피니티와 안티-어피니티 -파드간 어피니티와 안티-어피니티는 파드를 노드의 레이블이 아니라 *노드에서 이미 동작 중인 파드들의 레이블을 기반으로* +파드간 어피니티와 안티-어피니티는 파드를 노드의 레이블이 아닌 *노드에서 이미 동작 중인 파드들의 레이블을 기반으로* 동작할 수 있는 노드를 선택하게 할 수 있다. 이 규칙은 "이 파드는 반드시 Y 규칙을 만족하는 파드가 하나 이상 동작 중인 X에서만 동작할 수 있도록(안티-어피니티의 경우, 동작할 수 없도록) 한다"는 형태로 구성되어 있다. Y는 네임스페이스와 관련된 선택적 목록을 가진 LabelSelector로 표현된다; 노드와는 다르게 파드는 네임스페이스 @@ -185,12 +189,12 @@ spec: `preferredDuringSchedulingIgnoredDuringExecution` 라고 하는 파드 어피니티와 안티 어피니티 두 가지 종류가 있다. 앞선 노드 어피니티 섹션의 설명을 보면 된다. `requiredDuringSchedulingIgnoredDuringExecution` 어피니티의 예시는 -"서비스 A와 서비스 B는 서로 많은 통신을 하기 때문에 각 서비스의 파드들을 동일한 영역에 위치시킨다."이고 -`preferredDuringSchedulingIgnoredDuringExecution` 안티 어피니티의 예시는 "서비스를 여러 영역에 걸처 퍼트린다"가 될 것이다 +"서비스 A와 서비스 B는 서로 많은 통신을 하기 때문에 각 서비스의 파드들을 동일한 영역에 위치시킨다"고 +`preferredDuringSchedulingIgnoredDuringExecution` 안티 어피니티의 예시는 "서비스를 여러 영역에 걸처 퍼트린다"이다 (엄격한 제약조건은 파드가 영역의 수보다 많을 수 있기 때문에 말이 안된다). -파드간 어피니티는 파드 스펙에서 `affinity` 필드의 `podAffinity` 필드에서 지정할 수 있다. -그리고 파드간 안티-어피니티는 파드 스펙에서 `affinity` 필드의 `podAntiAffinity` 필드에서 지정할 수 있다. +파드간 어피니티는 PodSpec에서 `affinity` 필드의 `podAffinity` 필드에서 지정할 수 있다. +그리고 파드간 안티-어피니티는 PodSpec에서 `affinity` 필드의 `podAntiAffinity` 필드에서 지정할 수 있다. #### 파드 어피니티를 사용하는 파드의 예시 @@ -199,29 +203,29 @@ spec: 이 파드에서의 어피니티는 하나의 파드 어피니티 규칙과 하나의 안티-어피니티 규칙을 정의한다. 이 예시에서 `podAffinity` 는 `requiredDuringSchedulingIgnoredDuringExecution` 이고 `podAntiAffinity` 는 `preferredDuringSchedulingIgnoredDuringExecution` 이다. 파드 어피니티 규칙은 "security"를 키로 하고 - "S1"을 값으로 하는 레이블을 가진 파드가 최소한 하나라도 동작 중인 한 노드에서만 스케줄 될 수 있다고 말하고 있다. + "S1"을 값으로 하는 레이블을 가진 파드가 최소한 하나라도 동작 중인 한 노드에서만 스케줄 될 수 있다고 말하고 있다 (더 정확하게는 파드가 `failure-domain.beta.kubernetes.io/zone` 를 키로 하고 V를 값으로 하는 클러스터의 노드가 "security"를 키로하고 "S1"을 값으로 하는 레이블을 가진 파드를 동작시키고 있는 것과 같이 -노드 N이 `failure-domain.beta.kubernetes.io/zone` 을 키로 하고 어떤 V를 값으로 하는 레이블이 있는 노드 N에 뜨기에 적합하다.) +노드 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` 파드 안티-어피니티에 대해 어드미션 컨트롤러의 `LimitPodHardAntiAffinityTopology` 는 `topologyKey` 를 `kubernetes.io/hostname` 으로 제한하기 위해 도입되었다. 사용자 정의 토폴로지를 이용하고자 할 경우 어드미션 컨트롤러를 수정하거나 간단하게 이를 비활성화하면 된다. 3. `preferredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 `topologyKey` 가 비어있는 경우 이를 "모든 토폴로지"("모든 토폴로지"는 현재 `kubernetes.io/hostname`, `failure-domain.beta.kubernetes.io/zone`, `failure-domain.beta.kubernetes.io/region`로 제한된다)로 해석한다. -4. 위의 경우를 제외하면 `topologyKey` 는 어느 규칙에 맞는 레이블-키도 가능하다. +4. 위의 경우를 제외하면 `topologyKey` 는 규칙에 맞는 어느 레이블-키도 가능하다. `labelSelector` 와 `topologyKey` 외에도 `labelSelector` 가 매칭되어야 하는 네임스페이스의 `namespaces` 리스트를 선택적으로 지정할 수 있다(이는 `labelSelector` 와 `topologyKey` 와 같은 개위로 작성되어야 한다). @@ -240,7 +244,7 @@ spec: 세 개의 노드를 가진 클러스터가 있는 상황에서 웹 어플리케이션은 redis와 같은 인메모리 캐시를 가지고 있다. 웹 서버를 캐시가 있는 위치와 동일한 곳으로 최대한 많이 위치시키고 싶다. -이 짧은 yaml은 세 개의 레플리카를 가지고 `app=store` 라는 셀렉터 레이블을 가진 간단한 redis 디플로이먼트이다. 디플로이먼트는 `PodAntiAffinity` 설정이 있어 스케줄러가 레플리카들을 하나의 노드에만 위치하지 않도록 한다. +이 짧은 yaml은 세 개의 레플리카를 가지고 `app=store` 라는 셀렉터 레이블을 가진 간단한 redis 디플로이먼트이다. 디플로이먼트는 `PodAntiAffinity` 설정이 있어 스케줄러가 레플리카들이 하나의 노드에만 위치하지 않도록 한다. ```yaml apiVersion: apps/v1 @@ -347,12 +351,12 @@ redis 클러스터가 하나의 호스트에 두 개 이상 위치하지 않도 `nodeName` 노드 셀렉션을 하는 가장 간단한 형태이지만 자체의 한계 때문에 일반적으로 사용하지는 않는다. -`nodeName` 은 파드 스펙의 필드이다. 비어있지 않다면 스케줄러는 +`nodeName` 은 PodSpec의 필드이다. 비어있지 않다면 스케줄러는 이 파트를 무시하게 되고 해당되는 노드에서 동작 중인 kubelet이 -파드를 실행하려 할 것이다. 따라서 `nodeName` 이 파드 스펙에 +파드를 실행하려 할 것이다. 따라서 `nodeName` 이 PodSpec에 제공되면 노드 셀렉션에 대한 위의 방법들 중 가장 우선시된다. -`nodeName` 으로 노드를 선택하는 것의 제약사항이 몇 가지 있다: +`nodeName` 으로 노드를 선택하는 것에는 제약사항이 몇 가지 있다. - 그 이름을 가진 노드가 없을 경우 파드는 실행되지 않을 것이고 몇몇 경우에는 자동으로 삭제된다. @@ -362,7 +366,7 @@ redis 클러스터가 하나의 호스트에 두 개 이상 위치하지 않도 - 클라우드 환경에서의 노드 이름은 항상 예측이 가능하거나 안정적인 것이 아니다. -`nodeName` 필드를 사용한 파드 설정 파일의 예시이다: +`nodeName` 필드를 사용한 파드 설정 파일의 예시이다. ```yaml apiVersion: v1 @@ -376,7 +380,7 @@ spec: nodeName: kube-01 ``` -우의 파드는 kube-01 노드에서 동작할 것이다. +위의 파드는 kube-01 노드에서 동작할 것이다. {{% /capture %}} From 6cbd815d5654d76a1f8dcfb45e1c0bb921761110 Mon Sep 17 00:00:00 2001 From: KimMJ Date: Sun, 2 Feb 2020 17:25:58 +0900 Subject: [PATCH 07/12] =?UTF-8?q?commnet=202=EC=B0=A8=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../concepts/configuration/assign-pod-node.md | 152 +++++++++--------- 1 file changed, 76 insertions(+), 76 deletions(-) diff --git a/content/ko/docs/concepts/configuration/assign-pod-node.md b/content/ko/docs/concepts/configuration/assign-pod-node.md index 7088e8e3e36d3..5b8447019d7ec 100644 --- a/content/ko/docs/concepts/configuration/assign-pod-node.md +++ b/content/ko/docs/concepts/configuration/assign-pod-node.md @@ -165,86 +165,86 @@ spec: ### 파드간 어피니티와 안티-어피니티 -파드간 어피니티와 안티-어피니티는 파드를 노드의 레이블이 아닌 *노드에서 이미 동작 중인 파드들의 레이블을 기반으로* -동작할 수 있는 노드를 선택하게 할 수 있다. 이 규칙은 "이 파드는 반드시 Y 규칙을 만족하는 파드가 하나 이상 -동작 중인 X에서만 동작할 수 있도록(안티-어피니티의 경우, 동작할 수 없도록) 한다"는 형태로 구성되어 있다. Y는 -네임스페이스와 관련된 선택적 목록을 가진 LabelSelector로 표현된다; 노드와는 다르게 파드는 네임스페이스 -기반(이는 파드의 레이블이 네임스페이스 기반임을 내포한다)이고 파트 레이블에 대한 레이블 셀렉터는 반드시 -셀렉터가 어느 네임스페이스에 적용되어야 하는지 지정해 주어야 하기 때문이다. 개념적으로 X는 노드, 랙, -클라우드 제공자 영역, 클라우드 제공자 리젼 등과 같은 토폴로지 도메인이다. 시스템이 사용하는 토폴로지 -도메인을 의미하는 노드 레이블의 키인 `topologyKey` 를 사용하여 토폴로지 도메인을 표현할 수 있으며, -예시는 [넘어가기 전에: 빌트인 노드 레이블](#built-in-node-labels) 섹션에 나열된 레이블 키를 보면 된다. +파드간 어피니티와 안티-어피니티를 사용하면 노드의 레이블을 기반으로 하지 않고, *노드에서 이미 실행 중인 파드 레이블을 기반으로* +파드가 스케줄될 수 있는 노드를 제한할 수 있다. 규칙은 "X가 규칙 Y를 충족하는 하나 이상의 파드를 이미 실행중인 경우 +이 파드는 X에서 실행해야한다(또는 안티-어피니티가 없는 경우에는 동작하면 안된다)는 형태이다. Y는 +선택적으로 연관된 네임스페이스 목록을 가진 LabelSelector로 표현된다. 노드와는 다르게 파드는 네임스페이스이기에 +(그리고 따라서 파드의 레이블은 암암리에 네임스페이스이다) 파드 레이블위의 레이블 셀렉터는 반드시 +셀렉터가 적용될 네임스페이스를 지정해야만 한다. 개념적으로 X는 노드, 랙, +클라우드 공급자 영역, 클라우드 공급자 지역 등과 같은 토폴로지 도메인이다. 시스템이 이런 토폴로지 +도메인을 나타내는 데 사용하는 노드 레이블 키인 `topologyKey` 를 사용하여 이를 표현한다. +예: [넘어가기 전에: 빌트인 노드 레이블](#built-in-node-labels) 섹션 위에 나열된 레이블 키를 본다. {{< note >}} -파드간 어피니티와 안티-어피니티는 상당한 양의 연산을 필요로 하여 -큰 클러스터에서는 스케줄링을 상당히 느리게 할 수 있다. -수백 개의 노드가 넘는 클러스터에서 이를 사용하는 것은 추천하지 않는다. +파드간 어피니티와 안티-어피니티에는 상당한 양의 프로세싱이 필요하기에 +대규모 클러스터에서는 스케줄링 속도가 크게 느려질 수 있다. +수백 개의 노드를 넘어가는 클러스터에서 이를 사용하는 것은 추천하지 않는다. {{< /note >}} {{< note >}} -파드 안티-어피니티는 노드가 일관적으로 레이블을 가지고 있어야 함을 전제로 한다. 예를 들어 클러스터의 모든 노드는 `topologyKey` 와 매칭되는 적절한 레이블을 가지고 있어야 한다. 일부 또는 모든 노드가 지정된 `topologyKey` 레이블이 없다면 이는 의도치 않은 동작을 일으킬 수 있다. +파드 안티-어피니티에서는 노드에 일관된 레이블을 지정해야 한다. 즉, 클러스터의 모든 노드는 `topologyKey` 와 매칭되는 적절한 레이블이 가지고 있어야 한다. 일부 또는 모든 노드에 지정된 `topologyKey` 레이블이 없는 경우에는 의도하지 않은 동작을 발생할 수 있다. {{< /note >}} -노드 어피니티처럼 현재 각각 "엄격한"과 "유연한" 제약사항을 나타내는 `requiredDuringSchedulingIgnoredDuringExecution` 와 -`preferredDuringSchedulingIgnoredDuringExecution` 라고 하는 파드 어피니티와 안티 어피니티 두 가지 종류가 있다. -앞선 노드 어피니티 섹션의 설명을 보면 된다. +노드 어피니티와 마찬가지로 현재 파드 어피니티와 안티-어피니티로 부르는 "엄격함" 대 "유연함"의 요구사항을 나타내는 `requiredDuringSchedulingIgnoredDuringExecution` 와 +`preferredDuringSchedulingIgnoredDuringExecution` 두 가지 종류가 있다. +앞의 노드 어피니티 섹션의 설명을 보면 본다. `requiredDuringSchedulingIgnoredDuringExecution` 어피니티의 예시는 -"서비스 A와 서비스 B는 서로 많은 통신을 하기 때문에 각 서비스의 파드들을 동일한 영역에 위치시킨다"고 -`preferredDuringSchedulingIgnoredDuringExecution` 안티 어피니티의 예시는 "서비스를 여러 영역에 걸처 퍼트린다"이다 -(엄격한 제약조건은 파드가 영역의 수보다 많을 수 있기 때문에 말이 안된다). +"서로 많은 통신을 하기 때문에 서비스 A와 서비스 B를 같은 영역에 함께 위치시키는 것"이고, +`preferredDuringSchedulingIgnoredDuringExecution` 안티-어피니티의 예시는 "서비스를 여러 영역에 걸쳐서 분배하는 것"이다 +(엄격한 요구사항은 영역보다 파드가 더 많을 수 있기 때문에 엄격한 요구사항은 의미가 없다). -파드간 어피니티는 PodSpec에서 `affinity` 필드의 `podAffinity` 필드에서 지정할 수 있다. -그리고 파드간 안티-어피니티는 PodSpec에서 `affinity` 필드의 `podAntiAffinity` 필드에서 지정할 수 있다. +파드간 어피니티는 PodSpec에서 `affinity` 필드 중 `podAffinity` 필드로 지정한다. +그리고 파드간 안티-어피니티는 PodSpec에서 `affinity` 필드 중 `podAntiAffinity` 필드로 지정한다. #### 파드 어피니티를 사용하는 파드의 예시 {{< codenew file="pods/pod-with-pod-affinity.yaml" >}} -이 파드에서의 어피니티는 하나의 파드 어피니티 규칙과 하나의 안티-어피니티 규칙을 정의한다. +이 파드의 어피니티는 하나의 파드 어피니티 규칙과 하나의 파드 안티-어피니티 규칙을 정의한다. 이 예시에서 `podAffinity` 는 `requiredDuringSchedulingIgnoredDuringExecution` 이고 `podAntiAffinity` 는 -`preferredDuringSchedulingIgnoredDuringExecution` 이다. 파드 어피니티 규칙은 "security"를 키로 하고 - "S1"을 값으로 하는 레이블을 가진 파드가 최소한 하나라도 동작 중인 한 노드에서만 스케줄 될 수 있다고 말하고 있다 -(더 정확하게는 파드가 `failure-domain.beta.kubernetes.io/zone` 를 키로 하고 V를 값으로 하는 -클러스터의 노드가 "security"를 키로하고 "S1"을 값으로 하는 레이블을 가진 파드를 동작시키고 있는 것과 같이 -노드 N이 `failure-domain.beta.kubernetes.io/zone` 을 키로 하고 어떤 V를 값으로 하는 레이블이 있는 노드 N에 뜨기에 적합하다). -파드 안티-어피니티 규칙은 파드가 "security"를 키로 하고 "S2"를 값으로 하는 레이블을 가진 파드를 -실행시키고 있는 노드일 경우 해당 노드에 스케줄하지 않는 것을 선호한다고 말하고 있다 -(`topologyKey` 가 `failure-domain.beta.kubernetes.io/zone` 라면 이는 스케줄하고자 하는 파드가 -"security"를 키로 하고 "S2"를 값으로하는 레이블을 가진 파드를 실행하고 있는 노드와 -동일한 영역에 있는 노드들에 스케줄될 수 없음을 의미한다). +`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` 가 있다. +파드 어피니티와 안티-어피니티의 적합한 연산자는 `In`, `NotIn`, `Exists`, `DoesNotExist` 이다. -원칙적으로 `topologyKey` 는 규칙에 맞는 어느 레이블-키도 될 수 있다. -하지만 성능과 보안상의 이유로 토폴로지 키에는 몇 가지 제약사항이 있다. +원칙적으로, `topologyKey` 는 적법한 어느 레이블-키도 될 수 있다. +하지만, 성능과 보안상의 이유로 topologyKey에는 몇 가지 제약조건이 있다. -1. 어피니티와 `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 -`topologyKey` 가 비어있는 것은 허용하지 않는다. -2. `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 어드미션 컨트롤러의 `LimitPodHardAntiAffinityTopology` 는 `topologyKey` 를 `kubernetes.io/hostname` 으로 제한하기 위해 도입되었다. 사용자 정의 토폴로지를 이용하고자 할 경우 어드미션 컨트롤러를 수정하거나 간단하게 이를 비활성화하면 된다. -3. `preferredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 `topologyKey` 가 비어있는 경우 이를 "모든 토폴로지"("모든 토폴로지"는 현재 `kubernetes.io/hostname`, `failure-domain.beta.kubernetes.io/zone`, `failure-domain.beta.kubernetes.io/region`로 제한된다)로 해석한다. -4. 위의 경우를 제외하면 `topologyKey` 는 규칙에 맞는 어느 레이블-키도 가능하다. +1. 어피니티와 `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티는 대해 +`topologyKey` 가 비어있는 것을 허용하지 않는다. +2. `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에서 `topologyKey` 를 `kubernetes.io/hostname` 로 제한하기 위해 어드미션 컨트롤러 `LimitPodHardAntiAffinityTopology` 가 도입되었다. 사용자 지정 토폴로지를에 사용할 수 있도록 하려면, 어드미션 컨트롤러를 수정하거나 간단히 이를 비활성화 할 수 있다. +3. `preferredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티는 빈 `topologyKey` 를 "all topology"("all topology"는 현재 `kubernetes.io/hostname`, `failure-domain.beta.kubernetes.io/zone` 그리고 `failure-domain.beta.kubernetes.io/region` 의 조합으로 제한된다). +4. 위의 경우를 제외하고, `topologyKey` 는 적법한 어느 레이블-키도 가능하다. -`labelSelector` 와 `topologyKey` 외에도 `labelSelector` 가 매칭되어야 하는 네임스페이스의 `namespaces` -리스트를 선택적으로 지정할 수 있다(이는 `labelSelector` 와 `topologyKey` 와 같은 개위로 작성되어야 한다). +`labelSelector` 와 `topologyKey` 외에도 `labelSelector` 와 일치해야하는 네임스페이스 목록 `namespaces` 를 +선택적으로 지정할 수 있다(이것은 `labelSelector` 와 `topologyKey` 와 같은 수준의 정의이다). 생략되어있거나 비어있을 경우 어피니티/안티-어피니티 정의가 있는 파드의 네임스페이스가 기본 값이다. -파드가 노드에 스케줄 되려면 `requiredDuringSchedulingIgnoredDuringExecution` 어피니티 및 안티-어피니티와 -관련된 모든 `matchExpressions` 를 만족해야 한다. +파드를 노드에 스케줄하려면 `requiredDuringSchedulingIgnoredDuringExecution` 어피니티와 안티-어피니티와 +연관된 `matchExpressions` 가 모두 충족되어야 한다. #### 더 실용적인 유스케이스 파드간 어피니티와 안티-어피니티는 레플리카셋, 스테이트풀셋, 디플로이먼트 등과 같은 -상위 레벨의 컬렉션에 사용될 때 좀 더 유용할 수 있다. 이를 통해 같은 노드에 함께 위치시키는 것과 같이 -정의된 토폴로지와 동일한 곳에 함께 위치시키는 워크로드를 쉽게 구성할 수 있다. +상위 레벨 모음과 함께 사용할 때 더욱 유용할 수 있다. 워크로드 집합이 동일한 노드와 같이 +동일하게 정의된 토폴로지와 같은 위치에 배치되도록 쉽게 구성할 수 있다. ##### 항상 같은 노드에 위치시키기 -세 개의 노드를 가진 클러스터가 있는 상황에서 웹 어플리케이션은 redis와 같은 인메모리 캐시를 가지고 있다. 웹 서버를 캐시가 있는 위치와 동일한 곳으로 최대한 많이 위치시키고 싶다. +세 개의 노드가 있는 클러스터에서 웹 애플리케이션에는 redis와 같은 인-메모리 캐시가 있다. 웹 서버가 가능한 캐시와 함께 위치하기를 원한다. -이 짧은 yaml은 세 개의 레플리카를 가지고 `app=store` 라는 셀렉터 레이블을 가진 간단한 redis 디플로이먼트이다. 디플로이먼트는 `PodAntiAffinity` 설정이 있어 스케줄러가 레플리카들이 하나의 노드에만 위치하지 않도록 한다. +다음은 세 개의 레플리카와 셀렉터 레이블이 `app=store` 가 있는 간단한 redis 디플로이먼트의 yaml 스니펫이다. 디플로이먼트에는 스케줄러가 단일 노드에서 레플리카를 함꼐 배치하지 않도록 `PodAntiAffinity` 가 구성되어있다. ```yaml apiVersion: apps/v1 @@ -276,7 +276,7 @@ spec: image: redis:3.2-alpine ``` -아래의 짧은 yaml은 웹서버 디플로이먼트가 `podAntiAffinity` 와 `podAffinity` 설정을 가진 것이다. 이는 스케줄러에게 이 레플리카들이 `app=store` 라는 셀렉터 레이블을 가진 파드와 함께 위치시키고 싶다는 것을 알려준다. 또한 웹서버 레플리카가 하나의 노드에만 위치하지 않도록 한다. +아래 yaml 스니펫의 웹서버 디플로이먼트는 `podAntiAffinity` 와 `podAffinity` 설정을 가지고 있다. 이렇게 하면 스케줄러에 모든 레플리카는 셀렉터 레이블이 `app=store` 인 파드와 함꼐 위치해야 한다. 또한 각 웹 서버 레플리카가 단일 노드의 같은 위치에 있지 않도록 한다. ```yaml apiVersion: apps/v1 @@ -317,19 +317,19 @@ spec: image: nginx:1.12-alpine ``` -위의 두 디플로이먼트를 생성하면 세 개의 노드를 가진 클러스터는 다음과 같이 보일 것이다. +만약 위의 두 디플로이먼트를 생성하면 세 개의 노드가 있는 클러스터는 다음과 같아야 한다. | node-1 | node-2 | node-3 | |:--------------------:|:-------------------:|:------------------:| | *webserver-1* | *webserver-2* | *webserver-3* | | *cache-1* | *cache-2* | *cache-3* | -여기서 볼 수 있듯이 `web-server` 의 세 레플리카들이 기대했던 것처럼 알아서 캐시와 함께 위치하게 되었다. +여기서 볼 수 있듯이 `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 @@ -342,31 +342,31 @@ web-server-1287567482-s330j 1/1 Running 0 7m 10.192.3 ##### 절대 동일한 노드에 위치시키지 않게 하기 -위의 예시는 `PodAntiAffinity` 규칙을 `topologyKey:"kubernetes.io/hostname"` 과 함께 사용하여 -redis 클러스터가 하나의 호스트에 두 개 이상 위치하지 않도록 배포한다. -[ZooKeeper 튜토리얼](/docs/tutorials/stateful-application/zookeeper/#tolerating-node-failure)을 통해 -같은 방법을 사용하여 스테이트풀셋을 고가용성을 위해 안티-어피니티 설정을 한 예시를 확인할 수 있다. +위의 예시에서 `topologyKey:"kubernetes.io/hostname"` 과 함께 `PodAntiAffinity` 규칙을 사용해서 +두 개의 인스터스가 동일한 호스트에 있지 않도록 redis 클러스터를 배포한다. +같은 기술을 사용해서 고 가용성을 위해 안티-어피니티로 구성된 스테이트풀셋의 예시는 +[ZooKeeper 튜토리얼](/docs/tutorials/stateful-application/zookeeper/#tolerating-node-failure)을 본다. ## nodeName -`nodeName` 노드 셀렉션을 하는 가장 간단한 형태이지만 -자체의 한계 때문에 일반적으로 사용하지는 않는다. -`nodeName` 은 PodSpec의 필드이다. 비어있지 않다면 스케줄러는 -이 파트를 무시하게 되고 해당되는 노드에서 동작 중인 kubelet이 -파드를 실행하려 할 것이다. 따라서 `nodeName` 이 PodSpec에 -제공되면 노드 셀렉션에 대한 위의 방법들 중 가장 우선시된다. +`nodeName` 은 가장 간단한 형태의 노트 선택 제약 조건이지만, +한계로 인해 일반적으로는 사용하지 않는다. +`nodeName` 은 PodSpec의 필드이다. 만약 비어있지 않으면, 스케줄러는 +파드를 무시하고 명명된 노드에서 실행 중인 kubelet이 +파드를 실행하려고 한다. 따라서 만약 PodSpec에 `nodeName` 가 +제공된 경우, 노드 선텍을 위해 위의 방법보다 우선한다. -`nodeName` 으로 노드를 선택하는 것에는 제약사항이 몇 가지 있다. +`nodeName` 을 사용해서 노드를 선택할 때의 몇 가지 제한은 다음과 같다. -- 그 이름을 가진 노드가 없을 경우 파드는 실행되지 않을 것이고 - 몇몇 경우에는 자동으로 삭제된다. -- 그 이름을 가진 노드가 파드를 실행하기 위한 - 충분한 리소스가 없는 경우 파드의 실행은 실패하고 - OutOfmemory 또는 OutOfcpu와 같은 이유를 나타낼 것이다. -- 클라우드 환경에서의 노드 이름은 항상 예측이 가능하거나 - 안정적인 것이 아니다. +- 만약 명명된 노드가 없으면, 파드가 실행되지 않고 + 따라서 자동으로 삭제될 수 있다. +- 만약 명명된 노드에 파드를 수용할 수 있는 + 리소스가 없는 경우 파드가 실패하고, 그 이유는 다음과 같이 표시된다. + 예: OutOfmemory 또는 OutOfcpu. +- 클라우드 환경의 노드 이름은 항상 예측 가능하거나 + 안정적인 것은 아니다. -`nodeName` 필드를 사용한 파드 설정 파일의 예시이다. +여기에 `nodeName` 필드를 사용하는 파드 설정 파일 예시가 있다. ```yaml apiVersion: v1 @@ -380,7 +380,7 @@ spec: nodeName: kube-01 ``` -위의 파드는 kube-01 노드에서 동작할 것이다. +위 파드는 kube-01 노드에서 실행될 것이다. {{% /capture %}} @@ -389,11 +389,11 @@ spec: [테인트(Taints)](/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)에 대한 디자인 문서는 -이 기능들에 대한 추가적인 배경 정보를 포함한다. +[파드간 어피니티/안티-어피니티](https://git.k8s.io/community/contributors/design-proposals/scheduling/podaffinity.md)에 대한 디자인 문서에는 +이러한 기능에 대한 추가 배경 정보가 있다. -파드가 노드에 할당되고 나면 kubelet은 파드를 실행하고 노드의 로컬 리소스를 할당한다. +파드가 노드에 할당되면 kubelet은 파드를 실행하고 노드의 로컬 리소스를 할당한다. [토폴로지 매니저](/docs/tasks/administer-cluster/topology-manager/)는 -노드 레벨의 리소스 할당 결정의 일부분이 될 수 있다. +노드 수준의 리소스 할당 결정에 참여할 수 있다. {{% /capture %}} From a920f584e6fb8e57da0e445a168156a7d404b2c9 Mon Sep 17 00:00:00 2001 From: KimMJ Date: Fri, 24 Jan 2020 20:30:28 +0900 Subject: [PATCH 08/12] translate assign-pod-node.md --- .../concepts/configuration/assign-pod-node.md | 348 ++++++++++++++++++ content/ko/examples/pods/pod-nginx.yaml | 13 + .../examples/pods/pod-with-node-affinity.yaml | 26 ++ .../examples/pods/pod-with-pod-affinity.yaml | 29 ++ 4 files changed, 416 insertions(+) create mode 100644 content/ko/docs/concepts/configuration/assign-pod-node.md create mode 100644 content/ko/examples/pods/pod-nginx.yaml create mode 100644 content/ko/examples/pods/pod-with-node-affinity.yaml create mode 100644 content/ko/examples/pods/pod-with-pod-affinity.yaml diff --git a/content/ko/docs/concepts/configuration/assign-pod-node.md b/content/ko/docs/concepts/configuration/assign-pod-node.md new file mode 100644 index 0000000000000..4387e832345d6 --- /dev/null +++ b/content/ko/docs/concepts/configuration/assign-pod-node.md @@ -0,0 +1,348 @@ +--- +title: 노드에 파드 할당하기 +content_template: templates/concept +weight: 30 +--- + + +{{% capture overview %}} + +{{< glossary_tooltip text="파드" term_id="pod" >}}를 특정한 {{< glossary_tooltip text="노드" term_id="node" >}}에서만 동작하도록 하거나 특정 노드를 선호하도록 제한할 수 있다. +이를 위해서는 몇가지 방법이 있는데 그 중 하나는 선택 시 [레이블 셀렉터(label selector)](/ko/docs/concepts/overview/working-with-objects/labels/)를 사용하는 것이다. +스케쥴러가 알아서 합리적인 위치를 고르기 때문에 (예를 들어 파드를 노드에 퍼뜨리고, 리소스가 충분하지 않은 노드에는 파드를 위치시키지 않는 것 등) 일반적으로 이러한 제약은 불필요하지만 +파드가 SSD가 달려있는 머신에서 동작하도록 하거나 서로 통신을 많이 하는 두개의 각기 다른 서비스와 연결된 파드가 +동일한 가용성 영역(availability zone)에 위치시켜야 하는 것처럼 +파드가 위치할 노드에 대해 좀 더 제어가 필요한 몇가지 상황들이 있다. + +{{% /capture %}} + +{{% capture body %}} + +## 노드 셀렉터(nodeSelector) + +`nodeSelector`는 가장 간단하고 추천하는 형식의 노드 선택 제약이다. +`nodeSelector`는 파드 스펙의 필드이다. 이는 키-값 쌍의 맵을 지정한다. +파드가 노드에서 동작할 수 있도록 하려면 노드는 반드시 레이블(물론 이는 추가적인 레이블들을 가질 수도 있다)로 지정된 +키-값 쌍들을 모두 가지고 있어야 한다. 일반적인 사용법은 단일 키-값 쌍을 사용하는 것이다. + +`nodeSelector`를 어떻게 사용하는지 예시를 통해 알아보도록 하자. + +### 0 단계: 사전 준비 + +이 예시는 쿠버네티스에 대한 기본적인 이해를 하고 있고 [쿠버네티스 클러스터가 준비](/ko/docs/setup/)되어 있다고 가정한다. + +### 1 단계: 노드에 레이블 붙이기 {#step-one-attach-label-to-the-node} + +`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} + +노드에 [붙인](#step-one-attach-label-to-the-node) 레이블에 추가적으로 이미 만들어진 표준 레이블 모음이 있다. 이런 레이블들은 다음과 같다. + +* [`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) + +노드 오브젝트에 레이블을 추가하는 것은 파드가 특정한 노드들이나 노드 그룹들을 목표 대상으로 할 수 있도록 한다. +이는 특정한 파드가 어떤 격리, 보안, 규제 속성들을 가진 노드에서만 동작할 수 있도록 한다. +이는 compromised node들이 kubelet 자격증명(credential)을 사용하여 노드 오브젝트 자체에 레이블을 설정하지 않도록 하며 스케쥴러가 compromised node에 워크로드를 스케쥴하는 데 영향을 주지 않도록 한다. + +`NodeRestriction` 어드미션 플러그인은 kubelet이 레이블을 `node-restriction.kubernetes.io/` 접두사로 수정하거나 설정하는 것을 방지한다. 노드 격리를 위해 그 레이블 접두사를 사용하도록 하려면 다음과 같이 하면 된다: + +1. [Node authorizer](/docs/reference/access-authn-authz/node/)를 사용하고 있고 [NodeRestriction admission plugin](/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`와 비슷한 것(그러나 위의 리스트에서 말한 것 중 처음 두가지 이점을 가졌다)이고, +파드간 어피니티/안티-어피니티는 위 리스트의 3번째 리스트에서 설명한 것처럼 +노드 레이블이 아니라 파드의 레이블에 대해서 제약을 둘 수 있으면서 첫번째와 두번째 속성또한 가졌다. + +### 노드 어피니티 + +노드 어피니티는 개념적으로 `nodeSelector`와 비슷하다 -- 이는 노드에 달린 레이블을 기반으로 파드가 특정한 노드로 스케쥴이 가능하도록 제약을 줄 수 있다. + +`requiredDuringSchedulingIgnoredDuringExecution`과 `preferredDuringSchedulingIgnoredDuringExecution` 두가지 종류의 노드 어피니티가 있다. +전자는 파드가 노드에 스케쥴될 때 (`nodeSelector`와 비슷하지만 좀 더 표현이 풍부한 문법이다) 규칙을 *반드시* 만족해야 하는 것이고, 후자는 스케쥴러가 규칙을 지키려고 시도하겠지만 만족한다는 것을 보장하지는 않는, 규칙을 *선호*한다는 관점에서 이를 각각 "엄격한" 그리고 "유연한" 조건이라고 생각할 수 있다. +위의 이름에서 "IgnoredDuringExecution"라고 적혀있는 부분은 `nodeSelector`가 동작하는 방식과 비슷하게 노드의 레이블이 런타임에 변경될 경우 파드에 설정된 어피니티 규칙이 더이상 만족하지 않는 경우에도 파드가 여전히 그 노드에서 동작한다는 의미이다. +후에 `requiredDuringSchedulingRequiredDuringExecution` 설정을 제공하여 `requiredDuringSchedulingIgnoredDuringExecution` 처럼 동작하지만 파드가 동작하고 있는 노드가 더 이상 파드의 노드 어피니티 요구사항을 만족하지 않는 경우에 파드를 축출하는 것을 계획하고 있다. + +따라서 `requiredDuringSchedulingIgnoredDuringExecution`의 예시는 "인텔 CPU가 있는 노드에서만 파드를 동작시키겠다"가 될 수 있으며 +`preferredDuringSchedulingIgnoredDuringExecution`의 예시는 "XYZ 영역에 파드 세트를 동작시키려고 시도하지만 가능하지 않은 경우 다른곳에서 동작하는 것을 허용한다"가 되겠다. + +노드 어피니티는 파드 스펙에서 `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`를 사용하여 안티-어피니티 동작을 할 수 있고 [노드 테인트(node taints)](/docs/concepts/configuration/taint-and-toleration/) 사용하여 특정한 노드에서 파드를 쫓아낼 수 있다. + +`nodeSelector`와 `nodeAffinity`를 모두 지정한다면 파드가 후보 노드에 스케쥴 되기 위해서는 *둘 다* 반드시 만족해야한다. + +여러개의 `nodeAffinity` 타입과 관련하여 `nodeSelectorTerms`를 지정하면 파드는 `nodeSelectorTerms` 중에서 **하나라도 만족**하는 노드에 스케쥴될 수 있다. + +`nodeSelectorTerms`와 관련된 `matchExpressions`를 여러개 지정하면 파드는 `matchExpressions`가 **모두 만족**하는 노드에만 스케쥴될 수 있다. + +파드가 스케쥴된 노드의 레이블을 지우거나 변경해도 파드는 삭제되지 않는다. 다시 말해, 어피니티 선택은 파드가 스케쥴링 되는 시점에만 작동한다. + +`preferredDuringSchedulingIgnoredDuringExecution`에서 `weight` 필드는 1-100까지의 범위를 가진다. +모든 스케쥴링 요구사항 (리소스 요청, RequiredDuringScheduling 어피니티 표현식 등)을 만족하는 각 노드들에 대해서 스케쥴러는 이 필드를 순회하며 노드가 MatchExpressions에 적합할 때 "weight"를 누적 합계에 추가하여 총합을 계산할 것이다. +이 점수는 노드에 대해 다른 우선순위 함수의 점수들과 합쳐진다. 가장 높은 점수를 가진 노드를 가장 선호하게 된다. + +### 파드간 어피니티와 안티-어피니티 + +파드간 어피니티와 안티-어피니티는 파드를 노드의 레이블이 아니라 *노드에서 이미 동작 중인 파드들의 레이블을 기반으로* 동작할 수 있는 노드를 선택하게 할 수 있다. +이 규칙은 "이 파드는 반드시 Y 규칙을 만족하는 파드가 하나 이상 동작중인 X에서만 동작할 수 있도록(안티-어피니티의 경우, 동작할수 없도록) 한다"는 형태로 구성되어있다. +Y는 네임스페이스와 관련된 선택적 목록을 가진 LabelSelector로 표현된다; 노드와는 다르게 파드는 네임스페이스 기반(이는 파드의 레이블이 네임스페이스 기반임을 내포한다)이고 파트 레이블에 대한 레이블 셀렉터는 반드시 셀렉터가 어느 네임스페이스에 적용되어야 하는지 지정해 주어야 하기 때문이다. +개념적으로 X는 노드, 랙, 클라우드 제공자 영역, 클라우드 제공자 리젼 등과 같은 토폴로지 도메인이다. 시스템이 사용하는 토폴로지 도메인을 의미하는 노드 레이블의 키인 `topologyKey`를 사용하여 토폴로지 도메인을 표현할 수 있으며, 예시는 [넘어가기 전에: 빌트인 노드 레이블](#built-in-node-labels) 섹션에 나열된 레이블 키를 보면 된다. + +{{< note >}} +파드간 어피니티와 안티-어피니티는 상당한 양의 연산을 필요로 하여 큰 클러스터에서는 스케쥴링을 상당히 느리게 할 수 있다. +수백개의 노드가 넘는 클러스터에서 이를 사용하는 것은 추천하지 않는다. +{{< /note >}} + +{{< note >}} +파드 안티-어피니티는 노드가 일관적으로 레이블을 가지고 있어야 함을 전제로 한다. 예를들어 클러스터의 모든 노드는 `topologyKey`와 매칭되는 적절한 레이블을 가지고 있어야 한다. 일부 또는 모든 노드가 지정된 `topologyKey` 레이블이 없다면 이는 의도치 않은 동작을 일으킬 수 있다. +{{< /note >}} + +노드 어피니티처럼 현재 각각 "엄격한"과 "유연한" 제약사항을 나타내는 `requiredDuringSchedulingIgnoredDuringExecution`와 `preferredDuringSchedulingIgnoredDuringExecution`라고 하는 파드 어피니티와 안티 어피니티 두가지 종류가 있다. +앞선 노드 어피니티 섹션의 설명을 보면 된다. +`requiredDuringSchedulingIgnoredDuringExecution` 어피니티의 예시는 "서비스 A와 서비스 B는 서로 많은 통신을 하기 때문에 각 서비스의 파드들을 동일한 영역에 위치시킨다."이고 `preferredDuringSchedulingIgnoredDuringExecution` 안티 어피니티의 예시는 "서비스를 여러 영역에 걸처 퍼트린다"가 될 것이다 +(엄격한 제약조건은 파드가 영역의 수보다 많을 수 있기 때문에 말이 안된다). + +파드간 어피니티는 파드 스펙에서 `affinity` 필드의 `podAffinity` 필드에서 지정할 수 있다. 그리고 파드간 안티-어피니티는 파드 스펙에서 `affinity` 필드의 `podAntiAffinity` 필드에서 지정할 수 있다. + +#### 파드 어피니티를 사용하는 파드의 예시: + +{{< codenew file="pods/pod-with-pod-affinity.yaml" >}} + +이 파드에서의 어피니티는 하나의 파드 어피니티 규칙과 하나의 안티-어피니티 규칙을 정의한다. 이 예시에서 `podAffinity`는 `requiredDuringSchedulingIgnoredDuringExecution`이고 `podAntiAffinity`는 `preferredDuringSchedulingIgnoredDuringExecution`이다. +파드 어피니티 규칙은 "security"를 키로하고 "S1"을 값으로 하는 레이블을 가진 파드가 최소한 하나라도 동작 중인 한 노드에서만 스케쥴될 수 있다고 말하고 있다. +(더 정확하게는 파드가 `failure-domain.beta.kubernetes.io/zone`를 키로하고 V를 값으로 하는 클러스터의 노드가 "security"를 키로하고 "S1"을 값으로 하는 레이블을 가진 파드를 동작시키고 있는 것과 같이 노드 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`는 어느 규칙에 맞는 레이블-키도 될 수 있다. +하지만 성능과 보안상의 이유로 토폴로지 키에는 몇가지 제약사항이 있다. + +1. 어피니티와 `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 `topologyKey`가 비어있는 것은 허용하지 않는다. +2. `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 어드미션 컨트롤러의 `LimitPodHardAntiAffinityTopology`는 `topologyKey`를 `kubernetes.io/hostname`으로 제한하기 위해 도입되었다. 사용자 정의 토폴로지를 이용하고자 할 경우 어드미션 컨트롤러를 수정하거나 간단하게 이를 비활성화 하면 된다. +3. `preferredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 `topologyKey`가 비어있는 경우 이를 "모든 토폴로지"("모든 토폴로지"는 현재 `kubernetes.io/hostname`, `failure-domain.beta.kubernetes.io/zone`, `failure-domain.beta.kubernetes.io/region`로 제한된다)로 해석한다. +4. 위의 경우를 제외하면 `topologyKey`는 어느 규칙에 맞는 레이블-키도 가능하다. + +`labelSelector`와 `topologyKey`외에도 `labelSelector`가 매칭되어야 하는 네임스페이스의 `namespaces` 리스트를 선택적으로 지정할 수 있다(이는 `labelSelector`와 `topologyKey`와 같은 개위로 작성되어야 한다). +생략되어있거나 비어있을 경우 어피니티/안티-어피니티 정의가 있는 파드의 네임스페이스가 기본 값이다. + +파드가 노드에 스케쥴되려면 `requiredDuringSchedulingIgnoredDuringExecution` 어피니티 및 안티-어피니티와 관련된 모든 `matchExpressions`를 만족해야 한다. + +#### 더 실용적인 유스케이스 + +파드간 어피니티와 안티-어피니티는 레플리카셋, 스테이트풀셋, 디플로이먼트 등과 같은 상위 레벨의 컬렉션에 사용될 때 좀 더 유용할 수 있다. +이를 통해 같은 노드에 함께 위치시키는 것과 같이 정의된 토폴로지와 동일한 곳에 함께 위치시키는 워크로드를 쉽게 구성할 수 있다. + +##### 항상 같은 노드에 위치시키기 + +세개의 노드를 가진 클러스터가 있는 상황에서 웹 어플리케이션은 redis와 같은 인메모리 캐시를 가지고 있다. 웹 서버를 캐시가 있는 위치와 동일한 곳으로 최대한 많이 위치시키고 싶다. + +이 짧은 yaml은 세개의 레플리카를 가지고 `app=store`라는 셀렉터 레이블을 가진 간단한 redis 디플로이먼트이다. 디플로이먼트는 `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.12-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 +``` + +##### 절대 동일한 노드에 위치시키지 않게 하기 + +위의 예시는 `PodAntiAffinity` 규칙을 `topologyKey:"kubernetes.io/hostname"`과 함께 사용하여 redis 클러스터가 하나의 호스트에 두개 이상 위치하지 않도록 배포한다. +[ZooKeeper 튜토리얼](/docs/tutorials/stateful-application/zookeeper/#tolerating-node-failure)을 통해 같은 방법을 사용하여 스테이트풀셋을 고가용성을 위해 안티-어피니티 설정을 한 예시를 확인할 수 있다. + +## nodeName + +`nodeName` 노드 셀렉션을 하는 가장 간단한 형태이지만 자체의 한계때문에 일반적으로 사용하지는 않는다. +`nodeName`은 파드 스펙의 필드이다. 비어있지 않다면 스케쥴러는 이 파트를 무시하게 되고 해당되는 노드에서 동작중인 kubelet이 파드를 실행하려 할 것이다. +따라서 `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 %}} + +[테인트(Taints)](/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 %}} diff --git a/content/ko/examples/pods/pod-nginx.yaml b/content/ko/examples/pods/pod-nginx.yaml new file mode 100644 index 0000000000000..134ddae2aa1c8 --- /dev/null +++ b/content/ko/examples/pods/pod-nginx.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nginx + labels: + env: test +spec: + containers: + - name: nginx + image: nginx + imagePullPolicy: IfNotPresent + nodeSelector: + disktype: ssd diff --git a/content/ko/examples/pods/pod-with-node-affinity.yaml b/content/ko/examples/pods/pod-with-node-affinity.yaml new file mode 100644 index 0000000000000..253d2b21ea917 --- /dev/null +++ b/content/ko/examples/pods/pod-with-node-affinity.yaml @@ -0,0 +1,26 @@ +apiVersion: v1 +kind: Pod +metadata: + name: with-node-affinity +spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/e2e-az-name + operator: In + values: + - e2e-az1 + - e2e-az2 + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + preference: + matchExpressions: + - key: another-node-label-key + operator: In + values: + - another-node-label-value + containers: + - name: with-node-affinity + image: k8s.gcr.io/pause:2.0 \ No newline at end of file diff --git a/content/ko/examples/pods/pod-with-pod-affinity.yaml b/content/ko/examples/pods/pod-with-pod-affinity.yaml new file mode 100644 index 0000000000000..35e645ef1f376 --- /dev/null +++ b/content/ko/examples/pods/pod-with-pod-affinity.yaml @@ -0,0 +1,29 @@ +apiVersion: v1 +kind: Pod +metadata: + name: with-pod-affinity +spec: + affinity: + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: security + operator: In + values: + - S1 + topologyKey: failure-domain.beta.kubernetes.io/zone + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + - key: security + operator: In + values: + - S2 + topologyKey: failure-domain.beta.kubernetes.io/zone + containers: + - name: with-pod-affinity + image: k8s.gcr.io/pause:2.0 From 331a5990d053c24a18d2f27f10bbb8490a2ffe94 Mon Sep 17 00:00:00 2001 From: KimMJ Date: Sun, 2 Feb 2020 03:43:01 +0900 Subject: [PATCH 09/12] =?UTF-8?q?comment=201=EC=B0=A8=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../concepts/configuration/assign-pod-node.md | 233 +++++++++++------- 1 file changed, 140 insertions(+), 93 deletions(-) diff --git a/content/ko/docs/concepts/configuration/assign-pod-node.md b/content/ko/docs/concepts/configuration/assign-pod-node.md index 4387e832345d6..32f25b8558d43 100644 --- a/content/ko/docs/concepts/configuration/assign-pod-node.md +++ b/content/ko/docs/concepts/configuration/assign-pod-node.md @@ -7,12 +7,15 @@ weight: 30 {{% capture overview %}} -{{< glossary_tooltip text="파드" term_id="pod" >}}를 특정한 {{< glossary_tooltip text="노드" term_id="node" >}}에서만 동작하도록 하거나 특정 노드를 선호하도록 제한할 수 있다. -이를 위해서는 몇가지 방법이 있는데 그 중 하나는 선택 시 [레이블 셀렉터(label selector)](/ko/docs/concepts/overview/working-with-objects/labels/)를 사용하는 것이다. -스케쥴러가 알아서 합리적인 위치를 고르기 때문에 (예를 들어 파드를 노드에 퍼뜨리고, 리소스가 충분하지 않은 노드에는 파드를 위치시키지 않는 것 등) 일반적으로 이러한 제약은 불필요하지만 -파드가 SSD가 달려있는 머신에서 동작하도록 하거나 서로 통신을 많이 하는 두개의 각기 다른 서비스와 연결된 파드가 -동일한 가용성 영역(availability zone)에 위치시켜야 하는 것처럼 -파드가 위치할 노드에 대해 좀 더 제어가 필요한 몇가지 상황들이 있다. +{{< glossary_tooltip text="파드" term_id="pod" >}}를 특정한 {{< glossary_tooltip text="노드(emf)" term_id="node" >}}에서만 동작하도록 하거나, +특정 노드들을 선호하도록 제한할 수 있다. +이를 수행하는 방법에는 여러가지가 있으며, 권장되는 접근 방식은 모두 +[레이블 셀렉터(label selector)](/ko/docs/concepts/overview/working-with-objects/labels/)를 사용하여 선택한다. +보통 스케줄러가 자동으로 합리적인 배치를 수행하기에 이런 제약 조건은 필요하지 않지만 +(예: 노드들에 걸쳐 파드를 분배하거나, 여유 자원이 부족한 노드에 파드를 배치하는 등) +간혹 파드가 착츅하는 노드에 대해 더 많은 제어를 원할 수 있는 상황이 있다. +예를 들어 SSD가 장착되어 있는 머신에 파드가 연결되도록 하거나 또는 동일한 가용성 영역(availability zone)에서 +많은 것을 통신하는 두 개의 서로 다른 서비스의 파드를 같이 배치할 수 있다. {{% /capture %}} @@ -20,29 +23,26 @@ weight: 30 ## 노드 셀렉터(nodeSelector) -`nodeSelector`는 가장 간단하고 추천하는 형식의 노드 선택 제약이다. -`nodeSelector`는 파드 스펙의 필드이다. 이는 키-값 쌍의 맵을 지정한다. -파드가 노드에서 동작할 수 있도록 하려면 노드는 반드시 레이블(물론 이는 추가적인 레이블들을 가질 수도 있다)로 지정된 -키-값 쌍들을 모두 가지고 있어야 한다. 일반적인 사용법은 단일 키-값 쌍을 사용하는 것이다. +`nodeSelector` 는 가장 간단하고 권장하는 노드 선택 제약 조건의 형태이다. +`nodeSelector` 는 PodSpec의 필드이다. 이는 키-값 쌍의 매핑으로 지정한다. 파드가 노드에서 동작할 수 있으려면, +노드는 키-값의 쌍으로 표시되는 레이블을 각자 가지고 있어야 한다(이는 추가 레이블을 가지고 있을 수 있다). +대부분의 일반적인 사용은 하나의 키-값 쌍이다. -`nodeSelector`를 어떻게 사용하는지 예시를 통해 알아보도록 하자. +`nodeSelector` 를 어떻게 사용하는지 예시를 통해 알아보도록 하자. ### 0 단계: 사전 준비 -이 예시는 쿠버네티스에 대한 기본적인 이해를 하고 있고 [쿠버네티스 클러스터가 준비](/ko/docs/setup/)되어 있다고 가정한다. +이 예시는 쿠버네티스 파드에에 대한 기본적인 이해를 하고 있고 [쿠버네티스 클러스터가 설정](/ko/docs/setup/)되어 있다고 가정한다. -### 1 단계: 노드에 레이블 붙이기 {#step-one-attach-label-to-the-node} +### 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` 를 실행해서 클러스터 노드 이름을 가져온다. 이 중에 레이블을 추가하기 원하는 것 하나를 선택한 다음에 `kubectl label nodes <노드 이름> <레이블 키>=<레이블 값>` 을 실행해서 선택한 노드에 레이블을 추가 한다. 예를 들어 노드의 이름이 'kubernetes-foo-node-1.c.a-robinson.internal' 이고, 원하는 레이블이 'disktype=ssd' 라면, `kubectl label nodes ubernetes-foo-node-1.c.a-robinson.internal disktype=ssd` 를 실행 한다. -`kubectl get nodes --show-labels`를 다시 실행시켜서 노드에 레이블이 있는지 확인하여 이 작업이 잘 되었는지 검증할 수 있다. -또한 `kubectl describe node "노드 이름"`을 이용하여 주어진 노드에 대한 모든 레이블들의 리스트를 확인할 수 있다. +`kubectl get nodes --show-labels` 를 다시 실행해서 노드가 현재 가진 레이블을 확인하여, 이 작업을 검증할 수 있다. 또한 `kubectl describe node "노드 이름"` 을 사용해서 노드에 주어진 레이블의 전체 목록을 확인할 수 있다. ### 2 단계: 파드 설정에 nodeSelector 필드 추가하기 -아래와 같이 실행하고 싶은 파드의 설정 파일에 nodeSelector을 추가한다. 만약 파드 설정 파일이 다음과 같다면: +실행하고자 하는 파드의 설정 파일을 가져오고, 이와 같이 nodeSelector 섹션을 추가한다. 예를 들어 이것이 파드 설정이라면: ```yaml apiVersion: v1 @@ -57,16 +57,19 @@ spec: image: nginx ``` -nodeSelector를 이처럼 추가한다: +이 다음에 nodeSelector 를 다음과 같이 추가한다: {{< codenew file="pods/pod-nginx.yaml" >}} -`kubectl apply -f https://k8s.io/examples/pods/pod-nginx.yaml`을 실행시키면 파드는 레이블을 붙인 노드에 스케쥴될 것이다. -`kubectl get pods -o wide`를 실행시켜 파드가 할당된 "NODE"를 확인하여 검증할 수 있다. +그런 다음에 `kubectl apply -f https://k8s.io/examples/pods/pod-nginx.yaml` 을 +실행하면, 레이블이 붙여진 노드에 파드가 스케줄 된다. +`kubectl get pods -o wide` 를 실행해서 파드가 할당된 +"NODE" 를 보면 작동하는지 검증할 수 있다. ## 넘어가기 전에: 내장 노드 레이블들 {#built-in-node-labels} -노드에 [붙인](#step-one-attach-label-to-the-node) 레이블에 추가적으로 이미 만들어진 표준 레이블 모음이 있다. 이런 레이블들은 다음과 같다. +[붙인](#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) @@ -79,82 +82,98 @@ nodeSelector를 이처럼 추가한다: * [`kubernetes.io/arch`](/docs/reference/kubernetes-api/labels-annotations-taints/#kubernetes-io-arch) {{< note >}} -이 레이블들의 값은 클라우드 제공자에 따라 다르고 신뢰성이 보장되지 않는다. -예를 들어 `kubernetes.io/hostname`은 어떤 환경에서는 노드의 이름과 같고 다른 환경에서는 다른 값이 될 수 있다. +이 레이블들의 값은 클라우드 공급자에 따라 다르고 신뢰성이 보장되지 않는다. +예를 들어 `kubernetes.io/hostname` 은 어떤 환경에서는 노드 이름과 같지만, +다른 환경에서는 다른 값일 수 있다. {{< /note >}} ## 노드 격리(isolation)/제한(restriction) -노드 오브젝트에 레이블을 추가하는 것은 파드가 특정한 노드들이나 노드 그룹들을 목표 대상으로 할 수 있도록 한다. -이는 특정한 파드가 어떤 격리, 보안, 규제 속성들을 가진 노드에서만 동작할 수 있도록 한다. -이는 compromised node들이 kubelet 자격증명(credential)을 사용하여 노드 오브젝트 자체에 레이블을 설정하지 않도록 하며 스케쥴러가 compromised node에 워크로드를 스케쥴하는 데 영향을 주지 않도록 한다. +노드 오브젝트에 레이블을 추가하면 특정 노드 또는 노드 그룹에 파드를 대상으로 할 수 있다. +이는 특정 파드가 어떤 격리, 보안, 또는 규제 속성이 있는 노드에서만 실행되도록 사용할 수 있다. +이 목적으로 레이블을 사용하는 경우, 노드에서 kubelet 프로세스로 수정할 수 없는 레이블 키를 선택하는 것을 권장한다. +이렇게 하면 손상된 노드가 해당 kubelet 자격 증명을 사용해서 해당 레이블을 자체 노드 오브젝트에 설정하고, 스케줄러가 손상된 노드로 워크로드를 스케줄 하는 것을 방지할 수 있다. -`NodeRestriction` 어드미션 플러그인은 kubelet이 레이블을 `node-restriction.kubernetes.io/` 접두사로 수정하거나 설정하는 것을 방지한다. 노드 격리를 위해 그 레이블 접두사를 사용하도록 하려면 다음과 같이 하면 된다: +`NodeRestriction` 어드미션 플러그인은 kubelet이 `node-restriction.kubernetes.io/` 접두사로 레이블을 설정 또는 수정하지 못하게 한다. +노드 격리에 해당 레이블 접두사를 사용하려면 다음과 같이 한다. -1. [Node authorizer](/docs/reference/access-authn-authz/node/)를 사용하고 있고 [NodeRestriction admission plugin](/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`와 같이 설정한다. +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`는 파드를 특정 레이블을 가진 노드에서 동작하도록 제한을 하는 가장 간단한 방법이다. -어피니티/안티-어피니티는 표현할 수 있는 제약의 종류를 폭 넓게 할 수 있다. 개선할 수 있는 사항들은 다음과 같다. +`nodeSelector` 는 파드를 특정 레이블이 있는 도느로 제한하는 매우 간단한 방법을 제공한다. +어피니티/안티-어피니티 기능은 표현할 수 있는 제약 종류를 크게 확장한다. 주요 개선 사항은 다음과 같다. -1. 언어가 더욱 표현력있게 된다. (단순히 정확한 일치를 의미하는 "AND"가 아니다) -2. 엄격한 요구사항 대신 "유연한(soft)"/"선호(preference)" 규칙을 나타낼 수 있어 스케쥴러가 만족하지 못할 경우에도 여전히 파드가 스케쥴될 수 있도록 할 수 있다. -3. 노드 자체(또는 다른 토폴로지 도메인)에 대한 레이블에 대해서만 제약을 걸 수 있는것이 아니라 노드에 떠있는 파드들이 가진 레이블에 대해서도 제약을 걸어 파드가 서로 함께 위치하도록 하거나 위치하지 못하도록 할 수 있다. +1. 언어가 보다 표현적이다("AND 또는 정확한 일치" 만이 아니다). +2. 규칙이 엄격한 요구사항이 아니라 "유연한(soft)"/"선호(preference)" 규칙을 나타낼 수 있기에 스케줄러가 규칙을 만족할 수 없다면, + 파드는 계속 스케줄 되도록 한다. +3. 노드 자체에 레이블을 붙이기 보다는 노드(또는 다른 토폴로지 도메인)에서 실행중인 다른 파드의 레이블을 제한할 수 있다. + 이를 통해 어떤 파드가 함께 위치할 수 있는지와 없는지에 대한 규칙을 적용할 수 있다. -어피니티 기능은 "노드 어피니티", "파드 간 어피니티/안티-어피니티" 두가지 종류의 어피니티로 구성되어있다. -노드 어피니티는 기존 `nodeSelector`와 비슷한 것(그러나 위의 리스트에서 말한 것 중 처음 두가지 이점을 가졌다)이고, -파드간 어피니티/안티-어피니티는 위 리스트의 3번째 리스트에서 설명한 것처럼 -노드 레이블이 아니라 파드의 레이블에 대해서 제약을 둘 수 있으면서 첫번째와 두번째 속성또한 가졌다. +어피니티 기능은 "노드 어피니티" 와 "파드 간 어피니티/안티-어피니티" 두 종류의 어피니티로 구성된다. +노드 어피니티는 기존 `nodeSelector` 와 비슷하지만(그러나 위에서 나열된 첫 째와 두번째 이점이 있다.), +파드 간 어피니티/안티-어피니티는 위에서 나열된 세번째 항목에 설명된 대로 +노드 레이블이 아닌 파드 레이블에 대해 제한되고 위에서 나열된 첫번째와 두번째 속성을 가진다. ### 노드 어피니티 -노드 어피니티는 개념적으로 `nodeSelector`와 비슷하다 -- 이는 노드에 달린 레이블을 기반으로 파드가 특정한 노드로 스케쥴이 가능하도록 제약을 줄 수 있다. +노드 어피니티는 개념적으로 `nodeSelector` 와 비슷하다 -- 이는 노드의 레이블을 기반으로 파드를 +스케줄할 수 있는 노드를 제한할 수 있다. -`requiredDuringSchedulingIgnoredDuringExecution`과 `preferredDuringSchedulingIgnoredDuringExecution` 두가지 종류의 노드 어피니티가 있다. -전자는 파드가 노드에 스케쥴될 때 (`nodeSelector`와 비슷하지만 좀 더 표현이 풍부한 문법이다) 규칙을 *반드시* 만족해야 하는 것이고, 후자는 스케쥴러가 규칙을 지키려고 시도하겠지만 만족한다는 것을 보장하지는 않는, 규칙을 *선호*한다는 관점에서 이를 각각 "엄격한" 그리고 "유연한" 조건이라고 생각할 수 있다. -위의 이름에서 "IgnoredDuringExecution"라고 적혀있는 부분은 `nodeSelector`가 동작하는 방식과 비슷하게 노드의 레이블이 런타임에 변경될 경우 파드에 설정된 어피니티 규칙이 더이상 만족하지 않는 경우에도 파드가 여전히 그 노드에서 동작한다는 의미이다. -후에 `requiredDuringSchedulingRequiredDuringExecution` 설정을 제공하여 `requiredDuringSchedulingIgnoredDuringExecution` 처럼 동작하지만 파드가 동작하고 있는 노드가 더 이상 파드의 노드 어피니티 요구사항을 만족하지 않는 경우에 파드를 축출하는 것을 계획하고 있다. +여기에 현재 `requiredDuringSchedulingIgnoredDuringExecution` 와 `preferredDuringSchedulingIgnoredDuringExecution` 로 부르는 +두 가지 종류의 노드 어피니티가 있다. 전자는 파드가 노드에 스케줄 되도록 *반드시* 규칙을 만족해야 하는 것(`nodeSelector` 와 같으나 보다 표현적인 구문을 사용해서)을 지정하고, +후자는 스케줄러가 시도하려고는 하지만, 보증하지 않는 *선호(preferences)*를 지정한다는 점에서 이를 각각 "엄격함(hard)" 과 "유연함(soft)" 하다고 생각할 수 있다. +이름의 "IgnoredDuringExecution" 부분은 `nodeSelector` 작동 방식과 유사하게 노드의 +레이블이 런타임 중에 변경되어 파드의 어피니티 규칙이 더 이상 충족되지 않으면 파드가 여전히 그 노드에서 +동작한다는 의미이다. 향후에는 파드의 노드 어피니티 요구 사항을 충족하지 않는 노드에서 파드를 제거한다는 점을 제외하고는 `preferredDuringSchedulingIgnoredDuringExecution` 와 같은 `requiredDuringSchedulingIgnoredDuringExecution` 를 제공할 계획이다. -따라서 `requiredDuringSchedulingIgnoredDuringExecution`의 예시는 "인텔 CPU가 있는 노드에서만 파드를 동작시키겠다"가 될 수 있으며 -`preferredDuringSchedulingIgnoredDuringExecution`의 예시는 "XYZ 영역에 파드 세트를 동작시키려고 시도하지만 가능하지 않은 경우 다른곳에서 동작하는 것을 허용한다"가 되겠다. +따라서 `requiredDuringSchedulingIgnoredDuringExecution` 의 예로는 "인텔 CPU가 있는 노드에서만 파드 실행"이 +될 수 있고, `preferredDuringSchedulingIgnoredDuringExecution` 의 예로는 "장애 조치 영역 XYZ에 파드 집합을 실행하려고 +하지만, 불가능하다면 다른 곳에서 일부를 실행하도록 허용"이 된다. -노드 어피니티는 파드 스펙에서 `affinity`필드 내의 `nodeAffinity` 필드에서 지정된다. +노드 어피니티는 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`인 레이블을 가진 노드를 선호하도록 되어있다. +이 노드 어피니티 규칙은 키가 `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`를 사용하여 안티-어피니티 동작을 할 수 있고 [노드 테인트(node taints)](/docs/concepts/configuration/taint-and-toleration/) 사용하여 특정한 노드에서 파드를 쫓아낼 수 있다. +예시에서 연산자 `In` 이 사용되고 있는 것을 볼 수 있다. 새로운 노드 어피니티 구문은 다음의 연산자들을 지원한다. `In`, `NotIn`, `Exists`, `DoesNotExist`, `Gt`, `Lt`. +`NotIn` 과 `DoesNotExist` 를 사용해서 안티-어피니티를 수행하거나, +특정 노드에서 파드를 쫓아내는 [노드 테인트(taint)](/docs/concepts/configuration/taint-and-toleration/)를 할 수 있다. -`nodeSelector`와 `nodeAffinity`를 모두 지정한다면 파드가 후보 노드에 스케쥴 되기 위해서는 *둘 다* 반드시 만족해야한다. +`nodeSelector` 와 `nodeAffinity` 를 모두 지정한다면 파드가 후보 노드에 스케줄 되기 위해서는 +*둘 다* 반드시 만족해야한다. -여러개의 `nodeAffinity` 타입과 관련하여 `nodeSelectorTerms`를 지정하면 파드는 `nodeSelectorTerms` 중에서 **하나라도 만족**하는 노드에 스케쥴될 수 있다. +`nodeAffinity` 유형과 연관된 `nodeSelectorTerms` 를 지정하면, 파드를 `nodeSelectorTerms` 가 지정된 것 중 **하 가지**라도 만족하는 노드에 스케줄 할 수 있다. -`nodeSelectorTerms`와 관련된 `matchExpressions`를 여러개 지정하면 파드는 `matchExpressions`가 **모두 만족**하는 노드에만 스케쥴될 수 있다. +`nodeSelectorTerms` 와 연관된 여러 `matchExpressions` 를 지정하면, 파드는 `matchExpressions` 를 **모두** 만족하는 노드에만 스케줄할 수 있다. -파드가 스케쥴된 노드의 레이블을 지우거나 변경해도 파드는 삭제되지 않는다. 다시 말해, 어피니티 선택은 파드가 스케쥴링 되는 시점에만 작동한다. +파드가 스케줄된 노드의 레이블을 지우거나 변경해도 파드는 제거되지 않는다. 다시 말해서 어피니티 선택은 파드를 스케줄링 하는 시점에만 작동한다. -`preferredDuringSchedulingIgnoredDuringExecution`에서 `weight` 필드는 1-100까지의 범위를 가진다. -모든 스케쥴링 요구사항 (리소스 요청, RequiredDuringScheduling 어피니티 표현식 등)을 만족하는 각 노드들에 대해서 스케쥴러는 이 필드를 순회하며 노드가 MatchExpressions에 적합할 때 "weight"를 누적 합계에 추가하여 총합을 계산할 것이다. -이 점수는 노드에 대해 다른 우선순위 함수의 점수들과 합쳐진다. 가장 높은 점수를 가진 노드를 가장 선호하게 된다. +`preferredDuringSchedulingIgnoredDuringExecution` 의 `weight` 필드의 범위는 1-100 이다. 모든 스케줄링 요구사항 (리소스 요청, RequiredDuringScheduling 어피니티 표현식 등)을 만족하는 각 노드들에 대해 스케줄러는 이 필드의 요소들을 반복해서 합계를 계산하고 노드가 MatchExpressions 에 일치하는 경우 합계에 "가중치(weight)"를 추가 한다. 이후에 이 점수는 노드에 대한 다른 우선순위 함수의 점수와 합쳐진다. 전체 점수가 가장 높은 노드를 가장 선호한다. ### 파드간 어피니티와 안티-어피니티 -파드간 어피니티와 안티-어피니티는 파드를 노드의 레이블이 아니라 *노드에서 이미 동작 중인 파드들의 레이블을 기반으로* 동작할 수 있는 노드를 선택하게 할 수 있다. -이 규칙은 "이 파드는 반드시 Y 규칙을 만족하는 파드가 하나 이상 동작중인 X에서만 동작할 수 있도록(안티-어피니티의 경우, 동작할수 없도록) 한다"는 형태로 구성되어있다. -Y는 네임스페이스와 관련된 선택적 목록을 가진 LabelSelector로 표현된다; 노드와는 다르게 파드는 네임스페이스 기반(이는 파드의 레이블이 네임스페이스 기반임을 내포한다)이고 파트 레이블에 대한 레이블 셀렉터는 반드시 셀렉터가 어느 네임스페이스에 적용되어야 하는지 지정해 주어야 하기 때문이다. -개념적으로 X는 노드, 랙, 클라우드 제공자 영역, 클라우드 제공자 리젼 등과 같은 토폴로지 도메인이다. 시스템이 사용하는 토폴로지 도메인을 의미하는 노드 레이블의 키인 `topologyKey`를 사용하여 토폴로지 도메인을 표현할 수 있으며, 예시는 [넘어가기 전에: 빌트인 노드 레이블](#built-in-node-labels) 섹션에 나열된 레이블 키를 보면 된다. +파드간 어피니티와 안티-어피니티는 파드를 노드의 레이블이 아니라 *노드에서 이미 동작 중인 파드들의 레이블을 기반으로* +동작할 수 있는 노드를 선택하게 할 수 있다. 이 규칙은 "이 파드는 반드시 Y 규칙을 만족하는 파드가 하나 이상 +동작중인 X에서만 동작할 수 있도록(안티-어피니티의 경우, 동작할수 없도록) 한다"는 형태로 구성되어있다. Y는 +네임스페이스와 관련된 선택적 목록을 가진 LabelSelector로 표현된다; 노드와는 다르게 파드는 네임스페이스 +기반(이는 파드의 레이블이 네임스페이스 기반임을 내포한다)이고 파트 레이블에 대한 레이블 셀렉터는 반드시 +셀렉터가 어느 네임스페이스에 적용되어야 하는지 지정해 주어야 하기 때문이다. 개념적으로 X는 노드, 랙, +클라우드 제공자 영역, 클라우드 제공자 리젼 등과 같은 토폴로지 도메인이다. 시스템이 사용하는 토폴로지 +도메인을 의미하는 노드 레이블의 키인 `topologyKey`를 사용하여 토폴로지 도메인을 표현할 수 있으며, +예시는 [넘어가기 전에: 빌트인 노드 레이블](#built-in-node-labels) 섹션에 나열된 레이블 키를 보면 된다. {{< note >}} -파드간 어피니티와 안티-어피니티는 상당한 양의 연산을 필요로 하여 큰 클러스터에서는 스케쥴링을 상당히 느리게 할 수 있다. +파드간 어피니티와 안티-어피니티는 상당한 양의 연산을 필요로 하여 +큰 클러스터에서는 스케쥴링을 상당히 느리게 할 수 있다. 수백개의 노드가 넘는 클러스터에서 이를 사용하는 것은 추천하지 않는다. {{< /note >}} @@ -162,43 +181,60 @@ Y는 네임스페이스와 관련된 선택적 목록을 가진 LabelSelector로 파드 안티-어피니티는 노드가 일관적으로 레이블을 가지고 있어야 함을 전제로 한다. 예를들어 클러스터의 모든 노드는 `topologyKey`와 매칭되는 적절한 레이블을 가지고 있어야 한다. 일부 또는 모든 노드가 지정된 `topologyKey` 레이블이 없다면 이는 의도치 않은 동작을 일으킬 수 있다. {{< /note >}} -노드 어피니티처럼 현재 각각 "엄격한"과 "유연한" 제약사항을 나타내는 `requiredDuringSchedulingIgnoredDuringExecution`와 `preferredDuringSchedulingIgnoredDuringExecution`라고 하는 파드 어피니티와 안티 어피니티 두가지 종류가 있다. +노드 어피니티처럼 현재 각각 "엄격한"과 "유연한" 제약사항을 나타내는 `requiredDuringSchedulingIgnoredDuringExecution`와 +`preferredDuringSchedulingIgnoredDuringExecution`라고 하는 파드 어피니티와 안티 어피니티 두가지 종류가 있다. 앞선 노드 어피니티 섹션의 설명을 보면 된다. -`requiredDuringSchedulingIgnoredDuringExecution` 어피니티의 예시는 "서비스 A와 서비스 B는 서로 많은 통신을 하기 때문에 각 서비스의 파드들을 동일한 영역에 위치시킨다."이고 `preferredDuringSchedulingIgnoredDuringExecution` 안티 어피니티의 예시는 "서비스를 여러 영역에 걸처 퍼트린다"가 될 것이다 +`requiredDuringSchedulingIgnoredDuringExecution` 어피니티의 예시는 +"서비스 A와 서비스 B는 서로 많은 통신을 하기 때문에 각 서비스의 파드들을 동일한 영역에 위치시킨다."이고 +`preferredDuringSchedulingIgnoredDuringExecution` 안티 어피니티의 예시는 "서비스를 여러 영역에 걸처 퍼트린다"가 될 것이다 (엄격한 제약조건은 파드가 영역의 수보다 많을 수 있기 때문에 말이 안된다). -파드간 어피니티는 파드 스펙에서 `affinity` 필드의 `podAffinity` 필드에서 지정할 수 있다. 그리고 파드간 안티-어피니티는 파드 스펙에서 `affinity` 필드의 `podAntiAffinity` 필드에서 지정할 수 있다. +파드간 어피니티는 파드 스펙에서 `affinity` 필드의 `podAffinity` 필드에서 지정할 수 있다. +그리고 파드간 안티-어피니티는 파드 스펙에서 `affinity` 필드의 `podAntiAffinity` 필드에서 지정할 수 있다. #### 파드 어피니티를 사용하는 파드의 예시: {{< codenew file="pods/pod-with-pod-affinity.yaml" >}} -이 파드에서의 어피니티는 하나의 파드 어피니티 규칙과 하나의 안티-어피니티 규칙을 정의한다. 이 예시에서 `podAffinity`는 `requiredDuringSchedulingIgnoredDuringExecution`이고 `podAntiAffinity`는 `preferredDuringSchedulingIgnoredDuringExecution`이다. -파드 어피니티 규칙은 "security"를 키로하고 "S1"을 값으로 하는 레이블을 가진 파드가 최소한 하나라도 동작 중인 한 노드에서만 스케쥴될 수 있다고 말하고 있다. -(더 정확하게는 파드가 `failure-domain.beta.kubernetes.io/zone`를 키로하고 V를 값으로 하는 클러스터의 노드가 "security"를 키로하고 "S1"을 값으로 하는 레이블을 가진 파드를 동작시키고 있는 것과 같이 노드 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`의 파드 어피니티와 안티-어피니티에 대한 많은 예시를 확인할 수 있다. +이 파드에서의 어피니티는 하나의 파드 어피니티 규칙과 하나의 안티-어피니티 규칙을 정의한다. +이 예시에서 `podAffinity`는 `requiredDuringSchedulingIgnoredDuringExecution`이고 `podAntiAffinity`는 +`preferredDuringSchedulingIgnoredDuringExecution`이다. 파드 어피니티 규칙은 "security"를 키로하고 + "S1"을 값으로 하는 레이블을 가진 파드가 최소한 하나라도 동작 중인 한 노드에서만 스케쥴될 수 있다고 말하고 있다. +(더 정확하게는 파드가 `failure-domain.beta.kubernetes.io/zone`를 키로하고 V를 값으로 하는 +클러스터의 노드가 "security"를 키로하고 "S1"을 값으로 하는 레이블을 가진 파드를 동작시키고 있는 것과 같이 +노드 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`는 어느 규칙에 맞는 레이블-키도 될 수 있다. -하지만 성능과 보안상의 이유로 토폴로지 키에는 몇가지 제약사항이 있다. +하지만 성능과 보안상의 이유로 토폴로지 키에는 몇가지 제약사항이 있다: -1. 어피니티와 `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 `topologyKey`가 비어있는 것은 허용하지 않는다. +1. 어피니티와 `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 +`topologyKey`가 비어있는 것은 허용하지 않는다. 2. `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 어드미션 컨트롤러의 `LimitPodHardAntiAffinityTopology`는 `topologyKey`를 `kubernetes.io/hostname`으로 제한하기 위해 도입되었다. 사용자 정의 토폴로지를 이용하고자 할 경우 어드미션 컨트롤러를 수정하거나 간단하게 이를 비활성화 하면 된다. 3. `preferredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 `topologyKey`가 비어있는 경우 이를 "모든 토폴로지"("모든 토폴로지"는 현재 `kubernetes.io/hostname`, `failure-domain.beta.kubernetes.io/zone`, `failure-domain.beta.kubernetes.io/region`로 제한된다)로 해석한다. 4. 위의 경우를 제외하면 `topologyKey`는 어느 규칙에 맞는 레이블-키도 가능하다. -`labelSelector`와 `topologyKey`외에도 `labelSelector`가 매칭되어야 하는 네임스페이스의 `namespaces` 리스트를 선택적으로 지정할 수 있다(이는 `labelSelector`와 `topologyKey`와 같은 개위로 작성되어야 한다). +`labelSelector`와 `topologyKey`외에도 `labelSelector`가 매칭되어야 하는 네임스페이스의 `namespaces` +리스트를 선택적으로 지정할 수 있다(이는 `labelSelector`와 `topologyKey`와 같은 개위로 작성되어야 한다). 생략되어있거나 비어있을 경우 어피니티/안티-어피니티 정의가 있는 파드의 네임스페이스가 기본 값이다. -파드가 노드에 스케쥴되려면 `requiredDuringSchedulingIgnoredDuringExecution` 어피니티 및 안티-어피니티와 관련된 모든 `matchExpressions`를 만족해야 한다. +파드가 노드에 스케쥴되려면 `requiredDuringSchedulingIgnoredDuringExecution` 어피니티 및 안티-어피니티와 +관련된 모든 `matchExpressions`를 만족해야 한다. #### 더 실용적인 유스케이스 -파드간 어피니티와 안티-어피니티는 레플리카셋, 스테이트풀셋, 디플로이먼트 등과 같은 상위 레벨의 컬렉션에 사용될 때 좀 더 유용할 수 있다. -이를 통해 같은 노드에 함께 위치시키는 것과 같이 정의된 토폴로지와 동일한 곳에 함께 위치시키는 워크로드를 쉽게 구성할 수 있다. +파드간 어피니티와 안티-어피니티는 레플리카셋, 스테이트풀셋, 디플로이먼트 등과 같은 +상위 레벨의 컬렉션에 사용될 때 좀 더 유용할 수 있다. 이를 통해 같은 노드에 함께 위치시키는 것과 같이 +정의된 토폴로지와 동일한 곳에 함께 위치시키는 워크로드를 쉽게 구성할 수 있다. ##### 항상 같은 노드에 위치시키기 @@ -279,7 +315,6 @@ spec: 위의 두 디플로이먼트를 생성하면 세개의 노드를 가진 클러스터는 다음과 같이 보일 것이다. - | node-1 | node-2 | node-3 | |:--------------------:|:-------------------:|:------------------:| | *webserver-1* | *webserver-2* | *webserver-3* | @@ -303,20 +338,29 @@ web-server-1287567482-s330j 1/1 Running 0 7m 10.192.3 ##### 절대 동일한 노드에 위치시키지 않게 하기 -위의 예시는 `PodAntiAffinity` 규칙을 `topologyKey:"kubernetes.io/hostname"`과 함께 사용하여 redis 클러스터가 하나의 호스트에 두개 이상 위치하지 않도록 배포한다. -[ZooKeeper 튜토리얼](/docs/tutorials/stateful-application/zookeeper/#tolerating-node-failure)을 통해 같은 방법을 사용하여 스테이트풀셋을 고가용성을 위해 안티-어피니티 설정을 한 예시를 확인할 수 있다. +위의 예시는 `PodAntiAffinity` 규칙을 `topologyKey:"kubernetes.io/hostname"`과 함께 사용하여 +redis 클러스터가 하나의 호스트에 두개 이상 위치하지 않도록 배포한다. +[ZooKeeper 튜토리얼](/docs/tutorials/stateful-application/zookeeper/#tolerating-node-failure)을 통해 +같은 방법을 사용하여 스테이트풀셋을 고가용성을 위해 안티-어피니티 설정을 한 예시를 확인할 수 있다. ## nodeName -`nodeName` 노드 셀렉션을 하는 가장 간단한 형태이지만 자체의 한계때문에 일반적으로 사용하지는 않는다. -`nodeName`은 파드 스펙의 필드이다. 비어있지 않다면 스케쥴러는 이 파트를 무시하게 되고 해당되는 노드에서 동작중인 kubelet이 파드를 실행하려 할 것이다. -따라서 `nodeName`이 파드 스펙에 제공되면 노드 셀렉션에 대한 위의 방법들 중 가장 우선시된다. +`nodeName` 노드 셀렉션을 하는 가장 간단한 형태이지만 +자체의 한계때문에 일반적으로 사용하지는 않는다. +`nodeName`은 파드 스펙의 필드이다. 비어있지 않다면 스케쥴러는 +이 파트를 무시하게 되고 해당되는 노드에서 동작중인 kubelet이 +파드를 실행하려 할 것이다. 따라서 `nodeName`이 파드 스펙에 +제공되면 노드 셀렉션에 대한 위의 방법들 중 가장 우선시된다. `nodeName`으로 노드를 선택하는 것의 제약사항이 몇가지 있다: -- 그 이름을 가진 노드가 없을 경우 파드는 실행되지 않을 것이고 몇몇 경우에는 자동으로 삭제된다. -- 그 이름을 가진 노드가 파드를 실행하기 위한 충분한 리소스가 없는 경우 파드의 실행은 실패하고 OutOfmemory 또는 OutOfcpu와 같은 이유를 나타낼 것이다. -- 클라우드 환경에서의 노드 이름은 항상 예측이 가능하거나 안정적인 것이 아니다. +- 그 이름을 가진 노드가 없을 경우 파드는 실행되지 않을 것이고 + 몇몇 경우에는 자동으로 삭제된다. +- 그 이름을 가진 노드가 파드를 실행하기 위한 + 충분한 리소스가 없는 경우 파드의 실행은 실패하고 + OutOfmemory 또는 OutOfcpu와 같은 이유를 나타낼 것이다. +- 클라우드 환경에서의 노드 이름은 항상 예측이 가능하거나 + 안정적인 것이 아니다. `nodeName` 필드를 사용한 파드 설정 파일의 예시이다: @@ -340,9 +384,12 @@ spec: [테인트(Taints)](/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)에 대한 디자인 문서는 이 기능들에 대한 추가적인 배경 정보를 포함한다. +[노드 어피니티](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/)는 노드 레벨의 리소스 할당 결정의 일부분이 될 수 있다. +[토폴로지 매니저](/docs/tasks/administer-cluster/topology-manager/)는 +노드 레벨의 리소스 할당 결정의 일부분이 될 수 있다. {{% /capture %}} From 92a29d8da91b7dd14f6e6932a55553bb980dfd49 Mon Sep 17 00:00:00 2001 From: KimMJ Date: Sun, 2 Feb 2020 04:11:07 +0900 Subject: [PATCH 10/12] =?UTF-8?q?=EB=9D=84=EC=96=B4=EC=93=B0=EA=B8=B0=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../concepts/configuration/assign-pod-node.md | 162 +++++++++--------- 1 file changed, 81 insertions(+), 81 deletions(-) diff --git a/content/ko/docs/concepts/configuration/assign-pod-node.md b/content/ko/docs/concepts/configuration/assign-pod-node.md index 32f25b8558d43..cbc07d76852c7 100644 --- a/content/ko/docs/concepts/configuration/assign-pod-node.md +++ b/content/ko/docs/concepts/configuration/assign-pod-node.md @@ -9,12 +9,12 @@ weight: 30 {{< glossary_tooltip text="파드" term_id="pod" >}}를 특정한 {{< glossary_tooltip text="노드(emf)" term_id="node" >}}에서만 동작하도록 하거나, 특정 노드들을 선호하도록 제한할 수 있다. -이를 수행하는 방법에는 여러가지가 있으며, 권장되는 접근 방식은 모두 +이를 수행하는 방법에는 여러 가지가 있으며, 권장되는 접근 방식은 모두 [레이블 셀렉터(label selector)](/ko/docs/concepts/overview/working-with-objects/labels/)를 사용하여 선택한다. 보통 스케줄러가 자동으로 합리적인 배치를 수행하기에 이런 제약 조건은 필요하지 않지만 (예: 노드들에 걸쳐 파드를 분배하거나, 여유 자원이 부족한 노드에 파드를 배치하는 등) -간혹 파드가 착츅하는 노드에 대해 더 많은 제어를 원할 수 있는 상황이 있다. -예를 들어 SSD가 장착되어 있는 머신에 파드가 연결되도록 하거나 또는 동일한 가용성 영역(availability zone)에서 +간혹 파드가 착륙하는 노드에 대해 더 많은 제어를 원할 수 있는 상황이 있다. +예를 들어 SSD가 장착된 머신에 파드가 연결되도록 하거나 또는 동일한 가용성 영역(availability zone)에서 많은 것을 통신하는 두 개의 서로 다른 서비스의 파드를 같이 배치할 수 있다. {{% /capture %}} @@ -36,13 +36,13 @@ weight: 30 ### 1 단계: 노드에 레이블 붙이기 -`kubectl get nodes` 를 실행해서 클러스터 노드 이름을 가져온다. 이 중에 레이블을 추가하기 원하는 것 하나를 선택한 다음에 `kubectl label nodes <노드 이름> <레이블 키>=<레이블 값>` 을 실행해서 선택한 노드에 레이블을 추가 한다. 예를 들어 노드의 이름이 'kubernetes-foo-node-1.c.a-robinson.internal' 이고, 원하는 레이블이 'disktype=ssd' 라면, `kubectl label nodes ubernetes-foo-node-1.c.a-robinson.internal disktype=ssd` 를 실행 한다. +`kubectl get nodes` 를 실행해서 클러스터 노드 이름을 가져온다. 이 중에 레이블을 추가하기 원하는 것 하나를 선택한 다음에 `kubectl label nodes <노드 이름> <레이블 키>=<레이블 값>` 을 실행해서 선택한 노드에 레이블을 추가한다. 예를 들어 노드의 이름이 'kubernetes-foo-node-1.c.a-robinson.internal' 이고, 원하는 레이블이 'disktype=ssd' 라면, `kubectl label nodes ubernetes-foo-node-1.c.a-robinson.internal disktype=ssd` 를 실행한다. `kubectl get nodes --show-labels` 를 다시 실행해서 노드가 현재 가진 레이블을 확인하여, 이 작업을 검증할 수 있다. 또한 `kubectl describe node "노드 이름"` 을 사용해서 노드에 주어진 레이블의 전체 목록을 확인할 수 있다. ### 2 단계: 파드 설정에 nodeSelector 필드 추가하기 -실행하고자 하는 파드의 설정 파일을 가져오고, 이와 같이 nodeSelector 섹션을 추가한다. 예를 들어 이것이 파드 설정이라면: +실행하고자 하는 파드의 설정 파일을 가져오고, 이처럼 nodeSelector 섹션을 추가한다. 예를 들어 이것이 파드 설정이라면: ```yaml apiVersion: v1 @@ -97,25 +97,25 @@ spec: `NodeRestriction` 어드미션 플러그인은 kubelet이 `node-restriction.kubernetes.io/` 접두사로 레이블을 설정 또는 수정하지 못하게 한다. 노드 격리에 해당 레이블 접두사를 사용하려면 다음과 같이 한다. -1. [노드 권한부여자](/docs/reference/access-authn-authz/node/)를 사용하고 있고, [NodeRestriction 어드미션 플러그인](/docs/reference/access-authn-authz/admission-controllers/#noderestriction)을 _활성화_ 해야한다. +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` 는 파드를 특정 레이블이 있는 도느로 제한하는 매우 간단한 방법을 제공한다. +`nodeSelector` 는 파드를 특정 레이블이 있는 노드로 제한하는 매우 간단한 방법을 제공한다. 어피니티/안티-어피니티 기능은 표현할 수 있는 제약 종류를 크게 확장한다. 주요 개선 사항은 다음과 같다. 1. 언어가 보다 표현적이다("AND 또는 정확한 일치" 만이 아니다). -2. 규칙이 엄격한 요구사항이 아니라 "유연한(soft)"/"선호(preference)" 규칙을 나타낼 수 있기에 스케줄러가 규칙을 만족할 수 없다면, +2. 규칙이 엄격한 요구 사항이 아니라 "유연한(soft)"/"선호(preference)" 규칙을 나타낼 수 있기에 스케줄러가 규칙을 만족할 수 없다면, 파드는 계속 스케줄 되도록 한다. -3. 노드 자체에 레이블을 붙이기 보다는 노드(또는 다른 토폴로지 도메인)에서 실행중인 다른 파드의 레이블을 제한할 수 있다. +3. 노드 자체에 레이블을 붙이기보다는 노드(또는 다른 토폴로지 도메인)에서 실행 중인 다른 파드의 레이블을 제한할 수 있다. 이를 통해 어떤 파드가 함께 위치할 수 있는지와 없는지에 대한 규칙을 적용할 수 있다. 어피니티 기능은 "노드 어피니티" 와 "파드 간 어피니티/안티-어피니티" 두 종류의 어피니티로 구성된다. -노드 어피니티는 기존 `nodeSelector` 와 비슷하지만(그러나 위에서 나열된 첫 째와 두번째 이점이 있다.), +노드 어피니티는 기존 `nodeSelector` 와 비슷하지만(그러나 위에서 나열된 첫째와 두 번째 이점이 있다.), 파드 간 어피니티/안티-어피니티는 위에서 나열된 세번째 항목에 설명된 대로 -노드 레이블이 아닌 파드 레이블에 대해 제한되고 위에서 나열된 첫번째와 두번째 속성을 가진다. +노드 레이블이 아닌 파드 레이블에 대해 제한되고 위에서 나열된 첫 번째와 두 번째 속성을 가진다. ### 노드 어피니티 @@ -149,98 +149,98 @@ spec: 특정 노드에서 파드를 쫓아내는 [노드 테인트(taint)](/docs/concepts/configuration/taint-and-toleration/)를 할 수 있다. `nodeSelector` 와 `nodeAffinity` 를 모두 지정한다면 파드가 후보 노드에 스케줄 되기 위해서는 -*둘 다* 반드시 만족해야한다. +*둘 다* 반드시 만족해야 한다. -`nodeAffinity` 유형과 연관된 `nodeSelectorTerms` 를 지정하면, 파드를 `nodeSelectorTerms` 가 지정된 것 중 **하 가지**라도 만족하는 노드에 스케줄 할 수 있다. +`nodeAffinity` 유형과 연관된 `nodeSelectorTerms` 를 지정하면, 파드를 `nodeSelectorTerms` 가 지정된 것 중 **한 가지**라도 만족하는 노드에 스케줄할 수 있다. `nodeSelectorTerms` 와 연관된 여러 `matchExpressions` 를 지정하면, 파드는 `matchExpressions` 를 **모두** 만족하는 노드에만 스케줄할 수 있다. -파드가 스케줄된 노드의 레이블을 지우거나 변경해도 파드는 제거되지 않는다. 다시 말해서 어피니티 선택은 파드를 스케줄링 하는 시점에만 작동한다. +파드가 스케줄 된 노드의 레이블을 지우거나 변경해도 파드는 제거되지 않는다. 다시 말해서 어피니티 선택은 파드를 스케줄링 하는 시점에만 작동한다. -`preferredDuringSchedulingIgnoredDuringExecution` 의 `weight` 필드의 범위는 1-100 이다. 모든 스케줄링 요구사항 (리소스 요청, RequiredDuringScheduling 어피니티 표현식 등)을 만족하는 각 노드들에 대해 스케줄러는 이 필드의 요소들을 반복해서 합계를 계산하고 노드가 MatchExpressions 에 일치하는 경우 합계에 "가중치(weight)"를 추가 한다. 이후에 이 점수는 노드에 대한 다른 우선순위 함수의 점수와 합쳐진다. 전체 점수가 가장 높은 노드를 가장 선호한다. +`preferredDuringSchedulingIgnoredDuringExecution` 의 `weight` 필드의 범위는 1-100이다. 모든 스케줄링 요구 사항 (리소스 요청, RequiredDuringScheduling 어피니티 표현식 등)을 만족하는 각 노드들에 대해 스케줄러는 이 필드의 요소들을 반복해서 합계를 계산하고 노드가 MatchExpressions 에 일치하는 경우 합계에 "가중치(weight)"를 추가한다. 이후에 이 점수는 노드에 대한 다른 우선순위 함수의 점수와 합쳐진다. 전체 점수가 가장 높은 노드를 가장 선호한다. ### 파드간 어피니티와 안티-어피니티 -파드간 어피니티와 안티-어피니티는 파드를 노드의 레이블이 아니라 *노드에서 이미 동작 중인 파드들의 레이블을 기반으로* -동작할 수 있는 노드를 선택하게 할 수 있다. 이 규칙은 "이 파드는 반드시 Y 규칙을 만족하는 파드가 하나 이상 -동작중인 X에서만 동작할 수 있도록(안티-어피니티의 경우, 동작할수 없도록) 한다"는 형태로 구성되어있다. Y는 -네임스페이스와 관련된 선택적 목록을 가진 LabelSelector로 표현된다; 노드와는 다르게 파드는 네임스페이스 -기반(이는 파드의 레이블이 네임스페이스 기반임을 내포한다)이고 파트 레이블에 대한 레이블 셀렉터는 반드시 -셀렉터가 어느 네임스페이스에 적용되어야 하는지 지정해 주어야 하기 때문이다. 개념적으로 X는 노드, 랙, -클라우드 제공자 영역, 클라우드 제공자 리젼 등과 같은 토폴로지 도메인이다. 시스템이 사용하는 토폴로지 -도메인을 의미하는 노드 레이블의 키인 `topologyKey`를 사용하여 토폴로지 도메인을 표현할 수 있으며, +파드간 어피니티와 안티-어피니티는 파드를 노드의 레이블이 아니라 *노드에서 이미 동작 중인 파드들의 레이블을 기반으로* +동작할 수 있는 노드를 선택하게 할 수 있다. 이 규칙은 "이 파드는 반드시 Y 규칙을 만족하는 파드가 하나 이상 +동작 중인 X에서만 동작할 수 있도록(안티-어피니티의 경우, 동작할 수 없도록) 한다"는 형태로 구성되어 있다. Y는 +네임스페이스와 관련된 선택적 목록을 가진 LabelSelector로 표현된다; 노드와는 다르게 파드는 네임스페이스 +기반(이는 파드의 레이블이 네임스페이스 기반임을 내포한다)이고 파트 레이블에 대한 레이블 셀렉터는 반드시 +셀렉터가 어느 네임스페이스에 적용되어야 하는지 지정해 주어야 하기 때문이다. 개념적으로 X는 노드, 랙, +클라우드 제공자 영역, 클라우드 제공자 리젼 등과 같은 토폴로지 도메인이다. 시스템이 사용하는 토폴로지 +도메인을 의미하는 노드 레이블의 키인 `topologyKey` 를 사용하여 토폴로지 도메인을 표현할 수 있으며, 예시는 [넘어가기 전에: 빌트인 노드 레이블](#built-in-node-labels) 섹션에 나열된 레이블 키를 보면 된다. {{< note >}} -파드간 어피니티와 안티-어피니티는 상당한 양의 연산을 필요로 하여 -큰 클러스터에서는 스케쥴링을 상당히 느리게 할 수 있다. -수백개의 노드가 넘는 클러스터에서 이를 사용하는 것은 추천하지 않는다. +파드간 어피니티와 안티-어피니티는 상당한 양의 연산을 필요로 하여 +큰 클러스터에서는 스케줄링을 상당히 느리게 할 수 있다. +수백 개의 노드가 넘는 클러스터에서 이를 사용하는 것은 추천하지 않는다. {{< /note >}} {{< note >}} -파드 안티-어피니티는 노드가 일관적으로 레이블을 가지고 있어야 함을 전제로 한다. 예를들어 클러스터의 모든 노드는 `topologyKey`와 매칭되는 적절한 레이블을 가지고 있어야 한다. 일부 또는 모든 노드가 지정된 `topologyKey` 레이블이 없다면 이는 의도치 않은 동작을 일으킬 수 있다. +파드 안티-어피니티는 노드가 일관적으로 레이블을 가지고 있어야 함을 전제로 한다. 예를 들어 클러스터의 모든 노드는 `topologyKey` 와 매칭되는 적절한 레이블을 가지고 있어야 한다. 일부 또는 모든 노드가 지정된 `topologyKey` 레이블이 없다면 이는 의도치 않은 동작을 일으킬 수 있다. {{< /note >}} -노드 어피니티처럼 현재 각각 "엄격한"과 "유연한" 제약사항을 나타내는 `requiredDuringSchedulingIgnoredDuringExecution`와 -`preferredDuringSchedulingIgnoredDuringExecution`라고 하는 파드 어피니티와 안티 어피니티 두가지 종류가 있다. -앞선 노드 어피니티 섹션의 설명을 보면 된다. -`requiredDuringSchedulingIgnoredDuringExecution` 어피니티의 예시는 -"서비스 A와 서비스 B는 서로 많은 통신을 하기 때문에 각 서비스의 파드들을 동일한 영역에 위치시킨다."이고 +노드 어피니티처럼 현재 각각 "엄격한"과 "유연한" 제약사항을 나타내는 `requiredDuringSchedulingIgnoredDuringExecution` 와 +`preferredDuringSchedulingIgnoredDuringExecution` 라고 하는 파드 어피니티와 안티 어피니티 두 가지 종류가 있다. +앞선 노드 어피니티 섹션의 설명을 보면 된다. +`requiredDuringSchedulingIgnoredDuringExecution` 어피니티의 예시는 +"서비스 A와 서비스 B는 서로 많은 통신을 하기 때문에 각 서비스의 파드들을 동일한 영역에 위치시킨다."이고 `preferredDuringSchedulingIgnoredDuringExecution` 안티 어피니티의 예시는 "서비스를 여러 영역에 걸처 퍼트린다"가 될 것이다 (엄격한 제약조건은 파드가 영역의 수보다 많을 수 있기 때문에 말이 안된다). -파드간 어피니티는 파드 스펙에서 `affinity` 필드의 `podAffinity` 필드에서 지정할 수 있다. +파드간 어피니티는 파드 스펙에서 `affinity` 필드의 `podAffinity` 필드에서 지정할 수 있다. 그리고 파드간 안티-어피니티는 파드 스펙에서 `affinity` 필드의 `podAntiAffinity` 필드에서 지정할 수 있다. -#### 파드 어피니티를 사용하는 파드의 예시: +#### 파드 어피니티를 사용하는 파드의 예시 {{< codenew file="pods/pod-with-pod-affinity.yaml" >}} -이 파드에서의 어피니티는 하나의 파드 어피니티 규칙과 하나의 안티-어피니티 규칙을 정의한다. -이 예시에서 `podAffinity`는 `requiredDuringSchedulingIgnoredDuringExecution`이고 `podAntiAffinity`는 -`preferredDuringSchedulingIgnoredDuringExecution`이다. 파드 어피니티 규칙은 "security"를 키로하고 - "S1"을 값으로 하는 레이블을 가진 파드가 최소한 하나라도 동작 중인 한 노드에서만 스케쥴될 수 있다고 말하고 있다. -(더 정확하게는 파드가 `failure-domain.beta.kubernetes.io/zone`를 키로하고 V를 값으로 하는 -클러스터의 노드가 "security"를 키로하고 "S1"을 값으로 하는 레이블을 가진 파드를 동작시키고 있는 것과 같이 -노드 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`의 +이 파드에서의 어피니티는 하나의 파드 어피니티 규칙과 하나의 안티-어피니티 규칙을 정의한다. +이 예시에서 `podAffinity` 는 `requiredDuringSchedulingIgnoredDuringExecution` 이고 `podAntiAffinity` 는 +`preferredDuringSchedulingIgnoredDuringExecution` 이다. 파드 어피니티 규칙은 "security"를 키로 하고 + "S1"을 값으로 하는 레이블을 가진 파드가 최소한 하나라도 동작 중인 한 노드에서만 스케줄 될 수 있다고 말하고 있다. +(더 정확하게는 파드가 `failure-domain.beta.kubernetes.io/zone` 를 키로 하고 V를 값으로 하는 +클러스터의 노드가 "security"를 키로하고 "S1"을 값으로 하는 레이블을 가진 파드를 동작시키고 있는 것과 같이 +노드 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`가 있다. +파드 어피니티와 안티-어피니티에 대해 허용된 연산자는 `In`, `NotIn`, `Exists`, `DoesNotExist` 가 있다. -원칙적으로 `topologyKey`는 어느 규칙에 맞는 레이블-키도 될 수 있다. -하지만 성능과 보안상의 이유로 토폴로지 키에는 몇가지 제약사항이 있다: +원칙적으로 `topologyKey` 는 어느 규칙에 맞는 레이블-키도 될 수 있다. +하지만 성능과 보안상의 이유로 토폴로지 키에는 몇 가지 제약사항이 있다: -1. 어피니티와 `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 -`topologyKey`가 비어있는 것은 허용하지 않는다. -2. `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 어드미션 컨트롤러의 `LimitPodHardAntiAffinityTopology`는 `topologyKey`를 `kubernetes.io/hostname`으로 제한하기 위해 도입되었다. 사용자 정의 토폴로지를 이용하고자 할 경우 어드미션 컨트롤러를 수정하거나 간단하게 이를 비활성화 하면 된다. -3. `preferredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 `topologyKey`가 비어있는 경우 이를 "모든 토폴로지"("모든 토폴로지"는 현재 `kubernetes.io/hostname`, `failure-domain.beta.kubernetes.io/zone`, `failure-domain.beta.kubernetes.io/region`로 제한된다)로 해석한다. -4. 위의 경우를 제외하면 `topologyKey`는 어느 규칙에 맞는 레이블-키도 가능하다. +1. 어피니티와 `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 +`topologyKey` 가 비어있는 것은 허용하지 않는다. +2. `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 어드미션 컨트롤러의 `LimitPodHardAntiAffinityTopology` 는 `topologyKey` 를 `kubernetes.io/hostname` 으로 제한하기 위해 도입되었다. 사용자 정의 토폴로지를 이용하고자 할 경우 어드미션 컨트롤러를 수정하거나 간단하게 이를 비활성화하면 된다. +3. `preferredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 `topologyKey` 가 비어있는 경우 이를 "모든 토폴로지"("모든 토폴로지"는 현재 `kubernetes.io/hostname`, `failure-domain.beta.kubernetes.io/zone`, `failure-domain.beta.kubernetes.io/region`로 제한된다)로 해석한다. +4. 위의 경우를 제외하면 `topologyKey` 는 어느 규칙에 맞는 레이블-키도 가능하다. -`labelSelector`와 `topologyKey`외에도 `labelSelector`가 매칭되어야 하는 네임스페이스의 `namespaces` -리스트를 선택적으로 지정할 수 있다(이는 `labelSelector`와 `topologyKey`와 같은 개위로 작성되어야 한다). +`labelSelector` 와 `topologyKey` 외에도 `labelSelector` 가 매칭되어야 하는 네임스페이스의 `namespaces` +리스트를 선택적으로 지정할 수 있다(이는 `labelSelector` 와 `topologyKey` 와 같은 개위로 작성되어야 한다). 생략되어있거나 비어있을 경우 어피니티/안티-어피니티 정의가 있는 파드의 네임스페이스가 기본 값이다. -파드가 노드에 스케쥴되려면 `requiredDuringSchedulingIgnoredDuringExecution` 어피니티 및 안티-어피니티와 -관련된 모든 `matchExpressions`를 만족해야 한다. +파드가 노드에 스케줄 되려면 `requiredDuringSchedulingIgnoredDuringExecution` 어피니티 및 안티-어피니티와 +관련된 모든 `matchExpressions` 를 만족해야 한다. #### 더 실용적인 유스케이스 -파드간 어피니티와 안티-어피니티는 레플리카셋, 스테이트풀셋, 디플로이먼트 등과 같은 -상위 레벨의 컬렉션에 사용될 때 좀 더 유용할 수 있다. 이를 통해 같은 노드에 함께 위치시키는 것과 같이 +파드간 어피니티와 안티-어피니티는 레플리카셋, 스테이트풀셋, 디플로이먼트 등과 같은 +상위 레벨의 컬렉션에 사용될 때 좀 더 유용할 수 있다. 이를 통해 같은 노드에 함께 위치시키는 것과 같이 정의된 토폴로지와 동일한 곳에 함께 위치시키는 워크로드를 쉽게 구성할 수 있다. ##### 항상 같은 노드에 위치시키기 -세개의 노드를 가진 클러스터가 있는 상황에서 웹 어플리케이션은 redis와 같은 인메모리 캐시를 가지고 있다. 웹 서버를 캐시가 있는 위치와 동일한 곳으로 최대한 많이 위치시키고 싶다. +세 개의 노드를 가진 클러스터가 있는 상황에서 웹 어플리케이션은 redis와 같은 인메모리 캐시를 가지고 있다. 웹 서버를 캐시가 있는 위치와 동일한 곳으로 최대한 많이 위치시키고 싶다. -이 짧은 yaml은 세개의 레플리카를 가지고 `app=store`라는 셀렉터 레이블을 가진 간단한 redis 디플로이먼트이다. 디플로이먼트는 `PodAntiAffinity` 설정이 있어 스케쥴러가 레플리카들을 하나의 노드에만 위치하지 않도록 한다. +이 짧은 yaml은 세 개의 레플리카를 가지고 `app=store` 라는 셀렉터 레이블을 가진 간단한 redis 디플로이먼트이다. 디플로이먼트는 `PodAntiAffinity` 설정이 있어 스케줄러가 레플리카들을 하나의 노드에만 위치하지 않도록 한다. ```yaml apiVersion: apps/v1 @@ -272,7 +272,7 @@ spec: image: redis:3.2-alpine ``` -아래의 짧은 yaml은 웹서버 디플로이먼트가 `podAntiAffinity`와 `podAffinity` 설정을 가진 것이다. 이는 스케쥴러에게 이 레플리카들이 `app=store`라는 셀렉터 레이블을 가진 파드와 함께 위치시키고 싶다는 것을 알려준다. 또한 웹서버 레플리카가 하나의 노드에만 위치하지 않도록 한다. +아래의 짧은 yaml은 웹서버 디플로이먼트가 `podAntiAffinity` 와 `podAffinity` 설정을 가진 것이다. 이는 스케줄러에게 이 레플리카들이 `app=store` 라는 셀렉터 레이블을 가진 파드와 함께 위치시키고 싶다는 것을 알려준다. 또한 웹서버 레플리카가 하나의 노드에만 위치하지 않도록 한다. ```yaml apiVersion: apps/v1 @@ -313,14 +313,14 @@ spec: image: nginx:1.12-alpine ``` -위의 두 디플로이먼트를 생성하면 세개의 노드를 가진 클러스터는 다음과 같이 보일 것이다. +위의 두 디플로이먼트를 생성하면 세 개의 노드를 가진 클러스터는 다음과 같이 보일 것이다. | node-1 | node-2 | node-3 | |:--------------------:|:-------------------:|:------------------:| | *webserver-1* | *webserver-2* | *webserver-3* | | *cache-1* | *cache-2* | *cache-3* | -여기서 볼 수 있듯이 `web-server`의 세 레플리카들이 기대했던 것처럼 알아서 캐시와 함께 위치하게 되었다. +여기서 볼 수 있듯이 `web-server` 의 세 레플리카들이 기대했던 것처럼 알아서 캐시와 함께 위치하게 되었다. ``` kubectl get pods -o wide @@ -338,22 +338,22 @@ web-server-1287567482-s330j 1/1 Running 0 7m 10.192.3 ##### 절대 동일한 노드에 위치시키지 않게 하기 -위의 예시는 `PodAntiAffinity` 규칙을 `topologyKey:"kubernetes.io/hostname"`과 함께 사용하여 -redis 클러스터가 하나의 호스트에 두개 이상 위치하지 않도록 배포한다. -[ZooKeeper 튜토리얼](/docs/tutorials/stateful-application/zookeeper/#tolerating-node-failure)을 통해 +위의 예시는 `PodAntiAffinity` 규칙을 `topologyKey:"kubernetes.io/hostname"` 과 함께 사용하여 +redis 클러스터가 하나의 호스트에 두 개 이상 위치하지 않도록 배포한다. +[ZooKeeper 튜토리얼](/docs/tutorials/stateful-application/zookeeper/#tolerating-node-failure)을 통해 같은 방법을 사용하여 스테이트풀셋을 고가용성을 위해 안티-어피니티 설정을 한 예시를 확인할 수 있다. ## nodeName -`nodeName` 노드 셀렉션을 하는 가장 간단한 형태이지만 -자체의 한계때문에 일반적으로 사용하지는 않는다. -`nodeName`은 파드 스펙의 필드이다. 비어있지 않다면 스케쥴러는 -이 파트를 무시하게 되고 해당되는 노드에서 동작중인 kubelet이 -파드를 실행하려 할 것이다. 따라서 `nodeName`이 파드 스펙에 +`nodeName` 노드 셀렉션을 하는 가장 간단한 형태이지만 +자체의 한계 때문에 일반적으로 사용하지는 않는다. +`nodeName` 은 파드 스펙의 필드이다. 비어있지 않다면 스케줄러는 +이 파트를 무시하게 되고 해당되는 노드에서 동작 중인 kubelet이 +파드를 실행하려 할 것이다. 따라서 `nodeName` 이 파드 스펙에 제공되면 노드 셀렉션에 대한 위의 방법들 중 가장 우선시된다. -`nodeName`으로 노드를 선택하는 것의 제약사항이 몇가지 있다: - +`nodeName` 으로 노드를 선택하는 것의 제약사항이 몇 가지 있다: + - 그 이름을 가진 노드가 없을 경우 파드는 실행되지 않을 것이고 몇몇 경우에는 자동으로 삭제된다. - 그 이름을 가진 노드가 파드를 실행하기 위한 @@ -384,12 +384,12 @@ spec: [테인트(Taints)](/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)에 대한 디자인 문서는 +[노드 어피니티](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/)는 +파드가 노드에 할당되고 나면 kubelet은 파드를 실행하고 노드의 로컬 리소스를 할당한다. +[토폴로지 매니저](/docs/tasks/administer-cluster/topology-manager/)는 노드 레벨의 리소스 할당 결정의 일부분이 될 수 있다. {{% /capture %}} From d3483b8984a43bc4e611383ae94833fdc20686f1 Mon Sep 17 00:00:00 2001 From: KimMJ Date: Sun, 2 Feb 2020 04:28:36 +0900 Subject: [PATCH 11/12] =?UTF-8?q?=EB=9D=BC=EC=9D=B8=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../concepts/configuration/assign-pod-node.md | 48 ++++++++++--------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/content/ko/docs/concepts/configuration/assign-pod-node.md b/content/ko/docs/concepts/configuration/assign-pod-node.md index cbc07d76852c7..7088e8e3e36d3 100644 --- a/content/ko/docs/concepts/configuration/assign-pod-node.md +++ b/content/ko/docs/concepts/configuration/assign-pod-node.md @@ -92,7 +92,8 @@ spec: 노드 오브젝트에 레이블을 추가하면 특정 노드 또는 노드 그룹에 파드를 대상으로 할 수 있다. 이는 특정 파드가 어떤 격리, 보안, 또는 규제 속성이 있는 노드에서만 실행되도록 사용할 수 있다. 이 목적으로 레이블을 사용하는 경우, 노드에서 kubelet 프로세스로 수정할 수 없는 레이블 키를 선택하는 것을 권장한다. -이렇게 하면 손상된 노드가 해당 kubelet 자격 증명을 사용해서 해당 레이블을 자체 노드 오브젝트에 설정하고, 스케줄러가 손상된 노드로 워크로드를 스케줄 하는 것을 방지할 수 있다. +이렇게 하면 손상된 노드가 해당 kubelet 자격 증명을 사용해서 해당 레이블을 자체 노드 오브젝트에 설정하고, +스케줄러가 손상된 노드로 워크로드를 스케줄 하는 것을 방지할 수 있다. `NodeRestriction` 어드미션 플러그인은 kubelet이 `node-restriction.kubernetes.io/` 접두사로 레이블을 설정 또는 수정하지 못하게 한다. 노드 격리에 해당 레이블 접두사를 사용하려면 다음과 같이 한다. @@ -123,11 +124,14 @@ spec: 스케줄할 수 있는 노드를 제한할 수 있다. 여기에 현재 `requiredDuringSchedulingIgnoredDuringExecution` 와 `preferredDuringSchedulingIgnoredDuringExecution` 로 부르는 -두 가지 종류의 노드 어피니티가 있다. 전자는 파드가 노드에 스케줄 되도록 *반드시* 규칙을 만족해야 하는 것(`nodeSelector` 와 같으나 보다 표현적인 구문을 사용해서)을 지정하고, -후자는 스케줄러가 시도하려고는 하지만, 보증하지 않는 *선호(preferences)*를 지정한다는 점에서 이를 각각 "엄격함(hard)" 과 "유연함(soft)" 하다고 생각할 수 있다. +두 가지 종류의 노드 어피니티가 있다. 전자는 파드가 노드에 스케줄 되도록 *반드시* +규칙을 만족해야 하는 것(`nodeSelector` 와 같으나 보다 표현적인 구문을 사용해서)을 지정하고, +후자는 스케줄러가 시도하려고는 하지만, 보증하지 않는 *선호(preferences)*를 지정한다는 점에서 +이를 각각 "엄격함(hard)" 과 "유연함(soft)" 하다고 생각할 수 있다. 이름의 "IgnoredDuringExecution" 부분은 `nodeSelector` 작동 방식과 유사하게 노드의 레이블이 런타임 중에 변경되어 파드의 어피니티 규칙이 더 이상 충족되지 않으면 파드가 여전히 그 노드에서 -동작한다는 의미이다. 향후에는 파드의 노드 어피니티 요구 사항을 충족하지 않는 노드에서 파드를 제거한다는 점을 제외하고는 `preferredDuringSchedulingIgnoredDuringExecution` 와 같은 `requiredDuringSchedulingIgnoredDuringExecution` 를 제공할 계획이다. +동작한다는 의미이다. 향후에는 파드의 노드 어피니티 요구 사항을 충족하지 않는 노드에서 파드를 제거한다는 +점을 제외하고는 `preferredDuringSchedulingIgnoredDuringExecution` 와 같은 `requiredDuringSchedulingIgnoredDuringExecution` 를 제공할 계획이다. 따라서 `requiredDuringSchedulingIgnoredDuringExecution` 의 예로는 "인텔 CPU가 있는 노드에서만 파드 실행"이 될 수 있고, `preferredDuringSchedulingIgnoredDuringExecution` 의 예로는 "장애 조치 영역 XYZ에 파드 집합을 실행하려고 @@ -161,7 +165,7 @@ spec: ### 파드간 어피니티와 안티-어피니티 -파드간 어피니티와 안티-어피니티는 파드를 노드의 레이블이 아니라 *노드에서 이미 동작 중인 파드들의 레이블을 기반으로* +파드간 어피니티와 안티-어피니티는 파드를 노드의 레이블이 아닌 *노드에서 이미 동작 중인 파드들의 레이블을 기반으로* 동작할 수 있는 노드를 선택하게 할 수 있다. 이 규칙은 "이 파드는 반드시 Y 규칙을 만족하는 파드가 하나 이상 동작 중인 X에서만 동작할 수 있도록(안티-어피니티의 경우, 동작할 수 없도록) 한다"는 형태로 구성되어 있다. Y는 네임스페이스와 관련된 선택적 목록을 가진 LabelSelector로 표현된다; 노드와는 다르게 파드는 네임스페이스 @@ -185,12 +189,12 @@ spec: `preferredDuringSchedulingIgnoredDuringExecution` 라고 하는 파드 어피니티와 안티 어피니티 두 가지 종류가 있다. 앞선 노드 어피니티 섹션의 설명을 보면 된다. `requiredDuringSchedulingIgnoredDuringExecution` 어피니티의 예시는 -"서비스 A와 서비스 B는 서로 많은 통신을 하기 때문에 각 서비스의 파드들을 동일한 영역에 위치시킨다."이고 -`preferredDuringSchedulingIgnoredDuringExecution` 안티 어피니티의 예시는 "서비스를 여러 영역에 걸처 퍼트린다"가 될 것이다 +"서비스 A와 서비스 B는 서로 많은 통신을 하기 때문에 각 서비스의 파드들을 동일한 영역에 위치시킨다"고 +`preferredDuringSchedulingIgnoredDuringExecution` 안티 어피니티의 예시는 "서비스를 여러 영역에 걸처 퍼트린다"이다 (엄격한 제약조건은 파드가 영역의 수보다 많을 수 있기 때문에 말이 안된다). -파드간 어피니티는 파드 스펙에서 `affinity` 필드의 `podAffinity` 필드에서 지정할 수 있다. -그리고 파드간 안티-어피니티는 파드 스펙에서 `affinity` 필드의 `podAntiAffinity` 필드에서 지정할 수 있다. +파드간 어피니티는 PodSpec에서 `affinity` 필드의 `podAffinity` 필드에서 지정할 수 있다. +그리고 파드간 안티-어피니티는 PodSpec에서 `affinity` 필드의 `podAntiAffinity` 필드에서 지정할 수 있다. #### 파드 어피니티를 사용하는 파드의 예시 @@ -199,29 +203,29 @@ spec: 이 파드에서의 어피니티는 하나의 파드 어피니티 규칙과 하나의 안티-어피니티 규칙을 정의한다. 이 예시에서 `podAffinity` 는 `requiredDuringSchedulingIgnoredDuringExecution` 이고 `podAntiAffinity` 는 `preferredDuringSchedulingIgnoredDuringExecution` 이다. 파드 어피니티 규칙은 "security"를 키로 하고 - "S1"을 값으로 하는 레이블을 가진 파드가 최소한 하나라도 동작 중인 한 노드에서만 스케줄 될 수 있다고 말하고 있다. + "S1"을 값으로 하는 레이블을 가진 파드가 최소한 하나라도 동작 중인 한 노드에서만 스케줄 될 수 있다고 말하고 있다 (더 정확하게는 파드가 `failure-domain.beta.kubernetes.io/zone` 를 키로 하고 V를 값으로 하는 클러스터의 노드가 "security"를 키로하고 "S1"을 값으로 하는 레이블을 가진 파드를 동작시키고 있는 것과 같이 -노드 N이 `failure-domain.beta.kubernetes.io/zone` 을 키로 하고 어떤 V를 값으로 하는 레이블이 있는 노드 N에 뜨기에 적합하다.) +노드 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` 파드 안티-어피니티에 대해 어드미션 컨트롤러의 `LimitPodHardAntiAffinityTopology` 는 `topologyKey` 를 `kubernetes.io/hostname` 으로 제한하기 위해 도입되었다. 사용자 정의 토폴로지를 이용하고자 할 경우 어드미션 컨트롤러를 수정하거나 간단하게 이를 비활성화하면 된다. 3. `preferredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 `topologyKey` 가 비어있는 경우 이를 "모든 토폴로지"("모든 토폴로지"는 현재 `kubernetes.io/hostname`, `failure-domain.beta.kubernetes.io/zone`, `failure-domain.beta.kubernetes.io/region`로 제한된다)로 해석한다. -4. 위의 경우를 제외하면 `topologyKey` 는 어느 규칙에 맞는 레이블-키도 가능하다. +4. 위의 경우를 제외하면 `topologyKey` 는 규칙에 맞는 어느 레이블-키도 가능하다. `labelSelector` 와 `topologyKey` 외에도 `labelSelector` 가 매칭되어야 하는 네임스페이스의 `namespaces` 리스트를 선택적으로 지정할 수 있다(이는 `labelSelector` 와 `topologyKey` 와 같은 개위로 작성되어야 한다). @@ -240,7 +244,7 @@ spec: 세 개의 노드를 가진 클러스터가 있는 상황에서 웹 어플리케이션은 redis와 같은 인메모리 캐시를 가지고 있다. 웹 서버를 캐시가 있는 위치와 동일한 곳으로 최대한 많이 위치시키고 싶다. -이 짧은 yaml은 세 개의 레플리카를 가지고 `app=store` 라는 셀렉터 레이블을 가진 간단한 redis 디플로이먼트이다. 디플로이먼트는 `PodAntiAffinity` 설정이 있어 스케줄러가 레플리카들을 하나의 노드에만 위치하지 않도록 한다. +이 짧은 yaml은 세 개의 레플리카를 가지고 `app=store` 라는 셀렉터 레이블을 가진 간단한 redis 디플로이먼트이다. 디플로이먼트는 `PodAntiAffinity` 설정이 있어 스케줄러가 레플리카들이 하나의 노드에만 위치하지 않도록 한다. ```yaml apiVersion: apps/v1 @@ -347,12 +351,12 @@ redis 클러스터가 하나의 호스트에 두 개 이상 위치하지 않도 `nodeName` 노드 셀렉션을 하는 가장 간단한 형태이지만 자체의 한계 때문에 일반적으로 사용하지는 않는다. -`nodeName` 은 파드 스펙의 필드이다. 비어있지 않다면 스케줄러는 +`nodeName` 은 PodSpec의 필드이다. 비어있지 않다면 스케줄러는 이 파트를 무시하게 되고 해당되는 노드에서 동작 중인 kubelet이 -파드를 실행하려 할 것이다. 따라서 `nodeName` 이 파드 스펙에 +파드를 실행하려 할 것이다. 따라서 `nodeName` 이 PodSpec에 제공되면 노드 셀렉션에 대한 위의 방법들 중 가장 우선시된다. -`nodeName` 으로 노드를 선택하는 것의 제약사항이 몇 가지 있다: +`nodeName` 으로 노드를 선택하는 것에는 제약사항이 몇 가지 있다. - 그 이름을 가진 노드가 없을 경우 파드는 실행되지 않을 것이고 몇몇 경우에는 자동으로 삭제된다. @@ -362,7 +366,7 @@ redis 클러스터가 하나의 호스트에 두 개 이상 위치하지 않도 - 클라우드 환경에서의 노드 이름은 항상 예측이 가능하거나 안정적인 것이 아니다. -`nodeName` 필드를 사용한 파드 설정 파일의 예시이다: +`nodeName` 필드를 사용한 파드 설정 파일의 예시이다. ```yaml apiVersion: v1 @@ -376,7 +380,7 @@ spec: nodeName: kube-01 ``` -우의 파드는 kube-01 노드에서 동작할 것이다. +위의 파드는 kube-01 노드에서 동작할 것이다. {{% /capture %}} From dca6210f27b3026beffc4e61539f087b6d331197 Mon Sep 17 00:00:00 2001 From: KimMJ Date: Sun, 2 Feb 2020 17:25:58 +0900 Subject: [PATCH 12/12] =?UTF-8?q?commnet=202=EC=B0=A8=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../concepts/configuration/assign-pod-node.md | 152 +++++++++--------- 1 file changed, 76 insertions(+), 76 deletions(-) diff --git a/content/ko/docs/concepts/configuration/assign-pod-node.md b/content/ko/docs/concepts/configuration/assign-pod-node.md index 7088e8e3e36d3..5b8447019d7ec 100644 --- a/content/ko/docs/concepts/configuration/assign-pod-node.md +++ b/content/ko/docs/concepts/configuration/assign-pod-node.md @@ -165,86 +165,86 @@ spec: ### 파드간 어피니티와 안티-어피니티 -파드간 어피니티와 안티-어피니티는 파드를 노드의 레이블이 아닌 *노드에서 이미 동작 중인 파드들의 레이블을 기반으로* -동작할 수 있는 노드를 선택하게 할 수 있다. 이 규칙은 "이 파드는 반드시 Y 규칙을 만족하는 파드가 하나 이상 -동작 중인 X에서만 동작할 수 있도록(안티-어피니티의 경우, 동작할 수 없도록) 한다"는 형태로 구성되어 있다. Y는 -네임스페이스와 관련된 선택적 목록을 가진 LabelSelector로 표현된다; 노드와는 다르게 파드는 네임스페이스 -기반(이는 파드의 레이블이 네임스페이스 기반임을 내포한다)이고 파트 레이블에 대한 레이블 셀렉터는 반드시 -셀렉터가 어느 네임스페이스에 적용되어야 하는지 지정해 주어야 하기 때문이다. 개념적으로 X는 노드, 랙, -클라우드 제공자 영역, 클라우드 제공자 리젼 등과 같은 토폴로지 도메인이다. 시스템이 사용하는 토폴로지 -도메인을 의미하는 노드 레이블의 키인 `topologyKey` 를 사용하여 토폴로지 도메인을 표현할 수 있으며, -예시는 [넘어가기 전에: 빌트인 노드 레이블](#built-in-node-labels) 섹션에 나열된 레이블 키를 보면 된다. +파드간 어피니티와 안티-어피니티를 사용하면 노드의 레이블을 기반으로 하지 않고, *노드에서 이미 실행 중인 파드 레이블을 기반으로* +파드가 스케줄될 수 있는 노드를 제한할 수 있다. 규칙은 "X가 규칙 Y를 충족하는 하나 이상의 파드를 이미 실행중인 경우 +이 파드는 X에서 실행해야한다(또는 안티-어피니티가 없는 경우에는 동작하면 안된다)는 형태이다. Y는 +선택적으로 연관된 네임스페이스 목록을 가진 LabelSelector로 표현된다. 노드와는 다르게 파드는 네임스페이스이기에 +(그리고 따라서 파드의 레이블은 암암리에 네임스페이스이다) 파드 레이블위의 레이블 셀렉터는 반드시 +셀렉터가 적용될 네임스페이스를 지정해야만 한다. 개념적으로 X는 노드, 랙, +클라우드 공급자 영역, 클라우드 공급자 지역 등과 같은 토폴로지 도메인이다. 시스템이 이런 토폴로지 +도메인을 나타내는 데 사용하는 노드 레이블 키인 `topologyKey` 를 사용하여 이를 표현한다. +예: [넘어가기 전에: 빌트인 노드 레이블](#built-in-node-labels) 섹션 위에 나열된 레이블 키를 본다. {{< note >}} -파드간 어피니티와 안티-어피니티는 상당한 양의 연산을 필요로 하여 -큰 클러스터에서는 스케줄링을 상당히 느리게 할 수 있다. -수백 개의 노드가 넘는 클러스터에서 이를 사용하는 것은 추천하지 않는다. +파드간 어피니티와 안티-어피니티에는 상당한 양의 프로세싱이 필요하기에 +대규모 클러스터에서는 스케줄링 속도가 크게 느려질 수 있다. +수백 개의 노드를 넘어가는 클러스터에서 이를 사용하는 것은 추천하지 않는다. {{< /note >}} {{< note >}} -파드 안티-어피니티는 노드가 일관적으로 레이블을 가지고 있어야 함을 전제로 한다. 예를 들어 클러스터의 모든 노드는 `topologyKey` 와 매칭되는 적절한 레이블을 가지고 있어야 한다. 일부 또는 모든 노드가 지정된 `topologyKey` 레이블이 없다면 이는 의도치 않은 동작을 일으킬 수 있다. +파드 안티-어피니티에서는 노드에 일관된 레이블을 지정해야 한다. 즉, 클러스터의 모든 노드는 `topologyKey` 와 매칭되는 적절한 레이블이 가지고 있어야 한다. 일부 또는 모든 노드에 지정된 `topologyKey` 레이블이 없는 경우에는 의도하지 않은 동작을 발생할 수 있다. {{< /note >}} -노드 어피니티처럼 현재 각각 "엄격한"과 "유연한" 제약사항을 나타내는 `requiredDuringSchedulingIgnoredDuringExecution` 와 -`preferredDuringSchedulingIgnoredDuringExecution` 라고 하는 파드 어피니티와 안티 어피니티 두 가지 종류가 있다. -앞선 노드 어피니티 섹션의 설명을 보면 된다. +노드 어피니티와 마찬가지로 현재 파드 어피니티와 안티-어피니티로 부르는 "엄격함" 대 "유연함"의 요구사항을 나타내는 `requiredDuringSchedulingIgnoredDuringExecution` 와 +`preferredDuringSchedulingIgnoredDuringExecution` 두 가지 종류가 있다. +앞의 노드 어피니티 섹션의 설명을 보면 본다. `requiredDuringSchedulingIgnoredDuringExecution` 어피니티의 예시는 -"서비스 A와 서비스 B는 서로 많은 통신을 하기 때문에 각 서비스의 파드들을 동일한 영역에 위치시킨다"고 -`preferredDuringSchedulingIgnoredDuringExecution` 안티 어피니티의 예시는 "서비스를 여러 영역에 걸처 퍼트린다"이다 -(엄격한 제약조건은 파드가 영역의 수보다 많을 수 있기 때문에 말이 안된다). +"서로 많은 통신을 하기 때문에 서비스 A와 서비스 B를 같은 영역에 함께 위치시키는 것"이고, +`preferredDuringSchedulingIgnoredDuringExecution` 안티-어피니티의 예시는 "서비스를 여러 영역에 걸쳐서 분배하는 것"이다 +(엄격한 요구사항은 영역보다 파드가 더 많을 수 있기 때문에 엄격한 요구사항은 의미가 없다). -파드간 어피니티는 PodSpec에서 `affinity` 필드의 `podAffinity` 필드에서 지정할 수 있다. -그리고 파드간 안티-어피니티는 PodSpec에서 `affinity` 필드의 `podAntiAffinity` 필드에서 지정할 수 있다. +파드간 어피니티는 PodSpec에서 `affinity` 필드 중 `podAffinity` 필드로 지정한다. +그리고 파드간 안티-어피니티는 PodSpec에서 `affinity` 필드 중 `podAntiAffinity` 필드로 지정한다. #### 파드 어피니티를 사용하는 파드의 예시 {{< codenew file="pods/pod-with-pod-affinity.yaml" >}} -이 파드에서의 어피니티는 하나의 파드 어피니티 규칙과 하나의 안티-어피니티 규칙을 정의한다. +이 파드의 어피니티는 하나의 파드 어피니티 규칙과 하나의 파드 안티-어피니티 규칙을 정의한다. 이 예시에서 `podAffinity` 는 `requiredDuringSchedulingIgnoredDuringExecution` 이고 `podAntiAffinity` 는 -`preferredDuringSchedulingIgnoredDuringExecution` 이다. 파드 어피니티 규칙은 "security"를 키로 하고 - "S1"을 값으로 하는 레이블을 가진 파드가 최소한 하나라도 동작 중인 한 노드에서만 스케줄 될 수 있다고 말하고 있다 -(더 정확하게는 파드가 `failure-domain.beta.kubernetes.io/zone` 를 키로 하고 V를 값으로 하는 -클러스터의 노드가 "security"를 키로하고 "S1"을 값으로 하는 레이블을 가진 파드를 동작시키고 있는 것과 같이 -노드 N이 `failure-domain.beta.kubernetes.io/zone` 을 키로 하고 어떤 V를 값으로 하는 레이블이 있는 노드 N에 뜨기에 적합하다). -파드 안티-어피니티 규칙은 파드가 "security"를 키로 하고 "S2"를 값으로 하는 레이블을 가진 파드를 -실행시키고 있는 노드일 경우 해당 노드에 스케줄하지 않는 것을 선호한다고 말하고 있다 -(`topologyKey` 가 `failure-domain.beta.kubernetes.io/zone` 라면 이는 스케줄하고자 하는 파드가 -"security"를 키로 하고 "S2"를 값으로하는 레이블을 가진 파드를 실행하고 있는 노드와 -동일한 영역에 있는 노드들에 스케줄될 수 없음을 의미한다). +`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` 가 있다. +파드 어피니티와 안티-어피니티의 적합한 연산자는 `In`, `NotIn`, `Exists`, `DoesNotExist` 이다. -원칙적으로 `topologyKey` 는 규칙에 맞는 어느 레이블-키도 될 수 있다. -하지만 성능과 보안상의 이유로 토폴로지 키에는 몇 가지 제약사항이 있다. +원칙적으로, `topologyKey` 는 적법한 어느 레이블-키도 될 수 있다. +하지만, 성능과 보안상의 이유로 topologyKey에는 몇 가지 제약조건이 있다. -1. 어피니티와 `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 -`topologyKey` 가 비어있는 것은 허용하지 않는다. -2. `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 어드미션 컨트롤러의 `LimitPodHardAntiAffinityTopology` 는 `topologyKey` 를 `kubernetes.io/hostname` 으로 제한하기 위해 도입되었다. 사용자 정의 토폴로지를 이용하고자 할 경우 어드미션 컨트롤러를 수정하거나 간단하게 이를 비활성화하면 된다. -3. `preferredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에 대해 `topologyKey` 가 비어있는 경우 이를 "모든 토폴로지"("모든 토폴로지"는 현재 `kubernetes.io/hostname`, `failure-domain.beta.kubernetes.io/zone`, `failure-domain.beta.kubernetes.io/region`로 제한된다)로 해석한다. -4. 위의 경우를 제외하면 `topologyKey` 는 규칙에 맞는 어느 레이블-키도 가능하다. +1. 어피니티와 `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티는 대해 +`topologyKey` 가 비어있는 것을 허용하지 않는다. +2. `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에서 `topologyKey` 를 `kubernetes.io/hostname` 로 제한하기 위해 어드미션 컨트롤러 `LimitPodHardAntiAffinityTopology` 가 도입되었다. 사용자 지정 토폴로지를에 사용할 수 있도록 하려면, 어드미션 컨트롤러를 수정하거나 간단히 이를 비활성화 할 수 있다. +3. `preferredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티는 빈 `topologyKey` 를 "all topology"("all topology"는 현재 `kubernetes.io/hostname`, `failure-domain.beta.kubernetes.io/zone` 그리고 `failure-domain.beta.kubernetes.io/region` 의 조합으로 제한된다). +4. 위의 경우를 제외하고, `topologyKey` 는 적법한 어느 레이블-키도 가능하다. -`labelSelector` 와 `topologyKey` 외에도 `labelSelector` 가 매칭되어야 하는 네임스페이스의 `namespaces` -리스트를 선택적으로 지정할 수 있다(이는 `labelSelector` 와 `topologyKey` 와 같은 개위로 작성되어야 한다). +`labelSelector` 와 `topologyKey` 외에도 `labelSelector` 와 일치해야하는 네임스페이스 목록 `namespaces` 를 +선택적으로 지정할 수 있다(이것은 `labelSelector` 와 `topologyKey` 와 같은 수준의 정의이다). 생략되어있거나 비어있을 경우 어피니티/안티-어피니티 정의가 있는 파드의 네임스페이스가 기본 값이다. -파드가 노드에 스케줄 되려면 `requiredDuringSchedulingIgnoredDuringExecution` 어피니티 및 안티-어피니티와 -관련된 모든 `matchExpressions` 를 만족해야 한다. +파드를 노드에 스케줄하려면 `requiredDuringSchedulingIgnoredDuringExecution` 어피니티와 안티-어피니티와 +연관된 `matchExpressions` 가 모두 충족되어야 한다. #### 더 실용적인 유스케이스 파드간 어피니티와 안티-어피니티는 레플리카셋, 스테이트풀셋, 디플로이먼트 등과 같은 -상위 레벨의 컬렉션에 사용될 때 좀 더 유용할 수 있다. 이를 통해 같은 노드에 함께 위치시키는 것과 같이 -정의된 토폴로지와 동일한 곳에 함께 위치시키는 워크로드를 쉽게 구성할 수 있다. +상위 레벨 모음과 함께 사용할 때 더욱 유용할 수 있다. 워크로드 집합이 동일한 노드와 같이 +동일하게 정의된 토폴로지와 같은 위치에 배치되도록 쉽게 구성할 수 있다. ##### 항상 같은 노드에 위치시키기 -세 개의 노드를 가진 클러스터가 있는 상황에서 웹 어플리케이션은 redis와 같은 인메모리 캐시를 가지고 있다. 웹 서버를 캐시가 있는 위치와 동일한 곳으로 최대한 많이 위치시키고 싶다. +세 개의 노드가 있는 클러스터에서 웹 애플리케이션에는 redis와 같은 인-메모리 캐시가 있다. 웹 서버가 가능한 캐시와 함께 위치하기를 원한다. -이 짧은 yaml은 세 개의 레플리카를 가지고 `app=store` 라는 셀렉터 레이블을 가진 간단한 redis 디플로이먼트이다. 디플로이먼트는 `PodAntiAffinity` 설정이 있어 스케줄러가 레플리카들이 하나의 노드에만 위치하지 않도록 한다. +다음은 세 개의 레플리카와 셀렉터 레이블이 `app=store` 가 있는 간단한 redis 디플로이먼트의 yaml 스니펫이다. 디플로이먼트에는 스케줄러가 단일 노드에서 레플리카를 함꼐 배치하지 않도록 `PodAntiAffinity` 가 구성되어있다. ```yaml apiVersion: apps/v1 @@ -276,7 +276,7 @@ spec: image: redis:3.2-alpine ``` -아래의 짧은 yaml은 웹서버 디플로이먼트가 `podAntiAffinity` 와 `podAffinity` 설정을 가진 것이다. 이는 스케줄러에게 이 레플리카들이 `app=store` 라는 셀렉터 레이블을 가진 파드와 함께 위치시키고 싶다는 것을 알려준다. 또한 웹서버 레플리카가 하나의 노드에만 위치하지 않도록 한다. +아래 yaml 스니펫의 웹서버 디플로이먼트는 `podAntiAffinity` 와 `podAffinity` 설정을 가지고 있다. 이렇게 하면 스케줄러에 모든 레플리카는 셀렉터 레이블이 `app=store` 인 파드와 함꼐 위치해야 한다. 또한 각 웹 서버 레플리카가 단일 노드의 같은 위치에 있지 않도록 한다. ```yaml apiVersion: apps/v1 @@ -317,19 +317,19 @@ spec: image: nginx:1.12-alpine ``` -위의 두 디플로이먼트를 생성하면 세 개의 노드를 가진 클러스터는 다음과 같이 보일 것이다. +만약 위의 두 디플로이먼트를 생성하면 세 개의 노드가 있는 클러스터는 다음과 같아야 한다. | node-1 | node-2 | node-3 | |:--------------------:|:-------------------:|:------------------:| | *webserver-1* | *webserver-2* | *webserver-3* | | *cache-1* | *cache-2* | *cache-3* | -여기서 볼 수 있듯이 `web-server` 의 세 레플리카들이 기대했던 것처럼 알아서 캐시와 함께 위치하게 되었다. +여기서 볼 수 있듯이 `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 @@ -342,31 +342,31 @@ web-server-1287567482-s330j 1/1 Running 0 7m 10.192.3 ##### 절대 동일한 노드에 위치시키지 않게 하기 -위의 예시는 `PodAntiAffinity` 규칙을 `topologyKey:"kubernetes.io/hostname"` 과 함께 사용하여 -redis 클러스터가 하나의 호스트에 두 개 이상 위치하지 않도록 배포한다. -[ZooKeeper 튜토리얼](/docs/tutorials/stateful-application/zookeeper/#tolerating-node-failure)을 통해 -같은 방법을 사용하여 스테이트풀셋을 고가용성을 위해 안티-어피니티 설정을 한 예시를 확인할 수 있다. +위의 예시에서 `topologyKey:"kubernetes.io/hostname"` 과 함께 `PodAntiAffinity` 규칙을 사용해서 +두 개의 인스터스가 동일한 호스트에 있지 않도록 redis 클러스터를 배포한다. +같은 기술을 사용해서 고 가용성을 위해 안티-어피니티로 구성된 스테이트풀셋의 예시는 +[ZooKeeper 튜토리얼](/docs/tutorials/stateful-application/zookeeper/#tolerating-node-failure)을 본다. ## nodeName -`nodeName` 노드 셀렉션을 하는 가장 간단한 형태이지만 -자체의 한계 때문에 일반적으로 사용하지는 않는다. -`nodeName` 은 PodSpec의 필드이다. 비어있지 않다면 스케줄러는 -이 파트를 무시하게 되고 해당되는 노드에서 동작 중인 kubelet이 -파드를 실행하려 할 것이다. 따라서 `nodeName` 이 PodSpec에 -제공되면 노드 셀렉션에 대한 위의 방법들 중 가장 우선시된다. +`nodeName` 은 가장 간단한 형태의 노트 선택 제약 조건이지만, +한계로 인해 일반적으로는 사용하지 않는다. +`nodeName` 은 PodSpec의 필드이다. 만약 비어있지 않으면, 스케줄러는 +파드를 무시하고 명명된 노드에서 실행 중인 kubelet이 +파드를 실행하려고 한다. 따라서 만약 PodSpec에 `nodeName` 가 +제공된 경우, 노드 선텍을 위해 위의 방법보다 우선한다. -`nodeName` 으로 노드를 선택하는 것에는 제약사항이 몇 가지 있다. +`nodeName` 을 사용해서 노드를 선택할 때의 몇 가지 제한은 다음과 같다. -- 그 이름을 가진 노드가 없을 경우 파드는 실행되지 않을 것이고 - 몇몇 경우에는 자동으로 삭제된다. -- 그 이름을 가진 노드가 파드를 실행하기 위한 - 충분한 리소스가 없는 경우 파드의 실행은 실패하고 - OutOfmemory 또는 OutOfcpu와 같은 이유를 나타낼 것이다. -- 클라우드 환경에서의 노드 이름은 항상 예측이 가능하거나 - 안정적인 것이 아니다. +- 만약 명명된 노드가 없으면, 파드가 실행되지 않고 + 따라서 자동으로 삭제될 수 있다. +- 만약 명명된 노드에 파드를 수용할 수 있는 + 리소스가 없는 경우 파드가 실패하고, 그 이유는 다음과 같이 표시된다. + 예: OutOfmemory 또는 OutOfcpu. +- 클라우드 환경의 노드 이름은 항상 예측 가능하거나 + 안정적인 것은 아니다. -`nodeName` 필드를 사용한 파드 설정 파일의 예시이다. +여기에 `nodeName` 필드를 사용하는 파드 설정 파일 예시가 있다. ```yaml apiVersion: v1 @@ -380,7 +380,7 @@ spec: nodeName: kube-01 ``` -위의 파드는 kube-01 노드에서 동작할 것이다. +위 파드는 kube-01 노드에서 실행될 것이다. {{% /capture %}} @@ -389,11 +389,11 @@ spec: [테인트(Taints)](/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)에 대한 디자인 문서는 -이 기능들에 대한 추가적인 배경 정보를 포함한다. +[파드간 어피니티/안티-어피니티](https://git.k8s.io/community/contributors/design-proposals/scheduling/podaffinity.md)에 대한 디자인 문서에는 +이러한 기능에 대한 추가 배경 정보가 있다. -파드가 노드에 할당되고 나면 kubelet은 파드를 실행하고 노드의 로컬 리소스를 할당한다. +파드가 노드에 할당되면 kubelet은 파드를 실행하고 노드의 로컬 리소스를 할당한다. [토폴로지 매니저](/docs/tasks/administer-cluster/topology-manager/)는 -노드 레벨의 리소스 할당 결정의 일부분이 될 수 있다. +노드 수준의 리소스 할당 결정에 참여할 수 있다. {{% /capture %}}