Second Korean l10n work for release 1.18

* Translate /concepts/cluster-administration/kubelet-garbage-collection in Korean (#20274)
* Translate cluster-administration/logging.md in Korean (#20409)
* Translate tasks/configure-pod-container/assign-memory-resource.md in … (#20167)
* Translate community/_index.html in Korean. (#20317)
* Translate storage/storage-classes.md in Korean. (#20310)
* Translate configuration/resource-bin-packing.md in Korean. (#20276)
* Translate extend-kubernetes/compute-storage-net/device-plugins.md (#20406)
* Translate compute-storage-net/network-plugins.md in Korean (#20407)
* Translate concepts/cluster-administration/certificates.md (#20330)
* Translate assign-pods-nodes-using-node-affinity to Korean (#20307)
* Translate cluster-administration/manage-deployment.md in Korean (#20366)
* Translate configuration/taint-and-toleration.md in Korean (#20404)
* Translate logging-elasticsearch-kibana.md in Korean (#20300)
* add anchors of subtitle in ko/docs/concepts/policy/pod-security-policy (#20399)
* Translate task/scheduling-gpus in Korean (#20212)
* Translate conceps/storage/volume-snapshots in Korean (#19955)
* Translate network/validate-dual-stack.md in Korean (#20271)
* Update to Outdated files in the dev-1.18-ko.2 branch. (#20244)
* Update to a link to the newly translated document. (#20247)

Co-Authored-By: bluefriday <bluefriday86@gmail.com>
Co-Authored-By: cometrojan <d.gweon@samsung.com>
Co-Authored-By: coolguyhong <podolsmith@naver.com>
Co-Authored-By: DongMoon Kim <dmoons.kim@gmail.com>
Co-Authored-By: Jerry Park <jaehwa@gmail.com>
Co-Authored-By: jmyung <jesang.myung@gmail.com>
Co-Authored-By: June Yi <june.yi@samsung.com>
Co-Authored-By: seokho-son <shsongist@gmail.com>
Co-Authored-By: sunminjeon <sunmin.jeon@samsung.com>
Co-Authored-By: Yuk, Yongsu <ysyukr@gmail.com>
pull/20528/head
June Yi 2020-04-24 00:07:32 +09:00
parent dc3ce88f55
commit c74ce882ec
76 changed files with 4892 additions and 614 deletions

View File

@ -45,7 +45,7 @@ Google이 일주일에 수십억 개의 컨테이너들을 운영하게 해준
<br>
<br>
<br>
<a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-europe/?utm_source=kubernetes.io&utm_medium=nav&utm_campaign=kccnceu20" button id="desktopKCButton">Attend KubeCon in Amsterdam in July/August TBD</a>
<a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-europe/?utm_source=kubernetes.io&utm_medium=nav&utm_campaign=kccnceu20" button id="desktopKCButton">Attend KubeCon in Amsterdam on August 13-16, 2020</a>
<br>
<br>
<br>

View File

@ -0,0 +1,236 @@
---
title: 커뮤니티
layout: basic
cid: community
---
<div class="newcommunitywrapper">
<div class="banner1">
<img src="/images/community/kubernetes-community-final-02.jpg" alt="쿠버네티스 컨퍼런스 갤러리" style="width:100%;padding-left:0px" class="desktop">
<img src="/images/community/kubernetes-community-02-mobile.jpg" alt="쿠버네티스 컨퍼런스 갤러리" style="width:100%;padding-left:0px" class="mobile">
</div>
<div class="intro">
<br class="mobile">
<p>사용자, 기여자, 그리고 우리가 함께 구축한 문화로 구성된 쿠버네티스 커뮤니티는 이 오픈소스 프로젝트가 급부상하는 가장 큰 이유 중 하나입니다. 프로젝트 자체가 성장 하고 변화함에 따라 우리의 문화와 가치관이 계속 성장하고 변화하고 있습니다. 우리 모두는 프로젝트의 지속적인 개선과 작업 방식을 위해 함께 노력합니다.
<br><br>우리는 이슈를 제기하고 풀 리퀘스트하고, SIG 미팅과 쿠버네티스 모임 그리고 KubeCon에 참석하고 채택과 혁신을 옹호하며, <code>kubectl get pods</code> 을 실행하고, 다른 수천가지 중요한 방법으로 기여하는 사람들 입니다. 여러분이 어떻게 이 놀라운 공동체의 일부가 될 수 있는지 계속 읽어보세요.</p>
<br class="mobile">
</div>
<div class="navbar">
<a href="#conduct">행동 강령 </a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a href="#videos">비디오</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a href="#discuss">토론</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a href="#events">이벤트와 모임들</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a href="#news">새소식</a>
</div>
<br class="mobile"><br class="mobile">
<div class="imagecols">
<br class="mobile">
<div class="imagecol">
<img src="/images/community/kubernetes-community-final-03.jpg" alt="쿠버네티스 컨퍼런스 갤러리" style="width:100%" class="desktop">
</div>
<div class="imagecol">
<img src="/images/community/kubernetes-community-final-04.jpg" alt="쿠버네티스 컨퍼런스 갤러리" style="width:100%" class="desktop">
</div>
<div class="imagecol" style="margin-right:0% important">
<img src="/images/community/kubernetes-community-final-05.jpg" alt="쿠버네티스 컨퍼런스 갤러리" style="width:100%;margin-right:0% important" class="desktop">
</div>
<img src="/images/community/kubernetes-community-04-mobile.jpg" alt="쿠버네티스 컨퍼런스 갤러리" style="width:100%;margin-bottom:3%" class="mobile">
<a name="conduct"></a>
</div>
<div class="conduct">
<div class="conducttext">
<br class="mobile"><br class="mobile">
<br class="tablet"><br class="tablet">
<div class="conducttextnobutton" style="margin-bottom:2%"><h1>행동 강령</h1>
쿠버네티스 커뮤니티는 존중과 포괄성을 중요시하며 모든 상호작용에 행동 강령을 시행합니다. 이벤트나 회의, 슬랙 또는 다른 커뮤니케이션 메커니즘에서 행동 강령의 위반이 발견되면, 쿠버네티스 행동 강령 위원회 <a href="mailto:conduct@kubernetes.io" style="color:#0662EE;font-weight:300">conduct@kubernetes.io</a>에 연락하세요. 모든 보고서는 기밀로 유지됩니다. <a href="https://github.com/kubernetes/community/tree/master/committee-code-of-conduct" style="color:#0662EE;font-weight:300">여기</a>서 위원회에 대한 내용을 읽을 수 있습니다.
<br>
<a href="/ko/community/code-of-conduct/">
<br class="mobile"><br class="mobile">
<span class="fullbutton">
더 읽어 보기
</span>
</a>
</div><a name="videos"></a>
</div>
</div>
<div class="videos">
<br class="mobile"><br class="mobile">
<br class="tablet"><br class="tablet">
<h1 style="margin-top:0px">비디오</h1>
<div style="margin-bottom:4%;font-weight:300;text-align:center;padding-left:10%;padding-right:10%">유튜브에 많이 올라와 있어요. 다양한 주제에 대해 구독하세요.</div>
<div class="videocontainer">
<div class="video">
<iframe width="100%" height="250" src="https://www.youtube.com/embed/videoseries?list=PL69nYSiGNLP3azFUvYJjGn45YbF6C-uIg" title="월간 Office Hours" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
<a href="https://www.youtube.com/playlist?list=PL69nYSiGNLP3azFUvYJjGn45YbF6C-uIg">
<div class="videocta">
월간 Office Hours 보기&nbsp;&#9654;</div>
</a>
</div>
<div class="video">
<iframe width="100%" height="250" src="https://www.youtube.com/embed/videoseries?list=PL69nYSiGNLP1pkHsbPjzAewvMgGUpkCnJ" title="주간 커뮤니티 미팅" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
<a href="https://www.youtube.com/playlist?list=PL69nYSiGNLP1pkHsbPjzAewvMgGUpkCnJ">
<div class="videocta">
주간 커뮤니티 미팅 보기&nbsp;&#9654;
</div>
</a>
</div>
<div class="video">
<iframe width="100%" height="250" src="https://www.youtube.com/embed/videoseries?list=PL69nYSiGNLP3QpQrhZq_sLYo77BVKv09F" title="커뮤니티 멤버와의 대화" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
<a href="https://www.youtube.com/playlist?list=PL69nYSiGNLP3QpQrhZq_sLYo77BVKv09F">
<div class="videocta">
커뮤니티 멤버와의 대화 보기&nbsp;&#9654;
</div>
</a>
<a name="discuss"></a>
</div>
</div>
</div>
<div class="resources">
<br class="mobile"><br class="mobile">
<br class="tablet"><br class="tablet">
<h1 style="padding-top:1%">토론</h1>
<div style="font-weight:300;text-align:center">우리는 대화를 많이 합니다. 이 모든 플랫폼에서 우리를 찾아 대화에 참여하세요.</div>
<div class="resourcecontainer">
<div class="resourcebox">
<img src="/images/community/discuss.png" alt=Forum" style="width:80%;padding-bottom:2%">
<a href="https://discuss.kubernetes.io/" style="color:#0662EE;display:block;margin-top:1%">
포럼&nbsp;&#9654;
</a>
<div class="resourceboxtext" style="font-size:12px;text-transform:none !important;font-weight:300;line-height:1.4em;color:#333333;margin-top:4%">
문서, 스택오버플로우 등을 연결하는 주제 기반 기술 토론하는 곳입니다.
</div>
</div>
<div class="resourcebox">
<img src="/images/community/twitter.png" alt="Twitter" style="width:80%;padding-bottom:2%">
<a href="https://twitter.com/kubernetesio" style="color:#0662EE;display:block;margin-top:1%">
트위터&nbsp;&#9654;
</a>
<div class="resourceboxtext" style="font-size:12px;text-transform:none !important;font-weight:300;line-height:1.4em;color:#333333;margin-top:4%">블로그 게시물, 이벤트, 뉴스, 아이디어의 실시간 소식들입니다.
</div>
</div>
<div class="resourcebox">
<img src="/images/community/github.png" alt="GitHub" style="width:80%;padding-bottom:2%">
<a href="https://github.com/kubernetes/kubernetes" style="color:#0662EE;display:block;margin-top:1%">
깃헙&nbsp;&#9654;
</a>
<div class="resourceboxtext" style="font-size:12px;text-transform:none !important;font-weight:300;line-height:1.4em;color:#333333;margin-top:4%">
모든 프로젝트와 이슈 추적, 더불어 코드도 물론이죠.
</div>
</div>
<div class="resourcebox">
<img src="/images/community/stack.png" alt="Stack Overflow" style="width:80%;padding-bottom:2%">
<a href="https://stackoverflow.com/search?q=kubernetes" style="color:#0662EE;display:block;margin-top:1%">
스택 오버플로우&nbsp;&#9654;
</a>
<div class="resourceboxtext" style="font-size:12px;text-transform:none !important;font-weight:300;line-height:1.4em;color:#333333;margin-top:4%">
모든 유스 케이스에 대한 기술적인 문제 해결입니다.
<a name="events"></a>
</div>
</div>
<!--
<div class="resourcebox">
<img src="/images/community/slack.png" style="width:80%">
slack&nbsp;&#9654;
<div class="resourceboxtext" style="font-size:11px;text-transform:none !important;font-weight:200;line-height:1.4em;color:#333333;margin-top:4%">
170개 이상의 채널이 있으며, 필요에 맞는 채널을 찾을 수 있습니다.
</div>
</div>-->
</div>
</div>
<div class="events">
<br class="mobile"><br class="mobile">
<br class="tablet"><br class="tablet">
<div class="eventcontainer">
<h1 style="color:white !important">다가오는 이벤트</h1>
{{< upcoming-events >}}
</div>
</div>
<div class="meetups">
<div class="meetupcol">
<div class="meetuptext">
<h1 style="text-align:left">글로벌 커뮤니티</h1>
전 세계 150개가 넘는 모임이 있고 성장하고 있는 가운데, 현지 kube 사람들을 찾아보세요. 가까운 곳에 없다면, 책임감을 갖고 직접 만들어보세요.
</div>
<a href="https://www.meetup.com/topics/kubernetes/">
<div class="button">
모임 찾아보기
</div>
</a>
<a name="news"></a>
</div>
</div>
<!--
<div class="contributor">
<div class="contributortext">
<br>
<h1 style="text-align:left">
New Contributors Site
</h1>
Text about new contributors site.
<br><br>
<div class="button">
VISIT SITE
</div>
</div>
</div>
-->
<div class="news">
<br class="mobile"><br class="mobile">
<br class="tablet"><br class="tablet">
<h1 style="margin-bottom:2%">최근 소식들</h1>
<br>
<div class="twittercol1">
<a class="twitter-timeline" data-tweet-limit="1" href="https://twitter.com/kubernetesio?ref_src=twsrc%5Etfw">Tweets by kubernetesio</a> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</div>
<br>
<br><br><br><br>
</div>
</div>

View File

@ -0,0 +1,27 @@
---
title: 커뮤니티
layout: basic
cid: community
css: /css/community.css
---
<div class="community_main">
<h1>쿠버네티스 커뮤니티 행동 강령</h1>
쿠버네티스는
<a href="https://github.com/cncf/foundation/blob/master/code-of-conduct.md">CNCF의 행동 강령</a>을 따르고 있습니다.
<a href="https://github.com/cncf/foundation/blob/214585e24aab747fb85c2ea44fbf4a2442e30de6/code-of-conduct.md">커밋 214585e</a>
에 따라 CNCF 행동 강령의 내용이 아래에 복제됩니다.
만약 최신 버전이 아닌 경우에는
<a href="https://github.com/kubernetes/website/issues/new">이슈를 제기해 주세요</a>.
이벤트나 회의, 슬랙 또는 다른 커뮤니케이션
메커니즘에서 행동 강령을 위반한 경우
<a href="https://git.k8s.io/community/committee-code-of-conduct">쿠버네티스 행동 강령 위원회</a>에 연락하세요.
<a href="mailto:conduct@kubernetes.io">conduct@kubernetes.io</a>로 이메일을 보내 주세요.
당신의 익명성은 보호됩니다.
<div class="cncf_coc_container">
{{< include "/static/cncf-code-of-conduct.md" >}}
</div>
</div>

View File

@ -0,0 +1,2 @@
이 디렉터리의 파일은 다른 소스에서 가져왔습니다. 새 버전으로
교체하는 경우를 제외하고 직접 편집하지 마십시오.

View File

@ -0,0 +1,45 @@
<!-- Do not edit this file directly. Get the latest from
https://github.com/cncf/foundation/blob/master/code-of-conduct.md -->
## CNCF 커뮤니티 행동 강령 v1.0
### 참여자 행동 강령
본 프로젝트의 기여자 및 유지 관리자로서, 환영하는 분위기의 공개 커뮤니티를
육성하기 위하여, 저희는 이슈를 보고하고, 기술 요청을 작성하며, 문서를 업데이트하며,
pull 요청 또는 패치를 제출하고, 다른 활동에 참여하는
모든 분들을 존중하겠다고 약속드립니다.
저희는 경험 수준, 성별, 성 정체성과 표현, 성적 지향,
장애, 외양, 신체 크기, 인종, 민족, 나이, 종교, 또는
국적에 상관 없이 모두가 괴롭힘 없는 환경에서
본 프로젝트에 참여하도록 최선을 다하고 있습니다.
참여자에게 금지하는 행동의 예는 다음과 같습니다.:
* 성적 언어 또는 이미지 사용
* 개인적인 공격
* 시비 걸기 또는 모욕/경멸적인 코멘트
* 공적 및 사적 괴롭힘
* 분명한 허락을 받지 않은 타인의 사적 정보 출판,
예를 들어 물리적 또는 전자 주소
* 다른 비윤리적 또는 비전문적인 행동
프로젝트 유지 관리자는 본 행동 강령을 위반하는 코멘트, 협약, 강령,
위키 수정, 이슈와 다른 참여자를 제거, 수정, 삭제할 권한과
책임을 가집니다. 본 행동 강령을 적용하여, 프로젝트 유지 관리자는 본
프로젝트를 유지하는 모든 상황에 공정하고 일관적으로 이러한 원칙들을
적용하기 위해 헌신해야 합니다. 프로젝트 유지 관리자는
행동 강령이 프로젝트 팀에서 영구적으로 사라지도록 하거나 강요해서는 안됩니다.
본 행동 강령은 프로젝트 공간과 개인이 프로젝트 또는
그 커뮤니티를 대표하는 공적 공간에 모두 적용됩니다.
Kubernetes에서의 폭력, 학대 또는 기타 허용되지 않는 행동 사례는 이메일 주소 <conduct@kubernetes.io>를 통해 [Kubernetes 행동 강령 위원회](https://git.k8s.io/community/committee-code-of-conduct)로 신고하실 수 있습니다. 다른 프로젝트는 CNCF 프로젝트 관리자 또는 저희 중재자인 Mishi Choudhary에게 이메일 <mishi@linux.com>으로 연락하십시오.
본 행동강령은 참여자 Contributor Covenant (http://contributor-covenant.org)의
버전 1.2.0을 적용하였으며,
해당 내용은 여기 http://contributor-covenant.org/version/1/2/0/에서 확인할 수 있습니다.
### CNCF 커뮤니티 행동 강령
CNCF 이벤트는 리눅스 재단의 [행동 강령](https://events.linuxfoundation.org/code-of-conduct/) 을 따르며, 해당 내용은 이벤트 페이지에서 확인할 수 있습니다. 본 강령은 위 정책과 호환할 수 있도록 설계되었으며, 또한 사건에 따라 더 많은 세부 내용을 포함합니다.

View File

@ -113,17 +113,15 @@ weight: 30
디자인 원리에 따라, 쿠버네티스는 클러스터 상태의 각 특정 측면을
관리하는 많은 컨트롤러를 사용한다. 가장 일반적으로, 특정 컨트롤 루프
(컨트롤러)는 의도한 상태로서 한 종류의 리소스를 사용하고, 의도한 상태로
만들기 위해 다른 종류의 리소스를 관리한다.
만들기 위해 다른 종류의 리소스를 관리한다. 예를 들어, 잡 컨트롤러는
잡 오브젝트(새 작업을 발견하기 위해)와 파드 오브젝트(잡을 실행하고, 완료된 시기를
확인하기 위해)를 추적한다. 이 경우 파드는 잡 컨트롤러가 생성하는 반면,
잡은 다른 컨트롤러가 생성한다.
컨트롤 루프들로 연결 구성된 하나의 모놀리식(monolithic) 집합보다,
간단한 컨트롤러를 여러 개 사용하는 것이 유용하다. 컨트롤러는 실패할 수 있으므로, 쿠버네티스는 이를
허용하도록 디자인되었다.
예를 들어, 잡용 컨트롤러는 잡 오브젝트(새 작업을
발견하기 위해)와 파드 오브젝트(잡을 실행하고, 완료된 시기를
확인하기 위해)를 추적한다. 이 경우 파드는 잡 컨트롤러가 생성하는 반면,
잡은 다른 컨트롤러가 생성한다.
{{< note >}}
동일한 종류의 오브젝트를 만들거나 업데이트하는 여러 컨트롤러가 있을 수 있다.
이면에, 쿠버네티스 컨트롤러는 컨트롤 하고 있는 리소스에
@ -158,5 +156,5 @@ weight: 30
* [쿠버네티스 컨트롤 플레인](/ko/docs/concepts/#쿠버네티스-컨트롤-플레인)에 대해 읽기
* [쿠버네티스 오브젝트](/ko/docs/concepts/#쿠버네티스-오브젝트)의 몇 가지 기본 사항을 알아보자.
* [쿠버네티스 API](/ko/docs/concepts/overview/kubernetes-api/)에 대해 더 배워 보자.
* 만약 자신만의 컨트롤러를 작성하기 원한다면, 쿠버네티스 확장하기의 [확장 패턴](/docs/concepts/extend-kubernetes/extend-cluster/#extension-patterns)을 본다.
* 만약 자신만의 컨트롤러를 작성하기 원한다면, 쿠버네티스 확장하기의 [확장 패턴](/ko/docs/concepts/extend-kubernetes/extend-cluster/#익스텐션-패턴)을 본다.
{{% /capture %}}

View File

@ -93,13 +93,28 @@ HTTPS 엔드포인트에 의해 제공되는 인증서를 확인하지 않으며
### SSH 터널
쿠버네티스는 마스터 -> 클러스터 통신 경로를 보호하는 SSH 터널을
쿠버네티스는 마스터 클러스터 통신 경로를 보호하는 SSH 터널을
지원한다. 이 구성에서 apiserver는 클러스터의 각 노드에서 SSH 터널을
시작하고(포트 22번으로 수신 대기하는 ssh 서버에 연결), 터널을 통해
kubelet, 노드, 파드 또는 서비스로 향하는 모든 트래픽을 전달한다.
이 터널은 실행중인 노드의 트래픽이 외부로 노출되지
않도록 보장한다.
SSH 터널은 현재 사용 중단(deprecated)되었으므로, 무엇을 하고 있는지 알지 못하는 한 터널을 이용하지 말아야 한다. 이 통신 채널의 대체물을 설계 중이다.
SSH 터널은 현재 사용 중단(deprecated)되었으므로, 무엇을 하고 있는지 알지 못하는
한 터널을 이용하지 말아야 한다. Konnectivity 서비스는 이 통신
채널을 대체한다.
### Konnectivity 서비스
{{< feature-state for_k8s_version="v1.18" state="beta" >}}
SSH 터널을 대체하는 Konnectivity 서비스는 마스터 → 클러스터 통신을
위한 TCP 수준의 프록시를 제공한다. Konnectivity는 마스터
네트워크와 클러스터 네트워크에서 실행되는 Konnectivity 서버와
에이전트 두 부분으로 구성된다. Konnectivity 에이전트는
Konnectivity 서버에 대한 연결을 시작하고, 유지한다.
이 연결을 통해 모든 마스터 → 클러스터로의 트래픽이 통과하게 된다.
클러스터에서 설정하는 방법에 대해서는 [Konnectivity 서비스 구성](/docs/tasks/setup-konnectivity/)
하기를 참고한다.
{{% /capture %}}

View File

@ -69,7 +69,7 @@ kubectl describe node <insert-node-name-here>
]
```
ready 컨디션의 상태가 [kube-controller-manager](/docs/admin/kube-controller-manager/)에 인수로 넘겨지는 `pod-eviction-timeout` 보다 더 길게 `Unknown` 또는 `False`로 유지되는 경우, 노드 상에 모든 파드는 노드 컨트롤러에 의해 삭제되도록 스케줄 된다. 기본 축출 타임아웃 기간은 **5분** 이다. 노드에 접근이 불가할 때와 같은 경우, apiserver는 노드 상의 kubelet과 통신이 불가하다. apiserver와의 통신이 재개될 때까지 파드 삭제에 대한 결정은 kubelet에 전해질 수 없다. 그 사이, 삭제되도록 스케줄 되어진 파드는 분할된 노드 상에서 계속 동작할 수도 있다.
ready 컨디션의 상태가 `pod-eviction-timeout` ([kube-controller-manager](/docs/admin/kube-controller-manager/)에 전달된 인수) 보다 더 길게 `Unknown` 또는 `False`로 유지되는 경우, 노드 상에 모든 파드는 노드 컨트롤러에 의해 삭제되도록 스케줄 된다. 기본 축출 타임아웃 기간은 **5분** 이다. 노드에 접근이 불가할 때와 같은 경우, apiserver는 노드 상의 kubelet과 통신이 불가하다. apiserver와의 통신이 재개될 때까지 파드 삭제에 대한 결정은 kubelet에 전해질 수 없다. 그 사이, 삭제되도록 스케줄 되어진 파드는 분할된 노드 상에서 계속 동작할 수도 있다.
1.5 이전의 쿠버네티스 버전에서는, 노드 컨트롤러가 apiserver로부터 접근 불가한 이러한 파드를 [강제 삭제](/ko/docs/concepts/workloads/pods/pod/#파드-강제-삭제)
시킬 것이다. 그러나 1.5 이상에서는, 노드 컨트롤러가 클러스터 내 동작 중지된 것을 확신할 때까지는 파드를
@ -80,8 +80,8 @@ ready 컨디션의 상태가 [kube-controller-manager](/docs/admin/kube-controll
노드 수명주기 컨트롤러는 자동으로 컨디션을 나타내는
[테인트(taints)](/docs/concepts/configuration/taint-and-toleration/)를 생성한다.
스케줄러가 파드를 노드에 할당할 때, 스케줄러는 파드가 극복(tolerate)하는 테인트가
아닌 한, 노드 계정의 테인트를 고려 한다.
스케줄러는 파드를 노드에 할당 할 때 노드의 테인트를 고려한다.
또한 파드는 노드의 테인트를 극복(tolerate)할 수 있는 톨러레이션(toleration)을 가질 수 있다.
### 용량과 할당가능 {#capacity}

View File

@ -0,0 +1,252 @@
---
title: 인증서
content_template: templates/concept
weight: 20
---
{{% capture overview %}}
클라이언트 인증서로 인증을 사용하는 경우 `easyrsa`, `openssl` 또는 `cfssl`
을 통해 인증서를 수동으로 생성할 수 있다.
{{% /capture %}}
{{% capture body %}}
### easyrsa
**easyrsa** 는 클러스터 인증서를 수동으로 생성할 수 있다.
1. easyrsa3의 패치 버전을 다운로드하여 압축을 풀고, 초기화한다.
curl -LO https://storage.googleapis.com/kubernetes-release/easy-rsa/easy-rsa.tar.gz
tar xzf easy-rsa.tar.gz
cd easy-rsa-master/easyrsa3
./easyrsa init-pki
1. 새로운 인증 기관(CA)을 생성한다. `--batch` 는 자동 모드를 설정한다.
`--req-cn` 는 CA의 새 루트 인증서에 대한 일반 이름(Common Name (CN))을 지정한다.
./easyrsa --batch "--req-cn=${MASTER_IP}@`date +%s`" build-ca nopass
1. 서버 인증서와 키를 생성한다.
`--subject-alt-name` 인수는 API 서버에 접근이 가능한 IP와 DNS
이름을 설정한다. `MASTER_CLUSTER_IP` 는 일반적으로 API 서버와
컨트롤러 관리자 컴포넌트에 대해 `--service-cluster-ip-range` 인수로
지정된 서비스 CIDR의 첫 번째 IP이다. `--days` 인수는 인증서가 만료되는
일 수를 설정하는데 사용된다.
또한, 아래 샘플은 기본 DNS 이름으로 `cluster.local`
사용한다고 가정한다.
./easyrsa --subject-alt-name="IP:${MASTER_IP},"\
"IP:${MASTER_CLUSTER_IP},"\
"DNS:kubernetes,"\
"DNS:kubernetes.default,"\
"DNS:kubernetes.default.svc,"\
"DNS:kubernetes.default.svc.cluster,"\
"DNS:kubernetes.default.svc.cluster.local" \
--days=10000 \
build-server-full server nopass
1. `pki/ca.crt`, `pki/issued/server.crt` 그리고 `pki/private/server.key` 를 디렉터리에 복사한다.
1. API 서버 시작 파라미터에 다음 파라미터를 채우고 추가한다.
--client-ca-file=/yourdirectory/ca.crt
--tls-cert-file=/yourdirectory/server.crt
--tls-private-key-file=/yourdirectory/server.key
### openssl
**openssl** 은 클러스터 인증서를 수동으로 생성할 수 있다.
1. ca.key를 2048bit로 생성한다.
openssl genrsa -out ca.key 2048
1. ca.key에 따라 ca.crt를 생성한다(인증서 유효 기간을 사용하려면 -days를 사용한다).
openssl req -x509 -new -nodes -key ca.key -subj "/CN=${MASTER_IP}" -days 10000 -out ca.crt
1. server.key를 2048bit로 생성한다.
openssl genrsa -out server.key 2048
1. 인증서 서명 요청(Certificate Signing Request (CSR))을 생성하기 위한 설정 파일을 생성한다.
파일에 저장하기 전에 꺾쇠 괄호(예: `<MASTER_IP>`)로
표시된 값을 실제 값으로 대체한다(예: `csr.conf`).
`MASTER_CLUSTER_IP` 의 값은 이전 하위 섹션에서
설명한 대로 API 서버의 서비스 클러스터 IP이다.
또한, 아래 샘플에서는 `cluster.local` 을 기본 DNS 도메인
이름으로 사용하고 있다고 가정한다.
[ req ]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn
[ dn ]
C = <국가(country)>
ST = <도(state)>
L = <시(city)>
O = <조직(organization)>
OU = <조직 단위(organization unit)>
CN = <MASTER_IP>
[ req_ext ]
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = kubernetes
DNS.2 = kubernetes.default
DNS.3 = kubernetes.default.svc
DNS.4 = kubernetes.default.svc.cluster
DNS.5 = kubernetes.default.svc.cluster.local
IP.1 = <MASTER_IP>
IP.2 = <MASTER_CLUSTER_IP>
[ v3_ext ]
authorityKeyIdentifier=keyid,issuer:always
basicConstraints=CA:FALSE
keyUsage=keyEncipherment,dataEncipherment
extendedKeyUsage=serverAuth,clientAuth
subjectAltName=@alt_names
1. 설정 파일을 기반으로 인증서 서명 요청을 생성한다.
openssl req -new -key server.key -out server.csr -config csr.conf
1. ca.key, ca.crt 그리고 server.csr을 사용해서 서버 인증서를 생성한다.
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out server.crt -days 10000 \
-extensions v3_ext -extfile csr.conf
1. 인증서를 본다.
openssl x509 -noout -text -in ./server.crt
마지막으로, API 서버 시작 파라미터에 동일한 파라미터를 추가한다.
### cfssl
**cfssl** 은 인증서 생성을 위한 또 다른 도구이다.
1. 아래에 표시된 대로 커맨드 라인 도구를 다운로드하여 압축을 풀고 준비한다.
사용 중인 하드웨어 아키텍처 및 cfssl 버전에 따라 샘플
명령을 조정해야 할 수도 있다.
curl -L https://github.com/cloudflare/cfssl/releases/download/v1.4.1/cfssl_1.4.1_linux_amd64 -o cfssl
chmod +x cfssl
curl -L https://github.com/cloudflare/cfssl/releases/download/v1.4.1/cfssljson_1.4.1_linux_amd64 -o cfssljson
chmod +x cfssljson
curl -L https://github.com/cloudflare/cfssl/releases/download/v1.4.1/cfssl-certinfo_1.4.1_linux_amd64 -o cfssl-certinfo
chmod +x cfssl-certinfo
1. 아티팩트(artifact)를 보유할 디렉터리를 생성하고 cfssl을 초기화한다.
mkdir cert
cd cert
../cfssl print-defaults config > config.json
../cfssl print-defaults csr > csr.json
1. CA 파일을 생성하기 위한 JSON 설정 파일을 `ca-config.json` 예시와 같이 생성한다.
{
"signing": {
"default": {
"expiry": "8760h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "8760h"
}
}
}
}
1. CA 인증서 서명 요청(CSR)을 위한 JSON 설정 파일을
`ca-csr.json` 예시와 같이 생성한다. 꺾쇠 괄호로 표시된
값을 사용하려는 실제 값으로 변경한다.
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names":[{
"C": "<국가(country)>",
"ST": "<도(state)>",
"L": "<시(city)>",
"O": "<조직(organization)>",
"OU": "<조직 단위(organization unit)>"
}]
}
1. CA 키(`ca-key.pem`)와 인증서(`ca.pem`)을 생성한다.
../cfssl gencert -initca ca-csr.json | ../cfssljson -bare ca
1. API 서버의 키와 인증서를 생성하기 위한 JSON 구성파일을
`server-csr.json` 예시와 같이 생성한다. 꺾쇠 괄호 안의 값을
사용하려는 실제 값으로 변경한다. `MASTER_CLUSTER_IP`
이전 하위 섹션에서 설명한 API 서버의 클러스터 IP이다.
아래 샘플은 기본 DNS 도메인 이름으로 `cluster.local`
사용한다고 가정한다.
{
"CN": "kubernetes",
"hosts": [
"127.0.0.1",
"<MASTER_IP>",
"<MASTER_CLUSTER_IP>",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [{
"C": "<국가(country)>",
"ST": "<도(state)>",
"L": "<시(city)>",
"O": "<조직(organization)>",
"OU": "<조직 단위(organization unit)>"
}]
}
1. API 서버 키와 인증서를 생성하면, 기본적으로
`server-key.pem``server.pem` 파일에 각각 저장된다.
../cfssl gencert -ca=ca.pem -ca-key=ca-key.pem \
--config=ca-config.json -profile=kubernetes \
server-csr.json | ../cfssljson -bare server
## 자체 서명된 CA 인증서의 배포
클라이언트 노드는 자체 서명된 CA 인증서를 유효한 것으로 인식하지 않을 수 있다.
비-프로덕션 디플로이먼트 또는 회사 방화벽 뒤에서 실행되는
디플로이먼트의 경우, 자체 서명된 CA 인증서를 모든 클라이언트에
배포하고 유효한 인증서의 로컬 목록을 새로 고칠 수 있다.
각 클라이언트에서, 다음 작업을 수행한다.
```bash
sudo cp ca.crt /usr/local/share/ca-certificates/kubernetes.crt
sudo update-ca-certificates
```
```
Updating certificates in /etc/ssl/certs...
1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d....
done.
```
## 인증서 API
`certificates.k8s.io` API를 사용해서
[여기](/docs/tasks/tls/managing-tls-in-a-cluster)에
설명된 대로 인증에 사용할 x509 인증서를 프로비전 할 수 있다.
{{% /capture %}}

View File

@ -17,7 +17,6 @@ weight: 10
가이드를 고르기 전에, 몇 가지 고려사항이 있다.
- 단지 자신의 컴퓨터에 쿠버네티스를 테스트를 하는지, 또는 고가용성의 멀티 노드 클러스터를 만들려고 하는지에 따라 니즈에 가장 적절한 배포판을 고르자.
- **만약 고가용성을 만들려고 한다면**, [여러 영역에서의 클러스터](/ko/docs/concepts/cluster-administration/federation/) 설정에 대해 배우자.
- [구글 쿠버네티스 엔진](https://cloud.google.com/kubernetes-engine/)과 같은 **호스팅된 쿠버네티스 클러스터** 를 사용할 것인지, **자신의 클러스터에 호스팅할 것인지**?
- 클러스터가 **온프레미스** 인지, 또는 **클라우드(IaaS)** 인지? 쿠버네티스는 하이브리드 클러스터를 직접적으로 지원하지는 않는다. 대신에, 사용자는 여러 클러스터를 구성할 수 있다.
- **만약 온프레미스에서 쿠버네티스를 구성한다면**, 어떤 [네트워킹 모델](/docs/concepts/cluster-administration/networking/)이 가장 적합한지 고려한다.
@ -35,7 +34,7 @@ weight: 10
* 어떻게 [노드 관리](/ko/docs/concepts/architecture/nodes/)를 하는지 배워보자.
* 공유된 클러스터의 [자원 할당량](/docs/concepts/policy/resource-quotas/)을 어떻게 셋업하고 관리할 것인지 배워보자.
* 공유된 클러스터의 [리소스 쿼터](/ko/docs/concepts/policy/resource-quotas/)를 어떻게 셋업하고 관리할 것인지 배워보자.
## 클러스터 보안

View File

@ -0,0 +1,86 @@
---
title: kubelet 가비지(Garbage) 수집 설정하기
content_template: templates/concept
weight: 70
---
{{% capture overview %}}
가비지 수집은 사용되지 않는 이미지들과 컨테이너들을 정리하는 kubelet의 유용한 기능이다. Kubelet은 1분마다 컨테이너들에 대하여 가비지 수집을 수행하며, 5분마다 이미지들에 대하여 가비지 수집을 수행한다.
별도의 가비지 수집 도구들을 사용하는 것은, 이러한 도구들이 존재할 수도 있는 컨테이너들을 제거함으로써 kubelet 을 중단시킬 수도 있으므로 권장하지 않는다.
{{% /capture %}}
{{% capture body %}}
## 이미지 수집
쿠버네티스는 cadvisor와 imageManager를 통하여 모든 이미지들의
라이프사이클을 관리한다.
이미지들에 대한 가비지 수집 정책에는 다음 2가지 요소가 고려된다:
`HighThresholdPercent``LowThresholdPercent`. 임계값을 초과하는
디스크 사용량은 가비지 수집을 트리거 한다. 가비지 수집은 낮은 입계값에 도달 할 때까지 최근에 가장 적게 사용한
이미지들을 삭제한다.
## 컨테이너 수집
컨테이너에 대한 가비지 수집 정책은 세 가지 사용자 정의 변수들을 고려한다: `MinAge` 는 컨테이너를 가비지 수집 할 수 있는 최소 연령이다. `MaxPerPodContainer` 는 모든 단일 파드 (UID, 컨테이너 이름) 쌍이 가질 수 있는
최대 비활성 컨테이너의 수량이다. `MaxContainers` 죽은 컨테이너의 최대 수량이다. 이러한 변수는 `MinAge` 를 0으로 설정하고, `MaxPerPodContainer``MaxContainers` 를 각각 0 보다 작게 설정해서 비활성화 할 수 있다.
Kubelet은 미확인, 삭제 또는 앞에서 언급 한 플래그가 설정 한 경계를 벗어나거나, 확인되지 않은 컨테이너에 대해 조치를 취한다. 일반적으로 가장 오래된 컨테이너가 먼저 제거된다. `MaxPerPodContainer``MaxContainer` 는 파드 당 최대 컨테이너 수 (`MaxPerPodContainer`)가 허용 가능한 범위의 전체 죽은 컨테이너의 수(`MaxContainers`)를 벗어나는 상황에서 잠재적으로 서로 충돌할 수 있습니다. 이러한 상황에서 `MaxPerPodContainer` 가 조정된다: 최악의 시나리오는 `MaxPerPodContainer` 를 1로 다운그레이드하고 가장 오래된 컨테이너를 제거하는 것이다. 추가로, 삭제된 파드가 소유 한 컨테이너는 `MinAge` 보다 오래된 컨테이너가 제거된다.
kubelet이 관리하지 않는 컨테이너는 컨테이너 가비지 수집 대상이 아니다.
## 사용자 설정
사용자는 후술될 kubelet 플래그들을 통하여 이미지 가비지 수집을 조정하기 위하여 다음의 임계값을 조정할 수 있다.
1. `image-gc-high-threshold`, 이미지 가비지 수집을 발생시키는 디스크 사용량의 비율로
기본값은 85% 이다.
2. `image-gc-low-threshold`, 이미지 가비지 수집을 더 이상 시도하지 않는 디스크 사용량의 비율로
기본값은 80% 이다.
또한 사용자는 다음의 kubelet 플래그를 통해 가비지 수집 정책을 사용자 정의 할 수 있다.
1. `minimum-container-ttl-duration`, 종료된 컨테이너가 가비지 수집
되기 전의 최소 시간. 기본 값은 0 분이며, 이 경우 모든 종료된 컨테이너는 바로 가비지 수집의 대상이 된다.
2. `maximum-dead-containers-per-container`, 컨테이너가 보유할 수 있는 오래된
인스턴스의 최대 수. 기본 값은 1 이다.
3. `maximum-dead-containers`, 글로벌하게 보유 할 컨테이너의 최대 오래된 인스턴스의 최대 수.
기본 값은 -1이며, 이 경우 인스턴스 수의 제한은 없다.
컨테이너들은 유용성이 만료되기 이전에도 가비지 수집이 될 수 있다. 이러한 컨테이너들은
문제 해결에 도움이 될 수 있는 로그나 다른 데이터를 포함하고 있을 수 있다. 컨테이너 당 적어도
1개의 죽은 컨테이너가 허용될 수 있도록 `maximum-dead-containers-per-container`
값을 충분히 큰 값으로 지정하는 것을 권장한다. 동일한 이유로 `maximum-dead-containers`
의 값도 상대적으로 더 큰 값을 권장한다.
자세한 내용은 [해당 이슈](https://github.com/kubernetes/kubernetes/issues/13287)를 참고한다.
## 사용 중단(Deprecation)
문서에 있는 몇 가지 kubelet의 가비지 수집 특징은 향후에 kubelet 축출(eviction) 기능으로 대체될 예정이다.
포함:
| 기존 Flag | 신규 Flag | 근거 |
| ------------- | -------- | --------- |
| `--image-gc-high-threshold` | `--eviction-hard` or `--eviction-soft` | 기존의 축출 신호로 인하여 이미지 가비지 수집이 트리거 될 수 있음 |
| `--image-gc-low-threshold` | `--eviction-minimum-reclaim` | 축출 리클레임 기능이 동일한 행동을 수행 |
| `--maximum-dead-containers` | | 컨테이너의 외부 영역에 오래된 로그가 저장되어 사용중단(deprecated)됨 |
| `--maximum-dead-containers-per-container` | | 컨테이너의 외부 영역에 오래된 로그가 저장되어 사용중단(deprecated)됨 |
| `--minimum-container-ttl-duration` | | 컨테이너의 외부 영역에 오래된 로그가 저장되어 사용중단(deprecated)됨 |
| `--low-diskspace-threshold-mb` | `--eviction-hard` or `eviction-soft` | 축출이 다른 리소스에 대한 디스크 임계값을 일반화 함 |
| `--outofdisk-transition-frequency` | `--eviction-pressure-transition-period` | 축출이 다른 리소스로의 디스크 압력전환을 일반화 함 |
{{% /capture %}}
{{% capture whatsnext %}}
자세한 내용은 [리소스 부족 처리 구성](/docs/tasks/administer-cluster/out-of-resource/)를 본다.
{{% /capture %}}

View File

@ -0,0 +1,267 @@
---
title: 로깅 아키텍처
content_template: templates/concept
weight: 60
---
{{% capture overview %}}
애플리케이션과 시스템 로그는 클러스터 내부에서 발생하는 상황을 이해하는 데 도움이 된다. 로그는 문제를 디버깅하고 클러스터 활동을 모니터링하는 데 특히 유용하다. 대부분의 최신 애플리케이션에는 일종의 로깅 메커니즘이 있다. 따라서, 대부분의 컨테이너 엔진은 일종의 로깅을 지원하도록 설계되었다. 컨테이너화된 애플리케이션에 가장 쉽고 가장 널리 사용되는 로깅 방법은 표준 출력과 표준 에러 스트림에 작성하는 것이다.
그러나, 일반적으로 컨테이너 엔진이나 런타임에서 제공하는 기본 기능은 완전한 로깅 솔루션으로 충분하지 않다. 예를 들어, 컨테이너가 크래시되거나, 파드가 축출되거나, 노드가 종료된 경우에도 여전히 애플리케이션의 로그에 접근하려고 한다. 따라서, 로그는 노드, 파드 또는 컨테이너와는 독립적으로 별도의 스토리지와 라이프사이클을 가져야 한다. 이 개념을 _클러스터-레벨-로깅_ 이라고 한다. 클러스터-레벨 로깅은 로그를 저장하고, 분석하고, 쿼리하기 위해 별도의 백엔드가 필요하다. 쿠버네티스는 로그 데이터를 위한 네이티브 스토리지 솔루션을 제공하지 않지만, 기존의 많은 로깅 솔루션을 쿠버네티스 클러스터에 통합할 수 있다.
{{% /capture %}}
{{% capture body %}}
클러스터-레벨 로깅 아키텍처는 로깅 백엔드가
클러스터 내부 또는 외부에 존재한다고 가정하여 설명한다. 클러스터-레벨
로깅에 관심이 없는 경우에도, 노드에서 로그를 저장하고
처리하는 방법에 대한 설명이 여전히 유용할 수 있다.
## 쿠버네티스의 기본 로깅
이 섹션에서는, 쿠버네티스에서 표준 출력 스트림으로 데이터를
출력하는 기본 로깅의 예시를 볼 수 있다. 이 데모에서는
일부 텍스트를 초당 한 번씩 표준 출력에 쓰는 컨테이너와 함께
[파드 명세](/examples/debug/counter-pod.yaml)를 사용한다.
{{< codenew file="debug/counter-pod.yaml" >}}
이 파드를 실행하려면, 다음의 명령을 사용한다.
```shell
kubectl apply -f https://k8s.io/examples/debug/counter-pod.yaml
```
출력은 다음과 같다.
```
pod/counter created
```
로그를 가져오려면, 다음과 같이 `kubectl logs` 명령을 사용한다.
```shell
kubectl logs counter
```
출력은 다음과 같다.
```
0: Mon Jan 1 00:00:00 UTC 2001
1: Mon Jan 1 00:00:01 UTC 2001
2: Mon Jan 1 00:00:02 UTC 2001
...
```
컨테이너가 크래시된 경우, `kubectl logs``--previous` 플래그를 사용해서 컨테이너의 이전 인스턴스에 대한 로그를 검색할 수 있다. 파드에 여러 컨테이너가 있는 경우, 명령에 컨테이너 이름을 추가하여 접근하려는 컨테이너 로그를 지정해야 한다. 자세한 내용은 [`kubectl logs` 문서](/docs/reference/generated/kubectl/kubectl-commands#logs)를 참조한다.
## 노드 레벨에서의 로깅
![노드 레벨 로깅](/images/docs/user-guide/logging/logging-node-level.png)
컨테이너화된 애플리케이션이 `stdout(표준 출력)``stderr(표준 에러)` 에 쓰는 모든 것은 컨테이너 엔진에 의해 어딘가에서 처리와 리디렉션 된다. 예를 들어, 도커 컨테이너 엔진은 이 두 스트림을 [로깅 드라이버](https://docs.docker.com/engine/admin/logging/overview)로 리디렉션 한다. 이 드라이버는 쿠버네티스에서 json 형식의 파일에 작성하도록 구성된다.
{{< note >}}
도커 json 로깅 드라이버는 각 라인을 별도의 메시지로 취급한다. 도커 로깅 드라이버를 사용하는 경우, 멀티-라인 메시지를 직접 지원하지 않는다. 로깅 에이전트 레벨 이상에서 멀티-라인 메시지를 처리해야 한다.
{{< /note >}}
기본적으로, 컨테이너가 다시 시작되면, kubelet은 종료된 컨테이너 하나를 로그와 함께 유지한다. 파드가 노드에서 축출되면, 해당하는 모든 컨테이너도 로그와 함께 축출된다.
노드-레벨 로깅에서 중요한 고려 사항은 로그 로테이션을 구현하여,
로그가 노드에서 사용 가능한 모든 스토리지를 사용하지 않도록 하는 것이다. 쿠버네티스는
현재 로그 로테이션에 대한 의무는 없지만, 디플로이먼트 도구로
이를 해결하기 위한 솔루션을 설정해야 한다.
예를 들어, `kube-up.sh` 스크립트에 의해 배포된 쿠버네티스 클러스터에는,
매시간 실행되도록 구성된 [`logrotate`](https://linux.die.net/man/8/logrotate)
도구가 있다. 예를 들어, 도커의 `log-opt` 를 사용하여 애플리케이션의 로그를
자동으로 로테이션을 하도록 컨테이너 런타임을 설정할 수도 있다.
`kube-up.sh` 스크립트에서, 후자의 접근 방식은 GCP의 COS 이미지에 사용되며,
전자의 접근 방식은 다른 환경에서 사용된다. 두 경우 모두,
기본적으로 로그 파일이 10MB를 초과하면 로테이션이 되도록 구성된다.
예를 들어, `kube-up.sh` 가 해당 [스크립트][cosConfigureHelper]에서
GCP의 COS 이미지 로깅을 설정하는 방법에 대한 자세한 정보를 찾을 수 있다.
기본 로깅 예제에서와 같이 [`kubectl logs`](/docs/reference/generated/kubectl/kubectl-commands#logs)를
실행하면, 노드의 kubelet이 요청을 처리하고
로그 파일에서 직접 읽은 다음, 응답의 내용을 반환한다.
{{< note >}}
현재, 일부 외부 시스템에서 로테이션을 수행한 경우,
`kubectl logs` 를 통해 최신 로그 파일의 내용만
사용할 수 있다. 예를 들어, 10MB 파일이 있으면, `logrotate`
로테이션을 수행하고 두 개의 파일이 생긴다(크기가 10MB인 파일 하나와 비어있는 파일).
그 후 `kubectl logs` 는 빈 응답을 반환한다.
{{< /note >}}
[cosConfigureHelper]: https://github.com/kubernetes/kubernetes/blob/{{< param "githubbranch" >}}/cluster/gce/gci/configure-helper.sh
### 시스템 컴포넌트 로그
시스템 컴포넌트에는 컨테이너에서 실행되는 것과 컨테이너에서 실행되지 않는 두 가지 유형이 있다.
예를 들면 다음과 같다.
* 쿠버네티스 스케줄러와 kube-proxy는 컨테이너에서 실행된다.
* Kubelet과 컨테이너 런타임(예: 도커)은 컨테이너에서 실행되지 않는다.
systemd를 사용하는 시스템에서, kubelet과 컨테이너 런타임은 journald에 작성한다.
systemd를 사용하지 않으면, `/var/log` 디렉터리의 `.log` 파일에 작성한다.
컨테이너 내부의 시스템 컴포넌트는 기본 로깅 메커니즘을 무시하고,
항상 `/var/log` 디렉터리에 기록한다. 그것은 [klog][klog]
로깅 라이브러리를 사용한다. [로깅에 대한 개발 문서](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/logging.md)에서
해당 컴포넌트의 로깅 심각도(severity)에 대한 규칙을 찾을 수 있다.
컨테이너 로그와 마찬가지로, `/var/log` 디렉터리의 시스템 컴포넌트 로그를
로테이트해야 한다. `kube-up.sh` 스크립트로 구축한 쿠버네티스 클러스터에서
로그는 매일 또는 크기가 100MB를 초과하면
`logrotate` 도구에 의해 로테이트가 되도록 구성된다.
[klog]: https://github.com/kubernetes/klog
## 클러스터 레벨 로깅 아키텍처
쿠버네티스는 클러스터-레벨 로깅을 위한 네이티브 솔루션을 제공하지 않지만, 고려해야 할 몇 가지 일반적인 접근 방법을 고려할 수 있다. 여기 몇 가지 옵션이 있다.
* 모든 노드에서 실행되는 노드-레벨 로깅 에이전트를 사용한다.
* 애플리케이션 파드에 로깅을 위한 전용 사이드카 컨테이너를 포함한다.
* 애플리케이션 내에서 로그를 백엔드로 직접 푸시한다.
### 노드 로깅 에이전트 사용
![노드 레벨 로깅 에이전트 사용](/images/docs/user-guide/logging/logging-with-node-agent.png)
각 노드에 _노드-레벨 로깅 에이전트_ 를 포함시켜 클러스터-레벨 로깅을 구현할 수 있다. 로깅 에이전트는 로그를 노출하거나 로그를 백엔드로 푸시하는 전용 도구이다. 일반적으로, 로깅 에이전트는 해당 노드의 모든 애플리케이션 컨테이너에서 로그 파일이 있는 디렉터리에 접근할 수 있는 컨테이너이다.
로깅 에이전트는 모든 노드에서 실행해야 하므로, 이를 데몬셋 레플리카, 매니페스트 파드 또는 노드의 전용 네이티브 프로세스로 구현하는 것이 일반적이다. 그러나 후자의 두 가지 접근법은 더 이상 사용되지 않으며 절대 권장하지 않는다.
쿠버네티스 클러스터는 노드-레벨 로깅 에이전트를 사용하는 것이 가장 일반적이며 권장되는 방법으로, 이는 노드별 하나의 에이전트만 생성하며, 노드에서 실행되는 애플리케이션을 변경할 필요가 없기 때문이다. 그러나, 노드-레벨 로깅은 _애플리케이션의 표준 출력과 표준 에러에 대해서만 작동한다_ .
쿠버네티스는 로깅 에이전트를 지정하지 않지만, 쿠버네티스 릴리스에는 두 가지 선택적인 로깅 에이전트(Google 클라우드 플랫폼과 함께 사용하기 위한 [스택드라이버(Stackdriver) 로깅](/docs/user-guide/logging/stackdriver)과 [엘라스틱서치(Elasticsearch)](/ko/docs/tasks/debug-application-cluster/logging-elasticsearch-kibana/))가 패키지로 함께 제공된다. 전용 문서에서 자세한 정보와 지침을 찾을 수 있다. 두 가지 다 사용자 정의 구성이 된 [fluentd](http://www.fluentd.org/)를 에이전트로써 노드에서 사용한다.
### 로깅 에이전트와 함께 사이드카 컨테이너 사용
다음 중 한 가지 방법으로 사이드카 컨테이너를 사용할 수 있다.
* 사이드카 컨테이너는 애플리케이션 로그를 자체 `stdout` 으로 스트리밍한다.
* 사이드카 컨테이너는 로깅 에이전트를 실행하며, 애플리케이션 컨테이너에서 로그를 가져오도록 구성된다.
#### 사이드카 컨테이너 스트리밍
![스트리밍 컨테이너가 있는 사이드카 컨테이너](/images/docs/user-guide/logging/logging-with-streaming-sidecar.png)
사이드카 컨테이너를 자체 `stdout``stderr` 스트림으로
스트리밍하면, 각 노드에서 이미 실행 중인 kubelet과 로깅 에이전트를
활용할 수 있다. 사이드카 컨테이너는 파일, 소켓
또는 journald에서 로그를 읽는다. 각 개별 사이드카 컨테이너는 자체 `stdout`
또는 `stderr` 스트림에 로그를 출력한다.
이 방법을 사용하면 애플리케이션의 다른 부분에서 여러 로그 스트림을
분리할 수 ​​있고, 이 중 일부는 `stdout` 또는 `stderr`
작성하기 위한 지원이 부족할 수 있다. 로그를 리디렉션하는 로직은
미미하기 때문에, 큰 오버헤드가 거의 없다. 또한,
`stdout``stderr` 가 kubelet에서 처리되므로, `kubectl logs` 와 같은
빌트인 도구를 사용할 수 있다.
다음의 예를 고려해보자. 파드는 단일 컨테이너를 실행하고, 컨테이너는
서로 다른 두 가지 형식을 사용하여, 서로 다른 두 개의 로그 파일에 기록한다. 파드에 대한
구성 파일은 다음과 같다.
{{< codenew file="admin/logging/two-files-counter-pod.yaml" >}}
두 컴포넌트를 컨테이너의 `stdout` 스트림으로 리디렉션한 경우에도, 동일한 로그
스트림에 서로 다른 형식의 로그 항목을 갖는 것은
알아보기 힘들다. 대신, 두 개의 사이드카 컨테이너를 도입할 수 있다. 각 사이드카
컨테이너는 공유 볼륨에서 특정 로그 파일을 테일(tail)한 다음 로그를
자체 `stdout` 스트림으로 리디렉션할 수 있다.
다음은 사이드카 컨테이너가 두 개인 파드에 대한 구성 파일이다.
{{< codenew file="admin/logging/two-files-counter-pod-streaming-sidecar.yaml" >}}
이제 이 파드를 실행하면, 다음의 명령을 실행하여 각 로그 스트림에
개별적으로 접근할 수 있다.
```shell
kubectl logs counter count-log-1
```
```
0: Mon Jan 1 00:00:00 UTC 2001
1: Mon Jan 1 00:00:01 UTC 2001
2: Mon Jan 1 00:00:02 UTC 2001
...
```
```shell
kubectl logs counter count-log-2
```
```
Mon Jan 1 00:00:00 UTC 2001 INFO 0
Mon Jan 1 00:00:01 UTC 2001 INFO 1
Mon Jan 1 00:00:02 UTC 2001 INFO 2
...
```
클러스터에 설치된 노드-레벨 에이전트는 추가 구성없이
자동으로 해당 로그 스트림을 선택한다. 원한다면, 소스 컨테이너에
따라 로그 라인을 파싱(parse)하도록 에이전트를 구성할 수 있다.
참고로, CPU 및 메모리 사용량이 낮음에도 불구하고(cpu에 대한 몇 밀리코어의
요구와 메모리에 대한 몇 메가바이트의 요구), 로그를 파일에 기록한 다음
`stdout` 으로 스트리밍하면 디스크 사용량은 두 배가 될 수 있다. 단일 파일에
쓰는 애플리케이션이 있는 경우, 일반적으로 스트리밍
사이드카 컨테이너 방식을 구현하는 대신 `/dev/stdout` 을 대상으로
설정하는 것이 더 낫다.
사이드카 컨테이너를 사용하여 애플리케이션 자체에서 로테이션할 수 없는
로그 파일을 로테이션할 수도 있다. 이 방법의 예로는
정기적으로 logrotate를 실행하는 작은 컨테이너를 두는 것이다.
그러나, `stdout``stderr` 을 직접 사용하고 로테이션과
유지 정책을 kubelet에 두는 것이 권장된다.
#### 로깅 에이전트가 있는 사이드카 컨테이너
![로깅 에이전트가 있는 사이드카 컨테이너](/images/docs/user-guide/logging/logging-with-sidecar-agent.png)
노드-레벨 로깅 에이전트가 상황에 맞게 충분히 유연하지 않은 경우,
애플리케이션과 함께 실행하도록 특별히 구성된 별도의 로깅 에이전트를 사용하여
사이드카 컨테이너를 생성할 수 있다.
{{< note >}}
사이드카 컨테이너에서 로깅 에이전트를 사용하면
상당한 리소스 소비로 이어질 수 있다. 게다가, kubelet에 의해
제어되지 않기 때문에, `kubectl logs` 명령을 사용하여 해당 로그에
접근할 수 없다.
{{< /note >}}
예를 들어, 로깅 에이전트로 fluentd를 사용하는 [스택드라이버](/docs/tasks/debug-application-cluster/logging-stackdriver/)를
사용할 수 있다. 여기에 이 방법을 구현하는 데 사용할 수 있는
두 가지 구성 파일이 있다. 첫 번째 파일에는
fluentd를 구성하기 위한 [컨피그맵](/docs/tasks/configure-pod-container/configure-pod-configmap/)이 포함되어 있다.
{{< codenew file="admin/logging/fluentd-sidecar-config.yaml" >}}
{{< note >}}
fluentd의 구성은 이 문서의 범위를 벗어난다.
fluentd를 구성하는 것에 대한 자세한 내용은,
[공식 fluentd 문서](http://docs.fluentd.org/)를 참고한다.
{{< /note >}}
두 번째 파일은 fluentd가 실행되는 사이드카 컨테이너가 있는 파드를 설명한다.
파드는 fluentd가 구성 데이터를 가져올 수 있는 볼륨을 마운트한다.
{{< codenew file="admin/logging/two-files-counter-pod-agent-sidecar.yaml" >}}
얼마 후 스택드라이버 인터페이스에서 로그 메시지를 찾을 수 있다.
이것은 단지 예시일 뿐이며 실제로 애플리케이션 컨테이너 내의
모든 소스에서 읽은 fluentd를 로깅 에이전트로 대체할 수 있다는 것을
기억한다.
### 애플리케이션에서 직접 로그 노출
![애플리케이션에서 직접 로그 노출](/images/docs/user-guide/logging/logging-from-application.png)
모든 애플리케이션에서 직접 로그를 노출하거나 푸시하여 클러스터-레벨 로깅을
구현할 수 있다. 그러나, 이러한 로깅 메커니즘의 구현은
쿠버네티스의 범위를 벗어난다.
{{% /capture %}}

View File

@ -0,0 +1,457 @@
---
title: 리소스 관리
content_template: templates/concept
weight: 40
---
{{% capture overview %}}
애플리케이션을 배포하고 서비스를 통해 노출했다. 이제 무엇을 해야 할까? 쿠버네티스는 확장과 업데이트를 포함하여, 애플리케이션 배포를 관리하는 데 도움이 되는 여러 도구를 제공한다. 더 자세히 설명할 기능 중에는 [구성 파일](/ko/docs/concepts/configuration/overview/)과 [레이블](/ko/docs/concepts/overview/working-with-objects/labels/)이 있다.
{{% /capture %}}
{{% capture body %}}
## 리소스 구성 구성하기
많은 애플리케이션들은 디플로이먼트 및 서비스와 같은 여러 리소스를 필요로 한다. 여러 리소스의 관리는 동일한 파일에 그룹화하여 단순화할 수 있다(YAML에서 `---` 로 구분). 예를 들면 다음과 같다.
{{< codenew file="application/nginx-app.yaml" >}}
단일 리소스와 동일한 방식으로 여러 리소스를 생성할 수 있다.
```shell
kubectl apply -f https://k8s.io/examples/application/nginx-app.yaml
```
```shell
service/my-nginx-svc created
deployment.apps/my-nginx created
```
리소스는 파일에 표시된 순서대로 생성된다. 따라서, 스케줄러가 디플로이먼트와 같은 컨트롤러에서 생성한 서비스와 관련된 파드를 분산시킬 수 있으므로, 서비스를 먼저 지정하는 것이 가장 좋다.
`kubectl apply` 는 여러 개의 `-f` 인수도 허용한다.
```shell
kubectl apply -f https://k8s.io/examples/application/nginx/nginx-svc.yaml -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml
```
그리고 개별 파일 대신 또는 추가로 디렉터리를 지정할 수 있다.
```shell
kubectl apply -f https://k8s.io/examples/application/nginx/
```
`kubectl` 은 접미사가 `.yaml`, `.yml` 또는 `.json` 인 파일을 읽는다.
동일한 마이크로서비스 또는 애플리케이션 티어(tier)와 관련된 리소스를 동일한 파일에 배치하고, 애플리케이션과 연관된 모든 파일을 동일한 디렉터리에 그룹화하는 것이 좋다. 애플리케이션의 티어가 DNS를 사용하여 서로 바인딩되면, 스택의 모든 컴포넌트를 일괄로 배포할 수 있다.
URL을 구성 소스로 지정할 수도 있다. 이는 github에 체크인된 구성 파일에서 직접 배포하는 데 편리하다.
```shell
kubectl apply -f https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/application/nginx/nginx-deployment.yaml
```
```shell
deployment.apps/my-nginx created
```
## kubectl에서의 대량 작업
`kubectl` 이 대량으로 수행할 수 있는 작업은 리소스 생성만이 아니다. 또한 다른 작업을 수행하기 위해, 특히 작성한 동일한 리소스를 삭제하기 위해 구성 파일에서 리소스 이름을 추출할 수도 있다.
```shell
kubectl delete -f https://k8s.io/examples/application/nginx-app.yaml
```
```shell
deployment.apps "my-nginx" deleted
service "my-nginx-svc" deleted
```
두 개의 리소스만 있는 경우, 리소스/이름 구문을 사용하여 커맨드 라인에서 둘다 모두 쉽게 지정할 수도 있다.
```shell
kubectl delete deployments/my-nginx services/my-nginx-svc
```
리소스가 많을 경우, `-l` 또는 `--selector` 를 사용하여 지정된 셀렉터(레이블 쿼리)를 지정하여 레이블별로 리소스를 필터링하는 것이 더 쉽다.
```shell
kubectl delete deployment,services -l app=nginx
```
```shell
deployment.apps "my-nginx" deleted
service "my-nginx-svc" deleted
```
`kubectl` 은 입력을 받아들이는 것과 동일한 구문으로 리소스 이름을 출력하므로, `$()` 또는 `xargs` 를 사용하여 작업을 쉽게 연결할 수 있다.
```shell
kubectl get $(kubectl create -f docs/concepts/cluster-administration/nginx/ -o name | grep service)
```
```shell
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-nginx-svc LoadBalancer 10.0.0.208 <pending> 80/TCP 0s
```
위의 명령을 사용하여, 먼저 `examples/application/nginx/` 에 리소스를 생성하고 `-o name` 출력 형식으로 생성한 리소스를 출력한다(각 리소스를 resource/name으로 출력).
그런 다음 "service"만 `grep` 한 다음 `kubectl get` 으로 출력한다.
특정 디렉터리 내의 여러 서브 디렉터리에서 리소스를 구성하는 경우, `--filename,-f` 플래그와 함께 `--recursive` 또는 `-R` 을 지정하여, 서브 디렉터리에 대한 작업을 재귀적으로 수행할 수도 있다.
예를 들어, 리소스 유형별로 구성된 개발 환경에 필요한 모든 {{< glossary_tooltip text="매니페스트" term_id="manifest" >}}를 보유하는 `project/k8s/development` 디렉터리가 있다고 가정하자.
```
project/k8s/development
├── configmap
│   └── my-configmap.yaml
├── deployment
│   └── my-deployment.yaml
└── pvc
└── my-pvc.yaml
```
기본적으로, `project/k8s/development` 에서 대량 작업을 수행하면, 서브 디렉터리를 처리하지 않고, 디렉터리의 첫 번째 레벨에서 중지된다. 다음 명령을 사용하여 이 디렉터리에 리소스를 생성하려고 하면, 오류가 발생할 것이다.
```shell
kubectl apply -f project/k8s/development
```
```shell
error: you must provide one or more resources by argument or filename (.json|.yaml|.yml|stdin)
```
대신, 다음과 같이 `--filename,-f` 플래그와 함께 `--recursive` 또는 `-R` 플래그를 지정한다.
```shell
kubectl apply -f project/k8s/development --recursive
```
```shell
configmap/my-config created
deployment.apps/my-deployment created
persistentvolumeclaim/my-pvc created
```
`--recursive` 플래그는 `kubectl {create,get,delete,describe,rollout}` 등과 같이 `--filename,-f` 플래그를 허용하는 모든 작업에서 작동한다.
`--recursive` 플래그는 여러 개의 `-f` 인수가 제공될 때도 작동한다.
```shell
kubectl apply -f project/k8s/namespaces -f project/k8s/development --recursive
```
```shell
namespace/development created
namespace/staging created
configmap/my-config created
deployment.apps/my-deployment created
persistentvolumeclaim/my-pvc created
```
`kubectl` 에 대해 더 자세히 알고 싶다면, [kubectl 개요](/docs/reference/kubectl/overview/)를 참조한다.
## 효과적인 레이블 사용
지금까지 사용한 예는 모든 리소스에 최대 한 개의 레이블만 적용하는 것이었다. 세트를 서로 구별하기 위해 여러 레이블을 사용해야 하는 많은 시나리오가 있다.
예를 들어, 애플리케이션마다 `app` 레이블에 다른 값을 사용하지만, [방명록 예제](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/guestbook/)와 같은 멀티-티어 애플리케이션은 각 티어를 추가로 구별해야 한다. 프론트엔드는 다음의 레이블을 가질 수 있다.
```yaml
labels:
app: guestbook
tier: frontend
```
Redis 마스터와 슬레이브는 프론트엔드와 다른 `tier` 레이블을 가지지만, 아마도 추가로 `role` 레이블을 가질 것이다.
```yaml
labels:
app: guestbook
tier: backend
role: master
```
그리고
```yaml
labels:
app: guestbook
tier: backend
role: slave
```
레이블은 레이블로 지정된 차원에 따라 리소스를 분할하고 사용할 수 있게 한다.
```shell
kubectl apply -f examples/guestbook/all-in-one/guestbook-all-in-one.yaml
kubectl get pods -Lapp -Ltier -Lrole
```
```shell
NAME READY STATUS RESTARTS AGE APP TIER ROLE
guestbook-fe-4nlpb 1/1 Running 0 1m guestbook frontend <none>
guestbook-fe-ght6d 1/1 Running 0 1m guestbook frontend <none>
guestbook-fe-jpy62 1/1 Running 0 1m guestbook frontend <none>
guestbook-redis-master-5pg3b 1/1 Running 0 1m guestbook backend master
guestbook-redis-slave-2q2yf 1/1 Running 0 1m guestbook backend slave
guestbook-redis-slave-qgazl 1/1 Running 0 1m guestbook backend slave
my-nginx-divi2 1/1 Running 0 29m nginx <none> <none>
my-nginx-o0ef1 1/1 Running 0 29m nginx <none> <none>
```
```shell
kubectl get pods -lapp=guestbook,role=slave
```
```shell
NAME READY STATUS RESTARTS AGE
guestbook-redis-slave-2q2yf 1/1 Running 0 3m
guestbook-redis-slave-qgazl 1/1 Running 0 3m
```
## 카나리(canary) 디플로이먼트
여러 레이블이 필요한 또 다른 시나리오는 동일한 컴포넌트의 다른 릴리스 또는 구성의 디플로이먼트를 구별하는 것이다. 새 릴리스가 완전히 롤아웃되기 전에 실제 운영 트래픽을 수신할 수 있도록 새로운 애플리케이션 릴리스(파드 템플리트의 이미지 태그를 통해 지정됨)의 *카나리* 를 이전 릴리스와 나란히 배포하는 것이 일반적이다.
예를 들어, `track` 레이블을 사용하여 다른 릴리스를 구별할 수 있다.
기본(primary), 안정(stable) 릴리스에는 값이 `stable``track` 레이블이 있다.
```yaml
name: frontend
replicas: 3
...
labels:
app: guestbook
tier: frontend
track: stable
...
image: gb-frontend:v3
```
그런 다음 서로 다른 값(예: `canary`)으로 `track` 레이블을 전달하는 방명록 프론트엔드의 새 릴리스를 생성하여, 두 세트의 파드가 겹치지 않도록 할 수 있다.
```yaml
name: frontend-canary
replicas: 1
...
labels:
app: guestbook
tier: frontend
track: canary
...
image: gb-frontend:v4
```
프론트엔드 서비스는 레이블의 공통 서브셋을 선택하여(즉, `track` 레이블 생략) 두 레플리카 세트에 걸쳐 있으므로, 트래픽이 두 애플리케이션으로 리디렉션된다.
```yaml
selector:
app: guestbook
tier: frontend
```
안정 및 카나리 릴리스의 레플리카 수를 조정하여 실제 운영 트래픽을 수신할 각 릴리스의 비율을 결정한다(이 경우, 3:1).
확신이 들면, 안정 릴리스의 track을 새로운 애플리케이션 릴리스로 업데이트하고 카나리를 제거할 수 있다.
보다 구체적인 예시는, [Ghost 배포에 대한 튜토리얼](https://github.com/kelseyhightower/talks/tree/master/kubecon-eu-2016/demo#deploy-a-canary)을 확인한다.
## 레이블 업데이트
새로운 리소스를 만들기 전에 기존 파드 및 기타 리소스의 레이블을 다시 지정해야 하는 경우가 있다. 이것은 `kubectl label` 로 수행할 수 있다.
예를 들어, 모든 nginx 파드에 프론트엔드 티어로 레이블을 지정하려면, 간단히 다음과 같이 실행한다.
```shell
kubectl label pods -l app=nginx tier=fe
```
```shell
pod/my-nginx-2035384211-j5fhi labeled
pod/my-nginx-2035384211-u2c7e labeled
pod/my-nginx-2035384211-u3t6x labeled
```
먼저 "app=nginx" 레이블이 있는 모든 파드를 필터링한 다음, "tier=fe" 레이블을 지정한다.
방금 레이블을 지정한 파드를 보려면, 다음을 실행한다.
```shell
kubectl get pods -l app=nginx -L tier
```
```shell
NAME READY STATUS RESTARTS AGE TIER
my-nginx-2035384211-j5fhi 1/1 Running 0 23m fe
my-nginx-2035384211-u2c7e 1/1 Running 0 23m fe
my-nginx-2035384211-u3t6x 1/1 Running 0 23m fe
```
그러면 파드 티어의 추가 레이블 열(`-L` 또는 `--label-columns` 로 지정)과 함께, 모든 "app=nginx" 파드가 출력된다.
더 자세한 내용은, [레이블](/ko/docs/concepts/overview/working-with-objects/labels/) 및 [kubectl label](/docs/reference/generated/kubectl/kubectl-commands/#label)을 참고하길 바란다.
## 어노테이션 업데이트
때로는 어노테이션을 리소스에 첨부하려고 할 수도 있다. 어노테이션은 도구, 라이브러리 등과 같은 API 클라이언트가 검색할 수 있는 임의의 비-식별 메타데이터이다. 이는 `kubectl annotate` 으로 수행할 수 있다. 예를 들면 다음과 같다.
```shell
kubectl annotate pods my-nginx-v4-9gw19 description='my frontend running nginx'
kubectl get pods my-nginx-v4-9gw19 -o yaml
```
```shell
apiVersion: v1
kind: pod
metadata:
annotations:
description: my frontend running nginx
...
```
더 자세한 내용은, [어노테이션](/ko/docs/concepts/overview/working-with-objects/annotations/) 및 [kubectl annotate](/docs/reference/generated/kubectl/kubectl-commands/#annotate) 문서를 참고하길 바란다.
## 애플리케이션 스케일링
애플리케이션의 로드가 증가하거나 축소되면, `kubectl` 을 사용하여 쉽게 스케일링할 수 있다. 예를 들어, nginx 레플리카 수를 3에서 1로 줄이려면, 다음을 수행한다.
```shell
kubectl scale deployment/my-nginx --replicas=1
```
```shell
deployment.extensions/my-nginx scaled
```
이제 디플로이먼트가 관리하는 파드가 하나만 있다.
```shell
kubectl get pods -l app=nginx
```
```shell
NAME READY STATUS RESTARTS AGE
my-nginx-2035384211-j5fhi 1/1 Running 0 30m
```
시스템이 필요에 따라 1에서 3까지의 범위에서 nginx 레플리카 수를 자동으로 선택하게 하려면, 다음을 수행한다.
```shell
kubectl autoscale deployment/my-nginx --min=1 --max=3
```
```shell
horizontalpodautoscaler.autoscaling/my-nginx autoscaled
```
이제 nginx 레플리카가 필요에 따라 자동으로 확장되거나 축소된다.
더 자세한 내용은, [kubectl scale](/docs/reference/generated/kubectl/kubectl-commands/#scale), [kubectl autoscale](/docs/reference/generated/kubectl/kubectl-commands/#autoscale) 및 [horizontal pod autoscaler](/ko/docs/tasks/run-application/horizontal-pod-autoscale/) 문서를 참고하길 바란다.
## 리소스 인플레이스(in-place) 업데이트
때로는 자신이 만든 리소스를 필요한 부분만, 중단없이 업데이트해야 할 때가 있다.
### kubectl apply
구성 파일 셋을 소스 제어에서 유지하는 것이 좋으며([코드로서의 구성](http://martinfowler.com/bliki/InfrastructureAsCode.html) 참조),
그렇게 하면 구성하는 리소스에 대한 코드와 함께 버전을 지정하고 유지할 수 있다.
그런 다음, [`kubectl apply`](/docs/reference/generated/kubectl/kubectl-commands/#apply)를 사용하여 구성 변경 사항을 클러스터로 푸시할 수 있다.
이 명령은 푸시하려는 구성의 버전을 이전 버전과 비교하고 지정하지 않은 속성에 대한 자동 변경 사항을 덮어쓰지 않은 채 수정한 변경 사항을 적용한다.
```shell
kubectl apply -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml
deployment.apps/my-nginx configured
```
참고로 `kubectl apply` 는 이전의 호출 이후 구성의 변경 사항을 판별하기 위해 리소스에 어노테이션을 첨부한다. 호출되면, `kubectl apply` 는 리소스를 수정하는 방법을 결정하기 위해, 이전 구성과 제공된 입력 및 리소스의 현재 구성 간에 3-way diff를 수행한다.
현재, 이 어노테이션 없이 리소스가 생성되므로, `kubectl apply` 의 첫 번째 호출은 제공된 입력과 리소스의 현재 구성 사이의 2-way diff로 대체된다. 이 첫 번째 호출 중에는, 리소스를 생성할 때 설정된 특성의 삭제를 감지할 수 없다. 이러한 이유로, 그 특성들을 삭제하지 않는다.
`kubectl apply` 에 대한 모든 후속 호출, 그리고 `kubectl replace``kubectl edit` 와 같이 구성을 수정하는 다른 명령은, 어노테이션을 업데이트하여, `kubectl apply` 에 대한 후속 호출이 3-way diff를 사용하여 삭제를 감지하고 수행할 수 있도록 한다.
### kubectl edit
또는, `kubectl edit`로 리소스를 업데이트할 수도 있다.
```shell
kubectl edit deployment/my-nginx
```
이것은 먼저 리소스를 `get` 하여, 텍스트 편집기에서 편집한 다음, 업데이트된 버전으로 리소스를 `apply` 하는 것과 같다.
```shell
kubectl get deployment my-nginx -o yaml > /tmp/nginx.yaml
vi /tmp/nginx.yaml
# 편집한 다음, 파일을 저장한다.
kubectl apply -f /tmp/nginx.yaml
deployment.apps/my-nginx configured
rm /tmp/nginx.yaml
```
이를 통해 보다 중요한 변경을 더 쉽게 ​​수행할 수 있다. 참고로 `EDITOR` 또는 `KUBE_EDITOR` 환경 변수를 사용하여 편집기를 지정할 수 있다.
더 자세한 내용은, [kubectl edit](/docs/reference/generated/kubectl/kubectl-commands/#edit) 문서를 참고하길 바란다.
### kubectl patch
`kubectl patch` 를 사용하여 API 오브젝트를 인플레이스 업데이트할 수 있다. 이 명령은 JSON 패치,
JSON 병합 패치 그리고 전략적 병합 패치를 지원한다.
[kubectl patch를 사용한 인플레이스 API 오브젝트 업데이트](/docs/tasks/run-application/update-api-object-kubectl-patch/)와
[kubectl patch](/docs/reference/generated/kubectl/kubectl-commands/#patch)를
참조한다.
## 파괴적(disruptive) 업데이트
경우에 따라, 한 번 초기화하면 업데이트할 수 없는 리소스 필드를 업데이트해야 하거나, 디플로이먼트에서 생성된 손상된 파드를 고치는 등의 재귀적 변경을 즉시 원할 수도 있다. 이러한 필드를 변경하려면, `replace --force` 를 사용하여 리소스를 삭제하고 다시 만든다. 이 경우, 원래 구성 파일을 간단히 수정할 수 있다.
```shell
kubectl replace -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml --force
```
```shell
deployment.apps/my-nginx deleted
deployment.apps/my-nginx replaced
```
## 서비스 중단없이 애플리케이션 업데이트
언젠가는, 위의 카나리 디플로이먼트 시나리오에서와 같이, 일반적으로 새 이미지 또는 이미지 태그를 지정하여, 배포된 애플리케이션을 업데이트해야 한다. `kubectl` 은 여러 가지 업데이트 작업을 지원하며, 각 업데이트 작업은 서로 다른 시나리오에 적용할 수 있다.
디플로이먼트를 사용하여 애플리케이션을 생성하고 업데이트하는 방법을 안내한다.
nginx 1.14.2 버전을 실행한다고 가정해 보겠다.
```shell
kubectl create deployment my-nginx --image=nginx:1.14.2
```
```shell
deployment.apps/my-nginx created
```
3개의 레플리카를 포함한다(이전과 새 개정판이 공존할 수 있음).
```shell
kubectl scale deployment my-nginx --current-replicas=1 --replicas=3
```
```
deployment.apps/my-nginx scaled
```
1.16.1 버전으로 업데이트하려면, 위에서 배운 kubectl 명령을 사용하여 `.spec.template.spec.containers[0].image``nginx:1.14.2` 에서 `nginx:1.16.1` 로 간단히 변경한다.
```shell
kubectl edit deployment/my-nginx
```
이것으로 끝이다! 디플로이먼트는 배포된 nginx 애플리케이션을 배후에서 점차적으로 업데이트한다. 업데이트되는 동안 특정 수의 이전 레플리카만 중단될 수 있으며, 원하는 수의 파드 위에 특정 수의 새 레플리카만 생성될 수 있다. 이에 대한 더 자세한 내용을 보려면, [디플로이먼트 페이지](/ko/docs/concepts/workloads/controllers/deployment/)를 방문한다.
{{% /capture %}}
{{% capture whatsnext %}}
- [애플리케이션 검사 및 디버깅에 `kubectl` 을 사용하는 방법](/docs/tasks/debug-application-cluster/debug-application-introspection/)에 대해 알아본다.
- [구성 모범 사례 및 팁](/ko/docs/concepts/configuration/overview/)을 참고한다.
{{% /capture %}}

View File

@ -0,0 +1,193 @@
---
title: 확장된 리소스를 위한 리소스 빈 패킹(bin packing)
content_template: templates/concept
weight: 10
---
{{% capture overview %}}
{{< feature-state for_k8s_version="v1.16" state="alpha" >}}
kube-scheduler는 `RequestedToCapacityRatioResourceAllocation` 우선 순위 기능을 사용해서 확장된 리소스와 함께 리소스의 빈 패킹이 가능하도록 구성할 수 있다. 우선 순위 기능을 사용해서 맞춤 요구에 따라 kube-scheduler를 미세 조정할 수 있다.
{{% /capture %}}
{{% capture body %}}
## RequestedToCapacityRatioResourceAllocation을 사용해서 빈 패킹 활성화하기
쿠버네티스 1.15 이전에는 Kube-scheduler가 CPU 및 메모리와 같은 리소스의 용량 대비 요청 비율을 기반으로 노드의 점수를 매기는 것을 허용했다. 쿠버네티스 1.16은 우선 순위 기능에 새로운 파라미터를 추가해서 사용자가 용량 대비 요청 비율을 기반으로 노드에 점수를 매기도록 각 리소스의 가중치와 함께 리소스를 지정할 수 있다. 이를 통해 사용자는 적절한 파라미터를 사용해서 확장된 리소스를 빈 팩으로 만들수 있어 대규모의 클러스터에서 부족한 리소스의 활용도가 향상된다. `RequestedToCapacityRatioResourceAllocation` 우선 순위 기능의 동작은 `requestedToCapacityRatioArguments`라는 구성 옵션으로 제어할 수 있다. 이 인수는 `shape``resources` 두 개의 파라미터로 구성된다. 셰이프(shape)는 사용자가 `utilization``score` 값을 기반으로 최소 요청 또는 최대 요청된 대로 기능을 조정할 수 있게 한다. 리소스는
점수를 매길 때 고려할 리소스를 지정하는 `name` 과 각 리소스의 가중치를 지정하는 `weight` 로 구성된다.
다음은 확장된 리소스 `intel.com/foo``intel.com/bar` 에 대한 `requestedToCapacityRatioArguments` 를 빈 패킹 동작으로 설정하는 구성의 예시이다.
```json
{
"kind" : "Policy",
"apiVersion" : "v1",
...
"priorities" : [
...
{
"name": "RequestedToCapacityRatioPriority",
"weight": 2,
"argument": {
"requestedToCapacityRatioArguments": {
"shape": [
{"utilization": 0, "score": 0},
{"utilization": 100, "score": 10}
],
"resources": [
{"name": "intel.com/foo", "weight": 3},
{"name": "intel.com/bar", "weight": 5}
]
}
}
}
],
}
```
**이 기능은 기본적으로 비활성화되어 있다.**
### RequestedToCapacityRatioResourceAllocation 우선 순위 기능 튜닝하기
`shape``RequestedToCapacityRatioPriority` 기능의 동작을 지정하는 데 사용된다.
```yaml
{"utilization": 0, "score": 0},
{"utilization": 100, "score": 10}
```
위의 인수는 사용률이 0%인 경우 점수는 0, 사용률이 100%인 경우 10으로 하여, 빈 패킹 동작을 활성화한다. 최소 요청을 활성화하려면 점수 값을 다음과 같이 변경해야 한다.
```yaml
{"utilization": 0, "score": 100},
{"utilization": 100, "score": 0}
```
`resources` 는 기본적으로 다음과 같이 설정되는 선택적인 파라미터이다.
``` yaml
"resources": [
{"name": "CPU", "weight": 1},
{"name": "Memory", "weight": 1}
]
```
다음과 같이 확장된 리소스를 추가하는 데 사용할 수 있다.
```yaml
"resources": [
{"name": "intel.com/foo", "weight": 5},
{"name": "CPU", "weight": 3},
{"name": "Memory", "weight": 1}
]
```
가중치 파라미터는 선택 사항이며 지정되지 않은 경우 1로 설정 된다. 또한, 가중치는 음수로 설정할 수 없다.
### RequestedToCapacityRatioResourceAllocation 우선 순위 기능이 노드에 점수를 매기는 방법
이 섹션은 이 기능 내부의 세부적인 사항을 이해하려는 사람들을
위한 것이다.
아래는 주어진 값의 집합에 대해 노드 점수가 계산되는 방법의 예시이다.
```
Requested Resources
intel.com/foo : 2
Memory: 256MB
CPU: 2
Resource Weights
intel.com/foo : 5
Memory: 1
CPU: 3
FunctionShapePoint {{0, 0}, {100, 10}}
Node 1 Spec
Available:
intel.com/foo : 4
Memory : 1 GB
CPU: 8
Used:
intel.com/foo: 1
Memory: 256MB
CPU: 1
Node Score:
intel.com/foo = resourceScoringFunction((2+1),4)
= (100 - ((4-3)*100/4)
= (100 - 25)
= 75
= rawScoringFunction(75)
= 7
Memory = resourceScoringFunction((256+256),1024)
= (100 -((1024-512)*100/1024))
= 50
= rawScoringFunction(50)
= 5
CPU = resourceScoringFunction((2+1),8)
= (100 -((8-3)*100/8))
= 37.5
= rawScoringFunction(37.5)
= 3
NodeScore = (7 * 5) + (5 * 1) + (3 * 3) / (5 + 1 + 3)
= 5
Node 2 Spec
Available:
intel.com/foo: 8
Memory: 1GB
CPU: 8
Used:
intel.com/foo: 2
Memory: 512MB
CPU: 6
Node Score:
intel.com/foo = resourceScoringFunction((2+2),8)
= (100 - ((8-4)*100/8)
= (100 - 25)
= 50
= rawScoringFunction(50)
= 5
Memory = resourceScoringFunction((256+512),1024)
= (100 -((1024-768)*100/1024))
= 75
= rawScoringFunction(75)
= 7
CPU = resourceScoringFunction((2+6),8)
= (100 -((8-8)*100/8))
= 100
= rawScoringFunction(100)
= 10
NodeScore = (5 * 5) + (7 * 1) + (10 * 3) / (5 + 1 + 3)
= 7
```
{{% /capture %}}

View File

@ -0,0 +1,297 @@
---
title: 테인트(Taints)와 톨러레이션(Tolerations)
content_template: templates/concept
weight: 40
---
{{% capture overview %}}
[여기](/ko/docs/concepts/configuration/assign-pod-node/#어피니티-affinity-와-안티-어피니티-anti-affinity)에 설명된 노드 어피니티는
노드 셋을 *끌어들이는* (기본 설정 또는 어려운 요구 사항)
*파드* 속성이다. 테인트는 그 반대로, *노드* 가 파드 셋을
*제외* 할 수 있다.
테인트와 톨러레이션은 함께 작동하여 파드가 부적절한 노드에 스케줄되지
않게 한다. 하나 이상의 테인트가 노드에 적용된다. 이것은
노드가 테인트를 용인하지 않는 파드를 수용해서는 안 되는 것을 나타낸다.
톨러레이션은 파드에 적용되며, 파드를 일치하는 테인트가 있는 노드에 스케줄되게
하지만 필수는 아니다.
{{% /capture %}}
{{% capture body %}}
## 개요
[kubectl taint](/docs/reference/generated/kubectl/kubectl-commands#taint)를 사용하여 노드에 테인트을 추가한다.
예를 들면 다음과 같다.
```shell
kubectl taint nodes node1 key=value:NoSchedule
```
`node1` 노드에 테인트을 배치한다. 테인트에는 키 `key`, 값 `value` 및 테인트 이펙트(effect) `NoSchedule` 이 있다.
이는 일치하는 톨러레이션이 없으면 파드를 `node1` 에 스케줄할 수 없음을 의미한다.
위의 명령으로 추가한 테인트를 제거하려면, 다음을 실행한다.
```shell
kubectl taint nodes node1 key:NoSchedule-
```
PodSpec에서 파드에 대한 톨러레이션를 지정한다. 다음의 톨러레이션은
위의 `kubectl taint` 라인에 의해 생성된 테인트와 "일치"하므로, 어느 쪽 톨러레이션을 가진 파드이던
`node1` 에 스케줄 될 수 있다.
```yaml
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"
```
```yaml
tolerations:
- key: "key"
operator: "Exists"
effect: "NoSchedule"
```
톨러레이션을 사용하는 파드의 예는 다음과 같다.
{{< codenew file="pods/pod-with-toleration.yaml" >}}
톨러레이션은 키가 동일하고 이펙트가 동일한 경우, 테인트와 "일치"한다. 그리고 다음의 경우에도 마찬가지다.
* `operator``Exists` 인 경우(이 경우 `value` 를 지정하지 않아야 함), 또는
* `operator``Equal` 이고 `value``value` 로 같다.
지정하지 않으면 `operator` 의 기본값은 `Equal` 이다.
{{< note >}}
두 가지 특별한 경우가 있다.
* operator `Exists` 가 있는 비어있는 `key` 는 모든 키, 값 및 이펙트와 일치하므로
모든 것이 톨러레이션 된다.
```yaml
tolerations:
- operator: "Exists"
```
* 비어있는 `effect` 는 모든 이펙트를 키 `key` 와 일치시킨다.
```yaml
tolerations:
- key: "key"
operator: "Exists"
```
{{< /note >}}
위의 예는 `NoSchedule``effect` 를 사용했다. 또는, `PreferNoSchedule``effect` 를 사용할 수 있다.
이것은 `NoSchedule` 의 "기본 설정(preference)" 또는 "소프트(soft)" 버전이다. 시스템은 노드의 테인트를 허용하지 않는
파드를 배치하지 않으려고 *시도* 하지만, 필요하지는 않다. 세 번째 종류의 `effect`
나중에 설명할 `NoExecute` 이다.
동일한 노드에 여러 테인트를, 동일한 파드에 여러 톨러레이션을 둘 수 있다.
쿠버네티스가 여러 테인트 및 톨러레이션을 처리하는 방식은 필터와 같다.
모든 노드의 테인트로 시작한 다음, 파드에 일치하는 톨러레이션이 있는 것을 무시한다.
무시되지 않은 나머지 테인트는 파드에 표시된 이펙트를 가진다. 특히,
* `NoSchedule` 이펙트가 있는 무시되지 않은 테인트가 하나 이상 있으면 쿠버네티스는 해당 노드에
파드를 스케줄하지 않는다.
* `NoSchedule` 이펙트가 있는 무시되지 않은 테인트가 없지만 `PreferNoSchedule` 이펙트가 있는
무시되지 않은 테인트가 하나 이상 있으면 쿠버네티스는 파드를 노드에 스케쥴하지 않으려고 *시도* 한다
* `NoExecute` 이펙트가 있는 무시되지 않은 테인트가 하나 이상 있으면
파드가 노드에서 축출되고(노드에서 이미 실행 중인 경우), 노드에서
스케줄되지 않는다(아직 실행되지 않은 경우).
예를 들어, 이와 같은 노드를 테인트하는 경우는 다음과 같다.
```shell
kubectl taint nodes node1 key1=value1:NoSchedule
kubectl taint nodes node1 key1=value1:NoExecute
kubectl taint nodes node1 key2=value2:NoSchedule
```
그리고 파드에는 두 가지 톨러레이션이 있다.
```yaml
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoSchedule"
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoExecute"
```
이 경우, 세 번째 테인트와 일치하는 톨러레이션이 없기 때문에, 파드는
노드에 스케줄 될 수 없다. 그러나 세 번째 테인트가 파드에서 용인되지 않는 세 가지 중
하나만 있기 때문에, 테인트가 추가될 때 노드에서 이미 실행 중인 경우,
파드는 계속 실행할 수 있다.
일반적으로, `NoExecute` 이펙트가 있는 테인트가 노드에 추가되면, 테인트를
용인하지 않는 파드는 즉시 축출되고, 테인트를 용인하는 파드는
축출되지 않는다. 그러나 `NoExecute` 이펙트가 있는 톨러레이션은
테인트가 추가된 후 파드가 노드에 바인딩된 시간을 지정하는
선택적 `tolerationSeconds` 필드를 지정할 수 있다. 예를 들어,
```yaml
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoExecute"
tolerationSeconds: 3600
```
이것은 이 파드가 실행 중이고 일치하는 테인트가 노드에 추가되면,
파드는 3600초 동안 노드에 바인딩된 후, 축출된다는 것을 의미한다. 그 전에
테인트를 제거하면, 파드가 축출되지 않는다.
## 유스케이스 예시
테인트 및 톨러레이션은 파드를 노드에서 *멀어지게* 하거나 실행되지 않아야 하는
파드를 축출할 수 있는 유연한 방법이다. 유스케이스 중 일부는 다음과 같다.
* **전용 노드**: 특정 사용자들이 독점적으로 사용하도록
노드 셋을 전용하려면, 해당 노드에 테인트를 추가(예:
`kubectl taint nodes nodename dedicated=groupName:NoSchedule`)한 다음 해당
톨러레이션을 그들의 파드에 추가할 수 있다(사용자 정의 [어드미션 컨트롤러]
(/docs/reference/access-authn-authz/admission-controllers/)를 작성하면 가장 쉽게 수행할 수 있음).
그런 다음 톨러레이션이 있는 파드는 테인트된(전용) 노드와
클러스터의 다른 노드를 사용할 수 있다. 노드를 특정 사용자들에게 전용으로 지정하고 *그리고*
그 사용자들이 전용 노드 *만* 사용하려면, 동일한 노드 셋에
테인트와 유사한 레이블을 추가해야 하고(예: `dedicated=groupName`),
어드미션 컨트롤러는 추가로 파드가 `dedicated=groupName` 으로 레이블이 지정된 노드에만
스케줄될 수 있도록 노드 어피니티를 추가해야 한다.
* **특별한 하드웨어가 있는 노드**: 작은 서브셋의 노드에 특별한
하드웨어(예: GPU)가 있는 클러스터에서는, 특별한 하드웨어가 필요하지 않는 파드를
해당 노드에서 분리하여, 나중에 도착하는 특별한 하드웨어가 필요한 파드를 위한 공간을
남겨두는 것이 바람직하다. 이는 특별한 하드웨어가 있는
노드(예: `kubectl taint nodes nodename special=true:NoSchedule` 또는
`kubectl taint nodes nodename special=true:PreferNoSchedule`)에 테인트를 추가하고
특별한 하드웨어를 사용하는 파드에 해당 톨러레이션을 추가하여 수행할 수 있다. 전용 노드 유스케이스에서와 같이,
사용자 정의 [어드미션 컨트롤러](/docs/reference/access-authn-authz/admission-controllers/)를
사용하여 톨러레이션를 적용하는 것이 가장 쉬운 방법이다.
예를 들어, [확장된
리소스](/docs/concepts/configuration/manage-compute-resources-container/#extended-resources)를
사용하여 특별한 하드웨어를 나타내고, 확장된 리소스 이름으로
특별한 하드웨어 노드를 테인트시키고
[ExtendedResourceToleration](/docs/reference/access-authn-authz/admission-controllers/#extendedresourcetoleration)
어드미션 컨트롤러를 실행하는 것을 권장한다. 이제, 노드가 테인트되었으므로, 톨러레이션이 없는
파드는 스케줄되지 않는다. 그러나 확장된 리소스를 요청하는 파드를 제출하면,
`ExtendedResourceToleration` 어드미션 컨트롤러가
파드에 올바른 톨러레이션을 자동으로 추가하고 해당 파드는
특별한 하드웨어 노드에서 스케줄된다. 이렇게 하면 이러한 특별한 하드웨어 노드가
해당 하드웨어를 요청하는 파드가 전용으로 사용하며 파드에 톨러레이션을
수동으로 추가할 필요가 없다.
* **테인트 기반 축출**: 노드 문제가 있을 때 파드별로
구성 가능한 축출 동작은 다음 섹션에서 설명한다.
## 테인트 기반 축출
{{< feature-state for_k8s_version="1.18" state="stable" >}}
앞에서 우리는 노드에서 이미 실행 중인 파드에 영향을 주는 `NoExecute` 테인트 이펙트를
다음과 같이 언급했다.
* 테인트를 용인하지 않는 파드는 즉시 축출된다.
* 톨러레이션 명세에 `tolerationSeconds` 를 지정하지 않고
테인트를 용인하는 파드는 계속 바인딩된다.
* `tolerationSeconds` 가 지정된 테인트를 용인하는 파드는 지정된
시간 동안 바인딩된 상태로 유지된다.
덧붙여, 쿠버네티스 1.6 버전에서는 노드 문제를 나타내는 알파 지원이
도입되었다. 다시 말해, 특정 조건이 참일 때 노드 컨트롤러는 자동으로
노드를 테인트시킨다. 다음은 빌트인 테인트이다.
* `node.kubernetes.io/not-ready`: 노드가 준비되지 않았다. 이는 NodeCondition
`Ready` 가 "`False`"로 됨에 해당한다.
* `node.kubernetes.io/unreachable`: 노드가 노드 컨트롤러에서 도달할 수 없다. 이는
NodeCondition `Ready` 가 "`Unknown`"로 됨에 해당한다.
* `node.kubernetes.io/out-of-disk`: 노드에 디스크가 부족하다.
* `node.kubernetes.io/memory-pressure`: 노드에 메모리 할당 압박이 있다.
* `node.kubernetes.io/disk-pressure`: 노드에 디스크 할당 압박이 있다.
* `node.kubernetes.io/network-unavailable`: 노드의 네트워크를 사용할 수 없다.
* `node.kubernetes.io/unschedulable`: 노드를 스케줄할 수 없다.
* `node.cloudprovider.kubernetes.io/uninitialized`: "외부" 클라우드 공급자로
kubelet을 시작하면, 이 테인트가 노드에서 사용 불가능으로 표시되도록
설정된다. 클라우드-컨트롤러-관리자의 컨트롤러가 이 노드를 초기화하면,
kubelet이 이 테인트를 제거한다.
노드가 축출될 경우, 노드 컨트롤러 또는 kubelet은 `NoExecute` 이펙트로 관련
테인트를 추가한다. 장애 상태가 정상으로 돌아오면 kubelet 또는 노드 컨트롤러가
관련 테인트를 제거할 수 있다.
{{< note >}}
노드 문제로 인해 파드 축출의 기존 [비율 제한](/ko/docs/concepts/architecture/nodes/)
동작을 유지하기 위해, 시스템은 실제로 테인트를 비율-제한 방식으로
추가한다. 이는 마스터가 노드에서 분할되는 등의 시나리오에서
대규모 파드 축출을 방지한다.
{{< /note >}}
이 기능을 `tolerationSeconds` 와 함께 사용하면, 파드에서
이러한 문제 중 하나 또는 둘 다가 있는 노드에 바인딩된 기간을 지정할 수 있다.
예를 들어, 로컬 상태가 많은 애플리케이션은 네트워크 분할의 장애에서
네트워크가 복구된 후에 파드가 축출되는 것을 피하기 위해
오랫동안 노드에 바인딩된 상태를 유지하려고 할 수 있다.
이 경우 파드가 사용하는 톨러레이션은 다음과 같다.
```yaml
tolerations:
- key: "node.kubernetes.io/unreachable"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 6000
```
쿠버네티스는 사용자가 제공한 파드 구성에 이미 추가된
`node.kubernetes.io/not-ready` 에 대한 톨러레이션이 없는 경우
`tolerationSeconds=300` 으로 `node.kubernetes.io/not-ready` 에 대한
톨러레이션을 자동으로 추가한다.
마찬가지로 사용자가 제공한 파드 구성에 이미 추가된
`node.kubernetes.io/unreachable` 에 대한 톨러레이션이 없는 경우
`tolerationSeconds=300` 으로 `node.kubernetes.io/unreachable` 에 대한
톨러레이션을 추가한다.
자동으로 추가된 이 톨러레이션은 이러한 문제 중 하나가
감지된 후 5분 동안 바인딩 상태로 남아있는 기본 파드
동작이 유지되도록 한다.
[DefaultTolerationSecondsadmission controller](https://git.k8s.io/kubernetes/plugin/pkg/admission/defaulttolerationseconds)
어드미션 컨트롤러에 의해 두 개의 기본 톨러레이션이 추가된다.
[데몬셋](/ko/docs/concepts/workloads/controllers/daemonset/) 파드는 `tolerationSeconds` 가 없는
다음 테인트에 대해 `NoExecute` 톨러레이션를 가지고 생성된다.
* `node.kubernetes.io/unreachable`
* `node.kubernetes.io/not-ready`
이렇게 하면 이러한 문제로 인해 데몬셋 파드가 축출되지 않는다.
## 컨디션별 노드 테인트하기
노드 라이프사이클 컨트롤러는 `NoSchedule` 이펙트가 있는 노드 컨디션에 해당하는
테인트를 자동으로 생성한다.
마찬가지로 스케줄러는 노드 컨디션을 확인하지 않는다. 대신 스케줄러는 테인트를 확인한다. 이렇게 하면 노드 컨디션이 노드에 스케줄된 내용에 영향을 미치지 않는다. 사용자는 적절한 파드 톨러레이션을 추가하여 노드의 일부 문제(노드 컨디션으로 표시)를 무시하도록 선택할 수 있다.
쿠버네티스 1.8 버전부터 데몬셋 컨트롤러는 다음의 `NoSchedule` 톨러레이션을
모든 데몬에 자동으로 추가하여, 데몬셋이 중단되는 것을
방지한다.
* `node.kubernetes.io/memory-pressure`
* `node.kubernetes.io/disk-pressure`
* `node.kubernetes.io/out-of-disk` (*중요한 파드에만 해당*)
* `node.kubernetes.io/unschedulable` (1.10 이상)
* `node.kubernetes.io/network-unavailable` (*호스트 네트워크만 해당*)
이러한 톨러레이션을 추가하면 이전 버전과의 호환성이 보장된다. 데몬셋에
임의의 톨러레이션을 추가할 수도 있다.

View File

@ -9,7 +9,7 @@ weight: 10
애그리게이션 레이어는 코어 쿠버네티스 API가 제공하는 기능 이외에 더 많은 기능을 제공할 수 있도록 추가 API를 더해 쿠버네티스를 확장할 수 있게 해준다.
추가 API는 [서비스-카탈로그](/docs/concepts/extend-kubernetes/service-catalog/)와 같이 미리 만들어진 솔루션이거나 사용자가 직접 개발한 API일 수 있다.
애그리게이션 레이어는 [사용자 정의 리소스](/docs/concepts/extend-kubernetes/api-extension/custom-resources/)와는 다르며, 애그리게이션 레이어는 {{< glossary_tooltip term_id="kube-apiserver" text="kube-apiserver" >}} 가 새로운 종류의 오브젝트를 인식하도록 하는 방법이다.
애그리게이션 레이어는 [사용자 정의 리소스](/ko/docs/concepts/extend-kubernetes/api-extension/custom-resources/)와는 다르며, 애그리게이션 레이어는 {{< glossary_tooltip term_id="kube-apiserver" text="kube-apiserver" >}} 가 새로운 종류의 오브젝트를 인식하도록 하는 방법이다.
{{% /capture %}}

View File

@ -0,0 +1,4 @@
---
title: 컴퓨트, 스토리지 및 네트워킹 익스텐션
weight: 30
---

View File

@ -0,0 +1,235 @@
---
title: 장치 플러그인
description: GPU, NIC, FPGA, InfiniBand 및 공급 업체별 설정이 필요한 유사한 리소스를 위한 플러그인을 구현하는데 쿠버네티스 장치 플러그인 프레임워크를 사용한다.
content_template: templates/concept
weight: 20
---
{{% capture overview %}}
{{< feature-state for_k8s_version="v1.10" state="beta" >}}
쿠버네티스는 시스템 하드웨어 리소스를 {{< glossary_tooltip term_id="kubelet" >}}에 알리는 데 사용할 수 있는
[장치 플러그인 프레임워크](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/resource-management/device-plugin.md)를
제공한다.
공급 업체는 쿠버네티스 자체의 코드를 커스터마이징하는 대신, 수동 또는
{{< glossary_tooltip text="데몬셋" term_id="daemonset" >}}으로 배포하는 장치 플러그인을 구현할 수 있다.
대상이 되는 장치에는 GPU, 고성능 NIC, FPGA, InfiniBand 어댑터
및 공급 업체별 초기화 및 설정이 필요할 수 있는 기타 유사한 컴퓨팅 리소스가
포함된다.
{{% /capture %}}
{{% capture body %}}
## 장치 플러그인 등록
kubelet은 `Registration` gRPC 서비스를 노출시킨다.
```gRPC
service Registration {
rpc Register(RegisterRequest) returns (Empty) {}
}
```
장치 플러그인은 이 gRPC 서비스를 통해 kubelet에 자체 등록할 수 있다.
등록하는 동안, 장치 플러그인은 다음을 보내야 한다.
* 유닉스 소켓의 이름.
* 빌드된 장치 플러그인 API 버전.
* 알리려는 `ResourceName`. 여기서 `ResourceName`
[확장된 리소스 네이밍 체계](/docs/concepts/configuration/manage-compute-resources-container/#extended-resources)를
`vendor-domain/resourcetype` 의 형식으로 따라야 한다.
(예를 들어, NVIDIA GPU는 `nvidia.com/gpu` 로 알려진다.)
성공적으로 등록하고 나면, 장치 플러그인은 kubelet이 관리하는
장치 목록을 전송한 다음, kubelet은 kubelet 노드 상태 업데이트의 일부로
해당 자원을 API 서버에 알리는 역할을 한다.
예를 들어, 장치 플러그인이 kubelet에 `hardware-vendor.example/foo` 를 등록하고
노드에 두 개의 정상 장치를 보고하고 나면, 노드 상태가 업데이트되어
노드에 2개의 “Foo” 장치가 설치되어 사용 가능함을 알릴 수 있다.
그러고 나면, 사용자가
[컨테이너](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#container-v1-core) 명세에 있는 장치를 요청할 수 있다.
다만, 다른 종류의 리소스를 요청하는 것이므로 다음과 같은 제한이 있다.
* 확장된 리소스는 정수(integer) 형태만 지원되며 오버커밋(overcommit) 될 수 없다.
* 컨테이너간에 장치를 공유할 수 없다.
쿠버네티스 클러스터가 특정 노드에서 `hardware-vendor.example/foo` 리소스를 알리는 장치 플러그인을 실행한다고
가정해 보자. 다음은 데모 워크로드를 실행하기 위해 이 리소스를 요청하는 파드의 예이다.
```yaml
---
apiVersion: v1
kind: Pod
metadata:
name: demo-pod
spec:
containers:
- name: demo-container-1
image: k8s.gcr.io/pause:2.0
resources:
limits:
hardware-vendor.example/foo: 2
#
# 이 파드는 2개의 hardware-vendor.example/foo 장치가 필요하며
# 해당 요구를 충족할 수 있는 노드에만
# 예약될 수 있다.
#
# 노드에 2개 이상의 사용 가능한 장치가 있는 경우
# 나머지는 다른 파드에서 사용할 수 있다.
```
## 장치 플러그인 구현
장치 플러그인의 일반적인 워크플로우에는 다음 단계가 포함된다.
* 초기화. 이 단계에서, 장치 플러그인은 공급 업체별 초기화 및 설정을 수행하여
장치가 준비 상태에 있는지 확인한다.
* 플러그인은 다음의 인터페이스를 구현하는 호스트 경로 `/var/lib/kubelet/device-plugins/`
아래에 유닉스 소켓과 함께 gRPC 서비스를 시작한다.
```gRPC
service DevicePlugin {
// ListAndWatch는 장치 목록 스트림을 반환한다.
// 장치 상태가 변경되거나 장치가 사라질 때마다, ListAndWatch는
// 새 목록을 반환한다.
rpc ListAndWatch(Empty) returns (stream ListAndWatchResponse) {}
// 컨테이너를 생성하는 동안 Allocate가 호출되어 장치
// 플러그인이 장치별 작업을 실행하고 Kubelet에 장치를
// 컨테이너에서 사용할 수 있도록 하는 단계를 지시할 수 있다.
rpc Allocate(AllocateRequest) returns (AllocateResponse) {}
}
```
* 플러그인은 호스트 경로 `/var/lib/kubelet/device-plugins/kubelet.sock` 에서
유닉스 소켓을 통해 kubelet에 직접 등록한다.
* 성공적으로 등록하고 나면, 장치 플러그인은 서빙(serving) 모드에서 실행되며, 그 동안 플러그인은 장치 상태를
모니터링하고 장치 상태 변경 시 kubelet에 다시 보고한다.
또한 gRPC 요청 `Allocate` 를 담당한다. `Allocate` 하는 동안, 장치 플러그인은
GPU 정리 또는 QRNG 초기화와 같은 장치별 준비를 수행할 수 있다.
작업이 성공하면, 장치 플러그인은 할당된 장치에 접근하기 위한 컨테이너 런타임 구성이 포함된
`AllocateResponse` 를 반환한다. kubelet은 이 정보를
컨테이너 런타임에 전달한다.
### kubelet 재시작 처리
장치 플러그인은 일반적으로 kubelet의 재시작을 감지하고 새로운
kubelet 인스턴스에 자신을 다시 등록할 것으로 기대된다. 현재의 구현에서, 새 kubelet 인스턴스는 시작될 때
`/var/lib/kubelet/device-plugins` 아래에 있는 모든 기존의 유닉스 소켓을 삭제한다. 장치 플러그인은 유닉스 소켓의
삭제를 모니터링하고 이러한 이벤트가 발생하면 다시 자신을 등록할 수 있다.
## 장치 플러그인 배포
장치 플러그인을 데몬셋, 노드 운영 체제의 패키지
또는 수동으로 배포할 수 있다.
표준 디렉터리 `/var/lib/kubelet/device-plugins` 에는 특권을 가진 접근이 필요하므로,
장치 플러그인은 특권을 가진 보안 컨텍스트에서 실행해야 한다.
장치 플러그인을 데몬셋으로 배포하는 경우, 플러그인의
[PodSpec](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podspec-v1-core)에서
`/var/lib/kubelet/device-plugins`
{{< glossary_tooltip text="볼륨" term_id="volume" >}}으로 마운트해야 한다.
데몬셋 접근 방식을 선택하면 쿠버네티스를 사용하여 장치 플러그인의 파드를 노드에 배치하고,
장애 후 데몬 파드를 다시 시작하고, 업그레이드를 자동화할 수 있다.
## API 호환성
쿠버네티스 장치 플러그인 지원은 베타 버전이다. 호환되지 않는 방식으로 안정화 전에 API가
변경될 수 있다. 프로젝트로서, 쿠버네티스는 장치 플러그인 개발자에게 다음 사항을 권장한다.
* 향후 릴리스에서 변경 사항을 확인하자.
* 이전/이후 버전과의 호환성을 위해 여러 버전의 장치 플러그인 API를 지원한다.
최신 장치 플러그인 API 버전의 쿠버네티스 릴리스로 업그레이드해야 하는 노드에서 DevicePlugins 기능을 활성화하고
장치 플러그인을 실행하는 경우, 이 노드를 업그레이드하기 전에
두 버전을 모두 지원하도록 장치 플러그인을 업그레이드한다. 이 방법을 사용하면
업그레이드 중에 장치 할당이 지속적으로 작동한다.
## 장치 플러그인 리소스 모니터링
{{< feature-state for_k8s_version="v1.15" state="beta" >}}
장치 플러그인에서 제공하는 리소스를 모니터링하려면, 모니터링 에이전트가
노드에서 사용 중인 장치 셋을 검색하고 메트릭과 연관될 컨테이너를 설명하는
메타데이터를 얻을 수 있어야 한다. 장치 모니터링 에이전트에 의해 노출된
[프로메테우스(Prometheus)](https://prometheus.io/) 지표는
[쿠버네티스 Instrumentation 가이드라인](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/instrumentation.md)을 따라
`pod`, `namespace``container` 프로메테우스 레이블을 사용하여 컨테이너를 식별해야 한다.
kubelet은 gRPC 서비스를 제공하여 사용 중인 장치를 검색하고, 이러한 장치에 대한 메타데이터를
제공한다.
```gRPC
// PodResourcesLister는 kubelet에서 제공하는 서비스로, 노드의 포드 및 컨테이너가
// 사용한 노드 리소스에 대한 정보를 제공한다.
service PodResourcesLister {
rpc List(ListPodResourcesRequest) returns (ListPodResourcesResponse) {}
}
```
gRPC 서비스는 `/var/lib/kubelet/pod-resources/kubelet.sock` 의 유닉스 소켓을 통해 제공된다.
장치 플러그인 리소스에 대한 모니터링 에이전트는 데몬 또는 데몬셋으로 배포할 수 있다.
표준 디렉터리 `/var/lib/kubelet/pod-resources` 에는 특권을 가진 접근이 필요하므로, 모니터링
에이전트는 특권을 가진 ​​보안 컨텍스트에서 실행해야 한다. 장치 모니터링 에이전트가
데몬셋으로 실행 중인 경우, 플러그인의 [PodSpec](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podspec-v1-core)에서
`/var/lib/kubelet/pod-resources`
{{< glossary_tooltip text="볼륨" term_id="volume" >}}으로 마운트해야 한다.
"PodResources 서비스"를 지원하려면 `KubeletPodResources` [기능 게이트](/docs/reference/command-line-tools-reference/feature-gates/)를 활성화해야 한다. 쿠버네티스 1.15부터 기본적으로 활성화되어 있다.
## 토폴로지 관리자와 장치 플러그인 통합
{{< feature-state for_k8s_version="v1.17" state="alpha" >}}
토폴로지 관리자는 Kubelet 컴포넌트로, 리소스를 토폴로지 정렬 방식으로 조정할 수 있다. 이를 위해, 장치 플러그인 API가 `TopologyInfo` 구조체를 포함하도록 확장되었다.
```gRPC
message TopologyInfo {
repeated NUMANode nodes = 1;
}
message NUMANode {
int64 ID = 1;
}
```
토폴로지 관리자를 활용하려는 장치 플러그인은 장치 ID 및 장치의 정상 상태와 함께 장치 등록의 일부로 채워진 TopologyInfo 구조체를 다시 보낼 수 있다. 그런 다음 장치 관리자는 이 정보를 사용하여 토폴로지 관리자와 상의하고 리소스 할당 결정을 내린다.
`TopologyInfo``nil`(기본값) 또는 NUMA 노드 목록인 `nodes` 필드를 지원한다. 이를 통해 NUMA 노드에 걸쳐있을 수 있는 장치 플러그인을 게시할 수 있다.
장치 플러그인으로 장치에 대해 채워진 `TopologyInfo` 구조체의 예는 다음과 같다.
```
pluginapi.Device{ID: "25102017", Health: pluginapi.Healthy, Topology:&pluginapi.TopologyInfo{Nodes: []*pluginapi.NUMANode{&pluginapi.NUMANode{ID: 0,},}}}
```
## 장치 플러그인 예시 {#examples}
다음은 장치 플러그인 구현의 예이다.
* [AMD GPU 장치 플러그인](https://github.com/RadeonOpenCompute/k8s-device-plugin)
* 인텔 GPU, FPGA 및 QuickAssist 장치용 [인텔 장치 플러그인](https://github.com/intel/intel-device-plugins-for-kubernetes)
* 하드웨어 지원 가상화를 위한 [KubeVirt 장치 플러그인](https://github.com/kubevirt/kubernetes-device-plugins)
* [NVIDIA GPU 장치 플러그인](https://github.com/NVIDIA/k8s-device-plugin)
* GPU를 지원하는 Docker 컨테이너를 실행할 수 있는 [nvidia-docker](https://github.com/NVIDIA/nvidia-docker) 2.0이 필요하다.
* [컨테이너에 최적화된 OS를 위한 NVIDIA GPU 장치 플러그인](https://github.com/GoogleCloudPlatform/container-engine-accelerators/tree/master/cmd/nvidia_gpu)
* [RDMA 장치 플러그인](https://github.com/hustcat/k8s-rdma-device-plugin)
* [Solarflare 장치 플러그인](https://github.com/vikaschoudhary16/sfc-device-plugin)
* [SR-IOV 네트워크 장치 플러그인](https://github.com/intel/sriov-network-device-plugin)
* Xilinx FPGA 장치용 [Xilinx FPGA 장치 플러그인](https://github.com/Xilinx/FPGA_as_a_Service/tree/master/k8s-fpga-device-plugin/trunk)
{{% /capture %}}
{{% capture whatsnext %}}
* 장치 플러그인을 사용한 [GPU 리소스 스케줄링](/docs/tasks/manage-gpus/scheduling-gpus/)에 대해 알아보기
* 노드에서의 [확장 리소스 알리기](/docs/tasks/administer-cluster/extended-resource-node/)에 대해 배우기
* 쿠버네티스에서 [TLS 수신에 하드웨어 가속](https://kubernetes.io/blog/2019/04/24/hardware-accelerated-ssl/tls-termination-in-ingress-controllers-using-kubernetes-device-plugins-and-runtimeclass/) 사용에 대해 읽기
* [토폴로지 관리자](/docs/tasks/adminster-cluster/topology-manager/)에 대해 알아보기
{{% /capture %}}

View File

@ -0,0 +1,167 @@
---
title: 네트워크 플러그인
content_template: templates/concept
weight: 10
---
{{% capture overview %}}
{{< feature-state state="alpha" >}}
{{< caution >}}알파 기능은 빨리 변경될 수 있다. {{< /caution >}}
쿠버네티스의 네트워크 플러그인은 몇 가지 종류가 있다.
* CNI 플러그인: 상호 운용성을 위해 설계된 appc/CNI 명세를 준수한다.
* Kubenet 플러그인: `bridge``host-local` CNI 플러그인을 사용하여 기본 `cbr0` 구현한다.
{{% /capture %}}
{{% capture body %}}
## 설치
kubelet에는 단일 기본 네트워크 플러그인과 전체 클러스터에 공통된 기본 네트워크가 있다. 플러그인은 시작할 때 플러그인을 검색하고, 찾은 것을 기억하며, 파드 라이프사이클에서 적절한 시간에 선택한 플러그인을 실행한다(rkt는 자체 CNI 플러그인을 관리하므로 Docker에만 해당됨). 플러그인 사용 시 명심해야 할 두 가지 Kubelet 커맨드라인 파라미터가 있다.
* `cni-bin-dir`: Kubelet은 시작할 때 플러그인에 대해 이 디렉터리를 검사한다.
* `network-plugin`: `cni-bin-dir` 에서 사용할 네트워크 플러그인. 플러그인 디렉터리에서 검색한 플러그인이 보고된 이름과 일치해야 한다. CNI 플러그인의 경우, 이는 단순히 "cni"이다.
## 네트워크 플러그인 요구 사항
파드 네트워킹을 구성하고 정리하기 위해 [`NetworkPlugin` 인터페이스](https://github.com/kubernetes/kubernetes/tree/{{< param "fullversion" >}}/pkg/kubelet/dockershim/network/plugins.go)를 제공하는 것 외에도, 플러그인은 kube-proxy에 대한 특정 지원이 필요할 수 있다. iptables 프록시는 분명히 iptables에 의존하며, 플러그인은 컨테이너 트래픽이 iptables에 사용 가능하도록 해야 한다. 예를 들어, 플러그인이 컨테이너를 리눅스 브릿지에 연결하는 경우, 플러그인은 `net/bridge/bridge-nf-call-iptables` sysctl을 `1` 로 설정하여 iptables 프록시가 올바르게 작동하는지 확인해야 한다. 플러그인이 리눅스 브리지를 사용하지 않는 경우(그러나 Open vSwitch나 다른 메커니즘과 같은 기능을 사용함) 컨테이너 트래픽이 프록시에 대해 적절하게 라우팅되도록 해야 한다.
kubelet 네트워크 플러그인이 지정되지 않은 경우, 기본적으로 `noop` 플러그인이 사용되며, `net/bridge/bridge-nf-call-iptables=1` 을 설정하여 간단한 구성(브릿지가 있는 Docker 등)이 iptables 프록시에서 올바르게 작동하도록 한다.
### CNI
CNI 플러그인은 Kubelet에 `--network-plugin=cni` 커맨드라인 옵션을 전달하여 선택된다. Kubelet은 `--cni-conf-dir`(기본값은 `/etc/cni/net.d`)에서 파일을 읽고 해당 파일의 CNI 구성을 사용하여 각 파드의 네트워크를 설정한다. CNI 구성 파일은 [CNI 명세](https://github.com/containernetworking/cni/blob/master/SPEC.md#network-configuration)와 일치해야 하며, 구성에서 참조하는 필수 CNI 플러그인은 `--cni-bin-dir`(기본값은 `/opt/cni/bin`)에 있어야 한다.
디렉터리에 여러 CNI 구성 파일이 있는 경우, kubelet은 이름별 알파벳 순으로 구성 파일을 사용한다.
구성 파일에 지정된 CNI 플러그인 외에도, 쿠버네티스는 최소 0.2.0 버전의 표준 CNI [`lo`](https://github.com/containernetworking/plugins/blob/master/plugins/main/loopback/loopback.go) 플러그인이 필요하다.
#### hostPort 지원
CNI 네트워킹 플러그인은 `hostPort` 를 지원한다. CNI 플러그인 팀이 제공하는 공식 [포트맵(portmap)](https://github.com/containernetworking/plugins/tree/master/plugins/meta/portmap)
플러그인을 사용하거나 portMapping 기능이 있는 자체 플러그인을 사용할 수 있다.
`hostPort` 지원을 사용하려면, `cni-conf-dir``portMappings capability` 를 지정해야 한다.
예를 들면 다음과 같다.
```json
{
"name": "k8s-pod-network",
"cniVersion": "0.3.0",
"plugins": [
{
"type": "calico",
"log_level": "info",
"datastore_type": "kubernetes",
"nodename": "127.0.0.1",
"ipam": {
"type": "host-local",
"subnet": "usePodCidr"
},
"policy": {
"type": "k8s"
},
"kubernetes": {
"kubeconfig": "/etc/cni/net.d/calico-kubeconfig"
}
},
{
"type": "portmap",
"capabilities": {"portMappings": true}
}
]
}
```
#### 트래픽 셰이핑 지원
CNI 네트워킹 플러그인은 파드 수신 및 송신 트래픽 셰이핑도 지원한다. CNI 플러그인 팀에서 제공하는 공식 [대역폭(bandwidth)](https://github.com/containernetworking/plugins/tree/master/plugins/meta/bandwidth)
플러그인을 사용하거나 대역폭 제어 기능이 있는 자체 플러그인을 사용할 수 있다.
트래픽 셰이핑 지원을 활성화하려면, CNI 구성 파일 (기본값 `/etc/cni/net.d`)에 `bandwidth` 플러그인을
추가해야 한다.
```json
{
"name": "k8s-pod-network",
"cniVersion": "0.3.0",
"plugins": [
{
"type": "calico",
"log_level": "info",
"datastore_type": "kubernetes",
"nodename": "127.0.0.1",
"ipam": {
"type": "host-local",
"subnet": "usePodCidr"
},
"policy": {
"type": "k8s"
},
"kubernetes": {
"kubeconfig": "/etc/cni/net.d/calico-kubeconfig"
}
},
{
"type": "bandwidth",
"capabilities": {"bandwidth": true}
}
]
}
```
이제 파드에 `kubernetes.io/ingress-bandwidth``kubernetes.io/egress-bandwidth` 어노테이션을 추가할 수 있다.
예를 들면 다음과 같다.
```yaml
apiVersion: v1
kind: Pod
metadata:
annotations:
kubernetes.io/ingress-bandwidth: 1M
kubernetes.io/egress-bandwidth: 1M
...
```
### kubenet
Kubenet은 리눅스에서만 사용할 수 있는 매우 기본적이고, 간단한 네트워크 플러그인이다. 그 자체로는, 크로스-노드 네트워킹 또는 네트워크 정책과 같은 고급 기능을 구현하지 않는다. 일반적으로 노드 간, 또는 단일 노드 환경에서 통신을 위한 라우팅 규칙을 설정하는 클라우드 제공자와 함께 사용된다.
Kubenet은 `cbr0` 라는 리눅스 브리지를 만들고 각 쌍의 호스트 끝이 `cbr0` 에 연결된 각 파드에 대한 veth 쌍을 만든다. 쌍의 파드 끝에는 구성 또는 컨트롤러 관리자를 통해 노드에 할당된 범위 내에서 할당된 IP 주소가 지정된다. `cbr0` 에는 호스트에서 활성화된 일반 인터페이스의 가장 작은 MTU와 일치하는 MTU가 지정된다.
플러그인에는 몇 가지 사항이 필요하다.
* 표준 CNI `bridge`, `lo``host-local` 플러그인은 최소 0.2.0 버전이 필요하다. Kubenet은 먼저 `/opt/cni/bin` 에서 검색한다. 추가 검색 경로를 제공하려면 `cni-bin-dir` 을 지정한다. 처음 검색된 디렉터리가 적용된다.
* 플러그인을 활성화하려면 Kubelet을 `--network-plugin=kubenet` 인수와 함께 실행해야 한다.
* Kubelet은 `--non-masquerade-cidr=<clusterCidr>` 인수와 함께 실행하여 이 범위 밖 IP로의 트래픽이 IP 마스커레이드(masquerade)를 사용하도록 해야 한다.
* `--pod-cidr` kubelet 커맨드라인 옵션 또는 `--allocate-node-cidrs=true --cluster-cidr=<cidr>` 컨트롤러 관리자 커맨드라인 옵션을 통해 노드에 IP 서브넷을 할당해야 한다.
### MTU 사용자 정의 (kubenet 사용)
최상의 네트워킹 성능을 얻으려면 MTU를 항상 올바르게 구성해야 한다. 네트워크 플러그인은 일반적으로 합리적인 MTU를
유추하려고 시도하지만, 때로는 로직에 따라 최적의 MTU가 지정되지 않는다. 예를 들어,
Docker 브리지나 다른 인터페이스에 작은 MTU가 지정되어 있으면, kubenet은 현재 해당 MTU를 선택한다. 또는
IPSEC 캡슐화를 사용하는 경우, MTU를 줄여야 하며, 이 계산은 대부분의
네트워크 플러그인에서 범위를 벗어난다.
필요한 경우, `network-plugin-mtu` kubelet 옵션을 사용하여 MTU를 명시 적으로 지정할 수 있다. 예를 들어,
AWS에서 `eth0` MTU는 일반적으로 9001이므로, `--network-plugin-mtu=9001` 을 지정할 수 있다. IPSEC를 사용하는 경우
캡슐화 오버헤드를 허용하도록 `--network-plugin-mtu=8873` 과 같이 IPSEC을 줄일 수 있다.
이 옵션은 네트워크 플러그인에 제공된다. 현재 **kubenet만 `network-plugin-mtu` 를 지원한다**.
## 용법 요약
* `--network-plugin=cni``--cni-bin-dir`(기본값 `/opt/cni/bin`)에 있는 실제 CNI 플러그인 바이너리와 `--cni-conf-dir`(기본값 `/etc/cni/net.d`)에 있는 CNI 플러그인 구성과 함께 `cni` 네트워크 플러그인을 사용하도록 지정한다.
* `--network-plugin=kubenet``/opt/cni/bin` 또는 `cni-bin-dir` 에 있는 CNI `bridge``host-local` 플러그인과 함께 kubenet 네트워크 플러그인을 사용하도록 지정한다.
* 현재 kubenet 네트워크 플러그인에서만 사용하는 `--network-plugin-mtu=9001` 은 사용할 MTU를 지정한다.
{{% /capture %}}
{{% capture whatsnext %}}
{{% /capture %}}

View File

@ -112,12 +112,12 @@ kubectl에서
애플리케이션, 사용자 또는 모니터링 데이터의 데이터 저장소로 커스텀 리소스를 사용하지 않는다.
커스텀 리소스에 대한 자세한 내용은 [커스텀 리소스 개념 가이드](/docs/concepts/api-extension/custom-resources/)를 참고하길 바란다.
커스텀 리소스에 대한 자세한 내용은 [커스텀 리소스 개념 가이드](/ko/docs/concepts/extend-kubernetes/api-extension/custom-resources/)를 참고하길 바란다.
### 새로운 API와 자동화의 결합
사용자 정의 리소스 API와 컨트롤 루프의 조합을 [오퍼레이터(operator) 패턴](/docs/concepts/extend-kubernetes/operator/)이라고 한다. 오퍼레이터 패턴은 특정 애플리케이션, 일반적으로 스테이트풀(stateful) 애플리케이션을 관리하는 데 사용된다. 이러한 사용자 정의 API 및 컨트롤 루프를 사용하여 스토리지나 정책과 같은 다른 리소스를 제어할 수도 있다.
사용자 정의 리소스 API와 컨트롤 루프의 조합을 [오퍼레이터(operator) 패턴](/ko/docs/concepts/extend-kubernetes/operator/)이라고 한다. 오퍼레이터 패턴은 특정 애플리케이션, 일반적으로 스테이트풀(stateful) 애플리케이션을 관리하는 데 사용된다. 이러한 사용자 정의 API 및 컨트롤 루프를 사용하여 스토리지나 정책과 같은 다른 리소스를 제어할 수도 있다.
### 빌트인 리소스 변경
@ -194,7 +194,7 @@ Kubelet이 바이너리 플러그인을 호출하여 볼륨을 마운트하도
{{% capture whatsnext %}}
* [커스텀 리소스](/docs/concepts/api-extension/custom-resources/)에 대해 더 알아보기
* [커스텀 리소스](/ko/docs/concepts/extend-kubernetes/api-extension/custom-resources/)에 대해 더 알아보기
* [동적 어드미션 컨트롤](/docs/reference/access-authn-authz/extensible-admission-controllers/)에 대해 알아보기
* 인프라스트럭처 익스텐션에 대해 더 알아보기
* [네트워크 플러그인](/docs/concepts/cluster-administration/network-plugins/)

View File

@ -7,7 +7,7 @@ weight: 30
{{% capture overview %}}
오퍼레이터(Operator)는
[사용자 정의 리소스](/docs/concepts/extend-kubernetes/api-extension/custom-resources/)를
[사용자 정의 리소스](/ko/docs/concepts/extend-kubernetes/api-extension/custom-resources/)를
사용하여 애플리케이션 및 해당 컴포넌트를 관리하는 쿠버네티스의 소프트웨어 익스텐션이다. 오퍼레이터는
쿠버네티스 원칙, 특히 [컨트롤 루프](/ko/docs/concepts/#쿠버네티스-컨트롤-플레인)를 따른다.
@ -37,7 +37,7 @@ weight: 30
쿠버네티스의 {{< glossary_tooltip text="컨트롤러" term_id="controller" >}}
개념을 통해 쿠버네티스 코드 자체를 수정하지 않고도 클러스터의 동작을
확장할 수 있다.
오퍼레이터는 [사용자 정의 리소스](/docs/concepts/api-extension/custom-resources/)의
오퍼레이터는 [사용자 정의 리소스](/ko/docs/concepts/extend-kubernetes/api-extension/custom-resources/)의
컨트롤러 역할을 하는 쿠버네티스 API의 클라이언트이다.
## 오퍼레이터 예시 {#example}
@ -110,14 +110,14 @@ kubectl edit SampleDB/example-database # 일부 설정을 수동으로 변경하
사용할 수 있는 라이브러리 및 도구에 대한 몇 가지 링크를
찾을 수 있다.
또한 [쿠버네티스 API의 클라이언트](/docs/reference/using-api/client-libraries/)
또한 [쿠버네티스 API의 클라이언트](/ko/docs/reference/using-api/client-libraries/)
역할을 할 수 있는 모든 언어 / 런타임을 사용하여 오퍼레이터(즉, 컨트롤러)를 구현한다.
{{% /capture %}}
{{% capture whatsnext %}}
* [사용자 정의 리소스](/docs/concepts/extend-kubernetes/api-extension/custom-resources/)에 대해 더 알아보기
* [사용자 정의 리소스](/ko/docs/concepts/extend-kubernetes/api-extension/custom-resources/)에 대해 더 알아보기
* [OperatorHub.io](https://operatorhub.io/)에서 유스케이스에 맞는 이미 만들어진 오퍼레이터 찾기
* 기존 도구를 사용하여 자신만의 오퍼레이터를 작성해보자. 다음은 예시이다.
* [KUDO](https://kudo.dev/) (Kubernetes Universal Declarative Operator) 사용하기

View File

@ -121,6 +121,6 @@ cloud-controller-manager는 클라우드 벤더 코드와 쿠버네티스 코드
{{% capture whatsnext %}}
* [노드](/ko/docs/concepts/architecture/nodes/)에 대해 더 배우기
* [컨트롤러](/ko/docs/concepts/architecture/controller/)에 대해 더 배우기
* [kube-scheduler](/docs/concepts/scheduling/kube-scheduler/)에 대해 더 배우기
* [kube-scheduler](/ko/docs/concepts/scheduling/kube-scheduler/)에 대해 더 배우기
* etcd의 공식 [문서](https://etcd.io/docs/) 읽기
{{% /capture %}}

View File

@ -1,5 +1,5 @@
---
title: 쿠버네티스란 무엇인가
title: 쿠버네티스란 무엇인가?
description: >
쿠버네티스는 컨테이너화된 워크로드와 서비스를 관리하기 위한 이식할 수 있고, 확장 가능한 오픈소스 플랫폼으로, 선언적 구성과 자동화를 모두 지원한다. 쿠버네티스는 크고 빠르게 성장하는 생태계를 가지고 있다. 쿠버네티스 서비스, 지원 그리고 도구들은 광범위하게 제공된다.
content_template: templates/concept

View File

@ -25,7 +25,7 @@ weight: 30
네임스페이스를 통틀어서 유일할 필요는 없다. 네임스페이스는 서로 중첩될 수 없으며,
각 쿠버네티스 리소스는 하나의 네임스페이스에만 있을 수 있다.
네임스페이스는 클러스터 자원을 ([리소스 쿼터](/docs/concepts/policy/resource-quotas/)를 통해) 여러 사용자 사이에서 나누는 방법이다.
네임스페이스는 클러스터 자원을 ([리소스 쿼터](/ko/docs/concepts/policy/resource-quotas/)를 통해) 여러 사용자 사이에서 나누는 방법이다.
이후 버전의 쿠버네티스에서는 같은 네임스페이스의 오브젝트는 기본적으로
동일한 접근 제어 정책을 갖게 된다.
@ -51,6 +51,7 @@ NAME STATUS AGE
default Active 1d
kube-system Active 1d
kube-public Active 1d
kube-node-lease Active 1d
```
쿠버네티스는 처음에 세 개의 초기 네임스페이스를 갖는다.

View File

@ -49,335 +49,14 @@ _리밋레인지_ 는 다음과 같은 제약 조건을 제공한다.
경합이나 리밋레인지 변경은 이미 생성된 리소스에 영향을 미치지 않는다.
## 컨테이너 컴퓨팅 리소스 제한
다음 절에서는 컨테이너 레벨에서 작동하는 리밋레인지 생성에 대해 설명한다.
4개의 컨테이너가 있는 파드가 먼저 생성된다. 파드 내의 각 컨테이너에는 특정 `spec.resource` 구성이 있다.
파드 내의 각 컨테이너는 `LimitRanger` 어드미션 컨트롤러에 의해 다르게 처리된다.
다음 kubectl 명령을 사용하여 네임스페이스 `limitrange-demo`를 생성한다.
```shell
kubectl create namespace limitrange-demo
```
kubectl 명령에서 네임스페이스 대상인 `limitrange-demo`를 빠트리지 않으려면 다음 명령으로 컨텍스트를 변경한다.
```shell
kubectl config set-context --current --namespace=limitrange-demo
```
다음은 리밋레인지 오브젝트의 구성 파일이다.
{{< codenew file="admin/resource/limit-mem-cpu-container.yaml" >}}
이 오브젝트는 컨테이너에 적용할 최소 및 최대 CPU/메모리 제한, 기본 CPU/메모리 요청과 CPU/메모리 리소스에 대한 기본 제한을 정의한다.
다음 kubectl 명령을 사용하여 `limit-mem-cpu-per-container` 리밋레인지를 생성한다.
```shell
kubectl create -f https://k8s.io/examples/admin/resource/limit-mem-cpu-container.yaml
```
```shell
kubectl describe limitrange/limit-mem-cpu-per-container
```
```shell
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Container cpu 100m 800m 110m 700m -
Container memory 99Mi 1Gi 111Mi 900Mi -
```
다음은 4개의 컨테이너가 포함된 파드의 구성 파일로 리밋레인지 기능을 보여준다.
{{< codenew file="admin/resource/limit-range-pod-1.yaml" >}}
`busybox1` 파드를 생성한다.
```shell
kubectl apply -f https://k8s.io/examples/admin/resource/limit-range-pod-1.yaml
```
### 유효한 CPU/메모리 요청과 제한이 있는 컨테이너 스펙
`busybox-cnt01`의 리소스 구성을 보자.
```shell
kubectl get po/busybox1 -o json | jq ".spec.containers[0].resources"
```
```json
{
"limits": {
"cpu": "500m",
"memory": "200Mi"
},
"requests": {
"cpu": "100m",
"memory": "100Mi"
}
}
```
- `busybox` 파드 내의 `busybox-cnt01` 컨테이너는 `requests.cpu=100m``requests.memory=100Mi`로 정의됐다.
- `100m <= 500m <= 800m`, 컨테이너 CPU 제한(500m)은 승인된 CPU 리밋레인지 내에 있다.
- `99Mi <= 200Mi <= 1Gi`, 컨테이너 메모리 제한(200Mi)은 승인된 메모리 리밋레인지 내에 있다.
- CPU/메모리에 대한 요청/제한 비율 검증이 없으므로 컨테이너가 유효하며 생성되었다.
### 유효한 CPU/메모리 요청은 있지만 제한이 없는 컨테이너 스펙
`busybox-cnt02`의 리소스 구성을 보자.
```shell
kubectl get po/busybox1 -o json | jq ".spec.containers[1].resources"
```
```json
{
"limits": {
"cpu": "700m",
"memory": "900Mi"
},
"requests": {
"cpu": "100m",
"memory": "100Mi"
}
}
```
- `busybox1` 파드 내의 `busybox-cnt02` 컨테이너는 `requests.cpu=100m``requests.memory=100Mi`를 정의했지만 CPU와 메모리에 대한 제한은 없다.
- 컨테이너에 제한 섹션이 없다. `limit-mem-cpu-per-container` 리밋레인지 오브젝트에 정의된 기본 제한은 `limits.cpu=700mi``limits.memory=900Mi`로 이 컨테이너에 설정된다.
- `100m <= 700m <= 800m`, 컨테이너 CPU 제한(700m)이 승인된 CPU 제한 범위 내에 있다.
- `99Mi <= 900Mi <= 1Gi`, 컨테이너 메모리 제한(900Mi)이 승인된 메모리 제한 범위 내에 있다.
- 요청/제한 비율이 설정되지 않았으므로 컨테이너가 유효하며 생성되었다.
### 유효한 CPU/메모리 제한은 있지만 요청은 없는 컨테이너 스펙
`busybox-cnt03`의 리소스 구성을 보자.
```shell
kubectl get po/busybox1 -o json | jq ".spec.containers[2].resources"
```
```json
{
"limits": {
"cpu": "500m",
"memory": "200Mi"
},
"requests": {
"cpu": "500m",
"memory": "200Mi"
}
}
```
- `busybox1` 파드 내의 `busybox-cnt03` 컨테이너는 `limits.cpu=500m``limits.memory=200Mi`를 정의했지만 CPU와 메모리에 대한 요청은 없다.
- 컨테이너에 요청 섹션이 정의되지 않았다. `limit-mem-cpu-per-container` 리밋레인지에 정의된 기본 요청은 제한 섹션을 채우는 데 사용되지 않지만 컨테이너에 의해 정의된 제한은 `limits.cpu=500m``limits.memory=200Mi`로 설정된다.
- `100m <= 500m <= 800m`, 컨테이너 CPU 제한(500m)은 승인된 CPU 제한 범위 내에 있다.
- `99Mi <= 200Mi <= 1Gi`, 컨테이너 메모리 제한(200Mi)은 승인된 메모리 제한 범위 내에 있다.
- 요청/제한 비율이 설정되지 않았으므로 컨테이너가 유효하며 생성되었다.
### CPU/메모리 요청/제한이 없는 컨테이너 스펙
`busybox-cnt04`의 리소스 구성을 보자.
```shell
kubectl get po/busybox1 -o json | jq ".spec.containers[3].resources"
```
```json
{
"limits": {
"cpu": "700m",
"memory": "900Mi"
},
"requests": {
"cpu": "110m",
"memory": "111Mi"
}
}
```
- `busybox1``busybox-cnt04` 컨테이너는 제한이나 요청을 정의하지 않았다.
- 컨테이너는 제한 섹션을 정의하지 않으며 `limit-mem-cpu-per-container` 리밋레인지에 정의된 기본 제한은 `limit.cpu=700m``limits.memory=900Mi`로 설정된다.
- 컨테이너는 요청 섹션을 정의하지 않으며 `limit-mem-cpu-per-container` 리밋레인지에 정의된 defaultRequest는 `requests.cpu=110m``requests.memory=111Mi`로 설정된다.
- `100m <= 700m <= 800m`, 컨테이너 CPU 제한(700m)은 승인된 CPU 제한 범위 내에 있다.
- `99Mi <= 900Mi <= 1Gi`, 컨테이너 메모리 제한(900Mi)은 승인된 메모리 제한 범위 내에 있다.
- 요청/제한 비율이 설정되지 않았으므로 컨테이너가 유효하며 생성되었다.
`busybox` 파드에 정의된 모든 컨테이너는 리밋레인지 유효성 검사를 통과했으므로 이 파드는 유효하며 네임스페이스에서 생성된다.
## 파드 컴퓨팅 리소스 제한
다음 절에서는 파드 레벨에서 리소스를 제한하는 방법에 대해 설명한다.
{{< codenew file="admin/resource/limit-mem-cpu-pod.yaml" >}}
`busybox1` 파드를 삭제하지 않고 `limitrange-demo` 네임스페이스에 `limit-mem-cpu-pod` 리밋레인지를 생성한다.
```shell
kubectl apply -f https://k8s.io/examples/admin/resource/limit-mem-cpu-pod.yaml
```
리밋레인지가 생성되고 파드별로 CPU가 2 코어로, 메모리가 2Gi로 제한된다.
```shell
limitrange/limit-mem-cpu-per-pod created
```
다음 kubectl 명령을 사용하여 `limit-mem-cpu-per-pod` 리밋레인지 오브젝트의 정보를 나타낸다.
```shell
kubectl describe limitrange/limit-mem-cpu-per-pod
```
```shell
Name: limit-mem-cpu-per-pod
Namespace: limitrange-demo
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Pod cpu - 2 - - -
Pod memory - 2Gi - - -
```
이제 `busybox2` 파드를 생성한다.
{{< codenew file="admin/resource/limit-range-pod-2.yaml" >}}
```shell
kubectl apply -f https://k8s.io/examples/admin/resource/limit-range-pod-2.yaml
```
`busybox2` 파드 정의는 `busybox1`과 동일하지만 이제 파드 리소스가 제한되어 있으므로 오류가 보고된다.
```shell
Error from server (Forbidden): error when creating "limit-range-pod-2.yaml": pods "busybox2" is forbidden: [maximum cpu usage per Pod is 2, but limit is 2400m., maximum memory usage per Pod is 2Gi, but limit is 2306867200.]
```
```shell
kubectl get po/busybox1 -o json | jq ".spec.containers[].resources.limits.memory"
"200Mi"
"900Mi"
"200Mi"
"900Mi"
```
해당 컨테이너의 총 메모리 제한이 리밋레인지에 정의된 제한보다 크므로 `busybox2` 파드는 클러스터에서 허용되지 않는다.
`busyRange1`은 리밋레인지를 생성하기 전에 클러스터에서 생성되고 허용되므로 제거되지 않는다.
## 스토리지 리소스 제한
리밋레인지를 사용하여 네임스페이스에서 각 퍼시스턴트볼륨클레임이 요청할 수 있는 [스토리지 리소스](/ko/docs/concepts/storage/persistent-volumes/)의 최소 및 최대 크기를 지정할 수 있다.
{{< codenew file="admin/resource/storagelimits.yaml" >}}
`kubectl create`를 사용하여 YAML을 적용한다.
```shell
kubectl create -f https://k8s.io/examples/admin/resource/storagelimits.yaml
```
```shell
limitrange/storagelimits created
```
생성된 오브젝트의 정보를 나타낸다.
```shell
kubectl describe limits/storagelimits
```
출력은 다음과 같다.
```shell
Name: storagelimits
Namespace: limitrange-demo
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
PersistentVolumeClaim storage 1Gi 2Gi - - -
```
{{< codenew file="admin/resource/pvc-limit-lower.yaml" >}}
```shell
kubectl create -f https://k8s.io/examples/admin/resource/pvc-limit-lower.yaml
```
`requests.storage`가 리밋레인지의 Min 값보다 낮은 PVC를 만드는 동안 서버에서 발생하는 오류는 다음과 같다.
```shell
Error from server (Forbidden): error when creating "pvc-limit-lower.yaml": persistentvolumeclaims "pvc-limit-lower" is forbidden: minimum storage usage per PersistentVolumeClaim is 1Gi, but request is 500Mi.
```
`requests.storage`가 리밋레인지의 Max 값보다 큰 경우에도 동일한 동작이 나타난다.
{{< codenew file="admin/resource/pvc-limit-greater.yaml" >}}
```shell
kubectl create -f https://k8s.io/examples/admin/resource/pvc-limit-greater.yaml
```
```shell
Error from server (Forbidden): error when creating "pvc-limit-greater.yaml": persistentvolumeclaims "pvc-limit-greater" is forbidden: maximum storage usage per PersistentVolumeClaim is 2Gi, but request is 5Gi.
```
## 제한/요청 비율
`LimitRangeSpec``LimitRangeItem.maxLimitRequestRatio`가 지정되어 있으면 명명된 리소스는 제한을 요청으로 나눈 값이 열거된 값보다 작거나 같은 0이 아닌 값을 요청과 제한 모두 가져야 한다.
다음의 리밋레인지는 메모리 제한이 네임스페이스의 모든 파드에 대한 메모리 요청 양의 최대 두 배가 되도록 한다.
{{< codenew file="admin/resource/limit-memory-ratio-pod.yaml" >}}
```shell
kubectl apply -f https://k8s.io/examples/admin/resource/limit-memory-ratio-pod.yaml
```
다음의 kubectl 명령으로 `limit-memory-ratio-pod` 리밋레인지의 정보를 나타낸다.
```shell
kubectl describe limitrange/limit-memory-ratio-pod
```
```shell
Name: limit-memory-ratio-pod
Namespace: limitrange-demo
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Pod memory - - - - 2
```
`requests.memory=100Mi``limits.memory=300Mi`로 파드를 생성한다.
{{< codenew file="admin/resource/limit-range-pod-3.yaml" >}}
```shell
kubectl apply -f https://k8s.io/examples/admin/resource/limit-range-pod-3.yaml
```
위 예에서 제한/요청 비율(`3`)이 `limit-memory-ratio-pod` 리밋레인지에 지정된 제한 비율(`2`)보다 커서 파드 생성에 실패했다.
```
Error from server (Forbidden): error when creating "limit-range-pod-3.yaml": pods "busybox3" is forbidden: memory max limit to request ratio per Pod is 2, but provided ratio is 3.000000.
```
## 정리
모든 리소스를 해제하려면 `limitrange-demo` 네임스페이스를 삭제한다.
```shell
kubectl delete ns limitrange-demo
```
다음 명령을 사용하여 컨텍스트를 `default` 네임스페이스로 변경한다.
```shell
kubectl config set-context --current --namespace=default
```
## 예제
- [네임스페이스별 컴퓨팅 리소스를 제한하는 방법에 대한 튜토리얼](/docs/tasks/administer-cluster/manage-resources/cpu-constraint-namespace/)을 참고하길 바란다.
- [스토리지 사용을 제한하는 방법](/docs/tasks/administer-cluster/limit-storage-consumption/#limitrange-to-limit-requests-for-storage)을 확인하라.
- [네임스페이스별 쿼터에 대한 자세한 예](/docs/tasks/administer-cluster/quota-memory-cpu-namespace/)를 참고하길 바란다.
- [네임스페이스당 최소 및 최대 CPU 제약 조건을 설정하는 방법](/docs/tasks/administer-cluster/manage-resources/cpu-constraint-namespace/)을 본다.
- [네임스페이스당 최소 및 최대 메모리 제약 조건을 설정하는 방법](/docs/tasks/administer-cluster/manage-resources/memory-constraint-namespace/)을 본다.
- [네임스페이스당 기본 CPU 요청과 제한을 설정하는 방법](/docs/tasks/administer-cluster/manage-resources/cpu-default-namespace/)을 본다.
- [네임스페이스당 기본 메모리 요청과 제한을 설정하는 방법](/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/)을 본다.
- [네임스페이스당 최소 및 최대 스토리지 사용량을 설정하는 방법](/docs/tasks/administer-cluster/limit-storage-consumption/#limitrange-to-limit-requests-for-storage)을 확인한다.
- [네임스페이스당 할당량을 설정하는 자세한 예시](/docs/tasks/administer-cluster/quota-memory-cpu-namespace/)를 본다.
{{% /capture %}}

View File

@ -26,17 +26,17 @@ _Pod Security Policy_ 는 파드 명세의 보안 관련 측면을 제어하는
| 제어 측면 | 필드 이름 |
| ----------------------------------------------------| ------------------------------------------- |
| 특권을 가진(privileged) 컨테이너의 실행 | [`privileged`](#privileged) |
| 호스트 네임스페이스의 사용 | [`hostPID`, `hostIPC`](#host-namespaces) |
| 호스트 네트워킹과 포트의 사용 | [`hostNetwork`, `hostPorts`](#host-namespaces) |
| 볼륨 유형의 사용 | [`volumes`](#volumes-and-file-systems) |
| 호스트 파일시스템의 사용 | [`allowedHostPaths`](#volumes-and-file-systems) |
| FlexVolume 드라이버의 화이트리스트 | [`allowedFlexVolumes`](#flexvolume-drivers) |
| 파드 볼륨을 소유한 FSGroup 할당 | [`fsGroup`](#volumes-and-file-systems) |
| 읽기 전용 루트 파일시스템 사용 필요 | [`readOnlyRootFilesystem`](#volumes-and-file-systems) |
| 컨테이너의 사용자 및 그룹 ID | [`runAsUser`, `runAsGroup`, `supplementalGroups`](#users-and-groups) |
| 루트 특권으로의 에스컬레이션 제한 | [`allowPrivilegeEscalation`, `defaultAllowPrivilegeEscalation`](#privilege-escalation) |
| 리눅스 기능 | [`defaultAddCapabilities`, `requiredDropCapabilities`, `allowedCapabilities`](#capabilities) |
| 특권을 가진(privileged) 컨테이너의 실행 | [`privileged`](#특권을-가진) |
| 호스트 네임스페이스의 사용 | [`hostPID`, `hostIPC`](#호스트-네임스페이스) |
| 호스트 네트워킹과 포트의 사용 | [`hostNetwork`, `hostPorts`](#호스트-네임스페이스) |
| 볼륨 유형의 사용 | [`volumes`](#볼륨-및-파일시스템) |
| 호스트 파일시스템의 사용 | [`allowedHostPaths`](#볼륨-및-파일시스템) |
| FlexVolume 드라이버의 화이트리스트 | [`allowedFlexVolumes`](#flexvolume-드라이버) |
| 파드 볼륨을 소유한 FSGroup 할당 | [`fsGroup`](#볼륨-및-파일시스템) |
| 읽기 전용 루트 파일시스템 사용 필요 | [`readOnlyRootFilesystem`](#볼륨-및-파일시스템) |
| 컨테이너의 사용자 및 그룹 ID | [`runAsUser`, `runAsGroup`, `supplementalGroups`](#사용자-및-그룹) |
| 루트 특권으로의 에스컬레이션 제한 | [`allowPrivilegeEscalation`, `defaultAllowPrivilegeEscalation`](#권한-에스컬레이션) |
| 리눅스 기능 | [`defaultAddCapabilities`, `requiredDropCapabilities`, `allowedCapabilities`](#기능) |
| 컨테이너의 SELinux 컨텍스트 | [`seLinux`](#selinux) |
| 컨테이너에 허용된 Proc 마운트 유형 | [`allowedProcMountTypes`](#allowedprocmounttypes) |
| 컨테이너가 사용하는 AppArmor 프로파일 | [어노테이션](#apparmor) |

View File

@ -8,7 +8,7 @@ weight: 70
{{< feature-state for_k8s_version="1.14" state="beta" >}}
[kube-scheduler](/docs/concepts/scheduling/kube-scheduler/#kube-scheduler)
[kube-scheduler](/ko/docs/concepts/scheduling/kube-scheduler/#kube-scheduler)
는 쿠버네티스의 기본 스케줄러이다. 그것은 클러스터의
노드에 파드를 배치하는 역할을 한다.
@ -26,25 +26,69 @@ API 서버에 해당 결정을 통지한다.
{{% capture body %}}
## 점수를 측정할 노드의 비율
큰 규모의 클러스터에서는 스케줄러의 동작을 튜닝하여 응답 시간
(새 파드가 빠르게 배치됨)과 정확도(스케줄러가 배치 결정을 잘 못하는 경우가 드물게 됨)
사이에서의 스케줄링 결과를 균형 잡을 수 있다.
쿠버네티스 1.12 이전 버전에서, Kube-scheduler는 클러스터의 모든 노드에
대한 적합성(feasibility)을 확인한 후에 적합한 노드들에 대해서 점수를 측정했다.
쿠버네티스 1.12는 새로운 특징을 추가했으며, 이 특징은 스케줄러가 특정
숫자의 적합한 노드를 찾은 이후에 추가적인 적합 노드를 찾는 것을 중단하게 한다.
이것은 대규모 클러스터에서 스케줄러 성능을 향상시킨다. 해당 숫자는 클러스터
크기에 대한 비율로 지정된다. 그 비율은 `percentageOfNodesToScore` 구성
옵션으로 제어될 수 있다. 값의 범위는 1과 100 사이여야 한다. 더 높은 값은
100%로 간주된다. 0은 구성 옵션을 제공하지 않는 것과 동일하다.
점수를 측정할 노드의 비율이 구성 옵션에 명시되지 않은 경우를 대비하여, 쿠버네티스 1.14는
클러스터의 크기에 기반하여 해당 비율 값을 찾는 로직을 가지고 있다. 이 로직은
100-노드 클러스터에 대해 50%를 값으로 출력하는 선형 공식을 사용한다. 해당 공식은 5000-노드
클러스터에 대해서는 10%를 값으로 출력한다. 자동으로 지정되는 값의 하한값은 5%이다. 다시
말해, 사용자가 구성 옵션에 5 보다 낮은 값은 지정하지 않은 한, 스케줄러는
클러스터의 크기와 무관하게 적어도 5%의 클러스터에 대해서는 항상 점수를
측정한다.
kube-scheduler 의 `percentageOfNodesToScore` 설정을 통해
이 튜닝을 구성 한다. 이 KubeSchedulerConfiguration 설정에 따라 클러스터의
노드를 스케줄링할 수 있는 임계값이 결정된다.
아래는 `percentageOfNodesToScore`를 50%로 설정하는 구성 예제이다.
### 임계값 설정하기
`percentageOfNodesToScore` 옵션은 0과 100 사이의 값을
허용한다. 값 0은 kube-scheduler가 컴파일 된 기본값을
사용한다는 것을 나타내는 특별한 숫자이다.
`percentageOfNodesToScore` 를 100 보다 높게 설정해도 kube-scheduler는
마치 100을 설정한 것처럼 작동한다.
값을 변경하려면, kube-scheduler 구성 파일(이 파일은 `/etc/kubernetes/config/kube-scheduler.yaml`
일 수 있다)을 편집한 다음 스케줄러를 재시작 한다.
이를 변경한 후에 다음을 실행해서
```bash
kubectl get componentstatuses
```
kube-scheduler 컴포넌트가 정상인지 확인할 수 있다. 출력은 다음과 유사하다.
```
NAME STATUS MESSAGE ERROR
controller-manager Healthy ok
scheduler Healthy ok
...
```
## 노드 스코어링(scoring) 임계값 {#percentage-of-nodes-to-score}
스케줄링 성능을 향상시키기 위해 kube-scheduler는 실행 가능한
노드가 충분히 발견되면 이를 찾는 것을 중단할 수 있다. 큰 규모의 클러스터에서는
모든 노드를 고려하는 고지식한 접근 방식에 비해 시간이 절약된다.
클러스터에 있는 모든 노드의 정수 백분율로 충분한 노두의 수에
대한 임계값을 지정한다. kube-scheduler는 이 값을 노드의
정수 값(숫자)로 변환 한다. 스케줄링 중에 kube-scheduler가 구성된
비율을 초과 할만큼 충분히 실행 가능한 노드를 식별한 경우, kube-scheduler는
더 실행 가능한 노드를 찾는 검색을 중지하고
[스코어링 단계](/ko/docs/concepts/scheduling/kube-scheduler/#kube-scheduler-implementation)를 진행한다.
[스케줄러가 노드 탐색을 반복(iterate)하는 방법](#스케줄러가-노드-탐색을-반복-iterate-하는-방법)
은 이 프로세스를 자세히 설명한다.
### 기본 임계값
임계값을 지정하지 않으면 쿠버네티스는 100 노드 클러스터인
경우 50%, 5000 노드 클러스터인 경우 10%를 산출하는
선형 공식을 사용하여 수치를 계산한다. 자동 값의 하한선은 5% 이다.
즉, `percentageOfNodesToScore` 를 명시적으로 5보다 작게 설정하지
않은 경우 클러스터가 아무리 크더라도 kube-scheduler는
항상 클러스터의 최소 5%를 스코어링을 한다.
스케줄러가 클러스터의 모든 노드에 스코어링을 하려면
`percentageOfNodesToScore` 를 100으로 설정 한다.
## 예시
아래는 `percentageOfNodesToScore`를 50%로 설정하는 구성 예시이다.
```yaml
apiVersion: kubescheduler.config.k8s.io/v1alpha1
@ -57,38 +101,37 @@ algorithmSource:
percentageOfNodesToScore: 50
```
{{< note >}} 클러스터에서 적합한 노드가 50 미만인 경우, 스케줄러는 여전히
모든 노드를 확인한다. 그 이유는 스케줄러가 탐색을 조기 중단하기에는 적합한
노드의 수가 충분하지 않기 때문이다. {{< /note >}}
**이 특징을 비활성화하려면**, `percentageOfNodesToScore`를 100으로 지정한다.
### percentageOfNodesToScore 튜닝
`percentageOfNodesToScore`는 1과 100 사이의 값이어야하며
기본 값은 클러스터 크기에 따라 계산된다. 또한 50 노드로 하드 코딩된
최소 값도 있다. 이는 수백 개 정도의 노드가 있는
클러스터에서는 해당 옵션을 더 낮은 값으로 변경하더라도 스케줄러가
찾으려는 적합한 노드의 개수에는 크게 영향을 주지 않는다는 뜻이다.
이것은 규모가 작은 클러스터에서는 이 옵션의 조정이 성능을 눈에 띄게 향상시키지 않는
것을 감안하여 의도적으로 설계되었다. 1000 노드 이상의 큰 규모의 클러스터에서는 이 값을
낮은 수로 설정하면 눈에 띄는 성능 향상을 보일 수도 있다.
최소 값도 있다.
이 값을 세팅할 때 중요하게 고려해야 할 사항은, 클러스터에서
{{< note >}} 클러스터에서 적합한 노드가 50 미만인 경우, 스케줄러는 여전히
모든 노드를 확인한다. 그 이유는 스케줄러가 탐색을 조기 중단하기에는 적합한
노드의 수가 충분하지 않기 때문이다.
규모가 작은 클러스터에서는 `percentageOfNodesToScore` 에 낮은 값을 설정하면,
비슷한 이유로 변경 사항이 거의 또는 전혀 영향을 미치지 않게 된다.
클러스터에 수백 개 이하의 노드가 있는 경우 이 구성 옵션을
기본값으로 둔다. 이는 변경사항을 적용하더라도 스케줄러의
성능이 크게 향상되지 않는다.
{{< /note >}}
이 값을 세팅할 때 중요하고 자세한 사항은, 클러스터에서
적은 수의 노드에 대해서만 적합성을 확인하면, 주어진 파드에 대해서
일부 노드의 점수는 측정이되지 않는다는 것이다. 결과적으로, 주어진 파드를 실행하는데
가장 높은 점수를 가질 가능성이 있는 노드가 점수 측정 단계로 조차 넘어가지
않을 수 있다. 이것은 파드의 이상적인 배치보다 낮은 결과를 초래할 것이다.
그 이유로, 이 값은 너무 낮은 비율로 설정되면 안 된다. 대략의 경험적 법칙은 10 이하의
값으로는 설정하지 않는 것이다. 더 낮은 값은 사용자의 애플리케이션에서 스케줄러의
처리량이 치명적이고 노드의 점수가 중요하지 않을 경우에만 사용해야 한다. 다시 말해서, 파드의
실행에 적합하기만 하다면 어느 노드가 선택되어도 사용자에게 상관없는 경우를 말한다.
만약 사용자의 클러스터가 단지 백여 개 또는 더 적은 노드를 가지고 있는 경우, 이 구성 옵션의
기본 값보다 낮은 값으로의 변경을 추천하지 않는다. 그것이 스케줄러의 성능을 크게
향상시키지는 않을 것이다.
`percentageOfNodesToScore` 를 매우 낮게 설정해서 kube-scheduler가
파드 배치 결정을 잘못 내리지 않도록 해야 한다. 스케줄러의 처리량에
대해 애플리케이션이 중요하고 노드 점수가 중요하지 않은 경우가 아니라면
백분율을 10% 미만으로 설정하지 말아야 한다. 즉, 가능한 한
모든 노드에서 파드를 실행하는 것이 좋다.
### 스케줄러가 노드 탐색을 반복(iterate)하는 방법
## 스케줄러가 노드 탐색을 반복(iterate)하는 방법
이 섹션은 이 특징의 상세한 내부 방식을 이해하고 싶은 사람들을
위해 작성되었다.

View File

@ -6,7 +6,7 @@ feature:
쿠버네티스 클러스터에서 확장 가능한 네트워크 엔드포인트 추적.
content_template: templates/concept
weight: 10
weight: 15
---
@ -22,6 +22,21 @@ _엔드포인트슬라이스_ 는 쿠버네티스 클러스터 내의 네트워
{{% capture body %}}
## 사용동기
엔드포인트 API는 쿠버네티스에서 네트워크 엔드포인트를 추적하는
간단하고 직접적인 방법을 제공한다. 불행하게도 쿠버네티스 클러스터와
서비스가 점점 더 커짐에 따라, 이 API의 한계가 더욱 눈에 띄게 되었다.
특히나, 많은 수의 네트워크 엔드포인트로 확장하는 것에
어려움이 있었다.
이후로 서비스에 대한 모든 네트워크 엔드포인트가 단일 엔드포인트
리소스에 저장되기 때문에 엔드포인트 리소스가 상당히 커질 수 있다. 이것은 쿠버네티스
구성요소 (특히 마스터 컨트롤 플레인)의 성능에 영향을 미쳤고
엔드포인트가 변경될 때 상당한 양의 네트워크 트래픽과 처리를 초래했다.
엔드포인트슬라이스는 이러한 문제를 완화하고 토폴로지 라우팅과
같은 추가 기능을 위한 확장 가능한 플랫폼을 제공한다.
## 엔드포인트슬라이스 리소스 {#endpointslice-resource}
쿠버네티스에서 EndpointSlice는 일련의 네트워크 엔드 포인트에 대한
@ -163,21 +178,6 @@ text="kube-controller-manager" term_id="kube-controller-manager" >}} 플래그
교체되는 엔드포인트에 대해서 엔드포인트슬라이스를
자연스럽게 재포장한다.
## 사용동기
엔드포인트 API는 쿠버네티스에서 네트워크 엔드포인트를 추적하는
간단하고 직접적인 방법을 제공한다. 불행하게도 쿠버네티스 클러스터와
서비스가 점점 더 커짐에 따라, 이 API의 한계가 더욱 눈에 띄게 되었다.
특히나, 많은 수의 네트워크 엔드포인트로 확장하는 것에
어려움이 있었다.
이후로 서비스에 대한 모든 네트워크 엔드포인트가 단일 엔드포인트
리소스에 저장되기 때문에 엔드포인트 리소스가 상당히 커질 수 있다. 이것은 쿠버네티스
구성요소 (특히 마스터 컨트롤 플레인)의 성능에 영향을 미쳤고
엔드포인트가 변경될 때 상당한 양의 네트워크 트래픽과 처리를 초래했다.
엔드포인트슬라이스는 이러한 문제를 완화하고 토폴로지 라우팅과
같은 추가 기능을 위한 확장 가능한 플랫폼을 제공한다.
{{% /capture %}}
{{% capture whatsnext %}}

View File

@ -122,7 +122,7 @@ spec:
유형이 있다.
* _`ImplementationSpecific`_ (기본): 이 경로 유형의 일치 여부는 IngressClass에 따라
달라진다. 이를 구현할 때 별도 pathType으로 처리하거나, `Prefix` 또는 `Exact`
달라진다. 이를 구현할 때 별도 `pathType` 으로 처리하거나, `Prefix` 또는 `Exact`
경로 유형과 같이 동일하게 처리할 수 있다.
* _`Exact`_: URL 경로의 대소문자를 엄격하게 일치시킨다.

View File

@ -533,6 +533,25 @@ NodePort를 사용하면 자유롭게 자체 로드 밸런싱 솔루션을 설
이 서비스는 `<NodeIP>:spec.ports[*].nodePort`
`.spec.clusterIP:spec.ports[*].port`로 표기된다. (kube-proxy에서 `--nodeport-addresses` 플래그가 설정되면, <NodeIP>는 NodeIP를 필터링한다.)
예를 들면
```yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: NodePort
selector:
app: MyApp
ports:
# 기본적으로 그리고 편의상 `targetPort``port` 필드와 동일한 값으로 설정된다.
- port: 80
targetPort: 80
# 선택적 필드
# 기본적으로 그리고 편의상 쿠버네티스 컨트롤 플레인은 포트 범위에서 할당한다(기본값: 30000-32767)
nodePort: 30007
```
### 로드밸런서 유형 {#loadbalancer}
외부 로드 밸런서를 지원하는 클라우드 공급자 상에서, `type`

View File

@ -22,9 +22,9 @@ weight: 20
스토리지 관리는 컴퓨트 인스턴스 관리와는 별개의 문제다. 퍼시스턴트볼륨 서브시스템은 사용자 및 관리자에게 스토리지 사용 방법에서부터 스토리지가 제공되는 방법에 대한 세부 사항을 추상화하는 API를 제공한다. 이를 위해 퍼시스턴트볼륨 및 퍼시스턴트볼륨클레임이라는 두 가지 새로운 API 리소스를 소개한다.
퍼시스턴트볼륨(PV)은 관리자가 프로비저닝하거나 [스토리지 클래스](/docs/concepts/storage/storage-classes/)를 사용하여 동적으로 프로비저닝한 클러스터의 스토리지이다. 노드가 클러스터 리소스인 것처럼 PV는 클러스터 리소스이다. PV는 Volumes와 같은 볼륨 플러그인이지만, PV를 사용하는 개별 파드와는 별개의 라이프사이클을 가진다. 이 API 오브젝트는 NFS, iSCSI 또는 클라우드 공급자별 스토리지 시스템 등 스토리지 구현에 대한 세부 정보를 담아낸다.
_퍼시스턴트볼륨_ (PV)은 관리자가 프로비저닝하거나 [스토리지 클래스](/docs/concepts/storage/storage-classes/)를 사용하여 동적으로 프로비저닝한 클러스터의 스토리지이다. 노드가 클러스터 리소스인 것처럼 PV는 클러스터 리소스이다. PV는 Volumes와 같은 볼륨 플러그인이지만, PV를 사용하는 개별 파드와는 별개의 라이프사이클을 가진다. 이 API 오브젝트는 NFS, iSCSI 또는 클라우드 공급자별 스토리지 시스템 등 스토리지 구현에 대한 세부 정보를 담아낸다.
퍼시스턴트볼륨클레임(PVC)은 사용자의 스토리지에 대한 요청이다. 파드와 비슷하다. 파드는 노드 리소스를 사용하고 PVC는 PV 리소스를 사용한다. 파드는 특정 수준의 리소스(CPU 및 메모리)를 요청할 수 있다. 클레임은 특정 크기 및 접근 모드를 요청할 수 있다(예: 한 번 읽기/쓰기 또는 여러 번 읽기 전용으로 마운트 할 수 있음).
_퍼시스턴트볼륨클레임_ (PVC)은 사용자의 스토리지에 대한 요청이다. 파드와 비슷하다. 파드는 노드 리소스를 사용하고 PVC는 PV 리소스를 사용한다. 파드는 특정 수준의 리소스(CPU 및 메모리)를 요청할 수 있다. 클레임은 특정 크기 및 접근 모드를 요청할 수 있다(예: 한 번 읽기/쓰기 또는 여러 번 읽기 전용으로 마운트 할 수 있음).
퍼시스턴트볼륨클레임을 사용하면 사용자가 추상화된 스토리지 리소스를 사용할 수 있지만, 다른 문제들 때문에 성능과 같은 다양한 속성을 가진 퍼시스턴트볼륨이 필요한 경우가 일반적이다. 클러스터 관리자는 사용자에게 해당 볼륨의 구현 방법에 대한 세부 정보를 제공하지 않고 단순히 크기와 접근 모드와는 다른 방식으로 다양한 퍼시스턴트볼륨을 제공할 수 있어야 한다. 이러한 요구에는 _스토리지클래스_ 리소스가 있다.
@ -695,7 +695,7 @@ spec:
## 볼륨 복제
[볼륨 복제](/docs/concepts/storage/volume-pvc-datasource/)는 CSI 볼륨 플러그인만 사용할 수 있다.
[볼륨 복제](/ko/docs/concepts/storage/volume-pvc-datasource/)는 CSI 볼륨 플러그인만 사용할 수 있다.
### 기존 pvc에서 퍼시스턴트볼륨클레임 생성 {#create-persistent-volume-claim-from-an-existing-pvc}

View File

@ -0,0 +1,818 @@
---
title: 스토리지 클래스
content_template: templates/concept
weight: 30
---
{{% capture overview %}}
이 문서는 쿠버네티스의 스토리지클래스의 개념을 설명한다.
[볼륨](/ko/docs/concepts/storage/volumes/)과
[퍼시스턴트 볼륨](/ko/docs/concepts/storage/persistent-volumes)에 익숙해지는 것을 권장한다.
{{% /capture %}}
{{% capture body %}}
## 소개
스토리지클래스는 관리자가 제공하는 스토리지의 "classes"를 설명할 수 있는
방법을 제공한다. 다른 클래스는 서비스의 품질 수준 또는
백업 정책, 클러스터 관리자가 정한 임의의 정책에
매핑될 수 있다. 쿠버네티스 자체는 클래스가 무엇을 나타내는지에
대해 상관하지 않는다. 다른 스토리지 시스템에서는 이 개념을
"프로파일"이라고도 한다.
## 스토리지클래스 리소스
각 스토리지클래스에는 해당 스토리지클래스에 속하는 퍼시스턴트볼륨을 동적으로 프로비저닝
할 때 사용되는 `provisioner`, `parameters`
`reclaimPolicy` 필드가 포함된다.
스토리지클래스 오브젝트의 이름은 중요하며, 사용자가 특정
클래스를 요청할 수 있는 방법이다. 관리자는 스토리지클래스 오브젝트를
처음 생성할 때 클래스의 이름과 기타 파라미터를 설정하며,
일단 생성된 오브젝트는 업데이트할 수 없다.
관리자는 특정 클래스에 바인딩을 요청하지 않는 PVC에 대해서만 기본
스토리지클래스를 지정할 수 있다. 자세한 내용은
[퍼시스턴트볼륨클레임 섹션](/ko/docs/concepts/storage/persistent-volumes/#클래스-1)을
본다.
```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
reclaimPolicy: Retain
allowVolumeExpansion: true
mountOptions:
- debug
volumeBindingMode: Immediate
```
### 프로비저너
각 스토리지클래스에는 PV 프로비저닝에 사용되는 볼륨 플러그인을 결정하는
프로비저너가 있다. 이 필드는 반드시 지정해야 한다.
| 볼륨 플러그인 | 내부 프로비저너 | 설정 예시 |
| :--- | :---: | :---: |
| AWSElasticBlockStore | &#x2713; | [AWS EBS](#aws-ebs) |
| AzureFile | &#x2713; | [Azure 파일](#azure-파일) |
| AzureDisk | &#x2713; | [Azure 디스크](#azure-디스크) |
| CephFS | - | - |
| Cinder | &#x2713; | [OpenStack Cinder](#openstack-cinder)|
| FC | - | - |
| FlexVolume | - | - |
| Flocker | &#x2713; | - |
| GCEPersistentDisk | &#x2713; | [GCE PD](#gce-pd) |
| Glusterfs | &#x2713; | [Glusterfs](#glusterfs) |
| iSCSI | - | - |
| Quobyte | &#x2713; | [Quobyte](#quobyte) |
| NFS | - | - |
| RBD | &#x2713; | [Ceph RBD](#ceph-rbd) |
| VsphereVolume | &#x2713; | [vSphere](#vsphere) |
| PortworxVolume | &#x2713; | [Portworx 볼륨](#portworx-볼륨) |
| ScaleIO | &#x2713; | [ScaleIO](#scaleio) |
| StorageOS | &#x2713; | [StorageOS](#storageos) |
| Local | - | [Local](#local) |
여기 목록에서 "내부" 프로비저너를 지정할 수 있다(이
이름은 "kubernetes.io" 가 접두사로 시작하고, 쿠버네티스와
함께 제공된다). 또한, 쿠버네티스에서 정의한
[사양](https://git.k8s.io/community/contributors/design-proposals/storage/volume-provisioning.md)을
따르는 독립적인 프로그램인 외부 프로비저너를 실행하고 지정할 수 있다.
외부 프로비저너의 작성자는 코드의 수명, 프로비저너의
배송 방법, 실행 방법, (Flex를 포함한)볼륨 플러그인
등에 대한 완전한 재량권을 가진다. [kubernetes-sigs/sig-storage-lib-external-provisioner](https://github.com/kubernetes-sigs/sig-storage-lib-external-provisioner)
리포지터리에는 대량의 사양을 구현하는 외부 프로비저너를 작성하기
위한 라이브러리가 있다. 일부 외부 프로비저너의 목록은
[kubernetes-incubator/external-storage](https://github.com/kubernetes-incubator/external-storage) 리포지터리에 있다.
예를 들어, NFS는 내부 프로비저너를 제공하지 않지만, 외부
프로비저너를 사용할 수 있다. 타사 스토리지 업체가 자체 외부
프로비저너를 제공하는 경우도 있다.
### 리클레임 정책
스토리지클래스에 의해 동적으로 생성된 퍼시스턴트볼륨은 클래스의
`reclaimPolicy` 필드에 지정된 리클레임 정책을 가지는데,
이는 `Delete` 또는 `Retain` 이 될 수 있다. 스토리지클래스 오브젝트가
생성될 때 `reclaimPolicy` 가 지정되지 않으면 기본값은 `Delete` 이다.
수동으로 생성되고 스토리지클래스를 통해 관리되는 퍼시스턴트볼륨에는
생성 시 할당된 리클레임 정책이 있다.
### 볼륨 확장 허용
{{< feature-state for_k8s_version="v1.11" state="beta" >}}
퍼시스턴트볼륨은 확장이 가능하도록 구성할 수 있다. 이 기능을 `true` 로 설정하면
해당 PVC 오브젝트를 편집하여 볼륨 크기를 조정할 수 있다.
다음 볼륨 유형은 기본 스토리지클래스에서 `allowVolumeExpansion` 필드가
true로 설정된 경우 볼륨 확장을 지원한다.
{{< table caption = "Table of Volume types and the version of Kubernetes they require" >}}
볼륨 유형 | 요구되는 쿠버네티스 버전
:---------- | :--------------------------
gcePersistentDisk | 1.11
awsElasticBlockStore | 1.11
Cinder | 1.11
glusterfs | 1.11
rbd | 1.11
Azure File | 1.11
Azure Disk | 1.11
Portworx | 1.11
FlexVolume | 1.13
CSI | 1.14 (alpha), 1.16 (beta)
{{< /table >}}
{{< note >}}
볼륨 확장 기능을 사용해서 볼륨을 확장할 수 있지만, 볼륨을 축소할 수는 없다.
{{< /note >}}
### 마운트 옵션
스토리지클래스에 의해 동적으로 생성된 퍼시스턴트볼륨은
클래스의 `mountOptions` 필드에 지정된 마운트 옵션을 가진다.
만약 볼륨 플러그인이 마운트 옵션을 지원하지 않는데, 마운트
옵션을 지정하면 프로비저닝은 실패한다. 마운트 옵션은 클래스 또는 PV 에서
검증되지 않으므로 PV 마운트가 유효하지 않으면 마운트가 실패하게 된다.
### 볼륨 바인딩 모드
`volumeBindingMode` 필드는 [볼륨 바인딩과 동적
프로비저닝](/ko/docs/concepts/storage/persistent-volumes/#프로비저닝)의 시작 시기를 제어한다.
기본적으로, `Immediate` 모드는 퍼시스턴트볼륨클레임이 생성되면 볼륨
바인딩과 동적 프로비저닝이 즉시 발생하는 것을 나타낸다. 토폴로지 제약이
있고 클러스터의 모든 노드에서 전역적으로 접근할 수 없는 스토리지
백엔드의 경우, 파드의 스케줄링 요구 사항에 대한 지식 없이 퍼시스턴트볼륨이
바인딩되거나 프로비저닝된다. 이로 인해 스케줄되지 않은 파드가 발생할 수 있다.
클러스터 관리자는 `WaitForFirstConsumer` 모드를 지정해서 이 문제를 해결할 수 있는데
이 모드는 퍼시스턴트볼륨클레임을 사용하는 파드가 생성될 때까지 퍼시스턴트볼륨의 바인딩과 프로비저닝을 지연시킨다.
퍼시스턴트볼륨은 파드의 스케줄링 제약 조건에 의해 지정된 토폴로지에
따라 선택되거나 프로비전된다. 여기에는 [리소스
요구 사항](/docs/concepts/configuration/manage-compute-resources-container/),
[노드 셀렉터](/ko/docs/concepts/configuration/assign-pod-node/#노드-셀렉터-nodeselector),
[파드 어피니티(affinity)와
안티-어피니티(anti-affinity)](/ko/docs/concepts/configuration/assign-pod-node/#어피니티-affinity-와-안티-어피니티-anti-affinity)
그리고 [테인트(taint)와 톨러레이션(toleration)](/docs/concepts/configuration/taint-and-toleration/)이 포함된다.
다음 플러그인은 동적 프로비저닝과 `WaitForFirstConsumer` 를 지원한다.
* [AWSElasticBlockStore](#aws-ebs)
* [GCEPersistentDisk](#gce-pd)
* [Azure디스크](#azure-디스크)
다음 플러그인은 사전에 생성된 퍼시스턴트볼륨 바인딩으로 `WaitForFirstConsumer` 를 지원한다.
* 위에서 언급한 모든 플러그인
* [Local](#local)
{{< feature-state state="stable" for_k8s_version="v1.17" >}}
[CSI 볼륨](/ko/docs/concepts/storage/volumes/#csi)은 동적 프로비저닝과
사전에 생성된 PV에서도 지원되지만, 지원되는 토폴로지 키와 예시를 보려면 해당
CSI 드라이버에 대한 문서를 본다.
### 허용된 토폴로지
클러스터 운영자가 `WaitForFirstConsumer` 볼륨 바인딩 모드를 지정하면, 대부분의 상황에서
더 이상 특정 토폴로지로 프로비저닝을 제한할 필요가 없다. 그러나
여전히 필요한 경우에는 `allowedTopologies` 를 지정할 수 있다.
이 예시는 프로비전된 볼륨의 토폴로지를 특정 영역으로 제한하는 방법을
보여 주며 지원되는 플러그인의 `zone``zones` 파라미터를 대체하는
데 사용해야 한다.
```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard
provisioner: kubernetes.io/gce-pd
parameters:
type: pd-standard
volumeBindingMode: WaitForFirstConsumer
allowedTopologies:
- matchLabelExpressions:
- key: failure-domain.beta.kubernetes.io/zone
values:
- us-central1-a
- us-central1-b
```
## 파라미터
스토리지 클래스에는 스토리지 클래스에 속하는 볼륨을 설명하는 파라미터가
있다. `provisioner` 에 따라 다른 파라미터를 사용할 수 있다. 예를 들어,
파라미터 `type` 에 대한 값 `io1` 과 파라미터 `iopsPerGB`
EBS에만 사용할 수 있다. 파라미터 생략 시 일부 기본값이
사용된다.
스토리지클래스에 대해 최대 512개의 파라미터를 정의할 수 있다.
키와 값을 포함하여 파라미터 오브젝터의 총 길이는 256 KiB를
초과할 수 없다.
### AWS EBS
```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: slow
provisioner: kubernetes.io/aws-ebs
parameters:
type: io1
iopsPerGB: "10"
fsType: ext4
```
* `type`: `io1`, `gp2`, `sc1`, `st1`. 자세한 내용은
[AWS 문서](https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/ebs-volume-types.html)를
본다. 기본값: `gp2`.
* `zone` (사용 중단(deprecated)): AWS 영역. `zone``zones` 를 지정하지 않으면, 일반적으로
쿠버네티스 클러스터의 노드가 있는 모든 활성화된 영역에 걸쳐 볼륨이
라운드 로빈으로 조정된다. `zone``zones` 파라미터를 동시에 사용해서는 안된다.
* `zones` (사용 중단): 쉼표로 구분된 AWS 영역의 목록. `zone``zones`
지정하지 않으면, 일반적으로 쿠버네티스 클러스터의 노드가 있는 모든 활성화된 영역에 걸쳐
볼륨이 라운드 로빈으로 조정된다. `zone``zones` 파라미터를
동시에 사용해서는 안된다.
* `iopsPerGB`: `io1` 볼륨 전용이다. 1초당 GiB에 대한 I/O 작업 수이다. AWS
볼륨 플러그인은 요청된 볼륨 크기에 곱셈하여 볼륨의 IOPS를
계산하고 이를 20,000 IOPS로 제한한다(AWS에서 지원하는 최대값으로,
[AWS 문서](https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/ebs-volume-types.html)를 본다).
여기에는 문자열, 즉 `10` 이 아닌, `"10"` 이 필요하다.
* `fsType`: fsType은 쿠버네티스에서 지원된다. 기본값: `"ext4"`.
* `encrypted`: EBS 볼륨의 암호화 여부를 나타낸다.
유효한 값은 `"ture"` 또는 `"false"` 이다. 여기에는 문자열,
`true` 가 아닌, `"true"` 가 필요하다.
* `kmsKeyId`: 선택 사항. 볼륨을 암호화할 때 사용할 키의 전체 Amazon
리소스 이름이다. 아무것도 제공되지 않지만, `encrypted` 가 true라면
AWS에 의해 키가 생성된다. 유효한 ARN 값은 AWS 문서를 본다.
{{< note >}}
`zone``zones` 파라미터는 사용 중단 되었으며,
[allowedTopologies](#allowed-topologies)로 대체되었다.
{{< /note >}}
### GCE PD
```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: slow
provisioner: kubernetes.io/gce-pd
parameters:
type: pd-standard
fstype: ext4
replication-type: none
```
* `type`: `pd-standard` 또는 `pd-ssd`. 기본값: `pd-standard`
* `zone` (사용 중단): GCE 영역. `zone``zones` 를 모두 지정하지 않으면, 쿠버네티스 클러스터의
노드가 있는 모든 활성화된 영역에 걸쳐 볼륨이 라운드 로빈으로
조정된다. `zone``zones` 파라미터를 동시에 사용해서는 안된다.
* `zones` (사용 중단): 쉼표로 구분되는 GCE 영역의 목록. `zone``zones` 를 모두
지정하지 않으면, 쿠버네티스 클러스터의 노드가 있는 모든 활성화된 영역에
걸쳐 볼륨이 라운드 로빈으로 조정된다. `zone``zones` 파라미터를
동시에 사용해서는 안된다.
* `fstype`: `ext4` 또는 `xfs`. 기본값: `ext4`. 정의된 파일시스템 유형은 호스트 운영체제에서 지원되어야 한다.
* `replication-type`: `none` 또는 `regional-pd`. 기본값: `none`.
`replication-type``none` 으로 설정하면 (영역) PD가 프로비전된다.
`replication-type``regional-pd` 로 설정되면,
[지역 퍼시스턴트 디스크](https://cloud.google.com/compute/docs/disks/#repds)
가 프로비전된다. 이 경우, 사용자는 `zone` 대신 `zones` 를 사용해서 원하는
복제 영역을 지정해야 한다. 정확히 두 개의 영역이 지정된 경우, 해당
영역에서 지역 PD가 프로비전된다. 둘 이상의 영역이 지정되면
쿠버네티스는 지정된 영역 중에서 임의로 선택한다. `zones` 파라미터가 생략되면,
쿠버네티스는 클러스터가 관리하는 영역 중에서
임의로 선택한다.
{{< note >}}
`zone``zones` 파라미터는 사용 중단 되었으며,
[allowedTopologies](#allowed-topologies)로 대체되었다.
{{< /note >}}
### Glusterfs
```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: slow
provisioner: kubernetes.io/glusterfs
parameters:
resturl: "http://127.0.0.1:8081"
clusterid: "630372ccdc720a92c681fb928f27b53f"
restauthenabled: "true"
restuser: "admin"
secretNamespace: "default"
secretName: "heketi-secret"
gidMin: "40000"
gidMax: "50000"
volumetype: "replicate:3"
```
* `resturl`: 필요에 따라 gluster 볼륨을 프로비전하는 Gluster REST 서비스/Heketi
서비스 url 이다. 일반적인 형식은 `IPaddress:Port` 이어야 하며 이는 GlusterFS
동적 프로비저너의 필수 파라미터이다. Heketi 서비스가 openshift/kubernetes
설정에서 라우팅이 가능한 서비스로 노출이 되는 경우 이것은 fqdn이 해석할 수 있는
Heketi 서비스 url인 `http://heketi-storage-project.cloudapps.mystorage.com`
유사한 형식을 가질 수 있다.
* `restauthenabled` : REST 서버에 대한 인증을 가능하게 하는 Gluster REST 서비스
인증 부울이다. 이 값이 `"true"` 이면, `restuser``restuserkey`
또는 `secretNamespace` + `secretName` 을 채워야 한다. 이 옵션은
사용 중단이며, `restuser`, `restuserkey`, `secretName` 또는
`secretNamespace` 중 하나를 지정하면 인증이 활성화된다.
* `restuser` : Gluster REST 서비스/Heketi 사용자로 Gluster Trusted Pool에서
볼륨을 생성할 수 있다.
* `restuserkey` : REST 서버에 대한 인증에 사용될 Gluster REST 서비스/Heketi
사용자의 암호이다. 이 파라미터는 `secretNamespace` + `secretName` 을 위해
사용 중단 되었다.
* `secretNamespace`, `secretName` : Gluster REST 서비스와 통신할 때 사용할
사용자 암호가 포함된 시크릿 인스턴스를 식별한다. 이 파라미터는
선택 사항으로 `secretNamespace``secretName` 을 모두 생략하면
빈 암호가 사용된다. 제공된 시크릿은 `"kubernetes.io/glusterfs"` 유형이어야
하며, 예를 들어 다음과 같이 생성한다.
```
kubectl create secret generic heketi-secret \
--type="kubernetes.io/glusterfs" --from-literal=key='opensesame' \
--namespace=default
```
시크릿의 예시는
[glusterfs-provisioning-secret.yaml](https://github.com/kubernetes/examples/tree/master/staging/persistent-volume-provisioning/glusterfs/glusterfs-secret.yaml)에서 찾을 수 있다.
* `clusterid`: `630372ccdc720a92c681fb928f27b53f` 는 볼륨을 프로비저닝할
때 Heketi가 사용할 클러스터의 ID이다. 또한, 예시와 같이 클러스터
ID 목록이 될 수 있다. 예:
`"8452344e2becec931ece4e33c4674e4e,42982310de6c63381718ccfa6d8cf397"`. 이것은
선택적 파라미터이다.
* `gidMin`, `gidMax` : 스토리지클래스에 대한 GID 범위의 최소값과
최대값이다. 이 범위( gidMin-gidMax )의 고유한 값(GID)은 동적으로
프로비전된 볼륨에 사용된다. 이것은 선택적인 값이다. 지정하지 않으면,
볼륨은 각각 gidMin과 gidMax의 기본값인 2000-2147483647
사이의 값으로 프로비전된다.
* `volumetype` : 볼륨 유형과 파라미터는 이 선택적 값으로 구성할
수 있다. 볼륨 유형을 언급하지 않는 경우, 볼륨 유형을 결정하는 것은
프로비저너의 책임이다.
예를 들어:
* 레플리카 볼륨: `volumetype: replicate:3` 여기서 '3'은 레플리카의 수이다.
* Disperse/EC 볼륨: `volumetype: disperse:4:2` 여기서 '4'는 데이터이고 '2'는 중복 횟수이다.
* Distribute 볼륨: `volumetype: none`
사용 가능한 볼륨 유형과 관리 옵션에 대해서는
[관리 가이드](https://access.redhat.com/documentation/en-US/Red_Hat_Storage/3.1/html/Administration_Guide/part-Overview.html)를 참조한다.
자세한 정보는
[Heketi 구성 방법](https://github.com/heketi/heketi/wiki/Setting-up-the-topology)을 참조한다.
퍼시스턴트 볼륨이 동적으로 프로비전되면 Gluster 플러그인은
`gluster-dynamic-<claimname>` 이라는 이름으로 엔드포인트와
헤드리스 서비스를 자동으로 생성한다. 퍼시스턴트 볼륨 클레임을
삭제하면 동적 엔드포인트와 서비스가 자동으로 삭제된다.
### OpenStack Cinder
```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gold
provisioner: kubernetes.io/cinder
parameters:
availability: nova
```
* `availability`: 가용성 영역. 지정하지 않으면, 일반적으로 쿠버네티스 클러스터의
노드가 있는 모든 활성화된 영역에 걸쳐 볼륨이 라운드 로빈으로 조정된다.
{{< note >}}
{{< feature-state state="deprecated" for_k8s_version="v1.11" >}}
이 OpenStack 내부 프로비저너는 사용 중단 되었다. [OpenStack용 외부 클라우드 공급자](https://github.com/kubernetes/cloud-provider-openstack)를 사용한다.
{{< /note >}}
### vSphere
1. 사용자 지정 디스크 형식으로 스토리지클래스를 생성한다.
```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast
provisioner: kubernetes.io/vsphere-volume
parameters:
diskformat: zeroedthick
```
`diskformat`: `thin`, `zeroedthick``eagerzeroedthick`. 기본값: `"thin"`.
2. 사용자 지정 데이터스토어에 디스크 형식으로 스토리지클래스를 생성한다.
```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast
provisioner: kubernetes.io/vsphere-volume
parameters:
diskformat: zeroedthick
datastore: VSANDatastore
```
`datastore`: 또한, 사용자는 스토리지클래스에서 데이터스토어를 지정할 수 있다.
볼륨은 스토리지클래스에 지정된 데이터스토어에 생성되며,
이 경우 `VSANDatastore` 이다. 이 필드는 선택 사항이다. 데이터스토어를
지정하지 않으면, vSphere 클라우드 공급자를 초기화하는데 사용되는 vSphere
설정 파일에 지정된 데이터스토어에 볼륨이
생성된다.
3. 쿠버네티스 내부 스토리지 정책을 관리한다.
* 기존 vCenter SPBM 정책을 사용한다.
vSphere 스토리지 관리의 가장 중요한 기능 중 하나는
정책 기반 관리이다. 스토리지 정책 기반 관리(Storage Policy Based Management (SPBM))는
광범위한 데이터 서비스와 스토리지 솔루션에서 단일 통합 컨트롤 플레인을
제공하는 스토리지 정책 프레임워크이다. SPBM을 통해 vSphere 관리자는 용량 계획,
차별화된 서비스 수준과 용량의 헤드룸(headroom) 관리와 같은
선행 스토리지 프로비저닝 문제를
극복할 수 있다.
SPBM 정책은 `storagePolicyName` 파라미터를 사용하면
스토리지클래스에서 지정할 수 있다.
* 쿠버네티스 내부의 가상 SAN 정책 지원
Vsphere 인프라스트럭쳐(Vsphere Infrastructure (VI)) 관리자는
동적 볼륨 프로비저닝 중에 사용자 정의 가상 SAN 스토리지
기능을 지정할 수 있다. 이제 동적 볼륨 프로비저닝 중에 스토리지
기능의 형태로 성능 및 가용성과 같은 스토리지 요구 사항을 정의할
수 있다. 스토리지 기능 요구 사항은 가상 SAN 정책으로 변환된
퍼시스턴트 볼륨(가상 디스크)을 생성할 때
가상 SAN 계층으로 푸시된다. 가상 디스크는 가상 SAN 데이터
스토어에 분산되어 요구 사항을 충족시키게 된다.
퍼시스턴트 볼륨 관리에 스토리지 정책을 사용하는 방법에 대한 자세한 내용은
[볼륨의 동적 프로비저닝을 위한 스토리지 정책 기반 관리(SPBM)](https://vmware.github.io/vsphere-storage-for-kubernetes/documentation/policy-based-mgmt.html)를
참조한다.
vSphere용 쿠버네티스 내에서 퍼시스턴트 볼륨 관리를 시도하는
[vSphere 예시](https://github.com/kubernetes/examples/tree/master/staging/volumes/vsphere)는
거의 없다.
### Ceph RBD
```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast
provisioner: kubernetes.io/rbd
parameters:
monitors: 10.16.153.105:6789
adminId: kube
adminSecretName: ceph-secret
adminSecretNamespace: kube-system
pool: kube
userId: kube
userSecretName: ceph-secret-user
userSecretNamespace: default
fsType: ext4
imageFormat: "2"
imageFeatures: "layering"
```
* `monitors`: 쉼표로 구분된 Ceph 모니터. 이 파라미터는 필수이다.
* `adminId`: 풀에 이미지를 생성할 수 있는 Ceph 클라이언트 ID.
기본값은 "admin".
* `adminSecretName`: `adminId` 의 시크릿 이름. 이 파라미터는 필수이다.
제공된 시크릿은 "kubernetes.io/rbd" 유형이어야 한다.
* `adminSecretNamespace`: `adminSecretName` 의 네임스페이스. 기본값은 "default".
* `pool`: Ceph RBD 풀. 기본값은 "rbd".
* `userId`: RBD 이미지를 매핑하는 데 사용하는 Ceph 클라이언트 ID. 기본값은
`adminId` 와 동일하다.
* `userSecretName`: RDB 이미지를 매핑하기 위한 `userId` 에 대한 Ceph 시크릿 이름. PVC와
동일한 네임스페이스에 존재해야 한다. 이 파라미터는 필수이다.
제공된 시크릿은 "kubernetes.io/rbd" 유형이어야 하며, 다음의 예시와 같이
생성되어야 한다.
```shell
kubectl create secret generic ceph-secret --type="kubernetes.io/rbd" \
--from-literal=key='QVFEQ1pMdFhPUnQrSmhBQUFYaERWNHJsZ3BsMmNjcDR6RFZST0E9PQ==' \
--namespace=kube-system
```
* `userSecretNamespace`: `userSecretName` 의 네임스페이스.
* `fsType`: 쿠버네티스가 지원하는 fsType. 기본값: `"ext4"`.
* `imageFormat`: Ceph RBD 이미지 형식, "1" 또는 "2". 기본값은 "2".
* `imageFeatures`: 이 파라미터는 선택 사항이며, `imageFormat` 을 "2"로 설정한
경우에만 사용해야 한다. 현재 `layering` 에서만 기능이 지원된다.
기본값은 ""이며, 기능이 설정되어 있지 않다.
### Quobyte
```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: slow
provisioner: kubernetes.io/quobyte
parameters:
quobyteAPIServer: "http://138.68.74.142:7860"
registry: "138.68.74.142:7861"
adminSecretName: "quobyte-admin-secret"
adminSecretNamespace: "kube-system"
user: "root"
group: "root"
quobyteConfig: "BASE"
quobyteTenant: "DEFAULT"
```
* `quobyteAPIServer`: `"http(s)://api-server:7860"` 형식의
Quobyte의 API 서버이다.
* `registry`: 볼륨을 마운트하는 데 사용할 Quobyte 레지스트리이다. 레지스트리를
``<host>:<port>`` 의 쌍으로 지정하거나 여러 레지스트리를
지정하려면 쉼표만 있으면 된다.
예: ``<host1>:<port>,<host2>:<port>,<host3>:<port>``
호스트는 IP 주소이거나 DNS가 작동 중인 경우
DNS 이름을 제공할 수도 있다.
* `adminSecretNamespace`: `adminSecretName` 의 네임스페이스.
기본값은 "default".
* `adminSecretName`: 시크릿은 API 서버에 대해 인증하기 위한 Quobyte 사용자와 암호에
대한 정보를 담고 있다. 제공된 시크릿은 "kubernetes.io/quobyte"
유형과 `user``password` 키를 가져야 하며, 예를 들면
다음과 같다.
```shell
kubectl create secret generic quobyte-admin-secret \
--type="kubernetes.io/quobyte" --from-literal=user='admin' --from-literal=password='opensesame' \
--namespace=kube-system
```
* `user`: 이 사용자에 대한 모든 접근을 매핑한다. 기본값은 "root".
* `group`: 이 그룹에 대한 모든 접근을 매핑한다. 기본값은 "nfsnobody".
* `quobyteConfig`: 지정된 구성을 사용해서 볼륨을 생성한다. 웹 콘솔
또는 quobyte CLI를 사용해서 새 구성을 작성하거나 기존 구성을
수정할 수 있다. 기본값은 "BASE".
* `quobyteTenant`: 지정된 테넌트 ID를 사용해서 볼륨을 생성/삭제한다.
이 Quobyte 테넌트는 이미 Quobyte에 있어야 한다.
기본값은 "DEFAULT".
### Azure 디스크크
#### Azure 비관리 디스크 스토리지 클래스 {#azure-unmanaged-disk-storage-class}
```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: slow
provisioner: kubernetes.io/azure-disk
parameters:
skuName: Standard_LRS
location: eastus
storageAccount: azure_storage_account_name
```
* `skuName`: Azure 스토리지 계정 Sku 계층. 기본값은 없음.
* `location`: Azure 스토리지 계정 지역. 기본값은 없음.
* `storageAccount`: Azure 스토리지 계정 이름. 스토리지 계정이 제공되면, 클러스터와 동일한
리소스 그룹에 있어야 하며, `location` 은 무시된다. 스토리지 계정이
제공되지 않으면, 클러스터와 동일한 리소스
그룹에 새 스토리지 계정이 생성된다.
#### Azure 디스크 스토리지 클래스(v1.7.2부터 제공) {#azure-disk-storage-class}
```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: slow
provisioner: kubernetes.io/azure-disk
parameters:
storageaccounttype: Standard_LRS
kind: Shared
```
* `storageaccounttype`: Azure 스토리지 계정 Sku 계층. 기본값은 없음.
* `kind`: 가능한 값은 `shared` (기본값), `dedicated`, 그리고 `managed` 이다.
`kind``shared` 인 경우, 모든 비관리 디스크는 클러스터와
동일한 리소스 그룹에 있는 몇 개의 공유 스토리지 계정에 생성된다. `kind`
`dedicated` 인 경우, 클러스터와 동일한 리소스 그룹에서 새로운
비관리 디스크에 대해 새로운 전용 스토리지 계정이 생성된다. `kind`
`managed` 인 경우, 모든 관리 디스크는 클러스터와 동일한 리소스
그룹에 생성된다.
* `resourceGroup`: Azure 디스크를 만들 리소스 그룹을 지정한다.
기존에 있는 리소스 그룹 이름이어야 한다. 지정되지 않는 경우, 디스크는
현재 쿠버네티스 클러스터와 동일한 리소스 그룹에 배치된다.
- 프리미엄 VM은 표준 LRS(Standard_LRS)와 프리미엄 LRS(Premium_LRS) 디스크를 모두 연결할 수 있는 반면에,
표준 VM은 표준 LRS(Standard_LRS) 디스크만 연결할 수 있다.
- 관리되는 VM은 관리되는 디스크만 연결할 수 있고,
비관리 VM은 비관리 디스크만 연결할 수 있다.
### Azure 파일
```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: azurefile
provisioner: kubernetes.io/azure-file
parameters:
skuName: Standard_LRS
location: eastus
storageAccount: azure_storage_account_name
```
* `skuName`: Azure 스토리지 계정 Sku 계층. 기본값은 없음.
* `location`: Azure 스토리지 계정 지역. 기본값은 없음.
* `storageAccount`: Azure 스토리지 계정 이름. 기본값은 없음. 스토리지 계정이
제공되지 않으면, 리소스 그룹과 관련된 모든 스토리지 계정이
검색되어 `skuName``location` 이 일치하는 것을 찾는다. 스토리지 계정이
제공되면, 클러스터와 동일한 리소스 그룹에 있어야
하며 `skuName``location` 은 무시된다.
* `secretNamespace`: Azure 스토리지 계정 이름과 키가 포함된 시크릿
네임스페이스. 기본값은 파드와 동일하다.
* `secretName`: Azure 스토리지 계정 이름과 키가 포함된 시크릿 이름.
기본값은 `azure-storage-account-<accountName>-secret`
* `readOnly`: 스토리지가 읽기 전용으로 마운트되어야 하는지 여부를 나타내는 플래그.
읽기/쓰기 마운트를 의미하는 기본값은 false. 이 설정은
볼륨마운트(VolumeMounts)의 `ReadOnly` 설정에도 영향을 준다.
스토리지 프로비저닝 중에 마운트 자격증명에 대해 `secretName`
이라는 시크릿이 생성된다. 클러스터에
[RBAC](/docs/reference/access-authn-authz/rbac/)과
[컨트롤러의 롤(role)들](/docs/reference/access-authn-authz/rbac/#controller-roles)을
모두 활성화한 경우, clusterrole `system:controller:persistent-volume-binder`
에 대한 `secret` 리소스에 `create` 권한을 추가한다.
다중 테넌시 컨텍스트에서 `secretNamespace` 의 값을 명시적으로 설정하는
것을 권장하며, 그렇지 않으면 다른 사용자가 스토리지 계정 자격증명을
읽을 수 있기 때문이다.
### Portworx 볼륨
```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: portworx-io-priority-high
provisioner: kubernetes.io/portworx-volume
parameters:
repl: "1"
snap_interval: "70"
io_priority: "high"
```
* `fs`: 배치할 파일 시스템: `none/xfs/ext4` (기본값: `ext4`)
* `block_size`: Kbytes 단위의 블록 크기(기본값: `32`).
* `repl`: 레플리케이션 팩터 `1..3` (기본값: `1`)의 형태로 제공될
동기 레플리카의 수. 여기에는 문자열,
`0` 이 아닌, `"0"` 이 필요하다.
* `io_priority`: 볼륨이 고성능 또는 우선 순위가 낮은 스토리지에서
생성될 것인지를 결정한다 `high/medium/low` (기본값: `low`).
* `snap_interval`: 스냅샷을 트리거할 때의 시각/시간 간격(분).
스냅샷은 이전 스냅샷과의 차이에 따라 증분되며, 0은 스냅을
비활성화 한다(기본값: `0`). 여기에는 문자열,
`70` 이 아닌, `"70"` 이 필요하다.
* `aggregation_level`: 볼륨이 분배될 청크 수를 지정하며, 0은 집계되지 않은
볼륨을 나타낸다(기본값: `0`). 여기에는 문자열,
`0` 이 아닌, `"0"` 이 필요하다.
* `ephemeral`: 마운트 해제 후 볼륨을 정리해야 하는지 혹은 지속적이어야
하는지를 지정한다. `emptyDir` 에 대한 유스케이스는 이 값을 true로
설정할 수 있으며, `persistent volumes` 에 대한 유스케이스인
카산드라와 같은 데이터베이스는 false로 설정해야 한다. `true/false` (기본값 `false`)
여기에는 문자열, 즉 `true` 가 아닌, `"true"` 가 필요하다.
### ScaleIO
```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: slow
provisioner: kubernetes.io/scaleio
parameters:
gateway: https://192.168.99.200:443/api
system: scaleio
protectionDomain: pd0
storagePool: sp1
storageMode: ThinProvisioned
secretRef: sio-secret
readOnly: false
fsType: xfs
```
* `provisioner`: 속성이 `kubernetes.io/scaleio` 로 설정되어 있다.
* `gateway`: ScaleIO API 게이트웨이 주소(필수)
* `system`: ScaleIO 시스템의 이름(필수)
* `protectionDomain`: ScaleIO 보호 도메인의 이름(필수)
* `storagePool`: 볼륨 스토리지 풀의 이름(필수)
* `storageMode`: 스토리지 프로비전 모드: `ThinProvisioned` (기본값) 또는
`ThickProvisioned`
* `secretRef`: 구성된 시크릿 오브젝트에 대한 참조(필수)
* `readOnly`: 마운트된 볼륨에 대한 접근 모드의 지정(기본값: false)
* `fsType`: 볼륨에 사용할 파일 시스템 유형(기본값: ext4)
ScaleIO 쿠버네티스 볼륨 플러그인에는 구성된 시크릿 오브젝트가 필요하다.
시크릿은 다음 명령에 표시된 것처럼 `kubernetes.io/scaleio` 유형으로
작성해야 하며, PVC와 동일한 네임스페이스
값을 사용해야 한다.
```shell
kubectl create secret generic sio-secret --type="kubernetes.io/scaleio" \
--from-literal=username=sioadmin --from-literal=password=d2NABDNjMA== \
--namespace=default
```
### StorageOS
```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast
provisioner: kubernetes.io/storageos
parameters:
pool: default
description: Kubernetes volume
fsType: ext4
adminSecretNamespace: default
adminSecretName: storageos-secret
```
* `pool`: 볼륨을 프로비전할 StorageOS 분산 용량
풀의 이름. 지정되지 않은 경우 일반적으로 존재하는 `default` 풀을 사용한다.
* `description`: 동적으로 생성된 볼륨에 할당할 설명.
모든 볼륨 설명은 스토리지 클래스에 대해 동일하지만, 서로 다른
유스케이스에 대한 설명을 허용하기 위해 다른 스토리지 클래스를 사용할 수 있다.
기본값은 `Kubernetes volume`.
* `fsType`: 요청할 기본 파일 시스템 유형. StorageOS 내의 사용자
정의 규칙이 이 값을 무시할 수 있다. 기본 값은 `ext4`.
* `adminSecretNamespace`: API 구성 시크릿이 있는 네임스페이스.
adminSecretName 이 설정된 경우 필수이다.
* `adminSecretName`: StorageOS API 자격증명을 얻는 데 사용할 시크릿의 이름.
지정하지 않으면 기본값이 시도된다.
StorageOS 쿠버네티스 볼륨 플러그인은 시크릿 오브젝트를 사용해서 StorageOS API에
접근하기 위한 엔드포인트와 자격증명을 지정할 수 있다. 이것은 기본값이
변경된 경우에만 필요하다.
시크릿은 다음의 명령과 같이 `kubernetes.io/storageos` 유형으로
만들어야 한다.
```shell
kubectl create secret generic storageos-secret \
--type="kubernetes.io/storageos" \
--from-literal=apiAddress=tcp://localhost:5705 \
--from-literal=apiUsername=storageos \
--from-literal=apiPassword=storageos \
--namespace=default
```
동적으로 프로비전된 볼륨에 사용되는 시크릿은 모든 네임스페이스에서
생성할 수 있으며 `adminSecretNamespace` 파라미터로 참조될 수 있다.
사전에 프로비전된 볼륨에서 사용하는 시크릿은 이를 참조하는 PVC와
동일한 네임스페이스에서 작성해야 한다.
### Local
{{< feature-state for_k8s_version="v1.14" state="stable" >}}
```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
```
로컬 볼륨은 현재 동적 프로비저닝을 지원하지 않지만, 파드 스케줄링까지
볼륨 바인딩을 지연시키기 위해서는 스토리지클래스가 여전히 생성되어야 한다. 이것은
`WaitForFirstConsumer` 볼륨 바인딩 모드에 의해 지정된다.
볼륨 바인딩을 지연시키면 스케줄러가 퍼시스턴트볼륨클레임에
적절한 퍼시스턴트볼륨을 선택할 때 파드의 모든 스케줄링
제약 조건을 고려할 수 있다.
{{% /capture %}}

View File

@ -0,0 +1,149 @@
---
title: 볼륨 스냅샷
content_template: templates/concept
weight: 20
---
{{% capture overview %}}
{{< feature-state for_k8s_version="1.17" state="beta" >}}
쿠버네티스에서 스토리지 시스템 볼륨 스냅샷은 _VolumeSnapshot_ 을 나타낸다. 이 문서는 이미 쿠버네티스 [퍼시스턴트 볼륨](/docs/concepts/storage/persistent-volumes/)에 대해 잘 알고 있다고 가정한다.
{{% /capture %}}
{{% capture body %}}
## 소개
API 리소스 `PersistentVolume``PersistentVolumeClaim` 가 사용자 및 관리자가 볼륨을 프로비전할 때의 방법과 유사하게, `VolumeSnapshotContent``VolumeSnapshot` API 리소스는 볼륨 스냅샷을 생성하기 위해 제공된다.
`VolumeSnapshotContent` 는 관리자가 프로버져닝한 클러스터 볼륨에서의 스냅샷이다. 퍼시스턴트볼륨이 클러스터 리소스인 것처럼 이것 또한 클러스터 리소스이다.
`VolumeSnapshot` 은 사용자가 볼륨의 스냅샷을 요청할 수 있는 방법이다. 이는 퍼시스턴트볼륨클레임과 유사하다.
`VolumeSnapshotClass` 을 사용하면 `VolumeSnapshot` 에 속한 다른 속성을 지정할 수 있다. 이러한 속성은 스토리지 시스템에의 동일한 볼륨에서 가져온 스냅샷마다 다를 수 있으므로 `PersistentVolumeClaim``StorageClass` 를 사용하여 표현할 수는 없다.
사용자는 이 기능을 사용할 때 다음 사항을 알고 있어야 한다.
* API 객체인 `VolumeSnapshot`, `VolumeSnapshotContent`, `VolumeSnapshotClass` 는 핵심 API가 아닌, {{< glossary_tooltip term_id="CustomResourceDefinition" text="CRDs" >}}이다.
* `VolumeSnapshot` 은 CSI 드라이버에서만 사용할 수 있다.
* 쿠버네티스 팀은 `VolumeSnapshot` 베타 버젼의 배포 프로세스 일부로써, 컨트롤 플레인에 배포할 스냅샷 컨트롤러와 CSI 드라이버와 함께 배포할 csi-snapshotter라는 사이드카 헬퍼(helper) 컨테이너를 제공한다. 스냅샷 컨트롤러는 `VolumeSnapshot``VolumeSnapshotContent` 오브젝트를 관찰하고 동적 프로비저닝에서 `VolumeSnapshotContent` 오브젝트의 생성 및 삭제를 할 수 있다.사이드카 csi-snapshotter는 `VolumeSnapshotContent` 오브젝트를 관찰하고 CSI 엔드포인트에 대해 `CreateSnapshot``DeleteSnapshot` 을 트리거(trigger)한다.
* CSI 드라이버에서의 볼륨 스냅샷 기능 유무는 확실하지 않다. 볼륨 스냅샷 서포트를 제공하는 CSI 드라이버는 csi-snapshotter를 사용할 가능성이 높다. 자세한 사항은 [CSI 드라이버 문서](https://kubernetes-csi.github.io/docs/)를 확인하면 된다.
* CRDs 및 스냅샷 컨트롤러는 쿠버네티스 배포 시 설치된다.
## 볼륨 스냅샷 및 볼륨 스냅샷 컨텐츠의 라이프사이클
`VolumeSnapshotContents` 은 클러스터 리소스이다. `VolumeSnapshots` 은 이러한 리소스의 요청이다. `VolumeSnapshotContents``VolumeSnapshots`의 상호 작용은 다음과 같은 라이프사이클을 따른다.
### 프로비저닝 볼륨 스냅샷
스냅샷을 프로비저닝할 수 있는 방법에는 사전 프로비저닝 혹은 동적 프로비저닝의 두 가지가 있다: .
#### 사전 프로비전 {#static}
클러스터 관리자는 많은 `VolumeSnapshotContents` 을 생성한다. 그들은 클러스터 사용자들이 사용 가능한 스토리지 시스템의 실제 볼륨 스냅샷 세부 정보를 제공한다.
이것은 쿠버네티스 API에 있고 사용 가능하다.
#### 동적
사전 프로비저닝을 사용하는 대신 퍼시스턴트볼륨클레임에서 스냅샷을 동적으로 가져오도록 요청할 수 있다. [볼륨스냅샷클래스](/docs/concepts/storage/volume-snapshot-classes/)는 스냅샷 사용 시 스토리지 제공자의 특정 파라미터를 명세한다.
### 바인딩
스냅샷 컨트롤러는 사전 프로비저닝과 동적 프로비저닝된 시나리오에서 `VolumeSnapshot` 오브젝트와 적절한 `VolumeSnapshotContent` 오브젝트와의 바인딩을 처리한다. 바인딩은 1:1 매핑이다.
사전 프로비저닝된 경우, 볼륨스냅샷은 볼륨스냅샷컨텐츠 오브젝트 생성이 요청될 때까지 바인드되지 않은 상태로 유지된다.
### 스냅샷 소스 보호로서의 퍼시스턴트 볼륨 클레임
이 보호의 목적은 스냅샷이 생성되는 동안 사용 중인 퍼시스턴트볼륨클레임 API 오브젝트가 시스템에서 지워지지 않게 하는 것이다(데이터 손실이 발생할 수 있기 때문에).
퍼시스턴트볼륨클레임이 스냅샷을 생성할 동안에는 해당 퍼시스턴트볼륨클레임은 사용중인 상태이다. 스냅샷 소스로 사용 중인 퍼시스턴트볼륨클레임 API 객체를 삭제한다면, 퍼시스턴트볼륨클레임 객체는 즉시 삭제되지 않는다. 대신, 퍼시스턴트볼륨클레임 객체 삭제는 스냅샷이 준비(readyTouse) 혹은 중단(aborted) 상태가 될 때까지 연기된다.
### 삭제
삭제는 `VolumeSnapshot` 를 삭제 시 트리거로 `DeletionPolicy` 가 실행된다. `DeletionPolicy``Delete` 라면, 기본 스토리지 스냅샷이 `VolumeSnapshotContent` 오브젝트와 함께 삭제될 것이다. `DeletionPolicy``Retain` 이라면, 기본 스트리지 스냅샷과 `VolumeSnapshotContent` 둘 다 유지된다.
## 볼륨 스냅샷
각각의 볼륨 스냅샷은 스펙과 상태를 포함한다.
```yaml
apiVersion: snapshot.storage.k8s.io/v1beta1
kind: VolumeSnapshot
metadata:
name: new-snapshot-test
spec:
volumeSnapshotClassName: csi-hostpath-snapclass
source:
persistentVolumeClaimName: pvc-test
```
`persistentVolumeClaimName` 은 스냅샷을 위한 퍼시스턴트볼륨클레임 데이터 소스의 이름이다. 이 필드는 동적 프로비저닝 스냅샷이 필요하다.
볼륨 스냅샷은 `volumeSnapshotClassName` 속성을 사용하여
[볼륨스냅샷클래스](/docs/concepts/storage/volume-snapshot-classes/)의 이름을 지정하여
특정 클래스를 요청할 수 있다. 아무것도 설정하지 않으면, 사용 가능한 경우 기본 클래스가 사용될 것이다.
사전 프로비저닝된 스냅샷의 경우, 다음 예와 같이 `volumeSnapshotContentName`을 스냅샷 소스로 지정해야 한다. 사전 프로비저닝된 스냅샷에는 `volumeSnapshotContentName` 소스 필드가 필요하다.
```
apiVersion: snapshot.storage.k8s.io/v1beta1
kind: VolumeSnapshot
metadata:
name: test-snapshot
spec:
source:
volumeSnapshotContentName: test-content
```
## 볼륨 스냅샷 컨텐츠
각각의 볼륨스냅샷컨텐츠는 스펙과 상태를 포함한다. 동적 프로비저닝에서는, 스냅샷 공통 컨트롤러는 `VolumeSnapshotContent` 오브젝트를 생성한다. 예시는 다음과 같다.
```yaml
apiVersion: snapshot.storage.k8s.io/v1beta1
kind: VolumeSnapshotContent
metadata:
name: snapcontent-72d9a349-aacd-42d2-a240-d775650d2455
spec:
deletionPolicy: Delete
driver: hostpath.csi.k8s.io
source:
volumeHandle: ee0cfb94-f8d4-11e9-b2d8-0242ac110002
volumeSnapshotClassName: csi-hostpath-snapclass
volumeSnapshotRef:
name: new-snapshot-test
namespace: default
uid: 72d9a349-aacd-42d2-a240-d775650d2455
```
`volumeHandle` 은 스토리지 백엔드에서 생성되고 볼륨 생성 중에 CSI 드라이버가 반환하는 볼륨의 고유 식별자이다. 이 필드는 스냅샷을 동적 프로비저닝하는 데 필요하다. 이것은 스냅샷의 볼륨 소스를 지정한다.
사전 프로비저닝된 스냅샷의 경우, (클러스터 관리자로서) 다음과 같이 `VolumeSnapshotContent` 오브젝트를 작성해야 한다.
```yaml
apiVersion: snapshot.storage.k8s.io/v1beta1
kind: VolumeSnapshotContent
metadata:
name: new-snapshot-content-test
spec:
deletionPolicy: Delete
driver: hostpath.csi.k8s.io
source:
snapshotHandle: 7bdd0de3-aaeb-11e8-9aae-0242ac110002
volumeSnapshotRef:
name: new-snapshot-test
namespace: default
```
`snapshotHandle` 은 스토리지 백엔드에서 생성된 볼륨 스냅샷의 고유 식별자이다. 이 필드는 사전 프로비저닝된 스냅샷에 필요하다. `VolumeSnapshotContent` 가 나타내는 스토리지 시스템의 CSI 스냅샷 id를 지정한다.
## 스냅샷을 위한 프로비저닝 볼륨
`PersistentVolumeClaim` 오브젝트의 *dataSource* 필드를 사용하여
스냅샷 데이터로 미리 채워진 새 볼륨을 프로비저닝할 수 있다.
보다 자세한 사항은
[볼륨 스냅샷 및 스냅샷에서 볼륨 복원](/docs/concepts/storage/persistent-volumes/#volume-snapshot-and-restore-volume-from-snapshot-support)에서 확인할 수 있다.
{{% /capture %}}

View File

@ -744,11 +744,11 @@ spec:
### persistentVolumeClaim {#persistentvolumeclaim}
`persistentVolumeClaim` 볼륨은
[퍼시스턴트볼륨](/docs/concepts/storage/persistent-volumes/)을 파드에 마운트하는데 사용한다. 퍼시스턴트볼륨은
[퍼시스턴트볼륨](/ko/docs/concepts/storage/persistent-volumes)을 파드에 마운트하는데 사용한다. 퍼시스턴트볼륨은
사용자가 특정 클라우드 환경의 세부 내용을 몰라도 내구성이있는 스토리지 (GCE 퍼시스턴트디스크 또는
iSCSI 볼륨와 같은)를 "클레임" 할 수 있는 방법이다.
더 자세한 내용은 [퍼시스턴트볼륨 예시](/docs/concepts/storage/persistent-volumes/)를
더 자세한 내용은 [퍼시스턴트볼륨 예시](/ko/docs/concepts/storage/persistent-volumes)를
본다.
### projected {#projected}
@ -974,7 +974,7 @@ ScaleIO는 기존 하드웨어를 사용해서 확장 가능한 공유 블럭
생성할 수 있는 소프트웨어 기반 스포티리 플랫폼이다. `scaleIO` 볼륨
플러그인을 사용하면 배포된 파드가 기존 ScaleIO에 접근할 수
있다(또는 퍼시스턴트 볼륨 클래임을 위한 새 볼륨을 동적 프로비전할 수 있음,
[ScaleIO 퍼시스턴트 볼륨](/docs/concepts/storage/persistent-volumes/#scaleio)을 본다).
[ScaleIO 퍼시스턴트 볼륨](/ko/docs/concepts/storage/persistent-volumes/#scaleio)을 본다).
{{< caution >}}
사용하기 위해선 먼저 기존에 ScaleIO 클러스터를 먼저 설정하고
@ -1333,7 +1333,7 @@ CSI 호환 볼륨 드라이버가 쿠버네티스 클러스터에 배포되면
지원을 구현할 수 있다.
CSI 설정 변경 없이 평소와 같이
[원시 블록 볼륨 지원으로 PV/PVC 설정](/docs/concepts/storage/persistent-volumes/#raw-block-volume-support)을 할 수 있다.
[원시 블록 볼륨 지원으로 PV/PVC 설정](/ko/docs/concepts/storage/persistent-volumes/#원시-블록-볼륨-지원)을 할 수 있다.
#### CSI 임시(ephemeral) 볼륨

View File

@ -1075,7 +1075,7 @@ API 버전 `apps/v1` 에서는 `.spec.selector` 와 `.metadata.labels` 이 설
#### 디플로이먼트 롤링 업데이트
디플로이먼트는 `.spec.strategy.type==RollingUpdate` 이면 파드를 [롤링 업데이트](/docs/tasks/run-application/rolling-update-replication-controller/)
디플로이먼트는 `.spec.strategy.type==RollingUpdate` 이면 파드를 롤링 업데이트
방식으로 업데이트 한다. `maxUnavailable``maxSurge` 를 명시해서
롤링 업데이트 프로세스를 제어할 수 있다.
@ -1141,12 +1141,4 @@ API 버전 `apps/v1` 에서는 `.spec.selector` 와 `.metadata.labels` 이 설
일시 중지된 디플로이먼트는 PodTemplateSpec에 대한 변경 사항이 일시중지 된 경우 새 롤아웃을 트리거 하지 않는다.
디플로이먼트는 생성시 기본적으로 일시 중지되지 않는다.
## 디플로이먼트의 대안
### kubectl 롤링 업데이트
[`kubectl rolling-update`](/docs/reference/generated/kubectl/kubectl-commands#rolling-update)도
비슷한 방식으로 파드와 레플리케이션 컨트롤러를 업데이트한다. 그러나 디플로이먼트는 선언적이고, 서버 측면이며,
롤링 업데이트가 완료된 후에도 이전 수정 버전으로 롤백하는 것과 같은 추가 기능을 가지고 있으므로 권장한다.
{{% /capture %}}

View File

@ -22,8 +22,8 @@ weight: 10
레플리카셋이 새로운 파드를 생성해야 할 경우, 명시된 파드 템플릿을
사용한다.
레플리카셋과 파드와의 링크는 파드의 [metadata.ownerReferences](/ko/docs/concepts/workloads/controllers/garbage-collection/#소유자-owner-와-종속-dependent)
필드를 통해서 제공되며, 이는 현재 오브젝트가 소유한 리소스를 명시한다.
레플리카셋 파드의 [metadata.ownerReferences](/ko/docs/concepts/workloads/controllers/garbage-collection/#소유자-owner-와-종속-dependent)
필드를 통해 파드에 연결되며, 이는 현재 오브젝트가 소유한 리소스를 명시한다.
레플리카셋이 가지고 있는 모든 파드의 ownerReferences 필드는 해당 파드를 소유한 레플리카셋을 식별하기 위한 소유자 정보를 가진다.
이 링크를 통해 레플리카셋은 자신이 유지하는 파드의 상태를 확인하고 이에 따라 관리 한다.

View File

@ -217,9 +217,6 @@ REST API나 go 클라이언트 라이브러리를 사용하는 경우 간단히
두 레플리케이션 컨트롤러는 일반적으로 롤링 업데이트를 동기화 하는 이미지 업데이트이기 때문에 파드의 기본 컨테이너 이미지 태그와 같이 적어도 하나의 차별화된 레이블로 파드를 생성해야 한다.
롤링 업데이트는 클라이언트 툴에서 [`kubectl rolling-update`](/docs/reference/generated/kubectl/kubectl-commands#rolling-update) 로 수행된다.
좀 더 상세한 예제는 [`kubectl rolling-update` task](/docs/tasks/run-application/rolling-update-replication-controller/) 를 방문하라.
### 다수의 릴리스 트랙
롤링 업데이트가 진행되는 동안 다수의 애플리케이션 릴리스를 실행하는 것 외에도 다수의 릴리스 트랙을 사용하여 장기간에 걸쳐 또는 연속적으로 실행하는 것이 일반적이다. 트랙은 레이블 별로 구분된다.
@ -243,7 +240,7 @@ REST API나 go 클라이언트 라이브러리를 사용하는 경우 간단히
레플리케이션 컨트롤러는 이 좁은 책임에 영원히 제약을 받는다. 그 자체로는 준비성 또는 활성 프로브를 실행하지 않을 것이다. 오토 스케일링을 수행하는 대신, 외부 오토 스케일러 ([#492](http://issue.k8s.io/492)에서 논의된) 가 레플리케이션 컨트롤러의 `replicas` 필드를 변경함으로써 제어되도록 의도되었다. 레플리케이션 컨트롤러에 스케줄링 정책 (예를 들어 [spreading](http://issue.k8s.io/367#issuecomment-48428019)) 을 추가하지 않을 것이다. 오토사이징 및 기타 자동화 된 프로세스를 방해할 수 있으므로 제어된 파드가 현재 지정된 템플릿과 일치하는지 확인해야 한다. 마찬가지로 기한 완료, 순서 종속성, 구성 확장 및 기타 기능은 다른 곳에 속한다. 대량의 파드 생성 메커니즘 ([#170](http://issue.k8s.io/170)) 까지도 고려해야 한다.
레플리케이션 컨트롤러는 조합 가능한 빌딩-블록 프리미티브가 되도록 고안되었다. 향후 사용자의 편의를 위해 더 상위 수준의 API 및/또는 도구와 그리고 다른 보완적인 기본 요소가 그 위에 구축 될 것으로 기대한다. 현재 kubectl이 지원하는 "매크로" 작업 (실행, 스케일, 롤링 업데이트)은 개념 증명의 예시이다. 예를 들어 [Asgard](http://techblog.netflix.com/2012/06/asgard-web-based-cloud-management-and.html) 와 같이 레플리케이션 컨트롤러, 오토 스케일러, 서비스, 정책 스케줄링, 카나리 등을 관리할 수 있다.
레플리케이션 컨트롤러는 조합 가능한 빌딩-블록 프리미티브가 되도록 고안되었다. 향후 사용자의 편의를 위해 더 상위 수준의 API 및/또는 도구와 그리고 다른 보완적인 기본 요소가 그 위에 구축 될 것으로 기대한다. 현재 kubectl이 지원하는 "매크로" 작업 (실행, 스케일)은 개념 증명의 예시이다. 예를 들어 [Asgard](http://techblog.netflix.com/2012/06/asgard-web-based-cloud-management-and.html) 와 같이 레플리케이션 컨트롤러, 오토 스케일러, 서비스, 정책 스케줄링, 카나리 등을 관리할 수 있다.
## API 오브젝트
@ -263,9 +260,7 @@ API 오브젝트에 대한 더 자세한 것은
### 디플로이먼트 (권장되는)
[`디플로이먼트`](/ko/docs/concepts/workloads/controllers/deployment/) 는 `kubectl rolling-update` 와 비슷한 방식으로 기본 레플리카셋과 그 파드를 업데이트하는 상위 수준의 API 오브젝트이다.
`kubectl rolling-update` 와는 다르게 선언적이며, 서버 사이드이고,
추가 기능이 있기 때문에 롤링 업데이트 기능을 원한다면 디플로이먼트를 권장한다.
[`디플로이먼트`](/ko/docs/concepts/workloads/controllers/deployment/) 는 기본 레플리카셋과 그 파드를 업데이트하는 상위 수준의 API 오브젝트이다. 선언적이며, 서버 사이드이고, 추가 기능이 있기 때문에 롤링 업데이트 기능을 원한다면 디플로이먼트를 권장한다.
### 베어 파드

View File

@ -99,7 +99,7 @@ spec:
* 이름이 nginx라는 헤드리스 서비스는 네트워크 도메인을 컨트롤하는데 사용 한다.
* 이름이 web인 스테이트풀셋은 3개의 nginx 컨테이너의 레플리카가 고유의 파드에서 구동될 것이라 지시하는 Spec을 갖는다.
* volumeClaimTemplates은 퍼시스턴트 볼륨 프로비저너에서 프로비전한 [퍼시스턴트 볼륨](/docs/concepts/storage/persistent-volumes/)을 사용해서 안정적인 스토리지를 제공한다.
* volumeClaimTemplates은 퍼시스턴트 볼륨 프로비저너에서 프로비전한 [퍼시스턴트 볼륨](/ko/docs/concepts/storage/persistent-volumes/)을 사용해서 안정적인 스토리지를 제공한다.
스테이트풀셋 오브젝트의 이름은 유효한
[DNS 서브도메인 이름](/ko/docs/concepts/overview/working-with-objects/names/#dns-서브도메인-이름들)이어야 한다.
@ -153,7 +153,7 @@ N개의 레플리카가 있는 스테이트풀셋은 스테이트풀셋에 있
### 안정된 스토리지
쿠버네티스는 각 VolumeClaimTemplate마다 하나의 [퍼시스턴트 볼륨](/docs/concepts/storage/persistent-volumes/)을
쿠버네티스는 각 VolumeClaimTemplate마다 하나의 [퍼시스턴트 볼륨](/ko/docs/concepts/storage/persistent-volumes/)을
생성한다. 위의 nginx 예시에서 각 파드는 `my-storage-class` 라는 스토리지 클래스와
1 Gib의 프로비전된 스토리지를 가지는 단일 퍼시스턴트 볼륨을 받게된다. 만약 스토리지 클래스가
명시되지 않은 경우 기본 스토리지 클래스를 사용된다. 파드가 노드에서 스케줄 혹은 재스케줄이되면

View File

@ -243,8 +243,11 @@ myapp-pod 1/1 Running 0 9m
## 자세한 동작
파드 시동 시, 네트워크와 볼륨이 초기화되고 나면, 초기화 컨테이너가
순서대로 시작된다. 각 초기화 컨테이너는 다음 컨테이너가 시작되기 전에 성공적으로
파드 시작 시에 kubelet은 네트워크와 스토리지가 준비될 때까지
초기화 컨테이너의 실행을 지연시킨다. 그런 다음 kubelet은 파드 사양에
나와있는 순서대로 파드의 초기화 컨테이너를 실행한다.
각 초기화 컨테이너는 다음 컨테이너가 시작되기 전에 성공적으로
종료되어야 한다. 만약 런타임 문제나 실패 상태로 종료되는 문제로인하여 초기화 컨테이너의 시작이
실패된다면, 초기화 컨테이너는 파드의 `restartPolicy`에 따라서 재시도 된다. 다만,
파드의 `restartPolicy`이 항상(Always)으로 설정된 경우, 해당 초기화 컨테이너는

View File

@ -33,7 +33,7 @@ _파드_ 는 (고래 떼(pod of whales)나 콩꼬투리(pea pod)와 마찬가지
그들은 또한 SystemV 세마포어나, POSIX 공유 메모리와 같은 표준 프로세스 간 통신 방식으로
서로 통신할 수 있다.
다른 파드의 컨테이너에는 고유한 IP 주소가 있고,
[특별한 구성](/docs/concepts/policy/pod-security-policy/) 없이는 IPC에 의해서 통신 할 수 없다.
[특별한 구성](/ko/docs/concepts/policy/pod-security-policy/) 없이는 IPC에 의해서 통신 할 수 없다.
컨테이너는 주로 서로의 IP 주소를 통해 소통한다.
또한 파드 안의 애플리케이션은 파드의 일부로 정의되어,

View File

@ -4,14 +4,24 @@ title: 쿠버네티스 문서에 기여하기
linktitle: 기여
main_menu: true
weight: 80
card:
name: contribute
weight: 10
title: 기여 시작하기
---
{{% capture overview %}}
쿠버네티스 문서 또는 웹사이트에 기여하여 도움을 제공하고 싶다면,
우리는 당신의 도움을 기쁘게 생각한다! 당신이 새로운 프로젝트에 참여했거나
오랜 시간 동안 진행해온 누군가로서,
혹은 개발자, 최종 사용자 또는 단지 오타를 보고 참지 못하는 누군가로서 기여할 수 있다.
이 웹사이트는 [쿠버네티스 SIG Docs](/docs/contribute/#get-involved-with-sig-docs)에 의해서 관리됩니다.
쿠버네티스 문서 기여자들은
- 기존 콘텐츠를 개선합니다.
- 새 콘텐츠를 만듭니다.
- 문서를 번역합니다.
- 쿠버네티스 릴리스 주기에 맞추어 문서 부분을 관리하고 발행합니다.
쿠버네티스 문서는 새롭고 경험이 풍부한 모든 기여자의 개선을 환영합니다!
{{% /capture %}}
@ -19,44 +29,49 @@ weight: 80
## 시작하기
누구든지 문제에 대한 설명이나, 원하는 문서의 개선사항에 대한 이슈를 오픈 또는 풀 리퀘스트(PR)로 변경하는 기여를 할 수 있다.
일부 작업에는 쿠버네티스 조직에서 더 많은 신뢰와 더 많은 접근이 필요할 수 있다.
역할과 권한에 대한 자세한 내용은
[SIG Docs 참여](/ko/docs/contribute/participating/)를 본다.
쿠버네티스 문서는 GitHub 리포지터리에 있다. 우리는 누구나
기여를 환경하지만, 쿠버네티스 커뮤니티에서 효과적으로 활동하려면 git과 GitHub의
기초적인 이해가 필요하다.
누구든지 문서에 대한 이슈를 오픈 또는 풀 리퀘스트(PR)를 사용해서 [`kubernetes/website` GitHub 리포지터리](https://github.com/kubernetes/website)에 변경하는 기여를 할 수 있습니다. 당신이 쿠버네티스 커뮤니티에 효과적으로 기여하려면 [git](https://git-scm.com/)과 [GitHub](https://lab.github.com/)에 익숙해야 합니다.
문서에 참여하려면
1. CNCF [Contributor License Agreement](https://github.com/kubernetes/community/blob/master/CLA.md)에 서명다.
2. [문서 리포지터리](https://github.com/kubernetes/website) 와 웹사이트의 [정적 사이트 생성기](https://gohugo.io)를 숙지다.
3. [콘텐츠 향상](https://kubernetes.io/docs/contribute/start/#improve-existing-content)과 [변경 검토](https://kubernetes.io/docs/contribute/start/#review-docs-pull-requests)의 기본 프로세스를 이해하도록 한다.
1. CNCF [Contributor License Agreement](https://github.com/kubernetes/community/blob/master/CLA.md)에 서명합니다.
2. [문서 리포지터리](https://github.com/kubernetes/website) 와 웹사이트의 [정적 사이트 생성기](https://gohugo.io)를 숙지합니다.
3. [풀 리퀘스트 열기](/docs/contribute/new-content/open-a-pr/)와 [변경 검토](/docs/contribute/review/reviewing-prs/)의 기본 프로세스를 이해하도록 합니다.
## 기여 모범 사례
일부 작업에는 쿠버네티스 조직에서 더 많은 신뢰와 더 많은 접근이 필요할 수 있습니다.
역할과 권한에 대한 자세한 내용은
[SIG Docs 참여](/ko/docs/contribute/participating/)를 봅니다.
- 명확하고, 의미있는 GIT 커밋 메시지를 작성한다.
- 이슈를 참조하고, PR이 병합될 때 이슈를 자동으로 닫는 _Github 특수 키워드_ 를 포함한다.
- 오타 수정, 스타일 변경 또는 문법 변경과 같이 변경이 적은 PR을 생성할때, 비교적으로 적은 변화로 많은 커밋 개수를 받지 않도록 반드시 커밋을 스쿼시(squash)한다.
- 변경한 코드를 묘사하고, 코드를 변경한 이유를 포함하는 멋진 PR 설명을 포함하고 있는지와 리뷰어를 위한 충분한 정보가 있는지 꼭 확인한다.
- 추가적인 읽을거리들
- [chris.beams.io/posts/git-commit/](https://chris.beams.io/posts/git-commit/)
- [github.com/blog/1506-closing-issues-via-pull-requests ](https://github.com/blog/1506-closing-issues-via-pull-requests )
- [davidwalsh.name/squash-commits-git ](https://davidwalsh.name/squash-commits-git )
## 첫 번째 기여
## 다른 방법으로 기여하기
- [기여 개요](/docs/contribute/new-content/overview/)를 읽고 기여할 수 있는 다양한 방법에 대해 알아봅니다.
- 기존 문서에 대해 [GitHub을 사용해서 풀 리퀘스트 열거나](/docs/contribute/new-content/new-content/#changes-using-github) GitHub에서의 이슈 제기에 대해 자세히 알아봅니다.
- 정확성과 언어에 대해 다른 쿠버네티스 커뮤니티 맴버의 [풀 리퀘스트 검토](/docs/contribute/review/reviewing-prs/)를 합니다.
- 쿠버네티스 [컨텐츠](/docs/contribute/style/content-guide/)와 [스타일 가이드](/docs/contribute/style/style-guide/)를 읽고 정보에 대한 코멘트를 남길 수 있습니다.
- [페이지 템플릿 사용](/docs/contribute/style/page-templates/)과 [휴고(Hugo) 단축코드(shortcodes)](/docs/contribute/style/hugo-shortcodes/)를 사용해서 큰 변경을 하는 방법에 대해 배워봅니다.
- 트위터나 스택오버플로(Stack Overflow) 등의 온라인 포럼의 쿠버네티스 커뮤니티에 기여하거나 지역 모임과 쿠버네티스 이벤트에 관하여 알고 싶다면 [쿠버네티스 커뮤니티 사이트](/community/)를 확인한다.
- 기능 개발에 기여하려면 [기여자 치트시트](https://github.com/kubernetes/community/tree/master/contributors/guide/contributor-cheatsheet)를 읽고 시작한다.
{{% /capture %}}
{{% capture whatsnext %}}
- 문서에 기여하는 기본적인 사항들에 대한 자세한 내용은 [기여 시작](/docs/contribute/start/)을 본다.
- 변경을 제안할 때는 [쿠버네티스 문서 스타일가이드](/docs/contribute/style/style-guide/)를 따른다.
- SIG Docs에 대한 더 자세한 정보는 [SIG Docs에 참여하기](/ko/docs/contribute/participating/)를 본다.
- 쿠버네티스 문서 현지화에 대한 자세한 내용은 [쿠버네티스 문서 현지화](/docs/contribute/localization/)를 본다.
## 다음 단계
- 리포지터리의 [로컬 복제본에서 작업](/docs/contribute/new-content/new-content/#fork-the-repo)하는 방법을 배워봅니다.
- [릴리스된 기능](/docs/contribute/new-content/new-features/)을 문서화 합니다.
- [SIG Docs](/ko/docs/contribute/participating/)에 참여하고, [멤버 또는 검토자](/ko/docs/contribute/participating/#역할과-책임)가 되어봅니다.
- [현지화](/ko/docs/contribute/localization_ko/)를 시작하거나 도와줍니다.
## SIG Docs에 참여
[SIG Docs](/ko/docs/contribute/participating/)는 쿠버네티스 문서와 웹 사이트를 게시하고 관리하는 기여자 그룹입니다. SIG Docs에 참여하는 것은 쿠버네티스 기여자(기능 개발 및 다른 여러가지)가 쿠버네티스 프로젝트에 가장 큰 영향을 미칠 수 있는 좋은 방법입니다.
SIG Docs는 여러가지 방법으로 의견을 나누고 있습니다.
- [쿠버네티스 슬랙 인스턴스에서 `#sig-docs` 에 가입](http://slack.k8s.io/)을 하고,
자신을 소개하세요!
- 더 광범위한 토론이 이루어지고 공식적인 결정이 기록이 되는
[`kubernetes-sig-docs` 메일링 리스트에 가입](https://groups.google.com/forum/#!forum/kubernetes-sig-docs) 하세요.
- [주간 SIG Docs 화상 회의](https://github.com/kubernetes/community/tree/master/sig-docs)에 참여하세요. 회의는 항상 `#sig-docs` 에 발표되며 [쿠버네티스 커뮤니티 회의 일정](https://calendar.google.com/calendar/embed?src=cgnt364vd8s86hr2phapfjc6uk%40group.calendar.google.com&ctz=America/Los_Angeles)에 추가됩니다. [줌(Zoon) 클라이언트](https://zoom.us/download)를 다운로드 하거나 전화를 이용하여 전화 접속해야 합니다.
## 다른 기여 방법들
- [쿠버네티스 커뮤니티 사이트](/community/)를 방문하십시오. 트위터 또는 스택 오버플로우에 참여하고, 현지 쿠버네티스 모임과 이벤트 등에 대해 알아봅니다.
- [기여자 치트시트](https://github.com/kubernetes/community/tree/master/contributors/guide/contributor-cheatsheet)를 읽고 쿠버네티스 기능 개발에 참여합니다.
- [블로그 게시물 또는 사례 연구](/docs/contribute/new-content/blogs-case-studies/)를 제출합니다.
{{% /capture %}}

View File

@ -1,9 +1,10 @@
---
title: SIG Docs에 참여하기
content_template: templates/concept
weight: 60
card:
name: contribute
weight: 40
weight: 60
---
{{% capture overview %}}
@ -35,7 +36,7 @@ SIG Docs는 모든 컨트리뷰터의 콘텐츠와 리뷰를 환영한다.
## 역할과 책임
- **모든 사람** 은 쿠버네티스 문서에 기여할 수 있다. 기여시 [CLA에 서명](/docs/contribute/start#sign-the-cla)하고 GitHub 계정을 가지고 있어야 한다.
- **모든 사람** 은 쿠버네티스 문서에 기여할 수 있다. 기여시 [CLA에 서명](/docs/contribute/new-content/overview/#sign-the-cla))하고 GitHub 계정을 가지고 있어야 한다.
- 쿠버네티스 조직의 **멤버** 는 쿠버네티스 프로젝트에 시간과 노력을 투자한 기여자이다. 일반적으로 승인되는 변경이 되는 풀 리퀘스트를 연다. 멤버십 기준은 [커뮤니티 멤버십](https://github.com/kubernetes/community/blob/master/community-membership.md)을 참조한다.
- SIG Docs의 **리뷰어** 는 쿠버네티스 조직의 일원으로
문서 풀 리퀘스트에 관심을 표명했고, SIG Docs 승인자에
@ -61,7 +62,7 @@ SIG Docs는 모든 컨트리뷰터의 콘텐츠와 리뷰를 환영한다.
만약 쿠버네티스 조직의 멤버가 아니라면, `/lgtm` 을 사용하는 것은 자동화된 시스템에 아무런 영향을 주지 않는다.
{{< /note >}}
[CLA에 서명](/docs/contribute/start#sign-the-cla) 후에 누구나 다음을 할 수 있다.
[CLA에 서명](/docs/contribute/new-content/overview/#sign-the-cla)) 후에 누구나 다음을 할 수 있다.
- 기존 콘텐츠를 개선하거나, 새 콘텐츠를 추가하거나, 블로그 게시물 또는 사례연구 작성을 위해 풀 리퀘스트를 연다.
## 멤버
@ -222,7 +223,7 @@ GitHub 그룹에 당신을 추가하기를 요청한다. `kubernetes-website-adm
- 승인 전에 PR에 대한 Netlify 프리뷰 페이지를 방문하여, 제대로 보이는지 확인한다.
- 주간 로테이션을 위해 [PR Wrangler 로테이션 스케줄](https://github.com/kubernetes/website/wiki/PR-Wranglers)에 참여한다. SIG Docs는 모든 승인자들이 이 로테이션에 참여할
- 주간 로테이션을 위해 [PR Wrangler 로테이션 스케줄](https://github.com/kubernetes/website/wiki/PR-Wranglers)에 참여한다. SIG Docs는 모든 승인자들이 이 로테이션에 참여할
것으로 기대한다. [일주일 간 PR Wrangler 되기](/docs/contribute/advanced#be-the-pr-wrangler-for-a-week)
문서를 참고한다.
@ -298,7 +299,7 @@ PR 소유자에게 조언하는데 활용된다.
- 모든 쿠버네티스 멤버는 코멘트에 `/lgtm` 을 추가해서 `lgtm` 레이블을 추가할 수 있다.
- SIG Docs 승인자들만이 코멘트에 `/approve`
추가해서 풀 리퀘스트를 병합할 수 있다. 일부 승인자들은
[PR Wrangler](#pr-wrangler) 또는 [SIG Docs 의장](#sig-docs-의장)과
[PR Wrangler](/docs/contribute/advanced#be-the-pr-wrangler-for-a-week) 또는 [SIG Docs 의장](#sig-docs-의장)과
같은 특정 역할도 수행한다.
{{% /capture %}}
@ -307,8 +308,9 @@ PR 소유자에게 조언하는데 활용된다.
쿠버네티스 문서화에 기여하는 일에 대한 보다 많은 정보는 다음 문서를 참고한다.
- [기여 시작하기](/docs/contribute/start/)
- [문서 스타일](/docs/contribute/style/)
- [신규 컨텐츠 기여하기](/docs/contribute/overview/)
- [컨텐츠 검토하기](/docs/contribute/review/reviewing-prs)
- [문서 스타일 가이드](/docs/contribute/style/)
{{% /capture %}}

View File

@ -162,7 +162,6 @@ kubectl create -f https://k8s.io/examples/pods/storage/gce-volume.yaml
{{% /capture %}}
{{% capture whatsnext %}}
* [페이지 템플릿 사용](/docs/home/contribute/page-templates/)에 대해 알아보기.
* [변경 사항 준비](/docs/home/contribute/stage-documentation-changes/)에 대해 알아보기.
* [풀 리퀘스트 작성](/docs/home/contribute/create-pull-request/)에 대해 알아보기.
* [페이지 템플릿 사용](/docs/contribute/page-templates/))에 대해 알아보기.
* [풀 리퀘스트 작성](/docs/contribute/new-content/open-a-pr/)에 대해 알아보기.
{{% /capture %}}

View File

@ -2,7 +2,7 @@
title: 컨테이너 런타임
id: container-runtime
date: 2019-06-05
full_link: /docs/reference/generated/container-runtime
full_link: /docs/setup/production-environment/container-runtimes
short_description: >
컨테이너 런타임은 컨테이너 실행을 담당하는 소프트웨어이다.

View File

@ -2,7 +2,7 @@
title: 익스텐션(Extensions)
id: Extensions
date: 2019-02-01
full_link: /docs/concepts/extend-kubernetes/extend-cluster/#extensions
full_link: /ko/docs/concepts/extend-kubernetes/extend-cluster/#익스텐션
short_description: >
익스텐션은 새로운 타입의 하드웨어를 지원하기 위해 쿠버네티스를 확장하고 깊게 통합시키는 소프트웨어 컴포넌트이다.
@ -15,4 +15,4 @@ tags:
<!--more-->
대부분의 클러스터 관리자는 호스트된 쿠버네티스 또는 쿠버네티스의 배포 인스턴스를 사용할 것이다. 그 결과, 대부분의 쿠버네티스 사용자는 [익스텐션](/docs/concepts/extend-kubernetes/extend-cluster/#extensions)의 설치가 필요할 것이며, 일부 사용자만 직접 새로운 것을 만들 것이다.
대부분의 클러스터 관리자는 호스트된 쿠버네티스 또는 쿠버네티스의 배포 인스턴스를 사용할 것이다. 그 결과, 대부분의 쿠버네티스 사용자는 [익스텐션](/ko/docs/concepts/extend-kubernetes/extend-cluster/#익스텐션)의 설치가 필요할 것이며, 일부 사용자만 직접 새로운 것을 만들 것이다.

View File

@ -11,7 +11,7 @@ weight: 20
{{% capture body %}}
## 보안 공지
보안 및 주요 API 공지에 대한 이메일을 위해 [kubernetes-announce](https://groups.google.com/forum/#!forum/kubernetes-announce) 그룹에 가입하세요.
보안 및 주요 API 공지에 대한 이메일을 위해 [kubernetes-security-announce](https://groups.google.com/forum/#!forum/kubernetes-security-announce)) 그룹에 가입하세요.
[이 링크](https://groups.google.com/forum/feed/kubernetes-announce/msgs/rss_v2_0.xml?num=50)를 사용하여 RSS 피드를 구독할 수 있다.

View File

@ -200,7 +200,6 @@ kubectl diff -f ./my-manifest.yaml
## 리소스 업데이트
1.11 버전에서 `rolling-update`는 사용 중단(deprecated)되었다. ([CHANGELOG-1.11.md](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.11.md) 참고) 대신 `rollout`를 사용한다.
```bash
kubectl set image deployment/frontend www=image:v2 # "frontend" 디플로이먼트의 "www" 컨테이너 이미지를 업데이트하는 롤링 업데이트
@ -211,12 +210,6 @@ kubectl rollout status -w deployment/frontend # 완료될 때
kubectl rollout restart deployment/frontend # "frontend" 디플로이먼트의 롤링 재시작
# 버전 1.11 부터 사용 중단
kubectl rolling-update frontend-v1 -f frontend-v2.json # (사용중단) frontend-v1 파드의 롤링 업데이트
kubectl rolling-update frontend-v1 frontend-v2 --image=image:v2 # (사용중단) 리소스 이름 변경과 이미지 업데이트
kubectl rolling-update frontend --image=image:v2 # (사용중단) 프론트엔드의 파드 이미지 업데이트
kubectl rolling-update frontend-v1 frontend-v2 --rollback # (사용중단) 진행중인 기존 롤아웃 중단
cat pod.json | kubectl replace -f - # std로 전달된 JSON을 기반으로 파드 교체
# 리소스를 강제 교체, 삭제 후 재생성함. 이것은 서비스를 중단시킴.

View File

@ -18,11 +18,6 @@ content_template: templates/concept
[`kubeadm`](/docs/setup/production-environment/tools/kubeadm/install-kubeadm/)은 물리적 환경, 클라우드 서버, 또는 가상머신 상에서 안전한 쿠버네티스를 쉽게 프로비저닝하기 위한 커맨드라인 툴이다(현재는 알파 상태).
## Kubefed
[`kubefed`](/docs/tasks/federation/set-up-cluster-federation-kubefed/)는 페더레이션 클러스터를
관리하는데 도움이 되는 커맨드라인 툴이다.
## Minikube
[`minikube`](/ko/docs/tasks/tools/install-minikube/)는 개발과 테스팅 목적으로 하는

View File

@ -36,19 +36,15 @@ card:
|커뮤니티 |생태계 |
| ------------ | -------- |
| [Minikube](/docs/setup/learning-environment/minikube/) | [CDK on LXD](https://www.ubuntu.com/kubernetes/docs/install-local) |
| [kind (Kubernetes IN Docker)](/docs/setup/learning-environment/kind/) | [Docker Desktop](https://www.docker.com/products/docker-desktop)|
| | [Minishift](https://docs.okd.io/latest/minishift/)|
| [Minikube](/docs/setup/learning-environment/minikube/) | [Docker Desktop](https://www.docker.com/products/docker-desktop)|
| [kind (Kubernetes IN Docker)](/docs/setup/learning-environment/kind/) | [Minishift](https://docs.okd.io/latest/minishift/)|
| | [MicroK8s](https://microk8s.io/)|
| | [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)|
## 운영 환경
운영 환경을 위한 솔루션을 평가할 때에는, 쿠버네티스 클러스터 운영에 대한 어떤 측면(또는 _추상적인 개념_)을 스스로 관리하기를 원하는지, 제공자에게 넘기기를 원하는지 고려하자.
[공인 쿠버네티스](https://github.com/cncf/k8s-conformance/#certified-kubernetes) 공급자의 목록과 "[파트너](https://kubernetes.io/partners/#conformance)"를 참조한다.
[쿠버네티스 파트너](https://kubernetes.io/partners/#conformance)에는 [공인 쿠버네티스](https://github.com/cncf/k8s-conformance/#certified-kubernetes) 공급자 목록이 포함되어 있다.
{{% /capture %}}

View File

@ -327,8 +327,8 @@ Minikube는 사용자가 쿠버네티스 컴포넌트를 다양한 값으로 설
`minikube delete` 명령은 클러스터를 삭제하는데 사용할 수 있다.
이 명령어는 Minikube 가상 머신을 종료하고 삭제한다. 어떤 데이터나 상태도 보존되지 않다.
### minikube 업그레이드
[minikube 업그레이드](https://minikube.sigs.k8s.io/docs/start/macos/)를 본다.
### Minikube 업그레이드
macOS를 사용하는 경우 기존에 설치된 Minikube를 업그레이드하려면 [Minikube 업그레이드](https://minikube.sigs.k8s.io/docs/start/macos/#upgrading-minikube)를 참조한다.
## 클러스터와 상호 작용하기
@ -369,7 +369,7 @@ Minikube VM은 host-only IP 주소를 통해 호스트 시스템에 노출되고
`kubectl get service $SERVICE --output='jsonpath="{.spec.ports[0].nodePort}"'`
## 퍼시스턴트 볼륨
Minikube는 [퍼시스턴트 볼륨](/docs/concepts/storage/persistent-volumes/)을 `hostPath` 타입으로 지원한다.
Minikube는 [퍼시스턴트 볼륨](/ko/docs/concepts/storage/persistent-volumes/)을 `hostPath` 타입으로 지원한다.
이런 퍼시스턴트 볼륨은 Minikube VM 내에 디렉터리로 매핑됩니다.
Minikube VM은 tmpfs에서 부트하는데, 매우 많은 디렉터리가 재부트(`minikube stop`)까지는 유지되지 않다.

View File

@ -149,17 +149,17 @@ users:
username: exp
```
`fake-ca-file`, `fake-cert-file`, `fake-key-file`은 인증서 파일들의 실제 경로 위한
`fake-ca-file`, `fake-cert-file`, `fake-key-file`은 인증서 파일들의 실제 경로 이름을 위한
플레이스홀더(placeholder)이다.
당신의 환경에 맞게 이들을 실제 인증서 경로로 변경해줘야 한다.
만약 당신이 인증서 파일들의 경로 대신에 base64로 인코딩된 데이터를 여기에 사용하려고 한다면
키에 `-data` 접미사를 추가해야 한다. 예를 들면 `certificate-authority-data`,
만약 당신이 인증서 파일들의 경로 대신에 여기에 포함된 base64로 인코딩된 데이터를 사용하려고 한다면
이 경우 키에 `-data` 접미사를 추가해야 한다. 예를 들면 `certificate-authority-data`,
`client-certificate-data`, `client-key-data` 같이 사용할 수 있다.
컨텍스트는 세 가지(클러스터, 사용자, 네임스페이스) 요소들로 이뤄진다. 예를 들어
`dev-frontend` 컨텍스트는 `development` 클러스터의 `frontend` 네임스페이스에 접근하는데
`developer` 사용자 자격증명을 사용하라고 알려준다.
`dev-frontend` 컨텍스트는 "`development` 클러스터의 `frontend` 네임스페이스에 접근하는데
`developer` 사용자 자격증명을 사용하라고 알려준다."
현재 컨텍스트를 설정한다.
@ -275,7 +275,7 @@ Linux와 Mac에서는 콜론으로 구분되며 Windows에서는 세미콜론으
`KUBECONFIG` 환경 변수를 가지고 있다면, 리스트에 포함된 구성 파일들에
익숙해지길 바란다.
다음 예와 같이 임시로 `KUBECONFIG` 환경 변수에 두 개의 경로들을 덧붙여보자.<br>
다음 예와 같이 임시로 `KUBECONFIG` 환경 변수에 두 개의 경로들을 덧붙여보자.
### Linux
```shell
@ -359,11 +359,13 @@ kubectl config view
## 정리
`KUBECONFIG` 환경 변수를 원래 값으로 되돌려 놓자. 예를 들면:<br>
Linux:
### Linux
```shell
export KUBECONFIG=$KUBECONFIG_SAVED
```
Windows PowerShell
### Windows PowerShell
```shell
$Env:KUBECONFIG=$ENV:KUBECONFIG_SAVED
```
@ -378,4 +380,3 @@ Windows PowerShell
{{% /capture %}}

View File

@ -0,0 +1,356 @@
---
title: 컨테이너 및 파드 메모리 리소스 할당
content_template: templates/task
weight: 10
---
{{% capture overview %}}
이 페이지는 메모리 *요청량* 과 메모리 *상한* 을 컨테이너에 어떻게 지정하는지 보여준다.
컨테이너는 요청량 만큼의 메모리 확보가 보장되나
상한보다 더 많은 메모리는 사용할 수 없다.
{{% /capture %}}
{{% capture prerequisites %}}
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
클러스터의 각 노드에 최소 300 MiB 메모리가 있어야 한다.
이 페이지의 몇 가지 단계를 수행하기 위해서는 클러스터 내
[metrics-server](https://github.com/kubernetes-incubator/metrics-server)
서비스 실행이 필요하다. 이미 실행중인 metrics-server가 있다면
다음 단계를 건너뛸 수 있다.
Minikube를 사용 중이라면, 다음 명령어를 실행해 metric-server를 활성화 할 수 있다.
```shell
minikube addons enable metrics-server
```
metric-server가 실행 중인지 확인하거나 다른 제공자의 리소스 메트릭 API (`metrics.k8s.io`)를 확인하기 위해
다음의 명령어를 실행한다.
```shell
kubectl get apiservices
```
리소스 메트릭 API를 사용할 수 있다면 출력에
`metrics.k8s.io`에 대한 참조가 포함되어 있다.
```shell
NAME
v1beta1.metrics.k8s.io
```
{{% /capture %}}
{{% capture steps %}}
## 네임스페이스 생성
이 예제에서 생성할 자원과 클러스터 내 나머지를 분리하기 위해 네임스페이스를 생성한다.
```shell
kubectl create namespace mem-example
```
## 메모리 요청량 및 상한을 지정
컨테이너에 메모리 요청량을 지정하기 위해서는 컨테이너의 리소스 매니페스트에
`resources:requests` 필드를 포함한다. 리소스 상한을 지정하기 위해서는
`resources:limits` 필드를 포함한다.
이 예제에서 하나의 컨테이너를 가진 파드를 생성한다. 생성된 컨테이너는
100 MiB 메모리 요청량과 200 MiB 메모리 상한을 갖는다. 이 것이 파드 구성 파일이다.
{{< codenew file="pods/resource/memory-request-limit.yaml" >}}
구성 파일 내 `args` 섹션은 컨테이너가 시작될 때 아규먼트를 제공한다.
`"--vm-bytes", "150M"` 아규먼트는 컨테이너가 150 MiB 할당을 시도 하도록 한다.
파드 생성:
```shell
kubectl apply -f https://k8s.io/examples/pods/resource/memory-request-limit.yaml --namespace=mem-example
```
파드 컨테이너가 실행 중인지 확인:
```shell
kubectl get pod memory-demo --namespace=mem-example
```
파드에 대한 자세한 정보 보기:
```shell
kubectl get pod memory-demo --output=yaml --namespace=mem-example
```
출력은 파드 내 하나의 컨테이너에 100MiB 메모리 요청량과
200 MiB 메모리 상한이 있는 것을 보여준다.
```yaml
...
resources:
limits:
memory: 200Mi
requests:
memory: 100Mi
...
```
`kubectl top`을 실행하여 파드 메트릭 가져오기:
```shell
kubectl top pod memory-demo --namespace=mem-example
```
출력은 파드가 약 150MiB 해당하는 약 162,900,000 바이트 메모리를 사용하는 것을 보여준다.
이는 파드의 100 MiB 요청 보다 많으나 파드의 200 MiB 상한보다는 적다.
```
NAME CPU(cores) MEMORY(bytes)
memory-demo <something> 162856960
```
파드 삭제:
```shell
kubectl delete pod memory-demo --namespace=mem-example
```
## 컨테이너의 메모리 상한을 초과
노드 내 메모리가 충분하다면 컨테이너는 지정한 요청량보다 많은 메모리를 사용 할 수 있다. 그러나
컨테이너는 지정한 메모리 상한보다 많은 메모리를 사용할 수 없다. 만약 컨테이너가 지정한 메모리 상한보다
많은 메모리를 할당하면 해당 컨테이너는 종료 대상 후보가 된다. 만약 컨테이너가 지속적으로
지정된 상한보다 많은 메모리를 사용한다면, 해당 컨테이너는 종료된다. 만약 종료된 컨테이너가
재실행 가능하다면 다른 런타임 실패와 마찬가지로 kubelet에 의해 재실행된다.
이 예제에서는 상한보다 많은 메모리를 할당하려는 파드를 생성한다.
이 것은 50 MiB 메모리 요청량과 100 MiB 메모리 상한을 갖는
하나의 컨테이너를 갖는 파드의 구성 파일이다.
{{< codenew file="pods/resource/memory-request-limit-2.yaml" >}}
구성 파일의 'args' 섹션에서 컨테이너가
100 MiB 상한을 훨씬 초과하는 250 MiB의 메모리를 할당하려는 것을 볼 수 있다.
파드 생성:
```shell
kubectl apply -f https://k8s.io/examples/pods/resource/memory-request-limit-2.yaml --namespace=mem-example
```
파드에 대한 자세한 정보 보기:
```shell
kubectl get pod memory-demo-2 --namespace=mem-example
```
이 시점에 컨테이너가 실행되거나 종료되었을 수 있다. 컨테이너가 종료될 때까지 이전의 명령을 반복한다.
```shell
NAME READY STATUS RESTARTS AGE
memory-demo-2 0/1 OOMKilled 1 24s
```
컨테이너 상태의 상세 상태 보기:
```shell
kubectl get pod memory-demo-2 --output=yaml --namespace=mem-example
```
컨테이너가 메모리 부족 (OOM) 으로 종료되었음이 출력된다.
```shell
lastState:
terminated:
containerID: docker://65183c1877aaec2e8427bc95609cc52677a454b56fcb24340dbd22917c23b10f
exitCode: 137
finishedAt: 2017-06-20T20:52:19Z
reason: OOMKilled
startedAt: null
```
이 예제에서 컨테이너는 재실행 가능하여 kubelet에 의해 재실행된다.
컨테이너가 종료되었다 재실행되는 것을 보기 위해 다음 명령을 몇 번 반복한다.
```shell
kubectl get pod memory-demo-2 --namespace=mem-example
```
출력은 컨테이너의 종료, 재실행, 재종료, 재실행 등을 보여준다.
```
kubectl get pod memory-demo-2 --namespace=mem-example
NAME READY STATUS RESTARTS AGE
memory-demo-2 0/1 OOMKilled 1 37s
```
```
kubectl get pod memory-demo-2 --namespace=mem-example
NAME READY STATUS RESTARTS AGE
memory-demo-2 1/1 Running 2 40s
```
파드 내역에 대한 상세 정보 보기:
```
kubectl describe pod memory-demo-2 --namespace=mem-example
```
컨테이너가 반복적으로 시작하고 실패 하는 출력을 보여준다.
```
... Normal Created Created container with id 66a3a20aa7980e61be4922780bf9d24d1a1d8b7395c09861225b0eba1b1f8511
... Warning BackOff Back-off restarting failed container
```
클러스터 노드에 대한 자세한 정보 보기:
```
kubectl describe nodes
```
출력에는 컨테이너가 메모리 부족으로 종료된 기록이 포함된다.
```
Warning OOMKilling Memory cgroup out of memory: Kill process 4481 (stress) score 1994 or sacrifice child
```
파드 삭제:
```shell
kubectl delete pod memory-demo-2 --namespace=mem-example
```
## 노드에 비해 너무 큰 메모리 요청량의 지정
메모리 요청량과 상한은 컨테이너와 관련있지만, 파드가 가지는
메모리 요청량과 상한으로 이해하면 유용하다. 파드의 메모리 요청량은
파드 내 모든 컨테이너의 메모리 요청량의 합이다. 마찬가지로
파드의 메모리 상한은 파드 내 모든 컨테이너의 메모리 상한의 합이다.
파드는 요청량을 기반하여 스케줄링된다. 노드에 파드의 메모리 요청량을 충족하기에 충분한 메모리가 있는
경우에만 파드가 노드에서 스케줄링된다.
이 예제에서는 메모리 요청량이 너무 커 클러스터 내 모든 노드의 용량을 초과하는 파드를 생성한다.
다음은 클러스터 내 모든 노드의 용량을 초과할 수 있는 1000 GiB 메모리 요청을 포함하는
컨테이너를 갖는 파드의 구성 파일이다.
{{< codenew file="pods/resource/memory-request-limit-3.yaml" >}}
파드 생성:
```shell
kubectl apply -f https://k8s.io/examples/pods/resource/memory-request-limit-3.yaml --namespace=mem-example
```
파드 상태 보기:
```shell
kubectl get pod memory-demo-3 --namespace=mem-example
```
파드 상태가 PENDING 상태임이 출력된다. 즉 파드는 어떤 노드에서도 실행되도록 스케줄 되지 않고 PENDING가 계속 지속된다.
```
kubectl get pod memory-demo-3 --namespace=mem-example
NAME READY STATUS RESTARTS AGE
memory-demo-3 0/1 Pending 0 25s
```
이벤트를 포함한 파드 상세 정보 보기:
```shell
kubectl describe pod memory-demo-3 --namespace=mem-example
```
출력은 노드 내 메모리가 부족하여 파드가 스케줄링될 수 없음을 보여준다.
```shell
Events:
... Reason Message
------ -------
... FailedScheduling No nodes are available that match all of the following predicates:: Insufficient memory (3).
```
## 메모리 단위
메모리 리소스는 byte 단위로 측정된다. 다음 접미사 중 하나로 정수 또는 고정 소수점으로
메모리를 표시할 수 있다. E, P, T, G, M, K, Ei, Pi, Ti, Gi, Mi, Ki.
예를 들어 다음은 거의 유사한 값을 나타낸다.
```shell
128974848, 129e6, 129M , 123Mi
```
파드 삭제:
```shell
kubectl delete pod memory-demo-3 --namespace=mem-example
```
## 메모리 상한을 지정하지 않으면
컨테이너에 메모리 상한을 지정하지 않으면 다음 중 하나가 적용된다.
* 컨테이너가 사용할 수 있는 메모리 상한은 없다. 컨테이너가
실행 중인 노드에서 사용 가능한 모든 메모리를 사용하여 OOM Killer가 실행 될 수 있다. 또한 메모리 부족으로 인한 종료 시 메모리 상한이
없는 컨테이너가 종료될 가능성이 크다.
* 기본 메모리 상한을 갖는 네임스페이스 내에서 실행중인 컨테이너는
자동으로 기본 메모리 상한이 할당된다. 클러스터 관리자들은
[LimitRange](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#limitrange-v1-core)를
사용해 메모리 상한의 기본 값을 지정 가능하다.
## 메모리 요청량과 상한 동기부여
클러스터에서 실행되는 컨테이너에 메모리 요청량과 상한을 구성하여
클러스터 내 노드들의 메모리 리소스를 효율적으로 사용할 수 있게 할 수 있다.
파드의 메모리 요청량을 적게 유지하여 파드가 높은 확률로 스케줄링 될 수 있도록 한다.
메모리 상한이 메모리 요청량보다 크면 다음 두 가지가 수행된다.
* 가용한 메모리가 있는 경우 파드가 이를 사용할 수 있는 버스트(burst) 활동을 할 수 있다.
* 파드가 버스트 중 사용 가능한 메모리 양이 적절히 제한된다.
## 정리
네임스페이스를 지운다. 이 작업을 통해 네임스페이스 내 생성했던 모든 파드들은 삭제된다.
```shell
kubectl delete namespace mem-example
```
{{% /capture %}}
{{% capture whatsnext %}}
### 앱 개발자들을 위한
* [CPU 리소스를 컨테이너와 파드에 할당](/docs/tasks/configure-pod-container/assign-cpu-resource/)
* [파드에 서비스 품질 설정](/docs/tasks/configure-pod-container/quality-service-pod/)
### 클러스터 관리자들을 위한
* [네임스페이스에 기본 메모리 요청량 및 상한을 구성](/docs/tasks/administer-cluster/memory-default-namespace/)
* [네임스페이스에 기본 CPU 요청량 및 상한을 구성](/docs/tasks/administer-cluster/cpu-default-namespace/)
* [네임스페이스에 최소 및 최대 메모리 제약 조건 구성](/docs/tasks/administer-cluster/memory-constraint-namespace/)
* [네임스페이스에 최소 및 최대 CPU 제약 조건 구성](/docs/tasks/administer-cluster/cpu-constraint-namespace/)
* [네임스페이스에 메모리 및 CPU 할당량 구성](/docs/tasks/administer-cluster/quota-memory-cpu-namespace/)
* [네임스페이스에 파드 할당량 구성](/docs/tasks/administer-cluster/quota-pod-namespace/)
* [API 오브젝트에 할당량 구성 ](/docs/tasks/administer-cluster/quota-api-object/)
{{% /capture %}}

View File

@ -0,0 +1,120 @@
---
title: 노드 어피니티를 사용해 노드에 파드 할당
min-kubernetes-server-version: v1.10
content_template: templates/task
weight: 120
---
{{% capture overview %}}
이 문서는 쿠버네티스 클러스터의 특정 노드에 노드 어피니티를 사용해 쿠버네티스 파드를 할당하는
방법을 설명한다.
{{% /capture %}}
{{% capture prerequisites %}}
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
{{% /capture %}}
{{% capture steps %}}
## 노드에 레이블 추가
1. 클러스터의 노드를 레이블과 함께 나열하자.
```shell
kubectl get nodes --show-labels
```
결과는 아래와 같다.
```shell
NAME STATUS ROLES AGE VERSION LABELS
worker0 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker0
worker1 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker1
worker2 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker2
```
1. 노드 한 개를 선택하고, 레이블을 추가하자.
```shell
kubectl label nodes <your-node-name> disktype=ssd
```
`<your-node-name>` 는 선택한 노드의 이름이다.
1. 선택한 노드가 `disktype=ssd` 레이블을 갖고 있는지 확인하자.
```shell
kubectl get nodes --show-labels
```
결과는 아래와 같다.
```
NAME STATUS ROLES AGE VERSION LABELS
worker0 Ready <none> 1d v1.13.0 ...,disktype=ssd,kubernetes.io/hostname=worker0
worker1 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker1
worker2 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker2
```
위의 결과에서, `worker0` 노드에 `disktype=ssd` 레이블이 있는 것을
확인할 수 있다.
## 필수적인 노드 어피니티를 사용해 파드 스케줄하기
이 매니페스트는 `disktype: ssd` 라는 `requiredDuringSchedulingIgnoredDuringExecution` 노드 어피니티를 가진 파드를 설명한다.
파드가 `disktype=ssd` 레이블이 있는 노드에만 스케줄될 것이라는 것을 의미한다.
{{< codenew file="pods/pod-nginx-required-affinity.yaml" >}}
1. 매니페스트를 적용하여 선택한 노드에 스케줄된 파드를
생성한다.
```shell
kubectl apply -f https://k8s.io/examples/pods/pod-nginx-required-affinity.yaml
```
1. 파드가 선택한 노드에서 실행 중인지 확인하자.
```shell
kubectl get pods --output=wide
```
결과는 아래와 같다.
```
NAME READY STATUS RESTARTS AGE IP NODE
nginx 1/1 Running 0 13s 10.200.0.4 worker0
```
## 선호하는 노드 어피니티를 사용해 파드 스케줄하기
이 매니페스트는 `disktype: ssd` 라는 `preferredDuringSchedulingIgnoredDuringExecution` 노드 어피니티를 가진 파드를 설명한다.
파드가 `disktype=ssd` 레이블이 있는 노드를 선호한다는 것을 의미한다.
{{< codenew file="pods/pod-nginx-preferred-affinity.yaml" >}}
1. 매니페스트를 적용하여 선택한 노드에 스케줄된 파드를
생성한다.
```shell
kubectl apply -f https://k8s.io/examples/pods/pod-nginx-preferred-affinity.yaml
```
1. 파드가 선택한 노드에서 실행 중인지 확인하자.
```shell
kubectl get pods --output=wide
```
결과는 아래와 같다.
```
NAME READY STATUS RESTARTS AGE IP NODE
nginx 1/1 Running 0 13s 10.200.0.4 worker0
```
{{% /capture %}}
{{% capture whatsnext %}}
[노드 어피니티](/ko/docs/concepts/configuration/assign-pod-node/#node-affinity)에
대해 더 알아보기.
{{% /capture %}}

View File

@ -0,0 +1,121 @@
---
content_template: templates/concept
title: 엘라스틱서치(Elasticsearch) 및 키바나(Kibana)를 사용한 로깅
---
{{% capture overview %}}
Google 컴퓨트 엔진(Compute Engine, GCE) 플랫폼에서, 기본 로깅 지원은
[스택드라이버(Stackdriver) 로깅](https://cloud.google.com/logging/)을 대상으로 한다. 이는
[스택드라이버 로깅으로 로깅하기](/docs/user-guide/logging/stackdriver)에 자세히 설명되어 있다.
이 문서에서는 GCE에서 운영할 때 스택드라이버 로깅의 대안으로,
[엘라스틱서치](https://www.elastic.co/products/elasticsearch)에 로그를 수집하고
[키바나](https://www.elastic.co/products/kibana)를 사용하여 볼 수 있도록
클러스터를 설정하는 방법에 대해 설명한다.
{{< note >}}
Google 쿠버네티스 엔진(Kubernetes Engine)에서 호스팅되는 쿠버네티스 클러스터에는 엘라스틱서치 및 키바나를 자동으로 배포할 수 없다. 수동으로 배포해야 한다.
{{< /note >}}
{{% /capture %}}
{{% capture body %}}
클러스터 로깅에 엘라스틱서치, 키바나를 사용하려면 kube-up.sh를 사용하여
클러스터를 생성할 때 아래와 같이 다음의 환경 변수를
설정해야 한다.
```shell
KUBE_LOGGING_DESTINATION=elasticsearch
```
또한 `KUBE_ENABLE_NODE_LOGGING=true`(GCE 플랫폼의 기본값)인지 확인해야 한다.
이제, 클러스터를 만들 때, 각 노드에서 실행되는 Fluentd 로그 수집 데몬이
엘라스틱서치를 대상으로 한다는 메시지가 나타난다.
```shell
cluster/kube-up.sh
```
```
...
Project: kubernetes-satnam
Zone: us-central1-b
... calling kube-up
Project: kubernetes-satnam
Zone: us-central1-b
+++ Staging server tars to Google Storage: gs://kubernetes-staging-e6d0e81793/devel
+++ kubernetes-server-linux-amd64.tar.gz uploaded (sha1 = 6987c098277871b6d69623141276924ab687f89d)
+++ kubernetes-salt.tar.gz uploaded (sha1 = bdfc83ed6b60fa9e3bff9004b542cfc643464cd0)
Looking for already existing resources
Starting master and configuring firewalls
Created [https://www.googleapis.com/compute/v1/projects/kubernetes-satnam/zones/us-central1-b/disks/kubernetes-master-pd].
NAME ZONE SIZE_GB TYPE STATUS
kubernetes-master-pd us-central1-b 20 pd-ssd READY
Created [https://www.googleapis.com/compute/v1/projects/kubernetes-satnam/regions/us-central1/addresses/kubernetes-master-ip].
+++ Logging using Fluentd to elasticsearch
```
노드별 Fluentd 파드, 엘라스틱서치 파드 및 키바나 파드는
클러스터가 활성화된 직후 kube-system 네임스페이스에서 모두 실행되어야
한다.
```shell
kubectl get pods --namespace=kube-system
```
```
NAME READY STATUS RESTARTS AGE
elasticsearch-logging-v1-78nog 1/1 Running 0 2h
elasticsearch-logging-v1-nj2nb 1/1 Running 0 2h
fluentd-elasticsearch-kubernetes-node-5oq0 1/1 Running 0 2h
fluentd-elasticsearch-kubernetes-node-6896 1/1 Running 0 2h
fluentd-elasticsearch-kubernetes-node-l1ds 1/1 Running 0 2h
fluentd-elasticsearch-kubernetes-node-lz9j 1/1 Running 0 2h
kibana-logging-v1-bhpo8 1/1 Running 0 2h
kube-dns-v3-7r1l9 3/3 Running 0 2h
monitoring-heapster-v4-yl332 1/1 Running 1 2h
monitoring-influx-grafana-v1-o79xf 2/2 Running 0 2h
```
`fluentd-elasticsearch` 파드는 각 노드에서 로그를 수집하여
`elasticsearch-logging` 파드로 전송한다. 이 로그는 `elasticsearch-logging` 이라는
[서비스](/ko/docs/concepts/services-networking/service/)의 일부이다. 이
엘라스틱서치 파드는 로그를 저장하고 REST API를 통해 노출한다.
`kibana-logging` 파드는 엘라스틱서치에 저장된 로그를 읽기 위한 웹 UI를
제공하며, `kibana-logging` 이라는 서비스의 일부이다.
엘라스틱서치 및 키바나 서비스는 모두 `kube-system` 네임스페이스에
있으며 공개적으로 접근 가능한 IP 주소를 통해 직접 노출되지 않는다. 이를 위해,
[클러스터에서 실행 중인 서비스 접근](/ko/docs/tasks/access-application-cluster/access-cluster/#클러스터에서-실행되는-서비스로-액세스)에 대한 지침을 참고한다.
브라우저에서 `elasticsearch-logging` 서비스에 접근하려고 하면,
다음과 같은 상태 페이지가 표시된다.
![엘라스틱서치 상태](/images/docs/es-browser.png)
원할 경우, 이제 엘라스틱서치 쿼리를 브라우저에 직접 입력할 수
있다. 수행 방법에 대한 자세한 내용은 [엘라스틱서치의 문서](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-uri-request.html)를
참조한다.
또는, 키바나를 사용하여 클러스터의 로그를 볼 수도 있다(다시
[클러스터에서 실행되는 서비스에 접근하기 위한 지침](/ko/docs/tasks/access-application-cluster/access-cluster/#클러스터에서-실행되는-서비스로-액세스)을 참고).
키바나 URL을 처음 방문하면 수집된 로그 보기를
구성하도록 요청하는 페이지가 표시된다. 시계열 값에
대한 옵션을 선택하고 `@timestamp` 를 선택한다. 다음 페이지에서
`Discover` 탭을 선택하면 수집된 로그를 볼 수 있다.
로그를 정기적으로 새로 고치려면 새로 고침 간격을 5초로
설정할 수 있다.
키바나 뷰어에서 수집된 로그의 일반적인 보기는 다음과 같다.
![키바나 로그](/images/docs/kibana-logs.png)
{{% /capture %}}
{{% capture whatsnext %}}
키바나는 로그를 탐색하기 위한 모든 종류의 강력한 옵션을 제공한다! 이를 파헤치는 방법에 대한
아이디어는 [키바나의 문서](https://www.elastic.co/guide/en/kibana/current/discover.html)를 확인한다.
{{% /capture %}}

View File

@ -0,0 +1,219 @@
---
content_template: templates/concept
title: GPU 스케줄링
---
{{% capture overview %}}
{{< feature-state state="beta" for_k8s_version="1.10" >}}
쿠버네티스는 AMD 및 NVIDIA GPU(그래픽 프로세싱 유닛)를 노드들에 걸쳐 관리하기 위한 **실험적인**
지원을 포함한다.
이 페이지는 다른 쿠버네티스 버전 간에 걸쳐 사용자가 GPU들을 소비할 수 있는 방법과
현재의 제약 사항을 설명한다.
{{% /capture %}}
{{% capture body %}}
## 디바이스 플러그인 사용하기
쿠버네티스는 {{< glossary_tooltip text="디바이스 플러그인" term_id="device-plugin" >}}을 구현하여
파드가 GPU와 같이 특별한 하드웨어 기능에 접근할 수 있게 한다.
관리자는 해당하는 하드웨어 벤더의 GPU 드라이버를 노드에
설치해야 하며, GPU 벤더가 제공하는 디바이스 플러그인을
실행해야 한다.
* [AMD](#amd-gpu-디바이스-플러그인-배치하기)
* [NVIDIA](#nvidia-gpu-디바이스-플러그인-배치하기)
위의 조건이 만족되면, 쿠버네티스는 `amd.com/gpu` 또는
`nvidia.com/gpu` 를 스케줄 가능한 리소스로써 노출시킨다.
사용자는 이 GPU들을 `cpu``memory` 를 요청하는 방식과 동일하게
`<vendor>.com/gpu` 를 요청함으로써 컨테이너를 통해 소비할 수 있다.
그러나 GPU를 사용할 때는 리소스 요구 사항을 명시하는 방식에 약간의
제약이 있다.
- GPU는 `limits` 섹션에서만 명시되는 것을 가정한다. 그 의미는 다음과 같다.
* 쿠버네티스는 limits를 requests의 기본 값으로 사용하게 되므로
사용자는 GPU `limits` 를 명시할 때 `requests` 명시하지 않아도 된다.
* 사용자는 `limits``requests` 를 모두 명시할 수 있지만, 두 값은
동일해야 한다.
* 사용자는 `limits` 명시 없이는 GPU `requests` 를 명시할 수 없다.
- 컨테이너들(그리고 파드들)은 GPU를 공유하지 않는다. GPU에 대한 초과 할당(overcommitting)은 제공되지 않는다.
- 각 컨테이너는 하나 이상의 GPU를 요청할 수 있다. GPU의 일부(fraction)를 요청하는 것은
불가능하다.
다음은 한 예제를 보여준다.
```yaml
apiVersion: v1
kind: Pod
metadata:
name: cuda-vector-add
spec:
restartPolicy: OnFailure
containers:
- name: cuda-vector-add
# https://github.com/kubernetes/kubernetes/blob/v1.7.11/test/images/nvidia-cuda/Dockerfile
image: "k8s.gcr.io/cuda-vector-add:v0.1"
resources:
limits:
nvidia.com/gpu: 1 # GPU 1개 요청하기
```
### AMD GPU 디바이스 플러그인 배치하기
[공식 AMD GPU 디바이스 플러그인](https://github.com/RadeonOpenCompute/k8s-device-plugin)에는
다음의 요구 사항이 있다.
- 쿠버네티스 노드들에는 AMD GPU 리눅스 드라이버가 미리 설치되어 있어야 한다.
클러스터가 실행 중이고 위의 요구 사항이 만족된 후, AMD 디바이스 플러그인을 배치하기 위해서는
아래 명령어를 실행한다.
```shell
kubectl create -f https://raw.githubusercontent.com/RadeonOpenCompute/k8s-device-plugin/v1.10/k8s-ds-amdgpu-dp.yaml
```
[RadeonOpenCompute/k8s-device-plugin](https://github.com/RadeonOpenCompute/k8s-device-plugin)에 이슈를 로깅하여
해당 서드 파티 디바이스 플러그인에 대한 이슈를 리포트할 수 있다.
### NVIDIA GPU 디바이스 플러그인 배치하기
현재는 NVIDIA GPU에 대한 두 개의 디바이스 플러그인 구현체가 있다.
#### 공식 NVIDIA GPU 디바이스 플러그인
[공식 NVIDIA GPU 디바이스 플러그인](https://github.com/NVIDIA/k8s-device-plugin)은
다음의 요구 사항을 가진다.
- 쿠버네티스 노드에는 NVIDIA 드라이버가 미리 설치되어 있어야 한다.
- 쿠버네티스 노드에는 [nvidia-docker 2.0](https://github.com/NVIDIA/nvidia-docker)이 미리 설치되어 있어야 한다.
- Kubelet은 자신의 컨테이너 런타임으로 도커를 사용해야 한다.
- 도커는 runc 대신 `nvidia-container-runtime` 이 [기본 런타임](https://github.com/NVIDIA/k8s-device-plugin#preparing-your-gpu-nodes)으로
설정되어야 한다.
- NVIDIA 드라이버의 버전은 조건 ~= 361.93 을 만족해야 한다.
클러스터가 실행 중이고 위의 요구 사항이 만족된 후, NVIDIA 디바이스 플러그인을 배치하기 위해서는
아래 명령어를 실행한다.
```shell
kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/1.0.0-beta4/nvidia-device-plugin.yml
```
[NVIDIA/k8s-device-plugin](https://github.com/NVIDIA/k8s-device-plugin)에 이슈를 로깅하여
해당 서드 파티 디바이스 플러그인에 대한 이슈를 리포트할 수 있다.
#### GCE에서 사용되는 NVIDIA GPU 디바이스 플러그인
[GCE에서 사용되는 NVIDIA GPU 디바이스 플러그인](https://github.com/GoogleCloudPlatform/container-engine-accelerators/tree/master/cmd/nvidia_gpu)은
nvidia-docker의 사용이 필수가 아니며 컨테이너 런타임 인터페이스(CRI)에
호환되는 다른 컨테이너 런타임을 사용할 수 있다. 해당 사항은
[컨테이너에 최적화된 OS](https://cloud.google.com/container-optimized-os/)에서 테스트되었고,
우분투 1.9 이후 버전에 대한 실험적인 코드를 가지고 있다.
사용자는 다음 커맨드를 사용하여 NVIDIA 드라이버와 디바이스 플러그인을 설치할 수 있다.
```shell
# 컨테이너에 최적회된 OS에 NVIDIA 드라이버 설치:
kubectl create -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/stable/daemonset.yaml
# 우분투에 NVIDIA 드라이버 설치(실험적):
kubectl create -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/stable/nvidia-driver-installer/ubuntu/daemonset.yaml
# 디바이스 플러그인 설치:
kubectl create -f https://raw.githubusercontent.com/kubernetes/kubernetes/release-1.14/cluster/addons/device-plugins/nvidia-gpu/daemonset.yaml
```
[GoogleCloudPlatform/container-engine-accelerators](https://github.com/GoogleCloudPlatform/container-engine-accelerators)에 이슈를 로깅하여
해당 서드 파티 디바이스 플러그인에 대한 이슈를 리포트할 수 있다.
Google은 GKE에서 NVIDIA GPU 사용에 대한 자체 [설명서](https://cloud.google.com/kubernetes-engine/docs/how-to/gpus)를 게재하고 있다.
## 다른 타입의 GPU들을 포함하는 클러스터
만약 클러스터의 노드들이 서로 다른 타입의 GPU를 가지고 있다면, 사용자는
파드를 적합한 노드에 스케줄 하기 위해서
[노드 레이블과 노드 셀렉터](/docs/tasks/configure-pod-container/assign-pods-nodes/)를 사용할 수 있다.
예를 들면,
```shell
# 노드가 가진 가속기 타입에 따라 레이블을 단다.
kubectl label nodes <node-with-k80> accelerator=nvidia-tesla-k80
kubectl label nodes <node-with-p100> accelerator=nvidia-tesla-p100
```
## 노드 레이블링 자동화 {#node-labeller}
만약 AMD GPU 디바이스를 사용하고 있다면,
[노드 레이블러](https://github.com/RadeonOpenCompute/k8s-device-plugin/tree/master/cmd/k8s-node-labeller)를 배치할 수 있다.
노드 레이블러는 GPU 디바이스의 속성에 따라서 노드에 자동으로 레이블을 달아 주는
{{< glossary_tooltip text="컨트롤러" term_id="controller" >}}이다.
현재 이 컨트롤러는 다음의 속성에 대해 레이블을 추가할 수 있다.
* 디바이스 ID (-device-id)
* VRAM 크기 (-vram)
* SIMD 개수 (-simd-count)
* 계산 유닛 개수 (-cu-count)
* 펌웨어 및 기능 버전 (-firmware)
* GPU 계열, 두 개 문자 형태의 축약어 (-family)
* SI - Southern Islands
* CI - Sea Islands
* KV - Kaveri
* VI - Volcanic Islands
* CZ - Carrizo
* AI - Arctic Islands
* RV - Raven
```shell
kubectl describe node cluster-node-23
```
```
Name: cluster-node-23
Roles: <none>
Labels: beta.amd.com/gpu.cu-count.64=1
beta.amd.com/gpu.device-id.6860=1
beta.amd.com/gpu.family.AI=1
beta.amd.com/gpu.simd-count.256=1
beta.amd.com/gpu.vram.16G=1
beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/hostname=cluster-node-23
Annotations: kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
node.alpha.kubernetes.io/ttl: 0
```
노드 레이블러가 사용된 경우, GPU 타입을 파드 스펙에 명시할 수 있다.
```yaml
apiVersion: v1
kind: Pod
metadata:
name: cuda-vector-add
spec:
restartPolicy: OnFailure
containers:
- name: cuda-vector-add
# https://github.com/kubernetes/kubernetes/blob/v1.7.11/test/images/nvidia-cuda/Dockerfile
image: "k8s.gcr.io/cuda-vector-add:v0.1"
resources:
limits:
nvidia.com/gpu: 1
nodeSelector:
accelerator: nvidia-tesla-p100 # 또는 nvidia-tesla-k80 등.
```
이것은 파드가 사용자가 지정한 GPU 타입을 가진 노드에 스케줄 되도록
만든다.
{{% /capture %}}

View File

@ -0,0 +1,4 @@
---
title: "네트워크"
weight: 160
---

View File

@ -0,0 +1,158 @@
---
min-kubernetes-server-version: v1.16
title: IPv4/IPv6 이중 스택 검증
content_template: templates/task
---
{{% capture overview %}}
이 문서는 IPv4/IPv6 이중 스택이 활성화된 쿠버네티스 클러스터들을 어떻게 검증하는지 설명한다.
{{% /capture %}}
{{% capture prerequisites %}}
* 이중 스택 네트워킹을 위한 제공자 지원 (클라우드 제공자 또는 기타 제공자들은 라우팅 가능한 IPv4/IPv6 네트워크 인터페이스를 제공하는 쿠버네티스 노드들을 제공해야 한다.)
* 이중 스택을 지원하는 [네트워크 플러그인](/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/) (예. Kubenet 또는 Calico)
* IPVS 모드로 구동되는 Kube-proxy
* [이중 스택 활성화](/ko/docs/concepts/services-networking/dual-stack/) 클러스터
{{< version-check >}}
{{% /capture %}}
{{% capture steps %}}
## 어드레싱 검증
### 노드 어드레싱 검증
각각의 이중 스택 노드는 단일 IPv4 블록 및 단일 IPv6 블록을 할당받아야 한다. IPv4/IPv6 파드 주소 범위를 다음 커맨드를 실행하여 검증한다. 샘플 노드 이름을 클러스터 내 검증된 이중 스택 노드로 대체한다. 본 예제에서, 노드 이름은 `k8s-linuxpool1-34450317-0` 이다.
```shell
kubectl get nodes k8s-linuxpool1-34450317-0 -o go-template --template='{{range .spec.podCIDRs}}{{printf "%s\n" .}}{{end}}'
```
```
10.244.1.0/24
a00:100::/24
```
단일 IPv4 블록과 단일 IPv6 블록이 할당되어야 한다.
노드가 IPv4 및 IPv6 인터페이스를 가지고 있는지 검증한다. (노드 이름을 클러스터의 검증된 노드로 대체한다. 본 예제에서 노드 이름은 k8s-linuxpool1-34450317-0) 이다.
```shell
kubectl get nodes k8s-linuxpool1-34450317-0 -o go-template --template='{{range .status.addresses}}{{printf "%s: %s \n" .type .address}}{{end}}'
```
```
Hostname: k8s-linuxpool1-34450317-0
InternalIP: 10.240.0.5
InternalIP: 2001:1234:5678:9abc::5
```
### 파드 어드레싱 검증
파드가 IPv4 및 IPv6 주소를 할당받았는지 검증한다. (파드 이름을 클러스터에서 검증된 파드로 대체한다. 본 예제에서 파드 이름은 pod01 이다.)
```shell
kubectl get pods pod01 -o go-template --template='{{range .status.podIPs}}{{printf "%s \n" .ip}}{{end}}'
```
```
10.244.1.4
a00:100::4
```
`status.podIPs` fieldPath를 통한 다운워드(downward) API로 파드 IP들을 검증할 수도 있다. 다음 스니펫은 컨테이너 내 `MY_POD_IPS` 라는 환경 변수를 통해 파드 IP들을 어떻게 노출시킬 수 있는지 보여준다.
```
env:
- name: MY_POD_IPS
valueFrom:
fieldRef:
fieldPath: status.podIPs
```
다음 커맨드는 컨테이너 내 `MY_POD_IPS` 환경 변수의 값을 출력한다. 해당 값은 파드의 IPv4 및 IPv6 주소를 나타내는 쉼표로 구분된 목록이다.
```shell
kubectl exec -it pod01 -- set | grep MY_POD_IPS
```
```
MY_POD_IPS=10.244.1.4,a00:100::4
```
파드의 IP 주소는 또한 컨테이너 내 `/etc/hosts` 에 적힐 것이다. 다음 커맨드는 이중 스택 파드의 `/etc/hosts` 에 cat을 실행시킨다. 출력 값을 통해 파드의 IPv4 및 IPv6 주소 모두 검증할 수 있다.
```shell
kubectl exec -it pod01 -- cat /etc/hosts
```
```
# Kubernetes-managed hosts file.
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
fe00::0 ip6-mcastprefix
fe00::1 ip6-allnodes
fe00::2 ip6-allrouters
10.244.1.4 pod01
a00:100::4 pod01
```
## 서비스 검증
`ipFamily` 필드 세트 없이 다음 서비스를 생성한다. 필드가 구성되지 않았으면 서비스는 kube-controller-manager의 `--service-cluster-ip-range` 플래그를 통해 설정된 범위 내 첫 IP를 할당받는다.
{{< codenew file="service/networking/dual-stack-default-svc.yaml" >}}
해당 서비스의 YAML을 보면, 서비스의 `ipFamily` 필드가 kube-controller-manager의 `--service-cluster-ip-range` 플래그를 통해 첫 번째 설정된 범위의 주소 패밀리를 반영하도록 설정되어 있음을 확인할 수 있다.
```shell
kubectl get svc my-service -o yaml
```
```yaml
apiVersion: v1
kind: Service
metadata:
creationTimestamp: "2019-09-03T20:45:13Z"
labels:
app: MyApp
name: my-service
namespace: default
resourceVersion: "485836"
selfLink: /api/v1/namespaces/default/services/my-service
uid: b6fa83ef-fe7e-47a3-96a1-ac212fa5b030
spec:
clusterIP: 10.0.29.179
ipFamily: IPv4
ports:
- port: 80
protocol: TCP
targetPort: 9376
selector:
app: MyApp
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
```
`ipFamily` 필드를 `IPv6`로 설정하여 다음의 서비스를 생성한다.
{{< codenew file="service/networking/dual-stack-ipv6-svc.yaml" >}}
서비스가 IPv6 주소 블록에서 클러스터 IP 주소를 할당받는 것을 검증한다. 그리고 나서 IP 및 포트로 서비스 접근이 가능한지 검증할 수 있다.
```
kubectl get svc -l app=MyApp
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-service ClusterIP fe80:20d::d06b <none> 80/TCP 9s
```
### 이중 스택 로드 밸런싱 서비스 생성
만약 클라우드 제공자가 IPv6 기반 외부 로드 밸런서 구성을 지원한다면 `ipFamily` 필드를 `IPv6`로, `type` 필드를 `LoadBalancer` 로 설정하여 다음의 서비스를 생성한다.
{{< codenew file="service/networking/dual-stack-ipv6-lb-svc.yaml" >}}
서비스가 IPv6 주소 블록에서 `CLUSTER-IP` 주소 및 `EXTERNAL-IP` 주소를 할당받는지 검증한다. 그리고 나서 IP 및 포트로 서비스 접근이 가능한지 검증할 수 있다.
```
kubectl get svc -l app=MyApp
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-service ClusterIP fe80:20d::d06b 2001:db8:f100:4002::9d37:c0d7 80:31868/TCP 30s
```
{{% /capture %}}

View File

@ -199,8 +199,7 @@ Horizontal Pod Autoscaler는 모든 API 리소스와 마찬가지로 `kubectl`
## 롤링 업데이트 중 오토스케일링
현재 쿠버네티스에서는 레플리케이션 컨트롤러를 직접 관리하거나,
기본 레플리카 셋를 관리하는 디플로이먼트 오브젝트를 사용하여 [롤링 업데이트](/docs/tasks/run-application/rolling-update-replication-controller/)를 수행 할 수 있다.
현재 쿠버네티스에서는 기본 레플리카 셋를 관리하는 디플로이먼트 오브젝트를 사용하여 롤링 업데이트를 수행할 수 있다.
Horizontal Pod Autoscaler는 후자의 방법을 지원한다. Horizontal Pod Autoscaler는 디플로이먼트 오브젝트에 바인딩되고,
디플로이먼트 오브젝트를 위한 크기를 설정하며, 디플로이먼트는 기본 레플리카 셋의 크기를 결정한다.

View File

@ -31,7 +31,7 @@ weight: 10
일단 쿠버네티스 클러스터를 구동시키면, 그 위에 컨테이너화된 애플리케이션을 배포할 수 있다.
그러기 위해서, 쿠버네티스 <b>디플로이먼트</b> 설정을 만들어야 한다. 디플로이먼트는 쿠버네티스가
애플리케이션의 인스턴스를 어떻게 생성하고 업데이트해야 하는지를 지시한다. 디플로이먼트가 만들어지면,
쿠버네티스 마스터가 해당 애플리케이션 인스턴스를 클러스터의 개별 노드에 스케줄한다.
쿠버네티스 마스터가 해당 디플로이먼트에 포함된 애플리케이션 인스턴스가 클러스터의 개별 노드에서 실행되도록 스케줄한다.
</p>
<p>애플리케이션 인스턴스가 생성되면, 쿠버네티스 디플로이먼트 컨트롤러는 지속적으로 이들 인스턴스를

View File

@ -18,7 +18,7 @@ weight: 10
* [파드](/docs/user-guide/pods/single-container/)
* [클러스터 DNS(Cluster DNS)](/ko/docs/concepts/services-networking/dns-pod-service/)
* [헤드리스 서비스(Headless Services)](/ko/docs/concepts/services-networking/service/#헤드리스-headless-서비스)
* [퍼시스턴트볼륨(PersistentVolumes)](/docs/concepts/storage/persistent-volumes/)
* [퍼시스턴트볼륨(PersistentVolumes)](/ko/docs/concepts/storage/persistent-volumes/)
* [퍼시턴트볼륨 프로비저닝](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/persistent-volume-provisioning/)
* [스테이트풀셋](/ko/docs/concepts/workloads/controllers/statefulset/)
* [kubectl CLI](/docs/user-guide/kubectl/)
@ -257,7 +257,7 @@ NAME STATUS VOLUME CAPACITY ACCE
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개의 [퍼시스턴트볼륨](/ko/docs/concepts/storage/persistent-volumes/)에
묶인 2개의 퍼시스턴트볼륨클레임을 생성했다. 본 튜토리얼에서 사용되는 클러스터는 퍼시스턴트볼륨을 동적으로
프로비저닝하도록 설정되었으므로 생성된 퍼시스턴트볼륨도 자동으로 묶인다.

View File

@ -6,34 +6,31 @@ weight: 30
---
{{% capture overview %}}
이 튜토리얼은 네이티브 클라우드 [카산드라](http://cassandra.apache.org/)를 쿠버네티스에서 배포하는 방법을 소개한다. 이 예제에서 커스텀 카산드라 *시드 제공자(SeedProvider)* 는 카산드라가 클러스터에 조인한 새 카산드라 노드를 발견할 수 있게 한다.
이 튜토리얼은 쿠버네티스에서 [아파치 카산드라](http://cassandra.apache.org/)를 실행하는 방법을 소개한다. 데이터베이스인 카산드라는 데이터 내구성을 제공하기 위해 퍼시스턴트 스토리지가 필요하다(애플리케이션 _상태_). 이 예제에서 사용자 지정 카산드라 시드 공급자는 카산드라가 클러스터에 가입할 때 카산드라가 인스턴스를 검색할 수 있도록 한다.
*스테이트풀셋* 은 상태있는 애플리케이션을 클러스터 환경 쉽게 배포할 수 있게 한다. 이 튜토리얼에서 이용할 기능의 자세한 정보는 [*스테이트풀셋*](/ko/docs/concepts/workloads/controllers/statefulset/) 문서를 참조하자.
*스테이트풀셋* 은 상태있는 애플리케이션을 쿠버네티스 클러스터에 쉽게 배포할 수 있게 한다. 이 튜토리얼에서 이용할 기능의 자세한 정보는 [스테이트풀셋](/ko/docs/concepts/workloads/controllers/statefulset/)을 참조한다.
**도커에서 카산드라**
{{< note >}}
카산드라와 쿠버네티스는 클러스터 맴버라는 의미로 _노드_ 라는 용어를 사용한다. 이
튜토리얼에서 스테이트풀셋에 속하는 파드는 카산드라 노드이며 카산드라
클로스터의 맴버(_링_ 이라 함)이다. 해당 파드가 쿠버네티스 클러스터에서 실행될 때,
쿠버네티스 컨트롤 플레인은 해당 파드를 쿠버네티스
{{< glossary_tooltip text="노드" term_id="node" >}}에 스케줄 한다.
이 튜토리얼의 *파드* 는 구글의 [컨테이너 레지스트리](https://cloud.google.com/container-registry/docs/)에
[`gcr.io/google-samples/cassandra:v13`](https://github.com/kubernetes/examples/blob/master/cassandra/image/Dockerfile) 이미지를 이용한다.
이 도커 이미지는 [debian-base](https://github.com/kubernetes/kubernetes/tree/master/build/debian-base)에
기반하였고 OpenJDK 8을 포함한다.
이 이미지는 아파치 데비안 리포의 표준 카산드라 설치본을 포함한다.
환경변수를 이용하여 `cassandra.yaml`에 삽입된 값을 바꿀 수 있다.
| 환경 변수 | 기본값 |
| ------------- |:-------------: |
| `CASSANDRA_CLUSTER_NAME` | `'Test Cluster'` |
| `CASSANDRA_NUM_TOKENS` | `32` |
| `CASSANDRA_RPC_ADDRESS` | `0.0.0.0` |
카산드라 노드가 시작되면 _시드 목록_ 을 사용해서 링에 있는 다른 노드 검색을 위한
위한 부트스트랩을 한다.
이 튜토리얼에는 데이터베이스가 쿠버네티스 클러스터 내부에 나타날 때 새로운 카산드라
파드를 검색할 수 있는 사용자 지정 카산드라 시드 공급자를 배포한다.
{{< /note >}}
{{% /capture %}}
{{% capture objectives %}}
* 카산드라 헤드리스 [*서비스*](/ko/docs/concepts/services-networking/service/)를 생성하고 검증한다.
* [스테이트풀셋](/ko/docs/concepts/workloads/controllers/statefulset/)을 이용하여 카산드라 링을 생성한다.
* [스테이트풀셋](/ko/docs/concepts/workloads/controllers/statefulset/)을 검증한다.
* [스테이트풀셋](/ko/docs/concepts/workloads/controllers/statefulset/)을 수정한다.
* [스테이트풀셋](/ko/docs/concepts/workloads/controllers/statefulset/)과 포함된 [파드](/ko/docs/concepts/workloads/pods/pod/)를 삭제한다.
* 카산드라 헤드리스 {{< glossary_tooltip text="Service" term_id="service" >}}를 생성하고 검증한다.
* {{< glossary_tooltip term_id="StatefulSet" >}}을 이용하여 카산드라 링을 생성한다.
* 스테이트풀셋을 검증한다.
* 스테이트풀셋을 수정한다.
* 스테이트풀셋과 포함된 {{< glossary_tooltip text="파드" term_id="pod" >}}를 삭제한다.
{{% /capture %}}
{{% capture prerequisites %}}
@ -53,7 +50,7 @@ weight: 30
### 추가적인 Minikube 설정 요령
{{< caution >}}
[Minikube](/docs/getting-started-guides/minikube/)는 1024MB 메모리와 1개 CPU가 기본 설정이다. 이 튜토리얼에서 Minikube를 기본 리소스 설정으로 실행하면 리소스 부족 오류가 발생한다. 이런 오류를 피하려면 Minikube를 다음 설정으로 실행하자.
[Minikube](/docs/getting-started-guides/minikube/)는 1024MiB 메모리와 1개 CPU가 기본 설정이다. 이 튜토리얼에서 Minikube를 기본 리소스 설정으로 실행하면 리소스 부족 오류가 발생한다. 이런 오류를 피하려면 Minikube를 다음 설정으로 실행하자.
```shell
minikube start --memory 5120 --cpus=4
@ -63,22 +60,22 @@ minikube start --memory 5120 --cpus=4
{{% /capture %}}
{{% capture lessoncontent %}}
## 카산드라 헤드리스 서비스 생성하기
## 카산드라를 위한 헤드리스 서비스 생성하기 {#creating-a-cassandra-headless-service}
쿠버네티스 [서비스](/ko/docs/concepts/services-networking/service/)는 동일 작업을 수행하는 [파드](/ko/docs/concepts/workloads/pods/pod/)의 집합을 기술한다.
쿠버네티스 에서 {{< glossary_tooltip text="서비스" term_id="service" >}}는 동일 작업을 수행하는 {{< glossary_tooltip text="파드" term_id="pod" >}}의 집합을 기술한다.
다음의 `서비스` 쿠버네티스 클러스터에서 카산드라 파드와 클라이언트 간에 DNS 찾아보기 용도로 사용한다.
다음의 서비스는 클러스터에서 카산드라 파드와 클라이언트 간에 DNS 찾아보기 용도로 사용한다.
{{< codenew file="application/cassandra/cassandra-service.yaml" >}}
1. 다운로드 받은 매니페스트 파일 디렉터리에 터미널 윈도우를 열자.
1. `cassandra-service.yaml` 파일에서 카산드라 스테이트풀셋 노드를 모두 추적하는 서비스를 생성한다.
`cassandra-service.yaml` 파일에서 카산드라 스테이트풀셋 노드를 모두 추적하는 서비스를 생성한다.
```shell
kubectl apply -f https://k8s.io/examples/application/cassandra/cassandra-service.yaml
```
```shell
kubectl apply -f https://k8s.io/examples/application/cassandra/cassandra-service.yaml
```
### 검증하기 (선택)
### 검증하기(선택) {#validating}
카산드라 서비스 살펴보기
@ -105,12 +102,21 @@ cassandra ClusterIP None <none> 9042/TCP 45s
{{< codenew file="application/cassandra/cassandra-statefulset.yaml" >}}
1. 필요하면 스테이트풀셋 갱신
1. `cassandra-statefulset.yaml` 파일로 카산드라 스테이트풀셋 생성
`cassandra-statefulset.yaml` 파일로 카산드라 스테이트풀셋 생성
```shell
# cassandra-statefulset.yaml을 수정하지 않은 경우에 이것을 사용한다.
kubectl apply -f https://k8s.io/examples/application/cassandra/cassandra-statefulset.yaml
```
클러스터에 맞게 `cassandra-statefulset.yaml` 를 수정해야 하는 경우 다음을 다운로드 한 다음
수정된 버전을 저장한 폴더에서 해당 매니페스트를 적용한다.
https://k8s.io/examples/application/cassandra/cassandra-statefulset.yaml
```shell
# cassandra-statefulset.yaml을 로컬에서 수정한 경우에 사용한다.
kubectl apply -f cassandra-statefulset.yaml
```
```shell
kubectl apply -f https://k8s.io/examples/application/cassandra/cassandra-statefulset.yaml
```
## 카산드라 스테이트풀셋 검증하기
@ -120,7 +126,7 @@ cassandra ClusterIP None <none> 9042/TCP 45s
kubectl get statefulset cassandra
```
응답은 다음과 다.
응답은 다음과 유사하다.
```
NAME DESIRED CURRENT AGE
@ -135,7 +141,7 @@ cassandra ClusterIP None <none> 9042/TCP 45s
kubectl get pods -l="app=cassandra"
```
응답은 다음과 다.
응답은 다음과 유사하다.
```shell
NAME READY STATUS RESTARTS AGE
@ -143,7 +149,8 @@ cassandra ClusterIP None <none> 9042/TCP 45s
cassandra-1 0/1 ContainerCreating 0 8s
```
모든 3개 파드가 배포되기까지 몇 분이 소요될 수 있다. 배포 후에는 같은 명령은 다음같이 응답한다.
모든 3개 파드가 배포되기까지 몇 분이 소요될 수 있다. 배포 후, 동일 명령은 다음과 유사하게
응답한다.
```
NAME READY STATUS RESTARTS AGE
@ -152,7 +159,8 @@ cassandra ClusterIP None <none> 9042/TCP 45s
cassandra-2 1/1 Running 0 8m
```
3. 링의 상태를 보여주는 카산드라 [nodetool](https://wiki.apache.org/cassandra/NodeTool)을 실행하자.
3. 첫 번째 파드 내부에 링의 상태를 보여주는 카산드라
[nodetool](https://cwiki.apache.org/confluence/display/CASSANDRA2/NodeTool)을 실행하자.
```shell
kubectl exec -it cassandra-0 -- nodetool status
@ -181,14 +189,14 @@ cassandra ClusterIP None <none> 9042/TCP 45s
kubectl edit statefulset cassandra
```
이 명령은 터미널에서 편집기를 연다. 변경해야할 행은 `replicas` 필드이다. 다음 예제는 `StatefulSet` 파일에서 발췌했다.
이 명령은 터미널에서 편집기를 연다. 변경해야할 행은 `replicas` 필드이다. 다음 예제는 스테이트풀셋 파일에서 발췌했다.
```yaml
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
apiVersion: apps/v1
kind: StatefulSet
metadata:
creationTimestamp: 2016-08-13T18:40:58Z
@ -205,7 +213,7 @@ cassandra ClusterIP None <none> 9042/TCP 45s
1. 레플리카 개수를 4로 바꾸고, 매니페스트를 저장한다.
The `StatefulSet` now contains 4 Pods.
스테이트풀셋은 4개의 파드를 실행하기 위해 스케일 한다.
1. 검증하기 위해 카산드라 스테이트풀셋을 살펴보자
@ -213,7 +221,7 @@ cassandra ClusterIP None <none> 9042/TCP 45s
kubectl get statefulset cassandra
```
결과는 다음과 다.
결과는 다음과 유사하다.
```
NAME DESIRED CURRENT AGE
@ -229,22 +237,39 @@ cassandra ClusterIP None <none> 9042/TCP 45s
스토리지 클래스와 리클레임 정책에 따라 *퍼시스턴스볼륨클레임* 을 삭제하면 그와 연관된 볼륨도 삭제될 수 있다. 볼륨 요청이 삭제되어도 데이터를 접근할 수 있다고 절대로 가정하지 말자.
{{< /warning >}}
1. 다음 명령어(한 줄로 연결된)를 실행하여 카산드라 `스테이트풀셋`을 모두 제거하자.
1. 다음 명령어(한 줄로 연결된)를 실행하여 카산드라 스테이트풀셋을 모두 제거하자.
```shell
grace=$(kubectl get po cassandra-0 -o=jsonpath='{.spec.terminationGracePeriodSeconds}') \
grace=$(kubectl get pod cassandra-0 -o=jsonpath='{.spec.terminationGracePeriodSeconds}') \
&& kubectl delete statefulset -l app=cassandra \
&& echo "Sleeping $grace" \
&& echo "Sleeping ${grace} seconds" 1>&2 \
&& sleep $grace \
&& kubectl delete pvc -l app=cassandra
&& kubectl delete persistentvolumeclaim -l app=cassandra
```
1. 다음 명령어를 실행하여 카산드라 서비스를 제거하자.
1. 다음 명령어를 실행하여 카산드라에 대해 설정한 서비스를 제거하자.
```shell
kubectl delete service -l app=cassandra
```
## 카산드라 컨테이너 환경 변수
이 튜토리얼의 *파드* 는 구글의 [컨테이너 레지스트리](https://cloud.google.com/container-registry/docs/)에
[`gcr.io/google-samples/cassandra:v13`](https://github.com/kubernetes/examples/blob/master/cassandra/image/Dockerfile) 이미지를 이용한다.
이 도커 이미지는 [debian-base](https://github.com/kubernetes/kubernetes/tree/master/build/debian-base)에
기반하였고 OpenJDK 8을 포함한다.
이 이미지는 아파치 데비안 리포의 표준 카산드라 설치본을 포함한다.
환경변수를 이용하여 `cassandra.yaml`에 삽입된 값을 바꿀 수 있다.
| 환경 변수 | 기본값 |
| ------------- |:-------------: |
| `CASSANDRA_CLUSTER_NAME` | `'Test Cluster'` |
| `CASSANDRA_NUM_TOKENS` | `32` |
| `CASSANDRA_RPC_ADDRESS` | `0.0.0.0` |
{{% /capture %}}
{{% capture whatsnext %}}
@ -254,4 +279,3 @@ cassandra ClusterIP None <none> 9042/TCP 45s
* 커스텀 [시드 제공자 설정](https://git.k8s.io/examples/cassandra/java/README.md)를 살펴본다.
{{% /capture %}}

View File

@ -12,7 +12,7 @@ card:
{{% capture overview %}}
이 튜토리얼은 WordPress 사이트와 MySQL 데이터베이스를 Minikube를 이용하여 어떻게 배포하는지 보여준다. 애플리케이션 둘 다 퍼시스턴트 볼륨과 퍼시스턴트볼륨클레임을 데이터를 저장하기 위해 사용한다.
[퍼시스턴트볼륨](/docs/concepts/storage/persistent-volumes/)(PV)는 관리자가 수동으로 프로비저닝한 클러스터나 쿠버네티스 [스토리지클래스](/docs/concepts/storage/storage-classes)를 이용해 동적으로 프로비저닝된 저장소의 일부이다. [퍼시스턴트볼륨클레임](/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims)(PVC)은 PV로 충족할 수 있는 사용자에 의한 스토리지 요청이다. 퍼시스턴트볼륨은 파드 라이프사이클과 독립적이며 재시작, 재스케줄링이나 파드를 삭제할 때에도 데이터를 보존한다.
[퍼시스턴트볼륨](/ko/docs/concepts/storage/persistent-volumes/)(PV)는 관리자가 수동으로 프로비저닝한 클러스터나 쿠버네티스 [스토리지클래스](/docs/concepts/storage/storage-classes)를 이용해 동적으로 프로비저닝된 저장소의 일부이다. [퍼시스턴트볼륨클레임](/ko/docs/concepts/storage/persistent-volumes/#퍼시스턴트볼륨클레임)(PVC)은 PV로 충족할 수 있는 사용자에 의한 스토리지 요청이다. 퍼시스턴트볼륨은 파드 라이프사이클과 독립적이며 재시작, 재스케줄링이나 파드를 삭제할 때에도 데이터를 보존한다.
{{< warning >}}
이 배포는 프로덕션 사용 예로는 적절하지 않은데 이는 단일 인스턴스의 WordPress와 MySQL을 이용했기 때문이다. 프로덕션이라면 [WordPress Helm Chart](https://github.com/kubernetes/charts/tree/master/stable/wordpress)로 배포하기를 고려해보자.

View File

@ -0,0 +1,25 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: fluentd-config
data:
fluentd.conf: |
<source>
type tail
format none
path /var/log/1.log
pos_file /var/log/1.log.pos
tag count.format1
</source>
<source>
type tail
format none
path /var/log/2.log
pos_file /var/log/2.log.pos
tag count.format2
</source>
<match **>
type google_cloud
</match>

View File

@ -0,0 +1,39 @@
apiVersion: v1
kind: Pod
metadata:
name: counter
spec:
containers:
- name: count
image: busybox
args:
- /bin/sh
- -c
- >
i=0;
while true;
do
echo "$i: $(date)" >> /var/log/1.log;
echo "$(date) INFO $i" >> /var/log/2.log;
i=$((i+1));
sleep 1;
done
volumeMounts:
- name: varlog
mountPath: /var/log
- name: count-agent
image: k8s.gcr.io/fluentd-gcp:1.30
env:
- name: FLUENTD_ARGS
value: -c /etc/fluentd-config/fluentd.conf
volumeMounts:
- name: varlog
mountPath: /var/log
- name: config-volume
mountPath: /etc/fluentd-config
volumes:
- name: varlog
emptyDir: {}
- name: config-volume
configMap:
name: fluentd-config

View File

@ -0,0 +1,38 @@
apiVersion: v1
kind: Pod
metadata:
name: counter
spec:
containers:
- name: count
image: busybox
args:
- /bin/sh
- -c
- >
i=0;
while true;
do
echo "$i: $(date)" >> /var/log/1.log;
echo "$(date) INFO $i" >> /var/log/2.log;
i=$((i+1));
sleep 1;
done
volumeMounts:
- name: varlog
mountPath: /var/log
- name: count-log-1
image: busybox
args: [/bin/sh, -c, 'tail -n+1 -f /var/log/1.log']
volumeMounts:
- name: varlog
mountPath: /var/log
- name: count-log-2
image: busybox
args: [/bin/sh, -c, 'tail -n+1 -f /var/log/2.log']
volumeMounts:
- name: varlog
mountPath: /var/log
volumes:
- name: varlog
emptyDir: {}

View File

@ -0,0 +1,26 @@
apiVersion: v1
kind: Pod
metadata:
name: counter
spec:
containers:
- name: count
image: busybox
args:
- /bin/sh
- -c
- >
i=0;
while true;
do
echo "$i: $(date)" >> /var/log/1.log;
echo "$(date) INFO $i" >> /var/log/2.log;
i=$((i+1));
sleep 1;
done
volumeMounts:
- name: varlog
mountPath: /var/log
volumes:
- name: varlog
emptyDir: {}

View File

@ -0,0 +1,34 @@
apiVersion: v1
kind: Service
metadata:
name: my-nginx-svc
labels:
app: nginx
spec:
type: LoadBalancer
ports:
- port: 80
selector:
app: nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80

View File

@ -0,0 +1,10 @@
apiVersion: v1
kind: Pod
metadata:
name: counter
spec:
containers:
- name: count
image: busybox
args: [/bin/sh, -c,
'i=0; while true; do echo "$i: $(date)"; i=$((i+1)); sleep 1; done']

View File

@ -0,0 +1,19 @@
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: disktype
operator: In
values:
- ssd
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent

View File

@ -0,0 +1,18 @@
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values:
- ssd
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent

View File

@ -0,0 +1,15 @@
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
tolerations:
- key: "example-key"
operator: "Exists"
effect: "NoSchedule"

View File

@ -0,0 +1,16 @@
apiVersion: v1
kind: Pod
metadata:
name: memory-demo-2
namespace: mem-example
spec:
containers:
- name: memory-demo-2-ctr
image: polinux/stress
resources:
requests:
memory: "50Mi"
limits:
memory: "100Mi"
command: ["stress"]
args: ["--vm", "1", "--vm-bytes", "250M", "--vm-hang", "1"]

View File

@ -0,0 +1,16 @@
apiVersion: v1
kind: Pod
metadata:
name: memory-demo-3
namespace: mem-example
spec:
containers:
- name: memory-demo-3-ctr
image: polinux/stress
resources:
limits:
memory: "1000Gi"
requests:
memory: "1000Gi"
command: ["stress"]
args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]

View File

@ -0,0 +1,16 @@
apiVersion: v1
kind: Pod
metadata:
name: memory-demo
namespace: mem-example
spec:
containers:
- name: memory-demo-ctr
image: polinux/stress
resources:
limits:
memory: "200Mi"
requests:
memory: "100Mi"
command: ["stress"]
args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]

View File

@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: my-service
labels:
app: MyApp
spec:
ipFamily: IPv6
type: LoadBalancer
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376

View File

@ -7,14 +7,22 @@ cid: training
class: training
---
<div class="padded blue-bg">
<div class="main-section two-thirds-centered white-text">
<center>
<h2>클라우드 네이티브 커리어를 구축하세요</h2>
<p>쿠버네티스는 클라우드 네이티브 무브먼트의 핵심입니다. 리눅스 재단이 제공하는 교육과 인증 프로그램을 통해 커리어에 투자하고, 쿠버네티스를 배우며, 클라우드 네이티브 프로젝트를 성공적으로 수행하세요.</p>
</center>
<section class="call-to-action">
<div class="main-section">
<div class="call-to-action" id="cta-certification">
<div class="logo-certification cta-image cta-image-before" id="logo-cka">
<img src="/images/training/kubernetes-cka-white.svg"/>
</div>
<div class="logo-certification cta-image cta-image-after" id="logo-ckad">
<img src="/images/training/kubernetes-ckad-white.svg"/>
</div>
<div class="cta-text">
<h2>클라우드 네이티브 커리어를 구축하세요</h2>
<p>쿠버네티스는 클라우드 네이티브 무브먼트의 핵심입니다. 리눅스 재단이 제공하는 교육과 인증 프로그램을 통해 커리어에 투자하고, 쿠버네티스를 배우며, 클라우드 네이티브 프로젝트를 성공적으로 수행하세요.</p>
</div>
</div>
</div>
</div>
</section>
<section>
<div class="main-section padded">
@ -60,7 +68,7 @@ class: training
<center>
<h2>리눅스 재단과 함께 배우기</h2>
<p>리눅스 재단은 쿠버네티스 애플리케이션 개발과 운영 라이프사이클의 모든 측면에 대해 강사 주도와 자기 주도 학습 과정을 제공합니다.</p>
<br><br>
<br/><br/>
<a href="https://training.linuxfoundation.org/training/course-catalog/?_sft_technology=kubernetes" target="_blank" class="button">강좌 보기</a>
</center>
</div>
@ -71,25 +79,27 @@ class: training
<center>
<h2>쿠버네티스 공인 자격 획득하기</h2>
</center>
<div class="col-nav">
<center>
<h5>
<b>공인 쿠버네티스 애플리케이션 개발자(Certified Kubernetes Application Developer, CKAD)</b>
</h5>
<p>공인 쿠버네티스 애플리케이션 개발자 시험은 사용자가 쿠버네티스의 클라우드 네이티브 애플리케이션을 디자인, 구축, 구성과 노출을 할 수 있음을 인증합니다.</p>
<br>
<a href="https://training.linuxfoundation.org/certification/certified-kubernetes-application-developer-ckad/" target="_blank" class="button">인증으로 이동하기</a>
</center>
</div>
<div class="col-nav">
<center>
<h5>
<b>공인 쿠버네티스 관리자(Certified Kubernetes Administrator, CKA)</b>
</h5>
<p>공인 쿠버네티스 관리자 프로그램은 CKA가 쿠버네티스 관리자 직무을 수행할 수 있는 기술, 지식과 역량을 갖추고 있음을 보장합니다.</p>
<br>
<a href=https://training.linuxfoundation.org/certification/certified-kubernetes-administrator-cka/" target="_blank" class="button">인증으로 이동하기</a>
</center>
<div class="col-container">
<div class="col-nav">
<center>
<h5>
<b>공인 쿠버네티스 애플리케이션 개발자(Certified Kubernetes Application Developer, CKAD)</b>
</h5>
<p>공인 쿠버네티스 애플리케이션 개발자 시험은 사용자가 쿠버네티스의 클라우드 네이티브 애플리케이션을 디자인, 구축, 구성과 노출을 할 수 있음을 인증합니다.</p>
<br>
<a href="https://training.linuxfoundation.org/certification/certified-kubernetes-application-developer-ckad/" target="_blank" class="button">인증으로 이동하기</a>
</center>
</div>
<div class="col-nav">
<center>
<h5>
<b>공인 쿠버네티스 관리자(Certified Kubernetes Administrator, CKA)</b>
</h5>
<p>공인 쿠버네티스 관리자(CKA) 프로그램은 CKA가 쿠버네티스 관리자 직무을 수행할 수 있는 기술, 지식과 역량을 갖추고 있음을 보장합니다.</p>
<br>
<a href=https://training.linuxfoundation.org/certification/certified-kubernetes-administrator-cka/" target="_blank" class="button">인증으로 이동하기</a>
</center>
</div>
</div>
</div>
</section>