Revert "Repair and sync the dev-1.18 branch" (#19228)
This commit is contained in:
@@ -223,13 +223,11 @@ 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)
|
||||
|
||||
@@ -1,399 +0,0 @@
|
||||
---
|
||||
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 %}}
|
||||
@@ -120,9 +120,9 @@ kubelet은 ECR 자격 증명을 가져오고 주기적으로 갱신할 것이다
|
||||
- 위의 모든 요구 사항을 확인한다.
|
||||
- 워크스테이션에서 $REGION (예: `us-west-2`)의 자격 증명을 얻는다. 그 자격 증명을 사용하여 해당 호스트로 SSH를 하고 Docker를 수동으로 실행한다. 작동하는가?
|
||||
- kubelet이 `--cloud-provider=aws`로 실행 중인지 확인한다.
|
||||
- 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`
|
||||
- kubelet 로그에서 (예: `journalctl -u kubelet`) 다음과 같은 로그 라인을 확인한다.
|
||||
- `plugins.go:56] Registering credential provider: aws-ecr-key`
|
||||
- `provider.go:91] Refreshing cache for provider: *aws_credentials.ecrProvider`
|
||||
|
||||
### Azure 컨테이너 레지스트리(ACR) 사용
|
||||
[Azure 컨테이너 레지스트리](https://azure.microsoft.com/en-us/services/container-registry/)를 사용하는 경우
|
||||
@@ -202,7 +202,7 @@ Docker는 프라이빗 레지스트리를 위한 키를 `$HOME/.dockercfg` 또
|
||||
|
||||
프라이빗 이미지를 사용하는 파드를 생성하여 검증한다. 예를 들면 다음과 같다.
|
||||
|
||||
```shell
|
||||
```yaml
|
||||
kubectl apply -f - <<EOF
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
@@ -215,27 +215,20 @@ 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
|
||||
```
|
||||
|
||||
@@ -361,9 +354,7 @@ imagePullSecrets을 셋팅하여 자동화할 수 있다.
|
||||
- 각 테넌트에 대한 레지스트리 자격 증명을 생성하고, 시크릿에 넣고, 각 테넌트 네임스페이스에 시크릿을 채운다.
|
||||
- 테넌트는 해당 시크릿을 각 네임스페이스의 imagePullSecrets에 추가한다.
|
||||
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
다중 레지스트리에 접근해야 하는 경우, 각 레지스트리에 대해 하나의 시크릿을 생성할 수 있다.
|
||||
Kubelet은 모든`imagePullSecrets` 파일을 하나의 가상`.docker / config.json` 파일로 병합한다.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
@@ -117,7 +117,7 @@ CRI 런타임 설치에 대한 자세한 내용은 [CRI 설치](/docs/setup/prod
|
||||
|
||||
쿠버네티스의 내장 dockershim CRI는 런타임 핸들러를 지원하지 않는다.
|
||||
|
||||
#### {{< glossary_tooltip term_id="containerd" >}}
|
||||
#### [containerd](https://containerd.io/)
|
||||
|
||||
런타임 핸들러는 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
|
||||
|
||||
#### {{< glossary_tooltip term_id="cri-o" >}}
|
||||
#### [cri-o](https://cri-o.io/)
|
||||
|
||||
런타임 핸들러는 CRI-O의 구성파일인 `/etc/crio/crio.conf`을 통해 설정한다.
|
||||
[crio.runtime 테이블](https://github.com/cri-o/cri-o/blob/master/docs/crio.conf.5.md#crioruntime-table) 아래에
|
||||
런타임 핸들러는 cri-o의 구성파일인 `/etc/crio/crio.conf`을 통해 설정한다.
|
||||
[crio.runtime 테이블](https://github.com/kubernetes-sigs/cri-o/blob/master/docs/crio.conf.5.md#crioruntime-table) 아래에
|
||||
유효한 핸들러를 설정한다.
|
||||
|
||||
```
|
||||
@@ -140,9 +140,8 @@ https://github.com/containerd/cri/blob/master/docs/config.md
|
||||
runtime_path = "${PATH_TO_BINARY}"
|
||||
```
|
||||
|
||||
더 자세한 것은 CRI-O의 [설정 문서][100]를 본다.
|
||||
|
||||
[100]: https://raw.githubusercontent.com/cri-o/cri-o/9f11d1d/docs/crio.conf.5.md
|
||||
더 자세한 cri-o의 구성 문서를 살펴본다.
|
||||
https://github.com/kubernetes-sigs/cri-o/blob/master/cmd/crio/config.go
|
||||
|
||||
### 스케줄
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ card:
|
||||
|
||||
{{% capture overview %}}
|
||||
쿠버네티스를 배포하면 클러스터를 얻는다.
|
||||
{{< glossary_definition term_id="cluster" length="all" prepend="쿠버네티스 클러스터는">}}
|
||||
{{< glossary_definition term_id="cluster" length="all" prepend="클러스터는">}}
|
||||
|
||||
이 문서는 완전히 작동하는 쿠버네티스 클러스터를 갖기 위해 필요한
|
||||
다양한 컴포넌트들에 대해 요약하고 정리한다.
|
||||
@@ -21,12 +21,13 @@ 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,14 +22,13 @@ _엔드포인트슬라이스_ 는 쿠버네티스 클러스터 내의 네트워
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
## 엔드포인트슬라이스 리소스 {#endpointslice-resource}
|
||||
## 엔드포인트 슬라이스 리소스 {#endpointslice-resource}
|
||||
|
||||
쿠버네티스에서 EndpointSlice는 일련의 네트워크 엔드 포인트에 대한
|
||||
참조를 포함한다. 쿠버네티스 서비스에 {{< glossary_tooltip text="셀렉터"
|
||||
term_id="selector" >}} 가 지정되면 EndpointSlice
|
||||
컨트롤러는 자동으로 엔드포인트슬라이스를 생성한다. 이 엔드포인트슬라이스는
|
||||
서비스 셀렉터와 매치되는 모든 파드들을 포함하고 참조한다. 엔드포인트슬라이스는
|
||||
고유한 서비스와 포트 조합을 통해 네트워크 엔드포인트를 그룹화 한다.
|
||||
참조를 포함한다. 쿠버네티스 서비스에 셀렉터가 지정되면 EndpointSlice
|
||||
컨트롤러는 자동으로 엔드포인트 슬라이스를 생성한다. 이 엔드포인트 슬라이스는
|
||||
서비스 셀렉터와 매치되는 모든 파드들을 포함하고 참조한다. 엔드포인트
|
||||
슬라이스는 고유한 서비스와 포트 조합을 통해 네트워크 엔드포인트를 그룹화 한다.
|
||||
|
||||
예를 들어, 여기에 `example` 쿠버네티스 서비스를 위한 EndpointSlice
|
||||
리소스 샘플이 있다.
|
||||
@@ -48,7 +47,7 @@ ports:
|
||||
port: 80
|
||||
endpoints:
|
||||
- addresses:
|
||||
- "10.1.2.3"
|
||||
- "10.1.2.3"
|
||||
conditions:
|
||||
ready: true
|
||||
hostname: pod-1
|
||||
@@ -57,15 +56,15 @@ endpoints:
|
||||
topology.kubernetes.io/zone: us-west2-a
|
||||
```
|
||||
|
||||
기본적으로, EndpointSlice 컨트롤러가 관리하는 엔드포인트슬라이스에는
|
||||
각각 100개 이하의 엔드포인트를 가지고 있다. 이 스케일 아래에서 엔드포인트슬라이스는
|
||||
기본적으로, EndpointSlice 컨트롤러가 관리하는 엔드포인트 슬라이스에는
|
||||
각각 100개 이하의 엔드포인트를 가지고 있다. 이 스케일 아래에서 엔드포인트 슬라이스는
|
||||
엔드포인트 및 서비스와 1:1로 매핑해야하며, 유사한 성능을 가져야 한다.
|
||||
|
||||
엔드포인트슬라이스는 내부 트래픽을 라우트하는 방법에 대해 kube-proxy에
|
||||
엔드포인트 슬라이스는 내부 트래픽을 라우트하는 방법에 대해 kube-proxy에
|
||||
신뢰할 수 있는 소스로 역할을 할 수 있다. 이를 활성화 하면, 많은 수의 엔드포인트를 가지는
|
||||
서비스에 대해 성능 향상을 제공해야 한다.
|
||||
|
||||
### 주소 유형
|
||||
## 주소 유형
|
||||
|
||||
EndpointSlice는 다음 주소 유형을 지원한다.
|
||||
|
||||
@@ -73,94 +72,6 @@ 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는 쿠버네티스에서 네트워크 엔드포인트를 추적하는
|
||||
@@ -173,14 +84,14 @@ text="kube-controller-manager" term_id="kube-controller-manager" >}} 플래그
|
||||
리소스에 저장되기 때문에 엔드포인트 리소스가 상당히 커질 수 있다. 이것은 쿠버네티스
|
||||
구성요소 (특히 마스터 컨트롤 플레인)의 성능에 영향을 미쳤고
|
||||
엔드포인트가 변경될 때 상당한 양의 네트워크 트래픽과 처리를 초래했다.
|
||||
엔드포인트슬라이스는 이러한 문제를 완화하고 토폴로지 라우팅과
|
||||
엔드포인트 슬라이스는 이러한 문제를 완화하고 토폴로지 라우팅과
|
||||
같은 추가 기능을 위한 확장 가능한 플랫폼을 제공한다.
|
||||
|
||||
{{% /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,7 +21,6 @@ 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` 유형을 사용하려면 kube-dns 버전 1.7 또는 CoreDNS 버전 1.7 이상이 필요하다.
|
||||
`ExternalName` 유형을 사용하려면 CoreDNS 버전 1.7 이상이 필요하다.
|
||||
{{< /note >}}
|
||||
|
||||
[인그레스](/ko/docs/concepts/services-networking/ingress/)를 사용하여 서비스를 노출시킬 수도 있다. 인그레스는 서비스 유형이 아니지만, 클러스터의 진입점 역할을 한다. 동일한 IP 주소로 여러 서비스를 노출시킬 수 있기 때문에 라우팅 규칙을 단일 리소스로 통합할 수 있다.
|
||||
@@ -548,9 +548,6 @@ status:
|
||||
|
||||
외부 로드 밸런서의 트래픽은 백엔드 파드로 전달된다. 클라우드 공급자는 로드 밸런싱 방식을 결정한다.
|
||||
|
||||
로드 밸런서 서비스 유형의 경우 두 개 이상의 포트가 정의된 경우,
|
||||
모든 포트의 프로토콜이 동일해야 하고, 프로토콜은 `TCP`, `UDP` 그리고
|
||||
`SCTP` 중 하나여야 한다.
|
||||
|
||||
일부 클라우드 공급자는 `loadBalancerIP`를 지정할 수 있도록 허용한다. 이 경우, 로드 밸런서는
|
||||
사용자 지정 `loadBalancerIP`로 생성된다. `loadBalancerIP` 필드가 지정되지 않으면,
|
||||
@@ -1103,15 +1100,21 @@ 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 리버스 프록시를
|
||||
설정할 수 있다.
|
||||
@@ -1123,6 +1126,8 @@ HTTP / HTTPS 서비스를 노출할 수도 있다.
|
||||
|
||||
### PROXY 프로토콜
|
||||
|
||||
{{< feature-state for_k8s_version="v1.1" state="stable" >}}
|
||||
|
||||
클라우드 공급자가 지원하는 경우에 (예: [AWS](/docs/concepts/cluster-administration/cloud-providers/#aws)),
|
||||
LoadBalancer 모드의 서비스를 사용하여 쿠버네티스 자체 외부에
|
||||
로드 밸런서를 구성할 수 있으며, 이때 접두사가
|
||||
@@ -1191,6 +1196,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 %}}
|
||||
|
||||
@@ -73,7 +73,7 @@ kubectl describe rs/frontend
|
||||
```shell
|
||||
Name: frontend
|
||||
Namespace: default
|
||||
Selector: tier=frontend
|
||||
Selector: tier=frontend,tier in (frontend)
|
||||
Labels: app=guestbook
|
||||
tier=frontend
|
||||
Annotations: <none>
|
||||
@@ -132,7 +132,7 @@ metadata:
|
||||
name: frontend-9si5l
|
||||
namespace: default
|
||||
ownerReferences:
|
||||
- apiVersion: apps/v1
|
||||
- apiVersion: extensions/v1beta1
|
||||
blockOwnerDeletion: true
|
||||
controller: true
|
||||
kind: ReplicaSet
|
||||
@@ -257,7 +257,7 @@ REST API또는 `client-go` 라이브러리를 이용할 때는 -d 옵션으로 `
|
||||
예시:
|
||||
```shell
|
||||
kubectl proxy --port=8080
|
||||
curl -X DELETE 'localhost:8080/apis/apps/v1/namespaces/default/replicasets/frontend' \
|
||||
curl -X DELETE 'localhost:8080/apis/extensions/v1beta1/namespaces/default/replicasets/frontend' \
|
||||
> -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Foreground"}' \
|
||||
> -H "Content-Type: application/json"
|
||||
```
|
||||
@@ -269,7 +269,7 @@ REST API 또는 `client-go` 라이브러리를 이용할 때는 `propagationPoli
|
||||
예시:
|
||||
```shell
|
||||
kubectl proxy --port=8080
|
||||
curl -X DELETE 'localhost:8080/apis/apps/v1/namespaces/default/replicasets/frontend' \
|
||||
curl -X DELETE 'localhost:8080/apis/extensions/v1beta1/namespaces/default/replicasets/frontend' \
|
||||
> -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Orphan"}' \
|
||||
> -H "Content-Type: application/json"
|
||||
```
|
||||
|
||||
@@ -6,7 +6,7 @@ weight: 80
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
{{< feature-state state="alpha" for_k8s_version="v1.16" >}}
|
||||
{{< feature-state state="alpha" >}}
|
||||
|
||||
이 페이지는 임시 컨테이너에 대한 개요를 제공한다: 이 특별한 유형의 컨테이너는
|
||||
트러블 슈팅과 같은 사용자가 시작한 작업을 완료하기위해 기존 {{< glossary_tooltip term_id="pod" >}} 에서
|
||||
@@ -187,7 +187,6 @@ kubectl attach -it example-pod -c debugger
|
||||
예를 들어, 임시 컨테이너에 붙은 이후에 디버거 컨테이너에서 `ps` 를 실행한다.
|
||||
|
||||
```shell
|
||||
# "디버거" 임시 컨테이너 내부 쉘에서 이것을 실행한다.
|
||||
ps auxww
|
||||
```
|
||||
다음과 유사하게 출력된다.
|
||||
|
||||
@@ -186,7 +186,7 @@ kubelet은 실행 중인 컨테이너들에 대해서 선택적으로 세 가지
|
||||
...
|
||||
```
|
||||
|
||||
* `Running`: 컨테이너가 이슈 없이 구동된다는 뜻이다. `postStart` 훅(있는 경우)은 컨테이너가 Running 상태가 되기 전에 실행된다. 이 상태는 컨테이너가 언제 Running 상태에 돌입한 시간도 함께 출력된다.
|
||||
* `Running`: 컨테이너가 이슈 없이 구동된다는 뜻이다. 컨테이너가 Running 상태가 되면, `postStart` 훅이 (존재한다면) 실행된다. 이 상태는 컨테이너가 언제 Running 상태에 돌입한 시간도 함께 출력된다.
|
||||
|
||||
```yaml
|
||||
...
|
||||
|
||||
Reference in New Issue
Block a user