From 3bc455b2d957d84d6327a741a45c543ac3630b07 Mon Sep 17 00:00:00 2001 From: "Claudia J.Kang" Date: Tue, 19 Mar 2019 23:20:30 +0900 Subject: [PATCH] Eighth Korean I10n work for release-1.13 (#13250) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ko-trans: Update outdated contents in dev-1.13-ko.8 branch partly (#12986) * ko: Update outdated files in dev-1.13-ko.8 (#13000) * ko: add tutorials/stateful-application/basic-stateful-set #12449 (#13073) * Add missing word. (#13249) * Fixed wrong word. (#13246) * Translate concepts/cluster-administration/federation.md in Korean (#13159) * Translate concepts/overview/object-management-kubectl/imperative-comm… (#13076) Co-authored-by: June Yi Co-authored-by: Claudia J.Kang Co-authored-by: Yoon Co-authored-by: Thomas Sungjin Kang Co-authored-by: Seokho Co-authored-by: zerobig --- .../architecture/master-node-communication.md | 2 +- .../concepts/cluster-administration/_index.md | 5 + .../cluster-administration/federation.md | 187 +++ content/ko/docs/concepts/containers/images.md | 45 +- .../ko/docs/concepts/overview/components.md | 3 + .../docs/concepts/overview/kubernetes-api.md | 3 + .../imperative-command.md | 162 +++ .../concepts/overview/what-is-kubernetes.md | 5 +- .../kubernetes-objects.md | 5 +- .../concepts/workloads/pods/pod-overview.md | 3 + content/ko/docs/home/_index.md | 42 +- content/ko/docs/reference/glossary/index.md | 4 + content/ko/docs/setup/cri.md | 39 +- content/ko/docs/setup/multiple-zones.md | 93 +- content/ko/docs/setup/pick-right-solution.md | 14 + .../setup/release/building-from-source.md | 4 + .../horizontal-pod-autoscale-walkthrough.md | 2 +- .../ko/docs/tasks/tools/install-minikube.md | 3 + content/ko/docs/tutorials/hello-minikube.md | 3 + .../tutorials/kubernetes-basics/_index.html | 4 + .../tutorials/online-training/overview.md | 10 + .../basic-stateful-set.md | 1038 +++++++++++++++++ .../stateless-application/guestbook.md | 4 + .../application/web/web-parallel.yaml | 47 + content/ko/examples/application/web/web.yaml | 47 + .../ko/includes/federation-current-state.md | 1 + 26 files changed, 1708 insertions(+), 67 deletions(-) create mode 100755 content/ko/docs/concepts/cluster-administration/_index.md create mode 100644 content/ko/docs/concepts/cluster-administration/federation.md create mode 100644 content/ko/docs/concepts/overview/object-management-kubectl/imperative-command.md create mode 100644 content/ko/docs/tutorials/stateful-application/basic-stateful-set.md create mode 100644 content/ko/examples/application/web/web-parallel.yaml create mode 100644 content/ko/examples/application/web/web.yaml create mode 100644 content/ko/includes/federation-current-state.md diff --git a/content/ko/docs/concepts/architecture/master-node-communication.md b/content/ko/docs/concepts/architecture/master-node-communication.md index 7ab5615255..cbeda8aa78 100644 --- a/content/ko/docs/concepts/architecture/master-node-communication.md +++ b/content/ko/docs/concepts/architecture/master-node-communication.md @@ -68,7 +68,7 @@ apiserver는 kubelet의 제공 인증서를 확인하지 않는데, 루트 인증서 번들로 `--kubelet-certificate-authority` 플래그를 이용한다 그것이 불가능한 경우, 신뢰할 수 없는 또는 공인 네트워크에 대한 연결을 피하고 싶다면, -apiserver와 kubelet 사이에 [SSH 터널링](/docs/tasks/access-application-cluster/port-forward-access-application-cluster/)을 +apiserver와 kubelet 사이에 [SSH 터널링](/docs/concepts/architecture/master-node-communication/#ssh-tunnels)을 사용한다. 마지막으로, kubelet API를 안전하게 하기 위해 diff --git a/content/ko/docs/concepts/cluster-administration/_index.md b/content/ko/docs/concepts/cluster-administration/_index.md new file mode 100755 index 0000000000..e13a5fdb48 --- /dev/null +++ b/content/ko/docs/concepts/cluster-administration/_index.md @@ -0,0 +1,5 @@ +--- +title: "클러스터 관리" +weight: 100 +--- + diff --git a/content/ko/docs/concepts/cluster-administration/federation.md b/content/ko/docs/concepts/cluster-administration/federation.md new file mode 100644 index 0000000000..cf8396a05c --- /dev/null +++ b/content/ko/docs/concepts/cluster-administration/federation.md @@ -0,0 +1,187 @@ +--- +title: 페더레이션 +content_template: templates/concept +weight: 80 +--- + +{{% capture overview %}} + +{{< include "federation-current-state.md" >}} + +이 페이지는 여러 쿠버네티스 클러스터를 페더레이션을 통해서 관리해야 하는 이유와 방법을 +설명한다. +{{% /capture %}} + +{{% capture body %}} +## 페더레이션 이유 + +페더레이션을 사용하면 여러 클러스터를 쉽게 관리할 수 있다. 이는 2가지 주요 빌딩 블록을 +제공함으로써 이루어진다. + + * 클러스터 간의 리소스 동기화: 페더레이션은 여러 클러스터 내의 리소스를 + 동기화하는 능력을 제공한다. 예를 들면, 여러 클러스터에 동일한 디플로이먼트가 존재하는 것을 확인 할 수 있다. + * 클러스터 간의 디스커버리: 페더레이션은 모든 클러스터의 백엔드에 DNS 서버 및 로드벨런서를 자동 구성하는 능력을 제공한다. 예를 들면, 글로벌 VIP 또는 DNS 기록이 여러 클러스터의 백엔드 엑세스에 사용될 수 있는 것을 확인할 수 있다. + +페더레이션이 가능하게 하는 다른 사례는 다음과 같다. + +* 고가용성: 클러스터에 걸쳐서 부하를 분산하고 DNS + 서버와 로드벨런서를 자동 구성함으로써, 페더레이션은 클러스터 장애의 영향을 + 최소화한다. +* 공급자 락인(lock-in) 회피: 애플리케이션의 클러스터 간 마이그레이션을 쉽게 + 만듦으로써, 페더레이션은 클러스터 공급자의 락인을 방지한다. + + +여러 클러스터를 운영하는 경우가 아니면 페더레이션은 필요 없다. 여러 클러스터가 필요한 +이유의 일부는 다음과 같다. + +* 짧은 지연시간: 클러스터가 여러 지역(region)에 있으면 사용자에게 가장 가까운 클러스터로부터 + 서비스함으로써 지연시간을 최소화한다. +* 결함 격리: 하나의 큰 클러스터보다 여러 개의 작은 클러스터를 사용하는 것이 + 결함을 격리하는데 더 효과적이다(예를 들면, 클라우드 + 공급자의 다른 가용 영역(availability zone)에 있는 여러 클러스터). +* 확장성: 단일 쿠버네티스 클러스터는 확장성에 한계가 있다(일반적인 + 사용자에게 해당되는 사항은 아니다. 더 자세한 내용: + [쿠버네티스 스케일링 및 성능 목표](https://git.k8s.io/community/sig-scalability/goals.md)). +* [하이브리드 클라우드](#하이브리드-클라우드-역량): 다른 클라우드 공급자나 온-프레미스 데이터 센터에 있는 여러 클러스터를 + 운영할 수 있다. + +### 주의 사항 + +페더레이션에는 매력적인 사례가 많지만, 다소 주의 해야 할 +사항도 있다. + +* 네트워크 대역폭과 비용 증가: 페더레이션 컨트롤 플레인은 모든 클러스터를 + 감시하여 현재 상태가 예정된 상태와 같은지 확인한다. 이것은 클러스터들이 + 한 클라우드 제공자의 여러 다른 지역에서 또는 클라우드 제공자 간에 걸쳐 동작하는 + 경우 상당한 네트워크 비용을 초래할 수 있다. +* 클러스터 간 격리 수준 감소: 페더레이션 컨트롤 플레인에서의 오류는 모든 클러스터에 + 영향을 줄 수 있다. 이것은 페더레이션 컨트롤 플레인의 논리를 최소한으로 + 유지함으로써 완화된다. 페더레이션은 가능한 경우 언제라도 + 쿠버네티스 클러스터에 컨트롤 플레인을 위임한다. 페더레이션은 안전성을 제공하고 + 여러 클러스터의 중단을 방지할 수 있도록 민감하게 설계 및 구현되었다. +* 성숙도: 페더레이션 프로젝트는 상대적으로 신규 프로젝트이고 성숙도가 높지 않다. + 모든 리소스가 이용 가능한 상태는 아니며 많은 리소스가 아직 알파 상태이다. [이슈 + 88](https://github.com/kubernetes/federation/issues/88)은 팀이 해결 + 중에 있는 시스템의 알려진 이슈를 열거하고 있다. + +### 하이브리드 클라우드 역량 + +쿠버네티스 클러스터의 페더레이션은 다른 클라우드 제공자(예를 들어, Google 클라우드, AWS), +그리고 온-프레미스(예를 들어, OpenStack)에서 동작 중인 클러스터를 포함할 수 +있다. [Kubefed](https://kubernetes.io/docs/tasks/federation/set-up-cluster-federation-kubefed/)는 연합된 클러스터 배치에 권장되는 방법이다. + +그 후에, [API 리소스](#api-리소스)는 서로 다른 클러스터와 클라우드 +제공자에 걸쳐 확장될 수 있다. + +## 페더레이션 설치 + +여러 클러스터의 페더레이션 구성을 위해서는, 페더레이션 컨트롤 플레인을 우선적으로 +설치해야 한다. +페더레이션 컨트롤 플레인의 설치를 위해서는 [설치 가이드](/docs/tutorials/federation/set-up-cluster-federation-kubefed/) +를 따른다. + +## API 리소스 + +컨트롤 플레인이 설치되고 나면, 페더레이션 API 리소스 생성을 시작할 수 +있다. +다음의 가이드는 일부 리소스에 대해서 자세히 설명한다. + +* [클러스터](/docs/tasks/administer-federation/cluster/) +* [컨피그 맵](/docs/tasks/administer-federation/configmap/) +* [데몬 셋](/docs/tasks/administer-federation/daemonset/) +* [디플로이먼트](/docs/tasks/administer-federation/deployment/) +* [이벤트](/docs/tasks/administer-federation/events/) +* [Hpa](/docs/tasks/administer-federation/hpa/) +* [인그레스](/docs/tasks/administer-federation/ingress/) +* [잡](/docs/tasks/administer-federation/job/) +* [네임스페이스](/docs/tasks/administer-federation/namespaces/) +* [레플리카 셋](/docs/tasks/administer-federation/replicaset/) +* [시크릿](/docs/tasks/administer-federation/secret/) +* [서비스](/docs/concepts/cluster-administration/federation-service-discovery/) + + +[API 참조 문서](/docs/reference/federation/)는 페더레이션 +apiserver가 지원하는 모든 리소스를 열거한다. + +## 삭제 캐스케이딩(cascading) + +쿠버네티스 버전 1.6은 연합된 리소스에 대한 삭제 캐스케이딩을 +지원한다. 삭제 케스케이딩이 적용된 경우, 페더레이션 컨트롤 플레인에서 +리소스를 삭제하면, 모든 클러스터에서 상응하는 리소스가 삭제된다. + +REST API 사용하는 경우 삭제 캐스케이딩이 기본으로 활성화되지 않는다. 그것을 +활성화하려면, REST API를 사용하여 페더레이션 컨트롤 플레인에서 리소스를 삭제할 때 +`DeleteOptions.orphanDependents=false` 옵션을 설정한다. `kubectl +delete`를 사용하면 +삭제 캐스케이딩이 기본으로 활성화된다. `kubectl +delete --cascade=false`를 실행하여 비활성화할 수 있다. + +참고: 쿠버네티스 버전 1.5는 페더레이션 리소스의 부분 집합에 대한 삭제 +캐스케이딩을 지원하였다. + +## 단일 클러스터의 범위 + +Google Compute Engine 또는 Amazon Web Services와 같은 IaaS 제공자에서는, VM이 +[영역(zone)](https://cloud.google.com/compute/docs/zones) 또는 [가용 영역(availability +zone)](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html)에 존재한다. +다음과 같은 이유로, 쿠버네티스 클러스터의 모든 VM을 동일한 가용 영역에 두는 것을 추천한다. + + - 단일 글로벌 쿠버네티스 클러스터에 비해서, 장애에 대한 단일-포인트가 더 적다. + - 여러 가용 영역에 걸친 클러스터에 비해서, 단일-영역 클러스터의 가용성 속성에 대한 추론이 + 더 쉽다. + - 쿠버네티스 개발자가 시스템을 디자인할 때(예를 들어, 지연 시간, 대역폭, 연관된 장애를 + 고려할 때) 모든 기계가 단일 데이터 센터에 있거나 밀접하게 연결되어 있다고 가정하고 있다. + +가용 영역당 더 많은 VM이 포함되는 적은 수의 클러스터 실행을 추천한다. 다만, 여러 가용 영역 마다 여러 클러스터의 실행도 가능하다. + +가용 영역당 더 적은 수의 클러스터가 선호되는 이유는 다음과 같다. + + - 한 클러스터에 많은 노드가 있는 일부의 경우 파드의 빈 패킹(bin packing)이 향상됨(리소스 단편화 감소). + - 운영 오버헤드 감소(운영 툴과 프로세스의 성숙도에 의해 해당 장점은 반감되는 측면이 있음). + - apiserver VMs와 같이, 클러스터당 비용이 고정된 리소스의 비용을 감소(그러나 중간 규모 부터 큰 규모에 이르는 클러스터의 + 전체 클러스터 비용에 비하면 상대적으로 적은 비용). + +여러 클러스터가 필요한 이유는 다음을 포함한다. + + - 다른 업무의 계층으로부터 특정 계층의 격리가 요구되는 엄격한 보안 정책(다만, 아래의 클러스터 분할하기 정보를 확인하기 + 바람). + - 새로운 쿠버네티스 릴리스 또는 다른 클러스터 소프트웨어를 카나리아(canary) 방식으로 릴리스하기 위해서 클러스터를 테스트. + +## 적절한 클러스터 수 선택하기 + +쿠버네티스 클러스터의 수를 선택하는 것은 상대적으로 고정적인 선택이며, 가끔식만 재고된다. +대조적으로, 클러스터의 노드 수와 서비스 내의 파드 수는 부하와 규모 증가에 따라 +빈번하게 변경될 수 있다. + +클러스터의 수를 선택하기 위해서, 첫 번째로, 쿠버네티스에서 동작할 서비스의 모든 최종 사용자에게 적절한 지연 시간을 제공할 수 있는 지역들을 선택할 +필요가 있다(만약 콘텐츠 전송 네트워크를 사용한다면, CDN-호스트된 콘텐츠의 지연 시간 요구사항 +고려할 필요가 없음). 법적인 이슈 또한 이것에 영향을 줄 수 있다. 예를 들면, 어떤 글로벌 고객 기반의 회사는 US, AP, SA 지역 등 특정 지역에서 클러스터를 운영하도록 결정할 수도 있다. +지역의 수를 `R`이라 부르자. + +두 번째로, 여전히 사용 가능한 상태에서, 얼마나 많은 클러스터가 동시에 사용할 수 없는 상태가 될 수 있는지 결정한다. +사용하지 않는 상태가 될 수 있는 수를 `U`라고 하자. 만약이 값에 확신이 없다면, 1이 괜찮은 선택이다. + +클러스터 장애 상황에서 어느 지역으로든지 직접적인 트래픽에 대한 로드밸런싱이 허용된다면, `R` +또는 적어도 `U + 1` 이상의 클러스터가 있으면 된다. 만약 그렇지 않다면(예를 들어, 클러스터 장애 상황에서 모든 +사용자에 대한 낮은 지연 시간을 유지하고 싶다면), `R * (U + 1)`(각 `R` 지역 내에 `U + 1`) +클러스터가 필요하다. 어느 경우든지, 각 클러스터는 다른 영역에 배치하도록 노력하는 것이 좋다. + +마지막으로, 클러스터 중 어느 클러스터라도 쿠버네티스 클러스터에서 추천되는 최대 노드 수 보다 더 많은 노드가 필요하다면, +더 많은 클러스터가 필요할 것이다. 쿠버네티스 v1.3은 클러스터를 최대 1000노드까지 지원한다. 쿠버네티스 v1.8은 +클러스터를 최대 5000 노드까지 지원한다. 더 자세한 가이드는 [대규모 클러스터 구축하기](/docs/setup/cluster-large/)에서 확인 가능하다. + +{{% /capture %}} + +{{% capture whatsnext %}} +* [페더레이션 + 제안](https://github.com/kubernetes/community/blob/{{< param "githubbranch" >}}/contributors/design-proposals/multicluster/federation.md)에 대해 더 학습하기. +* 클러스터 페더레이션 [설치 가이드](/docs/tutorials/federation/set-up-cluster-federation-kubefed/) 보기. +* [Kubecon2016 페더레이션 발표](https://www.youtube.com/watch?v=pq9lbkmxpS8) 보기 +* [Kubecon2017 유럽 페더레이션 업데이트 내용](https://www.youtube.com/watch?v=kwOvOLnFYck) 보기 +* [Kubecon2018 유럽 sig-multicluster 업데이트 내용](https://www.youtube.com/watch?v=vGZo5DaThQU) 보기 +* [Kubecon2018 유럽 Federation-v2 프로토타입 발표](https://youtu.be/q27rbaX5Jis?t=7m20s) 보기 +* [Federation-v2 사용자 가이드](https://github.com/kubernetes-sigs/federation-v2/blob/master/docs/userguide.md) 보기 +{{% /capture %}} + + + diff --git a/content/ko/docs/concepts/containers/images.md b/content/ko/docs/concepts/containers/images.md index b58d11a08d..a01e11532c 100644 --- a/content/ko/docs/concepts/containers/images.md +++ b/content/ko/docs/concepts/containers/images.md @@ -279,43 +279,17 @@ kubectl create secret docker-registry myregistrykey --docker-server=DOCKER_REGIS secret/myregistrykey created. ``` -만약 다중 레지스트리에 접근이 필요하다면, 각 레지스트리에 대한 하나의 시크릿을 생성할 수 있다. -Kubelet은 파드를 위한 이미지를 풀링할 때 `imagePullSecrets`를 단일의 가상 `.docker/config.json` -에 병합할 것이다. +만약 Docer 자격 증명 파일이 이미 존재한다면, 위의 명령을 사용하지 않고, +자격 증명 파일을 쿠버네티스 시크릿으로 가져올 수 있다. +[기존 Docker 자격 증명으로 시크릿 생성](/docs/tasks/configure-pod-container/pull-image-private-registry/#registry-secret-existing-credentials)에서 관련 방법을 설명하고 있다. +`kubectl create secret docker-registry`는 +하나의 개인 레지스트리에서만 작동하는 시크릿을 생성하기 때문에, +여러 개인 컨테이너 레지스트리를 사용하는 경우 특히 유용하다. +{{< note >}} 파드는 이미지 풀 시크릿을 자신의 네임스페이스에서만 참조할 수 있다. 따라서 이 과정은 네임스페이스 당 한 번만 수행될 필요가 있다. - -##### kubectl create secrets 우회 - -어떤 이유에서 단일 `.docker/config.json`에 여러 항목이 필요하거나 -위의 커맨드를 통해서는 주어지지 않는 제어가 필요한 경우, [json 또는 yaml로 -시크릿 생성](/docs/user-guide/secrets/#creating-a-secret-manually)을 수행할 수 있다. - -다음 사항을 준수해야 한다. - -- `.dockerconfigjson`에 해당 데이터 항목의 이름을 설정 -- Docker 파일을 base64로 인코딩하여 해당 문자열을 붙여넣을 때, - `data[".dockerconfigjson"]` 필드의 값으로써 깨짐 방지 -- `kubernetes.io/dockerconfigjson`에 `type`을 설정 - -예: - -```yaml -apiVersion: v1 -kind: Secret -metadata: - name: myregistrykey - namespace: awesomeapps -data: - .dockerconfigjson: UmVhbGx5IHJlYWxseSByZWVlZWVlZWVlZWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGx5eXl5eXl5eXl5eXl5eXl5eXl5eSBsbGxsbGxsbGxsbGxsbG9vb29vb29vb29vb29vb29vb29vb29vb29vb25ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg== -type: kubernetes.io/dockerconfigjson -``` - - -`error: no objects passed to create`라는 에러 메시지가 나오면, 그것은 base64 인코딩된 문자열이 유효하지 않다는 것을 뜻한다. -`Secret "myregistrykey" is invalid: data[.dockerconfigjson]: invalid value ...`와 유사한 에러 메시지가 나오면, 그것은 -base64 인코딩 된 데이터가 성공적으로 디코딩되었지만, `.docker/config.json` 파일로는 파싱될 수 없었음을 의미한다. +{{< /note >}} #### 파드의 imagePullSecrets 참조 @@ -374,3 +348,6 @@ imagePullSecrets을 셋팅하여 자동화할 수 있다. - 테넌트는 해당 시크릿을 각 네임스페이스의 imagePullSecrets에 추가한다. {{% /capture %}} + +다중 레지스트리에 접근해야 하는 경우, 각 레지스트리에 대해 하나의 시크릿을 생성할 수 있다. +Kubelet은 모든`imagePullSecrets` 파일을 하나의 가상`.docker / config.json` 파일로 병합한다. diff --git a/content/ko/docs/concepts/overview/components.md b/content/ko/docs/concepts/overview/components.md index 717c2e6b29..2c1d161d2d 100644 --- a/content/ko/docs/concepts/overview/components.md +++ b/content/ko/docs/concepts/overview/components.md @@ -2,6 +2,9 @@ title: 쿠버네티스 컴포넌트 content_template: templates/concept weight: 20 +card: + name: concepts + weight: 20 --- {{% capture overview %}} diff --git a/content/ko/docs/concepts/overview/kubernetes-api.md b/content/ko/docs/concepts/overview/kubernetes-api.md index 860cdc003b..d5e93902cf 100644 --- a/content/ko/docs/concepts/overview/kubernetes-api.md +++ b/content/ko/docs/concepts/overview/kubernetes-api.md @@ -2,6 +2,9 @@ title: 쿠버네티스 API content_template: templates/concept weight: 30 +card: + name: concepts + weight: 30 --- {{% capture overview %}} diff --git a/content/ko/docs/concepts/overview/object-management-kubectl/imperative-command.md b/content/ko/docs/concepts/overview/object-management-kubectl/imperative-command.md new file mode 100644 index 0000000000..228363911b --- /dev/null +++ b/content/ko/docs/concepts/overview/object-management-kubectl/imperative-command.md @@ -0,0 +1,162 @@ +--- +title: 명령형 커맨드를 이용한 쿠버네티스 오브젝트 관리하기 +content_template: templates/concept +weight: 20 +--- + +{{% capture overview %}} +쿠버네티스 오브젝트는 `kubectl` 커맨드 라인 툴 속에 내장된 명령형 커맨드를 이용함으로써 +바로 신속하게 생성, 업데이트 및 삭제할 수 있다. 이 문서는 어떻게 커맨드가 구성되어 있으며, +이를 사용하여 활성 오브젝트를 어떻게 관리하는 지에 대해 설명한다. +{{% /capture %}} + +{{% capture body %}} + +## 트레이드 오프 + +`kubectl`툴은 3가지 종류의 오브젝트 관리를 지원한다. + +* 명령형 커맨드 +* 명령형 오브젝트 구성 +* 선언형 오브젝트 구성 + +각 종류별 오브젝트 관리의 장점과 단점에 대한 논의는 [쿠버네티스 오브젝트 관리](/ko/docs/concepts/overview/object-management-kubectl/overview/) +를 참고한다. + +## 오브젝트 생성 방법 + +`kubectl` 툴은 가장 일반적인 오브젝트 타입을 생성하는데 동사 형태 기반의 커맨드를 +지원한다. 쿠버네티스 오브젝트 타입에 익숙하지 않은 사용자가 인지할 수 있도록 커맨드 +이름이 지어졌다. + +- `run`: 하나 이상의 파드 내 컨테이너를 실행하도록 새로운 디플로이먼트 오브젝트를 생성한다. +- `expose`: 파드에 걸쳐 트래픽을 로드 밸런스하도록 새로운 서비스 오브젝트를 생성한다. +- `autoscale`: 디플로이먼트와 같이, 하나의 컨트롤러에 대해 자동으로 수평적 스케일이 이루어 지도록 새로운 Autoscaler 오브젝트를 생성한다. + +또한 `kubectl` 툴은 오브젝트 타입에 의해 구동되는 생성 커맨드를 지원한다. +이러한 커맨드는 더 많은 오브젝트 타입을 지원해주며 그 의도하는 바에 대해 +보다 명확하게 해주지만, 사용자가 생성하고자 하는 오브젝트 타입에 대해 +알 수 있도록 해야 한다. + +- `create <오브젝트 타입> [<서브 타입>] <인스턴스명>` + +일부 오브젝트 타입은 `create` 커맨드 내 정의할 수 있는 서브 타입을 가진다. +예를 들어, 서비스 오브젝트는 ClusterIP, LoadBalancer 및 NodePort 등을 +포함하는 여러 서브 타입을 가진다, 다음은 NodePort 서브 타입을 통해 서비스를 +생성하는 예제이다. + +```shell +kubectl create service nodeport <사용자 서비스 명칭> +``` + +이전 예제에서, `create service nodeport` 커맨드는 +`create service` 커맨드의 서브 커맨드라고 칭한다. + +`-h` 플래그를 사용하여 서브 커맨드에 의해 지원되는 인수 및 플래그를 +찾아 볼 수 있다. + +```shell +kubectl create service nodeport -h +``` + +## 오브젝트 업데이트 방법 + +`kubectl` 커맨드는 일반적인 몇몇의 업데이트 작업을 위해 동사 형태 기반의 커맨드를 지원한다. +이 커맨드는 쿠버네티스 오브젝트에 익숙하지 않은 사용자가 설정되어야 +하는 특정 필드를 모르는 상태에서도 업데이트를 수행할 수 있도록 +이름 지어졌다. + +- `scale`: 컨트롤러의 레플리카 수를 업데이트 함으로써 파드를 추가 또는 제거하는 컨트롤러를 수평적으로 스케일한다. +- `annotate`: 오브젝트로부터 어노테이션을 추가 또는 제거한다. +- `label`: 오브젝트에서 레이블을 추가 또는 제거한다. + +`kubectl` 커맨드는 또한 오브젝트 측면에서 구동되는 업데이트 커맨드를 지원한다. +이 측면의 설정은 다른 오브젝트 타입에 대한 다른 필드를 설정 할 수도 있다. + +- `set` ``: 오브젝트의 측면을 설정한다. + +{{< note >}} +쿠버네티스 1.5 버전에서는 모든 동사 형태 기반의 커맨드가 관련된 측면 중심의 커맨드를 가지는 것은 아니다. +{{< /note >}} + +`kubectl` 툴은 활성 오브젝트를 직접 업데이트하기 위해 추가적인 방법을 지원하지만, +쿠버네티스 오브젝트 스키마에 대한 추가적인 이해를 요구한다. + +- `edit`: 편집기에서 구성을 열어 활성 오브젝트에 대한 원래 그대로의 구성을 바로 편집한다. +- `patch`: 패치 문자열를 사용하여 활성 오브젝트를 바로 편집한다. +패치 문자열에 대한 보다 자세한 정보를 보려면 +[API 규정](https://git.k8s.io/community/contributors/devel/api-conventions.md#patch-operations)에서 패치 섹션을 참고한다. + +## 오브젝트 삭제 방법 + +클러스터에서 오브젝트를 삭제하기 위해 `delete` 커맨드을 사용할 수 있다. + +- `delete <타입>/<이름>` + +{{< note >}} +명령형 커맨드와 명령형 오브젝트 구성 모두 `kubectl delete`를 사용할 수 +있다. 차이점은 커맨드에 전해지는 인수에 있다. 명령형 커맨드로 +`kubectl delete`을 사용하기 위해, 삭제할 오브젝트를 인수로 전한다. +다음은 nginx라는 디플로이먼트 오브젝트를 전하는 예제이다. +{{< /note >}} + +```shell +kubectl delete deployment/nginx +``` + +## 오브젝트 확인 방법 + +{{< comment >}} +TODO(pwittrock): 구현이 이루어지면 주석을 해제한다. + +오브젝트의 특정 필드를 출력하기 위해 `kubectl view`를 사용할 수 있다. + +- `view`: 오브젝트의 특정 필드의 값을 출력한다. + +{{< /comment >}} + + + +오브젝트에 대한 정보를 출력하는 몇 가지 커맨드가 있다. + +- `get`: 일치하는 오브젝트에 대한 기본 정보를 출력한다. 옵션 리스트를 확인하기 위해 `get -h`를 사용한다. +- `describe`: 일치하는 오브젝트에 대해 수집한 상세한 정보를 출력한다. +- `logs`: 파드에서 실행 중인 컨테이너에 대한 stdout과 stderr를 출력한다. + +## 생성 전 오브젝트 수정을 위해 `set` 커맨드 사용하기 + +`create` 커맨드에 사용할 수 있는 플래그가 없는 몇 가지 오브젝트 +필드가 있다. 이러한 경우, 오브젝트 생성 전에 필드에 대한 값을 +정의하기 위해 `set`과 `create`을 조합해서 사용할 수 있다. +이는 `set` 커맨드에 `create` 커맨드의 출력을 파이프 함으로써 수행할 수 있다. +다음은 관련 예제이다. + +```sh +kubectl create service clusterip my-svc --clusterip="None" -o yaml --dry-run | kubectl set selector --local -f - 'environment=qa' -o yaml | kubectl create -f - +``` + +1. `kubectl create service -o yaml --dry-run` 커맨드는 서비스에 대한 구성을 생성하지만, 이를 쿠버네티스 API 서버에 전송하는 대신 YAML 형식으로 stdout에 출력한다. +1. `kubectl set selector --local -f - -o yaml` 커맨드는 stdin으로부터 구성을 읽어, YAML 형식으로 stdout에 업데이트된 구성을 기록한다. +1. `kubectl create -f -` 커맨드는 stdin을 통해 제공된 구성을 사용하여 오브젝트를 생성한다. + +## 생성 전 오브젝트 수정을 위해 `--edit` 사용하기 + +생성 전에 오브젝트에 임의의 변경을 가하기 위해 `kubectl create --edit` 을 사용할 수 있다. +다음은 관련 예제이다. + +```sh +kubectl create service clusterip my-svc --clusterip="None" -o yaml --dry-run > /tmp/srv.yaml +kubectl create --edit -f /tmp/srv.yaml +``` + +1. `kubectl create service` 커맨드는 서비스에 대한 구성을 생성하고 이를 `/tmp/srv.yaml`에 저장한다. +1. `kubectl create --edit` 커맨드는 오브젝트를 생성하기 전에 편집을 위해 구성파일을 열어준다. + +{{% /capture %}} + +{{% capture whatsnext %}} +- [오브젝트 구성을 이용하여 쿠베네티스 관리하기(명령형)](/docs/concepts/overview/object-management-kubectl/imperative-config/) +- [오브젝트 구성을 이용하여 쿠버네티스 관리하기(선언형)](/docs/concepts/overview/object-management-kubectl/declarative-config/) +- [Kubectl 커맨드 참조](/docs/reference/generated/kubectl/kubectl/) +- [쿠버네티스 API 참조](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/) +{{% /capture %}} \ No newline at end of file diff --git a/content/ko/docs/concepts/overview/what-is-kubernetes.md b/content/ko/docs/concepts/overview/what-is-kubernetes.md index e507e8540e..8d69e47990 100644 --- a/content/ko/docs/concepts/overview/what-is-kubernetes.md +++ b/content/ko/docs/concepts/overview/what-is-kubernetes.md @@ -2,6 +2,9 @@ title: 쿠버네티스란 무엇인가? content_template: templates/concept weight: 10 +card: + name: concepts + weight: 10 --- {{% capture overview %}} @@ -104,7 +107,7 @@ A에서 C로 어떻게 갔는지는 상관이 없다. 중앙화된 제어도 필 ![Why Containers?](/images/docs/why_containers.svg) -애플리케이션을 배포하는 *구식의 방법* 은 운영 체제의 패키지 관리자를 +애플리케이션을 배포하는 *옛 방식* 은 운영 체제의 패키지 관리자를 사용해서 애플리케이션을 호스트에 설치하는 것이었다. 이 방식은 애플리케이션의 실행 파일, 설정, 라이브러리 서로 간의 라이프사이클과 호스트 OS와 얽히게 된다는 단점이 있다. 예측 가능한 롤아웃과 롤백을 diff --git a/content/ko/docs/concepts/overview/working-with-objects/kubernetes-objects.md b/content/ko/docs/concepts/overview/working-with-objects/kubernetes-objects.md index 02f081bde9..6be2c9212d 100644 --- a/content/ko/docs/concepts/overview/working-with-objects/kubernetes-objects.md +++ b/content/ko/docs/concepts/overview/working-with-objects/kubernetes-objects.md @@ -2,6 +2,9 @@ title: 쿠버네티스 오브젝트 이해하기 content_template: templates/concept weight: 10 +card: + name: concepts + weight: 40 --- {{% capture overview %}} @@ -21,7 +24,7 @@ weight: 10 생성이든, 수정이든, 또는 삭제든 쿠버네티스 오브젝트를 동작시키려면, [Kubernetes API](/docs/concepts/overview/kubernetes-api/)를 이용해야 한다. 예를 들어, `kubectl` 커맨드-라인 인터페이스를 이용할 때, CLI는 여러분 대신 필요한 쿠버네티스 API를 호출해 준다. 또한, 여러분은 [Client Libraries](/docs/reference/using-api/client-libraries/) 중 하나를 이용하여 여러분만의 프로그램에서 쿠버네티스 API를 직접 이용할 수도 있다. -### 오브젝트 (spec)과 상태(status) +### 오브젝트 스펙(spec)과 상태(status) 모든 쿠버네티스 오브젝트는 오브젝트의 구성을 결정해주는 두 개의 중첩된 오브젝트 필드를 포함하는데 오브젝트 *spec* 과 오브젝트 *status* 가 그것이다. 필히 제공되어야만 하는 *spec* 은, 여러분이 오브젝트가 가졌으면 하고 원하는 특징, 즉 *의도한 상태* 를 기술한다. *status* 는 오브젝트의 *실제 상태* 를 기술하고, 쿠버네티스 시스템에 의해 제공되고 업데이트 된다. 주어진 임의의 시간에, 쿠버네티스 컨트롤 플레인은 오브젝트의 실제 상태를 여러분이 제시한 의도한 상태에 일치시키기 위해 능동적으로 관리한다. diff --git a/content/ko/docs/concepts/workloads/pods/pod-overview.md b/content/ko/docs/concepts/workloads/pods/pod-overview.md index 3af57fe0cc..416f3983eb 100644 --- a/content/ko/docs/concepts/workloads/pods/pod-overview.md +++ b/content/ko/docs/concepts/workloads/pods/pod-overview.md @@ -2,6 +2,9 @@ title: 파드(Pod) 개요 content_template: templates/concept weight: 10 +card: + name: concepts + weight: 60 --- {{% capture overview %}} diff --git a/content/ko/docs/home/_index.md b/content/ko/docs/home/_index.md index d418be6fb8..a2a01163ae 100644 --- a/content/ko/docs/home/_index.md +++ b/content/ko/docs/home/_index.md @@ -1,8 +1,9 @@ --- title: 쿠버네티스 문서 -noedit: true +noedit: true cid: docsHome layout: docsportal_home +class: gridPage linkTitle: "홈" main_menu: true weight: 10 @@ -13,4 +14,43 @@ menu: weight: 20 post: >

개념, 튜토리얼 및 참조 문서와 함께 쿠버네티스 사용하는 방법을 익힐 수 있다. 또한, 문서에 기여하는 것도 도움을 줄 수 있다!

+overview: > + 쿠버네티스는 배포, 스케일링, 그리고 컨테이너화된 애플리케이션의 관리를 자동화 해주는 오픈 소스 컨테이너 오케스트레이션 엔진이다. 본 오픈 소스 프로젝트는 Cloud Native Computing Foundation(CNCF)가 주관한다. +cards: +- name: concepts + title: "기초 이해하기" + description: "쿠버네티스와 쿠버네티스의 기본 개념을 배운다." + button: "개념 배우기" + button_path: "/docs/concepts" +- name: tutorials + title: "쿠버네티스 사용해보기" + description: "쿠버네티스에 애플리케이션을 배포하는 방법을 튜토리얼을 따라하며 배운다." + button: "튜토리얼 보기" + button_path: "/docs/tutorials" +- name: setup + title: "클러스터 구축하기" + description: "보유한 자원과 요구에 맞게 동작하는 쿠버네티스를 구축한다." + button: "쿠버네티스 구축하기" + button_path: "/docs/setup" +- name: tasks + title: "쿠버네티스 사용법 배우기" + description: "일반적인 태스크와 이를 수행하는 방법을 여러 단계로 구성된 짧은 시퀀스를 통해 살펴본다." + button: "태스크 보기" + button_path: "/docs/tasks" +- name: reference + title: 레퍼런스 정보 찾기 + description: 용어, 커맨드 라인 구문, API 자원 종류, 그리고 설치 툴 문서를 살펴본다. + button: 레퍼런스 보기 + button_path: /docs/reference +- name: contribute + title: 문서에 기여하기 + description: 이 프로젝트가 처음인 사람이든, 오래 활동한 사람이든 상관없이 누구나 기여할 수 있다. + button: 문서에 기여하기 + button_path: /docs/contribute +- name: download + title: 쿠버네티스 내려받기 + description: 쿠버네티스를 설치하거나 최신의 버전으로 업그레이드하는 경우, 현재 릴리스 노트를 참고한다. +- name: about + title: 문서에 대하여 + description: 이 웹사이트는 현재 버전과 이전 4개 버전의 쿠버네티스 문서를 포함한다. --- diff --git a/content/ko/docs/reference/glossary/index.md b/content/ko/docs/reference/glossary/index.md index d462206f54..c7a4b3a927 100755 --- a/content/ko/docs/reference/glossary/index.md +++ b/content/ko/docs/reference/glossary/index.md @@ -4,5 +4,9 @@ layout: glossary noedit: true default_active_tag: fundamental weight: 5 +card: + name: reference + weight: 10 + title: Glossary --- diff --git a/content/ko/docs/setup/cri.md b/content/ko/docs/setup/cri.md index af367d0852..f60582c985 100644 --- a/content/ko/docs/setup/cri.md +++ b/content/ko/docs/setup/cri.md @@ -4,33 +4,42 @@ content_template: templates/concept weight: 100 --- {{% capture overview %}} -v1.6.0에서부터, 쿠버네티스는 CRI(컨테이너 런타임 인터페이스) 사용을 기본으로 지원한다. +{{< feature-state for_k8s_version="v1.6" state="stable" >}} +파드에서 컨테이너를 실행하기 위해 쿠버네티스는 컨테이너 런타임을 사용한다. 이 페이지는 다양한 런타임들에 대한 설치 지침을 담고 있다. {{% /capture %}} {{% capture body %}} -다음의 커맨드들은 사용자의 운영체제에 따라 root로서 실행하길 바란다. -각 호스트에 SSH 접속 후 `sudo -i` 실행을 통해서 root 사용자가 될 수 있을 것이다. - {{< caution >}} -A flaw was found in the way runc handled system file descriptors when running containers. -A malicious container could use this flaw to overwrite contents of the runc binary and -consequently run arbitrary commands on the container host system. +컨테이너를 실행할 때 runc가 시스템 파일 디스크립터를 처리하는 방식에서 결함이 발견되었다. +악성 컨테이너는 이 결함을 사용하여 runc 바이너리의 내용을 덮어쓸 수 있으며 +따라서 컨테이너 호스트 시스템에서 임의의 명령을 실행할 수 있다. -Please refer to this link for more information about this issue -[cve-2019-5736 : runc vulnerability ] (https://access.redhat.com/security/cve/cve-2019-5736) +이 문제에 대한 자세한 내용은 +[cve-2019-5736 : runc 취약점 ] (https://access.redhat.com/security/cve/cve-2019-5736) 참고하자. {{< /caution >}} -## Cgroup 드라이버 +### 적용 가능성 -Linux 배포판의 init 시스템이 systemd인 경우, init 프로세스는 루트 cgroup을 생성 및 사용하고 -cgroup 관리자로 작동한다. Systemd는 cgroup과의 긴밀한 통합을 통해 -프로세스당 cgroup을 할당한다. 컨테이너 런타임과 kubelet이 -`cgroupfs`를 사용하도록 설정할 수 있다. 이 경우는 두 개의 서로 다른 cgroup 관리자가 존재하게 된다는 뜻이다. +{{< note >}} +이 문서는 Linux에 CRI를 설치하는 사용자를 위해 작성되었다. +다른 운영 체제의 경우, 해당 플랫폼과 관련된 문서를 찾아보자. +{{< /note >}} -Cgroup은 프로세스에 할당된 리소스를 제한하는데 사용된다. +이 가이드의 모든 명령은 `root`로 실행해야 한다. +예를 들어,`sudo`로 접두사를 붙이거나, `root` 사용자가 되어 명령을 실행한다. + +### Cgroup 드라이버 + +Linux 배포판의 init 시스템이 systemd인 경우, init 프로세스는 +root control group(`cgroup`)을 생성 및 사용하는 cgroup 관리자로 작동한다. +Systemd는 cgroup과의 긴밀한 통합을 통해 프로세스당 cgroup을 할당한다. +컨테이너 런타임과 kubelet이 `cgroupfs`를 사용하도록 설정할 수 있다. +systemd와 함께`cgroupfs`를 사용하면 두 개의 서로 다른 cgroup 관리자가 존재하게 된다는 뜻이다. + +Control group은 프로세스에 할당된 리소스를 제한하는데 사용된다. 단일 cgroup 관리자는 할당된 리소스가 무엇인지를 단순화하고, 기본적으로 사용가능한 리소스와 사용중인 리소스를 일관성있게 볼 수 있다. 관리자가 두 개인 경우, 이런 리소스도 두 개의 관점에서 보게 된다. kubelet과 Docker는 diff --git a/content/ko/docs/setup/multiple-zones.md b/content/ko/docs/setup/multiple-zones.md index b2360a9fe2..679a55f5ef 100644 --- a/content/ko/docs/setup/multiple-zones.md +++ b/content/ko/docs/setup/multiple-zones.md @@ -1,8 +1,17 @@ --- title: 여러 영역에서 구동 weight: 90 +content_template: templates/concept --- +{{% capture overview %}} + +이 페이지는 여러 영역에서 어떻게 클러스터를 구동하는지 설명한다. + +{{% /capture %}} + +{{% capture body %}} + ## 소개 Kubernetes 1.2 adds support for running a single cluster in multiple failure zones @@ -23,8 +32,6 @@ add similar support for other clouds or even bare metal, by simply arranging for the appropriate labels to be added to nodes and volumes). -{{< toc >}} - ## 기능 When nodes are started, the kubelet automatically adds labels to them with @@ -118,9 +125,12 @@ labels are `failure-domain.beta.kubernetes.io/region` for the region, and `failure-domain.beta.kubernetes.io/zone` for the zone: ```shell -> kubectl get nodes --show-labels +kubectl get nodes --show-labels +``` +The output is similar to this: +```shell NAME STATUS ROLES AGE VERSION LABELS kubernetes-master Ready,SchedulingDisabled 6m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-1,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-master kubernetes-minion-87j9 Ready 6m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-87j9 @@ -154,8 +164,12 @@ View the nodes again; 3 more nodes should have launched and be tagged in us-central1-b: ```shell -> kubectl get nodes --show-labels +kubectl get nodes --show-labels +``` +The output is similar to this: + +```shell NAME STATUS ROLES AGE VERSION LABELS kubernetes-master Ready,SchedulingDisabled 16m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-1,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-master kubernetes-minion-281d Ready 2m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-281d @@ -207,7 +221,12 @@ was addressed in 1.3+. Now let's validate that Kubernetes automatically labeled the zone & region the PV was created in. ```shell -> kubectl get pv --show-labels +kubectl get pv --show-labels +``` + +The output is similar to this: + +```shell NAME CAPACITY ACCESSMODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE LABELS pv-gce-mj4gm 5Gi RWO Retain Bound default/claim1 manual 46s failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a ``` @@ -240,9 +259,20 @@ Note that the pod was automatically created in the same zone as the volume, as cross-zone attachments are not generally permitted by cloud providers: ```shell -> kubectl describe pod mypod | grep Node +kubectl describe pod mypod | grep Node +``` + +```shell Node: kubernetes-minion-9vlv/10.240.0.5 -> kubectl get node kubernetes-minion-9vlv --show-labels +``` + +And check node labels: + +```shell +kubectl get node kubernetes-minion-9vlv --show-labels +``` + +```shell NAME STATUS AGE VERSION LABELS kubernetes-minion-9vlv Ready 22m v1.6.0+fff5156 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv ``` @@ -279,12 +309,20 @@ find kubernetes/examples/guestbook-go/ -name '*.json' | xargs -I {} kubectl crea The pods should be spread across all 3 zones: ```shell -> kubectl describe pod -l app=guestbook | grep Node +kubectl describe pod -l app=guestbook | grep Node +``` + +```shell Node: kubernetes-minion-9vlv/10.240.0.5 Node: kubernetes-minion-281d/10.240.0.8 Node: kubernetes-minion-olsh/10.240.0.11 +``` - > kubectl get node kubernetes-minion-9vlv kubernetes-minion-281d kubernetes-minion-olsh --show-labels +```shell +kubectl get node kubernetes-minion-9vlv kubernetes-minion-281d kubernetes-minion-olsh --show-labels +``` + +```shell NAME STATUS ROLES AGE VERSION LABELS kubernetes-minion-9vlv Ready 34m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv kubernetes-minion-281d Ready 20m v1.13.0 beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-b,kubernetes.io/hostname=kubernetes-minion-281d @@ -296,15 +334,42 @@ Load-balancers span all zones in a cluster; the guestbook-go example includes an example load-balanced service: ```shell -> kubectl describe service guestbook | grep LoadBalancer.Ingress +kubectl describe service guestbook | grep LoadBalancer.Ingress +``` + +The output is similar to this: + +```shell LoadBalancer Ingress: 130.211.126.21 +``` -> ip=130.211.126.21 +Set the above IP: -> curl -s http://${ip}:3000/env | grep HOSTNAME +```shell +export IP=130.211.126.21 +``` + +Explore with curl via IP: + +```shell +curl -s http://${IP}:3000/env | grep HOSTNAME +``` + +The output is similar to this: + +```shell "HOSTNAME": "guestbook-44sep", +``` -> (for i in `seq 20`; do curl -s http://${ip}:3000/env | grep HOSTNAME; done) | sort | uniq +Again, explore multiple times: + +```shell +(for i in `seq 20`; do curl -s http://${IP}:3000/env | grep HOSTNAME; done) | sort | uniq +``` + +The output is similar to this: + +```shell "HOSTNAME": "guestbook-44sep", "HOSTNAME": "guestbook-hum5n", "HOSTNAME": "guestbook-ppm40", @@ -331,3 +396,5 @@ KUBERNETES_PROVIDER=aws KUBE_USE_EXISTING_MASTER=true KUBE_AWS_ZONE=us-west-2c k KUBERNETES_PROVIDER=aws KUBE_USE_EXISTING_MASTER=true KUBE_AWS_ZONE=us-west-2b kubernetes/cluster/kube-down.sh KUBERNETES_PROVIDER=aws KUBE_AWS_ZONE=us-west-2a kubernetes/cluster/kube-down.sh ``` + +{{% /capture %}} diff --git a/content/ko/docs/setup/pick-right-solution.md b/content/ko/docs/setup/pick-right-solution.md index bf49e04cab..b6c60fd84a 100644 --- a/content/ko/docs/setup/pick-right-solution.md +++ b/content/ko/docs/setup/pick-right-solution.md @@ -2,6 +2,20 @@ title: 알맞은 솔루션 선정 weight: 10 content_template: templates/concept +card: + name: setup + weight: 20 + anchors: + - anchor: "#호스트-된-솔루션" + title: 호스트 된 솔루션 + - anchor: "#턴키-클라우드-솔루션" + title: 턴키 클라우드 솔루션 + - anchor: "#온-프레미스-턴키-클라우드-솔루션" + title: 온-프레미스 솔루션 + - anchor: "#사용자-지정-솔루션" + title: 사용자 지정 솔루션 + - anchor: "#로컬-머신-솔루션" + title: 로컬 머신 --- {{% capture overview %}} diff --git a/content/ko/docs/setup/release/building-from-source.md b/content/ko/docs/setup/release/building-from-source.md index 5320056d08..d8b9af438f 100644 --- a/content/ko/docs/setup/release/building-from-source.md +++ b/content/ko/docs/setup/release/building-from-source.md @@ -1,6 +1,10 @@ --- title: 릴리스 빌드 content_template: templates/concept +card: + name: download + weight: 20 + title: 릴리스 빌드하기 --- {{% capture overview %}} diff --git a/content/ko/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough.md b/content/ko/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough.md index c402d2740d..61884a8829 100644 --- a/content/ko/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough.md +++ b/content/ko/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough.md @@ -243,7 +243,7 @@ spec: resource: name: cpu target: - kind: AverageUtilization + type: AverageUtilization averageUtilization: 50 - type: Pods pods: diff --git a/content/ko/docs/tasks/tools/install-minikube.md b/content/ko/docs/tasks/tools/install-minikube.md index 1fd805533a..038851b475 100644 --- a/content/ko/docs/tasks/tools/install-minikube.md +++ b/content/ko/docs/tasks/tools/install-minikube.md @@ -2,6 +2,9 @@ title: Minikube 설치 content_template: templates/task weight: 20 +card: + name: tasks + weight: 10 --- {{% capture overview %}} diff --git a/content/ko/docs/tutorials/hello-minikube.md b/content/ko/docs/tutorials/hello-minikube.md index 0a00e5e5d0..e6269333d1 100644 --- a/content/ko/docs/tutorials/hello-minikube.md +++ b/content/ko/docs/tutorials/hello-minikube.md @@ -8,6 +8,9 @@ menu: weight: 10 post: >

Ready to get your hands dirty? Build a simple Kubernetes cluster that runs "Hello World" for Node.js.

+card: + name: tutorials + weight: 10 --- {{% capture overview %}} diff --git a/content/ko/docs/tutorials/kubernetes-basics/_index.html b/content/ko/docs/tutorials/kubernetes-basics/_index.html index ff57ddc2d3..1f9659628a 100644 --- a/content/ko/docs/tutorials/kubernetes-basics/_index.html +++ b/content/ko/docs/tutorials/kubernetes-basics/_index.html @@ -2,6 +2,10 @@ title: 쿠버네티스 기초 학습 linkTitle: 쿠버네티스 기초 학습 weight: 10 +card: + name: tutorials + weight: 20 + title: 쿠버네티스 기초 학습 --- diff --git a/content/ko/docs/tutorials/online-training/overview.md b/content/ko/docs/tutorials/online-training/overview.md index d3a41008fe..d2e9da7f48 100644 --- a/content/ko/docs/tutorials/online-training/overview.md +++ b/content/ko/docs/tutorials/online-training/overview.md @@ -17,6 +17,8 @@ content_template: templates/concept * [Google Kubernetes Engine 시작하기 (Coursera)](https://www.coursera.org/learn/google-kubernetes-engine) +* [Google Kubernetes Engine Deep Dive (Linux Academy)](https://linuxacademy.com/google-cloud-platform/training/course/name/google-kubernetes-engine-deep-dive) + * [쿠버네티스 시작하기 (Pluralsight)](https://www.pluralsight.com/courses/getting-started-kubernetes) * [쿠버네티스 소개 및 실습 (Instruqt)](https://play.instruqt.com/public/topics/getting-started-with-kubernetes) @@ -25,12 +27,20 @@ content_template: templates/concept * [쿠버네티스 소개 (edX)](https://www.edx.org/course/introduction-kubernetes-linuxfoundationx-lfs158x) +* [Kubernetes Essentials (Linux Academy)](https://linuxacademy.com/linux/training/course/name/kubernetes-essentials) + * [초보자를 위한 쿠버네티스 실습 랩 (KodeKloud.com)](https://kodekloud.com/p/kubernetes-for-the-absolute-beginners-hands-on) +* [Kubernetes Quick Start (Linux Academy)] (https://linuxacademy.com/linux/training/course/name/kubernetes-quick-start) + * [쿠버네티스 심화 학습 (LinuxAcademy.com)](https://linuxacademy.com/linux/training/course/name/kubernetes-the-hard-way) * [대화식 실습 시나리오를 사용하여 쿠버네티스 배우기 (Katacoda)](https://www.katacoda.com/courses/kubernetes/) +* [Monitoring Kubernetes With Prometheus (Linux Academy)] (https://linuxacademy.com/linux/training/course/name/kubernetes-and-prometheus) + * [쿠버네티스와 확장 가능한 마이크로서비스(Microservices) (Udacity)](https://www.udacity.com/course/scalable-microservices-with-kubernetes--ud615) +* [Self-paced Kubernetes online course (Learnk8s Academy)](https://learnk8s.io/academy) + {{% /capture %}} diff --git a/content/ko/docs/tutorials/stateful-application/basic-stateful-set.md b/content/ko/docs/tutorials/stateful-application/basic-stateful-set.md new file mode 100644 index 0000000000..4c80d9c805 --- /dev/null +++ b/content/ko/docs/tutorials/stateful-application/basic-stateful-set.md @@ -0,0 +1,1038 @@ +--- +reviewers: +title: 스테이트풀셋 기본 +content_template: templates/tutorial +weight: 10 +--- + +{{% capture overview %}} +이 튜토리얼은 스테이트풀셋([StatefulSets](/docs/concepts/workloads/controllers/statefulset/))을 이용하여 +애플리케이션을 관리하는 방법을 소개한다. 어떻게 스테이트풀셋의 파드(Pod)을 생성하고 삭제하며 +스케일링하고 업데이트하는지 시연한다. +{{% /capture %}} + +{{% capture prerequisites %}} +튜토리얼을 시작하기 전에 다음의 쿠버네티스 컨셉에 대해 +익숙해야 한다. + +* [파드](/docs/user-guide/pods/single-container/) +* [클러스터 DNS(Cluster DNS)](/docs/concepts/services-networking/dns-pod-service/) +* [헤드리스 서비스(Headless Services)](/docs/concepts/services-networking/service/#headless-services) +* [퍼시스턴트볼륨(PersistentVolumes)](/docs/concepts/storage/persistent-volumes/) +* [퍼시턴트볼륨 프로비저닝](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/persistent-volume-provisioning/) +* [스테이트풀셋](/docs/concepts/workloads/controllers/statefulset/) +* [kubectl CLI](/docs/user-guide/kubectl/) + +이 튜토리얼은 클러스터가 퍼시스턴스볼륨을 동적으로 프로비저닝 하도록 +설정되었다고 가정한다. 만약 클러스터가 이렇게 설정되어 있지 않다면, +튜토리얼 시작 전에 수동으로 2개의 1 GiB 볼륨을 +프로비저닝해야 한다. +{{% /capture %}} + +{{% capture objectives %}} +스테이트풀셋은 상태 유지가 필요한(stateful) 애플리케이션과 분산시스템에서 +이용하도록 의도했다. 그러나 쿠버네티스 상에 스테이트풀 애플리케이션과 +분산시스템을 관리하는 것은 광범위하고 복잡한 주제이다. 스테이트풀셋의 기본 기능을 보여주기 위해 +이 둘을 결합하지 않고, 스테이트풀셋을 사용한 +단순 웹 애플리케이션을 배포할 것이다. + +이 튜토리얼을 마치면 다음 항목에 대해 익숙해질 것이다. + +* 스테이트풀셋을 어떻게 생성하는지 +* 스테이트풀셋이 어떻게 파드를 관리하는지 +* 스테이트풀셋을 어떻게 삭제하는지 +* 스테이트풀셋은 어떻게 스케일링하는지 +* 스테이트풀셋의 파드는 어떻게 업데이트하는지 +{{% /capture %}} + +{{% capture lessoncontent %}} +## 스테이트풀셋 생성하기 + +아래 예제를 이용해서 스테이트풀셋을 생성하자. 이는 +[스테이트풀셋](/docs/concepts/workloads/controllers/statefulset/) 개념에서 보인 +예제와 유사하다. 이것은 `web`과 이 스테이트풀셋 파드의 IP 주소를 게시하는 +[헤드리스 서비스](/docs/concepts/services-networking/service/#headless-services)인 +`nginx` 를 생성한다. + +{{< codenew file="application/web/web.yaml" >}} + +위에 예제를 다운로드 받아서 파일이름을 `web.yaml`으로 저장하자. + +2개의 터미널창을 사용한다. 첫째 터미널에서 +[`kubectl get`](/docs/reference/generated/kubectl/kubectl-commands/#get)을 이용해서 +스테이트풀셋의 파드가 생성되는지 감시하자. + +```shell +kubectl get pods -w -l app=nginx +``` + +두번째 터미널에서 +[`kubectl create`](/docs/reference/generated/kubectl/kubectl-commands/#create)로 +`web.yaml`에 정의된 헤드리스 서비스와 스테이트풀셋을 생성한다. + +```shell +kubectl create -f web.yaml +service/nginx created +statefulset.apps/web created +``` + +상기 명령어는 [NGINX](https://www.nginx.com) 웹 서버를 +실행하는 2개의 파드를 생성한다. `nginx` 서비스와 +`web` 스테이트풀셋이 성공적으로 생성되었는지 알아보자. + +```shell +kubectl get service nginx +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +nginx ClusterIP None 80/TCP 12s + +kubectl get statefulset web +NAME DESIRED CURRENT AGE +web 2 1 20s +``` + +### 차례대로 파드 생성하기 + +N개의 레플리카를 가진 스테이트풀셋은 배포시에 +순차적으로 {0..N-1} 순으로 생성된다. +첫째 터미널에서 `kubectl get` 명령의 출력 내용을 살펴보자. +결국 그 내용은 아래 예와 비슷할 것이다. + +```shell +kubectl get pods -w -l app=nginx +NAME READY STATUS RESTARTS AGE +web-0 0/1 Pending 0 0s +web-0 0/1 Pending 0 0s +web-0 0/1 ContainerCreating 0 0s +web-0 1/1 Running 0 19s +web-1 0/1 Pending 0 0s +web-1 0/1 Pending 0 0s +web-1 0/1 ContainerCreating 0 0s +web-1 1/1 Running 0 18s +``` + +`web-1` 파드는 `web-0` 파드가 [Running과 Ready](/docs/user-guide/pod-states) 상태가 되기 전에 +시작하지 않음을 주의하자. + +## 스테이트풀셋 안에 파드 + +스테이트풀셋 안에 파드는 고유한 순번과 동일한 네트워크 신원을 가진다. + +### 파드 순번 살펴보기 + +스테이트풀셋의 파드를 가져오자. + +```shell +kubectl get pods -l app=nginx +NAME READY STATUS RESTARTS AGE +web-0 1/1 Running 0 1m +web-1 1/1 Running 0 1m + +``` + +[스테이트풀셋](/docs/concepts/workloads/controllers/statefulset/) 개념에서 +언급했듯 스테이트풀셋의 파드는 끈끈하고 고유한 정체성을 가진다. +이 정체성은 스테이트풀 컨트롤러에서 각 파드에 주어지는 +고유한 순번에 기인한다. 파드의 이름의 형식은 +`<스테이트풀셋 이름>-<순번>` 이다. 앞서 `web` 스테이트풀셋은 +2개의 레플리카를 가졌으므로 `web-0` 과 `web-1` 2개 파드를 생성한다. + +### 안정적인 네트워크 신원 사용하기 + +각 파드는 각 순번에 따른 안정적인 호스트네임을 갖는다. 각 파드에서 +`hostname` 명령어를 실행하도록 +[`kubectl exec`](/docs/reference/generated/kubectl/kubectl-commands/#exec)를 이용하자. + +```shell +for i in 0 1; do kubectl exec web-$i -- sh -c 'hostname'; done +web-0 +web-1 +``` + +`dnsutils` 패키지에서 `nslookup` 명령을 제공하는 컨테이너를 +실행하도록 [`kubectl run`](/docs/reference/generated/kubectl/kubectl-commands/#run)을 이용하자. +파드의 호스트네임에 `nslookup`을 이용하면 클러스터 내부 DNS 주소를 +확인할 수 있다. + +```shell +kubectl run -i --tty --image busybox dns-test --restart=Never --rm /bin/sh +nslookup web-0.nginx +Server: 10.0.0.10 +Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local + +Name: web-0.nginx +Address 1: 10.244.1.6 + +nslookup web-1.nginx +Server: 10.0.0.10 +Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local + +Name: web-1.nginx +Address 1: 10.244.2.6 +``` + +헤드리스 서비스의 CNAME은 SRV 레코드를 지칭한다 +(Running과 Ready 상태의 각 파드마다 1개). +SRV 레코드는 파드의 IP 주소를 포함한 A 레코드 엔트리를 지칭한다. + +첫째 터미널에서 스테이트풀셋의 파드를 가져오자. + +```shell +kubectl get pod -w -l app=nginx +``` +두번째 터미널에서 스테이트풀셋 내에 파드를 모두 삭제하기위해 +[`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands/#delete)를 +이용하자. + +```shell +kubectl delete pod -l app=nginx +pod "web-0" deleted +pod "web-1" deleted +``` + +스테이트풀셋이 재시작되고 두 파드가 Running과 Ready 상태로 +전환되도록 기다리자. + +```shell +kubectl get pod -w -l app=nginx +NAME READY STATUS RESTARTS AGE +web-0 0/1 ContainerCreating 0 0s +NAME READY STATUS RESTARTS AGE +web-0 1/1 Running 0 2s +web-1 0/1 Pending 0 0s +web-1 0/1 Pending 0 0s +web-1 0/1 ContainerCreating 0 0s +web-1 1/1 Running 0 34s +``` + +파드의 호스트네임과 클러스터 내부 DNS 엔트리를 보기 위해 +`kubectl exec`과 `kubectl run`을 이용하자. + +```shell +for i in 0 1; do kubectl exec web-$i -- sh -c 'hostname'; done +web-0 +web-1 + +kubectl run -i --tty --image busybox dns-test --restart=Never --rm /bin/sh +nslookup web-0.nginx +Server: 10.0.0.10 +Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local + +Name: web-0.nginx +Address 1: 10.244.1.7 + +nslookup web-1.nginx +Server: 10.0.0.10 +Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local + +Name: web-1.nginx +Address 1: 10.244.2.8 +``` + +파드의 순번, 호스트네임, SRV 레코드와 A 레코드이름은 변경되지 않지만 +파드의 IP 주소는 변경될 수 있다. 이는 튜토리얼에서 사용하는 클러스터나 +다른 클러스터에도 동일하다. 따라서 다른 애플리케이션이 IP 주소로 +스테이트풀셋의 파드에 접속하지 않도록 하는 것이 중요하다. + + +스테이트풀셋의 활성 맴버를 찾아 연결할 경우 +헤드리스 서비스(`nginx.default.svc.cluster.local`)의 CNAME을 쿼리해야 한다. +CNAME과 연관된 SRV 레코드는 스테이트풀셋의 +Running과 Ready 상태의 모든 파드들을 +담고 있다. + +애플리케이션에서 이미 활성상태(liveness)와 준비성(readiness) 테스트하는 +연결 로직을 구현되어 있다면 +파드`web-0.nginx.default.svc.cluster.local`, +`web-1.nginx.default.svc.cluster.local`)의 SRV레코드를 안정적으로 사용할 수 있어 +애플리케이션은 파드가 Running과 Ready 상태로 전환할 때 +파드의 주소를 검색할 수 있다. + +### 안정적인 스토리지에 쓰기 {#writing-to-stable-storage} + +`web-0`과 `web-1`에 대해 퍼시스턴트볼륨클레임(PersistentVolumeClaim)을 가져오자. + +```shell +kubectl get pvc -l app=nginx +NAME STATUS VOLUME CAPACITY ACCESSMODES AGE +www-web-0 Bound pvc-15c268c7-b507-11e6-932f-42010a800002 1Gi RWO 48s +www-web-1 Bound pvc-15c79307-b507-11e6-932f-42010a800002 1Gi RWO 48s +``` +스테이트풀셋 컨트롤러는 2개의 [퍼시스턴트볼륨](/docs/concepts/storage/persistent-volumes/)에 +묶인 2개의 퍼시스턴트볼륨클레임을 생성했다. 본 튜토리얼에서 사용되는 클러스터는 퍼시스턴트볼륨을 동적으로 +프로비저닝하도록 설정되었으므로 생성된 퍼시스턴트볼륨도 자동으로 묶인다. + +NGINX 웹서버는 기본 색인 파일로 +`/usr/share/nginx/html/index.html`을 이용합니다. +스테이트풀셋 `spec`내의 `volumeMounts` 필드는 `/usr/share/nginx/html` 디렉터리가 +퍼시스턴트볼륨으로 제공되는지 보증합니다. + +파드의 호스트네임을 `index.html` 파일에 작성하고 +NGINX 웹서버가 해당 호스트네임을 제공하는지 확인해보자. + +```shell +for i in 0 1; do kubectl exec web-$i -- sh -c 'echo $(hostname) > /usr/share/nginx/html/index.html'; done + +for i in 0 1; do kubectl exec -it web-$i -- curl localhost; done +web-0 +web-1 +``` + +{{< note >}} +위에 curl 명령어로 403 Forbidden 아닌 응답을 보려면 +`volumeMounts`로 마운트된 디렉터리의 퍼미션을 수정해야 한다 +([hostPath 볼륨을 사용할 때에 버그](https://github.com/kubernetes/kubernetes/issues/2630)로 인함). + +```shell +for i in 0 1; do kubectl exec web-$i -- chmod 755 /usr/share/nginx/html; done +``` + +위에 curl 명령을 재시도하기 전에 +{{< /note >}} + +첫째 터미널에서 스테이트풀셋의 파드를 감시하자. + +```shell +kubectl get pod -w -l app=nginx +``` + +두번째 터미널에서 스테이트풀셋의 모든 파드를 삭제하자. + +```shell +kubectl delete pod -l app=nginx +pod "web-0" deleted +pod "web-1" deleted +``` +첫번째 터미널에서 실행 중인 `kubectl get`명령어의 출력을 확인하고, +모든 파드가 Running과 Ready 상태로 전환될때까지 기다리자. + +```shell +kubectl get pod -w -l app=nginx +NAME READY STATUS RESTARTS AGE +web-0 0/1 ContainerCreating 0 0s +NAME READY STATUS RESTARTS AGE +web-0 1/1 Running 0 2s +web-1 0/1 Pending 0 0s +web-1 0/1 Pending 0 0s +web-1 0/1 ContainerCreating 0 0s +web-1 1/1 Running 0 34s +``` + +웹서버에서 자신의 호스트네임을 계속 제공하는지 확인하자. + +``` +for i in 0 1; do kubectl exec -it web-$i -- curl localhost; done +web-0 +web-1 +``` + +비록 `web-0`과 `web-1`이 재스케줄링되어도 계속해서 +자신의 호스트네임을 제공하는데 이는 각 퍼시스턴트볼륨클레임에 +연관된 퍼시스턴트볼륨이 해당 `volumeMounts`로 재마운트되기 때문이다. +`web-0`과 `web-1`의 스케줄링에 관계없이 +각각의 퍼시스턴트볼륨은 적절하게 마운트된다. + +## 스테이트풀셋 스케일링 +스테이트풀셋을 스케일링하는 것은 레플리카 개수를 늘리거나 줄이는 것을 의미한다. 이것은 `replicas` 필드를 갱신하여 이뤄진다. +[`kubectl scale`](/docs/reference/generated/kubectl/kubectl-commands/#scale)이나 +[`kubectl patch`](/docs/reference/generated/kubectl/kubectl-commands/#patch)을 +이용해서 스테이트풀셋을 스케일링할 수 있다. + +### 스케일 업 + +터미널창에서 스테이트풀셋의 파드를 감시하자. + +```shell +kubectl get pods -w -l app=nginx +``` + +다른 터미널창에서 `kubectl scale`을 이용하여 레플리카 개수를 +5로 스케일링하자. + +```shell +kubectl scale sts web --replicas=5 +statefulset.apps/web scaled +``` + +첫번째 터미널에서 실행 중인 `kubectl get`명령어의 출력을 확인하고, +3개의 추가 파드가 Running과 Ready 상태로 전환될때까지 기다리자. + +```shell +kubectl get pods -w -l app=nginx +NAME READY STATUS RESTARTS AGE +web-0 1/1 Running 0 2h +web-1 1/1 Running 0 2h +NAME READY STATUS RESTARTS AGE +web-2 0/1 Pending 0 0s +web-2 0/1 Pending 0 0s +web-2 0/1 ContainerCreating 0 0s +web-2 1/1 Running 0 19s +web-3 0/1 Pending 0 0s +web-3 0/1 Pending 0 0s +web-3 0/1 ContainerCreating 0 0s +web-3 1/1 Running 0 18s +web-4 0/1 Pending 0 0s +web-4 0/1 Pending 0 0s +web-4 0/1 ContainerCreating 0 0s +web-4 1/1 Running 0 19s +``` + +스테이트풀셋 컨트롤러는 레플리카개수를 스케일링한다. +[스테이트풀셋 생성](#ordered-pod-creation)으로 스테이트풀셋 컨트롤러는 +각 파드을 순차적으로 각 순번에 따라 생성하고 후속 파드 시작 전에 +이전 파드가 Running과 Ready 상태가 될때까지 +기다린다. + +### 스케일 다운 {#scaling-down} + +터미널에서 스테이트풀셋의 파드를 감시하자. + +```shell +kubectl get pods -w -l app=nginx +``` + +다른 터미널에서 `kubectl patch`으로 스테이트풀셋을 뒤로 + 3개의 레플리카로 스케일링하자. + +```shell +kubectl patch sts web -p '{"spec":{"replicas":3}}' +statefulset.apps/web patched +``` + +`web-4`와 `web-3`이 Terminating으로 전환되기까지 기다리자. + +``` +kubectl get pods -w -l app=nginx +NAME READY STATUS RESTARTS AGE +web-0 1/1 Running 0 3h +web-1 1/1 Running 0 3h +web-2 1/1 Running 0 55s +web-3 1/1 Running 0 36s +web-4 0/1 ContainerCreating 0 18s +NAME READY STATUS RESTARTS AGE +web-4 1/1 Running 0 19s +web-4 1/1 Terminating 0 24s +web-4 1/1 Terminating 0 24s +web-3 1/1 Terminating 0 42s +web-3 1/1 Terminating 0 42s +``` + +### 순차 파드 종료 + +컨트롤러는 순번의 역순으로 한번에 1개 파드를 삭제하고 +다음 파드를 삭제하기 전에 +각각이 완전하게 종료되기까지 기다린다. + +스테이트풀셋의 퍼시스턴트볼륨클레임을 가져오자. + +```shell +kubectl get pvc -l app=nginx +NAME STATUS VOLUME CAPACITY ACCESSMODES AGE +www-web-0 Bound pvc-15c268c7-b507-11e6-932f-42010a800002 1Gi RWO 13h +www-web-1 Bound pvc-15c79307-b507-11e6-932f-42010a800002 1Gi RWO 13h +www-web-2 Bound pvc-e1125b27-b508-11e6-932f-42010a800002 1Gi RWO 13h +www-web-3 Bound pvc-e1176df6-b508-11e6-932f-42010a800002 1Gi RWO 13h +www-web-4 Bound pvc-e11bb5f8-b508-11e6-932f-42010a800002 1Gi RWO 13h + +``` + +여전히 5개의 퍼시스턴트볼륨클레임과 5개의 퍼시스턴트볼륨이 있다. +파드의 [안전한 스토리지](#writing-to-stable-storage)를 탐색하면서 스테이트풀셋의 파드가 삭제될 때에 파드에 마운트된 스테이트풀셋의 퍼시스턴트볼륨이 삭제되지 않은 것을 보았다. 스테이트풀셋 스케일 다운으로 파드 삭제할 때에도 여전히 사실이다. + +## 스테이트풀셋 업데이트하기 + +쿠버네티스 1.7 이상에서 스테이트풀셋 컨트롤러는 자동 업데이트를 지원한다. +전략은 스테이트풀셋 API 오브젝트의 `spec.updateStrategy` 필드로 결정된다. +이 기능은 컨테이너 이미지, 스테이트풀셋의 리소스 요청이나 +혹은 한계와 레이블과 파드의 어노테이션을 업그레이드하기 위해 사용될 수 있다. +`RollingUpdate`과 `OnDelete`의 2개의 +유효한 업데이트 전략이 있다. + +`RollingUpdate` 업데이트 전략은 스테이트풀셋에서 기본 값이다. + +### 롤링 업데이트 + +`RollingUpdate` 업데이트 전략은 스테이트풀셋을 보장하면서 스테이트풀셋 내에 파드를 역순으로 업데이트합니다. + +스테이트풀셋 `web`의 업데이트 전략을 `RollingUpdate`으로 패치하자. + +```shell +kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate"}}}' +statefulset.apps/web patched +``` + +터미널 창에서 스테이트풀셋 `web`의 컨테이너 이미지를 바꾸도록 +또 패치하자. + +```shell +kubectl patch statefulset web --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"gcr.io/google_containers/nginx-slim:0.8"}]' +statefulset.apps/web patched +``` + +다른 터미널창에서 스테이트풀셋의 파드를 감시하자. + +```shell +kubectl get po -l app=nginx -w +NAME READY STATUS RESTARTS AGE +web-0 1/1 Running 0 7m +web-1 1/1 Running 0 7m +web-2 1/1 Running 0 8m +web-2 1/1 Terminating 0 8m +web-2 1/1 Terminating 0 8m +web-2 0/1 Terminating 0 8m +web-2 0/1 Terminating 0 8m +web-2 0/1 Terminating 0 8m +web-2 0/1 Terminating 0 8m +web-2 0/1 Pending 0 0s +web-2 0/1 Pending 0 0s +web-2 0/1 ContainerCreating 0 0s +web-2 1/1 Running 0 19s +web-1 1/1 Terminating 0 8m +web-1 0/1 Terminating 0 8m +web-1 0/1 Terminating 0 8m +web-1 0/1 Terminating 0 8m +web-1 0/1 Pending 0 0s +web-1 0/1 Pending 0 0s +web-1 0/1 ContainerCreating 0 0s +web-1 1/1 Running 0 6s +web-0 1/1 Terminating 0 7m +web-0 1/1 Terminating 0 7m +web-0 0/1 Terminating 0 7m +web-0 0/1 Terminating 0 7m +web-0 0/1 Terminating 0 7m +web-0 0/1 Terminating 0 7m +web-0 0/1 Pending 0 0s +web-0 0/1 Pending 0 0s +web-0 0/1 ContainerCreating 0 0s +web-0 1/1 Running 0 10s +``` + +스테이트풀셋 내에 파드는 순번의 역순으로 업데이트된다. +이 스테이트풀셋 컨트롤러는 각 파드를 종료시키고 다음 파드를 업데이트하기 전에 +그것이 Running과 Ready 상태로 전환될때까지 기다린다. +알아둘 것은 비록 스테이트풀셋 컨트롤러에서 이전 파드가 Running과 Ready 상태가 되기까지 +다음 파드를 업데이트하지 않아도 현재 버전으로 파드를 업데이트하다 실패하면 복원한다는 것이다. +업데이트를 이미 받은 파드는 업데이트된 버전으로 복원되고 아직 업데이트를 받지 못한 파드는 +이전 버전으로 복원한다. +이런 식으로 컨트롤러는 간헐적인 오류가 발생해도 +애플리케이션을 계속 건강하게 유지하고 +업데이트도 일관되게 유지하려 한다. + +컨테이너 이미지를 살펴보기 위해 파드를 가져오자. + +```shell +for p in 0 1 2; do kubectl get po web-$p --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'; echo; done +k8s.gcr.io/nginx-slim:0.8 +k8s.gcr.io/nginx-slim:0.8 +k8s.gcr.io/nginx-slim:0.8 + +``` + +스테이트풀셋의 모든 파드가 지금은 이전 컨테이너 이미지를 실행 중이이다. + +**팁** 롤링 업데이트 상황을 살펴보기 위해 `kubectl rollout status sts/` +명령어도 사용할 수 있다. + +#### 단계적으로 업데이트 하기 {#staging-an-update} +`RollingUpdate` 업데이트 전략의 파라미터인 `partition`를 이용하여 +스테이트풀셋의 단계적으로 업데이트할 수 있다. +단계적 업데이트는 스테이트풀셋의 모든 파드를 현재 버전으로 유지하면서 +스테이트풀셋의 `.spec.template`에 변경을 허용한다. + +스테이트풀셋 `web`의 `updateStrategy` 필드에 partition을 추가하자. + +```shell +kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate","rollingUpdate":{"partition":3}}}}' +statefulset.apps/web patched +``` + +컨테이너의 이미지를 바꾸도록 스테이트풀셋을 또 패치하자. + +```shell +kubectl patch statefulset web --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"k8s.gcr.io/nginx-slim:0.7"}]' +statefulset.apps/web patched +``` + +스테이트풀셋의 파드를 삭제하자. + +```shell +kubectl delete po web-2 +pod "web-2" deleted +``` + +파드가 Running과 Ready 상태가 되기까지 기다리자. + +```shell +kubectl get po -l app=nginx -w +NAME READY STATUS RESTARTS AGE +web-0 1/1 Running 0 4m +web-1 1/1 Running 0 4m +web-2 0/1 ContainerCreating 0 11s +web-2 1/1 Running 0 18s +``` + +파드의 컨테이너를 가져오자. + +```shell +kubectl get po web-2 --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}' +k8s.gcr.io/nginx-slim:0.8 + +``` + +비록 업데이트 전략이 `RollingUpdate`이지만 스테이트풀셋은 +파드를 그것의 원래 컨테이너로 복원한다. +파드의 순번이 `updateStrategy`에서 지정된 +`파티션`보다 작기 때문이다. + +#### 카나리(Canary) 롤링 아웃 +[위에서](#staging-an-update) 지정한 `partition`값을 차감시키면 +변경사항을 테스트하기 위해 카나리 롤아웃을 할 수 있다. + +스테이트풀셋에 partition을 차감하도록 패치하자. + +```shell +kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate","rollingUpdate":{"partition":2}}}}' +statefulset.apps/web patched +``` + +`web-2` 파드가 Running과 Ready 상태가 되기까지 기다리자. + +```shell +kubectl get po -l app=nginx -w +NAME READY STATUS RESTARTS AGE +web-0 1/1 Running 0 4m +web-1 1/1 Running 0 4m +web-2 0/1 ContainerCreating 0 11s +web-2 1/1 Running 0 18s +``` + +파드의 컨테이너를 가져오자. + +```shell +kubectl get po web-2 --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}' +k8s.gcr.io/nginx-slim:0.7 + +``` + +`partition`을 바꾸면 스테이트풀셋 컨트롤러는 자동으로 +`web-2` 파드를 업데이트하는데 +이는 해당 파드의 순번이 `partition` 이상이기 때문이다. + +`web-1` 파드를 삭제하자. + +```shell +kubectl delete po web-1 +pod "web-1" deleted +``` + +`web-1` 파드가 Running과 Ready 상태가 되기까지 기다리자. + +```shell +kubectl get po -l app=nginx -w +NAME READY STATUS RESTARTS AGE +web-0 1/1 Running 0 6m +web-1 0/1 Terminating 0 6m +web-2 1/1 Running 0 2m +web-1 0/1 Terminating 0 6m +web-1 0/1 Terminating 0 6m +web-1 0/1 Terminating 0 6m +web-1 0/1 Pending 0 0s +web-1 0/1 Pending 0 0s +web-1 0/1 ContainerCreating 0 0s +web-1 1/1 Running 0 18s +``` + +`web-1` 파드의 컨테이너를 가져오자. + +```shell +kubectl get po web-1 --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}' +k8s.gcr.io/nginx-slim:0.8 + +``` + +`web-1` 는 원래 환경설정으로 복원되었는데 +이는 파드의 순번이 partition보다 작기 때문이다. +스테이트풀셋의 `.spec.template`이 갱신되면, 지정된 partition 이상의 순번을 +가진 모든 파드는 업데이트된다. 미만의 순번을 가진 파드라면 삭제되거나 +종료되어 원래 환경설정으로 복원된다. + +#### 단계적 롤아웃 +[카나리 롤아웃](#rolling-out-a-canary)에서 했던 방법과 비슷하게 +분할된 롤링 업데이트를 이용하여 단계적 롤아웃(e.g. 선형, 기하 또는 지수적 롤아웃)을 +수행할 수 있다. 단계적 롤아웃을 수행하려면 +컨트롤러가 업데이트를 일시 중지할 순번으로 +`partition`를 정하자. + +partition은 현재 `2`이다. partition을 `0`으로 바꾸자. + +```shell +kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate","rollingUpdate":{"partition":0}}}}' +statefulset.apps/web patched +``` + +스테이트풀셋의 모든 파드가 Running과 Ready 상태가 되기까지 기다리자. + +```shell +kubectl get po -l app=nginx -w +NAME READY STATUS RESTARTS AGE +web-0 1/1 Running 0 3m +web-1 0/1 ContainerCreating 0 11s +web-2 1/1 Running 0 2m +web-1 1/1 Running 0 18s +web-0 1/1 Terminating 0 3m +web-0 1/1 Terminating 0 3m +web-0 0/1 Terminating 0 3m +web-0 0/1 Terminating 0 3m +web-0 0/1 Terminating 0 3m +web-0 0/1 Terminating 0 3m +web-0 0/1 Pending 0 0s +web-0 0/1 Pending 0 0s +web-0 0/1 ContainerCreating 0 0s +web-0 1/1 Running 0 3s +``` + +파드의 컨테이너를 가져오자. + +```shell +for p in 0 1 2; do kubectl get po web-$p --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'; echo; done +k8s.gcr.io/nginx-slim:0.7 +k8s.gcr.io/nginx-slim:0.7 +k8s.gcr.io/nginx-slim:0.7 + +``` + +`partition`을 `0`으로 이동하여 스테이트풀셋 컨트롤러에서 계속해서 +업데이트 처리를 하도록 허용하였다. + +### 삭제시 동작 + +`OnDelete` 업데이트 전략은 예전 동작(1.6 이하)으로, +이 업데이트 전략을 선택하면 스테이트풀셋 컨트롤러는 스테이트풀셋의 +`.spec.template` 필드에 수정 사항이 발생해도 자동으로 파드를 업데이트하지 않는다. +이 전략은 `.spec.template.updateStrategy.type`을 `OnDelete`로 설정하여 선택할 수 있다. + +## 스테이트풀셋 삭제하기 + +스테이트풀셋은 비종속적(non-cascading), 종속적(cascading) 삭제를 둘 다 지원한다. +비종속적 삭제에서는 스테이트풀셋이 지워질 때에 스테이트풀셋의 파드는 지워지지 않는다. +종속적 삭제에서는 스테이트풀셋과 그에 속한 파드가 모두 지워진다. + +### 비종속적 삭제 + +터미널창에서 스테이트풀셋의 파드를 감시하자. + +``` +kubectl get pods -w -l app=nginx +``` + +다른 터미널에서는 스테이트풀셋을 지우기 위해 +[`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands/#delete) 명령어를 이용하자. +이 명령어에 `--cascade=false` 파라미터가 추가되었다. +이 파라미터는 쿠버네티스에 스테이트풀셋만 삭제하고 그에 속한 파드는 지우지 않도록 요청한다. + +```shell +kubectl delete statefulset web --cascade=false +statefulset.apps "web" deleted +``` + +상태를 확인하기 위해 파드를 가져오자. + +```shell +kubectl get pods -l app=nginx +NAME READY STATUS RESTARTS AGE +web-0 1/1 Running 0 6m +web-1 1/1 Running 0 7m +web-2 1/1 Running 0 5m +``` + +비록 `web`이 삭제되고 있어도, 모든 파드는 여전히 Running과 Ready 상태이다. +`web-0`을 삭제하자. + +```shell +kubectl delete pod web-0 +pod "web-0" deleted +``` + +스테이트풀셋의 파드를 가져오자. + +```shell +kubectl get pods -l app=nginx +NAME READY STATUS RESTARTS AGE +web-1 1/1 Running 0 10m +web-2 1/1 Running 0 7m +``` + +스테이트풀셋 `web`이 삭제되는 동안 `web-0`은 재시작하지 않았다. + +첫째 터미널에서 스테이트풀셋의 파드를 감시하자. + +```shell +kubectl get pods -w -l app=nginx +``` + +두번째 터미널에서 스테이트풀셋을 다시 생성하자. +`nginx` 서비스(가지지 말았어야 하는)를 삭제하기 전까지는 그 서비스가 이미 존재한다는 에러를 +볼 것이라는 것을 명심하자. + +```shell +kubectl create -f web.yaml +statefulset.apps/web created +Error from server (AlreadyExists): error when creating "web.yaml": services "nginx" already exists +``` + +이 에러는 무시하자. 이것은 다만 해당 서비스가 있더라도 +nginx 헤드리스 서비스를 생성하려고 했음을 뜻한다. + +첫째 터미널에서 실행 중인 `kubectl get` 명령어의 출력을 살펴보자. + +```shell +kubectl get pods -w -l app=nginx +NAME READY STATUS RESTARTS AGE +web-1 1/1 Running 0 16m +web-2 1/1 Running 0 2m +NAME READY STATUS RESTARTS AGE +web-0 0/1 Pending 0 0s +web-0 0/1 Pending 0 0s +web-0 0/1 ContainerCreating 0 0s +web-0 1/1 Running 0 18s +web-2 1/1 Terminating 0 3m +web-2 0/1 Terminating 0 3m +web-2 0/1 Terminating 0 3m +web-2 0/1 Terminating 0 3m +``` + +`web` 스테이트풀셋이 다시 생성될때 먼저 `web-0` 시작한다. +`web-1`은 이미 Running과 Ready 상태이므로 `web-0`이 Running과 Ready 상태로 +전환될 때는 단순히 이 파드에 적용됬다. 스테이트풀셋에`replicas`를 2로 하고 +`web-0`을 재생성했다면 `web-1`이 +이미 Running과 Ready 상태이고, +`web-2`은 종료되었을 것이다. + +파드의 웹서버에서 제공한 `index.html` 파일 내용을 +다른 관점으로 살펴보자. + +```shell +for i in 0 1; do kubectl exec -it web-$i -- curl localhost; done +web-0 +web-1 +``` + +스테이트풀셋과 `web-0` 파드를 둘다 삭제했으나 여전히 `index.html` 파일에 입력했던 +원래 호스트네임을 제공한다. 스테이트풀셋은 +파드에 할당된 퍼시스턴트볼륨을 결코 삭제하지 않기때문이다. +다시 스테이트풀셋을 생성하면 `web-0`을 시작하며 +원래 퍼시스턴트볼륨을 다시 마운트한다. + +### 단계식 삭제 + +터미널창에서 스테이트풀셋의 파드를 감시하자. + +```shell +kubectl get pods -w -l app=nginx +``` + +다른 터미널창에서 스테이트풀셋을 다시 지우자. 이번에는 +`--cascade=false` 파라미터를 생략하자. + +```shell +kubectl delete statefulset web +statefulset.apps "web" deleted +``` +첫째 터미널에서 실행 중인 `kubectl get` 명령어의 출력을 살펴보고 +모든 파드가 Terminating 상태로 전환될때까지 기다리자. + +```shell +kubectl get pods -w -l app=nginx +NAME READY STATUS RESTARTS AGE +web-0 1/1 Running 0 11m +web-1 1/1 Running 0 27m +NAME READY STATUS RESTARTS AGE +web-0 1/1 Terminating 0 12m +web-1 1/1 Terminating 0 29m +web-0 0/1 Terminating 0 12m +web-0 0/1 Terminating 0 12m +web-0 0/1 Terminating 0 12m +web-1 0/1 Terminating 0 29m +web-1 0/1 Terminating 0 29m +web-1 0/1 Terminating 0 29m + +``` + +[스케일 다운](#scaling-down) 섹션에서 보았듯 파드는 +각 순번의 역순으로 하나씩 종료된다. 파드가 종료될 때 +스테이트풀 컨트롤러는 이전 파드가 +완전히 종료되기까지 기다린다. + +스테이트풀셋과 그 파드를 종속적으로 삭제하는 중에 연관된 헤드리스 서비스를 +삭제하지 않음을 주의하자. +꼭 `nginx` 서비스를 수동으로 삭제해라. + +```shell +kubectl delete service nginx +service "nginx" deleted +``` + +스테이트풀셋과 헤드리스 서비스를 한번 더 다시 생성하자. + +```shell +kubectl create -f web.yaml +service/nginx created +statefulset.apps/web created +``` + +스테이트풀셋의 모든 파드가 Running과 Ready 상태로 전환될 때 +`index.html` 파일 내용을 검색하자. + +```shell +for i in 0 1; do kubectl exec -it web-$i -- curl localhost; done +web-0 +web-1 +``` + +스테이트풀셋과 그 내부의 모든 파드를 삭제했지만 퍼시스턴트볼륨이 마운트된 채로 +다시 생성되고 `web-0`과 `web-1`은 여전히 +각 호스트네임을 제공한다. + +최종적으로 `web` 스테이트풀셋과`nginx` 서비스를 삭제한다. + +```shell +kubectl delete service nginx +service "nginx" deleted + +kubectl delete statefulset web +statefulset "web" deleted +``` + +## 파드 관리 정책 + +일부 분산 시스템의 경우 스테이트풀셋의 순서 보증은 +불필요하거나 바람직하지 않다. 이러한 시스템은 고유성과 신원만 필요하다. +이를 해결하기 위해 쿠버네티스 1.7에서 `.spec.podManagementPolicy`를 +스테이트풀셋 API 오브젝트에 도입했다. + +### OrderedReady 파드 관리 + +`OrderedReady` 파드 관리는 스테이트풀셋에서는 기본이다. +이는 스테이트풀셋 컨트롤러가 지금까지 위에서 설명했던 순서를 +보증함을 뜻한다. + +### Parallel 파드 관리 + +`Parallel` 파드 관리는 스테이트풀셋 컨트롤러가 모든 파드를 +병렬로 시작하고 종료하는 것으로 다른 파드를 시작/종료하기 전에 +파드가 Running과 Ready 상태로 전환되거나 완전히 종료되기까지 +기다리지 않음을 뜻한다. + +{{< codenew file="application/web/web-parallel.yaml" >}} + +상기 예제를 다운로드받아 파일 이름을 `web-parallel.yaml`로 저장하자. + +이 매니페스트는 `web` 스테이트풀셋의 `.spec.podManagementPolicy`이 +`Parallel`인 것 말고는 이전에 다운로드 받았던 것과 동일하다. + +터미널에서 스테이트풀셋의 파드를 감시하자. + +```shell +kubectl get po -l app=nginx -w +``` + +다른 터미널에서 매니페스트 안에 스테이트풀셋과 서비스를 생성하자. + +```shell +kubectl create -f web-parallel.yaml +service/nginx created +statefulset.apps/web created +``` + +첫째 터미널에서 실행했던 `kubectl get` 명령어의 출력을 살펴보자. + +```shell +kubectl get po -l app=nginx -w +NAME READY STATUS RESTARTS AGE +web-0 0/1 Pending 0 0s +web-0 0/1 Pending 0 0s +web-1 0/1 Pending 0 0s +web-1 0/1 Pending 0 0s +web-0 0/1 ContainerCreating 0 0s +web-1 0/1 ContainerCreating 0 0s +web-0 1/1 Running 0 10s +web-1 1/1 Running 0 10s +``` + +스테이트풀셋 컨트롤러는 `web-0`와 `web-1`를 둘다 동시에 시작했다. + +두번째 터미널을 열어 놓고 다른 터미널창에서 스테이트풀셋을 +스케일링 하자. + +```shell +kubectl scale statefulset/web --replicas=4 +statefulset.apps/web scaled +``` + +`kubectl get` 명령어를 실행 중인 터미널의 출력을 살펴보자. + +```shell +web-3 0/1 Pending 0 0s +web-3 0/1 Pending 0 0s +web-3 0/1 Pending 0 7s +web-3 0/1 ContainerCreating 0 7s +web-2 1/1 Running 0 10s +web-3 1/1 Running 0 26s +``` + + +스테이트풀 컨트롤러는 두개의 새 파드를 시작하였다. +두번째 것을 런칭하기 위해 먼저 런칭한 것이 Running과 Ready 상태가 될 떄까지 기다리지 않는다. + +이 터미널을 열어 놓고 다른 터미널에서 `web` 스테이트풀셋을 삭제하자. + +```shell +kubectl delete sts web +``` + +다시 한번 다른 터미널에서 실행 중인 `kubectl get`명령의 출력을 확인해보자. + +```shell +web-3 1/1 Terminating 0 9m +web-2 1/1 Terminating 0 9m +web-3 1/1 Terminating 0 9m +web-2 1/1 Terminating 0 9m +web-1 1/1 Terminating 0 44m +web-0 1/1 Terminating 0 44m +web-0 0/1 Terminating 0 44m +web-3 0/1 Terminating 0 9m +web-2 0/1 Terminating 0 9m +web-1 0/1 Terminating 0 44m +web-0 0/1 Terminating 0 44m +web-2 0/1 Terminating 0 9m +web-2 0/1 Terminating 0 9m +web-2 0/1 Terminating 0 9m +web-1 0/1 Terminating 0 44m +web-1 0/1 Terminating 0 44m +web-1 0/1 Terminating 0 44m +web-0 0/1 Terminating 0 44m +web-0 0/1 Terminating 0 44m +web-0 0/1 Terminating 0 44m +web-3 0/1 Terminating 0 9m +web-3 0/1 Terminating 0 9m +web-3 0/1 Terminating 0 9m +``` + +스테이트풀 컨트롤러는 모든 파드를 동시에 삭제한다. 파드를 삭제하기 전에 +그 파드의 순서상 후계자를 기다리지 않는다. + +`kubectl get` 명령어가 실행된 터미널을 닫고 +`nginx` 서비스를 삭제하자. + +```shell +kubectl delete svc nginx +``` +{{% /capture %}} + +{{% capture cleanup %}} +이 튜토리얼에서 사용된 퍼시턴트볼륨을 위한 +퍼시스턴트 스토리지 미디어를 삭제해야 한다. +모든 스토리지를 반환하도록 환경, 스토리지 설정과 +프로비저닝 방법에 따른 단계를 따르자. +{{% /capture %}} + + diff --git a/content/ko/docs/tutorials/stateless-application/guestbook.md b/content/ko/docs/tutorials/stateless-application/guestbook.md index e185446172..914f3a9607 100644 --- a/content/ko/docs/tutorials/stateless-application/guestbook.md +++ b/content/ko/docs/tutorials/stateless-application/guestbook.md @@ -2,6 +2,10 @@ title: "예시: Redis를 사용한 PHP 방명록 애플리케이션 배포하기" content_template: templates/tutorial weight: 20 +card: + name: tutorials + weight: 30 + title: "상태를 유지하지 않는 예제: Redis를 사용한 PHP 방명록" --- {{% capture overview %}} diff --git a/content/ko/examples/application/web/web-parallel.yaml b/content/ko/examples/application/web/web-parallel.yaml new file mode 100644 index 0000000000..4eab2dc206 --- /dev/null +++ b/content/ko/examples/application/web/web-parallel.yaml @@ -0,0 +1,47 @@ +apiVersion: v1 +kind: Service +metadata: + name: nginx + labels: + app: nginx +spec: + ports: + - port: 80 + name: web + clusterIP: None + selector: + app: nginx +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: web +spec: + serviceName: "nginx" + podManagementPolicy: "Parallel" + replicas: 2 + selector: + matchLabels: + app: nginx + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: k8s.gcr.io/nginx-slim:0.8 + ports: + - containerPort: 80 + name: web + volumeMounts: + - name: www + mountPath: /usr/share/nginx/html + volumeClaimTemplates: + - metadata: + name: www + spec: + accessModes: [ "ReadWriteOnce" ] + resources: + requests: + storage: 1Gi diff --git a/content/ko/examples/application/web/web.yaml b/content/ko/examples/application/web/web.yaml new file mode 100644 index 0000000000..37c1fabf9c --- /dev/null +++ b/content/ko/examples/application/web/web.yaml @@ -0,0 +1,47 @@ +apiVersion: v1 +kind: Service +metadata: + name: nginx + labels: + app: nginx +spec: + ports: + - port: 80 + name: web + clusterIP: None + selector: + app: nginx +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: web +spec: + serviceName: "nginx" + replicas: 2 + selector: + matchLabels: + app: nginx + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: k8s.gcr.io/nginx-slim:0.8 + ports: + - containerPort: 80 + name: web + volumeMounts: + - name: www + mountPath: /usr/share/nginx/html + volumeClaimTemplates: + - metadata: + name: www + spec: + accessModes: [ "ReadWriteOnce" ] + resources: + requests: + storage: 1Gi + diff --git a/content/ko/includes/federation-current-state.md b/content/ko/includes/federation-current-state.md new file mode 100644 index 0000000000..4ba85405e5 --- /dev/null +++ b/content/ko/includes/federation-current-state.md @@ -0,0 +1 @@ +쿠버네티스 API 리소스를 '있는 그대로' 재사용하는 현재의 쿠버네티스 페더레이션 API `Federation V1`는 많은 특징에 의해서 알파 상태로 여겨지고 있다. 페더레이션 API를 GA 단계로 진화시키는데 명확한 길은 없지만, 쿠버네티스 API와 별도로 페더레이션 전용 API를 구현하기 위한 `Federation V2`에 대한 노력이 진행 중이다. 자세한 사항은 [sig-multicluster 커뮤니티 페이지](https://github.com/kubernetes/community/tree/master/sig-multicluster)에서 확인할 수 있다.