Merge remote-tracking branch 'upstream/master' into dev-1.19

pull/21073/head
Savitha Raghunathan 2020-05-19 16:58:32 -04:00
commit 1f08c931df
172 changed files with 10181 additions and 4387 deletions

View File

@ -16,7 +16,7 @@
If you're working on a different localization (not English), or you
are documenting a feature that will be part of a future release, see
https://kubernetes.io/docs/contribute/start#choose-which-git-branch-to-use
https://kubernetes.io/docs/contribute/new-content/overview/#choose-which-git-branch-to-use
for advice.
-->

View File

@ -123,6 +123,7 @@ aliases:
sig-docs-id-reviews: # PR reviews for Indonesian content
- girikuncoro
- irvifa
- wahyuoi
sig-docs-it-owners: # Admins for Italian content
- fabriziopandini
- mattiaperi

View File

@ -1,58 +1,9 @@
# Документация по Kubernetes
[![Build Status](https://api.travis-ci.org/kubernetes/website.svg?branch=master)](https://travis-ci.org/kubernetes/website)
[![GitHub release](https://img.shields.io/github/release/kubernetes/website.svg)](https://github.com/kubernetes/website/releases/latest)
[![Netlify Status](https://api.netlify.com/api/v1/badges/be93b718-a6df-402a-b4a4-855ba186c97d/deploy-status)](https://app.netlify.com/sites/kubernetes-io-master-staging/deploys) [![GitHub release](https://img.shields.io/github/release/kubernetes/website.svg)](https://github.com/kubernetes/website/releases/latest)
Добро пожаловать! Данный репозиторий содержит все необходимые файлы для сборки [сайта Kubernetes и документации](https://kubernetes.io/). Мы благодарим вас за старания!
## Вклад в документацию
Нажмите на кнопку **Fork** в правом верхнем углу, чтобы создать копию этого репозитория в ваш GitHub-аккаунт. Эта копия называется *форк-репозиторием*. Делайте любые изменения в вашем форк-репозитории, и когда вы будете готовы опубликовать изменения, откройте форк-репозиторий и создайте новый пулреквест, чтобы уведомить нас.
После того, как вы отправите пулреквест, ревьювер Kubernetes даст по нему обратную связь. Вы, как автор пулреквеста, **должны обновить свой пулреквест после его рассмотрения ревьювером Kubernetes.** Вполне возможно, что более одного ревьювера Kubernetes оставят свои комментарии или даже может быть так, что новый комментарий ревьювера Kubernetes будет отличаться от первоначального назначенного ревьювера. Кроме того, в некоторых случаях один из ревьюверов может запросить технический обзор у [технического ревьювера Kubernetes](https://github.com/kubernetes/website/wiki/Tech-reviewers), если это будет необходимо. Ревьюверы сделают все возможное, чтобы как можно оперативно оставить свои предложения и пожелания, но время ответа может варьироваться в зависимости от обстоятельств.
Узнать подробнее о том, как поучаствовать в документации Kubernetes, вы можете по ссылкам ниже:
* [Начните вносить свой вклад](https://kubernetes.io/docs/contribute/start/)
* [Просмотр локальных изменений](http://kubernetes.io/docs/contribute/intermediate#view-your-changes-locally)
* [Использование шаблонов страниц](http://kubernetes.io/docs/contribute/style/page-templates/)
* [Руководство по оформлению документации](http://kubernetes.io/docs/contribute/style/style-guide/)
* [Руководство по локализации Kubernetes](https://kubernetes.io/docs/contribute/localization/)
## Файл `README.md` на других языках
| | |
|-------------------------------|-------------------------------|
| [Английский](README.md) | [Французский](README-fr.md) |
| [Корейский](README-ko.md) | [Немецкий](README-de.md) |
| [Португальский](README-pt.md) | [Хинди](README-hi.md) |
| [Испанский](README-es.md) | [Индонезийский](README-id.md) |
| [Китайский](README-zh.md) | [Японский](README-ja.md) |
| [Вьетнамский](README-vi.md) | [Итальянский](README-it.md) |
| [Польский]( README-pl.md) | [Украинский](README-uk.md) |
| | |
## Запуск сайта локально с помощью Docker
Рекомендованный способ запуска сайта Kubernetes на локальной машине - использовать специальный образ [Docker](https://docker.com), который включает статический генератор сайтов [Hugo](https://gohugo.io).
> Если вы используете Windows, вам необходимо установить дополнительные инструменты через [Chocolatey](https://chocolatey.org). `choco install make`
> Если вы хотите запустить сайт локально без Docker, обратитесь к разделу [Запуск сайта с помощью Hugo](#запуск-сайта-с-помощью-hugo) ниже на этой странице.
Когда Docker [установлен и запущен](https://www.docker.com/get-started), соберите локально Docker-образ `kubernetes-hugo`, выполнив команду в консоли:
```bash
make docker-image
```
После того, как вы собрали образ, можно запустить сайт локально:
```bash
make docker-serve
```
Откройте браузер и перейдите по ссылке http://localhost:1313, чтобы открыть сайт. Если вы редактируете исходные файлы сайта, Hugo автоматически применит изменения и обновит страницу в браузере.
## Запуск сайта с помощью Hugo
Обратитесь к [официальной документации Hugo](https://gohugo.io/getting-started/installing/), чтобы установить Hugo. Убедитесь, что вы установили правильную версию Hugo, которая устанавливается в переменной окружения `HUGO_VERSION` в файле [`netlify.toml`](netlify.toml#L10).
@ -60,7 +11,9 @@ make docker-serve
После установки Hugo, чтобы запустить сайт, выполните в консоли:
```bash
make serve
git clone https://github.com/kubernetes/website.git
cd website
hugo server --buildFuture
```
Эта команда запустит сервер Hugo на порту 1313. Откройте браузер и перейдите по ссылке http://localhost:1313, чтобы открыть сайт. Если вы отредактируете исходные файлы сайта, Hugo автоматически применит изменения и обновит страницу в браузере.
@ -74,9 +27,35 @@ make serve
- [Канал в Slack](https://kubernetes.slack.com/messages/sig-docs)
- [Рассылка](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)
## Вклад в документацию
Нажмите на кнопку **Fork** в правом верхнем углу, чтобы создать копию этого репозитория в ваш GitHub-аккаунт. Эта копия называется *форк-репозиторием*. Делайте любые изменения в вашем форк-репозитории, и когда вы будете готовы опубликовать изменения, откройте форк-репозиторий и создайте новый пулреквест, чтобы уведомить нас.
После того, как вы отправите пулреквест, ревьювер Kubernetes даст по нему обратную связь. Вы, как автор пулреквеста, **должны обновить свой пулреквест после его рассмотрения ревьювером Kubernetes.**
Вполне возможно, что более одного ревьювера Kubernetes оставят свои комментарии или даже может быть так, что новый комментарий ревьювера Kubernetes будет отличаться от первоначального назначенного ревьювера. Кроме того, в некоторых случаях один из ревьюверов может запросить технический обзор у [технического ревьювера Kubernetes](https://github.com/kubernetes/website/wiki/Tech-reviewers), если это будет необходимо. Ревьюверы сделают все возможное, чтобы как можно оперативно оставить свои предложения и пожелания, но время ответа может варьироваться в зависимости от обстоятельств.
Узнать подробнее о том, как поучаствовать в документации Kubernetes, вы можете по ссылкам ниже:
* [Начните вносить свой вклад](https://kubernetes.io/docs/contribute/)
* [Использование шаблонов страниц](http://kubernetes.io/docs/contribute/style/page-templates/)
* [Руководство по оформлению документации](http://kubernetes.io/docs/contribute/style/style-guide/)
* [Руководство по локализации Kubernetes](https://kubernetes.io/docs/contribute/localization/)
## Файл `README.md` на других языках
| другие языки | другие языки |
|-------------------------------|-------------------------------|
| [Английский](README.md) | [Французский](README-fr.md) |
| [Корейский](README-ko.md) | [Немецкий](README-de.md) |
| [Португальский](README-pt.md) | [Хинди](README-hi.md) |
| [Испанский](README-es.md) | [Индонезийский](README-id.md) |
| [Китайский](README-zh.md) | [Японский](README-ja.md) |
| [Вьетнамский](README-vi.md) | [Итальянский](README-it.md) |
| [Польский]( README-pl.md) | [Украинский](README-uk.md) |
### Кодекс поведения
Участие в сообществе Kubernetes регулируется [кодексом поведения Kubernetes](code-of-conduct.md).
Участие в сообществе Kubernetes регулируется [кодексом поведения CNCF](https://github.com/cncf/foundation/blob/master/code-of-conduct.md).
## Спасибо!

View File

@ -14,12 +14,6 @@ contentDir = "content/en"
timeout = 3000
# Highlighting config.
pygmentsCodeFences = true
pygmentsUseClasses = false
# See https://help.farbox.com/pygments.html
pygmentsStyle = "emacs"
# Enable Git variables like commit, lastmod
enableGitInfo = true
@ -27,10 +21,20 @@ enableGitInfo = true
# Hindi is disabled because it's currently in development.
disableLanguages = ["hi", "no"]
[blackfriday]
hrefTargetBlank = true
fractions = false
smartDashes = false
[markup]
[markup.goldmark]
[markup.goldmark.renderer]
unsafe = true
[markup.highlight]
codeFences = true
guessSyntax = false
hl_Lines = ""
lineNoStart = 1
lineNos = false
lineNumbersInTable = true
noClasses = true
style = "emacs"
tabWidth = 4
[frontmatter]
date = ["date", ":filename", "publishDate", "lastmod"]

View File

@ -97,7 +97,16 @@ reviews-v2-ccffdd984-9jnsj 2/2 Running 0 101s
reviews-v3-98dc67b68-nzw97 2/2 Running 0 101s
```
This command outputs useful data, so lets take a second to understand it. If you examine the READY column, each pod has two containers running: the service and an Envoy sidecar injected alongside it. Another thing to highlight is that there are three review pods but only 1 review service. The Envoy sidecar will load balance the traffic to three different review pods that contain different versions, giving us the ability to A/B test our changes. With that said, you should now be able to access your product page!
This command outputs useful data, so lets take a second to understand it. If you examine the READY column, each pod has two containers running: the service and an Envoy sidecar injected alongside it. Another thing to highlight is that there are three review pods but only 1 review service. The Envoy sidecar will load balance the traffic to three different review pods that contain different versions, giving us the ability to A/B test our changes. We have one step before we can access the deployed application. We need to add an additional annotation to the `productpage` service. To do so, run:
```
$ kubectl annotate service productpage ingress.kubernetes.io/service-upstream=true
service/productpage annotated
```
Both the API gateway (Kong) and the service mesh (Istio) can handle the load-balancing. Without the additional `ingress.kubernetes.io/service-upstream: "true"` annotation, Kong will try to load-balance by selecting its own endpoint/target from the productpage service. This causes Envoy to receive that pods IP as the upstream local address, instead of the services cluster IP. But we want the service's cluster IP so that Envoy can properly load balance.
With that added, you should now be able to access your product page!
```
$ kubectl exec -it $(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}') -c ratings -- curl productpage:9080/productpage | grep -o "<title>.*</title>"
@ -150,6 +159,8 @@ metadata:
name: do-not-preserve-host
route:
preserve_host: false
upstream:
host_header: productpage.default.svc
" | kubectl apply -f -
kongingress.configuration.konghq.com/do-not-preserve-host created
```

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -1,10 +1,10 @@
---
title: Booz Allen Case Study
linkTitle: booz-allen
linkTitle: Booz Allen Hamilton
case_study_styles: true
cid: caseStudies
css: /css/case-studies-gradient.css
logo: booz-allen_featured_logo.png
logo: booz-allen-featured-logo.svg
featured: true
weight: 2
quote: >

View File

@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 215 127"><defs><style>.cls-1{fill:none;}.cls-2{fill:#fbfbfb;}.cls-3{clip-path:url(#clip-path);}.cls-4{fill:#ee3248;fill-rule:evenodd;}</style><clipPath id="clip-path"><rect class="cls-1" x="4.70501" y="-8.81268" width="206.90403" height="145.3255"/></clipPath></defs><rect class="cls-2" x="-3.37342" y="-3.34411" width="223.25536" height="134.51135"/><g class="cls-3"><g class="cls-3"><path class="cls-4" d="M28.02166,50.76936l7.69058-.0617c6.9525.12305,7.75228,4.1837,4.61435,13.41275-2.64567,7.87531-6.76768,12.67414-14.58165,12.61279h-6.091ZM169.22325,61.044c4.55274-11.01316,10.52065-15.19686,22.76431-15.50454,10.9518-.24609,15.81224,4.79908,11.813,17.41187C199.49376,76.67151,191.67987,82.209,179.86693,82.209c-12.98175.06134-16.24263-7.87514-10.64368-21.165m8.429.73843c2.83006-7.01411,6.95215-11.87463,13.04345-11.93633,5.47555-.06125,6.46007,3.938,3.99905,12.36706-3.13794,10.82842-7.69068,15.5659-13.90466,15.44286-6.89106-.06135-6.768-6.82946-3.13784-15.87359m-15.07382-8.67536,2.09172-6.02932a34.76316,34.76316,0,0,0-10.95146-1.66134c-7.62924-.0616-13.35114,2.33806-15.6892,7.69066-3.69162,8.183,1.4766,10.70564,7.69084,13.59749,9.10583,4.245,3.876,11.56684-4.86069,10.82842-3.50688-.3077-6.58311-1.90724-9.65961-3.38384l-1.96859,6.15264A33.79646,33.79646,0,0,0,142.64393,82.209c9.0444-.55369,14.64308-4.184,16.91972-9.90595,2.584-6.52159-1.41525-10.52064-7.38324-12.42789-12.42831-3.99939-4.98338-15.75088,10.398-6.76811M95.57659,46.15492a19.153,19.153,0,0,1,2.215,3.62993L87.76306,81.47059H93.854l8.36766-26.45618,9.59791,26.45618h8.61375l-.36939-.98451,10.89012-34.33116h-6.15273l-7.99827,25.34837-9.22879-25.34837c-3.999,0-7.99836.06135-11.99767,0m-34.39259,0a14.395,14.395,0,0,1,2.21468,3.62993L53.43173,81.47059H79.826L81.05656,77.533H63.21437L67.152,65.16635H78.96492l1.23051-3.87627H68.3825L71.95081,49.9695H89.17822L90.347,46.15492c-9.72121,0-19.44208.06135-29.163,0m-42.26817,0a16.4482,16.4482,0,0,1,2.21468,3.62993L11.102,81.47059h8.61366l5.04517-.06135c14.766,0,21.77988-7.32179,24.73333-16.85828,4.245-13.5973-.92316-18.33469-13.47418-18.33469Z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1,110 @@
---
title: Denso Case Study
linkTitle: Denso
case_study_styles: true
cid: caseStudies
css: /css/case-studies-gradient.css
logo: denso_featured_logo.svg
featured: true
weight: 4
quote: >
We got Kubernetes experts involved on our team, and it dramatically accelerated development speed.
---
<div class="article image overlay" style="background-image: url('/images/Denso2.jpg')">
<h1> CASE STUDY: Denso</h1>
<div class="subhead">How DENSO Is Fueling Development on the Vehicle Edge with Kubernetes</div>
</div>
<div class="details">
Company &nbsp;<b>Denso</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Location &nbsp;<b>Japan</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Industry &nbsp;<b>Automotive, Edge</b>
</div>
<hr>
<section class="section1">
<div class="colsgradient">
<div class="col1">
<h2>Challenge</h2>
DENSO Corporation is one of the biggest automotive components suppliers in the world. With the advent of connected cars, the company launched a Digital Innovation Department to expand into software, working on vehicle edge and vehicle cloud products. But there were several technical challenges to creating an integrated vehicle edge/cloud platform: "the amount of computing resources, the occasional lack of mobile signal, and an enormous number of distributed vehicles," says R&D Product Manager Seiichi Koizumi.
<h2>Solution</h2>
Koizumis team realized that because mobility services evolve every day, they needed the flexibility of the cloud native ecosystem for their platform. After considering other orchestrators, DENSO went with Kubernetes for orchestration and added Prometheus, Fluentd, Envoy, Istio, and Helm to the platform. Today, DENSO is using a vehicle edge computer, a private Kubernetes cloud, and managed Kubernetes (GKE, EKS, AKS).
<h2>Impact</h2>
Critical layer features can take 2-3 years to implement in the traditional, waterfall model of development at DENSO. With the Kubernetes platform and agile methods, theres a 2-month development cycle for non-critical software. Now, ten new applications are released a year, and a new prototype is introduced every week. "By utilizing Kubernetes managed services, such as GKE/EKS/AKS, we can unify the environment and simplify our maintenance operation," says Koizumi.
</div>
</section>
<div class="article image overlay" style="background-image: url('/images/Denso1.png');">
<div class="quotetext">
"Another disruptive innovation is coming, so to survive in this situation, we need to change our culture."
<p><div class="quoteauthortext">- SEIICHI KOIZUMI, R&D PRODUCT MANAGER, DIGITAL INNOVATION DEPARTMENT AT DENSO</div></p>
</div>
</div>
<section class="section2">
<div class="fullcol">
<h4>Spun off from Toyota in 1949, DENSO Corporation is one of the top automotive suppliers in the world today, with consolidated net revenue of $48.3 billion.
</h4>
<p>The companys mission is "contributing to a better world by creating value together with a vision for the future"—and part of that vision in recent years has been development on the vehicle edge and vehicle cloud.</p>
<p>With the advent of connected cars, DENSO established a Digital Innovation Department to expand its business beyond the critical layer of the engine, braking systems, and other automotive parts into the non-critical analytics and entertainment layer. Comparing connected cars to smartphones, R&D Product Manager Seiichi Koizumi says DENSO wants the ability to quickly and easily develop and install apps for the "blank slate" of the car, and iterate them based on the drivers preferences. Thus "we need a flexible application platform," he says. </p>
<p>But working on vehicle edge and vehicle cloud products meant there were several technical challenges: "the amount of computing resources, the occasional lack of mobile signal, and an enormous number of distributed vehicles," says Koizumi. "We are tackling these challenges to create an integrated vehicle edge/cloud platform."</p>
</div>
</section>
<div class="greybanner">
<div class="greyquotetext">
"We got Kubernetes experts involved on our team, and it dramatically accelerated development speed."<p><div class="quoteauthortext">— SEIICHI KOIZUMI, R&D PRODUCT MANAGER, DIGITAL INNOVATION DEPARTMENT AT DENSO</div></p>
</div>
</div>
<section class="section3">
<div class="fullcol">
<p>
Koizumis team realized that because mobility services evolve every day, they needed the flexibility of the cloud native ecosystem for their platform. As they evaluated technologies, they were led by these criteria: Because their service-enabler business needed to support multiple cloud and on-premise environments, the solution needed to be cloud agnostic, with no vendor lock-in and open governance. It also had to support an edge-cloud integrated environment.</p>
<p>
After considering other orchestrators, DENSO went with Kubernetes for orchestration and added Prometheus, Fluentd, Envoy, Istio, and Helm to the platform. During implementation, the team used "design thinking to clarify use cases and their value proposition," says Koizumi. Next, an agile development team worked on a POC, then an MVP, in DevOps style. "Even in the development phase, we are keeping a channel to end users," he adds. </p>
<p>
One lesson learned during this process was the value of bringing in experts. "We tried to learn Kubernetes and cloud native technologies from scratch, but it took more time than expected," says Koizumi. "We got Kubernetes experts involved on our team, and it dramatically accelerated development speed."</p>
</p>
</div>
</section>
<div class="article image overlay" style="background-image: url('/images/Denso4.jpg');">
<div class="quotetext">
"By utilizing Kubernetes managed services, such as GKE/EKS/AKS, we can unify the environment and simplify our maintenance operation." <p><div class="quoteauthortext">- SEIICHI KOIZUMI, R&D PRODUCT MANAGER, DIGITAL INNOVATION DEPARTMENT AT DENSO</div></p>
</div>
</div>
<section class="section5">
<div class="fullcol">
<p>
Today, DENSO is using a vehicle edge computer, a private Kubernetes cloud, and managed Kubernetes on GKE, EKS, and AKS. "We are developing a vehicle edge/cloud integrated platform based on a microservice and service mesh architecture," says Koizumi. "We extend cloud into multiple vehicle edges and manage it as a unified platform."</p>
<p>
Cloud native has enabled DENSO to deliver applications via its new dash cam, which has a secure connection that collects data to the cloud. "Its like a smartphone," he says. "We are installing new applications and getting the data through the cloud, and we can keep updating new applications all through the dash cam."</p>
<p>
The unified cloud native platform, combined with agile development, has had a positive impact on productivity. Critical layer features—those involving engines or braking systems, for example—can take 2-3 years to implement at DENSO, because of the time needed to test safety, but also because of the traditional, waterfall model of development. With the Kubernetes platform and agile methods, theres a 2-month development cycle for non-critical software. Now, ten new applications are released a year, and with the departments scrum-style development, a new prototype is introduced every week. </p>
<p>
Application portability has also led to greater developer efficiency. "Theres no need to care about differences in the multi-cloud platform anymore," says Koizumi. Now, "we are also trying to have the same portability between vehicle edge and cloud platform."
</p>
<p>
Another improvement: Automotive Tier-1 suppliers like DENSO always have multiple Tier-2 suppliers. "To provide automotive-grade high-availability services, we tried to do the same thing on a multi-cloud platform," says Koizumi. Before Kubernetes, maintaining two different systems simultaneously was difficult. "By utilizing Kubernetes managed services, such as GKE/EKS/AKS, we can unify the environment and simplify our maintenance operation," he says.
</p>
<p>
Cloud native has also profoundly changed the culture at DENSO. The Digital Innovation Department is known as "Noahs Ark," and it has grown from 2 members to 70—with plans to more than double in the next year. The way they operate is completely different from the traditional Japanese automotive culture. But just as the company embraced change brought by hybrid cars in the past decade, Koizumi says, theyre doing it again now, as technology companies have moved into the connected car space. "Another disruptive innovation is coming," he says, "so to survive in this situation, we need to change our culture."
</p>
<p>
Looking ahead, Koizumi and his team are expecting serverless and zero-trust security architecture to be important enhancements of Kubernetes. They are glad DENSO has come along for the ride. "Mobility service businesses require agility and flexibility," he says. "DENSO is trying to bring cloud native flexibility into the vehicle infrastructure."
</p>
</div>
</section>
</body>

View File

@ -131,14 +131,14 @@ classes:
namespace). These are important to isolate from other traffic because failures
in leader election cause their controllers to fail and restart, which in turn
causes more expensive traffic as the new controllers sync their informers.
* The `workload-high` priority level is for other requests from built-in
controllers.
* The `workload-low` priority level is for requests from any other service
account, which will typically include all requests from controllers runing in
Pods.
* The `global-default` priority level handles all other traffic, e.g.
interactive `kubectl` commands run by nonprivileged users.
@ -150,7 +150,7 @@ are built in and may not be overwritten:
special `exempt` FlowSchema classifies all requests from the `system:masters`
group into this priority level. You may define other FlowSchemas that direct
other requests to this priority level, if appropriate.
* The special `catch-all` priority level is used in combination with the special
`catch-all` FlowSchema to make sure that every request gets some kind of
classification. Typically you should not rely on this catch-all configuration,
@ -164,7 +164,7 @@ are built in and may not be overwritten:
## Resources
The flow control API involves two kinds of resources.
[PriorityLevelConfigurations](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#prioritylevelconfiguration-v1alpha1-flowcontrol-apiserver-k8s-io)
[PriorityLevelConfigurations](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#prioritylevelconfiguration-v1alpha1-flowcontrol-apiserver-k8s-io)
define the available isolation classes, the share of the available concurrency
budget that each can handle, and allow for fine-tuning queuing behavior.
[FlowSchemas](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#flowschema-v1alpha1-flowcontrol-apiserver-k8s-io)
@ -204,7 +204,7 @@ to balance progress between request flows.
The queuing configuration allows tuning the fair queuing algorithm for a
priority level. Details of the algorithm can be read in the [enhancement
proposal](#what-s-next), but in short:
proposal](#whats-next), but in short:
* Increasing `queues` reduces the rate of collisions between different flows, at
the cost of increased memory usage. A value of 1 here effectively disables the
@ -233,20 +233,21 @@ given mouse (low-intensity flow) is squished by the elephants (high-intensity fl
an illustrative collection of numbers of elephants. See
https://play.golang.org/p/Gi0PLgVHiUg , which computes this table.
{{< table caption="Example Shuffle Sharding Configurations" >}}
|HandSize| Queues| 1 elephant| 4 elephants| 16 elephants|
|--------|-----------|------------|----------------|--------------------|
| 12| 32| 4.428838398950118e-09| 0.11431348830099144| 0.9935089607656024|
| 10| 32| 1.550093439632541e-08| 0.0626479840223545| 0.9753101519027554|
| 10| 64| 6.601827268370426e-12| 0.00045571320990370776| 0.49999929150089345|
| 9| 64| 3.6310049976037345e-11| 0.00045501212304112273| 0.4282314876454858|
| 8| 64| 2.25929199850899e-10| 0.0004886697053040446| 0.35935114681123076|
| 8| 128| 6.994461389026097e-13| 3.4055790161620863e-06| 0.02746173137155063|
| 7| 128| 1.0579122850901972e-11| 6.960839379258192e-06| 0.02406157386340147|
| 7| 256| 7.597695465552631e-14| 6.728547142019406e-08| 0.0006709661542533682|
| 6| 256| 2.7134626662687968e-12| 2.9516464018476436e-07| 0.0008895654642000348|
| 6| 512| 4.116062922897309e-14| 4.982983350480894e-09| 2.26025764343413e-05|
| 6| 1024| 6.337324016514285e-16| 8.09060164312957e-11| 4.517408062903668e-07|
{{< table caption = "Example Shuffle Sharding Configurations" >}}
HandSize | Queues | 1 elephant | 4 elephants | 16 elephants
|----------|-----------|------------|----------------|--------------------|
| 12 | 32 | 4.428838398950118e-09 | 0.11431348830099144 | 0.9935089607656024 |
| 10 | 32 | 1.550093439632541e-08 | 0.0626479840223545 | 0.9753101519027554 |
| 10 | 64 | 6.601827268370426e-12 | 0.00045571320990370776 | 0.49999929150089345 |
| 9 | 64 | 3.6310049976037345e-11 | 0.00045501212304112273 | 0.4282314876454858 |
| 8 | 64 | 2.25929199850899e-10 | 0.0004886697053040446 | 0.35935114681123076 |
| 8 | 128 | 6.994461389026097e-13 | 3.4055790161620863e-06 | 0.02746173137155063 |
| 7 | 128 | 1.0579122850901972e-11 | 6.960839379258192e-06 | 0.02406157386340147 |
| 7 | 256 | 7.597695465552631e-14 | 6.728547142019406e-08 | 0.0006709661542533682 |
| 6 | 256 | 2.7134626662687968e-12 | 2.9516464018476436e-07 | 0.0008895654642000348 |
| 6 | 512 | 4.116062922897309e-14 | 4.982983350480894e-09 | 2.26025764343413e-05 |
| 6 | 1024 | 6.337324016514285e-16 | 8.09060164312957e-11 | 4.517408062903668e-07 |
{{< /table >}}
### FlowSchema
@ -291,7 +292,7 @@ enabled has two extra headers: `X-Kubernetes-PF-FlowSchema-UID` and
`X-Kubernetes-PF-PriorityLevel-UID`, noting the flow schema that matched the request
and the priority level to which it was assigned, respectively. The API objects'
names are not included in these headers in case the requesting user does not
have permission to view them, so when debugging you can use a command like
have permission to view them, so when debugging you can use a command like
```shell
kubectl get flowschemas -o custom-columns="uid:{metadata.uid},name:{metadata.name}"
@ -363,7 +364,7 @@ poorly-behaved workloads that may be harming system health.
* `apiserver_flowcontrol_request_execution_seconds` gives a histogram of how
long requests took to actually execute, grouped by the FlowSchema that matched the
request and the PriorityLevel to which it was assigned.
{{% /capture %}}
@ -374,4 +375,4 @@ the [enhancement proposal](https://github.com/kubernetes/enhancements/blob/maste
You can make suggestions and feature requests via [SIG API
Machinery](https://github.com/kubernetes/community/tree/master/sig-api-machinery).
{{% /capture %}}
{{% /capture %}}

View File

@ -59,8 +59,7 @@ DNS server watches the Kubernetes API for new `Services` and creates a set of DN
- Avoid using `hostNetwork`, for the same reasons as `hostPort`.
- Use [headless Services](/docs/concepts/services-networking/service/#headless-
services) (which have a `ClusterIP` of `None`) for easy service discovery when you don't need `kube-proxy` load balancing.
- Use [headless Services](/docs/concepts/services-networking/service/#headless-services) (which have a `ClusterIP` of `None`) for easy service discovery when you don't need `kube-proxy` load balancing.
## Using Labels

View File

@ -9,9 +9,9 @@ weight: 1
{{% capture overview %}}
Containers are a technnology for packaging the (compiled) code for an
Containers are a technology for packaging the (compiled) code for an
application along with the dependencies it needs at run time. Each
container that you run is repeatable; the standardisation from having
container that you run is repeatable; the standardization from having
dependencies included means that you get the same behavior wherever you
run it.

View File

@ -106,7 +106,7 @@ as well as keeping the existing service in good shape.
## Writing your own Operator {#writing-operator}
If there isn't an Operator in the ecosystem that implements the behavior you
want, you can code your own. In [What's next](#what-s-next) you'll find a few
want, you can code your own. In [What's next](#whats-next) you'll find a few
links to libraries and tools you can use to write your own cloud native
Operator.
@ -129,4 +129,4 @@ that can act as a [client for the Kubernetes API](/docs/reference/using-api/clie
* Read [CoreOS' original article](https://coreos.com/blog/introducing-operators.html) that introduced the Operator pattern
* Read an [article](https://cloud.google.com/blog/products/containers-kubernetes/best-practices-for-building-kubernetes-operators-and-stateful-apps) from Google Cloud about best practices for building Operators
{{% /capture %}}
{{% /capture %}}

View File

@ -157,13 +157,13 @@ the three things:
1. **wait** (with a timeout) \
If a Permit plugin returns "wait", then the Pod is kept in an internal "waiting"
Pods list, and the binding cycle of this Pod starts but directly blocks until it
gets [approved](#frameworkhandle). If a timeout occurs, **wait** becomes **deny**
gets approved. If a timeout occurs, **wait** becomes **deny**
and the Pod is returned to the scheduling queue, triggering [Unreserve](#unreserve)
plugins.
{{< note >}}
While any plugin can access the list of "waiting" Pods and approve them
(see [`FrameworkHandle`](#frameworkhandle)), we expect only the permit
(see [`FrameworkHandle`](https://github.com/kubernetes/enhancements/blob/master/keps/sig-scheduling/20180409-scheduling-framework.md#frameworkhandle)), we expect only the permit
plugins to approve binding of reserved Pods that are in "waiting" state. Once a Pod
is approved, it is sent to the [PreBind](#pre-bind) phase.
{{< /note >}}
@ -239,4 +239,4 @@ If you are using Kubernetes v1.18 or later, you can configure a set of plugins a
a scheduler profile and then define multiple profiles to fit various kinds of workload.
Learn more at [multiple profiles](/docs/reference/scheduling/profiles/#multiple-profiles).
{{% /capture %}}
{{% /capture %}}

View File

@ -171,7 +171,7 @@ following pod-specific DNS policies. These policies are specified in the
- "`None`": It allows a Pod to ignore DNS settings from the Kubernetes
environment. All DNS settings are supposed to be provided using the
`dnsConfig` field in the Pod Spec.
See [Pod's DNS config](#pod-s-dns-config) subsection below.
See [Pod's DNS config](#pod-dns-config) subsection below.
{{< note >}}
"Default" is not the default DNS policy. If `dnsPolicy` is not
@ -201,7 +201,7 @@ spec:
dnsPolicy: ClusterFirstWithHostNet
```
### Pod's DNS Config
### Pod's DNS Config {#pod-dns-config}
Pod's DNS Config allows users more control on the DNS settings for a Pod.
@ -269,6 +269,4 @@ The availability of Pod DNS Config and DNS Policy "`None`"" is shown as below.
For guidance on administering DNS configurations, check
[Configure DNS Service](/docs/tasks/administer-cluster/dns-custom-nameservers/)
{{% /capture %}}
{{% /capture %}}

View File

@ -134,11 +134,10 @@ path types:
to the list of labels in the path split by the `/` separator. A request is a
match for path _p_ if every _p_ is an element-wise prefix of _p_ of the
request path.
{{< note >}}
If the last element of the path is a substring of the
last element in request path, it is not a match (for example:
`/foo/bar` matches`/foo/bar/baz`, but does not match `/foo/barbaz`).
{{< /note >}}
{{< note >}}
If the last element of the path is a substring of the last element in request path, it is not a match (for example: `/foo/bar` matches`/foo/bar/baz`, but does not match `/foo/barbaz`).
{{< /note >}}
#### Multiple Matches
In some cases, multiple paths within an Ingress will match a request. In those
@ -402,16 +401,16 @@ metadata:
spec:
tls:
- hosts:
- sslexample.foo.com
- sslexample.foo.com
secretName: testsecret-tls
rules:
- host: sslexample.foo.com
http:
paths:
- path: /
backend:
serviceName: service1
servicePort: 80
- host: sslexample.foo.com
http:
paths:
- path: /
backend:
serviceName: service1
servicePort: 80
```
{{< note >}}

View File

@ -736,9 +736,9 @@ and need persistent storage, it is recommended that you use the following patter
`persistentVolumeClaim.storageClassName` field.
This will cause the PVC to match the right storage
class if the cluster has StorageClasses enabled by the admin.
- If the user does not provide a storage class name, leave the
`persistentVolumeClaim.storageClassName` field as nil. This will cause a
PV to be automatically provisioned for the user with the default StorageClass
- If the user does not provide a storage class name, leave the
`persistentVolumeClaim.storageClassName` field as nil. This will cause a
PV to be automatically provisioned for the user with the default StorageClass
in the cluster. Many cluster environments have a default StorageClass installed,
or administrators can create their own default StorageClass.
- In your tooling, watch for PVCs that are not getting bound after some time
@ -759,4 +759,4 @@ and need persistent storage, it is recommended that you use the following patter
* [PersistentVolumeSpec](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#persistentvolumespec-v1-core)
* [PersistentVolumeClaim](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#persistentvolumeclaim-v1-core)
* [PersistentVolumeClaimSpec](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#persistentvolumeclaimspec-v1-core)
{{% /capture %}}
{{% /capture %}}

View File

@ -248,14 +248,14 @@ spec:
#### CSI Migration
{{< feature-state for_k8s_version="v1.14" state="alpha" >}}
{{< feature-state for_k8s_version="v1.18" state="beta" >}}
The CSI Migration feature for Cinder, when enabled, shims all plugin operations
from the existing in-tree plugin to the `cinder.csi.openstack.org` Container
Storage Interface (CSI) Driver. In order to use this feature, the [Openstack Cinder CSI
Driver](https://github.com/kubernetes/cloud-provider-openstack/blob/master/docs/using-cinder-csi-plugin.md)
must be installed on the cluster and the `CSIMigration` and `CSIMigrationOpenStack`
Alpha features must be enabled.
Beta features must be enabled.
### configMap {#configmap}

View File

@ -53,12 +53,13 @@ In this example:
In this case, you simply select a label that is defined in the Pod template (`app: nginx`).
However, more sophisticated selection rules are possible,
as long as the Pod template itself satisfies the rule.
{{< note >}}
The `.spec.selector.matchLabels` field is a map of {key,value} pairs. A single {key,value} in the `matchLabels` map
is equivalent to an element of `matchExpressions`, whose key field is "key" the operator is "In",
and the values array contains only "value".
All of the requirements, from both `matchLabels` and `matchExpressions`, must be satisfied in order to match.
{{< /note >}}
{{< note >}}
The `.spec.selector.matchLabels` field is a map of {key,value} pairs.
A single {key,value} in the `matchLabels` map is equivalent to an element of `matchExpressions`,
whose key field is "key" the operator is "In", and the values array contains only "value".
All of the requirements, from both `matchLabels` and `matchExpressions`, must be satisfied in order to match.
{{< /note >}}
* The `template` field contains the following sub-fields:
* The Pods are labeled `app: nginx`using the `.metadata.labels` field.
@ -67,84 +68,92 @@ In this example:
[Docker Hub](https://hub.docker.com/) image at version 1.14.2.
* Create one container and name it `nginx` using the `.spec.template.spec.containers[0].name` field.
Follow the steps given below to create the above Deployment:
Before you begin, make sure your Kubernetes cluster is up and running.
Follow the steps given below to create the above Deployment:
Before you begin, make sure your Kubernetes cluster is up and running.
1. Create the Deployment by running the following command:
1. Create the Deployment by running the following command:
{{< note >}}
You may specify the `--record` flag to write the command executed in the resource annotation `kubernetes.io/change-cause`. It is useful for future introspection.
For example, to see the commands executed in each Deployment revision.
{{< /note >}}
```shell
kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml
```
2. Run `kubectl get deployments` to check if the Deployment was created. If the Deployment is still being created, the output is similar to the following:
```shell
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 0/3 0 0 1s
```
When you inspect the Deployments in your cluster, the following fields are displayed:
* `NAME` lists the names of the Deployments in the namespace.
* `READY` displays how many replicas of the application are available to your users. It follows the pattern ready/desired.
* `UP-TO-DATE` displays the number of replicas that have been updated to achieve the desired state.
* `AVAILABLE` displays how many replicas of the application are available to your users.
* `AGE` displays the amount of time that the application has been running.
Notice how the number of desired replicas is 3 according to `.spec.replicas` field.
3. To see the Deployment rollout status, run `kubectl rollout status deployment.v1.apps/nginx-deployment`. The output is similar to this:
```shell
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
deployment.apps/nginx-deployment successfully rolled out
```
4. Run the `kubectl get deployments` again a few seconds later. The output is similar to this:
```shell
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 18s
```
Notice that the Deployment has created all three replicas, and all replicas are up-to-date (they contain the latest Pod template) and available.
5. To see the ReplicaSet (`rs`) created by the Deployment, run `kubectl get rs`. The output is similar to this:
```shell
NAME DESIRED CURRENT READY AGE
nginx-deployment-75675f5897 3 3 3 18s
```
ReplicaSet output shows the following fields:
* `NAME` lists the names of the ReplicaSets in the namespace.
* `DESIRED` displays the desired number of _replicas_ of the application, which you define when you create the Deployment. This is the _desired state_.
* `CURRENT` displays how many replicas are currently running.
* `READY` displays how many replicas of the application are available to your users.
* `AGE` displays the amount of time that the application has been running.
Notice that the name of the ReplicaSet is always formatted as `[DEPLOYMENT-NAME]-[RANDOM-STRING]`. The random string is
randomly generated and uses the `pod-template-hash` as a seed.
6. To see the labels automatically generated for each Pod, run `kubectl get pods --show-labels`. The following output is returned:
```shell
NAME READY STATUS RESTARTS AGE LABELS
nginx-deployment-75675f5897-7ci7o 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453
nginx-deployment-75675f5897-kzszj 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453
nginx-deployment-75675f5897-qqcnn 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453
```
The created ReplicaSet ensures that there are three `nginx` Pods.
```shell
kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml
```
{{< note >}}
You must specify an appropriate selector and Pod template labels in a Deployment (in this case,
`app: nginx`). Do not overlap labels or selectors with other controllers (including other Deployments and StatefulSets). Kubernetes doesn't stop you from overlapping, and if multiple controllers have overlapping selectors those controllers might conflict and behave unexpectedly.
You can specify the `--record` flag to write the command executed in the resource annotation `kubernetes.io/change-cause`.
The recorded change is useful for future introspection. For example, to see the commands executed in each Deployment revision.
{{< /note >}}
2. Run `kubectl get deployments` to check if the Deployment was created.
If the Deployment is still being created, the output is similar to the following:
```shell
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 0/3 0 0 1s
```
When you inspect the Deployments in your cluster, the following fields are displayed:
* `NAME` lists the names of the Deployments in the namespace.
* `READY` displays how many replicas of the application are available to your users. It follows the pattern ready/desired.
* `UP-TO-DATE` displays the number of replicas that have been updated to achieve the desired state.
* `AVAILABLE` displays how many replicas of the application are available to your users.
* `AGE` displays the amount of time that the application has been running.
Notice how the number of desired replicas is 3 according to `.spec.replicas` field.
3. To see the Deployment rollout status, run `kubectl rollout status deployment.v1.apps/nginx-deployment`.
The output is similar to:
```shell
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
deployment.apps/nginx-deployment successfully rolled out
```
4. Run the `kubectl get deployments` again a few seconds later.
The output is similar to this:
```shell
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 18s
```
Notice that the Deployment has created all three replicas, and all replicas are up-to-date (they contain the latest Pod template) and available.
5. To see the ReplicaSet (`rs`) created by the Deployment, run `kubectl get rs`. The output is similar to this:
```shell
NAME DESIRED CURRENT READY AGE
nginx-deployment-75675f5897 3 3 3 18s
```
ReplicaSet output shows the following fields:
* `NAME` lists the names of the ReplicaSets in the namespace.
* `DESIRED` displays the desired number of _replicas_ of the application, which you define when you create the Deployment. This is the _desired state_.
* `CURRENT` displays how many replicas are currently running.
* `READY` displays how many replicas of the application are available to your users.
* `AGE` displays the amount of time that the application has been running.
Notice that the name of the ReplicaSet is always formatted as `[DEPLOYMENT-NAME]-[RANDOM-STRING]`.
The random string is randomly generated and uses the `pod-template-hash` as a seed.
6. To see the labels automatically generated for each Pod, run `kubectl get pods --show-labels`.
The output is similar to:
```shell
NAME READY STATUS RESTARTS AGE LABELS
nginx-deployment-75675f5897-7ci7o 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453
nginx-deployment-75675f5897-kzszj 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453
nginx-deployment-75675f5897-qqcnn 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453
```
The created ReplicaSet ensures that there are three `nginx` Pods.
{{< note >}}
You must specify an appropriate selector and Pod template labels in a Deployment
(in this case, `app: nginx`).
Do not overlap labels or selectors with other controllers (including other Deployments and StatefulSets). Kubernetes doesn't stop you from overlapping, and if multiple controllers have overlapping selectors those controllers might conflict and behave unexpectedly.
{{< /note >}}
### Pod-template-hash label
{{< note >}}
{{< caution >}}
Do not change this label.
{{< /note >}}
{{< /caution >}}
The `pod-template-hash` label is added by the Deployment controller to every ReplicaSet that a Deployment creates or adopts.
@ -409,9 +418,7 @@ rolled back.
```
{{< note >}}
The Deployment controller stops the bad rollout automatically, and stops scaling up the new
ReplicaSet. This depends on the rollingUpdate parameters (`maxUnavailable` specifically) that you have specified.
Kubernetes by default sets the value to 25%.
The Deployment controller stops the bad rollout automatically, and stops scaling up the new ReplicaSet. This depends on the rollingUpdate parameters (`maxUnavailable` specifically) that you have specified. Kubernetes by default sets the value to 25%.
{{< /note >}}
* Get the description of the Deployment:
@ -901,9 +908,9 @@ example, rollback the Deployment to its previous version.
{{< /note >}}
{{< note >}}
If you pause a Deployment, Kubernetes does not check progress against your specified deadline. You can
safely pause a Deployment in the middle of a rollout and resume without triggering the condition for exceeding the
deadline.
If you pause a Deployment, Kubernetes does not check progress against your specified deadline.
You can safely pause a Deployment in the middle of a rollout and resume without triggering
the condition for exceeding the deadline.
{{< /note >}}
You may experience transient errors with your Deployments, either due to a low timeout that you have set or

View File

@ -156,7 +156,7 @@ Cluster Domain | Service (ns/name) | StatefulSet (ns/name) | StatefulSet Domain
{{< note >}}
Cluster Domain will be set to `cluster.local` unless
[otherwise configured](/docs/concepts/services-networking/dns-pod-service/#how-it-works).
[otherwise configured](/docs/concepts/services-networking/dns-pod-service/).
{{< /note >}}
### Stable Storage

View File

@ -241,7 +241,7 @@ myapp-pod 1/1 Running 0 9m
```
This simple example should provide some inspiration for you to create your own
init containers. [What's next](#what-s-next) contains a link to a more detailed example.
init containers. [What's next](#whats-next) contains a link to a more detailed example.
## Detailed behavior
@ -325,4 +325,4 @@ reasons:
* Read about [creating a Pod that has an init container](/docs/tasks/configure-pod-container/configure-pod-initialization/#creating-a-pod-that-has-an-init-container)
* Learn how to [debug init containers](/docs/tasks/debug-application-cluster/debug-init-containers/)
{{% /capture %}}
{{% /capture %}}

View File

@ -97,7 +97,7 @@ If we want an incoming Pod to be evenly spread with existing Pods across zones,
{{< codenew file="pods/topology-spread-constraints/one-constraint.yaml" >}}
`topologyKey: zone` implies the even distribution will only be applied to the nodes which have label pair "zone:<any value>" present. `whenUnsatisfiable: DoNotSchedule` tells the scheduler to let it stay pending if the incoming Pod cant satisfy the constraint.
`topologyKey: zone` implies the even distribution will only be applied to the nodes which have label pair "zone:&lt;any value&gt;" present. `whenUnsatisfiable: DoNotSchedule` tells the scheduler to let it stay pending if the incoming Pod cant satisfy the constraint.
If the scheduler placed this incoming Pod into "zoneA", the Pods distribution would become [3, 1], hence the actual skew is 2 (3 - 1) - which violates `maxSkew: 1`. In this example, the incoming Pod can only be placed onto "zoneB":

View File

@ -73,8 +73,7 @@ true:
[Prow](https://github.com/kubernetes/test-infra/blob/master/prow/README.md) is
the Kubernetes-based CI/CD system that runs jobs against pull requests (PRs). Prow
enables chatbot-style commands to handle GitHub actions across the Kubernetes
organization, like [adding and removing
labels](#add-and-remove-labels), closing issues, and assigning an approver. Enter Prow commands as GitHub comments using the `/<command-name>` format.
organization, like [adding and removing labels](#adding-and-removing-issue-labels), closing issues, and assigning an approver. Enter Prow commands as GitHub comments using the `/<command-name>` format.
The most common prow commands reviewers and approvers use are:

View File

@ -69,31 +69,49 @@ The following table includes short descriptions and the general syntax for all o
Operation | Syntax | Description
-------------------- | -------------------- | --------------------
`alpha` | `kubectl alpha SUBCOMMAND [flags]` | List the available commands that correspond to alpha features, which are not enabled in Kubernetes clusters by default.
`annotate` | <code>kubectl annotate (-f FILENAME &#124; TYPE NAME &#124; TYPE/NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--overwrite] [--all] [--resource-version=version] [flags]</code> | Add or update the annotations of one or more resources.
`api-resources` | `kubectl api-resources [flags]` | List the API resources that are available.
`api-versions` | `kubectl api-versions [flags]` | List the API versions that are available.
`apply` | `kubectl apply -f FILENAME [flags]`| Apply a configuration change to a resource from a file or stdin.
`attach` | `kubectl attach POD -c CONTAINER [-i] [-t] [flags]` | Attach to a running container either to view the output stream or interact with the container (stdin).
`auth` | `kubectl auth [flags] [options]` | Inspect authorization.
`autoscale` | <code>kubectl autoscale (-f FILENAME &#124; TYPE NAME &#124; TYPE/NAME) [--min=MINPODS] --max=MAXPODS [--cpu-percent=CPU] [flags]</code> | Automatically scale the set of pods that are managed by a replication controller.
`certificate` | `kubectl certificate SUBCOMMAND [options]` | Modify certificate resources.
`cluster-info` | `kubectl cluster-info [flags]` | Display endpoint information about the master and services in the cluster.
`completion` | `kubectl completion SHELL [options]` | Output shell completion code for the specified shell (bash or zsh).
`config` | `kubectl config SUBCOMMAND [flags]` | Modifies kubeconfig files. See the individual subcommands for details.
`convert` | `kubectl convert -f FILENAME [options]` | Convert config files between different API versions. Both YAML and JSON formats are accepted.
`cordon` | `kubectl cordon NODE [options]` | Mark node as unschedulable.
`cp` | `kubectl cp <file-spec-src> <file-spec-dest> [options]` | Copy files and directories to and from containers.
`create` | `kubectl create -f FILENAME [flags]` | Create one or more resources from a file or stdin.
`delete` | <code>kubectl delete (-f FILENAME &#124; TYPE [NAME &#124; /NAME &#124; -l label &#124; --all]) [flags]</code> | Delete resources either from a file, stdin, or specifying label selectors, names, resource selectors, or resources.
`describe` | <code>kubectl describe (-f FILENAME &#124; TYPE [NAME_PREFIX &#124; /NAME &#124; -l label]) [flags]</code> | Display the detailed state of one or more resources.
`diff` | `kubectl diff -f FILENAME [flags]`| Diff file or stdin against live configuration.
`drain` | `kubectl drain NODE [options]` | Drain node in preparation for maintenance.
`edit` | <code>kubectl edit (-f FILENAME &#124; TYPE NAME &#124; TYPE/NAME) [flags]</code> | Edit and update the definition of one or more resources on the server by using the default editor.
`exec` | `kubectl exec POD [-c CONTAINER] [-i] [-t] [flags] [-- COMMAND [args...]]` | Execute a command against a container in a pod.
`explain` | `kubectl explain [--recursive=false] [flags]` | Get documentation of various resources. For instance pods, nodes, services, etc.
`expose` | <code>kubectl expose (-f FILENAME &#124; TYPE NAME &#124; TYPE/NAME) [--port=port] [--protocol=TCP&#124;UDP] [--target-port=number-or-name] [--name=name] [--external-ip=external-ip-of-service] [--type=type] [flags]</code> | Expose a replication controller, service, or pod as a new Kubernetes service.
`get` | <code>kubectl get (-f FILENAME &#124; TYPE [NAME &#124; /NAME &#124; -l label]) [--watch] [--sort-by=FIELD] [[-o &#124; --output]=OUTPUT_FORMAT] [flags]</code> | List one or more resources.
`kustomize` | `kubectl kustomize <dir> [flags] [options]` | List a set of API resources generated from instructions in a kustomization.yaml file. The argument must be the path to the directory containing the file, or a git repository URL with a path suffix specifying same with respect to the repository root.
`label` | <code>kubectl label (-f FILENAME &#124; TYPE NAME &#124; TYPE/NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--overwrite] [--all] [--resource-version=version] [flags]</code> | Add or update the labels of one or more resources.
`logs` | `kubectl logs POD [-c CONTAINER] [--follow] [flags]` | Print the logs for a container in a pod.
`options` | `kubectl options` | List of global command-line options, which apply to all commands.
`patch` | <code>kubectl patch (-f FILENAME &#124; TYPE NAME &#124; TYPE/NAME) --patch PATCH [flags]</code> | Update one or more fields of a resource by using the strategic merge patch process.
`plugin` | `kubectl plugin [flags] [options]` | Provides utilities for interacting with plugins.
`port-forward` | `kubectl port-forward POD [LOCAL_PORT:]REMOTE_PORT [...[LOCAL_PORT_N:]REMOTE_PORT_N] [flags]` | Forward one or more local ports to a pod.
`proxy` | `kubectl proxy [--port=PORT] [--www=static-dir] [--www-prefix=prefix] [--api-prefix=prefix] [flags]` | Run a proxy to the Kubernetes API server.
`replace` | `kubectl replace -f FILENAME` | Replace a resource from a file or stdin.
`rollout` | `kubectl rollout SUBCOMMAND [options]` | Manage the rollout of a resource. Valid resource types include: deployments, daemonsets and statefulsets.
`run` | <code>kubectl run NAME --image=image [--env="key=value"] [--port=port] [--dry-run=server&#124;client&#124;none] [--overrides=inline-json] [flags]</code> | Run a specified image on the cluster.
`scale` | <code>kubectl scale (-f FILENAME &#124; TYPE NAME &#124; TYPE/NAME) --replicas=COUNT [--resource-version=version] [--current-replicas=count] [flags]</code> | Update the size of the specified replication controller.
`set` | `kubectl set SUBCOMMAND [options]` | Configure application resources.
`taint` | `kubectl taint NODE NAME KEY_1=VAL_1:TAINT_EFFECT_1 ... KEY_N=VAL_N:TAINT_EFFECT_N [options]` | Update the taints on one or more nodes.
`top` | `kubectl top [flags] [options]` | Display Resource (CPU/Memory/Storage) usage.
`uncordon` | `kubectl uncordon NODE [options]` | Mark node as schedulable.
`version` | `kubectl version [--client] [flags]` | Display the Kubernetes version running on the client and server.
`wait` | <code>kubectl wait ([-f FILENAME] &#124; resource.group/resource.name &#124; resource.group [(-l label &#124; --all)]) [--for=delete&#124;--for condition=available] [options]</code> | Experimental: Wait for a specific condition on one or many resources.
Remember: For more about command operations, see the [kubectl](/docs/user-guide/kubectl/) reference documentation.

View File

@ -325,7 +325,8 @@ deadlock conditions, kubeadm fails fast if `localhost:10255/healthz` (kubelet li
kubeadm relies on the kubelet to pull the control plane images and run them properly as static Pods.
After the control plane is up, kubeadm completes the tasks described in following paragraphs.
### (optional and alpha in v1.9) Write base kubelet configuration
### (optional) Write base kubelet configuration
{{< feature-state for_k8s_version="v1.9" state="alpha" >}}
If kubeadm is invoked with `--feature-gates=DynamicKubeletConfig`:
@ -516,7 +517,8 @@ Please note that:
access to CSR api during the `kubeadm init` process
- The automatic CSR approval is managed by the csrapprover controller, according with configuration done the `kubeadm init` process
### (optional and alpha in v1.9) Write init kubelet configuration
### (optional) Write init kubelet configuration
{{< feature-state for_k8s_version="v1.9" state="alpha" >}}
If kubeadm is invoked with `--feature-gates=DynamicKubeletConfig`:

View File

@ -37,116 +37,151 @@ See [Installing Minikube](/docs/tasks/tools/install-minikube/).
This brief demo guides you on how to start, use, and delete Minikube locally. Follow the steps given below to start and explore Minikube.
1. Start Minikube and create a cluster:
```shell
minikube start
```
The output is similar to this:
```
Starting local Kubernetes cluster...
Running pre-create checks...
Creating machine...
Starting local Kubernetes cluster...
```
For more information on starting your cluster on a specific Kubernetes version, VM, or container runtime, see [Starting a Cluster](#starting-a-cluster).
```shell
minikube start
```
The output is similar to this:
```
Starting local Kubernetes cluster...
Running pre-create checks...
Creating machine...
Starting local Kubernetes cluster...
```
For more information on starting your cluster on a specific Kubernetes version, VM, or container runtime, see [Starting a Cluster](#starting-a-cluster).
2. Now, you can interact with your cluster using kubectl. For more information, see [Interacting with Your Cluster](#interacting-with-your-cluster).
Lets create a Kubernetes Deployment using an existing image named `echoserver`, which is a simple HTTP server and expose it on port 8080 using `--port`.
```shell
kubectl create deployment hello-minikube --image=k8s.gcr.io/echoserver:1.10
```
The output is similar to this:
```
deployment.apps/hello-minikube created
```
3. To access the `hello-minikube` Deployment, expose it as a Service:
```shell
kubectl expose deployment hello-minikube --type=NodePort --port=8080
```
The option `--type=NodePort` specifies the type of the Service.
Lets create a Kubernetes Deployment using an existing image named `echoserver`, which is a simple HTTP server and expose it on port 8080 using `--port`.
```shell
kubectl create deployment hello-minikube --image=k8s.gcr.io/echoserver:1.10
```
The output is similar to this:
```
deployment.apps/hello-minikube created
```
3. To access the `hello-minikube` Deployment, expose it as a Service:
```shell
kubectl expose deployment hello-minikube --type=NodePort --port=8080
```
The option `--type=NodePort` specifies the type of the Service.
The output is similar to this:
```
service/hello-minikube exposed
```
The output is similar to this:
```
service/hello-minikube exposed
```
4. The `hello-minikube` Pod is now launched but you have to wait until the Pod is up before accessing it via the exposed Service.
Check if the Pod is up and running:
```shell
kubectl get pod
```
If the output shows the `STATUS` as `ContainerCreating`, the Pod is still being created:
```
NAME READY STATUS RESTARTS AGE
hello-minikube-3383150820-vctvh 0/1 ContainerCreating 0 3s
```
If the output shows the `STATUS` as `Running`, the Pod is now up and running:
```
NAME READY STATUS RESTARTS AGE
hello-minikube-3383150820-vctvh 1/1 Running 0 13s
```
Check if the Pod is up and running:
```shell
kubectl get pod
```
If the output shows the `STATUS` as `ContainerCreating`, the Pod is still being created:
```
NAME READY STATUS RESTARTS AGE
hello-minikube-3383150820-vctvh 0/1 ContainerCreating 0 3s
```
If the output shows the `STATUS` as `Running`, the Pod is now up and running:
```
NAME READY STATUS RESTARTS AGE
hello-minikube-3383150820-vctvh 1/1 Running 0 13s
```
5. Get the URL of the exposed Service to view the Service details:
```shell
minikube service hello-minikube --url
```
```shell
minikube service hello-minikube --url
```
6. To view the details of your local cluster, copy and paste the URL you got as the output, on your browser.
The output is similar to this:
```
Hostname: hello-minikube-7c77b68cff-8wdzq
The output is similar to this:
Pod Information:
-no pod information available-
```
Hostname: hello-minikube-7c77b68cff-8wdzq
Server values:
server_version=nginx: 1.13.3 - lua: 10008
Pod Information:
-no pod information available-
Request Information:
client_address=172.17.0.1
method=GET
real path=/
query=
request_version=1.1
request_scheme=http
request_uri=http://192.168.99.100:8080/
Server values:
server_version=nginx: 1.13.3 - lua: 10008
Request Headers:
Request Information:
client_address=172.17.0.1
method=GET
real path=/
query=
request_version=1.1
request_scheme=http
request_uri=http://192.168.99.100:8080/
Request Headers:
accept=*/*
host=192.168.99.100:30674
user-agent=curl/7.47.0
Request Body:
Request Body:
-no body in request-
```
If you no longer want the Service and cluster to run, you can delete them.
```
If you no longer want the Service and cluster to run, you can delete them.
7. Delete the `hello-minikube` Service:
```shell
kubectl delete services hello-minikube
```
The output is similar to this:
```
service "hello-minikube" deleted
```
```shell
kubectl delete services hello-minikube
```
The output is similar to this:
```
service "hello-minikube" deleted
```
8. Delete the `hello-minikube` Deployment:
```shell
kubectl delete deployment hello-minikube
```
The output is similar to this:
```
deployment.extensions "hello-minikube" deleted
```
```shell
kubectl delete deployment hello-minikube
```
The output is similar to this:
```
deployment.extensions "hello-minikube" deleted
```
9. Stop the local Minikube cluster:
```shell
minikube stop
```
The output is similar to this:
```
Stopping "minikube"...
"minikube" stopped.
```
For more information, see [Stopping a Cluster](#stopping-a-cluster).
```shell
minikube stop
```
The output is similar to this:
```
Stopping "minikube"...
"minikube" stopped.
```
For more information, see [Stopping a Cluster](#stopping-a-cluster).
10. Delete the local Minikube cluster:
```shell
minikube delete
```
@ -193,8 +228,8 @@ For example the command would be.
minikube start --driver=<driver_name>
```
Minikube supports the following drivers:
{{< note >}}
See [DRIVERS](https://minikube.sigs.k8s.io/docs/reference/drivers/) for details on supported drivers and how to install
{{< note >}}
See [DRIVERS](https://minikube.sigs.k8s.io/docs/reference/drivers/) for details on supported drivers and how to install
plugins.
{{< /note >}}

View File

@ -21,8 +21,8 @@ A flaw was found in the way runc handled system file descriptors when running co
A malicious container could use this flaw to overwrite contents of the runc binary and
consequently run arbitrary commands on the container host system.
Please refer to this link for more information about this issue
[cve-2019-5736 : runc vulnerability ] (https://access.redhat.com/security/cve/cve-2019-5736)
Please refer to [CVE-2019-5736](https://access.redhat.com/security/cve/cve-2019-5736) for more
information about the issue.
{{< /caution >}}
### Applicability
@ -70,29 +70,39 @@ Keep track of the latest verified Docker version in the Kubernetes release notes
Use the following commands to install Docker on your system:
{{< tabs name="tab-cri-docker-installation" >}}
{{< tab name="Ubuntu 16.04+" codelang="bash" >}}
# Install Docker CE
{{< tab name="Ubuntu 16.04+" >}}
```shell
# (Install Docker CE)
## Set up the repository:
### Install packages to allow apt to use a repository over HTTPS
apt-get update && apt-get install -y \
apt-transport-https ca-certificates curl software-properties-common gnupg2
```
### Add Dockers official GPG key
```shell
# Add Dockers official GPG key:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
```
### Add Docker apt repository.
```shell
# Add the Docker apt repository:
add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
```
## Install Docker CE.
```shell
# Install Docker CE
apt-get update && apt-get install -y \
containerd.io=1.2.13-1 \
docker-ce=5:19.03.8~3-0~ubuntu-$(lsb_release -cs) \
docker-ce-cli=5:19.03.8~3-0~ubuntu-$(lsb_release -cs)
```
# Setup daemon.
```shell
# Set up the Docker daemon
cat > /etc/docker/daemon.json <<EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
@ -103,34 +113,48 @@ cat > /etc/docker/daemon.json <<EOF
"storage-driver": "overlay2"
}
EOF
```
```shell
mkdir -p /etc/systemd/system/docker.service.d
```
# Restart docker.
```shell
# Restart Docker
systemctl daemon-reload
systemctl restart docker
```
{{< /tab >}}
{{< tab name="CentOS/RHEL 7.4+" codelang="bash" >}}
{{< tab name="CentOS/RHEL 7.4+" >}}
# Install Docker CE
```shell
# (Install Docker CE)
## Set up the repository
### Install required packages.
### Install required packages
yum install -y yum-utils device-mapper-persistent-data lvm2
```
### Add Docker repository.
```shell
## Add the Docker repository
yum-config-manager --add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
```
## Install Docker CE.
```shell
# Install Docker CE
yum update -y && yum install -y \
containerd.io-1.2.13 \
docker-ce-19.03.8 \
docker-ce-cli-19.03.8
```
## Create /etc/docker directory.
```shell
## Create /etc/docker
mkdir /etc/docker
```
# Setup daemon.
```shell
# Set up the Docker daemon
cat > /etc/docker/daemon.json <<EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
@ -144,12 +168,17 @@ cat > /etc/docker/daemon.json <<EOF
]
}
EOF
```
```shell
mkdir -p /etc/systemd/system/docker.service.d
```
```shell
# Restart Docker
systemctl daemon-reload
systemctl restart docker
```
{{< /tab >}}
{{< /tabs >}}
@ -173,7 +202,7 @@ For more information, see the [CRI-O compatiblity matrix](https://github.com/cri
modprobe overlay
modprobe br_netfilter
# Setup required sysctl params, these persist across reboots.
# Set up required sysctl params, these persist across reboots.
cat > /etc/sysctl.d/99-kubernetes-cri.conf <<EOF
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
@ -184,54 +213,79 @@ sysctl --system
```
{{< tabs name="tab-cri-cri-o-installation" >}}
{{< tab name="Debian" codelang="bash" >}}
{{< tab name="Debian" >}}
```shell
# Debian Unstable/Sid
echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_Unstable/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/Debian_Unstable/Release.key -O- | sudo apt-key add -
```
```shell
# Debian Testing
echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_Testing/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/Debian_Testing/Release.key -O- | sudo apt-key add -
```
```shell
# Debian 10
echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_10/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/Debian_10/Release.key -O- | sudo apt-key add -
```
```shell
# Raspbian 10
echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Raspbian_10/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/Raspbian_10/Release.key -O- | sudo apt-key add -
```
# Install CRI-O
and then install CRI-O:
```shell
sudo apt-get install cri-o-1.17
```
{{< /tab >}}
{{< tab name="Ubuntu 18.04, 19.04 and 19.10" codelang="bash" >}}
# Setup repository
{{< tab name="Ubuntu 18.04, 19.04 and 19.10" >}}
```shell
# Configure package repository
. /etc/os-release
sudo sh -c "echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/x${NAME}_${VERSION_ID}/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list"
wget -nv https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/x${NAME}_${VERSION_ID}/Release.key -O- | sudo apt-key add -
sudo apt-get update
```
```shell
# Install CRI-O
sudo apt-get install cri-o-1.17
```
{{< /tab >}}
{{< tab name="CentOS/RHEL 7.4+" codelang="bash" >}}
{{< tab name="CentOS/RHEL 7.4+" >}}
```shell
# Install prerequisites
yum-config-manager --add-repo=https://cbs.centos.org/repos/paas7-crio-115-release/x86_64/os/
curl -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable.repo https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/CentOS_7/devel:kubic:libcontainers:stable.repo
curl -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable:cri-o:{{< skew latestVersion >}}.repo https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable:cri-o:{{< skew latestVersion >}}/CentOS_7/devel:kubic:libcontainers:stable:cri-o:{{< skew latestVersion >}}.repo
```
```shell
# Install CRI-O
yum install --nogpgcheck -y cri-o
yum install -y cri-o
```
{{< /tab >}}
{{< tab name="openSUSE Tumbleweed" codelang="bash" >}}
{{< tab name="openSUSE Tumbleweed" >}}
```shell
sudo zypper install cri-o
```
{{< /tab >}}
{{< /tabs >}}
### Start CRI-O
```
```shell
systemctl daemon-reload
systemctl start crio
```
@ -269,51 +323,72 @@ sysctl --system
### Install containerd
{{< tabs name="tab-cri-containerd-installation" >}}
{{< tab name="Ubuntu 16.04" codelang="bash" >}}
# Install containerd
{{< tab name="Ubuntu 16.04" >}}
```shell
# (Install containerd)
## Set up the repository
### Install packages to allow apt to use a repository over HTTPS
apt-get update && apt-get install -y apt-transport-https ca-certificates curl software-properties-common
```
### Add Dockers official GPG key
```shell
## Add Dockers official GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
```
### Add Docker apt repository.
```shell
## Add Docker apt repository.
add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
```
```shell
## Install containerd
apt-get update && apt-get install -y containerd.io
```
```shell
# Configure containerd
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml
```
```shell
# Restart containerd
systemctl restart containerd
```
{{< /tab >}}
{{< tab name="CentOS/RHEL 7.4+" codelang="bash" >}}
# Install containerd
{{< tab name="CentOS/RHEL 7.4+" >}}
```shell
# (Install containerd)
## Set up the repository
### Install required packages
yum install -y yum-utils device-mapper-persistent-data lvm2
### Add docker repository
```shell
## Add docker repository
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
```shell
## Install containerd
yum update -y && yum install -y containerd.io
# Configure containerd
```shell
## Configure containerd
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml
```
```shell
# Restart containerd
systemctl restart containerd
```
{{< /tab >}}
{{< /tabs >}}

View File

@ -303,10 +303,10 @@ Below you can find installation instructions for some popular Pod network plugin
{{% tab name="Calico" %}}
[Calico](https://docs.projectcalico.org/latest/introduction/) is a networking and network policy provider. Calico supports a flexible set of networking options so you can choose the most efficient option for your situation, including non-overlay and overlay networks, with or without BGP. Calico uses the same engine to enforce network policy for hosts, pods, and (if using Istio & Envoy) applications at the service mesh layer. Calico works on several architectures, including `amd64`, `arm64`, and `ppc64le`.
By default, Calico uses `192.168.0.0/16` as the Pod network CIDR, though this can be configured in the calico.yaml file. For Calico to work correctly, you need to pass this same CIDR to the `kubeadm init` command using the `--pod-network-cidr=192.168.0.0/16` flag or via kubeadm's configuration.
Calico will automatically detect which IP address range to use for pod IPs based on the value provided via the `--pod-network-cidr` flag or via kubeadm's configuration.
```shell
kubectl apply -f https://docs.projectcalico.org/v3.11/manifests/calico.yaml
kubectl apply -f https://docs.projectcalico.org/v3.14/manifests/calico.yaml
```
{{% /tab %}}

View File

@ -122,8 +122,8 @@ option. Your cluster requirements may need a different configuration.
{{< /note >}}
{{< note >}}
Some CNI network plugins like Calico require a CIDR such as `192.168.0.0/16` and
some like Weave do not. See the [CNI network documentation](/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/#pod-network).
Some CNI network plugins require additional configuration, for example specifying the pod IP CIDR, while others do not.
See the [CNI network documentation](/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/#pod-network).
To add a pod CIDR pass the flag `--pod-network-cidr`, or if you are using a kubeadm configuration file
set the `podSubnet` field under the `networking` object of `ClusterConfiguration`.
{{< /note >}}

View File

@ -28,7 +28,7 @@ For information how to create a cluster with kubeadm once you have performed thi
* 2 GB or more of RAM per machine (any less will leave little room for your apps)
* 2 CPUs or more
* Full network connectivity between all machines in the cluster (public or private network is fine)
* Unique hostname, MAC address, and product_uuid for every node. See [here](#verify-the-mac-address-and-product-uuid-are-unique-for-every-node) for more details.
* Unique hostname, MAC address, and product_uuid for every node. See [here](#verify-mac-address) for more details.
* Certain ports are open on your machines. See [here](#check-required-ports) for more details.
* Swap disabled. You **MUST** disable swap in order for the kubelet to work properly.
@ -36,7 +36,7 @@ For information how to create a cluster with kubeadm once you have performed thi
{{% capture steps %}}
## Verify the MAC address and product_uuid are unique for every node
## Verify the MAC address and product_uuid are unique for every node {#verify-mac-address}
* You can get the MAC address of the network interfaces using the command `ip link` or `ifconfig -a`
* The product_uuid can be checked by using the command `sudo cat /sys/class/dmi/id/product_uuid`
@ -210,12 +210,14 @@ yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
systemctl enable --now kubelet
```
**Note:**
**Notes:**
- Setting SELinux in permissive mode by running `setenforce 0` and `sed ...` effectively disables it.
This is required to allow containers to access the host filesystem, which is needed by pod networks for example.
You have to do this until SELinux support is improved in the kubelet.
- You can leave SELinux enabled if you know how to configure it but it may require settings that are not supported by kubeadm.
{{% /tab %}}
{{% tab name="Container Linux" %}}
Install CNI plugins (required for most pod network):
@ -303,4 +305,4 @@ If you are running into difficulties with kubeadm, please consult our [troublesh
* [Using kubeadm to Create a Cluster](/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/)
{{% /capture %}}
{{% /capture %}}

View File

@ -21,7 +21,7 @@ Kubespray is a composition of [Ansible](http://docs.ansible.com/) playbooks, [in
* openSUSE Leap 15
* continuous integration tests
To choose a tool which best fits your use case, read [this comparison](https://github.com/kubernetes-sigs/kubespray/blob/master/docs/comparisons.md) to [kubeadm](/docs/admin/kubeadm/) and [kops](../kops).
To choose a tool which best fits your use case, read [this comparison](https://github.com/kubernetes-sigs/kubespray/blob/master/docs/comparisons.md) to [kubeadm](/docs/admin/kubeadm/) and [kops](/docs/setup/production-environment/tools/kops/).
{{% /capture %}}
@ -119,4 +119,4 @@ When running the reset playbook, be sure not to accidentally target your product
Check out planned work on Kubespray's [roadmap](https://github.com/kubernetes-sigs/kubespray/blob/master/docs/roadmap.md).
{{% /capture %}}
{{% /capture %}}

View File

@ -277,7 +277,7 @@ This shows the proxy-verb URL for accessing each service.
For example, this cluster has cluster-level logging enabled (using Elasticsearch), which can be reached
at `https://104.197.5.247/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/` if suitable credentials are passed. Logging can also be reached through a kubectl proxy, for example at:
`http://localhost:8080/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/`.
(See [above](#accessing-the-cluster-api) for how to pass credentials or use kubectl proxy.)
(See [Access Clusters Using the Kubernetes API](/docs/tasks/administer-cluster/access-cluster-api/) for how to pass credentials or use kubectl proxy.)
#### Manually constructing apiserver proxy URLs
@ -376,4 +376,4 @@ There are several different proxies you may encounter when using Kubernetes:
Kubernetes users will typically not need to worry about anything other than the first two types. The cluster admin
will typically ensure that the latter types are setup correctly.
{{% /capture %}}
{{% /capture %}}

View File

@ -97,7 +97,7 @@ If needed, you can expand the **Advanced options** section where you can specify
Example:
```conf
```conf
release=1.0
tier=frontend
environment=pod

View File

@ -28,6 +28,7 @@ into the Kubernetes API by creating a
{{% /capture %}}
{{% capture steps %}}
## Create a CustomResourceDefinition
When you create a new CustomResourceDefinition (CRD), the Kubernetes API Server
@ -41,6 +42,7 @@ For example, if you save the following CustomResourceDefinition to `resourcedefi
{{< tabs name="CustomResourceDefinition_example_1" >}}
{{% tab name="apiextensions.k8s.io/v1" %}}
```yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
@ -83,8 +85,10 @@ spec:
shortNames:
- ct
```
{{% /tab %}}
{{% tab name="apiextensions.k8s.io/v1beta1" %}}
```yaml
# Deprecated in v1.16 in favor of apiextensions.k8s.io/v1
apiVersion: apiextensions.k8s.io/v1beta1
@ -129,6 +133,7 @@ spec:
replicas:
type: integer
```
{{% /tab %}}
{{< /tabs >}}
@ -188,7 +193,7 @@ kubectl get crontab
Should print a list like this:
```console
```none
NAME AGE
my-new-cron-object 6s
```
@ -205,7 +210,7 @@ kubectl get ct -o yaml
You should see that it contains the custom `cronSpec` and `image` fields
from the yaml you used to create it:
```console
```yaml
apiVersion: v1
kind: List
items:
@ -228,14 +233,14 @@ metadata:
## Delete a CustomResourceDefinition
When you delete a CustomResourceDefinition, the server will uninstall the RESTful API endpoint
and **delete all custom objects stored in it**.
and delete all custom objects stored in it.
```shell
kubectl delete -f resourcedefinition.yaml
kubectl get crontabs
```
```console
```none
Error from server (NotFound): Unable to list {"stable.example.com" "v1" "crontabs"}: the server could not find the requested resource (get crontabs.stable.example.com)
```
@ -362,7 +367,7 @@ Structural schemas are a requirement for `apiextensions.k8s.io/v1`, and disables
* [Webhook Conversion](/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definition-versioning/#webhook-conversion)
* [Pruning](#preserving-unknown-fields)
### Pruning versus preserving unknown fields
### Pruning versus preserving unknown fields {#preserving-unknown-fields}
{{< feature-state state="stable" for_k8s_version="v1.16" >}}
@ -630,7 +635,9 @@ These fields can only be set with specific features enabled:
- `default`: can be set for `apiextensions.k8s.io/v1` CustomResourceDefinitions. Defaulting is in GA since 1.17 (beta since 1.16 with the `CustomResourceDefaulting` feature gate to be enabled, which is the case automatically for many clusters for beta features). Compare [Validation Schema Defaulting](/docs/tasks/access-kubernetes-api/extend-api-custom-resource-definitions/#defaulting).
Note: compare with [structural schemas](#specifying-a-structural-schema) for further restriction required for certain CustomResourceDefinition features.
{{< note >}}
Compare with [structural schemas](#specifying-a-structural-schema) for further restriction required for certain CustomResourceDefinition features.
{{< /note >}}
The schema is defined in the CustomResourceDefinition. In the following example, the
CustomResourceDefinition applies the following validations on the custom object:
@ -642,6 +649,7 @@ Save the CustomResourceDefinition to `resourcedefinition.yaml`:
{{< tabs name="CustomResourceDefinition_validation" >}}
{{% tab name="apiextensions.k8s.io/v1" %}}
```yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
@ -676,8 +684,10 @@ spec:
shortNames:
- ct
```
{{% /tab %}}
{{% tab name="apiextensions.k8s.io/v1beta1" %}}
```yaml
# Deprecated in v1.16 in favor of apiextensions.k8s.io/v1
apiVersion: apiextensions.k8s.io/v1beta1
@ -714,6 +724,7 @@ spec:
minimum: 1
maximum: 10
```
{{% /tab %}}
{{< /tabs >}}
@ -852,7 +863,7 @@ spec:
replicas: 1
```
Note that defaulting happens on the object
Defaulting happens on the object
* in the request to the API server using the request version defaults,
* when reading from etcd using the storage version defaults,
@ -895,9 +906,11 @@ columns are shown by the `kubectl get` command. You can customize these columns
CustomResourceDefinition. The following example adds the `Spec`, `Replicas`, and `Age`
columns.
1. Save the CustomResourceDefinition to `resourcedefinition.yaml`.
{{< tabs name="CustomResourceDefinition_printer_columns" >}}
{{% tab name="apiextensions.k8s.io/v1" %}}
Save the CustomResourceDefinition to `resourcedefinition.yaml`:
{{< tabs name="CustomResourceDefinition_printer_columns" >}}
{{% tab name="apiextensions.k8s.io/v1" %}}
```yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
@ -942,8 +955,10 @@ spec:
type: date
jsonPath: .metadata.creationTimestamp
```
{{% /tab %}}
{{% tab name="apiextensions.k8s.io/v1beta1" %}}
{{% /tab %}}
{{% tab name="apiextensions.k8s.io/v1beta1" %}}
```yaml
# Deprecated in v1.16 in favor of apiextensions.k8s.io/v1
apiVersion: apiextensions.k8s.io/v1beta1
@ -986,31 +1001,34 @@ spec:
type: date
JSONPath: .metadata.creationTimestamp
```
{{% /tab %}}
{{< /tabs >}}
2. Create the CustomResourceDefinition:
{{% /tab %}}
{{< /tabs >}}
```shell
kubectl apply -f resourcedefinition.yaml
```
Create the CustomResourceDefinition:
3. Create an instance using the `my-crontab.yaml` from the previous section.
```shell
kubectl apply -f resourcedefinition.yaml
```
4. Invoke the server-side printing:
Create an instance using the `my-crontab.yaml` from the previous section.
```shell
kubectl get crontab my-new-cron-object
```
Invoke the server-side printing:
Notice the `NAME`, `SPEC`, `REPLICAS`, and `AGE` columns in the output:
```shell
kubectl get crontab my-new-cron-object
```
```
NAME SPEC REPLICAS AGE
my-new-cron-object * * * * * 1 7s
```
Notice the `NAME`, `SPEC`, `REPLICAS`, and `AGE` columns in the output:
```
NAME SPEC REPLICAS AGE
my-new-cron-object * * * * * 1 7s
```
{{< note >}}
The `NAME` column is implicit and does not need to be defined in the CustomResourceDefinition.
{{< /note >}}
#### Priority
@ -1133,6 +1151,7 @@ Save the CustomResourceDefinition to `resourcedefinition.yaml`:
{{< tabs name="CustomResourceDefinition_scale" >}}
{{% tab name="apiextensions.k8s.io/v1" %}}
```yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
@ -1184,8 +1203,10 @@ spec:
shortNames:
- ct
```
{{% /tab %}}
{{% tab name="apiextensions.k8s.io/v1beta1" %}}
```yaml
# Deprecated in v1.16 in favor of apiextensions.k8s.io/v1
apiVersion: apiextensions.k8s.io/v1beta1
@ -1238,6 +1259,7 @@ spec:
# labelSelectorPath defines the JSONPath inside of a custom resource that corresponds to Scale.Status.Selector.
labelSelectorPath: .status.labelSelector
```
{{% /tab %}}
{{< /tabs >}}
@ -1307,6 +1329,7 @@ Save the following CustomResourceDefinition to `resourcedefinition.yaml`:
{{< tabs name="CustomResourceDefinition_categories" >}}
{{% tab name="apiextensions.k8s.io/v1" %}}
```yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
@ -1342,8 +1365,10 @@ spec:
categories:
- all
```
{{% /tab %}}
{{% tab name="apiextensions.k8s.io/v1beta1" %}}
```yaml
# Deprecated in v1.16 in favor of apiextensions.k8s.io/v1
apiVersion: apiextensions.k8s.io/v1beta1
@ -1380,6 +1405,7 @@ spec:
categories:
- all
```
{{% /tab %}}
{{< /tabs >}}
@ -1431,4 +1457,4 @@ crontabs/my-new-cron-object 3s
* Serve [multiple versions](/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definition-versioning/) of a
CustomResourceDefinition.
{{% /capture %}}
{{% /capture %}}

View File

@ -62,12 +62,12 @@ but not both in the same item).
The first provider in the list is used to encrypt resources going into storage. When reading
resources from storage each provider that matches the stored data attempts to decrypt the data in
order. If no provider can read the stored data due to a mismatch in format or secret key, an error
is returned which prevents clients from accessing that resource.
order. If no provider can read the stored data due to a mismatch in format or secret key, an error
is returned which prevents clients from accessing that resource.
{{< caution >}}
**IMPORTANT:** If any resource is not readable via the encryption config (because keys were changed),
the only recourse is to delete that key from the underlying etcd directly. Calls that attempt to
**IMPORTANT:** If any resource is not readable via the encryption config (because keys were changed),
the only recourse is to delete that key from the underlying etcd directly. Calls that attempt to
read that resource will fail until it is deleted or a valid decryption key is provided.
{{< /caution >}}
@ -117,9 +117,9 @@ To create a new secret perform the following steps:
1. Generate a 32 byte random key and base64 encode it. If you're on Linux or macOS, run the following command:
```
head -c 32 /dev/urandom | base64
```
```shell
head -c 32 /dev/urandom | base64
```
2. Place that value in the secret field.
3. Set the `--encryption-provider-config` flag on the `kube-apiserver` to point to the location of the config file.
@ -138,39 +138,42 @@ program to retrieve the contents of your secret.
1. Create a new secret called `secret1` in the `default` namespace:
```
kubectl create secret generic secret1 -n default --from-literal=mykey=mydata
```
```shell
kubectl create secret generic secret1 -n default --from-literal=mykey=mydata
```
2. Using the etcdctl commandline, read that secret out of etcd:
```
   ETCDCTL_API=3 etcdctl get /registry/secrets/default/secret1 [...] | hexdump -C
```
`ETCDCTL_API=3 etcdctl get /registry/secrets/default/secret1 [...] | hexdump -C`
where `[...]` must be the additional arguments for connecting to the etcd server.
3. Verify the stored secret is prefixed with `k8s:enc:aescbc:v1:` which indicates the `aescbc` provider has encrypted the resulting data.
where `[...]` must be the additional arguments for connecting to the etcd server.
3. Verify the stored secret is prefixed with `k8s:enc:aescbc:v1:` which indicates the `aescbc` provider has encrypted the resulting data.
4. Verify the secret is correctly decrypted when retrieved via the API:
```
kubectl describe secret secret1 -n default
```
```shell
kubectl describe secret secret1 -n default
```
should match `mykey: bXlkYXRh`, mydata is encoded, check [decoding a secret](/docs/concepts/configuration/secret#decoding-a-secret) to
completely decode the secret.
should match `mykey: bXlkYXRh`, mydata is encoded, check [decoding a secret](/docs/concepts/configuration/secret#decoding-a-secret) to
completely decode the secret.
## Ensure all secrets are encrypted
Since secrets are encrypted on write, performing an update on a secret will encrypt that content.
```
```shell
kubectl get secrets --all-namespaces -o json | kubectl replace -f -
```
The command above reads all secrets and then updates them to apply server side encryption.
{{< note >}}
If an error occurs due to a conflicting write, retry the command.
For larger clusters, you may wish to subdivide the secrets by namespace or script an update.
{{< /note >}}
## Rotating a decryption key
@ -206,7 +209,10 @@ resources:
secret: <BASE 64 ENCODED SECRET>
```
and restart all `kube-apiserver` processes. Then run the command `kubectl get secrets --all-namespaces -o json | kubectl replace -f -`
and restart all `kube-apiserver` processes. Then run:
```shell
kubectl get secrets --all-namespaces -o json | kubectl replace -f -
```
to force all secrets to be decrypted.
{{% /capture %}}

View File

@ -50,59 +50,59 @@ The upgrade workflow at high level is the following:
## Determine which version to upgrade to
1. Find the latest stable 1.18 version:
Find the latest stable 1.18 version:
{{< tabs name="k8s_install_versions" >}}
{{% tab name="Ubuntu, Debian or HypriotOS" %}}
{{< tabs name="k8s_install_versions" >}}
{{% tab name="Ubuntu, Debian or HypriotOS" %}}
apt update
apt-cache madison kubeadm
# find the latest 1.18 version in the list
# it should look like 1.18.x-00, where x is the latest patch
{{% /tab %}}
{{% tab name="CentOS, RHEL or Fedora" %}}
{{% /tab %}}
{{% tab name="CentOS, RHEL or Fedora" %}}
yum list --showduplicates kubeadm --disableexcludes=kubernetes
# find the latest 1.18 version in the list
# it should look like 1.18.x-0, where x is the latest patch
{{% /tab %}}
{{< /tabs >}}
{{% /tab %}}
{{< /tabs >}}
## Upgrading control plane nodes
### Upgrade the first control plane node
1. On your first control plane node, upgrade kubeadm:
- On your first control plane node, upgrade kubeadm:
{{< tabs name="k8s_install_kubeadm_first_cp" >}}
{{% tab name="Ubuntu, Debian or HypriotOS" %}}
{{< tabs name="k8s_install_kubeadm_first_cp" >}}
{{% tab name="Ubuntu, Debian or HypriotOS" %}}
# replace x in 1.18.x-00 with the latest patch version
apt-mark unhold kubeadm && \
apt-get update && apt-get install -y kubeadm=1.18.x-00 && \
apt-mark hold kubeadm
-
# since apt-get version 1.1 you can also use the following method
apt-get update && \
apt-get install -y --allow-change-held-packages kubeadm=1.18.x-00
{{% /tab %}}
{{% tab name="CentOS, RHEL or Fedora" %}}
{{% /tab %}}
{{% tab name="CentOS, RHEL or Fedora" %}}
# replace x in 1.18.x-0 with the latest patch version
yum install -y kubeadm-1.18.x-0 --disableexcludes=kubernetes
{{% /tab %}}
{{< /tabs >}}
{{% /tab %}}
{{< /tabs >}}
1. Verify that the download works and has the expected version:
- Verify that the download works and has the expected version:
```shell
kubeadm version
```
1. Drain the control plane node:
- Drain the control plane node:
```shell
# replace <cp-node-name> with the name of your control plane node
kubectl drain <cp-node-name> --ignore-daemonsets
```
1. On the control plane node, run:
- On the control plane node, run:
```shell
sudo kubeadm upgrade plan
@ -145,13 +145,13 @@ The upgrade workflow at high level is the following:
This command checks that your cluster can be upgraded, and fetches the versions you can upgrade to.
{{< note >}}
`kubeadm upgrade` also automatically renews the certificates that it manages on this node.
To opt-out of certificate renewal the flag `--certificate-renewal=false` can be used.
For more information see the [certificate management guide](/docs/tasks/administer-cluster/kubeadm/kubeadm-certs).
{{</ note >}}
{{< note >}}
`kubeadm upgrade` also automatically renews the certificates that it manages on this node.
To opt-out of certificate renewal the flag `--certificate-renewal=false` can be used.
For more information see the [certificate management guide](/docs/tasks/administer-cluster/kubeadmkubeadm-certs).
{{</ note >}}
1. Choose a version to upgrade to, and run the appropriate command. For example:
- Choose a version to upgrade to, and run the appropriate command. For example:
```shell
# replace x with the patch version you picked for this upgrade
@ -240,7 +240,7 @@ The upgrade workflow at high level is the following:
[upgrade/kubelet] Now that your control plane is upgraded, please proceed with upgrading your kubelets if you haven't already done so.
```
1. Manually upgrade your CNI provider plugin.
- Manually upgrade your CNI provider plugin.
Your Container Network Interface (CNI) provider may have its own upgrade instructions to follow.
Check the [addons](/docs/concepts/cluster-administration/addons/) page to
@ -248,7 +248,7 @@ The upgrade workflow at high level is the following:
This step is not required on additional control plane nodes if the CNI provider runs as a DaemonSet.
1. Uncordon the control plane node:
- Uncordon the control plane node:
```shell
# replace <cp-node-name> with the name of your control plane node
@ -257,46 +257,46 @@ The upgrade workflow at high level is the following:
### Upgrade additional control plane nodes
1. Same as the first control plane node but use:
Same as the first control plane node but use:
```
sudo kubeadm upgrade node
```
```
sudo kubeadm upgrade node
```
instead of:
instead of:
```
sudo kubeadm upgrade apply
```
```
sudo kubeadm upgrade apply
```
Also `sudo kubeadm upgrade plan` is not needed.
Also `sudo kubeadm upgrade plan` is not needed.
### Upgrade kubelet and kubectl
1. Upgrade the kubelet and kubectl on all control plane nodes:
Upgrade the kubelet and kubectl on all control plane nodes:
{{< tabs name="k8s_install_kubelet" >}}
{{% tab name="Ubuntu, Debian or HypriotOS" %}}
{{< tabs name="k8s_install_kubelet" >}}
{{% tab name="Ubuntu, Debian or HypriotOS" %}}
# replace x in 1.18.x-00 with the latest patch version
apt-mark unhold kubelet kubectl && \
apt-get update && apt-get install -y kubelet=1.18.x-00 kubectl=1.18.x-00 && \
apt-mark hold kubelet kubectl
-
# since apt-get version 1.1 you can also use the following method
apt-get update && \
apt-get install -y --allow-change-held-packages kubelet=1.18.x-00 kubectl=1.18.x-00
{{% /tab %}}
{{% tab name="CentOS, RHEL or Fedora" %}}
{{% /tab %}}
{{% tab name="CentOS, RHEL or Fedora" %}}
# replace x in 1.18.x-0 with the latest patch version
yum install -y kubelet-1.18.x-0 kubectl-1.18.x-0 --disableexcludes=kubernetes
{{% /tab %}}
{{< /tabs >}}
{{% /tab %}}
{{< /tabs >}}
1. Restart the kubelet
Restart the kubelet
```shell
sudo systemctl restart kubelet
```
```shell
sudo systemctl restart kubelet
```
## Upgrade worker nodes
@ -305,28 +305,28 @@ without compromising the minimum required capacity for running your workloads.
### Upgrade kubeadm
1. Upgrade kubeadm on all worker nodes:
- Upgrade kubeadm on all worker nodes:
{{< tabs name="k8s_install_kubeadm_worker_nodes" >}}
{{% tab name="Ubuntu, Debian or HypriotOS" %}}
{{< tabs name="k8s_install_kubeadm_worker_nodes" >}}
{{% tab name="Ubuntu, Debian or HypriotOS" %}}
# replace x in 1.18.x-00 with the latest patch version
apt-mark unhold kubeadm && \
apt-get update && apt-get install -y kubeadm=1.18.x-00 && \
apt-mark hold kubeadm
-
# since apt-get version 1.1 you can also use the following method
apt-get update && \
apt-get install -y --allow-change-held-packages kubeadm=1.18.x-00
{{% /tab %}}
{{% tab name="CentOS, RHEL or Fedora" %}}
{{% /tab %}}
{{% tab name="CentOS, RHEL or Fedora" %}}
# replace x in 1.18.x-0 with the latest patch version
yum install -y kubeadm-1.18.x-0 --disableexcludes=kubernetes
{{% /tab %}}
{{< /tabs >}}
{{% /tab %}}
{{< /tabs >}}
### Drain the node
1. Prepare the node for maintenance by marking it unschedulable and evicting the workloads:
- Prepare the node for maintenance by marking it unschedulable and evicting the workloads:
```shell
# replace <node-to-drain> with the name of your node you are draining
@ -343,7 +343,7 @@ without compromising the minimum required capacity for running your workloads.
### Upgrade the kubelet configuration
1. Call the following command:
- Call the following command:
```shell
sudo kubeadm upgrade node
@ -351,26 +351,26 @@ without compromising the minimum required capacity for running your workloads.
### Upgrade kubelet and kubectl
1. Upgrade the kubelet and kubectl on all worker nodes:
- Upgrade the kubelet and kubectl on all worker nodes:
{{< tabs name="k8s_kubelet_and_kubectl" >}}
{{% tab name="Ubuntu, Debian or HypriotOS" %}}
{{< tabs name="k8s_kubelet_and_kubectl" >}}
{{% tab name="Ubuntu, Debian or HypriotOS" %}}
# replace x in 1.18.x-00 with the latest patch version
apt-mark unhold kubelet kubectl && \
apt-get update && apt-get install -y kubelet=1.18.x-00 kubectl=1.18.x-00 && \
apt-mark hold kubelet kubectl
-
# since apt-get version 1.1 you can also use the following method
apt-get update && \
apt-get install -y --allow-change-held-packages kubelet=1.18.x-00 kubectl=1.18.x-00
{{% /tab %}}
{{% tab name="CentOS, RHEL or Fedora" %}}
{{% /tab %}}
{{% tab name="CentOS, RHEL or Fedora" %}}
# replace x in 1.18.x-0 with the latest patch version
yum install -y kubelet-1.18.x-0 kubectl-1.18.x-0 --disableexcludes=kubernetes
{{% /tab %}}
{{< /tabs >}}
{{% /tab %}}
{{< /tabs >}}
1. Restart the kubelet
- Restart the kubelet
```shell
sudo systemctl restart kubelet
@ -378,7 +378,7 @@ without compromising the minimum required capacity for running your workloads.
### Uncordon the node
1. Bring the node back online by marking it schedulable:
- Bring the node back online by marking it schedulable:
```shell
# replace <node-to-drain> with the name of your node
@ -441,4 +441,4 @@ and post-upgrade manifest file for a certain component, a backup file for it wil
`kubeadm upgrade node` does the following on worker nodes:
- Fetches the kubeadm `ClusterConfiguration` from the cluster.
- Upgrades the kubelet configuration for this node.
- Upgrades the kubelet configuration for this node.

View File

@ -70,10 +70,10 @@ and is overridden by command-line flags. Unspecified values in the new configura
will receive default values appropriate to the configuration version
(e.g. `kubelet.config.k8s.io/v1beta1`), unless overridden by flags.
The status of the Node's kubelet configuration is reported via
The status of the Node's kubelet configuration is reported via
`Node.Spec.Status.Config`. Once you have updated a Node to use the new
ConfigMap, you can observe this status to confirm that the Node is using the
intended configuration.
intended configuration.
This document describes editing Nodes using `kubectl edit`.
There are other ways to modify a Node's spec, including `kubectl patch`, for
@ -136,7 +136,7 @@ adapt the steps if you prefer to extract the `kubeletconfig` subobject manually.
1. Choose a Node to reconfigure. In this example, the name of this Node is
referred to as `NODE_NAME`.
2. Start the kubectl proxy in the background using the following command:
2. Start the kubectl proxy in the background using the following command:
```bash
kubectl proxy --port=8001 &
@ -236,8 +236,8 @@ Retrieve the Node using the `kubectl get node ${NODE_NAME} -o yaml` command and
The`lastKnownGood` configuration might not be present if it is set to its default value,
the local config deployed with the node. The status will update `lastKnownGood` to
match a valid `assigned` config after the kubelet becomes comfortable with the config.
The details of how the kubelet determines a config should become the `lastKnownGood` are
match a valid `assigned` config after the kubelet becomes comfortable with the config.
The details of how the kubelet determines a config should become the `lastKnownGood` are
not guaranteed by the API, but is currently implemented as a 10-minute grace period.
You can use the following command (using `jq`) to filter down
@ -287,7 +287,7 @@ by eye).
If an error occurs, the kubelet reports it in the `Node.Status.Config.Error`
structure. Possible errors are listed in
[Understanding Node.Status.Config.Error messages](#understanding-node-status-config-error-messages).
[Understanding Node.Status.Config.Error messages](#understanding-node-config-status-errors).
You can search for the identical text in the kubelet log for additional details
and context about the error.
@ -355,7 +355,7 @@ metadata and checkpoints. The structure of the kubelet's checkpointing directory
| - ...
```
## Understanding Node.Status.Config.Error messages
## Understanding Node.Status.Config.Error messages {#understanding-node-config-status-errors}
The following table describes error messages that can occur
when using Dynamic Kubelet Config. You can search for the identical text
@ -379,4 +379,4 @@ internal failure, see Kubelet log for details | The kubelet encountered some int
- For more information on configuring the kubelet via a configuration file, see
[Set kubelet parameters via a config file](/docs/tasks/administer-cluster/kubelet-config-file).
- See the reference documentation for [`NodeConfigSource`](https://kubernetes.io/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#nodeconfigsource-v1-core)
{{% /capture %}}
{{% /capture %}}

View File

@ -173,7 +173,7 @@ For example: in Centos, you can do this using the tuned toolset.
Memory pressure at the node level leads to System OOMs which affects the entire
node and all pods running on it. Nodes can go offline temporarily until memory
has been reclaimed. To avoid (or reduce the probability of) system OOMs kubelet
provides [`Out of Resource`](./out-of-resource.md) management. Evictions are
provides [`Out of Resource`](/docs/tasks/administer-cluster/out-of-resource/) management. Evictions are
supported for `memory` and `ephemeral-storage` only. By reserving some memory via
`--eviction-hard` flag, the `kubelet` attempts to `evict` pods whenever memory
availability on the node drops below the reserved value. Hypothetically, if
@ -190,7 +190,7 @@ The scheduler treats `Allocatable` as the available `capacity` for pods.
`kubelet` enforce `Allocatable` across pods by default. Enforcement is performed
by evicting pods whenever the overall usage across all pods exceeds
`Allocatable`. More details on eviction policy can be found
[here](./out-of-resource.md#eviction-policy). This enforcement is controlled by
[here](/docs/tasks/administer-cluster/out-of-resource/#eviction-policy). This enforcement is controlled by
specifying `pods` value to the kubelet flag `--enforce-node-allocatable`.
@ -251,4 +251,4 @@ If `kube-reserved` and/or `system-reserved` is not enforced and system daemons
exceed their reservation, `kubelet` evicts pods whenever the overall node memory
usage is higher than `31.5Gi` or `storage` is greater than `90Gi`
{{% /capture %}}
{{% /capture %}}

View File

@ -180,9 +180,6 @@ The output shows that the Pod status is Pending. That is, the Pod has not been
scheduled to run on any Node, and it will remain in the Pending state indefinitely:
```shell
kubectl get pod cpu-demo-2 --namespace=cpu-example
```
```
NAME READY STATUS RESTARTS AGE
cpu-demo-2 0/1 Pending 0 7m

View File

@ -16,6 +16,10 @@ This page shows how to use the `runAsUserName` setting for Pods and containers t
You need to have a Kubernetes cluster and the kubectl command-line tool must be configured to communicate with your cluster. The cluster is expected to have Windows worker nodes where pods with containers running Windows workloads will get scheduled.
{{% /capture %}}
{{% capture steps %}}
## Set the Username for a Pod
To specify the username with which to execute the Pod's container processes, include the `securityContext` field ([PodSecurityContext](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podsecuritycontext-v1-core) in the Pod specification, and within it, the `windowsOptions` ([WindowsSecurityContextOptions](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#windowssecuritycontextoptions-v1-core) field containing the `runAsUserName` field.
@ -118,4 +122,4 @@ For more information about these limtations, check [here](https://support.micros
* [Managing Workload Identity with Group Managed Service Accounts (GMSA)](/docs/setup/production-environment/windows/user-guide-windows-containers/#managing-workload-identity-with-group-managed-service-accounts)
* [Configure GMSA for Windows pods and containers](/docs/tasks/configure-pod-container/configure-gmsa/)
{{% /capture %}}
{{% /capture %}}

View File

@ -183,27 +183,38 @@ The content of `token` is elided here.
## Add ImagePullSecrets to a service account
First, create an imagePullSecret, as described [here](/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod).
Next, verify it has been created. For example:
### Create an imagePullSecret
```shell
kubectl get secrets myregistrykey
```
- Create an imagePullSecret, as described in [Specifying ImagePullSecrets on a Pod](/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod).
The output is similar to this:
```shell
kubectl create secret docker-registry myregistrykey --docker-server=DUMMY_SERVER \
--docker-username=DUMMY_USERNAME --docker-password=DUMMY_DOCKER_PASSWORD \
--docker-email=DUMMY_DOCKER_EMAIL
```
```
NAME TYPE DATA AGE
myregistrykey   kubernetes.io/.dockerconfigjson   1       1d
```
- Verify it has been created.
```shell
kubectl get secrets myregistrykey
```
The output is similar to this:
```
NAME TYPE DATA AGE
myregistrykey   kubernetes.io/.dockerconfigjson   1       1d
```
### Add image pull secret to service account
Next, modify the default service account for the namespace to use this secret as an imagePullSecret.
```shell
kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "myregistrykey"}]}'
```
Interactive version requires manual edit:
You can instead use `kubectl edit`, or manually edit the YAML manifests as shown below:
```shell
kubectl get serviceaccounts default -o yaml > ./sa.yaml
@ -248,12 +259,19 @@ Finally replace the serviceaccount with the new updated `sa.yaml` file
kubectl replace serviceaccount default -f ./sa.yaml
```
Now, any new pods created in the current namespace will have this added to their spec:
### Verify imagePullSecrets was added to pod spec
```yaml
spec:
imagePullSecrets:
- name: myregistrykey
Now, when a new Pod is created in the current namespace and using the default ServiceAccount, the new Pod has its `spec.imagePullSecrets` field set automatically:
```shell
kubectl run nginx --image=nginx --restart=Never
kubectl get pod nginx -o=jsonpath='{.spec.imagePullSecrets[0].name}{"\n"}'
```
The output is:
```
myregistrykey
```
<!--## Adding Secrets to a service account.

View File

@ -45,8 +45,7 @@ probably debugging your own Service you can substitute your own details, or you
can follow along and get a second data point.
```shell
kubectl run hostnames --image=k8s.gcr.io/serve_hostname \
--replicas=3
kubectl create deployment hostnames --image=k8s.gcr.io/serve_hostname
```
```none
deployment.apps/hostnames created
@ -54,6 +53,14 @@ deployment.apps/hostnames created
`kubectl` commands will print the type and name of the resource created or mutated, which can then be used in subsequent commands.
Let's scale the deployment to 3 replicas.
```shell
kubectl scale deployment hostnames --replicas=3
```
```none
deployment.apps/hostnames scaled
```
{{< note >}}
This is the same as if you had started the Deployment with the following
YAML:
@ -62,30 +69,32 @@ YAML:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: hostnames
name: hostnames
spec:
selector:
matchLabels:
run: hostnames
app: hostnames
replicas: 3
template:
metadata:
labels:
run: hostnames
app: hostnames
spec:
containers:
- name: hostnames
image: k8s.gcr.io/serve_hostname
```
The label "run" is automatically set by `kubectl run` to the name of the
The label "app" is automatically set by `kubectl create deployment` to the name of the
Deployment.
{{< /note >}}
You can confirm your Pods are running:
```shell
kubectl get pods -l run=hostnames
kubectl get pods -l app=hostnames
```
```none
NAME READY STATUS RESTARTS AGE
@ -98,7 +107,7 @@ You can also confirm that your Pods are serving. You can get the list of
Pod IP addresses and test them directly.
```shell
kubectl get pods -l run=hostnames \
kubectl get pods -l app=hostnames \
-o go-template='{{range .items}}{{.status.podIP}}{{"\n"}}{{end}}'
```
```none
@ -122,9 +131,9 @@ done
This should produce something like:
```
hostnames-0uton
hostnames-bvc05
hostnames-yp2kp
hostnames-632524106-bbpiw
hostnames-632524106-ly40y
hostnames-632524106-tlaok
```
If you are not getting the responses you expect at this point, your Pods
@ -193,10 +202,12 @@ As before, this is the same as if you had started the Service with YAML:
apiVersion: v1
kind: Service
metadata:
labels:
app: hostnames
name: hostnames
spec:
selector:
run: hostnames
app: hostnames
ports:
- name: default
protocol: TCP
@ -345,9 +356,9 @@ done
This should produce something like:
```
hostnames-0uton
hostnames-bvc05
hostnames-yp2kp
hostnames-632524106-bbpiw
hostnames-632524106-ly40y
hostnames-632524106-tlaok
```
If your Service is working, you should get correct responses. If not, there
@ -373,7 +384,7 @@ kubectl get service hostnames -o json
"resourceVersion": "347189",
"creationTimestamp": "2015-07-07T15:24:29Z",
"labels": {
"run": "hostnames"
"app": "hostnames"
}
},
"spec": {
@ -387,7 +398,7 @@ kubectl get service hostnames -o json
}
],
"selector": {
"run": "hostnames"
"app": "hostnames"
},
"clusterIP": "10.0.1.175",
"type": "ClusterIP",
@ -414,16 +425,16 @@ actually being selected by the Service.
Earlier you saw that the Pods were running. You can re-check that:
```shell
kubectl get pods -l run=hostnames
kubectl get pods -l app=hostnames
```
```none
NAME READY STATUS RESTARTS AGE
hostnames-0uton 1/1 Running 0 1h
hostnames-bvc05 1/1 Running 0 1h
hostnames-yp2kp 1/1 Running 0 1h
hostnames-632524106-bbpiw 1/1 Running 0 1h
hostnames-632524106-ly40y 1/1 Running 0 1h
hostnames-632524106-tlaok 1/1 Running 0 1h
```
The `-l run=hostnames` argument is a label selector - just like our Service
The `-l app=hostnames` argument is a label selector - just like our Service
has.
The "AGE" column says that these Pods are about an hour old, which implies that
@ -448,7 +459,8 @@ your Service. If the `ENDPOINTS` column is `<none>`, you should check that
the `spec.selector` field of your Service actually selects for
`metadata.labels` values on your Pods. A common mistake is to have a typo or
other error, such as the Service selecting for `app=hostnames`, but the
Deployment specifying `run=hostnames`.
Deployment specifying `run=hostnames`, as in versions previous to 1.18, where
the `kubectl run` command could have been also used to create a Deployment.
## Are the Pods working?
@ -473,9 +485,9 @@ done
This should produce something like:
```
hostnames-0uton
hostnames-bvc05
hostnames-yp2kp
hostnames-632524106-bbpiw
hostnames-632524106-ly40y
hostnames-632524106-tlaok
```
You expect each Pod in the Endpoints list to return its own hostname. If
@ -617,7 +629,7 @@ IP from one of your Nodes:
curl 10.0.1.175:80
```
```none
hostnames-0uton
hostnames-632524106-bbpiw
```
If this fails and you are using the userspace proxy, you can try accessing the
@ -631,7 +643,7 @@ examples it is "48577". Now connect to that:
curl localhost:48577
```
```none
hostnames-yp2kp
hostnames-632524106-tlaok
```
If this still fails, look at the `kube-proxy` logs for specific lines like:

View File

@ -9,7 +9,7 @@ toc_hide: true
{{% capture overview %}}
{{< note >}}
Be sure to also [create an entry in the table of contents](/docs/home/contribute/write-new-topic/#creating-an-entry-in-the-table-of-contents) for your new document.
Be sure to also [create an entry in the table of contents](/docs/contribute/style/write-new-topic/#placing-your-topic-in-the-table-of-contents) for your new document.
{{< /note >}}
This page shows how to ...
@ -29,7 +29,7 @@ This page shows how to ...
## Doing ...
1. Do this.
1. Do this next. Possibly read this [related explanation](...).
1. Do this next. Possibly read this [related explanation](#).
{{% /capture %}}
@ -49,6 +49,4 @@ Here's an interesting thing to know about the steps you just did.
* Learn more about [Writing a New Topic](/docs/home/contribute/write-new-topic/).
* See [Using Page Templates - Task template](/docs/home/contribute/page-templates/#task_template) for how to use this template.
{{% /capture %}}
{{% /capture %}}

View File

@ -146,7 +146,7 @@ is exposed:
my-app
39528$vdg7Jb
```
## Define container environment variables using Secret data
### Define a container environment variable with data from a single Secret
@ -157,40 +157,56 @@ is exposed:
kubectl create secret generic backend-user --from-literal=backend-username='backend-admin'
```
* Assign the `backend-username` value defined in the Secret to the `SECRET_USERNAME` environment variable in the Pod specification.
* Assign the `backend-username` value defined in the Secret to the `SECRET_USERNAME` environment variable in the Pod specification.
{{< codenew file="pods/inject/pod-single-secret-env-variable.yaml" >}}
* Create the Pod:
* Create the Pod:
```shell
kubectl create -f https://k8s.io/examples/pods/inject/pod-single-secret-env-variable.yaml
```
* Now, the Pods output includes environment variable `SECRET_USERNAME=backend-admin`
* In your shell, display the content of `SECRET_USERNAME` container environment variable
```shell
kubectl exec -it env-single-secret -- /bin/sh -c 'echo $SECRET_USERNAME'
```
The output is
```shell
backend-admin
```
### Define container environment variables with data from multiple Secrets
* As with the previous example, create the Secrets first.
```shell
kubectl create secret generic backend-user --from-literal=backend-username='backend-admin'
kubectl create secret generic db-user --from-literal=db-username='db-admin'
kubectl create secret generic backend-user --from-literal=backend-username='backend-admin'
kubectl create secret generic db-user --from-literal=db-username='db-admin'
```
* Define the environment variables in the Pod specification.
* Define the environment variables in the Pod specification.
{{< codenew file="pods/inject/pod-multiple-secret-env-variable.yaml" >}}
* Create the Pod:
```shell
kubectl create -f https://k8s.io/examples/pods/inject/pod-multiple-secret-env-variable.yaml
kubectl create -f https://k8s.io/examples/pods/inject/pod-multiple-secret-env-variable.yaml
```
* In your shell, display the container environment variables
```shell
kubectl exec -it envvars-multiple-secrets -- /bin/sh -c 'env | grep _USERNAME'
```
The output is
```shell
DB_USERNAME=db-admin
BACKEND_USERNAME=backend-admin
```
* Now, the Pods output includes `BACKEND_USERNAME=backend-admin` and `DB_USERNAME=db-admin` environment variables.
## Configure all key-value pairs in a Secret as container environment variables
@ -200,24 +216,33 @@ This functionality is available in Kubernetes v1.6 and later.
{{< /note >}}
* Create a Secret containing multiple key-value pairs
```shell
kubectl create secret generic test-secret --from-literal=username='my-app' --from-literal=password='39528$vdg7Jb'
```
* Use envFrom to define all of the Secrets data as container environment variables. The key from the Secret becomes the environment variable name in the Pod.
* Use envFrom to define all of the Secrets data as container environment variables. The key from the Secret becomes the environment variable name in the Pod.
{{< codenew file="pods/inject/pod-secret-envFrom.yaml" >}}
* Create the Pod:
```shell
kubectl create -f https://k8s.io/examples/pods/inject/pod-secret-envFrom.yaml
```
* Now, the Pods output includes `username=my-app` and `password=39528$vdg7Jb` environment variables.
* In your shell, display `username` and `password` container environment variables
````shell
kubectl exec -it envfrom-secret -- /bin/sh -c 'echo "username: $username\npassword: $password"'
````
The output is
````shell
username: my-app
password: 39528$vdg7Jb
````
{{% /capture %}}
{{% capture whatsnext %}}

View File

@ -46,13 +46,12 @@ Kustomize is a tool for customizing Kubernetes configurations. It has the follow
### Generating Resources
ConfigMap and Secret hold config or sensitive data that are used by other Kubernetes objects, such as Pods. The source
of truth of ConfigMap or Secret are usually from somewhere else, such as a `.properties` file or a ssh key file.
ConfigMaps and Secrets hold configuration or sensitive data that are used by other Kubernetes objects, such as Pods. The source of truth of ConfigMaps or Secrets are usually external to a cluster, such as a `.properties` file or an SSH keyfile.
Kustomize has `secretGenerator` and `configMapGenerator`, which generate Secret and ConfigMap from files or literals.
#### configMapGenerator
To generate a ConfigMap from a file, add an entry to `files` list in `configMapGenerator`. Here is an example of generating a ConfigMap with a data item from a file content.
To generate a ConfigMap from a file, add an entry to the `files` list in `configMapGenerator`. Here is an example of generating a ConfigMap with a data item from a `.properties` file:
```shell
# Create a application.properties file
@ -68,7 +67,7 @@ configMapGenerator:
EOF
```
The generated ConfigMap can be checked by the following command:
The generated ConfigMap can be examined with the following command:
```shell
kubectl kustomize ./
@ -86,7 +85,7 @@ metadata:
name: example-configmap-1-8mbdf7882g
```
ConfigMap can also be generated from literal key-value pairs. To generate a ConfigMap from a literal key-value pair, add an entry to `literals` list in configMapGenerator. Here is an example of generating a ConfigMap with a data item from a key-value pair.
ConfigMaps can also be generated from literal key-value pairs. To generate a ConfigMap from a literal key-value pair, add an entry to the `literals` list in configMapGenerator. Here is an example of generating a ConfigMap with a data item from a key-value pair:
```shell
cat <<EOF >./kustomization.yaml
@ -103,7 +102,7 @@ The generated ConfigMap can be checked by the following command:
kubectl kustomize ./
```
The generated ConfigMap is
The generated ConfigMap is:
```yaml
apiVersion: v1
@ -116,7 +115,7 @@ metadata:
#### secretGenerator
You can generate Secrets from files or literal key-value pairs. To generate a Secret from a file, add an entry to `files` list in `secretGenerator`. Here is an example of generating a Secret with a data item from a file.
You can generate Secrets from files or literal key-value pairs. To generate a Secret from a file, add an entry to the `files` list in `secretGenerator`. Here is an example of generating a Secret with a data item from a file:
```shell
# Create a password.txt file
@ -145,7 +144,7 @@ metadata:
type: Opaque
```
To generate a Secret from a literal key-value pair, add an entry to `literals` list in `secretGenerator`. Here is an example of generating a Secret with a data item from a key-value pair.
To generate a Secret from a literal key-value pair, add an entry to `literals` list in `secretGenerator`. Here is an example of generating a Secret with a data item from a key-value pair:
```shell
cat <<EOF >./kustomization.yaml
@ -172,7 +171,7 @@ type: Opaque
#### generatorOptions
The generated ConfigMaps and Secrets have a suffix appended by hashing the contents. This ensures that a new ConfigMap or Secret is generated when the content is changed. To disable the behavior of appending a suffix, one can use `generatorOptions`. Besides that, it is also possible to specify cross-cutting options for generated ConfigMaps and Secrets.
The generated ConfigMaps and Secrets have a content hash suffix appended. This ensures that a new ConfigMap or Secret is generated when the contents are changed. To disable the behavior of appending a suffix, one can use `generatorOptions`. Besides that, it is also possible to specify cross-cutting options for generated ConfigMaps and Secrets.
```shell
cat <<EOF >./kustomization.yaml
@ -209,7 +208,7 @@ metadata:
It is quite common to set cross-cutting fields for all Kubernetes resources in a project.
Some use cases for setting cross-cutting fields:
* setting the same namespace for all Resource
* setting the same namespace for all Resources
* adding the same name prefix or suffix
* adding the same set of labels
* adding the same set of annotations
@ -289,7 +288,7 @@ Kustomize offers composing Resources from different files and applying patches o
#### Composing
Kustomize supports composition of different resources. The `resources` field, in the `kustomization.yaml` file, defines the list of resources to include in a configuration. Set the path to a resource's configuration file in the `resources` list.
Here is an example for an nginx application with a Deployment and a Service.
Here is an example of an NGINX application comprised of a Deployment and a Service:
```shell
# Create a deployment.yaml file
@ -339,11 +338,11 @@ resources:
EOF
```
The Resources from `kubectl kustomize ./` contains both the Deployment and the Service objects.
The Resources from `kubectl kustomize ./` contain both the Deployment and the Service objects.
#### Customizing
On top of Resources, one can apply different customizations by applying patches. Kustomize supports different patching
Patches can be used to apply different customizations to Resources. Kustomize supports different patching
mechanisms through `patchesStrategicMerge` and `patchesJson6902`. `patchesStrategicMerge` is a list of file paths. Each file should be resolved to a [strategic merge patch](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-api-machinery/strategic-merge-patch.md). The names inside the patches must match Resource names that are already loaded. Small patches that do one thing are recommended. For example, create one patch for increasing the deployment replica number and another patch for setting the memory limit.
```shell

View File

@ -65,6 +65,7 @@ echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee -a /etc/
sudo apt-get update
sudo apt-get install -y kubectl
{{< /tab >}}
{{< tab name="CentOS, RHEL or Fedora" codelang="bash" >}}cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
@ -89,24 +90,30 @@ snap install kubectl --classic
kubectl version --client
```
{{% /tab %}}
{{% tab name="Homebrew" %}}
If you are on Linux and using [Homebrew](https://docs.brew.sh/Homebrew-on-Linux) package manager, kubectl is available for [installation](https://docs.brew.sh/Homebrew-on-Linux#install).
```shell
brew install kubectl
kubectl version --client
```
{{% /tab %}}
{{< /tabs >}}
## Install kubectl on macOS
### Install kubectl binary with curl on macOS
1. Download the latest release:
```
```
curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/darwin/amd64/kubectl"
```
@ -129,6 +136,7 @@ kubectl version --client
```
sudo mv ./kubectl /usr/local/bin/kubectl
```
4. Test to ensure the version you installed is up-to-date:
```
@ -144,8 +152,9 @@ If you are on macOS and using [Homebrew](https://brew.sh/) package manager, you
```
brew install kubectl
```
or
or
```
brew install kubernetes-cli
```
@ -188,11 +197,13 @@ If you are on macOS and using [Macports](https://macports.org/) package manager,
To find out the latest stable version (for example, for scripting), take a look at [https://storage.googleapis.com/kubernetes-release/release/stable.txt](https://storage.googleapis.com/kubernetes-release/release/stable.txt).
2. Add the binary in to your PATH.
3. Test to ensure the version of `kubectl` is the same as downloaded:
```
kubectl version --client
```
{{< note >}}
[Docker Desktop for Windows](https://docs.docker.com/docker-for-windows/#kubernetes) adds its own version of `kubectl` to PATH.
If you have installed Docker Desktop before, you may need to place your PATH entry before the one added by the Docker Desktop installer or remove the Docker Desktop's `kubectl`.
@ -208,10 +219,11 @@ If you are on Windows and using [Powershell Gallery](https://www.powershellgalle
Install-Script -Name install-kubectl -Scope CurrentUser -Force
install-kubectl.ps1 [-DownloadLocation <path>]
```
{{< note >}}If you do not specify a `DownloadLocation`, `kubectl` will be installed in the user's temp Directory.{{< /note >}}
The installer creates `$HOME/.kube` and instructs it to create a config file
{{< note >}}If you do not specify a `DownloadLocation`, `kubectl` will be installed in the user's temp Directory.
{{< /note >}}
The installer creates `$HOME/.kube` and instructs it to create a config file.
2. Test to ensure the version you installed is up-to-date:
@ -219,11 +231,14 @@ If you are on Windows and using [Powershell Gallery](https://www.powershellgalle
kubectl version --client
```
{{< note >}}Updating the installation is performed by rerunning the two commands listed in step 1.{{< /note >}}
{{< note >}}
Updating the installation is performed by rerunning the two commands listed in step 1.
{{< /note >}}
### Install on Windows using Chocolatey or Scoop
To install kubectl on Windows you can use either [Chocolatey](https://chocolatey.org) package manager or [Scoop](https://scoop.sh) command-line installer.
1. To install kubectl on Windows you can use either [Chocolatey](https://chocolatey.org) package manager or [Scoop](https://scoop.sh) command-line installer.
{{< tabs name="kubectl_win_install" >}}
{{% tab name="choco" %}}
@ -236,6 +251,8 @@ To install kubectl on Windows you can use either [Chocolatey](https://chocolatey
{{% /tab %}}
{{< /tabs >}}
2. Test to ensure the version you installed is up-to-date:
```
@ -265,13 +282,14 @@ To install kubectl on Windows you can use either [Chocolatey](https://chocolatey
New-Item config -type file
```
{{< note >}}Edit the config file with a text editor of your choice, such as Notepad.{{< /note >}}
{{< note >}}Edit the config file with a text editor of your choice, such as Notepad.{{< /note >}}
## Download as part of the Google Cloud SDK
You can install kubectl as part of the Google Cloud SDK.
1. Install the [Google Cloud SDK](https://cloud.google.com/sdk/).
2. Run the `kubectl` installation command:
```
@ -293,6 +311,7 @@ Check that kubectl is properly configured by getting the cluster state:
```shell
kubectl cluster-info
```
If you see a URL response, kubectl is correctly configured to access your cluster.
If you see a message similar to the following, kubectl is not configured correctly or is not able to connect to a Kubernetes cluster.
@ -350,18 +369,17 @@ You now need to ensure that the kubectl completion script gets sourced in all yo
```shell
echo 'source <(kubectl completion bash)' >>~/.bashrc
```
- Add the completion script to the `/etc/bash_completion.d` directory:
```shell
kubectl completion bash >/etc/bash_completion.d/kubectl
```
- If you have an alias for kubectl, you can extend shell completion to work with that alias:
If you have an alias for kubectl, you can extend shell completion to work with that alias:
```shell
echo 'alias k=kubectl' >>~/.bashrc
echo 'complete -F __start_kubectl k' >>~/.bashrc
```
```shell
echo 'alias k=kubectl' >>~/.bashrc
echo 'complete -F __start_kubectl k' >>~/.bashrc
```
{{< note >}}
bash-completion sources all completion scripts in `/etc/bash_completion.d`.
@ -382,7 +400,7 @@ The kubectl completion script for Bash can be generated with `kubectl completion
However, the kubectl completion script depends on [**bash-completion**](https://github.com/scop/bash-completion) which you thus have to previously install.
{{< warning>}}
there are two versions of bash-completion, v1 and v2. V1 is for Bash 3.2 (which is the default on macOS), and v2 is for Bash 4.1+. The kubectl completion script **doesn't work** correctly with bash-completion v1 and Bash 3.2. It requires **bash-completion v2** and **Bash 4.1+**. Thus, to be able to correctly use kubectl completion on macOS, you have to install and use Bash 4.1+ ([*instructions*](https://itnext.io/upgrading-bash-on-macos-7138bd1066ba)). The following instructions assume that you use Bash 4.1+ (that is, any Bash version of 4.1 or newer).
There are two versions of bash-completion, v1 and v2. V1 is for Bash 3.2 (which is the default on macOS), and v2 is for Bash 4.1+. The kubectl completion script **doesn't work** correctly with bash-completion v1 and Bash 3.2. It requires **bash-completion v2** and **Bash 4.1+**. Thus, to be able to correctly use kubectl completion on macOS, you have to install and use Bash 4.1+ ([*instructions*](https://itnext.io/upgrading-bash-on-macos-7138bd1066ba)). The following instructions assume that you use Bash 4.1+ (that is, any Bash version of 4.1 or newer).
{{< /warning >}}
### Upgrade Bash
@ -454,9 +472,9 @@ You now have to ensure that the kubectl completion script gets sourced in all yo
- If you installed kubectl with Homebrew (as explained [above](#install-with-homebrew-on-macos)), then the kubectl completion script should already be in `/usr/local/etc/bash_completion.d/kubectl`. In that case, you don't need to do anything.
{{< note >}}
the Homebrew installation of bash-completion v2 sources all the files in the `BASH_COMPLETION_COMPAT_DIR` directory, that's why the latter two methods work.
{{< /note >}}
{{< note >}}
The Homebrew installation of bash-completion v2 sources all the files in the `BASH_COMPLETION_COMPAT_DIR` directory, that's why the latter two methods work.
{{< /note >}}
In any case, after reloading your shell, kubectl completion should be working.
{{% /tab %}}
@ -489,6 +507,7 @@ compinit
{{% /tab %}}
{{< /tabs >}}
{{% /capture %}}
{{% capture whatsnext %}}

View File

@ -1,8 +0,0 @@
This feature is currently in a *alpha* state, meaning:
* The version names contain alpha (e.g. v1alpha1).
* Might be buggy. Enabling the feature may expose bugs. Disabled by default.
* Support for feature may be dropped at any time without notice.
* The API may change in incompatible ways in a later software release without notice.
* Recommended for use only in short-lived testing clusters, due to increased risk of bugs and lack of long-term support.

View File

@ -1,8 +0,0 @@
This feature is currently in a *beta* state, meaning:
* The version names contain beta (e.g. v2beta3).
* Code is well tested. Enabling the feature is considered safe. Enabled by default.
* Support for the overall feature will not be dropped, though details may change.
* The schema and/or semantics of objects may change in incompatible ways in a subsequent beta or stable release. When this happens, we will provide instructions for migrating to the next version. This may require deleting, editing, and re-creating API objects. The editing process may require some thought. This may require downtime for applications that rely on the feature.
* Recommended for only non-business-critical uses because of potential for incompatible changes in subsequent releases. If you have multiple clusters that can be upgraded independently, you may be able to relax this restriction.
* **Please do try our beta features and give feedback on them! After they exit beta, it may not be practical for us to make more changes.**

View File

@ -1,2 +0,0 @@
This feature is *deprecated*. For more information on this state, see the [Kubernetes Deprecation Policy](/docs/reference/deprecation-policy/).

View File

@ -1,5 +0,0 @@
This feature is *stable*, meaning:
* The version name is vX where X is an integer.
* Stable versions of features will appear in released software for many subsequent versions.

View File

@ -1,13 +0,0 @@
---
headless: true
resources:
- src: "*alpha*"
title: "alpha"
- src: "*beta*"
title: "beta"
- src: "*deprecated*"
title: "deprecated"
- src: "*stable*"
title: "stable"
---

View File

@ -723,7 +723,6 @@ unhealthy. You should use liveness probes to notify Kubernetes
that your application's processes are unhealthy and it should restart them.
The Pod `template` for the `zk` `StatefulSet` specifies a liveness probe.
``
```yaml
livenessProbe:

View File

@ -11,9 +11,9 @@ card:
---
{{% capture overview %}}
This tutorial builds upon the [PHP Guestbook with Redis](../guestbook) tutorial. Lightweight log, metric, and network data open source shippers, or *Beats*, from Elastic are deployed in the same Kubernetes cluster as the guestbook. The Beats collect, parse, and index the data into Elasticsearch so that you can view and analyze the resulting operational information in Kibana. This example consists of the following components:
This tutorial builds upon the [PHP Guestbook with Redis](/docs/tutorials/stateless-application/guestbook) tutorial. Lightweight log, metric, and network data open source shippers, or *Beats*, from Elastic are deployed in the same Kubernetes cluster as the guestbook. The Beats collect, parse, and index the data into Elasticsearch so that you can view and analyze the resulting operational information in Kibana. This example consists of the following components:
* A running instance of the [PHP Guestbook with Redis tutorial](../guestbook)
* A running instance of the [PHP Guestbook with Redis tutorial](/docs/tutorials/stateless-application/guestbook)
* Elasticsearch and Kibana
* Filebeat
* Metricbeat
@ -36,16 +36,16 @@ This tutorial builds upon the [PHP Guestbook with Redis](../guestbook) tutorial.
Additionally you need:
* A running deployment of the [PHP Guestbook with Redis](../guestbook) tutorial.
* A running deployment of the [PHP Guestbook with Redis](/docs/tutorials/stateless-application/guestbook) tutorial.
* A running Elasticsearch and Kibana deployment. You can use [Elasticsearch Service in Elastic Cloud](https://cloud.elastic.co), run the [download files](https://www.elastic.co/guide/en/elastic-stack-get-started/current/get-started-elastic-stack.html) on your workstation or servers, or the [Elastic Helm Charts](https://github.com/elastic/helm-charts).
* A running Elasticsearch and Kibana deployment. You can use [Elasticsearch Service in Elastic Cloud](https://cloud.elastic.co), run the [download files](https://www.elastic.co/guide/en/elastic-stack-get-started/current/get-started-elastic-stack.html) on your workstation or servers, or the [Elastic Helm Charts](https://github.com/elastic/helm-charts).
{{% /capture %}}
{{% capture lessoncontent %}}
## Start up the PHP Guestbook with Redis
This tutorial builds on the [PHP Guestbook with Redis](../guestbook) tutorial. If you have the guestbook application running, then you can monitor that. If you do not have it running then follow the instructions to deploy the guestbook and do not perform the **Cleanup** steps. Come back to this page when you have the guestbook running.
This tutorial builds on the [PHP Guestbook with Redis](/docs/tutorials/stateless-application/guestbook) tutorial. If you have the guestbook application running, then you can monitor that. If you do not have it running then follow the instructions to deploy the guestbook and do not perform the **Cleanup** steps. Come back to this page when you have the guestbook running.
## Add a Cluster role binding
Create a [cluster level role binding](/docs/reference/access-authn-authz/rbac/#rolebinding-and-clusterrolebinding) so that you can deploy kube-state-metrics and the Beats at the cluster level (in kube-system).
@ -403,4 +403,4 @@ Deleting the Deployments and Services also deletes any running Pods. Use labels
* Read more about [logging architecture](/docs/concepts/cluster-administration/logging/)
* Read more about [application introspection and debugging](/docs/tasks/debug-application-cluster/)
* Read more about [troubleshoot applications](/docs/tasks/debug-application-cluster/resource-usage-monitoring/)
{{% /capture %}}
{{% /capture %}}

View File

@ -6,6 +6,3 @@ spec:
containers:
- name: sec-ctx-3
image: gcr.io/google-samples/node-hello:1.0

View File

@ -146,7 +146,7 @@ Cluster Domain | Service (ns/nombre) | StatefulSet (ns/nombre) | StatefulSet Do
{{< note >}}
El valor de Cluster Domain se pondrá a `cluster.local` a menos que
[se configure de otra forma](/docs/concepts/services-networking/dns-pod-service/#how-it-works).
[se configure de otra forma](/docs/concepts/services-networking/dns-pod-service/).
{{< /note >}}
### Almacenamiento estable

View File

@ -0,0 +1,374 @@
---
title: Prioritas dan Kesetaraan API (API Priority and Fairness)
content_template: templates/concept
min-kubernetes-server-version: v1.18
---
{{% capture overview %}}
{{< feature-state state="alpha" for_k8s_version="v1.18" >}}
Mengontrol perilaku server API dari Kubernetes pada situasi beban berlebih
merupakan tugas utama dari administrator klaster. {{< glossary_tooltip term_id="kube-apiserver" text="kube-apiserver" >}} memiliki beberapa kontrol yang tersedia
(seperti opsi `--max-request-inflight` dan `--max-mutating-request-inflight`
pada baris perintah atau _command-line_) untuk membatasi jumlah pekerjaan luar biasa yang akan
diterima, untuk mencegah banjirnya permintaan masuk dari beban berlebih
yang berpotensi untuk menghancurkan server API. Namun opsi ini tidak cukup untuk memastikan
bahwa permintaan yang paling penting dapat diteruskan pada saat kondisi lalu lintas (_traffic_) yang cukup tinggi.
Fitur Prioritas dan Kesetaraan API atau _API Priority and Fairness_ (APF) adalah alternatif untuk meningkatkan
batasan _max-inflight_ seperti yang disebutkan di atas. APF mengklasifikasi
dan mengisolasi permintaan dengan cara yang lebih halus. Fitur ini juga memperkenalkan
jumlah antrian yang terbatas, sehingga tidak ada permintaan yang ditolak
pada saat terjadi lonjakan permintaan dalam waktu yang sangat singkat. Permintaan dibebaskan dari antrian dengan menggunakan
teknik antrian yang adil (_fair queuing_) sehingga, sebagai contoh, perilaku buruk dari satu
{{<glossary_tooltip text="controller" term_id="controller">}} tidak seharusnya
mengakibatkan _controller_ yang lain menderita (meskipun pada tingkat prioritas yang sama).
{{< caution >}}
Permintaan yang diklasifikasikan sebagai "long running" - terutama _watch_ - tidak
mengikuti filter prioritas dan kesetaraan API. Dimana ini juga berlaku pada
opsi `--max-request-inflight` tanpa mengaktifkan APF.
{{< /caution >}}
{{% /capture %}}
{{% capture body %}}
## Mengaktifkan prioritas dan kesetaraan API
Fitur APF dikontrol oleh sebuah gerbang fitur (_feature gate_)
dan fitur ini tidak diaktifkan secara bawaan. Silahkan lihat
[gerbang fitur](/docs/reference/command-line-tools-reference/feature-gates/)
untuk penjelasan umum tentang gerbang fitur dan bagaimana cara mengaktifkan dan menonaktifkannya.
Nama gerbang fitur untuk APF adalah "APIPriorityAndFairness".
Fitur ini melibatkan sebuah {{<glossary_tooltip term_id="api-group"
text="Grup API">}} yang harus juga diaktifkan. Kamu bisa melakukan ini dengan
menambahkan opsi pada baris perintah berikut pada permintaan ke `kube-apiserver` kamu:
```shell
kube-apiserver \
--feature-gates=APIPriorityAndFairness=true \
--runtime-config=flowcontrol.apiserver.k8s.io/v1alpha1=true \
# …dan opsi-opsi lainnya seperti biasa
```
Opsi pada baris perintah `--enable-priority-and-fairness=false` akan menonaktifkan fitur
APF, bahkan ketika opsi yang lain telah mengaktifkannya.
## Konsep
Ada beberapa fitur lainnya yang terlibat dalam fitur APF. Permintaan yang masuk diklasifikasikan berdasarkan atribut permintaan dengan menggunakan
FlowSchema, dan diserahkan ke tingkat prioritas. Tingkat prioritas menambahkan tingkat
isolasi dengan mempertahankan batas konkurensi yang terpisah, sehingga permintaan yang diserahkan
ke tingkat prioritas yang berbeda tidak dapat membuat satu sama lain menderita. Dalam sebuah tingkat prioritas,
algoritma _fair-queuing_ mencegah permintaan dari _flows_ yang berbeda akan memberikan penderitaan
kepada yang lainnya, dan memperbolehkan permintaan untuk dimasukkan ke dalam antrian untuk mencegah pelonjakan lalu lintas
yang akan menyebabkan gagalnya permintaan, walaupun pada saat beban rata-ratanya cukup rendah.
### Tingkat prioritas (_Priority Level_)
Tanpa pengaktifan APF, keseluruhan konkurensi dalam
server API dibatasi oleh opsi pada `kube-apiserver`
`--max-request-inflight` dan `--max-mutating-request-inflight`. Dengan pengaktifan APF,
batas konkurensi yang ditentukan oleh opsi ini akan dijumlahkan dan kemudian jumlah tersebut dibagikan
untuk sekumpulan tingkat prioritas (_priority level_) yang dapat dikonfigurasi. Setiap permintaan masuk diserahkan
ke sebuah tingkat prioritas, dan setiap tingkat prioritas hanya akan meneruskan sebanyak mungkin
permintaan secara bersamaan sesuai dengan yang diijinkan dalam konfigurasi.
Konfigurasi bawaan, misalnya, sudah mencakup tingkat prioritas terpisah untuk
permintaan dalam rangka pemilihan pemimpin (_leader-election_), permintaan dari _controller_ bawaan, dan permintaan dari
Pod. Hal ini berarti bahwa Pod yang berperilaku buruk, yang bisa membanjiri server API
dengan permintaan, tidak akan mampu mencegah kesuksesan pemilihan pemimpin atau tindakan yang dilakukan oleh _controller_ bawaan.
### Antrian (_Queuing_)
Bahkan dalam sebuah tingkat prioritas mungkin akan ada sumber lalu lintas yang berbeda dalam jumlah besar.
Dalam situasi beban berlebih, sangat penting untuk mencegah satu aliran
permintaan dari penderitaan karena aliran yang lainnya (khususnya, dalam kasus yang relatif umum dari sebuah
klien tunggal bermasalah (_buggy_) yang dapat membanjiri _kube-apiserver_ dengan permintaan, klien bermasalah itu
idealnya tidak memiliki banyak dampak yang bisa diukur terhadap klien yang lainnya). Hal ini
ditangani dengan menggunakan algoritma _fair-queuing_ untuk memproses permintaan yang diserahkan
oleh tingkat prioritas yang sama. Setiap permintaan diserahkan ke sebuah _flow_, yang diidentifikasi berdasarkan
nama FlowSchema yang sesuai, ditambah dengan _flow distinguisher_ - yang
bisa saja didasarkan pada pengguna yang meminta, sumber daya Namespace dari target, atau tidak sama sekali - dan
sistem mencoba untuk memberikan bobot yang hampir sama untuk permintaan dalam _flow_ yang berbeda dengan tingkat prioritas yang sama.
Setelah mengklasifikasikan permintaan ke dalam sebuah _flow_, fitur APF kemudian
dapat menyerahkan permintaan ke dalam sebuah antrian. Penyerahan ini menggunakan
teknik yang dikenal sebagai {{<glossary_tooltip term_id="shuffle-sharding"
text="_shuffle sharding_">}}, yang membuat penggunaan antrian yang relatif efisien
untuk mengisolasi _flow_ dengan intensitas rendah dari _flow_ dengan intensitas tinggi.
Detail dari algoritma antrian dapat disesuaikan untuk setiap tingkat prioritas, dan
memperbolehkan administrator untuk menukar (_trade off_) dengan penggunaan memori, kesetaraan (properti dimana
_flow_ yang independen akan membuat semua kemajuan ketika total dari lalu lintas sudah melebihi kapasitas),
toleransi untuk lonjakan lalu lintas, dan penambahan latensi yang dihasilkan oleh antrian.
### Permintaan yang dikecualikan (_Exempt Request_)
Beberapa permintaan dianggap cukup penting sehingga mereka tidak akan mengikuti
salah satu batasan yang diberlakukan oleh fitur ini. Pengecualian ini untuk mencegah
konfigurasi _flow control_ yang tidak terkonfigurasi dengan baik sehingga tidak benar-benar menonaktifkan server API.
## Bawaan (_Default_)
Fitur APF dikirimkan dengan konfigurasi yang disarankan
dimana konfigurasi itu seharusnya cukup untuk bereksperimen; jika klaster kamu cenderung
mengalami beban berat maka kamu harus mempertimbangkan konfigurasi apa yang akan bekerja paling baik.
Kelompok konfigurasi yang disarankan untuk semua permintaan terbagi dalam lima prioritas
kelas:
* Tingkat prioritas `system` diperuntukkan bagi permintaan dari grup `system:nodes`,
mis. Kubelet, yang harus bisa menghubungi server API agar
mendapatkan _workload_ untuk dijadwalkan.
* Tingkat prioritas `leader-election` diperuntukkan bagi permintaan dalam pemilihan pemimpin (_leader election_)
dari _controller_ bawaan (khususnya, permintaan untuk `endpoint`, `configmaps`,
atau `leases` yang berasal dari `system:kube-controller-manager` atau pengguna
`system:kube-scheduler` dan akun Service di Namespace `kube-system`). Hal ini
penting untuk mengisolasi permintaan ini dari lalu lintas yang lain karena
kegagalan dalam pemilihan pemimpin menyebabkan _controller_ akan gagal dan memulai kembali (_restart_),
yang pada akhirnya menyebabkan lalu lintas yang lebih mahal karena _controller_
yang baru perlu menyinkronkan para informannya.
* Tingkat prioritas `workload-high` diperuntukkan bagi permintaan yang lain dari _controller_ bawaan.
  
* Tingkat prioritas `workload-low` diperuntukkan bagi permintaan dari akun Service yang lain,
yang biasanya mencakup semua permintaan dari _controller_ yang bekerja didalam Pod.
  
* Tingkat prioritas `global-default` menangani semua lalu lintas lainnya, mis.
perintah interaktif `kubectl` yang dijalankan oleh pengguna yang tidak memiliki hak khusus.
Kemudian, ada dua PriorityLevelConfiguration dan dua FlowSchema yang telah
dibangun dan tidak mungkin ditimpa ulang:
* Tingkat prioritas khusus `exempt` diperuntukkan bagi permintaan yang tidak akan dikenakan
_flow control_ sama sekali: permintaan itu akan selalu diteruskan sesegera mungkin.
FlowSchema `exempt` khusus mengklasifikasikan semua permintaan dari kelompok `system:masters`
ke dalam tingkat prioritas khusus ini. Kamu juga dapat menentukan FlowSchema lain yang mengarahkan
permintaan lain ke tingkat prioritas ini juga, apabila permintaan tersebut sesuai.
* Tingkat prioritas khusus `catch-all` digunakan secara kombinasi dengan spesial
FlowSchema `catch-all` untuk memastikan bahwa setiap permintaan mendapatkan proses
klasifikasi. Biasanya kamu tidak harus bergantung pada konfigurasi _catch-all_ ini,
dan kamu seharusnya membuat FlowSchema _catch-all_ dan PriorityLevelConfiguration kamu sendiri
(atau gunakan konfigurasi `global-default` yang sudah diinstal secara bawaan) secara benar.
Untuk membantu menemukan kesalahan konfigurasi yang akan melewatkan beberapa klasifikasi
permintaan, maka tingkat prioritas `catch-all` hanya wajib mengijinkan satu konkurensi
bersama dan tidak melakukan memasukkan permintaan dalam antrian, sehingga membuat lalu lintas
yang secara relatif hanya sesuai dengan FlowSchema `catch-all` akan ditolak dengan kode kesalahan HTTP 429.
## Sumber daya (_Resource_)
_Flow control_ API melibatkan dua jenis sumber daya.
[PriorityLevelConfiguration](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#prioritylevelconfiguration-v1alpha1-flowcontrol-apiserver-k8s-io)
yang menentukan kelas isolasi yang tersedia, bagian dari konkurensi anggaran yang tersedia
yang masing-masing dapat menangani bagian tersebut, dan memperbolehkan untuk melakukan _fine-tuning_ terhadap perilaku antrian.
[FlowSchema](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#flowschema-v1alpha1-flowcontrol-apiserver-k8s-io)
yang digunakan untuk mengklasifikasikan permintaan individu yang masuk, mencocokkan masing-masing dengan setiap
PriorityLevelConfiguration.
### PriorityLevelConfiguration
Sebuah PriorityLevelConfiguration merepresentasikan sebuah kelas isolasi tunggal. Setiap
PriorityLevelConfiguration memiliki batas independensi dalam hal jumlah
permintaan yang belum diselesaikan, dan batasan dalam hal jumlah permintaan yang mengantri.
Batas konkurensi untuk PriorityLevelConfiguration tidak disebutkan dalam
jumlah permintaan secara mutlak, melainkan dalam "concurrency shares." Total batas konkurensi
untuk server API didistribusikan di antara PriorityLevelConfiguration yang ada
secara proporsional dengan "concurrency shares" tersebut. Ini mengizinkan seorang
administrator klaster untuk meningkatkan atau menurunkan jumlah total lalu lintas ke sebuah
server dengan memulai kembali `kube-apiserver` dengan nilai opsi
`--max-request-inflight` (atau `--max-mutating-request-inflight`) yang berbeda, dan semua
PriorityLevelConfiguration akan melihat konkurensi maksimum yang diizinkan kepadanya untuk menaikkan (atau
menurunkan) dalam fraksi yang sama.
{{< caution >}}
Dengan fitur Prioritas dan Kesetaraan yang diaktifkan, batas total konkurensi untuk
server diatur pada nilai penjumlahan dari `--max-request-inflight` dan
`--max-mutating-request-inflight`. Tidak akan ada lagi perbedaan
antara permintaan yang bermutasi dan permintaan yang tidak bermutasi; jika kamu ingin melayaninya
secara terpisah untuk suatu sumber daya yang ada, maka perlu membuat FlowSchema terpisah yang sesuai dengan
masing-masing kata kerja dari permintaan yang bermutasi dan yang tidak bermutasi tersebut.
{{< /caution >}}
Ketika jumlah permintaan masuk yang diserahkan kepada sebuah
PriorityLevelConfiguration melebihi dari tingkat konkurensi yang diizinkan,
bagian `type` dari spesifikasinya menentukan apa yang akan terjadi pada permintaan selanjutnya.
Tipe `Reject` berarti bahwa kelebihan lalu lintas akan segera ditolak
dengan kode kesalahan HTTP 429 (yang artinya terlalu banyak permintaan). Tipe `Queue` berarti permintaan
di atas batas tersebut akan mengantri, dengan teknik _sharding shuffle_ dan _fair queuing_ yang digunakan
untuk menyelaraskan kemajuan antara _flow_ permintaan.
Konfigurasi antrian memungkinkan mengatur algoritma _fair queuing_ untuk sebuah
tingkat prioritas. Detail algoritma dapat dibaca di [proposal pembaharuan](#what-s-next), namun secara singkat:
* Meningkatkan `queue` (antrian) berarti mengurangi tingkat tabrakan antara _flow_ yang berbeda,
sehingga berakibat pada biaya untuk meningkatkan penggunaan memori. Nilai 1 di sini secara
efektif menonaktifkan logika _fair-queuing_, tetapi masih mengizinkan permintaan untuk
dimasukkan kedalam antrian.
* Meningkatkan `queueLengthLimit` berarti memperbolehkan lonjakan yang lebih besar dari lalu lintas
untuk berkelanjutan tanpa menggagalkan permintaan apa pun, dengan konsekuensi akan meningkatkan
latensi dan penggunaan memori.
* Mengubah `handSize` berarti memperbolehkan kamu untuk menyesuaikan probabilitas tabrakan antara
   _flow_ yang berbeda dan keseluruhan konkurensi yang tersedia untuk satu _flow_ tunggal
dalam situasi beban berlebih.
{{< note >}}
`HandSize` yang lebih besar membuat dua _flow_ individual berpeluang kecil untuk bertabrakan
(dan dimana _flow_ yang satu bisa membuat _flow_ yang lain menderita), tetapi akan lebih memungkinkan
bahwa _flow_ dalam jumlah kecil akan dapat mendominasi apiserver. `HandSize` yang lebih besar juga
berpotensi meningkatkan jumlah latensi yang diakibatkan oleh satu _flow_ lalu lintas tunggal
yang tinggi. Jumlah maksimum permintaan dalam antrian yang diijinkan dari sebuah _flow_ tunggal
adalah `handSize * queueLengthLimit`.
{{< /note >}}
Berikut ini adalah tabel yang menunjukkan koleksi konfigurasi _shuffle sharding_
yang menarik, dimana setiap probabilitas _mouse_ (_flow_ dengan intensitas rendah)
yang diberikan akan dimampatkan oleh _elephant_ (_flow_ dengan intensitas tinggi) dalam sebuah koleksi ilustratif
dari jumlah _elephant_ yang berbeda. Silahkan lihat pada
https://play.golang.org/p/Gi0PLgVHiUg, yang digunakan untuk menghitung nilai-nilai dalam tabel ini.
{{< table caption="Contoh Konfigurasi Shuffle Sharding" >}}
|HandSize| Queues| 1 elephant| 4 elephants| 16 elephants|
|--------|-----------|------------|----------------|--------------------|
| 12| 32| 4.428838398950118e-09| 0.11431348830099144| 0.9935089607656024|
| 10| 32| 1.550093439632541e-08| 0.0626479840223545| 0.9753101519027554|
| 10| 64| 6.601827268370426e-12| 0.00045571320990370776| 0.49999929150089345|
| 9| 64| 3.6310049976037345e-11| 0.00045501212304112273| 0.4282314876454858|
| 8| 64| 2.25929199850899e-10| 0.0004886697053040446| 0.35935114681123076|
| 8| 128| 6.994461389026097e-13| 3.4055790161620863e-06| 0.02746173137155063|
| 7| 128| 1.0579122850901972e-11| 6.960839379258192e-06| 0.02406157386340147|
| 7| 256| 7.597695465552631e-14| 6.728547142019406e-08| 0.0006709661542533682|
| 6| 256| 2.7134626662687968e-12| 2.9516464018476436e-07| 0.0008895654642000348|
| 6| 512| 4.116062922897309e-14| 4.982983350480894e-09| 2.26025764343413e-05|
| 6| 1024| 6.337324016514285e-16| 8.09060164312957e-11| 4.517408062903668e-07|
### FlowSchema
FlowSchema mencocokkan beberapa permintaan yang masuk dan menetapkan permintaan ke dalam sebuah
tingkat prioritas. Setiap permintaan masuk diuji dengan setiap
FlowSchema secara bergiliran, dimulai dari yang terendah secara numerik ---
yang kita anggap sebagai yang tertinggi secara logis --- `matchingPrecedence` dan
begitu seterusnya. FlowSchema yang cocok pertama kali akan menang.
{{< caution >}}
Hanya FlowSchema yang pertama kali cocok untuk permintaan yang diberikan yang akan dianggap penting. Jika ada banyak
FlowSchema yang cocok dengan sebuah permintaan masuk, maka akan ditetapkan berdasarkan salah satu
yang mempunyai `matchingPrecedence` tertinggi. Jika ada beberapa FlowSchema dengan nilai
`matchingPrecedence` yang sama dan cocok dengan permintaan yang sama juga, permintaan dengan leksikografis
`name` yang lebih kecil akan menang, tetapi akan lebih baik untuk tidak mengandalkan metode ini, dan sebaiknya
perlu memastikan bahwa tidak ada dua FlowSchema yang memiliki `matchingPrecedence` yang sama.
{{< /caution >}}
Sebuah FlowSchema dianggap cocok dengan sebuah permintaan yang diberikan jika setidaknya salah satu dari `rules` nya
ada yang cocok. Sebuah aturan (_rule_) cocok jika setidaknya satu dari `subject` *dan*
ada salah satu dari `resourceRules` atau` nonResourceRules` (tergantung dari apakah permintaan
yang masuk adalah untuk URL sumber daya atau non-sumber daya) yang cocok dengan permintaan tersebut.
Untuk bagian `name` dalam subjek, dan bagian `verbs`, `apiGroups`, `resources`,
`namespaces`, dan `nonResourceURLs` dalam aturan sumber daya dan non-sumber daya,
_wildcard_ `*` mungkin bisa ditetapkan untuk mencocokkan semua nilai pada bagian yang diberikan,
sehingga secara efektif menghapusnya dari pertimbangan.
Sebuah `DistinguisherMethod.type` dari FlowSchema menentukan bagaimana permintaan
yang cocok dengan Skema itu akan dipisahkan menjadi _flow_. Nilai tipe itu bisa jadi `ByUser`, dalam
hal ini satu pengguna yang meminta tidak akan bisa menghabiskan kapasitas dari pengguna lain,
atau bisa juga `ByNamespace`, dalam hal ini permintaan sumber daya
di salah satu Namespace tidak akan bisa menyebabkan penderitaan bagi permintaan akan sumber daya
dalam kapasitas Namespace yang lain, atau bisa juga kosong (atau `distinguisherMethod`
dihilangkan seluruhnya), dalam hal ini semua permintaan yang cocok dengan FlowSchema ini akan
dianggap sebagai bagian dari sebuah _flow_ tunggal. Pilihan yang tepat untuk FlowSchema yang diberikan
akan bergantung pada sumber daya dan lingkungan khusus kamu.
## Diagnosis
Setiap respons HTTP dari server API dengan fitur prioritas dan kesetaraan
yang diaktifkan memiliki dua _header_ tambahan: `X-Kubernetes-PF-FlowSchema-UID` dan
`X-Kubernetes-PF-PriorityLevel-UID`, yang mencatat skema _flow_ yang cocok dengan permintaan
dan tingkat prioritas masing-masing. Name Objek API tidak termasuk dalam _header_ ini jika pengguna peminta tidak
memiliki izin untuk melihatnya, jadi ketika melakukan _debugging_ kamu dapat menggunakan perintah seperti ini
```shell
kubectl get flowschema -o custom-columns="uid:{metadata.uid},name:{metadata.name}"
kubectl get prioritylevelconfiguration -o custom-columns="uid:{metadata.uid},name:{metadata.name}"
```
untuk mendapatkan pemetaan UID ke names baik untuk FlowSchema maupun PriorityLevelConfiguration.
## Observabilitas
Saat kamu mengaktifkan fitur Prioritas dan Kesetaraan API atau APF, kube-apiserver
akan mengeluarkan metrik tambahan. Dengan memantau metrik ini dapat membantu kamu untuk menentukan apakah
konfigurasi kamu tidak tepat dalam membatasi lalu lintas yang penting, atau menemukan
beban kerja yang berperilaku buruk yang dapat membahayakan kesehatan dari sistem.
* `apiserver_flowcontrol_rejected_requests_total` menghitung permintaan yang
ditolak, mengelompokkannya berdasarkan nama dari tingkat prioritas yang ditetapkan,
nama FlowSchema yang ditetapkan, dan alasan penolakan tersebut.
Alasan penolakan akan mengambil dari salah satu alasan-alasan berikut:
* `queue-full`, yang mengindikasikan bahwa sudah terlalu banyak permintaan
yang menunggu dalam antrian,
* `concurrency-limit`, yang mengindikasikan bahwa PriorityLevelConfiguration
telah dikonfigurasi untuk menolak, bukan untuk memasukan permintaan berlebih ke
dalam antrian, atau
* `time-out`, yang mengindikasikan bahwa permintaan masih dalam antrian
ketika batas waktu antriannya telah berakhir.
* `apiserver_flowcontrol_dispatched_requests_total` menghitung permintaan
yang sudah mulai dieksekusi, mengelompokkannya berdasarkan nama dari tingkat
prioritas yang ditetapkan, dan nama dari FlowSchema yang ditetapkan.
* `apiserver_flowcontrol_current_inqueue_requests` memberikan
jumlah total sesaat secara instan dari permintaan dalam antrian (bukan yang dieksekusi),
dan mengelompokkannya berdasarkan tingkat prioritas dan FlowSchema.
* `apiserver_flowcontrol_current_executing_requests` memberikan
jumlah total yang instan dari permintaan yang dieksekusi, dan mengelompokkannya
berdasarkan tingkat prioritas dan FlowSchema.
* `apiserver_flowcontrol_request_queue_length_after_enqueue` memberikan
histogram dari panjang antrian untuk semua antrian yang ada, mengelompokkannya berdasarkan
tingkat prioritas dan FlowSchema, berdasarkan pengambilan sampel oleh permintaan
_enqueued_. Setiap permintaan yang mendapatkan antrian berkontribusi ke satu sampel
dalam histogramnya, pelaporan panjang antrian dilakukan setelah permintaan yang
mengantri tersebut ditambahkan. Perlu dicatat bahwa ini akan menghasilkan statistik
yang berbeda dengan survei yang tidak bias.
{{< note >}}
Nilai asing atau tidak biasa dalam histogram akan berarti ada kemungkinan sebuah _flow_
(misalnya, permintaan oleh satu pengguna atau untuk satu _namespace_, tergantung pada
konfigurasinya) telah membanjiri server API, dan sedang dicekik. Sebaliknya, jika
histogram dari satu tingkat prioritas menunjukkan bahwa semua antrian dalam prioritas
level itu lebih panjang daripada level prioritas yang lainnya, mungkin akan sesuai
untuk meningkatkan _concurrency shares_ dari PriorityLevelConfiguration itu.
{{< /note >}}
* `apiserver_flowcontrol_request_concurrency_limit` memberikan hasil perhitungan
batas konkurensi (berdasarkan pada batas konkurensi total dari server API dan
_concurrency share_ dari PriorityLevelConfiguration) untuk setiap
PriorityLevelConfiguration.
* `apiserver_flowcontrol_request_wait_duration_seconds` memberikan histogram tentang bagaimana
permintaan yang panjang dihabiskan dalam antrian, mengelompokkannya berdasarkan FlowSchema
yang cocok dengan permintaan, tingkat prioritas yang ditetapkan, dan apakah permintaan
tersebut berhasil dieksekusi atau tidak.
{{< note >}}
Karena setiap FlowSchema selalu memberikan permintaan untuk satu
PriorityLevelConfiguration, kamu dapat menambahkan histogram untuk semua
FlowSchema dalam satu tingkat prioritas untuk mendapatkan histogram yang efektif
dari permintaan yang ditetapkan ke tingkat prioritas tersebut.
{{< /note >}}
* `apiserver_flowcontrol_request_execution_seconds` memberikan histogram tentang bagaimana
caranya permintaan yang panjang diambil untuk benar-benar dieksekusi, mengelompokkannya
berdasarkan FlowSchema yang cocok dengan permintaan dan tingkat prioritas yang ditetapkan pada
permintaan tersebut.
{{% /capture %}}
{{% capture whatsnext %}}
Untuk latar belakang informasi mengenai detail desain dari prioritas dan kesetaraan API, silahkan lihat
[proposal pembaharuan](https://github.com/kubernetes/enhancements/blob/master/keps/sig-api-machinery/20190228-priority-and-fairness.md).
Kamu juga dapat membuat saran dan permintaan akan fitur melalui [SIG API
Machinery](https://github.com/kubernetes/community/tree/master/sig-api-machinery).
{{% /capture %}}

View File

@ -147,7 +147,7 @@ Domain Klaster | Service (ns/nama) | StatefulSet (ns/nama) | Domain StatefulSet
{{< note >}}
Domain klaster akan diatur menjadi `cluster.local` kecuali
[nilainya dikonfigurasi](/docs/concepts/services-networking/dns-pod-service/#how-it-works).
[nilainya dikonfigurasi](/docs/concepts/services-networking/dns-pod-service/).
{{< /note >}}
### Penyimpanan Stabil

View File

@ -0,0 +1,214 @@
---
title: Menjalankan Tugas-Tugas Otomatis dengan CronJob
min-kubernetes-server-version: v1.8
content_template: templates/task
weight: 10
---
{{% capture overview %}}
Kamu dapat menggunakan {{< glossary_tooltip text="CronJob" term_id="cronjob" >}} untuk menjalankan {{< glossary_tooltip text="Job" term_id="job" >}} yang dijadwalkan berbasis waktu. Job akan berjalan seperti pekerjaan-pekerjaan [Cron](https://en.wikipedia.org/wiki/Cron) di Linux atau sistem UNIX.
CronJob sangat berguna untuk membuat pekerjaan yang berjalan secara periodik dan berulang, misalnya menjalankan (_backup_) atau mengirim email.
CronJob juga dapat menjalankan pekerjaan individu pada waktu tertentu, misalnya jika kamu ingin menjadwalkan sebuah pekerjaan dengan periode aktivitas yang rendah.
CronJob memiliki keterbatasan dan kekhasan.
Misalnya, dalam keadaan tertentu, sebuah CronJob dapat membuat banyak Job.
Karena itu, Job haruslah _idempotent._
Untuk informasi lanjut mengenai keterbatasan, lihat [CronJob](/docs/concepts/workloads/controllers/cron-jobs).
{{% /capture %}}
{{% capture prerequisites %}}
* {{< include "task-tutorial-prereqs.md" >}}
{{% /capture %}}
{{% capture steps %}}
## Membuat Sebuah CronJob
CronJob membutuhkan sebuah berkas konfigurasi.
Ini adalah contoh dari berkas konfigurasi CronJob `.spec` yang akan mencetak waktu sekarang dan pesan "hello" setiap menit:
{{< codenew file="application/job/cronjob.yaml" >}}
Jalankan contoh CronJob menggunakan perintah berikut:
```shell
kubectl create -f https://k8s.io/examples/application/job/cronjob.yaml
```
Keluaran akan mirip dengan ini:
```
cronjob.batch/hello created
```
Kamu juga dapat menggunakan `kubectl run` untuk membuat sebuah CronJob tanpa menulis sebuah konfigurasi yang lengkap:
```shell
kubectl run hello --schedule="*/1 * * * *" --restart=OnFailure --image=busybox -- /bin/sh -c "date; echo Hello from the Kubernetes cluster"
```
Setelah membuat sebuah CronJob, untuk mengecek statusnya kamu dapat menggunakan perintah berikut:
```shell
kubectl get cronjob hello
```
Keluaran akan mirip dengan ini:
```
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
hello */1 * * * * False 0 <none> 10s
```
Seperti yang kamu lihat dari hasil perintah di atas, CronJob belum menjadwalkan atau menjalankan pekerjaan apa pun.
Waktu yang biasanya dibutuhkan untuk mengamati Job hingga Job tersebut dibuat akan membutuhkan sekitar satu menit:
```shell
kubectl get jobs --watch
```
Keluaran akan mirip dengan ini:
```
NAME COMPLETIONS DURATION AGE
hello-4111706356 0/1 0s
hello-4111706356 0/1 0s 0s
hello-4111706356 1/1 5s 5s
```
Sekarang kamu telah melihat satu Job berjalan yang dijadwalkan oleh "hello" CronJob.
Kamu dapat berhenti mengamati Job dan melihat CronJob lagi untuk melihat CronJob menjadwalkan sebuah Job:
```shell
kubectl get cronjob hello
```
Keluaran akan mirip dengan ini:
```
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
hello */1 * * * * False 0 50s 75s
```
Kamu dapat melihat bahwa CronJob `hello` berhasil menjadwalkan sebuah Job pada waktu yang ditentukan dalam `LAST SCHEDULE`. Saat ini ada 0 Job yang aktif, berarti sebuah Job telah selesai atau gagal.
Sekarang, temukan Pod yang dibuat oleh jadwal Job terakhir dan melihat keluaran bawaan dari salah satu Pod.
{{< note >}}
Nama Job dan nama Pod itu berbeda.
{{< /note >}}
```shell
# Ganti "hello-4111706356" dengan nama Job di sistem kamu
pods=$(kubectl get pods --selector=job-name=hello-4111706356 --output=jsonpath={.items[*].metadata.name})
```
Menampilkan log sebuah Pod:
```shell
kubectl logs $pods
```
Keluaran akan mirip dengan ini:
```
Fri Feb 22 11:02:09 UTC 2019
Hello from the Kubernetes cluster
```
## Menghapus sebuah CronJob
Ketika kamu tidak membutuhkan sebuah CronJob lagi, kamu dapat megnhapusnya dengan perintah `kubectl delete cronjob <cronjob name>`:
```shell
kubectl delete cronjob hello
```
Menghapus CronJob akan menghapus semua Job dan Pod yang telah terbuat dan menghentikanya dari pembuatan Job tambahan.
Kamu dapat membaca lebih lanjut tentang menghapus Job di [_garbage collection_](/docs/concepts/workloads/controllers/garbage-collection/).
## Menulis Speifikasi Sebuah Cron
Seperti semua konfigurasi Kubernetes, sebuah CronJob membutuhkan _field_ `apiVersion`, `kind`, dan `metadata`. Untuk informasi
umum tentang bekerja dengan berkas konfigurasi, lihat dokumentasi [men-_deploy_ aplikasi](/docs/user-guide/deploying-applications),
dan [mengunakan kubectl untuk manajemen sumber daya](/docs/user-guide/working-with-resources).
Sebuah konfigurasi CronJob juga membutuhkan sebuah [bagian `.spec`](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status).
{{< note >}}
Semua modifikasi pada sebuah CronJob, terutama `.spec`, akan diterapkan pada proses berikut.
{{< /note >}}
### Penjadwalan
`.spec.schedule` adalah _field_ yang wajib diisi dari sebuah `.spec`
Dibutuhkan sebuah format string [Cron](https://en.wikipedia.org/wiki/Cron), misalnya `0 * * * *` atau `@hourly`, sebagai jadwal Job untuk dibuat dan dieksekusi.
Format ini juga mencakup nilai langkah `Vixie cron`. Seperti penjelasan di [FreeBSD manual](https://www.freebsd.org/cgi/man.cgi?crontab%285%29):
> Nilai langkah dapat digunakan bersama dengan rentang. Sebuah rentang diikuti dengan
> `/<number>` menentukan lompatan angka melalui rentang.
> Misalnya, `0-23/2` dapat digunakan dalam jam untuk menentukan
> perintah akan dieksekusi setiap jam (alternatif dalam bawaan v7 adalah
> `0,2,4,6,8,10,12,14,16,18,20,22`). Langkah-langkah juga diizinkan setelah
> tanda bintang, jadi jika kamu menginginkan "setiap dua jam", gunakan saja `*/2`.
{{< note >}}
Sebuah tanda tanya (`?`) dalam penjadwalan memiliki makna yang sama dengan tanda bintang `*`, yaitu, singkatan dari nilai apa pun yang tersedia untuk _field_ tertentu.
{{< /note >}}
### Templat Job
`.spec.JobTemplate` adalah templat untuk sebuah Job, dan itu wajib.
Templat Job memiliki skema yang sama dengan [Job](/docs/concepts/workloads/controllers/jobs-run-to-completion/), kecuali jika bersarang dan tidak memiliki sebuah `apiVersion` atau `kind`.
Untuk informasi lebih lanjut tentang menulis sebuah Job `.spec` lihat [Menulis spesifikasi Job](/docs/concepts/workloads/controllers/jobs-run-to-completion/#writing-a-job-spec).
### _Starting Deadline_
_Field_ `.spec.startingDeadlineSeconds` adalah _field_ opsional.
_Field_ tersebut berarti batas waktu dalam satuan detik untuk memulai sebuah Job jika Job melewatkan waktu yang telah dijadwalkan karena alasan apapun.
Setelah mencapai batas waktu, CronJob tidak akan memulai sebuah Job.
Job yang tidak memenuhi batas waktu, dengan cara ini dianggap sebagai Job yang gagal.
Jika _field_ ini tidak ditentukan, maka Job tidak memiliki batas waktu.
_Controller_ CronJob menghitung berapa banyak jadwal yang terlewat untuk sebuah CronJob. jika lebih dari 100 jadwal yang terlewat, maka tidak ada lagi CronJob yang akan dijadwalkan. Ketika `.spec.startingDeadlineSeconds` tidak disetel, CronJob Controller menghitung jadwal yang terlewat dari `status.lastScheduleTime` hingga sekarang.
Misalnya, sebuah CronJob seharusnya berjalan setiap menit, `status.lastScheduleTime` CronJob adalah pukul 5:00am, tetapi sekarang pukul 07:00am. Itu berarti ada 120 jadwal yang terlewat, maka tidak ada lagi CronJob yang akan dijadwalkan.
Jika _field_ `.spec.startingDeadlineSeconds` disetel (tidak kosong), CronJob Controller akah menghitung berapa banyak Job yang terlewat dari nilai `.spec.startingDeadlineSeconds` hingga sekarang.
Misalnya, jika disetel ke `200`, CronJob Controller akan menghitung jadwal yang terlewat dalam 200 detik terakhir. Pada kasus ini, jika terdapat lebih dari 100 jadwal yang terlewat dalam 200 detik terakhir, maka tidak ada lagi CronJob yang akan dijadwalkan.
### Kebijakan _Concurrency_
_Field_ `.spec.concurrencyPolicy` juga opsional.
_Field_ tersebut menentukan bagaimana memperlakukan eksekusi _concurrent_ dari sebuah Job yang dibuat oleh CronJob.
Kamu dapat menetapkan hanya satu dari kebijakan _concurrency_:
* `Allow` (bawaan): CronJob mengizinkan Job berjalan secara _concurrent_
* `Forbid` : Job tidak mengizinkan Job berjalan secara _concurrent_; jika sudah saatnya untuk menjalankan Job baru dan Job sebelumnya belum selesai, maka CronJob akan melewatkan Job baru yang akan berjalan
* `Replace`: Jika sudah saatnya untuk menjalankan Job baru dan Job sebelumnya belum selesai, maka CronJob akan mengganti Job yang sedang berjalan dengan Job baru.
Perhatikan bahwa kebijakan _concurrency_ hanya berlaku untuk Job yang dibuat dengan CronJob yang sama.
Jika terdapat banyak CronJob, Job akan selalu diizinkan untuk berjalan secara _concurrent_.
### Penangguhan
_Field_ `.spec.suspend` juga opsional.
Jika _field_ tersebut disetel `true`, semua eksekusi selanjutnya akan ditangguhkan.
Konfigurasi ini tidak dapat berlaku untuk eksekusi yang sudah dimulai.
Secara bawaan _false_.
{{< caution >}}
Eksekusi yang ditangguhkan selama waktu yang dijadwalkan dihitung sebagai Job yang terlewat.
Ketika `.spec.suspend` diubah dari `true` ke `false` pada CronJob yang memiliki konfigurasi tanpa [batas waktu](#starting-deadline), Job yang terlewat akan dijadwalkan segera.
{{< /caution >}}
### Batas Riwayat Pekerjaan
_Field_ `.spec.successfulJobHistoryLimit` dan `.spec.failedJobHistoryLimit` juga opsional.
_Field_ tersebut menentukan berapa banyak Job yang sudah selesai dan gagal yang harus disimpan.
Secara bawaan, masing-masing _field_ tersebut disetel 3 dan 1. Mensetel batas ke `0` untuk menjaga tidak ada Job yang sesuai setelah Job tersebut selesai.
{{% /capture %}}

View File

@ -0,0 +1,256 @@
---
title: Menginstal Minikube
content_template: templates/task
weight: 20
card:
name: tasks
weight: 10
---
{{% capture overview %}}
Halaman ini menunjukkan cara instalasi [Minikube](/docs/tutorials/hello-minikube), sebuah alat untuk menjalankan sebuah klaster Kubernetes dengan satu Node pada mesin virtual yang ada di komputer kamu.
{{% /capture %}}
{{% capture prerequisites %}}
{{< tabs name="minikube_before_you_begin" >}}
{{% tab name="Linux" %}}
Untuk mengecek jika virtualisasi didukung pada Linux, jalankan perintah berikut dan pastikan keluarannya tidak kosong:
```
grep -E --color 'vmx|svm' /proc/cpuinfo
```
{{% /tab %}}
{{% tab name="macOS" %}}
Untuk mengecek jika virtualisasi didukung di macOS, jalankan perintah berikut di terminal kamu.
```
sysctl -a | grep -E --color 'machdep.cpu.features|VMX'
```
Jika kamu melihat `VMX` pada hasil keluaran (seharusnya berwarna), artinya fitur VT-x sudah diaktifkan di mesin kamu.
{{% /tab %}}
{{% tab name="Windows" %}}
Untuk mengecek jika virtualisasi didukung di Windows 8 ke atas, jalankan perintah berikut di terminal Windows atau _command prompt_ kamu.
```
systeminfo
```
Jika kamu melihat keluaran berikut, maka virtualisasi didukung di Windows kamu.
```
Hyper-V Requirements: VM Monitor Mode Extensions: Yes
Virtualization Enabled In Firmware: Yes
Second Level Address Translation: Yes
Data Execution Prevention Available: Yes
```
Jika kamu melihat keluaran berikut, sistem kamu sudah memiliki sebuah Hypervisor yang terinstal dan kamu bisa melewati langkah berikutnya.
```
Hyper-V Requirements: A hypervisor has been detected. Features required for Hyper-V will not be displayed.
```
{{% /tab %}}
{{< /tabs >}}
{{% /capture %}}
{{% capture steps %}}
# Menginstal minikube
{{< tabs name="tab_with_md" >}}
{{% tab name="Linux" %}}
### Menginstal kubectl
Pastikan kamu mempunyai kubectl yang terinstal. Kamu bisa menginstal kubectl dengan mengikuti instruksi pada halaman [Menginstal dan Menyiapkan kubectl](/docs/tasks/tools/install-kubectl/#install-kubectl-on-linux).
### Menginstal sebuah Hypervisor
Jika kamu belum menginstal sebuah Hypervisor, silakan instal salah satu dari:
• [KVM](https://www.linux-kvm.org/), yang juga menggunakan QEMU
• [VirtualBox](https://www.virtualbox.org/wiki/Downloads)
Minikube juga mendukung sebuah opsi `--driver=none` untuk menjalankan komponen-komponen Kubernetes pada _host_, bukan di dalam VM. Untuk menggunakan _driver_ ini maka diperlukan [Docker](https://www.docker.com/products/docker-desktop) dan sebuah lingkungan Linux, bukan sebuah hypervisor.
Jika kamu menggunakan _driver_ `none` pada Debian atau turunannya, gunakan paket (_package_) `.deb` untuk Docker daripada menggunakan paket _snap_-nya, karena paket _snap_ tidak berfungsi dengan Minikube.
Kamu bisa mengunduh paket `.deb` dari [Docker](https://www.docker.com/products/docker-desktop).
{{< caution >}}
*Driver* VM `none` dapat menyebabkan masalah pada keamanan dan kehilangan data. Sebelum menggunakan opsi `--driver=none`, periksa [dokumentasi ini](https://minikube.sigs.k8s.io/docs/reference/drivers/none/) untuk informasi lebih lanjut.
{{< /caution >}}
Minikube juga mendukung opsi `vm-driver=podman` yang mirip dengan _driver_ Docker. Podman yang berjalan dengan hak istimewa _superuser_ (pengguna _root_) adalah cara terbaik untuk memastikan kontainer-kontainer kamu memiliki akses penuh ke semua fitur yang ada pada sistem kamu.
{{< caution >}}
_Driver_ `podman` memerlukan kontainer yang berjalan dengan akses _root_ karena akun pengguna biasa tidak memiliki akses penuh ke semua fitur sistem operasi yang mungkin diperlukan oleh kontainer.
{{< /caution >}}
### Menginstal Minikube menggunakan sebuah paket
Tersedia paket uji coba untuk Minikube, kamu bisa menemukan paket untuk Linux (AMD64) di laman [rilisnya](https://github.com/kubernetes/minikube/releases) Minikube di GitHub.
Gunakan alat instalasi paket pada distribusi Linux kamu untuk menginstal paket yang sesuai.
### Menginstal Minikube melalui pengunduhan langsung
Jika kamu tidak menginstal melalui sebuah paket, kamu bisa mengunduh sebuah _stand-alone binary_ dan menggunakannya.
```shell
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 \
&& chmod +x minikube
```
Berikut adalah cara mudah untuk menambahkan program Minikube ke _path_ kamu.
```shell
sudo mkdir -p /usr/local/bin/
sudo install minikube /usr/local/bin/
```
### Menginstal Minikube menggunakan Homebrew
Sebagai alternatif, kamu bisa menginstal Minikube menggunakan Linux [Homebrew](https://docs.brew.sh/Homebrew-on-Linux):
```shell
brew install minikube
```
{{% /tab %}}
{{% tab name="macOS" %}}
### Instalasi kubectl
Pastikan kamu mempunyai kubectl yang terinstal. Kamu bisa menginstal kubectl berdasarkan instruksi pada laman [Menginstal dan Menyiapkan kubectl](/docs/tasks/tools/install-kubectl/#install-kubectl-on-macos).
### Instalasi sebuah Hypervisor
Jika kamu belum menginstal sebuah Hypervisor, silakan instal salah satu dari:
• [HyperKit](https://github.com/moby/hyperkit)
• [VirtualBox](https://www.virtualbox.org/wiki/Downloads)
• [VMware Fusion](https://www.vmware.com/products/fusion)
### Instalasi Minikube
Cara paling mudah untuk menginstal Minikube pada macOS adalah menggunakan [Homebrew](https://brew.sh):
```shell
brew install minikube
```
Kamu juga bisa menginstalnya dengan mengunduh _stand-alone binary_-nya:
```shell
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-amd64 \
&& chmod +x minikube
```
Berikut adalah cara mudah untuk menambahkan program Minikube ke _path_ kamu.
```shell
sudo mv minikube /usr/local/bin
```
{{% /tab %}}
{{% tab name="Windows" %}}
### Instalasi kubectl
Pastikan kamu mempunyai kubectl yang terinstal. Kamu bisa menginstal kubectl berdasarkan instruksi pada halaman [Menginstal dan Menyiapkan kubectl](/docs/tasks/tools/install-kubectl/#install-kubectl-on-windows).
### Menginstal sebuah Hypervisor
Jika kamu belum menginstal sebuah Hypervisor, silakan instal salah satu dari:
• [Hyper-V](https://msdn.microsoft.com/en-us/virtualization/hyperv_on_windows/quick_start/walkthrough_install)
• [VirtualBox](https://www.virtualbox.org/wiki/Downloads)
{{< note >}}
Hyper-V hanya dapat berjalan pada tiga versi dari Windows 10: Windows 10 Enterprise, Windows 10 Professional, dan Windows 10 Education.
{{< /note >}}
### Menginstal Minikube menggunakan Chocolatey
Cara paling mudah untuk menginstal Minikube pada Windows adalah menggunakan [Chocolatey](https://chocolatey.org/) (jalankan sebagai administrator):
```shell
choco install minikube
```
Setelah Minikube telah selesai diinstal, tutup sesi CLI dan hidupkan ulang CLI-nya. Minikube akan ditambahkan ke _path_ kamu secara otomatis.
### Menginstal Minikube menggunakan sebuah program penginstal
Untuk menginstal Minikube secara manual pada Windows menggunakan [Windows Installer](https://docs.microsoft.com/en-us/windows/desktop/msi/windows-installer-portal), unduh [`minikube-installer.exe`](https://github.com/kubernetes/minikube/releases/latest/download/minikube-installer.exe) dan jalankan program penginstal tersebut.
### Menginstal Minikube melalui pengunduhan langsung
Untuk menginstal Minikube secara manual pada Windows, unduh [`minikube-windows-amd64`](https://github.com/kubernetes/minikube/releases/latest), ubah nama menjadi `minikube.exe`, dan tambahkan ke _path_ kamu.
{{% /tab %}}
{{< /tabs >}}
{{% /capture %}}
{{% capture whatsnext %}}
* [Menjalanakan Kubernetes secara lokal dengan Minikube](/docs/setup/learning-environment/minikube/)
{{% /capture %}}
## Memastikan instalasi
Untuk memastikan keberhasilan kedua instalasi hypervisor dan Minikube, kamu bisa menjalankan perintah berikut untuk memulai sebuah klaster Kubernetes lokal:
{{< note >}}
Untuk pengaturan `--driver` dengan `minikube start`, masukkan nama hypervisor `<driver_name>` yang kamu instal dengan huruf kecil seperti yang ditunjukan dibawah. Daftar lengkap nilai `--driver` tersedia di [dokumentasi menentukan *driver* VM](/docs/setup/learning-environment/minikube/#specifying-the-vm-driver).
{{< /note >}}
```shell
minikube start --driver=<driver_name>
```
Setelah `minikube start` selesai, jalankan perintah di bawah untuk mengecek status klaster:
```shell
minikube status
```
Jika klasternya berjalan, keluaran dari `minikube status` akan mirip seperti ini:
```
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured
```
Setelah kamu memastikan bahwa Minikube berjalan sesuai dengan hypervisor yang telah kamu pilih, kamu dapat melanjutkan untuk menggunakan Minikube atau menghentikan klaster kamu. Untuk menghentikan klaster, jalankan:
```shell
minikube stop
```
## Membersihkan *state* lokal {#cleanup-local-state}
Jika sebelumnya kamu pernah menginstal Minikube, dan menjalankan:
```shell
minikube start
```
dan `minikube start` memberikan pesan kesalahan:
```
machine does not exist
```
maka kamu perlu membersihkan _state_ lokal Minikube:
```shell
minikube delete
```

View File

@ -0,0 +1,18 @@
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure

View File

@ -0,0 +1,4 @@
---
title: "Overview"
weight: 20
---

View File

@ -30,7 +30,7 @@ KubernetesはPodにそれぞれのIPアドレス割り振りや、Podのセッ
この仕組みはある問題を引き起こします。もし、あるPodのセット(ここでは"バックエンド"と呼びます)がクラスター内で他のPodのセット(ここでは"フロントエンド"と呼びます)に対して機能を提供する場合、フロントエンドのPodがワークロードにおけるバックエンドを使用するために、バックエンドのPodのIPアドレスを探し出したり、記録し続けるためにはどうすればよいでしょうか?
ここで_Service_ について説明します。
ここで _Service_ について説明します。
## Serviceリソース {#service-resource}

View File

@ -131,7 +131,7 @@ Cluster Domain | Service (ns/name) | StatefulSet (ns/name) | StatefulSet Domain
kube.local | foo/nginx | foo/web | nginx.foo.svc.kube.local | web-{0..N-1}.nginx.foo.svc.kube.local | web-{0..N-1} |
{{< note >}}
クラスタードメインは[その他の設定](/docs/concepts/services-networking/dns-pod-service/#how-it-works)がされない限り、`cluster.local`にセットされます。
クラスタードメインは[その他の設定](/docs/concepts/services-networking/dns-pod-service/)がされない限り、`cluster.local`にセットされます。
{{< /note >}}
### 安定したストレージ

View File

@ -1,20 +1,21 @@
---
title: 클라우트 컨트롤러 매니저 기반에 관한 개념
title: 클라우드 컨트롤러 매니저
content_template: templates/concept
weight: 40
---
{{% capture overview %}}
클라우드 컨트롤러 매니저(CCM) 개념(바이너리와 혼동하지 말 것)은 본래 클라우드 벤더에 특화된 코드와 쿠버네티스 코어가 상호 독립적으로 진화할 수 있도록 해주기 위해 생성되었다. 클라우드 컨트롤러 매니저는 쿠버네티스 컨트롤러 매니저, API 서버, 그리고 스케줄러와 같은 다른 마스터 컴포넌트와 함께 동작된다. 또한 쿠버네티스 위에서 동작하는 경우에는, 쿠버네티스 애드온으로서 구동된다.
{{< feature-state state="beta" for_k8s_version="v1.11" >}}
클라우드 컨트롤러 매니저의 디자인은 새로운 클라우드 제공사업자가 플러그인을 이용하여 쉽게 쿠버네티스와 함께 통합하도록 허용해 주는 플러그인 메커니즘을 토대로 한다. 쿠버네티스에 새로운 클라우드 제공사업자를 적응시키기 위한 그리고 기존 모델에서 새로운 CCM 모델로 클라우드 제공사업자들이 전환을 이루기 위한 준비된 계획들이 있다.
클라우드 인프라스트럭쳐 기술을 통해 퍼블릭, 프라이빗 그리고 하이브리드 클라우드에서 쿠버네티스를 실행할 수 있다.
쿠버네티스는 컴포넌트간의 긴밀한 결합 없이 자동화된 API 기반의 인프라스트럭쳐를
신뢰한다.
이 문서는 클라우드 컨트롤러 매니저 이면상의 개념들을 논의하고 그것과 연관된 기능들에 대한 세부적인 사항들을 제시한다.
{{< glossary_definition term_id="cloud-controller-manager" length="all" prepend="클라우드 컨트롤러 매니저는">}}
다음은 클라우드 컨트롤러 매니저가 존재하지 않는 형태의 쿠버네티스 클러스터 아키텍처이다.
![Pre CCM Kube Arch](/images/docs/pre-ccm-arch.png)
클라우드 컨트롤러 매니저는 다양한 클라우드 공급자가 자신의
플랫폼에 쿠버네티스를 통합할 수 있도록 하는 플러그인 메커니즘을 사용해서 구성된다.
{{% /capture %}}
@ -23,91 +24,69 @@ weight: 40
## 디자인
이전 다이어그램에서, 쿠버네티스와 클라우드 제공사업자는 여러 상이한 컴포넌트들을 통해 통합되었다.
![쿠버네티스 컴포넌트](/images/docs/components-of-kubernetes.png)
* Kubelet
* 쿠버네티스 컨트롤러 매니저
* 쿠버네티스 API 서버
CCM은 앞의 세 컴포넌트가 가진 클라우드 의존적인 로직을 한 곳에 모아서 클라우드 통합을 위한 단일 포인트를 만들었다. CCM을 활용한 새로운 아키텍처는 다음과 같다.
![CCM Kube Arch](/images/docs/post-ccm-arch.png)
## CCM의 컴포넌트
CCM은 쿠버네티스 컨트롤러 매니저(KCM)의 기능 일부를 독립시키고 분리된 프로세스로서 그것을 작동시킨다. 특히, 클라우드 종속적인 KCM 내 컨트롤러들을 독립시킨다. KCM은 다음과 같은 클라우드 종속적인 컨트롤러 루프를 가진다.
* 노드 컨트롤러
* 볼륨 컨트롤러
* 라우트 컨트롤러
* 서비스 컨트롤러
버전 1.9 에서, CCM은 이전 리스트로부터 다음의 컨트롤러를 작동시킨다.
* 노드 컨트롤러
* 라우트 컨트롤러
* 서비스 컨트롤러
클라우드 컨트롤러 매니저는 컨트롤 플레인에서 복제된 프로세스의 집합으로 실행된다(일반적으로,
파드의 컨테이너). 각 클라우드 컨트롤러 매니저는 단일
프로세스에 여러 {{< glossary_tooltip text="컨트롤러" term_id="controller" >}}를
구현한다.
{{< note >}}
볼륨 컨트롤러는 의도적으로 CCM의 일부가 되지 않도록 선택되었다. 연관된 복잡성 때문에 그리고 벤더 특유의 볼륨 로직 개념을 일반화 하기 위한 기존의 노력때문에, 볼륨 컨트롤러는 CCM으로 이전되지 않도록 결정되었다.
또한 사용자는 클라우드 컨트롤러 매니저를 컨트롤 플레인의 일부가 아닌 쿠버네티스
{{< glossary_tooltip text="애드온" term_id="addons" >}}으로
실행할 수도 있다.
{{< /note >}}
CCM을 이용하는 볼륨을 지원하기 위한 원래 계획은 플러그형 볼륨을 지원하기 위한 [Flex](/ko/docs/concepts/storage/volumes/#flexVolume) 볼륨을 사용하기 위한 것이었다. 그러나, [CSI](/ko/docs/concepts/storage/volumes/#csi)라 알려진 경쟁적인 노력이 Flex를 대체하도록 계획되고 있다.
## 클라우드 컨트롤러 매니저의 기능 {#functions-of-the-ccm}
이러한 역동성을 고려하여, CSI가 준비될 때까지 차이점에 대한 측정은 도중에 중지하기로 결정하였다.
## CCM의 기능
CCM은 클라우드 제공사업자에 종속적인 쿠버네티스 컴포넌트로부터 그 속성을 상속받는다. 이번 섹션은 그러한 컴포넌트를 근거로 구성되었다.
### 1. 쿠버네티스 컨트롤러 매니저
CCM의 주요 기능은 KCM으로부터 파생된다. 이전 섹션에서 언급한 바와 같이, CCM은 다음의 컨트롤러 루프를 작동시킨다.
* 노드 컨트롤러
* 라우트 컨트롤러
* 서비스 컨트롤러
#### 노드 컨트롤러
노드 컨트롤러는 클라우드 제공사업자의 클러스터에서 동작중인 노드에 대한 정보를 얻음으로써 노드를 초기화할 책임을 가진다. 노드 컨트롤러는 다음 기능을 수행한다.
1. 클라우드 특유의 영역/지역 레이블을 이용한 노드를 초기화한다.
2. 클라우드 특유의 인스턴스 세부사항, 예를 들어, 타입 그리고 크기 등을 이용한 노드를 초기화한다.
3. 노드의 네트워크 주소와 호스트네임을 취득한다.
4. 노드가 무응답일 경우, 클라우드로부터 해당 노드가 삭제된 것인지 확인한다. 클라우드로부터 삭제된 것이라면, 쿠버네티스 노드 오브젝트를 삭제한다.
#### 라우트 컨트롤러
라우트 컨트롤러는 클라우드에서 적합하게 경로를 구성하는 책임을 가지며 쿠버네티스 클러스터 내 상이한 노드 상의 컨테이너들이 상호 소통할 수 있도록 해준다. 라우트 컨트롤러는 오직 Google Compute Engine 클러스터에서만 적용가능 하다.
#### 서비스 컨트롤러
서비스 컨트롤러는 서비스 생성, 업데이트, 그리고 이벤트 삭제에 대한 책임을 가진다. 쿠버네티스 내 서비스의 현재 상태를 근거로, 쿠버네티스 내 서비스의 상태를 나타내기 위해 클라우드 로드 밸런서(ELB, Google LB, Oracle Cloud Infrastrucuture LB와 같은)를 구성해준다. 추가적으로, 클라우드 로드 밸런서를 위한 서비스 백엔드가 최신화 되도록 보장해 준다.
### 2. Kubelet
노드 컨트롤러는 kubelet의 클라우드 종속적인 기능을 포함한다. CCM이 도입되기 이전에는, kubelet 이 IP 주소, 지역/영역 레이블 그리고 인스턴스 타입 정보와 같은 클라우드 특유의 세부사항으로 노드를 초기화하는 책임을 가졌다. CCM의 도입으로 kubelet에서 CCM으로 이 초기화 작업이 이전되었다.
이 새로운 모델에서, kubelet은 클라우드 특유의 정보 없이 노드를 초기화 해준다. 그러나, kubelet은 새로 생성된 노드에 taint를 추가해서 CCM이 클라우드에 대한 정보를 가지고 노드를 초기화하기 전까지는 스케줄되지 않도록 한다. 그러고 나서 이 taint를 제거한다.
## 플러그인 메커니즘
클라우드 컨트롤러 매니저는 어떠한 클라우드에서든지 플러그 인 되어 구현될 수 있도록 Go 인터페이스를 이용한다. 구체적으로, [여기](https://github.com/kubernetes/cloud-provider/blob/9b77dc1c384685cb732b3025ed5689dd597a5971/cloud.go#L42-L62)에 정의된 CloudProvider 인터페이스를 이용한다.
위에서 강조되었던 4개의 공유 컨트롤러의 구현, 그리고 공유 cloudprovider 인터페이스와 더불어 일부 골격은 쿠버네티스 코어 내에 유지될 것이다. 클라우드 제공사업자 특유의 구현은 코어의 외부에 탑재되어 코어 내에 정의된 인터페이스를 구현할 것이다.
개발 중인 플러그인에 대한 보다 자세한 정보는, [클라우드 컨트롤러 매니저 개발하기](/docs/tasks/administer-cluster/developing-cloud-controller-manager/)를 참고한다.
## 인가
이 섹션은 CCM에 의해 작업을 수행하기 위해 다양한 API 오브젝트에서 요구되는 접근에 대해 구분해 본다.
클라우드 컨틀롤러 매니저의 내부 컨트롤러에는 다음 컨트롤러들이 포함된다.
### 노드 컨트롤러
노드 컨트롤러는 오직 노드 오브젝트와 동작한다. 노드 오브젝트를 get, list, create, update, patch, watch, 그리고 delete 하기 위한 모든 접근을 요한다.
노드 컨트롤러는 클라우드 인프라스트럭처에 새 서버가 생성될 때 {{< glossary_tooltip text="노드" term_id="node" >}}
오브젝트를 생성하는 역할을 한다. 노드 컨트롤러는 클라우드 공급자의 사용자
테넌시 내에서 실행되는 호스트에 대한 정보를 가져온다. 노드 컨트롤러는 다음 기능들을 수행한다.
v1/Node:
1. 컨트롤러가 클라우드 공급자 API를 통해 찾아내는 각 서버에 대해 노드 오브젝트를 초기화한다.
2. 클라우드 관련 정보(예를 들어, 노드가 배포되는 지역과 사용 가능한 리소스(CPU, 메모리 등))를
사용해서 노드 오브젝트에 어노테이션과 레이블을 작성한다.
3. 노드의 호스트 이름과 네트워크 주소를 가져온다.
4. 노드의 상태를 확인한다. 노드가 응답하지 않는 경우, 이 컨트롤러는 사용자가
이용하는 클라우드 공급자의 API를 통해 서버가 비활성화됨 / 삭제됨 / 종료됨인지 확인한다.
노드가 클라우드에서 삭제된 경우, 컨트롤러는 사용자의 쿠버네티스 클러스터에서 노드
오브젝트를 삭제한다.
일부 클라우드 공급자의 구현에서는 이를 노드 컨트롤러와 별도의 노드
라이프사이클 컨트롤러로 분리한다.
### 라우트 컨트롤러
라우트 컨트롤러는 사용자의 쿠버네티스 클러스터의 다른 노드에
있는 각각의 컨테이너가 서로 통신할 수 있도록 클라우드에서
라우트를 적절히 구성해야 한다.
클라우드 공급자에 따라 라우트 컨트롤러는 파드 네트워크
IP 주소 블록을 할당할 수도 있다.
### 서비스 컨트롤러
{{< glossary_tooltip text="서비스" term_id="service" >}} 는 관리형 로드 밸런서,
IP 주소, 네트워크 패킷 필터링 그리고 대상 상태 확인과 같은
클라우드 인프라스트럭처 컴포넌트와 통합된다. 서비스 컨트롤러는 사용자의 클라우드
공급자 API와 상호 작용해서 필요한 서비스 리소스를 선언할 때
로드 밸런서와 기타 인프라스트럭처 컴포넌트를 설정한다.
## 인가
이 섹션에서는 클라우드 컨트롤러 매니저가 작업을 수행하기 위해
다양한 API 오브젝트에 필요한 접근 권한을 세분화한다.
### 노드 컨트롤러 {#authorization-node-controller}
노드 컨트롤러는 노드 오브젝트에서만 작동한다. 노드 오브젝트를 읽고,
수정하려면 전체 접근 권한이 필요하다.
`v1/Node`:
- Get
- List
@ -117,23 +96,24 @@ v1/Node:
- Watch
- Delete
### 라우트 컨트롤러
### 라우트 컨트롤러 {#authorization-route-controller}
라우트 컨트롤러는 노드 오브젝트 생성에 대해 귀기울이고 적절하게 라우트를 구성한다. 노드 오브젝트에 대한 get 접근을 요한다.
라우트 컨트롤러가 노드 오브젝트의 생성을 수신하고 적절하게
라우트를 구성한다. 노드 오브젝트에 대한 접근 권한이 필요하다.
v1/Node:
`v1/Node`:
- Get
### 서비스 컨트롤러
### 서비스 컨트롤러 {#authorization-service-controller}
서비스 컨트롤러는 서비스 오브젝트 create, update 그리고 delete에 대해 귀기울이고, 서비스를 위해 적절하게 엔드포인트를 구성한다.
서비스 컨트롤러는 서비스 오브젝트 생성, 업데이트 그리고 삭제 이벤트를 수신한 다음 해당 서비스에 대한 엔드포인트를 적절하게 구성한다.
서비스에 접근하기 위해, list, 그리고 watch 접근을 요한다. 서비스 update를 위해 patch와 update 접근을 요한다.
서비스에 접근하려면, 목록과 감시 접근 권한이 필요하다. 서비스를 업데이트하려면, 패치와 업데이트 접근 권한이 필요하다.
서비스에 대한 엔드포인트 설정을 위해, create, list, get, watch, 그리고 update를 하기위한 접근을 요한다.
서비스에 대한 엔드포인트 리소스를 설정하려면 생성, 목록, 가져오기, 감시 그리고 업데이트에 대한 접근 권한이 필요하다.
v1/Service:
`v1/Service`:
- List
- Get
@ -141,21 +121,22 @@ v1/Service:
- Patch
- Update
### 그 외의 것들
### 그 외의 것들 {#authorization-miscellaneous}
CCM의 코어에 대한 구현은 이벤트를 create 하고, 보안 작업을 보장하기 위한 접근을 요하며, ServiceAccount를 create 하기 위한 접근을 요한다.
클라우드 컨트롤러 매니저의 핵심 구현을 위해 이벤트 오브젝트를 생성하고, 안전한 작동을 보장하기 위해 서비스어카운트(ServiceAccounts)를 생성해야 한다.
v1/Event:
`v1/Event`:
- Create
- Patch
- Update
v1/ServiceAccount:
`v1/ServiceAccount`:
- Create
CCM에 대한 RBAC ClusterRole은 다음과 같다.
클라우드 컨트롤러 매니저의 {{< glossary_tooltip term_id="rbac" text="RBAC" >}}
클러스터롤(ClusterRole)은 다음과 같다.
```yaml
apiVersion: rbac.authorization.k8s.io/v1
@ -219,24 +200,16 @@ rules:
- update
```
## 벤더 구현사항
다음은 클라우드 제공사업자들이 구현한 CCM들이다.
* [Alibaba Cloud](https://github.com/kubernetes/cloud-provider-alibaba-cloud)
* [AWS](https://github.com/kubernetes/cloud-provider-aws)
* [Azure](https://github.com/kubernetes/cloud-provider-azure)
* [BaiduCloud](https://github.com/baidu/cloud-provider-baiducloud)
* [DigitalOcean](https://github.com/digitalocean/digitalocean-cloud-controller-manager)
* [GCP](https://github.com/kubernetes/cloud-provider-gcp)
* [Hetzner](https://github.com/hetznercloud/hcloud-cloud-controller-manager)
* [Linode](https://github.com/linode/linode-cloud-controller-manager)
* [OpenStack](https://github.com/kubernetes/cloud-provider-openstack)
* [Oracle](https://github.com/oracle/oci-cloud-controller-manager)
* [TencentCloud](https://github.com/TencentCloud/tencentcloud-cloud-controller-manager)
## 클러스터 관리
CCM을 구성하고 작동하기 위한 전체 안내는 [여기](/docs/tasks/administer-cluster/running-cloud-controller/#cloud-controller-manager)에서 제공된다.
{{% /capture %}}
{{% capture whatsnext %}}
[클라우드 컨트롤러 매니저 관리](/docs/tasks/administer-cluster/running-cloud-controller/#cloud-controller-manager)에는
클라우드 컨트롤러 매니저의 실행과 관리에 대한 지침이 있다.
자체 클라우드 컨트롤러 매니저를 구현하거나 기존 프로젝트를 확장하는 방법을 알고 싶은가?
클라우드 컨트롤러 매니저는 Go 인터페이스를 사용해서 모든 클라우드 플러그인을 구현할 수 있다. 구체적으로, [kubernetes/cloud-provider](https://github.com/kubernetes/cloud-provider)의 [`cloud.go`](https://github.com/kubernetes/cloud-provider/blob/release-1.17/cloud.go#L42-L62)에 정의된 `CloudProvider` 인터페이스를 사용한다.
이 문서(노드, 라우트와 서비스)에서 강조된 공유 컨트롤러의 구현과 공유 cloudprovider 인터페이스와 함께 일부 스캐폴딩(scaffolding)은 쿠버네티스 핵심의 일부이다. 클라우드 공급자 전용 구현은 쿠버네티스의 핵심 바깥에 있으며 `CloudProvider` 인터페이스를 구현한다.
플러그인 개발에 대한 자세한 내용은 [클라우드 컨트롤러 매니저 개발하기](/docs/tasks/administer-cluster/developing-cloud-controller-manager/)를 참조한다.
{{% /capture %}}

View File

@ -0,0 +1,66 @@
---
title: 컨트롤 플레인-노드 간 통신
content_template: templates/concept
weight: 20
aliases:
- master-node-communication
---
{{% capture overview %}}
이 문서는 컨트롤 플레인(실제로는 API 서버)과 쿠버네티스 클러스터 사이에 대한 통신 경로의 목록을 작성한다. 이는 사용자가 신뢰할 수 없는 네트워크(또는 클라우드 공급자의 완전한 퍼블릭 IP)에서 클러스터를 실행할 수 있도록 네트워크 구성을 강화하기 위한 맞춤 설치를 할 수 있도록 한다.
{{% /capture %}}
{{% capture body %}}
## 노드에서 컨트롤 플레인으로의 통신
노드에서 컨트롤 플레인까지의 모든 통신 경로는 API 서버에서 종료된다(다른 마스터 컴포넌트 중 어느 것도 원격 서비스를 노출하도록 설계되지 않았다). 일반적인 배포에서 API 서버는 하나 이상의 클라이언트 [인증](/docs/reference/access-authn-authz/authentication/) 형식이 활성화된 보안 HTTPS 포트(443)에서 원격 연결을 수신하도록 구성된다.
특히 [익명의 요청](/docs/reference/access-authn-authz/authentication/#anonymous-requests) 또는 [서비스 어카운트 토큰](/docs/reference/access-authn-authz/authentication/#service-account-tokens)이 허용되는 경우, 하나 이상의 [권한 부여](/docs/reference/access-authn-authz/authorization/) 형식을 사용해야 한다.
노드는 유효한 클라이언트 자격 증명과 함께 API 서버에 안전하게 연결할 수 있도록 클러스터에 대한 공개 루트 인증서로 프로비전해야 한다. 예를 들어, 기본 GKE 배포에서, kubelet에 제공되는 클라이언트 자격 증명은 클라이언트 인증서 형식이다. kubelet 클라이언트 인증서의 자동 프로비저닝은 [kubelet TLS 부트스트랩](/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/)을 참고한다.
API 서버에 연결하려는 파드는 쿠버네티스가 공개 루트 인증서와 유효한 베어러 토큰(bearer token)을 파드가 인스턴스화될 때 파드에 자동으로 주입하도록 서비스 어카운트를 활용하여 안전하게 연결할 수 있다.
`kubernetes` 서비스(모든 네임스페이스의)는 API 서버의 HTTPS 엔드포인트로 리디렉션되는 가상 IP 주소(kube-proxy를 통해)로 구성되어 있다.
컨트롤 플레인 컴포넌트는 보안 포트를 통해 클러스터 API 서버와도 통신한다.
결과적으로, 노드 및 노드에서 실행되는 파드에서 컨트롤 플레인으로 연결하기 위한 기본 작동 모드는 기본적으로 보호되며 신뢰할 수 없는 네트워크 및/또는 공용 네트워크에서 실행될 수 있다.
## 컨트롤 플레인에서 노드로의 통신
컨트롤 플레인(API 서버)에서 노드로는 두 가지 기본 통신 경로가 있다. 첫 번째는 API 서버에서 클러스터의 각 노드에서 실행되는 kubelet 프로세스이다. 두 번째는 API 서버의 프록시 기능을 통해 API 서버에서 모든 노드, 파드 또는 서비스에 이르는 것이다.
### API 서버에서 kubelet으로의 통신
API 서버에서 kubelet으로의 연결은 다음의 용도로 사용된다.
* 파드에 대한 로그를 가져온다.
* 실행 중인 파드에 (kubectl을 통해) 연결한다.
* kubelet의 포트-포워딩 기능을 제공한다.
이 연결은 kubelet의 HTTPS 엔드포인트에서 종료된다. 기본적으로, API 서버는 kubelet의 서빙(serving) 인증서를 확인하지 않으므로, 연결이 중간자(man-in-the-middle) 공격의 대상이 되며, 신뢰할 수 없는 네트워크 및/또는 공용 네트워크에서 실행하기에 **안전하지 않다** .
이 연결을 확인하려면, `--kubelet-certificate-authority` 플래그를 사용하여 API 서버에 kubelet의 서빙 인증서를 확인하는 데 사용할 루트 인증서 번들을 제공한다.
이것이 가능하지 않은 경우, 신뢰할 수 없는 네트워크 또는 공용 네트워크를 통한 연결을 피하기 위해 필요한 경우 API 서버와 kubelet 사이에 [SSH 터널링](/ko/docs/concepts/architecture/control-plane-node-communication/#ssh-터널)을
사용한다.
마지막으로, kubelet API를 보호하려면 [Kubelet 인증 및/또는 권한 부여](/docs/admin/kubelet-authentication-authorization/)를 활성화해야 한다.
### API 서버에서 노드, 파드 및 서비스로의 통신
API 서버에서 노드, 파드 또는 서비스로의 연결은 기본적으로 일반 HTTP 연결로 연결되므로 인증되거나 암호화되지 않는다. API URL에서 노드, 파드 또는 서비스 이름을 접두어 `https:` 로 사용하여 보안 HTTPS 연결을 통해 실행될 수 있지만, HTTPS 엔드포인트가 제공한 인증서의 유효성을 검증하지 않거나 클라이언트 자격 증명을 제공하지 않으므로 연결이 암호화되는 동안 무결성을 보장하지 않는다. 이러한 연결은 신뢰할 수 없는 네트워크 및/또는 공용 네트워크에서 실행하기에 **현재는 안전하지 않다** .
### SSH 터널
쿠버네티스는 SSH 터널을 지원하여 컨트롤 플레인에서 노드로의 통신 경로를 보호한다. 이 구성에서, API 서버는 클러스터의 각 노드에 SSH 터널을 시작하고(포트 22에서 수신 대기하는 ssh 서버에 연결) 터널을 통해 kubelet, 노드, 파드 또는 서비스로 향하는 모든 트래픽을 전달한다.
이 터널은 트래픽이 노드가 실행 중인 네트워크 외부에 노출되지 않도록 한다.
SSH 터널은 현재 더 이상 사용되지 않으므로 수행 중인 작업이 어떤 것인지 모른다면 사용하면 안된다. Konnectivity 서비스는 이 통신 채널을 대체한다.
### Konnectivity 서비스
{{< feature-state for_k8s_version="v1.18" state="beta" >}}
SSH 터널을 대체하는 Konnectivity 서비스는 컨트롤 플레인에서 클러스터 통신에 TCP 레벨 프록시를 제공한다. Konnectivity는 컨트롤 플레인 네트워크와 노드 네트워크에서 각각 실행되는 Konnectivity 서버와 Konnectivity 에이전트의 두 부분으로 구성된다. Konnectivity 에이전트는 Konnectivity 서버에 대한 연결을 시작하고 연결을 유지한다.
그런 다음 컨트롤 플레인에서 노드로의 모든 트래픽은 이 연결을 통과한다.
클러스터에서 설정하는 방법에 대해서는 [Konnectivity 서비스 설정](/docs/tasks/setup-konnectivity/)을 참조한다.

View File

@ -52,7 +52,7 @@ weight: 30
작업을 수행한 다음 중지하는
쿠버네티스 리소스 이다.
(일단 [스케줄되면](/ko/docs/concepts/scheduling/), 파드 오브젝트는 kubelet
(일단 [스케줄되면](/ko/docs/concepts/scheduling-eviction/), 파드 오브젝트는 kubelet
의 의도한 상태 중 일부가 된다.)
잡 컨트롤러가 새로운 작업을 확인하면, 클러스터 어딘가에서

View File

@ -0,0 +1,57 @@
---
title: 애드온 설치
content_template: templates/concept
---
{{% capture overview %}}
애드온은 쿠버네티스의 기능을 확장한다.
이 페이지는 사용 가능한 일부 애드온과 관련 설치 지침 링크를 나열한다.
각 섹션의 애드온은 알파벳 순으로 정렬되어 있다. 순서는 우선 순위와는 상관없다.
{{% /capture %}}
{{% capture body %}}
## 네트워킹과 네트워크 폴리시
* [ACI](https://www.github.com/noironetworks/aci-containers)는 Cisco ACI로 통합 컨테이너 네트워킹 및 네트워크 보안을 제공한다.
* [Calico](https://docs.projectcalico.org/latest/introduction/)는 네트워킹 및 네트워크 폴리시 제공자이다. Calico는 유연한 네트워킹 옵션을 지원하므로 BGP 유무에 관계없이 비-오버레이 및 오버레이 네트워크를 포함하여 가장 상황에 맞는 옵션을 선택할 수 있다. Calico는 동일한 엔진을 사용하여 서비스 메시 계층(service mesh layer)에서 호스트, 파드 및 (이스티오(istio)와 Envoy를 사용하는 경우) 애플리케이션에 대한 네트워크 폴리시를 적용한다.
* [Canal](https://github.com/tigera/canal/tree/master/k8s-install)은 Flannel과 Calico를 통합하여 네트워킹 및 네트워크 폴리시를 제공한다.
* [Cilium](https://github.com/cilium/cilium)은 L3 네트워크 및 네트워크 폴리시 플러그인으로 HTTP/API/L7 폴리시를 투명하게 시행할 수 있다. 라우팅 및 오버레이/캡슐화 모드를 모두 지원하며, 다른 CNI 플러그인 위에서 작동할 수 있다.
* [CNI-Genie](https://github.com/Huawei-PaaS/CNI-Genie)를 사용하면 쿠버네티스는 Calico, Canal, Flannel, Romana 또는 Weave와 같은 CNI 플러그인을 완벽하게 연결할 수 있다.
* [Contiv](http://contiv.github.io)는 다양한 유스케이스와 풍부한 폴리시 프레임워크를 위해 구성 가능한 네트워킹(BGP를 사용하는 네이티브 L3, vxlan을 사용하는 오버레이, 클래식 L2 그리고 Cisco-SDN/ACI)을 제공한다. Contiv 프로젝트는 완전히 [오픈소스](http://github.com/contiv)이다. [인스톨러](http://github.com/contiv/install)는 kubeadm을 이용하거나, 그렇지 않은 경우에 대해서도 설치 옵션을 모두 제공한다.
* [Contrail](http://www.juniper.net/us/en/products-services/sdn/contrail/contrail-networking/)은 [Tungsten Fabric](https://tungsten.io)을 기반으로 하며, 오픈소스이고, 멀티 클라우드 네트워크 가상화 및 폴리시 관리 플랫폼이다. Contrail과 Tungsten Fabric은 쿠버네티스, OpenShift, OpenStack 및 Mesos와 같은 오케스트레이션 시스템과 통합되어 있으며, 가상 머신, 컨테이너/파드 및 베어 메탈 워크로드에 대한 격리 모드를 제공한다.
* [Flannel](https://github.com/coreos/flannel/blob/master/Documentation/kubernetes.md)은 쿠버네티스와 함께 사용할 수 있는 오버레이 네트워크 제공자이다.
* [Knitter](https://github.com/ZTE/Knitter/)는 쿠버네티스 파드에서 여러 네트워크 인터페이스를 지원하는 플러그인이다.
* [Multus](https://github.com/Intel-Corp/multus-cni)는 쿠버네티스에서 SRIOV, DPDK, OVS-DPDK 및 VPP 기반 워크로드 외에 모든 CNI 플러그인(예: Calico, Cilium, Contiv, Flannel)을 지원하기 위해 쿠버네티스에서 다중 네트워크 지원을 위한 멀티 플러그인이다.
* [NSX-T](https://docs.vmware.com/en/VMware-NSX-T/2.0/nsxt_20_ncp_kubernetes.pdf) 컨테이너 플러그인(NCP)은 VMware NSX-T와 쿠버네티스와 같은 컨테이너 오케스트레이터 간의 통합은 물론 NSX-T와 PKS(Pivotal 컨테이너 서비스) 및 OpenShift와 같은 컨테이너 기반 CaaS/PaaS 플랫폼 간의 통합을 제공한다.
* [Nuage](https://github.com/nuagenetworks/nuage-kubernetes/blob/v5.1.1-1/docs/kubernetes-1-installation.rst)는 가시성과 보안 모니터링 기능을 통해 쿠버네티스 파드와 비-쿠버네티스 환경 간에 폴리시 기반 네트워킹을 제공하는 SDN 플랫폼이다.
* [Romana](http://romana.io)는 [네트워크폴리시 API](/docs/concepts/services-networking/network-policies/)도 지원하는 파드 네트워크용 Layer 3 네트워킹 솔루션이다. Kubeadm 애드온 설치에 대한 세부 정보는 [여기](https://github.com/romana/romana/tree/master/containerize)에 있다.
* [Weave Net](https://www.weave.works/docs/net/latest/kube-addon/)은 네트워킹 및 네트워크 폴리시를 제공하고, 네트워크 파티션의 양면에서 작업을 수행하며, 외부 데이터베이스는 필요하지 않다.
## 서비스 검색
* [CoreDNS](https://coredns.io)는 유연하고 확장 가능한 DNS 서버로, 파드를 위한 클러스터 내 DNS로 [설치](https://github.com/coredns/deployment/tree/master/kubernetes)할 수 있다.
## 시각화 &amp; 제어
* [대시보드](https://github.com/kubernetes/dashboard#kubernetes-dashboard)는 쿠버네티스를 위한 대시보드 웹 인터페이스이다.
* [Weave Scope](https://www.weave.works/documentation/scope-latest-installing/#k8s)는 컨테이너, 파드, 서비스 등을 그래픽으로 시각화하는 도구이다. [Weave Cloud 어카운트](https://cloud.weave.works/)와 함께 사용하거나 UI를 직접 호스팅한다.
## 인프라스트럭처
* [KubeVirt](https://kubevirt.io/user-guide/#/installation/installation)는 쿠버네티스에서 가상 머신을 실행하기 위한 애드온이다. 일반적으로 베어 메탈 클러스터에서 실행한다.
## 레거시 애드온
더 이상 사용되지 않는 [cluster/addons](https://git.k8s.io/kubernetes/cluster/addons) 디렉터리에 다른 여러 애드온이 문서화되어 있다.
잘 관리된 것들이 여기에 연결되어 있어야 한다. PR을 환영한다!
{{% /capture %}}

View File

@ -0,0 +1,414 @@
---
title: 클라우드 제공자
content_template: templates/concept
weight: 30
---
{{% capture overview %}}
이 페이지에서는 특정 클라우드 제공자에서 실행 중인 쿠버네티스를 관리하는 방법에
대해 설명한다.
{{% /capture %}}
{{% capture body %}}
### kubeadm
[kubeadm](/docs/reference/setup-tools/kubeadm/kubeadm/)은 쿠버네티스 클러스터를 생성하는 데 많이 사용하는 옵션이다.
kubeadm에는 클라우드 제공자에 대한 구성 정보를 지정하는 구성 옵션이 있다. 예를 들어
kubeadm을 사용하여 일반적인 인-트리(in-tree) 클라우드 제공자를 아래와 같이 구성할 수 있다.
```yaml
apiVersion: kubeadm.k8s.io/v1beta2
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
cloud-provider: "openstack"
cloud-config: "/etc/kubernetes/cloud.conf"
---
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v1.13.0
apiServer:
extraArgs:
cloud-provider: "openstack"
cloud-config: "/etc/kubernetes/cloud.conf"
extraVolumes:
- name: cloud
hostPath: "/etc/kubernetes/cloud.conf"
mountPath: "/etc/kubernetes/cloud.conf"
controllerManager:
extraArgs:
cloud-provider: "openstack"
cloud-config: "/etc/kubernetes/cloud.conf"
extraVolumes:
- name: cloud
hostPath: "/etc/kubernetes/cloud.conf"
mountPath: "/etc/kubernetes/cloud.conf"
```
인-트리 클라우드 제공자는 일반적으로 [kube-apiserver](/docs/admin/kube-apiserver/), [kube-controller-manager](/docs/admin/kube-controller-manager/)
및 [kubelet](/docs/admin/kubelet/)의 커맨드 라인에 지정된 `--cloud-provider``--cloud-config` 가 모두 필요하다.
각 제공자에 대해 `--cloud-config` 에 지정된 파일의 내용도 아래에 설명되어 있다.
모든 외부 클라우드 제공자의 경우, 아래 제공자에 대한 제목 아래에 있는 개별 리포지터리의 지침을 따르거나,
[모든 리포지터리 목록](https://github.com/kubernetes?q=cloud-provider-&type=&language=)을 볼 수 있다
## AWS
이 섹션에서는 Amazon Web Services에서 쿠버네티스를 실행할 때 사용할 수 있는
모든 구성에 대해 설명한다.
이 외부 클라우드 제공자를 사용하려는 경우, 해당 리포지터리는 [kubernetes/cloud-provider-aws](https://github.com/kubernetes/cloud-provider-aws#readme)이다.
### 노드 이름
AWS 클라우드 제공자는 AWS 인스턴스의 프라이빗 DNS 이름을 쿠버네티스 노드 오브젝트의 이름으로 사용한다.
### 로드 밸런서
아래와 같이 어노테이션을 구성하여 AWS의 특정 기능을 사용하도록
[외부 로드 밸런서](/docs/tasks/access-application-cluster/create-external-load-balancer/)를 설정할 수 있다.
```yaml
apiVersion: v1
kind: Service
metadata:
name: example
namespace: kube-system
labels:
run: example
annotations:
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:xx-xxxx-x:xxxxxxxxx:xxxxxxx/xxxxx-xxxx-xxxx-xxxx-xxxxxxxxx #이 값을 교체한다
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http
spec:
type: LoadBalancer
ports:
- port: 443
targetPort: 5556
protocol: TCP
selector:
app: example
```
_어노테이션_ 을 사용하여 AWS의 로드 밸런서 서비스에 다른 설정을 적용할 수 있다. 다음은 AWS ELB에서 지원하는 어노테이션에 대해 설명한다.
* `service.beta.kubernetes.io/aws-load-balancer-access-log-emit-interval`: 액세스 로그 방출 간격을 지정하는 데 사용된다.
* `service.beta.kubernetes.io/aws-load-balancer-access-log-enabled`: 서비스에서 액세스 로그를 활성화하거나 비활성화하는 데 사용된다.
* `service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-name`: 액세스 로그 s3 버킷 이름을 지정하는 데 사용된다.
* `service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-prefix`: 액세스 로그 s3 버킷 접두사를 지정하는 데 사용된다.
* `service.beta.kubernetes.io/aws-load-balancer-additional-resource-tags`: 서비스에서 쉼표로 구분된 키-값 쌍의 목록을 지정하여 ELB에 추가 태그로 기록된다. 예를 들면 다음과 같다. `"Key1=Val1,Key2=Val2,KeyNoVal1=,KeyNoVal2"`
* `service.beta.kubernetes.io/aws-load-balancer-backend-protocol`: 서비스에서 리스너 뒤의 백엔드(파드)가 언급한 프로토콜을 지정하는 데 사용된다. 만약 `http` (기본값) 또는 `https` 인 경우, 연결을 종료하고 헤더를 파싱하는 HTTPS 리스너가 생성된다. `ssl` 이나 `tcp` 로 설정된 경우, "원시(raw)" SSL 리스너가 사용된다. `http` 로 설정하고 `aws-load-balancer-ssl-cert` 를 사용하지 않았다면 HTTP 리스너가 사용된다.
* `service.beta.kubernetes.io/aws-load-balancer-ssl-cert`: 서비스에서 보안 리스너를 요청하는 데 사용된다. 값은 유효한 인증서 ARN이다. 자세한 내용은, [ELB 리스너 구성](https://docs.aws.amazon.com/ko_kr/elasticloadbalancing/latest/classic/elb-listener-config.html)을 참고한다. CertARN은 IAM 또는 CM 인증서 ARN이다(예: `arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012`).
* `service.beta.kubernetes.io/aws-load-balancer-connection-draining-enabled`: 서비스에서 연결 드레이닝(draining)을 활성화하거나 비활성화하는 데 사용된다.
* `service.beta.kubernetes.io/aws-load-balancer-connection-draining-timeout`: 서비스에서 연결 드레이닝 타임아웃 값을 지정하는 데 사용된다.
* `service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout`: 서비스에서 유휴 연결 타임아웃 값을 지정하는 데 사용된다.
* `service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled`: 서비스에서 교차 영역의 로드 밸런싱을 활성화하거나 비활성화하는 데 사용된다.
* `service.beta.kubernetes.io/aws-load-balancer-security-groups`: 생성된 ELB에 추가할 보안 그룹을 지정하는 데 사용된다. 이는 이전에 ELB에 할당된 다른 모든 보안 그룹을 대체한다.
* `service.beta.kubernetes.io/aws-load-balancer-extra-security-groups`: 서비스에서 생성된 ELB에 추가할 추가적인 보안 그룹을 지정하는 데 사용된다.
* `service.beta.kubernetes.io/aws-load-balancer-internal`: 서비스에서 내부 ELB 사용 희망을 표시하기 위해 사용된다.
* `service.beta.kubernetes.io/aws-load-balancer-proxy-protocol`: 서비스에서 ELB에서 프록시 프로토콜을 활성화하는 데 사용된다. 현재는 모든 ELB 백엔드에서 프록시 프로토콜을 사용하도록 설정하는 `*` 값만 허용한다. 향후에는 특정 백엔드에서만 프록시 프로토콜을 설정할 수 있도록 이를 조정할 수 있게 된다.
* `service.beta.kubernetes.io/aws-load-balancer-ssl-ports`: SSL/HTTPS 리스너를 사용할 쉼표로 구분된 포트의 목록을 지정하기 위해 서비스에서 사용된다. 기본값은 `*`(모두)이다.
AWS 어노테이션에 대한 정보 출처는 [aws.go](https://github.com/kubernetes/legacy-cloud-providers/blob/master/aws/aws.go)의 코멘트이다.
## Azure
이 외부 클라우드 제공자를 사용하려는 경우, 해당 리포지터리는 [kubernetes/cloud-provider-azure](https://github.com/kubernetes/cloud-provider-azure#readme)이다.
### 노드 이름
Azure 클라우드 제공자는 쿠버네티스 노드 오브젝트의 이름으로 노드의 (kubelet에 의해 결정되거나 `--hostname-override` 로 재정의된) 호스트 이름(hostname)을 사용한다.
참고로 쿠버네티스 노드 이름은 Azure VM 이름과 일치해야 한다.
## CloudStack
이 외부 클라우드 제공자를 사용하려는 경우, 해당 리포지터리는 [apache/cloudstack-kubernetes-provider](https://github.com/apache/cloudstack-kubernetes-provider)이다.
### 노드 이름
CloudStack 클라우드 제공자는 쿠버네티스 노드 오브젝트의 이름으로 노드의 (kubelet에 의해 결정되거나 `--hostname-override` 로 재정의된) 호스트 이름을 사용한다.
참고로 쿠버네티스 노드 이름은 CloudStack VM 이름과 일치해야 한다.
## GCE
이 외부 클라우드 제공자를 사용하려는 경우, 해당 리포지터리는 [kubernetes/cloud-provider-gcp](https://github.com/kubernetes/cloud-provider-gcp#readme)이다.
### 노드 이름
GCE 클라우드 제공자는 쿠버네티스 노드 오브젝트의 이름으로 노드의 (kubelet에 의해 결정되거나 `--hostname-override` 로 재정의된) 호스트 이름을 사용한다.
참고로 쿠버네티스 노드 이름의 첫 번째 세그먼트는 GCE 인스턴스 이름과 일치해야 한다(예: `kubernetes-node-2.c.my-proj.internal` 이름이 지정된 노드는 `kubernetes-node-2` 이름이 지정된 인스턴스에 해당해야 함).
## OpenStack
이 섹션에서는 쿠버네티스와 함께 OpenStack을 사용할 때 사용할 수 있는
모든 구성에 대해 설명한다.
이 외부 클라우드 제공자를 사용하려는 경우, 해당 리포지터리는 [kubernetes/cloud-provider-openstack](https://github.com/kubernetes/cloud-provider-openstack#readme)이다.
### 노드 이름
OpenStack 클라우드 제공자는 (OpenStack 메타데이터에서 결정한) 인스턴스 이름을 쿠버네티스 노드 오브젝트의 이름으로 사용한다.
참고로 kubelet이 노드 오브젝트를 성공적으로 등록하려면 인스턴스 이름이 유효한 쿠버네티스 노드 이름이어야 한다.
### 서비스
쿠버네티스에 대한
OpenStack 클라우드 제공자 구현은 사용 가능한 경우 기본 클라우드에서
이러한 OpenStack 서비스 사용을 지원한다.
| 서비스 | API 버전 | 필수 |
|--------------------------|----------------|----------|
| 블록 스토리지 (Cinder) | V1†, V2, V3 | 아니오 |
| 컴퓨트 (Nova) | V2 | 아니오 |
| 아이덴티티(Identity) (Keystone) | V2‡, V3 | 예 |
| 로드 밸런싱 (Neutron) | V1§, V2 | 아니오 |
| 로드 밸런싱 (Octavia) | V2 | 아니오 |
† 블록 스토리지 V1 API 지원은 사용 중단(deprecated)되며, 쿠버네티스 1.9에서 블록 스토리지
V3 API 지원이 추가되었다.
‡ 아이덴티티 V2 API 지원은 사용 중단되며, 향후 릴리스에서는 제공자에서
제거될 예정이다. "Queens" 릴리스부터 OpenStack은 더 이상 아이덴티티 V2 API를
공개하지 않는다.
§ 로드 밸런싱 V1 API 지원이 쿠버네티스 1.9에서 제거되었다.
서비스 디스커버리는 제공자 구성에서 제공된 `auth-url` 을 사용하여
OpenStack 아이덴티티(Keystone)에서 관리하는 서비스 카탈로그를
나열하여 수행된다. Keystone 이외의 OpenStack 서비스를 사용할 수 없고
영향을 받는 기능에 대한 지원을 거부할 경우 제공자는 기능이
점진적으로 떨어진다. 기본 클라우드에서 Neutron이 게시한 확장 목록을 기반으로
특정 기능을 활성화하거나 비활성화할 수도 있다.
### cloud.conf
쿠버네티스는 cloud.conf 파일을 통해 OpenStack과 상호 작용하는 방법을 알고 있다. 쿠버네티스에
OpenStack 인증 엔드포인트의 자격 증명과 위치를 제공하는 파일이다.
다음의 세부 정보를 지정하여 cloud.conf 파일을 만들 수 있다.
#### 일반적인 구성
이것은 가장 자주 설정해야 하는 값에 대한 일반적인 구성의
예시이다. OpenStack 클라우드의 Keystone
엔드포인트에서, 제공자를 가리키고 이를 인증하는 방법에 대한 세부 사항을 제공하고,
로드 밸런서를 구성한다.
```yaml
[Global]
username=user
password=pass
auth-url=https://<keystone_ip>/identity/v3
tenant-id=c869168a828847f39f7f06edd7305637
domain-id=2a73b8f597c04551a0fdc8e95544be8a
[LoadBalancer]
subnet-id=6937f8fa-858d-4bc9-a3a5-18d2c957166a
```
##### 글로벌
OpenStack 제공자에 대한 다음의 구성 옵션은 글로벌
구성과 관련이 있으며 `cloud.conf` 파일의 `[Global]` 섹션에 있어야
한다.
* `auth-url` (필수): 인증에 사용되는 Keystone API의 URL이다.
OpenStack 제어판의 액세스 및 보안 > API 액세스 >
자격 증명에서 찾을 수 있다.
* `username` (필수): Keystone에 설정된 유효한 사용자의 username을 나타낸다.
* `password` (필수): Keystone에 설정된 유효한 사용자의 password를 나타낸다.
* `tenant-id` (필수): 리소스를 생성하려는 프로젝트의 id를 지정하는 데
사용된다.
* `tenant-name` (선택): 리소스를 생성하려는 프로젝트의 이름을
지정하는 데 사용된다.
* `trust-id` (선택): 권한 부여에 사용할 트러스트(trust)의 식별자를 지정하는 데
사용된다. 트러스트는 한 사용자(트러스터(trustor))의 권한을 다른 사용자(트러스티(trustee))에게 역할을
위임하고, 선택적으로 트러스티가 트러스터를 가장하도록
허용한다. 사용 가능한 트러스트는
Keystone API의 `/v3/OS-TRUST/trusts` 엔드포인트 아래에 있다.
* `domain-id` (선택): 사용자가 속한 도메인의 id를 지정하는 데
사용된다.
* `domain-name` (선택): 사용자가 속한 도메인의 이름을 지정하는 데
사용된다.
* `region` (선택): 멀티-리전(multi-region) OpenStack 클라우드에서
실행할 때 사용할 리전의 식별자를 지정하는 데 사용된다. 리전은 OpenStack 디플로이먼트의
일반 디비전(division)이다. 리전에 엄격한 지리적 의미는 없지만,
디플로이먼트 시 `us-east` 와 같은
리전의 식별자에 지리적 이름을 사용할 수 있다. 사용 가능한 지역은
Keystone API의 `/v3/regions` 엔드포인트 아래에 있다.
* `ca-file` (선택): 사용자 지정 CA 파일의 경로를 지정하는 데 사용된다.
테넌트를 프로젝트로 변경하는 Keystone V3을 사용하면 `tenant-id` 값이
API의 프로젝트 구성에 자동으로 매핑된다.
##### 로드 밸런서
OpenStack 제공자에 대한 다음의 구성 옵션은 로드 밸런서와 관련이 있으며
`cloud.conf` 파일의 `[LoadBalancer]` 섹션에 있어야
한다.
* `lb-version` (선택): 자동 버전 감지를 대체하는 데 사용된다. 유효한
값은 `v1` 또는 `v2` 이다. 값이 제공되지 않는 경우 자동 감지는
기본 OpenStack 클라우드에 의해 제공되는 가장 최신의 지원되는 버전을
선택한다.
* `use-octavia` (선택): Octavia LBaaS V2 서비스 카탈로그 엔드포인트를 찾고 사용할지의
여부를 결정하는 데 사용된다. 유효한 값은 `true` 또는 `false` 이다.
`true` 가 지정되고 Octaiva LBaaS V2 항목을 찾을 수 없는 경우,
제공자는 폴백(fall back)하고 대신 Neutron LBaaS V2 엔드포인트를 찾으려고
시도한다. 기본값은 `false` 이다.
* `subnet-id` (선택): 로드 밸런서를 생성하려는 서브넷의 id를
지정하는 데 사용된다. Network > Networks 에서 찾을 수 있다. 해당
네트워크를 클릭하여 서브넷을 가져온다.
* `floating-network-id` (선택): 지정된 경우, 로드 밸런서에 대한 유동 IP를
생성한다.
* `lb-method` (선택): 로드 밸런서 풀(pool)의 멤버 간에 부하가
분산되는 알고리즘을 지정하는 데 사용된다. 값은
`ROUND_ROBIN`, `LEAST_CONNECTIONS` 또는 `SOURCE_IP` 가 될 수 있다. 지정되지
않은 경우 기본 동작은 `ROUND_ROBIN` 이다.
* `lb-provider` (선택): 로드 밸런서의 제공자를 지정하는 데 사용된다.
지정하지 않으면, neutron에 구성된 기본 제공자 서비스가
사용된다.
* `create-monitor` (선택): Neutron 로드 밸런서에 대한 헬스 모니터를
생성할지의 여부를 나타낸다. 유효한 값은 `true``false` 이다.
기본값은 `false` 이다. `true` 가 지정되면 `monitor-delay`,
`monitor-timeout``monitor-max-retries` 도 설정해야 한다.
* `monitor-delay` (선택): 로드 밸런서의 멤버에게 프로브(probe)를
보내는 간격의 시간이다. 유효한 시간 단위를 지정해야 한다. 유효한 시간 단위는 "ns", "us"(또는 "µs"), "ms", "s", "m", "h"이다.
* `monitor-timeout` (선택): 모니터가 타임아웃 되기 전에 핑(ping) 응답을
기다리는 최대 시간이다. 값은 지연 값보다 작아야
한다. 유효한 시간 단위를 지정해야 한다. 유효한 시간 단위는 "ns", "us"(또는 "µs"), "ms", "s", "m", "h"이다.
* `monitor-max-retries` (선택): 로드 밸런서 멤버의 상태를 INACTIVE로
변경하기 전에 허용되는 핑 오류 수이다. 1에서 10 사이의
숫자여야 한다.
* `manage-security-groups` (선택): 로드 밸런서가 보안 그룹 규칙을
자동으로 관리해야 하는지의 여부를 결정한다. 유효한 값은
`true``false` 이다. 기본값은 `false` 이다. `true` 가 지정되면
`node-security-group` 도 제공해야 한다.
* `node-security-group` (선택): 관리할 보안 그룹의 ID이다.
##### 블록 스토리지
OpenStack 제공자에 대한 다음의 구성 옵션은 블록 스토리지와 관련이 있으며
`cloud.conf` 파일의 `[BlockStorage]` 섹션에 있어야 한다.
* `bs-version` (선택): 자동 버전 감지를 대체하는 데 사용된다. 유효한
값은 `v1`, `v2`, `v3``auto` 이다. `auto` 가 지정되면 자동
감지는 기본 OpenStack 클라우드에 의해 노출되는 가장 최신의 지원되는
버전을 선택한다. 제공되지 않은 경우 기본값은 `auto` 이다.
* `trust-device-path` (선택): 대부분의 시나리오에서 Cinder가 제공한
블록 장치 이름(예: `/dev/vda`)을 신뢰할 수 없다. 이 부울은
이 동작을 토글(toggle)한다. 이를 `true` 로 설정하면 Cinder에서 제공한
블록 장치 이름을 신뢰하게 된다. 기본값인 `false` 는 일련 번호와
`/dev/disk/by-id` 를 매핑하여 장치 경로를 검색하게 하며
권장하는 방법이다.
* `ignore-volume-az` (선택): Cinder 볼륨을 연결할 때 가용 영역(availability zone)
사용에 영향을 주기 위해 사용된다. Nova와 Cinder의 가용성
영역이 서로 다른 경우, 이 값을 `true` 로 설정해야 한다. 이는 가장 일반적인 상황으로 Nova 가용 영역은
많지만 Cinder는 하나의 가용 영역만 있는 경우이다.
이전 릴리스에서 사용된 동작을 유지하기 위해 기본값은 `false`
이지만, 나중에 변경될 수 있다.
* `node-volume-attach-limit` (선택): 노드에 연결할 수 있는
최대 볼륨 수이다. 기본값은 cinder의 경우 256이다.
포트가 아닌 경로를 사용하여 엔드포인트를 구별하는 OpenStack
디플로이먼트에서 1.8 이하의 쿠버네티스 버전을 배포하는 경우
명시적으로 `bs-version` 파라미터를 설정해야 한다. 경로 기반의 엔드포인트는
`http://foo.bar/volume` 형식이며 포트 기반의 엔드포인트는
`http://foo.bar:xxx` 형식이다.
경로 기반의 엔드포인트를 사용하고 쿠버네티스가 이전 자동 감지 로직을 사용하는 환경에서는
볼륨 분리 시도 시 `BS API version autodetection failed.` 오류가
리턴된다. 이 문제를 해결하려면 클라우드 제공자 구성에
다음을 추가하여 Cinder API 버전 2를 강제로
사용할 수 있다.
```yaml
[BlockStorage]
bs-version=v2
```
##### 메타데이터
OpenStack 제공자에 대한 다음의 구성 옵션은 메타데이터와 관련이 있으며
`cloud.conf` 파일의 `[Metadata]` 섹션에 있어야 한다.
* `search-order` (선택): 이 구성 키는 실행되는 인스턴스와
관련된 메타데이터를 제공자가 검색하는 방식에 영향을 준다. 기본값인
`configDrive,metadataService` 를 사용할 수 있는 경우에 제공자가
먼저 구성 드라이브에서 인스턴스와 관련된 메타데이터를
검색한 다음 메타데이터 서비스를 검색하게 한다. 대체할 수 있는 값은 다음과 같다.
* `configDrive` - 구성 드라이브에서 인스턴스 메타데이터만
검색한다.
* `metadataService` - 메타데이터 서비스에서 인스턴스 메타데이터만
검색한다.
* `metadataService,configDrive` - 사용할 수 있는 경우 먼저 메타데이터
서비스에서 인스턴스 메타데이터를 검색한 다음, 구성 드라이브를 검색한다.
구성 드라이브의 메타데이터는 시간이 지남에 따라
오래될 수 있지만, 메타데이터 서비스는 항상 최신 뷰를 제공하므로
이러한 설정은 바람직하다. 모든 OpenStack 클라우드가
구성 드라이브와 메타데이터 서비스를 모두 제공하는 것은 아니며 하나 또는 다른 하나만
사용할 수 있으므로 기본값은 둘 다를 확인하는 것이다.
##### 라우트
OpenStack 제공자에 대한 다음의 구성 옵션은 [kubenet]
쿠버네티스 네트워크 플러그인과 관련이 있으며 `cloud.conf` 파일의 `[Route]` 섹션에
있어야 한다.
* `router-id` (선택): 기본 클라우드의 Neutron 디플로이먼트가
`extraroutes` 확장을 지원하는 경우 경로를 추가할 라우터를 지정하는 데 `router-id`
를 사용한다. 선택한 라우터는 클러스터 노드를 포함하는 프라이빗 네트워크에
걸쳐 있어야 한다(일반적으로 하나의 노드 네트워크만 있으며, 이 값은
노드 네트워크의 기본 라우터여야 한다). 이 값은 OpenStack에서 [kubenet]을 사용하는 데
필요하다.
[kubenet]: /ko/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/#kubenet
{{% /capture %}}
## OVirt
### 노드 이름
OVirt 클라우드 제공자는 쿠버네티스 노드 오브젝트의 이름으로 노드의 (kubelet에 의해 결정되거나 `--hostname-override` 로 재정의된) 호스트 이름을 사용한다.
참고로 쿠버네티스 노드 이름은 VM FQDN(Ovirt의 `<vm><guest_info><fqdn>...</fqdn></guest_info></vm>` 아래에서 보고된)과 일치해야 한다.
## Photon
### 노드 이름
Photon 클라우드 제공자는 쿠버네티스 노드 오브젝트의 이름으로 노드의 (kubelet에 의해 결정되거나 `--hostname-override` 로 재정의된) 호스트 이름을 사용한다.
참고로 쿠버네티스 노드 이름은 Photon VM 이름(또는 `--cloud-config` 에서 `overrideIP` 가 true로 설정된 경우, 쿠버네티스 노드 이름은 Photon VM IP 주소와 일치해야 함)과 일치해야 한다.
## vSphere
{{< tabs name="vSphere cloud provider" >}}
{{% tab name="vSphere 6.7U3 이상" %}}
vSphere 6.7U3 이상의 모든 vSphere 디플로이먼트의 경우, [vSphere CSI 드라이버](https://github.com/kubernetes-sigs/vsphere-csi-driver)와 함께 [외부 vSphere 클라우드 제공자](https://github.com/kubernetes/cloud-provider-vsphere)를 권장한다. 퀵스타트 가이드는 [CSI와 CPI를 사용하여 vSphere에 쿠버네티스 클러스터 배포하기](https://cloud-provider-vsphere.sigs.k8s.io/tutorials/kubernetes-on-vsphere-with-kubeadm.html)를 참고한다.
{{% /tab %}}
{{% tab name="vSphere 6.7U3 미만" %}}
vSphere 6.7U3 미만을 사용할 경우, 인-트리 vSphere 클라우드 제공자를 권장한다. 퀵스타트 가이드는 [kubeadm을 사용하여 vSphere에 쿠버네티스 클러스터 실행하기](https://cloud-provider-vsphere.sigs.k8s.io/tutorials/k8s-vcp-on-vsphere-with-kubeadm.html)를 참고한다.
{{% /tab %}}
{{< /tabs >}}
vSphere 클라우드 제공자에 대한 자세한 문서를 보려면, [vSphere 클라우드 제공자 문서 사이트](https://cloud-provider-vsphere.sigs.k8s.io)를 방문한다.
## IBM 클라우드 쿠버네티스 서비스
### 컴퓨트 노드
IBM 클라우드 쿠버네티스 서비스 제공자를 사용하면, 단일 영역 또는 하나의 리전에서 여러 영역에 걸쳐 가상 노드와 물리(베어 메탈) 노드가 혼합된 클러스터를 생성할 수 있다. 자세한 정보는, [클러스터와 워커(worker) 노드 설정 계획](https://cloud.ibm.com/docs/containers?topic=containers-planning_worker_nodes)을 참고한다.
쿠버네티스 노드 오브젝트의 이름은 IBM 클라우드 쿠버네티스 서비스 워커 노드 인스턴스의 프라이빗 IP 주소이다.
### 네트워킹
IBM 클라우드 쿠버네티스 서비스 제공자는 노드의 네트워크 성능 품질과 네트워크 격리를 위한 VLAN을 제공한다. 사용자 정의 방화벽 및 Calico 네트워크 폴리시를 설정하여 클러스터에 추가적인 보안 계층을 추가하거나 VPN을 통해 온-프레미스 데이터센터에 클러스터를 연결할 수 있다. 자세한 내용은 [인-클러스터(in-cluster) 및 프라이빗 네트워킹 계획](https://cloud.ibm.com/docs/containers?topic=containers-cs_network_cluster#cs_network_cluster)을 참고한다.
퍼블릭 또는 클러스터 내에서 앱을 노출하기 위해 노드포트(NodePort), 로드밸런서 또는 인그레스 서비스를 활용할 수 있다. 어노테이션을 사용하여 인그레스 애플리케이션 로드 밸런서를 커스터마이징 할 수도 있다. 자세한 내용은 [외부 네트워킹으로 앱 노출 계획](https://cloud.ibm.com/docs/containers?topic=containers-cs_network_planning#cs_network_planning)을 참고한다.
### 스토리지
IBM 클라우드 쿠버네티스 서비스 제공자는 쿠버네티스-네이티브 퍼시스턴트 볼륨을 활용하여 사용자가 파일, 블록 및 클라우드 오브젝트 스토리지를 앱에 마운트할 수 있도록 한다. 데이터를 지속적으로 저장하기 위해 서비스로서의-데이터베이스(database-as-a-service)와 써드파티 애드온을 사용할 수도 있다. 자세한 정보는 [고가용성 퍼시스턴트 스토리지 계획](https://cloud.ibm.com/docs/containers?topic=containers-storage_planning#storage_planning)을 참고한다.
## Baidu 클라우드 컨테이너 엔진
### 노드 이름
Baidu 클라우드 제공자는 쿠버네티스 노드 오브젝트의 이름으로 노드의 (kubelet에 의해 결정되거나 `--hostname-override` 로 재정의된) 프라이빗 IP 주소를 사용한다.
참고로 쿠버네티스 노드 이름은 Baidu VM 프라이빗 IP와 일치해야 한다.
## Tencent 쿠버네티스 엔진
이 외부 클라우드 제공자를 사용하려는 경우, 해당 리포지터리는 [TencentCloud/tencentcloud-cloud-controller-manager](https://github.com/TencentCloud/tencentcloud-cloud-controller-manager)이다.
### 노드 이름
Tencent 클라우드 제공자는 쿠버네티스 노드 오브젝트의 이름으로 노드의 (kubelet에 의해 결정되거나 `--hostname-override` 로 재정의된) 호스트 이름을 사용한다.
참고로 쿠버네티스 노드 이름은 Tencent VM 프라이빗 IP와 일치해야 한다.

View File

@ -0,0 +1,317 @@
---
title: 클러스터 네트워킹
content_template: templates/concept
weight: 50
---
{{% capture overview %}}
네트워킹은 쿠버네티스의 중심적인 부분이지만, 어떻게 작동하는지 정확하게
이해하기가 어려울 수 있다. 쿠버네티스에는 4가지 대응해야 할 네트워킹
문제가 있다.
1. 고도로 결합된 컨테이너 간의 통신: 이 문제는
[파드](/ko/docs/concepts/workloads/pods/pod/)와 `localhost` 통신으로 해결된다.
2. 파드 간 통신: 이 문제가 이 문서의 주요 초점이다.
3. 파드와 서비스 간 통신: 이 문제는 [서비스](/ko/docs/concepts/services-networking/service/)에서 다룬다.
4. 외부와 서비스 간 통신: 이 문제는 [서비스](/ko/docs/concepts/services-networking/service/)에서 다룬다.
{{% /capture %}}
{{% capture body %}}
쿠버네티스는 애플리케이션 간에 머신을 공유하는 것이다. 일반적으로,
머신을 공유하려면 두 애플리케이션이 동일한 포트를 사용하지 않도록
해야 한다. 여러 개발자 간에 포트를 조정하는 것은 대규모로 실시하기가 매우 어렵고,
사용자가 통제할 수 없는 클러스터 수준의 문제에 노출된다.
동적 포트 할당은 시스템에 많은 복잡성을 야기한다. 모든
애플리케이션은 포트를 플래그로 가져와야 하며, API 서버는 동적 포트 번호를
구성 블록에 삽입하는 방법을 알아야 하고, 서비스는 서로를
찾는 방법 등을 알아야 한다. 쿠버네티스는 이런 것들을 다루는 대신
다른 접근법을 취한다.
## 쿠버네티스 네트워크 모델
모든 `Pod` 에는 고유의 IP 주소가 있다. 즉, `Pod` 간에 링크를 명시적으로
생성할 필요가 없으며 컨테이너 포트를 호스트 포트에 매핑할
필요가 거의 없다. 이렇게 하면 포트 할당, 이름 지정, 서비스 검색, 로드 밸런싱,
애플리케이션 구성 및 마이그레이션 관점에서 `Pod` 를 VM 또는
물리적 호스트처럼 취급할 수 있는 깔끔하고, 하위 호환성
있는 모델이 생성된다.
쿠버네티스는 모든 네트워크 구현에 다음과 같은
기본 요구 사항을 적용한다(의도적 네트워크 세분화 정책 제외).
* 노드의 파드는 NAT 없이 모든 노드의 모든 파드와 통신할 수 있다.
* 노드의 에이전트(예: 시스템 데몬, kubelet)는 해당 노드의 모든
파드와 통신할 수 있다.
참고: 호스트 네트워크에서 실행되는 `Pod` 를 지원하는 리눅스와 같은 플랫폼의 경우, 다음의 요구 사항을
적용한다.
* 노드의 호스트 네트워크에 있는 파드는 NAT 없이 모든 노드에 있는 모든
파드와 통신할 수 있다.
이 모델은 전체적으로 덜 복잡할 뿐만 아니라, 쿠버네티스를 위해 VM에서
컨테이너로 애플리케이션을 포팅할 때 충돌이 적게 구현하려는 요구와
주로 호환된다. 잡이 이전에 VM에서 실행된 경우, VM에 IP가 있고
프로젝트의 다른 VM과 통신할 수 있다. 이것은 동일한 기본 모델이다.
쿠버네티스의 IP 주소는 그것의 IP 주소를 포함하여 `Pod` 범위에 존재한다(`Pod` 내
컨테이너는 네트워크 네임스페이스를 공유함). 이것은 `Pod` 내 컨테이너가 모두
`localhost` 에서 서로의 포트에 도달할 수 있다는 것을 의미한다. 또한
`Pod` 내부의 컨테이너 포트의 사용을 조정해야하는 것을 의미하지만, 이것도
VM 내의 프로세스와 동일하다. 이것을 "IP-per-pod(파드별 IP)" 모델이라고 한다.
이것이 어떻게 구현되는 지는 사용 중인 특정 컨테이너 런타임의 세부 사항이다.
`Pod` 로 전달하는 `Node` 자체의 포트(호스트 포트라고 함)를
요청할 수 있지만, 이는 매우 틈새 작업이다. 전달이 구현되는 방법은
컨테이너 런타임의 세부 사항이기도 하다. `Pod` 자체는
호스트 포트의 존재 여부에 대해 인식하지 못한다.
## 쿠버네티스 네트워크 모델의 구현 방법
이 네트워크 모델을 구현할 수 있는 방법에는 여러 가지가 있다. 이
문서는 다양한 방법에 대한 철저한 연구는 아니지만, 다양한 기술에 대한
소개로 활용되며 도약하는 포인트로 사용되기를 바란다.
이 목록은 알파벳 순으로 정렬되어 있으며, 정렬된 순서가
우선 상태를 의미하는 것은 아니다.
### ACI
[Cisco 애플리케이션 센트릭 인프라스트럭처(Application Centric Infrastructure)](https://www.cisco.com/c/en/us/solutions/data-center-virtualization/application-centric-infrastructure/index.html)는 컨테이너, 가상 머신 및 베어메탈 서버를 지원하는 통합 오버레이 및 언더레이 SDN 솔루션을 제공한다. [ACI](https://www.github.com/noironetworks/aci-containers)는 ACI를 위한 컨테이너 네트워킹 통합을 제공한다. 통합의 개요는 [여기](https://www.cisco.com/c/dam/en/us/solutions/collateral/data-center-virtualization/application-centric-infrastructure/solution-overview-c22-739493.pdf)에서 제공된다.
### Antrea
프로젝트 [Antrea](https://github.com/vmware-tanzu/antrea)는 쿠버네티스 고유의 오픈소스 쿠버네티스 네트워킹 솔루션이다. 네트워킹 데이터 플레인으로 Open vSwitch를 활용한다. Open vSwitch는 리눅스와 윈도우를 모두 지원하는 고성능의 프로그래밍이 가능한 가상 스위치이다. Antrea는 Open vSwitch를 통해 쿠버네티스 네트워크 정책을 고성능의 효율적인 방식으로 구현할 수 있다.
Antrea는 Open vSwitch의 "프로그래밍이 가능한" 특성으로 인해 Open vSwitch 위에 광범위한 네트워킹 및 보안 기능과 서비스를 구현할 수 있다.
### Apstra의 AOS
[AOS](http://www.apstra.com/products/aos/)는 단순한 통합 플랫폼에서 복잡한 데이터센터 환경을 만들고 관리하는 의도기반(Intent-Based) 네트워킹 시스템이다. AOS는 확장성이 뛰어난 분산 설계를 활용하여 네트워크 중단을 제거하면서 비용을 최소화한다.
AOS 레퍼런스 디자인은 현재 레거시 Layer-2 스위칭 문제를 제거하는 Layer-3 연결 호스트를 지원한다. 이 Layer-3 호스트는 리눅스 서버(Debian, Ubuntu, CentOS)일 수 있으며 랙 상단 스위치(TOR)와 직접 BGP 인접 관계를 만든다. AOS는 라우팅 인접성을 자동화한 다음 쿠버네티스 디플로이먼트에서 일반적으로 사용되는 RHI(Route Health Injection)에 대한 세밀한 제어를 제공한다.
AOS는 쿠버네티스가 애플리케이션 요구 사항에 따라 네트워크 정책을 신속하게 변경할 수 있는 풍부한 REST API 엔드포인트 셋을 제공한다. 네트워크 설계에 사용된 AOS 그래프 모델을 워크로드 프로비저닝과 통합하여 프라이빗 클라우드와 퍼블릭 클라우드 모두에 대한 엔드-투-엔드 관리 시스템을 향상시킬 수 있다.
AOS는 Cisco, Arista, Dell, Mellanox, HPE 그리고 Microsoft SONiC, Dell OPX 및 Cumulus Linux와 같은 개방형 네트워크 운영체제와 수많은 화이트-박스 시스템을 포함한 제조업체의 일반적인 벤더 장비 사용을 지원한다.
AOS 시스템 작동 방식에 대한 자세한 내용은 다음을 참고한다. http://www.apstra.com/products/how-it-works/
### 쿠버네티스용 AWS VPC CNI
[AWS VPC CNI](https://github.com/aws/amazon-vpc-cni-k8s)는 쿠버네티스 클러스터를 위한 통합된 AWS 버추얼 프라이빗 클라우드(Virtual Private Cloud, VPC) 네트워킹을 제공한다. 이 CNI 플러그인은 높은 처리량과 가용성, 낮은 레이턴시(latency) 그리고 최소 네트워크 지터(jitter)를 제공한다. 또한, 사용자는 쿠버네티스 클러스터를 구축하기 위한 기존의 AWS VPC 네트워킹 및 보안 모범 사례를 적용할 수 있다. 여기에는 VPC 플로우 로그, VPC 라우팅 정책과 네트워크 트래픽 격리를 위한 보안 그룹을 사용하는 기능이 포함되어 있다.
이 CNI 플러그인을 사용하면 쿠버네티스 파드는 VPC 네트워크와 동일한 IP 주소를 파드 내부에 가질 수 있다. CNI는 각 쿠버네티스 노드에 AWS 엘라스틱 네트워킹 인터페이스(Elastic Networking Interfaces, ENI)를 할당하고 노드의 파드에 대해 각 ENI의 보조 IP 범위를 사용한다. CNI에는 파드를 빠르게 시작하기 위해 ENI와 IP 주소의 사전 할당 제어 기능이 포함되어 있으며 최대 2,000개의 노드로 구성된 대규모 클러스터가 가능하다.
또한, CNI는 [네트워크 폴리시 적용을 위해 캘리코(Calico)](https://docs.aws.amazon.com/eks/latest/userguide/calico.html)와 함께 실행할 수 있다. AWS VPC CNI 프로젝트는 [GitHub의 문서](https://github.com/aws/amazon-vpc-cni-k8s)와 함께 오픈소스로 공개되어 있다.
### 쿠버네티스용 Azure CNI
[Azure CNI](https://docs.microsoft.com/en-us/azure/virtual-network/container-networking-overview)는 VM과 동등한 네트워크 성능을 제공하는 Azure 버추얼 네트워크(VNet이라고도 알려진)와 쿠버네티스 파드를 통합하는 [오픈소스](https://github.com/Azure/azure-container-networking/blob/master/docs/cni.md) 플러그인이다. 파드는 피어링된 VNet과 Express Route 또는 사이트 간 VPN을 통해 온-프레미스에 연결할 수 있으며 이러한 네트워크에서 직접 연결할 수도 있다. 파드는 서비스 엔드포인트 또는 프라이빗 링크로 보호되는 스토리지와 SQL과 같은 Azure 서비스에 접근할 수 있다. VNet 보안 정책과 라우팅을 사용하여 파드 트래픽을 필터링할 수 있다. 플러그인은 쿠버네티스 노드의 네트워크 인터페이스에 사전 구성된 보조 IP 풀을 활용하여 VNet IP를 파드에 할당한다.
Azure CNI는 [Azure 쿠버네티스 서비스(Azure Kubernetes Service, AKS)](https://docs.microsoft.com/en-us/azure/aks/configure-azure-cni)에서 기본적으로 사용할 수 있다.
### Big Switch Networks의 빅 클라우드 패브릭(Big Cloud Fabric)
[빅 클라우드 패브릭](https://www.bigswitch.com/container-network-automation)은 클라우드 네이티브 네트워킹 아키텍처로, 프라이빗 클라우드/온-프레미스 환경에서 쿠버네티스를 실행하도록 디자인되었다. 통합된 물리 및 가상 SDN을 사용하여, 빅 클라우드 패브릭은 로드 밸런싱, 가시성, 문제 해결, 보안 정책 및 컨테이너 트래픽 모니터링과 같은 내재한 컨테이너 네트워킹 문제를 해결한다.
빅 클라우드 패브릭의 가상 파드 멀티 테넌트 아키텍처를 통해 쿠버네티스, RedHat OpenShift, Mesosphere DC/OS 및 Docker Swarm과 같은 컨테이너 오케스트레이션 시스템은 VMware, OpenStack 및 Nutanix와 같은 VM 오케스트레이션 시스템과 함께 네이티브로 통합된다. 고객은 원하는 수의 클러스터를 안전하게 상호 연결할 수 있으며 필요한 경우 이들 사이의 테넌트 간 통신을 활성화할 수 있다.
가트너는 최신의 [매직 쿼드런트(Magic Quadrant)](http://go.bigswitch.com/17GatedDocuments-MagicQuadrantforDataCenterNetworking_Reg.html)에서 BCF를 비저너리(Visionary)로 인정했다. BCF 쿠버네티스 온-프레미스 디플로이먼트 중 하나(지리적으로 다른 리전에 걸쳐 여러 DC에서 실행되는 쿠버네티스, DC/OS 및 VMware 포함)도 [여기](https://portworx.com/architects-corner-kubernetes-satya-komala-nio/)에서 사례로 참조된다.
### 실리움(Cilium)
[실리움](https://github.com/cilium/cilium)은 애플리케이션 컨테이너 간에
네트워크 연결을 제공하고 투명하게 보호하기 위한 오픈소스 소프트웨어이다.
실리움은 L7/HTTP를 인식하며 네트워크 주소 지정에서 분리된 ID 기반 보안 모델을 사용하여 L3-L7에서
네트워크 정책을 적용할 수 있으며,
다른 CNI 플러그인과 함께 사용할 수 있다.
### 화웨이의 CNI-Genie
[CNI-Genie](https://github.com/Huawei-PaaS/CNI-Genie)는 쿠버네티스가 런타임 시 [쿠버네티스 네트워크 모델](https://github.com/kubernetes/website/blob/master/content/en/docs/concepts/cluster-administration/networking.md#the-kubernetes-network-model)의 [서로 다른 구현에 동시에 접근](https://github.com/Huawei-PaaS/CNI-Genie/blob/master/docs/multiple-cni-plugins/README.md#what-cni-genie-feature-1-multiple-cni-plugins-enables)할 수 있는 CNI 플러그인이다. 여기에는 [플라넬(Flannel)](https://github.com/coreos/flannel#flannel), [캘리코](http://docs.projectcalico.org/), [로마나(Romana)](http://romana.io), [위브넷(Weave-net)](https://www.weave.works/products/weave-net/)과 같은 [CNI 플러그인](https://github.com/containernetworking/cni#3rd-party-plugins)으로 실행되는 모든 구현이 포함된다.
CNI-Genie는 각각 다른 CNI 플러그인에서 [하나의 파드에 여러 IP 주소를 할당](https://github.com/Huawei-PaaS/CNI-Genie/blob/master/docs/multiple-ips/README.md#feature-2-extension-cni-genie-multiple-ip-addresses-per-pod)하는 것도 지원한다.
### cni-ipvlan-vpc-k8s
[cni-ipvlan-vpc-k8s](https://github.com/lyft/cni-ipvlan-vpc-k8s)는
L2 모드에서 리눅스 커널의 IPvlan 드라이버를 사용하여 Amazon 엘라스틱 네트워크 인터페이스(ENI)를
사용하고 AWS 매니지드 IP를 파드에 바인딩하는
Amazon 버추얼 프라이빗 클라우드(VPC) 환경 내에서 쿠버네티스를 위한
간단하고, 호스트 로컬, 낮은 레이턴시, 높은 처리량 및 호환 네트워킹 스택을 제공하는
CNI와 IPAM 플러그인 셋을 포함한다.
플러그인은 VPC 내에서 구성하고 배포할 수 있도록 간단하게 설계되었다.
Kubelets는 오버레이 네트워크 관리, BGP 관리, 소스/대상 확인 비활성화 또는
VPC 라우팅 테이블을 조정하여 각 호스트에 인스턴스별 서브넷을
제공(VPC별 50-100개 항목으로 제한)하는 등의 자주 권장되는 복잡성을 요구하지 않고
부팅한 다음 필요에 따라 IP 사용량을 자체 구성하고 확장할
수 있다. 즉, cni-ipvlan-vpc-k8s는 AWS 내에서 쿠버네티스를
대규모로 배포하는 데 필요한 네트워크 복잡성을 크게 줄인다.
### 콘티브(Contiv)
[콘티브](https://github.com/contiv/netplugin)는 다양한 적용 사례에서 구성 가능한 네트워킹(BGP를 사용하는 네이티브 L3, vxlan을 사용하는 오버레이, 클래식 L2 또는 Cisco-SDN/ACI)을 제공한다. [콘티브](http://contiv.io)는 모두 오픈소스이다.
### 콘트레일(Contrail) / 텅스텐 패브릭(Tungsten Fabric)
[텅스텐 패브릭](https://tungsten.io)을 기반으로 하는 [콘트레일](http://www.juniper.net/us/en/products-services/sdn/contrail/contrail-networking/)은 진정한 개방형 멀티 클라우드 네트워크 가상화 및 정책 관리 플랫폼이다. 콘트레일 및 텅스텐 패브릭은 쿠버네티스, OpenShift, OpenStack 및 Mesos와 같은 다양한 오케스트레이션 시스템과 통합되어 있으며, 가상 머신, 컨테이너/파드 및 베어메탈 워크로드에 대해 서로 다른 격리 모드를 제공한다.
### DANM
[DANM](https://github.com/nokia/danm)은 쿠버네티스 클러스터에서 실행되는 통신사 워크로드를 위한 네트워킹 솔루션이다. 다음의 컴포넌트로 구성된다.
* 고급 기능들로 IPVLAN 인터페이스를 프로비저닝할 수 있는 CNI 플러그인
* 여러 클러스터 전체의 불연속 L3 네트워크를 관리하고 요청 시 동적, 정적 또는 IP를 할당하지 않는 방식을 제공하는 내장 IPAM 모듈
* 자체 CNI를 통해서, 또는 SRI-OV나 플라넬과 같은 널리 사용되는 CNI 솔루션에 잡을 동시에 위임하여 여러 네트워크 인터페이스를 컨테이너에 연결할 수 있는 CNI 메타플러그인
* 모든 쿠버네티스 호스트의 VxLAN 및 VLAN 인터페이스를 중앙에서 관리할 수 있는 쿠버네티스 컨트롤러
* 쿠버네티스의 서비스 기반의 서비스 검색 개념을 확장하여 파드의 모든 네트워크 인터페이스에서 작동하는 다른 쿠버네티스 컨트롤러
이 도구 셋을 통해 DANM은 여러 개의 분리된 네트워크 인터페이스를 제공할 수 있으며, 파드에 다른 네트워킹 백엔드 및 고급 IPAM 기능을 사용할 수 있다.
### 플라넬
[플라넬](https://github.com/coreos/flannel#flannel)은 쿠버네티스 요구 사항을
충족하는 매우 간단한 오버레이 네트워크이다. 많은
경우에 쿠버네티스와 플라넬은 성공적으로 적용이 가능하다.
### Google 컴퓨트 엔진(GCE)
Google 컴퓨트 엔진 클러스터 구성 스크립트의 경우, [고급
라우팅](https://cloud.google.com/vpc/docs/routes)을 사용하여
각 VM에 서브넷을 할당한다(기본값은 `/24` - 254개 IP). 해당 서브넷에 바인딩된
모든 트래픽은 GCE 네트워크 패브릭에 의해 VM으로 직접 라우팅된다. 이는
아웃 바운드 인터넷 접근을 위해 NAT로 구성된 VM에 할당된 "기본"
IP 주소에 추가된다. 리눅스 브릿지(`cbr0`)는 해당 서브넷에 존재하도록
구성되며, 도커의 `--bridge` 플래그로 전달된다.
도커는 다음의 설정으로 시작한다.
```shell
DOCKER_OPTS="--bridge=cbr0 --iptables=false --ip-masq=false"
```
이 브릿지는 노드의 `.spec.podCIDR`에 따라 Kubelet(`--network-plugin=kubenet`
플래그로 제어되는)에 의해 생성된다.
도커는 이제 `cbr-cidr` 블록에서 IP를 할당한다. 컨테이너는 `cbr0` 브릿지를
통해 서로 `Node` 에 도달할 수 있다. 이러한 IP는 모두 GCE 프로젝트 네트워크
내에서 라우팅할 수 있다.
그러나, GCE 자체는 이러한 IP에 대해 전혀 알지 못하므로, 아웃 바운드 인터넷 트래픽을 위해
IP를 NAT하지 않는다. 그것을 달성하기 위해 iptables 규칙을 사용하여
GCE 프로젝트 네트워크(10.0.0.0/8) 외부의 IP에 바인딩된 트래픽을
마스커레이드(일명 SNAT - 마치 패킷이 `Node` 자체에서 온 것처럼
보이게 함)한다.
```shell
iptables -t nat -A POSTROUTING ! -d 10.0.0.0/8 -o eth0 -j MASQUERADE
```
마지막으로 커널에서 IP 포워딩이 활성화되어 있으므로, 커널은 브릿지된 컨테이너에
대한 패킷을 처리한다.
```shell
sysctl net.ipv4.ip_forward=1
```
이 모든 것의 결과는 모든 `Pod` 가 서로에게 도달할 수 있고 인터넷으로 트래픽을
송신할 수 있다는 것이다.
### 재규어(Jaguar)
[재규어](https://gitlab.com/sdnlab/jaguar)는 OpenDaylight 기반의 쿠버네티스 네트워크를 위한 오픈소스 솔루션이다. 재규어는 vxlan을 사용하여 오버레이 네트워크를 제공하고 재규어 CNI 플러그인은 파드별로 하나의 IP 주소를 제공한다.
### k-vswitch
[k-vswitch](https://github.com/k-vswitch/k-vswitch)는 [Open vSwitch](https://www.openvswitch.org/) 기반의 간단한 쿠버네티스 네트워킹 플러그인이다. Open vSwitch의 기존 기능을 활용하여 운영하기 쉽고, 성능이 뛰어나고 안전한 강력한 네트워킹 플러그인을 제공한다.
### Knitter
[Knitter](https://github.com/ZTE/Knitter/)는 쿠버네티스에서 여러 네트워킹을 지원하는 네트워크 솔루션이다. 테넌트 관리 및 네트워크 관리 기능을 제공한다. Knitter에는 애플리케이션의 IP 주소 유지, IP 주소 마이그레이션 등과 같은 여러 네트워크 플레인 외에 엔드-투-엔드 NFV 컨테이너 네트워킹 솔루션 셋이 포함되어 있다.
### Kube-OVN
[Kube-OVN](https://github.com/alauda/kube-ovn)은 기업을 위한 OVN 기반 쿠버네티스 네트워크 패브릭이다. OVN/OVS의 도움으로, 서브넷, QoS, 고정 IP 할당, 트래픽 미러링, 게이트웨이, 오픈플로우 기반 네트워크 정책 및 서비스 프록시와 같은 고급 오버레이 네트워크 기능을 제공한다.
### Kube-router
[kube-router](https://github.com/cloudnativelabs/kube-router)는 쿠버네티스를 위한 특수 목적의 네트워킹 솔루션으로 고성능 및 운영 단순성을 제공한다. 큐브 라우터는 리눅스 [LVS/IPVS](http://www.linuxvirtualserver.org/software/ipvs.html) 기반 서비스 프록시, 오버레이가 없는 리눅스 커널 포워딩 기반의 파드 간 네트워킹 솔루션 그리고 iptables/ipset 기반 네트워크 정책 집행도구를 제공한다.
### L2 네트워크 및 리눅스 브릿지
"베어메탈" 환경의 간단한 스위치와 같은 "더미(dumb)" L2 네트워크가 있는 경우,
위의 GCE 설정과 비슷한 작업을 수행할 수 있어야 한다.
이 방법은 매우 우연히 시도되었고 작동하는 것으로 보이지만
철저히 테스트되지 않았다. 이 기술을 사용하여
프로세스를 완료한 경우, 알려주길 바란다.
Lars Kellogg-Stedman이 제공하는 [이 훌륭한
튜토리얼](http://blog.oddbit.com/2014/08/11/four-ways-to-connect-a-docker/)의
"With Linux Bridge devices" 섹션을 참고한다.
### Multus(멀티 네트워크 플러그인)
[Multus](https://github.com/Intel-Corp/multus-cni)는 쿠버네티스의 CRD 기반 네트워크 오브젝트를 사용하여 쿠버네티스에서 멀티 네트워킹 기능을 지원하는 멀티 CNI 플러그인이다.
Multus는 CNI 명세를 구현하는 모든 [레퍼런스 플러그인](https://github.com/containernetworking/plugins)(예: [플라넬](https://github.com/containernetworking/plugins/tree/master/plugins/meta/flannel), [DHCP](https://github.com/containernetworking/plugins/tree/master/plugins/ipam/dhcp), [Macvlan](https://github.com/containernetworking/plugins/tree/master/plugins/main/macvlan)) 및 써드파티 플러그인(예: [캘리코](https://github.com/projectcalico/cni-plugin), [위브(Weave)](https://github.com/weaveworks/weave), [실리움](https://github.com/cilium/cilium), [콘티브](https://github.com/contiv/netplugin))을 지원한다. 또한, Multus는 쿠버네티스의 클라우드 네이티브 애플리케이션과 NFV 기반 애플리케이션을 통해 쿠버네티스의 [SRIOV](https://github.com/hustcat/sriov-cni), [DPDK](https://github.com/Intel-Corp/sriov-cni), [OVS-DPDK 및 VPP](https://github.com/intel/vhost-user-net-plugin) 워크로드를 지원한다.
### NSX-T
[VMware NSX-T](https://docs.vmware.com/en/VMware-NSX-T/index.html)는 네트워크 가상화 및 보안 플랫폼이다. NSX-T는 멀티 클라우드 및 멀티 하이퍼바이저 환경에 네트워크 가상화를 제공할 수 있으며 이기종 엔드포인트와 기술 스택이 있는 새로운 애플리케이션 프레임워크 및 아키텍처에 중점을 둔다. vSphere 하이퍼바이저 외에도, 이러한 환경에는 KVM, 컨테이너 및 베어메탈과 같은 다른 하이퍼바이저가 포함된다.
[NSX-T 컨테이너 플러그인(NCP)](https://docs.vmware.com/en/VMware-NSX-T/2.0/nsxt_20_ncp_kubernetes.pdf)은 NSX-T와 쿠버네티스와 같은 컨테이너 오케스트레이터 사이의 통합은 물론, NSX-T와 Pivotal 컨테이너 서비스(PKS) 및 OpenShift와 같은 컨테이너 기반 CaaS/PaaS 플랫폼 간의 통합을 제공한다.
### Nuage Networks VCS(가상 클라우드 서비스)
[Nuage](http://www.nuagenetworks.net)는 확장성이 뛰어난 정책 기반의 소프트웨어 정의 네트워킹(SDN) 플랫폼을 제공한다. Nuage는 개방형 표준을 기반으로 구축된 풍부한 기능의 SDN 컨트롤러와 함께 데이터 플레인용 오픈소스 Open vSwitch를 사용한다.
Nuage 플랫폼은 오버레이를 사용하여 쿠버네티스 파드와 쿠버네티스가 아닌 환경(VM 및 베어메탈 서버) 간에 완벽한 정책 기반의 네트워킹을 제공한다. Nuage의 정책 추상화 모델은 애플리케이션을 염두에 두고 설계되었으며 애플리케이션에 대한 세분화된 정책을 쉽게 선언할 수 있도록 한다. 플랫폼의 실시간 분석 엔진을 통해 쿠버네티스 애플리케이션에 대한 가시성과 보안 모니터링이 가능하다.
### OpenVSwitch
[OpenVSwitch](https://www.openvswitch.org/)는 다소 성숙하지만
오버레이 네트워크를 구축하는 복잡한 방법이다. 이것은 네트워킹 분야의 몇몇
"대형 벤더"에 의해 승인되었다.
### OVN(오픈 버추얼 네트워킹)
OVN은 Open vSwitch 커뮤니티에서 개발한 오픈소스 네트워크
가상화 솔루션이다. 논리적 스위치, 논리적 라우터, 스테이트풀 ACL, 로드 밸런서 등을 생성하여
서로 다른 가상 네트워킹 토폴로지를 구축할 수 있다. 이 프로젝트에는
[ovn-kubernetes](https://github.com/openvswitch/ovn-kubernetes)에
특정 쿠버네티스 플러그인 및 문서가 있다.
### 프로젝트 캘리코
[프로젝트 캘리코](http://docs.projectcalico.org/)는 오픈소스 컨테이너 네트워킹 공급자 및 네트워크 정책 엔진이다.
캘리코는 리눅스(오픈소스)와 윈도우(독점 - [Tigera](https://www.tigera.io/essentials/)에서 사용 가능) 모두에서 인터넷과 동일한 IP 네트워킹 원칙을 기반으로 쿠버네티스 파드를 연결하기 위한 확장성이 뛰어난 네트워킹 및 네트워크 정책 솔루션을 제공한다. 캘리코는 캡슐화나 오버레이 없이 구축되어 고성능의 대규모 데이터센터 네트워킹을 제공할 수 있다. 또한 캘리코는 분산 방화벽을 통해 쿠버네티스 파드에 대해 세분화된 의도기반의 네트워크 보안 정책을 제공한다.
캘리코는 플라넬, 일명 [canal](https://github.com/tigera/canal) 또는 네이티브 GCE, AWS나 Azure 네트워킹과 같은 다른 네트워킹 솔루션과 함께 정책 적용 모드로 실행될 수도 있다.
### 로마나
[로마나](http://romana.io)는 오버레이 네트워크 없이 쿠버네티스를 배포할 수 있는 오픈소스 네트워크 및 보안 자동화 솔루션이다. 로마나는 쿠버네티스 [네트워크 폴리시](/ko/docs/concepts/services-networking/network-policies/)를 지원하여 네트워크 네임스페이스에서 격리를 제공한다.
### Weaveworks의 위브넷
[위브넷](https://www.weave.works/products/weave-net/)은
쿠버네티스 및 호스팅된 애플리케이션을 위한 탄력적이고 사용하기 쉬운 네트워크이다.
위브넷은 [CNI 플러그인](https://www.weave.works/docs/net/latest/cni-plugin/) 또는
독립형으로 실행된다. 두 버전에서, 실행하기 위해 구성이나 추가 코드가 필요하지 않으며,
두 경우 모두, 쿠버네티스의 표준과 같이 네트워크에서 파드별로 하나의 IP 주소를 제공한다.
{{% /capture %}}
{{% capture whatsnext %}}
네트워크 모델의 초기 설계와 그 근거 및 미래의 계획은
[네트워킹 디자인 문서](https://git.k8s.io/community/contributors/design-proposals/network/networking.md)에
자세히 설명되어 있다.
{{% /capture %}}

View File

@ -1,7 +1,7 @@
---
title: 노드에 파드 할당하기
content_template: templates/concept
weight: 30
weight: 50
---

View File

@ -0,0 +1,169 @@
---
title: 컨피그맵(ConfigMap)
content_template: templates/concept
weight: 20
---
{{% capture overview %}}
{{< glossary_definition term_id="configmap" prepend="컨피그맵은" length="all" >}}
{{< caution >}}
컨피그맵은 보안 또는 암호화를 제공하지 않는다.
저장하려는 데이터가 기밀인 경우, 컨피그맵
대신 {{< glossary_tooltip text="시크릿(Secret)" term_id="secret" >}} 또는 추가(써드파티) 도구를
사용하여 데이터를 비공개로 유지하자.
{{< /caution >}}
{{% /capture %}}
{{% capture body %}}
## 사용 동기
애플리케이션 코드와 별도로 구성 데이터를 설정하려면 컨피그맵을 사용하자.
예를 들어, 자신의 컴퓨터(개발용)와 클라우드(실제 트래픽 처리)에서
실행할 수 있는 애플리케이션을 개발한다고 가정해보자.
`DATABASE_HOST` 라는
환경 변수를 찾기 위해 코드를 작성한다. 로컬에서는 해당 변수를
`localhost` 로 설정한다. 클라우드에서는, 데이터베이스
컴포넌트를 클러스터에 노출하는 쿠버네티스 {{< glossary_tooltip text="서비스" term_id="service" >}}를 참조하도록
설정한다.
이를 통해 클라우드에서 실행 중인 컨테이너 이미지를 가져와
필요한 경우 정확히 동일한 코드를 로컬에서 디버깅할 수 있다.
## 컨피그맵 오브젝트
컨피그맵은 다른 오브젝트가 사용할 구성을 저장할 수 있는
API [오브젝트](/ko/docs/concepts/overview/working-with-objects/kubernetes-objects/)이다.
`spec` 이 있는 대부분의 쿠버네티스 오브젝트와 달리,
컨피그맵에는 항목(키)과 해당 값을 저장하는 `data` 섹션이 있다.
컨피그맵의 이름은 유효한
[DNS 서브도메인 이름](/ko/docs/concepts/overview/working-with-objects/names/#dns-서브도메인-이름)이어야 한다.
## 컨피그맵과 파드(Pod)
컨피그맵을 참조하는 파드 `spec` 을 작성하고 컨피그맵의 데이터를
기반으로 해당 파드의 컨테이너를 구성할 수 있다. 파드와 컨피그맵은
동일한 {{< glossary_tooltip text="네임스페이스" term_id="namespace" >}}에 있어야 한다.
다음은 단일 값을 가진 키와,
값이 구성 형식의 일부처럼 보이는 키를 가진 컨피그맵의
예시이다.
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
Name: game-demo
data:
# 속성과 비슷한 키; 각 키는 간단한 값으로 매핑됨
player_initial_lives: 3
ui_properties_file_name: "user-interface.properties"
#
# 파일과 비슷한 키
game.properties: |
enemy.types=aliens,monsters
player.maximum-lives=5
user-interface.properties: |
color.good=purple
color.bad=yellow
allow.textmode=true
```
컨피그맵을 사용하여 파드 내부에 컨테이너를 구성할 수 있는
네 가지 방법이 있다.
1. 컨테이너의 엔트리포인트에 대한 커맨드 라인 인수
1. 컨테이너에 대한 환경 변수
1. 애플리케이션이 읽을 수 있도록 읽기 전용 볼륨에 파일 추가
1. 쿠버네티스 API를 사용하여 컨피그맵을 읽는 파드 내에서 실행할 코드 작성
이러한 방법들은 소비되는 데이터를 모델링하는
방식에 따라 다르게 쓰인다.
처음 세 가지 방법의 경우,
{{< glossary_tooltip text="kubelet" term_id="kubelet" >}}은 파드의 컨테이너를 시작할 때
시크릿의 데이터를 사용한다.
네 번째 방법은 시크릿과 데이터를 읽기 위해 코드를 작성해야 한다는 것을 의미한다.
그러나, 쿠버네티스 API를 직접 사용하기 때문에, 애플리케이션은
컨피그맵이 변경될 때마다 업데이트를 받기 위해 구독할 수 있고, 업데이트가
있으면 반응한다. 쿠버네티스 API에 직접 접근하면, 이
기술을 사용하여 다른 네임스페이스의 컨피그맵에 접근할 수도 있다.
다음은 `game-demo` 의 값을 사용하여 파드를 구성하는 파드 예시이다.
```yaml
apiVersion: v1
kind: Pod
metadata:
name: configmap-demo-pod
spec:
containers:
- name: demo
image: game.example/demo-game
env:
# 환경 변수 정의
- name: PLAYER_INITIAL_LIVES # 참고로 여기서는 컨피그맵의 키 이름과
# 대소문자가 다르다.
valueFrom:
configMapKeyRef:
name: game-demo # 이 값의 컨피그맵.
key: player_initial_lives # 가져올 키.
- name: UI_PROPERTIES_FILE_NAME
valueFrom:
configMapKeyRef:
name: game-demo
key: ui_properties_file_name
volumeMounts:
- name: config
mountPath: "/config"
readOnly: true
volumes:
# 파드 레벨에서 볼륨을 설정한 다음, 해당 파드 내의 컨테이너에 마운트한다.
- name: config
configMap:
# 마운트하려는 컨피그맵의 이름을 제공한다.
name: game-demo
```
컨피그맵은 단일 라인 속성(single line property) 값과 멀티 라인의 파일과 비슷한(multi-line file-like) 값을
구분하지 않는다.
더 중요한 것은 파드와 다른 오브젝트가 이러한 값을 소비하는 방식이다.
이 예제에서, 볼륨을 정의하고 `demo` 컨테이너에
`/config` 로 마운트하면 4개의 파일이 생성된다.
- `/config/player_initial_lives`
- `/config/ui_properties_file_name`
- `/config/game.properties`
- `/config/user-interface.properties`
`/config``.properties` 확장자를 가진 파일만
포함시키려면, 두 개의 다른 컨피그맵을 사용하고, 파드에
대해서는 `spec` 의 두 컨피그맵을 참조한다. 첫 번째 컨피그맵은
`player_initial_lives``ui_properties_file_name` 을 정의한다. 두 번째
컨피그맵은 kubelet이 `/config` 에 넣는 파일을 정의한다.
{{< note >}}
컨피그맵을 사용하는 가장 일반적인 방법은 동일한 네임스페이스의
파드에서 실행되는 컨테이너에 대한 설정을 구성하는 것이다. 컨피그맵을
별도로 사용할 수도 있다.
예를 들어,
컨피그맵에 기반한 동작을 조정하는 {{< glossary_tooltip text="애드온" term_id="addons" >}}이나
{{< glossary_tooltip text="오퍼레이터" term_id="operator-pattern" >}}를
사용할 수도 있다.
{{< /note >}}
{{% /capture %}}
{{% capture whatsnext %}}
* [시크릿](/docs/concepts/configuration/secret/)에 대해 읽어본다.
* [컨피그맵을 사용하도록 파드 구성하기](/docs/tasks/configure-pod-container/configure-pod-configmap/)를 읽어본다.
* 코드를 구성에서 분리하려는 동기를 이해하려면
[Twelve-Factor 앱](https://12factor.net/ko/)을 읽어본다.
{{% /capture %}}

View File

@ -0,0 +1,761 @@
---
title: 컨테이너 리소스 관리
content_template: templates/concept
weight: 40
feature:
title: 자동 빈 패킹(bin packing)
description: >
리소스 요구 사항과 기타 제약 조건에 따라 컨테이너를 자동으로 배치하지만, 가용성은 그대로 유지한다. 활용도를 높이고 더 많은 리소스를 절약하기 위해 중요한(critical) 워크로드와 최선의(best-effort) 워크로드를 혼합한다.
---
{{% capture overview %}}
{{< glossary_tooltip text="파드" term_id="pod" >}}를 지정할 때,
{{< glossary_tooltip text="컨테이너" term_id="container" >}}에 필요한 각 리소스의 양을 선택적으로 지정할 수 있다.
지정할 가장 일반적인 리소스는 CPU와 메모리(RAM) 그리고 다른 것들이 있다.
파드에서 컨테이너에 대한 리소스 _요청(request)_ 을 지정하면, 스케줄러는 이 정보를
사용하여 파드가 배치될 노드를 결정한다. 컨테이너에 대한 리소스 _제한(limit)_
지정하면, kubelet은 실행 중인 컨테이너가 설정한 제한보다 많은 리소스를
사용할 수 없도록 해당 제한을 적용한다. 또한 kubelet은
컨테이너가 사용할 수 있도록 해당 시스템 리소스의 최소 _요청_ 량을
예약한다.
{{% /capture %}}
{{% capture body %}}
## 요청 및 제한
파드가 실행 중인 노드에 사용 가능한 리소스가 충분하면, 컨테이너가 해당
리소스에 지정한 `request` 보다 더 많은 리소스를 사용할 수 있도록 허용된다.
그러나, 컨테이너는 리소스 `limit` 보다 더 많은 리소스를 사용할 수는 없다.
예를 들어, 컨테이너에 대해 256MiB의 `memory` 요청을 설정하고, 해당 컨테이너가
8GiB의 메모리를 가진 노드로 스케줄된 파드에 있고 다른 파드는 없는 경우, 컨테이너는 더 많은 RAM을
사용할 수 있다.
해당 컨테이너에 대해 4GiB의 `memory` 제한을 설정하면, kubelet(그리고
{{< glossary_tooltip text="컨테이너 런타임" term_id="container-runtime" >}})이 제한을 적용한다.
런타임은 컨테이너가 구성된 리소스 제한을 초과하여 사용하지 못하게 한다. 예를 들어,
컨테이너의 프로세스가 허용된 양보다 많은 메모리를 사용하려고 하면,
시스템 커널은 메모리 부족(out of memory, OOM) 오류와 함께 할당을 시도한 프로세스를
종료한다.
제한은 반응적(시스템이 위반을 감지한 후에 개입)으로
또는 강제적(시스템이 컨테이너가 제한을 초과하지 않도록 방지)으로 구현할 수 있다. 런타임마다
다른 방식으로 동일한 제약을 구현할 수 있다.
## 리소스 타입
*CPU* 와 *메모리* 는 각각 *리소스 타입* 이다. 리소스 타입에는 기본 단위가 있다.
CPU는 컴퓨팅 처리를 나타내며 [쿠버네티스 CPU](#cpu의-의미) 단위로 지정된다.
메모리는 바이트 단위로 지정된다.
쿠버네티스 v1.14 이상을 사용하는 경우, _huge page_ 리소스를 지정할 수 있다.
Huge page는 노드 커널이 기본 페이지 크기보다 훨씬 큰 메모리
블록을 할당하는 리눅스 관련 기능이다.
예를 들어, 기본 페이지 크기가 4KiB인 시스템에서, `hugepages-2Mi: 80Mi` 제한을
지정할 수 있다. 컨테이너가 40개 이상의 2MiB huge page(총 80MiB)를
할당하려고 하면 해당 할당이 실패한다.
{{< note >}}
`hugepages-*` 리소스를 오버커밋할 수 없다.
이것은 `memory``cpu` 리소스와는 다르다.
{{< /note >}}
CPU와 메모리를 통칭하여 *컴퓨트 리소스* 또는 그냥 *리소스* 라고 한다. 컴퓨트
리소스는 요청, 할당 및 소비될 수 있는 측정 가능한
수량이다. 이것은
[API 리소스](/ko/docs/concepts/overview/kubernetes-api/)와는 다르다. 파드 및
[서비스](/ko/docs/concepts/services-networking/service/)와 같은 API 리소스는
쿠버네티스 API 서버를 통해 읽고 수정할 수
있는 오브젝트이다.
## 파드와 컨테이너의 리소스 요청 및 제한
파드의 각 컨테이너는 다음 중 하나 이상을 지정할 수 있다.
* `spec.containers[].resources.limits.cpu`
* `spec.containers[].resources.limits.memory`
* `spec.containers[].resources.limits.hugepages-<size>`
* `spec.containers[].resources.requests.cpu`
* `spec.containers[].resources.requests.memory`
* `spec.containers[].resources.requests.hugepages-<size>`
요청과 제한은 개별 컨테이너에서만 지정할 수 있지만,
파드 리소스 요청 및 제한에 대해 이야기하는 것이 편리하다.
특정 리소스 타입에 대한 *파드 리소스 요청/제한* 은 파드의 각 컨테이너에 대한
해당 타입의 리소스 요청/제한의 합이다.
## 쿠버네티스의 리소스 단위
### CPU의 의미
CPU 리소스에 대한 제한 및 요청은 *cpu* 단위로 측정된다.
쿠버네티스의 CPU 1개는 클라우드 공급자용 **vCPU/Core 1개** 와 베어메탈 인텔 프로세서에서의 **1개 하이퍼스레드** 에 해당한다.
분수의 요청이 허용된다.
`0.5``spec.containers[].resources.requests.cpu` 요청을 가진
컨테이너는 CPU 1개를 요구하는 컨테이너의 절반만큼 CPU를 보장한다. `0.1` 이라는 표현은
"백 밀리cpu"로 읽을 수 있는 `100m` 표현과 동일하다. 어떤 사람들은
"백 밀리코어"라고 말하는데, 같은 것을 의미하는 것으로 이해된다.
`0.1` 과 같이 소수점이 있는 요청은 API에 의해 `100m` 로 변환되며,
`1m` 도 허용되지 않게 정밀하다. 이러한 이유로, `100m` 형식이
선호될 수 있다.
CPU는 항상 절대 수량으로 요청되며, 상대적 수량은 아니다.
0.1은 단일 코어, 이중 코어 또는 48코어 시스템에서 동일한 양의 CPU이다.
### 메모리의 의미
`memory` 에 대한 제한 및 요청은 바이트 단위로 측정된다.
E, P, T, G, M, K와 같은 접미사 중 하나를 사용하여 메모리를
일반 정수 또는 고정 소수점 정수로 표현할 수 있다. Ei, Pi, Ti, Gi, Mi, Ki와
같은 2의 거듭제곱을 사용할 수도 있다. 예를 들어, 다음은 대략 동일한 값을 나타낸다.
```shell
128974848, 129e6, 129M, 123Mi
```
다음은 예제이다.
다음 파드에는 두 개의 컨테이너가 있다. 각 컨테이너에는 0.25 cpu와
64MiB(2<sup>26</sup> 바이트)의 메모리 요청이 있다. 각 컨테이너는 0.5
cpu와 128MiB 메모리로 제한된다. 파드에 0.5 cpu와 128 MiB
메모리, 1 cpu와 256MiB 메모리 제한이 있다고 말할 수 있다.
```yaml
apiVersion: v1
kind: Pod
metadata:
name: frontend
spec:
containers:
- name: db
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "password"
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
- name: wp
image: wordpress
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
```
## 리소스 요청이 포함된 파드를 스케줄링하는 방법
파드를 생성할 때, 쿠버네티스 스케줄러는 파드를 실행할 노드를
선택한다. 각 노드는 파드에 제공할 수 있는 CPU와 메모리 양과 같은 각 리소스 타입에 대해
최대 용량을 갖는다. 스케줄러는 각 리소스 타입마다
스케줄된 컨테이너의 리소스 요청 합계가
노드 용량보다 작도록 한다. 참고로 노드의 실제 메모리나
CPU 리소스 사용량은 매우 적지만, 용량 확인에 실패한 경우
스케줄러는 여전히 노드에 파드를 배치하지 않는다. 이는 리소스 사용량이
나중에 증가할 때, 예를 들어, 일일 요청 비율이
최대일 때 노드의 리소스 부족을 방지한다.
## 리소스 제한이 있는 파드가 실행되는 방법
kubelet은 파드의 컨테이너를 시작할 때, CPU와 메모리 제한을
컨테이너 런타임으로 전달한다.
도커를 사용하는 경우에는 다음과 같다.
- `spec.containers[].resources.requests.cpu` 는 잠재적인 분수이며,
1024를 곱한 값인 코어 값으로 변환된다. 이 숫자 또는 2보다
큰 값은 `docker run` 명령에서
[`--cpu-shares`](https://docs.docker.com/engine/reference/run/#cpu-share-constraint)
플래그의 값으로 사용된다.
- 이 `spec.containers[].resources.limits.cpu` 값은 밀리코어 값으로 변환되고
100을 곱한 값이다. 그 결과 값은 컨테이너가 100ms마다 사용할 수 있는 총 CPU
시간이다. 이 간격 동안 컨테이너는 CPU 시간을 초과하여 사용할 수 없다.
{{< note >}}
기본 쿼터 기간은 100ms이다. 최소 CPU 쿼터는 1ms이다.
{{</ note >}}
- `spec.containers[].resources.limits.memory` 는 정수로 변환되어,
`docker run` 명령에서
[`--memory`](https://docs.docker.com/engine/reference/run/#/user-memory-constraints)
플래그의 값으로 사용된다.
컨테이너가 메모리 제한을 초과하면, 컨테이너는 종료될 수 있다. 다시
시작할 수 있으면, 다른 타입의 런타임 오류와 마찬가지로, kubelet이 다시
시작한다.
컨테이너가 메모리 요청을 초과하면, 노드에 메모리가
부족할 때마다 파드가 축출될 수 있다.
컨테이너가 오랫동안 CPU 제한을 초과하는 것은 허용되거나 허용되지
않을 수 있다. 그러나, 과도한 CPU 사용으로 인해 종료되지는 않는다.
리소스 제한으로 인해 컨테이너를 스케줄할 수 없는지 또는
종료 중인지 확인하려면,
[문제 해결](#문제-해결) 섹션을 참조한다.
### 컴퓨트 및 메모리 리소스 사용량 모니터링
파드의 리소스 사용량은 파드 상태의 일부로 보고된다.
클러스터에서 선택적인 모니터링 도구를
사용할 수 있다면, [메트릭 API](/ko/docs/tasks/debug-application-cluster/resource-metrics-pipeline/#메트릭-api)에서
직접 또는 모니터링 도구에서 파드 리소스
사용량을 검색할 수 있다.
## 로컬 임시(ephemeral) 스토리지
<!-- feature gate LocalStorageCapacityIsolation -->
{{< feature-state for_k8s_version="v1.10" state="beta" >}}
노드에는 로컬에 연결된 쓰기 가능 장치 또는, 때로는 RAM에 의해
지원되는 로컬 임시 스토리지가 있다.
"임시"는 내구성에 대한 장기간의 보증이 없음을 의미한다.
파드는 스크래치 공간, 캐싱 및 로그에 대해 임시 로컬 스토리지를 사용한다.
kubelet은 로컬 임시 스토리지를 사용하여 컨테이너에
[`emptyDir`](https://kubernetes.io/docs/concepts/storage/volumes/#emptydir)
{{< glossary_tooltip term_id="volume" text="볼륨" >}}을 마운트하기 위해 파드에 스크래치 공간을 제공할 수 있다.
kubelet은 이러한 종류의 스토리지를 사용하여
[노드-레벨 컨테이너 로그](/ko/docs/concepts/cluster-administration/logging/#노드-레벨에서의-로깅),
컨테이너 이미지 및 실행 중인 컨테이너의 쓰기 가능 계층을 보유한다.
{{< caution >}}
노드가 실패하면, 임시 스토리지의 데이터가 손실될 수 있다.
애플리케이션은 로컬 임시 스토리지에서 성능에 대한 SLA(예: 디스크 IOPS)를
기대할 수 없다.
{{< /caution >}}
베타 기능에서, 쿠버네티스는 파드가 사용할 수 있는 임시 로컬 스토리지의 양을
추적, 예약 및 제한할 수 있도록 해준다.
### 로컬 임시 스토리지 구성
쿠버네티스는 노드에서 로컬 임시 스토리지를 구성하는 두 가지 방법을 지원한다.
{{< tabs name="local_storage_configurations" >}}
{{% tab name="단일 파일시스템" %}}
이 구성에서, 모든 종류의 임시 로컬 데이터(`emptyDir` 볼륨,
쓰기 가능 계층, 컨테이너 이미지, 로그)를 하나의 파일시스템에 배치한다.
kubelet을 구성하는 가장 효과적인 방법은 이 파일시스템을 쿠버네티스(kubelet) 데이터 전용으로
하는 것이다.
kubelet은 또한
[노드-레벨 컨테이너 로그](/ko/docs/concepts/cluster-administration/logging/#노드-레벨에서의-로깅)를
작성하고 임시 로컬 스토리지와 유사하게 처리한다.
kubelet은 구성된 로그 디렉터리 내의 파일에 로그를 기록한다(기본적으로
`/var/log`). 그리고 로컬에 저장된 다른 데이터에 대한 기본 디렉터리가 있다(기본적으로
`/var/lib/kubelet`).
일반적으로, `/var/lib/kubelet``/var/log` 모두 시스템 루트 파일시스템에 위치하고,
그리고 kubelet은 이런 레이아웃을 염두에 두고 설계되었다.
노드는 쿠버네티스에서 사용하지 않는 다른 많은 파일시스템을
가질 수 있다.
{{% /tab %}}
{{% tab name="두 개의 파일시스템" %}}
사용하고 있는 노드에 실행 중인 파드에서 발생하는 임시 데이터를
위한 파일시스템을 가진다(로그와 `emptyDir` 볼륨). 이 파일시스템을
다른 데이터(예를 들어, 쿠버네티스와 관련없는 시스템 로그)를 위해 사용할 수 있다. 이 파일시스템은
루트 파일시스템일 수도 있다.
kubelet은 또한
[노드-레벨 컨테이너 로그](/ko/docs/concepts/cluster-administration/logging/#노드-레벨에서의-로깅)를
첫 번째 파일시스템에 기록하고, 임시 로컬 스토리지와 유사하게 처리한다.
또한 다른 논리 스토리지 장치가 지원하는 별도의 파일시스템을 사용한다.
이 구성에서, 컨테이너 이미지 계층과 쓰기 가능한 계층을 배치하도록
kubelet에 지시하는 디렉터리는 이 두 번째 파일시스템에 있다.
첫 번째 파일시스템에는 이미지 계층이나 쓰기 가능한 계층이 없다.
노드는 쿠버네티스에서 사용하지 않는 다른 많은 파일시스템을
가질 수 있다.
{{% /tab %}}
{{< /tabs >}}
kubelet은 사용 중인 로컬 스토리지 양을 측정할 수 있다. 이것은 다음을
제공한다.
- `LocalStorageCapacityIsolation`
[기능 게이트](/docs/reference/command-line-tools-reference/feature-gates/)(이
기능이 기본적으로 설정되어 있음)를 활성화하고,
- 로컬 임시 스토리지에 대한 지원되는 구성 중 하나를
사용하여 노드를 설정한다.
다른 구성을 사용하는 경우, kubelet은 임시 로컬 스토리지에 대한 리소스
제한을 적용하지 않는다.
{{< note >}}
kubelet은 로컬 임시 스토리지가 아닌 컨테이너 메모리 사용으로
`tmpfs` emptyDir 볼륨을 추적한다.
{{< /note >}}
### 로컬 임시 스토리지에 대한 요청 및 제한 설정
_임시-스토리지_ 를 사용하여 로컬 임시 저장소를 관리할 수 있다. 파드의 각 컨테이너는 다음 중 하나 이상을 지정할 수 있다.
* `spec.containers[].resources.limits.ephemeral-storage`
* `spec.containers[].resources.requests.ephemeral-storage`
`ephemeral-storage` 에 대한 제한 및 요청은 바이트 단위로 측정된다. E, P, T, G, M, K와
같은 접미사 중 하나를 사용하여 스토리지를 일반 정수 또는 고정 소수점 정수로 표현할 수 있다.
Ei, Pi, Ti, Gi, Mi, Ki와 같은 2의 거듭제곱을 사용할 수도 있다.
예를 들어, 다음은 대략 동일한 값을 나타낸다.
```shell
128974848, 129e6, 129M, 123Mi
```
다음 예에서, 파드에 두 개의 컨테이너가 있다. 각 컨테이너에는 2GiB의 로컬 임시 스토리지 요청이 있다. 각 컨테이너에는 4GiB의 로컬 임시 스토리지 제한이 있다. 따라서, 파드는 4GiB의 로컬 임시 스토리지 요청과 8GiB 스토리지 제한을 가진다.
```yaml
apiVersion: v1
kind: Pod
metadata:
name: frontend
spec:
containers:
- name: db
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "password"
resources:
requests:
ephemeral-storage: "2Gi"
limits:
ephemeral-storage: "4Gi"
- name: wp
image: wordpress
resources:
requests:
ephemeral-storage: "2Gi"
limits:
ephemeral-storage: "4Gi"
```
### 임시-스토리지 요청이 있는 파드의 스케줄링 방법
파드를 생성할 때, 쿠버네티스 스케줄러는 파드를 실행할 노드를
선택한다. 각 노드에는 파드에 제공할 수 있는 최대 임시 스토리지 공간이 있다. 자세한 정보는, [노드 할당 가능](/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable)을 참조한다.
스케줄러는 스케줄된 컨테이너의 리소스 요청 합계가 노드 용량보다 작도록 한다.
### 임시 스토리지 소비 관리 {#resource-emphemeralstorage-consumption}
kubelet이 로컬 임시 스토리지를 리소스로 관리하는 경우,
kubelet은 다음에서 스토리지 사용을 측정한다.
- _tmpfs_ `emptyDir` 볼륨을 제외한 `emptyDir` 볼륨
- 노드-레벨 로그가 있는 디렉터리
- 쓰기 가능한 컨테이너 계층
허용하는 것보다 더 많은 임시 스토리지를 파드가 사용하는 경우, kubelet은
파드 축출을 트리거하는 축출 신호를 설정한다.
컨테이너-레벨 격리의 경우, 컨테이너의 쓰기 가능한 계층과 로그
사용량이 스토리지 제한을 초과하면, kubelet은 파드를 축출하도록 표시한다.
파드-레벨 격리에 대해 kubelet은 해당 파드의 컨테이너에 대한 제한을 합하여
전체 파드 스토리지 제한을 해결한다. 이 경우, 모든
컨테이너와 파드의 `emptyDir` 볼륨의 로컬 임시 스토리지 사용량 합계가
전체 파드 스토리지 제한을 초과하면, kubelet은 파드를 축출 대상으로
표시한다.
{{< caution >}}
kubelet이 로컬 임시 스토리지를 측정하지 않는 경우,
로컬 스토리지 제한을 초과하는 파드는 로컬 스토리지 리소스 제한을
위반해도 축출되지 않는다.
그러나, 쓰기 가능한 컨테이너 계층, 노드-레벨 로그
또는 `emptyDir` 볼륨의 파일 시스템 공간이 부족하면, 로컬
스토리지가 부족하다고 노드 자체에 {{< glossary_tooltip text="테인트" term_id="taint" >}}되고
이로인해 특별히 이 테인트를 허용하지 않는 모든 파드를 축출하도록 트리거한다.
임시 로컬 스토리지에 대해 지원되는 [구성](#로컬-임시-스토리지-구성)을
참조한다.
{{< /caution >}}
kubelet은 파드 스토리지 사용을 측정하는 다양한 방법을 지원한다.
{{< tabs name="resource-emphemeralstorage-measurement" >}}
{{% tab name="주기적 스캐닝" %}}
kubelet은 각 `emptyDir` 볼륨, 컨테이너 로그 디렉터리 및 쓰기 가능한 컨테이너 계층을
스캔하는 정기적인 스케줄 검사를 수행한다.
스캔은 사용된 공간의 양을 측정한다.
{{< note >}}
이 모드에서, kubelet은 삭제된 파일의 열린 파일 디스크립터를
추적하지 않는다.
여러분(또는 컨테이너)이 `emptyDir` 볼륨 안에 파일을 생성하면,
그 파일이 열리고, 파일이 열려있는 동안 파일을
삭제하면, 삭제된 파일의 inode는 해당 파일을 닫을 때까지
유지되지만 kubelet은 사용 중인 공간으로 분류하지 않는다.
{{< /note >}}
{{% /tab %}}
{{% tab name="파일시스템 프로젝트 쿼터" %}}
{{< feature-state for_k8s_version="v1.15" state="alpha" >}}
프로젝트 쿼터는 파일시스템에서 스토리지 사용을 관리하기 위한
운영체제 레벨의 기능이다. 쿠버네티스를 사용하면, 스토리지 사용을
모니터링하기 위해 프로젝트 쿼터를 사용할 수 있다. 노드에서 'emptyDir' 볼륨을
지원하는 파일시스템이 프로젝트 쿼터 지원을 제공하는지 확인한다.
예를 들어, XFS와 ext4fs는 프로젝트 쿼터를 지원한다.
{{< note >}}
프로젝트 쿼터를 통해 스토리지 사용을 모니터링할 수 있다. 이는 제한을 강제하지 않는다.
{{< /note >}}
쿠버네티스는 `1048576` 부터 프로젝트 ID를 사용한다. 사용 중인 ID는
`/etc/projects``/etc/projid` 에 등록되어 있다. 이 범위의 프로젝트 ID가
시스템에서 다른 목적으로 사용되는 경우, 쿠버네티스가
이를 사용하지 않도록 해당 프로젝트 ID를 `/etc/projects``/etc/projid`
등록해야 한다.
쿼터는 디렉터리 검색보다 빠르고 정확하다. 디렉터리가
프로젝트에 할당되면, 디렉터리 아래에 생성된
모든 파일이 해당 프로젝트에 생성되며, 커널은 해당 프로젝트의
파일에서 사용 중인 블록 수를 추적하기만 하면 된다.
파일이 생성되고 삭제되었지만, 열린 파일 디스크립터가 있으면,
계속 공간을 소비한다. 쿼터 추적은 공간을 정확하게 기록하는 반면
디렉터리 스캔은 삭제된 파일이 사용한 스토리지를 간과한다.
프로젝트 쿼터를 사용하려면, 다음을 수행해야 한다.
* kubelet 구성에서 `LocalStorageCapacityIsolationFSQuotaMonitoring=true`
[기능 게이트](/docs/reference/command-line-tools-reference/feature-gates/)를
활성화한다.
* 루트 파일시스템(또는 선택적인 런타임 파일시스템)에
프로젝트 쿼터가 활성화되어 있는지 확인한다. 모든 XFS 파일시스템은 프로젝트 쿼터를 지원한다.
ext4 파일시스템의 경우, 파일시스템이 마운트되지 않은 상태에서 프로젝트 쿼터
추적 기능을 활성화해야 한다.
```bash
# ext4인 /dev/block-device가 마운트되지 않은 경우
sudo tune2fs -O project -Q prjquota /dev/block-device
```
* 루트 파일시스템(또는 선택적인 런타임 파일시스템)은 프로젝트 쿼터를
활성화한 상태에서 마운트해야 힌다. XFS와 ext4fs 모두에서,
마운트 옵션의 이름은 `prjquota` 이다.
{{% /tab %}}
{{< /tabs >}}
## 확장된 리소스
확장된 리소스는 `kubernetes.io` 도메인 외부의 전체 주소(fully-qualified)
리소스 이름이다. 쿠버네티스에 내장되지 않은 리소스를 클러스터 운영자가 알리고
사용자는 사용할 수 있다.
확장된 리소스를 사용하려면 두 단계가 필요한다. 먼저, 클러스터
운영자는 확장된 리소스를 알려야 한다. 둘째, 사용자는 파드의
확장된 리소스를 요청해야 한다.
### 확장된 리소스 관리
#### 노드-레벨의 확장된 리소스
노드-레벨의 확장된 리소스는 노드에 연결된다.
##### 장치 플러그인 관리 리소스
각 노드에서
장치 플러그인 관리 리소스를 알리는 방법은
[장치 플러그인](/ko/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/)을 참조한다.
##### 기타 리소스
새로운 노드-레벨의 확장된 리소스를 알리기 위해, 클러스터 운영자는
API 서버에 `PATCH` HTTP 요청을 제출하여 클러스터의
노드에 대해 `status.capacity` 에서 사용할 수 있는 수량을 지정할 수 있다. 이 작업
후에는, 노드의 `status.capacity` 에 새로운 리소스가 포함된다. 이
`status.allocatable` 필드는 kubelet에 의해 비동기적으로 새로운
리소스로 자동 업데이트된다. 참고로 스케줄러가 파드 적합성을 평가할 때 노드
`status.allocatable` 값을 사용하므로, 노드 용량을
새 리소스로 패치하는 것과 해당 노드에서 리소스를 스케줄하도록 요청하는 첫 번째 파드
사이에 약간의 지연이 있을 수 있다.
**예제:**
다음은 `curl` 을 사용하여 마스터가 `k8s-master` 인 노드 `k8s-node-1`
5개의 "example.com/foo" 리소스를 알리는 HTTP 요청을 구성하는 방법을
보여주는 예이다.
```shell
curl --header "Content-Type: application/json-patch+json" \
--request PATCH \
--data '[{"op": "add", "path": "/status/capacity/example.com~1foo", "value": "5"}]' \
http://k8s-master:8080/api/v1/nodes/k8s-node-1/status
```
{{< note >}}
앞의 요청에서, `~1` 은 패치 경로에서 문자 `/`
인코딩이다. JSON-Patch의 작업 경로 값은
JSON-Pointer로 해석된다. 더 자세한 내용은,
[IETF RFC 6901, 섹션 3](https://tools.ietf.org/html/rfc6901#section-3)을 참조한다.
{{< /note >}}
#### 클러스터-레벨의 확장된 리소스
클러스터-레벨의 확장된 리소스는 노드에 연결되지 않는다. 이들은 일반적으로
리소스 소비와 리소스 쿼터를 처리하는 스케줄러 익스텐더(extender)에 의해 관리된다.
[스케줄러 정책 구성](https://github.com/kubernetes/kubernetes/blob/release-1.10/pkg/scheduler/api/v1/types.go#L31)에서
스케줄러 익스텐더가
처리하는 확장된 리소스를 지정할 수 있다.
**예제:**
스케줄러 정책에 대한 다음의 구성은 클러스터-레벨의 확장된 리소스
"example.com/foo"가 스케줄러 익스텐더에 의해 처리됨을
나타낸다.
- 파드가 "example.com/foo"를 요청하는 경우에만 스케줄러가 파드를 스케줄러
익스텐더로 보낸다.
- 이 `ignoredByScheduler` 필드는 스케줄러가 `PodFitsResources` 속성에서
"example.com/foo" 리소스를 확인하지 않도록 지정한다.
```json
{
"kind": "Policy",
"apiVersion": "v1",
"extenders": [
{
"urlPrefix":"<extender-endpoint>",
"bindVerb": "bind",
"managedResources": [
{
"name": "example.com/foo",
"ignoredByScheduler": true
}
]
}
]
}
```
### 확장된 리소스 소비
사용자는 CPU와 메모리 같은 파드 스펙의 확장된 리소스를 사용할 수 있다.
스케줄러는 리소스 어카운팅(resource accounting)을 관리하여 사용 가능한 양보다
많은 양의 리소스가 여러 파드에 동시에 할당되지 않도록 한다.
API 서버는 확장된 리소스의 수량을 정수로 제한한다.
_유효한_ 수량의 예로는 `3`, `3000m` 그리고 `3Ki` 를 들 수 있다. _유효하지 않은_
수량의 예는 `0.5``1500m` 이다.
{{< note >}}
확장된 리소스는 불명확한 정수 리소스를 대체한다.
사용자는 예약된 `kubernetes.io` 이외의 모든 도메인 이름 접두사를 사용할 수 있다.
{{< /note >}}
파드에서 확장된 리소스를 사용하려면, 컨테이너 사양에서 `spec.containers[].resources.limits`
맵에 리소스 이름을 키로 포함한다.
{{< note >}}
확장된 리소스는 오버커밋할 수 없으므로, 컨테이너 사양에
둘 다 있으면 요청과 제한이 동일해야 한다.
{{< /note >}}
파드는 CPU, 메모리 및 확장된 리소스를 포함하여 모든 리소스 요청이
충족되는 경우에만 예약된다. 리소스 요청을 충족할 수 없다면
파드는 `PENDING` 상태를 유지한다.
**예제:**
아래의 파드는 2개의 CPU와 1개의 "example.com/foo"(확장된 리소스)를 요청한다.
```yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: myimage
resources:
requests:
cpu: 2
example.com/foo: 1
limits:
example.com/foo: 1
```
## 문제 해결
### 내 파드가 failedScheduling 이벤트 메시지로 보류 중이다
파드가 배치될 수 있는 노드를 스케줄러가 찾을 수 없으면, 노드를
찾을 수 있을 때까지 파드는 스케줄되지 않은 상태로 유지한다. 스케줄러가 다음과 같이
파드의 위치를 ​​찾지 못하면 이벤트가 생성된다.
```shell
kubectl describe pod frontend | grep -A 3 Events
```
```
Events:
FirstSeen LastSeen Count From Subobject PathReason Message
36s 5s 6 {scheduler } FailedScheduling Failed for reason PodExceedsFreeCPU and possibly others
```
위의 예에서, 노드의 CPU 리소스가 충분하지 않아 이름이
"frontend"인 파드를 스케줄하지 못했다. 비슷한 메시지로
메모리 부족(PodExceedsFreeMemory)으로 인한 장애도 알릴 수 있다. 일반적으로, 파드가
이 타입의 메시지로 보류 중인 경우, 몇 가지 시도해 볼 것들이 있다.
- 클러스터에 더 많은 노드를 추가한다.
- 불필요한 파드를 종료하여 보류 중인 파드를 위한 공간을 확보한다.
- 파드가 모든 노드보다 크지 않은지 확인한다. 예를 들어, 모든
노드의 용량이 `cpu: 1` 인 경우, `cpu: 1.1` 요청이 있는 파드는
절대 스케줄되지 않는다.
`kubectl describe nodes` 명령으로 노드 용량과 할당된 양을
확인할 수 있다. 예를 들면, 다음과 같다.
```shell
kubectl describe nodes e2e-test-node-pool-4lw4
```
```
Name: e2e-test-node-pool-4lw4
[ ... 명확하게 하기 위해 라인들을 제거함 ...]
Capacity:
cpu: 2
memory: 7679792Ki
pods: 110
Allocatable:
cpu: 1800m
memory: 7474992Ki
pods: 110
[ ... 명확하게 하기 위해 라인들을 제거함 ...]
Non-terminated Pods: (5 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits
--------- ---- ------------ ---------- --------------- -------------
kube-system fluentd-gcp-v1.38-28bv1 100m (5%) 0 (0%) 200Mi (2%) 200Mi (2%)
kube-system kube-dns-3297075139-61lj3 260m (13%) 0 (0%) 100Mi (1%) 170Mi (2%)
kube-system kube-proxy-e2e-test-... 100m (5%) 0 (0%) 0 (0%) 0 (0%)
kube-system monitoring-influxdb-grafana-v4-z1m12 200m (10%) 200m (10%) 600Mi (8%) 600Mi (8%)
kube-system node-problem-detector-v0.1-fj7m3 20m (1%) 200m (10%) 20Mi (0%) 100Mi (1%)
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
CPU Requests CPU Limits Memory Requests Memory Limits
------------ ---------- --------------- -------------
680m (34%) 400m (20%) 920Mi (12%) 1070Mi (14%)
```
위의 출력에서, ​파드가 1120m 이상의 CPU 또는 6.23Gi의 메모리를
요청하는 것은 노드에 맞지 않음을 알 수 있다.
`Pods` 섹션을 살펴보면, 파드가 노드에서 공간을 차지하는 것을
볼 수 있다.
시스템 데몬이 사용 가능한 리소스의 일부를 사용하기 때문에, 파드에
사용 가능한 리소스의 양이 노드 용량보다 적다. `allocatable` 필드
[NodeStatus](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#nodestatus-v1-core)는
파드가 사용할 수 있는 리소스의 양을 제공한다. 자세한 정보는
[노드 할당 가능 리소스](https://git.k8s.io/community/contributors/design-proposals/node/node-allocatable.md)를 참조한다.
[리소스 쿼터](/ko/docs/concepts/policy/resource-quotas/) 기능은
소비될 수 있는 리소스의 총량을 제한하도록 구성할 수 있다. 네임스페이스와
함께 사용하면, 한 팀이 모든 리소스를 사용하는 경우를 방지할 수 있다.
### 내 컨테이너가 종료되었다
리소스가 부족하여 컨테이너가 종료될 수 있다. 리소스
제한에 도달하여 컨테이너가 종료되고 있는지 확인하려면,
관심있는 파드에 대해 `kubectl describe pod` 를 호출한다.
```shell
kubectl describe pod simmemleak-hra99
```
```
Name: simmemleak-hra99
Namespace: default
Image(s): saadali/simmemleak
Node: kubernetes-node-tf0f/10.240.216.66
Labels: name=simmemleak
Status: Running
Reason:
Message:
IP: 10.244.2.75
Replication Controllers: simmemleak (1/1 replicas created)
Containers:
simmemleak:
Image: saadali/simmemleak
Limits:
cpu: 100m
memory: 50Mi
State: Running
Started: Tue, 07 Jul 2015 12:54:41 -0700
Last Termination State: Terminated
Exit Code: 1
Started: Fri, 07 Jul 2015 12:54:30 -0700
Finished: Fri, 07 Jul 2015 12:54:33 -0700
Ready: False
Restart Count: 5
Conditions:
Type Status
Ready False
Events:
FirstSeen LastSeen Count From SubobjectPath Reason Message
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {scheduler } scheduled Successfully assigned simmemleak-hra99 to kubernetes-node-tf0f
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD pulled Pod container image "k8s.gcr.io/pause:0.8.0" already present on machine
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD created Created with docker id 6a41280f516d
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD started Started with docker id 6a41280f516d
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} spec.containers{simmemleak} created Created with docker id 87348f12526a
```
앞의 예제에서, `Restart Count: 5` 표시는 파드의 `simmemleak`
컨테이너가 종료되고 5번 다시 시작되었음을 나타낸다.
이전에 종료된 컨테이너의 상태를 가져오기 위해 `-o go-template=...` 옵션을 사용해서
`kubectl get pod` 를 호출할 수 있다.
```shell
kubectl get pod -o go-template='{{range.status.containerStatuses}}{{"Container Name: "}}{{.name}}{{"\r\nLastState: "}}{{.lastState}}{{end}}' simmemleak-hra99
```
```
Container Name: simmemleak
LastState: map[terminated:map[exitCode:137 reason:OOM Killed startedAt:2015-07-07T20:58:43Z finishedAt:2015-07-07T20:58:43Z containerID:docker://0e4095bba1feccdfe7ef9fb6ebffe972b4b14285d5acdec6f0d3ae8a22fad8b2]]
```
컨테이너가 `reason:OOM Killed`(`OOM` 은 메모리 부족(Out Of Memory)의 약자) 때문에 종료된 것을 알 수 있다.
{{% /capture %}}
{{% capture whatsnext %}}
* [컨테이너와 파드에 메모리 리소스를 할당](/ko/docs/tasks/configure-pod-container/assign-memory-resource/)하는 핸즈온 경험을 해보자.
* [컨테이너와 파드에 CPU 리소스를 할당](/docs/tasks/configure-pod-container/assign-cpu-resource/)하는 핸즈온 경험을 해보자.
* 요청과 제한의 차이점에 대한 자세한 내용은,
[리소스 QoS](https://git.k8s.io/community/contributors/design-proposals/node/resource-qos.md)를 참조한다.
* [컨테이너](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#container-v1-core) API 레퍼런스 읽어보기
* [ResourceRequirements](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#resourcerequirements-v1-core) API 레퍼런스 읽어보기
* XFS의 [프로젝트 쿼터](http://xfs.org/docs/xfsdocs-xml-dev/XFS_User_Guide/tmp/en-US/html/xfs-quotas.html)에 대해 읽어보기
{{% /capture %}}

View File

@ -0,0 +1,193 @@
---
title: 파드 오버헤드
content_template: templates/concept
weight: 20
---
{{% capture overview %}}
{{< feature-state for_k8s_version="v1.18" state="beta" >}}
노드 위에서 파드를 구동할 때, 파드는 그 자체적으로 많은 시스템 리소스를 사용한다.
이러한 리소스는 파드 내의 컨테이너들을 구동하기 위한 리소스 이외에 추가적으로 필요한 것이다.
_파드 오버헤드_ 는 컨테이너 리소스 요청과 상한 위에서 파드의 인프라에 의해
소비되는 리소스를 계산하는 기능이다.
{{% /capture %}}
{{% capture body %}}
쿠버네티스에서 파드의 오버헤드는 파드의
[런타임클래스](/ko/docs/concepts/containers/runtime-class/) 와 관련된 오버헤드에 따라
[어드미션](/docs/reference/access-authn-authz/extensible-admission-controllers/#what-are-admission-webhooks)
이 수행될 때 지정된다.
파드 오버헤드가 활성화 되면, 파드를 노드에 스케줄링 할 때 컨테이너 리소스 요청의 합에
파드의 오버헤드를 추가해서 스케줄링을 고려한다. 마찬가지로, Kubelet은 파드의 cgroups 크기를 변경하거나
파드의 축출 등급을 부여할 때에도 파드의 오버헤드를 포함하여 고려한다.
## 파드 오버헤드 활성화하기 {#set-up}
기능 활성화를 위해 클러스터에서
`PodOverhead` [기능 게이트](/docs/reference/command-line-tools-reference/feature-gates/) 가 활성화 되어 있고 (1.18 버전에서는 기본적으로 활성화),
`overhead` 필드를 정의하는 `RuntimeClass` 가 사용되고 있는지 확인해야 한다.
## 사용 예제
파드 오버헤드 기능을 사용하기 위하여, `overhead` 필드를 정의하는 런타임클래스가 필요하다.
예를 들어, 가상 머신 및 게스트 OS에 대하여 파드 당 120 MiB를 사용하는
가상화 컨테이너 런타임의 런타임클래스의 경우 다음과 같이 정의 할 수 있다.
```yaml
---
kind: RuntimeClass
apiVersion: node.k8s.io/v1beta1
metadata:
name: kata-fc
handler: kata-fc
overhead:
podFixed:
memory: "120Mi"
cpu: "250m"
```
`kata-fc` 런타임클래스 핸들러를 지정하는 워크로드는 리소스 쿼터 계산,
노드 스케줄링 및 파드 cgroup 크기 조정을 위하여 메모리와 CPU 오버헤드를 고려한다.
주어진 예제 워크로드 test-pod의 구동을 고려해보자.
```yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
runtimeClassName: kata-fc
containers:
- name: busybox-ctr
image: busybox
stdin: true
tty: true
resources:
limits:
cpu: 500m
memory: 100Mi
- name: nginx-ctr
image: nginx
resources:
limits:
cpu: 1500m
memory: 100Mi
```
어드미션 수행 시에, [어드미션 컨트롤러](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/)는
런타임클래스에 기술된 `overhead` 를 포함하기 위하여 워크로드의 PodSpec 항목을 갱신한다. 만약 PodSpec이 이미 해당 필드에 정의되어 있으면,
파드는 거부된다. 주어진 예제에서, 오직 런타임클래스의 이름만이 정의되어 있기 때문에, 어드미션 컨트롤러는 파드가
`overhead` 를 포함하도록 변경한다.
런타임클래스의 어드미션 수행 후에, 파드의 스펙이 갱신된 것을 확인할 수 있다.
```bash
kubectl get pod test-pod -o jsonpath='{.spec.overhead}'
```
명령 실행 결과는 다음과 같다.
```
map[cpu:250m memory:120Mi]
```
만약 리소스쿼터 항목이 정의되어 있다면, 컨테이너의 리소스 요청의 합에는
`overhead` 필드도 추가된다.
kube-scheduler 는 어떤 노드에 파드가 기동 되어야 할지를 정할 때, 파드의 `overhead`
해당 파드에 대한 컨테이너의 리소스 요청의 합을 고려한다. 이 예제에서, 스케줄러는
리소스 요청과 파드의 오버헤드를 더하고, 2.25 CPU와 320 MiB 메모리가 사용 가능한 노드를 찾는다.
일단 파드가 특정 노드에 스케줄링 되면, 해당 노드에 있는 kubelet 은 파드에 대한 새로운 {{< glossary_tooltip text="cgroup" term_id="cgroup" >}}을 생성한다.
기본 컨테이너 런타임이 만들어내는 컨테이너들은 이 파드 안에 존재한다.
만약 각 컨테이너에 대하여 QoS가 보장되었거나 향상이 가능하도록 QoS 의 리소스 상한 제한이 걸려있으면,
kubelet 은 해당 리소스(CPU의 경우 cpu.cfs_quota_us, 메모리의 경우 memory.limit_in_bytes)와 연관된 파드의
cgroup 의 상한선을 설정한다. 이 상한선은 컨테이너 리소스 상한과 PodSpec에
정의된 `overhead` 의 합에 기반한다.
CPU의 경우, 만약 파드가 보장형 또는 버스트형 QoS로 설정되었으면, kubelet은 PodSpec에 정의된 `overhead` 에 컨테이너의
리소스 요청의 합을 더한 값을 `cpu.shares` 로 설정한다.
다음의 예제를 참고하여, 워크로드에 대하여 컨테이너의 리소스 요청을 확인하자.
```bash
kubectl get pod test-pod -o jsonpath='{.spec.containers[*].resources.limits}'
```
컨테이너 리소스 요청의 합은 각각 CPU 2000m 와 메모리 200MiB 이다.
```
map[cpu: 500m memory:100Mi] map[cpu:1500m memory:100Mi]
```
노드에서 측정된 내용과 비교하여 확인해보자.
```bash
kubectl describe node | grep test-pod -B2
```
CPU 2250m와 메모리 320MiB 가 리소스로 요청되었으며, 이 결과는 파드의 오버헤드를 포함한다.
```
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits AGE
--------- ---- ------------ ---------- --------------- ------------- ---
default test-pod 2250m (56%) 2250m (56%) 320Mi (1%) 320Mi (1%) 36m
```
## 파드 cgroup 상한 확인하기
워크로드가 실행 중인 노드에서 파드의 메모리 cgroup들을 확인 해보자. 다음의 예제에서, [`crictl`](https://github.com/kubernetes-sigs/cri-tools/blob/master/docs/crictl.md)은 노드에서 사용되며,
CRI-호환 컨테이너 런타임을 위해서 노드에서 사용할 수 있는 CLI 를 제공한다.
파드의 오버헤드 동작을 보여주는 좋은 예이며,
사용자가 노드에서 직접 cgroup들을 확인하지 않아도 된다.
먼저 특정 노드에서 파드의 식별자를 확인해 보자.
```bash
# 파드가 스케줄 된 노드에서 이것을 실행
POD_ID="$(sudo crictl pods --name test-pod -q)"
```
여기에서, 파드의 cgroup 경로를 확인할 수 있다.
```bash
# 파드가 스케줄 된 노드에서 이것을 실행
sudo crictl inspectp -o=json $POD_ID | grep cgroupsPath
```
명령의 결과로 나온 cgroup 경로는 파드의 `pause` 컨테이너를 포함한다. 파드 레벨의 cgroup은 하나의 디렉터리이다.
```
"cgroupsPath": "/kubepods/podd7f4b509-cf94-4951-9417-d1087c92a5b2/7ccf55aee35dd16aca4189c952d83487297f3cd760f1bbf09620e206e7d0c27a"
```
아래의 특정한 경우에, 파드 cgroup 경로는 `kubepods/podd7f4b509-cf94-4951-9417-d1087c92a5b2` 이다. 메모리의 파드 레벨 cgroup 설정을 확인하자.
```bash
# 파드가 스케줄 된 노드에서 이것을 실행.
# 또한 사용자의 파드에 할당된 cgroup 이름에 맞춰 해당 이름을 수정.
cat /sys/fs/cgroup/memory/kubepods/podd7f4b509-cf94-4951-9417-d1087c92a5b2/memory.limit_in_bytes
```
예상대로 320 MiB 이다.
```
335544320
```
### 관찰성
`kube_pod_overhead` 항목은 [kube-state-metrics](https://github.com/kubernetes/kube-state-metrics)
에서 사용할 수 있어, 파드 오버헤드가 사용되는 시기를 식별하고,
정의된 오버헤드로 실행되는 워크로드의 안정성을 관찰할 수 있다.
이 기능은 kube-state-metrics 의 1.9 릴리스에서는 사용할 수 없지만, 다음 릴리스에서는 가능할 예정이다.
그 전까지는 소스로부터 kube-state-metric 을 빌드해야 한다.
{{% /capture %}}
{{% capture whatsnext %}}
* [런타임클래스](/ko/docs/concepts/containers/runtime-class/)
* [파드오버헤드 디자인](https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/20190226-pod-overhead.md)
{{% /capture %}}

View File

@ -0,0 +1,417 @@
---
title: 파드 우선순위(priority)와 선점(preemption)
content_template: templates/concept
weight: 70
---
{{% capture overview %}}
{{< feature-state for_k8s_version="v1.14" state="stable" >}}
[파드](/ko/docs/concepts/workloads/pods/pod/)는 _우선순위_ 를 가질 수 있다. 우선순위는
다른 파드에 대한 상대적인 파드의 중요성을 나타낸다. 파드를 스케줄링할 수 없는 경우,
스케줄러는 우선순위가 낮은 파드를 선점(축출)하여 보류 중인 파드를
스케줄링할 수 있게 한다.
{{% /capture %}}
{{% capture body %}}
{{< warning >}}
모든 사용자를 신뢰할 수 없는 클러스터에서, 악의적인 사용자가 우선순위가
가장 높은 파드를 생성하여 다른 파드가 축출되거나 스케줄링되지
않을 수 있다.
관리자는 리소스쿼터를 사용하여 사용자가 우선순위가 높은 파드를 생성하지
못하게 할 수 있다.
자세한 내용은 [기본적으로 프라이어리티 클래스(Priority Class) 소비 제한](/ko/docs/concepts/policy/resource-quotas/#기본적으로-우선-순위-클래스-소비-제한)을
참고한다.
{{< /warning >}}
## 우선순위와 선점을 사용하는 방법
우선순위와 선점을 사용하려면 다음을 참고한다.
1. 하나 이상의 [프라이어리티클래스](#프라이어리티클래스)를 추가한다.
1. 추가된 프라이어리티클래스 중 하나에 [`priorityClassName`](#파드-우선순위)이 설정된
파드를 생성한다. 물론 파드를 직접 생성할 필요는 없다.
일반적으로 디플로이먼트와 같은 컬렉션 오브젝트의 파드 템플릿에 `priorityClassName`
을 추가한다.
이 단계에 대한 자세한 내용은 계속 읽어보자.
{{< note >}}
쿠버네티스는 이미 `system-cluster-critical``system-node-critical`,
두 개의 프라이어리티클래스를 제공한다.
이들은 일반적인 클래스이며 [중요한(critical) 컴포넌트가 항상 먼저 스케줄링이 되도록 하는 데](/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods/) 사용된다.
{{< /note >}}
기능을 사용해 본 후 사용하지 않기로 했다면, PodPriority
커맨드-라인 플래그를 제거하거나 `false` 로 설정한 후, API 서버와
스케줄러를 다시 시작해야 한다. 기능이 비활성화된 후, 기존 파드는
우선순위 필드를 유지하지만, 선점은 비활성화되며, 우선순위 필드는
무시된다. 이 기능이 비활성화되면, 새로운 파드에서 `priorityClassName` 을 설정할 수
없다.
## 선점을 비활성화하는 방법
{{< caution >}}
중요 파드는 클러스터에 리소스 압박(resource pressure)이 가해지면
스케줄러 선점에 따라 스케줄링된다. 이런 이유로, 선점을 비활성화하지
않는 것을 권장한다.
{{< /caution >}}
{{< note >}}
쿠버네티스 1.15 이상에서, `NonPreemptingPriority` 기능이 활성화된 경우,
프라이어리티클래스는 옵션을 `preemptionPolicy: Never` 로 설정할 수 있다.
이렇게 하면 해당 프라이어리티클래스의 파드가 다른 파드를 축출할 수 없다.
{{< /note >}}
선점은 기본값이 `false`로 설정된 `disablePreemption` kube-scheduler
플래그에 의해 제어된다.
위의 주의에도 불구하고 선점을 비활성화하려는 경우,
`disablePreemption``true` 로 설정할 수 있다.
이 옵션은 컴포넌트 구성에서만 사용할 수 있으며
이전 스타일의 커맨드 라인 옵션에서는 사용할 수 없다. 다음은 선점을 비활성화하는 샘플 컴포넌트
구성이다.
```yaml
apiVersion: kubescheduler.config.k8s.io/v1alpha1
kind: KubeSchedulerConfiguration
algorithmSource:
provider: DefaultProvider
...
disablePreemption: true
```
## 프라이어리티클래스
프라이어리티클래스는 프라이어리티 클래스 이름에서 우선순위의 정수 값으로의 매핑을
정의하는 네임스페이스가 아닌(non-namespaced) 오브젝트이다. 이름은
프라이어리티클래스 오브젝트의 메타데이터의 `name` 필드에 지정된다. 값은
필수 `value` 필드에 지정되어 있다. 값이 클수록, 우선순위가
높다.
프라이어리티클래스 오브젝트의 이름은 유효한
[DNS 서브 도메인 이름](/ko/docs/concepts/overview/working-with-objects/names/#dns-서브도메인-이름)이어야 하며,
`system-` 접두사를 붙일 수 없다.
프라이어리티클래스 오브젝트는 10억 이하의 32비트 정수 값을 가질
수 있다. 일반적으로 선점하거나 축출해서는 안되는 중요한 시스템 파드에는 더 큰 숫자가
예약되어 있다. 클러스터 관리자는 원하는 각 매핑에 대해 프라이어리티클래스 오브젝트를
하나씩 생성해야 한다.
프라이어리티클래스에는 `globalDefault``description` 두 개의 선택적인 필드도 있다.
`globalDefault` 필드는 이 프라이어리티클래스의 값을 `priorityClassName` 이 없는
파드에 사용해야 함을 나타낸다. 시스템에서 `globalDefault``true` 로 설정된
프라이어리티클래스는 하나만 존재할 수 있다. `globalDefault` 가 설정된
프라이어리티클래스가 없을 경우, `priorityClassName` 이 없는 파드의
우선순위는 0이다.
`description` 필드는 임의의 문자열이다. 이 필드는 이 프라이어리티클래스를 언제
사용해야 하는지를 클러스터 사용자에게 알려주기 위한 것이다.
### PodPriority와 기존 클러스터에 대한 참고 사항
- 기존 클러스터를 업그레이드하고 이 기능을 활성화하면, 기존 파드의
우선순위는 사실상 0이다.
- `globalDefault``true` 로 설정된 프라이어리티클래스를 추가해도 기존 파드의
우선순위는 변경되지 않는다. 이러한 프라이어리티클래스의 값은
프라이어리티클래스를 추가한 후 생성된 파드에만 사용된다.
- 프라이어리티클래스를 삭제하면, 삭제된 프라이어리티클래스의 이름을 사용하는
기존 파드는 변경되지 않고 남아있지만, 삭제된 프라이어리티클래스의 이름을
사용하는 파드는 더 이상 생성할 수 없다.
### 프라이어리티클래스 예제
```yaml
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority
value: 1000000
globalDefault: false
description: "이 프라이어리티 클래스는 XYZ 서비스 파드에만 사용해야 한다."
```
## 비-선점 프라이어리티클래스 {#non-preempting-priority-class}
{{< feature-state for_k8s_version="v1.15" state="alpha" >}}
`PreemptionPolicy: Never` 를 가진 파드는 낮은 우선순위 파드의 스케줄링 대기열의
앞쪽에 배치되지만,
그 파드는 다른 파드를 축출할 수 없다.
스케줄링 대기 중인 비-선점 파드는 충분한 리소스가 확보되고
스케줄링될 수 있을 때까지
스케줄링 대기열에 대기한다.
다른 파드와 마찬가지로,
비-선점 파드는
스케줄러 백오프(back-off)에 종속된다.
이는 스케줄러가 이러한 파드를 스케줄링하려고 시도하고 스케줄링할 수 없는 경우,
더 적은 횟수로 재시도하여,
우선순위가 낮은 다른 파드를 미리 스케줄링할 수 있음을 의미한다.
비-선점 파드는 다른 우선순위가 높은 파드에 의해
축출될 수 있다.
`PreemptionPolicy` 는 기본값으로 `PreemptLowerPriority` 로 설정되어,
해당 프라이어리티클래스의 파드가 우선순위가 낮은 파드를 축출할 수
있다(기존의 기본 동작과 동일).
`PreemptionPolicy``Never` 로 설정된 경우,
해당 프라이어리티클래스의 파드는 비-선점될 것이다.
`PreemptionPolicy` 필드를 사용하려면 `NonPreemptingPriority`
[기능 게이트](/docs/reference/command-line-tools-reference/feature-gates/)가
활성화되어야 한다.
예제 유스케이스는 데이터 과학 관련 워크로드이다.
사용자는 다른 워크로드보다 우선순위가 높은 잡(job)을 제출할 수 있지만,
실행 중인 파드를 축출하여 기존의 작업을 삭제하지는 않을 것이다.
클러스터 리소스가 "자연스럽게" 충분히 사용할 수 있게 되면,
`PreemptionPolicy: Never` 의 우선순위가 높은 잡이
다른 대기 중인 파드보다 먼저 스케줄링된다.
### 비-선점 프라이어리티클래스 예제
```yaml
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority-nonpreempting
value: 1000000
preemptionPolicy: Never
globalDefault: false
description: "이 프라이어리티 클래스는 다른 파드를 축출하지 않는다."
```
## 파드 우선순위
프라이어리티클래스가 하나 이상 있으면, 그것의 명세에서 이들 프라이어리티클래스 이름 중 하나를
지정하는 파드를 생성할 수 있다. 우선순위 어드미션
컨트롤러는 `priorityClassName` 필드를 사용하고 우선순위의 정수 값을
채운다. 프라이어리티 클래스를 찾을 수 없으면, 파드가 거부된다.
다음의 YAML은 이전 예제에서 생성된 프라이어리티클래스를
사용하는 파드 구성의 예이다. 우선순위 어드미션 컨트롤러는
명세를 확인하고 파드의 우선순위를 1000000으로
해석한다.
```yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
priorityClassName: high-priority
```
### 스케줄링 순서에 대한 파드 우선순위의 영향
파드 우선순위가 활성화되면, 스케줄러가 우선순위에 따라 보류 중인
파드를 주문하고 보류 중인 파드는 스케줄링 대기열에서
우선순위가 낮은 다른 보류 중인 파드보다 우선한다. 결과적으로, 스케줄링
요구 사항이 충족되는 경우 우선순위가 더 낮은 파드보다 우선순위가 높은 파드가
더 빨리 스케줄링될 수 있다. 이러한 파드를 스케줄링할 수 없는 경우,
스케줄러는 계속 진행하고 우선순위가 낮은 다른 파드를 스케줄링하려고 한다.
## 선점
파드가 생성되면, 대기열로 이동하여 스케줄링을 기다린다.
스케줄러가 대기열에서 파드를 선택하여 노드에 스케줄링하려고 한다.
파드의 지정된 모든 요구 사항을 충족하는 노드가 없으면,
보류 중인 파드에 대해 선점 로직이 트리거된다. 보류 중인 파드를 P라 하자.
선점 로직은 P보다 우선순위가 낮은 하나 이상의 파드를 제거하면
해당 노드에서 P를 스케줄링할 수 있는 노드를 찾는다. 이러한
노드가 발견되면, 하나 이상의 우선순위가 낮은 파드가 노드에서 축출된다.
파드가 축출된 후, P는 노드에 스케줄링될 수 있다.
### 사용자 노출 정보
파드 P가 노드 N에서 하나 이상의 파드를 축출할 경우, 파드 P의 상태 `nominatedNodeName`
필드는 노드 N의 이름으로 설정된다. 이 필드는 스케줄러가 파드 P에
예약된 리소스를 추적하는 데 도움이 되고 사용자에게 클러스터의 선점에 대한
정보를 제공한다.
파드 P는 반드시 "지정된 노드"로 스케줄링되지는 않는다.
피해자 파드가 축출된 후, 그것은 정상적(graceful)으로 종료되는 기간을 갖는다.
스케줄러가 종료될 피해자 파드를 기다리는 동안 다른 노드를 사용할 수
있게 되면, 스케줄러는 파드 P를 스케줄링하기 위해 다른 노드를 사용한다. 그 결과,
파드 스펙의 `nominatedNodeName``nodeName` 은 항상 동일하지 않다. 또한,
스케줄러가 노드 N에서 파드를 축출했지만, 파드 P보다 우선순위가 높은 파드가
도착하면, 스케줄러가 노드 N에 새로운 우선순위가 높은 파드를 제공할 수 있다. 이러한
경우, 스케줄러는 파드 P의 `nominatedNodeName` 을 지운다. 이렇게하면, 스케줄러는
파드 P가 다른 노드에서 파드를 축출할 수 있도록 한다.
### 선점의 한계
#### 선점 피해자의 정상적인 종료
파드가 축출되면, 축출된 피해자 파드는
[정상적인 종료 기간](/ko/docs/concepts/workloads/pods/pod/#파드의-종료)을 가진다.
피해자 파드는 작업을 종료하고 빠져나가는 데(exit) 많은 시간을 가진다. 그렇지 않으면,
파드는 강제종료(kill) 된다. 이 정상적인 종료 기간은 스케줄러가 파드를 축출하는
지점과 보류 중인 파드(P)를 노드(N)에서 스케줄링할 수 있는 시점 사이의
시간 간격을 만든다. 그 동안, 스케줄러는 보류 중인 다른 파드를
계속 스케줄링한다. 피해자 파드가 빠져나가거나 종료되면, 스케줄러는 보류 대기열에서
파드를 스케줄하려고 한다. 따라서, 일반적으로 스케줄러가 피해자 파드를 축출하는 시점과
파드 P가 스케줄링된 시점 사이에 시간 간격이 있다.
이러한 차이를 최소화하기 위해, 우선순위가 낮은 파드의 정상적인 종료 기간을 0 또는
작은 수로 설정할 수 있다.
#### PodDisruptionBudget을 지원하지만, 보장하지 않음
[Pod Disruption Budget(PDB)](/ko/docs/concepts/workloads/pods/disruptions/)은
애플리케이션 소유자가 자발적 중단에서 동시에 다운된 복제된
애플리케이션의 파드 수를 제한할 수 있다. 쿠버네티스는 파드를
선점할 때 PDB를 지원하지만, PDB를 따르는 것이 최선의 노력이다. 스케줄러는
선점에 의해 PDB를 위반하지 않은 피해자 파드를 찾으려고 하지만, 그러한 피해자 파드가
발견되지 않으면, 선점은 여전히 발생하며, PDB를 위반하더라도 우선순위가
낮은 파드는 제거된다.
#### 우선순위가 낮은 파드에 대한 파드-간 어피니티
이 질문에 대한 답변이 '예'인 경우에만 노드가 선점 대상으로 간주된다.
"대기 중인 파드보다 우선순위가 낮은 모든 파드가 노드에서
제거되면, 보류 중인 파드를 노드에 스케줄링할 수 있습니까?"
{{< note >}}
선점으로 우선순위가 낮은 모든 파드를 반드시 제거할 필요는
없다. 우선순위가 낮은 모든 파드보다 적은 수를 제거하여 보류 중인 파드를
스케줄링할 수 있는 경우, 우선순위가 낮은 파드의 일부만 제거된다.
그럼에도 불구하고, 앞의 질문에 대한 대답은 '예'여야 한다. 답변이 '아니오'인 경우,
노드가 선점 대상으로 간주되지 않는다.
{{< /note >}}
보류 중인 파드가 노드에 있는 하나 이상의 우선순위가 낮은 파드에 대한 파드-간 어피니티를
가진 경우에, 우선순위가 낮은 파드가 없을 때 파드-간 어피니티 규칙을
충족할 수 없다. 이 경우, 스케줄러는 노드의 파드를 축출하지
않는다. 대신, 다른 노드를 찾는다. 스케줄러가
적합한 노드를 찾거나 찾지 못할 수 있다. 보류 중인 파드를 스케줄링할 수 있다는
보장은 없다.
이 문제에 대한 권장 솔루션은 우선순위가 같거나 높은 파드에 대해서만 파드-간 어피니티를
생성하는 것이다.
#### 교차 노드 선점
보류 중인 파드 P가 노드 N에 스케줄링될 수 있도록 노드 N이 선점 대상으로 고려되고
있다고 가정한다. 다른 노드의 파드가 축출된 경우에만 P가 N에서 실행 가능해질 수
있다. 예를 들면 다음과 같다.
* 파드 P는 노드 N에 대해 고려된다.
* 파드 Q는 노드 N과 동일한 영역의 다른 노드에서 실행 중이다.
* 파드 P는 파드 Q(`topologyKey:
failure-domain.beta.kubernetes.io/zone`)와 영역(zone) 전체의 안티-어피니티를 갖는다.
* 영역에서 파드 P와 다른 파드 간의 안티-어피니티에 대한 다른 경우는
없다.
* 노드 N에서 파드 P를 스케줄링하기 위해, 파드 Q를 축출할 수 있지만, 스케줄러는
교차-노드 선점을 수행하지 않는다. 따라서, 파드 P가 노드 N에서
스케줄링할 수 없는 것으로 간주된다.
파드 Q가 노드에서 제거되면, 파드 안티-어피니티 위반이
사라지고, 파드 P는 노드 N에서 스케줄링될 수 있다.
수요가 충분하고 합리적인 성능의 알고리즘을 찾을 경우
향후 버전에서 교차 노드 선점의 추가를 고려할 수 있다.
## 문제 해결
파드 우선순위와 선점은 원하지 않는 부작용을 가질 수 있다. 다음은
잠재적 문제의 예시와 이를 해결하는 방법이다.
### 파드가 불필요하게 선점(축출)됨
선점은 우선순위가 높은 보류 중인 파드를 위한 공간을 만들기 위해 리소스 압박을 받고 있는
클러스터에서 기존 파드를 제거한다. 실수로 특정 파드에 높은 우선순위를
부여하면, 의도하지 않은 높은 우선순위 파드가 클러스터에서
선점을 유발할 수 있다. 파드 우선순위는 파드 명세에서
`priorityClassName` 필드를 설정하여 지정한다. 그런 다음
우선순위의 정수 값이 분석되어 `podSpec``priority` 필드에 채워진다.
문제를 해결하기 위해, 해당 파드가 우선순위가 낮은 클래스를 사용하도록 `priorityClassName`
변경하거나, 해당 필드를 비워둘 수 있다. 빈
`priorityClassName` 은 기본값이 0으로 해석된다.
파드가 축출되면, 축출된 파드에 대한 이벤트가 기록된다.
선점은 클러스터가 파드에 대한 리소스를 충분히 가지지 못한 경우에만
발생한다. 이러한 경우, 선점은 보류 중인 파드(선점자)의 우선순위가
피해자 파드보다 높은 경우에만 발생한다. 보류 중인 파드가 없거나,
보류 중인 파드의 우선순위가 피해자 파드와 같거나 낮은 경우
선점이 발생하지 않아야 한다. 그러한 시나리오에서 선점이 발생하면, 이슈를 올리기 바란다.
### 파드가 축출되었지만, 선점자는 스케줄링되지 않음
파드가 축출되면, 요청된 정상적인 종료
기간(기본적으로 30초)이 주어진다. 이 기간 내에 대상 파드가
종료되지 않으면, 강제 종료된다. 모든 피해자 파드가 사라지면,
선점자 파드를 스케줄링할 수 있다.
선점자 파드가 피해자 파드가 없어지기를 기다리는 동안, 동일한 노드에
적합한 우선순위가 높은 파드가 생성될 수 있다. 이 경우, 스케줄러는
선점자 대신 우선순위가 높은 파드를 스케줄링한다.
이것은 예상된 동작이다. 우선순위가 높은 파드는 우선순위가 낮은 파드를
대체해야 한다. [클러스터 오토스케일링](/ko/docs/tasks/administer-cluster/cluster-management/#클러스터-오토스케일링)과
같은 다른 컨트롤러 작업은,
결국 보류 중인 파드를 스케줄링할 수 있는 용량을 제공할 수 있다.
### 우선순위가 높은 파드는 우선순위가 낮은 파드보다 우선함
스케줄러가 보류 중인 파드를 실행할 수 있는 노드를 찾으려고 한다. 노드를 찾지
못하면, 스케줄러는 임의의 노드에서 우선순위가 낮은 파드를 제거하여
보류 중인 파드를 위한 공간을 만든다.
우선순위가 낮은 파드가 있는 노드가 보류 중인 파드를 실행할 수 없는 경우, 스케줄러는
선점을 위해 우선순위가 높은 다른 노드(다른 노드의 파드와 비교)를
선택할 수 있다. 피해자 파드는 여전히 선점자 파드보다 우선순위가
낮아야 한다.
선점할 수 있는 여러 노드가 있는 경우, 스케줄러는
우선순위가 가장 낮은 파드 세트를 가진 노드를 선택하려고 한다. 그러나,
이러한 파드가 위반될 PodDisruptionBudget을 가지고 있고 축출된 경우
스케줄러는 우선순위가 높은 파드를 가진 다른 노드를 선택할 수 있다.
선점을 위해 여러 개의 노드가 존재하고 위의 시나리오 중 어느 것도 적용되지 않는 경우,
스케줄러는 우선순위가 가장 낮은 노드를 선택한다.
## 파드 우선순위와 서비스 품질 간의 상호 작용 {#interactions-of-pod-priority-and-qos}
파드 우선순위와 {{< glossary_tooltip text="QoS 클래스" term_id="qos-class" >}}는
상호 작용이 거의 없고 QoS 클래스를 기반으로 파드 우선순위를 설정하는 데 대한
기본 제한이 없는 두 개의 직교(orthogonal) 기능이다. 스케줄러의
선점 로직은 선점 대상을 선택할 때 QoS를 고려하지 않는다.
선점은 파드 우선순위를 고려하고 우선순위가 가장 낮은 대상 세트를
선택하려고 한다. 우선순위가 가장 높은 파드는 스케줄러가
선점자 파드를 스케줄링할 수 없거나 우선순위가 가장 낮은 파드가
`PodDisruptionBudget` 으로 보호되는 경우에만, 우선순위가 가장 낮은 파드를
축출 대상으로 고려한다.
QoS와 파드 우선순위를 모두 고려하는 유일한 컴포넌트는
[kubelet 리소스 부족 축출](/docs/tasks/administer-cluster/out-of-resource/)이다.
kubelet은 부족한 리소스의 사용이 요청을 초과하는지 여부에 따라, 그런 다음 우선순위에 따라,
파드의 스케줄링 요청에 대한 부족한 컴퓨팅 리소스의 소비에 의해
먼저 축출 대상 파드의 순위를 매긴다.
더 자세한 내용은
[엔드유저 파드 축출](/docs/tasks/administer-cluster/out-of-resource/#evicting-end-user-pods)을
참조한다.
kubelet 리소스 부족 축출은 사용량이 요청을 초과하지 않는 경우
파드를 축출하지 않는다. 우선순위가 낮은 파드가 요청을
초과하지 않으면, 축출되지 않는다. 요청을 초과하는 우선순위가
더 높은 다른 파드가 축출될 수 있다.
{{% /capture %}}
{{% capture whatsnext %}}
* 프라이어리티클래스와 관련하여 리소스쿼터 사용에 대해 [기본적으로 프라이어리티 클래스 소비 제한](/ko/docs/concepts/policy/resource-quotas/#기본적으로-우선-순위-클래스-소비-제한)을 읽어보자.
{{% /capture %}}

View File

@ -1,7 +1,7 @@
---
title: 확장된 리소스를 위한 리소스 빈 패킹(bin packing)
content_template: templates/concept
weight: 10
weight: 50
---
{{% capture overview %}}

View File

@ -198,7 +198,7 @@ tolerations:
## 테인트 기반 축출
{{< feature-state for_k8s_version="1.18" state="stable" >}}
{{< feature-state for_k8s_version="v1.18" state="stable" >}}
앞에서 우리는 노드에서 이미 실행 중인 파드에 영향을 주는 `NoExecute` 테인트 이펙트를
다음과 같이 언급했다.

View File

@ -78,7 +78,7 @@ _선언_ 하거나 지정할 수 있게 해주며 쿠버네티스 오브젝트
- 클라이언트는 "이 작업을 수행한다"라고 말하고 완료되면 동기(synchronous) 응답을 받는다.
- 클라이언트는 "이 작업을 수행한다"라고 말한 다음 작업 ID를 다시 가져오고 별도의 오퍼레이션(operation) 오브젝트를 확인하여 요청의 완료 여부를 결정해야 한다.
- RPC(원격 프로시저 호출)에 대해 얘기한다.
- 대량의 데이터를 직접 저장한다(예: > 오브젝트별 몇 kB 또는 >1000개의 오브젝트).
- 대량의 데이터를 직접 저장한다. 예: > 오브젝트별 몇 kB 또는 > 1000개의 오브젝트.
- 높은 대역폭 접근(초당 10개의 지속적인 요청)이 필요하다.
- 최종 사용자 데이터(예: 이미지, PII 등) 또는 애플리케이션에서 처리한 기타 대규모 데이터를 저장한다.
- 오브젝트에 대한 자연스러운 조작은 CRUD-y가 아니다.
@ -102,7 +102,7 @@ _선언_ 하거나 지정할 수 있게 해주며 쿠버네티스 오브젝트
다음 중 대부분이 적용되는 경우 커스텀 리소스(CRD 또는 애그리게이트 API(aggregated API))를 사용하자.
* 쿠버네티스 클라이언트 라이브러리 및 CLI를 사용하여 새 리소스를 만들고 업데이트하려고 한다.
* kubectl의 최상위 지원을 원한다(예: `kubectl get my-object object-name`).
* `kubectl` 의 최상위 지원을 원한다. 예: `kubectl get my-object object-name`.
* 새 오브젝트에 대한 업데이트를 감시한 다음 다른 오브젝트를 CRUD하거나 그 반대로 하는 새로운 자동화를 구축하려고 한다.
* 오브젝트의 업데이트를 처리하는 자동화를 작성하려고 한다.
* `.spec`, `.status``.metadata`와 같은 쿠버네티스 API 규칙을 사용하려고 한다.
@ -214,7 +214,7 @@ CRD 또는 AA를 통해 커스텀 리소스를 생성하면 쿠버네티스 플
### 써드파티 코드 및 새로운 장애 포인트
CRD를 생성해도 새로운 장애 포인트(예를 들어, API 서버에서 장애를 유발하는 써드파티 코드가 실행됨)가 자동으로 추가되지는 않지만, 패키지(예: 차트(Charts)) 또는 기타 설치 번들에는 CRD 및 새로운 커스텀 리소스에 대한 비즈니스 로직을 구현하는 써드파티 코드의 디플로이먼트가 포함되는 경우가 종종 있다.
CRD를 생성해도 새로운 장애 포인트(예를 들어, API 서버에서 장애를 유발하는 써드파티 코드가 실행됨)가 자동으로 추가되지는 않지만, 패키지(예: 차트(Charts)) 또는 기타 설치 번들에는 CRD 및 새로운 커스텀 리소스에 대한 비즈니스 로직을 구현하는 써드파티 코드의 디플로이먼트가 포함되는 경우가 종종 있다.
애그리게이트 API 서버를 설치하려면 항상 새 디플로이먼트를 실행해야 한다.
@ -234,11 +234,11 @@ CRD는 항상 API 서버의 빌트인 리소스와 동일한 인증, 권한 부
## 커스텀 리소스에 접근
쿠버네티스 [클라이언트 라이브러리](/docs/reference/using-api/client-libraries/)를 사용하여 커스텀 리소스에 접근할 수 있다. 모든 클라이언트 라이브러리가 커스텀 리소스를 지원하는 것은 아니다. Go와 python 클라이언트 라이브러리가 지원한다.
쿠버네티스 [클라이언트 라이브러리](/docs/reference/using-api/client-libraries/)를 사용하여 커스텀 리소스에 접근할 수 있다. 모든 클라이언트 라이브러리가 커스텀 리소스를 지원하는 것은 아니다. _Go_ _python_ 클라이언트 라이브러리가 지원한다.
커스텀 리소스를 추가하면 다음을 사용하여 접근할 수 있다.
- kubectl
- `kubectl`
- 쿠버네티스 동적 클라이언트
- 작성한 REST 클라이언트
- [쿠버네티스 클라이언트 생성 도구](https://github.com/kubernetes/code-generator)를 사용하여 생성된 클라이언트(하나를 생성하는 것은 고급 기능이지만, 일부 프로젝트는 CRD 또는 AA와 함께 클라이언트를 제공할 수 있다).

View File

@ -56,18 +56,19 @@ card:
### cloud-controller-manager
[cloud-controller-manager](/docs/tasks/administer-cluster/running-cloud-controller/)는 바탕을 이루는 클라우드 제공사업자와 상호작용하는 컨트롤러를 작동시킨다. cloud-controller-manager 바이너리는 쿠버네티스 릴리스 1.6에서 도입된 알파 기능이다.
cloud-controller-manager는 클라우드 제공자 전용 컨트롤러만 실행한다.
자신의 사내 또는 PC 내부의 학습 환경에서 쿠버네티스를 실행 중인 경우
클러스터에는 클라우드 컨트롤러 매니저가 없다.
cloud-controller-manager는 클라우드-제공사업자-특유 컨트롤러 루프만을 동작시킨다. 이 컨트롤러 루프는 kube-controller-manager에서 비활성 시켜야만 한다. kube-controller-manager를 구동시킬 때 `--cloud-provider` 플래그를 `external`로 설정함으로써 이 컨트롤러 루프를 비활성 시킬 수 있다.
kube-controller-manager와 마찬가지로 cloud-controller-manager는 논리적으로
독립적인 여러 컨트롤 루프를 단일 프로세스로 실행하는 단일 바이너리로 결합한다.
수평으로 확장(두 개 이상의 복제 실행)해서 성능을 향상시키거나 장애를 견딜 수 있다.
cloud-controller-manager는 클라우드 벤더 코드와 쿠버네티스 코드가 서로 독립적으로 발전시켜 나갈 수 있도록 해준다. 이전 릴리스에서는 코어 쿠버네티스 코드가 기능상으로 클라우드-제공사업자-특유 코드에 대해 의존적이었다. 향후 릴리스에서 클라우드 벤더만의 코드는 클라우드 벤더가 유지해야 하며, 쿠버네티스가 동작하는 동안 cloud-controller-manager에 연계되도록 해야 한다.
다음 컨트롤러들은 클라우드 제공 사업자의 의존성을 가질 수 있다.
다음 컨트롤러들은 클라우드 제공사업자의 의존성을 갖는다.
* 노드 컨트롤러: 노드가 응답을 멈춘 후 클라우드 상에서 삭제되었는지 판별하기 위해 클라우드 제공사업자에게 확인하는 것
* 노드 컨트롤러: 노드가 응답을 멈춘 후 클라우드 상에서 삭제되었는지 판별하기 위해 클라우드 제공 사업자에게 확인하는 것
* 라우트 컨트롤러: 기본 클라우드 인프라에 경로를 구성하는 것
* 서비스 컨트롤러: 클라우드 제공사업자 로드밸런서를 생성, 업데이트 그리고 삭제하는 것
* 볼륨 컨트롤러: 볼륨의 생성, 연결 그리고 마운트 하는 것과 오케스트레이션하기 위해 클라우드 제공사업자와 상호작용하는 것
* 서비스 컨트롤러: 클라우드 제공 사업자 로드밸런서를 생성, 업데이트 그리고 삭제하는 것
## 노드 컴포넌트
@ -121,6 +122,6 @@ cloud-controller-manager는 클라우드 벤더 코드와 쿠버네티스 코드
{{% capture whatsnext %}}
* [노드](/ko/docs/concepts/architecture/nodes/)에 대해 더 배우기
* [컨트롤러](/ko/docs/concepts/architecture/controller/)에 대해 더 배우기
* [kube-scheduler](/ko/docs/concepts/scheduling/kube-scheduler/)에 대해 더 배우기
* [kube-scheduler](/ko/docs/concepts/scheduling-eviction/kube-scheduler/)에 대해 더 배우기
* etcd의 공식 [문서](https://etcd.io/docs/) 읽기
{{% /capture %}}

View File

@ -32,8 +32,8 @@ card:
원하는 특징(_의도한 상태_)에 대한 설명을
제공해서 설정한다.
`status`는 오브젝트의 _현재 상태_ 를 기술하고, 쿠버네티스
컴포넌트에 의해 제공되고 업데이트 된다. 쿠버네티스
`status` 는 쿠버네티스 시스템과 컴포넌트에 의해 제공되고
업데이트된 오브젝트의 _현재 상태_ 를 설명한다. 쿠버네티스
{{< glossary_tooltip text="컨트롤 플레인" term_id="control-plane" >}}은 모든 오브젝트의
실제 상태를 사용자가 의도한 상태와 일치시키기 위해 끊임없이 그리고
능동적으로 관리한다.
@ -93,4 +93,3 @@ deployment.apps/nginx-deployment created
* [파드(Pod)](/ko/docs/concepts/workloads/pods/pod-overview/)와 같이, 가장 중요하고 기본적인 쿠버네티스 오브젝트에 대해 배운다.
* 쿠버네티스의 [컨트롤러](/ko/docs/concepts/architecture/controller/)에 대해 배운다.
{{% /capture %}}

View File

@ -7,7 +7,7 @@ weight: 10
{{% capture overview %}}
기본적으로 컨테이너는 쿠버네티스 클러스터에서 무제한 [컴퓨팅 리소스](/docs/user-guide/compute-resources)로 실행된다.
리소스 쿼터을 사용하면 클러스터 관리자는 네임스페이스별로 리소스 사용과 생성을 제한할 수 있다.
리소스 쿼터을 사용하면 클러스터 관리자는 {{< glossary_tooltip text="네임스페이스" term_id="namespace" >}}별로 리소스 사용과 생성을 제한할 수 있다.
네임스페이스 내에서 파드나 컨테이너는 네임스페이스의 리소스 쿼터에 정의된 만큼의 CPU와 메모리를 사용할 수 있다. 하나의 파드 또는 컨테이너가 사용 가능한 모든 리소스를 독점할 수 있다는 우려가 있다. 리밋레인지는 네임스페이스에서 리소스 할당(파드 또는 컨테이너)을 제한하는 정책이다.
{{% /capture %}}
@ -30,16 +30,16 @@ _리밋레인지_ 는 다음과 같은 제약 조건을 제공한다.
리밋레인지 오브젝트의 이름은 유효한 [DNS 서브도메인 이름](/ko/docs/concepts/overview/working-with-objects/names/#dns-서브도메인-이름)이어야한다.
### 범위 제한의 개요
### 리밋 레인지 개요
- 관리자는 하나의 네임스페이스에 하나의 `LimitRange`를 만든다.
- 관리자는 하나의 네임스페이스에 하나의 리밋레인지를 만든다.
- 사용자는 네임스페이스에서 파드, 컨테이너 및 퍼시스턴트볼륨클레임과 같은 리소스를 생성한다.
- `LimitRanger` 어드미션 컨트롤러는 컴퓨팅 리소스 요청 사항을 설정하지 않은 모든 파드와 컨테이너에 대한 기본값과 제한을 지정하고 네임스페이스의 리밋레인지에 정의된 리소스의 최소, 최대 및 비율을 초과하지 않도록 사용량을 추적한다.
- 리밋레인지 제약 조건을 위반하는 리소스(파드, 컨테이너, 퍼시스턴트볼륨클레임)를 생성하거나 업데이트하는 경우 HTTP 상태 코드 `403 FORBIDDEN` 및 위반된 제약 조건을 설명하는 메시지와 함께 API 서버에 대한 요청이 실패한다.
- `cpu`, `memory`와 같은 컴퓨팅 리소스의 네임스페이스에서 리밋레인지가 활성화된 경우 사용자는 해당 값에 대한 요청 또는 제한을 지정해야 한다. 그렇지 않으면 시스템에서 파드 생성이 거부될 수 있다.
- 리밋레인지 유효성 검사는 파드 실행 단계가 아닌 파드 어드미션 단계에서만 발생한다.
범위 제한을 사용하여 생성할 수 있는 정책의 예는 다음과 같다.
리밋 레인지를 사용하여 생성할 수 있는 정책의 예는 다음과 같다.
- 용량이 8GiB RAM과 16 코어인 2 노드 클러스터에서 네임스페이스의 파드를 제한하여 CPU의 최대 제한이 500m인 CPU 100m를 요청하고 메모리의 최대 제한이 600M인 메모리 200Mi를 요청하라.
- 스펙에 CPU 및 메모리 요청없이 시작된 컨테이너에 대해 기본 CPU 제한 및 요청을 150m로, 메모리 기본 요청을 300Mi로 정의하라.
@ -49,19 +49,20 @@ _리밋레인지_ 는 다음과 같은 제약 조건을 제공한다.
경합이나 리밋레인지 변경은 이미 생성된 리소스에 영향을 미치지 않는다.
## 예제
- [네임스페이스당 최소 및 최대 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 %}}
{{% capture whatsnext %}}
보다 자세한 내용은 [LimitRanger 설계 문서](https://git.k8s.io/community/contributors/design-proposals/resource-management/admission_control_limit_range.md)를 참고하길 바란다.
자세한 내용은 [LimitRanger 디자인 문서](https://git.k8s.io/community/contributors/design-proposals/resource-management/admission_control_limit_range.md)를 참조한다.
제한의 사용에 대한 예시는 다음을 참조한다.
- [네임스페이스당 최소 및 최대 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

@ -193,7 +193,7 @@ GPU 리소스를 다음과 같이 쿼터를 정의할 수 있다.
### PriorityClass별 리소스 쿼터
{{< feature-state for_k8s_version="1.12" state="beta" >}}
{{< feature-state for_k8s_version="v1.12" state="beta" >}}
특정 [우선 순위](/docs/concepts/configuration/pod-priority-preemption/#pod-priority)로 파드를 생성할 수 있다.
쿼터 스펙의 `scopeSelector` 필드를 사용하여 파드의 우선 순위에 따라 파드의 시스템 리소스 사용을

View File

@ -0,0 +1,4 @@
---
title: "스케줄링과 축출(eviction)"
weight: 90
---

View File

@ -1,5 +0,0 @@
---
title: "스케줄링"
weight: 90
---

View File

@ -140,8 +140,8 @@ RBAC 인증(쿠버네티스 API에 대한 접근) | https://kubernetes.io/docs/r
TLS를 통한 접근 | 코드가 TCP를 통해 통신해야 한다면, 클라이언트와 먼저 TLS 핸드 셰이크를 수행하는 것이 이상적이다. 몇 가지 경우를 제외하고, 기본 동작은 전송 중인 모든 것을 암호화하는 것이다. 한걸음 더 나아가, VPC의 "방화벽 뒤"에서도 서비스 간 네트워크 트래픽을 암호화하는 것이 좋다. 이것은 인증서를 가지고 있는 두 서비스의 양방향 검증을 [mTLS](https://en.wikipedia.org/wiki/Mutual_authentication)를 통해 수행할 수 있다. 이것을 수행하기 위해 쿠버네티스에는 [Linkerd](https://linkerd.io/) 및 [Istio](https://istio.io/)와 같은 수많은 도구가 있다. |
통신 포트 범위 제한 | 이 권장사항은 당연할 수도 있지만, 가능하면 통신이나 메트릭 수집에 꼭 필요한 서비스의 포트만 노출시켜야 한다. |
타사 종속성 보안 | 애플리케이션은 자체 코드베이스의 외부에 종속적인 경향이 있기 때문에, 코드의 종속성을 정기적으로 스캔하여 현재 알려진 취약점이 없는지 확인하는 것이 좋다. 각 언어에는 이런 검사를 자동으로 수행하는 도구를 가지고 있다. |
정적 코드 분석 | 대부분 언어에는 잠재적으로 안전하지 않은 코딩 방법에 대해 코드 스니펫을 분석할 수 있는 방법을 제공한다. 가능한 언제든지 일반적인 보안 오류에 대해 코드베이스를 스캔할 수 있는 자동화된 도구를 사용하여 검사를 한다. 도구는 다음에서 찾을 수 있다: https://www.owasp.org/index.php/Source_Code_Analysis_Tools |
동적 탐지 공격 | 일반적으로 서비스에서 발생할 수 있는 잘 알려진 공격 중 일부를 서비스에 테스트할 수 있는 자동화된 몇 가지 도구가 있다. 이런 잘 알려진 공격에는 SQL 인젝션, CSRF 및 XSS가 포함된다. 가장 널리 사용되는 동적 분석 도구는 OWASP Zed Attack 프록시다. https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project |
정적 코드 분석 | 대부분 언어에는 잠재적으로 안전하지 않은 코딩 방법에 대해 코드 스니펫을 분석할 수 있는 방법을 제공한다. 가능한 언제든지 일반적인 보안 오류에 대해 코드베이스를 스캔할 수 있는 자동화된 도구를 사용하여 검사를 한다. 도구는 다음에서 찾을 수 있다. https://owasp.org/www-community/Source_Code_Analysis_Tools |
동적 탐지 공격 | 일반적으로 서비스에서 발생할 수 있는 잘 알려진 공격 중 일부를 서비스에 테스트할 수 있는 자동화된 몇 가지 도구가 있다. 이런 잘 알려진 공격에는 SQL 인젝션, CSRF 및 XSS가 포함된다. 가장 널리 사용되는 동적 분석 도구는 OWASP Zed Attack 프록시다. https://owasp.org/www-project-zap/ |
## 강력한(robust) 자동화

View File

@ -164,7 +164,7 @@ DNS 정책은 파드별로 설정할 수 있다. 현재 쿠버네티스는 다
일치하지 않는 DNS 쿼리는 노드에서 상속된 업스트림 네임서버로 전달된다.
클러스터 관리자는 추가 스텁-도메인(stub-domain)과 업스트림 DNS 서버를 구축할 수 있다.
그러한 경우 DNS 쿼리를 어떻게 처리하는지에 대한 자세한 내용은
[관련 논의](/docs/tasks/administer-cluster/dns-custom-nameservers/#impacts-on-pods)
[관련 논의](/docs/tasks/administer-cluster/dns-custom-nameservers/#effects-on-pods)
에서 확인할 수 있다.
- "`ClusterFirstWithHostNet`": hostNetwork에서 running 상태인 파드의 경우 DNS 정책인
"`ClusterFirstWithHostNet`"을 명시적으로 설정해야 한다.

View File

@ -652,6 +652,16 @@ metadata:
[...]
```
{{% /tab %}}
{{% tab name="IBM Cloud" %}}
```yaml
[...]
metadata:
name: my-service
annotations:
service.kubernetes.io/ibm-load-balancer-cloud-provider-ip-type: "private"
[...]
```
{{% /tab %}}
{{% tab name="OpenStack" %}}
```yaml
[...]

View File

@ -296,12 +296,13 @@ parameters:
`replication-type``regional-pd` 로 설정되면,
[지역 퍼시스턴트 디스크](https://cloud.google.com/compute/docs/disks/#repds)
가 프로비전된다. 이 경우, 사용자는 `zone` 대신 `zones` 를 사용해서 원하는
복제 영역을 지정해야 한다. 정확히 두 개의 영역이 지정된 경우, 해당
영역에서 지역 PD가 프로비전된다. 둘 이상의 영역이 지정되면
쿠버네티스는 지정된 영역 중에서 임의로 선택한다. `zones` 파라미터가 생략되면,
쿠버네티스는 클러스터가 관리하는 영역 중에서
임의로 선택한다.
가 프로비전된다. 이는 퍼시스턴트볼륨클레임과 스토리지클래스를 소모하는 파드를
생성할 때 지역 퍼시스턴트 디스크는 두개의 영역으로
프로비전되기에 `volumeBindingMode: WaitForFirstConsumer`
설정하는 것을 강력히 권장한다. 하나의 영역은 파드가 스케줄된
영역과 동일하다. 다른 영역은 클러스터에서 사용할 수
있는 영역에서 임의로 선택된다. 디스크 영역은 `allowedTopologies`
사용하면 더 제한할 수 있다.
{{< note >}}
`zone``zones` 파라미터는 사용 중단 되었으며,

View File

@ -6,7 +6,7 @@ weight: 20
{{% capture overview %}}
{{< feature-state for_k8s_version="1.17" state="beta" >}}
{{< feature-state for_k8s_version="v1.17" state="beta" >}}
쿠버네티스에서 스토리지 시스템 볼륨 스냅샷은 _VolumeSnapshot_ 을 나타낸다. 이 문서는 이미 쿠버네티스 [퍼시스턴트 볼륨](/docs/concepts/storage/persistent-volumes/)에 대해 잘 알고 있다고 가정한다.
{{% /capture %}}
@ -55,7 +55,9 @@ API 리소스 `PersistentVolume` 및 `PersistentVolumeClaim` 가 사용자 및
### 스냅샷 소스 보호로서의 퍼시스턴트 볼륨 클레임
이 보호의 목적은 스냅샷이 생성되는 동안 사용 중인 퍼시스턴트볼륨클레임 API 오브젝트가 시스템에서 지워지지 않게 하는 것이다(데이터 손실이 발생할 수 있기 때문에).
이 보호의 목적은 스냅샷이 생성되는 동안 사용 중인
{{< glossary_tooltip text="퍼시스턴트볼륨클레임" term_id="persistent-volume-claim" >}}
API 오브젝트가 시스템에서 지워지지 않게 하는 것이다(데이터 손실이 발생할 수 있기 때문에).
퍼시스턴트볼륨클레임이 스냅샷을 생성할 동안에는 해당 퍼시스턴트볼륨클레임은 사용중인 상태이다. 스냅샷 소스로 사용 중인 퍼시스턴트볼륨클레임 API 객체를 삭제한다면, 퍼시스턴트볼륨클레임 객체는 즉시 삭제되지 않는다. 대신, 퍼시스턴트볼륨클레임 객체 삭제는 스냅샷이 준비(readyTouse) 혹은 중단(aborted) 상태가 될 때까지 연기된다.

View File

@ -9,7 +9,7 @@ weight: 10
컨테이너 내의 디스크에 있는 파일은 임시적이며, 컨테이너에서 실행될 때
애플리케이션에 적지 않은 몇 가지 문제가 발생한다. 첫째, 컨테이너가 충돌되면,
kubelet은 컨테이너를 재시작시키지만, 컨테이너는 깨끗한 상태로
시작되기 때문에 기존 파일이 유실된다. 둘째, `파드` 에서 컨테이너를 함께 실행할 때
시작되기 때문에 기존 파일이 유실된다. 둘째, `파드` 에서 컨테이너를 함께 실행할 때
컨테이너 사이에 파일을 공유해야 하는 경우가 자주 발생한다. 쿠버네티스의
`볼륨` 추상화는 이 두 가지 문제를 모두 해결한다.
@ -22,7 +22,7 @@ kubelet은 컨테이너를 재시작시키지만, 컨테이너는 깨끗한 상
## 배경
도커는 다소 느슨하고, 덜 관리되지만
도커는 다소 느슨하고, 덜 관리되지만
[볼륨](https://docs.docker.com/engine/admin/volumes/)이라는
개념을 가지고 있다. 도커에서 볼륨은 단순한 디스크 내 디렉터리 또는
다른 컨테이너에 있는 디렉터리다. 수명은 관리되지 않으며 최근까지는
@ -70,7 +70,7 @@ kubelet은 컨테이너를 재시작시키지만, 컨테이너는 깨끗한 상
* [csi](#csi)
* [downwardAPI](#downwardapi)
* [emptyDir](#emptydir)
* [fc (파이버 채널))](#fc)
* [fc (파이버 채널)](#fc)
* [flexVolume](#flexVolume)
* [flocker](#flocker)
* [gcePersistentDisk](#gcepersistentdisk)
@ -496,7 +496,7 @@ gitRepo 볼륨 유형은 사용 중단(deprecated)되었다. git repo가 있는
`gitRepo` 볼륨은 볼륨 플러그인으로 할 수 있는 예시이다. 빈
디렉터리를 마운트하고 파드가 사용할 수 있도록 해당 디렉터리에 git 리포지트리를
복제한다. 미래에는 모든 이용 사례에 대해 쿠버네티스 API를 확장하는 대신에
복제한다. 미래에는 모든 이용 사례에 대해 쿠버네티스 API를 확장하는 대신에
이런 볼륨은 훨씬 더 분리된 모델로 이동될 수 있다.
여기 gitRepo 볼륨의 예시가 있다.
@ -1031,7 +1031,7 @@ tmpfs(RAM 기반 파일시스템)로 지원되기 때문에 비 휘발성 스토
### storageOS {#storageos}
`storageos` 볼륨을 사용하면 기존 [StorageOS](https://www.storageos.com)
`storageos` 볼륨을 사용하면 기존 [StorageOS](https://www.storageos.com)
볼륨을 파드에 마운트할 수 있다.
StorageOS 는 쿠버네티스 환경에서 컨테이너로 실행되므로

View File

@ -8,13 +8,17 @@ weight: 80
{{< feature-state for_k8s_version="v1.8" state="beta" >}}
_크론 잡은_ 시간 기반의 일정에 따라 [](/ko/docs/concepts/workloads/controllers/jobs-run-to-completion/)을 만든다.
_크론잡은_ 반복 일정에 따라 {{< glossary_tooltip term_id="job" text="잡" >}}을 만든다.
하나의 크론잡 객체는 _크론탭_ (크론 테이블) 파일의 한 줄과 같다. 크론잡은 잡을 [크론](https://en.wikipedia.org/wiki/Cron)형식으로 쓰여진 주어진 일정에 따라 주기적으로 동작시킨다.
{{< caution >}}
모든 **크론잡** `일정:` 시간은 UTC로 표시된다.
모든 **크론잡** `일정:` 시간은
{{< glossary_tooltip term_id="kube-controller-manager" text="kube-controller-manager" >}}의 시간대를 기준으로 한다.
컨트롤 플레인이 파드 또는 베어 컨테이너에서 kube-controller-manager를 실행하는 경우,
kube-controller-manager 컨테이너에 설정된 시간대는 크론잡 컨트롤러가 사용하는 시간대로 결정한다.
{{< /caution >}}
크론잡 리소스에 대한 매니페스트를 생성할때에는 제공하는 이름이
@ -23,14 +27,26 @@ _크론 잡은_ 시간 기반의 일정에 따라 [잡](/ko/docs/concepts/worklo
11자를 자동으로 추가하고, 작업 이름의 최대 길이는
63자라는 제약 조건이 있기 때문이다.
크론 잡을 생성하고 작동하는 방법은 크론 잡의 스펙 파일을 확안한다. 내용은 [크론 잡으로 자동 작업 실행하기](/docs/tasks/job/automated-tasks-with-cron-jobs)를 참조한다.
{{% /capture %}}
{{% capture body %}}
## 크론 잡의 한계
## 크론잡
크론잡은 백업 실행 또는 이메일 전송과 같은 정기적이고 반복적인
작업을 만드는데 유용하다. 또한 크론잡은 클러스터가 유휴 상태일 때 잡을
스케줄링하는 것과 같이 특정 시간 동안의 개별 작업을 스케줄할 수 있다.
### 예제
이 크론잡 매니페스트 예제는 현재 시간과 hello 메시지를 1분마다 출력한다.
{{< codenew file="application/job/cronjob.yaml" >}}
([크론잡으로 자동화된 작업 실행하기](/docs/tasks/job/automated-tasks-with-cron-jobs/)는
이 예시를 더 자세히 설명한다.)
## 크론 잡의 한계 {#cron-job-limitations}
크론 잡은 일정의 실행시간 마다 _약_ 한 번의 잡을 생성한다. "약" 이라고 하는 이유는
특정 환경에서는 두 개의 잡이 만들어지거나, 잡이 생성되지 않기도 하기 때문이다. 보통 이렇게 하지
@ -62,3 +78,11 @@ Cannot determine if job needs to be started. Too many missed start time (> 100).
잡은 그 잡이 대표하는 파드 관리에 책임이 있다.
{{% /capture %}}
{{% capture whatsnext %}}
[크론 표현 포맷](https://pkg.go.dev/github.com/robfig/cron?tab=doc#hdr-CRON_Expression_Format)은
크론잡 `schedule` 필드의 포맷을 문서화 한다.
크론 잡 생성과 작업에 대한 지침과 크론잡 매니페스트의
예는 [크론 잡으로 자동화된 작업 실행하기](/docs/tasks/job/automated-tasks-with-cron-jobs/)를 참조한다.
{{% /capture %}}

View File

@ -46,24 +46,24 @@ _디플로이먼트_ 는 [파드](/ko/docs/concepts/workloads/pods/pod/)와
이 예시에 대한 설명은 다음과 같다.
* `.metadata.name` 필드에 따라 `nginx-deployment` 이름으로 디플로이먼트가 생성된다.
* `replicas` 필드에 따라 디플로이먼트는 3개의 레플리카 파드를 생성한다.
* `selector` 필드는 디플로이먼트가 관리할 파드를 찾는 방법을 정의한다.
* `.spec.replicas` 필드에 따라 디플로이먼트는 3개의 레플리카 파드를 생성한다.
* `.spec.selector` 필드는 디플로이먼트가 관리할 파드를 찾는 방법을 정의한다.
이 사례에서는 간단하게 파드 템플릿에 정의된 레이블(`app: nginx`)을 선택한다.
그러나 파드 템플릿 자체의 규칙이 만족되는 한,
보다 정교한 선택 규칙의 적용이 가능하다.
{{< note >}}
`matchLabels` 필드는 {key,value}의 쌍으로 매핑되어있다. `matchLabels` 에 매핑된
`.spec.selector.matchLabels` 필드는 {key,value}의 쌍으로 매핑되어있다. `matchLabels` 에 매핑된
단일 {key,value}은 `matchExpressions` 의 요소에 해당하며, 키 필드는 "key"에 그리고 연산자는 "In"에 대응되며
값 배열은 "value"만 포함한다.
매칭을 위해서는 `matchLabels``matchExpressions` 의 모든 요건이 충족되어야 한다.
{{< /note >}}
* `template` 필드에는 다음 하위 필드가 포함되어있다.
* 파드는 `labels` 필드를 사용해서 `app: nginx` 라는 레이블을 붙인다.
* 파드는 `.metadata.labels` 필드를 사용해서 `app: nginx` 라는 레이블을 붙인다.
* 파드 템플릿의 사양 또는 `.template.spec` 필드는
파드가 [도커 허브](https://hub.docker.com/)의 `nginx` 1.14.2 버전 이미지를 실행하는
`nginx` 컨테이너 1개를 실행하는 것을 나타낸다.
* 컨테이너 1개를 생성하고, `name` 필드를 사용해서 `nginx` 이름을 붙인다.
* 컨테이너 1개를 생성하고, `.spec.template.spec.containers[0].name` 필드를 사용해서 `nginx` 이름을 붙인다.
위의 디플로이먼트를 생성하려면 다음 단계를 따른다.
@ -87,9 +87,8 @@ _디플로이먼트_ 는 [파드](/ko/docs/concepts/workloads/pods/pod/)와
```
클러스터에서 디플로이먼트를 점검할 때 다음 필드가 표시된다.
* `NAME` 은 클러스터에 있는 디플로이먼트 이름의 목록이다.
* `DESIRED` 는 디플로이먼트의 생성시 정의된 의도한 애플리케이션 _레플리카_ 의 수를 표시한다. 이것이 _의도한 상태_ 이다.
* `CURRENT` 는 현재 실행 중인 레플리카의 수를 표시한다.
* `NAME` 은 네임스페이스에 있는 디플로이먼트 이름의 목록이다.
* `READY` 는 사용자가 사용할 수 있는 애플리케이션의 레플리카의 수를 표시한다. ready/desired 패턴을 따른다.
* `UP-TO-DATE` 는 의도한 상태를 얻기위해 업데이트 된 레플리카의 수를 표시한다.
* `AVAILABLE` 은 사용자가 사용 가능한 애플리케이션 레플리카의 수를 표시한다.
* `AGE` 는 애플리케이션의 실행 된 시간을 표시한다.
@ -114,8 +113,16 @@ _디플로이먼트_ 는 [파드](/ko/docs/concepts/workloads/pods/pod/)와
NAME DESIRED CURRENT READY AGE
nginx-deployment-75675f5897 3 3 3 18s
```
레플리카셋의 출력에는 다음 필드가 표시된다.
* `NAME` 은 네임스페이스에 있는 레플리카셋 이름의 목록이다.
* `DESIRED` 는 디플로이먼트의 생성 시 정의된 의도한 애플리케이션 _레플리카_ 의 수를 표시한다. 이것이 _의도한 상태_ 이다.
* `CURRENT` 는 현재 실행 중인 레플리카의 수를 표시한다.
* `READY` 는 사용자가 사용할 수 있는 애플리케이션의 레플리카의 수를 표시한다.
* `AGE` 는 애플리케이션의 실행된 시간을 표시한다.
레플리카셋의 이름은 항상 `[DEPLOYMENT-NAME]-[RANDOM-STRING]` 형식으로 된 것을 알 수 있다. 무작위 문자열은
무작위로 생성되며, Pod-template-hash를 시드(seed)로 사용한다.
무작위로 생성되며, `pod-template-hash` 를 시드(seed)로 사용한다.
6. 각 파드에 자동으로 생성된 레이블을 보려면 `kubectl get pods --show-labels` 를 실행한다. 다음과 유사하게 출력된다.
```shell
@ -508,7 +515,7 @@ API 버전 `apps/v1` 에서 디플로이먼트의 레이블 셀렉터는 생성
이와 유사하게 출력된다.
```
deployment.apps/nginx-deployment
deployment.apps/nginx-deployment rolled back
```
Alternatively, you can rollback to a specific revision by specifying it with `--to-revision`:
@ -518,7 +525,7 @@ API 버전 `apps/v1` 에서 디플로이먼트의 레이블 셀렉터는 생성
이와 유사하게 출력된다.
```
deployment.apps/nginx-deployment
deployment.apps/nginx-deployment rolled back
```
롤아웃 관련 명령에 대한 자세한 내용은 [`kubectl rollout`](/docs/reference/generated/kubectl/kubectl-commands#rollout)을 참조한다.
@ -1015,7 +1022,7 @@ $ echo $?
## 디플로이먼트 사양 작성
다른 모든 쿠버네티스 설정과 마찬가지로 디플로이먼트에는 `apiVersion`, `kind` 그리고 `metadata` 필드가 필요하다.
다른 모든 쿠버네티스 설정과 마찬가지로 디플로이먼트에는 `.apiVersion`, `.kind` 그리고 `.metadata` 필드가 필요하다.
설정 파일 작업에 대한 일반적인 내용은 [애플리케이션 배포하기](/docs/tutorials/stateless-application/run-stateless-application-deployment/),
컨테이너 구성하기 그리고 [kubectl을 사용해서 리소스 관리하기](/ko/docs/concepts/overview/working-with-objects/object-management/) 문서를 참조한다.
디플로이먼트 오브젝트의 이름은 유효한

View File

@ -147,7 +147,7 @@ N개의 레플리카가 있는 스테이트풀셋은 스테이트풀셋에 있
kube.local | foo/nginx | foo/web | nginx.foo.svc.kube.local | web-{0..N-1}.nginx.foo.svc.kube.local | web-{0..N-1} |
{{< note >}}
클러스터 도메인이 달리 [구성된 경우](/ko/docs/concepts/services-networking/dns-pod-service/#how-it-works)가
클러스터 도메인이 달리 [구성된 경우](/ko/docs/concepts/services-networking/dns-pod-service/)가
아니라면 `cluster.local`로 설정된다.
{{< /note >}}

View File

@ -181,7 +181,7 @@ kubelet은 실행 중인 컨테이너들에 대해서 선택적으로 세 가지
...
State: Waiting
Reason: ErrImagePull
...
...
```
* `Running`: 컨테이너가 이슈 없이 구동된다는 뜻이다. `postStart` 훅(있는 경우)은 컨테이너가 Running 상태가 되기 전에 실행된다. 이 상태는 컨테이너가 언제 Running 상태에 돌입한 시간도 함께 출력된다.
@ -206,31 +206,34 @@ kubelet은 실행 중인 컨테이너들에 대해서 선택적으로 세 가지
...
```
## 파드의 준비성 게이트(readiness gate)
## 파드의 준비성(readiness) {#pod-readiness-gate}
{{< feature-state for_k8s_version="v1.14" state="stable" >}}
파드의 준비성에 대한 확장성을 추가하기 위해서
추가적인 피드백이나 신호를 `PodStatus`에 주입하는 방법인,
[파드 준비++](https://github.com/kubernetes/enhancements/blob/master/keps/sig-network/0007-pod-ready%2B%2B.md)라는 특징이 쿠버네티스 1.11에서 소개되었다.
파드의 준비성을 평가하기 위한 추가적인 조건들을 `PodSpec` 내의 새로운 `ReadinessGate` 필드를
통해서 지정할 수 있다. 만약 쿠버네티스가 `status.conditions` 필드에서 해당하는
애플리케이션은 추가 피드백 또는 신호를 PodStatus: _Pod readiness_
와 같이 주입할 수 있다. 이를 사용하기 위해, 파드의 준비성을 평가하기
위한 추가적인 조건들을 `PodSpec` 내의 `ReadinessGate` 필드를 통해서 지정할 수 있다.
준비성 게이트는 파드에 대한 `status.condition` 필드의 현재
상태에 따라 결정된다. 만약 쿠버네티스가 `status.conditions` 필드에서 해당하는
조건을 찾지 못한다면, 그 조건의 상태는
기본 값인 "`False`"가 된다. 아래는 한 예제를 보여준다.
여기 예제가 있다.
```yaml
Kind: Pod
kind: Pod
...
spec:
readinessGates:
- conditionType: "www.example.com/feature-1"
status:
conditions:
- type: Ready # 이것은 내장된 PodCondition이다
- type: Ready # 내장된 PodCondition이다
status: "False"
lastProbeTime: null
lastTransitionTime: 2018-01-01T00:00:00Z
- type: "www.example.com/feature-1" # 추가적인 PodCondition
- type: "www.example.com/feature-1" # 추가적인 PodCondition
status: "False"
lastProbeTime: null
lastTransitionTime: 2018-01-01T00:00:00Z
@ -240,19 +243,23 @@ status:
...
```
파드의 새로운 조건들은
쿠버네티스의 [레이블 키 포멧](/ko/docs/concepts/overview/working-with-objects/labels/#구문과-캐릭터-셋)을 준수해야 한다.
`kubectl patch` 명령어가 오브젝트 상태 패치(patching)를 아직 제공하지 않기 때문에,
새로운 파드 조건들은 [KubeClient 라이브러리](/ko/docs/reference/using-api/client-libraries/)를 통한 `PATCH` 액션을 통해서 주입되어야 한다.
추가하는 파드 상태에는 쿠버네티스 [레이블 키 포맷](/ko/docs/concepts/overview/working-with-objects/labels/#구문과-캐릭터-셋)을 충족하는 이름이 있어야 한다.
새로운 파드 조건들이 적용된 경우, 파드는 **오직**
다음 두 문장이 모두 참일 때만 준비 상태로 평가된다.
### 파드 준비성 상태 {#pod-readiness-status}
`kubectl patch` 명령어는 아직 오브젝트 상태 패치(patching)를 지원하지 않는다.
이러한 `status.conditions` 을 파드에 설정하려면 애플리케이션과
{{< glossary_tooltip term_id="operator-pattern" text="오퍼레이터">}}의
`PATCH` 액션을 필요로 한다.
[쿠버네티스 클라이언트 라이브러리](/ko/docs/reference/using-api/client-libraries/)를
사용해서 파드 준비성에 대한 사용자 지정 파드 조건을 설정하는 코드를 작성할 수 있다.
사용자 지정 조건을 사용하는 파드의 경우, 다음 두 조건이 모두 적용되는
경우에 **만** 해당 파드가 준비된 것으로 평가된다.
* 파드 내의 모든 컨테이너들이 준비 상태이다.
* `ReadinessGates`에 지정된 모든 조건들이 "`True`"이다.
파드 준비성 평가에 대한 변경을 촉진하기 위해서,
이전 파드 조건인 `Ready`를 포착하기 위한 새로운 파드 조건 `ContainersReady`가 소개되었다.
* `ReadinessGates`에 지정된 모든 조건들이 `True` 이다.
## 재시작 정책
@ -269,32 +276,31 @@ kubelet에 의해서 재시작되는 종료된 컨테이너는
## 파드의 일생(lifetime)
일반적으로, 파드는 사람 혹은 컨트롤러의 프로세스가 명시적으로 파드를 삭제할 때까지 남아 있다.
일반적으로, 파드는 사람 혹은
{{< glossary_tooltip term_id="controller" text="컨트롤러" >}}의
프로세스가 명시적으로 파드를 삭제할 때까지 남아 있다.
컨트롤 플레인은 파드의 수가 설정된 임계치(kube-controller-manager에서
`terminated-pod-gc-threshold`에 의해 결정)를 초과할 때,
종료된 파드들(`Succeeded` 또는 `Failed` 단계)을 정리한다.
이로써 시간이 지남에 따라 파드들이 생성 및 종료되며 발생하는 리소스 누수를 피할 수 있다.
세 가지 유형의 컨트롤러를 사용할 수 있다.
파드에는 다음과 같은 다양한 종류의 리소스가 있다.
- 배치 연산과 같이, 종료가 예상되는 파드를 위해서는 [](/docs/concepts/jobs/run-to-completion-finite-workloads/)을
- 예를 들어 웹 서버와 같이 종료되지 않을 것으로 예상되는 파드용
{{< glossary_tooltip term_id="deployment" >}}, {{< glossary_tooltip term_id="replica-set" >}} 또는
{{< glossary_tooltip term_id="statefulset" >}}을 사용한다.
- 배치 연산과 같이, 종료가 예상되는 파드를 위해서는
{{< glossary_tooltip term_id="job" >}}을
사용하길 바란다. 잡은 `restartPolicy`가 실패 시(OnFailure) 또는 절대 안 함(Never)으로
지정된 경우에 적합하다.
- 웹 서버와 같이, 종료가 예상되지 않는 파드에 대해서는
[레플리케이션 컨트롤러](/ko/docs/concepts/workloads/controllers/replicationcontroller/),
[레플리카 셋](/ko/docs/concepts/workloads/controllers/replicaset/), 또는
[디플로이먼트](/ko/docs/concepts/workloads/controllers/deployment/)를 사용하길 바란다.
레플리케이션 컨트롤러는 `restartPolicy`가 항상(Always)으로 지정된
경우에만 적합하다.
- 적합한 노드 당 하나씩 실행해야 하는 파드에는
{{< glossary_tooltip term_id="daemonset" >}}을 사용한다.
- 머신 당 하나씩 실행해야하는 파드를 위해서는 [데몬 셋](/ko/docs/concepts/workloads/controllers/daemonset/)을 사용하길
바란다. 왜냐하면 데몬 셋은 특정 머신 전용 시스템 서비스(machine-specific system service)를 제공하기 때문이다.
세 가지 모든 컨트롤러 유형은 PodTemplate을 가지고 있다. 파드를
직접적으로 생성하는 것 보다는, 적절한 컨트롤러를 생성하고 컨트롤러가 파드를
생성하도록 하는 것이 추천된다. 그 이유는 파드
혼자서는 머신의 실패에 탄력적(resilient)이지 않지만, 컨트롤러는 탄력적이기 때문이다.
모든 워크로드 리소스에는 파드명세가 포함된다. 사용자가 직접적으로 파드를 생성하는
것보다 적절한 워크로드 리소스를 생성하고 리소스 컨트롤러가
사용자를 위한 파드를 생성하도록 하는 것을 권장한다.
만약 노드가 죽거나 다른 클러스터의 다른 노드들로부터 연결이 끊기면, 쿠버네티스는
잃어버린 노드에 있는 모든 파드의 `phase`를 실패된(Failed)으로 설정하는 정책을 적용한다.
@ -398,4 +404,3 @@ spec:
{{% /capture %}}

View File

@ -15,9 +15,9 @@ card:
{{% capture body %}}
## 파드에 대해 이해하기
*파드* 는 쿠버네티스 애플리케이션의 기본 실행 단위이다. 쿠버네티스 객체 모델 중 만들고 배포할 수 있는 가장 작고 간단한 단위이다. 파드는 {{< glossary_tooltip term_id="cluster" >}} 에서의 Running 프로세스를 나타낸다.
*파드* 는 쿠버네티스 애플리케이션의 기본 실행 단위이다. 쿠버네티스 객체 모델 중 만들고 배포할 수 있는 가장 작고 간단한 단위이다. 파드는 {{< glossary_tooltip term_id="cluster" text="클러스터" >}} 에서의 Running 프로세스를 나타낸다.
파드는 애플리케이션 컨테이너(또는, 몇몇의 경우, 다중 컨테이너), 저장소 리소스, 특정 네트워크 IP 그리고, {{< glossary_tooltip text="container" term_id="container" >}} 가 동작하기 위해 만들어진 옵션들을 캡슐화 한다. 파드는 배포의 단위를 말한다. 아마 단일 컨테이너로 구성되어 있거나, 강하게 결합되어 리소스를 공유하는 소수의 컨테이너로 구성되어 있는 *쿠버네티스에서의 애플리케이션 단일 인스턴스* 를 의미.
파드는 애플리케이션 컨테이너(또는, 몇몇의 경우, 다중 컨테이너), 저장소 리소스, 특정 네트워크 정체성(IP 주소) 및 컨테이너가 동작하기 위해 만들어진 옵션들을 캡슐화 한다. 파드는 배포의 단위를 말한다. 아마 단일 {{< glossary_tooltip text="컨테이너" term_id="container" >}}로 구성되어 있거나, 강하게 결합되어 리소스를 공유하는 소수의 컨테이너로 구성되어 있는 *쿠버네티스에서의 애플리케이션 단일 인스턴스* 를 의미한다.
[도커](https://www.docker.com)는 쿠버네티스 파드에서 사용되는 가장 대표적인 컨테이너 런타임이지만, 파드는 다른 [컨테이너 런타임](/ko/docs/setup/production-environment/container-runtimes/) 역시 지원한다.
@ -26,12 +26,9 @@ card:
* **단일 컨테이너만 동작하는 파드**. "단일 컨테이너 당 한 개의 파드" 모델은 쿠버네티스 사용 사례 중 가장 흔하다. 이 경우, 한 개의 파드가 단일 컨테이너를 감싸고 있다고 생각할 수 있으며, 쿠버네티스는 컨테이너가 아닌 파드를 직접 관리한다고 볼 수 있다.
* **함께 동작하는 작업이 필요한 다중 컨테이너가 동작하는 파드**. 아마 파드는 강하게 결합되어 있고 리소스 공유가 필요한 다중으로 함께 배치된 컨테이너로 구성되어 있을 것이다. 이렇게 함께 배치되어 설치된 컨테이너는 단일 결합 서비스 단위일 것이다. 한 컨테이너는 공유 볼륨에서 퍼블릭으로 파일들을 옮기고, 동시에 분리되어 있는 "사이드카" 컨테이너는 그 파일들을 업데이트 하거나 복구한다. 파드는 이 컨테이너와 저장소 리소스들을 한 개의 관리 가능한 요소로 묶는다.
[쿠버네티스 블로그](https://kubernetes.io/blog)에는 파드 사용 사례의 몇 가지 추가적인 정보가 있다. 더 많은 정보를 위해서 아래 내용을 참조하길 바란다.
* [분산 시스템 툴킷: 복합 컨테이너를 위한 패턴](https://kubernetes.io/blog/2015/06/the-distributed-system-toolkit-patterns)
* [컨테이너 디자인 패턴](https://kubernetes.io/blog/2016/06/container-design-patterns)
각각의 파드는 주어진 애플리케이션에서 단일 인스턴스로 동작을 하는 것을 말한다. 만약 애플리케이션을 수평적으로 스케일하기를 원하면(예를 들면, 다중 인스턴스 동작하는 것), 각 인스턴스 당 한 개씩 다중 파드를 사용해야 한다. 쿠버네티스에서는, 일반적으로 이것을 _복제_ 라고 한다. 복제된 파드는 주로 컨트롤러라고 하는 추상화 개념의 그룹에 의해 만들어지고 관리된다. 더 많은 정보는 [파드와 컨트롤러](#파드와-컨트롤러)를 참고하길 바란다.
각각의 파드는 주어진 애플리케이션에서 단일 인스턴스로 동작하는 것을 말한다. 만약 애플리케이션을 수평적으로 스케일하기를 원하면(더 많은 인스턴스를 실행해서 더 많은 전체 리소스를 제공하는 것), 각 인스턴스 당 한 개씩 다중 파드를 사용해야 한다. 쿠버네티스에서는, 일반적으로 이것을 _복제_ 라고 한다.
복제된 파드는 일반적으로 워크로드 리소스와 해당 {{< glossary_tooltip text="_컨트롤러_" term_id="controller" >}}에 의해 그룹으로 생성과 관리된다.
쿠버네티스가 컨트롤러를 사용해서 워크로드의 확장과 복구를 구현하는 방법에 대한 자세한 내용은 [파드와 컨트롤러](#파드와-컨트롤러)를 참고한다.
## 어떻게 파드가 다중 컨테이너를 관리하는가
@ -47,7 +44,7 @@ card:
#### 네트워킹
각각의 파드는 유한 IP주소를 할당 받는다. 한 파드 내부의 모든 컨테이너는 네트워크 네임스페이스와 IP주소 및 네트워크 포트를 공유한다. *파드 안에 있는* 컨테이너는 다른 컨테이너와 `localhost`를 통해서 통신할 수 있다. 특정 파드 안에 있는 컨테이너가 *파드 밖의* 요소들과 통신하기 위해서는, 네트워크 리소스를 어떻게 쓰고 있는지 공유 해야 한다(예를 들어 포트 등).
각각의 파드는 각 주소 패밀리의 고유한 IP 주소를 할당 받는다. 한 파드 내부의 모든 컨테이너는 네트워크 네임스페이스와 IP주소 및 네트워크 포트를 공유한다. *파드 안에 있는* 컨테이너는 다른 컨테이너와 `localhost` 를 통해서 통신할 수 있다. 특정 파드 안에 있는 컨테이너가 *파드 밖의* 요소들과 통신하기 위해서는, 네트워크 리소스를 어떻게 쓰고 있는지 공유해야 한다(예를 들어 포트 등).
#### 저장소
@ -55,54 +52,63 @@ card:
## 파드 작업
직접 쿠버네티스에서 싱글톤 파드이더라도 개별 파드를 만들일이 거의 없을 것이다. 그 이유는 파드가 상대적으로 수명이 짧고 일시적이기 때문이다. 파드가 만들어지면(직접 만들거나, 컨트롤러에 의해서 간접적으로 만들어지거나), 그것은 클러스터의 {{< glossary_tooltip term_id="node" >}} 에서 동작할 것이다. 파드는 프로세스가 종료되거나, 파드 객체가 삭제되거나, 파드가 리소스의 부족으로 인해 *제거되거나*, 노드에 장애가 생기지 않는 한 노드에 남아있다.
직접 쿠버네티스에서 싱글톤 파드이더라도 개별 파드를 만들 일이 거의 없을 것이다. 그 이유는 파드가 상대적으로 수명이 짧고 일시적이기 때문이다. 파드가 만들어지면(직접 만들거나, {{< glossary_tooltip text="_컨트롤러_" term_id="controller" >}}에 의해서 간접적으로 만들어지거나), 그것은 클러스터의 {{< glossary_tooltip term_id="node" >}}에서 동작할 것이다. 파드는 프로세스가 종료되거나, 파드 오브젝트가 삭제되거나, 파드가 리소스의 부족으로 인해 *축출되거나*, 노드에 장애가 생기지 않는 한 노드에 남아있다.
{{< note >}}
파드 내부에서 재시작되는 컨테이너를 파드와 함께 재시작되는 컨테이너로 혼동해서는 안된다. 파드는 자기 스스로 동작하지 않는다. 하지만 컨테이너 환경은 그것이 삭제될 때까지 계속 동작한다.
파드 내부에서 재시작되는 컨테이너를 파드와 함께 재시작되는 컨테이너로 혼동해서는 안된다. 파드는 프로세스가 아니라, 컨테이너를 실행하는 환경이다. 파드는 삭제될 때까지 유지된다.
{{< /note >}}
파드는 스스로 자신을 치료하지 않는다. 만약 파드가 스케줄링된 노드에 장애가 생기거나, 스케쥴링 동작이 스스로 실패할 경우 파드는 삭제된다. 그와 비슷하게, 파드는 리소스나 노드의 유지 부족으로 인해 제거되는 상황에서 살아남지 못할 것이다. 쿠버네티스는 상대적으로 일시적인 파드 인스턴스를 관리하는 작업을 처리하는 *컨트롤러* 라고 하는 고수준의 추상적 개념을 사용한다. 즉, 파드를 직접적으로 사용가능 하지만, 컨트롤러를 사용하여 파드를 관리하는 것이 쿠버네티스에서 훨씬 더 보편적이다. 쿠버네티스가 어떻게 파드 스케일링과 치료하는지 보려면 [파드와 컨트롤러](#파드와-컨트롤러)를 참고하길 바란다.
파드는 스스로 자신을 치료하지 않는다. 만약 파드가 스케줄링된 노드에 장애가 생기거나, 스케쥴링 동작이 스스로 실패할 경우 파드는 삭제된다. 그와 비슷하게, 파드는 리소스나 노드의 유지 부족으로 인해 축출되는 상황에서 살아남지 못할 것이다. 쿠버네티스는 상대적으로 일시적인 파드 인스턴스를 관리하는 작업을 처리하는 *컨트롤러* 라고 하는 고수준의 추상적 개념을 사용한다. 즉, 파드를 직접적으로 사용할 수 있지만, 컨트롤러를 사용하여 파드를 관리하는 것이 쿠버네티스에서 훨씬 더 보편적이다.
### 파드와 컨트롤러
컨트롤러는 다중 파드를 생성하고 관리해 주는데, 클러스터 범위 내에서의 레플리케이션 핸들링, 롤아웃 그리고 셀프힐링 기능 제공을 한다. 예를 들어, 만약 노드가 고장났을 때, 컨트롤러는 다른 노드에 파드를 스케줄링 함으로써 자동으로 교체할 것이다.
워크로드 리소스를 사용해서 여러 파드를 생성하고 관리할 수 있다. 리소스 컨트롤러는 파드 장애 발생 시 복제, 롤아웃, 자동 복구를 처리한다. 예를 들어, 노드에 장애가 발생하면, 컨트롤러는 해당 노드의 파드는 작동을 멈추고 교체용 파드를 생성한다는 것을 알게 된다. 스케줄러는 교체용 파드를 정상적인 노드에 배치하게 된다.
한 가지 또는 그 이상의 파드를 보유한 컨트롤러의 몇 가지 예시.
* [디플로이먼트](/ko/docs/concepts/workloads/controllers/deployment/)
* [스테이트풀 셋](/ko/docs/concepts/workloads/controllers/statefulset/)
* [데몬 셋](/ko/docs/concepts/workloads/controllers/daemonset/)
일반적으로, 컨트롤러는 책임을 지고 제공한 파드 템플릿을 사용한다.
* {{< glossary_tooltip text="디플로이먼트" term_id="deployment" >}}
* {{< glossary_tooltip text="스테이트풀셋" term_id="statefulset" >}}
* {{< glossary_tooltip text="데몬셋" term_id="daemonset" >}}
## 파드 템플릿
파드 템플릿은 [레플리케이션 컨트롤러](/ko/docs/concepts/workloads/controllers/replicationcontroller/),
[](/docs/concepts/jobs/run-to-completion-finite-workloads/),
[데몬 셋](/ko/docs/concepts/workloads/controllers/daemonset/)과 같은 다른 객체를 포함하는 파드 명세서이다.
컨트롤러는 파드 템플릿을 사용하여 실제 파드를 만든다.
아래 예시는 메시지를 출력하는 컨테이너를 포함하는 파드에 대한 간단한 매니페스트이다.
워크로드 리소스에 대한 컨트롤러는 파드 템플릿으로 파드를 생성하고
사용자를 대신해서 이러한 파드를 관리한다.
파드템플릿은 파드를 생성하기 위한 명세이며
[디플로이먼트](/ko/docs/concepts/workloads/controllers/deployment/),
[](/ko/docs/concepts/jobs/run-to-completion-finite-workloads/) 그리고
[데몬셋](/ko/docs/concepts/workloads/controllers/daemonset/)과 같은 워크로드 리소스에 포함되어 있다.
워크로드 리소스의 각 컨트롤러는 워크로드 오브젝트 내부의 파드템플릿을 사용해서 실제 파드를 만든다. 파드템플릿은 앱을 실행하는 데 사용되는 모든 워크로드 리소스의 의도하는 상태의 일부이다.
아래 샘플은 하나의 컨테이너를 시작하는 `template` 이 있는 간단한 잡에 대한 매니페스트이다. 파드의 컨테이너가 메시지를 출력한 후 일시 중지하게 된다.
```yaml
apiVersion: v1
kind: Pod
apiVersion: batch/v1
kind: Job
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox
command: ['sh', '-c', 'echo 안녕하세요 쿠버네티스! && sleep 3600']
name: hello
template:
# 이것이 파드 템플릿이다.
spec:
containers:
- name: hello
image: busybox
command: ['sh', '-c', 'echo "Hello, Kubernetes!" && sleep 3600']
restartPolicy: OnFailure
# 여기가 파드 템플릿의 끝이다.
```
모든 레플리카의 현재 원하는 상태를 지정하는 대신, 파드 템플릿은 쿠키 틀과 같다. 쿠키가 한 번 잘리면, 그 쿠키는 쿠키 틀과 더이상 관련이 없다. 양자 얽힘이 없는 것이다. 그 이후 템플릿을 변경하거나 새로운 템플릿으로 바꿔도 이미 만들어진 파드에는 직접적인 영향이 없다. 마찬가지로, 레플리케이션 컨트롤러에 의해 만들어진 파드는 아마 그 이후 직접 업데이트될 수 있다. 이것은 모든 컨테이너가 속해있는 파드에서 현재 원하는 상태를 명시하는 것과 의도적으로 대비가 된다. 이러한 접근은 시스템의 의미를 철저히 단순화하고 유연성을 증가시킨다.
파드 템플릿을 수정하거나 새 파드 템플릿으로 전환해도 이미 존재하는 파드에는 영향을 미치지 않는다. 파드는 템플릿 업데이트를 직접 수신하지 않지만, 대신에 수정된 파드 템플릿과 일치하는 새 파드가 생성된다.
예를 들어, 디플로이먼트 컨트롤러는 실행 중인 파드가 현재 파드 템플릿과 일치하는지 확인한다. 템플릿이 업데이트되면, 컨트롤러는 업데이트된 템플릿을 기반으로 기존 파드를 제거하고 새 파드를 생성한다. 각 워크로드 컨트롤러는 파드 템플릿의 변경사항을 처리하기 위해 자체 규칙을 구현한다.
노드에서 "kubelet"이 파드 템플릿과 업데이트에 관련된 세부 정보를 직접 관찰하거나 관리하지 않으며, 이러한 세부 정보는 추상화되지 않는다. 이러한 추상화와 분리는 시스템 시맨틱을 단순화하며, 기존 코드를 변경하지 않고 클러스터의 동작을 확장할 수 있도록 한다.
{{% /capture %}}
{{% capture whatsnext %}}
* [파드](/ko/docs/concepts/workloads/pods/pod/)에 대해 더 배워보자.
* [분산 시스템 툴킷: 복합 컨테이너의 패턴](https://kubernetes.io/blog/2015/06/the-distributed-system-toolkit-patterns)은 둘 이상의 컨테이너가 있는 파드의 공통 레이아웃에 대해 설명한다.
* 파드의 동작에 대해 더 알아보자.
* [파드 종료](/ko/docs/concepts/workloads/pods/pod/#파드의-종료)
* [파드 라이프사이클](/ko/docs/concepts/workloads/pods/pod-lifecycle/)

View File

@ -62,10 +62,10 @@ metadata:
name: mypod
spec:
topologySpreadConstraints:
- maxSkew: <integer>
topologyKey: <string>
whenUnsatisfiable: <string>
labelSelector: <object>
- maxSkew: <integer>
topologyKey: <string>
whenUnsatisfiable: <string>
labelSelector: <object>
```
사용자는 하나 또는 다중 `topologySpreadConstraint` 를 정의해서 kube-scheduler 에게 클러스터에 걸쳐 있는 기존 파드와 시작하는 각각의 파드와 연관하여 배치하는 방법을 명령할 수 있다. 필드는 다음과 같다.
@ -73,8 +73,8 @@ spec:
- **maxSkew** 는 파드가 균등하지 않게 분산될 수 있는 정도를 나타낸다. 이것은 주어진 토폴로지 유형의 임의의 두 토폴로지 도메인에 일치하는 파드의 수 사이에서 허용되는 차이의 최댓값이다. 이것은 0보다는 커야 한다.
- **topologyKey** 는 노드 레이블의 키다. 만약 두 노드가 이 키로 레이블이 지정되고, 레이블이 동일한 값을 가진다면 스케줄러는 두 노드를 같은 토폴로지에 있는것으로 여기게 된다. 스케줄러는 각 토폴로지 도메인에 균형잡힌 수의 파드를 배치하려고 시도한다.
- **whenUnsatisfiable** 는 분산 제약 조건을 만족하지 않을 경우에 처리하는 방법을 나타낸다.
- `DoNotSchedule` (기본값)은 스케줄러에 스케줄을 하지 말라고 알려준다.
- `ScheduleAnyway` 는 스케줄러에게 차이(skew)를 최소화하는 노드에 높은 우선순위를 부여하면서, 스케줄을 계속하도록 지시한다.
- `DoNotSchedule` (기본값)은 스케줄러에 스케줄을 하지 말라고 알려준다.
- `ScheduleAnyway` 는 스케줄러에게 차이(skew)를 최소화하는 노드에 높은 우선 순위를 부여하면서, 스케줄을 계속하도록 지시한다.
- **labelSelector** 는 일치하는 파드를 찾는데 사용된다. 이 레이블 셀렉터와 일치하는 파드의 수를 계산하여 해당 토폴로지 도메인에 속할 파드의 수를 결정한다. 자세한 내용은 [레이블 셀렉터](/ko/docs/concepts/overview/working-with-objects/labels/#레이블-셀렉터)를 참조한다.
사용자는 `kubectl explain Pod.spec.topologySpreadConstraints` 를 실행해서 이 필드에 대한 자세한 내용을 알 수 있다.
@ -160,8 +160,8 @@ spec:
- 신규 파드와 같은 네임스페이스를 갖는 파드만이 매칭의 후보가 된다.
- `topologySpreadConstraints[*].topologyKey` 가 없는 노드는 무시된다. 이것은 다음을 의미한다.
1. 이러한 노드에 위치한 파드는 "maxSkew" 계산에 영향을 미치지 않는다. - 위의 예시에서, "node1"은 "zone"레이블을 가지고 있지 않다고 가정하면, 파드 2개는 무시될 것이고, 이런 이유로 신규 파드는 "zoneA"로 스케줄된다.
2. 신규 파드는 이런 종류의 노드에 스케줄 될 기회가 없다. - 위의 예시에서, 레이블로 `{zone-typo: zoneC}` 를 가지는 "node5"가 클러스터에 편입한다고 가정하면, 레이블 키에 "zone"이 없기 때문에 무시하게 된다.
1. 이러한 노드에 위치한 파드는 "maxSkew" 계산에 영향을 미치지 않는다. - 위의 예시에서, "node1"은 "zone" 레이블을 가지고 있지 않다고 가정하면, 파드 2개는 무시될 것이고, 이런 이유로 신규 파드는 "zoneA"로 스케줄된다.
2. 신규 파드는 이런 종류의 노드에 스케줄 될 기회가 없다. - 위의 예시에서, 레이블로 `{zone-typo: zoneC}` 를 가지는 "node5"가 클러스터에 편입한다고 가정하면, 레이블 키에 "zone"이 없기 때문에 무시하게 된다.
- 들어오는 파드의 `topologySpreadConstraints[*].labelSelector` 와 자체 레이블과 일치하지 않을 경우 어떻게 되는지 알고 있어야 한다. 위의 예시에서, 만약 들어오는 파드의 레이블을 제거하더라도 여전히 제약 조건이 충족하기 때문에 "zoneB"에 배치할 수 있다. 그러나, 배치 이후에도 클러스터의 불균형 정도는 변경되지 않는다. - 여전히 zoneA는 {foo:bar} 레이블을 가지고 있는 2개의 파드를 가지고 있고, zoneB 도 {foo:bar}를 레이블로 가지는 파드 1개를 가지고 있다. 따라서 만약 예상과 다르면, 워크로드의 `topologySpreadConstraints[*].labelSelector` 가 자체 레이블과 일치하도록 하는 것을 권장한다.
@ -207,12 +207,12 @@ kind: KubeSchedulerConfiguration
profiles:
pluginConfig:
- name: PodTopologySpread
args:
defaultConstraints:
- maxSkew: 1
topologyKey: failure-domain.beta.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
- name: PodTopologySpread
args:
defaultConstraints:
- maxSkew: 1
topologyKey: failure-domain.beta.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
```
{{< note >}}
@ -229,14 +229,14 @@ profiles:
더 많이 채워지거나 더 많이 분산되는 방식으로 스케줄 되는 방법을 제어한다.
- `PodAffinity` 는, 사용자가 자격이 충족되는 토폴로지 도메인에
원하는 수의 파드를 얼마든지 채울 수 있다.
원하는 수의 파드를 얼마든지 채울 수 있다.
- `PodAntiAffinity` 로는, 단일 토폴로지 도메인에
단 하나의 파드만 스케줄 될 수 있다.
단 하나의 파드만 스케줄 될 수 있다.
"EvenPodsSpread" 기능은 다양한 토폴로지 도메인에 파드를 균등하게 분배해서
고 가용성 또는 비용 절감을 달성할 수 있는 유연한 옵션을 제공한다. 또한 워크로드의 롤링 업데이트와
레플리카의 원활한 스케일링 아웃에 도움이 될 수 있다.
더 자세한 내용은 [모티베이션(Motivation)](https://github.com/kubernetes/enhancements/blob/master/keps/sig-scheduling/20190221-even-pods-spreading.md#motivation)를 참조한다.
더 자세한 내용은 [모티베이션(Motivation)](https://github.com/kubernetes/enhancements/blob/master/keps/sig-scheduling/20190221-pod-topology-spread.md#motivation)를 참조한다.
## 알려진 제한사항

View File

@ -35,7 +35,7 @@ card:
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/)의 기본 프로세스를 이해하도록 합니다.
3. [풀 리퀘스트 열기](/docs/contribute/new-content/new-content/)와 [변경 검토](/docs/contribute/review/reviewing-prs/)의 기본 프로세스를 이해하도록 합니다.
일부 작업에는 쿠버네티스 조직에서 더 많은 신뢰와 더 많은 접근이 필요할 수 있습니다.
역할과 권한에 대한 자세한 내용은
@ -44,6 +44,7 @@ card:
## 첫 번째 기여
- [기여 개요](/docs/contribute/new-content/overview/)를 읽고 기여할 수 있는 다양한 방법에 대해 알아봅니다.
- [kubernetes/website에 기여하기](https://github.com/kubernetes/website/contribute)를 참조하여 좋은 진입점이 되는 이슈를 찾을 수 있습니다.
- 기존 문서에 대해 [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/)를 읽고 정보에 대한 코멘트를 남길 수 있습니다.

View File

@ -166,11 +166,13 @@ boilerplate | 상용구 |
Boot | 부트 |
Build | 빌드 |
Cache | 캐시 |
Calico | 캘리코(Calico) |
canary | 카나리(canary) | 릴리스 방식에 관련한 용어인 경우에 한함
cascading | 캐스케이딩(cascading) |
character set | 캐릭터 셋 |
Charts | 차트 |
checkpoint | 체크포인트 |
Cilium | 실리움(Cilium) |
CLI | CLI |
Cluster | 클러스터 |
Command Line Tool | 커맨드라인 툴 |
@ -200,19 +202,22 @@ disruption | 중단(disruption) |
distros | 배포판 |
Docker | 도커 |
Dockerfile | Dockerfile |
Docker Swarm | Docker Swarm |
Downward API | 다운워드(Downward) API |
draining | 드레이닝(draining) |
egress | 이그레스, 송신(egress) |
Endpoint | 엔드포인트 |
entry point | 진입점 |
Event | 이벤트 |
evict | 축출하다 |
eviction | 축출 |
Exec | Exec |
expose | 노출시키다 |
extension | 익스텐션(extension) |
Failed | Failed | 파드의 상태에 한함
Federation | 페더레이션 |
field | 필드 |
Flannel | Flannel |
Flannel | 플란넬(Flannel) |
form | 형식 |
Google Compute Engine | Google Compute Engine |
hash | 해시 |
@ -239,6 +244,7 @@ Job | 잡 |
kube-proxy | kube-proxy |
Kubelet | Kubelet |
Kubernetes | 쿠버네티스 |
Kube-router | Kube-router |
label | 레이블 |
lifecycle | 라이프사이클 |
Linux | 리눅스 |
@ -273,7 +279,7 @@ Persistent Volume | 퍼시스턴트 볼륨 |
Persistent Volume Claim | 퍼시스턴트 볼륨 클레임 |
pipeline | 파이프라인 |
placeholder pod | 플레이스홀더(placeholder) 파드 |
Pod(파드) | 파드 |
Pod | 파드 |
Pod Preset | 파드 프리셋 |
PodAntiAffinity | 파드안티어피니티(PodAntiAffinity) |
PodDisruptionBudget | PodDisruptionBudget |
@ -307,6 +313,7 @@ Role | 롤 |
rollback | 롤백 |
rolling update | 롤링 업데이트 |
rollout | 롤아웃 |
Romana | 로마나(Romana) |
Running | Running | 파드의 상태에 한함
runtime | 런타임 |
Scale | 스케일 |
@ -325,6 +332,7 @@ Shell | 셸 |
Sign In | 로그인 |
Sign Out | 로그아웃 |
skew | 차이(skew) |
snippet | 스니펫(snippet) |
spec | 명세, 스펙, 사양 |
specification | 명세 |
Stateful Set | 스테이트풀 셋 |
@ -352,6 +360,7 @@ virtualization | 가상화 |
Volume | 볼륨 |
Waiting | Waiting | 파드의 상태에 한함
Walkthrough | 연습 |
Weave-net | 위브넷(Weave Net) | Weaveworks 사의 솔루션 공식 명칭은 'Weave Net'이므로 한영병기 시 공식 명칭 사용
Windows | 윈도우 |
Worker | 워커 | 노드의 형태에 한함
Workload | 워크로드 |

Some files were not shown because too many files have changed in this diff Show More