Merge pull request #34257 from jihoon-seo/220613_Update_outdated_dev-1.23-ko.3_M17

[ko] Update outdated files in `dev-1.23-ko.3` (M17-M43)
pull/34423/head
Kubernetes Prow Robot 2022-06-19 16:04:03 -07:00 committed by GitHub
commit 04e900f07b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 616 additions and 459 deletions

View File

@ -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
```

View File

@ -29,8 +29,7 @@ weight: 10
레지스트리 호스트 이름을 지정하지 않으면, 쿠버네티스는 도커 퍼블릭 레지스트리를 의미한다고 가정한다.
이미지 이름 부분 다음에 _tag_ 를 추가할 수 있다(`docker` 와 `podman`
등의 명령과 함께 사용).
이미지 이름 부분 다음에 _tag_ 를 추가할 수 있다(`docker` 또는 `podman` 과 같은 명령을 사용할 때와 동일한 방식으로).
태그를 사용하면 동일한 시리즈 이미지의 다른 버전을 식별할 수 있다.
이미지 태그는 소문자와 대문자, 숫자, 밑줄(`_`),
@ -91,7 +90,7 @@ weight: 10
`<image-name>:<tag>``<image-name>@<digest>`로 교체한다.
(예를 들어, `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 - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: private-image-test-1
spec:
containers:
- name: uses-private-image
image: $PRIVATE_IMAGE_NAME
imagePullPolicy: Always
command: [ "echo", "SUCCESS" ]
EOF
```
```
pod/private-image-test-1 created
```
만약 모든 것이 잘 작동한다면, 잠시 후에, 다음을 실행할 수 있다.
```shell
kubectl logs private-image-test-1
```
그리고 커맨드 출력을 본다.
```
SUCCESS
```
명령이 실패한 것으로 의심되는 경우 다음을 실행할 수 있다.
```shell
kubectl describe pods/private-image-test-1 | grep 'Failed'
```
실패하는 케이스에는 출력이 다음과 유사하다.
```
Fri, 26 Jun 2015 15:36:13 -0700 Fri, 26 Jun 2015 15:39:13 -0700 19 {kubelet node-i2hq} spec.containers{uses-private-image} failed Failed to pull image "user/privaterepo:v1": Error: image user/privaterepo:v1 not found
```
클러스터의 모든 노드가 반드시 동일한 `.docker/config.json`를 가져야 한다. 그렇지 않으면, 파드가
일부 노드에서만 실행되고 다른 노드에서는 실패할 것이다. 예를 들어, 노드 오토스케일링을 사용한다면, 각 인스턴스
템플릿은 `.docker/config.json`을 포함하거나 그것을 포함한 드라이브를 마운트해야 한다.
프라이빗 레지스트리 키가 `.docker/config.json`에 추가되고 나면 모든 파드는
프라이빗 레지스트리의 이미지에 읽기 접근 권한을 가지게 될 것이다.
프라이빗 컨테이너 이미지 레지스트리 구성 예시를 보려면,
[프라이빗 레지스트리에서 이미지 가져오기](/ko/docs/tasks/configure-pod-container/pull-image-private-registry/)를 참조한다.
해당 예시는 도커 허브에서 제공하는 프라이빗 레지스트리를 사용한다.
### config.json 파일 해석 {#config-json}
@ -332,6 +247,7 @@ kubelet은 인식된 모든 크리덴셜을 순차적으로 이용하여 이미
이미지를 풀 해야 한다고 명시하면,
kubelet은 크리덴셜을 순차적으로 사용하여 풀을 시도한다.
### 미리 내려받은 이미지 {#pre-pulled-images}
{{< note >}}
@ -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" %}}

View File

@ -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" >}}

View File

@ -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/).

View File

@ -26,7 +26,7 @@ weight: 10
동적 등록을 통해 실행 중인 클러스터에서 커스텀 리소스가 나타나거나 사라질 수 있으며
클러스터 관리자는 클러스터 자체와 독립적으로 커스텀 리소스를 업데이트 할 수 있다.
커스텀 리소스가 설치되면 사용자는 *파드* 와 같은 빌트인 리소스와 마찬가지로
[kubectl](/ko/docs/reference/kubectl/overview/)을 사용하여 해당 오브젝트를 생성하고
[kubectl](/ko/docs/reference/kubectl/)을 사용하여 해당 오브젝트를 생성하고
접근할 수 있다.
## 커스텀 컨트롤러

View File

@ -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)

View File

@ -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)

View File

@ -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/) 살펴보기

View File

@ -28,7 +28,7 @@ card:
컨트롤 플레인 컴포넌트는 클러스터 내 어떠한 머신에서든지 동작할 수 있다. 그러나
간결성을 위하여, 구성 스크립트는 보통 동일 머신 상에 모든 컨트롤 플레인 컴포넌트를 구동시키고,
사용자 컨테이너는 해당 머신 상에 동작시키지 않는다. 여러 VM에서
사용자 컨테이너는 해당 머신 상에 동작시키지 않는다. 여러 머신에서
실행되는 컨트롤 플레인 설정의 예제를 보려면
[kubeadm을 사용하여 고가용성 클러스터 만들기](/docs/setup/production-environment/tools/kubeadm/high-availability/)를 확인해본다.

View File

@ -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/)과
같은 다른 커맨드 라인 도구를 통해 수행할 수 있다.

View File

@ -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" %}}

View File

@ -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" >}} </br>
`kubectl drain` 명령과 같은 kube-apiserver의 클라언트를 사용하여,
축출 API를 직접 호출해 축출 요청을 할 수 있다.
그러면 API 서버가 파드를 종료하는 `Eviction` 오브젝트가 생성된다.
축출 API를 직접 호출하거나, 또는 `kubectl drain` 명령과 같이
{{<glossary_tooltip term_id="kube-apiserver" text="API 서버">}}의 클라이언트를 사용하여 프로그램적인 방법으로 축출 요청을 할 수 있다.
이는 `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`: 현재 설정된
{{<glossary_tooltip term_id="pod-disruption-budget" text="PodDisruptionBudget">}} 때문에
축출이 현재 허용되지 않는다.
또는 API 요청 속도 제한(rate limiting) 때문에 이 응답을 받았을 수도 있다.
* `500 Internal Server Error`: 잘못된 환경 설정(예:
여러 PodDisruptionBudget이 하나의 동일한 파드를 참조함)으로 인해 축출이 허용되지 않는다.
축출하려는 파드가
PodDisruptionBudget이 설정된 워크로드에 속하지 않는다면,
API 서버는 항상 `200 OK`를 반환하고 축출을 허용한다.
API 서버가 축출을 허용하면, 파드는 다음과 같이 삭제된다.
1. API 서버 내 `Pod` 리소스의 삭제 타임스탬프(deletion timestamp)가 업데이트되며,
이 타임스탬프에 명시된 시각이 경과하면 API 서버는 해당 `Pod` 리소스를 종료 대상으로 간주한다.
또한 설정된 그레이스 시간(grace period)이 `Pod` 리소스에 기록된다.
1. 로컬 파드가 실행되고 있는 노드의 {{<glossary_tooltip term_id="kubelet" text="kubelet">}}이
`Pod`가 종료 대상으로 표시된 것을 감지하고
로컬 파드의 그레이스풀 셧다운을 시작한다.
1. kubelet이 파드를 종료하는 와중에, 컨트롤 플레인은
{{<glossary_tooltip term_id="endpoint" text="엔드포인트">}} 및
{{<glossary_tooltip term_id="endpoint-slice" text="엔드포인트슬라이스">}} 오브젝트에서 파드를 삭제한다.
이 결과, 컨트롤러는 파드를 더 이상 유효한 오브젝트로 간주하지 않는다.
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/)에 대해 알아본다.

View File

@ -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)에 배치하는 경우와 같이,
파드가 어느 노드에 배포될지를 제어해야 하는 경우도 있다.
<!-- body -->
## 노드 셀렉터(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/)되어 있다고 가정한다.
{{<note>}}
이러한 레이블에 대한 값은 클라우드 제공자별로 다르며 정확하지 않을 수 있다.
예를 들어, `kubernetes.io/hostname`에 대한 값은 특정 환경에서는 노드 이름과 동일할 수 있지만
다른 환경에서는 다른 값일 수도 있다.
{{</note>}}
### 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 "노드 이름"` 을 사용해서 노드에 주어진 레이블의 전체 목록을 확인할 수 있다.
노드 격리를 위해 레이블을 사용할 때, {{<glossary_tooltip text="kubelet" term_id="kubelet">}}이 변경할 수 없는 레이블 키를 선택한다.
그렇지 않으면 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` 는 파드를 특정 레이블이 있는 노드로 제한하는 매우 간단한 방법을 제공한다.
어피니티/안티-어피니티 기능은 표현할 수 있는 제약 종류를 크게 확장한다. 주요 개선 사항은 다음과 같다.
{{<note>}}
앞의 두 유형에서, `IgnoredDuringExecution`
쿠버네티스가 파드를 스케줄링한 뒤에 노드 레이블이 변경되어도 파드는 계속 해당 노드에서 실행됨을 의미한다.
{{</note>}}
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`**모두** 만족하는 노드에만 스케줄된다.
{{<note>}}
`nodeSelector``nodeAffinity`를 모두 사용하는 경우,
파드가 노드에 스케줄링되려면 두 조건 *모두* 만족되어야 한다.
파드가 스케줄된 노드의 레이블을 지우거나 변경해도 파드는 제거되지 않는다. 다시 말해서 어피니티 선택은 파드를 스케줄링 하는 시점에만 작동한다.
`nodeAffinity`에 연결된 `nodeSelectorTerms`를 여러 개 명시한 경우,
명시된 `nodeSelectorTerms` 중 하나를 만족하는 노드에도
파드가 스케줄링될 수 있다.
`preferredDuringSchedulingIgnoredDuringExecution``weight` 필드의 범위는 1-100이다. 모든 스케줄링 요구 사항 (리소스 요청, RequiredDuringScheduling 어피니티 표현식 등)을 만족하는 각 노드들에 대해 스케줄러는 이 필드의 요소들을 반복해서 합계를 계산하고 노드가 MatchExpressions 에 일치하는 경우 합계에 "가중치(weight)"를 추가한다. 이후에 이 점수는 노드에 대한 다른 우선순위 함수의 점수와 합쳐진다. 전체 점수가 가장 높은 노드를 가장 선호한다.
단일 `nodeSelectorTerms`와 연결된 `matchExpressions`를 여러 개 명시한 경우,
모든 `matchExpressions`를 만족하는 노드에만
파드가 스케줄링될 수 있다.
{{</note>}}
#### 스케줄링 프로파일당 노드 어피니티
[노드 어피니티를 사용해 노드에 파드 할당](/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`를 확인한 뒤
해당 노드에 대한 다른 점수에 가중치를 더하고,
최종 점수가 가장 높은 노드에 해당 파드를 스케줄링한다.
{{<note>}}
이 예시에서 쿠버네티스가 정상적으로 파드를 스케줄링하려면,
보유하고 있는 노드에 `kubernetes.io/os=linux` 레이블이 있어야 한다.
{{</note>}}
#### 스케줄링 프로파일당 노드 어피니티 {#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` 는 규칙이 적용된 파드의 네임스페이스에 매치된다.
파드간 어피니티와 안티-어피니티는 레플리카셋, 스테이트풀셋, 디플로이먼트 등과 같은
상위 레벨 모음과 함께 사용할 때 더욱 유용할 수 있다. 워크로드 집합이 동일한 노드와 같이
{{<note>}}
이 기능은 베타 단계이며 기본적으로 활성화되어 있다.
kube-apiserver 및 kube-scheduler의 `PodAffinityNamespaceSelector`
[기능 게이트](/ko/docs/reference/command-line-tools-reference/feature-gates/)를 통해 이를 비활성화할 수 있다.
{{</note>}}
#### 더 실제적인 유스케이스 {#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/)를 어떻게 사용하는지 알아본다.

View File

@ -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` 로 설정한다.

View File

@ -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:
# ...

View File

@ -1,7 +1,9 @@
---
title: 쿠버네티스 API 접근 제어하기
content_type: concept
weight: 5
---
<!-- overview -->
@ -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

View File

@ -323,17 +323,6 @@ kube-apiserver와 kubelet에 `ExpandedDNSConfig` 기능 게이트가 활성화
쿠버네티스는 최대 32개의 탐색 도메인과
최대 2048자의 탐색 도메인 목록을 허용한다.
### 기능 가용성
파드 DNS 환경 설정 기능과 DNS 정책 "`None`" 기능의 쿠버네티스 버전별 가용성은 다음과 같다.
| 쿠버네티스 버전 | 기능 지원 |
| :---------: |:-----------:|
| 1.14 | 안정 |
| 1.10 | 베타 (기본값으로 켜져 있음)|
| 1.9 | 알파 |
## {{% heading "whatsnext" %}}

View File

@ -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 >}}
### 관리

View File

@ -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/) 프록시 용 인그레스 컨트롤러다.

View File

@ -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

View File

@ -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/)가 활성화된 경우

View File

@ -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) 엔드포인트와 함께 사용되면 다른 종류의 백엔드도 추상화할 수 있으며,
여기에는 클러스터 외부에서 실행되는 것도 포함된다. 예시는 다음과 같다.
* 프로덕션 환경에서는 외부 데이터베이스 클러스터를 사용하려고 하지만,
테스트 환경에서는 자체 데이터베이스를 사용한다.

View File

@ -19,6 +19,12 @@ _토폴로지 인지 힌트(Topology Aware Hints)_ 는 클라이언트가 엔드
예를 들어, 비용을 줄이거나 네트워크 성능을 높이기 위해,
인접성을 고려하여 트래픽을 라우트할 수 있다.
{{< note >}}
"토폴로지 인지 힌트" 기능은 베타 단계이며 기본적으로 활성화되어 있지 **않다**.
이 기능을 사용해 보려면,
`TopologyAwareHints` [기능 게이트](/ko/docs/reference/command-line-tools-reference/feature-gates/)를 활성화해야 한다.
{{< /note >}}
<!-- body -->
## 동기(motivation)

View File

@ -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/#스토리지-리소스-쿼터)는 여전히 적용되므로,
사용자가 이 새로운 메카니즘을 사용할 수 있도록 허용되었어도,

View File

@ -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

View File

@ -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