Fourth Korean L10n Work For Release 1.17 (#19127)

* translate assign-pod-node.md (#18955)
* correct the misspelling (#19063)
* Update to Outdated files in dev-1.17-ko.4 branch. (#19002)

Co-Authored-By: KimMJ <a01083612486@gmail.com>
Co-Authored-By: forybm <forybm1@naver.com>
Co-Authored-By: Yuk, Yongsu <ysyukr@gmail.com>

Co-authored-by: KimMJ <a01083612486@gmail.com>
Co-authored-by: forybm <forybm1@naver.com>
Co-authored-by: Yuk, Yongsu <ysyukr@gmail.com>
This commit is contained in:
June Yi
2020-02-15 10:59:27 +09:00
committed by vineeth
parent 360790946d
commit 1048fa8b40
41 changed files with 1024 additions and 259 deletions
@@ -223,11 +223,13 @@ rules:
다음은 클라우드 제공사업자들이 구현한 CCM들이다.
* [Alibaba Cloud](https://github.com/kubernetes/cloud-provider-alibaba-cloud)
* [AWS](https://github.com/kubernetes/cloud-provider-aws)
* [Azure](https://github.com/kubernetes/cloud-provider-azure)
* [BaiduCloud](https://github.com/baidu/cloud-provider-baiducloud)
* [DigitalOcean](https://github.com/digitalocean/digitalocean-cloud-controller-manager)
* [GCP](https://github.com/kubernetes/cloud-provider-gcp)
* [Hetzner](https://github.com/hetznercloud/hcloud-cloud-controller-manager)
* [Linode](https://github.com/linode/linode-cloud-controller-manager)
* [OpenStack](https://github.com/kubernetes/cloud-provider-openstack)
* [Oracle](https://github.com/oracle/oci-cloud-controller-manager)
@@ -0,0 +1,399 @@
---
title: 노드에 파드 할당하기
content_template: templates/concept
weight: 30
---
{{% 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` 는 "all topology"("all topology"는 현재 `kubernetes.io/hostname`, `failure-domain.beta.kubernetes.io/zone` 그리고 `failure-domain.beta.kubernetes.io/region` 의 조합으로 제한된다)로 해석한다.
4. 위의 경우를 제외하고, `topologyKey` 는 적법한 어느 레이블-키도 가능하다.
`labelSelector``topologyKey` 외에도 `labelSelector` 와 일치해야 하는 네임스페이스 목록 `namespaces`
선택적으로 지정할 수 있다(이것은 `labelSelector``topologyKey` 와 같은 수준의 정의이다).
생략되어있거나 비어있을 경우 어피니티/안티-어피니티 정의가 있는 파드의 네임스페이스가 기본 값이다.
파드를 노드에 스케줄하려면 `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.12-alpine
```
만약 위의 두 디플로이먼트를 생성하면 세 개의 노드가 있는 클러스터는 다음과 같아야 한다.
| node-1 | node-2 | node-3 |
|:--------------------:|:-------------------:|:------------------:|
| *webserver-1* | *webserver-2* | *webserver-3* |
| *cache-1* | *cache-2* | *cache-3* |
여기서 볼 수 있듯이 `web-server` 의 세 레플리카들이 기대했던 것처럼 자동으로 캐시와 함께 위치하게 된다.
```
kubectl get pods -o wide
```
출력은 다음과 유사할 것이다.
```
NAME READY STATUS RESTARTS AGE IP NODE
redis-cache-1450370735-6dzlj 1/1 Running 0 8m 10.192.4.2 kube-node-3
redis-cache-1450370735-j2j96 1/1 Running 0 8m 10.192.2.2 kube-node-1
redis-cache-1450370735-z73mh 1/1 Running 0 8m 10.192.3.1 kube-node-2
web-server-1287567482-5d4dz 1/1 Running 0 7m 10.192.2.3 kube-node-1
web-server-1287567482-6f7v5 1/1 Running 0 7m 10.192.4.3 kube-node-3
web-server-1287567482-s330j 1/1 Running 0 7m 10.192.3.2 kube-node-2
```
##### 절대 동일한 노드에 위치시키지 않게 하기
위의 예시에서 `topologyKey:"kubernetes.io/hostname"` 과 함께 `PodAntiAffinity` 규칙을 사용해서
두 개의 인스터스가 동일한 호스트에 있지 않도록 redis 클러스터를 배포한다.
같은 기술을 사용해서 고 가용성을 위해 안티-어피니티로 구성된 스테이트풀셋의 예시는
[ZooKeeper 튜토리얼](/docs/tutorials/stateful-application/zookeeper/#tolerating-node-failure)을 본다.
## 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 %}}
+56 -47
View File
@@ -6,7 +6,7 @@ weight: 10
{{% capture overview %}}
사용자 Docker 이미지를 생성하고 레지스트리에 푸시(push)하여 쿠버네티스 파드에서 참조되기 이전에 대비한다.
사용자 Docker 이미지를 생성하고 레지스트리에 푸시(push)하여 쿠버네티스 파드에서 참조되기 이전에 대비한다.
컨테이너의 `image` 속성은 `docker` 커맨드에서 지원하는 문법과 같은 문법을 지원한다. 이는 프라이빗 레지스트리와 태그를 포함한다.
@@ -17,8 +17,8 @@ weight: 10
## 이미지 업데이트
기본 풀(pull) 정책은 `IfNotPresent`이며, 이것은 Kubelet이 이미
존재하는 이미지에 대한 풀을 생략하게 한다. 만약 항상 풀을 강제하고 싶다면,
기본 풀(pull) 정책은 `IfNotPresent`이며, 이것은 Kubelet이 이미
존재하는 이미지에 대한 풀을 생략하게 한다. 만약 항상 풀을 강제하고 싶다면,
다음 중 하나를 수행하면 된다.
- 컨테이너의 `imagePullPolicy``Always`로 설정.
@@ -35,7 +35,7 @@ Docker CLI는 현재 `docker manifest` 커맨드와 `create`, `annotate`, `push`
다음에서 docker 문서를 확인하기 바란다.
https://docs.docker.com/edge/engine/reference/commandline/manifest/
이것을 사용하는 방법에 대한 예제는 빌드 하니스(harness)에서 참조한다.
이것을 사용하는 방법에 대한 예제는 빌드 하니스(harness)에서 참조한다.
https://cs.k8s.io/?q=docker%20manifest%20(create%7Cpush%7Cannotate)&i=nope&files=&repos=
이 커맨드는 Docker CLI에 의존하며 그에 전적으로 구현된다. `$HOME/.docker/config.json` 편집 및 `experimental` 키를 `enabled`로 설정하거나, CLI 커맨드 호출 시 간단히 `DOCKER_CLI_EXPERIMENTAL` 환경 변수를 `enabled`로만 설정해도 된다.
@@ -79,9 +79,9 @@ Docker *18.06 또는 그 이상* 을 사용하길 바란다. 더 낮은 버전
### Google 컨테이너 레지스트리 사용
쿠버네티스는 Google 컴퓨트 엔진(GCE)에서 동작할 때, [Google 컨테이너
레지스트리(GCR)](https://cloud.google.com/tools/container-registry/)를 자연스럽게
지원한다. 사용자의 클러스터가 GCE 또는 Google 쿠버네티스 엔진에서 동작 중이라면, 간단히
쿠버네티스는 Google 컴퓨트 엔진(GCE)에서 동작할 때, [Google 컨테이너
레지스트리(GCR)](https://cloud.google.com/tools/container-registry/)를 자연스럽게
지원한다. 사용자의 클러스터가 GCE 또는 Google 쿠버네티스 엔진에서 동작 중이라면, 간단히
이미지의 전체 이름(예: gcr.io/my_project/image:tag)을 사용하면 된다.
클러스터 내에서 모든 파드는 해당 레지스트리에 있는 이미지에 읽기 접근 권한을 가질 것이다.
@@ -95,10 +95,10 @@ GCR을 인증할 것이다. 인스턴스의 서비스 계정은
쿠버네티스는 노드가 AWS EC2 인스턴스일 때, [Amazon Elastic Container Registry](https://aws.amazon.com/ecr/)를 자연스럽게 지원한다.
간단히 이미지의 전체 이름(예: `ACCOUNT.dkr.ecr.REGION.amazonaws.com/imagename:tag`)을
간단히 이미지의 전체 이름(예: `ACCOUNT.dkr.ecr.REGION.amazonaws.com/imagename:tag`)을
파드 정의에 사용하면 된다.
파드를 생성할 수 있는 클러스터의 모든 사용자는 ECR 레지스트리에 있는 어떠한
파드를 생성할 수 있는 클러스터의 모든 사용자는 ECR 레지스트리에 있는 어떠한
이미지든지 파드를 실행하는데 사용할 수 있다.
kubelet은 ECR 자격 증명을 가져오고 주기적으로 갱신할 것이다. 이것을 위해서는 다음에 대한 권한이 필요하다.
@@ -122,17 +122,17 @@ kubelet은 ECR 자격 증명을 가져오고 주기적으로 갱신할 것이다
- 위의 모든 요구 사항을 확인한다.
- 워크스테이션에서 $REGION (예: `us-west-2`)의 자격 증명을 얻는다. 그 자격 증명을 사용하여 해당 호스트로 SSH를 하고 Docker를 수동으로 실행한다. 작동하는가?
- kubelet이 `--cloud-provider=aws`로 실행 중인지 확인한다.
- kubelet 로그에서 (예: `journalctl -u kubelet`) 다음과 같은 로그 라인을 확인한다.
- `plugins.go:56] Registering credential provider: aws-ecr-key`
- `provider.go:91] Refreshing cache for provider: *aws_credentials.ecrProvider`
- kubelet 로그 수준을 최소 3 이상으로 늘리고 kubelet 로그에서 (예: `journalctl -u kubelet`) 다음과 같은 로그 라인을 확인한다.
- `aws_credentials.go:109] unable to get ECR credentials from cache, checking ECR API`
- `aws_credentials.go:116] Got ECR credentials from ECR API for <AWS account ID for ECR>.dkr.ecr.<AWS region>.amazonaws.com`
### Azure 컨테이너 레지스트리(ACR) 사용
[Azure 컨테이너 레지스트리](https://azure.microsoft.com/en-us/services/container-registry/)를 사용하는 경우
[Azure 컨테이너 레지스트리](https://azure.microsoft.com/en-us/services/container-registry/)를 사용하는 경우
관리자 역할의 사용자나 서비스 주체(principal) 중 하나를 사용하여 인증할 수 있다.
어느 경우라도, 인증은 표준 Docker 인증을 통해서 수행된다. 이러한 지침은
어느 경우라도, 인증은 표준 Docker 인증을 통해서 수행된다. 이러한 지침은
[azure-cli](https://github.com/azure/azure-cli) 명령줄 도구 사용을 가정한다.
우선 레지스트리를 생성하고 자격 증명을 만들어야한다. 이에 대한 전체 문서는
우선 레지스트리를 생성하고 자격 증명을 만들어야한다. 이에 대한 전체 문서는
[Azure 컨테이너 레지스트리 문서](https://docs.microsoft.com/en-us/azure/container-registry/container-registry-get-started-azure-cli)에서 찾을 수 있다.
컨테이너 레지스트리를 생성하고 나면, 다음의 자격 증명을 사용하여 로그인한다.
@@ -142,7 +142,7 @@ kubelet은 ECR 자격 증명을 가져오고 주기적으로 갱신할 것이다
* `DOCKER_REGISTRY_SERVER`: `${some-registry-name}.azurecr.io`
* `DOCKER_EMAIL`: `${some-email-address}`
해당 변수에 대한 값을 채우고 나면
해당 변수에 대한 값을 채우고 나면
[쿠버네티스 시크릿을 구성하고 그것을 파드 디플로이를 위해서 사용](/ko/docs/concepts/containers/images/#파드에-imagepullsecrets-명시)할 수 있다.
### IBM 클라우드 컨테이너 레지스트리 사용
@@ -159,13 +159,13 @@ Google 쿠버네티스 엔진에서 동작 중이라면, 이미 각 노드에 Go
{{< /note >}}
{{< note >}}
AWS EC2에서 동작 중이고 EC2 컨테이너 레지스트리(ECR)을 사용 중이라면, 각 노드의 kubelet은
AWS EC2에서 동작 중이고 EC2 컨테이너 레지스트리(ECR)을 사용 중이라면, 각 노드의 kubelet은
ECR 로그인 자격 증명을 관리하고 업데이트할 것이다. 그렇다면 이 방법은 쓸 수 없다.
{{< /note >}}
{{< note >}}
이 방법은 노드의 구성을 제어할 수 있는 경우에만 적합하다. 이 방법은
GCE 및 자동 노드 교체를 수행하는 다른 클라우드 제공자에 대해서는 신뢰성 있게 작동하지
이 방법은 노드의 구성을 제어할 수 있는 경우에만 적합하다. 이 방법은
GCE 및 자동 노드 교체를 수행하는 다른 클라우드 제공자에 대해서는 신뢰성 있게 작동하지
않을 것이다.
{{< /note >}}
@@ -174,7 +174,7 @@ GCE 및 자동 노드 교체를 수행하는 다른 클라우드 제공자에
{{< /note >}}
Docker는 프라이빗 레지스트리를 위한 키를 `$HOME/.dockercfg` 또는 `$HOME/.docker/config.json` 파일에 저장한다. 만약 동일한 파일을
Docker는 프라이빗 레지스트리를 위한 키를 `$HOME/.dockercfg` 또는 `$HOME/.docker/config.json` 파일에 저장한다. 만약 동일한 파일을
아래의 검색 경로 리스트에 넣으면, kubelete은 이미지를 풀 할 때 해당 파일을 자격 증명 공급자로 사용한다.
* `{--root-dir:-/var/lib/kubelet}/config.json`
@@ -190,11 +190,11 @@ Docker는 프라이빗 레지스트리를 위한 키를 `$HOME/.dockercfg` 또
아마도 kubelet을 위한 사용자의 환경 파일에 `HOME=/root`을 명시적으로 설정해야 할 것이다.
{{< /note >}}
프라이빗 레지스트리를 사용도록 사용자의 노드를 구성하기 위해서 권장되는 단계는 다음과 같다. 이
프라이빗 레지스트리를 사용도록 사용자의 노드를 구성하기 위해서 권장되는 단계는 다음과 같다. 이
예제의 경우, 사용자의 데스크탑/랩탑에서 아래 내용을 실행한다.
1. 사용하고 싶은 각 자격 증명 세트에 대해서 `docker login [서버]`를 실행한다. 이것은 `$HOME/.docker/config.json`를 업데이트한다.
1. 편집기에서 `$HOME/.docker/config.json`를 보고 사용하고 싶은 자격 증명만 포함하고 있는지 확인한다.
1. 편집기에서 `$HOME/.docker/config.json`를 보고 사용하고 싶은 자격 증명만 포함하고 있는지 확인한다.
1. 노드의 리스트를 구한다. 예를 들면 다음과 같다.
- 이름을 원하는 경우: `nodes=$(kubectl get nodes -o jsonpath='{range.items[*].metadata}{.name} {end}')`
- IP를 원하는 경우: `nodes=$(kubectl get nodes -o jsonpath='{range .items[*].status.addresses[?(@.type=="ExternalIP")]}{.address} {end}')`
@@ -203,7 +203,7 @@ Docker는 프라이빗 레지스트리를 위한 키를 `$HOME/.dockercfg` 또
프라이빗 이미지를 사용하는 파드를 생성하여 검증한다. 예를 들면 다음과 같다.
```yaml
```shell
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
@@ -216,29 +216,36 @@ spec:
imagePullPolicy: Always
command: [ "echo", "SUCCESS" ]
EOF
```
```
pod/private-image-test-1 created
```
만약 모든 것이 잘 작동한다면, 잠시 후에, 다음 메시지를 볼 것이다.
만약 모든 것이 잘 작동한다면, 잠시 후에, 다음을 실행할 수 있다.
```shell
kubectl logs private-image-test-1
```
그리고 커맨드 출력을 본다.
```
SUCCESS
```
만약 실패했다면, 다음 메시지를 볼 것이다.
명령이 실패한 것으로 의심되는 경우 다음을 실행할 수 있다.
```shell
kubectl describe pods/private-image-test-1 | grep "Failed"
kubectl describe pods/private-image-test-1 | grep 'Failed'
```
실패하는 케이스에는 출력이 다음과 유사하다.
```
Fri, 26 Jun 2015 15:36:13 -0700 Fri, 26 Jun 2015 15:39:13 -0700 19 {kubelet node-i2hq} spec.containers{uses-private-image} failed Failed to pull image "user/privaterepo:v1": Error: image user/privaterepo:v1 not found
```
클러스터의 모든 노드가 반드시 동일한 `.docker/config.json`를 가져야 한다. 그렇지 않으면, 파드가
일부 노드에서만 실행되고 다른 노드에서는 실패할 것이다. 예를 들어, 노드 오토스케일링을 사용한다면, 각 인스턴스
클러스터의 모든 노드가 반드시 동일한 `.docker/config.json`를 가져야 한다. 그렇지 않으면, 파드가
일부 노드에서만 실행되고 다른 노드에서는 실패할 것이다. 예를 들어, 노드 오토스케일링을 사용한다면, 각 인스턴스
템플릿은 `.docker/config.json`을 포함하거나 그것을 포함한 드라이브를 마운트해야 한다.
프라이빗 레지스트리 키가 `.docker/config.json`에 추가되고 나면 모든 파드는
프라이빗 레지스트리 키가 `.docker/config.json`에 추가되고 나면 모든 파드는
프라이빗 레지스트리의 이미지에 읽기 접근 권한을 가지게 될 것이다.
### 미리 내려받은 이미지
@@ -248,16 +255,16 @@ Google 쿠버네티스 엔진에서 동작 중이라면, 이미 각 노드에 Go
{{< /note >}}
{{< note >}}
이 방법은 노드의 구성을 제어할 수 있는 경우에만 적합하다. 이 방법은
GCE 및 자동 노드 교체를 수행하는 다른 클라우드 제공자에 대해서는 신뢰성 있게 작동하지
이 방법은 노드의 구성을 제어할 수 있는 경우에만 적합하다. 이 방법은
GCE 및 자동 노드 교체를 수행하는 다른 클라우드 제공자에 대해서는 신뢰성 있게 작동하지
않을 것이다.
{{< /note >}}
기본적으로, kubelet은 지정된 레지스트리에서 각 이미지를 풀 하려고 할 것이다.
그러나, 컨테이너의 `imagePullPolicy` 속성이 `IfNotPresent` 또는 `Never`으로 설정되어 있다면,
그러나, 컨테이너의 `imagePullPolicy` 속성이 `IfNotPresent` 또는 `Never`으로 설정되어 있다면,
로컬 이미지가 사용된다(우선적으로 또는 배타적으로).
레지스트리 인증의 대안으로 미리 풀 된 이미지에 의존하고 싶다면,
레지스트리 인증의 대안으로 미리 풀 된 이미지에 의존하고 싶다면,
클러스터의 모든 노드가 동일한 미리 내려받은 이미지를 가지고 있는지 확인해야 한다.
이것은 특정 이미지를 속도를 위해 미리 로드하거나 프라이빗 레지스트리에 대한 인증의 대안으로 사용될 수 있다.
@@ -267,7 +274,7 @@ GCE 및 자동 노드 교체를 수행하는 다른 클라우드 제공자에
### 파드에 ImagePullSecrets 명시
{{< note >}}
이 방법은 현재 Google 쿠버네티스 엔진, GCE 및 노드 생성이 자동화된 모든 클라우드 제공자에게
이 방법은 현재 Google 쿠버네티스 엔진, GCE 및 노드 생성이 자동화된 모든 클라우드 제공자에게
권장된다.
{{< /note >}}
@@ -281,10 +288,10 @@ GCE 및 자동 노드 교체를 수행하는 다른 클라우드 제공자에
kubectl create secret docker-registry <name> --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
```
만약 Docker 자격 증명 파일이 이미 존재한다면, 위의 명령을 사용하지 않고,
만약 Docker 자격 증명 파일이 이미 존재한다면, 위의 명령을 사용하지 않고,
자격 증명 파일을 쿠버네티스 시크릿으로 가져올 수 있다.
[기존 Docker 자격 증명으로 시크릿 생성](/docs/tasks/configure-pod-container/pull-image-private-registry/#registry-secret-existing-credentials)에서 관련 방법을 설명하고 있다.
`kubectl create secret docker-registry`
`kubectl create secret docker-registry`
하나의 개인 레지스트리에서만 작동하는 시크릿을 생성하기 때문에,
여러 개인 컨테이너 레지스트리를 사용하는 경우 특히 유용하다.
@@ -295,7 +302,7 @@ kubectl create secret docker-registry <name> --docker-server=DOCKER_REGISTRY_SER
#### 파드의 imagePullSecrets 참조
이제, `imagePullSecrets` 섹션을 파드의 정의에 추가함으로써 해당 시크릿을
이제, `imagePullSecrets` 섹션을 파드의 정의에 추가함으로써 해당 시크릿을
참조하는 파드를 생성할 수 있다.
```shell
@@ -321,41 +328,43 @@ EOF
이것은 프라이빗 레지스트리를 사용하는 각 파드에 대해서 수행될 필요가 있다.
그러나, 이 필드의 셋팅은 [서비스 어카운트](/docs/user-guide/service-accounts) 리소스에
그러나, 이 필드의 셋팅은 [서비스 어카운트](/docs/user-guide/service-accounts) 리소스에
imagePullSecrets을 셋팅하여 자동화할 수 있다.
자세한 지침을 위해서는 [서비스 어카운트에 ImagePullSecrets 추가](/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account)를 확인한다.
이것은 노드 당 `.docker/config.json`와 함께 사용할 수 있다. 자격 증명은
이것은 노드 당 `.docker/config.json`와 함께 사용할 수 있다. 자격 증명은
병합될 것이다. 이 방법은 Google 쿠버네티스 엔진에서 작동될 것이다.
### 유스케이스
프라이빗 레지스트리를 구성하기 위한 많은 솔루션이 있다. 다음은 여러 가지
일반적인 유스케이스와 제안된 솔루션이다.
프라이빗 레지스트리를 구성하기 위한 많은 솔루션이 있다. 다음은 여러 가지
일반적인 유스케이스와 제안된 솔루션이다.
1. 비소유 이미지(예를 들어, 오픈소스)만 실행하는 클러스터의 경우. 이미지를 숨길 필요가 없다.
- Docker hub의 퍼블릭 이미지를 사용한다.
- 설정이 필요 없다.
- GCE 및 Google 쿠버네티스 엔진에서는, 속도와 가용성 향상을 위해서 로컬 미러가 자동적으로 사용된다.
1. 모든 클러스터 사용자에게는 보이지만, 회사 외부에는 숨겨야하는 일부 독점 이미지를
- GCE 및 Google 쿠버네티스 엔진에서는, 속도와 가용성 향상을 위해서 로컬 미러가 자동적으로 사용된다.
1. 모든 클러스터 사용자에게는 보이지만, 회사 외부에는 숨겨야하는 일부 독점 이미지를
실행하는 클러스터의 경우.
- 호스트 된 프라이빗 [Docker 레지스트리](https://docs.docker.com/registry/)를 사용한다.
- 그것은 [Docker Hub](https://hub.docker.com/signup)에 호스트 되어 있거나, 다른 곳에 되어 있을 것이다.
- 위에 설명된 바와 같이 수동으로 .docker/config.json을 구성한다.
- 또는, 방화벽 뒤에서 읽기 접근 권한을 가진 내부 프라이빗 레지스트리를 실행한다.
- 쿠버네티스 구성은 필요 없다.
- 쿠버네티스 구성은 필요 없다.
- 또는, GCE 및 Google 쿠버네티스 엔진에서는, 프로젝트의 Google 컨테이너 레지스트리를 사용한다.
- 그것은 수동 노드 구성에 비해서 클러스터 오토스케일링과 더 잘 동작할 것이다.
- 또는, 노드의 구성 변경이 불편한 클러스터에서는, `imagePullSecrets`를 사용한다.
1. 독점 이미지를 가진 클러스터로, 그 중 일부가 더 엄격한 접근 제어를 필요로 하는 경우.
- [AlwaysPullImages 어드미션 컨트롤러](/docs/reference/access-authn-authz/admission-controllers/#alwayspullimages)가 활성화되어 있는지 확인한다. 그렇지 않으면, 모든 파드가 잠재적으로 모든 이미지에 접근 권한을 가진다.
- 민감한 데이터는 이미지 안에 포장하는 대신, "시크릿" 리소스로 이동한다.
- 민감한 데이터는 이미지 안에 포장하는 대신, "시크릿" 리소스로 이동한다.
1. 멀티-테넌트 클러스터에서 각 테넌트가 자신의 프라이빗 레지스트리를 필요로 하는 경우.
- [AlwaysPullImages 어드미션 컨트롤러](/docs/reference/access-authn-authz/admission-controllers/#alwayspullimages)가 활성화되어 있는지 확인한다. 그렇지 않으면, 모든 파드가 잠재적으로 모든 이미지에 접근 권한을 가진다.
- 인가가 요구되도록 프라이빗 레지스트리를 실행한다.
- 인가가 요구되도록 프라이빗 레지스트리를 실행한다.
- 각 테넌트에 대한 레지스트리 자격 증명을 생성하고, 시크릿에 넣고, 각 테넌트 네임스페이스에 시크릿을 채운다.
- 테넌트는 해당 시크릿을 각 네임스페이스의 imagePullSecrets에 추가한다.
다중 레지스트리에 접근해야 하는 경우, 각 레지스트리에 대해 하나의 시크릿을 생성할 수 있다.
Kubelet은 모든`imagePullSecrets` 파일을 하나의 가상`.docker / config.json` 파일로 병합한다.
{{% /capture %}}
@@ -117,7 +117,7 @@ CRI 런타임 설치에 대한 자세한 내용은 [CRI 설치](/docs/setup/prod
쿠버네티스의 내장 dockershim CRI는 런타임 핸들러를 지원하지 않는다.
#### [containerd](https://containerd.io/)
#### {{< glossary_tooltip term_id="containerd" >}}
런타임 핸들러는 containerd의 구성 파일인 `/etc/containerd/config.toml` 통해 설정한다.
유효한 핸들러는 runtimes 단락 아래에서 설정한다.
@@ -129,10 +129,10 @@ CRI 런타임 설치에 대한 자세한 내용은 [CRI 설치](/docs/setup/prod
더 자세한 containerd의 구성 문서를 살펴본다.
https://github.com/containerd/cri/blob/master/docs/config.md
#### [cri-o](https://cri-o.io/)
#### {{< glossary_tooltip term_id="cri-o" >}}
런타임 핸들러는 cri-o의 구성파일인 `/etc/crio/crio.conf`을 통해 설정한다.
[crio.runtime 테이블](https://github.com/kubernetes-sigs/cri-o/blob/master/docs/crio.conf.5.md#crioruntime-table) 아래에
런타임 핸들러는 CRI-O의 구성파일인 `/etc/crio/crio.conf`을 통해 설정한다.
[crio.runtime 테이블](https://github.com/cri-o/cri-o/blob/master/docs/crio.conf.5.md#crioruntime-table) 아래에
유효한 핸들러를 설정한다.
```
@@ -140,8 +140,9 @@ https://github.com/containerd/cri/blob/master/docs/config.md
runtime_path = "${PATH_TO_BINARY}"
```
더 자세한 cri-o의 구성 문서를 살펴본다.
https://github.com/kubernetes-sigs/cri-o/blob/master/cmd/crio/config.go
더 자세한 것은 CRI-O의 [설정 문서][100]를 본다.
[100]: https://raw.githubusercontent.com/cri-o/cri-o/9f11d1d/docs/crio.conf.5.md
### 스케줄
@@ -9,7 +9,7 @@ card:
{{% capture overview %}}
쿠버네티스를 배포하면 클러스터를 얻는다.
{{< glossary_definition term_id="cluster" length="all" prepend="클러스터는">}}
{{< glossary_definition term_id="cluster" length="all" prepend="쿠버네티스 클러스터는">}}
이 문서는 완전히 작동하는 쿠버네티스 클러스터를 갖기 위해 필요한
다양한 컴포넌트들에 대해 요약하고 정리한다.
@@ -21,13 +21,12 @@ card:
{{% /capture %}}
{{% capture body %}}
## 마스터 컴포넌트
## 컨트롤 플래인 컴포넌트
마스터 컴포넌트는 클러스터의 컨트롤 플레인을 제공한다. 마스터 컴포넌트는 클러스터에 관한 전반적인 결정
(예를 들어, 스케줄링)을 수행하고 클러스터 이벤트(예를 들어, 디플로이먼트의 `replicas` 필드가 요구조건을 충족되지 않을 경우 새로운 {{< glossary_tooltip text="파드" term_id="pod">}}를 구동시키는 것)를 감지하고 반응한다.
컨트롤 플래인 컴포넌트는 클러스터에 관한 전반적인 결정(예를 들어, 스케줄링)을 수행하고 클러스터 이벤트(예를 들어, 디플로이먼트의 `replicas` 필드에 대한 요구조건을 충족되지 않을 경우 새로운 {{< glossary_tooltip text="파드" term_id="pod">}}를 구동시키는 것)를 감지하고 반응한다.
마스터 컴포넌트는 클러스터 내 어떠한 머신에서든지 동작 될 수 있다. 그러나
간결성을 위하여, 구성 스크립트는 보통 동일 머신 상에 모든 마스터 컴포넌트를 구동시키고,
컨트롤 플래인 컴포넌트는 클러스터 내 어떠한 머신에서든지 동작 될 수 있다. 그러나
간결성을 위하여, 구성 스크립트는 보통 동일 머신 상에 모든 컨트롤 플래인 컴포넌트를 구동시키고,
사용자 컨테이너는 해당 머신 상에 동작시키지 않는다. 다중-마스터-VM 설치 예제를 보려면
[고가용성 클러스터 구성하기](/docs/admin/high-availability/)를 확인해본다.
@@ -59,7 +59,7 @@ GET /swagger-2.0.0.pb-v1.gz | GET /openapi/v2 **Accept**: application/com.github
1.14 이전 버전에서 쿠버네티스 apiserver는 `/swaggerapi`에서 [Swagger v1.2](http://swagger.io/)
쿠버네티스 API 스펙을 검색하는데 사용할 수 있는 API도 제공한다.
이러한 엔드포인트는 사용 중단되었으며, 쿠버네티스 1.14에서 제거될 예정이다.
이러한 엔드포인트는 사용 중단되었으며, 쿠버네티스 1.14에서 제거되었다.
## API 버전 규칙
@@ -13,7 +13,7 @@ weight: 30
기본적으로 도커는 호스트-프라이빗 네트워킹을 사용하기에 컨테이너는 동일한 머신에 있는 경우에만 다른 컨테이너와 통신 할 수 있다. 도커 컨테이너가 노드를 통해 통신하려면 머신 포트에 IP 주소가 할당되어야 컨테이너에 전달되거나 프록시된다. 이것은 컨테이너가 사용하는 포트를 매우 신중하게 조정하거나 포트를 동적으로 할당해야 한다는 의미이다.
여러 개발자에 걸쳐있는 포트를 조정하는 것은 규모면에서 매우 어려우며, 사용자가 제어할 수 없는 클러스터 수준의 문제에 노출된다. 쿠버네티스는 파드가 배치된 호스트와는 무관하게 다른 파드와 통신할 수 있다고 가정한다. 모든 파드에게 자체 클러스터-프라이빗-IP 주소를 제공하기 때문에 파드간에 명시적으로 링크를 만들거나 컨테이너 포트를 호스트 포트에 매핑 할 필요가 없다. 이것은 파드 내의 컨테이너는 모두 로컬호스트에서 서로의 포트에 도달할 수 있으며 클러스터의 모든 파드는 NAT 없이 서로를 볼 수 있다는 의미이다. 이 문서의 나머지 부분에서는 이러한 네트워킹 모델에서 신뢰할 수 있는 서비스를 실행하는 방법에 대해 자세히 설명할 것이다.
컨테이너를 제공하는 여러 개발자 또는 팀에서 포트를 조정하는 것은 규모면에서 매우 어려우며, 사용자가 제어할 수 없는 클러스터 수준의 문제에 노출된다. 쿠버네티스는 파드가 배치된 호스트와는 무관하게 다른 파드와 통신할 수 있다고 가정한다. 쿠버네티스는 모든 파드에게 자체 클러스터-프라이빗 IP 주소를 제공하기 때문에 파드간에 명시적으로 링크를 만들거나 컨테이너 포트를 호스트 포트에 매핑 할 필요가 없다. 이것은 파드 내의 컨테이너는 모두 로컬호스트에서 서로의 포트에 도달할 수 있으며 클러스터의 모든 파드는 NAT 없이 서로를 볼 수 있다는 의미이다. 이 문서의 나머지 부분에서는 이러한 네트워킹 모델에서 신뢰할 수 있는 서비스를 실행하는 방법에 대해 자세히 설명할 것이다.
이 가이드는 간단한 nginx 서버를 사용해서 개념증명을 보여준다. 동일한 원칙이 보다 완전한 [Jenkins CI 애플리케이션](https://kubernetes.io/blog/2015/07/strong-simple-ssl-for-kubernetes)에서 구현된다.
@@ -1,7 +1,7 @@
---
title: 엔드포인트 슬라이스
title: 엔드포인트슬라이스
feature:
title: 엔드포인트 슬라이스
title: 엔드포인트슬라이스
description: >
쿠버네티스 클러스터에서 확장 가능한 네트워크 엔드포인트 추적.
@@ -14,7 +14,7 @@ weight: 10
{{< feature-state for_k8s_version="v1.17" state="beta" >}}
_엔드포인트 슬라이스_ 는 쿠버네티스 클러스터 내의 네트워크 엔드포인트를
_엔드포인트슬라이스_ 는 쿠버네티스 클러스터 내의 네트워크 엔드포인트를
추적하는 간단한 방법을 제공한다. 이것은 엔드포인트를 더 확장하고, 확장 가능한
대안을 제안한다.
@@ -22,13 +22,14 @@ _엔드포인트 슬라이스_ 는 쿠버네티스 클러스터 내의 네트워
{{% capture body %}}
## 엔드포인트 슬라이스 리소스 {#endpointslice-resource}
## 엔드포인트슬라이스 리소스 {#endpointslice-resource}
쿠버네티스에서 EndpointSlice는 일련의 네트워크 엔드 포인트에 대한
참조를 포함한다. 쿠버네티스 서비스에 셀렉터가 지정되면 EndpointSlice
컨트롤러는 자동으로 엔드포인트 슬라이스를 생성한다. 이 엔드포인트 슬라이스는
서비스 셀렉터와 매치되는 모든 파드들을 포함하고 참조한다. 엔드포인트
슬라이스는 고유한 서비스와 포트 조합을 통해 네트워크 엔드포인트를 그룹화 한다.
참조를 포함한다. 쿠버네티스 서비스에 {{< glossary_tooltip text="셀렉터"
term_id="selector" >}} 가 지정되면 EndpointSlice
컨트롤러는 자동으로 엔드포인트슬라이스를 생성한다. 엔드포인트슬라이스는
서비스 셀렉터와 매치되는 모든 파드들을 포함하고 참조한다. 엔드포인트슬라이스는
고유한 서비스와 포트 조합을 통해 네트워크 엔드포인트를 그룹화 한다.
예를 들어, 여기에 `example` 쿠버네티스 서비스를 위한 EndpointSlice
리소스 샘플이 있다.
@@ -47,7 +48,7 @@ ports:
port: 80
endpoints:
- addresses:
- "10.1.2.3"
- "10.1.2.3"
conditions:
ready: true
hostname: pod-1
@@ -56,15 +57,15 @@ endpoints:
topology.kubernetes.io/zone: us-west2-a
```
기본적으로, EndpointSlice 컨트롤러가 관리하는 엔드포인트 슬라이스에는
각각 100개 이하의 엔드포인트를 가지고 있다. 이 스케일 아래에서 엔드포인트 슬라이스는
기본적으로, EndpointSlice 컨트롤러가 관리하는 엔드포인트슬라이스에는
각각 100개 이하의 엔드포인트를 가지고 있다. 이 스케일 아래에서 엔드포인트슬라이스는
엔드포인트 및 서비스와 1:1로 매핑해야하며, 유사한 성능을 가져야 한다.
엔드포인트 슬라이스는 내부 트래픽을 라우트하는 방법에 대해 kube-proxy에
엔드포인트슬라이스는 내부 트래픽을 라우트하는 방법에 대해 kube-proxy에
신뢰할 수 있는 소스로 역할을 할 수 있다. 이를 활성화 하면, 많은 수의 엔드포인트를 가지는
서비스에 대해 성능 향상을 제공해야 한다.
## 주소 유형
### 주소 유형
EndpointSlice는 다음 주소 유형을 지원한다.
@@ -72,6 +73,94 @@ EndpointSlice는 다음 주소 유형을 지원한다.
* IPv6
* FQDN (Fully Qualified Domain Name)
### 토폴로지
엔드포인트슬라이스 내 각 엔드포인트는 연관된 토폴로지 정보를 포함할 수 있다.
이는 해당 노드, 영역 그리고 지역에 대한 정보가 포함된
엔드포인트가 있는 위치를 나타나는데 사용 한다. 값을 사용할 수 있으면
다음의 토폴로지 레이블이 엔드포인트슬라이스 컨트롤러에 의해 설정된다.
* `kubernetes.io/hostname` - 이 엔드포인트가 있는 노드의 이름.
* `topology.kubernetes.io/zone` - 이 엔드포인트가 있는 영역의 이름.
* `topology.kubernetes.io/region` - 이 엔드포인트가 있는 지역의 이름.
이런 레이블 값은 슬라이스의 각 엔드포인트와 연관된 리소스에서
파생된다. 호스트 이름 레이블은 해당 파드의
NodeName 필드 값을 나타낸다. 영역 및 지역 레이블은 해당
노드에서 이름이 같은 값을 나타낸다.
### 관리
기본적으로 엔드포인트슬라이스는 엔드포인트슬라이스 컨트롤러에의해
생성되고 관리된다. 서비스 메시 구현과 같은 다른 엔드포인트슬라이스
유스 케이스는 다른 엔터티나 컨트롤러가 추가 엔드포인트슬라이스
집합을 관리할 수 있게 할 수 있다. 여러 엔티티가 서로 간섭하지 않고
엔드포인트슬라이스를 관리할 수 있도록 엔드포인트슬라이스를 관리하는
엔티티를 나타내는데 `endpointslice.kubernetes.io/managed-by` 레이블이 사용된다.
엔드포인트슬라이스 컨트롤러는 관리하는 모든 엔드포인트
슬라이스에 레이블의 값으로 `endpointslice-controller.k8s.io` 를 설정한다.
엔드포인트슬라이스를 관리하는 다른 엔티티도 이 레이블에
고유한 값을 설정해야 한다.
### 소유권
대부분의 유스 케이스에서 엔드포인트를 추적하는 서비스가 엔드포인트슬라이스를
소유한다. 이는 각 엔드포인트슬라이스의 참조와 서비스에 속하는 모든
엔드포인트슬라이스를 간단하게 조회할 수 있는 `kubernetes.io/service-name`
레이블로 표시된다.
## 엔드포인트슬라이스 컨트롤러
엔드포인트슬라이스 컨트롤러는 해당 엔드포인트슬라이스가 최신 상태인지
확인하기 위해 서비스와 파드를 감시한다. 컨트롤러가 셀렉터로 지정한 모든
서비스에 대해 엔드포인트슬라이스를 관리한다. 이는 서비스 셀렉터와
일치하는 파드의 IP를 나타내게 된다.
### 엔드포인트슬라이스의 크기
기본적으로 엔드포인트슬라이스는 각각 100개의 엔드포인트 크기로 제한된다.
최대 1000개까지 `--max-endpoints-per-slice` {{< glossary_tooltip
text="kube-controller-manager" term_id="kube-controller-manager" >}} 플래그를
사용해서 구성할 수 있다.
### 엔드포인트슬라이스의 배포
각 엔드포인트슬라이스에는 리소스 내에 모든 엔드포인트가 적용되는
포트 집합이 있다. 서비스에 알려진 포트를 사용하는 경우 파드는
동일하게 알려진 포트에 대해 다른 대상 포트 번호로 끝날 수 있으며 다른
엔드포인트슬라이스가 필요하다. 이는 하위 집합이 엔드포인트와 그룹화하는
방식의 논리와 유사하다.
컨트롤러는 엔드포인트슬라이스를 최대한 채우려고 노력하지만,
적극적으로 재조정하지는 않는다. 컨트롤러의 동작은 매우 직관적이다.
1. 기존 엔드포인트슬라이스에 대해 반복적으로, 더 이상 필요하지 않는 엔드포인트를
제거하고 변경에 의해 일치하는 엔드포인트를 업데이트 한다.
2. 첫 번째 단계에서 수정된 엔드포인트슬라이스를 반복해서
필요한 새 엔드포인트로 채운다.
3. 추가할 새 엔드포인트가 여전히 남아있으면, 이전에 변경되지 않은
슬라이스에 엔드포인트를 맞추거나 새로운 것을 생성한다.
중요한 것은, 세 번째 단계는 엔드포인트슬라이스를 완벽하게 전부 배포하는 것보다
엔드포인트슬라이스 업데이트 제한을 우선시한다. 예를 들어, 추가할 새 엔드포인트가
10개이고 각각 5개의 공간을 사용할 수 있는 엔드포인트 공간이 있는 2개의
엔드포인트슬라이스가 있는 경우, 이 방법은 기존 엔드포인트슬라이스
2개를 채우는 대신에 새 엔드포인트슬라이스를 생성한다. 다른 말로, 단일
엔드포인트슬라이스를 생성하는 것이 여러 엔드포인트슬라이스를 업데이트하는 것 보다 더 선호된다.
각 노드에서 kube-proxy를 실행하고 엔드포인트슬라이스를 관찰하면,
엔드포인트슬라이스에 대한 모든 변경 사항이 클러스터의 모든 노드로 전송되기
때문에 상대적으로 비용이 많이 소요된다. 이 방법은 여러 엔드포인트슬라이스가
가득 차지 않은 결과가 발생할지라도, 모든 노드에 전송해야 하는
변경 횟수를 의도적으로 제한하기 위한 것이다.
실제로는, 이러한 이상적이지 않은 분배는 드물 것이다. 엔드포인트슬라이스
컨트롤러에서 처리하는 대부분의 변경 내용은 기존 엔드포인트슬라이스에
적합할 정도로 적고, 그렇지 않은 경우 새 엔드포인트슬라이스가
필요할 수 있다. 디플로이먼트의 롤링 업데이트도 모든 파드와 해당
교체되는 엔드포인트에 대해서 엔드포인트슬라이스를
자연스럽게 재포장한다.
## 사용동기
엔드포인트 API는 쿠버네티스에서 네트워크 엔드포인트를 추적하는
@@ -84,14 +173,14 @@ EndpointSlice는 다음 주소 유형을 지원한다.
리소스에 저장되기 때문에 엔드포인트 리소스가 상당히 커질 수 있다. 이것은 쿠버네티스
구성요소 (특히 마스터 컨트롤 플레인)의 성능에 영향을 미쳤고
엔드포인트가 변경될 때 상당한 양의 네트워크 트래픽과 처리를 초래했다.
엔드포인트 슬라이스는 이러한 문제를 완화하고 토폴로지 라우팅과
엔드포인트슬라이스는 이러한 문제를 완화하고 토폴로지 라우팅과
같은 추가 기능을 위한 확장 가능한 플랫폼을 제공한다.
{{% /capture %}}
{{% capture whatsnext %}}
* [엔드포인트 슬라이스 활성화하기](/docs/tasks/administer-cluster/enabling-endpointslices)
* [엔드포인트슬라이스 활성화하기](/docs/tasks/administer-cluster/enabling-endpointslices)
* [애플리케이션을 서비스와 함께 연결하기](/ko/docs/concepts/services-networking/connect-applications-service/) 를 읽는다.
{{% /capture %}}
@@ -21,6 +21,7 @@ kube-controller-manager 바이너리의 일부로 실행되는 컨트롤러의
## 추가 컨트롤러
* [AKS Application Gateway Ingress Controller](https://github.com/Azure/application-gateway-kubernetes-ingress) is an ingress controller that enables ingress to [AKS clusters](https://docs.microsoft.com/azure/aks/kubernetes-walkthrough-portal) using the [Azure Application Gateway](https://docs.microsoft.com/azure/application-gateway/overview).
* [Ambassador](https://www.getambassador.io/) API 게이트웨이는 [Datawire](https://www.datawire.io/)의
[커뮤니티](https://www.getambassador.io/docs) 혹은 [상업적](https://www.getambassador.io/pro/) 지원을 제공하는
[Envoy](https://www.envoyproxy.io) 기반 인그레스 컨트롤러다.
@@ -184,17 +184,17 @@ ExternalName 서비스는 셀렉터가 없고
DNS명을 대신 사용하는 특수한 상황의 서비스이다. 자세한 내용은
이 문서 뒷부분의 [ExternalName](#externalname) 섹션을 참조한다.
### 엔드포인트 슬라이스
### 엔드포인트슬라이스
{{< feature-state for_k8s_version="v1.17" state="beta" >}}
엔드포인트 슬라이스는 엔드포인트에 보다 확장 가능한 대안을 제공할 수 있는
API 리소스이다. 개념적으로 엔드포인트와 매우 유사하지만, 엔드포인트 슬라이스를
엔드포인트슬라이스는 엔드포인트에 보다 확장 가능한 대안을 제공할 수 있는
API 리소스이다. 개념적으로 엔드포인트와 매우 유사하지만, 엔드포인트슬라이스를
사용하면 여러 리소스에 네트워크 엔드포인트를 분산시킬 수 있다. 기본적으로,
엔드포인트 슬라이스는 100개의 엔드포인트에 도달하면 "가득찬 것"로 간주되며,
추가 엔드포인트를 저장하기 위해서는 추가 엔드포인트 슬라이스가
엔드포인트슬라이스는 100개의 엔드포인트에 도달하면 "가득찬 것"로 간주되며,
추가 엔드포인트를 저장하기 위해서는 추가 엔드포인트슬라이스가
생성된다.
엔드포인트 슬라이스는 [엔드포인트 슬라이스](/ko/docs/concepts/services-networking/endpoint-slices/)에서
엔드포인트슬라이스는 [엔드포인트슬라이스](/ko/docs/concepts/services-networking/endpoint-slices/)에서
자세하게 설명된 추가적인 속성 및 기능을 제공한다.
## 가상 IP와 서비스 프록시
@@ -484,7 +484,7 @@ API에서 `엔드포인트` 레코드를 생성하고, DNS 구성을 수정하
`externalName` 필드의 컨텐츠 (예:`foo.bar.example.com`)에
맵핑한다. 어떤 종류의 프록시도 설정되어 있지 않다.
{{< note >}}
`ExternalName` 유형을 사용하려면 CoreDNS 버전 1.7 이상이 필요하다.
`ExternalName` 유형을 사용하려면 kube-dns 버전 1.7 또는 CoreDNS 버전 1.7 이상이 필요하다.
{{< /note >}}
[인그레스](/ko/docs/concepts/services-networking/ingress/)를 사용하여 서비스를 노출시킬 수도 있다. 인그레스는 서비스 유형이 아니지만, 클러스터의 진입점 역할을 한다. 동일한 IP 주소로 여러 서비스를 노출시킬 수 있기 때문에 라우팅 규칙을 단일 리소스로 통합할 수 있다.
@@ -548,6 +548,9 @@ status:
외부 로드 밸런서의 트래픽은 백엔드 파드로 전달된다. 클라우드 공급자는 로드 밸런싱 방식을 결정한다.
로드 밸런서 서비스 유형의 경우 두 개 이상의 포트가 정의된 경우,
모든 포트의 프로토콜이 동일해야 하고, 프로토콜은 `TCP`, `UDP` 그리고
`SCTP` 중 하나여야 한다.
일부 클라우드 공급자는 `loadBalancerIP`를 지정할 수 있도록 허용한다. 이 경우, 로드 밸런서는
사용자 지정 `loadBalancerIP`로 생성된다. `loadBalancerIP` 필드가 지정되지 않으면,
@@ -1100,21 +1103,15 @@ IPVS는 로드 밸런싱을 위해 설계되었고 커널-내부 해시 테이
### TCP
{{< feature-state for_k8s_version="v1.0" state="stable" >}}
모든 종류의 서비스에 TCP를 사용할 수 있으며, 이는 기본 네트워크 프로토콜이다.
### UDP
{{< feature-state for_k8s_version="v1.0" state="stable" >}}
대부분의 서비스에 UDP를 사용할 수 있다. type=LoadBalancer 서비스의 경우, UDP 지원은
이 기능을 제공하는 클라우드 공급자에 따라 다르다.
### HTTP
{{< feature-state for_k8s_version="v1.1" state="stable" >}}
클라우드 공급자가 이를 지원하는 경우, LoadBalancer 모드의
서비스를 사용하여 서비스의 엔드포인트로 전달하는 외부 HTTP / HTTPS 리버스 프록시를
설정할 수 있다.
@@ -1126,8 +1123,6 @@ HTTP / HTTPS 서비스를 노출할 수도 있다.
### PROXY 프로토콜
{{< feature-state for_k8s_version="v1.1" state="stable" >}}
클라우드 공급자가 지원하는 경우에 (예: [AWS](/docs/concepts/cluster-administration/cloud-providers/#aws)),
LoadBalancer 모드의 서비스를 사용하여 쿠버네티스 자체 외부에
로드 밸런서를 구성할 수 있으며, 이때 접두사가
@@ -1196,6 +1191,6 @@ kube-proxy는 유저스페이스 모드에 있을 때 SCTP 연결 관리를 지
* [서비스와 애플리케이션 연결](/docs/concepts/services-networking/connect-applications-service/) 알아보기
* [인그레스](/ko/docs/concepts/services-networking/ingress/)에 대해 알아보기
* [엔드포인트 슬라이스](/ko/docs/concepts/services-networking/endpoint-slices/)에 대해 알아보기
* [엔드포인트슬라이스](/ko/docs/concepts/services-networking/endpoint-slices/)에 대해 알아보기
{{% /capture %}}
@@ -16,8 +16,8 @@ weight: 10
## 레플리카셋의 작동 방식
레플리카셋을 정의하는 필드는 획득 가능한 파드를 식별하는 방법이 명시된 셀렉터, 유지해야 하는 파드 개수를 명시하는 레플리카의 개수,
그리고 레플리카 수 유지를 위해 생성하는 신규 파드에 대한 데이터를 명시하는 파드 템플릿을 포함한다.
레플리카셋을 정의하는 필드는 획득 가능한 파드를 식별하는 방법이 명시된 셀렉터, 유지해야 하는 파드 개수를 명시하는 레플리카의 개수,
그리고 레플리카 수 유지를 위해 생성하는 신규 파드에 대한 데이터를 명시하는 파드 템플릿을 포함한다.
그러면 레플리카셋은 필드에 지정된 설정을 충족하기 위해 필요한 만큼 파드를 만들고 삭제한다.
레플리카셋이 새로운 파드를 생성해야 할 경우, 명시된 파드 템플릿을
사용한다.
@@ -27,16 +27,16 @@ weight: 10
레플리카셋이 가지고 있는 모든 파드의 ownerReferences 필드는 해당 파드를 소유한 레플리카셋을 식별하기 위한 소유자 정보를 가진다.
이 링크를 통해 레플리카셋은 자신이 유지하는 파드의 상태를 확인하고 이에 따라 관리 한다.
레플리카셋은 셀렉터를 이용해서 필요한 새 파드를 식별한다. 만약 파드에 OwnerReference이 없거나
OwnerReference가 {{< glossary_tooltip term_id="controller" >}} 가 아니고 레플리카셋의 셀렉터와 일치한다면 레플리카셋이 즉각 파드를
레플리카셋은 셀렉터를 이용해서 필요한 새 파드를 식별한다. 만약 파드에 OwnerReference이 없거나
OwnerReference가 {{< glossary_tooltip term_id="controller" >}} 가 아니고 레플리카셋의 셀렉터와 일치한다면 레플리카셋이 즉각 파드를
가지게 될 것이다.
## 레플리카셋을 사용하는 시기
레플리카셋은 지정된 수의 파드 레플리카가 항상 실행되도록 보장한다.
그러나 디플로이먼트는 레플리카셋을 관리하고 다른 유용한 기능과 함께
그러나 디플로이먼트는 레플리카셋을 관리하고 다른 유용한 기능과 함께
파드에 대한 선언적 업데이트를 제공하는 상위 개념이다.
따라서 우리는 사용자 지정 오케스트레이션이 필요하거나 업데이트가 전혀 필요하지 않은 경우라면
따라서 우리는 사용자 지정 오케스트레이션이 필요하거나 업데이트가 전혀 필요하지 않은 경우라면
레플리카셋을 직접적으로 사용하기 보다는 디플로이먼트를 사용하는 것을 권장한다.
이는 레플리카셋 오브젝트를 직접 조작할 필요가 없다는 것을 의미한다.
@@ -46,7 +46,7 @@ OwnerReference가 {{< glossary_tooltip term_id="controller" >}} 가 아니고
{{< codenew file="controllers/frontend.yaml" >}}
이 매니페스트를 `frontend.yaml`에 저장하고 쿠버네티스 클러스터에 적용하면 정의되어있는 레플리카셋이
이 매니페스트를 `frontend.yaml`에 저장하고 쿠버네티스 클러스터에 적용하면 정의되어있는 레플리카셋이
생성되고 레플리카셋이 관리하는 파드가 생성된다.
```shell
@@ -129,7 +129,7 @@ metadata:
name: frontend-b2zdv
namespace: default
ownerReferences:
- apiVersion: extensions/v1beta1
- apiVersion: apps/v1
blockOwnerDeletion: true
controller: true
kind: ReplicaSet
@@ -141,24 +141,24 @@ metadata:
## 템플릿을 사용하지 않는 파드의 획득
단독(bare) 파드를 생성하는 것에는 문제가 없지만, 단독 파드가 레플리카셋의 셀렉터와 일치하는 레이블을 가지지
않도록 하는 것을 강력하게 권장한다. 그 이유는 레플리카셋이 소유하는 파드가 템플릿에 명시된 파드에만 국한되지 않고,
않도록 하는 것을 강력하게 권장한다. 그 이유는 레플리카셋이 소유하는 파드가 템플릿에 명시된 파드에만 국한되지 않고,
이전 섹션에서 명시된 방식에 의해서도 다른 파드의 획득이 가능하기 때문이다.
이전 프런트엔드 레플리카셋 예제와 다음의 매니페스트에 명시된 파드를 가져와 참조한다.
{{< codenew file="pods/pod-rs.yaml" >}}
기본 파드는 소유자 관련 정보에 컨트롤러(또는 오브젝트)를 가지지 않기 때문에 프런트엔드
기본 파드는 소유자 관련 정보에 컨트롤러(또는 오브젝트)를 가지지 않기 때문에 프런트엔드
레플리카셋의 셀렉터와 일치하면 즉시 레플리카셋에 소유된다.
프런트엔드 레플리카셋이 배치되고 초기 파드 레플리카가 셋업된 이후에, 레플리카 수 요구 사항을 충족시키기 위해서
프런트엔드 레플리카셋이 배치되고 초기 파드 레플리카가 셋업된 이후에, 레플리카 수 요구 사항을 충족시키기 위해서
신규 파드를 생성한다고 가정해보자.
```shell
kubectl apply -f https://kubernetes.io/examples/pods/pod-rs.yaml
```
새로운 파드는 레플리카셋에 의해 인식되며 레플리카셋이 필요한 수량을 초과하면
새로운 파드는 레플리카셋에 의해 인식되며 레플리카셋이 필요한 수량을 초과하면
즉시 종료된다.
파드를 가져온다.
@@ -186,7 +186,7 @@ kubectl apply -f https://kubernetes.io/examples/pods/pod-rs.yaml
kubectl apply -f https://kubernetes.io/examples/controllers/frontend.yaml
```
레플리카셋이 해당 파드를 소유한 것을 볼 수 있으며 새 파드 및 기존 파드의 수가
레플리카셋이 해당 파드를 소유한 것을 볼 수 있으며 새 파드 및 기존 파드의 수가
레플리카셋이 필요로 하는 수와 일치할 때까지 사양에 따라 신규 파드만 생성한다. 파드를 가져온다.
```shell
kubectl get pods
@@ -230,7 +230,7 @@ matchLabels:
tier: frontend
```
레플리카셋에서 `.spec.template.metadata.labels``spec.selector`과 일치해야 하며
레플리카셋에서 `.spec.template.metadata.labels``spec.selector`과 일치해야 하며
그렇지 않으면 API에 의해 거부된다.
{{< note >}}
@@ -250,12 +250,12 @@ matchLabels:
레플리카셋 및 모든 파드를 삭제하려면 [`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete)를 사용한다. [가비지 수집기](/ko/docs/concepts/workloads/controllers/garbage-collection/)는 기본적으로 종속되어있는 모든 파드를 자동으로 삭제한다.
REST API또는 `client-go` 라이브러리를 이용할 때는 -d 옵션으로 `propagationPolicy``Background`또는 `Foreground`
REST API또는 `client-go` 라이브러리를 이용할 때는 -d 옵션으로 `propagationPolicy``Background`또는 `Foreground`
설정해야 한다.
예시:
```shell
kubectl proxy --port=8080
curl -X DELETE 'localhost:8080/apis/extensions/v1beta1/namespaces/default/replicasets/frontend' \
curl -X DELETE 'localhost:8080/apis/apps/v1/namespaces/default/replicasets/frontend' \
> -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Foreground"}' \
> -H "Content-Type: application/json"
```
@@ -267,7 +267,7 @@ REST API 또는 `client-go` 라이브러리를 이용할 때는 `propagationPoli
예시:
```shell
kubectl proxy --port=8080
curl -X DELETE 'localhost:8080/apis/extensions/v1beta1/namespaces/default/replicasets/frontend' \
curl -X DELETE 'localhost:8080/apis/apps/v1/namespaces/default/replicasets/frontend' \
> -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Orphan"}' \
> -H "Content-Type: application/json"
```
@@ -275,12 +275,12 @@ curl -X DELETE 'localhost:8080/apis/extensions/v1beta1/namespaces/default/repli
원본이 삭제되면 새 레플리카셋을 생성해서 대체할 수 있다.
기존 `.spec.selector`와 신규 `.spec.selector`가 같으면 새 레플리카셋은 기존 파드를 선택한다.
하지만 신규 레플리카셋은 기존 파드를 신규 레플리카셋의 새롭고 다른 파드 템플릿에 일치시키는 작업을 수행하지는 않는다.
컨트롤 방식으로 파드를 새로운 사양으로 업데이트 하기 위해서는 [디플로이먼트](/ko/docs/concepts/workloads/controllers/deployment/#디플로이먼트-생성)를 이용하면 된다.
컨트롤 방식으로 파드를 새로운 사양으로 업데이트 하기 위해서는 [디플로이먼트](/ko/docs/concepts/workloads/controllers/deployment/#디플로이먼트-생성)를 이용하면 된다.
이는 레플리카셋이 롤링 업데이트를 직접적으로 지원하지 않기 때문이다.
### 레플리카셋에서 파드 격리
레이블을 변경하면 레플리카셋에서 파드를 제거할 수 있다. 이 방식은 디버깅과 데이터 복구 등을
레이블을 변경하면 레플리카셋에서 파드를 제거할 수 있다. 이 방식은 디버깅과 데이터 복구 등을
위해 서비스에서 파드를 제거하는 데 사용할 수 있다. 이 방식으로 제거된 파드는 자동으로 교체된다(
레플리카의 수가 변경되지 않는다고 가정한다).
@@ -291,15 +291,15 @@ curl -X DELETE 'localhost:8080/apis/extensions/v1beta1/namespaces/default/repli
### 레플리카셋을 Horizontal Pod Autoscaler 대상으로 설정
레플리카 셋은
레플리카 셋은
[Horizontal Pod Autoscalers (HPA)](/ko/docs/tasks/run-application/horizontal-pod-autoscale/)의 대상이 될 수 있다.
즉, 레플리카셋은 HPA에 의해 오토스케일될 수 있다.
다음은 이전에 만든 예시에서 만든 레플리카셋을 대상으로 하는 HPA 예시이다.
{{< codenew file="controllers/hpa-rs.yaml" >}}
이 매니페스트를 `hpa-rs.yaml`로 저장한 다음 쿠버네티스
클러스터에 적용하면 CPU 사용량에 따라 파드가 복제되는
이 매니페스트를 `hpa-rs.yaml`로 저장한 다음 쿠버네티스
클러스터에 적용하면 CPU 사용량에 따라 파드가 복제되는
오토스케일 레플리카 셋 HPA가 생성된다.
```shell
@@ -317,7 +317,7 @@ kubectl autoscale rs frontend --max=10
### 디플로이먼트(권장)
[`디플로이먼트`](/ko/docs/concepts/workloads/controllers/deployment/)는 레플리카셋을 소유하거나 업데이트를 하고,
[`디플로이먼트`](/ko/docs/concepts/workloads/controllers/deployment/)는 레플리카셋을 소유하거나 업데이트를 하고,
파드의 선언적인 업데이트와 서버측 롤링 업데이트를 할 수 있는 오브젝트이다.
레플리카셋은 단독으로 사용할 수 있지만, 오늘날에는 주로 디플로이먼트로 파드의 생성과 삭제 그리고 업데이트를 오케스트레이션하는 메커니즘으로 사용한다.
디플로이먼트를 이용해서 배포할 때 생성되는 레플리카셋을 관리하는 것에 대해 걱정하지 않아도 된다.
@@ -335,14 +335,14 @@ kubectl autoscale rs frontend --max=10
### 데몬셋
머신 모니터링 또는 머신 로깅과 같은 머신-레벨의 기능을 제공하는 파드를 위해서는 레플리카셋 대신
머신 모니터링 또는 머신 로깅과 같은 머신-레벨의 기능을 제공하는 파드를 위해서는 레플리카셋 대신
[`데몬셋`](/ko/docs/concepts/workloads/controllers/daemonset/)을 사용한다.
이러한 파드의 수명은 머신의 수명과 연관되어 있고, 머신에서 다른 파드가 시작하기 전에 실행되어야 하며,
이러한 파드의 수명은 머신의 수명과 연관되어 있고, 머신에서 다른 파드가 시작하기 전에 실행되어야 하며,
머신의 재부팅/종료가 준비되었을 때, 해당 파드를 종료하는 것이 안전하다.
### 레플리케이션 컨트롤러
레플리카셋은 [_레플리케이션 컨트롤러_](/ko/docs/concepts/workloads/controllers/replicationcontroller/)를 계승하였다.
이 두 개의 용도는 동일하고, 유사하게 동작하며, 레플리케이션 컨트롤러가 [레이블 사용자 가이드](/ko/docs/concepts/overview/working-with-objects/labels/#레이블-셀렉터)에
이 두 개의 용도는 동일하고, 유사하게 동작하며, 레플리케이션 컨트롤러가 [레이블 사용자 가이드](/ko/docs/concepts/overview/working-with-objects/labels/#레이블-셀렉터)에
설명된 설정-기반의 셀렉터의 요건을 지원하지 않는다는 점을 제외하면 유사하다.
따라서 레플리카셋이 레플리케이션 컨트롤러보다 선호된다.
@@ -6,7 +6,7 @@ weight: 80
{{% capture overview %}}
{{< feature-state state="alpha" >}}
{{< feature-state state="alpha" for_k8s_version="v1.16" >}}
이 페이지는 임시 컨테이너에 대한 개요를 제공한다: 이 특별한 유형의 컨테이너는
트러블 슈팅과 같은 사용자가 시작한 작업을 완료하기위해 기존 {{< glossary_tooltip term_id="pod" >}} 에서
@@ -187,6 +187,7 @@ kubectl attach -it example-pod -c debugger
예를 들어, 임시 컨테이너에 붙은 이후에 디버거 컨테이너에서 `ps` 를 실행한다.
```shell
# "디버거" 임시 컨테이너 내부 쉘에서 이것을 실행한다.
ps auxww
```
다음과 유사하게 출력된다.
@@ -184,7 +184,7 @@ kubelet은 실행 중인 컨테이너들에 대해서 선택적으로 세 가지
...
```
* `Running`: 컨테이너가 이슈 없이 구동된다는 뜻이다. 컨테이너가 Running 상태가 되면, `postStart` 훅이 (존재한다면) 실행된다. 이 상태는 컨테이너가 언제 Running 상태에 돌입한 시간도 함께 출력된다.
* `Running`: 컨테이너가 이슈 없이 구동된다는 뜻이다. `postStart` 훅(있는 경우)은 컨테이너가 Running 상태가 되기 전에 실행된다. 이 상태는 컨테이너가 언제 Running 상태에 돌입한 시간도 함께 출력된다.
```yaml
...