Fourth Korean l10n work for release 1.18
- Translate docs/reference/issues-security/_index.md into Korean (#21145) - Translate tasks/administer-cluster/kubeadm/adding-windows-nodes.md into Korean (#21003) - Translate manage-resources/memory-default-namespace.md into Korean (#21089) - Translate tasks/configure-pod-container/pull-image-private-registry in Korean (#21036) - Translate contribute/advanced.md into Korean (#21002) - Update to Outdated files in the dev-1.18-ko.4 branch. (#21102) - Translate manage-resources/cpu-constraint-namespace.md into Korean (#21048) - Translate manage-resources/memory-constraint-namespace.md into Korean (#21091) - Translate setup/release/notes.md in Korean (#21158) - Translate manage-resources/quota-pod-namespace.md into Korean (#21087) - Translate tasks/administer-cluster/kubeadm/upgrading-windows-nodes.md into Korean (#20999) - Translate tasks/administer-cluster/kubeadm/kubeadm-certs.md into Korean (#21000) - Translate manage-resources/quota-memory-cpu-namespace.md into Korean (#21088) - Translate manage-resources/cpu-default-namespace.md into Korean (#21090) - Translate contribute/suggesting-improvements.md into Korean (#21001) - Translate quality-service-pod in Korean (#21081) Co-authored-by: Jerry Park <jaehwa@gmail.com> Co-authored-by: Jesang Myung <jesang.myung@gmail.com> Co-authored-by: DongMoon Kim <dmoons.kim@gmail.com> Co-authored-by: Jesang Myung <jesang.myung@gmail.com> Co-authored-by: Yuk, Yongsu <ysyukr@gmail.com> Co-authored-by: bluefriday <bluefriday86@gmail.com>pull/21310/head
|
@ -50,7 +50,7 @@ Google이 일주일에 수십억 개의 컨테이너들을 운영하게 해준
|
|||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-north-america/?utm_source=kubernetes.io&utm_medium=nav&utm_campaign=kccncna20" button id="desktopKCButton">Attend KubeCon in Boston on November 17-20, 2020</a>
|
||||
<a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-europe/?utm_source=kubernetes.io&utm_medium=nav&utm_campaign=kccnceu20" button id="desktopKCButton">Attend KubeCon EU virtually on August 17-20, 2020</a>
|
||||
</div>
|
||||
<div id="videoPlayer">
|
||||
<iframe data-url="https://www.youtube.com/embed/H06qrNmGqyE?autoplay=1" frameborder="0" allowfullscreen></iframe>
|
||||
|
|
Before Width: | Height: | Size: 20 KiB |
|
@ -1,4 +0,0 @@
|
|||
---
|
||||
title: CCP Games
|
||||
content_url: https://cloud.google.com/customers/ccp-games/
|
||||
---
|
Before Width: | Height: | Size: 6.1 KiB |
|
@ -1,4 +0,0 @@
|
|||
---
|
||||
title: Comcast
|
||||
content_url: https://youtu.be/lmeFkH-rHII
|
||||
---
|
Before Width: | Height: | Size: 19 KiB |
|
@ -1,4 +0,0 @@
|
|||
---
|
||||
title: Concur
|
||||
content_url: http://searchitoperations.techtarget.com/news/450297178/Tech-firms-roll-out-Kubernetes-in-production
|
||||
---
|
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 7.1 KiB |
|
@ -1,4 +0,0 @@
|
|||
---
|
||||
title: Ebay
|
||||
content_url: http://www.nextplatform.com/2015/11/12/inside-ebays-shift-to-kubernetes-and-containers-atop-openstack/
|
||||
---
|
Before Width: | Height: | Size: 22 KiB |
|
@ -1,4 +0,0 @@
|
|||
---
|
||||
title: Goldman Sachs
|
||||
content_url: http://blogs.wsj.com/cio/2016/02/24/big-changes-in-goldmans-software-emerge-from-small-containers/
|
||||
---
|
Before Width: | Height: | Size: 27 KiB |
|
@ -1,4 +0,0 @@
|
|||
---
|
||||
title: Home Office UK
|
||||
content_url: https://www.youtube.com/watch?v=F3iMkz_NSvU
|
||||
---
|
|
@ -1,4 +0,0 @@
|
|||
---
|
||||
title: JD.COM
|
||||
content_url: https://kubernetes.io/blog/2017/02/inside-jd-com-shift-to-kubernetes-from-openstack
|
||||
---
|
Before Width: | Height: | Size: 10 KiB |
|
@ -1,4 +0,0 @@
|
|||
---
|
||||
title: LivePerson
|
||||
content_url: https://www.openstack.org/videos/video/running-kubernetes-on-openstack-at-liveperson
|
||||
---
|
Before Width: | Height: | Size: 19 KiB |
|
@ -1,4 +0,0 @@
|
|||
---
|
||||
title: Monzo
|
||||
content_url: https://youtu.be/YkOY7DgXKyw
|
||||
---
|
Before Width: | Height: | Size: 5.4 KiB |
|
@ -1,4 +0,0 @@
|
|||
---
|
||||
title: Philips
|
||||
content_url: https://cloud.google.com/customers/philips/
|
||||
---
|
Before Width: | Height: | Size: 3.8 KiB |
|
@ -1,4 +0,0 @@
|
|||
---
|
||||
title: Pokemon GO
|
||||
content_url: https://cloudplatform.googleblog.com/2016/09/bringing-Pokemon-GO-to-life-on-Google-Cloud.html
|
||||
---
|
Before Width: | Height: | Size: 19 KiB |
|
@ -1,4 +0,0 @@
|
|||
---
|
||||
title: Samsung SDS
|
||||
content_url: http://www.nextplatform.com/2016/05/24/samsung-experts-put-kubernetes-paces/
|
||||
---
|
Before Width: | Height: | Size: 22 KiB |
|
@ -1,4 +0,0 @@
|
|||
---
|
||||
title: SAP
|
||||
content_url: https://youtu.be/4gyeixJLabo
|
||||
---
|
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 4.8 KiB |
|
@ -1,4 +0,0 @@
|
|||
---
|
||||
title: Soundcloud
|
||||
content_url: https://www.youtube.com/watch?v=5378N5iLb2Q
|
||||
---
|
Before Width: | Height: | Size: 22 KiB |
|
@ -1,4 +0,0 @@
|
|||
---
|
||||
title: WePay
|
||||
content_url: http://thenewstack.io/wepay-kubernetes-changed-business/
|
||||
---
|
Before Width: | Height: | Size: 20 KiB |
|
@ -1,4 +0,0 @@
|
|||
---
|
||||
title: Zulily
|
||||
content_url: https://www.youtube.com/embed/of45hYbkIZs
|
||||
---
|
Before Width: | Height: | Size: 7.8 KiB |
Before Width: | Height: | Size: 8.6 KiB |
|
@ -1,120 +0,0 @@
|
|||
---
|
||||
title: 마스터-노드 커뮤니케이션
|
||||
content_template: templates/concept
|
||||
weight: 20
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
이 문서는 마스터(실제 apiserver)와 쿠버네티스 클러스터 사이의
|
||||
커뮤니케이션 경로를 나열해 본다. 그 목적은 신뢰할 수 없는 네트워크
|
||||
(또는 클라우드 제공자의 공인 IP만으로 구성된 네트워크)에서도 동작될 수 있는
|
||||
클러스터 구축을 위해, 네트워크의 구성을 강화하는 사용자
|
||||
맞춤형 설치를 허용하기 위함이다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
## 클러스터에서 마스터로
|
||||
|
||||
클러스터에서 마스터로의 모든 커뮤니케이션 경로는 apiserver에서 끝난다
|
||||
(어떤 다른 마스터 컴포넌트도 원격 서비스를 노출하기 위해 설계되지 않는다).
|
||||
전형적인 배포에서, apiserver는 하나 또는 그 이상의 클라이언트
|
||||
[인증](/docs/reference/access-authn-authz/authentication/) 형태가
|
||||
사용가능토록 하여 안전한 HTTPS 포트(443)를 통해 원격 연결에 대해 서비스 리슨하도록 구성된다.
|
||||
특히 [익명의 요청](/docs/reference/access-authn-authz/authentication/#anonymous-requests)
|
||||
또는 [서비스 계정 토큰](/docs/reference/access-authn-authz/authentication/#service-account-tokens)이
|
||||
허용된 경우에는 하나 또는 그 이상의
|
||||
[인가](/docs/reference/access-authn-authz/authorization/) 형태가 사용 가능해야만 한다.
|
||||
|
||||
노드는 유효한 클라이언트 자격증명과 함께 apiserver에 안전하게 접속할 수 있는
|
||||
그런 클러스터용 공인 루트 인증서를 가지고 제공되어야 한다.
|
||||
예를 들어, 기본 GKE 배포의 경우, kubelet에 제공되는 클라이언트 자격증명은
|
||||
클라이언트 인증서의 형태로 존재한다. kubelet 클라이언트 인증서에
|
||||
대한 자동화 프로비저닝에 대해서는
|
||||
[kubelet TLS bootstrapping](/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/)을 참고한다.
|
||||
|
||||
apiserver에 접속하려는 파드는 서비스 계정에 영향력을 발휘함으로써 안전하게
|
||||
그리 행할 수 있으며 따라서 쿠버네티스는 인스턴스화 될 때 공인 루트 인증서와
|
||||
유효한 베어러 토큰을 파드 속으로 자동 주입할 수 있게 된다.
|
||||
(모든 네임스페이스 내) `kubernetes` 서비스는 apiserver 상의 HTTPS 엔드포인트로
|
||||
(kube-proxy를 통해) 리다이렉트 되는 가상 IP 주소를
|
||||
가지고 구성된다.
|
||||
|
||||
마스터 컴포넌트는 또한 신뢰할 수 있는 포트를 통해 클러스터 apiserver와 소통한다.
|
||||
|
||||
결과적으로, 클러스터 (노드 그리고 노드에서 동작하는 파드)에서
|
||||
마스터로의 기본 동작 모드는 기본적으로 안전하며
|
||||
신뢰할 수 없는그리고/또는 공인 네트워크 상에서 동작할 수 있다.
|
||||
|
||||
## 마스터에서 클러스터로
|
||||
|
||||
마스터(apiserver)에서 클러스터로의 두 가지 주된 커뮤니케이션 경로가 존재한다.
|
||||
첫 번째는 클러스터 내 각 노드를 동작시키는 apiserver에서 kubelet 프로세스로의
|
||||
경로이다. 두 번째는 apiserver에서 apiserver의 프록시 기능을 통한 임의의 노드,
|
||||
파드 또는 서비스로의 경로이다.
|
||||
|
||||
### apiserver에서 kubelet으로
|
||||
|
||||
apiserver에서 kubelet으로의 연결은 다음을 위해 이용된다.
|
||||
|
||||
* 파드에 대한 로그 가져오기
|
||||
* 동작중인 파드에 (kubectl을 통해) 연관짓기
|
||||
* kubelet의 포트 포워딩 기능 제공하기
|
||||
|
||||
이 연결은 kubelet의 HTTPS 엔드포인트에서 끝난다. 기본적으로,
|
||||
apiserver는 kubelet의 제공 인증서를 확인하지 않는데,
|
||||
이는 연결에 대한 중간자 공격을 당하게 하고, 신뢰할 수 없는
|
||||
그리고/또는 공인 네트워크에서 운영하기에는 **불안** 하게 만든다.
|
||||
|
||||
이 연결을 확인하려면, apiserver에 kubelet의 제공 인증서 확인을
|
||||
위해 사용하는 루트 인증서 번들로 `--kubelet-certificate-authority`
|
||||
플래그를 이용한다
|
||||
|
||||
그것이 불가능한 경우, 신뢰할 수 없는 또는 공인 네트워크에 대한 연결을 피하고 싶다면,
|
||||
apiserver와 kubelet 사이에 [SSH 터널링](/ko/docs/concepts/architecture/master-node-communication/#ssh-터널)을
|
||||
사용한다.
|
||||
|
||||
마지막으로, kubelet API를 안전하게 하기 위해
|
||||
[Kubelet 인증 그리고/또는 인가](/docs/admin/kubelet-authentication-authorization/)가 활성화 되어야만 한다.
|
||||
|
||||
### apiserver에서 노드, 파드, 그리고 서비스로
|
||||
|
||||
apiserver에서 노드, 파드, 또는 서비스로의 연결은 보통 HTTP 연결을
|
||||
기본으로 하므로 인증도 암호화도 되지 않는다. API URL 내 노드, 파드, 또는 서비스 이름에
|
||||
`https:` 프리픽스를 붙임으로써 안전한 HTTPS 연결로 동작될 수 있지만,
|
||||
HTTPS 엔드포인트에 의해 제공되는 인증서를 확인하지 않으며
|
||||
클라이언트 자격증명 또한 제공하지 않는다.
|
||||
그래서 연결이 암호화될 동안, 어떠한 무결성도 제공되지 않을 것이다.
|
||||
이러한 연결들은 신뢰할 수 없는 그리고/또는 공인 네트워크에서 동작하기에
|
||||
**현재로서는 안전하지 않다**.
|
||||
|
||||
### SSH 터널
|
||||
|
||||
쿠버네티스는 마스터 → 클러스터 통신 경로를 보호하는 SSH 터널을
|
||||
지원한다. 이 구성에서 apiserver는 클러스터의 각 노드에서 SSH 터널을
|
||||
시작하고(포트 22번으로 수신 대기하는 ssh 서버에 연결), 터널을 통해
|
||||
kubelet, 노드, 파드 또는 서비스로 향하는 모든 트래픽을 전달한다.
|
||||
이 터널은 실행중인 노드의 트래픽이 외부로 노출되지
|
||||
않도록 보장한다.
|
||||
|
||||
SSH 터널은 현재 사용 중단(deprecated)되었으므로, 무엇을 하고 있는지 알지 못하는
|
||||
한 터널을 이용하지 말아야 한다. Konnectivity 서비스는 이 통신
|
||||
채널을 대체한다.
|
||||
|
||||
### Konnectivity 서비스
|
||||
{{< feature-state for_k8s_version="v1.18" state="beta" >}}
|
||||
|
||||
SSH 터널을 대체하는 Konnectivity 서비스는 마스터 → 클러스터 통신을
|
||||
위한 TCP 수준의 프록시를 제공한다. Konnectivity는 마스터
|
||||
네트워크와 클러스터 네트워크에서 실행되는 Konnectivity 서버와
|
||||
에이전트 두 부분으로 구성된다. Konnectivity 에이전트는
|
||||
Konnectivity 서버에 대한 연결을 시작하고, 유지한다.
|
||||
이 연결을 통해 모든 마스터 → 클러스터로의 트래픽이 통과하게 된다.
|
||||
|
||||
클러스터에서 설정하는 방법에 대해서는 [Konnectivity 서비스 구성](/docs/tasks/setup-konnectivity/)
|
||||
하기를 참고한다.
|
||||
|
||||
{{% /capture %}}
|
|
@ -6,18 +6,112 @@ weight: 10
|
|||
|
||||
{{% capture overview %}}
|
||||
|
||||
하나의 노드는 쿠버네티스에서 하나의 워커 머신으로, 이전에는 `미니언`으로 알려졌다. 노드는
|
||||
클러스터에 따라, VM 또는 물리 머신이 될 수 있다. 각 노드는
|
||||
[파드](/ko/docs/concepts/workloads/pods/pod/)를 동작시키기 위해 필요한 서비스를 포함하며 마스터 컴포넌트에 의해 관리된다. 노드 상의 서비스는 [컨테이너 런타임](/ko/docs/concepts/overview/components/#컨테이너-런타임), kubelet 그리고 kube-proxy를 포함한다. 보다
|
||||
상세한 내용은 아키텍처 문서 내
|
||||
[쿠버네티스 노드](https://git.k8s.io/community/contributors/design-proposals/architecture/architecture.md#the-kubernetes-node)
|
||||
섹션을 확인한다.
|
||||
쿠버네티스는 컨테이너를 파드내에 배치하고 _노드_ 에서 실행함으로 워크로드를 구동한다.
|
||||
노드는 클러스터에 따라 가상 또는 물리적 머신일 수 있다. 각 노드에는
|
||||
{{< glossary_tooltip text="컨트롤 플레인" term_id="control-plane" >}}이라는
|
||||
{{< glossary_tooltip text="파드" term_id="pod" >}}를
|
||||
실행하는데 필요한 서비스가 포함되어 있다.
|
||||
|
||||
일반적으로 클러스터에는 여러개의 노드가 있으며, 학습 또는 리소스가 제한되는
|
||||
환경에서는 하나만 있을 수도 있다.
|
||||
|
||||
노드의 [컴포넌트](/ko/docs/concepts/overview/components/#노드-컴포넌트)에는
|
||||
{{< glossary_tooltip text="kubelet" term_id="kubelet" >}},
|
||||
{{< glossary_tooltip text="컨테이너 런타임" term_id="container-runtime" >}}
|
||||
그리고 {{< glossary_tooltip text="kube-proxy" term_id="kube-proxy" >}}가 포함된다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
## 관리
|
||||
|
||||
{{< glossary_tooltip text="API 서버" term_id="kube-apiserver" >}}에 노드를 추가하는 두가지 주요 방법이 있다.
|
||||
|
||||
1. 노드의 kubelet으로 컨트롤 플레인에 자체 등록
|
||||
2. 사용자 또는 다른 사용자가 노드 오브젝트를 수동으로 추가
|
||||
|
||||
노드 오브젝트 또는 노드의 kubelet으로 자체 등록한 후 컨트롤 플레인은 새 노드 오브젝트가 유효한지 확인한다.
|
||||
예를 들어 다음 JSON 매니페스트에서 노드를 만들려는 경우이다.
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": "Node",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "10.240.79.157",
|
||||
"labels": {
|
||||
"name": "my-first-k8s-node"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
쿠버네티스는 내부적으로 노드 오브젝트를 생성한다(표시한다). 쿠버네티스는
|
||||
kubelet이 노드의 `metadata.name` 필드와 일치하는 API 서버에 등록이 되어있는지 확인한다.
|
||||
노드가 정상이면(필요한 모든 서비스가 실행중인 경우) 파드를 실행할 수 있게 된다.
|
||||
그렇지 않으면, 해당 노드는 정상이 될때까지 모든 클러스터 활동에
|
||||
대해 무시된다.
|
||||
|
||||
{{< note >}}
|
||||
쿠버네티스는 유효하지 않은 노드 오브젝트를 유지하고, 노드가
|
||||
정상적인지 확인한다.
|
||||
|
||||
상태 확인을 중지하려면 사용자 또는 {{< glossary_tooltip term_id="controller" text="컨트롤러">}}에서
|
||||
노드 오브젝트를 명시적으로 삭제해야한다.
|
||||
{{< /note >}}
|
||||
|
||||
노드 오브젝트의 이름은 유효한 [DNS 서브도메인 이름](/ko/docs/concepts/overview/working-with-objects/names/#dns-서브도메인-이름들)이어야 한다.
|
||||
|
||||
### 노드에 대한 자체-등록
|
||||
|
||||
kubelet 플래그 `--register-node`는 참(기본값)일 경우, kubelet 은 API 서버에
|
||||
스스로 등록을 시도할 것이다. 이는 대부분의 배포판에 의해 이용되는, 선호하는 패턴이다.
|
||||
|
||||
자체-등록에 대해, kubelet은 다음 옵션과 함께 시작된다.
|
||||
|
||||
- `--kubeconfig` - apiserver에 스스로 인증하기 위한 자격증명에 대한 경로.
|
||||
- `--cloud-provider` - 자신에 대한 메터데이터를 읽기 위해 어떻게 {{< glossary_tooltip text="클라우드 제공자" term_id="cloud-provider" >}}와 소통할지에 대한 방법.
|
||||
- `--register-node` - 자동으로 API 서버에 등록.
|
||||
- `--register-with-taints` - 주어진 taint 리스트 (콤마로 분리된 `<key>=<value>:<effect>`)를 가진 노드 등록. `register-node`가 거짓이면 동작 안함.
|
||||
- `--node-ip` - 노드의 IP 주소.
|
||||
- `--node-labels` - 클러스터에 노드를 등록할 때 추가 할 {{< glossary_tooltip text="레이블" term_id="label" >}}([NodeRestriction admission plugin](/docs/reference/access-authn-authz/admission-controllers/#noderestriction)에 의해 적용되는 레이블 제한 사항 참고).
|
||||
- `--node-status-update-frequency` - 얼마나 자주 kubelet이 마스터에 노드 상태를 게시할 지 정의.
|
||||
|
||||
[Node authorization mode](/docs/reference/access-authn-authz/node/)와
|
||||
[NodeRestriction admission plugin](/docs/reference/access-authn-authz/admission-controllers/#noderestriction)이 활성화 되면,
|
||||
kubelets 은 자신의 노드 리소스를 생성/수정할 권한을 가진다.
|
||||
|
||||
#### 수동 노드 관리
|
||||
|
||||
{{< glossary_tooltip text="kubectl" term_id="kubectl" >}}을
|
||||
사용해서 노드 오브젝트를 생성하고 수정할 수 있다.
|
||||
|
||||
노드 오브젝트를 수동으로 생성하려면 kubelet 플래그를 `--register-node=false` 로 설정한다.
|
||||
|
||||
`--register-node` 설정과 관계 없이 노드 오브젝트를 수정할 수 있다.
|
||||
예를 들어 기존 노드에 레이블을 설정하거나, 스케줄 불가로 표시할 수 있다.
|
||||
|
||||
파드의 노드 셀렉터와 함께 노드의 레이블을 사용해서 스케줄링을 제어할 수 있다.
|
||||
예를 들어, 사용 가능한 노드의 하위 집합에서만 실행되도록
|
||||
파드를 제한할 수 있다.
|
||||
|
||||
노드를 스케줄 불가로 표시하면 스케줄러가 해당 노드에 새 파드를 배치할 수 없지만,
|
||||
노드에 있는 기존 파드에는 영향을 미치지 않는다.
|
||||
이는 노드 재부팅 또는 기타 유지보수 준비 단계에서 유용하다.
|
||||
|
||||
노드를 스케줄 불가로 표시하려면 다음을 실행한다.
|
||||
|
||||
```shell
|
||||
kubectl cordon $NODENAME
|
||||
```
|
||||
|
||||
{{< note >}}
|
||||
{{< glossary_tooltip term_id="daemonset" >}}에 포함되는 일부 파드는
|
||||
스케줄 불가 노드에서 실행될 수 있다. 일반적으로 데몬셋은 워크로드 애플리케이션을
|
||||
비우는 경우에도 노드에서 실행되어야 하는 노드 로컬 서비스를 제공한다.
|
||||
{{< /note >}}
|
||||
|
||||
## 노드 상태
|
||||
|
||||
노드의 상태는 다음의 정보를 포함한다.
|
||||
|
@ -27,11 +121,13 @@ weight: 10
|
|||
* [용량과 할당가능](#capacity)
|
||||
* [정보](#info)
|
||||
|
||||
노드의 상태와 상세 정보는 다음 커맨드를 통해 확인할 수 있다.
|
||||
`kubectl` 을 사용해서 노드 상태와 기타 세부 정보를 볼수 있다.
|
||||
|
||||
```shell
|
||||
kubectl describe node <insert-node-name-here>
|
||||
```
|
||||
각 섹션은 아래 상세하게 기술되었다.
|
||||
|
||||
출력되는 각 섹션은 아래에 설명되어있다.
|
||||
|
||||
### 주소 {#addresses}
|
||||
|
||||
|
@ -46,13 +142,21 @@ kubectl describe node <insert-node-name-here>
|
|||
|
||||
`conditions` 필드는 모든 `Running` 노드의 상태를 기술한다. 컨디션의 예로 다음을 포함한다.
|
||||
|
||||
| Node Condition | Description |
|
||||
{{< table caption = "노드 컨디션과 각 컨디션이 적용되는 시기에 대한 설명들이다." >}}
|
||||
| 노드 컨디션 | 설명 |
|
||||
|----------------|-------------|
|
||||
| `Ready` | 노드가 상태 양호하며 파드를 수용할 준비가 되어 있는 경우 `True`, 노드의 상태가 불량하여 파드를 수용하지 못할 경우 `False`, 그리고 노드 컨트롤러가 마지막 `node-monitor-grace-period` (기본값 40 기간 동안 노드로부터 응답을 받지 못한 경우) `Unknown` |
|
||||
| `DiskPressure` | 디스크 사이즈 상에 압박이 있는 경우, 즉 디스크 용량이 넉넉치 않은 경우 `True`, 반대의 경우 `False` |
|
||||
| `MemoryPressure` | 노드 메모리 상에 압박이 있는 경우, 즉 노드 메모리가 넉넉치 않은 경우 `True`, 반대의 경우 `False` |
|
||||
| `PIDPressure` | 프로세스 상에 압박이 있는 경우, 즉 노드 상에 많은 프로세스들이 존재하는 경우 `True`, 반대의 경우 `False` |
|
||||
| `DiskPressure` | 디스크 사이즈 상에 압박이 있는 경우, 즉 디스크 용량이 넉넉치 않은 경우 `True`, 반대의 경우 `False` |
|
||||
| `NetworkUnavailable` | 노드에 대해 네트워크가 올바르게 구성되지 않은 경우 `True`, 반대의 경우 `False` |
|
||||
{{< /table >}}
|
||||
|
||||
{{< note >}}
|
||||
커맨드 라인 도구를 사용해서 코드화된 노드의 세부 정보를 출력하는 경우 조건에는
|
||||
`SchedulingDisabled` 이 포함된다. `SchedulingDisabled` 은 쿠버네티스 API의 조건이 아니며,
|
||||
대신 코드화된 노드는 사양에 스케줄 불가로 표시된다.
|
||||
{{< /note >}}
|
||||
|
||||
노드 컨디션은 JSON 오브젝트로 표현된다. 예를 들어, 다음 응답은 상태 양호한 노드를 나타낸다.
|
||||
|
||||
|
@ -69,17 +173,18 @@ kubectl describe node <insert-node-name-here>
|
|||
]
|
||||
```
|
||||
|
||||
ready 컨디션의 상태가 `pod-eviction-timeout` ([kube-controller-manager](/docs/admin/kube-controller-manager/)에 전달된 인수) 보다 더 길게 `Unknown` 또는 `False`로 유지되는 경우, 노드 상에 모든 파드는 노드 컨트롤러에 의해 삭제되도록 스케줄 된다. 기본 축출 타임아웃 기간은 **5분** 이다. 노드에 접근이 불가할 때와 같은 경우, apiserver는 노드 상의 kubelet과 통신이 불가하다. apiserver와의 통신이 재개될 때까지 파드 삭제에 대한 결정은 kubelet에 전해질 수 없다. 그 사이, 삭제되도록 스케줄 되어진 파드는 분할된 노드 상에서 계속 동작할 수도 있다.
|
||||
ready 컨디션의 상태가 `pod-eviction-timeout` ({{< glossary_tooltip text="kube-controller-manager" term_id="kube-controller-manager" >}}에 전달된 인수) 보다 더 길게 `Unknown` 또는 `False`로 유지되는 경우, 노드 상에 모든 파드는 노드 컨트롤러에 의해 삭제되도록 스케줄 된다. 기본 축출 타임아웃 기간은 **5분** 이다. 노드에 접근이 불가할 때와 같은 경우, apiserver는 노드 상의 kubelet과 통신이 불가하다. apiserver와의 통신이 재개될 때까지 파드 삭제에 대한 결정은 kubelet에 전해질 수 없다. 그 사이, 삭제되도록 스케줄 되어진 파드는 분할된 노드 상에서 계속 동작할 수도 있다.
|
||||
|
||||
1.5 이전의 쿠버네티스 버전에서는, 노드 컨트롤러가 apiserver로부터 접근 불가한 이러한 파드를 [강제 삭제](/ko/docs/concepts/workloads/pods/pod/#파드-강제-삭제)
|
||||
시킬 것이다. 그러나 1.5 이상에서는, 노드 컨트롤러가 클러스터 내 동작 중지된 것을 확신할 때까지는 파드를
|
||||
노드 컨트롤러가 클러스터 내 동작 중지된 것을 확신할 때까지는 파드를
|
||||
강제로 삭제하지 않는다. 파드가 `Terminating` 또는 `Unknown` 상태로 있을 때 접근 불가한 노드 상에서
|
||||
동작되고 있는 것을 보게 될 수도 있다. 노드가 영구적으로 클러스터에서 삭제되었는지에 대한 여부를 쿠버네티스가 기반 인프라로부터 유추할 수 없는 경우,
|
||||
노드가 클러스터를 영구적으로 탈퇴하게 되면, 클러스터 관리자는 손수 노드 오브젝트를 삭제해야 할 수도 있다. 쿠버네티스에서 노드 오브젝트를 삭제하면
|
||||
노드 상에서 동작중인 모든 파드 오브젝트가 apiserver로부터 삭제되어 그 이름을 사용할 수 있는 결과를 낳는다.
|
||||
동작되고 있는 것을 보게 될 수도 있다. 노드가 영구적으로 클러스터에서 삭제되었는지에
|
||||
대한 여부를 쿠버네티스가 기반 인프라로부터 유추할 수 없는 경우, 노드가 클러스터를 영구적으로
|
||||
탈퇴하게 되면, 클러스터 관리자는 손수 노드 오브젝트를 삭제해야 할 수도 있다.
|
||||
쿠버네티스에서 노드 오브젝트를 삭제하면 노드 상에서 동작중인 모든 파드 오브젝트가
|
||||
apiserver로부터 삭제되어 그 이름을 사용할 수 있는 결과를 낳는다.
|
||||
|
||||
노드 수명주기 컨트롤러는 자동으로 컨디션을 나타내는
|
||||
[테인트(taints)](/docs/concepts/configuration/taint-and-toleration/)를 생성한다.
|
||||
[테인트(taints)](/docs/concepts/scheduling-eviction/taint-and-toleration/)를 생성한다.
|
||||
스케줄러는 파드를 노드에 할당 할 때 노드의 테인트를 고려한다.
|
||||
또한 파드는 노드의 테인트를 극복(tolerate)할 수 있는 톨러레이션(toleration)을 가질 수 있다.
|
||||
|
||||
|
@ -101,47 +206,10 @@ ready 컨디션의 상태가 `pod-eviction-timeout` ([kube-controller-manager](/
|
|||
커널 버전, 쿠버네티스 버전 (kubelet과 kube-proxy 버전), (사용하는 경우) Docker 버전, OS 이름과 같은노드에 대한 일반적인 정보를 보여준다.
|
||||
이 정보는 Kubelet에 의해 노드로부터 수집된다.
|
||||
|
||||
## 관리
|
||||
|
||||
[파드](/ko/docs/concepts/workloads/pods/pod/)와 [서비스](/ko/docs/concepts/services-networking/service/)와 달리,
|
||||
노드는 본래 쿠버네티스에 의해 생성되지 않는다. 구글 컴퓨트 엔진과 같은 클라우드 제공사업자에 의해
|
||||
외부로부터 생성 되거나, 물리적 또는 가상 머신의 풀 내에서 존재한다.
|
||||
그래서 쿠버네티스가 노드를 생성할 때,
|
||||
노드를 나타내는 오브젝트를 생성한다.
|
||||
생성 이후, 쿠버네티스는 노드의 유효성 여부를 검사한다. 예를 들어,
|
||||
다음 내용으로 노드를 생성하려 한다면,
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": "Node",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "10.240.79.157",
|
||||
"labels": {
|
||||
"name": "my-first-k8s-node"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
쿠버네티스는 내부적으로 (표현을) 노드 오브젝트를 생성하고,
|
||||
`metadata.name` 필드를 근거로 상태 체크를 수행하여 노드의 유효성을 확인한다. 노드가 유효하면, 즉
|
||||
모든 필요한 서비스가 동작 중이면, 파드를 동작시킬 자격이 된다. 그렇지 않으면,
|
||||
유효하게 될때까지 어떠한 클러스터 활동에 대해서도 무시된다.
|
||||
노드 오브젝트의 이름은 유효한 [DNS 서브도메인 이름](/ko/docs/concepts/overview/working-with-objects/names/#dns-서브도메인-이름들)이어야 한다.
|
||||
|
||||
{{< note >}}
|
||||
쿠버네티스는 유효하지 않은 노드로부터 오브젝트를 보호하고 유효한 상태로 이르는지 확인하기 위해 지속적으로 체크한다.
|
||||
이러한 프로세스를 중지시키기 위해는 명시적으로 노드 오브젝트를 삭제해야 한다.
|
||||
{{< /note >}}
|
||||
|
||||
현재, 쿠버네티스 노드 인터페이스와 상호작용 하는 3개의 컴포넌트가 존재하는데,
|
||||
노드 컨트롤러, kubelet, 그리고 kubectl 이다.
|
||||
|
||||
### 노드 컨트롤러
|
||||
|
||||
노드 컨트롤러는 노드의 다양한 측면을 관리하는 쿠버네티스
|
||||
마스터 컴포넌트다.
|
||||
노드 {{< glossary_tooltip text="컨트롤러" term_id="controller" >}}는
|
||||
노드의 다양한 측면을 관리하는 쿠버네티스 컨트롤 플레인 컴포넌트이다.
|
||||
|
||||
노드 컨트롤러는 노드가 생성되어 유지되는 동안 다양한 역할을 한다. 첫째는 등록 시점에
|
||||
(CIDR 할당이 사용토록 설정된 경우) 노드에 CIDR 블럭을 할당하는 것이다.
|
||||
|
@ -164,6 +232,7 @@ NodeStatus의 NodeReady 컨디션을 ConditionUnknown으로 업데이트 하는
|
|||
#### 하트비트
|
||||
|
||||
쿠버네티스 노드에서 보내는 하트비트는 노드의 가용성을 결정하는데 도움이 된다.
|
||||
|
||||
하트비트의 두 가지 형태는 `NodeStatus` 와
|
||||
[리스(Lease) 오브젝트](/docs/reference/generated/kubernetes-api/{{< latest-version >}}/#lease-v1-coordination-k8s-io) 이다.
|
||||
각 노드에는 `kube-node-lease` 라는
|
||||
|
@ -184,13 +253,7 @@ kubelet은 `NodeStatus` 와 리스 오브젝트를 생성하고 업데이트 할
|
|||
|
||||
#### 안정성
|
||||
|
||||
쿠버네티스 1.4에서, 대량의 노드들이 마스터 접근에
|
||||
문제를 지닐 경우 (예를 들어 마스터에 네트워크 문제들이 발생했기 때문에)
|
||||
더 개선된 문제 해결을 하도록 노드 컨트롤러의 로직을 업데이트 했다. 1.4를 시작으로,
|
||||
노드 컨트롤러는 파드 축출에 대한 결정을 내릴 경우 클러스터
|
||||
내 모든 노드를 살핀다.
|
||||
|
||||
대부분의 경우, 노드 컨트롤러는 초당 `--node-eviction-rate`(기본값 0.1)로
|
||||
대부분의 경우, 노드 컨트롤러는 초당 `--node-eviction-rate`(기본값 0.1)로
|
||||
축출 비율을 제한한다. 이 말은 10초당 1개의 노드를 초과하여
|
||||
파드 축출을 하지 않는다는 의미가 된다.
|
||||
|
||||
|
@ -216,62 +279,11 @@ kubelet은 `NodeStatus` 와 리스 오브젝트를 생성하고 업데이트 할
|
|||
이러한 경우, 노드 컨트롤러는 마스터 연결에 문제가 있어 일부 연결이
|
||||
복원될 때까지 모든 축출을 중지하는 것으로 여긴다.
|
||||
|
||||
쿠버네티스 1.6을 시작으로 NodeController는 파드가 taint를 허용하지 않을 때,
|
||||
`NoExecute` taint 상태의 노드 상에 동작하는 파드 축출에 대한 책임 또한
|
||||
지고 있다. 추가로, 기본적으로 비활성화 된 알파 기능으로, NodeController는 노드 접근 불가
|
||||
또는 준비 부족과 같은 노드 문제에 상응하는 taint 추가에 대한 책임을 진다.
|
||||
`NoExecute` taints와 알파 기능에 대한 보다 상세한
|
||||
내용은 [이 문서](/docs/concepts/configuration/taint-and-toleration/)를 참고한다.
|
||||
|
||||
1.8 버전을 시작으로, 노드 컨트롤러는 노드 상태를 나타내는 taint 생성에 대한 책임을 지도록
|
||||
만들 수 있다. 이는 버전 1.8 의 알파 기능이다.
|
||||
|
||||
### 노드에 대한 자체-등록
|
||||
|
||||
kubelet 플래그 `--register-node`는 참(기본값)일 경우, kubelet 은 API 서버에
|
||||
스스로 등록을 시도할 것이다. 이는 대부분의 배포판에 의해 이용되는, 선호하는 패턴이다.
|
||||
|
||||
자체-등록에 대해, kubelet은 다음 옵션과 함께 시작된다.
|
||||
|
||||
- `--kubeconfig` - apiserver에 스스로 인증하기 위한 자격증명에 대한 경로.
|
||||
- `--cloud-provider` - 자신에 대한 메터데이터를 읽기 위해 어떻게 클라우드 제공사업자와 소통할지에 대한 방법.
|
||||
- `--register-node` - 자동으로 API 서버에 등록.
|
||||
- `--register-with-taints` - 주어진 taint 리스트 (콤마로 분리된 `<key>=<value>:<effect>`)를 가진 노드 등록. `register-node`가 거짓이면 동작 안함.
|
||||
- `--node-ip` - 노드의 IP 주소.
|
||||
- `--node-labels` - 클러스터 내 노드를 등록할 경우 추가되는 레이블 (1.13+ 에서 [NodeRestriction admission plugin](/docs/reference/access-authn-authz/admission-controllers/#noderestriction)에 의해 강제되는 레이블 제약사항 참고).
|
||||
- `--node-status-update-frequency` - 얼마나 자주 kubelet이 마스터에 노드 상태를 게시할 지 정의.
|
||||
|
||||
[Node authorization mode](/docs/reference/access-authn-authz/node/)와
|
||||
[NodeRestriction admission plugin](/docs/reference/access-authn-authz/admission-controllers/#noderestriction)이 활성화 되면,
|
||||
kubelets 은 자신의 노드 리소스를 생성/수정할 권한을 가진다.
|
||||
|
||||
#### 수동 노드 관리
|
||||
|
||||
클러스터 관리자는 노드 오브젝트를 생성하고 수정할 수 있다.
|
||||
|
||||
관리자가 수동으로 오브젝트를 생성하고자 한다면, kubelet 플래그를
|
||||
`--register-node=false`로 설정한다.
|
||||
|
||||
관리자는 노드 리소스를 수정할 수 있다(`--register-node`설정과 무관하게).
|
||||
수정은 노드 상에 레이블 설정과 스케줄 불가 마킹을 포함한다.
|
||||
|
||||
노드 상의 레이블은 스케줄링을 제어하기 위해,
|
||||
즉 하나의 파드가 오직 노드의 서브셋 상에 동작할 수 있도록 제한하기 위해 노드 셀렉터와 함께 이용될 수 있다.
|
||||
|
||||
노드를 스케줄 불가로 마킹하게 되면, 해당 노드에 새로운 파드가 스케줄되는 것을 막아주지만,
|
||||
노드 상의 임의의 기존 파드에 대해서는 영향을 미치치 않는다. 이는 노드 리부트
|
||||
전이나 기타 등의 준비 조치로 유용하다. 예를 들어, 노드를 스케줄 불가로
|
||||
마크하기 위해 다음 명령을 수행한다.
|
||||
|
||||
```shell
|
||||
kubectl cordon $NODENAME
|
||||
```
|
||||
|
||||
{{< note >}}
|
||||
DaemonSet 컨트롤러에 의해 생성된 파드는 쿠버네티스 스케줄러를
|
||||
우회하고 노드 상에 스케줄 불가 속성을 고려하지 않는다. 심지어 리부트를 준비하는 동안
|
||||
애플리케이션을 유출시키는 중이라 할지라도 머신 상에 속한 데몬으로 여긴다.
|
||||
{{< /note >}}
|
||||
또한, 노드 컨트롤러는 파드가 테인트를 허용하지 않을 때 `NoExecute` 테인트 상태의
|
||||
노드에서 동작하는 파드에 대한 축출 책임을 가지고 있다.
|
||||
추가로, 노드 컨틀로러는 연결할 수 없거나, 준비되지 않은 노드와 같은 노드 문제에 상응하는
|
||||
{{< glossary_tooltip text="테인트" term_id="taint" >}}를 추가한다.
|
||||
이는 스케줄러가 비정상적인 노드에 파드를 배치하지 않게 된다.
|
||||
|
||||
{{< caution >}}
|
||||
`kubectl cordon` 은 노드를 'unschedulable'로 표기하는데, 이는
|
||||
|
@ -281,34 +293,41 @@ DaemonSet 컨트롤러에 의해 생성된 파드는 쿠버네티스 스케줄
|
|||
|
||||
### 노드 용량
|
||||
|
||||
노드의 용량 (cpu 수와 메모리 양) 은 노드 오브젝트의 한 부분이다.
|
||||
일반적으로, 노드는 스스로 등록하고 노드 오브젝트를 생성할 때 자신의 용량을 알린다. 만약
|
||||
[수동 노드 관리](#수동-노드-관리)를 수행 한다면, 노드를 추가할 때
|
||||
노드 용량을 설정해야 한다.
|
||||
노드 오브젝트는 노드 리소스 용량에 대한 정보(예: 사용 가능한 메모리의
|
||||
양과 CPU의 수)를 추적한다.
|
||||
노드의 [자체 등록](#노드에-대한-자체-등록)은 등록하는 중에 용량을 보고한다.
|
||||
[수동](#수동-노드-관리)으로 노드를 추가하는 경우 추가할 때
|
||||
노드의 용량 정보를 설정해야 한다.
|
||||
|
||||
쿠버네티스 스케줄러는 노드 상에 모든 노드에 대해 충분한 리소스가 존재하도록 보장한다.
|
||||
노드 상에 컨테이너에 대한 요청의 합이 노드 용량보다 더 크지 않도록 체크한다.
|
||||
kubelet에 의해 구동된 모든 컨테이너를 포함하지만, [컨테이너 런타임](/ko/docs/concepts/overview/components/#컨테이너-런타임)에 의해 직접 구동된 컨테이너 또는 컨테이너 외부에서 동작하는 임의의 프로세스는 해당되지 않는다.
|
||||
쿠버네티스 {{< glossary_tooltip text="스케줄러" term_id="kube-scheduler" >}}는
|
||||
노드 상에 모든 노드에 대해 충분한 리소스가 존재하도록 보장한다. 스케줄러는 노드 상에
|
||||
컨테이너에 대한 요청의 합이 노드 용량보다 더 크지 않도록 체크한다.
|
||||
요청의 합은 kubelet에서 관리하는 모든 컨테이너를 포함하지만, 컨테이너 런타임에
|
||||
의해 직접적으로 시작된 컨 테이너는 제외되고 kubelet의 컨트롤 범위
|
||||
밖에서 실행되는 모든 프로세스도 제외된다.
|
||||
|
||||
{{< note >}}
|
||||
파드 형태가 아닌 프로세스에 대해 명시적으로 리소스를 확보하려면,
|
||||
[reserve resources for system daemons](/docs/tasks/administer-cluster/reserve-compute-resources/#system-reserved) 튜토리얼을 따른다.
|
||||
[시스템 데몬에 사용할 리소스 예약하기](/docs/tasks/administer-cluster/reserve-compute-resources/#system-reserved)을 본다.
|
||||
{{< /note >}}
|
||||
|
||||
## 노드 토폴로지
|
||||
|
||||
{{< feature-state state="alpha" >}}
|
||||
{{< feature-state state="alpha" for_k8s_version="v1.16" >}}
|
||||
|
||||
`TopologyManager`
|
||||
[기능 게이트(feature gate)](/docs/reference/command-line-tools-reference/feature-gates/)를
|
||||
활성화 시켜두면, kubelet이 리소스 할당 결정을 할 때 토폴로지 힌트를 사용할 수 있다.
|
||||
|
||||
## API 오브젝트
|
||||
|
||||
노드는 쿠버네티스 REST API 내 탑-레벨 리소스 이다. API 오브젝트에 대한
|
||||
보다 자세한 내용은
|
||||
[노드 API 오브젝트](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#node-v1-core)에서 확인할 수 있다.
|
||||
자세한 내용은
|
||||
[노드의 컨트롤 토폴로지 관리 정책](/docs/tasks/administer-cluster/topology-manager/)을 본다.
|
||||
|
||||
{{% /capture %}}
|
||||
{{% capture whatsnext %}}
|
||||
* [노드 컴포넌트](/ko/docs/concepts/overview/components/#노드-컴포넌트)에 대해 읽기
|
||||
* 노드 수준 토폴로지에 대해 읽기: [노드의 토폴로지 정책 제어하기](/docs/tasks/administer-cluster/topology-manager/)
|
||||
* 노드를 구성하는 [컴포넌트](/ko/docs/concepts/overview/components/#노드-컴포넌트)에 대해 알아본다.
|
||||
* [노드에 대한 API 정의](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#node-v1-core)를 읽어본다.
|
||||
* 아키텍처 디자인 문서의 [노드](https://git.k8s.io/community/contributors/design-proposals/architecture/architecture.md#the-kubernetes-node)
|
||||
섹션을 읽어본다.
|
||||
* [테인트와 톨러레이션](/ko/docs/concepts/configuration/taint-and-toleration/)을 읽어본다.
|
||||
* [클러스터 오토스케일링](/ko/docs/tasks/administer-cluster/cluster-management/#클러스터-오토스케일링)을 읽어본다.
|
||||
{{% /capture %}}
|
||||
|
|
|
@ -30,6 +30,7 @@ content_template: templates/concept
|
|||
* [Flannel](https://github.com/coreos/flannel/blob/master/Documentation/kubernetes.md)은 쿠버네티스와 함께 사용할 수 있는 오버레이 네트워크 제공자이다.
|
||||
* [Knitter](https://github.com/ZTE/Knitter/)는 쿠버네티스 파드에서 여러 네트워크 인터페이스를 지원하는 플러그인이다.
|
||||
* [Multus](https://github.com/Intel-Corp/multus-cni)는 쿠버네티스에서 SRIOV, DPDK, OVS-DPDK 및 VPP 기반 워크로드 외에 모든 CNI 플러그인(예: Calico, Cilium, Contiv, Flannel)을 지원하기 위해 쿠버네티스에서 다중 네트워크 지원을 위한 멀티 플러그인이다.
|
||||
* [OVN4NFV-K8S-Plugin](https://github.com/opnfv/ovn4nfv-k8s-plugin)은 OVN 기반의 CNI 컨트롤러 플러그인으로 클라우드 네이티브 기반 서비스 기능 체인(Service function chaining(SFC)), 다중 OVN 오버레이 네트워킹, 동적 서브넷 생성, 동적 가상 네트워크 생성, VLAN 공급자 네트워크, 직접 공급자 네트워크와 멀티 클러스터 네트워킹의 엣지 기반 클라우드 등 네이티브 워크로드에 이상적인 멀티 네티워크 플러그인이다.
|
||||
* [NSX-T](https://docs.vmware.com/en/VMware-NSX-T/2.0/nsxt_20_ncp_kubernetes.pdf) 컨테이너 플러그인(NCP)은 VMware NSX-T와 쿠버네티스와 같은 컨테이너 오케스트레이터 간의 통합은 물론 NSX-T와 PKS(Pivotal 컨테이너 서비스) 및 OpenShift와 같은 컨테이너 기반 CaaS/PaaS 플랫폼 간의 통합을 제공한다.
|
||||
* [Nuage](https://github.com/nuagenetworks/nuage-kubernetes/blob/v5.1.1-1/docs/kubernetes-1-installation.rst)는 가시성과 보안 모니터링 기능을 통해 쿠버네티스 파드와 비-쿠버네티스 환경 간에 폴리시 기반 네트워킹을 제공하는 SDN 플랫폼이다.
|
||||
* [Romana](http://romana.io)는 [네트워크폴리시 API](/docs/concepts/services-networking/network-policies/)도 지원하는 파드 네트워크용 Layer 3 네트워킹 솔루션이다. Kubeadm 애드온 설치에 대한 세부 정보는 [여기](https://github.com/romana/romana/tree/master/containerize)에 있다.
|
||||
|
|
|
@ -134,6 +134,15 @@ CloudStack 클라우드 제공자는 쿠버네티스 노드 오브젝트의 이
|
|||
GCE 클라우드 제공자는 쿠버네티스 노드 오브젝트의 이름으로 노드의 (kubelet에 의해 결정되거나 `--hostname-override` 로 재정의된) 호스트 이름을 사용한다.
|
||||
참고로 쿠버네티스 노드 이름의 첫 번째 세그먼트는 GCE 인스턴스 이름과 일치해야 한다(예: `kubernetes-node-2.c.my-proj.internal` 이름이 지정된 노드는 `kubernetes-node-2` 이름이 지정된 인스턴스에 해당해야 함).
|
||||
|
||||
## HUAWEI 클라우드
|
||||
|
||||
외부 클라우드 제공자를 사용하려는 경우, 해당 리포지터리는 [kubernetes-sigs/cloud-provider-huaweicloud](https://github.com/kubernetes-sigs/cloud-provider-huaweicloud)이다.
|
||||
|
||||
### 노드 이름
|
||||
|
||||
HUAWEI 클라우드 제공자는 쿠버네티스 노드 오브젝트의 이름으로 노드의 프라이빗 IP 주소가 필요하다.
|
||||
노드에서 kubelet을 시작할 때 반드시 `--hostname-override=<node private IP>` 를 사용한다.
|
||||
|
||||
## OpenStack
|
||||
이 섹션에서는 쿠버네티스와 함께 OpenStack을 사용할 때 사용할 수 있는
|
||||
모든 구성에 대해 설명한다.
|
||||
|
@ -412,3 +421,15 @@ Baidu 클라우드 제공자는 쿠버네티스 노드 오브젝트의 이름으
|
|||
|
||||
Tencent 클라우드 제공자는 쿠버네티스 노드 오브젝트의 이름으로 노드의 (kubelet에 의해 결정되거나 `--hostname-override` 로 재정의된) 호스트 이름을 사용한다.
|
||||
참고로 쿠버네티스 노드 이름은 Tencent VM 프라이빗 IP와 일치해야 한다.
|
||||
|
||||
## Alibaba 클라우드 쿠버네티스
|
||||
|
||||
이 외부 클라우드 제공자를 사용하려는 경우, 해당 리포지터리는 [kubernetes/cloud-provider-alibaba-cloud](https://github.com/kubernetes/cloud-provider-alibaba-cloud)이다.
|
||||
|
||||
### 노드 이름
|
||||
|
||||
Alibaba 클라우드는 노드 이름의 형식을 요구하지는 않지만, kubelet은 `--provider-id=${REGION_ID}.${INSTANCE_ID}` 를 추가해야만 한다. 파라미터 `${REGION_ID}` 는 쿠버네티스의 지역 ID에 해당하고, `${INSTANCE_ID}` 는 Alibaba ECS (Elastic Compute Service) ID를 의미한다.
|
||||
|
||||
### 로드 밸런서
|
||||
|
||||
[어노테이션](https://www.alibabacloud.com/help/en/doc-detail/86531.htm)을 구성해서 Alibaba 클라우드의 특정 기능을 사용하도록 외부 로드 밸런서를 설정할 수 있다.
|
||||
|
|
|
@ -260,6 +260,10 @@ Lars Kellogg-Stedman이 제공하는 [이 훌륭한
|
|||
|
||||
Multus는 CNI 명세를 구현하는 모든 [레퍼런스 플러그인](https://github.com/containernetworking/plugins)(예: [플라넬](https://github.com/containernetworking/plugins/tree/master/plugins/meta/flannel), [DHCP](https://github.com/containernetworking/plugins/tree/master/plugins/ipam/dhcp), [Macvlan](https://github.com/containernetworking/plugins/tree/master/plugins/main/macvlan)) 및 써드파티 플러그인(예: [캘리코](https://github.com/projectcalico/cni-plugin), [위브(Weave)](https://github.com/weaveworks/weave), [실리움](https://github.com/cilium/cilium), [콘티브](https://github.com/contiv/netplugin))을 지원한다. 또한, Multus는 쿠버네티스의 클라우드 네이티브 애플리케이션과 NFV 기반 애플리케이션을 통해 쿠버네티스의 [SRIOV](https://github.com/hustcat/sriov-cni), [DPDK](https://github.com/Intel-Corp/sriov-cni), [OVS-DPDK 및 VPP](https://github.com/intel/vhost-user-net-plugin) 워크로드를 지원한다.
|
||||
|
||||
### OVN4NFV-K8s-Plugin (OVN 기반의 CNI 컨트롤러 & 플러그인)
|
||||
|
||||
[OVN4NFV-K8S-Plugin](https://github.com/opnfv/ovn4nfv-k8s-plugin)은 OVN 기반의 CNI 컨트롤러 플러그인으로 클라우드 네이티브 기반 서비스 기능 체인(Service function chaining(SFC)), 다중 OVN 오버레이 네트워킹, 동적 서브넷 생성, 동적 가상 네트워크 생성, VLAN 공급자 네트워크, 직접 공급자 네트워크와 멀티 클러스터 네트워킹의 엣지 기반 클라우드 등 네이티브 워크로드에 이상적인 멀티 네티워크 플러그인이다.
|
||||
|
||||
### NSX-T
|
||||
|
||||
[VMware NSX-T](https://docs.vmware.com/en/VMware-NSX-T/index.html)는 네트워크 가상화 및 보안 플랫폼이다. NSX-T는 멀티 클라우드 및 멀티 하이퍼바이저 환경에 네트워크 가상화를 제공할 수 있으며 이기종 엔드포인트와 기술 스택이 있는 새로운 애플리케이션 프레임워크 및 아키텍처에 중점을 둔다. vSphere 하이퍼바이저 외에도, 이러한 환경에는 KVM, 컨테이너 및 베어메탈과 같은 다른 하이퍼바이저가 포함된다.
|
||||
|
|
|
@ -57,7 +57,7 @@ API [오브젝트](/ko/docs/concepts/overview/working-with-objects/kubernetes-ob
|
|||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
Name: game-demo
|
||||
name: game-demo
|
||||
data:
|
||||
# 속성과 비슷한 키; 각 키는 간단한 값으로 매핑됨
|
||||
player_initial_lives: 3
|
||||
|
|
|
@ -321,7 +321,7 @@ Ei, Pi, Ti, Gi, Mi, Ki와 같은 2의 거듭제곱을 사용할 수도 있다.
|
|||
128974848, 129e6, 129M, 123Mi
|
||||
```
|
||||
|
||||
다음 예에서, 파드에 두 개의 컨테이너가 있다. 각 컨테이너에는 2GiB의 로컬 임시 스토리지 요청이 있다. 각 컨테이너에는 4GiB의 로컬 임시 스토리지 제한이 있다. 따라서, 파드는 4GiB의 로컬 임시 스토리지 요청과 8GiB 스토리지 제한을 가진다.
|
||||
다음 예에서, 파드에 두 개의 컨테이너가 있다. 각 컨테이너에는 2GiB의 로컬 임시 스토리지 요청이 있다. 각 컨테이너에는 4GiB의 로컬 임시 스토리지 제한이 있다. 따라서, 파드는 4GiB의 로컬 임시 스토리지 요청과 8GiB 로컬 임시 스토리지 제한을 가진다.
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
|
|
|
@ -48,13 +48,6 @@ weight: 70
|
|||
이들은 일반적인 클래스이며 [중요한(critical) 컴포넌트가 항상 먼저 스케줄링이 되도록 하는 데](/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods/) 사용된다.
|
||||
{{< /note >}}
|
||||
|
||||
기능을 사용해 본 후 사용하지 않기로 했다면, PodPriority
|
||||
커맨드-라인 플래그를 제거하거나 `false` 로 설정한 후, API 서버와
|
||||
스케줄러를 다시 시작해야 한다. 기능이 비활성화된 후, 기존 파드는
|
||||
우선순위 필드를 유지하지만, 선점은 비활성화되며, 우선순위 필드는
|
||||
무시된다. 이 기능이 비활성화되면, 새로운 파드에서 `priorityClassName` 을 설정할 수
|
||||
없다.
|
||||
|
||||
## 선점을 비활성화하는 방법
|
||||
|
||||
{{< caution >}}
|
||||
|
@ -117,7 +110,7 @@ disablePreemption: true
|
|||
|
||||
### PodPriority와 기존 클러스터에 대한 참고 사항
|
||||
|
||||
- 기존 클러스터를 업그레이드하고 이 기능을 활성화하면, 기존 파드의
|
||||
- 이 기능없이 기존 클러스터를 업그레이드 하는 경우, 기존 파드의
|
||||
우선순위는 사실상 0이다.
|
||||
|
||||
- `globalDefault` 가 `true` 로 설정된 프라이어리티클래스를 추가해도 기존 파드의
|
||||
|
|
|
@ -158,7 +158,7 @@ https://github.com/containerd/cri/blob/master/docs/config.md
|
|||
노드의 합집합을 취한다.
|
||||
|
||||
노드 셀렉터와 톨러레이션 설정에 대해 더 배우려면
|
||||
[노드에 파드 할당](/ko/docs/concepts/configuration/assign-pod-node/)을 참고한다.
|
||||
[노드에 파드 할당](/ko/docs/concepts/scheduling-eviction/assign-pod-node/)을 참고한다.
|
||||
|
||||
[런타임 클래스 어드미션 컨트롤러]: /docs/reference/access-authn-authz/admission-controllers/#runtimeclass
|
||||
|
||||
|
|
|
@ -223,6 +223,6 @@ selector:
|
|||
#### 노드 셋 선택
|
||||
|
||||
레이블을 통해 선택하는 사용 사례 중 하나는 파드를 스케줄 할 수 있는 노드 셋을 제한하는 것이다.
|
||||
자세한 내용은 [노드 선택](/ko/docs/concepts/configuration/assign-pod-node/) 문서를 참조한다.
|
||||
자세한 내용은 [노드 선택](/ko/docs/concepts/scheduling-eviction/assign-pod-node/) 문서를 참조한다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
|
|
@ -490,7 +490,8 @@ kubectl create quota test --hard=count/deployments.extensions=2,count/replicaset
|
|||
```
|
||||
|
||||
```shell
|
||||
kubectl run nginx --image=nginx --replicas=2 --namespace=myspace
|
||||
kubectl create deployment nginx --image=nginx --namespace=myspace
|
||||
kubectl scale deployment nginx --replicas=2 --namespace=myspace
|
||||
```
|
||||
|
||||
```shell
|
||||
|
|
|
@ -1,400 +1,400 @@
|
|||
---
|
||||
title: 노드에 파드 할당하기
|
||||
content_template: templates/concept
|
||||
weight: 50
|
||||
---
|
||||
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
{{< glossary_tooltip text="파드" term_id="pod" >}}를 특정한 {{< glossary_tooltip text="노드(들)" term_id="node" >}}에서만 동작하도록 하거나,
|
||||
특정 노드들을 선호하도록 제한할 수 있다.
|
||||
이를 수행하는 방법에는 여러 가지가 있으며, 권장되는 접근 방식은 모두
|
||||
[레이블 셀렉터](/ko/docs/concepts/overview/working-with-objects/labels/)를 사용하여 선택한다.
|
||||
보통 스케줄러가 자동으로 합리적인 배치(예: 노드들에 걸쳐 파드를 분배하거나,
|
||||
자원이 부족한 노드에 파드를 배치하지 않는 등)를 수행하기에 이런 제약 조건은 필요하지 않지만
|
||||
간혹 파드가 배치되는 노드에 대해 더 많은 제어를 원할 수 있는 상황이 있다.
|
||||
예를 들어 SSD가 장착된 머신에 파드가 연결되도록 하거나 또는 동일한 가용성 영역(availability zone)에서
|
||||
많은 것을 통신하는 두 개의 서로 다른 서비스의 파드를 같이 배치할 수 있다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
## 노드 셀렉터(nodeSelector)
|
||||
|
||||
`nodeSelector` 는 가장 간단하고 권장되는 노드 선택 제약 조건의 형태이다.
|
||||
`nodeSelector` 는 PodSpec의 필드이다. 이는 키-값 쌍의 매핑으로 지정한다. 파드가 노드에서 동작할 수 있으려면,
|
||||
노드는 키-값의 쌍으로 표시되는 레이블을 각자 가지고 있어야 한다(이는 추가 레이블을 가지고 있을 수 있다).
|
||||
일반적으로 하나의 키-값 쌍이 사용된다.
|
||||
|
||||
`nodeSelector` 를 어떻게 사용하는지 예시를 통해 알아보도록 하자.
|
||||
|
||||
### 0 단계: 사전 준비
|
||||
|
||||
이 예시는 쿠버네티스 파드에 대한 기본적인 이해를 하고 있고 [쿠버네티스 클러스터가 설정](/ko/docs/setup/)되어 있다고 가정한다.
|
||||
|
||||
### 1 단계: 노드에 레이블 붙이기
|
||||
|
||||
`kubectl get nodes` 를 실행해서 클러스터 노드 이름을 가져온다. 이 중에 레이블을 추가하기 원하는 것 하나를 선택한 다음에 `kubectl label nodes <노드 이름> <레이블 키>=<레이블 값>` 을 실행해서 선택한 노드에 레이블을 추가한다. 예를 들어 노드의 이름이 'kubernetes-foo-node-1.c.a-robinson.internal' 이고, 원하는 레이블이 'disktype=ssd' 라면, `kubectl label nodes kubernetes-foo-node-1.c.a-robinson.internal disktype=ssd` 를 실행한다.
|
||||
|
||||
`kubectl get nodes --show-labels` 를 다시 실행해서 노드가 현재 가진 레이블을 확인하여, 이 작업을 검증할 수 있다. 또한 `kubectl describe node "노드 이름"` 을 사용해서 노드에 주어진 레이블의 전체 목록을 확인할 수 있다.
|
||||
|
||||
### 2 단계: 파드 설정에 nodeSelector 필드 추가하기
|
||||
|
||||
실행하고자 하는 파드의 설정 파일을 가져오고, 이처럼 nodeSelector 섹션을 추가한다. 예를 들어 이것이 파드 설정이라면,
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: nginx
|
||||
labels:
|
||||
env: test
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx
|
||||
```
|
||||
|
||||
이 다음에 nodeSelector 를 다음과 같이 추가한다.
|
||||
|
||||
{{< codenew file="pods/pod-nginx.yaml" >}}
|
||||
|
||||
그런 다음에 `kubectl apply -f https://k8s.io/examples/pods/pod-nginx.yaml` 을
|
||||
실행하면, 레이블이 붙여진 노드에 파드가 스케줄 된다.
|
||||
`kubectl get pods -o wide` 를 실행해서 파드가 할당된
|
||||
"NODE" 를 보면 작동하는지 검증할 수 있다.
|
||||
|
||||
## 넘어가기 전에: 내장 노드 레이블들 {#built-in-node-labels}
|
||||
|
||||
[붙인](#1-단계-노드에-레이블-붙이기) 레이블뿐만 아니라, 노드에는
|
||||
표준 레이블 셋이 미리 채워져 있다. 이 레이블들은 다음과 같다.
|
||||
|
||||
* [`kubernetes.io/hostname`](/docs/reference/kubernetes-api/labels-annotations-taints/#kubernetes-io-hostname)
|
||||
* [`failure-domain.beta.kubernetes.io/zone`](/docs/reference/kubernetes-api/labels-annotations-taints/#failure-domainbetakubernetesiozone)
|
||||
* [`failure-domain.beta.kubernetes.io/region`](/docs/reference/kubernetes-api/labels-annotations-taints/#failure-domainbetakubernetesioregion)
|
||||
* [`topology.kubernetes.io/zone`](/docs/reference/kubernetes-api/labels-annotations-taints/#topologykubernetesiozone)
|
||||
* [`topology.kubernetes.io/region`](/docs/reference/kubernetes-api/labels-annotations-taints/#topologykubernetesiozone)
|
||||
* [`beta.kubernetes.io/instance-type`](/docs/reference/kubernetes-api/labels-annotations-taints/#beta-kubernetes-io-instance-type)
|
||||
* [`node.kubernetes.io/instance-type`](/docs/reference/kubernetes-api/labels-annotations-taints/#nodekubernetesioinstance-type)
|
||||
* [`kubernetes.io/os`](/docs/reference/kubernetes-api/labels-annotations-taints/#kubernetes-io-os)
|
||||
* [`kubernetes.io/arch`](/docs/reference/kubernetes-api/labels-annotations-taints/#kubernetes-io-arch)
|
||||
|
||||
{{< note >}}
|
||||
이 레이블들의 값은 클라우드 공급자에 따라 다르고 신뢰성이 보장되지 않는다.
|
||||
예를 들어 `kubernetes.io/hostname` 은 어떤 환경에서는 노드 이름과 같지만,
|
||||
다른 환경에서는 다른 값일 수 있다.
|
||||
{{< /note >}}
|
||||
|
||||
## 노드 격리(isolation)/제한(restriction)
|
||||
|
||||
노드 오브젝트에 레이블을 추가하면 파드가 특정 노드 또는 노드 그룹을 목표 대상으로 할 수 있게 된다.
|
||||
이는 특정 파드가 어떤 격리, 보안, 또는 규제 속성이 있는 노드에서만 실행되도록 사용할 수 있다.
|
||||
이 목적으로 레이블을 사용하는 경우, 노드에서 kubelet 프로세스로 수정할 수 없는 레이블 키를 선택하는 것을 권장한다.
|
||||
이렇게 하면 손상된 노드가 해당 kubelet 자격 증명을 사용해서 해당 레이블을 자체 노드 오브젝트에 설정하고,
|
||||
스케줄러가 손상된 노드로 워크로드를 스케줄 하는 것을 방지할 수 있다.
|
||||
|
||||
`NodeRestriction` 어드미션 플러그인은 kubelet이 `node-restriction.kubernetes.io/` 접두사로 레이블을 설정 또는 수정하지 못하게 한다.
|
||||
노드 격리에 해당 레이블 접두사를 사용하려면 다음과 같이 한다.
|
||||
|
||||
1. [노드 권한부여자](/docs/reference/access-authn-authz/node/)를 사용하고 있고, [NodeRestriction 어드미션 플러그인](/docs/reference/access-authn-authz/admission-controllers/#noderestriction)을 _활성화_ 해야 한다.
|
||||
2. 노드 오브젝트의 `node-restriction.kubernetes.io/` 접두사 아래에 레이블을 추가하고, 해당 레이블을 노드 셀렉터에서 사용한다.
|
||||
예를 들어, `example.com.node-restriction.kubernetes.io/fips=true` 또는 `example.com.node-restriction.kubernetes.io/pci-dss=true` 이다.
|
||||
|
||||
## 어피니티(affinity)와 안티-어피니티(anti-affinity)
|
||||
|
||||
`nodeSelector` 는 파드를 특정 레이블이 있는 노드로 제한하는 매우 간단한 방법을 제공한다.
|
||||
어피니티/안티-어피니티 기능은 표현할 수 있는 제약 종류를 크게 확장한다. 주요 개선 사항은 다음과 같다.
|
||||
|
||||
1. 어피니티/안티-어피니티 언어가 더 표현적이다. 언어는 논리 연산자인 AND 연산으로 작성된
|
||||
정확한 매칭 항목 이외에 더 많은 매칭 규칙을 제공한다.
|
||||
2. 규칙이 엄격한 요구 사항이 아니라 "유연한(soft)"/"선호(preference)" 규칙을 나타낼 수 있기에 스케줄러가 규칙을 만족할 수 없더라도,
|
||||
파드가 계속 스케줄 되도록 한다.
|
||||
3. 노드 자체에 레이블을 붙이기보다는 노드(또는 다른 토폴로지 도메인)에서 실행 중인 다른 파드의 레이블을 제한할 수 있다.
|
||||
이를 통해 어떤 파드가 함께 위치할 수 있는지와 없는지에 대한 규칙을 적용할 수 있다.
|
||||
|
||||
어피니티 기능은 "노드 어피니티" 와 "파드 간 어피니티/안티-어피니티" 두 종류의 어피니티로 구성된다.
|
||||
노드 어피니티는 기존 `nodeSelector` 와 비슷하지만(그러나 위에서 나열된 첫째와 두 번째 이점이 있다.),
|
||||
파드 간 어피니티/안티-어피니티는 위에서 나열된 세번째 항목에 설명된 대로
|
||||
노드 레이블이 아닌 파드 레이블에 대해 제한되고 위에서 나열된 첫 번째와 두 번째 속성을 가진다.
|
||||
|
||||
### 노드 어피니티
|
||||
|
||||
노드 어피니티는 개념적으로 `nodeSelector` 와 비슷하다 -- 이는 노드의 레이블을 기반으로 파드를
|
||||
스케줄할 수 있는 노드를 제한할 수 있다.
|
||||
|
||||
여기에 현재 `requiredDuringSchedulingIgnoredDuringExecution` 와 `preferredDuringSchedulingIgnoredDuringExecution` 로 부르는
|
||||
두 가지 종류의 노드 어피니티가 있다. 전자는 파드가 노드에 스케줄 되도록 *반드시*
|
||||
규칙을 만족해야 하는 것(`nodeSelector` 와 같으나 보다 표현적인 구문을 사용해서)을 지정하고,
|
||||
후자는 스케줄러가 시도하려고는 하지만, 보증하지 않는 *선호(preferences)* 를 지정한다는 점에서
|
||||
이를 각각 "엄격함(hard)" 과 "유연함(soft)" 으로 생각할 수 있다.
|
||||
이름의 "IgnoredDuringExecution" 부분은 `nodeSelector` 작동 방식과 유사하게 노드의
|
||||
레이블이 런타임 중에 변경되어 파드의 어피니티 규칙이 더 이상 충족되지 않으면 파드가 여전히 그 노드에서
|
||||
동작한다는 의미이다. 향후에는 파드의 노드 어피니티 요구 사항을 충족하지 않는 노드에서 파드를 제거한다는
|
||||
점을 제외하고는 `preferredDuringSchedulingIgnoredDuringExecution` 와 같은 `requiredDuringSchedulingIgnoredDuringExecution` 를 제공할 계획이다.
|
||||
|
||||
따라서 `requiredDuringSchedulingIgnoredDuringExecution` 의 예로는 "인텔 CPU가 있는 노드에서만 파드 실행"이
|
||||
될 수 있고, `preferredDuringSchedulingIgnoredDuringExecution` 의 예로는 "장애 조치 영역 XYZ에 파드 집합을 실행하려고
|
||||
하지만, 불가능하다면 다른 곳에서 일부를 실행하도록 허용"이 있을 것이다.
|
||||
|
||||
노드 어피니티는 PodSpec의 `affinity` 필드의 `nodeAffinity` 필드에서 지정된다.
|
||||
|
||||
여기에 노드 어피니티를 사용하는 파드 예시가 있다.
|
||||
|
||||
{{< codenew file="pods/pod-with-node-affinity.yaml" >}}
|
||||
|
||||
이 노드 어피니티 규칙은 키가 `kubernetes.io/e2e-az-name` 이고 값이 `e2e-az1` 또는 `e2e-az2` 인
|
||||
레이블이 있는 노드에만 파드를 배치할 수 있다고 말한다. 또한, 이 기준을 충족하는 노드들
|
||||
중에서 키가 `another-node-label-key` 이고 값이 `another-node-label-value` 인 레이블이 있는 노드를
|
||||
선호하도록 한다.
|
||||
|
||||
예시에서 연산자 `In` 이 사용되고 있는 것을 볼 수 있다. 새로운 노드 어피니티 구문은 다음의 연산자들을 지원한다. `In`, `NotIn`, `Exists`, `DoesNotExist`, `Gt`, `Lt`.
|
||||
`NotIn` 과 `DoesNotExist` 를 사용해서 안티-어피니티를 수행하거나,
|
||||
특정 노드에서 파드를 쫓아내는 [노드 테인트(taint)](/docs/concepts/configuration/taint-and-toleration/)를 설정할 수 있다.
|
||||
|
||||
`nodeSelector` 와 `nodeAffinity` 를 모두 지정한다면 파드가 후보 노드에 스케줄 되기 위해서는
|
||||
*둘 다* 반드시 만족해야 한다.
|
||||
|
||||
`nodeAffinity` 유형과 연관된 `nodeSelectorTerms` 를 지정하면, 파드는 `nodeSelectorTerms` 를 **모두** 만족하는 노드에만 스케줄할 수 있다.
|
||||
|
||||
`nodeSelectorTerms` 와 연관된 여러 `matchExpressions` 를 지정하면, 파드는 `matchExpressions` 이 지정된 것 중 **한 가지**라도 만족하는 노드에만 스케줄할 수 있다.
|
||||
|
||||
파드가 스케줄 된 노드의 레이블을 지우거나 변경해도 파드는 제거되지 않는다. 다시 말해서 어피니티 선택은 파드를 스케줄링 하는 시점에만 작동한다.
|
||||
|
||||
`preferredDuringSchedulingIgnoredDuringExecution` 의 `weight` 필드의 범위는 1-100이다. 모든 스케줄링 요구 사항 (리소스 요청, RequiredDuringScheduling 어피니티 표현식 등)을 만족하는 각 노드들에 대해 스케줄러는 이 필드의 요소들을 반복해서 합계를 계산하고 노드가 MatchExpressions 에 일치하는 경우 합계에 "가중치(weight)"를 추가한다. 이후에 이 점수는 노드에 대한 다른 우선순위 함수의 점수와 합쳐진다. 전체 점수가 가장 높은 노드를 가장 선호한다.
|
||||
|
||||
### 파드간 어피니티와 안티-어피니티
|
||||
|
||||
파드간 어피니티와 안티-어피니티를 사용하면 노드의 레이블을 기반으로 하지 않고, *노드에서 이미 실행 중인 파드 레이블을 기반으로*
|
||||
파드가 스케줄될 수 있는 노드를 제한할 수 있다. 규칙은 "X가 규칙 Y를 충족하는 하나 이상의 파드를 이미 실행중인 경우
|
||||
이 파드는 X에서 실행해야 한다(또는 안티-어피니티가 없는 경우에는 동작하면 안된다)"는 형태이다. Y는
|
||||
선택적으로 연관된 네임스페이스 목록을 가진 LabelSelector로 표현된다. 노드와는 다르게 파드는 네임스페이스이기에
|
||||
(그리고 따라서 파드의 레이블은 암암리에 네임스페이스이다) 파드 레이블위의 레이블 셀렉터는 반드시
|
||||
셀렉터가 적용될 네임스페이스를 지정해야만 한다. 개념적으로 X는 노드, 랙,
|
||||
클라우드 공급자 영역, 클라우드 공급자 지역 등과 같은 토폴로지 도메인이다. 시스템이 이런 토폴로지
|
||||
도메인을 나타내는 데 사용하는 노드 레이블 키인 `topologyKey` 를 사용하여 이를 표현한다.
|
||||
예: [넘어가기 전에: 빌트인 노드 레이블](#built-in-node-labels) 섹션 위에 나열된 레이블 키를 본다.
|
||||
|
||||
{{< note >}}
|
||||
파드간 어피니티와 안티-어피니티에는 상당한 양의 프로세싱이 필요하기에
|
||||
대규모 클러스터에서는 스케줄링 속도가 크게 느려질 수 있다.
|
||||
수백 개의 노드를 넘어가는 클러스터에서 이를 사용하는 것은 추천하지 않는다.
|
||||
{{< /note >}}
|
||||
|
||||
{{< note >}}
|
||||
파드 안티-어피니티에서는 노드에 일관된 레이블을 지정해야 한다. 즉, 클러스터의 모든 노드는 `topologyKey` 와 매칭되는 적절한 레이블을 가지고 있어야 한다. 일부 또는 모든 노드에 지정된 `topologyKey` 레이블이 없는 경우에는 의도하지 않은 동작이 발생할 수 있다.
|
||||
{{< /note >}}
|
||||
|
||||
노드 어피니티와 마찬가지로 현재 파드 어피니티와 안티-어피니티로 부르는 "엄격함" 대 "유연함"의 요구사항을 나타내는 `requiredDuringSchedulingIgnoredDuringExecution` 와
|
||||
`preferredDuringSchedulingIgnoredDuringExecution` 두 가지 종류가 있다.
|
||||
앞의 노드 어피니티 섹션의 설명을 본다.
|
||||
`requiredDuringSchedulingIgnoredDuringExecution` 어피니티의 예시는
|
||||
"서로 많은 통신을 하기 때문에 서비스 A와 서비스 B를 같은 영역에 함께 위치시키는 것"이고,
|
||||
`preferredDuringSchedulingIgnoredDuringExecution` 안티-어피니티의 예시는 "서비스를 여러 영역에 걸쳐서 분배하는 것"이다
|
||||
(엄격한 요구사항은 영역보다 파드가 더 많을 수 있기 때문에 엄격한 요구사항은 의미가 없다).
|
||||
|
||||
파드간 어피니티는 PodSpec에서 `affinity` 필드 중 `podAffinity` 필드로 지정한다.
|
||||
그리고 파드간 안티-어피니티는 PodSpec에서 `affinity` 필드 중 `podAntiAffinity` 필드로 지정한다.
|
||||
|
||||
#### 파드 어피니티를 사용하는 파드의 예시
|
||||
|
||||
{{< codenew file="pods/pod-with-pod-affinity.yaml" >}}
|
||||
|
||||
이 파드의 어피니티는 하나의 파드 어피니티 규칙과 하나의 파드 안티-어피니티 규칙을 정의한다.
|
||||
이 예시에서 `podAffinity` 는 `requiredDuringSchedulingIgnoredDuringExecution` 이고 `podAntiAffinity` 는
|
||||
`preferredDuringSchedulingIgnoredDuringExecution` 이다. 파드 어피니티 규칙에 의하면 키 "security" 와 값
|
||||
"S1"인 레이블이 있는 하나 이상의 이미 실행 중인 파드와 동일한 영역에 있는 경우에만 파드를 노드에 스케줄할 수 있다.
|
||||
(보다 정확하게는, 클러스터에 키 "security"와 값 "S1"인 레이블을 가지고 있는 실행 중인 파드가 있는 키
|
||||
`failure-domain.beta.kubernetes.io/zone` 와 값 V인 노드가 최소 하나 이상 있고, 노드 N이 키
|
||||
`failure-domain.beta.kubernetes.io/zone` 와 일부 값이 V인 레이블을 가진다면 파드는 노드 N에서 실행할 수 있다.)
|
||||
파드 안티-어피니티 규칙에 의하면 노드가 이미 키 "security"와 값 "S2"인 레이블을 가진 파드를
|
||||
실행하고 있는 파드는 노드에 스케줄되는 것을 선호하지 않는다.
|
||||
(만약 `topologyKey` 가 `failure-domain.beta.kubernetes.io/zone` 라면 노드가 키
|
||||
"security"와 값 "S2"를 레이블로 가진 파드와
|
||||
동일한 영역에 있는 경우, 노드에 파드를 예약할 수 없음을 의미한다.)
|
||||
[디자인 문서](https://git.k8s.io/community/contributors/design-proposals/scheduling/podaffinity.md)를 통해
|
||||
`requiredDuringSchedulingIgnoredDuringExecution` 와 `preferredDuringSchedulingIgnoredDuringExecution` 의
|
||||
파드 어피니티와 안티-어피니티에 대한 많은 예시를 맛볼 수 있다.
|
||||
|
||||
파드 어피니티와 안티-어피니티의 적합한 연산자는 `In`, `NotIn`, `Exists`, `DoesNotExist` 이다.
|
||||
|
||||
원칙적으로, `topologyKey` 는 적법한 어느 레이블-키도 될 수 있다.
|
||||
하지만, 성능과 보안상의 이유로 topologyKey에는 몇 가지 제약조건이 있다.
|
||||
|
||||
1. 어피니티와 `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티는 대해
|
||||
`topologyKey` 가 비어있는 것을 허용하지 않는다.
|
||||
2. `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에서 `topologyKey` 를 `kubernetes.io/hostname` 로 제한하기 위해 어드미션 컨트롤러 `LimitPodHardAntiAffinityTopology` 가 도입되었다. 사용자 지정 토폴로지를에 사용할 수 있도록 하려면, 어드미션 컨트롤러를 수정하거나 간단히 이를 비활성화 할 수 있다.
|
||||
3. `preferredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티는 `topologyKey` 가 비어있는 것을 허용하지 않는다.
|
||||
4. 위의 경우를 제외하고, `topologyKey` 는 적법한 어느 레이블-키도 가능하다.
|
||||
|
||||
`labelSelector` 와 `topologyKey` 외에도 `labelSelector` 와 일치해야 하는 네임스페이스 목록 `namespaces` 를
|
||||
선택적으로 지정할 수 있다(이것은 `labelSelector` 와 `topologyKey` 와 같은 수준의 정의이다).
|
||||
생략되어있거나 비어있을 경우 어피니티/안티-어피니티 정의가 있는 파드의 네임스페이스가 기본 값이다.
|
||||
|
||||
파드를 노드에 스케줄하려면 `requiredDuringSchedulingIgnoredDuringExecution` 어피니티와 안티-어피니티와
|
||||
연관된 `matchExpressions` 가 모두 충족되어야 한다.
|
||||
|
||||
#### 더 실용적인 유스케이스
|
||||
|
||||
파드간 어피니티와 안티-어피니티는 레플리카셋, 스테이트풀셋, 디플로이먼트 등과 같은
|
||||
상위 레벨 모음과 함께 사용할 때 더욱 유용할 수 있다. 워크로드 집합이 동일한 노드와 같이
|
||||
동일하게 정의된 토폴로지와 같은 위치에 배치되도록 쉽게 구성할 수 있다.
|
||||
|
||||
##### 항상 같은 노드에 위치시키기
|
||||
|
||||
세 개의 노드가 있는 클러스터에서 웹 애플리케이션에는 redis와 같은 인-메모리 캐시가 있다. 웹 서버가 가능한 캐시와 함께 위치하기를 원한다.
|
||||
|
||||
다음은 세 개의 레플리카와 셀렉터 레이블이 `app=store` 가 있는 간단한 redis 디플로이먼트의 yaml 스니펫이다. 디플로이먼트에는 스케줄러가 단일 노드에서 레플리카를 함께 배치하지 않도록 `PodAntiAffinity` 가 구성되어 있다.
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: redis-cache
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: store
|
||||
replicas: 3
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: store
|
||||
spec:
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- labelSelector:
|
||||
matchExpressions:
|
||||
- key: app
|
||||
operator: In
|
||||
values:
|
||||
- store
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
containers:
|
||||
- name: redis-server
|
||||
image: redis:3.2-alpine
|
||||
```
|
||||
|
||||
아래 yaml 스니펫의 웹서버 디플로이먼트는 `podAntiAffinity` 와 `podAffinity` 설정을 가지고 있다. 이렇게 하면 스케줄러에 모든 레플리카는 셀렉터 레이블이 `app=store` 인 파드와 함께 위치해야 한다. 또한 각 웹 서버 레플리카가 단일 노드의 같은 위치에 있지 않도록 한다.
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: web-server
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: web-store
|
||||
replicas: 3
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: web-store
|
||||
spec:
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- labelSelector:
|
||||
matchExpressions:
|
||||
- key: app
|
||||
operator: In
|
||||
values:
|
||||
- web-store
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
podAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- labelSelector:
|
||||
matchExpressions:
|
||||
- key: app
|
||||
operator: In
|
||||
values:
|
||||
- store
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
containers:
|
||||
- name: web-app
|
||||
image: nginx:1.16-alpine
|
||||
```
|
||||
|
||||
만약 위의 두 디플로이먼트를 생성하면 세 개의 노드가 있는 클러스터는 다음과 같아야 한다.
|
||||
|
||||
| node-1 | node-2 | node-3 |
|
||||
|:--------------------:|:-------------------:|:------------------:|
|
||||
| *webserver-1* | *webserver-2* | *webserver-3* |
|
||||
| *cache-1* | *cache-2* | *cache-3* |
|
||||
|
||||
여기서 볼 수 있듯이 `web-server` 의 세 레플리카들이 기대했던 것처럼 자동으로 캐시와 함께 위치하게 된다.
|
||||
|
||||
```
|
||||
kubectl get pods -o wide
|
||||
```
|
||||
출력은 다음과 유사할 것이다.
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE IP NODE
|
||||
redis-cache-1450370735-6dzlj 1/1 Running 0 8m 10.192.4.2 kube-node-3
|
||||
redis-cache-1450370735-j2j96 1/1 Running 0 8m 10.192.2.2 kube-node-1
|
||||
redis-cache-1450370735-z73mh 1/1 Running 0 8m 10.192.3.1 kube-node-2
|
||||
web-server-1287567482-5d4dz 1/1 Running 0 7m 10.192.2.3 kube-node-1
|
||||
web-server-1287567482-6f7v5 1/1 Running 0 7m 10.192.4.3 kube-node-3
|
||||
web-server-1287567482-s330j 1/1 Running 0 7m 10.192.3.2 kube-node-2
|
||||
```
|
||||
|
||||
##### 절대 동일한 노드에 위치시키지 않게 하기
|
||||
|
||||
위의 예시에서 `topologyKey:"kubernetes.io/hostname"` 과 함께 `PodAntiAffinity` 규칙을 사용해서
|
||||
두 개의 인스터스가 동일한 호스트에 있지 않도록 redis 클러스터를 배포한다.
|
||||
같은 기술을 사용해서 고 가용성을 위해 안티-어피니티로 구성된 스테이트풀셋의 예시는
|
||||
[ZooKeeper 튜토리얼](/ko/docs/tutorials/stateful-application/zookeeper/#노드-실패-방지)을 본다.
|
||||
|
||||
## nodeName
|
||||
|
||||
`nodeName` 은 가장 간단한 형태의 노트 선택 제약 조건이지만,
|
||||
한계로 인해 일반적으로는 사용하지 않는다.
|
||||
`nodeName` 은 PodSpec의 필드이다. 만약 비어있지 않으면, 스케줄러는
|
||||
파드를 무시하고 명명된 노드에서 실행 중인 kubelet이
|
||||
파드를 실행하려고 한다. 따라서 만약 PodSpec에 `nodeName` 가
|
||||
제공된 경우, 노드 선텍을 위해 위의 방법보다 우선한다.
|
||||
|
||||
`nodeName` 을 사용해서 노드를 선택할 때의 몇 가지 제한은 다음과 같다.
|
||||
|
||||
- 만약 명명된 노드가 없으면, 파드가 실행되지 않고
|
||||
따라서 자동으로 삭제될 수 있다.
|
||||
- 만약 명명된 노드에 파드를 수용할 수 있는
|
||||
리소스가 없는 경우 파드가 실패하고, 그 이유는 다음과 같이 표시된다.
|
||||
예: OutOfmemory 또는 OutOfcpu.
|
||||
- 클라우드 환경의 노드 이름은 항상 예측 가능하거나
|
||||
안정적인 것은 아니다.
|
||||
|
||||
여기에 `nodeName` 필드를 사용하는 파드 설정 파일 예시가 있다.
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx
|
||||
nodeName: kube-01
|
||||
```
|
||||
|
||||
위 파드는 kube-01 노드에서 실행될 것이다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
|
||||
[테인트](/docs/concepts/configuration/taint-and-toleration/)는 노드가 특정 파드들을 *쫓아내게* 할 수 있다.
|
||||
|
||||
[노드 어피니티](https://git.k8s.io/community/contributors/design-proposals/scheduling/nodeaffinity.md)와
|
||||
[파드간 어피니티/안티-어피니티](https://git.k8s.io/community/contributors/design-proposals/scheduling/podaffinity.md)에 대한 디자인 문서에는
|
||||
이러한 기능에 대한 추가 배경 정보가 있다.
|
||||
|
||||
파드가 노드에 할당되면 kubelet은 파드를 실행하고 노드의 로컬 리소스를 할당한다.
|
||||
[토폴로지 매니저](/docs/tasks/administer-cluster/topology-manager/)는
|
||||
노드 수준의 리소스 할당 결정에 참여할 수 있다.
|
||||
|
||||
{{% /capture %}}
|
||||
---
|
||||
title: 노드에 파드 할당하기
|
||||
content_template: templates/concept
|
||||
weight: 50
|
||||
---
|
||||
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
{{< glossary_tooltip text="파드" term_id="pod" >}}를 특정한 {{< glossary_tooltip text="노드(들)" term_id="node" >}}에서만 동작하도록 하거나,
|
||||
특정 노드들을 선호하도록 제한할 수 있다.
|
||||
이를 수행하는 방법에는 여러 가지가 있으며, 권장되는 접근 방식은 모두
|
||||
[레이블 셀렉터](/ko/docs/concepts/overview/working-with-objects/labels/)를 사용하여 선택한다.
|
||||
보통 스케줄러가 자동으로 합리적인 배치(예: 노드들에 걸쳐 파드를 분배하거나,
|
||||
자원이 부족한 노드에 파드를 배치하지 않는 등)를 수행하기에 이런 제약 조건은 필요하지 않지만
|
||||
간혹 파드가 배치되는 노드에 대해 더 많은 제어를 원할 수 있는 상황이 있다.
|
||||
예를 들어 SSD가 장착된 머신에 파드가 연결되도록 하거나 또는 동일한 가용성 영역(availability zone)에서
|
||||
많은 것을 통신하는 두 개의 서로 다른 서비스의 파드를 같이 배치할 수 있다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
## 노드 셀렉터(nodeSelector)
|
||||
|
||||
`nodeSelector` 는 가장 간단하고 권장되는 노드 선택 제약 조건의 형태이다.
|
||||
`nodeSelector` 는 PodSpec의 필드이다. 이는 키-값 쌍의 매핑으로 지정한다. 파드가 노드에서 동작할 수 있으려면,
|
||||
노드는 키-값의 쌍으로 표시되는 레이블을 각자 가지고 있어야 한다(이는 추가 레이블을 가지고 있을 수 있다).
|
||||
일반적으로 하나의 키-값 쌍이 사용된다.
|
||||
|
||||
`nodeSelector` 를 어떻게 사용하는지 예시를 통해 알아보도록 하자.
|
||||
|
||||
### 0 단계: 사전 준비
|
||||
|
||||
이 예시는 쿠버네티스 파드에 대한 기본적인 이해를 하고 있고 [쿠버네티스 클러스터가 설정](/ko/docs/setup/)되어 있다고 가정한다.
|
||||
|
||||
### 1 단계: 노드에 레이블 붙이기
|
||||
|
||||
`kubectl get nodes` 를 실행해서 클러스터 노드 이름을 가져온다. 이 중에 레이블을 추가하기 원하는 것 하나를 선택한 다음에 `kubectl label nodes <노드 이름> <레이블 키>=<레이블 값>` 을 실행해서 선택한 노드에 레이블을 추가한다. 예를 들어 노드의 이름이 'kubernetes-foo-node-1.c.a-robinson.internal' 이고, 원하는 레이블이 'disktype=ssd' 라면, `kubectl label nodes kubernetes-foo-node-1.c.a-robinson.internal disktype=ssd` 를 실행한다.
|
||||
|
||||
`kubectl get nodes --show-labels` 를 다시 실행해서 노드가 현재 가진 레이블을 확인하여, 이 작업을 검증할 수 있다. 또한 `kubectl describe node "노드 이름"` 을 사용해서 노드에 주어진 레이블의 전체 목록을 확인할 수 있다.
|
||||
|
||||
### 2 단계: 파드 설정에 nodeSelector 필드 추가하기
|
||||
|
||||
실행하고자 하는 파드의 설정 파일을 가져오고, 이처럼 nodeSelector 섹션을 추가한다. 예를 들어 이것이 파드 설정이라면,
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: nginx
|
||||
labels:
|
||||
env: test
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx
|
||||
```
|
||||
|
||||
이 다음에 nodeSelector 를 다음과 같이 추가한다.
|
||||
|
||||
{{< codenew file="pods/pod-nginx.yaml" >}}
|
||||
|
||||
그런 다음에 `kubectl apply -f https://k8s.io/examples/pods/pod-nginx.yaml` 을
|
||||
실행하면, 레이블이 붙여진 노드에 파드가 스케줄 된다.
|
||||
`kubectl get pods -o wide` 를 실행해서 파드가 할당된
|
||||
"NODE" 를 보면 작동하는지 검증할 수 있다.
|
||||
|
||||
## 넘어가기 전에: 내장 노드 레이블들 {#built-in-node-labels}
|
||||
|
||||
[붙인](#1-단계-노드에-레이블-붙이기) 레이블뿐만 아니라, 노드에는
|
||||
표준 레이블 셋이 미리 채워져 있다. 이 레이블들은 다음과 같다.
|
||||
|
||||
* [`kubernetes.io/hostname`](/docs/reference/kubernetes-api/labels-annotations-taints/#kubernetes-io-hostname)
|
||||
* [`failure-domain.beta.kubernetes.io/zone`](/docs/reference/kubernetes-api/labels-annotations-taints/#failure-domainbetakubernetesiozone)
|
||||
* [`failure-domain.beta.kubernetes.io/region`](/docs/reference/kubernetes-api/labels-annotations-taints/#failure-domainbetakubernetesioregion)
|
||||
* [`topology.kubernetes.io/zone`](/docs/reference/kubernetes-api/labels-annotations-taints/#topologykubernetesiozone)
|
||||
* [`topology.kubernetes.io/region`](/docs/reference/kubernetes-api/labels-annotations-taints/#topologykubernetesiozone)
|
||||
* [`beta.kubernetes.io/instance-type`](/docs/reference/kubernetes-api/labels-annotations-taints/#beta-kubernetes-io-instance-type)
|
||||
* [`node.kubernetes.io/instance-type`](/docs/reference/kubernetes-api/labels-annotations-taints/#nodekubernetesioinstance-type)
|
||||
* [`kubernetes.io/os`](/docs/reference/kubernetes-api/labels-annotations-taints/#kubernetes-io-os)
|
||||
* [`kubernetes.io/arch`](/docs/reference/kubernetes-api/labels-annotations-taints/#kubernetes-io-arch)
|
||||
|
||||
{{< note >}}
|
||||
이 레이블들의 값은 클라우드 공급자에 따라 다르고 신뢰성이 보장되지 않는다.
|
||||
예를 들어 `kubernetes.io/hostname` 은 어떤 환경에서는 노드 이름과 같지만,
|
||||
다른 환경에서는 다른 값일 수 있다.
|
||||
{{< /note >}}
|
||||
|
||||
## 노드 격리(isolation)/제한(restriction)
|
||||
|
||||
노드 오브젝트에 레이블을 추가하면 파드가 특정 노드 또는 노드 그룹을 목표 대상으로 할 수 있게 된다.
|
||||
이는 특정 파드가 어떤 격리, 보안, 또는 규제 속성이 있는 노드에서만 실행되도록 사용할 수 있다.
|
||||
이 목적으로 레이블을 사용하는 경우, 노드에서 kubelet 프로세스로 수정할 수 없는 레이블 키를 선택하는 것을 권장한다.
|
||||
이렇게 하면 손상된 노드가 해당 kubelet 자격 증명을 사용해서 해당 레이블을 자체 노드 오브젝트에 설정하고,
|
||||
스케줄러가 손상된 노드로 워크로드를 스케줄 하는 것을 방지할 수 있다.
|
||||
|
||||
`NodeRestriction` 어드미션 플러그인은 kubelet이 `node-restriction.kubernetes.io/` 접두사로 레이블을 설정 또는 수정하지 못하게 한다.
|
||||
노드 격리에 해당 레이블 접두사를 사용하려면 다음과 같이 한다.
|
||||
|
||||
1. [노드 권한부여자](/docs/reference/access-authn-authz/node/)를 사용하고 있고, [NodeRestriction 어드미션 플러그인](/docs/reference/access-authn-authz/admission-controllers/#noderestriction)을 _활성화_ 해야 한다.
|
||||
2. 노드 오브젝트의 `node-restriction.kubernetes.io/` 접두사 아래에 레이블을 추가하고, 해당 레이블을 노드 셀렉터에서 사용한다.
|
||||
예를 들어, `example.com.node-restriction.kubernetes.io/fips=true` 또는 `example.com.node-restriction.kubernetes.io/pci-dss=true` 이다.
|
||||
|
||||
## 어피니티(affinity)와 안티-어피니티(anti-affinity)
|
||||
|
||||
`nodeSelector` 는 파드를 특정 레이블이 있는 노드로 제한하는 매우 간단한 방법을 제공한다.
|
||||
어피니티/안티-어피니티 기능은 표현할 수 있는 제약 종류를 크게 확장한다. 주요 개선 사항은 다음과 같다.
|
||||
|
||||
1. 어피니티/안티-어피니티 언어가 더 표현적이다. 언어는 논리 연산자인 AND 연산으로 작성된
|
||||
정확한 매칭 항목 이외에 더 많은 매칭 규칙을 제공한다.
|
||||
2. 규칙이 엄격한 요구 사항이 아니라 "유연한(soft)"/"선호(preference)" 규칙을 나타낼 수 있기에 스케줄러가 규칙을 만족할 수 없더라도,
|
||||
파드가 계속 스케줄 되도록 한다.
|
||||
3. 노드 자체에 레이블을 붙이기보다는 노드(또는 다른 토폴로지 도메인)에서 실행 중인 다른 파드의 레이블을 제한할 수 있다.
|
||||
이를 통해 어떤 파드가 함께 위치할 수 있는지와 없는지에 대한 규칙을 적용할 수 있다.
|
||||
|
||||
어피니티 기능은 "노드 어피니티" 와 "파드 간 어피니티/안티-어피니티" 두 종류의 어피니티로 구성된다.
|
||||
노드 어피니티는 기존 `nodeSelector` 와 비슷하지만(그러나 위에서 나열된 첫째와 두 번째 이점이 있다.),
|
||||
파드 간 어피니티/안티-어피니티는 위에서 나열된 세번째 항목에 설명된 대로
|
||||
노드 레이블이 아닌 파드 레이블에 대해 제한되고 위에서 나열된 첫 번째와 두 번째 속성을 가진다.
|
||||
|
||||
### 노드 어피니티
|
||||
|
||||
노드 어피니티는 개념적으로 `nodeSelector` 와 비슷하다 -- 이는 노드의 레이블을 기반으로 파드를
|
||||
스케줄할 수 있는 노드를 제한할 수 있다.
|
||||
|
||||
여기에 현재 `requiredDuringSchedulingIgnoredDuringExecution` 와 `preferredDuringSchedulingIgnoredDuringExecution` 로 부르는
|
||||
두 가지 종류의 노드 어피니티가 있다. 전자는 파드가 노드에 스케줄 되도록 *반드시*
|
||||
규칙을 만족해야 하는 것(`nodeSelector` 와 같으나 보다 표현적인 구문을 사용해서)을 지정하고,
|
||||
후자는 스케줄러가 시도하려고는 하지만, 보증하지 않는 *선호(preferences)* 를 지정한다는 점에서
|
||||
이를 각각 "엄격함(hard)" 과 "유연함(soft)" 으로 생각할 수 있다.
|
||||
이름의 "IgnoredDuringExecution" 부분은 `nodeSelector` 작동 방식과 유사하게 노드의
|
||||
레이블이 런타임 중에 변경되어 파드의 어피니티 규칙이 더 이상 충족되지 않으면 파드가 여전히 그 노드에서
|
||||
동작한다는 의미이다. 향후에는 파드의 노드 어피니티 요구 사항을 충족하지 않는 노드에서 파드를 제거한다는
|
||||
점을 제외하고는 `preferredDuringSchedulingIgnoredDuringExecution` 와 같은 `requiredDuringSchedulingIgnoredDuringExecution` 를 제공할 계획이다.
|
||||
|
||||
따라서 `requiredDuringSchedulingIgnoredDuringExecution` 의 예로는 "인텔 CPU가 있는 노드에서만 파드 실행"이
|
||||
될 수 있고, `preferredDuringSchedulingIgnoredDuringExecution` 의 예로는 "장애 조치 영역 XYZ에 파드 집합을 실행하려고
|
||||
하지만, 불가능하다면 다른 곳에서 일부를 실행하도록 허용"이 있을 것이다.
|
||||
|
||||
노드 어피니티는 PodSpec의 `affinity` 필드의 `nodeAffinity` 필드에서 지정된다.
|
||||
|
||||
여기에 노드 어피니티를 사용하는 파드 예시가 있다.
|
||||
|
||||
{{< codenew file="pods/pod-with-node-affinity.yaml" >}}
|
||||
|
||||
이 노드 어피니티 규칙은 키가 `kubernetes.io/e2e-az-name` 이고 값이 `e2e-az1` 또는 `e2e-az2` 인
|
||||
레이블이 있는 노드에만 파드를 배치할 수 있다고 말한다. 또한, 이 기준을 충족하는 노드들
|
||||
중에서 키가 `another-node-label-key` 이고 값이 `another-node-label-value` 인 레이블이 있는 노드를
|
||||
선호하도록 한다.
|
||||
|
||||
예시에서 연산자 `In` 이 사용되고 있는 것을 볼 수 있다. 새로운 노드 어피니티 구문은 다음의 연산자들을 지원한다. `In`, `NotIn`, `Exists`, `DoesNotExist`, `Gt`, `Lt`.
|
||||
`NotIn` 과 `DoesNotExist` 를 사용해서 안티-어피니티를 수행하거나,
|
||||
특정 노드에서 파드를 쫓아내는 [노드 테인트(taint)](/docs/concepts/configuration/taint-and-toleration/)를 설정할 수 있다.
|
||||
|
||||
`nodeSelector` 와 `nodeAffinity` 를 모두 지정한다면 파드가 후보 노드에 스케줄 되기 위해서는
|
||||
*둘 다* 반드시 만족해야 한다.
|
||||
|
||||
`nodeAffinity` 유형과 연관된 `nodeSelectorTerms` 를 지정하면, 파드는 `nodeSelectorTerms` 를 **모두** 만족하는 노드에만 스케줄할 수 있다.
|
||||
|
||||
`nodeSelectorTerms` 와 연관된 여러 `matchExpressions` 를 지정하면, 파드는 `matchExpressions` 이 지정된 것 중 **한 가지**라도 만족하는 노드에만 스케줄할 수 있다.
|
||||
|
||||
파드가 스케줄 된 노드의 레이블을 지우거나 변경해도 파드는 제거되지 않는다. 다시 말해서 어피니티 선택은 파드를 스케줄링 하는 시점에만 작동한다.
|
||||
|
||||
`preferredDuringSchedulingIgnoredDuringExecution` 의 `weight` 필드의 범위는 1-100이다. 모든 스케줄링 요구 사항 (리소스 요청, RequiredDuringScheduling 어피니티 표현식 등)을 만족하는 각 노드들에 대해 스케줄러는 이 필드의 요소들을 반복해서 합계를 계산하고 노드가 MatchExpressions 에 일치하는 경우 합계에 "가중치(weight)"를 추가한다. 이후에 이 점수는 노드에 대한 다른 우선순위 함수의 점수와 합쳐진다. 전체 점수가 가장 높은 노드를 가장 선호한다.
|
||||
|
||||
### 파드간 어피니티와 안티-어피니티
|
||||
|
||||
파드간 어피니티와 안티-어피니티를 사용하면 노드의 레이블을 기반으로 하지 않고, *노드에서 이미 실행 중인 파드 레이블을 기반으로*
|
||||
파드가 스케줄될 수 있는 노드를 제한할 수 있다. 규칙은 "X가 규칙 Y를 충족하는 하나 이상의 파드를 이미 실행중인 경우
|
||||
이 파드는 X에서 실행해야 한다(또는 안티-어피니티가 없는 경우에는 동작하면 안된다)"는 형태이다. Y는
|
||||
선택적으로 연관된 네임스페이스 목록을 가진 LabelSelector로 표현된다. 노드와는 다르게 파드는 네임스페이스이기에
|
||||
(그리고 따라서 파드의 레이블은 암암리에 네임스페이스이다) 파드 레이블위의 레이블 셀렉터는 반드시
|
||||
셀렉터가 적용될 네임스페이스를 지정해야만 한다. 개념적으로 X는 노드, 랙,
|
||||
클라우드 공급자 영역, 클라우드 공급자 지역 등과 같은 토폴로지 도메인이다. 시스템이 이런 토폴로지
|
||||
도메인을 나타내는 데 사용하는 노드 레이블 키인 `topologyKey` 를 사용하여 이를 표현한다.
|
||||
예: [넘어가기 전에: 빌트인 노드 레이블](#built-in-node-labels) 섹션 위에 나열된 레이블 키를 본다.
|
||||
|
||||
{{< note >}}
|
||||
파드간 어피니티와 안티-어피니티에는 상당한 양의 프로세싱이 필요하기에
|
||||
대규모 클러스터에서는 스케줄링 속도가 크게 느려질 수 있다.
|
||||
수백 개의 노드를 넘어가는 클러스터에서 이를 사용하는 것은 추천하지 않는다.
|
||||
{{< /note >}}
|
||||
|
||||
{{< note >}}
|
||||
파드 안티-어피니티에서는 노드에 일관된 레이블을 지정해야 한다. 즉, 클러스터의 모든 노드는 `topologyKey` 와 매칭되는 적절한 레이블을 가지고 있어야 한다. 일부 또는 모든 노드에 지정된 `topologyKey` 레이블이 없는 경우에는 의도하지 않은 동작이 발생할 수 있다.
|
||||
{{< /note >}}
|
||||
|
||||
노드 어피니티와 마찬가지로 현재 파드 어피니티와 안티-어피니티로 부르는 "엄격함" 대 "유연함"의 요구사항을 나타내는 `requiredDuringSchedulingIgnoredDuringExecution` 와
|
||||
`preferredDuringSchedulingIgnoredDuringExecution` 두 가지 종류가 있다.
|
||||
앞의 노드 어피니티 섹션의 설명을 본다.
|
||||
`requiredDuringSchedulingIgnoredDuringExecution` 어피니티의 예시는
|
||||
"서로 많은 통신을 하기 때문에 서비스 A와 서비스 B를 같은 영역에 함께 위치시키는 것"이고,
|
||||
`preferredDuringSchedulingIgnoredDuringExecution` 안티-어피니티의 예시는 "서비스를 여러 영역에 걸쳐서 분배하는 것"이다
|
||||
(엄격한 요구사항은 영역보다 파드가 더 많을 수 있기 때문에 엄격한 요구사항은 의미가 없다).
|
||||
|
||||
파드간 어피니티는 PodSpec에서 `affinity` 필드 중 `podAffinity` 필드로 지정한다.
|
||||
그리고 파드간 안티-어피니티는 PodSpec에서 `affinity` 필드 중 `podAntiAffinity` 필드로 지정한다.
|
||||
|
||||
#### 파드 어피니티를 사용하는 파드의 예시
|
||||
|
||||
{{< codenew file="pods/pod-with-pod-affinity.yaml" >}}
|
||||
|
||||
이 파드의 어피니티는 하나의 파드 어피니티 규칙과 하나의 파드 안티-어피니티 규칙을 정의한다.
|
||||
이 예시에서 `podAffinity` 는 `requiredDuringSchedulingIgnoredDuringExecution` 이고 `podAntiAffinity` 는
|
||||
`preferredDuringSchedulingIgnoredDuringExecution` 이다. 파드 어피니티 규칙에 의하면 키 "security" 와 값
|
||||
"S1"인 레이블이 있는 하나 이상의 이미 실행 중인 파드와 동일한 영역에 있는 경우에만 파드를 노드에 스케줄할 수 있다.
|
||||
(보다 정확하게는, 클러스터에 키 "security"와 값 "S1"인 레이블을 가지고 있는 실행 중인 파드가 있는 키
|
||||
`failure-domain.beta.kubernetes.io/zone` 와 값 V인 노드가 최소 하나 이상 있고, 노드 N이 키
|
||||
`failure-domain.beta.kubernetes.io/zone` 와 일부 값이 V인 레이블을 가진다면 파드는 노드 N에서 실행할 수 있다.)
|
||||
파드 안티-어피니티 규칙에 의하면 노드가 이미 키 "security"와 값 "S2"인 레이블을 가진 파드를
|
||||
실행하고 있는 파드는 노드에 스케줄되는 것을 선호하지 않는다.
|
||||
(만약 `topologyKey` 가 `failure-domain.beta.kubernetes.io/zone` 라면 노드가 키
|
||||
"security"와 값 "S2"를 레이블로 가진 파드와
|
||||
동일한 영역에 있는 경우, 노드에 파드를 예약할 수 없음을 의미한다.)
|
||||
[디자인 문서](https://git.k8s.io/community/contributors/design-proposals/scheduling/podaffinity.md)를 통해
|
||||
`requiredDuringSchedulingIgnoredDuringExecution` 와 `preferredDuringSchedulingIgnoredDuringExecution` 의
|
||||
파드 어피니티와 안티-어피니티에 대한 많은 예시를 맛볼 수 있다.
|
||||
|
||||
파드 어피니티와 안티-어피니티의 적합한 연산자는 `In`, `NotIn`, `Exists`, `DoesNotExist` 이다.
|
||||
|
||||
원칙적으로, `topologyKey` 는 적법한 어느 레이블-키도 될 수 있다.
|
||||
하지만, 성능과 보안상의 이유로 topologyKey에는 몇 가지 제약조건이 있다.
|
||||
|
||||
1. 어피니티와 `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티는 대해
|
||||
`topologyKey` 가 비어있는 것을 허용하지 않는다.
|
||||
2. `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에서 `topologyKey` 를 `kubernetes.io/hostname` 로 제한하기 위해 어드미션 컨트롤러 `LimitPodHardAntiAffinityTopology` 가 도입되었다. 사용자 지정 토폴로지를에 사용할 수 있도록 하려면, 어드미션 컨트롤러를 수정하거나 간단히 이를 비활성화 할 수 있다.
|
||||
3. `preferredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티는 `topologyKey` 가 비어있는 것을 허용하지 않는다.
|
||||
4. 위의 경우를 제외하고, `topologyKey` 는 적법한 어느 레이블-키도 가능하다.
|
||||
|
||||
`labelSelector` 와 `topologyKey` 외에도 `labelSelector` 와 일치해야 하는 네임스페이스 목록 `namespaces` 를
|
||||
선택적으로 지정할 수 있다(이것은 `labelSelector` 와 `topologyKey` 와 같은 수준의 정의이다).
|
||||
생략되어있거나 비어있을 경우 어피니티/안티-어피니티 정의가 있는 파드의 네임스페이스가 기본 값이다.
|
||||
|
||||
파드를 노드에 스케줄하려면 `requiredDuringSchedulingIgnoredDuringExecution` 어피니티와 안티-어피니티와
|
||||
연관된 `matchExpressions` 가 모두 충족되어야 한다.
|
||||
|
||||
#### 더 실용적인 유스케이스
|
||||
|
||||
파드간 어피니티와 안티-어피니티는 레플리카셋, 스테이트풀셋, 디플로이먼트 등과 같은
|
||||
상위 레벨 모음과 함께 사용할 때 더욱 유용할 수 있다. 워크로드 집합이 동일한 노드와 같이
|
||||
동일하게 정의된 토폴로지와 같은 위치에 배치되도록 쉽게 구성할 수 있다.
|
||||
|
||||
##### 항상 같은 노드에 위치시키기
|
||||
|
||||
세 개의 노드가 있는 클러스터에서 웹 애플리케이션에는 redis와 같은 인-메모리 캐시가 있다. 웹 서버가 가능한 캐시와 함께 위치하기를 원한다.
|
||||
|
||||
다음은 세 개의 레플리카와 셀렉터 레이블이 `app=store` 가 있는 간단한 redis 디플로이먼트의 yaml 스니펫이다. 디플로이먼트에는 스케줄러가 단일 노드에서 레플리카를 함께 배치하지 않도록 `PodAntiAffinity` 가 구성되어 있다.
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: redis-cache
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: store
|
||||
replicas: 3
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: store
|
||||
spec:
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- labelSelector:
|
||||
matchExpressions:
|
||||
- key: app
|
||||
operator: In
|
||||
values:
|
||||
- store
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
containers:
|
||||
- name: redis-server
|
||||
image: redis:3.2-alpine
|
||||
```
|
||||
|
||||
아래 yaml 스니펫의 웹서버 디플로이먼트는 `podAntiAffinity` 와 `podAffinity` 설정을 가지고 있다. 이렇게 하면 스케줄러에 모든 레플리카는 셀렉터 레이블이 `app=store` 인 파드와 함께 위치해야 한다. 또한 각 웹 서버 레플리카가 단일 노드의 같은 위치에 있지 않도록 한다.
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: web-server
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: web-store
|
||||
replicas: 3
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: web-store
|
||||
spec:
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- labelSelector:
|
||||
matchExpressions:
|
||||
- key: app
|
||||
operator: In
|
||||
values:
|
||||
- web-store
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
podAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- labelSelector:
|
||||
matchExpressions:
|
||||
- key: app
|
||||
operator: In
|
||||
values:
|
||||
- store
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
containers:
|
||||
- name: web-app
|
||||
image: nginx:1.16-alpine
|
||||
```
|
||||
|
||||
만약 위의 두 디플로이먼트를 생성하면 세 개의 노드가 있는 클러스터는 다음과 같아야 한다.
|
||||
|
||||
| node-1 | node-2 | node-3 |
|
||||
|:--------------------:|:-------------------:|:------------------:|
|
||||
| *webserver-1* | *webserver-2* | *webserver-3* |
|
||||
| *cache-1* | *cache-2* | *cache-3* |
|
||||
|
||||
여기서 볼 수 있듯이 `web-server` 의 세 레플리카들이 기대했던 것처럼 자동으로 캐시와 함께 위치하게 된다.
|
||||
|
||||
```
|
||||
kubectl get pods -o wide
|
||||
```
|
||||
출력은 다음과 유사할 것이다.
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE IP NODE
|
||||
redis-cache-1450370735-6dzlj 1/1 Running 0 8m 10.192.4.2 kube-node-3
|
||||
redis-cache-1450370735-j2j96 1/1 Running 0 8m 10.192.2.2 kube-node-1
|
||||
redis-cache-1450370735-z73mh 1/1 Running 0 8m 10.192.3.1 kube-node-2
|
||||
web-server-1287567482-5d4dz 1/1 Running 0 7m 10.192.2.3 kube-node-1
|
||||
web-server-1287567482-6f7v5 1/1 Running 0 7m 10.192.4.3 kube-node-3
|
||||
web-server-1287567482-s330j 1/1 Running 0 7m 10.192.3.2 kube-node-2
|
||||
```
|
||||
|
||||
##### 절대 동일한 노드에 위치시키지 않게 하기
|
||||
|
||||
위의 예시에서 `topologyKey:"kubernetes.io/hostname"` 과 함께 `PodAntiAffinity` 규칙을 사용해서
|
||||
두 개의 인스터스가 동일한 호스트에 있지 않도록 redis 클러스터를 배포한다.
|
||||
같은 기술을 사용해서 고 가용성을 위해 안티-어피니티로 구성된 스테이트풀셋의 예시는
|
||||
[ZooKeeper 튜토리얼](/ko/docs/tutorials/stateful-application/zookeeper/#노드-실패-방지)을 본다.
|
||||
|
||||
## nodeName
|
||||
|
||||
`nodeName` 은 가장 간단한 형태의 노트 선택 제약 조건이지만,
|
||||
한계로 인해 일반적으로는 사용하지 않는다.
|
||||
`nodeName` 은 PodSpec의 필드이다. 만약 비어있지 않으면, 스케줄러는
|
||||
파드를 무시하고 명명된 노드에서 실행 중인 kubelet이
|
||||
파드를 실행하려고 한다. 따라서 만약 PodSpec에 `nodeName` 가
|
||||
제공된 경우, 노드 선텍을 위해 위의 방법보다 우선한다.
|
||||
|
||||
`nodeName` 을 사용해서 노드를 선택할 때의 몇 가지 제한은 다음과 같다.
|
||||
|
||||
- 만약 명명된 노드가 없으면, 파드가 실행되지 않고
|
||||
따라서 자동으로 삭제될 수 있다.
|
||||
- 만약 명명된 노드에 파드를 수용할 수 있는
|
||||
리소스가 없는 경우 파드가 실패하고, 그 이유는 다음과 같이 표시된다.
|
||||
예: OutOfmemory 또는 OutOfcpu.
|
||||
- 클라우드 환경의 노드 이름은 항상 예측 가능하거나
|
||||
안정적인 것은 아니다.
|
||||
|
||||
여기에 `nodeName` 필드를 사용하는 파드 설정 파일 예시가 있다.
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx
|
||||
nodeName: kube-01
|
||||
```
|
||||
|
||||
위 파드는 kube-01 노드에서 실행될 것이다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
|
||||
[테인트](/docs/concepts/configuration/taint-and-toleration/)는 노드가 특정 파드들을 *쫓아내게* 할 수 있다.
|
||||
|
||||
[노드 어피니티](https://git.k8s.io/community/contributors/design-proposals/scheduling/nodeaffinity.md)와
|
||||
[파드간 어피니티/안티-어피니티](https://git.k8s.io/community/contributors/design-proposals/scheduling/podaffinity.md)에 대한 디자인 문서에는
|
||||
이러한 기능에 대한 추가 배경 정보가 있다.
|
||||
|
||||
파드가 노드에 할당되면 kubelet은 파드를 실행하고 노드의 로컬 리소스를 할당한다.
|
||||
[토폴로지 매니저](/docs/tasks/administer-cluster/topology-manager/)는
|
||||
노드 수준의 리소스 할당 결정에 참여할 수 있다.
|
||||
|
||||
{{% /capture %}}
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: 쿠버네티스 스케줄러
|
||||
content_template: templates/concept
|
||||
weight: 50
|
||||
weight: 10
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
|
|
@ -91,7 +91,7 @@ hostaliases-pod 0/1 Completed 0 6s 10.200
|
|||
`hosts` 파일 내용은 아래와 같을 것이다.
|
||||
|
||||
```shell
|
||||
kubectl logs hostaliases-pod
|
||||
kubectl exec hostaliases-pod -- cat /etc/hosts
|
||||
```
|
||||
|
||||
```none
|
||||
|
|
|
@ -171,7 +171,7 @@ DNS 정책은 파드별로 설정할 수 있다. 현재 쿠버네티스는 다
|
|||
- "`None`": 이 정책은 파드가 쿠버네티스 환경의 DNS 설정을 무시하도록 한다.
|
||||
모든 DNS 설정은 파드 스펙 내에 `dnsConfig`필드를 사용하여 제공해야 한다.
|
||||
아래 절인
|
||||
[파드의 DNS 설정](#파드의-dns-설정)
|
||||
[파드의 DNS 설정](#pod-dns-config)
|
||||
에서 자세한 내용을 확인할 수 있다.
|
||||
|
||||
{{< note >}}
|
||||
|
@ -202,7 +202,7 @@ spec:
|
|||
dnsPolicy: ClusterFirstWithHostNet
|
||||
```
|
||||
|
||||
### 파드의 DNS 설정
|
||||
### 파드의 DNS 설정 {#pod-dns-config}
|
||||
|
||||
사용자들은 파드의 DNS 설정을 통해서 직접 파드의 DNS를 세팅할 수 있다.
|
||||
|
||||
|
@ -272,4 +272,3 @@ DNS 구성 관리에 대한 지침은
|
|||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
|
|
|
@ -36,27 +36,30 @@ IPv4/IPv6 이중 스택 쿠버네티스 클러스터를 활용하려면 다음
|
|||
* 쿠버네티스 1.16 또는 이후 버전
|
||||
* 이중 스택 네트워킹을 위한 공급자의 지원(클라우드 공급자 또는 다른 방식으로 쿠버네티스 노드에 라우팅 가능한 IPv4/IPv6 네트워크 인터페이스를 제공할 수 있어야 한다.)
|
||||
* 이중 스택(예: Kubenet 또는 Calico)을 지원하는 네트워크 플러그인
|
||||
* IPVS 모드에서 구동 중인 Kube-Proxy
|
||||
|
||||
## IPv4/IPv6 이중 스택 활성화
|
||||
|
||||
IPv4/IPv6 이중 스택을 활성화 하려면, 클러스터의 관련 구성요소에 대해 `IPv6DualStack` [기능 게이트](/docs/reference/command-line-tools-reference/feature-gates/) 를 활성화 하고, 이중 스택 클러스터 네트워크 할당을 설정한다.
|
||||
|
||||
* kube-apiserver:
|
||||
* `--feature-gates="IPv6DualStack=true"`
|
||||
* kube-controller-manager:
|
||||
* `--feature-gates="IPv6DualStack=true"`
|
||||
* `--cluster-cidr=<IPv4 CIDR>,<IPv6 CIDR>` 예: `--cluster-cidr=10.244.0.0/16,fc00::/24`
|
||||
* `--cluster-cidr=<IPv4 CIDR>,<IPv6 CIDR>`
|
||||
* `--service-cluster-ip-range=<IPv4 CIDR>,<IPv6 CIDR>`
|
||||
* `--node-cidr-mask-size-ipv4|--node-cidr-mask-size-ipv6` IPv4의 기본값은 /24 이고 IPv6의 기본값은 /64이다.
|
||||
* kubelet:
|
||||
* `--feature-gates="IPv6DualStack=true"`
|
||||
* kube-proxy:
|
||||
* `--proxy-mode=ipvs`
|
||||
* `--cluster-cidr=<IPv4 CIDR>,<IPv6 CIDR>`
|
||||
* `--feature-gates="IPv6DualStack=true"`
|
||||
|
||||
{{< caution >}}
|
||||
명령줄에서 `--cluster-cidr` 를 통해 /24보다 큰 IPv6 주소 블럭을 지정하면 할당이 실패한다.
|
||||
{{< /caution >}}
|
||||
{{< note >}}
|
||||
IPv4 CIDR의 예: `10.244.0.0/16` (자신의 주소 범위를 제공하더라도)
|
||||
|
||||
IPv6 CIDR의 예: `fdXY:IJKL:MNOP:15::/64` (이 형식으로 표시되지만, 유효한 주소는 아니다 - [RFC 4193](https://tools.ietf.org/html/rfc4193)을 본다.)
|
||||
|
||||
{{< /note >}}
|
||||
|
||||
## 서비스
|
||||
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
---
|
||||
title: 엔드포인트슬라이스
|
||||
feature:
|
||||
title: 엔드포인트슬라이스
|
||||
description: >
|
||||
쿠버네티스 클러스터에서 확장 가능한 네트워크 엔드포인트 추적.
|
||||
|
||||
content_template: templates/concept
|
||||
weight: 15
|
||||
---
|
||||
|
|
|
@ -132,11 +132,11 @@ spec:
|
|||
요소별로 경로 요소에 대해 수행한다.
|
||||
모든 _p_ 가 요청 경로의 요소별 접두사가 _p_ 인 경우
|
||||
요청은 _p_ 경로에 일치한다.
|
||||
{{< note >}}
|
||||
경로의 마지막 요소가 요청 경로에 있는 마지막 요소의
|
||||
하위 문자열인 경우에는 일치하지 않는다(예시:
|
||||
`/foo/bar` 와 `/foo/bar/baz` 와 일치하지만, `/foo/barbaz` 는 일치하지 않는다).
|
||||
{{< /note >}}
|
||||
|
||||
{{< note >}}
|
||||
경로의 마지막 요소가 요청 경로에 있는 마지막 요소의 하위 문자열인 경우에는 일치하지 않는다(예시:
|
||||
`/foo/bar` 와 `/foo/bar/baz` 와 일치하지만, `/foo/barbaz` 는 일치하지 않는다).
|
||||
{{< /note >}}
|
||||
|
||||
#### 다중 일치
|
||||
경우에 따라 인그레스의 여러 경로가 요청과 일치할 수 있다.
|
||||
|
@ -400,16 +400,16 @@ metadata:
|
|||
spec:
|
||||
tls:
|
||||
- hosts:
|
||||
- sslexample.foo.com
|
||||
- sslexample.foo.com
|
||||
secretName: testsecret-tls
|
||||
rules:
|
||||
- host: sslexample.foo.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: service1
|
||||
servicePort: 80
|
||||
- host: sslexample.foo.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: service1
|
||||
servicePort: 80
|
||||
```
|
||||
|
||||
{{< note >}}
|
||||
|
|
|
@ -310,7 +310,7 @@ IPVS는 트래픽을 백엔드 파드로 밸런싱하기 위한 추가 옵션을
|
|||
- `nq`: 큐 미사용 (never queue)
|
||||
|
||||
{{< note >}}
|
||||
IPVS 모드에서 kube-proxy를 실행하려면, kube-proxy를 시작하기 전에 노드에서 IPVS Linux를
|
||||
IPVS 모드에서 kube-proxy를 실행하려면, kube-proxy를 시작하기 전에 노드에서 IPVS를
|
||||
사용 가능하도록 해야한다.
|
||||
|
||||
kube-proxy가 IPVS 프록시 모드에서 시작될 때, IPVS 커널 모듈을
|
||||
|
@ -691,6 +691,15 @@ metadata:
|
|||
[...]
|
||||
```
|
||||
{{% /tab %}}
|
||||
{{% tab name="Alibaba Cloud" %}}
|
||||
```yaml
|
||||
[...]
|
||||
metadata:
|
||||
annotations:
|
||||
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-address-type: "intranet"
|
||||
[...]
|
||||
```
|
||||
{{% /tab %}}
|
||||
{{< /tabs >}}
|
||||
|
||||
|
||||
|
@ -895,7 +904,7 @@ NLB는 특정 인스턴스 클래스에서만 작동한다. 지원되는 인스
|
|||
헬스 체크에 실패하고 트래픽을 수신하지 못하게 된다.
|
||||
|
||||
트래픽을 균일하게 하려면, DaemonSet을 사용하거나,
|
||||
[파드 안티어피니티(pod anti-affinity)](/ko/docs/concepts/configuration/assign-pod-node/#어피니티-affinity-와-안티-어피니티-anti-affinity)
|
||||
[파드 안티어피니티(pod anti-affinity)](/ko/docs/concepts/scheduling-eviction/assign-pod-node/#어피니티-affinity-와-안티-어피니티-anti-affinity)
|
||||
를 지정하여 동일한 노드에 위치하지 않도록 한다.
|
||||
|
||||
[내부 로드 밸런서](/ko/docs/concepts/services-networking/service/#internal-load-balancer) 어노테이션과 함께 NLB 서비스를
|
||||
|
|
|
@ -329,7 +329,7 @@ spec:
|
|||
가장 빠른 방법을 파드에 제공하는 데 유용하다. 반면에 파드에서 실행되는 애플리케이션은
|
||||
원시 블록 장치를 처리하는 방법을 알아야 한다.
|
||||
파드에서 `volumeMode: Block`으로 볼륨을 사용하는 방법에 대한 예는
|
||||
[원시 블록 볼륨 지원](/ko/docs/concepts/storage/persistent-volumes/#원시-블록-볼륨-지원)를 참조하십시오.
|
||||
[원시 블록 볼륨 지원](#원시-블록-볼륨-지원)를 참조하십시오.
|
||||
|
||||
### 접근 모드
|
||||
|
||||
|
|
|
@ -164,9 +164,9 @@ CSI | 1.14 (alpha), 1.16 (beta)
|
|||
퍼시스턴트볼륨은 파드의 스케줄링 제약 조건에 의해 지정된 토폴로지에
|
||||
따라 선택되거나 프로비전된다. 여기에는 [리소스
|
||||
요구 사항](/docs/concepts/configuration/manage-compute-resources-container/),
|
||||
[노드 셀렉터](/ko/docs/concepts/configuration/assign-pod-node/#노드-셀렉터-nodeselector),
|
||||
[노드 셀렉터](/ko/docs/concepts/scheduling-eviction/assign-pod-node/#노드-셀렉터-nodeselector),
|
||||
[파드 어피니티(affinity)와
|
||||
안티-어피니티(anti-affinity)](/ko/docs/concepts/configuration/assign-pod-node/#어피니티-affinity-와-안티-어피니티-anti-affinity)
|
||||
안티-어피니티(anti-affinity)](/ko/docs/concepts/scheduling-eviction/assign-pod-node/#어피니티-affinity-와-안티-어피니티-anti-affinity)
|
||||
그리고 [테인트(taint)와 톨러레이션(toleration)](/docs/concepts/configuration/taint-and-toleration/)이 포함된다.
|
||||
|
||||
다음 플러그인은 동적 프로비저닝과 `WaitForFirstConsumer` 를 지원한다.
|
||||
|
|
|
@ -243,14 +243,14 @@ spec:
|
|||
|
||||
#### CSI 마이그레이션
|
||||
|
||||
{{< feature-state for_k8s_version="v1.14" state="alpha" >}}
|
||||
{{< feature-state for_k8s_version="v1.18" state="beta" >}}
|
||||
|
||||
Cinder의 CSI 마이그레이션 기능이 활성화된 경우, 기존 트리 내 플러그인에서
|
||||
`cinder.csi.openstack.org` 컨테이너 스토리지 인터페이스(CSI)
|
||||
드라이버로 모든 플러그인 작업을 수행한다. 이 기능을 사용하려면, 클러스터에 [오픈스택 Cinder CSI
|
||||
드라이버](https://github.com/kubernetes/cloud-provider-openstack/blob/master/docs/using-cinder-csi-plugin.md)
|
||||
를 설치하고 `CSIMigration` 과 `CSIMigrationOpenStack`
|
||||
알파 기능을 활성화해야 한다.
|
||||
베타 기능을 활성화해야 한다.
|
||||
|
||||
### configMap {#configmap}
|
||||
|
||||
|
@ -300,6 +300,11 @@ ConfigMap을 [subPath](#subpath-사용하기) 볼륨 마운트로 사용하는
|
|||
업데이트를 수신하지 않는다.
|
||||
{{< /note >}}
|
||||
|
||||
{{< note >}}
|
||||
텍스트 데이터는 UTF-8 문자 인코딩을 사용하는 파일로 노출된다. 다른 문자 인코딩을 사용하려면, binaryData를 사용한다.
|
||||
{{< /note >}}
|
||||
|
||||
|
||||
### downwardAPI {#downwardapi}
|
||||
|
||||
`downwardAPI` 볼륨은 애플리케이션에서 다운워드(downward) API 데이터를 사용할 수 있도록 하는데 사용된다.
|
||||
|
|
|
@ -91,9 +91,9 @@ kubectl apply -f https://k8s.io/examples/controllers/daemonset.yaml
|
|||
### 오직 일부 노드에서만 파드 실행
|
||||
|
||||
만약 `.spec.template.spec.nodeSelector` 를 명시하면 데몬셋 컨트롤러는
|
||||
[노드 셀렉터](/ko/docs/concepts/configuration/assign-pod-node/#노드-셀렉터-nodeselector)와
|
||||
[노드 셀렉터](/ko/docs/concepts/scheduling-eviction/assign-pod-node/#노드-셀렉터-nodeselector)와
|
||||
일치하는 노드에 파드를 생성한다. 마찬가지로 `.spec.template.spec.affinity` 를 명시하면
|
||||
데몬셋 컨트롤러는 [노트 어피니티](/ko/docs/concepts/configuration/assign-pod-node/#노드-어피니티)와 일치하는 노드에 파드를 생성한다.
|
||||
데몬셋 컨트롤러는 [노트 어피니티](/ko/docs/concepts/scheduling-eviction/assign-pod-node/#노드-어피니티)와 일치하는 노드에 파드를 생성한다.
|
||||
만약 둘 중 하나를 명시하지 않으면 데몬셋 컨트롤러는 모든 노드에서 파드를 생성한다.
|
||||
|
||||
## 데몬 파드가 스케줄 되는 방법
|
||||
|
|
|
@ -51,12 +51,13 @@ _디플로이먼트_ 는 [파드](/ko/docs/concepts/workloads/pods/pod/)와
|
|||
이 사례에서는 간단하게 파드 템플릿에 정의된 레이블(`app: nginx`)을 선택한다.
|
||||
그러나 파드 템플릿 자체의 규칙이 만족되는 한,
|
||||
보다 정교한 선택 규칙의 적용이 가능하다.
|
||||
{{< note >}}
|
||||
`.spec.selector.matchLabels` 필드는 {key,value}의 쌍으로 매핑되어있다. `matchLabels` 에 매핑된
|
||||
단일 {key,value}은 `matchExpressions` 의 요소에 해당하며, 키 필드는 "key"에 그리고 연산자는 "In"에 대응되며
|
||||
값 배열은 "value"만 포함한다.
|
||||
매칭을 위해서는 `matchLabels` 와 `matchExpressions` 의 모든 요건이 충족되어야 한다.
|
||||
{{< /note >}}
|
||||
|
||||
{{< note >}}
|
||||
`.spec.selector.matchLabels` 필드는 {key,value}의 쌍으로 매핑되어있다. `matchLabels` 에 매핑된
|
||||
단일 {key,value}은 `matchExpressions` 의 요소에 해당하며, 키 필드는 "key"에 그리고 연산자는 "In"에 대응되며
|
||||
값 배열은 "value"만 포함한다.
|
||||
매칭을 위해서는 `matchLabels` 와 `matchExpressions` 의 모든 요건이 충족되어야 한다.
|
||||
{{< /note >}}
|
||||
|
||||
* `template` 필드에는 다음 하위 필드가 포함되어있다.
|
||||
* 파드는 `.metadata.labels` 필드를 사용해서 `app: nginx` 라는 레이블을 붙인다.
|
||||
|
@ -65,86 +66,95 @@ _디플로이먼트_ 는 [파드](/ko/docs/concepts/workloads/pods/pod/)와
|
|||
`nginx` 컨테이너 1개를 실행하는 것을 나타낸다.
|
||||
* 컨테이너 1개를 생성하고, `.spec.template.spec.containers[0].name` 필드를 사용해서 `nginx` 이름을 붙인다.
|
||||
|
||||
위의 디플로이먼트를 생성하려면 다음 단계를 따른다.
|
||||
시작하기 전에, 쿠버네티스 클러스터가 시작되고 실행 중인지 확인한다.
|
||||
위의 디플로이먼트를 생성하려면 다음 단계를 따른다.
|
||||
|
||||
시작하기 전에, 쿠버네티스 클러스터가 시작되고 실행 중인지 확인한다.
|
||||
|
||||
1. 다음 명령어를 실행해서 디플로이먼트를 생성한다.
|
||||
1. 다음 명령어를 실행해서 디플로이먼트를 생성한다.
|
||||
|
||||
{{< note >}}
|
||||
`--record` 플래그를 지정해서 실행된 명령을 `kubernetes.io/change-cause` 리소스 어노테이션에 작성할 수 있다. 이것은 향후 인트로스펙션(introspection)에 유용하다.
|
||||
예를 들면, 디플로이먼트의 각 수정 버전에서 실행된 명령을 볼 수 있다.
|
||||
{{< /note >}}
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml
|
||||
```
|
||||
|
||||
2. `kubectl get deployments` 을 실행해서 디플로이먼트가 생성되었는지 확인한다. 만약 디플로이먼트가 여전히 생성중이면 다음과 유사하게 출력된다.
|
||||
```shell
|
||||
NAME READY UP-TO-DATE AVAILABLE AGE
|
||||
nginx-deployment 0/3 0 0 1s
|
||||
```
|
||||
클러스터에서 디플로이먼트를 점검할 때 다음 필드가 표시된다.
|
||||
|
||||
* `NAME` 은 네임스페이스에 있는 디플로이먼트 이름의 목록이다.
|
||||
* `READY` 는 사용자가 사용할 수 있는 애플리케이션의 레플리카의 수를 표시한다. ready/desired 패턴을 따른다.
|
||||
* `UP-TO-DATE` 는 의도한 상태를 얻기위해 업데이트 된 레플리카의 수를 표시한다.
|
||||
* `AVAILABLE` 은 사용자가 사용 가능한 애플리케이션 레플리카의 수를 표시한다.
|
||||
* `AGE` 는 애플리케이션의 실행 된 시간을 표시한다.
|
||||
|
||||
`.spec.replicas` 필드에 따라 의도한 레플리카의 수가 3개인지 알 수 있다.
|
||||
|
||||
3. 디플로이먼트의 롤아웃 상태를 보려면 `kubectl rollout status deployment.v1.apps/nginx-deployment` 를 실행한다. 다음과 유사하게 출력된다.
|
||||
```shell
|
||||
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
|
||||
deployment.apps/nginx-deployment successfully rolled out
|
||||
```
|
||||
|
||||
4. 몇 초 후 `kubectl get deployments` 를 다시 실행한다. 다음과 유사하게 출력된다.
|
||||
```shell
|
||||
NAME READY UP-TO-DATE AVAILABLE AGE
|
||||
nginx-deployment 3/3 3 3 18s
|
||||
```
|
||||
디플로이먼트에서 3개의 레플리카가 생성되었고, 모든 레플리카는 최신 상태(최신 파드 템플릿을 포함)이며 사용 가능한 것을 알 수 있다.
|
||||
|
||||
5. 디플로이먼트로 생성된 레플리카셋(`rs`)을 보려면 `kubectl get rs` 를 실행한다. 다음과 유사하게 출력된다.
|
||||
```shell
|
||||
NAME DESIRED CURRENT READY AGE
|
||||
nginx-deployment-75675f5897 3 3 3 18s
|
||||
```
|
||||
레플리카셋의 출력에는 다음 필드가 표시된다.
|
||||
|
||||
* `NAME` 은 네임스페이스에 있는 레플리카셋 이름의 목록이다.
|
||||
* `DESIRED` 는 디플로이먼트의 생성 시 정의된 의도한 애플리케이션 _레플리카_ 의 수를 표시한다. 이것이 _의도한 상태_ 이다.
|
||||
* `CURRENT` 는 현재 실행 중인 레플리카의 수를 표시한다.
|
||||
* `READY` 는 사용자가 사용할 수 있는 애플리케이션의 레플리카의 수를 표시한다.
|
||||
* `AGE` 는 애플리케이션의 실행된 시간을 표시한다.
|
||||
|
||||
레플리카셋의 이름은 항상 `[DEPLOYMENT-NAME]-[RANDOM-STRING]` 형식으로 된 것을 알 수 있다. 무작위 문자열은
|
||||
무작위로 생성되며, `pod-template-hash` 를 시드(seed)로 사용한다.
|
||||
|
||||
6. 각 파드에 자동으로 생성된 레이블을 보려면 `kubectl get pods --show-labels` 를 실행한다. 다음과 유사하게 출력된다.
|
||||
```shell
|
||||
NAME READY STATUS RESTARTS AGE LABELS
|
||||
nginx-deployment-75675f5897-7ci7o 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453
|
||||
nginx-deployment-75675f5897-kzszj 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453
|
||||
nginx-deployment-75675f5897-qqcnn 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453
|
||||
```
|
||||
만들어진 레플리카셋은 3개의 `nginx` 파드가 있는 것을 보장한다.
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml
|
||||
```
|
||||
|
||||
{{< note >}}
|
||||
디플로이먼트에는 파드 템플릿 레이블과 적절한 셀렉터를 반드시 명시해야 한다(이 예시에서는 `app: nginx`).
|
||||
레이블 또는 셀렉터는 다른 컨트롤러(다른 디플로이먼트와 스테이트풀 셋 포함)와 겹치지 않아야 한다. 쿠버네티스는 겹치는 것을 막지 않으며, 만약 다중 컨트롤러가 겹치는 셀렉터를 가지는 경우 해당 컨트롤러의 충돌 또는 예기치 않은 동작을 야기할 수 있다.
|
||||
`--record` 플래그를 지정해서 실행된 명령을 `kubernetes.io/change-cause` 리소스 어노테이션에 작성할 수 있다.
|
||||
기록된 변경사항은 향후 인트로스펙션(introspection)에 유용하다. 예를 들면, 디플로이먼트의 각 수정 버전에서 실행된 명령을 볼 수 있다.
|
||||
{{< /note >}}
|
||||
|
||||
|
||||
2. `kubectl get deployments` 을 실행해서 디플로이먼트가 생성되었는지 확인한다.
|
||||
|
||||
만약 디플로이먼트가 여전히 생성 중이면, 다음과 유사하게 출력된다.
|
||||
```shell
|
||||
NAME READY UP-TO-DATE AVAILABLE AGE
|
||||
nginx-deployment 0/3 0 0 1s
|
||||
```
|
||||
클러스터에서 디플로이먼트를 점검할 때, 다음 필드가 표시된다.
|
||||
* `NAME` 은 네임스페이스에 있는 디플로이먼트 이름의 목록이다.
|
||||
* `READY` 는 사용자가 사용할 수 있는 애플리케이션의 레플리카의 수를 표시한다. ready/desired 패턴을 따른다.
|
||||
* `UP-TO-DATE` 는 의도한 상태를 얻기 위해 업데이트된 레플리카의 수를 표시한다.
|
||||
* `AVAILABLE` 은 사용자가 사용할 수 있는 애플리케이션 레플리카의 수를 표시한다.
|
||||
* `AGE` 는 애플리케이션의 실행된 시간을 표시한다.
|
||||
|
||||
`.spec.replicas` 필드에 따라 의도한 레플리카의 수가 3개인지 알 수 있다.
|
||||
|
||||
3. 디플로이먼트의 롤아웃 상태를 보려면, `kubectl rollout status deployment.v1.apps/nginx-deployment` 를 실행한다.
|
||||
|
||||
다음과 유사하게 출력된다.
|
||||
```shell
|
||||
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
|
||||
deployment.apps/nginx-deployment successfully rolled out
|
||||
```
|
||||
|
||||
4. 몇 초 후 `kubectl get deployments` 를 다시 실행한다.
|
||||
다음과 유사하게 출력된다.
|
||||
```shell
|
||||
NAME READY UP-TO-DATE AVAILABLE AGE
|
||||
nginx-deployment 3/3 3 3 18s
|
||||
```
|
||||
디플로이먼트에서 3개의 레플리카가 생성되었고, 모든 레플리카는 최신 상태(최신 파드 템플릿을 포함)이며 사용 가능한 것을 알 수 있다.
|
||||
|
||||
5. 디플로이먼트로 생성된 레플리카셋(`rs`)을 보려면, `kubectl get rs` 를 실행한다. 다음과 유사하게 출력된다.
|
||||
```shell
|
||||
NAME DESIRED CURRENT READY AGE
|
||||
nginx-deployment-75675f5897 3 3 3 18s
|
||||
```
|
||||
레플리카셋의 출력에는 다음 필드가 표시된다.
|
||||
|
||||
* `NAME` 은 네임스페이스에 있는 레플리카셋 이름의 목록이다.
|
||||
* `DESIRED` 는 디플로이먼트의 생성 시 정의된 의도한 애플리케이션 _레플리카_ 의 수를 표시한다. 이것이 _의도한 상태_ 이다.
|
||||
* `CURRENT` 는 현재 실행 중인 레플리카의 수를 표시한다.
|
||||
* `READY` 는 사용자가 사용할 수 있는 애플리케이션의 레플리카의 수를 표시한다.
|
||||
* `AGE` 는 애플리케이션의 실행된 시간을 표시한다.
|
||||
|
||||
레플리카셋의 이름은 항상 `[DEPLOYMENT-NAME]-[RANDOM-STRING]` 형식으로 된 것을 알 수 있다. 무작위 문자열은
|
||||
무작위로 생성되며, `pod-template-hash` 를 시드(seed)로 사용한다.
|
||||
|
||||
6. 각 파드에 자동으로 생성된 레이블을 보려면, `kubectl get pods --show-labels` 를 실행한다.
|
||||
다음과 유사하게 출력된다.
|
||||
```shell
|
||||
NAME READY STATUS RESTARTS AGE LABELS
|
||||
nginx-deployment-75675f5897-7ci7o 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453
|
||||
nginx-deployment-75675f5897-kzszj 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453
|
||||
nginx-deployment-75675f5897-qqcnn 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453
|
||||
```
|
||||
만들어진 레플리카셋은 실행 중인 3개의 `nginx` 파드를 보장한다.
|
||||
|
||||
{{< note >}}
|
||||
디플로이먼트에는 파드 템플릿 레이블과 적절한 셀렉터를 반드시 명시해야 한다
|
||||
(이 예시에서는 `app: nginx`).
|
||||
|
||||
레이블 또는 셀렉터는 다른 컨트롤러(다른 디플로이먼트와 스테이트풀 셋 포함)와 겹치지 않아야 한다. 쿠버네티스는 겹치는 것을 막지 않으며, 만약 다중 컨트롤러가 겹치는 셀렉터를 가지는 경우 해당 컨트롤러의 충돌 또는 예기치 않은 동작을 야기할 수 있다.
|
||||
{{< /note >}}
|
||||
|
||||
### Pod-template-hash 레이블
|
||||
|
||||
{{< note >}}
|
||||
{{< caution >}}
|
||||
이 레이블은 변경하면 안 된다.
|
||||
{{< /note >}}
|
||||
{{< /caution >}}
|
||||
|
||||
`pod-template-hash` 레이블은 디플로이먼트 컨트롤러에 의해서 디플로이먼트가 생성 또는 채택한 모든 레플리케셋에 추가된다.
|
||||
`pod-template-hash` 레이블은 디플로이먼트 컨트롤러에 의해서 디플로이먼트가 생성 또는 채택한 모든 레플리카셋에 추가된다.
|
||||
|
||||
이 레이블은 디플로이먼트의 자식 레플리카셋이 겹치지 않도록 보장한다. 레플리카셋의 `PodTemplate` 을 해싱하고, 해시 결과를 레플리카셋 셀렉터,
|
||||
파드 템플릿 레이블 및 레플리카셋 이 가질 수 있는 기존의 모든 파드에 레이블 값으로 추가해서 사용하도록 생성한다.
|
||||
|
@ -407,9 +417,7 @@ API 버전 `apps/v1` 에서 디플로이먼트의 레이블 셀렉터는 생성
|
|||
```
|
||||
|
||||
{{< note >}}
|
||||
디플로이먼트 컨트롤러가 잘못된 롤아웃을 자동으로 중지하고, 새로운 레플리카셋의 스케일 업을 중지한다.
|
||||
이는 지정한 롤링 업데이트의 파라미터(구체적으로 `maxUnavailable`)에 따라 달라진다.
|
||||
쿠버네티스는 기본값으로 25%를 설정한다.
|
||||
디플로이먼트 컨트롤러가 잘못된 롤아웃을 자동으로 중지하고, 새로운 레플리카셋의 스케일 업을 중지한다. 이는 지정한 롤링 업데이트의 파라미터(구체적으로 `maxUnavailable`)에 따라 달라진다. 쿠버네티스는 기본값으로 25%를 설정한다.
|
||||
{{< /note >}}
|
||||
|
||||
* 디플로이먼트에 대한 설명 보기
|
||||
|
@ -1080,6 +1088,15 @@ API 버전 `apps/v1` 에서는 `.spec.selector` 와 `.metadata.labels` 이 설
|
|||
|
||||
기존의 모든 파드는 `.spec.strategy.type==Recreate` 이면 새 파드가 생성되기 전에 죽는다.
|
||||
|
||||
{{< note >}}
|
||||
이렇게 하면 업그레이드를 생성하기 전에 파드 종료를 보장할 수 있다. 디플로이먼트를 업그레이드하면,
|
||||
이전 버전의 모든 파드가 즉시 종료된다. 신규 버전의 파드가 생성되기 전에 성공적으로 제거가
|
||||
완료되기를 대기한다. 파드를 수동으로 삭제하면, 라이프사이클은 레플리카셋에 의해
|
||||
제어되며(이전 파드가 여전히 종료 상태에 있는 경우에도) 교체용 파드가 즉시 생성된다. 파드에
|
||||
대해 "최대" 보장이 필요한 경우
|
||||
[스테이트풀셋](/ko/docs/concepts/workloads/controllers/statefulset/)의 사용을 고려해야 한다.
|
||||
{{< /note >}}
|
||||
|
||||
#### 디플로이먼트 롤링 업데이트
|
||||
|
||||
디플로이먼트는 `.spec.strategy.type==RollingUpdate` 이면 파드를 롤링 업데이트
|
||||
|
@ -1114,7 +1131,7 @@ API 버전 `apps/v1` 에서는 `.spec.selector` 와 `.metadata.labels` 이 설
|
|||
`.spec.progressDeadlineSeconds` 는 디플로어먼트가 표면적으로 `Type=Progressing`, `Status=False`의
|
||||
상태 그리고 리소스가 `Reason=ProgressDeadlineExceeded` 상태로 [진행 실패](#디플로이먼트-실패)를 보고하기 전에
|
||||
디플로이먼트가 진행되는 것을 대기시키는 시간(초)를 명시하는 선택적 필드이다.
|
||||
디플로이먼트 컨트롤러는 디플로이먼트를 계속 재시도 한다.
|
||||
디플로이먼트 컨트롤러는 디플로이먼트를 계속 재시도 한다. 기본값은 600(초)이다.
|
||||
미래에 자동화된 롤백이 구현된다면 디플로이먼트 컨트롤러는 상태를 관찰하고,
|
||||
그 즉시 디플로이먼트를 롤백할 것이다.
|
||||
|
||||
|
|
|
@ -326,7 +326,7 @@ kubectl apply -f https://k8s.io/examples/controllers/hpa-rs.yaml
|
|||
(그리고 더 쉽다!)
|
||||
|
||||
```shell
|
||||
kubectl autoscale rs frontend --max=10
|
||||
kubectl autoscale rs frontend --max=10 --min=3 --cpu-percent=50
|
||||
```
|
||||
|
||||
## 레플리카셋의 대안
|
||||
|
|
|
@ -83,6 +83,8 @@ weight: 60
|
|||
|
||||
## Disruption Budgets의 작동 방식
|
||||
|
||||
{{< feature-state for_k8s_version="v1.5" state="beta" >}}
|
||||
|
||||
애플리케이션 소유자는 각 애플리케이션에 대해 `PodDisruptionBudget` 오브젝트(PDB)를 만들 수 있다.
|
||||
PDB는 자발적 중단으로 일시에 중지되는 복제된 애플리케이션 파드의 수를 제한한다.
|
||||
예를 들어 정족수 기반의 애플리케이션이
|
||||
|
@ -192,7 +194,7 @@ drain 커멘드는 `pod-b`를 축출하는데 성공했다.
|
|||
|
||||
| node-1 *drained* | node-2 | node-3 | *no node* |
|
||||
|:--------------------:|:-------------------:|:------------------:|:------------------:|
|
||||
| | pod-b *available* | pod-c *available* | pod-e *pending* |
|
||||
| | pod-b *terminating* | pod-c *available* | pod-e *pending* |
|
||||
| | pod-d *available* | pod-y | |
|
||||
|
||||
이 시점에서 클러스터 관리자는
|
||||
|
|
|
@ -44,8 +44,8 @@ weight: 40
|
|||
그러나, 초기화 컨테이너를 위한 리소스 요청량과 상한은
|
||||
[리소스](#리소스)에 문서화된 것처럼 다르게 처리된다.
|
||||
|
||||
또한, 초기화 컨테이너는 준비성 프로브(readiness probe)를 지원하지 않는다. 왜냐하면 초기화 컨테이너는
|
||||
파드가 준비 상태가 되기 전에 완료를 목표로 실행되어야 하기 때문이다.
|
||||
또한, 초기화 컨테이너는 `lifecycle`, `livenessProbe`, `readinessProbe` 또는 `startupProbe` 를 지원하지 않는다.
|
||||
왜냐하면 초기화 컨테이너는 파드가 준비 상태가 되기 전에 완료를 목표로 실행되어야 하기 때문이다.
|
||||
|
||||
만약 다수의 초기화 컨테이너가 파드에 지정되어 있다면, Kubelet은 해당 초기화 컨테이너들을
|
||||
한 번에 하나씩 실행한다. 각 초기화 컨테이너는 다음 컨테이너를 실행하기 전에 꼭 성공해야 한다.
|
||||
|
@ -239,7 +239,7 @@ myapp-pod 1/1 Running 0 9m
|
|||
```
|
||||
|
||||
이 간단한 예제는 사용자만의 초기화 컨테이너를 생성하는데
|
||||
영감을 줄 것이다. [다음 순서](#what-s-next)에는 더 자세한 예제의 링크가 있다.
|
||||
영감을 줄 것이다. [다음 순서](#다음-내용)에는 더 자세한 예제의 링크가 있다.
|
||||
|
||||
## 자세한 동작
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ node4 Ready <none> 2m43s v1.16.0 node=node4,zone=zoneB
|
|||
|
||||
`pod.spec.topologySpreadConstraints` 필드는 1.16에서 다음과 같이 도입되었다.
|
||||
|
||||
```yaml
|
||||
```
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
|
@ -97,7 +97,7 @@ spec:
|
|||
|
||||
{{< codenew file="pods/topology-spread-constraints/one-constraint.yaml" >}}
|
||||
|
||||
`topologyKey: zone` 는 "zone:<any value>" 레이블 쌍을 가지는 노드에 대해서만 균등한 분배를 적용하는 것을 의미한다. `whenUnsatisfiable: DoNotSchedule` 은 만약 들어오는 파드가 제약 조건을 만족시키지 못하면 스케줄러에게 pending 상태를 유지하도록 지시한다.
|
||||
`topologyKey: zone` 는 "zone:<any value>" 레이블 쌍을 가지는 노드에 대해서만 균등한 분배를 적용하는 것을 의미한다. `whenUnsatisfiable: DoNotSchedule` 은 만약 들어오는 파드가 제약 조건을 만족시키지 못하면 스케줄러에게 pending 상태를 유지하도록 지시한다.
|
||||
|
||||
만약 스케줄러가 이 신규 파드를 "zoneA"에 배치하면 파드 분포는 [3, 1]이 되며, 따라서 실제 차이(skew)는 2 (3 - 1)가 되어 `maxSkew: 1` 를 위반하게 된다. 이 예시에서는 들어오는 파드는 오직 "zoneB"에만 배치할 수 있다.
|
||||
|
||||
|
|
|
@ -5,7 +5,9 @@ weight: 50
|
|||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
이 페이지는 파드 프리셋에 대한 개요를 제공한다. 파드 프리셋은 파드 생성 시간에 파드에
|
||||
{{< feature-state for_k8s_version="v1.6" state="alpha" >}}
|
||||
|
||||
이 페이지는 파드프리셋(PodPreset)에 대한 개요를 제공한다. 파드프리셋은 파드 생성 시간에 파드에
|
||||
특정 정보를 주입하기 위한 오브젝트이다. 해당 정보에는
|
||||
시크릿, 볼륨, 볼륨 마운트, 환경 변수가 포함될 수 있다.
|
||||
{{% /capture %}}
|
||||
|
@ -14,16 +16,33 @@ weight: 50
|
|||
{{% capture body %}}
|
||||
## 파드 프리셋 이해하기
|
||||
|
||||
`Pod Preset`은 파드 생성 시간에 파드에 추가적인 런타임 요구사항을
|
||||
파드프리셋은 파드 생성 시간에 파드에 추가적인 런타임 요구사항을
|
||||
주입하기 위한 API 리소스이다.
|
||||
주어진 파드 프리셋이 적용되도록 파드에 명시하기 위해서는
|
||||
주어진 파드프리셋이 적용되도록 파드에 명시하기 위해서는
|
||||
[레이블 셀렉터](/ko/docs/concepts/overview/working-with-objects/labels/#레이블-셀렉터)를 사용한다.
|
||||
|
||||
파드 프리셋을 사용하는 것은 파드 템플릿 작성자에게 모든 파드를 위한 모든 정보를 명시적으로
|
||||
파드프리셋을 사용하는 것은 파드 템플릿 작성자에게 모든 파드를 위한 모든 정보를 명시적으로
|
||||
제공하지는 않아도 되도록 한다. 이렇게 하면, 어떤 특정 서비스를 사용할 파드의 파드
|
||||
템플릿 작성자는 해당 서비스에 대한 모든 세부 사항을 알 필요가 없다.
|
||||
|
||||
그 배경에 대한 자세한 정보를 위해서는, [파드 프리셋을 위한 디자인 제안](https://git.k8s.io/community/contributors/design-proposals/service-catalog/pod-preset.md)을 참고한다.
|
||||
## 클러스터에서 파드프리셋 활성화하기 {#enable-pod-preset}
|
||||
|
||||
클러스터에서 파드 프리셋을 사용하기 위해서는 다음 사항이 반드시 이행되어야 한다.
|
||||
|
||||
1. API 타입 `settings.k8s.io/v1alpha1/podpreset`을 활성화하였다.
|
||||
예를 들면, 이것은 API 서버의 `--runtime-config` 옵션에 `settings.k8s.io/v1alpha1=true`을 포함하여 완료할 수 있다.
|
||||
minikube에서는 클러스터가 시작할 때
|
||||
`--extra-config=apiserver.runtime-config=settings.k8s.io/v1alpha1=true`
|
||||
플래그를 추가한다.
|
||||
1. 어드미션 컨트롤러 `PodPreset`을 활성화하였다. 이것을 이루는 방법 중 하나는
|
||||
API 서버를 위해서 명시된 `--enable-admission-plugins` 옵션에 `PodPreset`을 포함하는 것이다.
|
||||
minikube에서는 클러스터가 시작할 때
|
||||
|
||||
```shell
|
||||
--extra-config=apiserver.enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota,PodPreset
|
||||
```
|
||||
|
||||
플래그를 추가한다.
|
||||
|
||||
## 어떻게 동작하는가
|
||||
|
||||
|
@ -60,31 +79,12 @@ weight: 50
|
|||
있을 것이다. 이 경우에는, 다음과 같은 양식으로 어노테이션을 파드 스펙에
|
||||
추가한다. `podpreset.admission.kubernetes.io/exclude: "true"`.
|
||||
|
||||
## 파드 프리셋 활성화하기
|
||||
|
||||
클러스터에서 파드 프리셋을 사용하기 위해서는 다음 사항이 반드시 이행되어야 한다.
|
||||
|
||||
1. API 타입 `settings.k8s.io/v1alpha1/podpreset`을 활성화하였다.
|
||||
예를 들면, 이것은 API 서버의 `--runtime-config` 옵션에 `settings.k8s.io/v1alpha1=true`을 포함하여 완료할 수 있다.
|
||||
minikube에서는 클러스터가 시작할 때
|
||||
`--extra-config=apiserver.runtime-config=settings.k8s.io/v1alpha1=true`
|
||||
플래그를 추가한다.
|
||||
1. 어드미션 컨트롤러 `PodPreset`을 활성화하였다. 이것을 이루는 방법 중 하나는
|
||||
API 서버를 위해서 명시된 `--enable-admission-plugins` 옵션에 `PodPreset`을 포함하는 것이다.
|
||||
minikube에서는 클러스터가 시작할 때
|
||||
|
||||
```shell
|
||||
--extra-config=apiserver.enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota,PodPreset
|
||||
```
|
||||
|
||||
플래그를 추가한다.
|
||||
1. 사용할 네임스페이스 안에서 `PodPreset` 오브젝트를 생성하여
|
||||
파드 프리셋을 정의하였다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
|
||||
* [파드 프리셋을 사용하여 파드에 데이터 주입하기](/docs/tasks/inject-data-application/podpreset/)
|
||||
[파드프리셋을 사용하여 파드에 데이터 주입하기](/docs/tasks/inject-data-application/podpreset/)를 본다.
|
||||
|
||||
배경에 대한 자세한 정보를 위해서는, [파드프리셋을 위한 디자인 제안](https://git.k8s.io/community/contributors/design-proposals/service-catalog/pod-preset.md)을 본다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
|
|
@ -0,0 +1,248 @@
|
|||
---
|
||||
title: 고급 기여
|
||||
slug: advanced
|
||||
content_template: templates/concept
|
||||
weight: 98
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
이 페이지에서는 당신이
|
||||
[새로운 콘텐츠에 기여](/ko/docs/contribute/new-content/overview)하고
|
||||
[다른 사람의 작업을 리뷰](/ko/docs/contribute/review/reviewing-prs/)하는 방법을
|
||||
이해한다고 가정한다. 또한 기여하기 위한 더 많은 방법에 대해 배울 준비가 되었다고 가정한다. 이러한
|
||||
작업 중 일부에는 Git 커맨드 라인 클라이언트와 다른 도구를 사용해야 한다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
## 일주일 동안 PR 랭글러(Wrangler) 되기
|
||||
|
||||
SIG Docs [승인자](/ko/docs/contribute/participating/#승인자)는 리포지터리에 대해 1주일 정도씩 [PR을 조정(wrangling)](https://github.com/kubernetes/website/wiki/PR-Wranglers)하는 역할을 맡는다.
|
||||
|
||||
PR 랭글러의 임무는 다음과 같다.
|
||||
|
||||
- [스타일](/docs/contribute/style/style-guide/)과 [콘텐츠](/docs/contribute/style/content-guide/) 가이드를 준수하는지에 대해 [열린(open) 풀 리퀘스트](https://github.com/kubernetes/website/pulls)를 매일 리뷰한다.
|
||||
- 가장 작은 PR(`size/XS`)을 먼저 리뷰한 다음, 가장 큰(`size/XXL`) PR까지 옮겨가며 리뷰를 반복한다.
|
||||
- 가능한 한 많은 PR을 리뷰한다.
|
||||
- 각 기여자가 CLA에 서명했는지 확인한다.
|
||||
- 새로운 기여자가 [CLA](https://github.com/kubernetes/community/blob/master/CLA.md)에 서명하도록 도와준다.
|
||||
- CLA에 서명하지 않은 기여자에게 CLA에 서명하도록 자동으로 알리려면 [이](https://github.com/zparnold/k8s-docs-pr-botherer) 스크립트를 사용한다.
|
||||
- 제안된 변경 사항에 대한 피드백을 제공하고 다른 SIG의 멤버로부터의 기술 리뷰가 잘 진행되게 조율한다.
|
||||
- 제안된 콘텐츠 변경에 대해 PR에 인라인 제안(inline suggestion)을 제공한다.
|
||||
- 내용을 확인해야 하는 경우, PR에 코멘트를 달고 자세한 내용을 요청한다.
|
||||
- 관련 `sig/` 레이블을 할당한다.
|
||||
- 필요한 경우, 파일의 머리말(front matter)에 있는 `reviewers:` 블록의 리뷰어를 할당한다.
|
||||
- PR의 리뷰 상태를 표시하기 위해 `Docs Review` 와 `Tech Review` 레이블을 할당한다.
|
||||
- 아직 리뷰되지 않은 PR에 `Needs Doc Review` 나 `Needs Tech Review` 를 할당한다.
|
||||
- 리뷰가 진행되었고, 병합하기 전에 추가 입력이나 조치가 필요한 PR에 `Doc Review: Open Issues` 나 `Tech Review: Open Issues` 를 할당한다.
|
||||
- 병합할 수 있는 PR에 `/lgtm` 과 `/approve` 를 할당한다.
|
||||
- PR이 준비가 되면 병합하거나, 수락해서는 안되는 PR을 닫는다.
|
||||
- 새로운 이슈를 매일 심사하고 태그를 지정한다. SIG Docs가 메타데이터를 사용하는 방법에 대한 지침은 [이슈 심사 및 분류](/ko/docs/contribute/review/for-approvers/#이슈-심사와-분류)를 참고한다.
|
||||
|
||||
## 랭글러에게 유용한 GitHub 쿼리
|
||||
|
||||
다음의 쿼리는 랭글러에게 도움이 된다. 이 쿼리들을 수행하여 작업한 후에는, 리뷰할 나머지 PR 목록은
|
||||
일반적으로 작다. 이 쿼리들은 특히 현지화 PR을 제외하고, `master` 브랜치만 포함한다(마지막 쿼리는 제외).
|
||||
|
||||
- [CLA 서명 없음, 병합할 수 없음](https://github.com/kubernetes/website/pulls?q=is%3Aopen+is%3Apr+label%3A%22cncf-cla%3A+no%22+-label%3Ado-not-merge+label%3Alanguage%2Fen):
|
||||
CLA에 서명하도록 기여자에게 상기시킨다. 봇과 사람이 이미 알렸다면, PR을 닫고
|
||||
CLA에 서명한 후 PR을 열 수 있음을 알린다.
|
||||
**작성자가 CLA에 서명하지 않은 PR은 리뷰하지 않는다!**
|
||||
- [LGTM 필요](https://github.com/kubernetes/website/pulls?utf8=%E2%9C%93&q=is%3Aopen+is%3Apr+-label%3Ado-not-merge+label%3Alanguage%2Fen+-label%3Algtm+):
|
||||
기술 리뷰가 필요한 경우, 봇이 제안한 리뷰어 중 한 명을 지정한다. 문서 리뷰나
|
||||
교정이 필요한 경우, 변경 사항을 제안하거나 교정하는 커밋을 PR에 추가하여 진행한다.
|
||||
- [LGTM 보유, 문서 승인 필요](https://github.com/kubernetes/website/pulls?q=is%3Aopen+is%3Apr+-label%3Ado-not-merge+label%3Alanguage%2Fen+label%3Algtm):
|
||||
PR을 병합하기 위해 추가 변경이나 업데이트가 필요한지 여부를 결정한다. PR을 병합할 준비가 되었다고 생각되면, `/approve` 코멘트를 남긴다.
|
||||
- [퀵윈(Quick Wins)](https://github.com/kubernetes/website/pulls?utf8=%E2%9C%93&q=is%3Apr+is%3Aopen+base%3Amaster+-label%3A%22do-not-merge%2Fwork-in-progress%22+-label%3A%22do-not-merge%2Fhold%22+label%3A%22cncf-cla%3A+yes%22+label%3A%22size%2FXS%22+label%3A%22language%2Fen%22+): 명확한 결격 사유가 없는 master에 대한 작은 PR인 경우. ([XS, S, M, L, XL, XXL] 크기의 PR을 작업할 때 크기 레이블에서 "XS"를 변경한다)
|
||||
- [master 이외의 브랜치에 대한 PR](https://github.com/kubernetes/website/pulls?utf8=%E2%9C%93&q=is%3Aopen+is%3Apr+-label%3Ado-not-merge+label%3Alanguage%2Fen+-base%3Amaster): `dev-` 브랜치에 대한 것일 경우, 곧 출시될 예정인 릴리스이다. `/assign @<meister's_github-username>` 을 코멘트로 추가하여 [릴리스 마이스터](https://github.com/kubernetes/sig-release/tree/master/release-team)가 그것에 대해 알고 있는지 확인한다. 오래된 브랜치에 대한 PR인 경우, PR 작성자가 가장 적합한 브랜치를 대상으로 하고 있는지 여부를 파악할 수 있도록 도와준다.
|
||||
|
||||
### 풀 리퀘스트를 종료하는 시기
|
||||
|
||||
리뷰와 승인은 PR 대기열을 최신 상태로 유지하는 도구 중 하나이다. 또 다른 도구는 종료(closure)이다.
|
||||
|
||||
- CLA가 2주 동안 서명되지 않은 모든 PR을 닫는다.
|
||||
PR 작성자는 CLA에 서명한 후 PR을 다시 열 수 있으므로, 이는 어떤 것도 CLA 서명없이 병합되지 않게 하는 위험이 적은 방법이다.
|
||||
|
||||
- 작성자가 2주 이상 동안 코멘트나 피드백에 응답하지 않은 모든 PR을 닫는다.
|
||||
|
||||
풀 리퀘스트를 닫는 것을 두려워하지 말자. 기여자는 진행 중인 작업을 쉽게 다시 열고 다시 시작할 수 있다. 종종 종료 통지는 작성자가 기여를 재개하고 끝내도록 자극하는 것이다.
|
||||
|
||||
풀 리퀘스트를 닫으려면, PR에 `/close` 코멘트를 남긴다.
|
||||
|
||||
{{< note >}}
|
||||
|
||||
[`fejta-bot`](https://github.com/fejta-bot)이라는 자동화 서비스는 90일 동안 활동이 없으면 자동으로 이슈를 오래된 것으로 표시한 다음, 그 상태에서 추가로 30일 동안 활동이 없으면 종료한다. PR 랭글러는 14-30일 동안 활동이 없으면 이슈를 닫아야 한다.
|
||||
|
||||
{{< /note >}}
|
||||
|
||||
## 개선 제안
|
||||
|
||||
SIG Docs [멤버](/ko/docs/contribute/participating/#멤버)는 개선을 제안할 수 있다.
|
||||
|
||||
한 동안 쿠버네티스 문서에 기여한 후에,
|
||||
[스타일 가이드](/docs/contribute/style/style-guide/),
|
||||
[컨텐츠 가이드](/docs/contribute/style/content-guide/), 문서 작성에 사용되는 툴체인,
|
||||
website 스타일, 풀 리퀘스트 리뷰와 병합
|
||||
프로세스 또는 문서 작성의 다른 측면을 개선하기 위한 아이디어가 있을 수 있다. 투명성을 극대화하려면,
|
||||
이러한 유형의 제안을 SIG Docs 회의나
|
||||
[kubernetes-sig-docs 메일링리스트](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)에서 논의해야 한다.
|
||||
또한, 현재의 작업 방식과 과거의 결정이 왜 획기적인 변경을
|
||||
제안하기 전에 결정되었는지에 대한 맥락을 이해하는 데 실제로
|
||||
도움이 될 수 있다. 현재의 문서 작업이 어떻게 진행되는지에 대한 질문의
|
||||
답변을 얻는 가장 빠른 방법은 [kubernetes.slack.com](https://kubernetes.slack.com)의
|
||||
`#sig-docs` 슬랙 채널에 문의하는 것이다.
|
||||
|
||||
토론이 진행되고 원하는 결과에 SIG가 동의한
|
||||
후에는, 제안한 변경 사항과 가장 적합한 방식으로
|
||||
작업할 수 있다. 예를 들어, 스타일 가이드나 website의
|
||||
기능을 업데이트하려면, sig-testing과 함께 작업이 필요할 수 있는
|
||||
문서 테스트와 관련된 변경에 대해 풀 리퀘스트를 열어야 할 수 있다.
|
||||
|
||||
## 쿠버네티스 릴리스를 위한 문서 조정
|
||||
|
||||
SIG Docs [승인자](/ko/docs/contribute/participating/#승인자)는 쿠버네티스
|
||||
릴리스에 대한 문서를 조정할 수 있다.
|
||||
|
||||
각 쿠버네티스 릴리스는 sig-release SIG(Special Interest Group)에 참여하는
|
||||
사람들의 팀에 의해 조정된다. 특정 릴리스에 대한 릴리스 팀의 다른 구성원에는
|
||||
전체 릴리스 리드와 sig-pm, sig-testing 및 기타 담당자가
|
||||
포함된다. 쿠버네티스 릴리스 프로세스에 대한 자세한 내용은
|
||||
[https://github.com/kubernetes/sig-release](https://github.com/kubernetes/sig-release)를
|
||||
참고한다.
|
||||
|
||||
특정 릴리스의 SIG Docs 담당자는 다음 작업을 조정한다.
|
||||
|
||||
- 문서에 영향을 미치는 새로운 기능이나 변경된 기능이 있는지 기능-추적 스프레드시트를
|
||||
모니터링한다. 특정 기능에 대한 문서가 릴리스를 위해 준비가
|
||||
되지 않은 경우, 해당 기능이 릴리스 되지 않을 수 있다.
|
||||
- sig-release 미팅에 정기적으로 참석하고 릴리스에 대한 문서의
|
||||
상태를 업데이트한다.
|
||||
- 기능 구현을 담당하는 SIG가 작성한 기능 문서를
|
||||
리뷰하고 교정한다.
|
||||
- 릴리스 관련 풀 리퀘스트를 병합하고 릴리스에 대한 Git 기능 브랜치를
|
||||
유지 보수한다.
|
||||
- 앞으로 이 역할을 수행하는 방법을 배우려는 다른 SIG Docs 기여자들을
|
||||
멘토링한다. 이것을 "섀도잉"이라고 한다.
|
||||
- 릴리스에 대한 산출물이 공개될 때 릴리스와 관련된 문서 변경
|
||||
사항을 공개한다.
|
||||
|
||||
릴리스 조정은 일반적으로 3-4개월의 책임이며, SIG Docs 승인자
|
||||
사이에서 의무가 순환된다.
|
||||
|
||||
## 새로운 기여자 홍보대사로 봉사
|
||||
|
||||
SIG Docs [승인자](/ko/docs/contribute/participating/#승인자)는 새로운 기여자
|
||||
홍보대사로 활동할 수 있다.
|
||||
|
||||
새로운 기여자 홍보대사는 SIG-Docs에 기여한 새 기여자를 환영하고,
|
||||
새 기여자에게 PR을 제안하고, 첫 몇 번의 PR 제출을 통해
|
||||
새 기여자를 멘토링한다.
|
||||
|
||||
새로운 기여자 홍보대사의 책임은 다음과 같다.
|
||||
|
||||
- [#sig-docs 슬랙 채널](https://kubernetes.slack.com)에서 새로운 기여자의 질문을 모니터링한다.
|
||||
- PR 랭글러와 협력하여 새로운 기여자에게 좋은 첫 이슈를 파악한다.
|
||||
- 문서 리포지터리에 대한 처음 몇 번의 PR을 통해 새로운 기여자를 멘토링한다.
|
||||
- 새로운 기여자가 쿠버네티스 멤버가 되기 위해 필요한 보다 복잡한 PR을 작성하도록 지원한다.
|
||||
- 쿠버네티스 멤버 가입을 위해 [기여자를 후원](/ko/docs/contribute/advanced/#새로운-기여자-후원)한다.
|
||||
|
||||
현재 새로운 기여자 홍보대사는 각 SIG-Docs 회의와 [쿠버네티스 #sig-docs 채널](https://kubernetes.slack.com)에서 발표된다.
|
||||
|
||||
## 새로운 기여자 후원
|
||||
|
||||
SIG Docs [리뷰어](/ko/docs/contribute/participating/#리뷰어)는 새로운 기여자를
|
||||
후원할 수 있다.
|
||||
|
||||
새로운 기여자가 하나 이상의 쿠버네티스 리포지터리에 5개의
|
||||
실질적인 풀 리퀘스트를 성공적으로 제출한 후에는
|
||||
쿠버네티스 조직의 [멤버십](/ko/docs/contribute/participating#멤버)을
|
||||
신청할 수 있다. 기여자의 멤버십은 이미 리뷰어인 두 명의 스폰서가
|
||||
후원해야 한다.
|
||||
|
||||
새로운 문서 기여자는 [쿠버네티스 슬랙 인스턴스](https://kubernetes.slack.com)의 #sig-docs
|
||||
채널이나 [SIG Docs 메일링리스트](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)에서
|
||||
스폰서를 요청할 수 있다.
|
||||
신청자의 작업에 대해 확신이 있다면, 리뷰어는 신청자를 후원한다.
|
||||
신청자가 멤버십 신청서를 제출할 때, 신청서에 "+1"로 코멘트를 남기고
|
||||
신청자가 쿠버네티스 조직의 멤버십에
|
||||
적합한 이유에 대한 세부 정보를 포함한다.
|
||||
|
||||
## SIG 공동 의장으로 봉사
|
||||
|
||||
SIG Docs [승인자](/ko/docs/contribute/participating/#승인자)는 SIG Docs의 공동 의장 역할을 할 수 있다.
|
||||
|
||||
### 전제 조건
|
||||
|
||||
승인자는 공동 의장이 되려면 다음의 요구 사항을 충족해야 한다.
|
||||
|
||||
- 6개월 이상 SIG Docs 승인자로 활동한다.
|
||||
- [쿠버네티스 문서 릴리스 주도](/ko/docs/contribute/advanced/#쿠버네티스-릴리스를-위한-문서-조정) 또는 두 개의 릴리스에서 섀도잉을 수행한다.
|
||||
- SIG Docs 워크플로와 툴링을 이해한다(git, Hugo, 현지화, 블로그 하위 프로젝트).
|
||||
- [k/org의 팀](https://github.com/kubernetes/org/blob/master/config/kubernetes/sig-docs/teams.yaml), [k/community의 프로세스](https://github.com/kubernetes/community/tree/master/sig-docs), [k/test-infra](https://github.com/kubernetes/test-infra/)의 플러그인 및 [SIG 아키텍처](https://github.com/kubernetes/community/tree/master/sig-architecture)의 역할을 포함하여 다른 쿠버네티스 SIG와 리포지터리가 SIG Docs 워크플로에 미치는 영향을 이해한다.
|
||||
- 최소 6개월 동안 일주일에 5시간 이상(대부분 더)을 역할에 책임진다.
|
||||
|
||||
### 책임
|
||||
|
||||
공동 의장의 역할은 서비스 중 하나이다. 공동 의장은 기여자 역량 확보, 프로세스와 정책 처리, 회의 예약과 진행, PR 랭글러 스케줄링, 쿠버네티스 커뮤니티의 문서에 대한 지지, 쿠버네티스 릴리스 주기에서 성공적으로 문서화되는지 확인하고, SIG Docs를 효과적인 우선순위에 놓이도록 집중한다.
|
||||
|
||||
다음과 같은 책임을 가진다.
|
||||
|
||||
- SIG Docs가 우수한 문서화를 통해 개발자의 행복을 극대화하는 데 집중한다.
|
||||
- 스스로가 [커뮤니티 행동 강령](https://github.com/cncf/foundation/blob/master/code-of-conduct-languages/ko.md)을 준수하여 예를 보이고, SIG 멤버들이 지킬 수 있도록 책임을 진다.
|
||||
- 기여에 대한 새로운 지침을 확인하여 SIG에 대한 모범 사례를 배우고 설정한다.
|
||||
- SIG 회의를 예약하고 진행한다. 주간 상태 업데이트, 브랜치별 회고/기획 세션과 필요에 따라 그 외 세션을 진행한다.
|
||||
- KubeCon 이벤트 및 기타 컨퍼런스에서 문서 스프린트를 스케줄링하고 진행한다.
|
||||
- {{< glossary_tooltip text="CNCF" term_id="cncf" >}}와 플래티넘 파트너인 Google, Oracle, Azure, IBM 및 Huawei를 통해 SIG Docs를 대신하여 채용과 지지를 보낸다.
|
||||
- SIG를 원활하게 운영한다.
|
||||
|
||||
### 효과적인 회의 운영
|
||||
|
||||
효과적으로 회의를 예약하고 진행하기 위해, 이 지침은 수행할 작업, 수행 방법과 이유를 보여준다.
|
||||
|
||||
**[커뮤니티 행동 강령](https://github.com/cncf/foundation/blob/master/code-of-conduct-languages/ko.md)을 지킨다**.
|
||||
|
||||
- 정중함을 유지하고, 포괄적인 언어로, 정중하고 포괄적인 토론을 한다.
|
||||
|
||||
**명확한 안건을 설정한다**.
|
||||
|
||||
- 주제의 명확한 안건을 설정한다.
|
||||
- 안건을 미리 게시한다.
|
||||
|
||||
주간 회의의 경우, 지난 주 회의록을 회의록의 "지난 회의" 섹션에 복사하여 붙여 넣는다.
|
||||
|
||||
**정확한 회의록에 대해 공동 작업한다**.
|
||||
|
||||
- 회의의 토론 내용을 기록한다.
|
||||
- 회의록 작성자의 역할을 위임한다.
|
||||
|
||||
**조치 항목을 명확하고 정확하게 지정한다**.
|
||||
|
||||
- 조치 항목, 조치 항목에 할당된 멤버 그리고 예상 완료 날짜를 기록한다.
|
||||
|
||||
**필요에 따라 완급을 조절한다**.
|
||||
|
||||
- 토론이 안건에서 벗어난 경우, 참가자의 초점을 현재의 주제로 다시 맞춘다.
|
||||
- 토론에 집중하고 사람들의 시간을 존중하면서 다양한 토론 스타일을 위한 공간을 확보한다.
|
||||
|
||||
**사람들의 시간을 존중한다**.
|
||||
|
||||
정시에 회의를 시작하고 끝낸다.
|
||||
|
||||
**줌(Zoom)을 효과적으로 사용한다**.
|
||||
|
||||
- [쿠버네티스에 대한 줌 가이드라인](https://github.com/kubernetes/community/blob/master/communication/zoom-guidelines.md)에 익숙해진다.
|
||||
- 호스트 키를 입력하여 로그인할 때 호스트 역할을 선택한다.
|
||||
|
||||
<img src="/images/docs/contribute/claim-host.png" width="75%" alt="줌에서 호스트 역할 신청" />
|
||||
|
||||
### 줌에서 회의 녹화
|
||||
|
||||
녹화를 시작할 준비가 되면, Record to Cloud를 클릭한다.
|
||||
|
||||
녹화를 중지하려면, Stop을 클릭한다.
|
||||
|
||||
비디오가 자동으로 유튜브에 업로드된다.
|
||||
|
||||
{{% /capture %}}
|
|
@ -73,8 +73,7 @@ PR 코멘트를 남기는 것이 도움이 되지만, 대신 다른 사람의 PR
|
|||
[Prow](https://github.com/kubernetes/test-infra/blob/master/prow/README.md)는
|
||||
풀 리퀘스트 (PR)에 대한 작업을 실행하는 쿠버네티스 기반 CI/CD 시스템이다. Prow는
|
||||
챗봇 스타일 명령으로 쿠버네티스
|
||||
조직 전체에서 [레이블 추가와
|
||||
제거](#이슈-레이블-추가와-제거), 이슈 종료 및 승인자 할당과 같은 GitHub 작업을 처리할 수 있다. `/<command-name>` 형식을 사용하여 Prow 명령을 GitHub 코멘트로 입력한다.
|
||||
조직 전체에서 [레이블 추가와 제거](#이슈-레이블-추가와-제거), 이슈 종료 및 승인자 할당과 같은 GitHub 작업을 처리할 수 있다. `/<command-name>` 형식을 사용하여 Prow 명령을 GitHub 코멘트로 입력한다.
|
||||
|
||||
리뷰어와 승인자가 사용하는 가장 일반적인 Prow 명령은 다음과 같다.
|
||||
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
---
|
||||
title: 콘텐츠 개선 제안
|
||||
slug: suggest-improvements
|
||||
content_template: templates/concept
|
||||
weight: 10
|
||||
card:
|
||||
name: contribute
|
||||
weight: 20
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
쿠버네티스 문서에 문제가 있거나, 새로운 내용에 대한 아이디어가 있으면, 이슈를 연다. [GitHub 계정](https://github.com/join)과 웹 브라우저만 있으면 된다.
|
||||
|
||||
대부분의 경우, 쿠버네티스 문서에 대한 새로운 작업은 GitHub의 이슈로 시작된다. 그런 다음
|
||||
쿠버네티스 기여자는 필요에 따라 이슈를 리뷰, 분류하고 태그를 지정한다. 다음으로, 여러분이나
|
||||
다른 쿠버네티스 커뮤니티 멤버가 문제를 해결하기 위한 변경 사항이 있는 풀 리퀘스트를 연다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
## 이슈 열기
|
||||
|
||||
기존 콘텐츠에 대한 개선을 제안하거나, 오류를 발견하면, 이슈를 연다.
|
||||
|
||||
1. 페이지 하단으로 이동하여 **이슈 생성하기** 버튼을 클릭한다. 그러면 헤더가
|
||||
미리 채워진 GitHub 이슈 페이지로 리디렉션된다.
|
||||
2. 개선을 위한 문제나 제안 사항을 설명한다. 가능한 한 많은 정보를 제공한다.
|
||||
3. **Submit new issue** 를 클릭한다.
|
||||
|
||||
이슈를 제출한 후, 가끔 확인하거나 GitHub 알림을 켜자.
|
||||
리뷰어와 다른 커뮤니티 멤버가 이슈에 대한 조치를 취하기 전에
|
||||
여러분에게 질문을 할 수 있다.
|
||||
|
||||
## 새로운 콘텐츠 제안
|
||||
|
||||
새로운 콘텐츠에 대한 아이디어가 있지만, 어디로 가야 할지 확실하지 않은 경우에도
|
||||
이슈를 제기할 수 있다. 다음 중 하나를 선택하면 된다.
|
||||
|
||||
- 콘텐츠가 속한 섹션에서 기존 페이지를 선택하고 **이슈 생성하기** 를 클릭한다.
|
||||
- [GitHub](https://github.com/kubernetes/website/issues/new/)으로 이동하여 이슈를 직접 제기한다.
|
||||
|
||||
## 이슈를 제기하는 좋은 방법
|
||||
|
||||
|
||||
이슈를 제기할 때 다음의 사항에 유의한다.
|
||||
|
||||
- 명확하게 이슈에 대한 설명을 제공한다. 구체적으로 무엇이 누락되었거나, 오래되었거나,
|
||||
잘못되었거나, 개선이 필요한 사항인지를 설명한다.
|
||||
- 이 이슈가 사용자에게 미치는 영향을 설명한다.
|
||||
- 주어진 이슈의 범위를 합리적인 작업 단위로 제한한다. 넓은 범위에 대한
|
||||
이슈의 경우 더 작은 이슈로 분류한다. 예를 들어, "보안 문서 수정"은
|
||||
너무 광범위하지만, "'네트워크 접근 제한' 주제에 세부 사항 추가"는
|
||||
실행할 수 있을 정도로 구체적이다.
|
||||
- 기존 이슈를 검색하여 새로운 이슈와 관련이 있거나 비슷한 것이 있는지
|
||||
확인한다.
|
||||
- 새로운 이슈가 다른 이슈나 풀 리퀘스트와 관련이 있는 경우, 전체 URL이나
|
||||
`#` 문자로 시작하는 이슈나 풀 리퀘스트의 번호로
|
||||
참고한다. 예를 들면, `#987654 와 관련있습니다.` 와 같이 하면 된다.
|
||||
- [행동 강령](/ko/community/code-of-conduct/)을 따른다. 동료 기여자를
|
||||
존중한다. 예를 들어, "문서가 끔찍하다"는 도움이
|
||||
되지 않거나 예의 바르지 않은 피드백이다.
|
||||
|
||||
{{% /capture %}}
|
|
@ -15,3 +15,5 @@ tags:
|
|||
<!--more-->
|
||||
|
||||
작업 노드는 클러스터에 따라 VM이거나 물리 머신일 것이다. {{< glossary_tooltip text="파드" term_id="pod" >}} 실행에 필요한 로컬 데몬과 서비스를 가지고 있으며, 콘트롤 플레인에 의해서 관리된다. 노드에 있는 데몬은 {{< glossary_tooltip text="kubelet" term_id="kubelet" >}}, {{< glossary_tooltip text="kube-proxy" term_id="kube-proxy" >}}와 {{< glossary_tooltip term_id="docker" >}} 같이 컨테이너 런타임을 구현한 {{< glossary_tooltip text="CRI" term_id="cri" >}}를 포함한다.
|
||||
|
||||
초기 쿠버네티스 버전에서는 노드를 "미니언(Minions)"으로 불렀었다.
|
|
@ -2,7 +2,7 @@
|
|||
title: 테인트(Taint)
|
||||
id: taint
|
||||
date: 2019-01-11
|
||||
full_link: /docs/concepts/configuration/taint-and-toleration/
|
||||
full_link: /docs/concepts/scheduling-eviction/taint-and-toleration/
|
||||
short_description: >
|
||||
세 가지 필수 속성: 키(key), 값(value), 효과(effect)로 구성된 코어 오브젝트. 테인트는 파드가 노드나 노드 그룹에 스케줄링되는 것을 방지한다.
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
title: 톨러레이션(Toleration)
|
||||
id: toleration
|
||||
date: 2019-01-11
|
||||
full_link: /docs/concepts/configuration/taint-and-toleration/
|
||||
full_link: /docs/concepts/scheduling-eviction/taint-and-toleration/
|
||||
short_description: >
|
||||
세 가지 필수 속성: 키(key), 값(value), 효과(effect)로 구성된 코어 오브젝트. 톨러레이션은 매칭되는 테인트(taint)를 가진 노드나 노드 그룹에 파드가 스케줄링되는 것을 활성화한다.
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: 쿠버네티스 이슈와 보안
|
||||
weight: 10
|
||||
toc-hide: true
|
||||
---
|
|
@ -33,116 +33,151 @@ Minikube는 다음과 같은 쿠버네티스의 기능을 제공한다.
|
|||
여기서 기술하는 간단한 데모는 어떻게 로컬에서 Minikube를 시작하고, 사용하고 삭제하는지를 안내한다. 다음의 주어진 단계를 따라서 Minikube를 시작하고 탐구한다.
|
||||
|
||||
1. Minikube를 시작하고 클러스터를 생성
|
||||
```shell
|
||||
|
||||
```shell
|
||||
minikube start
|
||||
```
|
||||
```
|
||||
|
||||
결과는 다음과 비슷하다.
|
||||
|
||||
```
|
||||
Starting local Kubernetes cluster...
|
||||
Running pre-create checks...
|
||||
Creating machine...
|
||||
Starting local Kubernetes cluster...
|
||||
```
|
||||
특정 쿠버네티스 버전, VM, 컨테이너 런타임 상에서 클러스터를 시작하기 위한 보다 상세한 정보는 [클러스터 시작하기](#클러스터-시작하기)를 참조한다.
|
||||
```
|
||||
Starting local Kubernetes cluster...
|
||||
Running pre-create checks...
|
||||
Creating machine...
|
||||
Starting local Kubernetes cluster...
|
||||
```
|
||||
|
||||
특정 쿠버네티스 버전, VM, 컨테이너 런타임 상에서 클러스터를 시작하기 위한 보다 상세한 정보는 [클러스터 시작하기](#클러스터-시작하기)를 참조한다.
|
||||
|
||||
2. 이제, kubectl을 통해서 클러스터와 상호작용할 수 있다. 보다 상세한 정보는 [클러스터와 상호 작용하기](#클러스터와-상호-작용하기)를 참조한다.
|
||||
|
||||
단순한 HTTP 서버인 `echoserver` 이미지를 사용해서 쿠버네티스 디플로이먼트를 만들고 `--port`를 이용해서 8080 포트로 노출해보자.
|
||||
```shell
|
||||
kubectl create deployment hello-minikube --image=k8s.gcr.io/echoserver:1.10
|
||||
```
|
||||
결과는 다음과 비슷하다.
|
||||
```
|
||||
deployment.apps/hello-minikube created
|
||||
```
|
||||
3. `hello-minikube` 디플로이먼트에 액세스하기 위해, 서비스로 노출시킨다.
|
||||
```shell
|
||||
kubectl expose deployment hello-minikube --type=NodePort --port=8080
|
||||
```
|
||||
`--type=NodePort` 옵션은 서비스 타입을 지정한다.
|
||||
간단한 HTTP 서버인 `echoserver` 이미지를 사용해서 쿠버네티스 디플로이먼트를 만들고 `--port`를 이용해서 8080 포트로 노출해보자.
|
||||
|
||||
```shell
|
||||
kubectl create deployment hello-minikube --image=k8s.gcr.io/echoserver:1.10
|
||||
```
|
||||
|
||||
결과는 다음과 비슷하다.
|
||||
```
|
||||
service/hello-minikube exposed
|
||||
```
|
||||
|
||||
```
|
||||
deployment.apps/hello-minikube created
|
||||
```
|
||||
3. `hello-minikube` 디플로이먼트에 액세스하기 위해, 서비스로 노출시킨다.
|
||||
|
||||
```shell
|
||||
kubectl expose deployment hello-minikube --type=NodePort --port=8080
|
||||
```
|
||||
|
||||
`--type=NodePort` 옵션은 서비스 타입을 지정한다.
|
||||
|
||||
결과는 다음과 비슷하다.
|
||||
|
||||
```
|
||||
service/hello-minikube exposed
|
||||
```
|
||||
|
||||
4. `hello-minikube` 파드가 이제 시작되었지만 노출된 서비스를 통해서 접근하기 전에 파드가 뜨기를 기다려야한다.
|
||||
|
||||
파드가 떠서 구동되고 있는지 확인한다.
|
||||
```shell
|
||||
kubectl get pod
|
||||
```
|
||||
출력에서 `STATUS`가 `ContainerCreating`으로 나타나는 경우, 파드는 아직 생성 중이다.
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
hello-minikube-3383150820-vctvh 0/1 ContainerCreating 0 3s
|
||||
```
|
||||
출력에서 `STATUS`가 `Running`으로 나타나는 경우, 파드는 이제 떠서 기동 중이다.
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
hello-minikube-3383150820-vctvh 1/1 Running 0 13s
|
||||
```
|
||||
파드가 시작되고 실행 중인지 확인한다.
|
||||
|
||||
```shell
|
||||
kubectl get pod
|
||||
```
|
||||
|
||||
출력에서 `STATUS`가 `ContainerCreating`으로 나타나는 경우, 파드는 아직 생성 중이다.
|
||||
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
hello-minikube-3383150820-vctvh 0/1 ContainerCreating 0 3s
|
||||
```
|
||||
|
||||
출력에서 `STATUS`가 `Running`으로 나타나는 경우, 파드는 이제 시작돼서 실행 중이다.
|
||||
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
hello-minikube-3383150820-vctvh 1/1 Running 0 13s
|
||||
```
|
||||
|
||||
5. 서비스 상세를 보기 위해서 노출된 서비스의 URL을 얻는다.
|
||||
```shell
|
||||
minikube service hello-minikube --url
|
||||
```
|
||||
6. 로컬 클러스터의 상세를 보기위해서, 출력에서 얻은 URL을 브라우저에 복사해서 붙여 넣는다.
|
||||
|
||||
출력은 다음과 비슷하다.
|
||||
```
|
||||
Hostname: hello-minikube-7c77b68cff-8wdzq
|
||||
```shell
|
||||
minikube service hello-minikube --url
|
||||
```
|
||||
|
||||
Pod Information:
|
||||
-no pod information available-
|
||||
6. 로컬 클러스터의 상세를 보기위해서, 출력에서 얻은 URL을 브라우저에 복사해서 붙여넣는다.
|
||||
|
||||
Server values:
|
||||
server_version=nginx: 1.13.3 - lua: 10008
|
||||
출력은 다음과 비슷하다.
|
||||
|
||||
Request Information:
|
||||
client_address=172.17.0.1
|
||||
method=GET
|
||||
real path=/
|
||||
query=
|
||||
request_version=1.1
|
||||
request_scheme=http
|
||||
request_uri=http://192.168.99.100:8080/
|
||||
```
|
||||
Hostname: hello-minikube-7c77b68cff-8wdzq
|
||||
|
||||
Request Headers:
|
||||
Pod Information:
|
||||
-no pod information available-
|
||||
|
||||
Server values:
|
||||
server_version=nginx: 1.13.3 - lua: 10008
|
||||
|
||||
Request Information:
|
||||
client_address=172.17.0.1
|
||||
method=GET
|
||||
real path=/
|
||||
query=
|
||||
request_version=1.1
|
||||
request_scheme=http
|
||||
request_uri=http://192.168.99.100:8080/
|
||||
|
||||
Request Headers:
|
||||
accept=*/*
|
||||
host=192.168.99.100:30674
|
||||
user-agent=curl/7.47.0
|
||||
|
||||
Request Body:
|
||||
Request Body:
|
||||
-no body in request-
|
||||
```
|
||||
서비스나 클러스터가 더 이상 구동되지 않도록 하려면, 삭제한다.
|
||||
```
|
||||
|
||||
서비스나 클러스터가 더 이상 구동되지 않도록 하려면, 삭제한다.
|
||||
|
||||
7. `hello-minikube` 서비스 삭제
|
||||
```shell
|
||||
kubectl delete services hello-minikube
|
||||
```
|
||||
출력은 다음과 비슷하다.
|
||||
```
|
||||
service "hello-minikube" deleted
|
||||
```
|
||||
|
||||
```shell
|
||||
kubectl delete services hello-minikube
|
||||
```
|
||||
|
||||
The output is similar to this:
|
||||
|
||||
```
|
||||
service "hello-minikube" deleted
|
||||
```
|
||||
|
||||
8. `hello-minikube` 디플로이먼트 삭제
|
||||
```shell
|
||||
kubectl delete deployment hello-minikube
|
||||
```
|
||||
출력은 다음과 비슷하다.
|
||||
```
|
||||
deployment.extensions "hello-minikube" deleted
|
||||
```
|
||||
|
||||
```shell
|
||||
kubectl delete deployment hello-minikube
|
||||
```
|
||||
|
||||
The output is similar to this:
|
||||
|
||||
```
|
||||
deployment.extensions "hello-minikube" deleted
|
||||
```
|
||||
|
||||
9. 로컬 Minikube 클러스터 중지
|
||||
```shell
|
||||
minikube stop
|
||||
```
|
||||
출력은 다음과 비슷하다.
|
||||
```
|
||||
Stopping "minikube"...
|
||||
"minikube" stopped.
|
||||
```
|
||||
보다 상세한 정보는 [클러스터 중지하기](#클러스터-중지하기)를 참조한다.
|
||||
|
||||
```shell
|
||||
minikube stop
|
||||
```
|
||||
|
||||
The output is similar to this:
|
||||
|
||||
```
|
||||
Stopping "minikube"...
|
||||
"minikube" stopped.
|
||||
```
|
||||
|
||||
보다 상세한 정보는 [클러스터 중지하기](#클러스터-중지하기)를 참조한다.
|
||||
|
||||
10. 로컬 Minikube 클러스터 삭제
|
||||
|
||||
```shell
|
||||
minikube delete
|
||||
```
|
||||
|
@ -188,14 +223,15 @@ minikube start --kubernetes-version {{< param "fullversion" >}}
|
|||
```shell
|
||||
minikube start --driver=<driver_name>
|
||||
```
|
||||
Minikube는 다음의 드라이버를 지원한다.
|
||||
{{< note >}}
|
||||
지원되는 드라이버와 플러그인 설치 방법에 대한 보다 상세한 정보는 [드라이버](https://minikube.sigs.k8s.io/docs/reference/drivers/)를 참조한다.
|
||||
Minikube는 다음의 드라이버를 지원한다.
|
||||
{{< note >}}
|
||||
지원되는 드라이버와 플러그인 설치 방법에 대한 보다 상세한 정보는 [드라이버](https://minikube.sigs.k8s.io/docs/reference/drivers/)를 참조한다.
|
||||
{{< /note >}}
|
||||
|
||||
* virtualbox
|
||||
* docker ([드라이버 설치](https://minikube.sigs.k8s.io/docs/drivers/docker/))
|
||||
* virtualbox ([드라이버 설치](https://minikube.sigs.k8s.io/docs/drivers/virtualbox/))
|
||||
* podman ([드라이버 설치](https://minikube.sigs.k8s.io/docs/drivers/podman/)) (EXPERIMENTAL)
|
||||
* vmwarefusion
|
||||
* docker ([드라이버 설치](https://minikube.sigs.k8s.io/docs/drivers/docker/)
|
||||
* kvm2 ([드라이버 설치](https://minikube.sigs.k8s.io/docs/reference/drivers/kvm2/))
|
||||
* hyperkit ([드라이버 설치](https://minikube.sigs.k8s.io/docs/reference/drivers/hyperkit/))
|
||||
* hyperv ([드라이버 설치](https://minikube.sigs.k8s.io/docs/reference/drivers/hyperv/))
|
||||
|
|
|
@ -18,8 +18,8 @@ weight: 10
|
|||
악성 컨테이너는 이 결함을 사용하여 runc 바이너리의 내용을 덮어쓸 수 있으며
|
||||
따라서 컨테이너 호스트 시스템에서 임의의 명령을 실행할 수 있다.
|
||||
|
||||
이 문제에 대한 자세한 내용은
|
||||
[cve-2019-5736 : runc 취약점 ] (https://access.redhat.com/security/cve/cve-2019-5736) 참고하자.
|
||||
문제에 대한 자세한 내용은 [CVE-2019-5736](https://access.redhat.com/security/cve/cve-2019-5736)
|
||||
를 참고한다.
|
||||
{{< /caution >}}
|
||||
|
||||
### 적용 가능성
|
||||
|
@ -49,7 +49,7 @@ Control group은 프로세스에 할당된 리소스를 제한하는데 사용
|
|||
리소스가 부족할 때 불안정해지는 사례를 본 적이 있다.
|
||||
|
||||
컨테이너 런타임과 kubelet이 `systemd`를 cgroup 드라이버로 사용하도록 설정을 변경하면
|
||||
시스템이 안정화된다. 아래의 Docker 설정에서 `native.cgroupdriver=systemd` 옵션을 확인하라.
|
||||
시스템이 안정화된다. 아래의 도커 설정에서 `native.cgroupdriver=systemd` 옵션을 확인하라.
|
||||
|
||||
{{< caution >}}
|
||||
클러스터에 결합되어 있는 노드의 cgroup 관리자를 변경하는 것은 권장하지 않는다.
|
||||
|
@ -59,38 +59,48 @@ kubelet을 재시작 하는 것은 에러를 해결할 수 없을 것이다.
|
|||
추천하는 방법은 워크로드에서 노드를 제거하고, 클러스터에서 제거한 다음 다시 결합시키는 것이다.
|
||||
{{< /caution >}}
|
||||
|
||||
## Docker
|
||||
## 도커
|
||||
|
||||
각 머신들에 대해서, Docker를 설치한다.
|
||||
각 머신들에 대해서, 도커를 설치한다.
|
||||
버전 19.03.8이 추천된다. 그러나 1.13.1, 17.03, 17.06, 17.09, 18.06 그리고 18.09도 동작하는 것으로 알려져 있다.
|
||||
쿠버네티스 릴리스 노트를 통해서, 최신에 검증된 Docker 버전의 지속적인 파악이 필요하다.
|
||||
쿠버네티스 릴리스 노트를 통해서, 최신에 검증된 도커 버전의 지속적인 파악이 필요하다.
|
||||
|
||||
시스템에 Docker를 설치하기 위해서 아래의 커맨드들을 사용한다.
|
||||
시스템에 도커를 설치하기 위해서 아래의 커맨드들을 사용한다.
|
||||
|
||||
{{< tabs name="tab-cri-docker-installation" >}}
|
||||
{{< tab name="Ubuntu 16.04+" codelang="bash" >}}
|
||||
# Docker CE 설치
|
||||
{{< tab name="Ubuntu 16.04+" >}}
|
||||
|
||||
```shell
|
||||
# (도커 CE 설치)
|
||||
## 리포지터리 설정
|
||||
### apt가 HTTPS 리포지터리를 사용할 수 있도록 해주는 패키지 설치
|
||||
apt-get update && apt-get install -y \
|
||||
apt-transport-https ca-certificates curl software-properties-common gnupg2
|
||||
```
|
||||
|
||||
### Docker의 공식 GPG 키 추가
|
||||
```shell
|
||||
# 도커 공식 GPG 키 추가
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
|
||||
```
|
||||
|
||||
### Docker apt 리포지터리 추가.
|
||||
```shell
|
||||
# 도커 apt 리포지터리 추가.
|
||||
add-apt-repository \
|
||||
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
|
||||
$(lsb_release -cs) \
|
||||
stable"
|
||||
```
|
||||
|
||||
## Docker CE 설치.
|
||||
```shell
|
||||
# 도커 CE 설치.
|
||||
apt-get update && apt-get install -y \
|
||||
containerd.io=1.2.13-1 \
|
||||
docker-ce=5:19.03.8~3-0~ubuntu-$(lsb_release -cs) \
|
||||
docker-ce-cli=5:19.03.8~3-0~ubuntu-$(lsb_release -cs)
|
||||
```
|
||||
|
||||
# 데몬 설정.
|
||||
```shell
|
||||
# 도커 데몬 설정
|
||||
cat > /etc/docker/daemon.json <<EOF
|
||||
{
|
||||
"exec-opts": ["native.cgroupdriver=systemd"],
|
||||
|
@ -101,34 +111,48 @@ cat > /etc/docker/daemon.json <<EOF
|
|||
"storage-driver": "overlay2"
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
```shell
|
||||
mkdir -p /etc/systemd/system/docker.service.d
|
||||
```
|
||||
|
||||
# Docker 재시작.
|
||||
```shell
|
||||
# 도커 재시작.
|
||||
systemctl daemon-reload
|
||||
systemctl restart docker
|
||||
```
|
||||
{{< /tab >}}
|
||||
{{< tab name="CentOS/RHEL 7.4+" codelang="bash" >}}
|
||||
{{< tab name="CentOS/RHEL 7.4+" >}}
|
||||
|
||||
# Docker CE 설치
|
||||
```shell
|
||||
# (도커 CE 설치)
|
||||
## 리포지터리 설정
|
||||
### 필요한 패키지 설치.
|
||||
### 필요한 패키지 설치
|
||||
yum install -y yum-utils device-mapper-persistent-data lvm2
|
||||
```
|
||||
|
||||
### Docker 리포지터리 추가
|
||||
```shell
|
||||
## 도커 리포지터리 추가
|
||||
yum-config-manager --add-repo \
|
||||
https://download.docker.com/linux/centos/docker-ce.repo
|
||||
```
|
||||
|
||||
## Docker CE 설치.
|
||||
```shell
|
||||
# 도커 CE 설치.
|
||||
yum update -y && yum install -y \
|
||||
containerd.io-1.2.13 \
|
||||
docker-ce-19.03.8 \
|
||||
docker-ce-cli-19.03.8
|
||||
```
|
||||
|
||||
## /etc/docker 디렉터리 생성.
|
||||
```shell
|
||||
## /etc/docker 생성.
|
||||
mkdir /etc/docker
|
||||
```
|
||||
|
||||
# 데몬 설정.
|
||||
```shell
|
||||
# 도커 데몬 설정.
|
||||
cat > /etc/docker/daemon.json <<EOF
|
||||
{
|
||||
"exec-opts": ["native.cgroupdriver=systemd"],
|
||||
|
@ -142,16 +166,21 @@ cat > /etc/docker/daemon.json <<EOF
|
|||
]
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
```shell
|
||||
mkdir -p /etc/systemd/system/docker.service.d
|
||||
```
|
||||
|
||||
# Docker 재시작.
|
||||
```shell
|
||||
# 도커 재시작.
|
||||
systemctl daemon-reload
|
||||
systemctl restart docker
|
||||
```
|
||||
{{< /tab >}}
|
||||
{{< /tabs >}}
|
||||
|
||||
자세한 내용은 [공식 Docker 설치 가이드](https://docs.docker.com/engine/installation/)
|
||||
자세한 내용은 [공식 도커 설치 가이드](https://docs.docker.com/engine/installation/)
|
||||
를 참고한다.
|
||||
|
||||
## CRI-O
|
||||
|
@ -182,53 +211,78 @@ sysctl --system
|
|||
```
|
||||
|
||||
{{< tabs name="tab-cri-cri-o-installation" >}}
|
||||
{{< tab name="Debian" codelang="bash" >}}
|
||||
{{< tab name="Debian" >}}
|
||||
|
||||
```shell
|
||||
# Debian 개발 배포본(Unstable/Sid)
|
||||
echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_Unstable/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
|
||||
wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/Debian_Unstable/Release.key -O- | sudo apt-key add -
|
||||
```
|
||||
|
||||
```shell
|
||||
# Debian Testing
|
||||
echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_Testing/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
|
||||
wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/Debian_Testing/Release.key -O- | sudo apt-key add -
|
||||
```
|
||||
|
||||
```shell
|
||||
# Debian 10
|
||||
echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_10/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
|
||||
wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/Debian_10/Release.key -O- | sudo apt-key add -
|
||||
```
|
||||
|
||||
```shell
|
||||
# Raspbian 10
|
||||
echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Raspbian_10/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
|
||||
wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/Raspbian_10/Release.key -O- | sudo apt-key add -
|
||||
```
|
||||
|
||||
# CRI-O 설치
|
||||
그리고 다음과 같이 CRI-O 설치한다.
|
||||
```shell
|
||||
sudo apt-get install cri-o-1.17
|
||||
```
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab name="Ubuntu 18.04, 19.04 and 19.10" codelang="bash" >}}
|
||||
# 리포지터리 설치
|
||||
{{< tab name="Ubuntu 18.04, 19.04 and 19.10" >}}
|
||||
|
||||
```shell
|
||||
# 패키지 리포지터리 설정
|
||||
. /etc/os-release
|
||||
sudo sh -c "echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/x${NAME}_${VERSION_ID}/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list"
|
||||
wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/x${NAME}_${VERSION_ID}/Release.key -O- | sudo apt-key add -
|
||||
sudo apt-get update
|
||||
```
|
||||
|
||||
```shell
|
||||
# CRI-O 설치
|
||||
sudo apt-get install cri-o-1.17
|
||||
```
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab name="CentOS/RHEL 7.4+" codelang="bash" >}}
|
||||
{{< tab name="CentOS/RHEL 7.4+" >}}
|
||||
|
||||
```shell
|
||||
# 선행 조건 설치
|
||||
yum-config-manager --add-repo=https://cbs.centos.org/repos/paas7-crio-115-release/x86_64/os/
|
||||
curl -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable.repo https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/CentOS_7/devel:kubic:libcontainers:stable.repo
|
||||
curl -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable:cri-o:{{< skew latestVersion >}}.repo https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable:cri-o:{{< skew latestVersion >}}/CentOS_7/devel:kubic:libcontainers:stable:cri-o:{{< skew latestVersion >}}.repo
|
||||
```
|
||||
|
||||
```shell
|
||||
# CRI-O 설치
|
||||
yum install --nogpgcheck -y cri-o
|
||||
yum install -y cri-o
|
||||
```
|
||||
|
||||
{{< tab name="openSUSE Tumbleweed" codelang="bash" >}}
|
||||
{{< tab name="openSUSE Tumbleweed" >}}
|
||||
|
||||
```shell
|
||||
sudo zypper install cri-o
|
||||
```
|
||||
{{< /tab >}}
|
||||
{{< /tabs >}}
|
||||
|
||||
### CRI-O 시작
|
||||
|
||||
```
|
||||
```shell
|
||||
systemctl daemon-reload
|
||||
systemctl start crio
|
||||
```
|
||||
|
@ -266,51 +320,75 @@ sysctl --system
|
|||
### containerd 설치
|
||||
|
||||
{{< tabs name="tab-cri-containerd-installation" >}}
|
||||
{{< tab name="Ubuntu 16.04" codelang="bash" >}}
|
||||
# containerd 설치
|
||||
{{< tab name="Ubuntu 16.04" >}}
|
||||
|
||||
```shell
|
||||
# (containerd 설치)
|
||||
## 리포지터리 설정
|
||||
### apt가 HTTPS로 리포지터리를 사용하는 것을 허용하기 위한 패키지 설치
|
||||
apt-get update && apt-get install -y apt-transport-https ca-certificates curl software-properties-common
|
||||
```
|
||||
|
||||
### Docker의 공식 GPG 키 추가
|
||||
```shell
|
||||
## 도커 공식 GPG 키 추가
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
|
||||
```
|
||||
|
||||
### Docker apt 리포지터리 추가.
|
||||
```shell
|
||||
## 도커 apt 리포지터리 추가.
|
||||
add-apt-repository \
|
||||
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
|
||||
$(lsb_release -cs) \
|
||||
stable"
|
||||
```
|
||||
|
||||
```shell
|
||||
## containerd 설치
|
||||
apt-get update && apt-get install -y containerd.io
|
||||
```
|
||||
|
||||
```shell
|
||||
# containerd 설정
|
||||
mkdir -p /etc/containerd
|
||||
containerd config default > /etc/containerd/config.toml
|
||||
```
|
||||
|
||||
```shell
|
||||
# containerd 재시작
|
||||
systemctl restart containerd
|
||||
```
|
||||
{{< /tab >}}
|
||||
{{< tab name="CentOS/RHEL 7.4+" codelang="bash" >}}
|
||||
# containerd 설치
|
||||
{{< tab name="CentOS/RHEL 7.4+" >}}
|
||||
|
||||
```shell
|
||||
# (containerd 설치)
|
||||
## 리포지터리 설정
|
||||
### 필요한 패키지 설치
|
||||
yum install -y yum-utils device-mapper-persistent-data lvm2
|
||||
```
|
||||
|
||||
### Docker 리포지터리 추가리
|
||||
```shell
|
||||
## 도커 리포지터리 추가
|
||||
yum-config-manager \
|
||||
--add-repo \
|
||||
https://download.docker.com/linux/centos/docker-ce.repo
|
||||
```
|
||||
|
||||
```shell
|
||||
## containerd 설치
|
||||
yum update -y && yum install -y containerd.io
|
||||
```
|
||||
|
||||
# containerd 설정
|
||||
```shell
|
||||
## containerd 설정
|
||||
mkdir -p /etc/containerd
|
||||
containerd config default > /etc/containerd/config.toml
|
||||
```
|
||||
|
||||
```shell
|
||||
# containerd 재시작
|
||||
systemctl restart containerd
|
||||
```
|
||||
{{< /tab >}}
|
||||
{{< /tabs >}}
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ spec:
|
|||
- -command
|
||||
- "<#code used from https://gist.github.com/wagnerandrade/5424431#> ; $$listener = New-Object System.Net.HttpListener ; $$listener.Prefixes.Add('http://*:80/') ; $$listener.Start() ; $$callerCounts = @{} ; Write-Host('Listening at http://*:80/') ; while ($$listener.IsListening) { ;$$context = $$listener.GetContext() ;$$requestUrl = $$context.Request.Url ;$$clientIP = $$context.Request.RemoteEndPoint.Address ;$$response = $$context.Response ;Write-Host '' ;Write-Host('> {0}' -f $$requestUrl) ; ;$$count = 1 ;$$k=$$callerCounts.Get_Item($$clientIP) ;if ($$k -ne $$null) { $$count += $$k } ;$$callerCounts.Set_Item($$clientIP, $$count) ;$$ip=(Get-NetAdapter | Get-NetIpAddress); $$header='<html><body><H1>Windows Container Web Server</H1>' ;$$callerCountsString='' ;$$callerCounts.Keys | % { $$callerCountsString+='<p>IP {0} callerCount {1} ' -f $$ip[1].IPAddress,$$callerCounts.Item($$_) } ;$$footer='</body></html>' ;$$content='{0}{1}{2}' -f $$header,$$callerCountsString,$$footer ;Write-Output $$content ;$$buffer = [System.Text.Encoding]::UTF8.GetBytes($$content) ;$$response.ContentLength64 = $$buffer.Length ;$$response.OutputStream.Write($$buffer, 0, $$buffer.Length) ;$$response.Close() ;$$responseStatus = $$response.StatusCode ;Write-Host('< {0}' -f $$responseStatus) } ; "
|
||||
nodeSelector:
|
||||
beta.kubernetes.io/os: windows
|
||||
kubernetes.io/os: windows
|
||||
```
|
||||
|
||||
{{< note >}}
|
||||
|
|
|
@ -277,7 +277,7 @@ heapster is running at https://104.197.5.247/api/v1/namespaces/kube-system/servi
|
|||
예를 들어 위 클러스터는 클러스터 수준의 logging(Elasticsearch 사용)이 활성화되었으므로 적절한 인증을 통과하여
|
||||
`https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/`로 액세스할 수 있다. 예를 들어 kubectl proxy로
|
||||
`http://localhost:8080/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/`를 통해 logging에 액세스할 수도 있다.
|
||||
(인증을 통과하는 방법이나 kubectl proxy를 사용하는 것은 [위 내용](#rest-api에-직접-액세스)을 참조한다.)
|
||||
(인증을 통과하는 방법이나 kubectl proxy를 사용하는 것은 [쿠버네티스 API를 사용해서 클러스터에 접근하기](/docs/tasks/administer-cluster/access-cluster-api/)을 참조한다.)
|
||||
|
||||
#### 수작업으로 apiserver proxy URL을 구축
|
||||
|
||||
|
|
|
@ -346,7 +346,7 @@ export KUBECONFIG=$KUBECONFIG:$HOME/.kube/config
|
|||
```
|
||||
### Windows Powershell
|
||||
```shell
|
||||
$Env:KUBECONFIG=($Env:KUBECONFIG;$HOME/.kube/config)
|
||||
$Env:KUBECONFIG="$Env:KUBECONFIG;$HOME\.kube\config"
|
||||
```
|
||||
|
||||
이제 `KUBECONFIG` 환경 변수에 리스트에 포함된 모든 파일들이 합쳐진 구성 정보를 보자.
|
||||
|
|
|
@ -93,7 +93,7 @@ Kubeconfig 인증 방법은 외부 아이덴티티 프로파이더 또는 x509
|
|||
|
||||
예를 들면:
|
||||
|
||||
```conf
|
||||
```conf
|
||||
release=1.0
|
||||
tier=frontend
|
||||
environment=pod
|
||||
|
|
|
@ -0,0 +1,182 @@
|
|||
---
|
||||
title: Windows 노드 추가
|
||||
min-kubernetes-server-version: 1.17
|
||||
content_template: templates/tutorial
|
||||
weight: 30
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
{{< feature-state for_k8s_version="v1.18" state="beta" >}}
|
||||
|
||||
쿠버네티스를 사용하여 리눅스와 Windows 노드를 혼합하여 실행할 수 있으므로, 리눅스에서 실행되는 파드와 Windows에서 실행되는 파드를 혼합할 수 있다. 이 페이지는 Windows 노드를 클러스터에 등록하는 방법을 보여준다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture prerequisites %}} {{< version-check >}}
|
||||
|
||||
* Windows 컨테이너를 호스팅하는 Windows 노드를 구성하려면
|
||||
[Windows Server 2019 라이선스](https://www.microsoft.com/en-us/cloud-platform/windows-server-pricing) 이상이 필요하다.
|
||||
VXLAN/오버레이 네트워킹을 사용하는 경우 [KB4489899](https://support.microsoft.com/help/4489899)도 설치되어 있어야 한다.
|
||||
|
||||
* 컨트롤 플레인에 접근할 수 있는 리눅스 기반의 쿠버네티스 kubeadm 클러스터([kubeadm을 사용하여 단일 컨트롤 플레인 클러스터 생성](/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/) 참고)가 필요하다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture objectives %}}
|
||||
|
||||
* 클러스터에 Windows 노드 등록
|
||||
* 리눅스 및 Windows의 파드와 서비스가 서로 통신할 수 있도록 네트워킹 구성
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture lessoncontent %}}
|
||||
|
||||
## 시작하기: 클러스터에 Windows 노드 추가
|
||||
|
||||
### 네트워킹 구성
|
||||
|
||||
리눅스 기반 쿠버네티스 컨트롤 플레인 노드가 있으면 네트워킹 솔루션을 선택할 수 있다. 이 가이드는 VXLAN 모드의 플란넬(Flannel)을 사용하는 방법을 짧막하게 보여준다.
|
||||
|
||||
#### 플란넬 구성
|
||||
|
||||
1. 플란넬을 위한 쿠버네티스 컨트롤 플레인 준비
|
||||
|
||||
클러스터의 쿠버네티스 컨트롤 플레인에서 약간의 준비가 필요하다. 플란넬을 사용할 때 iptables 체인에 브릿지된 IPv4 트래픽을 활성화하는 것을 권장한다. 아래 명령을 모든 리눅스 노드에서 실행해야만 한다.
|
||||
|
||||
```bash
|
||||
sudo sysctl net.bridge.bridge-nf-call-iptables=1
|
||||
```
|
||||
|
||||
1. 리눅스용 플란넬 다운로드 및 구성
|
||||
|
||||
가장 최근의 플란넬 매니페스트를 다운로드한다.
|
||||
|
||||
```bash
|
||||
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
|
||||
```
|
||||
|
||||
VNI를 4096으로 설정하고 포트를 4789로 설정하려면 플란넬 매니페스트의 `net-conf.json` 섹션을 수정한다. 다음과 같을 것이다.
|
||||
|
||||
```json
|
||||
net-conf.json: |
|
||||
{
|
||||
"Network": "10.244.0.0/16",
|
||||
"Backend": {
|
||||
"Type": "vxlan",
|
||||
"VNI" : 4096,
|
||||
"Port": 4789
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
{{< note >}}리눅스의 플란넬이 Windows의 플란넬과 상호 운용되도록 하려면 VNI를 4096으로, 포트를 4789로 설정해야 한다. 이 필드들에 대한 설명은 [VXLAN 문서](https://github.com/coreos/flannel/blob/master/Documentation/backends.md#vxlan)를
|
||||
참고한다.{{< /note >}}
|
||||
|
||||
{{< note >}}L2Bridge/Host-gateway 모드를 대신 사용하려면 `Type` 의 값을 `"host-gw"` 로 변경하고 `VNI` 와 `Port` 를 생략한다.{{< /note >}}
|
||||
|
||||
1. 플란넬 매니페스트 적용 및 유효성 검사
|
||||
|
||||
플란넬 구성을 적용해보자.
|
||||
|
||||
```bash
|
||||
kubectl apply -f kube-flannel.yml
|
||||
```
|
||||
|
||||
몇 분 후에, 플란넬 파드 네트워크가 배포되었다면 모든 파드가 실행 중인 것으로 표시된다.
|
||||
|
||||
```bash
|
||||
kubectl get pods -n kube-system
|
||||
```
|
||||
|
||||
출력 결과에 리눅스 flannel 데몬셋(DaemonSet)이 실행 중인 것으로 나와야 한다.
|
||||
|
||||
```
|
||||
NAMESPACE NAME READY STATUS RESTARTS AGE
|
||||
...
|
||||
kube-system kube-flannel-ds-54954 1/1 Running 0 1m
|
||||
```
|
||||
|
||||
1. Windows 플란넬 및 kube-proxy 데몬셋 추가
|
||||
|
||||
이제 Windows 호환 버전의 플란넬과 kube-proxy를 추가할 수 있다. 호환 가능한
|
||||
kube-proxy 버전을 얻으려면, 이미지의 태그를
|
||||
대체해야 한다. 다음의 예시는 쿠버네티스 {{< param "fullversion" >}}의 사용법을 보여주지만,
|
||||
사용자의 배포에 맞게 버전을 조정해야 한다.
|
||||
|
||||
```bash
|
||||
curl -L https://github.com/kubernetes-sigs/sig-windows-tools/releases/latest/download/kube-proxy.yml | sed 's/VERSION/{{< param "fullversion" >}}/g' | kubectl apply -f -
|
||||
kubectl apply -f https://github.com/kubernetes-sigs/sig-windows-tools/releases/latest/download/flannel-overlay.yml
|
||||
```
|
||||
{{< note >}}
|
||||
host-gateway를 사용하는 경우 https://github.com/kubernetes-sigs/sig-windows-tools/releases/latest/download/flannel-host-gw.yml 을 대신 사용한다.
|
||||
{{< /note >}}
|
||||
|
||||
{{< note >}}
|
||||
Windows 노드에서 이더넷이 아닌 다른 인터페이스(예: "Ethernet0 2")를 사용하는 경우, flannel-host-gw.yml이나 flannel-overlay.yml 파일에서 다음 라인을 수정한다.
|
||||
|
||||
```powershell
|
||||
wins cli process run --path /k/flannel/setup.exe --args "--mode=overlay --interface=Ethernet"
|
||||
```
|
||||
|
||||
그리고, 이에 따라 인터페이스를 지정해야 한다.
|
||||
|
||||
```bash
|
||||
# 예시
|
||||
curl -L https://github.com/kubernetes-sigs/sig-windows-tools/releases/latest/download/flannel-overlay.yml | sed 's/Ethernet/Ethernet0 2/g' | kubectl apply -f -
|
||||
```
|
||||
{{< /note >}}
|
||||
|
||||
|
||||
|
||||
### Windows 워커 노드 조인(joining)
|
||||
{{< note >}}
|
||||
`Containers` 기능을 설치하고 도커를 설치해야 한다.
|
||||
[Windows Server에 Docker Engine - Enterprise 설치](https://docs.docker.com/ee/docker-ee/windows/docker-ee/#install-docker-engine---enterprise)에서 설치에 대한 내용을 참고할 수 있다.
|
||||
{{< /note >}}
|
||||
|
||||
{{< note >}}
|
||||
Windows 섹션의 모든 코드 스니펫(snippet)은 Windows 워커 노드의
|
||||
높은 권한(관리자)이 있는 PowerShell 환경에서 실행해야 한다.
|
||||
{{< /note >}}
|
||||
|
||||
1. wins, kubelet 및 kubeadm 설치
|
||||
|
||||
```PowerShell
|
||||
curl.exe -LO https://github.com/kubernetes-sigs/sig-windows-tools/releases/latest/download/PrepareNode.ps1
|
||||
.\PrepareNode.ps1 -KubernetesVersion {{< param "fullversion" >}}
|
||||
```
|
||||
|
||||
1. 노드에 조인하기 위해 `kubeadm` 실행
|
||||
|
||||
컨트롤 플레인 호스트에서 `kubeadm init` 실행할 때 제공된 명령을 사용한다.
|
||||
이 명령이 더 이상 없거나, 토큰이 만료된 경우, `kubeadm token create --print-join-command`
|
||||
(컨트롤 플레인 호스트에서)를 실행하여 새 토큰 및 조인 명령을 생성할 수 있다.
|
||||
|
||||
|
||||
#### 설치 확인
|
||||
이제 다음을 실행하여 클러스터에서 Windows 노드를 볼 수 있다.
|
||||
|
||||
```bash
|
||||
kubectl get nodes -o wide
|
||||
```
|
||||
|
||||
새 노드가 `NotReady` 상태인 경우 플란넬 이미지가 여전히 다운로드 중일 수 있다.
|
||||
`kube-system` 네임스페이스에서 flannel 파드를 확인하여 이전과 같이 진행 상황을 확인할 수 있다.
|
||||
|
||||
```shell
|
||||
kubectl -n kube-system get pods -l app=flannel
|
||||
```
|
||||
|
||||
flannel 파드가 실행되면, 노드는 `Ready` 상태가 되고 워크로드를 처리할 수 있어야 한다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
|
||||
- [Windows kubeadm 노드 업그레이드](/ko/docs/tasks/administer-cluster/kubeadm/upgrading-windows-nodes)
|
||||
|
||||
{{% /capture %}}
|
|
@ -0,0 +1,243 @@
|
|||
---
|
||||
title: kubeadm을 사용한 인증서 관리
|
||||
content_template: templates/task
|
||||
weight: 10
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
{{< feature-state for_k8s_version="v1.15" state="stable" >}}
|
||||
|
||||
[kubeadm](/docs/reference/setup-tools/kubeadm/kubeadm/)으로 생성된 클라이언트 인증서는 1년 후에 만료된다. 이 페이지는 kubeadm으로 인증서 갱신을 관리하는 방법을 설명한다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture prerequisites %}}
|
||||
|
||||
[쿠버네티스의 PKI 인증서와 요구 조건](/ko/docs/setup/best-practices/certificates/)에 익숙해야 한다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture steps %}}
|
||||
|
||||
## 사용자 정의 인증서 사용 {#custom-certificates}
|
||||
|
||||
기본적으로, kubeadm은 클러스터를 실행하는 데 필요한 모든 인증서를 생성한다.
|
||||
사용자는 자체 인증서를 제공하여 이 동작을 무시할 수 있다.
|
||||
|
||||
이렇게 하려면, `--cert-dir` 플래그 또는 kubeadm `ClusterConfiguration` 의
|
||||
`certificatesDir` 필드에 지정된 디렉터리에 배치해야 한다.
|
||||
기본적으로 `/etc/kubernetes/pki` 이다.
|
||||
|
||||
`kubeadm init` 을 실행하기 전에 지정된 인증서와 개인 키(private key) 쌍이 존재하면,
|
||||
kubeadm은 이를 덮어 쓰지 않는다. 이는 예를 들어, 기존 CA를
|
||||
`/etc/kubernetes/pki/ca.crt` 와 `/etc/kubernetes/pki/ca.key` 에
|
||||
복사할 수 있고, kubeadm은 이 CA를 사용하여 나머지 인증서에 서명한다는 걸 의미한다.
|
||||
|
||||
## 외부 CA 모드 {#external-ca-mode}
|
||||
|
||||
`ca.key` 파일이 아닌 `ca.crt` 파일만 제공할
|
||||
수도 있다(이는 다른 인증서 쌍이 아닌 루트 CA 파일에만 사용 가능함).
|
||||
다른 모든 인증서와 kubeconfig 파일이 있으면, kubeadm은 이 조건을
|
||||
인식하고 "외부 CA" 모드를 활성화한다. kubeadm은 디스크에
|
||||
CA 키없이 진행한다.
|
||||
|
||||
대신, `--controllers=csrsigner` 사용하여 controller-manager를
|
||||
독립적으로 실행하고 CA 인증서와 키를 가리킨다.
|
||||
|
||||
[PKI 인증서와 요구 조건](/ko/docs/setup/best-practices/certificates/)은 외부 CA를
|
||||
사용하도록 클러스터 설정에 대한 지침을 포함한다.
|
||||
|
||||
## 인증서 만료 확인
|
||||
|
||||
`check-expiration` 하위 명령을 사용하여 인증서가 만료되는 시기를 확인할 수 있다.
|
||||
|
||||
```
|
||||
kubeadm alpha certs check-expiration
|
||||
```
|
||||
|
||||
출력 결과는 다음과 비슷하다.
|
||||
|
||||
```
|
||||
CERTIFICATE EXPIRES RESIDUAL TIME CERTIFICATE AUTHORITY EXTERNALLY MANAGED
|
||||
admin.conf Dec 30, 2020 23:36 UTC 364d no
|
||||
apiserver Dec 30, 2020 23:36 UTC 364d ca no
|
||||
apiserver-etcd-client Dec 30, 2020 23:36 UTC 364d etcd-ca no
|
||||
apiserver-kubelet-client Dec 30, 2020 23:36 UTC 364d ca no
|
||||
controller-manager.conf Dec 30, 2020 23:36 UTC 364d no
|
||||
etcd-healthcheck-client Dec 30, 2020 23:36 UTC 364d etcd-ca no
|
||||
etcd-peer Dec 30, 2020 23:36 UTC 364d etcd-ca no
|
||||
etcd-server Dec 30, 2020 23:36 UTC 364d etcd-ca no
|
||||
front-proxy-client Dec 30, 2020 23:36 UTC 364d front-proxy-ca no
|
||||
scheduler.conf Dec 30, 2020 23:36 UTC 364d no
|
||||
|
||||
CERTIFICATE AUTHORITY EXPIRES RESIDUAL TIME EXTERNALLY MANAGED
|
||||
ca Dec 28, 2029 23:36 UTC 9y no
|
||||
etcd-ca Dec 28, 2029 23:36 UTC 9y no
|
||||
front-proxy-ca Dec 28, 2029 23:36 UTC 9y no
|
||||
```
|
||||
|
||||
이 명령은 `/etc/kubernetes/pki` 폴더의 클라이언트 인증서와 kubeadm이 사용하는 KUBECONFIG 파일(`admin.conf`, `controller-manager.conf` 및 `scheduler.conf`)에 포함된 클라이언트 인증서의 만료/잔여 기간을 표시한다.
|
||||
|
||||
또한, kubeadm은 인증서가 외부에서 관리되는지를 사용자에게 알린다. 이 경우 사용자는 수동으로 또는 다른 도구를 사용해서 인증서 갱신 관리를 해야 한다.
|
||||
|
||||
{{< warning >}}
|
||||
`kubeadm` 은 외부 CA가 서명한 인증서를 관리할 수 없다.
|
||||
{{< /warning >}}
|
||||
|
||||
{{< note >}}
|
||||
kubeadm은 자동 인증서 갱신을 위해 kubelet을 구성하기 때문에 `kubelet.conf` 는 위 목록에 포함되어 있지 않다.
|
||||
{{< /note >}}
|
||||
|
||||
{{< warning >}}
|
||||
kubeadm 1.17 이전의 버전에서 `kubeadm init` 으로 작성된 노드에는
|
||||
`kubelet.conf` 의 내용을 수동으로 수정해야 하는 [버그](https://github.com/kubernetes/kubeadm/issues/1753)가 있다. `kubeadm init` 수행 완료 후, `client-certificate-data` 및 `client-key-data` 를 다음과 같이 교체하여,
|
||||
로테이트된 kubelet 클라이언트 인증서를 가리키도록 `kubelet.conf` 를 업데이트해야 한다.
|
||||
|
||||
```yaml
|
||||
client-certificate: /var/lib/kubelet/pki/kubelet-client-current.pem
|
||||
client-key: /var/lib/kubelet/pki/kubelet-client-current.pem
|
||||
```
|
||||
{{< /warning >}}
|
||||
|
||||
## 자동 인증서 갱신
|
||||
|
||||
kubeadm은 컨트롤 플레인 [업그레이드](/ko/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/) 동안 모든 인증서를 갱신한다.
|
||||
|
||||
이 기능은 가장 간단한 유스케이스를 해결하기 위해 설계되었다.
|
||||
인증서 갱신에 대해 특별한 요구 사항이 없고 쿠버네티스 버전 업그레이드를 정기적으로(매 1년 이내 업그레이드 수행) 수행하는 경우, kubeadm은 클러스터를 최신 상태로 유지하고 합리적으로 보안을 유지한다.
|
||||
|
||||
{{< note >}}
|
||||
보안을 유지하려면 클러스터를 자주 업그레이드하는 것이 가장 좋다.
|
||||
{{< /note >}}
|
||||
|
||||
인증서 갱신에 대해 보다 복잡한 요구 사항이 있는 경우, `--certificate-renewal=false` 를 `kubeadm upgrade apply` 또는 `kubeadm upgrade node` 와 함께 사용하여 기본 동작이 수행되지 않도록 할 수 있다.
|
||||
|
||||
{{< warning >}}
|
||||
kubeadm 1.17 이전 버전에는 `kubeadm upgrade node` 명령에서
|
||||
`--certificate-renewal` 의 기본값이 `false` 인 [버그](https://github.com/kubernetes/kubeadm/issues/1818)가
|
||||
있다. 이 경우 `--certificate-renewal=true` 를 명시적으로 설정해야 한다.
|
||||
{{< /warning >}}
|
||||
|
||||
## 수동 인증서 갱신
|
||||
|
||||
`kubeadm alpha certs renew` 명령을 사용하여 언제든지 인증서를 수동으로 갱신할 수 있다.
|
||||
|
||||
이 명령은 `/etc/kubernetes/pki` 에 저장된 CA(또는 프론트 프록시 CA) 인증서와 키를 사용하여 갱신을 수행한다.
|
||||
|
||||
{{< warning >}}
|
||||
HA 클러스터를 실행 중인 경우, 모든 컨트롤 플레인 노드에서 이 명령을 실행해야 한다.
|
||||
{{< /warning >}}
|
||||
|
||||
{{< note >}}
|
||||
`alpha certs renew` 는 기존 인증서를 kubeadm-config 컨피그맵(ConfigMap) 대신 속성(공통 이름, 조직, SAN 등)의 신뢰할 수 있는 소스로 사용한다. 둘 다 동기화 상태를 유지하는 것을 강력히 권장한다.
|
||||
{{< /note >}}
|
||||
|
||||
`kubeadm alpha certs renew` 는 다음의 옵션을 제공한다.
|
||||
|
||||
쿠버네티스 인증서는 일반적으로 1년 후 만료일에 도달한다.
|
||||
|
||||
- `--csr-only` 는 실제로 인증서를 갱신하지 않고 인증서 서명 요청을 생성하여 외부 CA로 인증서를 갱신하는 데 사용할 수 있다. 자세한 내용은 다음 단락을 참고한다.
|
||||
|
||||
- 모든 인증서 대신 단일 인증서를 갱신할 수도 있다.
|
||||
|
||||
## 쿠버네티스 인증서 API를 사용하여 인증서 갱신
|
||||
|
||||
이 섹션에서는 쿠버네티스 인증서 API를 사용하여 수동 인증서 갱신을 실행하는 방법에 대한 자세한 정보를 제공한다.
|
||||
|
||||
{{< caution >}}
|
||||
조직의 인증서 인프라를 kubeadm으로 생성된 클러스터에 통합해야 하는 사용자를 위한 고급 주제이다. 기본 kubeadm 구성이 요구 사항을 충족하면 kubeadm이 인증서를 대신 관리하도록 해야 한다.
|
||||
{{< /caution >}}
|
||||
|
||||
### 서명자 설정
|
||||
|
||||
쿠버네티스 인증 기관(Certificate Authority)은 기본적으로 작동하지 않는다.
|
||||
[cert-manager][cert-manager-issuer] 와 같은 외부 서명자를 설정하거나, 빌트인 서명자를 사용할 수 있다.
|
||||
|
||||
빌트인 서명자는 [`kube-controller-manager`][kcm] 의 일부이다.
|
||||
|
||||
빌트인 서명자를 활성화하려면, `--cluster-signing-cert-file` 와 `--cluster-signing-key-file` 플래그를 전달해야 한다.
|
||||
|
||||
새 클러스터를 생성하는 경우, kubeadm [구성 파일][config]을 사용할 수 있다.
|
||||
|
||||
```yaml
|
||||
apiVersion: kubeadm.k8s.io/v1beta2
|
||||
kind: ClusterConfiguration
|
||||
controllerManager:
|
||||
extraArgs:
|
||||
cluster-signing-cert-file: /etc/kubernetes/pki/ca.crt
|
||||
cluster-signing-key-file: /etc/kubernetes/pki/ca.key
|
||||
```
|
||||
|
||||
[cert-manager-issuer]: https://docs.cert-manager.io/en/latest/tasks/issuers/setup-ca.html
|
||||
[kcm]: /docs/reference/command-line-tools-reference/kube-controller-manager/
|
||||
[config]: https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2
|
||||
|
||||
### 인증서 서명 요청(CSR) 생성
|
||||
|
||||
`kubeadm alpha certs renew --use-api` 로 쿠버네티스 인증서 API에 대한 인증서 서명 요청을 만들 수 있다.
|
||||
|
||||
[cert-manager][cert-manager] 와 같은 외부 서명자를 설정하면, 인증서 서명 요청(CSR)이 자동으로 승인된다.
|
||||
그렇지 않으면, [`kubectl certificate`][certs] 명령을 사용하여 인증서를 수동으로 승인해야 한다.
|
||||
다음의 kubeadm 명령은 승인할 인증서 이름을 출력한 다음, 승인이 발생하기를 차단하고 기다린다.
|
||||
|
||||
```shell
|
||||
sudo kubeadm alpha certs renew apiserver --use-api &
|
||||
```
|
||||
출력 결과는 다음과 비슷하다.
|
||||
```
|
||||
[1] 2890
|
||||
[certs] certificate request "kubeadm-cert-kube-apiserver-ld526" created
|
||||
```
|
||||
|
||||
### 인증서 서명 요청(CSR) 승인
|
||||
|
||||
외부 서명자를 설정하면, 인증서 서명 요청(CSR)이 자동으로 승인된다.
|
||||
|
||||
그렇지 않으면, [`kubectl certificate`][certs] 명령을 사용하여 인증서를 수동으로 승인해야 한다. 예를 들어 다음과 같다.
|
||||
|
||||
```shell
|
||||
kubectl certificate approve kubeadm-cert-kube-apiserver-ld526
|
||||
```
|
||||
출력 결과는 다음과 비슷하다.
|
||||
```shell
|
||||
certificatesigningrequest.certificates.k8s.io/kubeadm-cert-kube-apiserver-ld526 approved
|
||||
```
|
||||
|
||||
`kubectl get csr` 명령으로 보류 중인 인증서 목록을 볼 수 있다.
|
||||
|
||||
## 외부 CA로 인증서 갱신
|
||||
|
||||
이 섹션에서는 외부 CA를 사용하여 수동 인증서 갱신을 실행하는 방법에 대한 자세한 정보를 제공한다.
|
||||
|
||||
외부 CA와 보다 효과적으로 통합하기 위해 kubeadm은 인증서 서명 요청(CSR)을 생성할 수도 있다.
|
||||
CSR은 클라이언트의 서명된 인증서에 대한 CA 요청을 나타낸다.
|
||||
kubeadm 관점에서, 일반적으로 온-디스크(on-disk) CA에 의해 서명되는 모든 인증서는 CSR로 생성될 수 있다. 그러나 CA는 CSR로 생성될 수 없다.
|
||||
|
||||
### 인증서 서명 요청(CSR) 생성
|
||||
|
||||
`kubeadm alpha certs renew --csr-only` 로 인증서 서명 요청을 만들 수 있다.
|
||||
|
||||
CSR과 함께 제공되는 개인 키가 모두 출력된다.
|
||||
`--csr-dir` 로 사용할 디텍터리를 전달하여 지정된 위치로 CSR을 출력할 수 있다.
|
||||
`--csr-dir` 을 지정하지 않으면, 기본 인증서 디렉터리(`/etc/kubernetes/pki`)가 사용된다.
|
||||
|
||||
`kubeadm alpha certs renew --csr-only` 로 인증서를 갱신할 수 있다.
|
||||
`kubeadm init` 과 마찬가지로 출력 디렉터리를 `--csr-dir` 플래그로 지정할 수 있다.
|
||||
|
||||
CSR에는 인증서 이름, 도메인 및 IP가 포함되지만, 용도를 지정하지는 않는다.
|
||||
인증서를 발행할 때 [올바른 인증서 용도][cert-table]를 지정하는 것은 CA의 책임이다.
|
||||
|
||||
* `openssl` 의 경우 [`openssl ca` command][openssl-ca] 명령으로 수행한다.
|
||||
* `cfssl` 의 경우 [설정 파일에 용도][cfssl-usages]를 지정한다.
|
||||
|
||||
선호하는 방법으로 인증서에 서명한 후, 인증서와 개인 키를 PKI 디렉터리(기본적으로 `/etc/kubernetes/pki`)에 복사해야 한다.
|
||||
|
||||
[cert-manager]: https://github.com/jetstack/cert-manager
|
||||
[openssl-ca]: https://superuser.com/questions/738612/openssl-ca-keyusage-extension
|
||||
[cfssl-usages]: https://github.com/cloudflare/cfssl/blob/master/doc/cmd/cfssl.txt#L170
|
||||
[certs]: /ko/docs/setup/best-practices/certificates/
|
||||
[cert-cas]: /ko/docs/setup/best-practices/certificates/#단일-루트-ca
|
||||
[cert-table]: /ko/docs/setup/best-practices/certificates/#모든-인증서
|
||||
|
||||
{{% /capture %}}
|
|
@ -0,0 +1,93 @@
|
|||
---
|
||||
title: Windows 노드 업그레이드
|
||||
min-kubernetes-server-version: 1.17
|
||||
content_template: templates/task
|
||||
weight: 40
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
{{< feature-state for_k8s_version="v1.18" state="beta" >}}
|
||||
|
||||
이 페이지는 [kubeadm으로 생성된](/ko/docs/tasks/administer-cluster/kubeadm/adding-windows-nodes) Windows 노드를 업그레이드하는 방법을 설명한다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture prerequisites %}}
|
||||
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
|
||||
* [남은 kubeadm 클러스터를 업그레이드하는 프로세스](/ko/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade)에
|
||||
익숙해져야 한다. Windows 노드를
|
||||
업그레이드하기 전에 컨트롤 플레인 노드를 업그레이드해야 한다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture steps %}}
|
||||
|
||||
## 워커 노드 업그레이드
|
||||
|
||||
### kubeadm 업그레이드
|
||||
|
||||
1. Windows 노드에서, kubeadm을 업그레이드한다.
|
||||
|
||||
```powershell
|
||||
# replace {{< param "fullversion" >}} with your desired version
|
||||
curl.exe -Lo C:\k\kubeadm.exe https://dl.k8s.io/{{< param "fullversion" >}}/bin/windows/amd64/kubeadm.exe
|
||||
```
|
||||
|
||||
### 노드 드레인
|
||||
|
||||
1. 쿠버네티스 API에 접근할 수 있는 머신에서,
|
||||
스케줄 불가능한 것으로 표시하고 워크로드를 축출하여 유지 보수할 노드를 준비한다.
|
||||
|
||||
```shell
|
||||
# <node-to-drain>을 드레이닝하려는 노드 이름으로 바꾼다
|
||||
kubectl drain <node-to-drain> --ignore-daemonsets
|
||||
```
|
||||
|
||||
다음과 비슷한 출력이 표시되어야 한다.
|
||||
|
||||
```
|
||||
node/ip-172-31-85-18 cordoned
|
||||
node/ip-172-31-85-18 drained
|
||||
```
|
||||
|
||||
### kubelet 구성 업그레이드
|
||||
|
||||
1. Windows 노드에서, 다음의 명령을 호출하여 새 kubelet 구성을 동기화한다.
|
||||
|
||||
```powershell
|
||||
kubeadm upgrade node
|
||||
```
|
||||
|
||||
### kubelet 업그레이드
|
||||
|
||||
1. Windows 노드에서, kubelet을 업그레이드하고 다시 시작한다.
|
||||
|
||||
```powershell
|
||||
stop-service kubelet
|
||||
curl.exe -Lo C:\k\kubelet.exe https://dl.k8s.io/{{< param "fullversion" >}}/bin/windows/amd64/kubelet.exe
|
||||
restart-service kubelet
|
||||
```
|
||||
|
||||
### 노드에 적용된 cordon 해제
|
||||
|
||||
1. 쿠버네티스 API에 접근할 수 있는 머신에서,
|
||||
스케줄 가능으로 표시하여 노드를 다시 온라인으로 가져온다.
|
||||
|
||||
```shell
|
||||
# <node-to-drain>을 노드의 이름으로 바꾼다
|
||||
kubectl uncordon <node-to-drain>
|
||||
```
|
||||
### kube-proxy 업그레이드
|
||||
|
||||
1. 쿠버네티스 API에 접근할 수 있는 머신에서, 다음을 실행하여,
|
||||
{{< param "fullversion" >}}을 원하는 버전으로 다시 바꾼다.
|
||||
|
||||
```shell
|
||||
curl -L https://github.com/kubernetes-sigs/sig-windows-tools/releases/latest/download/kube-proxy.yml | sed 's/VERSION/{{< param "fullversion" >}}/g' | kubectl apply -f -
|
||||
```
|
||||
|
||||
|
||||
{{% /capture %}}
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: 메모리, CPU 와 API 리소스 관리
|
||||
weight: 20
|
||||
---
|
|
@ -0,0 +1,269 @@
|
|||
---
|
||||
title: 네임스페이스에 대한 CPU의 최소 및 최대 제약 조건 구성
|
||||
content_template: templates/task
|
||||
weight: 40
|
||||
---
|
||||
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
이 페이지는 네임스페이스에서 컨테이너와 파드가 사용하는 CPU 리소스의 최솟값과 최댓값을 설정하는
|
||||
방법을 보여준다. [리밋레인지(LimitRange)](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#limitrange-v1-core)
|
||||
오브젝트에 CPU의 최솟값과 최댓값을
|
||||
지정한다. 리밋레인지에 의해 부과된 제약 조건을 파드가 충족하지 않으면, 네임스페이스에서
|
||||
생성될 수 없다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture prerequisites %}}
|
||||
|
||||
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
|
||||
|
||||
태스크 예제를 실행하려면 클러스터에 적어도 1 CPU 이상이 사용 가능해야 한다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture steps %}}
|
||||
|
||||
## 네임스페이스 생성
|
||||
|
||||
이 연습에서 생성한 리소스가 클러스터의 나머지와
|
||||
격리되도록 네임스페이스를 생성한다.
|
||||
|
||||
```shell
|
||||
kubectl create namespace constraints-cpu-example
|
||||
```
|
||||
|
||||
## 리밋레인지와 파드 생성
|
||||
|
||||
다음은 리밋레인지에 대한 구성 파일이다.
|
||||
|
||||
{{< codenew file="admin/resource/cpu-constraints.yaml" >}}
|
||||
|
||||
리밋레인지를 생성한다.
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/admin/resource/cpu-constraints.yaml --namespace=constraints-cpu-example
|
||||
```
|
||||
|
||||
리밋레인지에 대한 자세한 정보를 본다.
|
||||
|
||||
```shell
|
||||
kubectl get limitrange cpu-min-max-demo-lr --output=yaml --namespace=constraints-cpu-example
|
||||
```
|
||||
|
||||
출력 결과는 예상대로 CPU의 최소와 최대 제약 조건을 보여준다. 그러나
|
||||
참고로 리밋레인지에 대한 구성 파일에 기본값을
|
||||
지정하지 않아도 자동으로 생성된다.
|
||||
|
||||
```yaml
|
||||
limits:
|
||||
- default:
|
||||
cpu: 800m
|
||||
defaultRequest:
|
||||
cpu: 800m
|
||||
max:
|
||||
cpu: 800m
|
||||
min:
|
||||
cpu: 200m
|
||||
type: Container
|
||||
```
|
||||
|
||||
이제 constraints-cpu-example 네임스페이스에 컨테이너가 생성될 때마다, 쿠버네티스는
|
||||
다음 단계를 수행한다.
|
||||
|
||||
* 컨테이너가 자체 CPU 요청량(request)과 상한(limit)을 지정하지 않으면, 컨테이너에
|
||||
CPU 요청량과 상한의 기본값(default)을 지정한다.
|
||||
|
||||
* 컨테이너가 200 millicpu 이상의 CPU 요청량을 지정하는지 확인한다.
|
||||
|
||||
* 컨테이너가 800 millicpu 이하의 CPU 상한을 지정하는지 확인한다.
|
||||
|
||||
{{< note >}}
|
||||
`LimitRange` 오브젝트를 생성할 때, huge-pages
|
||||
또는 GPU에도 상한을 지정할 수 있다. 그러나, 이 리소스들에 `default` 와 `defaultRequest` 가
|
||||
모두 지정되어 있으면, 두 값은 같아야 한다.
|
||||
{{< /note >}}
|
||||
|
||||
컨테이너가 하나인 파드의 구성 파일은 다음과 같다. 컨테이너 매니페스트는
|
||||
500 millicpu의 CPU 요청량 및 800 millicpu의 CPU 상한을 지정한다. 이는 리밋레인지에
|
||||
의해 부과된 CPU의 최소와 최대 제약 조건을 충족시킨다.
|
||||
|
||||
{{< codenew file="admin/resource/cpu-constraints-pod.yaml" >}}
|
||||
|
||||
파드를 생성한다.
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/admin/resource/cpu-constraints-pod.yaml --namespace=constraints-cpu-example
|
||||
```
|
||||
|
||||
파드의 컨테이너가 실행 중인지 확인한다.
|
||||
|
||||
```shell
|
||||
kubectl get pod constraints-cpu-demo --namespace=constraints-cpu-example
|
||||
```
|
||||
|
||||
파드에 대한 자세한 정보를 본다.
|
||||
|
||||
```shell
|
||||
kubectl get pod constraints-cpu-demo --output=yaml --namespace=constraints-cpu-example
|
||||
```
|
||||
|
||||
출력 결과는 컨테이너의 CPU 요청량이 500 millicpu이고, CPU 상한이 800 millicpu임을
|
||||
나타낸다. 이는 리밋레인지에 의해 부과된 제약 조건을 만족시킨다.
|
||||
|
||||
```yaml
|
||||
resources:
|
||||
limits:
|
||||
cpu: 800m
|
||||
requests:
|
||||
cpu: 500m
|
||||
```
|
||||
|
||||
## 파드 삭제
|
||||
|
||||
```shell
|
||||
kubectl delete pod constraints-cpu-demo --namespace=constraints-cpu-example
|
||||
```
|
||||
|
||||
## CPU 최대 제약 조건을 초과하는 파드 생성 시도
|
||||
|
||||
컨테이너가 하나인 파드의 구성 파일은 다음과 같다. 컨테이너는
|
||||
500 millicpu의 CPU 요청량과 1.5 cpu의 CPU 상한을 지정한다.
|
||||
|
||||
{{< codenew file="admin/resource/cpu-constraints-pod-2.yaml" >}}
|
||||
|
||||
파드 생성을 시도한다.
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/admin/resource/cpu-constraints-pod-2.yaml --namespace=constraints-cpu-example
|
||||
```
|
||||
|
||||
컨테이너가 너무 큰 CPU 상한을 지정하므로, 출력 결과에 파드가 생성되지 않은 것으로
|
||||
표시된다.
|
||||
|
||||
```
|
||||
Error from server (Forbidden): error when creating "examples/admin/resource/cpu-constraints-pod-2.yaml":
|
||||
pods "constraints-cpu-demo-2" is forbidden: maximum cpu usage per Container is 800m, but limit is 1500m.
|
||||
```
|
||||
|
||||
## 최소 CPU 요청량을 충족하지 않는 파드 생성 시도
|
||||
|
||||
컨테이너가 하나인 파드의 구성 파일은 다음과 같다. 컨테이너는
|
||||
100 millicpu의 CPU 요청량과 800 millicpu의 CPU 상한을 지정한다.
|
||||
|
||||
{{< codenew file="admin/resource/cpu-constraints-pod-3.yaml" >}}
|
||||
|
||||
파드 생성을 시도한다.
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/admin/resource/cpu-constraints-pod-3.yaml --namespace=constraints-cpu-example
|
||||
```
|
||||
|
||||
컨테이너가 너무 작은 CPU 요청량을 지정하므로, 출력 결과에 파드가 생성되지
|
||||
않은 것으로 표시된다.
|
||||
|
||||
```
|
||||
Error from server (Forbidden): error when creating "examples/admin/resource/cpu-constraints-pod-3.yaml":
|
||||
pods "constraints-cpu-demo-3" is forbidden: minimum cpu usage per Container is 200m, but request is 100m.
|
||||
```
|
||||
|
||||
## CPU 요청량 또는 상한을 지정하지 않은 파드 생성
|
||||
|
||||
컨테이너가 하나인 파드의 구성 파일은 다음과 같다. 컨테이너는
|
||||
CPU 요청량을 지정하지 않으며, CPU 상한을 지정하지 않는다.
|
||||
|
||||
{{< codenew file="admin/resource/cpu-constraints-pod-4.yaml" >}}
|
||||
|
||||
파드를 생성한다.
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/admin/resource/cpu-constraints-pod-4.yaml --namespace=constraints-cpu-example
|
||||
```
|
||||
|
||||
파드에 대한 자세한 정보를 본다.
|
||||
|
||||
```
|
||||
kubectl get pod constraints-cpu-demo-4 --namespace=constraints-cpu-example --output=yaml
|
||||
```
|
||||
|
||||
출력 결과는 파드의 컨테이너에 대한 CPU 요청량이 800 millicpu이고, CPU 상한이 800 millicpu임을 나타낸다.
|
||||
컨테이너는 어떻게 이런 값을 얻었을까?
|
||||
|
||||
```yaml
|
||||
resources:
|
||||
limits:
|
||||
cpu: 800m
|
||||
requests:
|
||||
cpu: 800m
|
||||
```
|
||||
|
||||
컨테이너가 자체 CPU 요청량과 상한을 지정하지 않았으므로, 리밋레인지로부터
|
||||
[CPU 요청량과 상한의 기본값](/ko/docs/tasks/administer-cluster/manage-resources/cpu-default-namespace/)이
|
||||
주어졌다.
|
||||
|
||||
이 시점에서, 컨테이너는 실행 중이거나 실행 중이 아닐 수 있다. 이 태스크의 전제 조건은 클러스터에 1 CPU 이상 사용 가능해야 한다는 것이다. 각 노드에 1 CPU만 있는 경우, 노드에 할당할 수 있는 CPU가 800 millicpu의 요청량을 수용하기에 충분하지 않을 수 있다. 2 CPU인 노드를 사용하는 경우에는, CPU가 800 millicpu 요청량을 수용하기에 충분할 것이다.
|
||||
|
||||
파드를 삭제한다.
|
||||
|
||||
```
|
||||
kubectl delete pod constraints-cpu-demo-4 --namespace=constraints-cpu-example
|
||||
```
|
||||
|
||||
## CPU의 최소 및 최대 제약 조건의 적용
|
||||
|
||||
리밋레인지에 의해 네임스페이스에 부과된 CPU의 최대 및 최소 제약 조건은
|
||||
파드를 생성하거나 업데이트할 때만 적용된다. 리밋레인지를 변경해도, 이전에 생성된 파드에는
|
||||
영향을 미치지 않는다.
|
||||
|
||||
## CPU의 최소 및 최대 제약 조건에 대한 동기
|
||||
|
||||
클러스터 관리자는 파드가 사용할 수 있는 CPU 리소스에 제한을 둘 수 있다.
|
||||
예를 들면 다음과 같다.
|
||||
|
||||
* 클러스터의 각 노드에는 2 CPU가 있다. 클러스터의 어떤 노드도 요청량을 지원할 수 없기 때문에,
|
||||
2 CPU 이상을 요청하는 파드를 수락하지 않으려고 한다.
|
||||
|
||||
* 클러스터는 프로덕션과 개발 부서에서 공유한다.
|
||||
프로덕션 워크로드가 최대 3 CPU를 소비하도록 하고 싶지만, 개발 워크로드는 1 CPU로
|
||||
제한하려고 한다. 프로덕션과 개발을 위해 별도의 네임스페이스를 생성하고, 각 네임스페이스에 CPU 제약 조건을
|
||||
적용한다.
|
||||
|
||||
## 정리
|
||||
|
||||
네임스페이스를 삭제한다.
|
||||
|
||||
```shell
|
||||
kubectl delete namespace constraints-cpu-example
|
||||
```
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
|
||||
### 클러스터 관리자를 위한 문서
|
||||
|
||||
* [네임스페이스에 대한 기본 메모리 요청량과 상한 구성](/ko/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/)
|
||||
|
||||
* [네임스페이스에 대한 기본 CPU 요청량과 상한 구성](/ko/docs/tasks/administer-cluster/manage-resources/cpu-default-namespace/)
|
||||
|
||||
* [네임스페이스에 대한 메모리의 최소 및 최대 제약 조건 구성](/ko/docs/tasks/administer-cluster/manage-resources/memory-constraint-namespace/)
|
||||
|
||||
* [네임스페이스에 대한 메모리 및 CPU 쿼터 구성](/ko/docs/tasks/administer-cluster/manage-resources/quota-memory-cpu-namespace/)
|
||||
|
||||
* [네임스페이스에 대한 파드 쿼터 구성](/ko/docs/tasks/administer-cluster/manage-resources/quota-pod-namespace/)
|
||||
|
||||
* [API 오브젝트에 대한 쿼터 구성](/docs/tasks/administer-cluster/quota-api-object/)
|
||||
|
||||
### 앱 개발자를 위한 문서
|
||||
|
||||
* [컨테이너 및 파드 메모리 리소스 할당](/ko/docs/tasks/configure-pod-container/assign-memory-resource/)
|
||||
|
||||
* [컨테이너와 파드 CPU 리소스 할당](/docs/tasks/configure-pod-container/assign-cpu-resource/)
|
||||
|
||||
* [파드에 대한 서비스 품질(QoS) 구성](/docs/tasks/configure-pod-container/quality-service-pod/)
|
||||
|
||||
|
||||
{{% /capture %}}
|
|
@ -0,0 +1,191 @@
|
|||
---
|
||||
title: 네임스페이스에 대한 기본 CPU 요청량과 상한 구성
|
||||
content_template: templates/task
|
||||
weight: 20
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
이 페이지는 네임스페이스에 대한 기본 CPU 요청량(request) 및 상한(limit)을 구성하는 방법을 보여준다.
|
||||
쿠버네티스 클러스터는 네임스페이스로 나눌 수 있다. 기본 CPU 상한이 있는 네임스페이스에서
|
||||
컨테이너가 생성되고, 컨테이너가 자체 CPU 상한을 지정하지 않으면,
|
||||
컨테이너에 기본 CPU 상한이 할당된다. 쿠버네티스는 이 문서의 뒷부분에서
|
||||
설명하는 특정 조건에서 기본 CPU 요청량을 할당한다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture prerequisites %}}
|
||||
|
||||
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture steps %}}
|
||||
|
||||
## 네임스페이스 생성
|
||||
|
||||
이 연습에서 생성한 리소스가 클러스터의 나머지와
|
||||
격리되도록 네임스페이스를 생성한다.
|
||||
|
||||
```shell
|
||||
kubectl create namespace default-cpu-example
|
||||
```
|
||||
|
||||
## 리밋레인지(LimitRange)와 파드 생성
|
||||
|
||||
다음은 리밋레인지 오브젝트의 구성 파일이다. 구성은
|
||||
기본 CPU 요청량 및 기본 CPU 상한을 지정한다.
|
||||
|
||||
{{< codenew file="admin/resource/cpu-defaults.yaml" >}}
|
||||
|
||||
default-cpu-example 네임스페이스에 리밋레인지를 생성한다.
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/admin/resource/cpu-defaults.yaml --namespace=default-cpu-example
|
||||
```
|
||||
|
||||
이제 컨테이너가 default-cpu-example 네임스페이스에 생성되고,
|
||||
컨테이너가 CPU 요청량 및 CPU 상한에 대해 고유한 값을 지정하지 않으면,
|
||||
컨테이너에 CPU 요청량의 기본값 0.5와 CPU 상한
|
||||
기본값 1이 부여된다.
|
||||
|
||||
컨테이너가 하나인 파드의 구성 파일은 다음과 같다. 컨테이너는
|
||||
CPU 요청량과 상한을 지정하지 않는다.
|
||||
|
||||
{{< codenew file="admin/resource/cpu-defaults-pod.yaml" >}}
|
||||
|
||||
파드를 생성한다.
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/admin/resource/cpu-defaults-pod.yaml --namespace=default-cpu-example
|
||||
```
|
||||
|
||||
파드의 사양을 확인한다.
|
||||
|
||||
```shell
|
||||
kubectl get pod default-cpu-demo --output=yaml --namespace=default-cpu-example
|
||||
```
|
||||
|
||||
출력 결과는 파드의 컨테이너에 500 milicpu의 CPU 요청량과
|
||||
1 cpu의 CPU 상한이 있음을 나타낸다. 이것은 리밋레인지에 의해 지정된 기본값이다.
|
||||
|
||||
```shell
|
||||
containers:
|
||||
- image: nginx
|
||||
imagePullPolicy: Always
|
||||
name: default-cpu-demo-ctr
|
||||
resources:
|
||||
limits:
|
||||
cpu: "1"
|
||||
requests:
|
||||
cpu: 500m
|
||||
```
|
||||
|
||||
## 컨테이너 상한은 지정하고, 요청량을 지정하지 않으면 어떻게 되나?
|
||||
|
||||
컨테이너가 하나인 파드의 구성 파일은 다음과 같다. 컨테이너는
|
||||
CPU 상한을 지정하지만, 요청량은 지정하지 않는다.
|
||||
|
||||
{{< codenew file="admin/resource/cpu-defaults-pod-2.yaml" >}}
|
||||
|
||||
파드를 생성한다.
|
||||
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/admin/resource/cpu-defaults-pod-2.yaml --namespace=default-cpu-example
|
||||
```
|
||||
|
||||
파드 사양을 확인한다.
|
||||
|
||||
```
|
||||
kubectl get pod default-cpu-demo-2 --output=yaml --namespace=default-cpu-example
|
||||
```
|
||||
|
||||
출력 결과는 컨테이너의 CPU 요청량이 CPU 상한과 일치하도록 설정되었음을 보여준다.
|
||||
참고로 컨테이너에는 CPU 요청량의 기본값인 0.5 cpu가 할당되지 않았다.
|
||||
|
||||
```
|
||||
resources:
|
||||
limits:
|
||||
cpu: "1"
|
||||
requests:
|
||||
cpu: "1"
|
||||
```
|
||||
|
||||
## 컨테이너의 요청량은 지정하고, 상한을 지정하지 않으면 어떻게 되나?
|
||||
|
||||
컨테이너가 하나인 파드의 구성 파일은 다음과 같다. 컨테이너는
|
||||
CPU 요청량을 지정하지만, 상한은 지정하지 않았다.
|
||||
|
||||
{{< codenew file="admin/resource/cpu-defaults-pod-3.yaml" >}}
|
||||
|
||||
파드를 생성한다.
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/admin/resource/cpu-defaults-pod-3.yaml --namespace=default-cpu-example
|
||||
```
|
||||
|
||||
파드 사양을 확인한다.
|
||||
|
||||
```
|
||||
kubectl get pod default-cpu-demo-3 --output=yaml --namespace=default-cpu-example
|
||||
```
|
||||
|
||||
출력 결과는 컨테이너의 CPU 요청량이 컨테이너의 구성 파일에 지정된 값으로
|
||||
설정되었음을 보여준다. 컨테이너의 CPU 상한은 1 cpu로 설정되며, 이는
|
||||
네임스페이스의 CPU 상한 기본값이다.
|
||||
|
||||
```
|
||||
resources:
|
||||
limits:
|
||||
cpu: "1"
|
||||
requests:
|
||||
cpu: 750m
|
||||
```
|
||||
|
||||
## CPU 상한 및 요청량의 기본값에 대한 동기
|
||||
|
||||
네임스페이스에 [리소스 쿼터](/ko/docs/tasks/administer-cluster/manage-resources/quota-memory-cpu-namespace/)가 있는 경우,
|
||||
CPU 상한에 대해 기본값을 설정하는 것이 좋다.
|
||||
다음은 리소스 쿼터가 네임스페이스에 적용하는 두 가지 제한 사항이다.
|
||||
|
||||
* 네임스페이스에서 실행되는 모든 컨테이너에는 자체 CPU 상한이 있어야 한다.
|
||||
* 네임스페이스의 모든 컨테이너가 사용하는 총 CPU 양은 지정된 상한을 초과하지 않아야 한다.
|
||||
|
||||
컨테이너가 자체 CPU 상한을 지정하지 않으면, 상한 기본값이 부여되고, 쿼터에
|
||||
의해 제한되는 네임스페이스에서 실행될 수 있다.
|
||||
|
||||
## 정리
|
||||
|
||||
네임스페이스를 삭제한다.
|
||||
|
||||
```shell
|
||||
kubectl delete namespace default-cpu-example
|
||||
```
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
|
||||
### 클러스터 관리자를 위한 문서
|
||||
|
||||
* [네임스페이스에 대한 기본 메모리 요청량과 상한 구성](/ko/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/)
|
||||
|
||||
* [네임스페이스에 대한 메모리의 최소 및 최대 제약 조건 구성](/ko/docs/tasks/administer-cluster/manage-resources/memory-constraint-namespace/)
|
||||
|
||||
* [네임스페이스에 대한 CPU의 최소 및 최대 제약 조건 구성](/ko/docs/tasks/administer-cluster/manage-resources/cpu-constraint-namespace/)
|
||||
|
||||
* [네임스페이스에 대한 메모리 및 CPU 쿼터 구성](/ko/docs/tasks/administer-cluster/manage-resources/quota-memory-cpu-namespace/)
|
||||
|
||||
* [네임스페이스에 대한 파드 쿼터 구성](/ko/docs/tasks/administer-cluster/manage-resources/quota-pod-namespace/)
|
||||
|
||||
* [API 오브젝트에 대한 쿼터 구성](/docs/tasks/administer-cluster/quota-api-object/)
|
||||
|
||||
### 앱 개발자를 위한 문서
|
||||
|
||||
* [컨테이너 및 파드 메모리 리소스 할당](/ko/docs/tasks/configure-pod-container/assign-memory-resource/)
|
||||
|
||||
* [컨테이너 및 파드 CPU 리소스 할당](/docs/tasks/configure-pod-container/assign-cpu-resource/)
|
||||
|
||||
* [파드에 대한 서비스 품질(QoS) 구성](/docs/tasks/configure-pod-container/quality-service-pod/)
|
||||
|
||||
{{% /capture %}}
|
|
@ -0,0 +1,268 @@
|
|||
---
|
||||
title: 네임스페이스에 대한 메모리의 최소 및 최대 제약 조건 구성
|
||||
content_template: templates/task
|
||||
weight: 30
|
||||
---
|
||||
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
이 페이지는 네임스페이스에서 실행되는 컨테이너가 사용하는 메모리의 최솟값과 최댓값을
|
||||
설정하는 방법을 보여준다. [리밋레인지(LimitRange)](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#limitrange-v1-core)
|
||||
오브젝트에 최소 및 최대 메모리 값을
|
||||
지정한다. 파드가 리밋레인지에 의해 부과된 제약 조건을 충족하지 않으면,
|
||||
네임스페이스에서 생성될 수 없다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture prerequisites %}}
|
||||
|
||||
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
|
||||
|
||||
클러스터의 각 노드에는 최소 1GiB의 메모리가 있어야 한다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture steps %}}
|
||||
|
||||
## 네임스페이스 생성
|
||||
|
||||
이 연습에서 생성한 리소스가 클러스터의 나머지와
|
||||
격리되도록 네임스페이스를 생성한다.
|
||||
|
||||
```shell
|
||||
kubectl create namespace constraints-mem-example
|
||||
```
|
||||
|
||||
## 리밋레인지와 파드 생성
|
||||
|
||||
다음은 리밋레인지의 구성 파일이다.
|
||||
|
||||
{{< codenew file="admin/resource/memory-constraints.yaml" >}}
|
||||
|
||||
리밋레인지를 생성한다.
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/admin/resource/memory-constraints.yaml --namespace=constraints-mem-example
|
||||
```
|
||||
|
||||
리밋레인지에 대한 자세한 정보를 본다.
|
||||
|
||||
```shell
|
||||
kubectl get limitrange mem-min-max-demo-lr --namespace=constraints-mem-example --output=yaml
|
||||
```
|
||||
|
||||
출력 결과는 예상대로 메모리의 최소 및 최대 제약 조건을 보여준다. 그러나
|
||||
참고로 리밋레인지의 구성 파일에 기본값(default)을
|
||||
지정하지 않아도 자동으로 생성된다.
|
||||
|
||||
```
|
||||
limits:
|
||||
- default:
|
||||
memory: 1Gi
|
||||
defaultRequest:
|
||||
memory: 1Gi
|
||||
max:
|
||||
memory: 1Gi
|
||||
min:
|
||||
memory: 500Mi
|
||||
type: Container
|
||||
```
|
||||
|
||||
이제 constraints-mem-example 네임스페이스에 컨테이너가 생성될 때마다, 쿠버네티스는
|
||||
다음 단계를 수행한다.
|
||||
|
||||
* 컨테이너가 자체 메모리 요청량(request)과 상한(limit)을 지정하지 않으면, 기본 메모리 요청량과
|
||||
상한을 컨테이너에 지정한다.
|
||||
|
||||
* 컨테이너에 500MiB 이상의 메모리 요청량이 있는지 확인한다.
|
||||
|
||||
* 컨테이너의 메모리 상한이 1GiB 이하인지 확인한다.
|
||||
|
||||
컨테이너가 하나인 파드의 구성 파일은 다음과 같다. 컨테이너 매니페스트는
|
||||
600MiB의 메모리 요청량과 800MiB의 메모리 상한을 지정한다. 이들은
|
||||
리밋레인지에 의해 부과된 메모리의 최소 및 최대 제약 조건을 충족한다.
|
||||
|
||||
{{< codenew file="admin/resource/memory-constraints-pod.yaml" >}}
|
||||
|
||||
파드를 생성한다.
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/admin/resource/memory-constraints-pod.yaml --namespace=constraints-mem-example
|
||||
```
|
||||
|
||||
파드의 컨테이너가 실행 중인지 확인한다.
|
||||
|
||||
```shell
|
||||
kubectl get pod constraints-mem-demo --namespace=constraints-mem-example
|
||||
```
|
||||
|
||||
파드에 대한 자세한 정보를 본다.
|
||||
|
||||
```shell
|
||||
kubectl get pod constraints-mem-demo --output=yaml --namespace=constraints-mem-example
|
||||
```
|
||||
|
||||
출력 결과는 컨테이너의 메모리 요청량이 600MiB이고 메모리 상한이 800MiB임을
|
||||
나타낸다. 이는 리밋레인지에 의해 부과된 제약 조건을 충족한다.
|
||||
|
||||
```yaml
|
||||
resources:
|
||||
limits:
|
||||
memory: 800Mi
|
||||
requests:
|
||||
memory: 600Mi
|
||||
```
|
||||
|
||||
파드를 삭제한다.
|
||||
|
||||
```shell
|
||||
kubectl delete pod constraints-mem-demo --namespace=constraints-mem-example
|
||||
```
|
||||
|
||||
## 최대 메모리 제약 조건을 초과하는 파드 생성 시도
|
||||
|
||||
컨테이너가 하나인 파드의 구성 파일은 다음과 같다. 컨테이너는
|
||||
800MiB의 메모리 요청량과 1.5GiB의 메모리 상한을 지정한다.
|
||||
|
||||
{{< codenew file="admin/resource/memory-constraints-pod-2.yaml" >}}
|
||||
|
||||
파드 생성을 시도한다.
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/admin/resource/memory-constraints-pod-2.yaml --namespace=constraints-mem-example
|
||||
```
|
||||
|
||||
컨테이너가 너무 큰 메모리 상한을 지정하므로, 출력 결과에 파드가 생성되지 않은 것으로
|
||||
표시된다.
|
||||
|
||||
```
|
||||
Error from server (Forbidden): error when creating "examples/admin/resource/memory-constraints-pod-2.yaml":
|
||||
pods "constraints-mem-demo-2" is forbidden: maximum memory usage per Container is 1Gi, but limit is 1536Mi.
|
||||
```
|
||||
|
||||
## 최소 메모리 요청량을 충족하지 않는 파드 생성 시도
|
||||
|
||||
컨테이너가 하나인 파드의 구성 파일은 다음과 같다. 컨테이너는
|
||||
100MiB의 메모리 요청량과 800MiB의 메모리 상한을 지정한다.
|
||||
|
||||
{{< codenew file="admin/resource/memory-constraints-pod-3.yaml" >}}
|
||||
|
||||
파드 생성을 시도한다.
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/admin/resource/memory-constraints-pod-3.yaml --namespace=constraints-mem-example
|
||||
```
|
||||
|
||||
컨테이너가 너무 작은 메모리 요청량을 지정하므로, 출력 결과에 파드가 생성되지
|
||||
않은 것으로 표시된다.
|
||||
|
||||
```
|
||||
Error from server (Forbidden): error when creating "examples/admin/resource/memory-constraints-pod-3.yaml":
|
||||
pods "constraints-mem-demo-3" is forbidden: minimum memory usage per Container is 500Mi, but request is 100Mi.
|
||||
```
|
||||
|
||||
## 메모리 요청량 또는 상한을 지정하지 않은 파드 생성
|
||||
|
||||
|
||||
|
||||
컨테이너가 하나인 파드의 구성 파일은 다음과 같다. 컨테이너는
|
||||
메모리 요청량을 지정하지 않으며, 메모리 상한을 지정하지 않는다.
|
||||
|
||||
{{< codenew file="admin/resource/memory-constraints-pod-4.yaml" >}}
|
||||
|
||||
파드를 생성한다.
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/admin/resource/memory-constraints-pod-4.yaml --namespace=constraints-mem-example
|
||||
```
|
||||
|
||||
파드에 대한 자세한 정보를 본다.
|
||||
|
||||
```
|
||||
kubectl get pod constraints-mem-demo-4 --namespace=constraints-mem-example --output=yaml
|
||||
```
|
||||
|
||||
출력 결과는 파드의 컨테이너에 1GiB의 메모리 요청량과 1GiB의 메모리 상한이 있음을 보여준다.
|
||||
컨테이너는 이러한 값을 어떻게 얻었을까?
|
||||
|
||||
```
|
||||
resources:
|
||||
limits:
|
||||
memory: 1Gi
|
||||
requests:
|
||||
memory: 1Gi
|
||||
```
|
||||
|
||||
컨테이너가 자체 메모리 요청량과 상한을 지정하지 않았으므로,
|
||||
리밋레인지의 [메모리의 요청량과 상한 기본값](/ko/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/)이
|
||||
제공되었다.
|
||||
|
||||
이 시점에서, 컨테이너가 실행 중이거나 실행 중이 아닐 수 있다. 이 태스크의 전제 조건은
|
||||
노드에 최소 1GiB의 메모리가 있어야 한다는 것이다. 각 노드에
|
||||
1GiB의 메모리만 있는 경우, 노드에 할당할 수 있는 메모리가 1GiB의 메모리 요청량을 수용하기에 충분하지
|
||||
않을 수 있다. 메모리가 2GiB인 노드를 사용하는 경우에는, 메모리가
|
||||
1GiB 요청량을 수용하기에 충분할 것이다.
|
||||
|
||||
파드를 삭제한다.
|
||||
|
||||
```
|
||||
kubectl delete pod constraints-mem-demo-4 --namespace=constraints-mem-example
|
||||
```
|
||||
|
||||
## 메모리의 최소 및 최대 제약 조건 적용
|
||||
|
||||
리밋레인지에 의해 네임스페이스에 부과된 메모리의 최대 및 최소 제약 조건은
|
||||
파드를 생성하거나 업데이트할 때만 적용된다. 리밋레인지를 변경해도, 이전에 생성된
|
||||
파드에는 영향을 미치지 않는다.
|
||||
|
||||
## 메모리의 최소 및 최대 제약 조건에 대한 동기
|
||||
|
||||
클러스터 관리자는 파드가 사용할 수 있는 메모리 양에 제한을 둘 수 있다.
|
||||
예를 들면 다음과 같다.
|
||||
|
||||
* 클러스터의 각 노드에는 2GB의 메모리가 있다. 클러스터의 어떤 노드도 2GB 이상의 요청량을
|
||||
지원할 수 없으므로, 2GB 이상의 메모리를 요청하는 파드를 수락하지 않으려고 한다.
|
||||
|
||||
* 클러스터는 운영 부서와 개발 부서에서 공유한다.
|
||||
프로덕션 워크로드가 최대 8GB의 메모리를 소비하도록 하려면,
|
||||
개발 워크로드를 512MB로 제한해야 한다. 프로덕션 및 개발을 위해
|
||||
별도의 네임스페이스를 만들고, 각 네임스페이스에 메모리 제약 조건을 적용한다.
|
||||
|
||||
## 정리
|
||||
|
||||
네임스페이스를 삭제한다.
|
||||
|
||||
```shell
|
||||
kubectl delete namespace constraints-mem-example
|
||||
```
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
|
||||
### 클러스터 관리자를 위한 문서
|
||||
|
||||
* [네임스페이스에 대한 기본 메모리 요청량과 상한 구성](/ko/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/)
|
||||
|
||||
* [네임스페이스에 대한 기본 CPU 요청량과 상한 구성](/ko/docs/tasks/administer-cluster/manage-resources/cpu-default-namespace/)
|
||||
|
||||
* [네임스페이스에 대한 CPU의 최소 및 최대 제약 조건 구성](/ko/docs/tasks/administer-cluster/manage-resources/cpu-constraint-namespace/)
|
||||
|
||||
* [네임스페이스에 대한 메모리 및 CPU 쿼터 구성](/ko/docs/tasks/administer-cluster/manage-resources/quota-memory-cpu-namespace/)
|
||||
|
||||
* [네임스페이스에 대한 파드 쿼터 구성](/ko/docs/tasks/administer-cluster/manage-resources/quota-pod-namespace/)
|
||||
|
||||
* [API 오브젝트에 대한 쿼터 구성](/docs/tasks/administer-cluster/quota-api-object/)
|
||||
|
||||
### 앱 개발자를 위한 문서
|
||||
|
||||
* [컨테이너 및 파드 메모리 리소스 할당](/ko/docs/tasks/configure-pod-container/assign-memory-resource/)
|
||||
|
||||
* [컨테이너 및 파드 CPU 리소스 할당](/docs/tasks/configure-pod-container/assign-cpu-resource/)
|
||||
|
||||
* [파드에 대한 서비스 품질(QoS) 구성](/docs/tasks/configure-pod-container/quality-service-pod/)
|
||||
|
||||
{{% /capture %}}
|
|
@ -0,0 +1,199 @@
|
|||
---
|
||||
title: 네임스페이스에 대한 기본 메모리 요청량과 상한 구성
|
||||
content_template: templates/task
|
||||
weight: 10
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
이 페이지는 네임스페이스에 대한 기본 메모리 요청량(request)과 상한(limit)을 구성하는 방법을 보여준다.
|
||||
기본 메모리 상한이 있는 네임스페이스에서 컨테이너가 생성되고, 컨테이너가
|
||||
자체 메모리 상한을 지정하지 않으면, 컨테이너에 기본 메모리 상한이 할당된다.
|
||||
쿠버네티스는 이 문서의 뒷부분에서 설명하는 특정 조건에서 기본 메모리 요청량을 할당한다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture prerequisites %}}
|
||||
|
||||
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
|
||||
|
||||
클러스터의 각 노드에는 최소 2GiB의 메모리가 있어야 한다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture steps %}}
|
||||
|
||||
## 네임스페이스 생성
|
||||
|
||||
이 연습에서 생성한 리소스가 클러스터의 다른 리소스와
|
||||
격리되도록 네임스페이스를 생성한다.
|
||||
|
||||
```shell
|
||||
kubectl create namespace default-mem-example
|
||||
```
|
||||
|
||||
## 리밋레인지(LimitRange)와 파드 생성
|
||||
|
||||
다음은 리밋레인지 오브젝트의 구성 파일이다. 구성은
|
||||
메모리 요청량 기본값(default)과 메모리 상한 기본값을 지정한다.
|
||||
|
||||
{{< codenew file="admin/resource/memory-defaults.yaml" >}}
|
||||
|
||||
default-mem-example 네임스페이스에 리밋레인지를 생성한다.
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/admin/resource/memory-defaults.yaml --namespace=default-mem-example
|
||||
```
|
||||
|
||||
이제 컨테이너가 default-mem-example 네임스페이스에 생성되고,
|
||||
컨테이너가 메모리 요청량 및 메모리 상한에 대해 고유한 값을 지정하지 않으면,
|
||||
컨테이너에 메모리 요청량 기본값 256MiB와 메모리 상한 기본값
|
||||
512MiB가 지정된다.
|
||||
|
||||
컨테이너가 하나인 파드의 구성 파일은 다음과 같다. 컨테이너는
|
||||
메모리 요청량 및 상한을 지정하지 않는다.
|
||||
|
||||
{{< codenew file="admin/resource/memory-defaults-pod.yaml" >}}
|
||||
|
||||
파드를 생성한다.
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/admin/resource/memory-defaults-pod.yaml --namespace=default-mem-example
|
||||
```
|
||||
|
||||
파드에 대한 자세한 정보를 본다.
|
||||
|
||||
```shell
|
||||
kubectl get pod default-mem-demo --output=yaml --namespace=default-mem-example
|
||||
```
|
||||
|
||||
출력 결과는 파드의 컨테이너에 256MiB의 메모리 요청량과
|
||||
512MiB의 메모리 상한이 있음을 나타낸다. 이것은 리밋레인지에 의해 지정된 기본값이다.
|
||||
|
||||
```shell
|
||||
containers:
|
||||
- image: nginx
|
||||
imagePullPolicy: Always
|
||||
name: default-mem-demo-ctr
|
||||
resources:
|
||||
limits:
|
||||
memory: 512Mi
|
||||
requests:
|
||||
memory: 256Mi
|
||||
```
|
||||
|
||||
파드를 삭제한다.
|
||||
|
||||
```shell
|
||||
kubectl delete pod default-mem-demo --namespace=default-mem-example
|
||||
```
|
||||
|
||||
## 컨테이너 상한은 지정하고, 요청량을 지정하지 않으면 어떻게 되나?
|
||||
|
||||
컨테이너가 하나인 파드의 구성 파일은 다음과 같다. 컨테이너는
|
||||
메모리 상한을 지정하지만, 요청량은 지정하지 않는다.
|
||||
|
||||
{{< codenew file="admin/resource/memory-defaults-pod-2.yaml" >}}
|
||||
|
||||
파드를 생성한다.
|
||||
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/admin/resource/memory-defaults-pod-2.yaml --namespace=default-mem-example
|
||||
```
|
||||
|
||||
파드에 대한 자세한 정보를 본다.
|
||||
|
||||
```shell
|
||||
kubectl get pod default-mem-demo-2 --output=yaml --namespace=default-mem-example
|
||||
```
|
||||
|
||||
출력 결과는 컨테이너의 메모리 요청량이 메모리 상한과 일치하도록 설정되었음을 보여준다.
|
||||
참고로 컨테이너에는 기본 메모리 요청량의 값인 256Mi가 할당되지 않았다.
|
||||
|
||||
```
|
||||
resources:
|
||||
limits:
|
||||
memory: 1Gi
|
||||
requests:
|
||||
memory: 1Gi
|
||||
```
|
||||
|
||||
## 컨테이너의 요청량은 지정하고, 상한을 지정하지 않으면 어떻게 되나?
|
||||
|
||||
컨테이너가 하나인 파드의 구성 파일은 다음과 같다. 컨테이너는
|
||||
메모리 요청량을 지정하지만, 상한은 지정하지 않았다.
|
||||
|
||||
{{< codenew file="admin/resource/memory-defaults-pod-3.yaml" >}}
|
||||
|
||||
파드를 생성한다.
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/admin/resource/memory-defaults-pod-3.yaml --namespace=default-mem-example
|
||||
```
|
||||
|
||||
파드 사양을 확인한다.
|
||||
|
||||
```shell
|
||||
kubectl get pod default-mem-demo-3 --output=yaml --namespace=default-mem-example
|
||||
```
|
||||
|
||||
출력 결과는 컨테이너의 메모리 요청량이 컨테이너의 구성 파일에 지정된 값으로
|
||||
설정되었음을 보여준다. 컨테이너의 메모리 상한은 네임스페이스의
|
||||
기본 메모리 상한인 512Mi로 설정되어 있다.
|
||||
|
||||
```
|
||||
resources:
|
||||
limits:
|
||||
memory: 512Mi
|
||||
requests:
|
||||
memory: 128Mi
|
||||
```
|
||||
|
||||
## 기본 메모리 상한 및 요청량에 대한 동기
|
||||
|
||||
네임스페이스에 리소스 쿼터가 있는 경우,
|
||||
메모리 상한에 기본값을 설정하는 것이 좋다.
|
||||
다음은 리소스 쿼터가 네임스페이스에 적용하는 두 가지 제한 사항이다.
|
||||
|
||||
* 네임스페이스에서 실행되는 모든 컨테이너에는 자체 메모리 상한이 있어야 한다.
|
||||
* 네임스페이스의 모든 컨테이너가 사용하는 총 메모리 양은 지정된 상한을 초과하지 않아야 한다.
|
||||
|
||||
컨테이너가 자체 메모리 상한을 지정하지 않으면, 기본 상한이 부여되고,
|
||||
쿼터에 의해 제한되는 네임스페이스에서 실행될 수 있다.
|
||||
|
||||
## 정리
|
||||
|
||||
네임스페이스를 삭제한다.
|
||||
|
||||
```shell
|
||||
kubectl delete namespace default-mem-example
|
||||
```
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
|
||||
### 클러스터 관리자를 위한 문서
|
||||
|
||||
* [네임스페이스에 대한 기본 CPU 요청량과 상한 구성](/ko/docs/tasks/administer-cluster/manage-resources/cpu-default-namespace/)
|
||||
|
||||
* [네임스페이스에 대한 메모리의 최소 및 최대 제약 조건 구성](/ko/docs/tasks/administer-cluster/manage-resources/memory-constraint-namespace/)
|
||||
|
||||
* [네임스페이스에 대한 CPU의 최소 및 최대 제약 조건 구성](/ko/docs/tasks/administer-cluster/manage-resources/cpu-constraint-namespace/)
|
||||
|
||||
* [네임스페이스에 대한 메모리 및 CPU 쿼터 구성](/ko/docs/tasks/administer-cluster/manage-resources/quota-memory-cpu-namespace/)
|
||||
|
||||
* [네임스페이스에 대한 파드 쿼터 구성](/ko/docs/tasks/administer-cluster/manage-resources/quota-pod-namespace/)
|
||||
|
||||
* [API 오브젝트에 대한 쿼터 구성](/docs/tasks/administer-cluster/quota-api-object/)
|
||||
|
||||
### 앱 개발자를 위한 문서
|
||||
|
||||
* [컨테이너 및 파드 메모리 리소스 할당](/ko/docs/tasks/configure-pod-container/assign-memory-resource/)
|
||||
|
||||
* [컨테이너 및 파드 CPU 리소스 할당](/docs/tasks/configure-pod-container/assign-cpu-resource/)
|
||||
|
||||
* [파드에 대한 서비스 품질(QoS) 구성](/docs/tasks/configure-pod-container/quality-service-pod/)
|
||||
|
||||
{{% /capture %}}
|
|
@ -0,0 +1,175 @@
|
|||
---
|
||||
title: 네임스페이스에 대한 메모리 및 CPU 쿼터 구성
|
||||
content_template: templates/task
|
||||
weight: 50
|
||||
---
|
||||
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
이 페이지는 네임스페이스에서 실행 중인 모든 컨테이너가 사용할 수 있는
|
||||
총 메모리 및 CPU 양에 대한 쿼터를 설정하는 방법을 보여준다.
|
||||
[리소스쿼터(ResourceQuota)](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#resourcequota-v1-core)
|
||||
오브젝트에 쿼터를 지정한다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture prerequisites %}}
|
||||
|
||||
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
|
||||
|
||||
클러스터의 각 노드에는 최소 1GiB의 메모리가 있어야 한다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture steps %}}
|
||||
|
||||
## 네임스페이스 생성
|
||||
|
||||
이 연습에서 생성한 리소스가 클러스터의 나머지와
|
||||
격리되도록 네임스페이스를 생성한다.
|
||||
|
||||
```shell
|
||||
kubectl create namespace quota-mem-cpu-example
|
||||
```
|
||||
|
||||
## 리소스쿼터 생성
|
||||
|
||||
다음은 리소스쿼터 오브젝트의 구성 파일이다.
|
||||
|
||||
{{< codenew file="admin/resource/quota-mem-cpu.yaml" >}}
|
||||
|
||||
리소스쿼터를 생성한다.
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/admin/resource/quota-mem-cpu.yaml --namespace=quota-mem-cpu-example
|
||||
```
|
||||
|
||||
리소스쿼터에 대한 자세한 정보를 본다.
|
||||
|
||||
```shell
|
||||
kubectl get resourcequota mem-cpu-demo --namespace=quota-mem-cpu-example --output=yaml
|
||||
```
|
||||
|
||||
리소스쿼터는 이러한 요구 사항을 quota-mem-cpu-example 네임스페이스에 배치한다.
|
||||
|
||||
* 모든 컨테이너에는 메모리 요청량(request), 메모리 상한(limit), CPU 요청량 및 CPU 상한이 있어야 한다.
|
||||
* 모든 컨테이너에 대한 총 메모리 요청량은 1GiB를 초과하지 않아야 한다.
|
||||
* 모든 컨테이너에 대한 총 메모리 상한은 2GiB를 초과하지 않아야 한다.
|
||||
* 모든 컨테이너에 대한 총 CPU 요청량은 1 cpu를 초과해서는 안된다.
|
||||
* 모든 컨테이너에 대한 총 CPU 상한은 2 cpu를 초과해서는 안된다.
|
||||
|
||||
## 파드 생성
|
||||
|
||||
파드의 구성 파일은 다음과 같다.
|
||||
|
||||
{{< codenew file="admin/resource/quota-mem-cpu-pod.yaml" >}}
|
||||
|
||||
|
||||
파드를 생성한다.
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/admin/resource/quota-mem-cpu-pod.yaml --namespace=quota-mem-cpu-example
|
||||
```
|
||||
|
||||
파드의 컨테이너가 실행 중인지 확인한다.
|
||||
|
||||
```
|
||||
kubectl get pod quota-mem-cpu-demo --namespace=quota-mem-cpu-example
|
||||
```
|
||||
|
||||
다시 한 번, 리소스쿼터에 대한 자세한 정보를 본다.
|
||||
|
||||
```
|
||||
kubectl get resourcequota mem-cpu-demo --namespace=quota-mem-cpu-example --output=yaml
|
||||
```
|
||||
|
||||
출력 결과는 쿼터와 사용된 쿼터를 함께 보여준다.
|
||||
파드의 메모리와 CPU 요청량 및 상한이 쿼터를 초과하지 않은 것을
|
||||
볼 수 있다.
|
||||
|
||||
```
|
||||
status:
|
||||
hard:
|
||||
limits.cpu: "2"
|
||||
limits.memory: 2Gi
|
||||
requests.cpu: "1"
|
||||
requests.memory: 1Gi
|
||||
used:
|
||||
limits.cpu: 800m
|
||||
limits.memory: 800Mi
|
||||
requests.cpu: 400m
|
||||
requests.memory: 600Mi
|
||||
```
|
||||
|
||||
## 두 번째 파드 생성 시도
|
||||
|
||||
다음은 두 번째 파드의 구성 파일이다.
|
||||
|
||||
{{< codenew file="admin/resource/quota-mem-cpu-pod-2.yaml" >}}
|
||||
|
||||
구성 파일에서, 파드의 메모리 요청량이 700MiB임을 알 수 있다.
|
||||
사용된 메모리 요청량과 이 새 메모리 요청량의 합계가
|
||||
메모리 요청량 쿼터를 초과한다. 600MiB + 700MiB > 1GiB
|
||||
|
||||
파드 생성을 시도한다.
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/admin/resource/quota-mem-cpu-pod-2.yaml --namespace=quota-mem-cpu-example
|
||||
```
|
||||
|
||||
두 번째 파드는 생성되지 않는다. 출력 결과는 두 번째 파드를 생성하면
|
||||
메모리 요청량의 총 합계가 메모리 요청량 쿼터를 초과함을 보여준다.
|
||||
|
||||
```
|
||||
Error from server (Forbidden): error when creating "examples/admin/resource/quota-mem-cpu-pod-2.yaml":
|
||||
pods "quota-mem-cpu-demo-2" is forbidden: exceeded quota: mem-cpu-demo,
|
||||
requested: requests.memory=700Mi,used: requests.memory=600Mi, limited: requests.memory=1Gi
|
||||
```
|
||||
|
||||
## 토론
|
||||
|
||||
이 연습에서 보았듯이, 리소스쿼터를 사용하여
|
||||
네임스페이스에서 실행 중인 모든 컨테이너에 대한 메모리 요청량의 총 합계를 제한할 수 있다.
|
||||
메모리 상한, CPU 요청량 및 CPU 상한의 총 합계를 제한할 수도 있다.
|
||||
|
||||
모든 컨테이너에 대한 합계 대신 개별 컨테이너를 제한하려면,
|
||||
[리밋레인지(LimitRange)](/ko/docs/tasks/administer-cluster/manage-resources/memory-constraint-namespace/)를 사용한다.
|
||||
|
||||
## 정리
|
||||
|
||||
네임스페이스를 삭제한다.
|
||||
|
||||
```shell
|
||||
kubectl delete namespace quota-mem-cpu-example
|
||||
```
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
|
||||
### 클러스터 관리자를 위한 문서
|
||||
|
||||
* [네임스페이스에 대한 기본 메모리 요청량과 상한 구성](/ko/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/)
|
||||
|
||||
* [네임스페이스에 대한 기본 CPU 요청량과 상한 구성](/ko/docs/tasks/administer-cluster/manage-resources/cpu-default-namespace/)
|
||||
|
||||
* [네임스페이스에 대한 메모리의 최소 및 최대 제약 조건 구성](/ko/docs/tasks/administer-cluster/manage-resources/memory-constraint-namespace/)
|
||||
|
||||
* [네임스페이스에 대한 CPU의 최소 및 최대 제약 조건 구성](/ko/docs/tasks/administer-cluster/manage-resources/cpu-constraint-namespace/)
|
||||
|
||||
* [네임스페이스에 대한 파드 쿼터 구성](/ko/docs/tasks/administer-cluster/manage-resources/quota-pod-namespace/)
|
||||
|
||||
* [API 오브젝트에 대한 쿼터 구성](/docs/tasks/administer-cluster/quota-api-object/)
|
||||
|
||||
### 앱 개발자를 위한 문서
|
||||
|
||||
* [컨테이너 및 파드 메모리 리소스 할당](/ko/docs/tasks/configure-pod-container/assign-memory-resource/)
|
||||
|
||||
* [컨테이너 및 파드 CPU 리소스 할당](/docs/tasks/configure-pod-container/assign-cpu-resource/)
|
||||
|
||||
* [파드에 대한 서비스 품질(QoS) 구성](/docs/tasks/configure-pod-container/quality-service-pod/)
|
||||
|
||||
{{% /capture %}}
|
|
@ -0,0 +1,136 @@
|
|||
---
|
||||
title: 네임스페이스에 대한 파드 쿼터 구성
|
||||
content_template: templates/task
|
||||
weight: 60
|
||||
---
|
||||
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
이 페이지는 네임스페이스에서 실행할 수 있는 총 파드 수에 대한 쿼터를
|
||||
설정하는 방법을 보여준다.
|
||||
[리소스쿼터(ResourceQuota)](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#resourcequota-v1-core)
|
||||
오브젝트에 쿼터를 지정한다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture prerequisites %}}
|
||||
|
||||
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture steps %}}
|
||||
|
||||
## 네임스페이스 생성
|
||||
|
||||
이 실습에서 생성한 리소스가 클러스터의 나머지와
|
||||
격리되도록 네임스페이스를 생성한다.
|
||||
|
||||
```shell
|
||||
kubectl create namespace quota-pod-example
|
||||
```
|
||||
|
||||
## 리소스쿼터 생성
|
||||
|
||||
다음은 리소스쿼터 오브젝트의 구성 파일이다.
|
||||
|
||||
{{< codenew file="admin/resource/quota-pod.yaml" >}}
|
||||
|
||||
리소스쿼터를 생성한다.
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/admin/resource/quota-pod.yaml --namespace=quota-pod-example
|
||||
```
|
||||
|
||||
리소스쿼터에 대한 자세한 정보를 본다.
|
||||
|
||||
```shell
|
||||
kubectl get resourcequota pod-demo --namespace=quota-pod-example --output=yaml
|
||||
```
|
||||
|
||||
출력 결과는 네임스페이스에 두 개의 파드 쿼터가 있고, 현재 파드가 없음을
|
||||
보여준다. 즉, 쿼터 중 어느 것도 사용되지 않았다.
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
hard:
|
||||
pods: "2"
|
||||
status:
|
||||
hard:
|
||||
pods: "2"
|
||||
used:
|
||||
pods: "0"
|
||||
```
|
||||
|
||||
다음은 디플로이먼트(Deployment) 구성 파일이다.
|
||||
|
||||
{{< codenew file="admin/resource/quota-pod-deployment.yaml" >}}
|
||||
|
||||
구성 파일에서, `replicas: 3` 은 쿠버네티스가 모두 동일한 애플리케이션을 실행하는 세 개의 파드를 만들도록 지시한다.
|
||||
|
||||
디플로이먼트를 생성한다.
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/admin/resource/quota-pod-deployment.yaml --namespace=quota-pod-example
|
||||
```
|
||||
|
||||
디플로이먼트에 대한 자세한 정보를 본다.
|
||||
|
||||
```shell
|
||||
kubectl get deployment pod-quota-demo --namespace=quota-pod-example --output=yaml
|
||||
```
|
||||
|
||||
출력 결과는 디플로이먼트에서 3개의 레플리카를 지정하더라도, 쿼터로
|
||||
인해 2개의 파드만 생성되었음을 보여준다.
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
...
|
||||
replicas: 3
|
||||
...
|
||||
status:
|
||||
availableReplicas: 2
|
||||
...
|
||||
lastUpdateTime: 2017-07-07T20:57:05Z
|
||||
message: 'unable to create pods: pods "pod-quota-demo-1650323038-" is forbidden:
|
||||
exceeded quota: pod-demo, requested: pods=1, used: pods=2, limited: pods=2'
|
||||
```
|
||||
|
||||
## 정리
|
||||
|
||||
네임스페이스를 삭제한다.
|
||||
|
||||
```shell
|
||||
kubectl delete namespace quota-pod-example
|
||||
```
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
|
||||
### 클러스터 관리자를 위한 문서
|
||||
|
||||
* [네임스페이스에 대한 기본 메모리 요청량과 상한 구성](/ko/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/)
|
||||
|
||||
* [네임스페이스에 대한 기본 CPU 요청량과 상한 구성](/ko/docs/tasks/administer-cluster/manage-resources/cpu-default-namespace/)
|
||||
|
||||
* [네임스페이스에 대한 메모리의 최소 및 최대 제약 조건 구성](/ko/docs/tasks/administer-cluster/manage-resources/memory-constraint-namespace/)
|
||||
|
||||
* [네임스페이스에 대한 CPU의 최소 및 최대 제약 조건 구성](/ko/docs/tasks/administer-cluster/manage-resources/cpu-constraint-namespace/)
|
||||
|
||||
* [네임스페이스에 대한 메모리 및 CPU 쿼터 구성](/ko/docs/tasks/administer-cluster/manage-resources/quota-memory-cpu-namespace/)
|
||||
|
||||
* [API 오브젝트에 대한 쿼터 구성](/docs/tasks/administer-cluster/quota-api-object/)
|
||||
|
||||
### 앱 개발자를 위한 문서
|
||||
|
||||
* [컨테이너 및 파드 메모리 리소스 할당](/ko/docs/tasks/configure-pod-container/assign-memory-resource/)
|
||||
|
||||
* [컨테이너 및 파드 CPU 리소스 할당](/docs/tasks/configure-pod-container/assign-cpu-resource/)
|
||||
|
||||
* [파드에 대한 서비스 품질(QoS) 구성](/docs/tasks/configure-pod-container/quality-service-pod/)
|
||||
|
||||
{{% /capture %}}
|
|
@ -115,6 +115,6 @@ weight: 120
|
|||
{{% /capture %}}
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
[노드 어피니티](/ko/docs/concepts/configuration/assign-pod-node/#node-affinity)에
|
||||
[노드 어피니티](/ko/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity)에
|
||||
대해 더 알아보기.
|
||||
{{% /capture %}}
|
||||
|
|
|
@ -0,0 +1,214 @@
|
|||
---
|
||||
title: 프라이빗 레지스트리에서 이미지 받아오기
|
||||
content_template: templates/task
|
||||
weight: 100
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
이 페이지는 프라이빗 도커 레지스트리나 리포지터리로부터 이미지를 받아오기 위해 시크릿(Secret)을
|
||||
사용하는 파드(Pod)를 생성하는 방법을 보여준다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture prerequisites %}}
|
||||
|
||||
* {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
|
||||
|
||||
* 이 실습을 수행하기 위해,
|
||||
[도커 ID](https://docs.docker.com/docker-id/)와 비밀번호가 필요하다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture steps %}}
|
||||
|
||||
## 도커 로그인
|
||||
|
||||
노트북에 프라이빗 이미지를 받아오기 위하여 레지스트리 인증을 필수로 수행해야 한다.
|
||||
|
||||
```shell
|
||||
docker login
|
||||
```
|
||||
|
||||
프롬프트가 나타나면, 도커 사용자 이름(username)과 비밀번호(password)를 입력하자.
|
||||
|
||||
로그인 프로세스는 권한 토큰 정보를 가지고 있는 `config.json` 파일을 생성하거나 업데이트 한다.
|
||||
|
||||
`config.json` 파일을 확인하자.
|
||||
|
||||
```shell
|
||||
cat ~/.docker/config.json
|
||||
```
|
||||
|
||||
하단과 유사한 결과를 확인할 수 있다.
|
||||
|
||||
```json
|
||||
{
|
||||
"auths": {
|
||||
"https://index.docker.io/v1/": {
|
||||
"auth": "c3R...zE2"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
{{< note >}}
|
||||
도커 자격 증명 저장소를 사용하는 경우, `auth` 항목이 아닌, 저장소의 이름을 값으로 사용하는 `credsStore` 항목을 확인할 수 있다.
|
||||
{{< /note >}}
|
||||
|
||||
## 기존의 도커 자격 증명을 기반으로 시크릿 생성하기 {#registry-secret-existing-credentials}
|
||||
|
||||
쿠버네티스 클러스터는 프라이빗 이미지를 받아올 때, 컨테이너 레지스트리에 인증하기 위하여
|
||||
`docker-registry` 타입의 시크릿을 사용한다.
|
||||
|
||||
만약 이미 `docker login` 을 수행하였다면, 이 때 생성된 자격 증명을 쿠버네티스 클러스터로 복사할 수 있다.
|
||||
|
||||
```shell
|
||||
kubectl create secret generic regcred \
|
||||
--from-file=.dockerconfigjson=<path/to/.docker/config.json> \
|
||||
--type=kubernetes.io/dockerconfigjson
|
||||
```
|
||||
|
||||
오브젝트에 대한 더 세밀한 제어(새로운 시크릿에 대한 네임스페이스나 레이블을 지정하는 등)가 필요할 경우,
|
||||
시크릿을 사용자 정의한 후에 저장할 수도 있다.
|
||||
다음을 확인하자.
|
||||
|
||||
- 데이터 항목의 이름을 `.dockerconfigjson` 으로 설정한다
|
||||
- 도커 파일을 base64로 인코딩하고 그 문자열을 `data[".dockerconfigjson"]`
|
||||
필드에 자르지 않고 한 줄로 이어서 붙여넣는다
|
||||
- `type` 을 `kubernetes.io/dockerconfigjson` 으로 설정한다
|
||||
|
||||
예:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: myregistrykey
|
||||
namespace: awesomeapps
|
||||
data:
|
||||
.dockerconfigjson: UmVhbGx5IHJlYWxseSByZWVlZWVlZWVlZWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGx5eXl5eXl5eXl5eXl5eXl5eXl5eSBsbGxsbGxsbGxsbGxsbG9vb29vb29vb29vb29vb29vb29vb29vb29vb25ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg==
|
||||
type: kubernetes.io/dockerconfigjson
|
||||
```
|
||||
|
||||
만약 `error: no objects passed to create` 메세지가 출력될 경우, base64로 인코딩된 문자열이 유효하지 않음을 의미한다.
|
||||
또한 `Secret "myregistrykey" is invalid: data[.dockerconfigjson]: invalid value ...` 메세지가 출력될 경우,
|
||||
base64로 인코딩된 문자열이 정상적으로 디코딩되었으나, `.docker/config.json` 파일로 파싱되지 못한 것을 의미한다.
|
||||
|
||||
## 커맨드 라인에서 자격 증명을 통하여 시크릿 생성하기
|
||||
|
||||
`regcred` 라는 이름의 시크릿을 생성하자.
|
||||
|
||||
```shell
|
||||
kubectl create secret docker-registry regcred --docker-server=<your-registry-server> --docker-username=<your-name> --docker-password=<your-pword> --docker-email=<your-email>
|
||||
```
|
||||
|
||||
아래의 각 항목에 대한 설명을 참고한다.
|
||||
|
||||
* `<your-registry-server>` 은 프라이빗 도커 저장소의 FQDN 주소이다. (도커허브(DockerHub)의 경우, https://index.docker.io/v1/)
|
||||
* `<your-name>` 은 도커 사용자의 계정이다.
|
||||
* `<your-pword>` 은 도커 사용자의 비밀번호이다.
|
||||
* `<your-email>` 은 도커 사용자의 이메일 주소이다.
|
||||
|
||||
이를 통해 `regcred` 라는 시크릿으로 클러스터 내에서 도커 자격 증명을 생성했다.
|
||||
|
||||
{{< note >}}
|
||||
커맨드 라인에서 시크릿을 입력하는 경우, 보호되지 않는 셸 히스토리에 내용이 저장될 수 있으며,
|
||||
이러한 시크릿들은 `kubectl` 이 구동 중인 동안 사용자의 PC의 다른 사용자들에게
|
||||
보일 수도 있다.
|
||||
{{< /note >}}
|
||||
|
||||
|
||||
## 시크릿 `regcred` 검증하기
|
||||
|
||||
방금 생성한 `regcred` 시크릿의 내용을 확인하기 위하여, YAML 형식으로 시크릿을 확인하자.
|
||||
|
||||
```shell
|
||||
kubectl get secret regcred --output=yaml
|
||||
```
|
||||
|
||||
결과는 다음과 같다.
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
...
|
||||
name: regcred
|
||||
...
|
||||
data:
|
||||
.dockerconfigjson: eyJodHRwczovL2luZGV4L ... J0QUl6RTIifX0=
|
||||
type: kubernetes.io/dockerconfigjson
|
||||
```
|
||||
|
||||
`.dockerconfigjson` 필드의 값은 도커 자격 증명의 base64 인코딩 결과이다.
|
||||
|
||||
`.dockerconfigjson` 필드의 값을 확인하기 위하여, 시크릿 데이터를 읽을 수 있는
|
||||
형식으로 변경한다.
|
||||
|
||||
```shell
|
||||
kubectl get secret regcred --output="jsonpath={.data.\.dockerconfigjson}" | base64 --decode
|
||||
```
|
||||
|
||||
결과는 다음과 같다.
|
||||
|
||||
```json
|
||||
{"auths":{"your.private.registry.example.com":{"username":"janedoe","password":"xxxxxxxxxxx","email":"jdoe@example.com","auth":"c3R...zE2"}}}
|
||||
```
|
||||
|
||||
`auth` 필드의 값을 확인하기 위하여, base64로 인코딩된 데이터를 읽을 수 있는 형식으로 변경한다.
|
||||
|
||||
```shell
|
||||
echo "c3R...zE2" | base64 --decode
|
||||
```
|
||||
|
||||
결과로, 사용자 이름과 비밀번호가 `:` 로 연결되어 아래와 같이 표현된다.
|
||||
|
||||
```none
|
||||
janedoe:xxxxxxxxxxx
|
||||
```
|
||||
|
||||
참고로 시크릿 데이터에는 사용자의 로컬에 있는 `~/.docker/config.json` 파일과 유사한 인증 토큰이 포함되어 있다.
|
||||
|
||||
이를 통해 `regcred` 라는 시크릿으로 클러스터 내에서 도커 자격 증명을 생성했다.
|
||||
|
||||
## 시크릿을 사용하는 파드 생성하기
|
||||
|
||||
다음은 `regcred` 에 있는 도커 자격 증명에 접근해야 하는 파드의 구성 파일이다.
|
||||
|
||||
{{< codenew file="pods/private-reg-pod.yaml" >}}
|
||||
|
||||
아래의 파일을 다운로드받는다.
|
||||
|
||||
```shell
|
||||
wget -O my-private-reg-pod.yaml https://k8s.io/examples/pods/private-reg-pod.yaml
|
||||
```
|
||||
|
||||
`my-private-reg-pod.yaml` 파일 안에서, `<your-private-image>` 값을 다음과 같은 프라이빗 저장소 안의 이미지 경로로 변경한다.
|
||||
|
||||
```none
|
||||
your.private.registry.example.com/janedoe/jdoe-private:v1
|
||||
```
|
||||
|
||||
프라이빗 저장소에서 이미지를 받아오기 위하여, 쿠버네티스에서 자격 증명이 필요하다.
|
||||
구성 파일의 `imagePullSecrets` 필드를 통해 쿠버네티스가 `regcred` 라는 시크릿으로부터 자격 증명을 가져올 수 있다.
|
||||
|
||||
시크릿을 사용해서 파드를 생성하고, 파드가 실행되는지 확인하자.
|
||||
|
||||
```shell
|
||||
kubectl apply -f my-private-reg-pod.yaml
|
||||
kubectl get pod private-reg
|
||||
```
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
|
||||
* [시크릿](/docs/concepts/configuration/secret/)에 대해 더 배워 보기.
|
||||
* [프라이빗 레지스트리 사용](/ko/docs/concepts/containers/images/#프라이빗-레지스트리-사용)에 대해 더 배워 보기.
|
||||
* [서비스 어카운트에 풀 시크릿(pull secret) 추가하기](/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account)에 대해 더 배워 보기.
|
||||
* [kubectl create secret docker-registry](/docs/reference/generated/kubectl/kubectl-commands/#-em-secret-docker-registry-em-)에 대해 읽어보기.
|
||||
* [시크릿](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#secret-v1-core)에 대해 읽어보기.
|
||||
* [PodSpec](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podspec-v1-core)의 `imagePullSecrets` 필드에 대해 읽어보기.
|
||||
|
||||
{{% /capture %}}
|
|
@ -0,0 +1,266 @@
|
|||
---
|
||||
title: 파드에 대한 서비스 품질(QoS) 구성
|
||||
content_template: templates/task
|
||||
weight: 30
|
||||
---
|
||||
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
이 페이지는 특정 서비스 품질(QoS) 클래스를 할당하기 위해 어떻게 파드를
|
||||
구성해야 하는지 보여준다. 쿠버네티스는 QoS 클래스를 사용하여 파드
|
||||
스케줄링과 축출을 결정한다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture prerequisites %}}
|
||||
|
||||
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture steps %}}
|
||||
|
||||
## QoS 클래스
|
||||
|
||||
쿠버네티스가 파드를 생성할 때, 파드에 다음의 QoS 클래스 중 하나를 할당한다.
|
||||
|
||||
* Guaranteed
|
||||
* Burstable
|
||||
* BestEffort
|
||||
|
||||
## 네임스페이스 생성
|
||||
|
||||
이 연습에서 생성한 리소스가 클러스터의 나머지와
|
||||
격리되도록 네임스페이스를 생성한다.
|
||||
|
||||
```shell
|
||||
kubectl create namespace qos-example
|
||||
```
|
||||
|
||||
## Guaranteed QoS 클래스가 할당되는 파드 생성
|
||||
|
||||
파드에 Guaranteed QoS 클래스 할당을 위한 전제 조건은 다음과 같다.
|
||||
|
||||
* 파드 내 모든 컨테이너는 메모리 상한과 메모리 요청량을 가지고 있어야 하며, 이는 동일해야 한다.
|
||||
* 파드 내 모든 컨테이너는 CPU 상한과 CPU 요청량을 가지고 있어야 하며, 이는 동일해야 한다.
|
||||
|
||||
이것은 하나의 컨테이너를 갖는 파드의 구성 파일이다. 해당 컨테이너는 메모리 상한과
|
||||
메모리 요청량을 갖고 있고, 200MiB로 동일하다. 해당 컨테이너는 CPU 상한과 CPU 요청량을 가지며, 700 milliCPU로 동일하다.
|
||||
|
||||
{{< codenew file="pods/qos/qos-pod.yaml" >}}
|
||||
|
||||
파드를 생성한다.
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/pods/qos/qos-pod.yaml --namespace=qos-example
|
||||
```
|
||||
|
||||
파드의 상세 정보를 본다.
|
||||
|
||||
```shell
|
||||
kubectl get pod qos-demo --namespace=qos-example --output=yaml
|
||||
```
|
||||
|
||||
출력 결과는 쿠버네티스가 파드에 Guaranteed QoS 클래스를 부여했음을 보여준다. 또한
|
||||
파드의 컨테이너가 메모리 요청량과 일치하는 메모리 상한을 가지며,
|
||||
CPU 요청량과 일치하는 CPU 상한을 갖고 있음을 확인할 수 있다.
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
containers:
|
||||
...
|
||||
resources:
|
||||
limits:
|
||||
cpu: 700m
|
||||
memory: 200Mi
|
||||
requests:
|
||||
cpu: 700m
|
||||
memory: 200Mi
|
||||
...
|
||||
qosClass: Guaranteed
|
||||
```
|
||||
|
||||
{{< note >}}
|
||||
컨테이너가 자신의 메모리 상한을 지정하지만, 메모리 요청량을 지정하지 않는 경우,
|
||||
쿠버네티스는 상한과 일치하는 메모리 요청량을 자동으로 할당한다. 이와 유사하게, 만약 컨테이너가 자신의
|
||||
CPU 상한을 지정하지만, CPU 요청량을 지정하지 않은 경우, 쿠버네티스는 상한과 일치하는 CPU 요청량을 자동으로
|
||||
할당한다.
|
||||
{{< /note >}}
|
||||
|
||||
파드를 삭제한다.
|
||||
|
||||
```shell
|
||||
kubectl delete pod qos-demo --namespace=qos-example
|
||||
```
|
||||
|
||||
## Burstable QoS 클래스가 할당되는 파드 생성
|
||||
|
||||
다음의 경우 파드에 Burstable QoS 클래스가 부여된다.
|
||||
|
||||
* 파드가 Guaranteed QoS 클래스 기준을 만족하지 않는다.
|
||||
* 파드 내에서 최소한 하나의 컨테이너가 메모리 또는 CPU 요청량을 가진다.
|
||||
|
||||
컨테이너가 하나인 파드의 구성 파일은 다음과 같다. 컨테이너는
|
||||
200MiB의 메모리 상한과 100MiB의 메모리 요청량을 가진다.
|
||||
|
||||
{{< codenew file="pods/qos/qos-pod-2.yaml" >}}
|
||||
|
||||
파드를 생성한다.
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/pods/qos/qos-pod-2.yaml --namespace=qos-example
|
||||
```
|
||||
|
||||
파드의 상세 정보를 본다.
|
||||
|
||||
```shell
|
||||
kubectl get pod qos-demo-2 --namespace=qos-example --output=yaml
|
||||
```
|
||||
|
||||
출력 결과는 쿠버네티스가 파드에 Burstable QoS 클래스를 부여했음을 보여준다.
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx
|
||||
imagePullPolicy: Always
|
||||
name: qos-demo-2-ctr
|
||||
resources:
|
||||
limits:
|
||||
memory: 200Mi
|
||||
requests:
|
||||
memory: 100Mi
|
||||
...
|
||||
qosClass: Burstable
|
||||
```
|
||||
|
||||
파드를 삭제한다.
|
||||
|
||||
```shell
|
||||
kubectl delete pod qos-demo-2 --namespace=qos-example
|
||||
```
|
||||
|
||||
## BestEffort QoS 클래스가 할당되는 파드 생성
|
||||
|
||||
파드에 QoS 클래스 BestEffort를 제공하려면, 파드의 컨테이너에
|
||||
메모리 또는 CPU의 상한이나 요청량이 없어야 한다.
|
||||
|
||||
컨테이너가 하나인 파드의 구성 파일이다. 해당 컨테이너는 메모리 또는 CPU의
|
||||
상한이나 요청량을 갖지 않는다.
|
||||
|
||||
{{< codenew file="pods/qos/qos-pod-3.yaml" >}}
|
||||
|
||||
파드를 생성한다.
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/pods/qos/qos-pod-3.yaml --namespace=qos-example
|
||||
```
|
||||
|
||||
파드의 상세 정보를 본다.
|
||||
|
||||
```shell
|
||||
kubectl get pod qos-demo-3 --namespace=qos-example --output=yaml
|
||||
```
|
||||
|
||||
출력 결과는 쿠버네티스가 파드에 BestEffort QoS 클래스를 부여했음을 보여준다.
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
containers:
|
||||
...
|
||||
resources: {}
|
||||
...
|
||||
qosClass: BestEffort
|
||||
```
|
||||
|
||||
파드를 삭제한다.
|
||||
|
||||
```shell
|
||||
kubectl delete pod qos-demo-3 --namespace=qos-example
|
||||
```
|
||||
|
||||
## 컨테이너가 두 개인 파드 생성
|
||||
|
||||
컨테이너가 두 개인 파드의 구성 파일이다. 한 컨테이너는 200MiB의 메모리
|
||||
요청량을 지정한다. 다른 컨테이너는 어떤 요청량이나 상한을 지정하지 않는다.
|
||||
|
||||
{{< codenew file="pods/qos/qos-pod-4.yaml" >}}
|
||||
|
||||
참고로 이 파드는 Burstable QoS 클래스의 기준을 충족한다. 즉, Guaranteed QoS 클래스에 대한
|
||||
기준을 충족하지 않으며, 해당 컨테이너 중 하나가 메모리 요청량을 갖는다.
|
||||
|
||||
파드를 생성한다.
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/pods/qos/qos-pod-4.yaml --namespace=qos-example
|
||||
```
|
||||
|
||||
파드의 상세 정보를 본다.
|
||||
|
||||
```shell
|
||||
kubectl get pod qos-demo-4 --namespace=qos-example --output=yaml
|
||||
```
|
||||
|
||||
출력 결과는 쿠버네티스가 파드에 Burstable QoS 클래스를 부여했음을 보여준다.
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
containers:
|
||||
...
|
||||
name: qos-demo-4-ctr-1
|
||||
resources:
|
||||
requests:
|
||||
memory: 200Mi
|
||||
...
|
||||
name: qos-demo-4-ctr-2
|
||||
resources: {}
|
||||
...
|
||||
qosClass: Burstable
|
||||
```
|
||||
|
||||
파드를 삭제한다.
|
||||
|
||||
```shell
|
||||
kubectl delete pod qos-demo-4 --namespace=qos-example
|
||||
```
|
||||
|
||||
## 정리
|
||||
|
||||
네임스페이스를 삭제한다.
|
||||
|
||||
```shell
|
||||
kubectl delete namespace qos-example
|
||||
```
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
|
||||
|
||||
### 앱 개발자를 위한 문서
|
||||
|
||||
* [컨테이너 및 파드 메모리 리소스 할당](/ko/docs/tasks/configure-pod-container/assign-memory-resource/)
|
||||
|
||||
* [컨테이너 및 파드 CPU 리소스 할당](/docs/tasks/configure-pod-container/assign-cpu-resource/)
|
||||
|
||||
### 클러스터 관리자를 위한 문서
|
||||
|
||||
* [네임스페이스에 대한 기본 메모리 요청과 상한 구성](/ko/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/)
|
||||
|
||||
* [네임스페이스에 대한 기본 CPU 요청과 상한 구성](/ko/docs/tasks/administer-cluster/manage-resources/cpu-default-namespace/)
|
||||
|
||||
* [네임스페이스에 대한 메모리의 최소 및 최대 메모리 제약 조건 구성](/ko/docs/tasks/administer-cluster/manage-resources/memory-constraint-namespace/)
|
||||
|
||||
* [네임스페이스에 대한 CPU의 최소 및 최대 제약 조건 구성](/ko/docs/tasks/administer-cluster/manage-resources/cpu-constraint-namespace/)
|
||||
|
||||
* [네임스페이스에 대한 메모리 및 CPU 쿼터 구성](/ko/docs/tasks/administer-cluster/manage-resources/quota-memory-cpu-namespace/)
|
||||
|
||||
* [네임스페이스에 대한 파드 쿼터 구성](/ko/docs/tasks/administer-cluster/manage-resources/quota-pod-namespace/)
|
||||
|
||||
* [API 오브젝트 할당량 구성](/docs/tasks/administer-cluster/quota-api-object/)
|
||||
|
||||
* [노드의 토폴로지 관리 정책 제어](/docs/tasks/administer-cluster/topology-manager/)
|
||||
{{% /capture %}}
|
|
@ -49,7 +49,7 @@ CPU는 일정 기간 동안 [CPU 코어](https://kubernetes.io/docs/concepts/con
|
|||
[메트릭 서버](https://github.com/kubernetes-incubator/metrics-server)는 클러스터 전역에서 리소스 사용량 데이터를 집계한다.
|
||||
`kube-up.sh` 스크립트에 의해 생성된 클러스터에는 기본적으로 메트릭 서버가
|
||||
디플로이먼트 오브젝트로 배포된다. 만약 다른 쿠버네티스 설치 메커니즘을 사용한다면, 제공된
|
||||
[배포 yaml들](https://github.com/kubernetes-incubator/metrics-server/tree/master/deploy)을 사용하여 메트릭 서버를 배포할 수 있다.
|
||||
[디플로이먼트 components.yaml](https://github.com/kubernetes-sigs/metrics-server/releases) 파일을 사용하여 메트릭 서버를 배포할 수 있다.
|
||||
|
||||
메트릭 서버는 각 노드에서 [Kubelet](/docs/admin/kubelet/)에 의해 노출된 Summary API에서 메트릭을 수집한다.
|
||||
|
||||
|
|
|
@ -235,7 +235,7 @@ kubectl scale deployment/nginx-deployment --replicas=2
|
|||
`kubectl get`을 사용하여 활성 구성을 출력한다.
|
||||
|
||||
```shell
|
||||
kubectl get -f https://k8s.io/examples/application/simple_deployment.yaml -o yaml
|
||||
kubectl get deployment nginx-deployment -o yaml
|
||||
```
|
||||
|
||||
출력은 `replicas` 필드가 2로 설정된 것을 보여주며, `last-applied-configuration`
|
||||
|
@ -294,7 +294,7 @@ kubectl apply -f https://k8s.io/examples/application/update_deployment.yaml
|
|||
`kubectl get`을 사용하여 활성 구성을 출력한다.
|
||||
|
||||
```shell
|
||||
kubectl get -f https://k8s.io/examples/application/simple_deployment.yaml -o yaml
|
||||
kubectl get -f https://k8s.io/examples/application/update_deployment.yaml -o yaml
|
||||
```
|
||||
|
||||
출력은 활성 구성에 다음의 변경사항을 보여준다.
|
||||
|
|
|
@ -109,7 +109,7 @@ php-apache Deployment/php-apache/scale 0% / 50% 1 10 1
|
|||
|
||||
|
||||
```shell
|
||||
kubectl run --generator=run-pod/v1 -it --rm load-generator --image=busybox /bin/sh
|
||||
kubectl run -it --rm load-generator --image=busybox /bin/sh
|
||||
|
||||
Hit enter for command prompt
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@ echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee -a /etc/
|
|||
sudo apt-get update
|
||||
sudo apt-get install -y kubectl
|
||||
{{< /tab >}}
|
||||
|
||||
{{< tab name="CentOS, RHEL 또는 Fedora" codelang="bash" >}}cat <<EOF > /etc/yum.repos.d/kubernetes.repo
|
||||
[kubernetes]
|
||||
name=Kubernetes
|
||||
|
@ -86,17 +87,23 @@ snap install kubectl --classic
|
|||
|
||||
kubectl version --client
|
||||
```
|
||||
|
||||
{{% /tab %}}
|
||||
|
||||
{{% tab name="Homebrew" %}}
|
||||
리눅스 상에서 [Homebrew](https://docs.brew.sh/Homebrew-on-Linux) 패키지 관리자를 사용한다면, [설치](https://docs.brew.sh/Homebrew-on-Linux#install)를 통해 kubectl을 사용할 수 있다.
|
||||
|
||||
```shell
|
||||
brew install kubectl
|
||||
|
||||
kubectl version --client
|
||||
```
|
||||
|
||||
{{% /tab %}}
|
||||
|
||||
{{< /tabs >}}
|
||||
|
||||
|
||||
## macOS에 kubectl 설치
|
||||
|
||||
### macOS에서 curl을 사용하여 kubectl 바이너리 설치
|
||||
|
@ -125,6 +132,7 @@ kubectl version --client
|
|||
```
|
||||
sudo mv ./kubectl /usr/local/bin/kubectl
|
||||
```
|
||||
|
||||
4. 설치한 버전이 최신 버전인지 확인한다.
|
||||
|
||||
```
|
||||
|
@ -140,6 +148,7 @@ macOS에서 [Homebrew](https://brew.sh/) 패키지 관리자를 사용하는 경
|
|||
```
|
||||
brew install kubectl
|
||||
```
|
||||
|
||||
또는
|
||||
|
||||
```
|
||||
|
@ -184,11 +193,13 @@ macOS에서 [Macports](https://macports.org/) 패키지 관리자를 사용하
|
|||
최신의 안정 버전(예: 스크립팅을 위한)을 찾으려면, [https://storage.googleapis.com/kubernetes-release/release/stable.txt](https://storage.googleapis.com/kubernetes-release/release/stable.txt)를 참고한다.
|
||||
|
||||
2. 바이너리를 PATH가 설정된 디렉터리에 추가한다.
|
||||
|
||||
3. `kubectl` 의 버전이 다운로드한 버전과 같은지 확인한다.
|
||||
|
||||
```
|
||||
kubectl version --client
|
||||
```
|
||||
|
||||
{{< note >}}
|
||||
[Windows용 도커 데스크톱](https://docs.docker.com/docker-for-windows/#kubernetes)은 자체 버전의 `kubectl` 을 PATH에 추가한다.
|
||||
도커 데스크톱을 이전에 설치한 경우, 도커 데스크톱 설치 프로그램에서 추가한 PATH 항목 앞에 PATH 항목을 배치하거나 도커 데스크톱의 `kubectl` 을 제거해야 할 수도 있다.
|
||||
|
@ -205,9 +216,9 @@ Windows에서 [Powershell Gallery](https://www.powershellgallery.com/) 패키지
|
|||
install-kubectl.ps1 [-DownloadLocation <path>]
|
||||
```
|
||||
|
||||
{{< note >}}`DownloadLocation` 을 지정하지 않으면, `kubectl` 은 사용자의 임시 디렉터리에 설치된다.{{< /note >}}
|
||||
{{< note >}}`DownloadLocation` 을 지정하지 않으면, `kubectl` 은 사용자의 임시 디렉터리에 설치된다.{{< /note >}}
|
||||
|
||||
설치 프로그램은 `$HOME/.kube` 를 생성하고 구성 파일을 작성하도록 지시한다.
|
||||
설치 프로그램은 `$HOME/.kube` 를 생성하고 구성 파일을 작성하도록 지시한다.
|
||||
|
||||
2. 설치한 버전이 최신 버전인지 확인한다.
|
||||
|
||||
|
@ -215,11 +226,14 @@ Windows에서 [Powershell Gallery](https://www.powershellgallery.com/) 패키지
|
|||
kubectl version --client
|
||||
```
|
||||
|
||||
{{< note >}}설치 업데이트는 1 단계에서 나열한 두 명령을 다시 실행하여 수행한다.{{< /note >}}
|
||||
{{< note >}}
|
||||
설치 업데이트는 1 단계에서 나열한 두 명령을 다시 실행하여 수행한다.
|
||||
{{< /note >}}
|
||||
|
||||
### Chocolatey 또는 Scoop을 사용하여 Windows에 설치
|
||||
|
||||
Windows에 kubectl을 설치하기 위해서 [Chocolatey](https://chocolatey.org) 패키지 관리자나 [Scoop](https://scoop.sh) 커맨드 라인 설치 프로그램을 사용할 수 있다.
|
||||
1. Windows에 kubectl을 설치하기 위해서 [Chocolatey](https://chocolatey.org) 패키지 관리자나 [Scoop](https://scoop.sh) 커맨드 라인 설치 프로그램을 사용할 수 있다.
|
||||
|
||||
{{< tabs name="kubectl_win_install" >}}
|
||||
{{% tab name="choco" %}}
|
||||
|
||||
|
@ -232,6 +246,8 @@ Windows에 kubectl을 설치하기 위해서 [Chocolatey](https://chocolatey.org
|
|||
|
||||
{{% /tab %}}
|
||||
{{< /tabs >}}
|
||||
|
||||
|
||||
2. 설치한 버전이 최신 버전인지 확인한다.
|
||||
|
||||
```
|
||||
|
@ -261,13 +277,14 @@ Windows에 kubectl을 설치하기 위해서 [Chocolatey](https://chocolatey.org
|
|||
New-Item config -type file
|
||||
```
|
||||
|
||||
{{< note >}}메모장과 같은 텍스트 편집기를 선택하여 구성 파일을 편집한다.{{< /note >}}
|
||||
{{< note >}}메모장과 같은 텍스트 편집기를 선택하여 구성 파일을 편집한다.{{< /note >}}
|
||||
|
||||
## Google Cloud SDK의 일부로 다운로드
|
||||
|
||||
kubectl을 Google Cloud SDK의 일부로 설치할 수 있다.
|
||||
|
||||
1. [Google Cloud SDK](https://cloud.google.com/sdk/)를 설치한다.
|
||||
|
||||
2. `kubectl` 설치 명령을 실행한다.
|
||||
|
||||
```
|
||||
|
@ -289,6 +306,7 @@ kubectl이 쿠버네티스 클러스터를 찾아 접근하려면, [kube-up.sh](
|
|||
```shell
|
||||
kubectl cluster-info
|
||||
```
|
||||
|
||||
URL 응답이 표시되면, kubectl이 클러스터에 접근하도록 올바르게 구성된 것이다.
|
||||
|
||||
다음과 비슷한 메시지가 표시되면, kubectl이 올바르게 구성되지 않았거나 쿠버네티스 클러스터에 연결할 수 없다.
|
||||
|
@ -346,18 +364,17 @@ source /usr/share/bash-completion/bash_completion
|
|||
```shell
|
||||
echo 'source <(kubectl completion bash)' >>~/.bashrc
|
||||
```
|
||||
|
||||
- 완성 스크립트를 `/etc/bash_completion.d` 디렉터리에 추가한다.
|
||||
|
||||
```shell
|
||||
kubectl completion bash >/etc/bash_completion.d/kubectl
|
||||
```
|
||||
- kubectl에 대한 앨리어스(alias)가 있는 경우, 해당 앨리어스로 작업하도록 셸 완성을 확장할 수 있다.
|
||||
kubectl에 대한 앨리어스(alias)가 있는 경우, 해당 앨리어스로 작업하도록 셸 완성을 확장할 수 있다.
|
||||
|
||||
```shell
|
||||
echo 'alias k=kubectl' >>~/.bashrc
|
||||
echo 'complete -F __start_kubectl k' >>~/.bashrc
|
||||
```
|
||||
```shell
|
||||
echo 'alias k=kubectl' >>~/.bashrc
|
||||
echo 'complete -F __start_kubectl k' >>~/.bashrc
|
||||
```
|
||||
|
||||
{{< note >}}
|
||||
bash-completion은 `/etc/bash_completion.d` 에 있는 모든 완성 스크립트를 소싱한다.
|
||||
|
@ -450,9 +467,9 @@ export BASH_COMPLETION_COMPAT_DIR="/usr/local/etc/bash_completion.d"
|
|||
|
||||
- Homebrew로 kubectl을 설치한 경우([위](#macos에서-homebrew를-사용하여-설치)의 설명을 참고), kubectl 완성 스크립트는 이미 `/usr/local/etc/bash_completion.d/kubectl` 에 있어야 한다. 이 경우, 아무 것도 할 필요가 없다.
|
||||
|
||||
{{< note >}}
|
||||
bash-completion v2의 Homebrew 설치는 `BASH_COMPLETION_COMPAT_DIR` 디렉터리의 모든 파일을 소싱하므로, 후자의 두 가지 방법이 적용된다.
|
||||
{{< /note >}}
|
||||
{{< note >}}
|
||||
bash-completion v2의 Homebrew 설치는 `BASH_COMPLETION_COMPAT_DIR` 디렉터리의 모든 파일을 소싱하므로, 후자의 두 가지 방법이 적용된다.
|
||||
{{< /note >}}
|
||||
|
||||
어쨌든, 셸을 다시 로드 한 후에, kubectl 완성이 작동해야 한다.
|
||||
{{% /tab %}}
|
||||
|
@ -485,6 +502,7 @@ compinit
|
|||
{{% /tab %}}
|
||||
{{< /tabs >}}
|
||||
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture whatsnext %}}
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
이 기능은 현재 *알파(alpha)* 상태로, 다음을 의미한다.
|
||||
|
||||
* 버전 이름에는 알파(예: v1alpha1)가 포함되어 있다.
|
||||
* 버그가 있을 수 있다. 기능을 활성화하면 버그가 노출될 수 있다. 기본적으로 비활성화되어 있다.
|
||||
* 기능 지원은 예고 없이 언제든지 중단될 수 있다.
|
||||
* API는 이후 소프트웨어 릴리즈에서 예고 없이 호환되지 않는 방식으로 변경될 수 있다.
|
||||
* 버그에 의한 위험 증가와 장기적인 지원 부족으로, 단기 테스트 클러스터에서만 사용할 것을 권장한다.
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
이 기능은 현재 *베타(beta)* 상태로, 다음을 의미한다.
|
||||
|
||||
* 버전 이름에는 베타(예: v2beta3)가 포함된다.
|
||||
* 코드의 테스트가 완료되었다. 기능을 활성화해도 안전한 것으로 간주한다. 기본으로 활성화되어 있다.
|
||||
* 자세한 내용은 변경될 수 있지만, 전체 기능에 대한 지원은 중단되지 않는다.
|
||||
* 오브젝트의 스키마 및(또는) 의미(semantics)는 후속 베타 또는 안정적인 릴리즈에서 호환되지 않는 방식으로 변경될 수 있다. 이 경우, 다음 버전으로 마이그레이션하기 위한 지침을 제공할 것이다. 이를 위해서는 API 오브젝트의 삭제, 수정 또는 재생성이 필요할 수 있다. 편집 과정에서 약간의 생각이 필요할 수 있다. 이 기능을 사용하는 애플리케이션은 가동 중지 시간(downtime)이 필요할 수 있다.
|
||||
* 후속 릴리즈에서 호환되지 않는 변경 가능성이 있으므로 오직 업무상 중요하지 않은 용도로만 권장한다. 만약 사용자가 독립적으로 업그레이드가 가능한 다중 클러스터를 가지고 있다면, 이 제약은 완화될 수 있다.
|
||||
* **베타 기능을 사용해보고, 우리에게 피드백을 주십시오! 베타가 종료된 후에 많은 것을 변경하는 것은 타당하지 않을 수 있습니다.**
|
|
@ -1,2 +0,0 @@
|
|||
|
||||
이 기능은 *사용중단(deprecated)* 상태이다. 이 상태에 대한 더 많은 정보는 [쿠버네티스 사용중단(deprecation) 정책](/docs/reference/deprecation-policy/)을 참조한다.
|