diff --git a/content/ko/docs/concepts/containers/container-lifecycle-hooks.md b/content/ko/docs/concepts/containers/container-lifecycle-hooks.md index d9a1137024..fbf587344f 100644 --- a/content/ko/docs/concepts/containers/container-lifecycle-hooks.md +++ b/content/ko/docs/concepts/containers/container-lifecycle-hooks.md @@ -99,28 +99,28 @@ TERM 신호를 보내기 전에 실행을 완료해야 한다. 실행 중에 `Pr 예를 들어, 훅을 전송하는 도중에 kubelet이 재시작된다면, Kubelet이 구동된 후에 해당 훅은 재전송될 것이다. -### 디버깅 훅 핸들러 +### 훅 핸들러 디버깅 훅 핸들러의 로그는 파드 이벤트로 노출되지 않는다. 만약 핸들러가 어떠한 이유로 실패하면, 핸들러는 이벤트를 방송한다. `PostStart`의 경우, 이것은 `FailedPostStartHook` 이벤트이며, `PreStop`의 경우, 이것은 `FailedPreStopHook` 이벤트이다. -이 이벤트는 `kubectl describe pod <파드_이름>`를 실행하면 볼 수 있다. -다음은 이 커맨드 실행을 통한 이벤트 출력의 몇 가지 예다. +실패한 `FailedPreStopHook` 이벤트를 직접 생성하려면, [lifecycle-events.yaml](https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/pods/lifecycle-events.yaml) 파일을 수정하여 postStart 명령을 "badcommand"로 변경하고 이를 적용한다. +다음은 `kubectl describe pod lifecycle-demo` 실행을 통한 이벤트 출력 예시이다. ``` Events: - FirstSeen LastSeen Count From SubObjectPath Type Reason Message - --------- -------- ----- ---- ------------- -------- ------ ------- - 1m 1m 1 {default-scheduler } Normal Scheduled Successfully assigned test-1730497541-cq1d2 to gke-test-cluster-default-pool-a07e5d30-siqd - 1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Pulling pulling image "test:1.0" - 1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Created Created container with docker id 5c6a256a2567; Security:[seccomp=unconfined] - 1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Pulled Successfully pulled image "test:1.0" - 1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Started Started container with docker id 5c6a256a2567 - 38s 38s 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Killing Killing container with docker id 5c6a256a2567: PostStart handler: Error executing in Docker Container: 1 - 37s 37s 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Killing Killing container with docker id 8df9fdfd7054: PostStart handler: Error executing in Docker Container: 1 - 38s 37s 2 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} Warning FailedSync Error syncing pod, skipping: failed to "StartContainer" for "main" with RunContainerError: "PostStart handler: Error executing in Docker Container: 1" - 1m 22s 2 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Warning FailedPostStartHook + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal Scheduled 7s default-scheduler Successfully assigned default/lifecycle-demo to ip-XXX-XXX-XX-XX.us-east-2... + Normal Pulled 6s kubelet Successfully pulled image "nginx" in 229.604315ms + Normal Pulling 4s (x2 over 6s) kubelet Pulling image "nginx" + Normal Created 4s (x2 over 5s) kubelet Created container lifecycle-demo-container + Normal Started 4s (x2 over 5s) kubelet Started container lifecycle-demo-container + Warning FailedPostStartHook 4s (x2 over 5s) kubelet Exec lifecycle hook ([badcommand]) for Container "lifecycle-demo-container" in Pod "lifecycle-demo_default(30229739-9651-4e5a-9a32-a8f1688862db)" failed - error: command 'badcommand' exited with 126: , message: "OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: \"badcommand\": executable file not found in $PATH: unknown\r\n" + Normal Killing 4s (x2 over 5s) kubelet FailedPostStartHook + Normal Pulled 4s kubelet Successfully pulled image "nginx" in 215.66395ms + Warning BackOff 2s (x2 over 3s) kubelet Back-off restarting failed container ``` diff --git a/content/ko/docs/concepts/containers/images.md b/content/ko/docs/concepts/containers/images.md index d066719921..5ccd3e7e53 100644 --- a/content/ko/docs/concepts/containers/images.md +++ b/content/ko/docs/concepts/containers/images.md @@ -29,8 +29,7 @@ weight: 10 레지스트리 호스트 이름을 지정하지 않으면, 쿠버네티스는 도커 퍼블릭 레지스트리를 의미한다고 가정한다. -이미지 이름 부분 다음에 _tag_ 를 추가할 수 있다(`docker` 와 `podman` -등의 명령과 함께 사용). +이미지 이름 부분 다음에 _tag_ 를 추가할 수 있다(`docker` 또는 `podman` 과 같은 명령을 사용할 때와 동일한 방식으로). 태그를 사용하면 동일한 시리즈 이미지의 다른 버전을 식별할 수 있다. 이미지 태그는 소문자와 대문자, 숫자, 밑줄(`_`), @@ -91,7 +90,7 @@ weight: 10 `:`를 `@`로 교체한다. (예를 들어, `image@sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2`). -이미지 태그를 사용하는 경우, 이미지 레지스트리에서 한 이미지를 나타내는 태그에 코드를 변경하게 되면, 기존 코드와 신규 코드를 구동하는 파드가 섞이게 되고 만다. 이미지 다이제스트를 통해 이미지의 특정 버전을 유일하게 식별할 수 있기 때문에, 쿠버네티스는 매번 해당 이미지 이름과 다이제스트가 명시된 컨테이너를 기동해서 같은 코드를 구동한다. 이미지를 명시하는 것은 구동할 코드를 고정시켜서 레지스트리에서의 변경으로 인해 버전이 섞이는 일이 발생하지 않도록 해준다. +이미지 태그를 사용하는 경우, 이미지 레지스트리에서 한 이미지를 나타내는 태그에 코드를 변경하게 되면, 기존 코드와 신규 코드를 구동하는 파드가 섞이게 되고 만다. 이미지 다이제스트를 통해 이미지의 특정 버전을 유일하게 식별할 수 있기 때문에, 쿠버네티스는 매번 해당 이미지 이름과 다이제스트가 명시된 컨테이너를 기동해서 같은 코드를 구동한다. 이미지를 다이제스트로 명시하면 구동할 코드를 고정시켜서 레지스트리에서의 변경으로 인해 버전이 섞이는 일이 발생하지 않도록 해 준다. 파드(및 파드 템플릿)가 생성될 때 구동 중인 워크로드가 태그가 아닌 이미지 다이제스트를 통해 정의되도록 조작해주는 @@ -175,95 +174,11 @@ kubelet이 컨테이너 런타임을 사용하여 파드의 컨테이너 생성 ### 프라이빗 레지스트리에 인증하도록 노드 구성 -노드에서 도커를 실행하는 경우, 프라이빗 컨테이너 레지스트리를 인증하도록 -도커 컨테이너 런타임을 구성할 수 있다. +크리덴셜 설정에 대한 상세 지침은 사용하는 컨테이너 런타임 및 레지스트리에 따라 다르다. 가장 정확한 정보는 솔루션 설명서를 참조해야 한다. -이 방법은 노드 구성을 제어할 수 있는 경우에 적합하다. - -{{< note >}} -기본 쿠버네티스는 도커 구성에서 `auths` 와 `HttpHeaders` 섹션만 지원한다. -도커 자격 증명 도우미(`credHelpers` 또는 `credsStore`)는 지원되지 않는다. -{{< /note >}} - - -도커는 프라이빗 레지스트리를 위한 키를 `$HOME/.dockercfg` 또는 `$HOME/.docker/config.json` 파일에 저장한다. 만약 동일한 파일을 -아래의 검색 경로 리스트에 넣으면, kubelet은 이미지를 풀 할 때 해당 파일을 자격 증명 공급자로 사용한다. - -* `{--root-dir:-/var/lib/kubelet}/config.json` -* `{cwd of kubelet}/config.json` -* `${HOME}/.docker/config.json` -* `/.docker/config.json` -* `{--root-dir:-/var/lib/kubelet}/.dockercfg` -* `{cwd of kubelet}/.dockercfg` -* `${HOME}/.dockercfg` -* `/.dockercfg` - -{{< note >}} -kubelet 프로세스의 환경 변수에서 `HOME=/root` 를 명시적으로 설정해야 할 수 있다. -{{< /note >}} - -프라이빗 레지스트리를 사용도록 사용자의 노드를 구성하기 위해서 권장되는 단계는 다음과 같다. 이 -예제의 경우, 사용자의 데스크탑/랩탑에서 아래 내용을 실행한다. - - 1. 사용하고 싶은 각 자격 증명 세트에 대해서 `docker login [서버]`를 실행한다. 이것은 여러분 PC의 `$HOME/.docker/config.json`를 업데이트한다. - 1. 편집기에서 `$HOME/.docker/config.json`를 보고 사용하고 싶은 자격 증명만 포함하고 있는지 확인한다. - 1. 노드의 리스트를 구한다. 예를 들면 다음과 같다. - - 이름을 원하는 경우: `nodes=$( kubectl get nodes -o jsonpath='{range.items[*].metadata}{.name} {end}' )` - - IP를 원하는 경우: `nodes=$( kubectl get nodes -o jsonpath='{range .items[*].status.addresses[?(@.type=="ExternalIP")]}{.address} {end}' )` - 1. 로컬의 `.docker/config.json`를 위의 검색 경로 리스트 중 하나에 복사한다. - - 이를 테스트하기 위한 예: `for n in $nodes; do scp ~/.docker/config.json root@"$n":/var/lib/kubelet/config.json; done` - -{{< note >}} -프로덕션 클러스터의 경우, 이 설정을 필요한 모든 노드에 적용할 수 있도록 -구성 관리 도구를 사용한다. -{{< /note >}} - -프라이빗 이미지를 사용하는 파드를 생성하여 검증한다. 예를 들면 다음과 같다. - -```shell -kubectl apply -f - <}} @@ -362,6 +278,8 @@ kubelet은 크리덴셜을 순차적으로 사용하여 풀을 시도한다. #### 도커 구성으로 시크릿 생성 +레지스트리에 인증하기 위해서는, 레지스트리 호스트네임 뿐만 아니라, +사용자 이름, 비밀번호 및 클라이언트 이메일 주소를 알아야 한다. 대문자 값을 적절히 대체하여, 다음 커맨드를 실행한다. ```shell @@ -426,16 +344,15 @@ imagePullSecrets을 셋팅하여 자동화할 수 있다. 일반적인 유스케이스와 제안된 솔루션이다. 1. 비소유 이미지(예를 들어, 오픈소스)만 실행하는 클러스터의 경우. 이미지를 숨길 필요가 없다. - - 도커 허브의 퍼블릭 이미지를 사용한다. + - 퍼블릭 레지스트리의 퍼블릭 이미지를 사용한다. - 설정이 필요 없다. - 일부 클라우드 제공자는 퍼블릭 이미지를 자동으로 캐시하거나 미러링하므로, 가용성이 향상되고 이미지를 가져오는 시간이 줄어든다. 1. 모든 클러스터 사용자에게는 보이지만, 회사 외부에는 숨겨야하는 일부 독점 이미지를 실행하는 클러스터의 경우. - - 호스트 된 프라이빗 [도커 레지스트리](https://docs.docker.com/registry/)를 사용한다. - - 그것은 [도커 허브](https://hub.docker.com/signup)에 호스트 되어 있거나, 다른 곳에 되어 있을 것이다. - - 위에 설명된 바와 같이 수동으로 .docker/config.json을 구성한다. + - 호스트된 프라이빗 레지스트리를 사용한다. + - 프라이빗 레지스트리에 접근해야 하는 노드에 수동 설정이 필요할 수 있다 - 또는, 방화벽 뒤에서 읽기 접근 권한을 가진 내부 프라이빗 레지스트리를 실행한다. - - 쿠버네티스 구성은 필요 없다. + - 쿠버네티스 구성은 필요하지 않다. - 이미지 접근을 제어하는 호스팅된 컨테이너 이미지 레지스트리 서비스를 사용한다. - 그것은 수동 노드 구성에 비해서 클러스터 오토스케일링과 더 잘 동작할 것이다. - 또는, 노드의 구성 변경이 불편한 클러스터에서는, `imagePullSecrets`를 사용한다. @@ -450,8 +367,6 @@ imagePullSecrets을 셋팅하여 자동화할 수 있다. 다중 레지스트리에 접근해야 하는 경우, 각 레지스트리에 대해 하나의 시크릿을 생성할 수 있다. -Kubelet은 모든 `imagePullSecrets` 파일을 하나의 가상 `.docker/config.json` 파일로 병합한다. - ## {{% heading "whatsnext" %}} diff --git a/content/ko/docs/concepts/containers/runtime-class.md b/content/ko/docs/concepts/containers/runtime-class.md index ffcda1b2b8..90d8811d8a 100644 --- a/content/ko/docs/concepts/containers/runtime-class.md +++ b/content/ko/docs/concepts/containers/runtime-class.md @@ -126,8 +126,7 @@ dockershim은 사용자 정의 런타임 핸들러를 지원하지 않는다. [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.${HANDLER_NAME}] ``` -더 자세한 containerd의 구성 문서를 살펴본다. -https://github.com/containerd/cri/blob/master/docs/config.md +더 자세한 내용은 containerd의 [구성 문서](https://github.com/containerd/cri/blob/master/docs/config.md)를 살펴본다. #### {{< glossary_tooltip term_id="cri-o" >}} diff --git a/content/ko/docs/concepts/extend-kubernetes/_index.md b/content/ko/docs/concepts/extend-kubernetes/_index.md index 42a6561bc6..43a695fca9 100644 --- a/content/ko/docs/concepts/extend-kubernetes/_index.md +++ b/content/ko/docs/concepts/extend-kubernetes/_index.md @@ -39,6 +39,7 @@ no_list: true *구성 파일* 및 *플래그* 는 온라인 문서의 레퍼런스 섹션에 각 바이너리 별로 문서화되어 있다. * [kubelet](/docs/reference/command-line-tools-reference/kubelet/) +* [kube-proxy](/docs/reference/command-line-tools-reference/kube-proxy/) * [kube-apiserver](/docs/reference/command-line-tools-reference/kube-apiserver/) * [kube-controller-manager](/docs/reference/command-line-tools-reference/kube-controller-manager/) * [kube-scheduler](/docs/reference/command-line-tools-reference/kube-scheduler/). diff --git a/content/ko/docs/concepts/extend-kubernetes/api-extension/custom-resources.md b/content/ko/docs/concepts/extend-kubernetes/api-extension/custom-resources.md index 2e5bc89cd9..ef87cd1ec6 100644 --- a/content/ko/docs/concepts/extend-kubernetes/api-extension/custom-resources.md +++ b/content/ko/docs/concepts/extend-kubernetes/api-extension/custom-resources.md @@ -26,7 +26,7 @@ weight: 10 동적 등록을 통해 실행 중인 클러스터에서 커스텀 리소스가 나타나거나 사라질 수 있으며 클러스터 관리자는 클러스터 자체와 독립적으로 커스텀 리소스를 업데이트 할 수 있다. 커스텀 리소스가 설치되면 사용자는 *파드* 와 같은 빌트인 리소스와 마찬가지로 -[kubectl](/ko/docs/reference/kubectl/overview/)을 사용하여 해당 오브젝트를 생성하고 +[kubectl](/ko/docs/reference/kubectl/)을 사용하여 해당 오브젝트를 생성하고 접근할 수 있다. ## 커스텀 컨트롤러 diff --git a/content/ko/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins.md b/content/ko/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins.md index 0450864dcd..944818a67a 100644 --- a/content/ko/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins.md +++ b/content/ko/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins.md @@ -344,12 +344,13 @@ pluginapi.Device{ID: "25102017", Health: pluginapi.Healthy, Topology:&pluginapi. 다음은 장치 플러그인 구현의 예이다. * [AMD GPU 장치 플러그인](https://github.com/RadeonOpenCompute/k8s-device-plugin) -* 인텔 GPU, FPGA 및 QuickAssist 장치용 [인텔 장치 플러그인](https://github.com/intel/intel-device-plugins-for-kubernetes) +* 인텔 GPU, FPGA, QAT, VPU, SGX, DSA, DLB 및 IAA 장치용 [인텔 장치 플러그인](https://github.com/intel/intel-device-plugins-for-kubernetes) * 하드웨어 지원 가상화를 위한 [KubeVirt 장치 플러그인](https://github.com/kubevirt/kubernetes-device-plugins) * [NVIDIA GPU 장치 플러그인](https://github.com/NVIDIA/k8s-device-plugin) * GPU를 지원하는 Docker 컨테이너를 실행할 수 있는 [nvidia-docker](https://github.com/NVIDIA/nvidia-docker) 2.0이 필요하다. * [컨테이너에 최적화된 OS를 위한 NVIDIA GPU 장치 플러그인](https://github.com/GoogleCloudPlatform/container-engine-accelerators/tree/master/cmd/nvidia_gpu) * [RDMA 장치 플러그인](https://github.com/hustcat/k8s-rdma-device-plugin) +* [SocketCAN 장치 플러그인](https://github.com/collabora/k8s-socketcan) * [Solarflare 장치 플러그인](https://github.com/vikaschoudhary16/sfc-device-plugin) * [SR-IOV 네트워크 장치 플러그인](https://github.com/intel/sriov-network-device-plugin) * Xilinx FPGA 장치용 [Xilinx FPGA 장치 플러그인](https://github.com/Xilinx/FPGA_as_a_Service/tree/master/k8s-fpga-device-plugin) diff --git a/content/ko/docs/concepts/extend-kubernetes/operator.md b/content/ko/docs/concepts/extend-kubernetes/operator.md index 36b217db9c..0403a1f1b8 100644 --- a/content/ko/docs/concepts/extend-kubernetes/operator.md +++ b/content/ko/docs/concepts/extend-kubernetes/operator.md @@ -111,6 +111,7 @@ kubectl edit SampleDB/example-database # 일부 설정을 수동으로 변경하 {{% thirdparty-content %}} * [Charmed Operator Framework](https://juju.is/) +* [Kopf](https://github.com/nolar/kopf) (Kubernetes Operator Pythonic Framework) * [kubebuilder](https://book.kubebuilder.io/) 사용하기 * [KubeOps](https://buehler.github.io/dotnet-operator-sdk/) (.NET 오퍼레이터 SDK) * [KUDO](https://kudo.dev/) (Kubernetes Universal Declarative Operator) diff --git a/content/ko/docs/concepts/extend-kubernetes/service-catalog.md b/content/ko/docs/concepts/extend-kubernetes/service-catalog.md index fa3d50aeb6..6d2bd2ee39 100644 --- a/content/ko/docs/concepts/extend-kubernetes/service-catalog.md +++ b/content/ko/docs/concepts/extend-kubernetes/service-catalog.md @@ -230,4 +230,3 @@ spec: * 만약 당신이 {{< glossary_tooltip text="Helm Charts" term_id="helm-chart" >}}에 익숙하다면, 당신의 쿠버네티스 클러스터에 [Helm을 이용하여 서비스 카탈로그를 설치](/docs/tasks/service-catalog/install-service-catalog-using-helm/)할 수 있다. 다른 방법으로 [SC tool을 이용하여 서비스 카탈로그를 설치](/ko/docs/tasks/service-catalog/install-service-catalog-using-sc/)할 수 있다. * [샘플 서비스 브로커](https://github.com/openservicebrokerapi/servicebroker/blob/master/gettingStarted.md#sample-service-brokers) 살펴보기 * [kubernetes-sigs/service-catalog](https://github.com/kubernetes-sigs/service-catalog) 프로젝트 탐색 -* [svc-cat.io](https://svc-cat.io/docs/) 살펴보기 diff --git a/content/ko/docs/concepts/overview/components.md b/content/ko/docs/concepts/overview/components.md index 4a93cf9e5c..7a6d6f73a1 100644 --- a/content/ko/docs/concepts/overview/components.md +++ b/content/ko/docs/concepts/overview/components.md @@ -28,7 +28,7 @@ card: 컨트롤 플레인 컴포넌트는 클러스터 내 어떠한 머신에서든지 동작할 수 있다. 그러나 간결성을 위하여, 구성 스크립트는 보통 동일 머신 상에 모든 컨트롤 플레인 컴포넌트를 구동시키고, -사용자 컨테이너는 해당 머신 상에 동작시키지 않는다. 여러 VM에서 +사용자 컨테이너는 해당 머신 상에 동작시키지 않는다. 여러 머신에서 실행되는 컨트롤 플레인 설정의 예제를 보려면 [kubeadm을 사용하여 고가용성 클러스터 만들기](/docs/setup/production-environment/tools/kubeadm/high-availability/)를 확인해본다. diff --git a/content/ko/docs/concepts/overview/kubernetes-api.md b/content/ko/docs/concepts/overview/kubernetes-api.md index cc043139c4..c62033fc18 100644 --- a/content/ko/docs/concepts/overview/kubernetes-api.md +++ b/content/ko/docs/concepts/overview/kubernetes-api.md @@ -22,7 +22,7 @@ card: 쿠버네티스 API를 사용하면 쿠버네티스의 API 오브젝트(예: 파드(Pod), 네임스페이스(Namespace), 컨피그맵(ConfigMap) 그리고 이벤트(Event))를 질의(query)하고 조작할 수 있다. -대부분의 작업은 [kubectl](/ko/docs/reference/kubectl/overview/) +대부분의 작업은 [kubectl](/ko/docs/reference/kubectl/) 커맨드 라인 인터페이스 또는 API를 사용하는 [kubeadm](/ko/docs/reference/setup-tools/kubeadm/)과 같은 다른 커맨드 라인 도구를 통해 수행할 수 있다. diff --git a/content/ko/docs/concepts/overview/working-with-objects/kubernetes-objects.md b/content/ko/docs/concepts/overview/working-with-objects/kubernetes-objects.md index c090b171f4..9800f9ba8f 100644 --- a/content/ko/docs/concepts/overview/working-with-objects/kubernetes-objects.md +++ b/content/ko/docs/concepts/overview/working-with-objects/kubernetes-objects.md @@ -63,7 +63,7 @@ spec과 status간의 차이에 대응한다. [`kubectl apply`](/docs/reference/generated/kubectl/kubectl-commands#apply) 커맨드를 이용하는 것이다. 다음 예시와 같다. ```shell -kubectl apply -f https://k8s.io/examples/application/deployment.yaml --record +kubectl apply -f https://k8s.io/examples/application/deployment.yaml ``` 그 출력 내용은 다음과 유사하다. @@ -83,10 +83,19 @@ deployment.apps/nginx-deployment created 오브젝트 `spec`에 대한 정확한 포맷은 모든 쿠버네티스 오브젝트마다 다르고, 그 오브젝트 특유의 중첩된 필드를 포함한다. [쿠버네티스 API 레퍼런스](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/) 는 쿠버네티스를 이용하여 생성할 수 있는 오브젝트에 대한 모든 spec 포맷을 살펴볼 수 있도록 해준다. -예를 들어, API 내 파드에 대한 상세 정보는 [`spec` 필드](/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodSpec)에 대한 레퍼런스에서, -디플로이먼트에 대한 상세 정보는 [`spec` 필드](/docs/reference/kubernetes-api/workload-resources/deployment-v1/#DeploymentSpec)에 대한 레퍼런스에서 확인할 수 있다. -해당 API 레퍼런스 페이지에서 PodSpec과 DeploymentSpec에 대해 언급된 내용을 볼 수 있다. 이 이름들은 쿠버네티스가 API를 구현하는데 사용한 Go 언어 코드 구현의 세부 내용이다. - +예를 들어, 파드 API 레퍼런스를 보려면 +[`spec` 필드](/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodSpec)를 참조한다. +각 파드에 대해, `.spec` 필드는 파드 및 파드의 원하는 상태(desired state)를 +기술한다(예: 파드의 각 컨테이너에 대한 컨테이너 이미지). +오브젝트 상세에 대한 또 다른 예시는 스테이트풀셋 API의 +[`spec` 필드](/docs/reference/kubernetes-api/workload-resources/stateful-set-v1/#StatefulSetSpec)이다. +스테이트풀셋의 경우, `.spec` 필드는 스테이트풀셋 및 스테이트풀셋의 원하는 상태(desired state)를 기술한다. +스테이트풀셋의 `.spec`에는 파드 오브젝트에 대한 +[템플릿](/ko/docs/concepts/workloads/pods/#파드-템플릿)이 존재한다. +이 템플릿은 스테이트풀셋 명세를 만족시키기 위해 +스테이트풀셋 컨트롤러가 생성할 파드에 대한 상세 사항을 설명한다. +서로 다른 종류의 오브젝트는 서로 다른 `.status`를 가질 수 있다. +다시 한번 말하자면, 각 API 레퍼런스 페이지는 각 오브젝트 타입에 대해 해당 `.status` 필드의 구조와 내용에 대해 소개한다. ## {{% heading "whatsnext" %}} diff --git a/content/ko/docs/concepts/scheduling-eviction/api-eviction.md b/content/ko/docs/concepts/scheduling-eviction/api-eviction.md index 45077a6674..8368be9831 100644 --- a/content/ko/docs/concepts/scheduling-eviction/api-eviction.md +++ b/content/ko/docs/concepts/scheduling-eviction/api-eviction.md @@ -1,18 +1,122 @@ --- -title: API를 이용한 축출(Eviction) +title: API를 이용한 축출(API-initiated Eviction) content_type: concept weight: 70 --- {{< glossary_definition term_id="api-eviction" length="short" >}}
-`kubectl drain` 명령과 같은 kube-apiserver의 클라이언트를 사용하여, -축출 API를 직접 호출해 축출 요청을 할 수 있다. -그러면 API 서버가 파드를 종료하는 `Eviction` 오브젝트가 생성된다. +축출 API를 직접 호출하거나, 또는 `kubectl drain` 명령과 같이 +{{}}의 클라이언트를 사용하여 프로그램적인 방법으로 축출 요청을 할 수 있다. +이는 `Eviction` 오브젝트를 만들며, API 서버로 하여금 파드를 종료하도록 만든다. -API를 이용한 축출은 구성된 [`PodDisruptionBudgets`](/docs/tasks/run-application/configure-pdb/) 및 [`terminationGracePeriodSeconds`](/ko/docs/concepts/workloads/pods/pod-lifecycle/#pod-termination)를 준수한다. +API를 이용한 축출은 사용자가 설정한 [`PodDisruptionBudgets`](/docs/tasks/run-application/configure-pdb/) 및 +[`terminationGracePeriodSeconds`](/ko/docs/concepts/workloads/pods/pod-lifecycle/#pod-termination) 값을 준수한다. + +API를 사용하여 `Eviction` 오브젝트를 만드는 것은 +정책 기반의 파드 [`DELETE` 동작](/docs/reference/kubernetes-api/workload-resources/pod-v1/#delete-delete-a-pod)을 수행하는 것과 +비슷한 효과를 낸다. + +## 축출 API 호출하기 + +[각 언어 별 쿠버네티스 클라이언트](/ko/docs/tasks/administer-cluster/access-cluster-api/#api에-프로그래밍-방식으로-접근)를 사용하여 +쿠버네티스 API를 호출하고 `Eviction` 오브젝트를 생성할 수 있다. +이를 실행하려면, 아래의 예시를 참고하여 POST 호출을 수행한다. + +{{< tabs name="Eviction_example" >}} +{{% tab name="policy/v1" %}} +{{< note >}} +`policy/v1` 축출은 v1.22 이상에서 사용 가능하다. 이전 버전에서는 `policy/v1beta1`를 사용한다. +{{< /note >}} + +```json +{ + "apiVersion": "policy/v1", + "kind": "Eviction", + "metadata": { + "name": "quux", + "namespace": "default" + } +} +``` +{{% /tab %}} +{{% tab name="policy/v1beta1" %}} +{{< note >}} +v1.22에서 사용 중단 및 `policy/v1`으로 대체되었다. +{{< /note >}} + +```json +{ + "apiVersion": "policy/v1beta1", + "kind": "Eviction", + "metadata": { + "name": "quux", + "namespace": "default" + } +} +``` +{{% /tab %}} +{{< /tabs >}} + +또는 다음 예시와 같이 `curl` 또는 `wget`으로 API에 접근하여 +축출 동작을 시도할 수도 있다. + +```bash +curl -v -H 'Content-type: application/json' https://your-cluster-api-endpoint.example/api/v1/namespaces/default/pods/quux/eviction -d @eviction.json +``` + +## API를 이용한 축출의 동작 + +API를 사용하여 축출을 요청하면, +API 서버는 인가 확인(admission checks)를 수행하고 다음 중 하나로 응답한다. + +* `200 OK`: 축출 요청이 허용되었고, `Eviction` 서브리소스가 생성되었고, + (마치 파드 URL에 `DELETE` 요청을 보낸 것처럼) 파드가 삭제되었다. +* `429 Too Many Requests`: 현재 설정된 + {{}} 때문에 + 축출이 현재 허용되지 않는다. + 또는 API 요청 속도 제한(rate limiting) 때문에 이 응답을 받았을 수도 있다. +* `500 Internal Server Error`: 잘못된 환경 설정(예: + 여러 PodDisruptionBudget이 하나의 동일한 파드를 참조함)으로 인해 축출이 허용되지 않는다. + +축출하려는 파드가 +PodDisruptionBudget이 설정된 워크로드에 속하지 않는다면, +API 서버는 항상 `200 OK`를 반환하고 축출을 허용한다. + +API 서버가 축출을 허용하면, 파드는 다음과 같이 삭제된다. + +1. API 서버 내 `Pod` 리소스의 삭제 타임스탬프(deletion timestamp)가 업데이트되며, + 이 타임스탬프에 명시된 시각이 경과하면 API 서버는 해당 `Pod` 리소스를 종료 대상으로 간주한다. + 또한 설정된 그레이스 시간(grace period)이 `Pod` 리소스에 기록된다. +1. 로컬 파드가 실행되고 있는 노드의 {{}}이 + `Pod`가 종료 대상으로 표시된 것을 감지하고 + 로컬 파드의 그레이스풀 셧다운을 시작한다. +1. kubelet이 파드를 종료하는 와중에, 컨트롤 플레인은 + {{}} 및 + {{}} 오브젝트에서 파드를 삭제한다. + 이 결과, 컨트롤러는 파드를 더 이상 유효한 오브젝트로 간주하지 않는다. +1. 파드의 그레이스 시간이 만료되면, + kubelet이 로컬 파드를 강제로 종료한다. +1. kubelet이 API 서버에 `Pod` 리소스를 삭제하도록 지시한다. +1. API 서버가 `Pod` 리소스를 삭제한다. + +## 문제가 있어 중단된 축출 트러블슈팅하기 + +일부 경우에, 애플리케이션이 잘못된 상태로 돌입하여, +직접 개입하기 전에는 축출 API가 `429` 또는 `500` 응답만 반환할 수 있다. +이러한 현상은, 예를 들면 레플리카셋이 애플리케이션을 서비스할 파드를 생성했지만 +새 파드가 `Ready`로 바뀌지 못하는 경우에 발생할 수 있다. +또는 마지막으로 축출된 파드가 긴 종료 그레이스 시간을 가진 경우에 이러한 현상을 목격할 수도 있다. + +문제가 있어 중단된 축출을 발견했다면, 다음 해결책 중 하나를 시도해 본다. + +* 이 문제를 발생시키는 자동 동작(automated operation)을 중단하거나 일시 중지한다. + 해당 동작을 재시작하기 전에, 문제가 있어 중단된 애플리케이션을 조사한다. +* 잠시 기다린 뒤, 축출 API를 사용하는 것 대신 + 클러스터 컨트롤 플레인에서 파드를 직접 삭제한다. ## {{% heading "whatsnext" %}} -- [노드-압박 축출](/ko/docs/concepts/scheduling-eviction/node-pressure-eviction/)에 대해 더 배우기 -- [파드 우선순위와 선점](/ko/docs/concepts/scheduling-eviction/pod-priority-preemption/)에 대해 더 배우기 +* [Pod Disruption Budget](/docs/tasks/run-application/configure-pdb/)을 사용하여 애플리케이션을 보호하는 방법에 대해 알아본다. +* [노드-압박 축출](/ko/docs/concepts/scheduling-eviction/node-pressure-eviction/)에 대해 알아본다. +* [파드 우선순위와 선점](/ko/docs/concepts/scheduling-eviction/pod-priority-preemption/)에 대해 알아본다. diff --git a/content/ko/docs/concepts/scheduling-eviction/assign-pod-node.md b/content/ko/docs/concepts/scheduling-eviction/assign-pod-node.md index 494d3b1601..f4d0613c72 100644 --- a/content/ko/docs/concepts/scheduling-eviction/assign-pod-node.md +++ b/content/ko/docs/concepts/scheduling-eviction/assign-pod-node.md @@ -15,159 +15,182 @@ weight: 20 {{< glossary_tooltip text="파드" term_id="pod" >}}를 제한할 수 있다. 이를 수행하는 방법에는 여러 가지가 있으며 권장되는 접근 방식은 모두 [레이블 셀렉터](/ko/docs/concepts/overview/working-with-objects/labels/)를 사용하여 선택을 용이하게 한다. -보통 스케줄러가 자동으로 합리적인 배치(예: 자원이 부족한 노드에 파드를 배치하지 않도록 -노드 간에 파드를 분배하는 등)를 수행하기에 이러한 제약 조건은 필요하지 않지만 -간혹 파드가 배포될 노드를 제어해야 하는 경우가 있다. -예를 들어 SSD가 장착된 머신에 파드가 배포되도록 하거나 또는 많은 통신을 하는 두 개의 서로 다른 서비스의 파드를 -동일한 가용성 영역(availability zone)에 배치할 수 있다. - +보통은 스케줄러가 자동으로 합리적인 배치(예: 자원이 부족한 노드에 파드를 배치하지 않도록 +노드 간에 파드를 분배)를 수행하기에 이러한 제약 조건은 필요하지 않다. +그러나, 예를 들어 SSD가 장착된 머신에 파드가 배포되도록 하거나 또는 +많은 통신을 하는 두 개의 서로 다른 서비스의 파드를 동일한 가용성 영역(availability zone)에 배치하는 경우와 같이, +파드가 어느 노드에 배포될지를 제어해야 하는 경우도 있다. -## 노드 셀렉터(nodeSelector) +쿠버네티스가 특정 파드를 어느 노드에 스케줄링할지 고르는 +다음의 방법 중 하나를 골라 사용할 수 있다. -`nodeSelector` 는 가장 간단하고 권장되는 노드 선택 제약 조건의 형태이다. -`nodeSelector` 는 PodSpec의 필드이다. 이는 키-값 쌍의 매핑으로 지정한다. 파드가 노드에서 동작할 수 있으려면, -노드는 키-값의 쌍으로 표시되는 레이블을 각자 가지고 있어야 한다(이는 추가 레이블을 가지고 있을 수 있다). -일반적으로 하나의 키-값 쌍이 사용된다. + * [노드 레이블](#built-in-node-labels)에 매칭되는 [nodeSelector](#nodeselector) 필드 + * [어피니티 / 안티 어피니티](#affinity-and-anti-affinity) + * [nodeName](#nodename) 필드 -`nodeSelector` 를 어떻게 사용하는지 예시를 통해 알아보도록 하자. +## 노드 레이블 {#built-in-node-labels} -### 0 단계: 사전 준비 +다른 쿠버네티스 오브젝트와 마찬가지로, 노드도 [레이블](/ko/docs/concepts/overview/working-with-objects/labels/)을 가진다. +[레이블을 수동으로 추가](/ko/docs/tasks/configure-pod-container/assign-pods-nodes/#노드에-레이블-추가)할 수 있다. +또한 쿠버네티스도 클러스터의 모든 노드에 표준화된 레이블 집합을 적용한다. +[잘 알려진 레이블, 어노테이션, 테인트](/ko/docs/reference/labels-annotations-taints/)에서 널리 사용되는 노드 레이블의 목록을 확인한다. -이 예시는 쿠버네티스 파드에 대한 기본적인 이해를 하고 있고 [쿠버네티스 클러스터가 설정](/ko/docs/setup/)되어 있다고 가정한다. +{{}} +이러한 레이블에 대한 값은 클라우드 제공자별로 다르며 정확하지 않을 수 있다. +예를 들어, `kubernetes.io/hostname`에 대한 값은 특정 환경에서는 노드 이름과 동일할 수 있지만 +다른 환경에서는 다른 값일 수도 있다. +{{}} -### 1 단계: 노드에 레이블 붙이기 +### 노드 격리/제한 {#node-isolation-restriction} -`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 "노드 이름"` 을 사용해서 노드에 주어진 레이블의 전체 목록을 확인할 수 있다. +노드 격리를 위해 레이블을 사용할 때, {{}}이 변경할 수 없는 레이블 키를 선택한다. +그렇지 않으면 kubelet이 해당 레이블을 변경하여 노드가 사용 불가능(compromised) 상태로 빠지고 +스케줄러가 이 노드에 워크로드를 스케줄링하는 일이 발생할 수 있다. -### 2 단계: 파드 설정에 nodeSelector 필드 추가하기 +[`NodeRestriction` 어드미션 플러그인](/docs/reference/access-authn-authz/admission-controllers/#noderestriction)은 +kubelet이 `node-restriction.kubernetes.io/` 접두사를 갖는 레이블을 +설정하거나 변경하지 못하도록 한다. -실행하고자 하는 파드의 설정 파일을 가져오고, 이처럼 nodeSelector 섹션을 추가한다. 예를 들어 이것이 파드 설정이라면, +노드 격리를 위해 레이블 접두사를 사용하려면, -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: nginx - labels: - env: test -spec: - containers: - - name: nginx - image: nginx -``` +1. [노드 인가자(authorizer)](/docs/reference/access-authn-authz/node/)를 사용하고 있는지, 그리고 `NodeRestriction` 어드미션 플러그인을 **활성화** 했는지 확인한다. +1. 노드에 `node-restriction.kubernetes.io/` 접두사를 갖는 레이블을 추가하고, [노드 셀렉터](#nodeselector)에서 해당 레이블을 사용한다. + 예: `example.com.node-restriction.kubernetes.io/fips=true` 또는 `example.com.node-restriction.kubernetes.io/pci-dss=true` -이 다음에 nodeSelector 를 다음과 같이 추가한다. +## 노드셀렉터(nodeSelector) {#nodeselector} -{{< codenew file="pods/pod-nginx.yaml" >}} +`nodeSelector`는 노드 선택 제약사항의 가장 간단하면서도 추천하는 형태이다. +파드 스펙에 `nodeSelector` 필드를 추가하고, +타겟으로 삼고 싶은 노드가 갖고 있는 [노드 레이블](#built-in-node-labels)을 명시한다. +쿠버네티스는 사용자가 명시한 레이블을 갖고 있는 노드에만 +파드를 스케줄링한다. -그런 다음에 `kubectl apply -f https://k8s.io/examples/pods/pod-nginx.yaml` 을 -실행하면, 레이블이 붙여진 노드에 파드가 스케줄된다. -`kubectl get pods -o wide` 를 실행해서 파드가 할당된 -"NODE" 를 보면 작동하는지 검증할 수 있다. +[노드에 파드 할당](/ko/docs/tasks/configure-pod-container/assign-pods-nodes)에서 +더 많은 정보를 확인한다. -## 넘어가기 전에: 내장 노드 레이블들 {#built-in-node-labels} +## 어피니티(affinity)와 안티-어피니티(anti-affinity) {#affinity-and-anti-affinity} -[붙인](#1-단계-노드에-레이블-붙이기) 레이블뿐만 아니라, 노드에는 -표준 레이블 셋이 미리 채워져 있다. 이들 목록은 [잘 알려진 레이블, 어노테이션 및 테인트](/ko/docs/reference/labels-annotations-taints/)를 참고한다. +`nodeSelector` 는 파드를 특정 레이블이 있는 노드로 제한하는 가장 간단한 방법이다. +어피니티/안티-어피니티 기능은 표현할 수 있는 제약 종류를 크게 확장한다. +주요 개선 사항은 다음과 같다. -{{< note >}} -이 레이블들의 값은 클라우드 공급자에 따라 다르고 신뢰성이 보장되지 않는다. -예를 들어 `kubernetes.io/hostname` 은 어떤 환경에서는 노드 이름과 같지만, -다른 환경에서는 다른 값일 수 있다. -{{< /note >}} +* 어피니티/안티-어피니티 언어가 더 표현적이다. + `nodeSelector`로는 명시한 레이블이 있는 노드만 선택할 수 있다. + 어피니티/안티-어피니티는 선택 로직에 대한 좀 더 많은 제어권을 제공한다. +* 규칙이 "소프트(soft)" 또는 "선호사항(preference)" 임을 나타낼 수 있으며, + 이 덕분에 스케줄러는 매치되는 노드를 찾지 못한 경우에도 파드를 스케줄링할 수 있다. +* 다른 노드 (또는 다른 토폴로지 도메인)에서 실행 중인 + 다른 파드의 레이블을 사용하여 파드를 제한할 수 있으며, + 이를 통해 어떤 파드들이 노드에 함께 위치할 수 있는지에 대한 규칙을 정의할 수 있다. -## 노드 격리(isolation)/제한(restriction) +어피니티 기능은 다음의 두 가지 종류로 구성된다. -노드 오브젝트에 레이블을 추가하면 파드가 특정 노드 또는 노드 그룹을 목표 대상으로 할 수 있게 된다. -이는 특정 파드가 어떤 격리, 보안, 또는 규제 속성이 있는 노드에서만 실행되도록 사용할 수 있다. -이 목적으로 레이블을 사용하는 경우, 노드에서 kubelet 프로세스로 수정할 수 없는 레이블 키를 선택하는 것을 권장한다. -이렇게 하면 손상된 노드가 해당 kubelet 자격 증명을 사용해서 해당 레이블을 자체 노드 오브젝트에 설정하고, -스케줄러가 손상된 노드로 워크로드를 스케줄 하는 것을 방지할 수 있다. +* *노드 어피니티* 기능은 `nodeSelector` 필드와 비슷하지만 + 더 표현적이고 소프트(soft) 규칙을 지정할 수 있게 해 준다. +* *파드 간 어피니티/안티-어피니티* 는 다른 파드의 레이블을 이용하여 + 해당 파드를 제한할 수 있게 해 준다. -`NodeRestriction` 어드미션 플러그인은 kubelet이 `node-restriction.kubernetes.io/` 접두사로 레이블을 설정 또는 수정하지 못하게 한다. -노드 격리에 해당 레이블 접두사를 사용하려면 다음과 같이 한다. +### 노드 어피니티 {#node-affinity} -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` 이다. +노드 어피니티는 개념적으로 `nodeSelector` 와 비슷하며, +노드의 레이블을 기반으로 파드가 스케줄링될 수 있는 노드를 제한할 수 있다. +노드 어피니티에는 다음의 두 종류가 있다. -## 어피니티(affinity)와 안티-어피니티(anti-affinity) + * `requiredDuringSchedulingIgnoredDuringExecution`: + 규칙이 만족되지 않으면 스케줄러가 파드를 스케줄링할 수 없다. + 이 기능은 `nodeSelector`와 유사하지만, 좀 더 표현적인 문법을 제공한다. + * `preferredDuringSchedulingIgnoredDuringExecution`: + 스케줄러는 조건을 만족하는 노드를 찾으려고 노력한다. + 해당되는 노드가 없더라도, 스케줄러는 여전히 파드를 스케줄링한다. -`nodeSelector` 는 파드를 특정 레이블이 있는 노드로 제한하는 매우 간단한 방법을 제공한다. -어피니티/안티-어피니티 기능은 표현할 수 있는 제약 종류를 크게 확장한다. 주요 개선 사항은 다음과 같다. +{{}} +앞의 두 유형에서, `IgnoredDuringExecution`는 +쿠버네티스가 파드를 스케줄링한 뒤에 노드 레이블이 변경되어도 파드는 계속 해당 노드에서 실행됨을 의미한다. +{{}} -1. 어피니티/안티-어피니티 언어가 더 표현적이다. 언어는 논리 연산자인 AND 연산으로 작성된 - 정확한 매칭 항목 이외에 더 많은 매칭 규칙을 제공한다. -2. 규칙이 엄격한 요구 사항이 아니라 "유연한(soft)"/"선호(preference)" 규칙을 나타낼 수 있기에 스케줄러가 규칙을 만족할 수 없더라도, - 파드가 계속 스케줄되도록 한다. -3. 노드 자체에 레이블을 붙이기보다는 노드(또는 다른 토폴로지 도메인)에서 실행 중인 다른 파드의 레이블을 제한할 수 있다. - 이를 통해 어떤 파드가 함께 위치할 수 있는지와 없는지에 대한 규칙을 적용할 수 있다. +파드 스펙의 `.spec.affinity.nodeAffinity` 필드에 +노드 어피니티를 명시할 수 있다. -어피니티 기능은 "노드 어피니티" 와 "파드 간 어피니티/안티-어피니티" 두 종류의 어피니티로 구성된다. -노드 어피니티는 기존 `nodeSelector` 와 비슷하지만(그러나 위에서 나열된 첫째와 두 번째 이점이 있다.), -파드 간 어피니티/안티-어피니티는 위에서 나열된 세번째 항목에 설명된 대로 -노드 레이블이 아닌 파드 레이블에 대해 제한되고 위에서 나열된 첫 번째와 두 번째 속성을 가진다. - -### 노드 어피니티 - -노드 어피니티는 개념적으로 `nodeSelector` 와 비슷하다 -- 이는 노드의 레이블을 기반으로 파드를 -스케줄할 수 있는 노드를 제한할 수 있다. - -여기에 현재 `requiredDuringSchedulingIgnoredDuringExecution` 와 `preferredDuringSchedulingIgnoredDuringExecution` 로 부르는 -두 가지 종류의 노드 어피니티가 있다. 전자는 파드가 노드에 스케줄되도록 *반드시* -규칙을 만족해야 하는 것(`nodeSelector` 와 비슷하나 보다 표현적인 구문을 사용해서)을 지정하고, -후자는 스케줄러가 시도하려고는 하지만, 보증하지 않는 *선호(preferences)* 를 지정한다는 점에서 -이를 각각 "엄격함(hard)" 과 "유연함(soft)" 으로 생각할 수 있다. -이름의 "IgnoredDuringExecution" 부분은 `nodeSelector` 작동 방식과 유사하게 노드의 -레이블이 런타임 중에 변경되어 파드의 어피니티 규칙이 더 이상 충족되지 않으면 파드가 그 노드에서 -동작한다는 의미이다. 향후에는 파드의 노드 어피니티 요구 사항을 충족하지 않는 노드에서 파드를 제거한다는 -점을 제외하고는 `requiredDuringSchedulingIgnoredDuringExecution` 와 동일한 `requiredDuringSchedulingRequiredDuringExecution` 를 제공할 계획이다. - -따라서 `requiredDuringSchedulingIgnoredDuringExecution` 의 예로는 "인텔 CPU가 있는 노드에서만 파드 실행"이 -될 수 있고, `preferredDuringSchedulingIgnoredDuringExecution` 의 예로는 "장애 조치 영역 XYZ에 파드 집합을 실행하려고 -하지만, 불가능하다면 다른 곳에서 일부를 실행하도록 허용"이 있을 것이다. - -노드 어피니티는 PodSpec의 `affinity` 필드의 `nodeAffinity` 필드에서 지정된다. - -여기에 노드 어피니티를 사용하는 파드 예시가 있다. +예를 들어, 다음과 같은 파드 스펙이 있다고 하자. {{< codenew file="pods/pod-with-node-affinity.yaml" >}} -이 노드 어피니티 규칙은 키가 `kubernetes.io/e2e-az-name` 이고 값이 `e2e-az1` 또는 `e2e-az2` 인 -레이블이 있는 노드에만 파드를 배치할 수 있다고 말한다. 또한, 이 기준을 충족하는 노드들 -중에서 키가 `another-node-label-key` 이고 값이 `another-node-label-value` 인 레이블이 있는 노드를 -선호하도록 한다. +이 예시에서는 다음의 규칙이 적용된다. -예시에서 연산자 `In` 이 사용되고 있는 것을 볼 수 있다. 새로운 노드 어피니티 구문은 다음의 연산자들을 지원한다. `In`, `NotIn`, `Exists`, `DoesNotExist`, `Gt`, `Lt`. -`NotIn` 과 `DoesNotExist` 를 사용해서 안티-어피니티를 수행하거나, -특정 노드에서 파드를 쫓아내는 [노드 테인트(taint)](/ko/docs/concepts/scheduling-eviction/taint-and-toleration/)를 설정할 수 있다. + * 노드는 키가 `kubernetes.io/os`이고 값이 `linux`인 레이블을 + 갖고 *있어야 한다* . + * 키가 `another-node-label-key`이고 값이 `another-node-label-value`인 레이블을 + 갖고 있는 노드를 *선호한다* . -`nodeSelector` 와 `nodeAffinity` 를 모두 지정한다면 파드가 후보 노드에 스케줄되기 위해서는 -*둘 다* 반드시 만족해야 한다. +`operator` 필드를 사용하여 +쿠버네티스가 규칙을 해석할 때 사용할 논리 연산자를 지정할 수 있다. +`In`, `NotIn`, `Exists`, `DoesNotExist`, `Gt` 및 `Lt` 연산자를 사용할 수 있다. -`nodeAffinity` 유형과 연관된 `nodeSelectorTerms` 를 지정하면, `nodeSelectorTerms` 중 **하나라도** 만족시키는 노드에 파드가 스케줄된다. +`NotIn` 및 `DoesNotExist` 연산자를 사용하여 노드 안티-어피니티 규칙을 정의할 수 있다. +또는, 특정 노드에서 파드를 쫓아내는 +[노드 테인트(taint)](/ko/docs/concepts/scheduling-eviction/taint-and-toleration/)를 설정할 수 있다. -`nodeSelectorTerms` 와 연관된 여러 `matchExpressions` 를 지정하면, 파드는 `matchExpressions` 를 **모두** 만족하는 노드에만 스케줄된다. +{{}} +`nodeSelector`와 `nodeAffinity`를 모두 사용하는 경우, +파드가 노드에 스케줄링되려면 두 조건 *모두* 만족되어야 한다. -파드가 스케줄된 노드의 레이블을 지우거나 변경해도 파드는 제거되지 않는다. 다시 말해서 어피니티 선택은 파드를 스케줄링 하는 시점에만 작동한다. +`nodeAffinity`에 연결된 `nodeSelectorTerms`를 여러 개 명시한 경우, +명시된 `nodeSelectorTerms` 중 하나를 만족하는 노드에도 +파드가 스케줄링될 수 있다. -`preferredDuringSchedulingIgnoredDuringExecution` 의 `weight` 필드의 범위는 1-100이다. 모든 스케줄링 요구 사항 (리소스 요청, RequiredDuringScheduling 어피니티 표현식 등)을 만족하는 각 노드들에 대해 스케줄러는 이 필드의 요소들을 반복해서 합계를 계산하고 노드가 MatchExpressions 에 일치하는 경우 합계에 "가중치(weight)"를 추가한다. 이후에 이 점수는 노드에 대한 다른 우선순위 함수의 점수와 합쳐진다. 전체 점수가 가장 높은 노드를 가장 선호한다. +단일 `nodeSelectorTerms`와 연결된 `matchExpressions`를 여러 개 명시한 경우, +모든 `matchExpressions`를 만족하는 노드에만 +파드가 스케줄링될 수 있다. +{{}} -#### 스케줄링 프로파일당 노드 어피니티 +[노드 어피니티를 사용해 노드에 파드 할당](/ko/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/)에서 +더 많은 정보를 확인한다. + +#### 노드 어피니티 가중치(weight) {#node-affinity-weight} + +각 `preferredDuringSchedulingIgnoredDuringExecution` 어피니티 타입 인스턴스에 대해 +1-100 범위의 `weight`를 명시할 수 있다. +스케줄러가 다른 모든 파드 스케줄링 요구 사항을 만족하는 노드를 찾으면, +스케줄러는 노드가 만족한 모든 선호하는(preferred) 규칙에 대해 +합계 계산을 위한 `weight` 값을 각각 추가한다. + +최종 합계는 해당 노드에 대한 다른 우선 순위 함수 점수에 더해진다. +스케줄러가 파드에 대한 스케줄링 판단을 할 때, +총 점수가 가장 높은 노드가 우선 순위를 갖는다. + +예를 들어, 다음과 같은 파드 스펙이 있다고 하자. + +{{< codenew file="pods/pod-with-affinity-anti-affinity.yaml" >}} + +`requiredDuringSchedulingIgnoredDuringExecution` 규칙을 만족하는 노드가 2개 있고, +하나에는 `label-1:key-1` 레이블이 있고 다른 하나에는 `label-2:key-2` 레이블이 있으면, +스케줄러는 각 노드의 `weight`를 확인한 뒤 +해당 노드에 대한 다른 점수에 가중치를 더하고, +최종 점수가 가장 높은 노드에 해당 파드를 스케줄링한다. + +{{}} +이 예시에서 쿠버네티스가 정상적으로 파드를 스케줄링하려면, +보유하고 있는 노드에 `kubernetes.io/os=linux` 레이블이 있어야 한다. +{{}} + +#### 스케줄링 프로파일당 노드 어피니티 {#node-affinity-per-scheduling-profile} {{< feature-state for_k8s_version="v1.20" state="beta" >}} 여러 [스케줄링 프로파일](/ko/docs/reference/scheduling/config/#여러-프로파일)을 구성할 때 노드 어피니티가 있는 프로파일을 연결할 수 있는데, 이는 프로파일이 특정 노드 집합에만 적용되는 경우 유용하다. -이렇게 하려면 [스케줄러 구성](/ko/docs/reference/scheduling/config/)에 있는 -[`NodeAffinity` 플러그인](/ko/docs/reference/scheduling/config/#스케줄링-플러그인-1)의 인수에 `addedAffinity`를 추가한다. 예를 들면 +이렇게 하려면 다음과 같이 [스케줄러 구성](/ko/docs/reference/scheduling/config/)에 있는 +[`NodeAffinity` 플러그인](/ko/docs/reference/scheduling/config/#스케줄링-플러그인-1)의 `args` 필드에 `addedAffinity`를 추가한다. ```yaml -apiVersion: kubescheduler.config.k8s.io/v1beta1 +apiVersion: kubescheduler.config.k8s.io/v1beta3 kind: KubeSchedulerConfiguration profiles: @@ -188,29 +211,41 @@ profiles: `addedAffinity`는 `.spec.schedulerName`을 `foo-scheduler`로 설정하는 모든 파드에 적용되며 PodSpec에 지정된 NodeAffinity도 적용된다. -즉, 파드를 매칭시키려면, 노드가 `addedAffinity`와 파드의 `.spec.NodeAffinity`를 충족해야 한다. +즉, 파드를 매칭시키려면, 노드가 `addedAffinity`와 +파드의 `.spec.NodeAffinity`를 충족해야 한다. -`addedAffinity`는 엔드 유저에게 표시되지 않으므로, 예상치 못한 동작이 일어날 수 있다. 프로파일의 -스케줄러 이름과 명확한 상관 관계가 있는 노드 레이블을 사용하는 것이 좋다. +`addedAffinity`는 엔드 유저에게 표시되지 않으므로, +예상치 못한 동작이 일어날 수 있다. +스케줄러 프로파일 이름과 명확한 상관 관계가 있는 노드 레이블을 사용한다. {{< note >}} -[데몬셋용 파드를 생성](/ko/docs/concepts/workloads/controllers/daemonset/#기본-스케줄러로-스케줄)하는 데몬셋 컨트롤러는 -스케줄링 프로파일을 인식하지 못한다. -따라서 `addedAffinity`없이 `default-scheduler`와 같은 스케줄러 프로파일을 유지하는 것이 좋다. 그런 다음 데몬셋의 파드 템플릿이 스케줄러 이름을 사용해야 한다. -그렇지 않으면, 데몬셋 컨트롤러에 의해 생성된 일부 파드가 스케줄되지 않은 상태로 유지될 수 있다. +[데몬셋 파드를 생성](/ko/docs/concepts/workloads/controllers/daemonset/#기본-스케줄러로-스케줄)하는 데몬셋 컨트롤러는 +스케줄링 프로파일을 지원하지 않는다. +데몬셋 컨트롤러가 파드를 생성할 때, 기본 쿠버네티스 스케줄러는 해당 파드를 배치하고 +데몬셋 컨트롤러의 모든 `nodeAffinity` 규칙을 준수한다. {{< /note >}} -### 파드간 어피니티와 안티-어피니티 +### 파드간 어피니티와 안티-어피니티 {#inter-pod-affinity-and-anti-affinity} -파드간 어피니티와 안티-어피니티를 사용하면 노드의 레이블을 기반으로 하지 않고, *노드에서 이미 실행 중인 파드 레이블을 기반으로* -파드가 스케줄될 수 있는 노드를 제한할 수 있다. 규칙은 "X가 규칙 Y를 충족하는 하나 이상의 파드를 이미 실행중인 경우 -이 파드는 X에서 실행해야 한다(또는 안티-어피니티가 없는 경우에는 동작하면 안된다)"는 형태이다. Y는 -선택적으로 연관된 네임스페이스 목록을 가진 LabelSelector로 표현된다. 노드와는 다르게 파드는 네임스페이스이기에 -(그리고 따라서 파드의 레이블은 암암리에 네임스페이스이다) 파드 레이블위의 레이블 셀렉터는 반드시 -셀렉터가 적용될 네임스페이스를 지정해야만 한다. 개념적으로 X는 노드, 랙, -클라우드 공급자 영역, 클라우드 공급자 지역 등과 같은 토폴로지 도메인이다. 시스템이 이런 토폴로지 -도메인을 나타내는 데 사용하는 노드 레이블 키인 `topologyKey` 를 사용하여 이를 표현한다. -예: [넘어가기 전에: 빌트인 노드 레이블](#built-in-node-labels) 섹션 위에 나열된 레이블 키를 본다. +파드간 어피니티와 안티-어피니티를 사용하여, +노드 레이블 대신, 각 노드에 이미 실행 중인 다른 **파드** 의 레이블을 기반으로 +파드가 스케줄링될 노드를 제한할 수 있다. + +파드간 어피니티와 안티-어피니티 규칙은 +"X가 규칙 Y를 충족하는 하나 이상의 파드를 이미 실행중인 경우 이 파드는 X에서 실행해야 한다(또는 +안티-어피니티의 경우에는 "실행하면 안 된다")"의 형태이며, +여기서 X는 노드, 랙, 클라우드 제공자 존 또는 리전 등이며 +Y는 쿠버네티스가 충족할 규칙이다. + +이러한 규칙(Y)은 [레이블 셀렉터](/ko/docs/concepts/overview/working-with-objects/labels/#레이블-셀렉터) 형태로 작성하며, +연관된 네임스페이스 목록을 선택적으로 명시할 수도 있다. +쿠버네티스에서 파드는 네임스페이스에 속하는(namespaced) 오브젝트이므로, +파드 레이블도 암묵적으로 특정 네임스페이스에 속하게 된다. +파드 레이블에 대한 모든 레이블 셀렉터는 쿠버네티스가 해당 레이블을 어떤 네임스페이스에서 탐색할지를 명시해야 한다. + +`topologyKey`를 사용하여 토폴로지 도메인(X)를 나타낼 수 있으며, +이는 시스템이 도메인을 표시하기 위해 사용하는 노드 레이블의 키이다. +이에 대한 예시는 [잘 알려진 레이블, 어노테이션, 테인트](/ko/docs/reference/labels-annotations-taints/)를 참고한다. {{< note >}} 파드간 어피니티와 안티-어피니티에는 상당한 양의 프로세싱이 필요하기에 @@ -219,80 +254,106 @@ PodSpec에 지정된 NodeAffinity도 적용된다. {{< /note >}} {{< note >}} -파드 안티-어피니티에서는 노드에 일관된 레이블을 지정해야 한다. 즉, 클러스터의 모든 노드는 `topologyKey` 와 매칭되는 적절한 레이블을 가지고 있어야 한다. 일부 또는 모든 노드에 지정된 `topologyKey` 레이블이 없는 경우에는 의도하지 않은 동작이 발생할 수 있다. +파드 안티-어피니티에서는 노드에 일관된 레이블을 지정해야 한다. +즉, 클러스터의 모든 노드는 `topologyKey` 와 매칭되는 적절한 레이블을 가지고 있어야 한다. +일부 또는 모든 노드에 지정된 `topologyKey` 레이블이 없는 경우에는 +의도하지 않은 동작이 발생할 수 있다. {{< /note >}} -노드 어피니티와 마찬가지로 현재 파드 어피니티와 안티-어피니티로 부르는 "엄격함" 대 "유연함"의 요구사항을 나타내는 `requiredDuringSchedulingIgnoredDuringExecution` 와 -`preferredDuringSchedulingIgnoredDuringExecution` 두 가지 종류가 있다. -앞의 노드 어피니티 섹션의 설명을 본다. -`requiredDuringSchedulingIgnoredDuringExecution` 어피니티의 예시는 -"서로 많은 통신을 하기 때문에 서비스 A와 서비스 B를 같은 영역에 함께 위치시키는 것"이고, -`preferredDuringSchedulingIgnoredDuringExecution` 안티-어피니티의 예시는 "서비스를 여러 영역에 걸쳐서 분배하는 것"이다 -(엄격한 요구사항은 영역보다 파드가 더 많을 수 있기 때문에 엄격한 요구사항은 의미가 없다). +#### 파드간 어피니티 및 안티-어피니티 종류 {#types-of-inter-pod-affinity-and-anti-affinity} -파드간 어피니티는 PodSpec에서 `affinity` 필드 중 `podAffinity` 필드로 지정한다. -그리고 파드간 안티-어피니티는 PodSpec에서 `affinity` 필드 중 `podAntiAffinity` 필드로 지정한다. +노드 어피니티와 마찬가지로 +파드 어피니티 및 안티-어피니티에는 다음의 2 종류가 있다. -#### 파드 어피니티를 사용하는 파드의 예시 + * `requiredDuringSchedulingIgnoredDuringExecution` + * `preferredDuringSchedulingIgnoredDuringExecution` + +예를 들어, `requiredDuringSchedulingIgnoredDuringExecution` 어피니티를 사용하여 +서로 통신을 많이 하는 두 서비스의 파드를 +동일 클라우드 제공자 존에 배치하도록 스케줄러에게 지시할 수 있다. +비슷하게, `preferredDuringSchedulingIgnoredDuringExecution` 안티-어피니티를 사용하여 +서비스의 파드를 +여러 클라우드 제공자 존에 퍼뜨릴 수 있다. + +파드간 어피니티를 사용하려면, 파드 스펙에 `affinity.podAffinity` 필드를 사용한다. +파드간 안티-어피니티를 사용하려면, +파드 스펙에 `affinity.podAntiAffinity` 필드를 사용한다. + +#### 파드 어피니티 예시 {#an-example-of-a-pod-that-uses-pod-affinity} + +다음과 같은 파드 스펙을 가정한다. {{< codenew file="pods/pod-with-pod-affinity.yaml" >}} -이 파드의 어피니티는 하나의 파드 어피니티 규칙과 하나의 파드 안티-어피니티 규칙을 정의한다. -이 예시에서 `podAffinity` 는 `requiredDuringSchedulingIgnoredDuringExecution` 이고 `podAntiAffinity` 는 -`preferredDuringSchedulingIgnoredDuringExecution` 이다. 파드 어피니티 규칙에 의하면 키 "security" 와 값 -"S1"인 레이블이 있는 하나 이상의 이미 실행 중인 파드와 동일한 영역에 있는 경우에만 파드를 노드에 스케줄할 수 있다. -(보다 정확하게는, 클러스터에 키 "security"와 값 "S1"인 레이블을 가지고 있는 실행 중인 파드가 있는 키 -`topology.kubernetes.io/zone` 와 값 V인 노드가 최소 하나 이상 있고, -노드 N이 키 `topology.kubernetes.io/zone` 와 -일부 값이 V인 레이블을 가진다면 파드는 노드 N에서 실행할 수 있다.) -파드 안티-어피니티 규칙에 의하면 파드는 키 "security"와 값 "S2"인 레이블을 가진 파드와 -동일한 영역의 노드에 스케줄되지 않는다. -[디자인 문서](https://git.k8s.io/community/contributors/design-proposals/scheduling/podaffinity.md)를 통해 -`requiredDuringSchedulingIgnoredDuringExecution` 와 `preferredDuringSchedulingIgnoredDuringExecution` 의 -파드 어피니티와 안티-어피니티에 대한 많은 예시를 맛볼 수 있다. +이 예시는 하나의 파드 어피니티 규칙과 +하나의 파드 안티-어피니티 규칙을 정의한다. +파드 어피니티 규칙은 "하드" `requiredDuringSchedulingIgnoredDuringExecution`을, +안티-어피니티 규칙은 "소프트" `preferredDuringSchedulingIgnoredDuringExecution`을 사용한다. -파드 어피니티와 안티-어피니티의 적합한 연산자는 `In`, `NotIn`, `Exists`, `DoesNotExist` 이다. +위의 어피니티 규칙은 `security=S1` 레이블이 있는 하나 이상의 기존 파드의 존와 동일한 존에 있는 노드에만 +파드를 스케줄링하도록 스케줄러에 지시한다. +더 정확히 말하면, 만약 `security=S1` 파드 레이블이 있는 하나 이상의 기존 파드를 실행하고 있는 노드가 +`zone=V`에 하나 이상 존재한다면, +스케줄러는 파드를 `topology.kubernetes.io/zone=V` 레이블이 있는 노드에 배치해야 한다. -원칙적으로, `topologyKey` 는 적법한 어느 레이블-키도 될 수 있다. -하지만, 성능과 보안상의 이유로 topologyKey에는 몇 가지 제약조건이 있다. +위의 안티-어피니티 규칙은 `security=S2` 레이블이 있는 하나 이상의 기존 파드의 존와 동일한 존에 있는 노드에는 +가급적 파드를 스케줄링하지 않도록 스케줄러에 지시한다. +더 정확히 말하면, 만약 `security=S2` 파드 레이블이 있는 파드가 실행되고 있는 `zone=R`에 +다른 노드도 존재한다면, +스케줄러는 `topology.kubernetes.io/zone=R` 레이블이 있는 노드에는 가급적 해당 파드를 스케줄링하지 않야아 한다. -1. 파드 어피니티에서 `requiredDuringSchedulingIgnoredDuringExecution` 와 `preferredDuringSchedulingIgnoredDuringExecution` 는 -`topologyKey` 의 빈 값을 허용하지 않는다. -2. 파드 안티-어피니티에서도 `requiredDuringSchedulingIgnoredDuringExecution` 와 `preferredDuringSchedulingIgnoredDuringExecution` 는 -`topologyKey` 의 빈 값을 허용하지 않는다. -3. `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에서 `topologyKey` 를 `kubernetes.io/hostname` 로 제한하기 위해 어드미션 컨트롤러 `LimitPodHardAntiAffinityTopology` 가 도입되었다. 사용자 지정 토폴로지를 사용할 수 있도록 하려면, 어드미션 컨트롤러를 수정하거나 아니면 이를 비활성화해야 한다. -4. 위의 경우를 제외하고, `topologyKey` 는 적법한 어느 레이블-키도 가능하다. +[디자인 문서](https://git.k8s.io/community/contributors/design-proposals/scheduling/podaffinity.md)에서 +파드 어피니티와 안티-어피니티에 대한 +많은 예시를 볼 수 있다. -`labelSelector` 와 `topologyKey` 외에도 `labelSelector` 와 일치해야 하는 네임스페이스 목록 `namespaces` 를 -선택적으로 지정할 수 있다(이것은 `labelSelector` 와 `topologyKey` 와 같은 수준의 정의이다). -생략되어 있거나 비어있을 경우 어피니티/안티-어피니티 정의가 있는 파드의 네임스페이스가 기본 값이다. +파드 어피니티와 안티-어피니티의 `operator` 필드에 +`In`, `NotIn`, `Exists` 및 `DoesNotExist` 값을 사용할 수 있다. -파드를 노드에 스케줄하려면 `requiredDuringSchedulingIgnoredDuringExecution` 어피니티와 안티-어피니티와 -연관된 `matchExpressions` 가 모두 충족되어야 한다. +원칙적으로, `topologyKey` 에는 성능과 보안상의 이유로 다음의 예외를 제외하면 +어느 레이블 키도 사용할 수 있다. -#### 네임스페이스 셀렉터 -{{< feature-state for_k8s_version="v1.22" state="beta" >}} +* 파드 어피니티 및 안티-어피니티에 대해, 빈 `topologyKey` 필드는 + `requiredDuringSchedulingIgnoredDuringExecution` 및 `preferredDuringSchedulingIgnoredDuringExecution` 내에 허용되지 않는다. +* `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티 규칙에 대해, + `LimitPodHardAntiAffinityTopology` 어드미션 컨트롤러는 + `topologyKey`를 `kubernetes.io/hostname`으로 제한한다. + 커스텀 토폴로지를 허용하고 싶다면 어드미션 컨트롤러를 수정하거나 비활성화할 수 있다. -사용자는 네임스페이스 집합에 대한 레이블 쿼리인 `namespaceSelector` 를 사용하여 일치하는 네임스페이스를 선택할 수도 있다. -어피니티 용어는 `namespaceSelector` 에서 선택한 네임스페이스와 `namespaces` 필드에 나열된 네임스페이스의 결합에 적용된다. -빈 `namespaceSelector` ({})는 모든 네임스페이스와 일치하는 반면, null 또는 빈 `namespaces` 목록과 -null `namespaceSelector` 는 "이 파드의 네임스페이스"를 의미한다. +`labelSelector`와 `topologyKey`에 더하여 선택적으로, +`labelSelector`가 비교해야 하는 네임스페이스의 목록을 +`labelSelector` 및 `topologyKey` 필드와 동일한 계위의 `namespaces` 필드에 명시할 수 있다. +생략하거나 비워 두면, +해당 어피니티/안티-어피니티 정의가 있는 파드의 네임스페이스를 기본값으로 사용한다. -이 기능은 베타이며 기본으로 활성화되어 있다. kube-apiserver 및 kube-scheduler 모두에서 -[기능 게이트](/ko/docs/reference/command-line-tools-reference/feature-gates/) -`PodAffinityNamespaceSelector` 를 사용하여 비활성화할 수 있다. +#### 네임스페이스 셀렉터 {#namespace-selector} +{{< feature-state for_k8s_version="v1.24" state="stable" >}} -#### 더 실용적인 유스케이스 +네임스페이스 집합에 대한 레이블 쿼리인 `namespaceSelector` 를 사용하여 일치하는 네임스페이스를 선택할 수도 있다. +`namespaceSelector` 또는 `namespaces` 필드에 의해 선택된 네임스페이스 모두에 적용된다. +빈 `namespaceSelector` ({})는 모든 네임스페이스와 일치하는 반면, +null 또는 빈 `namespaces` 목록과 null `namespaceSelector` 는 규칙이 적용된 파드의 네임스페이스에 매치된다. -파드간 어피니티와 안티-어피니티는 레플리카셋, 스테이트풀셋, 디플로이먼트 등과 같은 -상위 레벨 모음과 함께 사용할 때 더욱 유용할 수 있다. 워크로드 집합이 동일한 노드와 같이 +{{}} +이 기능은 베타 단계이며 기본적으로 활성화되어 있다. +kube-apiserver 및 kube-scheduler의 `PodAffinityNamespaceSelector` +[기능 게이트](/ko/docs/reference/command-line-tools-reference/feature-gates/)를 통해 이를 비활성화할 수 있다. +{{}} + +#### 더 실제적인 유스케이스 {#more-practical-use-cases} + +파드간 어피니티와 안티-어피니티는 레플리카셋, 스테이트풀셋, 디플로이먼트 등과 같은 +상위 레벨 모음과 함께 사용할 때 더욱 유용할 수 있다. +이러한 규칙을 사용하여, 워크로드 집합이 예를 들면 '동일한 노드'와 같이 동일하게 정의된 토폴로지와 같은 위치에 배치되도록 쉽게 구성할 수 있다. -##### 항상 같은 노드에 위치시키기 +redis와 같은 인-메모리 캐시를 사용하는 웹 애플리케이션을 실행하는 세 개의 노드로 구성된 클러스터를 가정한다. +이 때 웹 서버를 가능한 한 캐시와 같은 위치에서 실행되도록 하기 위해 +파드간 어피니티/안티-어피니티를 사용할 수 있다. -세 개의 노드가 있는 클러스터에서 웹 애플리케이션에는 redis와 같은 인-메모리 캐시가 있다. 웹 서버가 가능한 캐시와 함께 위치하기를 원한다. - -다음은 세 개의 레플리카와 셀렉터 레이블이 `app=store` 가 있는 간단한 redis 디플로이먼트의 yaml 스니펫이다. 디플로이먼트에는 스케줄러가 단일 노드에서 레플리카를 함께 배치하지 않도록 `PodAntiAffinity` 가 구성되어 있다. +다음의 redis 캐시 디플로이먼트 예시에서, 레플리카는 `app=store` 레이블을 갖는다. +`podAntiAffinity` 규칙은 스케줄러로 하여금 +`app=store` 레이블이 있는 레플리카를 한 노드에 여러 개 배치하지 못하도록 한다. +이렇게 하여 캐시 파드를 각 노드에 분산하여 생성한다. ```yaml apiVersion: apps/v1 @@ -324,7 +385,10 @@ spec: image: redis:3.2-alpine ``` -아래 yaml 스니펫의 웹서버 디플로이먼트는 `podAntiAffinity` 와 `podAffinity` 설정을 가지고 있다. 이렇게 하면 스케줄러에 모든 레플리카는 셀렉터 레이블이 `app=store` 인 파드와 함께 위치해야 한다. 또한 각 웹 서버 레플리카가 단일 노드의 같은 위치에 있지 않도록 한다. +웹 서버를 위한 다음의 디플로이먼트는 `app=web-store` 레이블을 갖는 레플리카를 생성한다. +파드 어피니티 규칙은 스케줄러로 하여금 `app=store` 레이블이 있는 파드를 실행 중인 노드에 각 레플리카를 배치하도록 한다. +파드 안티-어피니티 규칙은 스케줄러로 하여금 `app=web-store` 레이블이 있는 서버 파드를 +한 노드에 여러 개 배치하지 못하도록 한다. ```yaml apiVersion: apps/v1 @@ -365,44 +429,25 @@ spec: image: nginx:1.16-alpine ``` -만약 위의 두 디플로이먼트를 생성하면 세 개의 노드가 있는 클러스터는 다음과 같아야 한다. +위의 두 디플로이먼트를 생성하면 다음과 같은 클러스터 형상이 나타나는데, +세 노드에 각 웹 서버가 캐시와 함께 있는 형상이다. | node-1 | node-2 | node-3 | |:--------------------:|:-------------------:|:------------------:| | *webserver-1* | *webserver-2* | *webserver-3* | | *cache-1* | *cache-2* | *cache-3* | -여기서 볼 수 있듯이 `web-server` 의 세 레플리카들이 기대했던 것처럼 자동으로 캐시와 함께 위치하게 된다. +[ZooKeeper 튜토리얼](/ko/docs/tutorials/stateful-application/zookeeper/#노드-실패-방지)에서 +위 예시와 동일한 기술을 사용해 +고 가용성을 위한 안티-어피니티로 구성된 스테이트풀셋의 예시를 확인한다. -``` -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 -``` +## nodeName {#nodename} -##### 절대 동일한 노드에 위치시키지 않게 하기 - -위의 예시에서 `topologyKey:"kubernetes.io/hostname"` 과 함께 `PodAntiAffinity` 규칙을 사용해서 -두 개의 인스터스가 동일한 호스트에 있지 않도록 redis 클러스터를 배포한다. -같은 기술을 사용해서 고 가용성을 위해 안티-어피니티로 구성된 스테이트풀셋의 예시는 -[ZooKeeper 튜토리얼](/ko/docs/tutorials/stateful-application/zookeeper/#노드-실패-방지)을 본다. - -## nodeName - -`nodeName` 은 가장 간단한 형태의 노트 선택 제약 조건이지만, -한계로 인해 일반적으로는 사용하지 않는다. -`nodeName` 은 PodSpec의 필드이다. 만약 비어있지 않으면, 스케줄러는 -파드를 무시하고 명명된 노드에서 실행 중인 kubelet이 -파드를 실행하려고 한다. 따라서 만약 PodSpec에 `nodeName` 가 -제공된 경우, 노드 선택을 위해 위의 방법보다 우선한다. +`nodeName`은 어피니티 또는 `nodeSelector`보다 더 직접적인 형태의 노드 선택 방법이다. +`nodeName`은 파드 스펙의 필드 중 하나이다. +`nodeName` 필드가 비어 있지 않으면, 스케줄러는 파드를 무시하고, +명명된 노드의 kubelet이 해당 파드를 자기 노드에 배치하려고 시도한다. +`nodeName`은 `nodeSelector` 또는 어피니티/안티-어피니티 규칙이 무시된다. `nodeName` 을 사용해서 노드를 선택할 때의 몇 가지 제한은 다음과 같다. @@ -414,7 +459,7 @@ web-server-1287567482-s330j 1/1 Running 0 7m 10.192.3 - 클라우드 환경의 노드 이름은 항상 예측 가능하거나 안정적인 것은 아니다. -여기에 `nodeName` 필드를 사용하는 파드 설정 파일 예시가 있다. +다음은 `nodeName` 필드를 사용하는 파드 스펙 예시이다. ```yaml apiVersion: v1 @@ -428,19 +473,14 @@ spec: nodeName: kube-01 ``` -위 파드는 kube-01 노드에서 실행될 것이다. - - +위 파드는 `kube-01` 노드에서만 실행될 것이다. ## {{% heading "whatsnext" %}} - -[테인트](/ko/docs/concepts/scheduling-eviction/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/)는 -노드 수준의 리소스 할당 결정에 참여할 수 있다. +* [테인트 및 톨러레이션](/ko/docs/concepts/scheduling-eviction/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)에 대한 디자인 문서를 읽어본다. +* [토폴로지 매니저](/docs/tasks/administer-cluster/topology-manager/)가 + 노드 수준 리소스 할당 결정에 어떻게 관여하는지 알아본다. +* [노드셀렉터(nodeSelector)](/ko/docs/tasks/configure-pod-container/assign-pods-nodes/)를 어떻게 사용하는지 알아본다. +* [어피니티/안티-어피니티](/ko/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/)를 어떻게 사용하는지 알아본다. diff --git a/content/ko/docs/concepts/scheduling-eviction/pod-overhead.md b/content/ko/docs/concepts/scheduling-eviction/pod-overhead.md index b0da80ceae..61fafa4ed4 100644 --- a/content/ko/docs/concepts/scheduling-eviction/pod-overhead.md +++ b/content/ko/docs/concepts/scheduling-eviction/pod-overhead.md @@ -1,4 +1,8 @@ --- + + + + title: 파드 오버헤드 content_type: concept weight: 30 @@ -25,11 +29,11 @@ _파드 오버헤드_ 는 컨테이너 리소스 요청과 상한 위에서 파 [어드미션](/docs/reference/access-authn-authz/extensible-admission-controllers/#what-are-admission-webhooks) 이 수행될 때 지정된다. -파드 오버헤드가 활성화 되면, 파드를 노드에 스케줄링 할 때 컨테이너 리소스 요청의 합에 -파드의 오버헤드를 추가해서 스케줄링을 고려한다. 마찬가지로, kubelet은 파드의 cgroups 크기를 변경하거나 -파드의 축출 등급을 부여할 때에도 파드의 오버헤드를 포함하여 고려한다. +파드를 노드에 스케줄링할 때, 컨테이너 리소스 요청의 합 뿐만 아니라 파드의 오버헤드도 함께 고려된다. +마찬가지로, kubelet은 파드의 cgroups 크기를 변경하거나 파드의 축출 등급을 부여할 때에도 +파드의 오버헤드를 포함하여 고려한다. -## 파드 오버헤드 활성화하기 {#set-up} +## 파드 오버헤드 환경 설정하기 {#set-up} 기능 활성화를 위해 클러스터에서 `PodOverhead` [기능 게이트](/ko/docs/reference/command-line-tools-reference/feature-gates/)가 활성화되어 있고(1.18 버전에서는 기본적으로 활성화), @@ -37,7 +41,7 @@ _파드 오버헤드_ 는 컨테이너 리소스 요청과 상한 위에서 파 ## 사용 예제 -파드 오버헤드 기능을 사용하기 위하여, `overhead` 필드를 정의하는 런타임클래스가 필요하다. +파드 오버헤드를 활용하려면, `overhead` 필드를 정의하는 런타임클래스가 필요하다. 예를 들어, 가상 머신 및 게스트 OS에 대하여 파드 당 120 MiB를 사용하는 가상화 컨테이너 런타임의 런타임클래스의 경우 다음과 같이 정의 할 수 있다. @@ -68,7 +72,7 @@ spec: runtimeClassName: kata-fc containers: - name: busybox-ctr - image: busybox + image: busybox:1.28 stdin: true tty: true resources: @@ -109,10 +113,10 @@ kube-scheduler 는 어떤 노드에 파드가 기동 되어야 할지를 정할 일단 파드가 특정 노드에 스케줄링 되면, 해당 노드에 있는 kubelet 은 파드에 대한 새로운 {{< glossary_tooltip text="cgroup" term_id="cgroup" >}}을 생성한다. 기본 컨테이너 런타임이 만들어내는 컨테이너들은 이 파드 안에 존재한다. -만약 각 컨테이너에 대하여 QoS가 보장되었거나 향상이 가능하도록 QoS 의 리소스 상한 제한이 걸려있으면, -kubelet 은 해당 리소스(CPU의 경우 cpu.cfs_quota_us, 메모리의 경우 memory.limit_in_bytes)와 연관된 파드의 -cgroup 의 상한선을 설정한다. 이 상한선은 컨테이너 리소스 상한과 PodSpec에 -정의된 `overhead` 의 합에 기반한다. +만약 각 컨테이너에 대하여 리소스 상한 제한이 걸려있으면 +(제한이 걸려있는 보장된(Guaranteed) Qos 또는 향상 가능한(Burstable) QoS), +kubelet 은 해당 리소스(CPU의 경우 cpu.cfs_quota_us, 메모리의 경우 memory.limit_in_bytes)와 연관된 파드의 cgroup 의 상한선을 설정한다. +이 상한선은 컨테이너 리소스 상한과 PodSpec에 정의된 `overhead` 의 합에 기반한다. CPU의 경우, 만약 파드가 보장형 또는 버스트형 QoS로 설정되었으면, kubelet은 PodSpec에 정의된 `overhead` 에 컨테이너의 리소스 요청의 합을 더한 값을 `cpu.shares` 로 설정한다. diff --git a/content/ko/docs/concepts/scheduling-eviction/resource-bin-packing.md b/content/ko/docs/concepts/scheduling-eviction/resource-bin-packing.md index c3dcf84727..8c5f19b8ff 100644 --- a/content/ko/docs/concepts/scheduling-eviction/resource-bin-packing.md +++ b/content/ko/docs/concepts/scheduling-eviction/resource-bin-packing.md @@ -21,25 +21,24 @@ kube-scheduler를 미세 조정할 수 있다. ## RequestedToCapacityRatioResourceAllocation을 사용해서 빈 패킹 활성화하기 -쿠버네티스를 사용하면 사용자가 각 리소스에 대한 가중치와 함께 리소스를 지정하여 -용량 대비 요청 비율을 기반으로 노드의 점수를 매기는 것을 허용한다. 이를 -통해 사용자는 적절한 파라미터를 사용해서 확장된 리소스를 빈 팩으로 만들 수 있어 -대규모의 클러스터에서 부족한 리소스의 활용도가 향상된다. -`RequestedToCapacityRatioResourceAllocation` 우선 순위 기능의 -동작은 `RequestedToCapacityRatioArgs`라는 -구성 옵션으로 제어할 수 있다. 이 인수는 `shape`와 `resources` -두 개의 파라미터로 구성된다. `shape` 파라미터는 사용자가 `utilization`과 -`score` 값을 기반으로 최소 요청 또는 최대 요청된 대로 기능을 -조정할 수 있게 한다. `resources` 파라미터는 점수를 매길 때 고려할 -리소스의 `name` 과 각 리소스의 가중치를 지정하는 `weight` 로 -구성된다. +쿠버네티스는 사용자가 각 리소스에 대한 가중치와 함께 리소스를 지정하여 +용량 대비 요청 비율을 기반으로 노드의 점수를 매기는 것을 허용한다. +이를 통해 사용자는 적절한 파라미터를 사용해서 확장된 리소스를 빈 팩으로 만들 수 있어 +대규모의 클러스터에서 부족한 리소스의 활용도가 향상된다. +`RequestedToCapacityRatioResourceAllocation` 우선 순위 기능의 동작은 +`RequestedToCapacityRatioArgs`라는 구성 옵션으로 제어할 수 있다. +이 인수는 `shape`와 `resources` 두 개의 파라미터로 구성된다. +`shape` 파라미터는 사용자가 `utilization`과 `score` 값을 기반으로 +최소 요청 또는 최대 요청된 대로 기능을 조정할 수 있게 한다. +`resources` 파라미터는 점수를 매길 때 고려할 리소스의 `name` 과 +각 리소스의 가중치를 지정하는 `weight` 로 구성된다. 다음은 확장된 리소스 `intel.com/foo` 와 `intel.com/bar` 에 대한 `requestedToCapacityRatioArguments` 를 빈 패킹 동작으로 설정하는 구성의 예시이다. ```yaml -apiVersion: kubescheduler.config.k8s.io/v1beta1 +apiVersion: kubescheduler.config.k8s.io/v1beta3 kind: KubeSchedulerConfiguration profiles: # ... diff --git a/content/ko/docs/concepts/security/controlling-access.md b/content/ko/docs/concepts/security/controlling-access.md index cf2fc529ce..ad30adf3c6 100644 --- a/content/ko/docs/concepts/security/controlling-access.md +++ b/content/ko/docs/concepts/security/controlling-access.md @@ -1,7 +1,9 @@ --- + + + title: 쿠버네티스 API 접근 제어하기 content_type: concept -weight: 5 --- @@ -29,13 +31,16 @@ API 서버의 인증서에 대한 루트 인증서를 포함하며, 이 인증서는 일반적으로 `$USER/.kube/config`에 자동으로 기록된다. 클러스터에 여러 명의 사용자가 있는 경우, 작성자는 인증서를 다른 사용자와 공유해야 한다. +클라이언트는 이 단계에서 TLS 클라이언트 인증서를 제시할 수 있다. + ## 인증 TLS가 설정되면 HTTP 요청이 인증 단계로 넘어간다. 이는 다이어그램에 **1**단계로 표시되어 있다. 클러스터 생성 스크립트 또는 클러스터 관리자는 API 서버가 하나 이상의 인증기 모듈을 실행하도록 구성한다. -인증기는 [여기](/docs/reference/access-authn-authz/authentication/)에서 더 자세히 서술한다. +인증기에 대해서는 +[인증](/docs/reference/access-authn-authz/authentication/)에서 더 자세히 서술한다. 인증 단계로 들어가는 것은 온전한 HTTP 요청이지만 일반적으로 헤더 그리고/또는 클라이언트 인증서를 검사한다. @@ -46,8 +51,6 @@ JWT 토큰(서비스 어카운트에 사용됨)을 포함한다. 여러 개의 인증 모듈을 지정할 수 있으며, 이 경우 하나의 인증 모듈이 성공할 때까지 각 모듈을 순차적으로 시도한다. -GCE에서는 클라이언트 인증서, 암호, 일반 토큰 및 JWT 토큰이 모두 사용 가능하다. - 요청을 인증할 수 없는 경우 HTTP 상태 코드 401과 함께 거부된다. 이 외에는 사용자가 특정 `username`으로 인증되며, 이 username은 다음 단계에서 사용자의 결정에 사용할 수 있다. @@ -126,6 +129,12 @@ Bob이 `projectCaribou` 네임스페이스에 있는 오브젝트에 쓰기(`cre 요청이 모든 어드미션 제어 모듈을 통과하면 유효성 검사 루틴을 사용하여 해당 API 오브젝트를 검증한 후 오브젝트 저장소에 기록(**4**단계)된다. +## 감사(Auditing) + +쿠버네티스 감사는 클러스터에서 발생하는 일들의 순서를 문서로 기록하여, 보안과 관련되어 있고 시간 순서로 정리된 기록을 제공한다. +클러스터는 사용자, 쿠버네티스 API를 사용하는 애플리케이션, 그리고 컨트롤 플레인 자신이 생성한 활동을 감사한다. + +더 많은 정보는 [감사](/docs/tasks/debug/debug-cluster/audit/)를 참고한다. ## API 서버 포트와 IP diff --git a/content/ko/docs/concepts/services-networking/dns-pod-service.md b/content/ko/docs/concepts/services-networking/dns-pod-service.md index 75c1d14ccf..9b4521e2b7 100644 --- a/content/ko/docs/concepts/services-networking/dns-pod-service.md +++ b/content/ko/docs/concepts/services-networking/dns-pod-service.md @@ -323,17 +323,6 @@ kube-apiserver와 kubelet에 `ExpandedDNSConfig` 기능 게이트가 활성화 쿠버네티스는 최대 32개의 탐색 도메인과 최대 2048자의 탐색 도메인 목록을 허용한다. -### 기능 가용성 - -파드 DNS 환경 설정 기능과 DNS 정책 "`None`" 기능의 쿠버네티스 버전별 가용성은 다음과 같다. - -| 쿠버네티스 버전 | 기능 지원 | -| :---------: |:-----------:| -| 1.14 | 안정 | -| 1.10 | 베타 (기본값으로 켜져 있음)| -| 1.9 | 알파 | - - ## {{% heading "whatsnext" %}} diff --git a/content/ko/docs/concepts/services-networking/endpoint-slices.md b/content/ko/docs/concepts/services-networking/endpoint-slices.md index 4ea1281faa..7a3c2f0e0e 100644 --- a/content/ko/docs/concepts/services-networking/endpoint-slices.md +++ b/content/ko/docs/concepts/services-networking/endpoint-slices.md @@ -1,4 +1,6 @@ --- + + title: 엔드포인트슬라이스 content_type: concept weight: 45 @@ -144,12 +146,12 @@ endpoints: v1 API에서는, 전용 필드 `nodeName` 및 `zone` 을 위해 엔드 포인트별 `topology` 가 효과적으로 제거되었다. -`EndpointSlice` 리소스의 `endpoint` 필드에 임의의 토폴로지 필드를 -설정하는 것은 더 이상 사용되지 않으며, v1 API에서 지원되지 않는다. 대신, -v1 API는 개별 `nodeName` 및 `zone` 필드 설정을 지원한다. 이러한 -필드는 API 버전 간에 자동으로 번역된다. 예를 들어, -v1beta1 API의 `topology` 필드에 있는 `"topology.kubernetes.io/zone"` -키 값은 v1 API의 `zone` 필드로 접근할 수 있다. +`EndpointSlice` 리소스의 `endpoint` 필드에 임의의 토폴로지 필드를 설정하는 것은 +더 이상 사용되지 않으며 v1 API에서 지원되지 않는다. +대신, v1 API는 개별 `nodeName` 및 `zone` 필드 설정을 지원한다. +이러한 필드는 API 버전 간에 자동으로 번역된다. +예를 들어, v1beta1 API의 `topology` 필드에 있는 `"topology.kubernetes.io/zone"` 키 값은 +v1 API의 `zone` 필드로 접근할 수 있다. {{< /note >}} ### 관리 diff --git a/content/ko/docs/concepts/services-networking/ingress-controllers.md b/content/ko/docs/concepts/services-networking/ingress-controllers.md index 72c68d0563..67073efa4c 100644 --- a/content/ko/docs/concepts/services-networking/ingress-controllers.md +++ b/content/ko/docs/concepts/services-networking/ingress-controllers.md @@ -23,7 +23,7 @@ weight: 40 {{% thirdparty-content %}} -* [AKS 애플리케이션 게이트웨이 인그레스 컨트롤러](https://azure.github.io/application-gateway-kubernetes-ingress/)는 [Azure 애플리케이션 게이트웨이](https://docs.microsoft.com)를 구성하는 인그레스 컨트롤러다. +* [AKS 애플리케이션 게이트웨이 인그레스 컨트롤러](https://docs.microsoft.com/azure/application-gateway/tutorial-ingress-controller-add-on-existing?toc=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Faks%2Ftoc.json&bc=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fbread%2Ftoc.json)는 [Azure 애플리케이션 게이트웨이](https://docs.microsoft.com/azure/application-gateway/overview)를 구성하는 인그레스 컨트롤러다. * [Ambassador](https://www.getambassador.io/) API 게이트웨이는 [Envoy](https://www.envoyproxy.io) 기반 인그레스 컨트롤러다. * [Apache APISIX 인그레스 컨트롤러](https://github.com/apache/apisix-ingress-controller)는 [Apache APISIX](https://github.com/apache/apisix) 기반의 인그레스 컨트롤러이다. @@ -48,6 +48,7 @@ weight: 40 구동하는 인그레스 컨트롤러다. * [쿠버네티스 용 NGINX 인그레스 컨트롤러](https://www.nginx.com/products/nginx-ingress-controller/)는 [NGINX](https://www.nginx.com/resources/glossary/nginx/) 웹서버(프록시로 사용)와 함께 작동한다. +* [Pomerium 인그레스 컨트롤러](https://www.pomerium.com/docs/k8s/ingress.html)는 [Pomerium](https://pomerium.com/) 기반 인그레스 컨트롤러이며, 상황 인지 접근 정책을 제공한다. * [Skipper](https://opensource.zalando.com/skipper/kubernetes/ingress-controller/)는 사용자의 커스텀 프록시를 구축하기 위한 라이브러리로 설계된 쿠버네티스 인그레스와 같은 유스케이스를 포함한 서비스 구성을 위한 HTTP 라우터 및 역방향 프록시다. * [Traefik 쿠버네티스 인그레스 제공자](https://doc.traefik.io/traefik/providers/kubernetes-ingress/)는 [Traefik](https://traefik.io/traefik/) 프록시 용 인그레스 컨트롤러다. diff --git a/content/ko/docs/concepts/services-networking/ingress.md b/content/ko/docs/concepts/services-networking/ingress.md index dff0437b00..ba281bf659 100644 --- a/content/ko/docs/concepts/services-networking/ingress.md +++ b/content/ko/docs/concepts/services-networking/ingress.md @@ -74,7 +74,7 @@ graph LR; {{< codenew file="service/networking/minimal-ingress.yaml" >}} -다른 모든 쿠버네티스 리소스와 마찬가지로 인그레스에는 `apiVersion`, `kind`, 그리고 `metadata` 필드가 필요하다. +인그레스에는 `apiVersion`, `kind`, `metadata` 및 `spec` 필드가 명시되어야 한다. 인그레스 오브젝트의 이름은 유효한 [DNS 서브도메인 이름](/ko/docs/concepts/overview/working-with-objects/names/#dns-서브도메인-이름)이어야 한다. 설정 파일의 작성에 대한 일반적인 내용은 [애플리케이션 배포하기](/ko/docs/tasks/run-application/run-stateless-application-deployment/), [컨테이너 구성하기](/docs/tasks/configure-pod-container/configure-pod-configmap/), [리소스 관리하기](/ko/docs/concepts/cluster-administration/manage-deployment/)를 참조한다. @@ -118,8 +118,14 @@ graph LR; ### DefaultBackend {#default-backend} -규칙이 없는 인그레스는 모든 트래픽을 단일 기본 백엔드로 전송한다. `defaultBackend` 는 일반적으로 -[인그레스 컨트롤러](/ko/docs/concepts/services-networking/ingress-controllers)의 구성 옵션이며, 인그레스 리소스에 지정되어 있지 않다. +규칙이 없는 인그레스는 모든 트래픽을 단일 기본 백엔드로 전송하며, +`.spec.defaultBackend`는 이와 같은 경우에 요청을 처리할 백엔드를 지정한다. +`defaultBackend` 는 일반적으로 [인그레스 컨트롤러](/ko/docs/concepts/services-networking/ingress-controllers)의 구성 옵션이며, +인그레스 리소스에 지정되어 있지 않다. +`.spec.rules` 가 명시되어 있지 않으면, +`.spec.defaultBackend` 는 반드시 명시되어 있어야 한다. +`defaultBackend` 가 설정되어 있지 않으면, 어느 규칙에도 해당되지 않는 요청의 처리는 인그레스 컨트롤러의 구현을 따른다(이러한 +경우를 어떻게 처리하는지 알아보려면 해당 인그레스 컨트롤러 문서를 참고한다). 만약 인그레스 오브젝트의 HTTP 요청과 일치하는 호스트 또는 경로가 없으면, 트래픽은 기본 백엔드로 라우팅 된다. @@ -309,7 +315,7 @@ spec: controller: example.com/ingress-controller parameters: # 이 인그레스클래스에 대한 파라미터는 - # "external-configuration" 환경 설정 네임스페이스에 있는 + # "external-configuration" 네임스페이스에 있는 # "external-config" 라는 IngressParameter(API 그룹 k8s.example.com)에 기재되어 있다. scope: Namespace apiGroup: k8s.example.com diff --git a/content/ko/docs/concepts/services-networking/network-policies.md b/content/ko/docs/concepts/services-networking/network-policies.md index a7d47701ac..f72d1f0cff 100644 --- a/content/ko/docs/concepts/services-networking/network-policies.md +++ b/content/ko/docs/concepts/services-networking/network-policies.md @@ -45,42 +45,7 @@ pod- 또는 namespace- 기반의 네트워크폴리시를 정의할 때, {{< glo 네트워크폴리시 의 예시는 다음과 같다. -```yaml -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - name: test-network-policy - namespace: default -spec: - podSelector: - matchLabels: - role: db - policyTypes: - - Ingress - - Egress - ingress: - - from: - - ipBlock: - cidr: 172.17.0.0/16 - except: - - 172.17.1.0/24 - - namespaceSelector: - matchLabels: - project: myproject - - podSelector: - matchLabels: - role: frontend - ports: - - protocol: TCP - port: 6379 - egress: - - to: - - ipBlock: - cidr: 10.0.0.0/24 - ports: - - protocol: TCP - port: 5978 -``` +{{< codenew file="service/networking/networkpolicy.yaml" >}} {{< note >}} 선택한 네트워킹 솔루션이 네트워킹 정책을 지원하지 않으면 클러스터의 API 서버에 이를 POST 하더라도 효과가 없다. @@ -281,7 +246,7 @@ API 서버에 대해 `--feature-gates=NetworkPolicyEndPort=false,…` 명령을 ## 이름으로 네임스페이스 지정 -{{< feature-state state="beta" for_k8s_version="1.21" >}} +{{< feature-state for_k8s_version="1.22" state="stable" >}} 쿠버네티스 컨트롤 플레인은 `NamespaceDefaultLabelName` [기능 게이트](/ko/docs/reference/command-line-tools-reference/feature-gates/)가 활성화된 경우 diff --git a/content/ko/docs/concepts/services-networking/service.md b/content/ko/docs/concepts/services-networking/service.md index 871323ea2a..265f5904d8 100644 --- a/content/ko/docs/concepts/services-networking/service.md +++ b/content/ko/docs/concepts/services-networking/service.md @@ -24,7 +24,7 @@ weight: 10 ## 동기 -쿠버네티스 {{< glossary_tooltip term_id="pod" text="파드" >}}는 클러스터 상태와 +쿠버네티스 {{< glossary_tooltip term_id="pod" text="파드" >}}는 클러스터 목표 상태(desired state)와 일치하도록 생성되고 삭제된다. 파드는 비영구적 리소스이다. 만약 앱을 실행하기 위해 {{< glossary_tooltip term_id="deployment" text="디플로이먼트" >}}를 사용한다면, 동적으로 파드를 생성하고 제거할 수 있다. @@ -108,13 +108,46 @@ spec: 필드와 같은 값으로 설정된다. {{< /note >}} -파드의 포트 정의에는 이름이 있고, 서비스의 `targetPort` 속성에서 이 이름을 -참조할 수 있다. 이것은 다른 포트 번호를 통한 가용한 동일 네트워크 프로토콜이 있고, -단일 구성 이름을 사용하는 서비스 내에 -혼합된 파드가 존재해도 가능하다. -이를 통해 서비스를 배포하고 진전시키는데 많은 유연성을 제공한다. -예를 들어, 클라이언트를 망가뜨리지 않고, 백엔드 소프트웨어의 다음 -버전에서 파드가 노출시키는 포트 번호를 변경할 수 있다. +파드의 포트 정의에 이름이 있으므로, +서비스의 `targetPort` 속성에서 이 이름을 참조할 수 있다. +예를 들어, 다음과 같은 방법으로 서비스의 `targetPort`를 파드 포트에 바인딩할 수 있다. + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: nginx + labels: + app.kubernetes.io/name: proxy +spec: + containers: + - name: nginx + image: nginx:11.14.2 + ports: + - containerPort: 80 + name: http-web-svc + +--- +apiVersion: v1 +kind: Service +metadata: + name: nginx-service +spec: + selector: + app.kubernetes.io/name: proxy + ports: + - name: name-of-service-port + protocol: TCP + port: 80 + targetPort: http-web-svc +``` + + +이것은 서로 다른 포트 번호를 통해 가용한 동일 네트워크 프로토콜이 있고, +단일 구성 이름을 사용하는 서비스 내에 혼합된 파드가 존재해도 가능하다. +이를 통해 서비스를 배포하고 진전시키는 데 많은 유연성을 제공한다. +예를 들어, 클라이언트를 망가뜨리지 않고, +백엔드 소프트웨어의 다음 버전에서 파드가 노출시키는 포트 번호를 변경할 수 있다. 서비스의 기본 프로토콜은 TCP이다. 다른 [지원되는 프로토콜](#protocol-support)을 사용할 수도 있다. @@ -125,9 +158,9 @@ spec: ### 셀렉터가 없는 서비스 -서비스는 일반적으로 쿠버네티스 파드에 대한 접근을 추상화하지만, -다른 종류의 백엔드를 추상화할 수도 있다. -예를 들면 +서비스는 일반적으로 셀렉터를 이용하여 쿠버네티스 파드에 대한 접근을 추상화하지만, +셀렉터 대신 매칭되는(corresponding) 엔드포인트와 함께 사용되면 다른 종류의 백엔드도 추상화할 수 있으며, +여기에는 클러스터 외부에서 실행되는 것도 포함된다. 예시는 다음과 같다. * 프로덕션 환경에서는 외부 데이터베이스 클러스터를 사용하려고 하지만, 테스트 환경에서는 자체 데이터베이스를 사용한다. diff --git a/content/ko/docs/concepts/services-networking/topology-aware-hints.md b/content/ko/docs/concepts/services-networking/topology-aware-hints.md index 7f086a5eee..bf0f1fb8c2 100644 --- a/content/ko/docs/concepts/services-networking/topology-aware-hints.md +++ b/content/ko/docs/concepts/services-networking/topology-aware-hints.md @@ -19,6 +19,12 @@ _토폴로지 인지 힌트(Topology Aware Hints)_ 는 클라이언트가 엔드 예를 들어, 비용을 줄이거나 네트워크 성능을 높이기 위해, 인접성을 고려하여 트래픽을 라우트할 수 있다. +{{< note >}} +"토폴로지 인지 힌트" 기능은 베타 단계이며 기본적으로 활성화되어 있지 **않다**. +이 기능을 사용해 보려면, +`TopologyAwareHints` [기능 게이트](/ko/docs/reference/command-line-tools-reference/feature-gates/)를 활성화해야 한다. +{{< /note >}} + ## 동기(motivation) diff --git a/content/ko/docs/concepts/storage/ephemeral-volumes.md b/content/ko/docs/concepts/storage/ephemeral-volumes.md index ea3a05d74b..99a426aa07 100644 --- a/content/ko/docs/concepts/storage/ephemeral-volumes.md +++ b/content/ko/docs/concepts/storage/ephemeral-volumes.md @@ -107,7 +107,7 @@ metadata: spec: containers: - name: my-frontend - image: busybox + image: busybox:1.28 volumeMounts: - mountPath: "/data" name: my-csi-inline-vol @@ -125,9 +125,17 @@ spec: 더 자세한 사항은 각 CSI 드라이버 문서를 참고한다. +### CSI 드라이버 제한 사항 + +{{< feature-state for_k8s_version="v1.21" state="deprecated" >}} + 클러스터 관리자는, [파드시큐리티폴리시(PodSecurityPolicy)](/ko/docs/concepts/policy/pod-security-policy/)를 사용하여 파드 내에서 어떤 CSI 드라이버가 사용될 수 있는지를 제어할 수 있으며, [`allowedCSIDrivers` 필드](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podsecuritypolicyspec-v1beta1-policy)에 기재하면 된다. +{{< note >}} +파드시큐리티폴리시는 사용 중단되었으며 쿠버네티스 v1.25 릴리스에서 제거될 예정이다. +{{< /note >}} + ### 일반 임시 볼륨 {#generic-ephemeral-volumes} {{< feature-state for_k8s_version="v1.23" state="stable" >}} @@ -158,7 +166,7 @@ metadata: spec: containers: - name: my-frontend - image: busybox + image: busybox:1.28 volumeMounts: - mountPath: "/scratch" name: scratch-volume @@ -242,13 +250,12 @@ GenericEphemeralVolume 기능을 활성화하면 심지어 사용자가 PVC를 직접적으로 만들 수 있는 권한이 없는 경우에도 이를 허용한다. 클러스터 관리자는 이를 명심해야 한다. 이것이 보안 모델에 부합하지 않는다면, 다음의 두 가지 선택지가 있다. -- `volumes`의 목록 중에 `ephemeral` 볼륨 타입이 없는 경우, - [파드시큐리티폴리시](/ko/docs/concepts/policy/pod-security-policy/)를 - 사용한다(쿠버네티스 - 1.21에서 사용 중단됨). - 일반 임시 볼륨을 갖는 파드와 같은 오브젝트를 거부하는 [어드미션 웹훅](/docs/reference/access-authn-authz/extensible-admission-controllers/)을 사용한다. +- `volumes`의 목록 중에 `ephemeral` 볼륨 타입이 없는 경우, + [파드시큐리티폴리시](/ko/docs/concepts/policy/pod-security-policy/)를 + 사용한다(쿠버네티스 1.21에서 사용 중단됨). 일반적인 [PVC의 네임스페이스 쿼터](/ko/docs/concepts/policy/resource-quotas/#스토리지-리소스-쿼터)는 여전히 적용되므로, 사용자가 이 새로운 메카니즘을 사용할 수 있도록 허용되었어도, diff --git a/content/ko/examples/pods/pod-with-affinity-anti-affinity.yaml b/content/ko/examples/pods/pod-with-affinity-anti-affinity.yaml new file mode 100644 index 0000000000..a7d14b2d6f --- /dev/null +++ b/content/ko/examples/pods/pod-with-affinity-anti-affinity.yaml @@ -0,0 +1,32 @@ +apiVersion: v1 +kind: Pod +metadata: + name: with-affinity-anti-affinity +spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/os + operator: In + values: + - linux + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + preference: + matchExpressions: + - key: label-1 + operator: In + values: + - key-1 + - weight: 50 + preference: + matchExpressions: + - key: label-2 + operator: In + values: + - key-2 + containers: + - name: with-node-affinity + image: k8s.gcr.io/pause:2.0 \ No newline at end of file diff --git a/content/ko/examples/service/networking/networkpolicy.yaml b/content/ko/examples/service/networking/networkpolicy.yaml new file mode 100644 index 0000000000..e91eed2f67 --- /dev/null +++ b/content/ko/examples/service/networking/networkpolicy.yaml @@ -0,0 +1,35 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: test-network-policy + namespace: default +spec: + podSelector: + matchLabels: + role: db + policyTypes: + - Ingress + - Egress + ingress: + - from: + - ipBlock: + cidr: 172.17.0.0/16 + except: + - 172.17.1.0/24 + - namespaceSelector: + matchLabels: + project: myproject + - podSelector: + matchLabels: + role: frontend + ports: + - protocol: TCP + port: 6379 + egress: + - to: + - ipBlock: + cidr: 10.0.0.0/24 + ports: + - protocol: TCP + port: 5978 +