From f42a59211595e393768ee1aca901e2b3da3cc942 Mon Sep 17 00:00:00 2001 From: "Yuk, Yongsu" Date: Tue, 14 Jan 2020 12:19:09 +0900 Subject: [PATCH] Third Korean L10n Work For Release 1.17 * Changed some words in the IPv4/IPv6 dual-stack korean doc. (#18668) * Update to Outdated files in dev-1.17-ko.3 branch. (#18580) * Translate content/ko/docs/concepts/services-networking/service in Korean (#18195) * Translate docs/tasks/access-application-cluster/port-forward-access-application-cluster.md in Korean (#18721) * Translate controllers/garbage-collection.md in Korean. (#18595) Co-Authored-by: Seokho Son Co-Authored-by: Lawrence Kay Co-Authored-by: Jesang Myung Co-Authored-by: Claudia J.Kang Co-Authored-by: Yuk, Yongsu Co-Authored-By: June Yi --- .../connect-applications-service.md | 2 +- .../services-networking/dual-stack.md | 8 +- .../concepts/services-networking/service.md | 1201 +++++++++++++++++ .../workloads/controllers/cron-jobs.md | 5 + .../controllers/garbage-collection.md | 182 +++ .../concepts/workloads/pods/pod-overview.md | 2 +- .../glossary/customresourcedefinition.md | 2 +- .../ko/docs/reference/kubectl/cheatsheet.md | 5 +- content/ko/docs/setup/_index.md | 6 +- ...port-forward-access-application-cluster.md | 153 +++ .../ko/examples/controllers/replicaset.yaml | 17 + 11 files changed, 1570 insertions(+), 13 deletions(-) create mode 100644 content/ko/docs/concepts/services-networking/service.md create mode 100644 content/ko/docs/concepts/workloads/controllers/garbage-collection.md create mode 100644 content/ko/docs/tasks/access-application-cluster/port-forward-access-application-cluster.md create mode 100644 content/ko/examples/controllers/replicaset.yaml diff --git a/content/ko/docs/concepts/services-networking/connect-applications-service.md b/content/ko/docs/concepts/services-networking/connect-applications-service.md index a0728564afe07..fce55dbf8e2fc 100644 --- a/content/ko/docs/concepts/services-networking/connect-applications-service.md +++ b/content/ko/docs/concepts/services-networking/connect-applications-service.md @@ -334,7 +334,7 @@ NAME READY STATUS RESTARTS AGE curl-deployment-1515033274-1410r 1/1 Running 0 1m ``` ```shell -kubectl exec curl-deployment-1515033274-1410r -- curl https://my-nginx --cacert /etc/nginx/ssl/nginx.crt +kubectl exec curl-deployment-1515033274-1410r -- curl https://my-nginx --cacert /etc/nginx/ssl/tls.crt ... Welcome to nginx! ... diff --git a/content/ko/docs/concepts/services-networking/dual-stack.md b/content/ko/docs/concepts/services-networking/dual-stack.md index cf4e03d0f7e26..2cdfb310284f1 100644 --- a/content/ko/docs/concepts/services-networking/dual-stack.md +++ b/content/ko/docs/concepts/services-networking/dual-stack.md @@ -28,7 +28,7 @@ weight: 70 * 이중 스택 파드 네트워킹(파드 당 단일 IPv4와 IPv6 주소 할당) * IPv4와 IPv6 지원 서비스(각 서비스는 단일 주소 패밀리이어야 한다.) * Kubenet 다중 주소 패밀리 지원(IPv4와 IPv6) - * IPv4와 IPv6 인터페이스를 통한 파드 오프(off) 클러스터 송신 라우팅(예: 인터넷) + * IPv4와 IPv6 인터페이스를 통한 파드 오프(off) 클러스터 이그레스 라우팅(예: 인터넷) ## 필수 구성 요소 @@ -62,7 +62,7 @@ IPv4/IPv6 이중 스택을 활성화 하려면, 클러스터의 관련 구성요 ## 서비스 만약 클러스터 IPv4/IPv6 이중 스택 네트워킹을 활성화한 경우, IPv4 또는 IPv6 주소로 {{< glossary_tooltip text="서비스" term_id="service" >}} 를 만들 수 있다. 해당 서비스에서 `.spec.ipFamily` 필드를 설정하면, 서비스 클러스터 IP의 주소 패밀리를 선택할 수 있다. -새 서비스를 생성할 때만 이 필드를 설정할 수 있다. `.spec.ipFamily` 필드는 선택 사항이며 클러스터에서 {{< glossary_tooltip text="서비스" term_id="service" >}} 와 {{< glossary_tooltip text="인그레스" term_id="ingress" >}} 를 IPv4와 IPv6로 사용하도록 설정할 경우에만 사용해야 한다. 이 필드의 구성은 [송신](#송신-트래픽)에 대한 요구사항이 아니다. +새 서비스를 생성할 때만 이 필드를 설정할 수 있다. `.spec.ipFamily` 필드는 선택 사항이며 클러스터에서 {{< glossary_tooltip text="서비스" term_id="service" >}} 와 {{< glossary_tooltip text="인그레스" term_id="ingress" >}} 를 IPv4와 IPv6로 사용하도록 설정할 경우에만 사용해야 한다. 이 필드의 구성은 [이그레스](#이그레스-트래픽)에 대한 요구사항이 아니다. {{< note >}} 클러스터의 기본 주소 패밀리는 `--service-cluster-ip-range` 플래그로 kube-controller-manager에 구성된 첫 번째 서비스 클러스터 IP 범위의 주소 패밀리이다. @@ -89,9 +89,9 @@ IPv4/IPv6 이중 스택을 활성화 하려면, 클러스터의 관련 구성요 IPv6가 활성화된 외부 로드 밸런서를 지원하는 클라우드 공급자들은 `type` 필드를 `LoadBalancer` 로 설정하고, 추가적으로 `ipFamily` 필드를 `IPv6` 로 설정하면 서비스에 대한 클라우드 로드 밸런서가 구축된다. -## 송신 트래픽 +## 이그레스 트래픽 -근본적으로 {{< glossary_tooltip text="CNI" term_id="cni" >}} 공급자가 전송을 구현할 수 있는 경우 공개적으로 라우팅 하거나 비공개 라우팅만 가능한 IPv6 주소 블록의 사용은 허용된다. 만약 비공개 라우팅만 가능한 IPv6를 사용하는 파드가 있고, 해당 파드가 오프 클러스터 목적지(예: 공용 인터넷)에 도달하기를 원하는 경우에는 송신 트래픽과 모든 응답을 위한 위장 IP를 설정해야 한다. [ip-masq-agent](https://github.com/kubernetes-incubator/ip-masq-agent) 는 이중 스택을 인식하기에, 이중 스택 클러스터에서 위장 IP에 ip-masq-agent 를 사용할 수 있다. +근본적으로 {{< glossary_tooltip text="CNI" term_id="cni" >}} 공급자가 전송을 구현할 수 있는 경우 공개적으로 라우팅 하거나 비공개 라우팅만 가능한 IPv6 주소 블록의 사용은 허용된다. 만약 비공개 라우팅만 가능한 IPv6를 사용하는 파드가 있고, 해당 파드가 오프 클러스터 목적지(예: 공용 인터넷)에 도달하기를 원하는 경우에는 이그레스 트래픽과 모든 응답을 위한 마스커레이딩 IP를 설정해야 한다. [ip-masq-agent](https://github.com/kubernetes-incubator/ip-masq-agent) 는 이중 스택을 인식하기에, 이중 스택 클러스터에서 마스커레이딩 IP에 ip-masq-agent 를 사용할 수 있다. ## 알려진 이슈들 diff --git a/content/ko/docs/concepts/services-networking/service.md b/content/ko/docs/concepts/services-networking/service.md new file mode 100644 index 0000000000000..ba0d78cf2fdac --- /dev/null +++ b/content/ko/docs/concepts/services-networking/service.md @@ -0,0 +1,1201 @@ +--- +title: 서비스 +feature: + title: 서비스 디스커버리와 로드 밸런싱 + description: > + 쿠버네티스를 사용하면 익숙하지 않은 서비스 디스커버리 메커니즘을 사용하기 위해 애플리케이션을 수정할 필요가 없다. 쿠버네티스는 파드에게 고유한 IP 주소와 파드 집합에 대한 단일 DNS 명을 부여하고, 그것들 간에 로드-밸런스를 수행할 수 있다. + +content_template: templates/concept +weight: 10 +--- + + + + +{{% capture overview %}} + +{{< glossary_definition term_id="service" length="short" >}} + +쿠버네티스를 사용하면 익숙하지 않은 서비스 디스커버리 메커니즘을 사용하기 위해 애플리케이션을 수정할 필요가 없다. +쿠버네티스는 파드에게 고유한 IP 주소와 파드 집합에 대한 단일 DNS 명을 부여하고, +그것들 간에 로드-밸런스를 수행할 수 있다. + +{{% /capture %}} + +{{% capture body %}} + +## 동기 + +쿠버네티스 {{< glossary_tooltip term_id="pod" text="파드" >}}는 수명이 있다. +파드는 생성되고, 소멸된 후 부활하지 않는다. +만약 앱을 실행하기 위해 {{< glossary_tooltip term_id="deployment" text="디플로이먼트" >}}를 사용한다면, +동적으로 파드를 생성하고 제거할 수 있다. + +각 파드는 고유한 IP 주소를 갖지만, 디플로이먼트에서는 +한 시점에 실행되는 파드 집합이 +잠시 후 실행되는 해당 파드 집합과 다를 수 있다. + +이는 다음과 같은 문제를 야기한다. (“백엔드”라 불리는) 일부 파드 집합이 +클러스터의 (“프론트엔드”라 불리는) 다른 파드에 기능을 제공하는 경우, +프론트엔드가 워크로드의 백엔드를 사용하기 위해, +프론트엔드가 어떻게 연결할 IP 주소를 찾아서 추적할 수 있는가? + +_서비스_ 로 들어가보자. + +## 서비스 리소스 {#service-resource} + +쿠버네티스에서 서비스는 파드의 논리적 집합과 그것들에 접근할 수 있는 +정책을 정의하는 추상적 개념이다. (때로는 이 패턴을 +마이크로-서비스라고 한다.) 서비스가 대상으로 하는 파드 집합은 일반적으로 +{{< glossary_tooltip text="셀렉터" term_id="selector" >}}가 결정한다. +(셀렉터가 _없는_ 서비스가 필요한 이유는 [아래](#셀렉터가-없는-서비스)를 +참조한다). + +예를 들어, 3개의 레플리카로 실행되는 스테이트리스 이미지-처리 백엔드를 +생각해보자. 이러한 레플리카는 대체 가능하다. 즉, 프론트엔드는 그것들이 사용하는 백엔드를 +신경쓰지 않는다. 백엔드 세트를 구성하는 실제 파드는 변경될 수 있지만, +프론트엔드 클라이언트는 이를 인식할 필요가 없으며, 백엔드 세트 자체를 추적해야 할 필요도 +없다. + +서비스 추상화는 이러한 디커플링을 가능하게 한다. + +### 클라우드-네이티브 서비스 디스커버리 + +애플리케이션에서 서비스 디스커버리를 위해 쿠버네티스 API를 사용할 수 있는 경우, +서비스 내 파드 세트가 변경될 때마다 업데이트되는 엔드포인트를 {{< glossary_tooltip text="API 서버" term_id="kube-apiserver" >}}에 +질의할 수 ​​있다. + +네이티브 애플리케이션이 아닌 (non-native applications) 경우, 쿠버네티스는 애플리케이션과 백엔드 파드 사이에 네트워크 포트 또는 로드 +밸런서를 배치할 수 있는 방법을 제공한다. + +## 서비스 정의 + +쿠버네티스의 서비스는 파드와 비슷한 REST 오브젝트이다. 모든 REST 오브젝트와 +마찬가지로, 서비스 정의를 API 서버에 `POST`하여 +새 인스턴스를 생성할 수 있다. + +예를 들어, 각각 TCP 포트 9376에서 수신하고 +`app=MyApp` 레이블을 가지고 있는 파드 세트가 있다고 가정해 보자. + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: my-service +spec: + selector: + app: MyApp + ports: + - protocol: TCP + port: 80 + targetPort: 9376 +``` + +이 명세는 “my-service”라는 새로운 서비스 오브젝트를 생성하고, +`app=MyApp` 레이블을 가진 파드의 TCP 9376 포트를 대상으로 한다. + +쿠버네티스는 이 서비스에 서비스 프록시가 사용하는 IP 주소 ("cluster IP"라고도 함) +를 할당한다. +(이하 [가상 IP와 서비스 프록시](#가상-ip와-서비스-프록시) 참고) + +서비스 셀렉터의 컨트롤러는 셀렉터와 일치하는 파드를 지속적으로 검색하고, +“my-service”라는 엔드포인트 오브젝트에 대한 +모든 업데이트를 POST한다. + +{{< note >}} +서비스는 _모든_ 수신 `port`를 `targetPort`에 매핑할 수 있다. 기본적으로 그리고 +편의상, `targetPort`는 `port` +필드와 같은 값으로 설정된다. +{{< /note >}} + +파드의 포트 정의에는 이름이 있고, 서비스의 `targetPort` 속성에서 이 이름을 +참조할 수 있다. 이것은 다른 포트 번호를 통한 가용한 동일 네트워크 프로토콜이 있고, +단일 구성 이름을 사용하는 서비스 내에 +혼합된 파드가 존재해도 가능하다. +이를 통해 서비스를 배포하고 진전시키는데 많은 유연성을 제공한다. +예를 들어, 클라이언트를 망가뜨리지 않고, 백엔드 소프트웨어의 다음 +버전에서 파드가 노출시키는 포트 번호를 변경할 수 있다. + +서비스의 기본 프로토콜은 TCP이다. 다른 +[지원되는 프로토콜](#protocol-support)을 사용할 수도 있다. + +많은 서비스가 하나 이상의 포트를 노출해야 하기 때문에, 쿠버네티스는 서비스 오브젝트에서 다중 +포트 정의를 지원한다. +각 포트는 동일한 `프로토콜` 또는 다른 프로토콜로 정의될 수 있다. + +### 셀렉터가 없는 서비스 + +서비스는 일반적으로 쿠버네티스 파드에 대한 접근을 추상화하지만, +다른 종류의 백엔드를 추상화할 수도 있다. +예를 들면 + + * 프로덕션 환경에서는 외부 데이터베이스 클러스터를 사용하려고 하지만, + 테스트 환경에서는 자체 데이터베이스를 사용한다. + * 한 서비스에서 다른 + {{< glossary_tooltip term_id="namespace" text="네임스페이스">}} 또는 다른 클러스터의 서비스를 지정하려고 한다. + * 워크로드를 쿠버네티스로 마이그레이션하고 있다. 해당 방식을 평가하는 동안, + 쿠버네티스에서는 일정 비율의 백엔드만 실행한다. + +이러한 시나리오 중에서 파드 셀렉터 _없이_ 서비스를 정의 할 수 있다. +예를 들면 + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: my-service +spec: + ports: + - protocol: TCP + port: 80 + targetPort: 9376 +``` + +이 서비스에는 셀렉터가 없으므로, 해당 엔드포인트 오브젝트가 자동으로 +생성되지 *않는다*. 엔드포인트 오브젝트를 수동으로 추가하여, 서비스를 실행 중인 네트워크 주소 및 포트에 +서비스를 수동으로 매핑할 수 있다. + +```yaml +apiVersion: v1 +kind: Endpoints +metadata: + name: my-service +subsets: + - addresses: + - ip: 192.0.2.42 + ports: + - port: 9376 +``` + +{{< note >}} +엔드포인트 IP는 루프백(loopback) (IPv4의 경우 127.0.0.0/8, IPv6의 경우 ::1/128), 또는 +링크-로컬 (IPv4의 경우 169.254.0.0/16와 224.0.0.0/24, IPv6의 경우 fe80::/64)이 _되어서는 안된다_. + +엔드포인트 IP 주소는 다른 쿠버네티스 서비스의 클러스터 IP일 수 없는데, +{{< glossary_tooltip term_id="kube-proxy" >}}는 가상 IP를 +목적지(destination)로 지원하지 않기 때문이다. +{{< /note >}} + +셀렉터가 없는 서비스에 접근하면 셀렉터가 있는 것처럼 동일하게 작동한다. +위의 예에서, 트래픽은 YAML에 정의된 단일 엔드 포인트로 +라우팅된다. `192.0.2.42:9376` (TCP) + +ExternalName 서비스는 셀렉터가 없고 +DNS명을 대신 사용하는 특수한 상황의 서비스이다. 자세한 내용은 +이 문서 뒷부분의 [ExternalName](#externalname) 섹션을 참조한다. + +### 엔드포인트 슬라이스 +{{< feature-state for_k8s_version="v1.17" state="beta" >}} + +엔드포인트 슬라이스는 엔드포인트에 보다 확장 가능한 대안을 제공할 수 있는 +API 리소스이다. 개념적으로 엔드포인트와 매우 유사하지만, 엔드포인트 슬라이스를 +사용하면 여러 리소스에 네트워크 엔드포인트를 분산시킬 수 있다. 기본적으로, +엔드포인트 슬라이스는 100개의 엔드포인트에 도달하면 "가득찬 것"로 간주되며, +추가 엔드포인트를 저장하기 위해서는 추가 엔드포인트 슬라이스가 +생성된다. + +엔드포인트 슬라이스는 [엔드포인트 슬라이스](/ko/docs/concepts/services-networking/endpoint-slices/)에서 +자세하게 설명된 추가적인 속성 및 기능을 제공한다. + +## 가상 IP와 서비스 프록시 + +쿠버네티스 클러스터의 모든 노드는 `kube-proxy`를 실행한다. `kube-proxy`는 +[`ExternalName`](#externalname) 이외의 유형의 `서비스`에 대한 +가상 IP 형식을 구현한다. + +### 라운드-로빈 DNS를 사용하지 않는 이유 + +항상 발생하는 질문은 왜 쿠버네티스가 인바운드 트래픽을 백엔드로 전달하기 위해 프록시에 +의존하는가 하는 점이다. 다른 접근법이 +있는가? 예를 들어, 여러 A 값 (또는 IPv6의 경우 AAAA)을 가진 +DNS 레코드를 구성하고, 라운드-로빈 이름 확인 방식을 +취할 수 있는가? + +서비스에 프록시를 사용하는 데는 몇 가지 이유가 있다. + + * 레코드 TTL을 고려하지 않고, 만료된 이름 검색 결과를 + 캐싱하는 DNS 구현에 대한 오래된 역사가 있다. + * 일부 앱은 DNS 검색을 한 번만 수행하고 결과를 무기한으로 캐시한다. + * 앱과 라이브러리가 적절히 재-확인을 했다고 하더라도, DNS 레코드의 TTL이 + 낮거나 0이면 DNS에 부하가 높아 관리하기가 + 어려워 질 수 있다. + +### 유저 스페이스(User space) 프록시 모드 {#proxy-mode-userspace} + +이 모드에서는, kube-proxy는 쿠버네티스 마스터의 서비스, 엔드포인트 오브젝트의 +추가와 제거를 감시한다. 각 서비스는 로컬 노드에서 +포트(임의로 선택됨)를 연다. 이 "프록시 포트"에 대한 모든 +연결은 (엔드포인트를 통해 보고된대로) 서비스의 백엔드 파드 중 하나로 +프록시된다. kube-proxy는 사용할 백엔드 파드를 결정할 때 서비스의 +`SessionAffinity` 설정을 고려한다. + +마지막으로, 유저-스페이스 프록시는 서비스의 +`clusterIP` (가상)와 `port` 에 대한 트래픽을 캡처하는 iptables 규칙을 설치한다. 이 규칙은 +트래픽을 백엔드 파드를 프록시하는 프록시 포트로 리다이렉션한다. + +기본적으로, 유저스페이스 모드의 kube-proxy는 라운드-로빈 알고리즘으로 백엔드를 선택한다. + +![유저스페이스 프록시에 대한 서비스 개요 다이어그램](/images/docs/services-userspace-overview.svg) + +### `iptables` 프록시 모드 {#proxy-mode-iptables} + +이 모드에서는, kube-proxy는 쿠버네티스 컨트롤 플레인의 서비스, 엔드포인트 오브젝트의 +추가와 제거를 감시한다. 각 서비스에 대해, 서비스의 +`clusterIP` 및 `port`에 대한 트래픽을 캡처하고 해당 트래픽을 서비스의 +백엔드 세트 중 하나로 리다이렉트(redirect)하는 +iptables 규칙을 설치한다. 각 엔드포인트 오브젝트에 대해, +백엔드 파드를 선택하는 iptables 규칙을 설치한다. + +기본적으로, iptables 모드의 kube-proxy는 임의의 백엔드를 선택한다. + +트래픽을 처리하기 위해 iptables를 사용하면 시스템 오버헤드가 줄어드는데, 유저스페이스와 +커널 스페이스 사이를 전환할 필요없이 리눅스 넷필터(netfilter)가 트래픽을 처리하기 +때문이다. 이 접근 방식은 더 신뢰할 수 있기도 하다. + +kube-proxy가 iptables 모드에서 실행 중이고 선택된 첫 번째 파드가 +응답하지 않으면, 연결이 실패한다. 이는 userspace 모드와 +다르다. 해당 시나리오에서는, kube-proxy는 첫 번째 +파드에 대한 연결이 실패했음을 감지하고 다른 백엔드 파드로 자동으로 재시도한다. + +파드 [준비성 프로브(readiness probe)](/ko/docs/concepts/workloads/pods/pod-lifecycle/#container-probes)를 사용하여 +백엔드 파드가 제대로 작동하는지 확인할 수 있으므로, iptables 모드의 kube-proxy는 +정상으로 테스트된 백엔드만 볼 수 있다. 이렇게 하면 트래픽이 kube-proxy를 통해 +실패한 것으로 알려진 파드로 전송되는 것을 막을 수 있다. + +![iptables 프록시에 대한 서비스 개요 다이어그램](/images/docs/services-iptables-overview.svg) + +### IPVS 프록시 모드 {#proxy-mode-ipvs} + +{{< feature-state for_k8s_version="v1.11" state="stable" >}} + +`ipvs` 모드에서는, kube-proxy는 쿠버네티스 서비스와 엔드포인트를 감시하고, +`netlink` 인터페이스를 호출하여 그에 따라 IPVS 규칙을 생성하고 +IPVS 규칙을 쿠버네티스 서비스와 엔드포인트와 주기적으로 동기화한다. +이 제어 루프는 IPVS 상태가 원하는 상태와 일치하도록 +보장한다. +서비스에 접근하면, IPVS는 트래픽을 백엔드 파드 중 하나로 보낸다. + +IPVS 프록시 모드는 iptables 모드와 유사한 넷필터 후크 기능을 +기반으로 하지만, 해시 테이블을 기본 데이터 구조로 사용하고 +커널 스페이스에서 동작한다. +이는 IPVS 모드의 kube-proxy는 iptables 모드의 kube-proxy보다 +지연 시간이 짧은 트래픽을 리다이렉션하고, 프록시 규칙을 동기화할 때 성능이 +훨씬 향상됨을 의미한다. 다른 프록시 모드와 비교했을 때, IPVS 모드는 +높은 네트워크 트래픽 처리량도 지원한다. + +IPVS는 트래픽을 백엔드 파드로 밸런싱하기 위한 추가 옵션을 제공한다. +다음과 같다. + +- `rr`: 라운드-로빈 +- `lc`: 최소 연결 (가장 적은 수의 열려있는 연결) +- `dh`: 목적지 해싱 +- `sh`: 소스 해싱 +- `sed`: 최단 예상 지연 (shortest expected delay) +- `nq`: 큐 미사용 (never queue) + +{{< note >}} +IPVS 모드에서 kube-proxy를 실행하려면, kube-proxy를 시작하기 전에 노드에서 IPVS Linux를 +사용 가능하도록 해야한다. + +kube-proxy가 IPVS 프록시 모드에서 시작될 때, IPVS 커널 모듈을 +사용할 수 있는지 확인한다. IPVS 커널 모듈이 감지되지 않으면, kube-proxy는 +iptables 프록시 모드에서 다시 실행된다. +{{< /note >}} + +![IPVS 프록시에 대한 서비스 개요 다이어그램](/images/docs/services-ipvs-overview.svg) + +이 프록시 모델에서 클라이언트가 쿠버네티스 또는 서비스 또는 파드에 +대해 알지 못하는 경우 서비스의 IP:포트로 향하는 트래픽은 +적절한 백엔드로 프록시된다. + +특정 클라이언트의 연결이 매번 동일한 파드로 +전달되도록 하려면, `service.spec.sessionAffinity`를 "ClientIP"로 설정하여 +클라이언트의 IP 주소를 기반으로 세션 어피니티(Affinity)를 선택할 수 있다. +(기본값은 "None") +`service.spec.sessionAffinityConfig.clientIP.timeoutSeconds`를 적절히 설정하여 +최대 세션 고정 시간을 설정할 수도 있다. +(기본값은 10800으로, 3시간) + +## 멀티-포트 서비스 + +일부 서비스의 경우, 둘 이상의 포트를 노출해야 한다. +쿠버네티스는 서비스 오브젝트에서 멀티 포트 정의를 구성할 수 있도록 지원한다. +서비스에 멀티 포트를 사용하는 경우, 모든 포트 이름을 +명확하게 지정해야 한다. +예를 들면 + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: my-service +spec: + selector: + app: MyApp + ports: + - name: http + protocol: TCP + port: 80 + targetPort: 9376 + - name: https + protocol: TCP + port: 443 + targetPort: 9377 +``` + +{{< note >}} +쿠버네티스의 일반적인 {{< glossary_tooltip term_id="name" text="이름">}}과 마찬가지로, 포트 이름은 +소문자 영숫자와 `-` 만 포함해야 한다. 포트 이름은 +영숫자로 시작하고 끝나야 한다. + +예를 들어, `123-abc` 와 `web` 은 유효하지만, `123_abc` 와 `-web` 은 유효하지 않다. +{{< /note >}} + +## 자신의 IP 주소 선택 + +`서비스` 생성 요청시 고유한 클러스터 IP 주소를 지정할 수 +있다. 이를 위해, `.spec.clusterIP` 필드를 설정한다. 예를 들어, +재사용하려는 기존 DNS 항목이 있거나, 특정 IP 주소로 구성되어 +재구성이 어려운 레거시 시스템인 경우이다. + +선택한 IP 주소는 API 서버에 대해 구성된 `service-cluster-ip-range` +CIDR 범위 내의 유효한 IPv4 또는 IPv6 주소여야 한다. +유효하지 않은 clusterIP 주소 값으로 서비스를 생성하려고 하면, API 서버는 +422 HTTP 상태 코드를 리턴하여 문제점이 있음을 알린다. + +## 서비스 디스커버리하기 + +쿠버네티스는 서비스를 찾는 두 가지 기본 모드를 지원한다. - 환경 +변수와 DNS + +### 환경 변수 + +파드가 노드에서 실행될 때, kubelet은 각 활성화된 서비스에 대해 +환경 변수 세트를 추가한다. [도커 링크 +호환](https://docs.docker.com/userguide/dockerlinks/) 변수 +([makeLinkVariables](http://releases.k8s.io/{{< param "githubbranch" >}}/pkg/kubelet/envvars/envvars.go#L49) 참조)와 +보다 간단한 `{SVCNAME}_SERVICE_HOST` 및 `{SVCNAME}_SERVICE_PORT` 변수를 지원하고, +이때 서비스 이름은 대문자이고 대시는 밑줄로 변환된다. + +예를 들어, TCP 포트 6379를 개방하고 +클러스터 IP 주소 10.0.0.11이 할당된 서비스 `"redis-master"`는, +다음 환경 변수를 생성한다. + +```shell +REDIS_MASTER_SERVICE_HOST=10.0.0.11 +REDIS_MASTER_SERVICE_PORT=6379 +REDIS_MASTER_PORT=tcp://10.0.0.11:6379 +REDIS_MASTER_PORT_6379_TCP=tcp://10.0.0.11:6379 +REDIS_MASTER_PORT_6379_TCP_PROTO=tcp +REDIS_MASTER_PORT_6379_TCP_PORT=6379 +REDIS_MASTER_PORT_6379_TCP_ADDR=10.0.0.11 +``` + +{{< note >}} +서비스에 접근이 필요한 파드가 있고, 환경 변수를 +사용해 포트 및 클러스터 IP를 클라이언트 파드에 부여하는 +경우, 클라이언트 파드가 생성되기 *전에* 서비스를 만들어야 한다. +그렇지 않으면, 해당 클라이언트 파드는 환경 변수를 생성할 수 없다. + +DNS 만 사용하여 서비스의 클러스터 IP를 검색하는 경우, 이 순서 +이슈에 대해 신경 쓸 필요가 없다. +{{< /note >}} + +### DNS + +[애드-온](/docs/concepts/cluster-administration/addons/)을 사용하여 쿠버네티스 +클러스터의 DNS 서비스를 설정할 수(대개는 필수적임) 있다. + +CoreDNS와 같은, 클러스터-인식 DNS 서버는 새로운 서비스를 위해 쿠버네티스 API를 감시하고 +각각에 대한 DNS 레코드 세트를 생성한다. 클러스터 전체에서 DNS가 활성화된 경우 +모든 파드는 DNS 이름으로 서비스를 자동으로 +확인할 수 있어야 한다. + +예를 들면, 쿠버네티스 네임스페이스 `"my-ns"`에 `"my-service"`라는 +서비스가 있는 경우, 컨트롤 플레인과 DNS 서비스가 함께 작동하여 +`"my-service.my-ns"`에 대한 DNS 레코드를 만든다. `"my-ns"` 네임 스페이스의 파드들은 +간단히 `my-service`에 대한 이름 조회를 수행하여 찾을 수 있어야 한다 +(`"my-service.my-ns"` 역시 동작함). + +다른 네임스페이스의 파드들은 이름을 `my-service.my-ns`으로 사용해야 한다. 이 이름은 +서비스에 할당된 클러스터 IP로 변환된다. + +쿠버네티스는 또한 알려진 포트에 대한 DNS SRV (서비스) 레코드를 지원한다. +`"my-service.my-ns"` 서비스에 프로토콜이 `TCP`로 설정된 `"http"`라는 포트가 있는 경우, +IP 주소와 `"http"`에 대한 포트 번호를 검색하기 위해 `_http._tcp.my-service.my-ns` 에 대한 +DNS SRV 쿼리를 수행할 수 있다. + +쿠버네티스 DNS 서버는 `ExternalName` 서비스에 접근할 수 있는 유일한 방법이다. +[DNS 파드와 서비스](/ko/docs/concepts/services-networking/dns-pod-service/)에서 +`ExternalName` 검색에 대한 자세한 정보를 찾을 수 있다. + +## 헤드리스(Headless) 서비스 + +때때로 로드-밸런싱과 단일 서비스 IP는 필요치 않다. 이 경우, +"헤드리스" 서비스라는 것을 만들 수 있는데, 명시적으로 +클러스터 IP (`.spec.clusterIP`)에 "None"을 지정한다. + +쿠버네티스의 구현에 묶이지 않고, 헤드리스 서비스를 사용하여 +다른 서비스 디스커버리 메커니즘과 인터페이스할 수 있다. + +헤드리스 `서비스`의 경우, 클러스터 IP가 할당되지 않고, kube-proxy가 +이러한 서비스를 처리하지 않으며, 플랫폼에 의해 로드 밸런싱 또는 프록시를 +하지 않는다. DNS가 자동으로 구성되는 방법은 서비스에 셀렉터가 정의되어 있는지 +여부에 달려있다. + +### 셀렉터가 있는 경우 + +셀렉터를 정의하는 헤드리스 서비스의 경우, 엔드포인트 컨트롤러는 +API에서 `엔드포인트` 레코드를 생성하고, DNS 구성을 수정하여 +`서비스` 를 지원하는 `파드` 를 직접 가리키는 레코드 (주소)를 반환한다. + +### 셀렉터가 없는 경우 + +셀렉터를 정의하지 않는 헤드리스 서비스의 경우, 엔드포인트 컨트롤러는 +`엔드포인트` 레코드를 생성하지 않는다. 그러나 DNS 시스템은 다음 중 하나를 찾고 +구성한다. + + * [`ExternalName`](#externalname)-유형 서비스에 대한 CNAME 레코드 + * 다른 모든 유형에 대해, 서비스의 이름을 공유하는 모든 `엔드포인트`에 + 대한 레코드 + +## 서비스 퍼블리싱 (ServiceTypes) {#publishing-services-service-types} + +애플리케이션 중 일부(예: 프론트엔드)는 서비스를 클러스터 밖에 +위치한 외부 IP 주소에 노출하고 싶은 경우가 있을 것이다. + +쿠버네티스 `ServiceTypes`는 원하는 서비스 종류를 지정할 수 있도록 해준다. +기본 값은 `ClusterIP`이다. + +`Type` 값과 그 동작은 다음과 같다. + + * `ClusterIP`: 서비스를 클러스터-내부 IP에 노출시킨다. 이 값을 선택하면 + 클러스터 내에서만 서비스에 도달할 수 있다. 이것은 + `ServiceTypes`의 기본 값이다. + * [`NodePort`](#nodeport): 고정 포트 (`NodePort`)로 각 노드의 IP에 서비스를 + 노출시킨다. `NodePort` 서비스가 라우팅되는 `ClusterIP` 서비스가 + 자동으로 생성된다. `:`를 요청하여, + 클러스터 외부에서 + `NodePort` 서비스에 접속할 수 있다. + * [`LoadBalancer`](#loadbalancer): 클라우드 공급자의 로드 밸런서를 사용하여 + 서비스를 외부에 노출시킨다. 외부 로드 밸런서가 라우팅되는 + `NodePort`와 `ClusterIP` 서비스가 자동으로 생성된다. + * [`ExternalName`](#externalname): 값과 함께 CNAME 레코드를 리턴하여, 서비스를 + `externalName` 필드의 컨텐츠 (예:`foo.bar.example.com`)에 + 맵핑한다. 어떤 종류의 프록시도 설정되어 있지 않다. + {{< note >}} + `ExternalName` 유형을 사용하려면 CoreDNS 버전 1.7 이상이 필요하다. + {{< /note >}} + +[인그레스](/ko/docs/concepts/services-networking/ingress/)를 사용하여 서비스를 노출시킬 수도 있다. 인그레스는 서비스 유형이 아니지만, 클러스터의 진입점 역할을 한다. 동일한 IP 주소로 여러 서비스를 노출시킬 수 있기 때문에 라우팅 규칙을 단일 리소스로 통합할 수 있다. + + +### NodePort 유형 {#nodeport} + +`type` 필드를 `NodePort`로 설정하면, 쿠버네티스 컨트롤 플레인은 +`--service-node-port-range` 플래그로 지정된 범위에서 포트를 할당한다 (기본값 : 30000-32767). +각 노드는 해당 포트 (모든 노드에서 동일한 포트 번호)를 서비스로 프록시한다. +서비스는 할당된 포트를 `.spec.ports[*].nodePort` 필드에 나타낸다. + + +포트를 프록시하기 위해 특정 IP를 지정하려면 kube-proxy의 `--nodeport-addresses` 플래그를 특정 IP 블록으로 설정할 수 있다. 이것은 쿠버네티스 v1.10부터 지원된다. +이 플래그는 쉼표로 구분된 IP 블록 목록 (예: 10.0.0.0/8, 192.0.2.0/25)을 사용하여 kube-proxy가 로컬 노드로 고려해야 하는 IP 주소 범위를 지정한다. + +예를 들어, `--nodeport-addresses=127.0.0.0/8` 플래그로 kube-proxy를 시작하면, kube-proxy는 NodePort 서비스에 대하여 루프백(loopback) 인터페이스만 선택한다. `--nodeport-addresses`의 기본 값은 비어있는 목록이다. 이것은 kube-proxy가 NodePort에 대해 사용 가능한 모든 네트워크 인터페이스를 고려해야 한다는 것을 의미한다. (이는 이전 쿠버네티스 릴리스와도 호환된다). + +특정 포트 번호를 원한다면, `nodePort` 필드에 값을 지정할 수 +있다. 컨트롤 플레인은 해당 포트를 할당하거나 API 트랜잭션이 +실패했다고 보고한다. +이는 사용자 스스로 포트 충돌의 가능성을 고려해야 한다는 의미이다. +또한 NodePort 사용을 위해 구성된 범위 내에 있는, 유효한 포트 번호를 +사용해야 한다. + +NodePort를 사용하면 자유롭게 자체 로드 밸런싱 솔루션을 설정하거나, +쿠버네티스가 완벽하게 지원하지 않는 환경을 구성하거나, +하나 이상의 노드 IP를 직접 노출시킬 수 있다. + +이 서비스는 `:spec.ports[*].nodePort`와 +`.spec.clusterIP:spec.ports[*].port`로 표기된다. (kube-proxy에서 `--nodeport-addresses` 플래그가 설정되면, 는 NodeIP를 필터링한다.) + +### 로드밸런서 유형 {#loadbalancer} + +외부 로드 밸런서를 지원하는 클라우드 공급자 상에서, `type` +필드를 `LoadBalancer`로 설정하면 서비스에 대한 로드 밸런서를 프로비저닝한다. +로드 밸런서의 실제 생성은 비동기적으로 수행되고, +프로비저닝된 밸런서에 대한 정보는 서비스의 +`.status.loadBalancer` 필드에 발행된다. +예를 들면 + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: my-service +spec: + selector: + app: MyApp + ports: + - protocol: TCP + port: 80 + targetPort: 9376 + clusterIP: 10.0.171.239 + type: LoadBalancer +status: + loadBalancer: + ingress: + - ip: 192.0.2.127 +``` + +외부 로드 밸런서의 트래픽은 백엔드 파드로 전달된다. 클라우드 공급자는 로드 밸런싱 방식을 결정한다. + + +일부 클라우드 공급자는 `loadBalancerIP`를 지정할 수 있도록 허용한다. 이 경우, 로드 밸런서는 +사용자 지정 `loadBalancerIP`로 생성된다. `loadBalancerIP` 필드가 지정되지 않으면, +임시 IP 주소로 loadBalancer가 설정된다. `loadBalancerIP`를 지정했지만 +클라우드 공급자가 이 기능을 지원하지 않는 경우, 설정한 `loadbalancerIP` 필드는 +무시된다. + +{{< note >}} +SCTP를 사용하는 경우, `LoadBalancer` 서비스 유형에 대한 아래의 [경고](#caveat-sctp-loadbalancer-service-type)를 +참고한다. +{{< /note >}} + +{{< note >}} + +**Azure** 에서 사용자 지정 공개(public) 유형 `loadBalancerIP`를 사용하려면, 먼저 +정적 유형 공개 IP 주소 리소스를 생성해야 한다. 이 공개 IP 주소 리소스는 +클러스터에서 자동으로 생성된 다른 리소스와 동일한 리소스 그룹에 있어야 한다. +예를 들면, `MC_myResourceGroup_myAKSCluster_eastus`이다. + +할당된 IP 주소를 loadBalancerIP로 지정한다. 클라우드 공급자 구성 파일에서 securityGroupName을 업데이트했는지 확인한다. `CreatingLoadBalancerFailed` 권한 문제 해결에 대한 자세한 내용은 [Azure Kubernetes Service (AKS) 로드 밸런서에서 고정 IP 주소 사용](https://docs.microsoft.com/en-us/azure/aks/static-ip) 또는 [고급 네트워킹 AKS 클러스터에서 CreateLoadBalancerFailed](https://github.com/Azure/AKS/issues/357)를 참고한다. + +{{< /note >}} + +#### 내부 로드 밸런서 {#internal-load-balancer} +혼재된 환경에서는 서비스의 트래픽을 동일한 (가상) 네트워크 주소 블록 내로 +라우팅해야하는 경우가 있다. + +수평 분할 DNS 환경에서는 외부와 내부 트래픽을 엔드포인트로 라우팅 할 수 있는 두 개의 서비스가 필요하다. + +서비스에 다음 어노테이션 중 하나를 추가하여 이를 수행할 수 있다. +추가할 어노테이션은 사용 중인 클라우드 서비스 공급자에 따라 다르다. + +{{< tabs name="service_tabs" >}} +{{% tab name="Default" %}} +탭 중 하나를 선택 +{{% /tab %}} +{{% tab name="GCP" %}} +```yaml +[...] +metadata: + name: my-service + annotations: + cloud.google.com/load-balancer-type: "Internal" +[...] +``` +{{% /tab %}} +{{% tab name="AWS" %}} +```yaml +[...] +metadata: + name: my-service + annotations: + service.beta.kubernetes.io/aws-load-balancer-internal: "true" +[...] +``` +{{% /tab %}} +{{% tab name="Azure" %}} +```yaml +[...] +metadata: + name: my-service + annotations: + service.beta.kubernetes.io/azure-load-balancer-internal: "true" +[...] +``` +{{% /tab %}} +{{% tab name="OpenStack" %}} +```yaml +[...] +metadata: + name: my-service + annotations: + service.beta.kubernetes.io/openstack-internal-load-balancer: "true" +[...] +``` +{{% /tab %}} +{{% tab name="Baidu Cloud" %}} +```yaml +[...] +metadata: + name: my-service + annotations: + service.beta.kubernetes.io/cce-load-balancer-internal-vpc: "true" +[...] +``` +{{% /tab %}} +{{% tab name="Tencent Cloud" %}} +```yaml +[...] +metadata: + annotations: + service.kubernetes.io/qcloud-loadbalancer-internal-subnetid: subnet-xxxxx +[...] +``` +{{% /tab %}} +{{< /tabs >}} + + +#### AWS에서 TLS 지원 {#ssl-support-on-aws} + +AWS에서 실행되는 클러스터에서 부분적으로 TLS / SSL을 지원하기 위해, `LoadBalancer` 서비스에 세 가지 +어노테이션을 추가할 수 있다. + +```yaml +metadata: + name: my-service + annotations: + service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012 +``` + +첫 번째는 사용할 인증서의 ARN을 지정한다. IAM에 업로드된 +써드파티 발급자의 인증서이거나 AWS Certificate Manager에서 +생성된 인증서일 수 있다. + +```yaml +metadata: + name: my-service + annotations: + service.beta.kubernetes.io/aws-load-balancer-backend-protocol: (https|http|ssl|tcp) +``` + +두 번째 어노테이션은 파드가 알려주는 프로토콜을 지정한다. HTTPS와 +SSL의 경우, ELB는 인증서를 사용하여 암호화된 연결을 통해 파드가 스스로를 +인증할 것으로 예상한다. + +HTTP와 HTTPS는 7 계층 프록시를 선택한다. ELB는 요청을 전달할 때 +사용자와의 연결을 종료하고, 헤더를 파싱하고 사용자의 IP 주소로 `X-Forwarded-For` +헤더를 삽입한다. (파드는 해당 연결의 다른 종단에서의 +ELB의 IP 주소만 참조) + +TCP 및 SSL은 4 계층 프록시를 선택한다. ELB는 헤더를 수정하지 않고 +트래픽을 전달한다. + +일부 포트는 보안성을 갖추고 다른 포트는 암호화되지 않은 혼재된 사용 환경에서는 +다음 어노테이션을 사용할 수 있다. + +```yaml + metadata: + name: my-service + annotations: + service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http + service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443,8443" +``` + +위의 예에서, 서비스에 `80`, `443`, `8443`의 3개 포트가 포함된 경우, +`443`, `8443`은 SSL 인증서를 사용하지만, `80`은 단순히 +프록시만 하는 HTTP이다. + +쿠버네티스 v1.9부터는 서비스에 대한 HTTPS 또는 SSL 리스너와 함께 [사전에 정의된 AWS SSL 정책](http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-security-policy-table.html)을 사용할 수 있다. +사용 가능한 정책을 확인하려면, `aws` 커맨드라인 툴을 사용한다. + +```bash +aws elb describe-load-balancer-policies --query 'PolicyDescriptions[].PolicyName' +``` + +그리고 +"`service.beta.kubernetes.io/aws-load-balancer-ssl-negotiation-policy`" +어노테이션을 사용하여 이러한 정책 중 하나를 지정할 수 있다. 예를 들면 + +```yaml + metadata: + name: my-service + annotations: + service.beta.kubernetes.io/aws-load-balancer-ssl-negotiation-policy: "ELBSecurityPolicy-TLS-1-2-2017-01" +``` + +#### AWS에서 지원하는 프록시 프로토콜 + +AWS에서 실행되는 클러스터에 대한 [프록시 프로토콜](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) +지원을 활성화하려면, 다음의 서비스 어노테이션을 +사용할 수 있다. + +```yaml + metadata: + name: my-service + annotations: + service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*" +``` + +버전 1.3.0 부터, 이 어노테이션의 사용은 ELB에 의해 프록시되는 모든 포트에 적용되며 +다르게 구성할 수 없다. + +#### AWS의 ELB 접근 로그 + +AWS ELB 서비스의 접근 로그를 관리하기 위한 몇 가지 어노테이션이 있다. + +`service.beta.kubernetes.io/aws-load-balancer-access-log-enabled` 어노테이션은 +접근 로그의 활성화 여부를 제어한다. + +`service.beta.kubernetes.io/aws-load-balancer-access-log-emit-interval` 어노테이션은 +접근 로그를 게시하는 간격을 분 단위로 제어한다. 5분 또는 60분의 +간격으로 지정할 수 있다. + +`service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-name` 어노테이션은 +로드 밸런서 접근 로그가 저장되는 Amazon S3 버킷의 이름을 +제어한다. + +`service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-prefix` 어노테이션은 +Amazon S3 버킷을 생성한 논리적 계층을 지정한다. + +```yaml + metadata: + name: my-service + annotations: + service.beta.kubernetes.io/aws-load-balancer-access-log-enabled: "true" + # 로드 밸런서의 접근 로그 활성화 여부를 명시. + service.beta.kubernetes.io/aws-load-balancer-access-log-emit-interval: "60" + # 접근 로그를 게시하는 간격을 분 단위로 제어. 5분 또는 60분의 간격을 지정. + service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-name: "my-bucket" + # 로드 밸런서 접근 로그가 저장되는 Amazon S3 버킷의 이름 명시. + service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-prefix: "my-bucket-prefix/prod" + # Amazon S3 버킷을 생성한 논리적 계층을 지정. 예: `my-bucket-prefix/prod` +``` + +#### AWS의 연결 드레이닝(Draining) + +Classic ELB의 연결 드레이닝은 +`service.beta.kubernetes.io/aws-load-balancer-connection-draining-enabled` 어노테이션을 +`"true"`값으로 설정하여 관리할 수 ​​있다. `service.beta.kubernetes.io/aws-load-balancer-connection-draining-timeout` 어노테이션을 +사용하여 인스턴스를 해제하기 전에, +기존 연결을 열어 두는 목적으로 최대 시간을 초 단위로 설정할 수도 있다. + + +```yaml + metadata: + name: my-service + annotations: + service.beta.kubernetes.io/aws-load-balancer-connection-draining-enabled: "true" + service.beta.kubernetes.io/aws-load-balancer-connection-draining-timeout: "60" +``` + +#### 다른 ELB 어노테이션 + +이하는 클래식 엘라스틱 로드 밸런서(Classic Elastic Load Balancers)를 관리하기 위한 다른 어노테이션이다. + +```yaml + metadata: + name: my-service + annotations: + service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: "60" + # 로드 밸런서가 연결을 닫기 전에, 유휴 상태(연결을 통해 전송 된 데이터가 없음)의 연결을 허용하는 초단위 시간 + + service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true" + # 로드 밸런서에 교차-영역(cross-zone) 로드 밸런싱을 사용할 지 여부를 지정 + + service.beta.kubernetes.io/aws-load-balancer-additional-resource-tags: "environment=prod,owner=devops" + # 쉼표로 구분된 key-value 목록은 ELB에 + # 추가 태그로 기록됨 + + service.beta.kubernetes.io/aws-load-balancer-healthcheck-healthy-threshold: "" + # 백엔드가 정상인 것으로 간주되는데 필요한 연속적인 + # 헬스 체크 성공 횟수이다. 기본값은 2이며, 2와 10 사이여야 한다. + + service.beta.kubernetes.io/aws-load-balancer-healthcheck-unhealthy-threshold: "3" + # 백엔드가 비정상인 것으로 간주되는데 필요한 + # 헬스 체크 실패 횟수이다. 기본값은 6이며, 2와 10 사이여야 한다. + + service.beta.kubernetes.io/aws-load-balancer-healthcheck-interval: "20" + # 개별 인스턴스의 상태 점검 사이의 + # 대략적인 간격 (초 단위). 기본값은 10이며, 5와 300 사이여야 한다. + service.beta.kubernetes.io/aws-load-balancer-healthcheck-timeout: "5" + # 헬스 체크 실패를 의미하는 무 응답의 총 시간 (초 단위) + # 이 값은 service.beta.kubernetes.io/aws-load-balancer-healthcheck-interval + # 값 보다 작아야한다. 기본값은 5이며, 2와 60 사이여야 한다. + + service.beta.kubernetes.io/aws-load-balancer-extra-security-groups: "sg-53fae93f,sg-42efd82e" + # ELB에 추가될 추가 보안 그룹(security group) 목록 +``` + +#### AWS의 네트워크 로드 밸런서 지원 {#aws-nlb-support} + +{{< feature-state for_k8s_version="v1.15" state="beta" >}} + +AWS에서 네트워크 로드 밸런서를 사용하려면, `nlb` 값이 설정된 `service.beta.kubernetes.io/aws-load-balancer-type` 어노테이션을 사용한다. + +```yaml + metadata: + name: my-service + annotations: + service.beta.kubernetes.io/aws-load-balancer-type: "nlb" +``` + +{{< note >}} +NLB는 특정 인스턴스 클래스에서만 작동한다. 지원되는 인스턴스 유형 목록은 엘라스틱 로드 밸런싱에 대한 [AWS 문서](http://docs.aws.amazon.com/elasticloadbalancing/latest/network/target-group-register-targets.html#register-deregister-targets) +를 참고한다. +{{< /note >}} + +클래식 엘라스틱 로드 밸런서와 달리, 네트워크 로드 밸런서 (NLB)는 +클라이언트의 IP 주소를 노드로 전달한다. 서비스의 `.spec.externalTrafficPolicy`가 +`Cluster`로 설정되어 있으면, 클라이언트의 IP 주소가 종단 파드로 +전파되지 않는다. + +`.spec.externalTrafficPolicy`를 `Local`로 설정하면, 클라이언트 IP 주소가 +종단 파드로 전파되지만, 트래픽이 고르지 않게 +분배될 수 있다. 특정 로드밸런서 서비스를 위한 파드가 없는 노드는 자동 할당된 +`.spec.healthCheckNodePort`에 의해서 NLB 대상 그룹의 +헬스 체크에 실패하고 트래픽을 수신하지 못하게 된다. + +트래픽을 균일하게 하려면, DaemonSet을 사용하거나, +[파드 안티어피니티(pod anti-affinity)](/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity) +를 지정하여 동일한 노드에 위치하지 않도록 한다. + +[내부 로드 밸런서](/ko/docs/concepts/services-networking/service/#internal-load-balancer) 어노테이션과 함께 NLB 서비스를 +사용할 수도 있다. + +클라이언트 트래픽이 NLB 뒤의 인스턴스에 도달하기 위해, 노드 보안 +그룹은 다음 IP 규칙으로 수정된다. + +| 규칙 | 프로토콜 | 포트 | IP 범위 | IP 범위 설명 | +|------|----------|---------|------------|---------------------| +| 헬스 체크 | TCP | NodePort(s) (`.spec.healthCheckNodePort` for `.spec.externalTrafficPolicy = Local`) | VPC CIDR | kubernetes.io/rule/nlb/health=\ | +| 클라이언트 트래픽 | TCP | NodePort(s) | `.spec.loadBalancerSourceRanges` (defaults to `0.0.0.0/0`) | kubernetes.io/rule/nlb/client=\ | +| MTU 탐색 | ICMP | 3,4 | `.spec.loadBalancerSourceRanges` (defaults to `0.0.0.0/0`) | kubernetes.io/rule/nlb/mtu=\ | + +네트워크 로드 밸런서에 접근할 수 있는 클라이언트 IP를 제한하려면, +`loadBalancerSourceRanges`를 지정한다. + +```yaml +spec: + loadBalancerSourceRanges: + - "143.231.0.0/16" +``` + +{{< note >}} +`.spec.loadBalancerSourceRanges`가 설정되어 있지 않으면, 쿠버네티스는 +`0.0.0.0/0`에서 노드 보안 그룹으로의 트래픽을 허용한다. 노드에 퍼블릭 IP 주소가 +있는 경우, 비(non)-NLB 트래픽도 해당 수정된 보안 그룹의 +모든 인스턴스에 도달할 수 있다. + +{{< /note >}} + +#### Tencent Kubernetes Engine (TKE)의 다른 CLB 어노테이션 + +아래 표시된 것처럼 TKE에서 클라우드 로드 밸런서를 관리하기 위한 다른 어노테이션이 있다. + +```yaml + metadata: + name: my-service + annotations: + # 지정된 노드로 로드 밸런서 바인드 + service.kubernetes.io/qcloud-loadbalancer-backends-label: key in (value1, value2) + + # 기존 로드 밸런서의 ID + service.kubernetes.io/tke-existed-lbid:lb-6swtxxxx + + # 로드 밸런서 (LB)에 대한 사용자 지정 매개 변수는 아직 LB 유형 수정을 지원하지 않음 + service.kubernetes.io/service.extensiveParameters: "" + + # LB 리스너의 사용자 정의 매개 변수 + service.kubernetes.io/service.listenerParameters: "" + + # 로드 밸런서 유형 지정 + # 유효 값 : 클래식 (클래식 클라우드 로드 밸런서) 또는 애플리케이션 (애플리케이션 클라우드 로드 밸런서) + service.kubernetes.io/loadbalance-type: xxxxx + + # 퍼블릭 네트워크 대역폭 청구 방법 지정 + # 유효 값: TRAFFIC_POSTPAID_BY_HOUR (트래픽 별) 및 BANDWIDTH_POSTPAID_BY_HOUR (대역폭 별) + service.kubernetes.io/qcloud-loadbalancer-internet-charge-type: xxxxxx + + # 대역폭 값 지정 (값 범위 : [1,2000] Mbps). + service.kubernetes.io/qcloud-loadbalancer-internet-max-bandwidth-out: "10" + + # 이 어느테이션이 설정되면, 로드 밸런서는 파드가 + # 실행중인 노드만 등록하고, 그렇지 않으면 모든 노드가 등록됨 + service.kubernetes.io/local-svc-only-bind-node-with-pod: true +``` + +### ExternalName 유형 {#externalname} + +ExternalName 유형의 서비스는 `my-service` 또는 `cassandra`와 같은 일반적인 셀렉터에 대한 서비스가 아닌, +DNS 이름에 대한 서비스에 매핑한다. `spec.externalName` 파라미터를 사용하여 이러한 서비스를 지정한다. + +예를 들면, 이 서비스 정의는 `prod` 네임 스페이스의 +`my-service` 서비스를 `my.database.example.com`에 매핑한다. + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: my-service + namespace: prod +spec: + type: ExternalName + externalName: my.database.example.com +``` +{{< note >}} +ExternalName은 IPv4 주소 문자열을 허용하지만, IP 주소가 아닌 숫자로 구성된 DNS 이름을 허용한다. IPv4 주소와 유사한 ExternalName은 CoreDNS 또는 ingress-nginx에 의해 확인되지 않는데, ExternalName은 +정식(canonical) DNS 이름을 지정하기 때문이다. IP 주소를 하드 코딩하려면, +[헤드리스(headless) 서비스](#headless-services) 사용을 고려한다. +{{< /note >}} + +`my-service.prod.svc.cluster.local` 호스트를 검색하면, 클러스터 DNS 서비스는 +`my.database.example.com` 값의 `CNAME` 레코드를 반환한다. `my-service`에 접근하는 것은 +다른 서비스와 같은 방식으로 작동하지만, 리다이렉션은 프록시 또는 +포워딩을 통하지 않고 DNS 수준에서 발생한다는 중요한 +차이점이 있다. 나중에 데이터베이스를 클러스터로 이동하기로 결정한 경우, 해당 +파드를 시작하고 적절한 셀렉터 또는 엔드포인트를 추가하고, +서비스의 `유형(type)`을 변경할 수 있다. + +{{< warning >}} +HTTP 및 HTTPS를 포함한, 몇몇 일반적인 프로토콜에 ExternalName을 사용하는 것은 문제가 있을 수 있다. ExternalName을 사용하는 경우, 클러스터 내부의 클라이언트가 사용하는 호스트 이름(hostname)이 ExternalName이 참조하는 이름과 다르다. + +호스트 이름을 사용하는 프로토콜의 경우, 이러한 차이로 인해 오류가 발생하거나 예기치 않은 응답이 발생할 수 있다. HTTP 요청에는 오리진(origin) 서버가 인식하지 못하는 `Host :` 헤더가 있다. TLS 서버는 클라이언트가 연결된 호스트 이름과 일치하는 인증서를 제공할 수 없다. +{{< /warning >}} + +{{< note >}} +이 섹션은 [Alen Komljen](https://akomljen.com/)의 [쿠버네티스 팁 - Part +1](https://akomljen.com/kubernetes-tips-part-1/) 블로그 게시물에 대한 내용이다. +{{< /note >}} + +### 외부 IP + +하나 이상의 클러스터 노드로 라우팅되는 외부 IP가 있는 경우, 쿠버네티스 서비스는 이러한 +`externalIPs`에 노출될 수 있다. 서비스 포트에서 외부 IP (목적지 IP)를 사용하여 클러스터로 들어오는 트래픽은 +서비스 엔드포인트 중 하나로 라우팅된다. `externalIPs`는 쿠버네티스에 의해 관리되지 않으며 +클러스터 관리자에게 책임이 있다. + +서비스 명세에서, `externalIPs`는 모든 `ServiceTypes`와 함께 지정할 수 있다. +아래 예에서, 클라이언트는 "`80.11.12.10:80`"(`외부 IP:포트`)로 "`my-service`"에 접근할 수 있다. + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: my-service +spec: + selector: + app: MyApp + ports: + - name: http + protocol: TCP + port: 80 + targetPort: 9376 + externalIPs: + - 80.11.12.10 +``` + +## 단점 + +VIP용으로 유저스페이스 프록시를 사용하면, 중소 급 스케일에서는 동작하지만, 수천 개의 +서비스가 포함된 대규모 클러스터로는 확장되지 않는다. [포털에 대한 +독창적인 설계 제안](http://issue.k8s.io/1107)에 이에 대한 자세한 내용이 +있다. + +유저스페이스 프록시를 사용하면 서비스에 접근하는 패킷의 소스 IP 주소가 +가려진다. +이것은 일종의 네트워크 필터링 (방화벽)을 불가능하게 만든다. iptables +프록시 모드는 클러스터 내 +소스 IP를 가리지 않지만, 여전히 로드 밸런서 또는 노드-포트를 통해 오는 +클라이언트에 영향을 미친다. + +`Type` 필드는 중첩된 기능으로 설계되었다. - 각 레벨은 이전 레벨에 +추가된다. 이는 모든 클라우드 공급자에 반드시 필요한 것은 아니지만, (예: Google Compute Engine는 +`LoadBalancer`를 작동시키기 위해 `NodePort`를 할당할 필요는 없지만, AWS는 필요하다) +현재 API에는 필요하다. + +## 가상 IP 구현 {#the-gory-details-of-virtual-ips} + +서비스를 사용하려는 많은 사람들에게 이전 정보가 +충분해야 한다. 그러나, 이해가 필요한 부분 뒤에는 +많은 일이 있다. + +### 충돌 방지 + +쿠버네티스의 주요 철학 중 하나는 잘못한 것이 +없는 경우 실패할 수 있는 상황에 노출되어서는 +안된다는 것이다. 서비스 리소스 설계 시, 다른 사람의 포트 선택과 +충돌할 경우에 대비해 자신의 포트 번호를 선택하지 +않아도 된다. 그것은 격리 실패이다. + +서비스에 대한 포트 번호를 선택할 수 있도록 하기 위해, 두 개의 +서비스가 충돌하지 않도록 해야한다. 쿠버네티스는 각 서비스에 고유한 IP 주소를 +할당하여 이를 수행한다. + +각 서비스가 고유한 IP를 받도록 하기 위해, 내부 할당기는 +각 서비스를 만들기 전에 {{< glossary_tooltip term_id="etcd" >}}에서 +글로벌 할당 맵을 원자적으로(atomically) 업데이트한다. 서비스가 IP 주소 할당을 가져오려면 +레지스트리에 맵 오브젝트가 있어야 하는데, 그렇지 않으면 +IP 주소를 할당할 수 없다는 메시지와 함께 생성에 실패한다. + +컨트롤 플레인에서, 백그라운드 컨트롤러는 해당 맵을 +생성해야 한다. (인-메모리 잠금을 사용하는 이전 버전의 쿠버네티스에서 마이그레이션 +지원 필요함) 쿠버네티스는 또한 컨트롤러를 사용하여 유효하지 않은 +할당 (예: 관리자 개입으로)을 체크하고 더 이상 서비스에서 사용하지 않는 할당된 +IP 주소를 정리한다. + +### 서비스 IP 주소 {#ips-and-vips} + +실제로 고정된 목적지로 라우팅되는 파드 IP 주소와 달리, +서비스 IP는 실제로 단일 호스트에서 응답하지 않는다. 대신에, kube-proxy는 +iptables (Linux의 패킷 처리 로직)를 필요에 따라 +명백하게 리다이렉션되는 _가상_ IP 주소를 정의하기 위해 사용한다. 클라이언트가 VIP에 +연결하면, 트래픽이 자동으로 적절한 엔드포인트로 전송된다. +환경 변수와 서비스 용 DNS는 실제로 서비스의 +가상 IP 주소 (및 포트)로 채워진다. + +kube-proxy는 조금씩 다르게 작동하는 세 가지 프록시 모드—유저스페이스, iptables and IPVS—를 +지원한다. + +#### 유저스페이스 (Userspace) + +예를 들어, 위에서 설명한 이미지 처리 애플리케이션을 고려한다. +백엔드 서비스가 생성되면, 쿠버네티스 마스터는 가상 +IP 주소(예 : 10.0.0.1)를 할당한다. 서비스 포트를 1234라고 가정하면, 서비스는 +클러스터의 모든 kube-proxy 인스턴스에서 관찰된다. +프록시가 새 서비스를 발견하면, 새로운 임의의 포트를 열고, 가상 IP 주소에서 +이 새로운 포트로 iptables 리다이렉션을 설정한 후, +연결을 수락하기 시작한다. + +클라이언트가 서비스의 가상 IP 주소에 연결하면, iptables +규칙이 시작되고, 패킷을 프록시의 자체 포트로 리다이렉션한다. +"서비스 프록시"는 백엔드를 선택하고, 클라이언트에서 백엔드로의 트래픽을 프록시하기 시작한다. + +이는 서비스 소유자가 충돌 위험 없이 원하는 어떤 포트든 선택할 수 있음을 +의미한다. 클라이언트는 실제로 접근하는 파드를 몰라도, IP와 포트에 +간단히 연결할 수 있다. + +#### iptables + +다시 한번, 위에서 설명한 이미지 처리 애플리케이션을 고려한다. +백엔드 서비스가 생성되면, 쿠버네티스 컨트롤 플레인은 가상 +IP 주소(예 : 10.0.0.1)를 할당한다. 서비스 포트를 1234라고 가정하면, 서비스는 +클러스터의 모든 kube-proxy 인스턴스에서 관찰된다. +프록시가 새로운 서비스를 발견하면, 가상 IP 주소에서 서비스-별 규칙으로 +리다이렉션되는 일련의 iptables 규칙을 설치한다. 서비스-별 +규칙은 트래픽을 (목적지 NAT를 사용하여) 백엔드로 리다이렉션하는 엔드포인트-별 규칙에 +연결한다. + +클라이언트가 서비스의 가상 IP 주소에 연결하면 iptables 규칙이 시작한다. +(세션 어피니티(Affinity)에 따라 또는 무작위로) 백엔드가 선택되고 패킷이 +백엔드로 리다이렉션된다. 유저스페이스 프록시와 달리, 패킷은 유저스페이스로 +복사되지 않으며, 가상 IP 주소가 작동하기 위해 kube-proxy가 +실행 중일 필요는 없으며, 노드는 변경되지 않은 클라이언트 IP 주소에서 오는 +트래픽을 본다. + +트래픽이 노드-포트 또는 로드 밸런서를 통해 들어오는 경우에도, +이와 동일한 기본 흐름이 실행되지만, 클라이언트 IP는 변경된다. + +#### IPVS + +iptables 작업은 대규모 클러스터 (예: 10,000 서비스)에서 크게 느려진다. +IPVS는 로드 밸런싱을 위해 설계되었고 커널-내부 해시 테이블을 기반으로 한다. 따라서 IPVS 기반 kube-proxy로부터 많은 개수의 서비스에서 일관성 있는 성능을 가질 수 있다. 한편, IPVS 기반 kube-proxy는 보다 정교한 로드 밸런싱 알고리즘 (least conns, locality, weighted, persistence)을 가진다. + +## API 오브젝트 + +서비스는 쿠버네티스 REST API의 최상위 리소스이다. API 오브젝트에 대한 +자세한 내용은 다음을 참고한다. [서비스 API 오브젝트](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#service-v1-core) + +## 지원되는 프로토콜 {#protocol-support} + +### 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 리버스 프록시를 +설정할 수 있다. + +{{< note >}} +서비스 대신 {{< glossary_tooltip term_id="ingress" text="인그레스" >}} 를 사용하여 +HTTP / HTTPS 서비스를 노출할 수도 있다. +{{< /note >}} + +### PROXY 프로토콜 + +{{< feature-state for_k8s_version="v1.1" state="stable" >}} + +클라우드 공급자가 지원하는 경우에 (예: [AWS](/docs/concepts/cluster-administration/cloud-providers/#aws)), +LoadBalancer 모드의 서비스를 사용하여 쿠버네티스 자체 외부에 +로드 밸런서를 구성할 수 있으며, 이때 접두사가 +[PROXY 프로토콜](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) 인 연결을 전달하게 된다. + +로드 밸런서는 들어오는 연결을 설명하는 초기 일련의 +옥텟(octets)을 전송하며, 이 예와 유사하게 + +``` +PROXY TCP4 192.0.2.202 10.0.42.7 12345 7\r\n +``` +클라이언트 데이터가 뒤따라온다. + +### SCTP + +{{< feature-state for_k8s_version="v1.12" state="alpha" >}} + +쿠버네티스는 서비스, 엔드포인트, 네트워크 정책 및 파드 정의에서 알파 기능으로 SCTP를 `프로토콜` 값으로 지원한다. 이 기능을 활성화하기 위해서는, 클러스터 관리자가 API 서버에서 `--feature-gates=SCTPSupport=true,…`처럼 `SCTPSupport` 기능 게이트를 활성화해야 한다. + +기능 게이트가 활성화되면, 서비스, 엔드포인트, 네트워크 정책 또는 파드의 `프로토콜` 필드를 `SCTP`로 설정할 수 있다. 쿠버네티스는 TCP 연결과 마찬가지로, SCTP 연결에 맞게 네트워크를 설정한다. + +#### 경고 {#caveat-sctp-overview} + +##### 멀티홈드(multihomed) SCTP 연결을 위한 지원 {#caveat-sctp-multihomed} + +{{< warning >}} +멀티홈 SCTP 연결을 위해서는 먼저 CNI 플러그인이 파드에 대해 멀티 인터페이스 및 IP 주소 할당이 지원되어야 한다. + +멀티홈 SCTP 연결을 위한 NAT는 해당 커널 모듈 내에 특수한 로직을 필요로 한다. +{{< /warning >}} + +##### type=LoadBalancer 서비스 {#caveat-sctp-loadbalancer-service-type} + +{{< warning >}} +클라우드 공급자의 로드 밸런서 구현이 프로토콜로서 SCTP를 지원하는 경우에만 LoadBalancer `유형`과 SCTP `프로토콜`을 사용하여 서비스를 생성할 수 있다. 그렇지 않으면, 서비스 생성 요청이 거부된다. 현재 클라우드 로드 밸런서 공급자 세트 (Azure, AWS, CloudStack, GCE, OpenStack)는 모두 SCTP에 대한 지원이 없다. +{{< /warning >}} + +##### Windows {#caveat-sctp-windows-os} + +{{< warning >}} +SCTP는 Windows 기반 노드를 지원하지 않는다. +{{< /warning >}} + +##### 유저스페이스 kube-proxy {#caveat-sctp-kube-proxy-userspace} + +{{< warning >}} +kube-proxy는 유저스페이스 모드에 있을 때 SCTP 연결 관리를 지원하지 않는다. +{{< /warning >}} + +## 향후 작업 + +향후, 서비스에 대한 프록시 정책은 예를 들어, 마스터-선택 또는 샤드 같은 +단순한 라운드-로빈 밸런싱보다 미묘한 차이가 생길 수 있다. 또한 +일부 서비스에는 "실제" 로드 밸런서가 있을 것으로 예상되는데, 이 경우 +가상 IP 주소는 단순히 패킷을 그곳으로 전송한다. + +쿠버네티스 프로젝트는 L7 (HTTP) 서비스에 대한 지원을 개선하려고 한다. + +쿠버네티스 프로젝트는 현재 ClusterIP, NodePort 및 LoadBalancer 모드 등을 포함하는 서비스에 대해 +보다 유연한 인그레스 모드를 지원하려고 한다. + + +{{% /capture %}} + +{{% capture whatsnext %}} + +* [서비스와 애플리케이션 연결](/docs/concepts/services-networking/connect-applications-service/) 알아보기 +* [인그레스](/ko/docs/concepts/services-networking/ingress/)에 대해 알아보기 +* [엔드포인트 슬라이스](/ko/docs/concepts/services-networking/endpoint-slices/)에 대해 알아보기 + +{{% /capture %}} diff --git a/content/ko/docs/concepts/workloads/controllers/cron-jobs.md b/content/ko/docs/concepts/workloads/controllers/cron-jobs.md index d7c6f10739c69..ff76d12f868bf 100644 --- a/content/ko/docs/concepts/workloads/controllers/cron-jobs.md +++ b/content/ko/docs/concepts/workloads/controllers/cron-jobs.md @@ -17,6 +17,11 @@ _크론 잡은_ 시간 기반의 일정에 따라 [잡](/docs/concepts/workloads 모든 **크론잡** `일정:` 시간은 잡이 처음 시작된 마스터의 시간대를 기반으로 한다. {{< /note >}} +크론잡 리소스에 대한 매니페스트를 생성할때에는 제공하는 이름이 +52자 이하인지 확인해야 한다. 이는 크론잡 컨트롤러는 제공된 잡 이름에 +11자를 자동으로 추가하고, 작업 이름의 최대 길이는 +63자라는 제약 조건이 있기 때문이다. + 크론 잡을 생성하고 작동하는 방법은 크론 잡의 스펙 파일을 확안한다. 내용은 [크론 잡으로 자동 작업 실행하기](/docs/tasks/job/automated-tasks-with-cron-jobs)를 참조한다. {{% /capture %}} diff --git a/content/ko/docs/concepts/workloads/controllers/garbage-collection.md b/content/ko/docs/concepts/workloads/controllers/garbage-collection.md new file mode 100644 index 0000000000000..9ccc803dce1e2 --- /dev/null +++ b/content/ko/docs/concepts/workloads/controllers/garbage-collection.md @@ -0,0 +1,182 @@ +--- +title: 가비지(Garbage) 수집 +content_template: templates/concept +weight: 60 +--- + +{{% capture overview %}} + +쿠버네티스의 가비지 수집기는 한때 소유자가 있었지만, 더 이상 +소유자가 없는 오브젝트들을 삭제하는 역할을 한다. + +{{% /capture %}} + + +{{% capture body %}} + +## 소유자(owner)와 종속(dependent) + +일부 쿠버네티스 오브젝트는 다른 오브젝트의 소유자이다. 예를 들어 레플리카셋은 +파드 집합의 소유자이다. 소유자 오브젝트에게 소유된 오브젝트를 *종속* +이라고 한다. 모든 종속 오브젝트는 소유하는 오브젝트를 가르키는 `metadata.ownerReferences` +필드를 가지고 있다. + +때때로, 쿠버네티스는 `ownerReference` 값을 자동적으로 설정한다. +예를 들어 레플리카셋을 만들 때 쿠버네티스는 레플리카셋에 있는 각 파드의 +`ownerReference` 필드를 자동으로 설정한다. 1.8 에서는 쿠버네티스가 +레플리케이션컨트롤러, 레플리카셋, 스테이트풀셋, 데몬셋, 디플로이먼트, 잡 +그리고 크론잡에 의해서 생성되거나 차용된 오브젝트의 `ownerReference` 값을 +자동으로 설정한다. + +또한 `ownerReference` 필드를 수동으로 설정해서 소유자와 종속 항목 간의 +관계를 지정할 수도 있다. + +여기에 파드 3개가 있는 레플리카셋의 구성 파일이 있다. + +{{< codenew file="controllers/replicaset.yaml" >}} + +레플리카셋을 생성하고 파드의 메타데이터를 본다면, +OwnerReferences 필드를 찾을 수 있다. + +```shell +kubectl apply -f https://k8s.io/examples/controllers/replicaset.yaml +kubectl get pods --output=yaml +``` + +출력 결과는 파드의 소유자가 `my-repset` 이라는 이름의 레플리카셋인 것을 보여준다. + +```yaml +apiVersion: v1 +kind: Pod +metadata: + ... + ownerReferences: + - apiVersion: apps/v1 + controller: true + blockOwnerDeletion: true + kind: ReplicaSet + name: my-repset + uid: d9607e19-f88f-11e6-a518-42010a800195 + ... +``` + +{{< note >}} +교차 네임스페이스(cross-namespace)의 소유자 참조는 디자인상 허용되지 않는다. 이는 다음을 의미한다. +1) 네임스페이스 범위의 종속 항목은 동일한 네임스페이스의 소유자와 +클러스터 범위의 소유자만 지정할 수 있다. +2) 클러스터 범위의 종속 항목은 클러스터 범위의 소유자만 지정할 수 있으며, +네임스페이스 범위의 소유자는 불가하다. +{{< /note >}} + +## 가비지 수집기의 종속 항목 삭제 방식 제어 + +오브젝트를 삭제할 때, 오브젝트의 종속 항목을 자동으로 삭제하는지의 +여부를 지정할 수 있다. 종속 항목을 자동으로 삭제하는 것을 *캐스케이딩(cascading) +삭제* 라고 한다. *캐스케이딩 삭제* 에는 *백그라운드* 와 *포어그라운드* 2가지 모드가 있다. + +만약 종속 항목을 자동으로 삭제하지 않고 오브젝트를 삭제한다면, +종속 항목은 *분리됨(orphaned)* 이라고 한다. + +### 포어그라운드 캐스케이딩 삭제 + +*포어그라운드 캐스케이딩 삭제* 에서는 루트 오브젝트가 먼저 +"삭제 중(deletion in progress)" 상태가 된다. "삭제 중" 상태에서는 +다음 사항이 적용된다. + + * 오브젝트는 REST API를 통해 여전히 볼 수 있음 + * 오브젝트에 `deletionTimestamp` 가 설정됨 + * 오브젝트의 "foregroundDeletion"에 `metadata.finalizers` 값이 포함됨. + +"삭제 중" 상태가 설정되면, 가비지 +수집기는 오브젝트의 종속 항목을 삭제한다. 가비지 수집기는 모든 +"차단" 종속 항목(`ownerReference.blockOwnerDeletion=true` 가 있는 오브젝트)의 삭제가 완료되면, +소유자 오브젝트를 삭제한다. + +"foregroundDeletion" 에서는 ownerReference.blockOwnerDeletion=true 로 +설정된 종속 항목만 소유자 오브젝트의 삭제를 차단한다는 것을 참고한다. +쿠버네티스 버전 1.7에서는 소유자 오브젝트에 대한 삭제 권한에 따라 `blockOwnerDeletion` 를 true로 설정하기 위해 사용자 접근을 제어하는 +[어드미션 컨트롤러](/docs/reference/access-authn-authz/admission-controllers/#ownerreferencespermissionenforcement)가 +추가되었기에 권한이 없는 종속 항목은 소유자 오브젝트의 삭제를 지연시킬 수 없다. + +만약 오브젝트의 `ownerReferences` 필드가 컨트롤러(디플로이먼트 또는 레플리카셋과 같은)에 +의해 설정된 경우 blockOwnerDeletion이 자동으로 설정되므로 이 필드를 수동으로 수정할 필요가 없다. + +### 백그라운드 캐스케이딩 삭제 + +*백그라운드 캐스케이딩 삭제* 에서 쿠버네티스는 소유자 오브젝트를 +즉시 삭제하고, 가비지 수집기는 백그라운드에서 종속 항목을 +삭제한다. + +### 캐스케이딩 삭제 정책 설정하기 + +캐스케이딩 삭제 정책을 제어하려면, 오브젝트를 삭제할 때 `deleteOptions` +인수를 `propagationPolicy` 필드에 설정한다. 여기에 가능한 값으로는 "Orphan", +"Foreground" 또는 "Background" 이다. + +쿠버네티스 1.9 이전에는 많은 컨트롤러의 리소스에 대한 기본 가비지 수집 정책이 `orphan` 이었다. +여기에는 레플리케이션컨트롤러, 레플리카셋, 스테이트풀셋, 데몬셋 그리고 +디플로이먼트가 포함된다. 그룹 버전 `extensions/v1beta1`, `apps/v1beta1` 그리고 `apps/v1beta2` 의 kinds에서는 +달리 지정하지 않는 한 오브젝트가 분리되는 것이 기본이다. 쿠버네티스 1.9에서는 그룹 버전 `apps/v1` 의 모든 kinds에 해당하는 +종속 오브젝트들이 기본적으로 삭제된다. + +여기에 백그라운드에서 종속 항목을 삭제하는 예시가 있다. + +```shell +kubectl proxy --port=8080 +curl -X DELETE localhost:8080/apis/apps/v1/namespaces/default/replicasets/my-repset \ + -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Background"}' \ + -H "Content-Type: application/json" +``` + +여기에 포어그라운드에서 종속 항목을 삭제하는 예시가 있다. + +```shell +kubectl proxy --port=8080 +curl -X DELETE localhost:8080/apis/apps/v1/namespaces/default/replicasets/my-repset \ + -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Foreground"}' \ + -H "Content-Type: application/json" +``` + +여기에 종속 항목을 분리됨으로 하는 예시가 있다. + +```shell +kubectl proxy --port=8080 +curl -X DELETE localhost:8080/apis/apps/v1/namespaces/default/replicasets/my-repset \ + -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Orphan"}' \ + -H "Content-Type: application/json" +``` + +kubectl도 캐스케이딩 삭제를 지원한다. +kubectl을 사용해서 종속 항목을 자동으로 삭제하려면 `--cascade` 를 true로 설정한다. 종속 항목을 +분리하기 위해서는 `--cascase` 를 false로 설정한다. `--cascade` 의 기본값은 +true 이다. + +여기에 레플리카셋의 종속 항목을 분리로 만드는 예시가 있다. + +```shell +kubectl delete replicaset my-repset --cascade=false +``` + +### 디플로이먼트에 대한 추가 참고 + +1.7 이전에서는 디플로이먼트와 캐스케이딩 삭제를 사용하면 반드시 `propagationPolicy: Foreground` +를 사용해서 생성된 레플리카셋 뿐만 아니라 해당 파드도 삭제해야 한다. 만약 이 _propagationPolicy_ +유형을 사용하지 않는다면, 레플리카셋만 삭제되고 파드는 분리된 상태로 남을 것이다. +더 많은 정보는 [kubeadm/#149](https://github.com/kubernetes/kubeadm/issues/149#issuecomment-284766613)를 본다. + +## 알려진 이슈들 + +[#26120](https://github.com/kubernetes/kubernetes/issues/26120)을 추적한다. + +{{% /capture %}} + + +{{% capture whatsnext %}} + +[디자인 문서 1](https://git.k8s.io/community/contributors/design-proposals/api-machinery/garbage-collection.md) + +[디자인 문서 2](https://git.k8s.io/community/contributors/design-proposals/api-machinery/synchronous-garbage-collection.md) + +{{% /capture %}} + + diff --git a/content/ko/docs/concepts/workloads/pods/pod-overview.md b/content/ko/docs/concepts/workloads/pods/pod-overview.md index ef0b0de7558f4..55126172feb7a 100644 --- a/content/ko/docs/concepts/workloads/pods/pod-overview.md +++ b/content/ko/docs/concepts/workloads/pods/pod-overview.md @@ -26,7 +26,7 @@ card: * **단일 컨테이너만 동작하는 파드**. "단일 컨테이너 당 한 개의 파드" 모델은 쿠버네티스 사용 사례 중 가장 흔하다. 이 경우, 한 개의 파드가 단일 컨테이너를 감싸고 있다고 생각할 수 있으며, 쿠버네티스는 컨테이너가 아닌 파드를 직접 관리한다고 볼 수 있다. * **함께 동작하는 작업이 필요한 다중 컨테이너가 동작하는 파드**. 아마 파드는 강하게 결합되어 있고 리소스 공유가 필요한 다중으로 함께 배치된 컨테이너로 구성되어 있을 것이다. 이렇게 함께 배치되어 설치된 컨테이너는 단일 결합 서비스 단위일 것이다. 한 컨테이너는 공유 볼륨에서 퍼블릭으로 파일들을 옮기고, 동시에 분리되어 있는 "사이드카" 컨테이너는 그 파일들을 업데이트 하거나 복구한다. 파드는 이 컨테이너와 저장소 리소스들을 한 개의 관리 가능한 요소로 묶는다. -[쿠버네티스 블로그](http://kubernetes.io/blog)에는 파드 사용 사례의 몇 가지 추가적인 정보가 있다. 더 많은 정보를 위해서 아래 내용을 참조하길 바란다. +[쿠버네티스 블로그](https://kubernetes.io/blog)에는 파드 사용 사례의 몇 가지 추가적인 정보가 있다. 더 많은 정보를 위해서 아래 내용을 참조하길 바란다. * [분산 시스템 툴킷: 복합 컨테이너를 위한 패턴](https://kubernetes.io/blog/2015/06/the-distributed-system-toolkit-patterns) * [컨테이너 디자인 패턴](https://kubernetes.io/blog/2016/06/container-design-patterns) diff --git a/content/ko/docs/reference/glossary/customresourcedefinition.md b/content/ko/docs/reference/glossary/customresourcedefinition.md index d21612e118370..3e680ca2bd822 100755 --- a/content/ko/docs/reference/glossary/customresourcedefinition.md +++ b/content/ko/docs/reference/glossary/customresourcedefinition.md @@ -2,7 +2,7 @@ title: 커스텀 리소스 데피니션(CustomResourceDefinition) id: CustomResourceDefinition date: 2018-04-12 -full_link: docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/ +full_link: /docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/ short_description: > 사용자 정의 서버를 완전히 새로 구축할 필요가 없도록 쿠버네티스 API 서버에 추가할 리소스를 정의하는 사용자 정의 코드. diff --git a/content/ko/docs/reference/kubectl/cheatsheet.md b/content/ko/docs/reference/kubectl/cheatsheet.md index a964a4a6d6e0b..8c6e54aabb41c 100644 --- a/content/ko/docs/reference/kubectl/cheatsheet.md +++ b/content/ko/docs/reference/kubectl/cheatsheet.md @@ -82,7 +82,7 @@ kubectl config unset users.foo # foo 사용자 삭제 ## 오브젝트 생성 -쿠버네티스 매니페스트는 json이나 yaml로 정의된다. 파일 확장자는 `.yaml` +쿠버네티스 매니페스트는 JSON이나 YAML로 정의된다. 파일 확장자는 `.yaml` , `.yml`, `.json` 이 사용된다. ```bash @@ -203,6 +203,7 @@ kubectl rollout history deployment/frontend # 현 리비전 kubectl rollout undo deployment/frontend # 이전 디플로이먼트로 롤백 kubectl rollout undo deployment/frontend --to-revision=2 # 특정 리비전으로 롤백 kubectl rollout status -w deployment/frontend # 완료될 때까지 "frontend" 디플로이먼트의 롤링 업데이트 상태를 감시 +kubectl rollout restart deployment/frontend # "frontend" 디플로이먼트의 롤링 재시작 # 버전 1.11 부터 사용 중단 @@ -330,7 +331,7 @@ kubectl api-resources --api-group=extensions # "extensions" API 그룹의 모든 ### 출력 형식 지정 -특정 형식으로 터미널 창에 세부 사항을 출력하려면, 지원되는 `kubectl` 명령에 `-o` 또는 `--output` 플래그를 추가하면 된다. +특정 형식으로 터미널 창에 세부 사항을 출력하려면, 지원되는 `kubectl` 명령에 `-o` (또는 `--output`) 플래그를 추가한다. 출력 형식 | 세부 사항 --------------| ----------- diff --git a/content/ko/docs/setup/_index.md b/content/ko/docs/setup/_index.md index d10d66cd204db..8e6bc5e66887a 100644 --- a/content/ko/docs/setup/_index.md +++ b/content/ko/docs/setup/_index.md @@ -43,7 +43,6 @@ card: | | [IBM Cloud Private-CE (Community Edition)](https://github.com/IBM/deploy-ibm-cloud-private) | | | [IBM Cloud Private-CE (Community Edition) on Linux Containers](https://github.com/HSBawa/icp-ce-on-linux-containers)| | | [k3s](https://k3s.io)| -| | [Ubuntu on LXD](/docs/getting-started-guides/ubuntu/)| ## 운영 환경 @@ -77,11 +76,10 @@ card: | [Digital Rebar](https://provision.readthedocs.io/en/tip/README.html) | | | | | | ✔ | [DigitalOcean](https://www.digitalocean.com/products/kubernetes/) | ✔ | | | | | | [Docker Enterprise](https://www.docker.com/products/docker-enterprise) | |✔ | ✔ | | | ✔ -| [Fedora (멀티 노드)](https://kubernetes.io/docs/getting-started-guides/fedora/flannel_multi_node_cluster/)  | | | | | ✔ | ✔ -| [Fedora (단일 노드)](https://kubernetes.io/docs/getting-started-guides/fedora/fedora_manual_config/)  | | | | | | ✔ | [Gardener](https://gardener.cloud/) | ✔ | ✔ | ✔ | ✔ | ✔ | [사용자 정의 확장](https://github.com/gardener/gardener/blob/master/docs/extensions/overview.md) | | [Giant Swarm](https://www.giantswarm.io/) | ✔ | ✔ | ✔ | | | [Google](https://cloud.google.com/) | [Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine/) | [Google Compute Engine (GCE)](https://cloud.google.com/compute/)|[GKE On-Prem](https://cloud.google.com/gke-on-prem/) | | | | | | | | +| [Hidora](https:/hidora.com/) | ✔ | ✔| ✔ | | | | | | | | | [IBM](https://www.ibm.com/in-en/cloud) | [IBM Cloud Kubernetes Service](https://cloud.ibm.com/kubernetes/catalog/cluster)| |[IBM Cloud Private](https://www.ibm.com/in-en/cloud/private) | | | [Ionos](https://www.ionos.com/enterprise-cloud) | [Ionos Managed Kubernetes](https://www.ionos.com/enterprise-cloud/managed-kubernetes) | [Ionos Enterprise Cloud](https://www.ionos.com/enterprise-cloud) | | | [Kontena Pharos](https://www.kontena.io/pharos/) | |✔| ✔ | | | @@ -92,6 +90,7 @@ card: | [Kublr](https://kublr.com/) |✔ | ✔ |✔ |✔ |✔ |✔ | | [Microsoft Azure](https://azure.microsoft.com) | [Azure Kubernetes Service (AKS)](https://azure.microsoft.com/en-us/services/kubernetes-service/) | | | | | | [Mirantis Cloud Platform](https://www.mirantis.com/software/kubernetes/) | | | ✔ | | | +| [NetApp Kubernetes Service (NKS)](https://cloud.netapp.com/kubernetes-service) | ✔ | ✔ | ✔ | | | | [Nirmata](https://www.nirmata.com/) | | ✔ | ✔ | | | | [Nutanix](https://www.nutanix.com/en) | [Nutanix Karbon](https://www.nutanix.com/products/karbon) | [Nutanix Karbon](https://www.nutanix.com/products/karbon) | | | [Nutanix AHV](https://www.nutanix.com/products/acropolis/virtualization) | | [OpenNebula](https://www.opennebula.org) |[OpenNebula Kubernetes](https://marketplace.opennebula.systems/docs/service/kubernetes.html) | | | | | @@ -101,7 +100,6 @@ card: | [Pivotal](https://pivotal.io/) | | [Enterprise Pivotal Container Service (PKS)](https://pivotal.io/platform/pivotal-container-service) | [Enterprise Pivotal Container Service (PKS)](https://pivotal.io/platform/pivotal-container-service) | | | | [Platform9](https://platform9.com/) | [Platform9 Managed Kubernetes](https://platform9.com/managed-kubernetes/) | | [Platform9 Managed Kubernetes](https://platform9.com/managed-kubernetes/) | ✔ | ✔ | ✔ | [Rancher](https://rancher.com/) | | [Rancher 2.x](https://rancher.com/docs/rancher/v2.x/en/) | | [Rancher Kubernetes Engine (RKE)](https://rancher.com/docs/rke/latest/en/) | | [k3s](https://k3s.io/) -| [StackPoint](https://stackpoint.io/)  | ✔ | ✔ | | | | | [Supergiant](https://supergiant.io/) | |✔ | | | | | [SUSE](https://www.suse.com/) | | ✔ | | | | | [SysEleven](https://www.syseleven.io/) | ✔ | | | | | diff --git a/content/ko/docs/tasks/access-application-cluster/port-forward-access-application-cluster.md b/content/ko/docs/tasks/access-application-cluster/port-forward-access-application-cluster.md new file mode 100644 index 0000000000000..3d9a5d1d99195 --- /dev/null +++ b/content/ko/docs/tasks/access-application-cluster/port-forward-access-application-cluster.md @@ -0,0 +1,153 @@ +--- +title: 포트 포워딩을 사용해서 클러스터 내 애플리케이션에 접근하기 +content_template: templates/task +weight: 40 +--- + +{{% capture overview %}} + +이 페이지는 `kubectl port-forward` 를 사용해서 쿠버네티스 클러스터 내에서 +실행중인 Redis 서버에 연결하는 방법을 보여준다. 이 유형의 연결은 데이터베이스 +디버깅에 유용할 수 있다. + +{{% /capture %}} + + +{{% capture prerequisites %}} + +* {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} + +* [redis-cli](http://redis.io/topics/rediscli)를 설치한다. + +{{% /capture %}} + + +{{% capture steps %}} + +## Redis 디플로이먼트와 서비스 생성하기 + +1. Redis 디플로이먼트를 생성한다. + + kubectl apply -f https://k8s.io/examples/application/guestbook/redis-master-deployment.yaml + + 성공적인 명령어의 출력은 디플로이먼트가 생성됐다는 것을 확인해준다. + + deployment.apps/redis-master created + + 파드 상태를 조회하여 파드가 준비되었는지 확인한다. + + kubectl get pods + + 출력은 파드가 생성되었다는 것을 보여준다. + + NAME READY STATUS RESTARTS AGE + redis-master-765d459796-258hz 1/1 Running 0 50s + + 디플로이먼트 상태를 조회한다. + + kubectl get deployment + + 출력은 디플로이먼트가 생성되었다는 것을 보여준다. + + NAME READY UP-TO-DATE AVAILABLE AGE + redis-master 1/1 1 1 55s + + 아래의 명령어를 사용하여 레플리카셋 상태를 조회한다. + + kubectl get rs + + 출력은 레플리카셋이 생성되었다는 것을 보여준다. + + NAME DESIRED CURRENT READY AGE + redis-master-765d459796 1 1 1 1m + + +2. Redis 서비스를 생성한다. + + kubectl apply -f https://k8s.io/examples/application/guestbook/redis-master-service.yaml + + 성공적인 커맨드의 출력은 서비스가 생성되었다는 것을 확인해준다. + + service/redis-master created + + 서비스가 생성되었는지 확인한다. + + kubectl get svc | grep redis + + 출력은 서비스가 생성되었다는 것을 보여준다. + + NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE + redis-master ClusterIP 10.0.0.213 6379/TCP 27s + +3. Redis 서버가 파드 안에서 실행되고 있고, 6379번 포트에서 수신하고 있는지 확인한다. + + kubectl get pods redis-master-765d459796-258hz --template='{{(index (index .spec.containers 0).ports 0).containerPort}}{{"\n"}}' + + 출력은 포트 번호를 보여준다. + + 6379 + + +## 파드의 포트를 로컬 포트로 포워딩하기 + +1. 쿠버네티스 1.10 버전부터, `kubectl port-forward` 명령어는 파드 이름과 같이 리소스 이름을 사용하여 일치하는 파드를 선택해 포트 포워딩하는 것을 허용한다. + + kubectl port-forward redis-master-765d459796-258hz 7000:6379 + + 이것은 + + kubectl port-forward pods/redis-master-765d459796-258hz 7000:6379 + + 또는 + + kubectl port-forward deployment/redis-master 7000:6379 + + 또는 + + kubectl port-forward rs/redis-master 7000:6379 + + 또는 다음과 같다. + + kubectl port-forward svc/redis-master 7000:6379 + + 위의 명령어들은 모두 동일하게 동작한다. 이와 유사하게 출력된다. + + I0710 14:43:38.274550 3655 portforward.go:225] Forwarding from 127.0.0.1:7000 -> 6379 + I0710 14:43:38.274797 3655 portforward.go:225] Forwarding from [::1]:7000 -> 6379 + +2. Redis 커맨드라인 인터페이스를 실행한다. + + redis-cli -p 7000 + +3. Redis 커맨드라인 프롬프트에 `ping` 명령을 입력한다. + + 127.0.0.1:7000>ping + + 성공적인 핑 요청은 PONG을 반환한다. + +{{% /capture %}} + + +{{% capture discussion %}} + +## 토의 + +로컬 7000 포트에 대한 연결은 Redis 서버가 실행중인 파드의 6379 포트로 포워딩된다. +이 연결로 로컬 워크스테이션에서 파드 안에서 실행 중인 데이터베이스를 디버깅하는데 +사용할 수 있다. + +{{< warning >}} +알려진 제한사항으로 인해, 오늘날 포트 포워딩은 TCP 프로토콜에서만 작동한다. UDP 프로토콜에 대한 지원은 +[이슈 47862](https://github.com/kubernetes/kubernetes/issues/47862) +에서 추적되고 있다. +{{< /warning >}} + +{{% /capture %}} + + +{{% capture whatsnext %}} +[kubectl port-forward](/docs/reference/generated/kubectl/kubectl-commands/#port-forward)에 대해 더 알아본다. +{{% /capture %}} + + + diff --git a/content/ko/examples/controllers/replicaset.yaml b/content/ko/examples/controllers/replicaset.yaml new file mode 100644 index 0000000000000..e5dfdf6c43ce5 --- /dev/null +++ b/content/ko/examples/controllers/replicaset.yaml @@ -0,0 +1,17 @@ +apiVersion: apps/v1 +kind: ReplicaSet +metadata: + name: my-repset +spec: + replicas: 3 + selector: + matchLabels: + pod-is-for: garbage-collection-example + template: + metadata: + labels: + pod-is-for: garbage-collection-example + spec: + containers: + - name: nginx + image: nginx