Merge remote-tracking branch 'upstream/main' into dev-1.25
This commit is contained in:
+2
-2
@@ -65,7 +65,7 @@ The Kubernetes website uses the [Docsy Hugo theme](https://github.com/google/doc
|
||||
Kubernetes 网站使用的是 [Docsy Hugo 主题](https://github.com/google/docsy#readme)。 即使你打算在容器中运行网站,我们也强烈建议你通过运行以下命令来引入子模块和其他开发依赖项:
|
||||
|
||||
```bash
|
||||
# pull in the Docsy submodule
|
||||
# 引入 Docsy 子模块
|
||||
git submodule update --init --recursive --depth 1
|
||||
```
|
||||
|
||||
@@ -113,7 +113,7 @@ Hugo 扩展版本。
|
||||
若要在本地构造和测试网站,请运行:
|
||||
|
||||
```bash
|
||||
# install dependencies
|
||||
# 安装依赖
|
||||
npm ci
|
||||
make serve
|
||||
```
|
||||
|
||||
@@ -41,7 +41,7 @@ These repo labels let reviewers filter for PRs and issues by language. For examp
|
||||
|
||||
### Team review
|
||||
|
||||
L10n teams can now review and approve their own PRs. For example, review and approval permissions for English are [assigned in an OWNERS file](https://github.com/kubernetes/website/blob/master/content/en/OWNERS) in the top subfolder for English content.
|
||||
L10n teams can now review and approve their own PRs. For example, review and approval permissions for English are [assigned in an OWNERS file](https://github.com/kubernetes/website/blob/main/content/en/OWNERS) in the top subfolder for English content.
|
||||
|
||||
Adding `OWNERS` files to subdirectories lets localization teams review and approve changes without requiring a rubber stamp approval from reviewers who may lack fluency.
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ date: 2019-04-26
|
||||
|
||||
Last year we optimized the Kubernetes website for [hosting multilingual content](/blog/2018/11/08/kubernetes-docs-updates-international-edition/). Contributors responded by adding multiple new localizations: as of April 2019, Kubernetes docs are partially available in nine different languages, with six added in 2019 alone. You can see a list of available languages in the language selector at the top of each page.
|
||||
|
||||
By _partially available_, I mean that localizations are ongoing projects. They range from mostly complete ([Chinese docs for 1.12](https://v1-12.docs.kubernetes.io/zh/)) to brand new (1.14 docs in [Portuguese](https://kubernetes.io/pt/)). If you're interested in helping an existing localization, read on!
|
||||
By _partially available_, I mean that localizations are ongoing projects. They range from mostly complete ([Chinese docs for 1.12](https://v1-12.docs.kubernetes.io/zh-cn/)) to brand new (1.14 docs in [Portuguese](https://kubernetes.io/pt/)). If you're interested in helping an existing localization, read on!
|
||||
|
||||
## What is a localization?
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ so we added two administrator-facing tools to help track use of deprecated APIs
|
||||
Starting in Kubernetes v1.19, when a request is made to a deprecated REST API endpoint,
|
||||
an `apiserver_requested_deprecated_apis` gauge metric is set to `1` in the kube-apiserver process.
|
||||
This metric has labels for the API `group`, `version`, `resource`, and `subresource`,
|
||||
and a `removed_version` label that indicates the Kubernetes release in which the API will no longer be served.
|
||||
and a `removed_release` label that indicates the Kubernetes release in which the API will no longer be served.
|
||||
|
||||
This is an example query using `kubectl`, [prom2json](https://github.com/prometheus/prom2json),
|
||||
and [jq](https://stedolan.github.io/jq/) to determine which deprecated APIs have been requested
|
||||
@@ -169,7 +169,7 @@ You can also find that information through the following Prometheus query,
|
||||
which returns information about requests made to deprecated APIs which will be removed in v1.22:
|
||||
|
||||
```promql
|
||||
apiserver_requested_deprecated_apis{removed_version="1.22"} * on(group,version,resource,subresource)
|
||||
apiserver_requested_deprecated_apis{removed_release="1.22"} * on(group,version,resource,subresource)
|
||||
group_right() apiserver_request_total
|
||||
```
|
||||
|
||||
|
||||
@@ -30,9 +30,9 @@ This led to design principles that allow the Gateway API to improve upon Ingress
|
||||
|
||||
The Gateway API introduces a few new resource types:
|
||||
|
||||
- **[GatewayClasses](https://gateway-api.sigs.k8s.io/v1alpha1/references/spec/#networking.x-k8s.io/v1alpha1.GatewayClass)** are cluster-scoped resources that act as templates to explicitly define behavior for Gateways derived from them. This is similar in concept to StorageClasses, but for networking data-planes.
|
||||
- **[Gateways](https://gateway-api.sigs.k8s.io/v1alpha1/references/spec/#networking.x-k8s.io/v1alpha1.Gateway)** are the deployed instances of GatewayClasses. They are the logical representation of the data-plane which performs routing, which may be in-cluster proxies, hardware LBs, or cloud LBs.
|
||||
- **Routes** are not a single resource, but represent many different protocol-specific Route resources. The [HTTPRoute](https://gateway-api.sigs.k8s.io/v1alpha1/references/spec/#networking.x-k8s.io/v1alpha1.HTTPRoute) has matching, filtering, and routing rules that get applied to Gateways that can process HTTP and HTTPS traffic. Similarly, there are [TCPRoutes](https://gateway-api.sigs.k8s.io/v1alpha1/references/spec/#networking.x-k8s.io/v1alpha1.TCPRoute), [UDPRoutes](https://gateway-api.sigs.k8s.io/v1alpha1/references/spec/#networking.x-k8s.io/v1alpha1.UDPRoute), and [TLSRoutes](https://gateway-api.sigs.k8s.io/v1alpha1/references/spec/#networking.x-k8s.io/v1alpha1.TLSRoute) which also have protocol-specific semantics. This model also allows the Gateway API to incrementally expand its protocol support in the future.
|
||||
- **[GatewayClasses](https://gateway-api.sigs.k8s.io/concepts/api-overview/#gatewayclass)** are cluster-scoped resources that act as templates to explicitly define behavior for Gateways derived from them. This is similar in concept to StorageClasses, but for networking data-planes.
|
||||
- **[Gateways](https://gateway-api.sigs.k8s.io/concepts/api-overview/#gateway)** are the deployed instances of GatewayClasses. They are the logical representation of the data-plane which performs routing, which may be in-cluster proxies, hardware LBs, or cloud LBs.
|
||||
- **Routes** are not a single resource, but represent many different protocol-specific Route resources. The [HTTPRoute](https://gateway-api.sigs.k8s.io/concepts/api-overview/#httproute) has matching, filtering, and routing rules that get applied to Gateways that can process HTTP and HTTPS traffic. Similarly, there are [TCPRoutes](https://gateway-api.sigs.k8s.io/concepts/api-overview/#tcproute-and-udproute), [UDPRoutes](https://gateway-api.sigs.k8s.io/concepts/api-overview/#tcproute-and-udproute), and [TLSRoutes](https://gateway-api.sigs.k8s.io/concepts/api-overview/#gateway) which also have protocol-specific semantics. This model also allows the Gateway API to incrementally expand its protocol support in the future.
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ samplingRatePerMillion: 10000
|
||||
|
||||
### Enabling Etcd Tracing
|
||||
|
||||
Add `--experimental-enable-distributed-tracing`, `--experimental-distributed-tracing-address=0.0.0.0:4317`, `--experimental-distributed-tracing-service-name=etcd` flags to etcd to enable tracing. Note that this traces every request, so it will probably generate a lot of traces if you enable it.
|
||||
Add `--experimental-enable-distributed-tracing`, `--experimental-distributed-tracing-address=0.0.0.0:4317`, `--experimental-distributed-tracing-service-name=etcd` flags to etcd to enable tracing. Note that this traces every request, so it will probably generate a lot of traces if you enable it. Required etcd version is [v3.5+](https://etcd.io/docs/v3.5/op-guide/monitoring/#distributed-tracing).
|
||||
|
||||
### Example Trace: List Nodes
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ in Kubernetes 1.24.
|
||||
|
||||
If you're running Kubernetes v1.24 or later, see [Can I still use Docker Engine as my container runtime?](#can-i-still-use-docker-engine-as-my-container-runtime).
|
||||
(Remember, you can switch away from the dockershim if you're using any supported Kubernetes release; from release v1.24, you
|
||||
**must** switch as Kubernetes no longer incluides the dockershim).
|
||||
**must** switch as Kubernetes no longer includes the dockershim).
|
||||
|
||||
[kubelet]: /docs/reference/command-line-tools-reference/kubelet/
|
||||
|
||||
|
||||
@@ -471,11 +471,15 @@ poorly-behaved workloads that may be harming system health.
|
||||
requests, broken down by the labels `phase` (which takes on the
|
||||
values `waiting` and `executing`) and `request_kind` (which takes on
|
||||
the values `mutating` and `readOnly`). The observations are made
|
||||
periodically at a high rate.
|
||||
periodically at a high rate. Each observed value is a ratio,
|
||||
between 0 and 1, of a number of requests divided by the
|
||||
corresponding limit on the number of requests (queue length limit
|
||||
for waiting and concurrency limit for executing).
|
||||
|
||||
* `apiserver_flowcontrol_read_vs_write_request_count_watermarks` is a
|
||||
histogram vector of high or low water marks of the number of
|
||||
requests broken down by the labels `phase` (which takes on the
|
||||
requests (divided by the corresponding limit to get a ratio in the
|
||||
range 0 to 1) broken down by the labels `phase` (which takes on the
|
||||
values `waiting` and `executing`) and `request_kind` (which takes on
|
||||
the values `mutating` and `readOnly`); the label `mark` takes on
|
||||
values `high` and `low`. The water marks are accumulated over
|
||||
@@ -502,11 +506,15 @@ poorly-behaved workloads that may be harming system health.
|
||||
values `waiting` and `executing`) and `priority_level`. Each
|
||||
histogram gets observations taken periodically, up through the last
|
||||
activity of the relevant sort. The observations are made at a high
|
||||
rate.
|
||||
rate. Each observed value is a ratio, between 0 and 1, of a number
|
||||
of requests divided by the corresponding limit on the number of
|
||||
requests (queue length limit for waiting and concurrency limit for
|
||||
executing).
|
||||
|
||||
* `apiserver_flowcontrol_priority_level_request_count_watermarks` is a
|
||||
histogram vector of high or low water marks of the number of
|
||||
requests broken down by the labels `phase` (which takes on the
|
||||
requests (divided by the corresponding limit to get a ratio in the
|
||||
range 0 to 1) broken down by the labels `phase` (which takes on the
|
||||
values `waiting` and `executing`) and `priority_level`; the label
|
||||
`mark` takes on values `high` and `low`. The water marks are
|
||||
accumulated over windows bounded by the times when an observation
|
||||
@@ -514,6 +522,31 @@ poorly-behaved workloads that may be harming system health.
|
||||
`apiserver_flowcontrol_priority_level_request_count_samples`. These
|
||||
water marks show the range of values that occurred between samples.
|
||||
|
||||
* `apiserver_flowcontrol_priority_level_seat_count_samples` is a
|
||||
histogram vector of observations of the utilization of a priority
|
||||
level's concurrency limit, broken down by `priority_level`. This
|
||||
utilization is the fraction (number of seats occupied) /
|
||||
(concurrency limit). This metric considers all stages of execution
|
||||
(both normal and the extra delay at the end of a write to cover for
|
||||
the corresponding notification work) of all requests except WATCHes;
|
||||
for those it considers only the initial stage that delivers
|
||||
notifications of pre-existing objects. Each histogram in the vector
|
||||
is also labeled with `phase: executing` (there is no seat limit for
|
||||
the waiting phase). Each histogram gets observations taken
|
||||
periodically, up through the last activity of the relevant sort.
|
||||
The observations
|
||||
are made at a high rate.
|
||||
|
||||
* `apiserver_flowcontrol_priority_level_seat_count_watermarks` is a
|
||||
histogram vector of high or low water marks of the utilization of a
|
||||
priority level's concurrency limit, broken down by `priority_level`
|
||||
and `mark` (which takes on values `high` and `low`). Each histogram
|
||||
in the vector is also labeled with `phase: executing` (there is no
|
||||
seat limit for the waiting phase). The water marks are accumulated
|
||||
over windows bounded by the times when an observation was added to
|
||||
`apiserver_flowcontrol_priority_level_seat_count_samples`. These
|
||||
water marks show the range of values that occurred between samples.
|
||||
|
||||
* `apiserver_flowcontrol_request_queue_length_after_enqueue` is a
|
||||
histogram vector of queue lengths for the queues, broken down by
|
||||
the labels `priority_level` and `flow_schema`, as sampled by the
|
||||
@@ -556,6 +589,22 @@ poorly-behaved workloads that may be harming system health.
|
||||
and `priority_level` (indicating the one to which the request was
|
||||
assigned).
|
||||
|
||||
* `apiserver_flowcontrol_watch_count_samples` is a histogram vector of
|
||||
the number of active WATCH requests relevant to a given write,
|
||||
broken down by `flow_schema` and `priority_level`.
|
||||
|
||||
* `apiserver_flowcontrol_work_estimated_seats` is a histogram vector
|
||||
of the number of estimated seats (maximum of initial and final stage
|
||||
of execution) associated with requests, broken down by `flow_schema`
|
||||
and `priority_level`.
|
||||
|
||||
* `apiserver_flowcontrol_request_dispatch_no_accommodation_total` is a
|
||||
counter vec of the number of events that in principle could have led
|
||||
to a request being dispatched but did not, due to lack of available
|
||||
concurrency, broken down by `flow_schema` and `priority_level`. The
|
||||
relevant sorts of events are arrival of a request and completion of
|
||||
a request.
|
||||
|
||||
### Debug endpoints
|
||||
|
||||
When you enable the API Priority and Fairness feature, the `kube-apiserver`
|
||||
|
||||
@@ -799,7 +799,7 @@ memory limit (and possibly request) for that container.
|
||||
* Get hands-on experience [assigning Memory resources to containers and Pods](/docs/tasks/configure-pod-container/assign-memory-resource/).
|
||||
* Get hands-on experience [assigning CPU resources to containers and Pods](/docs/tasks/configure-pod-container/assign-cpu-resource/).
|
||||
* Read how the API reference defines a [container](/docs/reference/kubernetes-api/workload-resources/pod-v1/#Container)
|
||||
and its [resource requirements](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#resources)
|
||||
and its [resource requirements](/docs/reference/kubernetes-api/workload-resources/pod-v1/#resources)
|
||||
* Read about [project quotas](https://xfs.org/index.php/XFS_FAQ#Q:_Quota:_Do_quotas_work_on_XFS.3F) in XFS
|
||||
* Read more about the [kube-scheduler configuration reference (v1beta3)](/docs/reference/config-api/kube-scheduler-config.v1beta3/)
|
||||
|
||||
|
||||
@@ -17,26 +17,29 @@ no_list: true
|
||||
|
||||
<!-- overview -->
|
||||
|
||||
Kubernetes is highly configurable and extensible. As a result,
|
||||
there is rarely a need to fork or submit patches to the Kubernetes
|
||||
project code.
|
||||
Kubernetes is highly configurable and extensible. As a result, there is rarely a need to fork or
|
||||
submit patches to the Kubernetes project code.
|
||||
|
||||
This guide describes the options for customizing a Kubernetes
|
||||
cluster. It is aimed at {{< glossary_tooltip text="cluster operators" term_id="cluster-operator" >}} who want to
|
||||
understand how to adapt their Kubernetes cluster to the needs of
|
||||
their work environment. Developers who are prospective {{< glossary_tooltip text="Platform Developers" term_id="platform-developer" >}} or Kubernetes Project {{< glossary_tooltip text="Contributors" term_id="contributor" >}} will also find it
|
||||
useful as an introduction to what extension points and patterns
|
||||
exist, and their trade-offs and limitations.
|
||||
This guide describes the options for customizing a Kubernetes cluster. It is aimed at
|
||||
{{< glossary_tooltip text="cluster operators" term_id="cluster-operator" >}} who want to understand
|
||||
how to adapt their Kubernetes cluster to the needs of their work environment. Developers who are
|
||||
prospective {{< glossary_tooltip text="Platform Developers" term_id="platform-developer" >}} or
|
||||
Kubernetes Project {{< glossary_tooltip text="Contributors" term_id="contributor" >}} will also
|
||||
find it useful as an introduction to what extension points and patterns exist, and their
|
||||
trade-offs and limitations.
|
||||
|
||||
<!-- body -->
|
||||
|
||||
## Overview
|
||||
|
||||
Customization approaches can be broadly divided into *configuration*, which only involves changing flags, local configuration files, or API resources; and *extensions*, which involve running additional programs or services. This document is primarily about extensions.
|
||||
Customization approaches can be broadly divided into *configuration*, which only involves changing
|
||||
flags, local configuration files, or API resources; and *extensions*, which involve running
|
||||
additional programs or services. This document is primarily about extensions.
|
||||
|
||||
## Configuration
|
||||
|
||||
*Configuration files* and *flags* are documented in the Reference section of the online documentation, under each binary:
|
||||
*Configuration files* and *flags* are documented in the Reference section of the online
|
||||
documentation, under each binary:
|
||||
|
||||
* [kubelet](/docs/reference/command-line-tools-reference/kubelet/)
|
||||
* [kube-proxy](/docs/reference/command-line-tools-reference/kube-proxy/)
|
||||
@@ -44,9 +47,22 @@ Customization approaches can be broadly divided into *configuration*, which only
|
||||
* [kube-controller-manager](/docs/reference/command-line-tools-reference/kube-controller-manager/)
|
||||
* [kube-scheduler](/docs/reference/command-line-tools-reference/kube-scheduler/).
|
||||
|
||||
Flags and configuration files may not always be changeable in a hosted Kubernetes service or a distribution with managed installation. When they are changeable, they are usually only changeable by the cluster administrator. Also, they are subject to change in future Kubernetes versions, and setting them may require restarting processes. For those reasons, they should be used only when there are no other options.
|
||||
Flags and configuration files may not always be changeable in a hosted Kubernetes service or a
|
||||
distribution with managed installation. When they are changeable, they are usually only changeable
|
||||
by the cluster administrator. Also, they are subject to change in future Kubernetes versions, and
|
||||
setting them may require restarting processes. For those reasons, they should be used only when
|
||||
there are no other options.
|
||||
|
||||
*Built-in Policy APIs*, such as [ResourceQuota](/docs/concepts/policy/resource-quotas/), [PodSecurityPolicies](/docs/concepts/security/pod-security-policy/), [NetworkPolicy](/docs/concepts/services-networking/network-policies/) and Role-based Access Control ([RBAC](/docs/reference/access-authn-authz/rbac/)), are built-in Kubernetes APIs. APIs are typically used with hosted Kubernetes services and with managed Kubernetes installations. They are declarative and use the same conventions as other Kubernetes resources like pods, so new cluster configuration can be repeatable and be managed the same way as applications. And, where they are stable, they enjoy a [defined support policy](/docs/reference/using-api/deprecation-policy/) like other Kubernetes APIs. For these reasons, they are preferred over *configuration files* and *flags* where suitable.
|
||||
*Built-in Policy APIs*, such as [ResourceQuota](/docs/concepts/policy/resource-quotas/),
|
||||
[PodSecurityPolicies](/docs/concepts/security/pod-security-policy/),
|
||||
[NetworkPolicy](/docs/concepts/services-networking/network-policies/) and Role-based Access Control
|
||||
([RBAC](/docs/reference/access-authn-authz/rbac/)), are built-in Kubernetes APIs.
|
||||
APIs are typically used with hosted Kubernetes services and with managed Kubernetes installations.
|
||||
They are declarative and use the same conventions as other Kubernetes resources like pods,
|
||||
so new cluster configuration can be repeatable and be managed the same way as applications.
|
||||
And, where they are stable, they enjoy a
|
||||
[defined support policy](/docs/reference/using-api/deprecation-policy/) like other Kubernetes APIs.
|
||||
For these reasons, they are preferred over *configuration files* and *flags* where suitable.
|
||||
|
||||
## Extensions
|
||||
|
||||
@@ -70,10 +86,9 @@ There is a specific pattern for writing client programs that work well with
|
||||
Kubernetes called the *Controller* pattern. Controllers typically read an
|
||||
object's `.spec`, possibly do things, and then update the object's `.status`.
|
||||
|
||||
A controller is a client of Kubernetes. When Kubernetes is the client and
|
||||
calls out to a remote service, it is called a *Webhook*. The remote service
|
||||
is called a *Webhook Backend*. Like Controllers, Webhooks do add a point of
|
||||
failure.
|
||||
A controller is a client of Kubernetes. When Kubernetes is the client and calls out to a remote
|
||||
service, it is called a *Webhook*. The remote service is called a *Webhook Backend*. Like
|
||||
Controllers, Webhooks do add a point of failure.
|
||||
|
||||
In the webhook model, Kubernetes makes a network request to a remote service.
|
||||
In the *Binary Plugin* model, Kubernetes executes a binary (program).
|
||||
@@ -95,15 +110,35 @@ This diagram shows the extension points in a Kubernetes system.
|
||||
<!-- image source diagrams: https://docs.google.com/drawings/d/1k2YdJgNTtNfW7_A8moIIkij-DmVgEhNrn3y2OODwqQQ/view -->
|
||||

|
||||
|
||||
1. Users often interact with the Kubernetes API using `kubectl`. [Kubectl plugins](/docs/tasks/extend-kubectl/kubectl-plugins/) extend the kubectl binary. They only affect the individual user's local environment, and so cannot enforce site-wide policies.
|
||||
2. The apiserver handles all requests. Several types of extension points in the apiserver allow authenticating requests, or blocking them based on their content, editing content, and handling deletion. These are described in the [API Access Extensions](#api-access-extensions) section.
|
||||
3. The apiserver serves various kinds of *resources*. *Built-in resource kinds*, like `pods`, are defined by the Kubernetes project and can't be changed. You can also add resources that you define, or that other projects have defined, called *Custom Resources*, as explained in the [Custom Resources](#user-defined-types) section. Custom Resources are often used with API Access Extensions.
|
||||
4. The Kubernetes scheduler decides which nodes to place pods on. There are several ways to extend scheduling. These are described in the [Scheduler Extensions](#scheduler-extensions) section.
|
||||
5. Much of the behavior of Kubernetes is implemented by programs called Controllers which are clients of the API-Server. Controllers are often used in conjunction with Custom Resources.
|
||||
6. The kubelet runs on servers, and helps pods appear like virtual servers with their own IPs on the cluster network. [Network Plugins](#network-plugins) allow for different implementations of pod networking.
|
||||
7. The kubelet also mounts and unmounts volumes for containers. New types of storage can be supported via [Storage Plugins](#storage-plugins).
|
||||
1. Users often interact with the Kubernetes API using `kubectl`.
|
||||
[Kubectl plugins](/docs/tasks/extend-kubectl/kubectl-plugins/) extend the kubectl binary.
|
||||
They only affect the individual user's local environment, and so cannot enforce site-wide policies.
|
||||
|
||||
If you are unsure where to start, this flowchart can help. Note that some solutions may involve several types of extensions.
|
||||
1. The API server handles all requests. Several types of extension points in the API server allow
|
||||
authenticating requests, or blocking them based on their content, editing content, and handling
|
||||
deletion. These are described in the [API Access Extensions](#api-access-extensions) section.
|
||||
|
||||
1. The API server serves various kinds of *resources*. *Built-in resource kinds*, like `pods`, are
|
||||
defined by the Kubernetes project and can't be changed. You can also add resources that you
|
||||
define, or that other projects have defined, called *Custom Resources*, as explained in the
|
||||
[Custom Resources](#user-defined-types) section. Custom Resources are often used with API access
|
||||
extensions.
|
||||
|
||||
1. The Kubernetes scheduler decides which nodes to place pods on. There are several ways to extend
|
||||
scheduling. These are described in the [Scheduler Extensions](#scheduler-extensions) section.
|
||||
|
||||
1. Much of the behavior of Kubernetes is implemented by programs called Controllers which are
|
||||
clients of the API server. Controllers are often used in conjunction with Custom Resources.
|
||||
|
||||
1. The kubelet runs on servers, and helps pods appear like virtual servers with their own IPs on
|
||||
the cluster network. [Network Plugins](#network-plugins) allow for different implementations of
|
||||
pod networking.
|
||||
|
||||
1. The kubelet also mounts and unmounts volumes for containers. New types of storage can be
|
||||
supported via [Storage Plugins](#storage-plugins).
|
||||
|
||||
If you are unsure where to start, this flowchart can help. Note that some solutions may involve
|
||||
several types of extensions.
|
||||
|
||||
<!-- image source drawing: https://docs.google.com/drawings/d/1sdviU6lDz4BpnzJNHfNpQrqI9F19QZ07KnhnxVrp2yg/edit -->
|
||||

|
||||
@@ -112,60 +147,86 @@ If you are unsure where to start, this flowchart can help. Note that some soluti
|
||||
|
||||
### User-Defined Types
|
||||
|
||||
Consider adding a Custom Resource to Kubernetes if you want to define new controllers, application configuration objects or other declarative APIs, and to manage them using Kubernetes tools, such as `kubectl`.
|
||||
Consider adding a Custom Resource to Kubernetes if you want to define new controllers, application
|
||||
configuration objects or other declarative APIs, and to manage them using Kubernetes tools, such
|
||||
as `kubectl`.
|
||||
|
||||
Do not use a Custom Resource as data storage for application, user, or monitoring data.
|
||||
|
||||
For more about Custom Resources, see the [Custom Resources concept guide](/docs/concepts/extend-kubernetes/api-extension/custom-resources/).
|
||||
For more about Custom Resources, see the
|
||||
[Custom Resources concept guide](/docs/concepts/extend-kubernetes/api-extension/custom-resources/).
|
||||
|
||||
|
||||
### Combining New APIs with Automation
|
||||
|
||||
The combination of a custom resource API and a control loop is called the [Operator pattern](/docs/concepts/extend-kubernetes/operator/). The Operator pattern is used to manage specific, usually stateful, applications. These custom APIs and control loops can also be used to control other resources, such as storage or policies.
|
||||
The combination of a custom resource API and a control loop is called the
|
||||
[Operator pattern](/docs/concepts/extend-kubernetes/operator/). The Operator pattern is used to manage
|
||||
specific, usually stateful, applications. These custom APIs and control loops can also be used to
|
||||
control other resources, such as storage or policies.
|
||||
|
||||
### Changing Built-in Resources
|
||||
|
||||
When you extend the Kubernetes API by adding custom resources, the added resources always fall into a new API Groups. You cannot replace or change existing API groups.
|
||||
Adding an API does not directly let you affect the behavior of existing APIs (e.g. Pods), but API Access Extensions do.
|
||||
When you extend the Kubernetes API by adding custom resources, the added resources always fall
|
||||
into a new API Groups. You cannot replace or change existing API groups.
|
||||
Adding an API does not directly let you affect the behavior of existing APIs (e.g. Pods), but API
|
||||
Access Extensions do.
|
||||
|
||||
|
||||
### API Access Extensions
|
||||
|
||||
When a request reaches the Kubernetes API Server, it is first Authenticated, then Authorized, then subject to various types of Admission Control. See [Controlling Access to the Kubernetes API](/docs/concepts/security/controlling-access/) for more on this flow.
|
||||
When a request reaches the Kubernetes API Server, it is first Authenticated, then Authorized, then
|
||||
subject to various types of Admission Control. See
|
||||
[Controlling Access to the Kubernetes API](/docs/concepts/security/controlling-access/)
|
||||
for more on this flow.
|
||||
|
||||
Each of these steps offers extension points.
|
||||
|
||||
Kubernetes has several built-in authentication methods that it supports. It can also sit behind an authenticating proxy, and it can send a token from an Authorization header to a remote service for verification (a webhook). All of these methods are covered in the [Authentication documentation](/docs/reference/access-authn-authz/authentication/).
|
||||
Kubernetes has several built-in authentication methods that it supports. It can also sit behind an
|
||||
authenticating proxy, and it can send a token from an Authorization header to a remote service for
|
||||
verification (a webhook). All of these methods are covered in the
|
||||
[Authentication documentation](/docs/reference/access-authn-authz/authentication/).
|
||||
|
||||
### Authentication
|
||||
|
||||
[Authentication](/docs/reference/access-authn-authz/authentication/) maps headers or certificates in all requests to a username for the client making the request.
|
||||
|
||||
Kubernetes provides several built-in authentication methods, and an [Authentication webhook](/docs/reference/access-authn-authz/authentication/#webhook-token-authentication) method if those don't meet your needs.
|
||||
[Authentication](/docs/reference/access-authn-authz/authentication/) maps headers or certificates
|
||||
in all requests to a username for the client making the request.
|
||||
|
||||
Kubernetes provides several built-in authentication methods, and an
|
||||
[Authentication webhook](/docs/reference/access-authn-authz/authentication/#webhook-token-authentication)
|
||||
method if those don't meet your needs.
|
||||
|
||||
### Authorization
|
||||
|
||||
[Authorization](/docs/reference/access-authn-authz/authorization/) determines whether specific users can read, write, and do other operations on API resources. It works at the level of whole resources -- it doesn't discriminate based on arbitrary object fields. If the built-in authorization options don't meet your needs, [Authorization webhook](/docs/reference/access-authn-authz/webhook/) allows calling out to user-provided code to make an authorization decision.
|
||||
|
||||
[Authorization](/docs/reference/access-authn-authz/authorization/) determines whether specific
|
||||
users can read, write, and do other operations on API resources. It works at the level of whole
|
||||
resources -- it doesn't discriminate based on arbitrary object fields. If the built-in
|
||||
authorization options don't meet your needs, [Authorization webhook](/docs/reference/access-authn-authz/webhook/)
|
||||
allows calling out to user-provided code to make an authorization decision.
|
||||
|
||||
### Dynamic Admission Control
|
||||
|
||||
After a request is authorized, if it is a write operation, it also goes through [Admission Control](/docs/reference/access-authn-authz/admission-controllers/) steps. In addition to the built-in steps, there are several extensions:
|
||||
After a request is authorized, if it is a write operation, it also goes through
|
||||
[Admission Control](/docs/reference/access-authn-authz/admission-controllers/) steps.
|
||||
In addition to the built-in steps, there are several extensions:
|
||||
|
||||
* The [Image Policy webhook](/docs/reference/access-authn-authz/admission-controllers/#imagepolicywebhook) restricts what images can be run in containers.
|
||||
* To make arbitrary admission control decisions, a general [Admission webhook](/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks) can be used. Admission Webhooks can reject creations or updates.
|
||||
* The [Image Policy webhook](/docs/reference/access-authn-authz/admission-controllers/#imagepolicywebhook)
|
||||
restricts what images can be run in containers.
|
||||
* To make arbitrary admission control decisions, a general
|
||||
[Admission webhook](/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks)
|
||||
can be used. Admission Webhooks can reject creations or updates.
|
||||
|
||||
## Infrastructure Extensions
|
||||
|
||||
### Storage Plugins
|
||||
|
||||
[Flex Volumes](https://git.k8s.io/design-proposals-archive/storage/flexvolume-deployment.md
|
||||
) allow users to mount volume types without built-in support by having the
|
||||
Kubelet call a Binary Plugin to mount the volume.
|
||||
|
||||
FlexVolume is deprecated since Kubernetes v1.23. The Out-of-tree CSI driver is the recommended way to write volume drivers in Kubernetes. See [Kubernetes Volume Plugin FAQ for Storage Vendors](https://github.com/kubernetes/community/blob/master/sig-storage/volume-plugin-faq.md#kubernetes-volume-plugin-faq-for-storage-vendors) for more information.
|
||||
[Flex Volumes](https://git.k8s.io/design-proposals-archive/storage/flexvolume-deployment.md)
|
||||
allow users to mount volume types without built-in support by having the kubelet call a binary
|
||||
plugin to mount the volume.
|
||||
|
||||
FlexVolume is deprecated since Kubernetes v1.23. The out-of-tree CSI driver is the recommended way
|
||||
to write volume drivers in Kubernetes. See
|
||||
[Kubernetes Volume Plugin FAQ for Storage Vendors](https://github.com/kubernetes/community/blob/master/sig-storage/volume-plugin-faq.md#kubernetes-volume-plugin-faq-for-storage-vendors)
|
||||
for more information.
|
||||
|
||||
### Device Plugins
|
||||
|
||||
@@ -173,7 +234,6 @@ Device plugins allow a node to discover new Node resources (in addition to the
|
||||
builtin ones like cpu and memory) via a
|
||||
[Device Plugin](/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/).
|
||||
|
||||
|
||||
### Network Plugins
|
||||
|
||||
Different networking fabrics can be supported via node-level
|
||||
|
||||
@@ -1,237 +0,0 @@
|
||||
---
|
||||
title: Service Catalog
|
||||
reviewers:
|
||||
- chenopis
|
||||
content_type: concept
|
||||
weight: 40
|
||||
---
|
||||
|
||||
<!-- overview -->
|
||||
{{< glossary_definition term_id="service-catalog" length="all" prepend="Service Catalog is" >}}
|
||||
|
||||
A service broker, as defined by the [Open service broker API spec](https://github.com/openservicebrokerapi/servicebroker/blob/v2.13/spec.md), is an endpoint for a set of managed services offered and maintained by a third-party, which could be a cloud provider such as AWS, GCP, or Azure.
|
||||
Some examples of managed services are Microsoft Azure Cloud Queue, Amazon Simple Queue Service, and Google Cloud Pub/Sub, but they can be any software offering that can be used by an application.
|
||||
|
||||
Using Service Catalog, a {{< glossary_tooltip text="cluster operator" term_id="cluster-operator" >}} can browse the list of managed services offered by a service broker, provision an instance of a managed service, and bind with it to make it available to an application in the Kubernetes cluster.
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- body -->
|
||||
## Example use case
|
||||
|
||||
An {{< glossary_tooltip text="application developer" term_id="application-developer" >}} wants to use message queuing as part of their application running in a Kubernetes cluster.
|
||||
However, they do not want to deal with the overhead of setting such a service up and administering it themselves.
|
||||
Fortunately, there is a cloud provider that offers message queuing as a managed service through its service broker.
|
||||
|
||||
A cluster operator can setup Service Catalog and use it to communicate with the cloud provider's service broker to provision an instance of the message queuing service and make it available to the application within the Kubernetes cluster.
|
||||
The application developer therefore does not need to be concerned with the implementation details or management of the message queue.
|
||||
The application can access the message queue as a service.
|
||||
|
||||
## Architecture
|
||||
|
||||
Service Catalog uses the [Open service broker API](https://github.com/openservicebrokerapi/servicebroker) to communicate with service brokers, acting as an intermediary for the Kubernetes API Server to negotiate the initial provisioning and retrieve the credentials necessary for the application to use a managed service.
|
||||
|
||||
It is implemented using a [CRDs-based](/docs/concepts/extend-kubernetes/api-extension/custom-resources/#custom-resources) architecture.
|
||||
|
||||
<br>
|
||||
|
||||

|
||||
|
||||
|
||||
### API Resources
|
||||
|
||||
Service Catalog installs the `servicecatalog.k8s.io` API and provides the following Kubernetes resources:
|
||||
|
||||
* `ClusterServiceBroker`: An in-cluster representation of a service broker, encapsulating its server connection details.
|
||||
These are created and managed by cluster operators who wish to use that broker server to make new types of managed services available within their cluster.
|
||||
* `ClusterServiceClass`: A managed service offered by a particular service broker.
|
||||
When a new `ClusterServiceBroker` resource is added to the cluster, the Service Catalog controller connects to the service broker to obtain a list of available managed services. It then creates a new `ClusterServiceClass` resource corresponding to each managed service.
|
||||
* `ClusterServicePlan`: A specific offering of a managed service. For example, a managed service may have different plans available, such as a free tier or paid tier, or it may have different configuration options, such as using SSD storage or having more resources. Similar to `ClusterServiceClass`, when a new `ClusterServiceBroker` is added to the cluster, Service Catalog creates a new `ClusterServicePlan` resource corresponding to each Service Plan available for each managed service.
|
||||
* `ServiceInstance`: A provisioned instance of a `ClusterServiceClass`.
|
||||
These are created by cluster operators to make a specific instance of a managed service available for use by one or more in-cluster applications.
|
||||
When a new `ServiceInstance` resource is created, the Service Catalog controller connects to the appropriate service broker and instruct it to provision the service instance.
|
||||
* `ServiceBinding`: Access credentials to a `ServiceInstance`.
|
||||
These are created by cluster operators who want their applications to make use of a `ServiceInstance`.
|
||||
Upon creation, the Service Catalog controller creates a Kubernetes `Secret` containing connection details and credentials for the Service Instance, which can be mounted into Pods.
|
||||
|
||||
### Authentication
|
||||
|
||||
Service Catalog supports these methods of authentication:
|
||||
|
||||
* Basic (username/password)
|
||||
* [OAuth 2.0 Bearer Token](https://tools.ietf.org/html/rfc6750)
|
||||
|
||||
## Usage
|
||||
|
||||
A cluster operator can use Service Catalog API Resources to provision managed services and make them available within a Kubernetes cluster. The steps involved are:
|
||||
|
||||
1. Listing the managed services and Service Plans available from a service broker.
|
||||
1. Provisioning a new instance of the managed service.
|
||||
1. Binding to the managed service, which returns the connection credentials.
|
||||
1. Mapping the connection credentials into the application.
|
||||
|
||||
### Listing managed services and Service Plans
|
||||
|
||||
First, a cluster operator must create a `ClusterServiceBroker` resource within the `servicecatalog.k8s.io` group. This resource contains the URL and connection details necessary to access a service broker endpoint.
|
||||
|
||||
This is an example of a `ClusterServiceBroker` resource:
|
||||
|
||||
```yaml
|
||||
apiVersion: servicecatalog.k8s.io/v1beta1
|
||||
kind: ClusterServiceBroker
|
||||
metadata:
|
||||
name: cloud-broker
|
||||
spec:
|
||||
# Points to the endpoint of a service broker. (This example is not a working URL.)
|
||||
url: https://servicebroker.somecloudprovider.com/v1alpha1/projects/service-catalog/brokers/default
|
||||
#####
|
||||
# Additional values can be added here, which may be used to communicate
|
||||
# with the service broker, such as bearer token info or a caBundle for TLS.
|
||||
#####
|
||||
```
|
||||
|
||||
The following is a sequence diagram illustrating the steps involved in listing managed services and Plans available from a service broker:
|
||||
|
||||

|
||||
|
||||
1. Once the `ClusterServiceBroker` resource is added to Service Catalog, it triggers a call to the external service broker for a list of available services.
|
||||
1. The service broker returns a list of available managed services and a list of Service Plans, which are cached locally as `ClusterServiceClass` and `ClusterServicePlan` resources respectively.
|
||||
1. A cluster operator can then get the list of available managed services using the following command:
|
||||
|
||||
kubectl get clusterserviceclasses -o=custom-columns=SERVICE\ NAME:.metadata.name,EXTERNAL\ NAME:.spec.externalName
|
||||
|
||||
It should output a list of service names with a format similar to:
|
||||
|
||||
SERVICE NAME EXTERNAL NAME
|
||||
4f6e6cf6-ffdd-425f-a2c7-3c9258ad2468 cloud-provider-service
|
||||
... ...
|
||||
|
||||
They can also view the Service Plans available using the following command:
|
||||
|
||||
kubectl get clusterserviceplans -o=custom-columns=PLAN\ NAME:.metadata.name,EXTERNAL\ NAME:.spec.externalName
|
||||
|
||||
It should output a list of plan names with a format similar to:
|
||||
|
||||
PLAN NAME EXTERNAL NAME
|
||||
86064792-7ea2-467b-af93-ac9694d96d52 service-plan-name
|
||||
... ...
|
||||
|
||||
|
||||
### Provisioning a new instance
|
||||
|
||||
A cluster operator can initiate the provisioning of a new instance by creating a `ServiceInstance` resource.
|
||||
|
||||
This is an example of a `ServiceInstance` resource:
|
||||
|
||||
```yaml
|
||||
apiVersion: servicecatalog.k8s.io/v1beta1
|
||||
kind: ServiceInstance
|
||||
metadata:
|
||||
name: cloud-queue-instance
|
||||
namespace: cloud-apps
|
||||
spec:
|
||||
# References one of the previously returned services
|
||||
clusterServiceClassExternalName: cloud-provider-service
|
||||
clusterServicePlanExternalName: service-plan-name
|
||||
#####
|
||||
# Additional parameters can be added here,
|
||||
# which may be used by the service broker.
|
||||
#####
|
||||
```
|
||||
|
||||
The following sequence diagram illustrates the steps involved in provisioning a new instance of a managed service:
|
||||
|
||||

|
||||
|
||||
1. When the `ServiceInstance` resource is created, Service Catalog initiates a call to the external service broker to provision an instance of the service.
|
||||
1. The service broker creates a new instance of the managed service and returns an HTTP response.
|
||||
1. A cluster operator can then check the status of the instance to see if it is ready.
|
||||
|
||||
### Binding to a managed service
|
||||
|
||||
After a new instance has been provisioned, a cluster operator must bind to the managed service to get the connection credentials and service account details necessary for the application to use the service. This is done by creating a `ServiceBinding` resource.
|
||||
|
||||
The following is an example of a `ServiceBinding` resource:
|
||||
|
||||
```yaml
|
||||
apiVersion: servicecatalog.k8s.io/v1beta1
|
||||
kind: ServiceBinding
|
||||
metadata:
|
||||
name: cloud-queue-binding
|
||||
namespace: cloud-apps
|
||||
spec:
|
||||
instanceRef:
|
||||
name: cloud-queue-instance
|
||||
#####
|
||||
# Additional information can be added here, such as a secretName or
|
||||
# service account parameters, which may be used by the service broker.
|
||||
#####
|
||||
```
|
||||
|
||||
The following sequence diagram illustrates the steps involved in binding to a managed service instance:
|
||||
|
||||

|
||||
|
||||
1. After the `ServiceBinding` is created, Service Catalog makes a call to the external service broker requesting the information necessary to bind with the service instance.
|
||||
1. The service broker enables the application permissions/roles for the appropriate service account.
|
||||
1. The service broker returns the information necessary to connect and access the managed service instance. This is provider and service-specific so the information returned may differ between Service Providers and their managed services.
|
||||
|
||||
### Mapping the connection credentials
|
||||
|
||||
After binding, the final step involves mapping the connection credentials and service-specific information into the application.
|
||||
These pieces of information are stored in secrets that the application in the cluster can access and use to connect directly with the managed service.
|
||||
|
||||
<br>
|
||||
|
||||

|
||||
|
||||
#### Pod configuration File
|
||||
|
||||
One method to perform this mapping is to use a declarative Pod configuration.
|
||||
|
||||
The following example describes how to map service account credentials into the application. A key called `sa-key` is stored in a volume named `provider-cloud-key`, and the application mounts this volume at `/var/secrets/provider/key.json`. The environment variable `PROVIDER_APPLICATION_CREDENTIALS` is mapped from the value of the mounted file.
|
||||
|
||||
```yaml
|
||||
...
|
||||
spec:
|
||||
volumes:
|
||||
- name: provider-cloud-key
|
||||
secret:
|
||||
secretName: sa-key
|
||||
containers:
|
||||
...
|
||||
volumeMounts:
|
||||
- name: provider-cloud-key
|
||||
mountPath: /var/secrets/provider
|
||||
env:
|
||||
- name: PROVIDER_APPLICATION_CREDENTIALS
|
||||
value: "/var/secrets/provider/key.json"
|
||||
```
|
||||
|
||||
The following example describes how to map secret values into application environment variables. In this example, the messaging queue topic name is mapped from a secret named `provider-queue-credentials` with a key named `topic` to the environment variable `TOPIC`.
|
||||
|
||||
|
||||
```yaml
|
||||
...
|
||||
env:
|
||||
- name: "TOPIC"
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: provider-queue-credentials
|
||||
key: topic
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
* If you are familiar with {{< glossary_tooltip text="Helm Charts" term_id="helm-chart" >}}, [install Service Catalog using Helm](/docs/tasks/service-catalog/install-service-catalog-using-helm/) into your Kubernetes cluster. Alternatively, you can [install Service Catalog using the SC tool](/docs/tasks/service-catalog/install-service-catalog-using-sc/).
|
||||
* View [sample service brokers](https://github.com/openservicebrokerapi/servicebroker/blob/master/gettingStarted.md#sample-service-brokers).
|
||||
* Explore the [kubernetes-sigs/service-catalog](https://github.com/kubernetes-sigs/service-catalog) project.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ In the `.yaml` file for the Kubernetes object you want to create, you'll need to
|
||||
* `metadata` - Data that helps uniquely identify the object, including a `name` string, `UID`, and optional `namespace`
|
||||
* `spec` - What state you desire for the object
|
||||
|
||||
The precise format of the object `spec` is different for every Kubernetes object, and contains nested fields specific to that object. The [Kubernetes API Reference](https://kubernetes.io/docs/reference/kubernetes-api/) can help you find the spec format for all of the objects you can create using Kubernetes.
|
||||
The precise format of the object `spec` is different for every Kubernetes object, and contains nested fields specific to that object. The [Kubernetes API Reference](/docs/reference/kubernetes-api/) can help you find the spec format for all of the objects you can create using Kubernetes.
|
||||
|
||||
For example, see the [`spec` field](/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodSpec)
|
||||
for the Pod API reference.
|
||||
|
||||
@@ -124,8 +124,8 @@ For example, consider the following Pod spec:
|
||||
|
||||
In this example, the following rules apply:
|
||||
|
||||
* The node *must* have a label with the key `kubernetes.io/os` and
|
||||
the value `linux`.
|
||||
* The node *must* have a label with the key `topology.kubernetes.io/zone` and
|
||||
the value of that label *must* be either `antarctica-east1` or `antarctica-west1`.
|
||||
* The node *preferably* has a label with the key `another-node-label-key` and
|
||||
the value `another-node-label-value`.
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ is a property of {{< glossary_tooltip text="Pods" term_id="pod" >}} that *attrac
|
||||
a set of {{< glossary_tooltip text="nodes" term_id="node" >}} (either as a preference or a
|
||||
hard requirement). _Taints_ are the opposite -- they allow a node to repel a set of pods.
|
||||
|
||||
_Tolerations_ are applied to pods. Tolerations allow the scheduler to schedule pods with matching taints. Tolerations allow scheduling but don't guarantee scheduling: the scheduler also [evaluates other parameters](https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/) as part of its function.
|
||||
_Tolerations_ are applied to pods. Tolerations allow the scheduler to schedule pods with matching taints. Tolerations allow scheduling but don't guarantee scheduling: the scheduler also [evaluates other parameters](/docs/concepts/scheduling-eviction/pod-priority-preemption/) as part of its function.
|
||||
|
||||
Taints and tolerations work together to ensure that pods are not scheduled
|
||||
onto inappropriate nodes. One or more taints are applied to a node; this
|
||||
|
||||
@@ -4,6 +4,7 @@ reviewers:
|
||||
- lavalamp
|
||||
title: Controlling Access to the Kubernetes API
|
||||
content_type: concept
|
||||
weight: 50
|
||||
---
|
||||
|
||||
<!-- overview -->
|
||||
|
||||
+271
@@ -0,0 +1,271 @@
|
||||
---
|
||||
title: Multi-tenancy
|
||||
content_type: concept
|
||||
weight: 70
|
||||
---
|
||||
|
||||
<!-- overview -->
|
||||
|
||||
This page provides an overview of available configuration options and best practices for cluster multi-tenancy.
|
||||
|
||||
Sharing clusters saves costs and simplifies administration. However, sharing clusters also presents challenges such as security, fairness, and managing _noisy neighbors_.
|
||||
|
||||
Clusters can be shared in many ways. In some cases, different applications may run in the same cluster. In other cases, multiple instances of the same application may run in the same cluster, one for each end user. All these types of sharing are frequently described using the umbrella term _multi-tenancy_.
|
||||
|
||||
While Kubernetes does not have first-class concepts of end users or tenants, it provides several features to help manage different tenancy requirements. These are discussed below.
|
||||
|
||||
<!-- body -->
|
||||
## Use cases
|
||||
|
||||
The first step to determining how to share your cluster is understanding your use case, so you can evaluate the patterns and tools available. In general, multi-tenancy in Kubernetes clusters falls into two broad categories, though many variations and hybrids are also possible.
|
||||
|
||||
### Multiple teams
|
||||
|
||||
A common form of multi-tenancy is to share a cluster between multiple teams within an organization, each of whom may operate one or more workloads. These workloads frequently need to communicate with each other, and with other workloads located on the same or different clusters.
|
||||
|
||||
In this scenario, members of the teams often have direct access to Kubernetes resources via tools such as `kubectl`, or indirect access through GitOps controllers or other types of release automation tools. There is often some level of trust between members of different teams, but Kubernetes policies such as RBAC, quotas, and network policies are essential to safely and fairly share clusters.
|
||||
|
||||
### Multiple customers
|
||||
|
||||
The other major form of multi-tenancy frequently involves a Software-as-a-Service (SaaS) vendor running multiple instances of a workload for customers. This business model is so strongly associated with this deployment style that many people call it "SaaS tenancy." However, a better term might be "multi-customer tenancy,” since SaaS vendors may also use other deployment models, and this deployment model can also be used outside of SaaS.
|
||||
|
||||
|
||||
In this scenario, the customers do not have access to the cluster; Kubernetes is invisible from their perspective and is only used by the vendor to manage the workloads. Cost optimization is frequently a critical concern, and Kubernetes policies are used to ensure that the workloads are strongly isolated from each other.
|
||||
|
||||
|
||||
## Terminology
|
||||
|
||||
### Tenants
|
||||
|
||||
When discussing multi-tenancy in Kubernetes, there is no single definition for a "tenant". Rather, the definition of a tenant will vary depending on whether multi-team or multi-customer tenancy is being discussed.
|
||||
|
||||
In multi-team usage, a tenant is typically a team, where each team typically deploys a small number of workloads that scales with the complexity of the service. However, the definition of "team" may itself be fuzzy, as teams may be organized into higher-level divisions or subdivided into smaller teams.
|
||||
|
||||
|
||||
By contrast, if each team deploys dedicated workloads for each new client, they are using a multi-customer model of tenancy. In this case, a "tenant" is simply a group of users who share a single workload. This may be as large as an entire company, or as small as a single team at that company.
|
||||
|
||||
In many cases, the same organization may use both definitions of "tenants" in different contexts. For example, a platform team may offer shared services such as security tools and databases to multiple internal “customers” and a SaaS vendor may also have multiple teams sharing a development cluster. Finally, hybrid architectures are also possible, such as a SaaS provider using a combination of per-customer workloads for sensitive data, combined with multi-tenant shared services.
|
||||
|
||||
|
||||
{{< figure src="/images/docs/multi-tenancy.png" title="A cluster showing coexisting tenancy models" class="diagram-large" >}}
|
||||
|
||||
|
||||
### Isolation
|
||||
|
||||
There are several ways to design and build multi-tenant solutions with Kubernetes. Each of these methods comes with its own set of tradeoffs that impact the isolation level, implementation effort, operational complexity, and cost of service.
|
||||
|
||||
|
||||
A Kubernetes cluster consists of a control plane which runs Kubernetes software, and a data plane consisting of worker nodes where tenant workloads are executed as pods. Tenant isolation can be applied in both the control plane and the data plane based on organizational requirements.
|
||||
|
||||
The level of isolation offered is sometimes described using terms like “hard” multi-tenancy, which implies strong isolation, and “soft” multi-tenancy, which implies weaker isolation. In particular, "hard" multi-tenancy is often used to describe cases where the tenants do not trust each other, often from security and resource sharing perspectives (e.g. guarding against attacks such as data exfiltration or DoS). Since data planes typically have much larger attack surfaces, "hard" multi-tenancy often requires extra attention to isolating the data-plane, though control plane isolation also remains critical.
|
||||
|
||||
However, the terms "hard" and "soft" can often be confusing, as there is no single definition that will apply to all users. Rather, "hardness" or "softness" is better understood as a broad spectrum, with many different techniques that can be used to maintain different types of isolation in your clusters, based on your requirements.
|
||||
|
||||
|
||||
In more extreme cases, it may be easier or necessary to forgo any cluster-level sharing at all and assign each tenant their dedicated cluster, possibly even running on dedicated hardware if VMs are not considered an adequate security boundary. This may be easier with managed Kubernetes clusters, where the overhead of creating and operating clusters is at least somewhat taken on by a cloud provider. The benefit of stronger tenant isolation must be evaluated against the cost and complexity of managing multiple clusters. The [Multi-cluster SIG](https://git.k8s.io/community/sig-multicluster/README.md) is responsible for addressing these types of use cases.
|
||||
|
||||
|
||||
|
||||
The remainder of this page focuses on isolation techniques used for shared Kubernetes clusters. However, even if you are considering dedicated clusters, it may be valuable to review these recommendations, as it will give you the flexibility to shift to shared clusters in the future if your needs or capabilities change.
|
||||
|
||||
|
||||
## Control plane isolation
|
||||
|
||||
Control plane isolation ensures that different tenants cannot access or affect each others' Kubernetes API resources.
|
||||
|
||||
### Namespaces
|
||||
|
||||
In Kubernetes, a {{< glossary_tooltip text="Namespace" term_id="namespace" >}} provides a mechanism for isolating groups of API resources within a single cluster. This isolation has two key dimensions:
|
||||
|
||||
1. Object names within a namespace can overlap with names in other namespaces, similar to files in folders. This allows tenants to name their resources without having to consider what other tenants are doing.
|
||||
|
||||
2. Many Kubernetes security policies are scoped to namespaces. For example, RBAC Roles and Network Policies are namespace-scoped resources. Using RBAC, Users and Service Accounts can be restricted to a namespace.
|
||||
|
||||
In a multi-tenant environment, a Namespace helps segment a tenant's workload into a logical and distinct management unit. In fact, a common practice is to isolate every workload in its own namespace, even if multiple workloads are operated by the same tenant. This ensures that each workload has its own identity and can be configured with an appropriate security policy.
|
||||
|
||||
The namespace isolation model requires configuration of several other Kubernetes resources, networking plugins, and adherence to security best practices to properly isolate tenant workloads. These considerations are discussed below.
|
||||
|
||||
### Access controls
|
||||
|
||||
The most important type of isolation for the control plane is authorization. If teams or their workloads can access or modify each others' API resources, they can change or disable all other types of policies thereby negating any protection those policies may offer. As a result, it is critical to ensure that each tenant has the appropriate access to only the namespaces they need, and no more. This is known as the "Principle of Least Privilege."
|
||||
|
||||
|
||||
Role-based access control (RBAC) is commonly used to enforce authorization in the Kubernetes control plane, for both users and workloads (service accounts). [Roles](/docs/reference/access-authn-authz/rbac/#role-and-clusterrole) and [role bindings](/docs/reference/access-authn-authz/rbac/#rolebinding-and-clusterrolebinding) are Kubernetes objects that are used at a namespace level to enforce access control in your application; similar objects exist for authorizing access to cluster-level objects, though these are less useful for multi-tenant clusters.
|
||||
|
||||
In a multi-team environment, RBAC must be used to restrict tenants' access to the appropriate namespaces, and ensure that cluster-wide resources can only be accessed or modified by privileged users such as cluster administrators.
|
||||
|
||||
If a policy ends up granting a user more permissions than they need, this is likely a signal that the namespace containing the affected resources should be refactored into finer-grained namespaces. Namespace management tools may simplify the management of these finer-grained namespaces by applying common RBAC policies to different namespaces, while still allowing fine-grained policies where necessary.
|
||||
|
||||
### Quotas
|
||||
|
||||
Kubernetes workloads consume node resources, like CPU and memory. In a multi-tenant environment, you can use
|
||||
[Resource Quotas](/docs/concepts/policy/resource-quotas/) to manage resource usage of tenant workloads.
|
||||
For the multiple teams use case, where tenants have access to the Kubernetes API, you can use resource quotas
|
||||
to limit the number of API resources (for example: the number of Pods, or the number of ConfigMaps)
|
||||
that a tenant can create. Limits on object count ensure fairness and aim to avoid _noisy neighbor_ issues from
|
||||
affecting other tenants that share a control plane.
|
||||
|
||||
Resource quotas are namespaced objects. By mapping tenants to namespaces, cluster admins can use quotas to ensure that a tenant cannot monopolize a cluster's resources or overwhelm its control plane. Namespace management tools simplify the administration of quotas. In addition, while Kubernetes quotas only apply within a single namespace, some namespace management tools allow groups of namespaces to share quotas, giving administrators far more flexibility with less effort than built-in quotas.
|
||||
|
||||
Quotas prevent a single tenant from consuming greater than their allocated share of resources hence minimizing the “noisy neighbor” issue, where one tenant negatively impacts the performance of other tenants' workloads.
|
||||
|
||||
When you apply a quota to namespace, Kubernetes requires you to also specify resource requests and limits for each container. Limits are the upper bound for the amount of resources that a container can consume. Containers that attempt to consume resources that exceed the configured limits will either be throttled or killed, based on the resource type. When resource requests are set lower than limits, each container is guaranteed the requested amount but there may still be some potential for impact across workloads.
|
||||
|
||||
Quotas cannot protect against all kinds of resource sharing, such as network traffic. Node isolation (described below) may be a better solution for this problem.
|
||||
|
||||
## Data Plane Isolation
|
||||
|
||||
Data plane isolation ensures that pods and workloads for different tenants are sufficiently isolated.
|
||||
|
||||
### Network isolation
|
||||
|
||||
By default, all pods in a Kubernetes cluster are allowed to communicate with each other, and all network traffic is unencrypted. This can lead to security vulnerabilities where traffic is accidentally or maliciously sent to an unintended destination, or is intercepted by a workload on a compromised node.
|
||||
|
||||
Pod-to-pod communication can be controlled using [Network Policies](/docs/concepts/services-networking/network-policies/), which restrict communication between pods using namespace labels or IP address ranges. In a multi-tenant environment where strict network isolation between tenants is required, starting with a default policy that denies communication between pods is recommended with another rule that allows all pods to query the DNS server for name resolution. With such a default policy in place, you can begin adding more permissive rules that allow for communication within a namespace. This scheme can be further refined as required. Note that this only applies to pods within a single control plane; pods that belong to different virtual control planes cannot talk to each other via Kubernetes networking.
|
||||
|
||||
Namespace management tools may simplify the creation of default or common network policies. In addition, some of these tools allow you to enforce a consistent set of namespace labels across your cluster, ensuring that they are a trusted basis for your policies.
|
||||
|
||||
{{< warning >}}
|
||||
Network policies require a [CNI plugin](/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/#cni) that supports the implementation of network policies. Otherwise, NetworkPolicy resources will be ignored.
|
||||
{{< /warning >}}
|
||||
|
||||
More advanced network isolation may be provided by service meshes, which provide OSI Layer 7 policies based on workload identity, in addition to namespaces. These higher-level policies can make it easier to manage namespaced based multi-tenancy, especially when multiple namespaces are dedicated to a single tenant. They frequently also offer encryption using mutual TLS, protecting your data even in the presence of a compromised node, and work across dedicated or virtual clusters. However, they can be significantly more complex to manage and may not be appropriate for all users.
|
||||
|
||||
### Storage isolation
|
||||
|
||||
Kubernetes offers several types of volumes that can be used as persistent storage for workloads. For security and data-isolation, [dynamic volume provisioning](/docs/concepts/storage/dynamic-provisioning/) is recommended and volume types that use node resources should be avoided.
|
||||
|
||||
[StorageClasses](/docs/concepts/storage/storage-classes/) allow you to describe custom "classes" of storage offered by your cluster, based on quality-of-service levels, backup policies, or custom policies determined by the cluster administrators.
|
||||
|
||||
Pods can request storage using a [PersistentVolumeClaim](/docs/concepts/storage/persistent-volumes/). A PersistentVolumeClaim is a namespaced resource, which enables isolating portions of the storage system and dedicating it to tenants within the shared Kubernetes cluster. However, it is important to note that a PersistentVolume is a cluster-wide resource and has a lifecycle independent of workloads and namespaces.
|
||||
|
||||
For example, you can configure a separate StorageClass for each tenant and use this to strengthen isolation.
|
||||
If a StorageClass is shared, you should set a [reclaim policy of `Delete`](/docs/concepts/storage/storage-classes/#reclaim-policy)
|
||||
to ensure that a PersistentVolume cannot be reused across different namespaces.
|
||||
|
||||
### Sandboxing containers
|
||||
|
||||
{{% thirdparty-content %}}
|
||||
|
||||
Kubernetes pods are composed of one or more containers that execute on worker nodes. Containers utilize OS-level virtualization and hence offer a weaker isolation boundary than virtual machines that utilize hardware-based virtualization.
|
||||
|
||||
In a shared environment, unpatched vulnerabilities in the application and system layers can be exploited by attackers for container breakouts and remote code execution that allow access to host resources. In some applications, like a Content Management System (CMS), customers may be allowed the ability to upload and execute untrusted scripts or code. In either case, mechanisms to further isolate and protect workloads using strong isolation are desirable.
|
||||
|
||||
Sandboxing provides a way to isolate workloads running in a shared cluster. It typically involves running each pod in a separate execution environment such as a virtual machine or a userspace kernel. Sandboxing is often recommended when you are running untrusted code, where workloads are assumed to be malicious. Part of the reason this type of isolation is necessary is because containers are processes running on a shared kernel; they mount file systems like /sys and /proc from the underlying host, making them less secure than an application that runs on a virtual machine which has its own kernel. While controls such as seccomp, AppArmor, and SELinux can be used to strengthen the security of containers, it is hard to apply a universal set of rules to all workloads running in a shared cluster. Running workloads in a sandbox environment helps to insulate the host from container escapes, where an attacker exploits a vulnerability to gain access to the host system and all the processes/files running on that host.
|
||||
|
||||
Virtual machines and userspace kernels are 2 popular approaches to sandboxing. The following sandboxing implementations are available:
|
||||
* [gVisor](https://gvisor.dev/) intercepts syscalls from containers and runs them through a userspace kernel, written in Go, with limited access to the underlying host.
|
||||
* [Kata Containers](https://katacontainers.io/) is an OCI compliant runtime that allows you to run containers in a VM. The hardware virtualization available in Kata offers an added layer of security for containers running untrusted code.
|
||||
|
||||
### Node Isolation
|
||||
|
||||
Node isolation is another technique that you can use to isolate tenant workloads from each other. With node isolation, a set of nodes is dedicated to running pods from a particular tenant and co-mingling of tenant pods is prohibited. This configuration reduces the noisy tenant issue, as all pods running on a node will belong to a single tenant. The risk of information disclosure is slightly lower with node isolation because an attacker that manages to escape from a container will only have access to the containers and volumes mounted to that node.
|
||||
|
||||
Although workloads from different tenants are running on different nodes, it is important to be aware that the kubelet and (unless using virtual control planes) the API service are still shared services. A skilled attacker could use the permissions assigned to the kubelet or other pods running on the node to move laterally within the cluster and gain access to tenant workloads running on other nodes. If this is a major concern, consider implementing compensating controls such as seccomp, AppArmor or SELinux or explore using sandboxed containers or creating separate clusters for each tenant.
|
||||
|
||||
Node isolation is a little easier to reason about from a billing standpoint than sandboxing containers since you can charge back per node rather than per pod. It also has fewer compatibility and performance issues and may be easier to implement than sandboxing containers. For example, nodes for each tenant can be configured with taints so that only pods with the corresponding toleration can run on them. A mutating webhook could then be used to automatically add tolerations and node affinities to pods deployed into tenant namespaces so that they run on a specific set of nodes designated for that tenant.
|
||||
|
||||
Node isolation can be implemented using an [pod node selectors](/docs/concepts/scheduling-eviction/assign-pod-node/) or a [Virtual Kubelet](https://github.com/virtual-kubelet).
|
||||
|
||||
## Additional Considerations
|
||||
|
||||
This section discusses other Kubernetes constructs and patterns that are relevant for multi-tenancy.
|
||||
|
||||
### API Priority and Fairness
|
||||
|
||||
[API priority and fairness](/docs/concepts/cluster-administration/flow-control/) is a Kubernetes feature that allows you to assign a priority to certain pods running within the cluster. When an application calls the Kubernetes API, the API server evaluates the priority assigned to pod. Calls from pods with higher priority are fulfilled before those with a lower priority. When contention is high, lower priority calls can be queued until the server is less busy or you can reject the requests.
|
||||
|
||||
Using API priority and fairness will not be very common in SaaS environments unless you are allowing customers to run applications that interface with the Kubernetes API, e.g. a controller.
|
||||
|
||||
### Quality-of-Service (QoS) {#qos}
|
||||
|
||||
When you’re running a SaaS application, you may want the ability to offer different Quality-of-Service (QoS) tiers of service to different tenants. For example, you may have freemium service that comes with fewer performance guarantees and features and a for-fee service tier with specific performance guarantees. Fortunately, there are several Kubernetes constructs that can help you accomplish this within a shared cluster, including network QoS, storage classes, and pod priority and preemption. The idea with each of these is to provide tenants with the quality of service that they paid for. Let’s start by looking at networking QoS.
|
||||
|
||||
Typically, all pods on a node share a network interface. Without network QoS, some pods may consume an unfair share of the available bandwidth at the expense of other pods. The Kubernetes [bandwidth plugin](https://www.cni.dev/plugins/current/meta/bandwidth/) creates an [extended resource](/docs/concepts/configuration/manage-resources-containers/#extended-resources) for networking that allows you to use Kubernetes resources constructs, i.e. requests/limits, to apply rate limits to pods by using Linux tc queues. Be aware that the plugin is considered experimental as per the [Network Plugins](/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/#support-traffic-shaping) documentation and should be thoroughly tested before use in production environments.
|
||||
|
||||
For storage QoS, you will likely want to create different storage classes or profiles with different performance characteristics. Each storage profile can be associated with a different tier of service that is optimized for different workloads such IO, redundancy, or throughput. Additional logic might be necessary to allow the tenant to associate the appropriate storage profile with their workload.
|
||||
|
||||
Finally, there’s [pod priority and preemption](/docs/concepts/scheduling-eviction/pod-priority-preemption/) where you can assign priority values to pods. When scheduling pods, the scheduler will try evicting pods with lower priority when there are insufficient resources to schedule pods that are assigned a higher priority. If you have a use case where tenants have different service tiers in in a shared cluster e.g. free and paid, you may want to give higher priority to certain tiers using this feature.
|
||||
|
||||
### DNS
|
||||
|
||||
Kubernetes clusters include a Domain Name System (DNS) service to provide translations from names to IP addresses, for all Services and Pods. By default, the Kubernetes DNS service allows lookups across all namespaces in the cluster.
|
||||
|
||||
In multi-tenant environments where tenants can access pods and other Kubernetes resources, or where
|
||||
stronger isolation is required, it may be necessary to prevent pods from looking up services in other
|
||||
Namespaces.
|
||||
You can restrict cross-namespace DNS lookups by configuring security rules for the DNS service.
|
||||
For example, CoreDNS (the default DNS service for Kubernetes) can leverage Kubernetes metadata
|
||||
to restrict queries to Pods and Services within a namespace. For more information, read an
|
||||
[example](https://github.com/coredns/policy#kubernetes-metadata-multi-tenancy-policy) of configuring
|
||||
this within the CoreDNS documentation.
|
||||
|
||||
When a [Virtual Control Plane per tenant](#virtual-control-plane-per-tenant) model is used, a DNS service must be configured per tenant or a multi-tenant DNS service must be used. Here is an example of a [customized version of CoreDNS](https://github.com/kubernetes-sigs/cluster-api-provider-nested/blob/main/virtualcluster/doc/tenant-dns.md) that supports multiple tenants.
|
||||
|
||||
### Operators
|
||||
|
||||
[Operators](/docs/concepts/extend-kubernetes/operator/) are Kubernetes controllers that manage applications. Operators can simplify the management of multiple instances of an application, like a database service, which makes them a common building block in the multi-consumer (SaaS) multi-tenancy use case.
|
||||
|
||||
Operators used in a multi-tenant environment should follow a stricter set of guidelines. Specifically, the Operator should:
|
||||
* Support creating resources within different tenant namespaces, rather than just in the namespace in which the Operator is deployed.
|
||||
* Ensure that the Pods are configured with resource requests and limits, to ensure scheduling and fairness.
|
||||
* Support configuration of Pods for data-plane isolation techniques such as node isolation and sandboxed containers.
|
||||
|
||||
## Implementations
|
||||
|
||||
{{% thirdparty-content %}}
|
||||
|
||||
There are two primary ways to share a Kubernetes cluster for multi-tenancy: using Namespaces (i.e. a Namespace per tenant) or by virtualizing the control plane (i.e. Virtual control plane per tenant).
|
||||
|
||||
In both cases, data plane isolation, and management of additional considerations such as API Priority and Fairness, is also recommended.
|
||||
|
||||
Namespace isolation is well-supported by Kubernetes, has a negligible resource cost, and provides mechanisms to allow tenants to interact appropriately, such as by allowing service-to-service communication. However, it can be difficult to configure, and doesn't apply to Kubernetes resources that can't be namespaced, such as Custom Resource Definitions, Storage Classes, and Webhooks.
|
||||
|
||||
Control plane virtualization allows for isolation of non-namespaced resources at the cost of somewhat higher resource usage and more difficult cross-tenant sharing. It is a good option when namespace isolation is insufficient but dedicated clusters are undesirable, due to the high cost of maintaining them (especially on-prem) or due to their higher overhead and lack of resource sharing. However, even within a virtualized control plane, you will likely see benefits by using namespaces as well.
|
||||
|
||||
The two options are discussed in more detail in the following sections:
|
||||
|
||||
### Namespace per tenant
|
||||
|
||||
As previously mentioned, you should consider isolating each workload in its own namespace, even if you are using dedicated clusters or virtualized control planes. This ensures that each workload only has access to its own resources, such as Config Maps and Secrets, and allows you to tailor dedicated security policies for each workload. In addition, it is a best practice to give each namespace names that are unique across your entire fleet (i.e., even if they are in separate clusters), as this gives you the flexibility to switch between dedicated and shared clusters in the future, or to use multi-cluster tooling such as service meshes.
|
||||
|
||||
Conversely, there are also advantages to assigning namespaces at the tenant level, not just the workload level, since there are often policies that apply to all workloads owned by a single tenant. However, this raises its own problems. Firstly, this makes it difficult or impossible to customize policies to individual workloads, and secondly, it may be challenging to come up with a single level of "tenancy" that should be given a namespace. For example, an organization may have divisions, teams, and subteams - which should be assigned a namespace?
|
||||
|
||||
To solve this, Kubernetes provides the [Hierarchical Namespace Controller (HNC)](https://github.com/kubernetes-sigs/hierarchical-namespaces), which allows you to organize your namespaces into hierarchies, and share certain policies and resources between them. It also helps you manage namespace labels, namespace lifecycles, and delegated management, and share resource quotas across related namespaces. These capabilities can be useful in both multi-team and multi-customer scenarios.
|
||||
|
||||
Other projects that provide similar capabilities and aid in managing namespaced resources are listed below:
|
||||
|
||||
#### Multi-team tenancy
|
||||
|
||||
* [Capsule](https://github.com/clastix/capsule)
|
||||
* [Kiosk](https://github.com/loft-sh/kiosk)
|
||||
|
||||
#### Multi-customer tenancy
|
||||
|
||||
* [Kubeplus](https://github.com/cloud-ark/kubeplus)
|
||||
|
||||
#### Policy engines
|
||||
|
||||
Policy engines provide features to validate and generate tenant configurations:
|
||||
|
||||
* [Kyverno](https://kyverno.io/)
|
||||
* [OPA/Gatekeeper](https://github.com/open-policy-agent/gatekeeper)
|
||||
|
||||
### Virtual control plane per tenant
|
||||
|
||||
Another form of control-plane isolation is to use Kubernetes extensions to provide each tenant a virtual control-plane that enables segmentation of cluster-wide API resources. [Data plane isolation](#data-plane-isolation) techniques can be used with this model to securely manage worker nodes across tenants.
|
||||
|
||||
The virtual control plane based multi-tenancy model extends namespace-based multi-tenancy by providing each tenant with dedicated control plane components, and hence complete control over cluster-wide resources and add-on services. Worker nodes are shared across all tenants, and are managed by a Kubernetes cluster that is normally inaccessible to tenants. This cluster is often referred to as a _super-cluster_ (or sometimes as a _host-cluster_). Since a tenant’s control-plane is not directly associated with underlying compute resources it is referred to as a _virtual control plane_.
|
||||
|
||||
A virtual control plane typically consists of the Kubernetes API server, the controller manager, and the etcd data store. It interacts with the super cluster via a metadata synchronization controller which coordinates changes across tenant control planes and the control plane of the super--cluster.
|
||||
|
||||
By using per-tenant dedicated control planes, most of the isolation problems due to sharing one API server among all tenants are solved. Examples include noisy neighbors in the control plane, uncontrollable blast radius of policy misconfigurations, and conflicts between cluster scope objects such as webhooks and CRDs. Hence, the virtual control plane model is particularly suitable for cases where each tenant requires access to a Kubernetes API server and expects the full cluster manageability.
|
||||
|
||||
The improved isolation comes at the cost of running and maintaining an individual virtual control plane per tenant. In addition, per-tenant control planes do not solve isolation problems in the data plane, such as node-level noisy neighbors or security threats. These must still be addressed separately.
|
||||
|
||||
The Kubernetes [Cluster API - Nested (CAPN)](https://github.com/kubernetes-sigs/cluster-api-provider-nested/tree/main/virtualcluster) project provides an implementation of virtual control planes.
|
||||
|
||||
#### Other implementations
|
||||
* [Kamaji](https://github.com/clastix/kamaji)
|
||||
* [vcluster](https://github.com/loft-sh/vcluster)
|
||||
|
||||
@@ -4,6 +4,7 @@ title: Role Based Access Control Good Practices
|
||||
description: >
|
||||
Principles and practices for good RBAC design for cluster operators.
|
||||
content_type: concept
|
||||
weight: 60
|
||||
---
|
||||
|
||||
<!-- overview -->
|
||||
|
||||
@@ -6,7 +6,7 @@ reviewers:
|
||||
- perithompson
|
||||
title: Security For Windows Nodes
|
||||
content_type: concept
|
||||
weight: 75
|
||||
weight: 40
|
||||
---
|
||||
|
||||
<!-- overview -->
|
||||
|
||||
@@ -207,7 +207,7 @@ because then the scheduler is free to choose a suitable node for
|
||||
the Pod. With immediate binding, the scheduler is forced to select a node that has
|
||||
access to the volume once it is available.
|
||||
|
||||
In terms of [resource ownership](/docs/concepts/workloads/controllers/garbage-collection/#owners-and-dependents),
|
||||
In terms of [resource ownership](/docs/concepts/workloads/controllers/garbage-collection/#owners-dependents),
|
||||
a Pod that has generic ephemeral storage is the owner of the PersistentVolumeClaim(s)
|
||||
that provide that ephemeral storage. When the Pod is deleted,
|
||||
the Kubernetes garbage collector deletes the PVC, which then usually
|
||||
|
||||
@@ -121,7 +121,7 @@ section refers to several key workload abstractions and how they map to Windows.
|
||||
In the above list, wildcards (`*`) indicate all elements in a list.
|
||||
For example, `spec.containers[*].securityContext` refers to the SecurityContext object
|
||||
for all containers. If any of these fields is specified, the Pod will
|
||||
not be admited by the API server.
|
||||
not be admitted by the API server.
|
||||
|
||||
* [Workload resources](/docs/concepts/workloads/controllers/) including:
|
||||
* ReplicaSet
|
||||
|
||||
@@ -307,4 +307,4 @@ spec:
|
||||
app: iis-2019
|
||||
```
|
||||
|
||||
[RuntimeClass]: https://kubernetes.io/docs/concepts/containers/runtime-class/
|
||||
[RuntimeClass]: /docs/concepts/containers/runtime-class/
|
||||
|
||||
@@ -417,5 +417,5 @@ You can use [Descheduler](https://github.com/kubernetes-sigs/descheduler) to reb
|
||||
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
- [Blog: Introducing PodTopologySpread](https://kubernetes.io/blog/2020/05/introducing-podtopologyspread/)
|
||||
- [Blog: Introducing PodTopologySpread](/blog/2020/05/introducing-podtopologyspread/)
|
||||
explains `maxSkew` in details, as well as bringing up some advanced usage examples.
|
||||
|
||||
@@ -145,7 +145,7 @@ class first,second white
|
||||
{{</ mermaid >}}
|
||||
Figure 2. Preparation for your first contribution.
|
||||
|
||||
- Read the [Contribution overview](/docs/contribute/new-content/overview/) to
|
||||
- Read the [Contribution overview](/docs/contribute/new-content/) to
|
||||
learn about the different ways you can contribute.
|
||||
- Check [`kubernetes/website` issues list](https://github.com/kubernetes/website/issues/)
|
||||
for issues that make good entry points.
|
||||
|
||||
@@ -8,7 +8,7 @@ weight: 98
|
||||
<!-- overview -->
|
||||
|
||||
This page assumes that you understand how to
|
||||
[contribute to new content](/docs/contribute/new-content/overview) and
|
||||
[contribute to new content](/docs/contribute/new-content/) and
|
||||
[review others' work](/docs/contribute/review/reviewing-prs/), and are ready
|
||||
to learn about more ways to contribute. You need to use the Git command line
|
||||
client and other tools for some of these tasks.
|
||||
|
||||
@@ -13,14 +13,19 @@ card:
|
||||
|
||||
<!-- overview -->
|
||||
|
||||
This page shows you how to [localize](https://blog.mozilla.org/l10n/2011/12/14/i18n-vs-l10n-whats-the-diff/) the docs for a different language.
|
||||
This page shows you how to
|
||||
[localize](https://blog.mozilla.org/l10n/2011/12/14/i18n-vs-l10n-whats-the-diff/) the docs for a
|
||||
different language.
|
||||
|
||||
|
||||
<!-- body -->
|
||||
|
||||
## Contribute to an existing localization
|
||||
|
||||
You can help add or improve content to an existing localization. In [Kubernetes Slack](https://slack.k8s.io/) you'll find a channel for each localization. There is also a general [SIG Docs Localizations Slack channel](https://kubernetes.slack.com/messages/sig-docs-localizations) where you can say hello.
|
||||
You can help add or improve content to an existing localization. In [Kubernetes
|
||||
Slack](https://slack.k8s.io/) you'll find a channel for each localization. There is also a general
|
||||
[SIG Docs Localizations Slack channel](https://kubernetes.slack.com/messages/sig-docs-localizations)
|
||||
where you can say hello.
|
||||
|
||||
{{< note >}}
|
||||
If you want to work on a localization that already exists, check
|
||||
@@ -30,11 +35,14 @@ English original. You might see extra details there.
|
||||
|
||||
### Find your two-letter language code
|
||||
|
||||
First, consult the [ISO 639-1 standard](https://www.loc.gov/standards/iso639-2/php/code_list.php) to find your localization's two-letter language code. For example, the two-letter code for Korean is `ko`.
|
||||
First, consult the [ISO 639-1 standard](https://www.loc.gov/standards/iso639-2/php/code_list.php)
|
||||
to find your localization's two-letter language code. For example, the two-letter code for Korean
|
||||
is `ko`.
|
||||
|
||||
### Fork and clone the repo
|
||||
|
||||
First, [create your own fork](/docs/contribute/new-content/open-a-pr/#fork-the-repo) of the [kubernetes/website](https://github.com/kubernetes/website) repository.
|
||||
First, [create your own fork](/docs/contribute/new-content/open-a-pr/#fork-the-repo) of the
|
||||
[kubernetes/website](https://github.com/kubernetes/website) repository.
|
||||
|
||||
Then, clone your fork and `cd` into it:
|
||||
|
||||
@@ -43,7 +51,8 @@ git clone https://github.com/<username>/website
|
||||
cd website
|
||||
```
|
||||
|
||||
The website content directory includes sub-directories for each language. The localization you want to help out with is inside `content/<two-letter-code>`.
|
||||
The website content directory includes sub-directories for each language. The localization you
|
||||
want to help out with is inside `content/<two-letter-code>`.
|
||||
|
||||
### Suggest changes
|
||||
|
||||
@@ -57,8 +66,9 @@ equivalent fix by updating the localization you're working on.
|
||||
Please limit pull requests to a single localization, since pull requests that change
|
||||
content in multiple localizations could be difficult to review.
|
||||
|
||||
Follow [Suggesting Content Improvements](/docs/contribute/suggest-improvements/) to propose changes to
|
||||
that localization. The process is very similar to proposing changes to the upstream (English) content.
|
||||
Follow [Suggesting Content Improvements](/docs/contribute/suggesting-improvements/)
|
||||
to propose changes to that localization. The process is very similar to proposing changes to the
|
||||
upstream (English) content.
|
||||
|
||||
## Start a new localization
|
||||
|
||||
@@ -86,40 +96,62 @@ can incrementally work towards that goal.
|
||||
|
||||
### Find community
|
||||
|
||||
Let Kubernetes SIG Docs know you're interested in creating a localization! Join the [SIG Docs Slack channel](https://kubernetes.slack.com/messages/sig-docs) and the [SIG Docs Localizations Slack channel](https://kubernetes.slack.com/messages/sig-docs-localizations). Other localization teams are happy to help you get started and answer any questions you have.
|
||||
Let Kubernetes SIG Docs know you're interested in creating a localization! Join the
|
||||
[SIG Docs Slack channel](https://kubernetes.slack.com/messages/sig-docs) and the
|
||||
[SIG Docs Localizations Slack channel](https://kubernetes.slack.com/messages/sig-docs-localizations).
|
||||
Other localization teams are happy to help you get started and answer any questions you have.
|
||||
|
||||
Please also consider participating in the [SIG Docs Localization Subgroup meeting](https://github.com/kubernetes/community/tree/master/sig-docs). The mission of the SIG Docs localization subgroup is to work across the SIG Docs localization teams to collaborate on defining and documenting the processes for creating localized contribution guides. In addition, the SIG Docs localization subgroup will look for opportunities for the creation and sharing of common tools across localization teams and also serve to identify new requirements to the SIG Docs Leadership team. If you have questions about this meeting, please inquire on the [SIG Docs Localizations Slack channel](https://kubernetes.slack.com/messages/sig-docs-localizations).
|
||||
Please also consider participating in the
|
||||
[SIG Docs Localization Subgroup meeting](https://github.com/kubernetes/community/tree/master/sig-docs).
|
||||
The mission of the SIG Docs localization subgroup is to work across the SIG Docs localization
|
||||
teams to collaborate on defining and documenting the processes for creating localized contribution
|
||||
guides. In addition, the SIG Docs localization subgroup will look for opportunities for the
|
||||
creation and sharing of common tools across localization teams and also serve to identify new
|
||||
requirements to the SIG Docs Leadership team. If you have questions about this meeting, please
|
||||
inquire on the [SIG Docs Localizations Slack channel](https://kubernetes.slack.com/messages/sig-docs-localizations).
|
||||
|
||||
You can also create a Slack channel for your localization in the `kubernetes/community` repository. For an example of adding a Slack channel, see the PR for [adding a channel for Persian](https://github.com/kubernetes/community/pull/4980).
|
||||
You can also create a Slack channel for your localization in the `kubernetes/community`
|
||||
repository. For an example of adding a Slack channel, see the PR for
|
||||
[adding a channel for Persian](https://github.com/kubernetes/community/pull/4980).
|
||||
|
||||
### Join the Kubernetes GitHub organization
|
||||
|
||||
Once you've opened a localization PR, you can become members of the Kubernetes GitHub organization. Each person on the team needs to create their own [Organization Membership Request](https://github.com/kubernetes/org/issues/new/choose) in the `kubernetes/org` repository.
|
||||
Once you've opened a localization PR, you can become members of the Kubernetes GitHub
|
||||
organization. Each person on the team needs to create their own
|
||||
[Organization Membership Request](https://github.com/kubernetes/org/issues/new/choose)
|
||||
in the `kubernetes/org` repository.
|
||||
|
||||
### Add your localization team in GitHub
|
||||
|
||||
Next, add your Kubernetes localization team to [`sig-docs/teams.yaml`](https://github.com/kubernetes/org/blob/main/config/kubernetes/sig-docs/teams.yaml). For an example of adding a localization team, see the PR to add the [Spanish localization team](https://github.com/kubernetes/org/pull/685).
|
||||
|
||||
Members of `@kubernetes/sig-docs-**-owners` can approve PRs that change content within (and only within) your localization directory: `/content/**/`.
|
||||
|
||||
For each localization, The `@kubernetes/sig-docs-**-reviews` team automates review assignment for new PRs.
|
||||
Next, add your Kubernetes localization team to
|
||||
[`sig-docs/teams.yaml`](https://github.com/kubernetes/org/blob/main/config/kubernetes/sig-docs/teams.yaml).
|
||||
For an example of adding a localization team, see the PR to add the
|
||||
[Spanish localization team](https://github.com/kubernetes/org/pull/685).
|
||||
|
||||
Members of `@kubernetes/sig-docs-**-owners` can approve PRs that change content within (and only
|
||||
within) your localization directory: `/content/**/`.
|
||||
For each localization, The `@kubernetes/sig-docs-**-reviews` team automates review assignment for
|
||||
new PRs.
|
||||
Members of `@kubernetes/website-maintainers` can create new localization branches to coordinate translation efforts.
|
||||
|
||||
Members of `@kubernetes/website-milestone-maintainers` can use the `/milestone` [Prow command](https://prow.k8s.io/command-help) to assign a milestone to issues or PRs.
|
||||
Members of `@kubernetes/website-milestone-maintainers` can use the `/milestone`
|
||||
[Prow command](https://prow.k8s.io/command-help) to assign a milestone to issues or PRs.
|
||||
|
||||
### Configure the workflow
|
||||
|
||||
Next, add a GitHub label for your localization in the `kubernetes/test-infra` repository. A label lets you filter issues and pull requests for your specific language.
|
||||
|
||||
For an example of adding a label, see the PR for adding the [Italian language label](https://github.com/kubernetes/test-infra/pull/11316).
|
||||
Next, add a GitHub label for your localization in the `kubernetes/test-infra` repository. A label
|
||||
lets you filter issues and pull requests for your specific language.
|
||||
|
||||
For an example of adding a label, see the PR for adding the
|
||||
[Italian language label](https://github.com/kubernetes/test-infra/pull/11316).
|
||||
|
||||
### Modify the site configuration
|
||||
|
||||
The Kubernetes website uses Hugo as its web framework. The website's Hugo configuration resides in the [`config.toml`](https://github.com/kubernetes/website/tree/main/config.toml) file. To support a new localization, you'll need to modify `config.toml`.
|
||||
The Kubernetes website uses Hugo as its web framework. The website's Hugo configuration resides in
|
||||
the [`config.toml`](https://github.com/kubernetes/website/tree/main/config.toml) file.
|
||||
To support a new localization, you'll need to modify `config.toml`.
|
||||
|
||||
Add a configuration block for the new language to `config.toml`, under the existing `[languages]` block. The German block, for example, looks like:
|
||||
Add a configuration block for the new language to `config.toml`, under the existing `[languages]` block.
|
||||
The German block, for example, looks like:
|
||||
|
||||
```toml
|
||||
[languages.de]
|
||||
@@ -131,17 +163,25 @@ contentDir = "content/de"
|
||||
weight = 8
|
||||
```
|
||||
|
||||
The value for `languageName` will be listed in language selection bar. Assign "language name in native script and language (English language name in latin script)" to `languageName`. For example, `languageName = "한국어 (Korean)"` or `languageName = "Deutsch (German)"`.
|
||||
The value for `languageName` will be listed in language selection bar. Assign "language name in
|
||||
native script and language (English language name in latin script)" to `languageName`.
|
||||
For example, `languageName = "한국어 (Korean)"` or `languageName = "Deutsch (German)"`.
|
||||
|
||||
`languageNameLatinScript` can be used to access the language name in latin script and use it in the theme. Assign "language name in latin script" to `languageNameLatinScript`. For example, `languageNameLatinScript ="Korean"` or `languageNameLatinScript = "Deutsch"`.
|
||||
`languageNameLatinScript` can be used to access the language name in latin script and use it in
|
||||
the theme. Assign "language name in latin script" to `languageNameLatinScript`. For example,
|
||||
`languageNameLatinScript ="Korean"` or `languageNameLatinScript = "Deutsch"`.
|
||||
|
||||
When assigning a `weight` parameter for your block, find the language block with the highest weight and add 1 to that value.
|
||||
When assigning a `weight` parameter for your block, find the language block with the highest
|
||||
weight and add 1 to that value.
|
||||
|
||||
For more information about Hugo's multilingual support, see "[Multilingual Mode](https://gohugo.io/content-management/multilingual/)".
|
||||
For more information about Hugo's multilingual support, see
|
||||
"[Multilingual Mode](https://gohugo.io/content-management/multilingual/)".
|
||||
|
||||
### Add a new localization directory
|
||||
|
||||
Add a language-specific subdirectory to the [`content`](https://github.com/kubernetes/website/tree/main/content) folder in the repository. For example, the two-letter code for German is `de`:
|
||||
Add a language-specific subdirectory to the
|
||||
[`content`](https://github.com/kubernetes/website/tree/main/content) folder in the repository.
|
||||
For example, the two-letter code for German is `de`:
|
||||
|
||||
```shell
|
||||
mkdir content/de
|
||||
@@ -151,28 +191,34 @@ You also need to create a directory inside `data/i18n` for
|
||||
[localized strings](#site-strings-in-i18n); look at existing localizations
|
||||
for an example. To use these new strings, you must also create a symbolic link
|
||||
from `i18n/<localization>.toml` to the actual string configuration in
|
||||
`data/i18n/<localization>/<localization>.toml` (remember to commit the symbolic
|
||||
link).
|
||||
`data/i18n/<localization>/<localization>.toml` (remember to commit the symbolic link).
|
||||
|
||||
For example, for German the strings live in `data/i18n/de/de.toml`, and
|
||||
`i18n/de.toml` is a symbolic link to `data/i18n/de/de.toml`.
|
||||
|
||||
### Localize the community code of conduct
|
||||
|
||||
Open a PR against the [`cncf/foundation`](https://github.com/cncf/foundation/tree/main/code-of-conduct-languages) repository to add the code of conduct in your language.
|
||||
|
||||
Open a PR against the [`cncf/foundation`](https://github.com/cncf/foundation/tree/main/code-of-conduct-languages)
|
||||
repository to add the code of conduct in your language.
|
||||
|
||||
### Setting up the OWNERS files
|
||||
|
||||
To set the roles of each user contributing to the localization, create an `OWNERS` file inside the language-specific subdirectory with:
|
||||
To set the roles of each user contributing to the localization, create an `OWNERS` file inside the
|
||||
language-specific subdirectory with:
|
||||
|
||||
- **reviewers**: A list of kubernetes teams with reviewer roles, in this case, the `sig-docs-**-reviews` team created in [Add your localization team in GitHub](#add-your-localization-team-in-github).
|
||||
- **approvers**: A list of kubernetes teams with approvers roles, in this case, the `sig-docs-**-owners` team created in [Add your localization team in GitHub](#add-your-localization-team-in-github).
|
||||
- **labels**: A list of GitHub labels to automatically apply to a PR, in this case, the language label created in [Configure the workflow](#configure-the-workflow).
|
||||
- **reviewers**: A list of kubernetes teams with reviewer roles, in this case, the
|
||||
`sig-docs-**-reviews` team created in
|
||||
[Add your localization team in GitHub](#add-your-localization-team-in-github).
|
||||
- **approvers**: A list of kubernetes teams with approvers roles, in this case, the
|
||||
`sig-docs-**-owners` team created in
|
||||
[Add your localization team in GitHub](#add-your-localization-team-in-github).
|
||||
- **labels**: A list of GitHub labels to automatically apply to a PR, in this case, the language
|
||||
label created in [Configure the workflow](#configure-the-workflow).
|
||||
|
||||
More information about the `OWNERS` file can be found at [go.k8s.io/owners](https://go.k8s.io/owners).
|
||||
|
||||
The [Spanish OWNERS file](https://git.k8s.io/website/content/es/OWNERS), with language code `es`, looks like:
|
||||
The [Spanish OWNERS file](https://git.k8s.io/website/content/es/OWNERS),
|
||||
with language code `es`, looks like:
|
||||
|
||||
```yaml
|
||||
# See the OWNERS docs at https://go.k8s.io/owners
|
||||
@@ -190,9 +236,13 @@ labels:
|
||||
- language/es
|
||||
```
|
||||
|
||||
After adding the language-specific `OWNERS` file, update the [root `OWNERS_ALIASES`](https://git.k8s.io/website/OWNERS_ALIASES) file with the new Kubernetes teams for the localization, `sig-docs-**-owners` and `sig-docs-**-reviews`.
|
||||
After adding the language-specific `OWNERS` file, update the [root
|
||||
`OWNERS_ALIASES`](https://git.k8s.io/website/OWNERS_ALIASES) file with the new Kubernetes teams
|
||||
for the localization, `sig-docs-**-owners` and `sig-docs-**-reviews`.
|
||||
|
||||
For each team, add the list of GitHub users requested in [Add your localization team in GitHub](#add-your-localization-team-in-github), in alphabetical order.
|
||||
For each team, add the list of GitHub users requested in
|
||||
[Add your localization team in GitHub](#add-your-localization-team-in-github),
|
||||
in alphabetical order.
|
||||
|
||||
```diff
|
||||
--- a/OWNERS_ALIASES
|
||||
@@ -216,33 +266,45 @@ For each team, add the list of GitHub users requested in [Add your localization
|
||||
|
||||
### Open a pull request
|
||||
|
||||
Next, [open a pull request](/docs/contribute/new-content/open-a-pr/#open-a-pr) (PR) to add a localization to the `kubernetes/website` repository.
|
||||
Next, [open a pull request](/docs/contribute/new-content/open-a-pr/#open-a-pr) (PR) to add a
|
||||
localization to the `kubernetes/website` repository.
|
||||
The PR must include all of the [minimum required content](#minimum-required-content) before it can
|
||||
be approved.
|
||||
|
||||
The PR must include all of the [minimum required content](#minimum-required-content) before it can be approved.
|
||||
|
||||
For an example of adding a new localization, see the PR to enable [docs in French](https://github.com/kubernetes/website/pull/12548).
|
||||
For an example of adding a new localization, see the PR to enable
|
||||
[docs in French](https://github.com/kubernetes/website/pull/12548).
|
||||
|
||||
### Add a localized README file
|
||||
|
||||
To guide other localization contributors, add a new [`README-**.md`](https://help.github.com/articles/about-readmes/) to the top level of [k/website](https://github.com/kubernetes/website/), where `**` is the two-letter language code. For example, a German README file would be `README-de.md`.
|
||||
To guide other localization contributors, add a new
|
||||
[`README-**.md`](https://help.github.com/articles/about-readmes/) to the top level of
|
||||
[k/website](https://github.com/kubernetes/website/), where `**` is the two-letter language code.
|
||||
For example, a German README file would be `README-de.md`.
|
||||
|
||||
Provide guidance to localization contributors in the localized `README-**.md` file. Include the same information contained in `README.md` as well as:
|
||||
Provide guidance to localization contributors in the localized `README-**.md` file.
|
||||
Include the same information contained in `README.md` as well as:
|
||||
|
||||
- A point of contact for the localization project
|
||||
- Any information specific to the localization
|
||||
|
||||
After you create the localized README, add a link to the file from the main English `README.md`, and include contact information in English. You can provide a GitHub ID, email address, [Slack channel](https://slack.com/), or other method of contact. You must also provide a link to your localized Community Code of Conduct.
|
||||
After you create the localized README, add a link to the file from the main English `README.md`,
|
||||
and include contact information in English. You can provide a GitHub ID, email address,
|
||||
[Slack channel](https://slack.com/), or other method of contact. You must also provide a link to your
|
||||
localized Community Code of Conduct.
|
||||
|
||||
### Launching your new localization
|
||||
|
||||
Once a localization meets requirements for workflow and minimum output, SIG Docs will:
|
||||
|
||||
- Enable language selection on the website
|
||||
- Publicize the localization's availability through [Cloud Native Computing Foundation](https://www.cncf.io/about/) (CNCF) channels, including the [Kubernetes blog](https://kubernetes.io/blog/).
|
||||
- Publicize the localization's availability through
|
||||
[Cloud Native Computing Foundation](https://www.cncf.io/about/)(CNCF) channels, including the
|
||||
[Kubernetes blog](/blog/).
|
||||
|
||||
## Translating content
|
||||
|
||||
Localizing *all* of the Kubernetes documentation is an enormous task. It's okay to start small and expand over time.
|
||||
Localizing *all* of the Kubernetes documentation is an enormous task. It's okay to start small and
|
||||
expand over time.
|
||||
|
||||
### Minimum required content
|
||||
|
||||
@@ -253,23 +315,29 @@ Description | URLs
|
||||
Home | [All heading and subheading URLs](/docs/home/)
|
||||
Setup | [All heading and subheading URLs](/docs/setup/)
|
||||
Tutorials | [Kubernetes Basics](/docs/tutorials/kubernetes-basics/), [Hello Minikube](/docs/tutorials/hello-minikube/)
|
||||
Site strings | [All site strings](#Site-strings-in-i18n) in a new localized TOML file
|
||||
Site strings | [All site strings](#site-strings-in-i18n) in a new localized TOML file
|
||||
Releases | [All heading and subheading URLs](/releases)
|
||||
|
||||
Translated documents must reside in their own `content/**/` subdirectory, but otherwise follow the same URL path as the English source. For example, to prepare the [Kubernetes Basics](/docs/tutorials/kubernetes-basics/) tutorial for translation into German, create a subfolder under the `content/de/` folder and copy the English source:
|
||||
Translated documents must reside in their own `content/**/` subdirectory, but otherwise follow the
|
||||
same URL path as the English source. For example, to prepare the
|
||||
[Kubernetes Basics](/docs/tutorials/kubernetes-basics/) tutorial for translation into German,
|
||||
create a subfolder under the `content/de/` folder and copy the English source:
|
||||
|
||||
```shell
|
||||
mkdir -p content/de/docs/tutorials
|
||||
cp content/en/docs/tutorials/kubernetes-basics.md content/de/docs/tutorials/kubernetes-basics.md
|
||||
```
|
||||
|
||||
Translation tools can speed up the translation process. For example, some editors offers plugins to quickly translate text.
|
||||
Translation tools can speed up the translation process. For example, some editors offers plugins
|
||||
to quickly translate text.
|
||||
|
||||
{{< caution >}}
|
||||
Machine-generated translation is insufficient on its own. Localization requires extensive human review to meet minimum standards of quality.
|
||||
Machine-generated translation is insufficient on its own. Localization requires extensive human
|
||||
review to meet minimum standards of quality.
|
||||
{{< /caution >}}
|
||||
|
||||
To ensure accuracy in grammar and meaning, members of your localization team should carefully review all machine-generated translations before publishing.
|
||||
To ensure accuracy in grammar and meaning, members of your localization team should carefully
|
||||
review all machine-generated translations before publishing.
|
||||
|
||||
### Source files
|
||||
|
||||
@@ -280,17 +348,21 @@ To find source files for your target version:
|
||||
|
||||
1. Navigate to the Kubernetes website repository at https://github.com/kubernetes/website.
|
||||
2. Select a branch for your target version from the following table:
|
||||
Target version | Branch
|
||||
-----|-----
|
||||
Latest version | [`main`](https://github.com/kubernetes/website/tree/main)
|
||||
Previous version | [`release-{{< skew prevMinorVersion >}}`](https://github.com/kubernetes/website/tree/release-{{< skew prevMinorVersion >}})
|
||||
Next version | [`dev-{{< skew nextMinorVersion >}}`](https://github.com/kubernetes/website/tree/dev-{{< skew nextMinorVersion >}})
|
||||
|
||||
The `main` branch holds content for the current release `{{< latest-version >}}`. The release team will create a `{{< release-branch >}}` branch before the next release: v{{< skew nextMinorVersion >}}.
|
||||
Target version | Branch
|
||||
-----|-----
|
||||
Latest version | [`main`](https://github.com/kubernetes/website/tree/main)
|
||||
Previous version | [`release-{{< skew prevMinorVersion >}}`](https://github.com/kubernetes/website/tree/release-{{< skew prevMinorVersion >}})
|
||||
Next version | [`dev-{{< skew nextMinorVersion >}}`](https://github.com/kubernetes/website/tree/dev-{{< skew nextMinorVersion >}})
|
||||
|
||||
The `main` branch holds content for the current release `{{< latest-version >}}`. The release team
|
||||
will create a `{{< release-branch >}}` branch before the next release: v{{< skew nextMinorVersion >}}.
|
||||
|
||||
### Site strings in i18n
|
||||
|
||||
Localizations must include the contents of [`data/i18n/en/en.toml`](https://github.com/kubernetes/website/blob/main/data/i18n/en/en.toml) in a new language-specific file. Using German as an example: `data/i18n/de/de.toml`.
|
||||
Localizations must include the contents of
|
||||
[`data/i18n/en/en.toml`](https://github.com/kubernetes/website/blob/main/data/i18n/en/en.toml)
|
||||
in a new language-specific file. Using German as an example: `data/i18n/de/de.toml`.
|
||||
|
||||
Add a new localization directory and file to `data/i18n/`. For example, with German (`de`):
|
||||
|
||||
@@ -308,17 +380,22 @@ placeholder text for the search form:
|
||||
other = "Suchen"
|
||||
```
|
||||
|
||||
Localizing site strings lets you customize site-wide text and features: for example, the legal copyright text in the footer on each page.
|
||||
Localizing site strings lets you customize site-wide text and features: for example, the legal
|
||||
copyright text in the footer on each page.
|
||||
|
||||
### Language specific style guide and glossary
|
||||
|
||||
Some language teams have their own language-specific style guide and glossary. For example, see the [Korean Localization Guide](/ko/docs/contribute/localization_ko/).
|
||||
Some language teams have their own language-specific style guide and glossary.
|
||||
For example, see the [Korean Localization Guide](/ko/docs/contribute/localization_ko/).
|
||||
|
||||
### Language specific Zoom meetings
|
||||
|
||||
If the localization project needs a separate meeting time, contact a SIG Docs Co-Chair or Tech Lead to create a new reoccurring Zoom meeting and calendar invite. This is only needed when the the team is large enough to sustain and require a separate meeting.
|
||||
If the localization project needs a separate meeting time, contact a SIG Docs Co-Chair or Tech
|
||||
Lead to create a new reoccurring Zoom meeting and calendar invite. This is only needed when
|
||||
the team is large enough to sustain and require a separate meeting.
|
||||
|
||||
Per CNCF policy, the localization teams must upload their meetings to the SIG Docs YouTube playlist. A SIG Docs Co-Chair or Tech Lead can help with the process until SIG Docs automates it.
|
||||
Per CNCF policy, the localization teams must upload their meetings to the SIG Docs YouTube
|
||||
playlist. A SIG Docs Co-Chair or Tech Lead can help with the process until SIG Docs automates it.
|
||||
|
||||
## Branching strategy
|
||||
|
||||
@@ -328,42 +405,66 @@ when starting out and the localization is not yet live.
|
||||
|
||||
To collaborate on a localization branch:
|
||||
|
||||
1. A team member of [@kubernetes/website-maintainers](https://github.com/orgs/kubernetes/teams/website-maintainers) opens a localization branch from a source branch on https://github.com/kubernetes/website.
|
||||
1. A team member of
|
||||
[@kubernetes/website-maintainers](https://github.com/orgs/kubernetes/teams/website-maintainers)
|
||||
opens a localization branch from a source branch on https://github.com/kubernetes/website.
|
||||
|
||||
Your team approvers joined the `@kubernetes/website-maintainers` team when you [added your localization team](#add-your-localization-team-in-github) to the [`kubernetes/org`](https://github.com/kubernetes/org) repository.
|
||||
Your team approvers joined the `@kubernetes/website-maintainers` team when you
|
||||
[added your localization team](#add-your-localization-team-in-github) to the
|
||||
[`kubernetes/org`](https://github.com/kubernetes/org) repository.
|
||||
|
||||
We recommend the following branch naming scheme:
|
||||
We recommend the following branch naming scheme:
|
||||
|
||||
`dev-<source version>-<language code>.<team milestone>`
|
||||
`dev-<source version>-<language code>.<team milestone>`
|
||||
|
||||
For example, an approver on a German localization team opens the localization branch `dev-1.12-de.1` directly against the k/website repository, based on the source branch for Kubernetes v1.12.
|
||||
For example, an approver on a German localization team opens the localization branch
|
||||
`dev-1.12-de.1` directly against the k/website repository, based on the source branch for
|
||||
Kubernetes v1.12.
|
||||
|
||||
2. Individual contributors open feature branches based on the localization branch.
|
||||
|
||||
For example, a German contributor opens a pull request with changes to `kubernetes:dev-1.12-de.1` from `username:local-branch-name`.
|
||||
For example, a German contributor opens a pull request with changes to
|
||||
`kubernetes:dev-1.12-de.1` from `username:local-branch-name`.
|
||||
|
||||
3. Approvers review and merge feature branches into the localization branch.
|
||||
|
||||
4. Periodically, an approver merges the localization branch to its source branch by opening and approving a new pull request. Be sure to squash the commits before approving the pull request.
|
||||
4. Periodically, an approver merges the localization branch to its source branch by opening and
|
||||
approving a new pull request. Be sure to squash the commits before approving the pull request.
|
||||
|
||||
Repeat steps 1-4 as needed until the localization is complete. For example, subsequent German localization branches would be: `dev-1.12-de.2`, `dev-1.12-de.3`, etc.
|
||||
Repeat steps 1-4 as needed until the localization is complete. For example, subsequent German
|
||||
localization branches would be: `dev-1.12-de.2`, `dev-1.12-de.3`, etc.
|
||||
|
||||
Teams must merge localized content into the same branch from which the content was sourced.
|
||||
|
||||
For example:
|
||||
|
||||
- a localization branch sourced from `main` must be merged into `main`.
|
||||
- a localization branch sourced from `release-{{% skew "prevMinorVersion" %}}` must be merged into `release-{{% skew "prevMinorVersion" %}}`.
|
||||
- a localization branch sourced from `release-{{% skew "prevMinorVersion" %}}` must be merged into
|
||||
`release-{{% skew "prevMinorVersion" %}}`.
|
||||
|
||||
{{< note >}}
|
||||
If your localization branch was created from `main` branch but it is not merged into `main` before new release branch `{{< release-branch >}}` created, merge it into both `main` and new release branch `{{< release-branch >}}`. To merge your localization branch into new release branch `{{< release-branch >}}`, you need to switch upstream branch of your localization branch to `{{< release-branch >}}`.
|
||||
If your localization branch was created from `main` branch but it is not merged into `main` before
|
||||
new release branch `{{< release-branch >}}` created, merge it into both `main` and new release
|
||||
branch `{{< release-branch >}}`. To merge your localization branch into new release branch
|
||||
`{{< release-branch >}}`, you need to switch upstream branch of your localization branch to
|
||||
`{{< release-branch >}}`.
|
||||
{{< /note >}}
|
||||
|
||||
At the beginning of every team milestone, it's helpful to open an issue comparing upstream changes between the previous localization branch and the current localization branch. There are two scripts for comparing upstream changes. [`upstream_changes.py`](https://github.com/kubernetes/website/tree/main/scripts#upstream_changespy) is useful for checking the changes made to a specific file. And [`diff_l10n_branches.py`](https://github.com/kubernetes/website/tree/main/scripts#diff_l10n_branchespy) is useful for creating a list of outdated files for a specific localization branch.
|
||||
At the beginning of every team milestone, it's helpful to open an issue comparing upstream changes
|
||||
between the previous localization branch and the current localization branch.
|
||||
There are two scripts for comparing upstream changes.
|
||||
|
||||
While only approvers can open a new localization branch and merge pull requests, anyone can open a pull request for a new localization branch. No special permissions are required.
|
||||
- [`upstream_changes.py`](https://github.com/kubernetes/website/tree/main/scripts#upstream_changespy)
|
||||
is useful for checking the changes made to a specific file. And
|
||||
- [`diff_l10n_branches.py`](https://github.com/kubernetes/website/tree/main/scripts#diff_l10n_branchespy)
|
||||
is useful for creating a list of outdated files for a specific localization branch.
|
||||
|
||||
For more information about working from forks or directly from the repository, see ["fork and clone the repo"](#fork-and-clone-the-repo).
|
||||
While only approvers can open a new localization branch and merge pull requests, anyone can open a
|
||||
pull request for a new localization branch. No special permissions are required.
|
||||
|
||||
For more information about working from forks or directly from the repository, see
|
||||
["fork and clone the repo"](#fork-and-clone-the-repo).
|
||||
|
||||
## Upstream contributions
|
||||
|
||||
SIG Docs welcomes upstream contributions and corrections to the English source.
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ the techniques described in
|
||||
### Find out about upcoming features
|
||||
|
||||
To find out about upcoming features, attend the weekly SIG Release meeting (see
|
||||
the [community](https://kubernetes.io/community/) page for upcoming meetings)
|
||||
the [community](/community/) page for upcoming meetings)
|
||||
and monitor the release-specific documentation
|
||||
in the [kubernetes/sig-release](https://github.com/kubernetes/sig-release/)
|
||||
repository. Each release has a sub-directory in the [/sig-release/tree/master/releases/](https://github.com/kubernetes/sig-release/tree/master/releases)
|
||||
|
||||
@@ -15,13 +15,15 @@ upcoming Kubernetes release, see
|
||||
[Document a new feature](/docs/contribute/new-content/new-features/).
|
||||
{{< /note >}}
|
||||
|
||||
To contribute new content pages or improve existing content pages, open a pull request (PR). Make sure you follow all the requirements in the [Before you begin](/docs/contribute/new-content/overview/#before-you-begin) section.
|
||||
|
||||
If your change is small, or you're unfamiliar with git, read [Changes using GitHub](#changes-using-github) to learn how to edit a page.
|
||||
|
||||
If your changes are large, read [Work from a local fork](#fork-the-repo) to learn how to make changes locally on your computer.
|
||||
To contribute new content pages or improve existing content pages, open a pull request (PR).
|
||||
Make sure you follow all the requirements in the
|
||||
[Before you begin](/docs/contribute/new-content/) section.
|
||||
|
||||
If your change is small, or you're unfamiliar with git, read
|
||||
[Changes using GitHub](#changes-using-github) to learn how to edit a page.
|
||||
|
||||
If your changes are large, read [Work from a local fork](#fork-the-repo) to learn how to make
|
||||
changes locally on your computer.
|
||||
|
||||
<!-- body -->
|
||||
|
||||
@@ -63,38 +65,39 @@ class id1 k8s
|
||||
|
||||
Figure 1. Steps for opening a PR using GitHub.
|
||||
|
||||
1. On the page where you see the issue, select the pencil icon at the top right.
|
||||
You can also scroll to the bottom of the page and select **Edit this page**.
|
||||
1. On the page where you see the issue, select the pencil icon at the top right.
|
||||
You can also scroll to the bottom of the page and select **Edit this page**.
|
||||
|
||||
2. Make your changes in the GitHub markdown editor.
|
||||
1. Make your changes in the GitHub markdown editor.
|
||||
|
||||
3. Below the editor, fill in the **Propose file change**
|
||||
form. In the first field, give your commit message a title. In
|
||||
the second field, provide a description.
|
||||
1. Below the editor, fill in the **Propose file change** form.
|
||||
In the first field, give your commit message a title.
|
||||
In the second field, provide a description.
|
||||
|
||||
{{< note >}}
|
||||
Do not use any [GitHub Keywords](https://help.github.com/en/github/managing-your-work-on-github/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword) in your commit message. You can add those to the pull request
|
||||
description later.
|
||||
{{< /note >}}
|
||||
{{< note >}}
|
||||
Do not use any [GitHub Keywords](https://help.github.com/en/github/managing-your-work-on-github/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword)
|
||||
in your commit message. You can add those to the pull request description later.
|
||||
{{< /note >}}
|
||||
|
||||
4. Select **Propose file change**.
|
||||
1. Select **Propose file change**.
|
||||
|
||||
5. Select **Create pull request**.
|
||||
1. Select **Create pull request**.
|
||||
|
||||
6. The **Open a pull request** screen appears. Fill in the form:
|
||||
1. The **Open a pull request** screen appears. Fill in the form:
|
||||
|
||||
- The **Subject** field of the pull request defaults to the commit summary.
|
||||
You can change it if needed.
|
||||
- The **Body** contains your extended commit message, if you have one,
|
||||
and some template text. Add the
|
||||
details the template text asks for, then delete the extra template text.
|
||||
- Leave the **Allow edits from maintainers** checkbox selected.
|
||||
- The **Subject** field of the pull request defaults to the commit summary.
|
||||
You can change it if needed.
|
||||
- The **Body** contains your extended commit message, if you have one,
|
||||
and some template text. Add the
|
||||
details the template text asks for, then delete the extra template text.
|
||||
- Leave the **Allow edits from maintainers** checkbox selected.
|
||||
|
||||
{{< note >}}
|
||||
PR descriptions are a great way to help reviewers understand your change. For more information, see [Opening a PR](#open-a-pr).
|
||||
{{</ note >}}
|
||||
{{< note >}}
|
||||
PR descriptions are a great way to help reviewers understand your change.
|
||||
For more information, see [Opening a PR](#open-a-pr).
|
||||
{{</ note >}}
|
||||
|
||||
7. Select **Create pull request**.
|
||||
1. Select **Create pull request**.
|
||||
|
||||
### Addressing feedback in GitHub
|
||||
|
||||
@@ -106,12 +109,12 @@ leave a comment with their GitHub username in it.
|
||||
If a reviewer asks you to make changes:
|
||||
|
||||
1. Go to the **Files changed** tab.
|
||||
2. Select the pencil (edit) icon on any files changed by the
|
||||
pull request.
|
||||
3. Make the changes requested.
|
||||
4. Commit the changes.
|
||||
1. Select the pencil (edit) icon on any files changed by the pull request.
|
||||
1. Make the changes requested.
|
||||
1. Commit the changes.
|
||||
|
||||
If you are waiting on a reviewer, reach out once every 7 days. You can also post a message in the `#sig-docs` Slack channel.
|
||||
If you are waiting on a reviewer, reach out once every 7 days. You can also post a message in the
|
||||
`#sig-docs` Slack channel.
|
||||
|
||||
When your review is complete, a reviewer merges your PR and your changes go live a few minutes later.
|
||||
|
||||
@@ -120,7 +123,8 @@ When your review is complete, a reviewer merges your PR and your changes go live
|
||||
If you're more experienced with git, or if your changes are larger than a few lines,
|
||||
work from a local fork.
|
||||
|
||||
Make sure you have [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) installed on your computer. You can also use a git UI application.
|
||||
Make sure you have [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) installed
|
||||
on your computer. You can also use a git UI application.
|
||||
|
||||
Figure 2 shows the steps to follow when you work from a local fork. The details for each step follow.
|
||||
|
||||
@@ -157,53 +161,56 @@ Figure 2. Working from a local fork to make your changes.
|
||||
### Fork the kubernetes/website repository
|
||||
|
||||
1. Navigate to the [`kubernetes/website`](https://github.com/kubernetes/website/) repository.
|
||||
2. Select **Fork**.
|
||||
1. Select **Fork**.
|
||||
|
||||
### Create a local clone and set the upstream
|
||||
|
||||
3. In a terminal window, clone your fork and update the [Docsy Hugo theme](https://github.com/google/docsy#readme):
|
||||
1. In a terminal window, clone your fork and update the [Docsy Hugo theme](https://github.com/google/docsy#readme):
|
||||
|
||||
```bash
|
||||
git clone git@github.com/<github_username>/website
|
||||
cd website
|
||||
git submodule update --init --recursive --depth 1
|
||||
```
|
||||
```shell
|
||||
git clone git@github.com/<github_username>/website
|
||||
cd website
|
||||
git submodule update --init --recursive --depth 1
|
||||
```
|
||||
|
||||
4. Navigate to the new `website` directory. Set the `kubernetes/website` repository as the `upstream` remote:
|
||||
1. Navigate to the new `website` directory. Set the `kubernetes/website` repository as the `upstream` remote:
|
||||
|
||||
```bash
|
||||
cd website
|
||||
```shell
|
||||
cd website
|
||||
|
||||
git remote add upstream https://github.com/kubernetes/website.git
|
||||
```
|
||||
git remote add upstream https://github.com/kubernetes/website.git
|
||||
```
|
||||
|
||||
5. Confirm your `origin` and `upstream` repositories:
|
||||
1. Confirm your `origin` and `upstream` repositories:
|
||||
|
||||
```bash
|
||||
git remote -v
|
||||
```
|
||||
```shell
|
||||
git remote -v
|
||||
```
|
||||
|
||||
Output is similar to:
|
||||
Output is similar to:
|
||||
|
||||
```bash
|
||||
origin git@github.com:<github_username>/website.git (fetch)
|
||||
origin git@github.com:<github_username>/website.git (push)
|
||||
upstream https://github.com/kubernetes/website.git (fetch)
|
||||
upstream https://github.com/kubernetes/website.git (push)
|
||||
```
|
||||
```none
|
||||
origin git@github.com:<github_username>/website.git (fetch)
|
||||
origin git@github.com:<github_username>/website.git (push)
|
||||
upstream https://github.com/kubernetes/website.git (fetch)
|
||||
upstream https://github.com/kubernetes/website.git (push)
|
||||
```
|
||||
|
||||
6. Fetch commits from your fork's `origin/main` and `kubernetes/website`'s `upstream/main`:
|
||||
1. Fetch commits from your fork's `origin/main` and `kubernetes/website`'s `upstream/main`:
|
||||
|
||||
```bash
|
||||
git fetch origin
|
||||
git fetch upstream
|
||||
```
|
||||
```shell
|
||||
git fetch origin
|
||||
git fetch upstream
|
||||
```
|
||||
|
||||
This makes sure your local repository is up to date before you start making changes.
|
||||
This makes sure your local repository is up to date before you start making changes.
|
||||
|
||||
{{< note >}}
|
||||
This workflow is different than the [Kubernetes Community GitHub Workflow](https://github.com/kubernetes/community/blob/master/contributors/guide/github-workflow.md). You do not need to merge your local copy of `main` with `upstream/main` before pushing updates to your fork.
|
||||
{{< /note >}}
|
||||
{{< note >}}
|
||||
This workflow is different than the
|
||||
[Kubernetes Community GitHub Workflow](https://github.com/kubernetes/community/blob/master/contributors/guide/github-workflow.md).
|
||||
You do not need to merge your local copy of `main` with `upstream/main` before pushing updates
|
||||
to your fork.
|
||||
{{< /note >}}
|
||||
|
||||
### Create a branch
|
||||
|
||||
@@ -211,21 +218,23 @@ Figure 2. Working from a local fork to make your changes.
|
||||
|
||||
- For improvements to existing content, use `upstream/main`.
|
||||
- For new content about existing features, use `upstream/main`.
|
||||
- For localized content, use the localization's conventions. For more information, see [localizing Kubernetes documentation](/docs/contribute/localization/).
|
||||
- For new features in an upcoming Kubernetes release, use the feature branch. For more information, see [documenting for a release](/docs/contribute/new-content/new-features/).
|
||||
- For localized content, use the localization's conventions. For more information, see
|
||||
[localizing Kubernetes documentation](/docs/contribute/localization/).
|
||||
- For new features in an upcoming Kubernetes release, use the feature branch. For more
|
||||
information, see [documenting for a release](/docs/contribute/new-content/new-features/).
|
||||
- For long-running efforts that multiple SIG Docs contributors collaborate on,
|
||||
like content reorganization, use a specific feature branch created for that
|
||||
effort.
|
||||
like content reorganization, use a specific feature branch created for that effort.
|
||||
|
||||
If you need help choosing a branch, ask in the `#sig-docs` Slack channel.
|
||||
|
||||
2. Create a new branch based on the branch identified in step 1. This example assumes the base branch is `upstream/main`:
|
||||
1. Create a new branch based on the branch identified in step 1. This example assumes the base
|
||||
branch is `upstream/main`:
|
||||
|
||||
```bash
|
||||
git checkout -b <my_new_branch> upstream/main
|
||||
```
|
||||
```shell
|
||||
git checkout -b <my_new_branch> upstream/main
|
||||
```
|
||||
|
||||
3. Make your changes using a text editor.
|
||||
3. Make your changes using a text editor.
|
||||
|
||||
At any time, use the `git status` command to see what files you've changed.
|
||||
|
||||
@@ -235,109 +244,116 @@ When you are ready to submit a pull request, commit your changes.
|
||||
|
||||
1. In your local repository, check which files you need to commit:
|
||||
|
||||
```bash
|
||||
git status
|
||||
```
|
||||
```shell
|
||||
git status
|
||||
```
|
||||
|
||||
Output is similar to:
|
||||
Output is similar to:
|
||||
|
||||
```bash
|
||||
On branch <my_new_branch>
|
||||
Your branch is up to date with 'origin/<my_new_branch>'.
|
||||
```none
|
||||
On branch <my_new_branch>
|
||||
Your branch is up to date with 'origin/<my_new_branch>'.
|
||||
|
||||
Changes not staged for commit:
|
||||
(use "git add <file>..." to update what will be committed)
|
||||
(use "git checkout -- <file>..." to discard changes in working directory)
|
||||
Changes not staged for commit:
|
||||
(use "git add <file>..." to update what will be committed)
|
||||
(use "git checkout -- <file>..." to discard changes in working directory)
|
||||
|
||||
modified: content/en/docs/contribute/new-content/contributing-content.md
|
||||
modified: content/en/docs/contribute/new-content/contributing-content.md
|
||||
|
||||
no changes added to commit (use "git add" and/or "git commit -a")
|
||||
```
|
||||
no changes added to commit (use "git add" and/or "git commit -a")
|
||||
```
|
||||
|
||||
2. Add the files listed under **Changes not staged for commit** to the commit:
|
||||
1. Add the files listed under **Changes not staged for commit** to the commit:
|
||||
|
||||
```bash
|
||||
git add <your_file_name>
|
||||
```
|
||||
```shell
|
||||
git add <your_file_name>
|
||||
```
|
||||
|
||||
Repeat this for each file.
|
||||
Repeat this for each file.
|
||||
|
||||
3. After adding all the files, create a commit:
|
||||
1. After adding all the files, create a commit:
|
||||
|
||||
```bash
|
||||
git commit -m "Your commit message"
|
||||
```
|
||||
```shell
|
||||
git commit -m "Your commit message"
|
||||
```
|
||||
|
||||
{{< note >}}
|
||||
Do not use any [GitHub Keywords](https://help.github.com/en/github/managing-your-work-on-github/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword) in your commit message. You can add those to the pull request
|
||||
description later.
|
||||
{{< /note >}}
|
||||
{{< note >}}
|
||||
Do not use any [GitHub Keywords](https://help.github.com/en/github/managing-your-work-on-github/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword)
|
||||
in your commit message. You can add those to the pull request
|
||||
description later.
|
||||
{{< /note >}}
|
||||
|
||||
4. Push your local branch and its new commit to your remote fork:
|
||||
1. Push your local branch and its new commit to your remote fork:
|
||||
|
||||
```bash
|
||||
git push origin <my_new_branch>
|
||||
```
|
||||
```shell
|
||||
git push origin <my_new_branch>
|
||||
```
|
||||
|
||||
### Preview your changes locally {#preview-locally}
|
||||
|
||||
It's a good idea to preview your changes locally before pushing them or opening a pull request. A preview lets you catch build errors or markdown formatting problems.
|
||||
It's a good idea to preview your changes locally before pushing them or opening a pull request.
|
||||
A preview lets you catch build errors or markdown formatting problems.
|
||||
|
||||
You can either build the website's container image or run Hugo locally. Building the container image is slower but displays [Hugo shortcodes](/docs/contribute/style/hugo-shortcodes/), which can be useful for debugging.
|
||||
You can either build the website's container image or run Hugo locally. Building the container
|
||||
image is slower but displays [Hugo shortcodes](/docs/contribute/style/hugo-shortcodes/), which can
|
||||
be useful for debugging.
|
||||
|
||||
{{< tabs name="tab_with_hugo" >}}
|
||||
{{% tab name="Hugo in a container" %}}
|
||||
|
||||
{{< note >}}
|
||||
The commands below use Docker as default container engine. Set the `CONTAINER_ENGINE` environment variable to override this behaviour.
|
||||
The commands below use Docker as default container engine. Set the `CONTAINER_ENGINE` environment
|
||||
variable to override this behaviour.
|
||||
{{< /note >}}
|
||||
|
||||
1. Build the container image locally
|
||||
_You only need this step if you are testing a change to the Hugo tool itself_
|
||||
```bash
|
||||
|
||||
```shell
|
||||
# Run this in a terminal (if required)
|
||||
make container-image
|
||||
```
|
||||
|
||||
1. Start Hugo in a container:
|
||||
|
||||
```bash
|
||||
```shell
|
||||
# Run this in a terminal
|
||||
make container-serve
|
||||
```
|
||||
|
||||
1. In a web browser, navigate to `https://localhost:1313`. Hugo watches the
|
||||
changes and rebuilds the site as needed.
|
||||
1. In a web browser, navigate to `https://localhost:1313`. Hugo watches the
|
||||
changes and rebuilds the site as needed.
|
||||
|
||||
1. To stop the local Hugo instance, go back to the terminal and type `Ctrl+C`,
|
||||
or close the terminal window.
|
||||
1. To stop the local Hugo instance, go back to the terminal and type `Ctrl+C`,
|
||||
or close the terminal window.
|
||||
|
||||
{{% /tab %}}
|
||||
{{% tab name="Hugo on the command line" %}}
|
||||
|
||||
Alternately, install and use the `hugo` command on your computer:
|
||||
|
||||
1. Install the [Hugo](https://gohugo.io/getting-started/installing/) version specified in [`website/netlify.toml`](https://raw.githubusercontent.com/kubernetes/website/main/netlify.toml).
|
||||
1. Install the [Hugo](https://gohugo.io/getting-started/installing/) version specified in
|
||||
[`website/netlify.toml`](https://raw.githubusercontent.com/kubernetes/website/main/netlify.toml).
|
||||
|
||||
2. If you have not updated your website repository, the `website/themes/docsy` directory is empty.
|
||||
The site cannot build without a local copy of the theme. To update the website theme, run:
|
||||
1. If you have not updated your website repository, the `website/themes/docsy` directory is empty.
|
||||
The site cannot build without a local copy of the theme. To update the website theme, run:
|
||||
|
||||
```bash
|
||||
git submodule update --init --recursive --depth 1
|
||||
```
|
||||
```shell
|
||||
git submodule update --init --recursive --depth 1
|
||||
```
|
||||
|
||||
3. In a terminal, go to your Kubernetes website repository and start the Hugo server:
|
||||
1. In a terminal, go to your Kubernetes website repository and start the Hugo server:
|
||||
|
||||
```bash
|
||||
cd <path_to_your_repo>/website
|
||||
hugo server --buildFuture
|
||||
```
|
||||
```shell
|
||||
cd <path_to_your_repo>/website
|
||||
hugo server --buildFuture
|
||||
```
|
||||
|
||||
4. In a web browser, navigate to `https://localhost:1313`. Hugo watches the
|
||||
changes and rebuilds the site as needed.
|
||||
1. In a web browser, navigate to `https://localhost:1313`. Hugo watches the
|
||||
changes and rebuilds the site as needed.
|
||||
|
||||
5. To stop the local Hugo instance, go back to the terminal and type `Ctrl+C`,
|
||||
or close the terminal window.
|
||||
1. To stop the local Hugo instance, go back to the terminal and type `Ctrl+C`,
|
||||
or close the terminal window.
|
||||
|
||||
{{% /tab %}}
|
||||
{{< /tabs >}}
|
||||
@@ -345,6 +361,7 @@ Alternately, install and use the `hugo` command on your computer:
|
||||
### Open a pull request from your fork to kubernetes/website {#open-a-pr}
|
||||
|
||||
Figure 3 shows the steps to open a PR from your fork to the K8s/website. The details follow.
|
||||
|
||||
<!-- See https://github.com/kubernetes/website/issues/28808 for live-editor URL to this figure -->
|
||||
<!-- You can also cut/paste the mermaid code into the live editor at https://mermaid-js.github.io/mermaid-live-editor to play around with it -->
|
||||
|
||||
@@ -374,47 +391,55 @@ class first,second white
|
||||
Figure 3. Steps to open a PR from your fork to the K8s/website.
|
||||
|
||||
1. In a web browser, go to the [`kubernetes/website`](https://github.com/kubernetes/website/) repository.
|
||||
2. Select **New Pull Request**.
|
||||
3. Select **compare across forks**.
|
||||
4. From the **head repository** drop-down menu, select your fork.
|
||||
5. From the **compare** drop-down menu, select your branch.
|
||||
6. Select **Create Pull Request**.
|
||||
7. Add a description for your pull request:
|
||||
1. Select **New Pull Request**.
|
||||
1. Select **compare across forks**.
|
||||
1. From the **head repository** drop-down menu, select your fork.
|
||||
1. From the **compare** drop-down menu, select your branch.
|
||||
1. Select **Create Pull Request**.
|
||||
`. Add a description for your pull request:
|
||||
|
||||
- **Title** (50 characters or less): Summarize the intent of the change.
|
||||
- **Description**: Describe the change in more detail.
|
||||
- If there is a related GitHub issue, include `Fixes #12345` or `Closes #12345` in the description. GitHub's automation closes the mentioned issue after merging the PR if used. If there are other related PRs, link those as well.
|
||||
- If you want advice on something specific, include any questions you'd like reviewers to think about in your description.
|
||||
|
||||
8. Select the **Create pull request** button.
|
||||
- If there is a related GitHub issue, include `Fixes #12345` or `Closes #12345` in the
|
||||
description. GitHub's automation closes the mentioned issue after merging the PR if used.
|
||||
If there are other related PRs, link those as well.
|
||||
- If you want advice on something specific, include any questions you'd like reviewers to
|
||||
think about in your description.
|
||||
|
||||
1. Select the **Create pull request** button.
|
||||
|
||||
Congratulations! Your pull request is available in [Pull requests](https://github.com/kubernetes/website/pulls).
|
||||
|
||||
After opening a PR, GitHub runs automated tests and tries to deploy a preview using
|
||||
[Netlify](https://www.netlify.com/).
|
||||
|
||||
After opening a PR, GitHub runs automated tests and tries to deploy a preview using [Netlify](https://www.netlify.com/).
|
||||
- If the Netlify build fails, select **Details** for more information.
|
||||
- If the Netlify build succeeds, select **Details** opens a staged version of the Kubernetes
|
||||
website with your changes applied. This is how reviewers check your changes.
|
||||
|
||||
- If the Netlify build fails, select **Details** for more information.
|
||||
- If the Netlify build succeeds, select **Details** opens a staged version of the Kubernetes website with your changes applied. This is how reviewers check your changes.
|
||||
|
||||
GitHub also automatically assigns labels to a PR, to help reviewers. You can add them too, if needed. For more information, see [Adding and removing issue labels](/docs/contribute/review/for-approvers/#adding-and-removing-issue-labels).
|
||||
GitHub also automatically assigns labels to a PR, to help reviewers. You can add them too, if
|
||||
needed. For more information, see [Adding and removing issue labels](/docs/contribute/review/for-approvers/#adding-and-removing-issue-labels).
|
||||
|
||||
### Addressing feedback locally
|
||||
|
||||
1. After making your changes, amend your previous commit:
|
||||
|
||||
```bash
|
||||
git commit -a --amend
|
||||
```
|
||||
```shell
|
||||
git commit -a --amend
|
||||
```
|
||||
|
||||
- `-a`: commits all changes
|
||||
- `--amend`: amends the previous commit, rather than creating a new one
|
||||
- `-a`: commits all changes
|
||||
- `--amend`: amends the previous commit, rather than creating a new one
|
||||
|
||||
2. Update your commit message if needed.
|
||||
1. Update your commit message if needed.
|
||||
|
||||
3. Use `git push origin <my_new_branch>` to push your changes and re-run the Netlify tests.
|
||||
1. Use `git push origin <my_new_branch>` to push your changes and re-run the Netlify tests.
|
||||
|
||||
{{< note >}}
|
||||
If you use `git commit -m` instead of amending, you must [squash your commits](#squashing-commits) before merging.
|
||||
{{< /note >}}
|
||||
{{< note >}}
|
||||
If you use `git commit -m` instead of amending, you must [squash your commits](#squashing-commits)
|
||||
before merging.
|
||||
{{< /note >}}
|
||||
|
||||
#### Changes from reviewers
|
||||
|
||||
@@ -422,89 +447,97 @@ Sometimes reviewers commit to your pull request. Before making any other changes
|
||||
|
||||
1. Fetch commits from your remote fork and rebase your working branch:
|
||||
|
||||
```bash
|
||||
git fetch origin
|
||||
git rebase origin/<your-branch-name>
|
||||
```
|
||||
```shell
|
||||
git fetch origin
|
||||
git rebase origin/<your-branch-name>
|
||||
```
|
||||
|
||||
2. After rebasing, force-push new changes to your fork:
|
||||
1. After rebasing, force-push new changes to your fork:
|
||||
|
||||
```bash
|
||||
git push --force-with-lease origin <your-branch-name>
|
||||
```
|
||||
```shell
|
||||
git push --force-with-lease origin <your-branch-name>
|
||||
```
|
||||
|
||||
#### Merge conflicts and rebasing
|
||||
|
||||
{{< note >}}
|
||||
For more information, see [Git Branching - Basic Branching and Merging](https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging#_basic_merge_conflicts), [Advanced Merging](https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging), or ask in the `#sig-docs` Slack channel for help.
|
||||
For more information, see [Git Branching - Basic Branching and Merging](https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging#_basic_merge_conflicts),
|
||||
[Advanced Merging](https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging), or ask in the
|
||||
`#sig-docs` Slack channel for help.
|
||||
{{< /note >}}
|
||||
|
||||
If another contributor commits changes to the same file in another PR, it can create a merge conflict. You must resolve all merge conflicts in your PR.
|
||||
If another contributor commits changes to the same file in another PR, it can create a merge
|
||||
conflict. You must resolve all merge conflicts in your PR.
|
||||
|
||||
1. Update your fork and rebase your local branch:
|
||||
|
||||
```bash
|
||||
git fetch origin
|
||||
git rebase origin/<your-branch-name>
|
||||
```
|
||||
```shell
|
||||
git fetch origin
|
||||
git rebase origin/<your-branch-name>
|
||||
```
|
||||
|
||||
Then force-push the changes to your fork:
|
||||
Then force-push the changes to your fork:
|
||||
|
||||
```bash
|
||||
git push --force-with-lease origin <your-branch-name>
|
||||
```
|
||||
```shell
|
||||
git push --force-with-lease origin <your-branch-name>
|
||||
```
|
||||
|
||||
2. Fetch changes from `kubernetes/website`'s `upstream/main` and rebase your branch:
|
||||
1. Fetch changes from `kubernetes/website`'s `upstream/main` and rebase your branch:
|
||||
|
||||
```bash
|
||||
```shell
|
||||
git fetch upstream
|
||||
git rebase upstream/main
|
||||
```
|
||||
|
||||
3. Inspect the results of the rebase:
|
||||
1. Inspect the results of the rebase:
|
||||
|
||||
```bash
|
||||
git status
|
||||
```
|
||||
```shell
|
||||
git status
|
||||
```
|
||||
|
||||
This results in a number of files marked as conflicted.
|
||||
This results in a number of files marked as conflicted.
|
||||
|
||||
4. Open each conflicted file and look for the conflict markers: `>>>`, `<<<`, and `===`. Resolve the conflict and delete the conflict marker.
|
||||
1. Open each conflicted file and look for the conflict markers: `>>>`, `<<<`, and `===`.
|
||||
Resolve the conflict and delete the conflict marker.
|
||||
|
||||
{{< note >}}
|
||||
For more information, see [How conflicts are presented](https://git-scm.com/docs/git-merge#_how_conflicts_are_presented).
|
||||
{{< /note >}}
|
||||
{{< note >}}
|
||||
For more information, see [How conflicts are presented](https://git-scm.com/docs/git-merge#_how_conflicts_are_presented).
|
||||
{{< /note >}}
|
||||
|
||||
5. Add the files to the changeset:
|
||||
1. Add the files to the changeset:
|
||||
|
||||
```bash
|
||||
git add <filename>
|
||||
```
|
||||
6. Continue the rebase:
|
||||
```shell
|
||||
git add <filename>
|
||||
```
|
||||
|
||||
```bash
|
||||
git rebase --continue
|
||||
```
|
||||
1. Continue the rebase:
|
||||
|
||||
7. Repeat steps 2 to 5 as needed.
|
||||
``
|
||||
git rebase --continue
|
||||
```
|
||||
|
||||
After applying all commits, the `git status` command shows that the rebase is complete.
|
||||
1. Repeat steps 2 to 5 as needed.
|
||||
|
||||
8. Force-push the branch to your fork:
|
||||
After applying all commits, the `git status` command shows that the rebase is complete.
|
||||
|
||||
```bash
|
||||
git push --force-with-lease origin <your-branch-name>
|
||||
```
|
||||
1. Force-push the branch to your fork:
|
||||
|
||||
The pull request no longer shows any conflicts.
|
||||
```shell
|
||||
git push --force-with-lease origin <your-branch-name>
|
||||
```
|
||||
|
||||
The pull request no longer shows any conflicts.
|
||||
|
||||
### Squashing commits
|
||||
|
||||
{{< note >}}
|
||||
For more information, see [Git Tools - Rewriting History](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History), or ask in the `#sig-docs` Slack channel for help.
|
||||
For more information, see [Git Tools - Rewriting History](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History),
|
||||
or ask in the `#sig-docs` Slack channel for help.
|
||||
{{< /note >}}
|
||||
|
||||
If your PR has multiple commits, you must squash them into a single commit before merging your PR. You can check the number of commits on your PR's **Commits** tab or by running the `git log` command locally.
|
||||
If your PR has multiple commits, you must squash them into a single commit before merging your PR.
|
||||
You can check the number of commits on your PR's **Commits** tab or by running the `git log`
|
||||
command locally.
|
||||
|
||||
{{< note >}}
|
||||
This topic assumes `vim` as the command line text editor.
|
||||
@@ -512,79 +545,83 @@ This topic assumes `vim` as the command line text editor.
|
||||
|
||||
1. Start an interactive rebase:
|
||||
|
||||
```bash
|
||||
git rebase -i HEAD~<number_of_commits_in_branch>
|
||||
```
|
||||
```shell
|
||||
git rebase -i HEAD~<number_of_commits_in_branch>
|
||||
```
|
||||
|
||||
Squashing commits is a form of rebasing. The `-i` switch tells git you want to rebase interactively. `HEAD~<number_of_commits_in_branch` indicates how many commits to look at for the rebase.
|
||||
Squashing commits is a form of rebasing. The `-i` switch tells git you want to rebase interactively.
|
||||
`HEAD~<number_of_commits_in_branch` indicates how many commits to look at for the rebase.
|
||||
|
||||
Output is similar to:
|
||||
Output is similar to:
|
||||
|
||||
```bash
|
||||
pick d875112ca Original commit
|
||||
pick 4fa167b80 Address feedback 1
|
||||
pick 7d54e15ee Address feedback 2
|
||||
```none
|
||||
pick d875112ca Original commit
|
||||
pick 4fa167b80 Address feedback 1
|
||||
pick 7d54e15ee Address feedback 2
|
||||
|
||||
# Rebase 3d18sf680..7d54e15ee onto 3d183f680 (3 commands)
|
||||
# Rebase 3d18sf680..7d54e15ee onto 3d183f680 (3 commands)
|
||||
|
||||
...
|
||||
...
|
||||
|
||||
# These lines can be re-ordered; they are executed from top to bottom.
|
||||
```
|
||||
# These lines can be re-ordered; they are executed from top to bottom.
|
||||
```
|
||||
|
||||
The first section of the output lists the commits in the rebase. The second section lists the options for each commit. Changing the word `pick` changes the status of the commit once the rebase is complete.
|
||||
The first section of the output lists the commits in the rebase. The second section lists the
|
||||
options for each commit. Changing the word `pick` changes the status of the commit once the rebase
|
||||
is complete.
|
||||
|
||||
For the purposes of rebasing, focus on `squash` and `pick`.
|
||||
For the purposes of rebasing, focus on `squash` and `pick`.
|
||||
|
||||
{{< note >}}
|
||||
For more information, see [Interactive Mode](https://git-scm.com/docs/git-rebase#_interactive_mode).
|
||||
{{< /note >}}
|
||||
{{< note >}}
|
||||
For more information, see [Interactive Mode](https://git-scm.com/docs/git-rebase#_interactive_mode).
|
||||
{{< /note >}}
|
||||
|
||||
2. Start editing the file.
|
||||
1. Start editing the file.
|
||||
|
||||
Change the original text:
|
||||
Change the original text:
|
||||
|
||||
```bash
|
||||
pick d875112ca Original commit
|
||||
pick 4fa167b80 Address feedback 1
|
||||
pick 7d54e15ee Address feedback 2
|
||||
```
|
||||
```none
|
||||
pick d875112ca Original commit
|
||||
pick 4fa167b80 Address feedback 1
|
||||
pick 7d54e15ee Address feedback 2
|
||||
```
|
||||
|
||||
To:
|
||||
To:
|
||||
|
||||
```bash
|
||||
pick d875112ca Original commit
|
||||
squash 4fa167b80 Address feedback 1
|
||||
squash 7d54e15ee Address feedback 2
|
||||
```
|
||||
```none
|
||||
pick d875112ca Original commit
|
||||
squash 4fa167b80 Address feedback 1
|
||||
squash 7d54e15ee Address feedback 2
|
||||
```
|
||||
|
||||
This squashes commits `4fa167b80 Address feedback 1` and `7d54e15ee Address feedback 2` into `d875112ca Original commit`, leaving only `d875112ca Original commit` as a part of the timeline.
|
||||
This squashes commits `4fa167b80 Address feedback 1` and `7d54e15ee Address feedback 2` into
|
||||
`d875112ca Original commit`, leaving only `d875112ca Original commit` as a part of the timeline.
|
||||
|
||||
3. Save and exit your file.
|
||||
1. Save and exit your file.
|
||||
|
||||
4. Push your squashed commit:
|
||||
1. Push your squashed commit:
|
||||
|
||||
```bash
|
||||
git push --force-with-lease origin <branch_name>
|
||||
```
|
||||
```shell
|
||||
git push --force-with-lease origin <branch_name>
|
||||
```
|
||||
|
||||
## Contribute to other repos
|
||||
|
||||
The [Kubernetes project](https://github.com/kubernetes) contains 50+ repositories. Many of these repositories contain documentation: user-facing help text, error messages, API references or code comments.
|
||||
The [Kubernetes project](https://github.com/kubernetes) contains 50+ repositories. Many of these
|
||||
repositories contain documentation: user-facing help text, error messages, API references or code
|
||||
comments.
|
||||
|
||||
If you see text you'd like to improve, use GitHub to search all repositories in the Kubernetes organization.
|
||||
This can help you figure out where to submit your issue or PR.
|
||||
If you see text you'd like to improve, use GitHub to search all repositories in the Kubernetes
|
||||
organization. This can help you figure out where to submit your issue or PR.
|
||||
|
||||
Each repository has its own processes and procedures. Before you file an
|
||||
issue or submit a PR, read that repository's `README.md`, `CONTRIBUTING.md`, and
|
||||
`code-of-conduct.md`, if they exist.
|
||||
Each repository has its own processes and procedures. Before you file an issue or submit a PR,
|
||||
read that repository's `README.md`, `CONTRIBUTING.md`, and `code-of-conduct.md`, if they exist.
|
||||
|
||||
Most repositories use issue and PR templates. Have a look through some open
|
||||
issues and PRs to get a feel for that team's processes. Make sure to fill out
|
||||
the templates with as much detail as possible when you file issues or PRs.
|
||||
Most repositories use issue and PR templates. Have a look through some open issues and PRs to get
|
||||
a feel for that team's processes. Make sure to fill out the templates with as much detail as
|
||||
possible when you file issues or PRs.
|
||||
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
|
||||
- Read [Reviewing](/docs/contribute/review/reviewing-prs) to learn more about the review process.
|
||||
|
||||
|
||||
@@ -115,6 +115,6 @@ SIG Docs approvers. Here's how it works.
|
||||
|
||||
For more information about contributing to the Kubernetes documentation, see:
|
||||
|
||||
- [Contributing new content](/docs/contribute/new-content/overview/)
|
||||
- [Contributing new content](/docs/contribute/new-content/)
|
||||
- [Reviewing content](/docs/contribute/review/reviewing-prs)
|
||||
- [Documentation style guide](/docs/contribute/style/)
|
||||
|
||||
@@ -32,7 +32,7 @@ Anyone can:
|
||||
- Suggest improvements on [Slack](https://slack.k8s.io/) or the
|
||||
[SIG docs mailing list](https://groups.google.com/forum/#!forum/kubernetes-sig-docs).
|
||||
|
||||
After [signing the CLA](/docs/contribute/new-content/overview/#sign-the-cla), anyone can also:
|
||||
After [signing the CLA](https://github.com/kubernetes/community/blob/master/CLA.md), anyone can also:
|
||||
|
||||
- Open a pull request to improve existing content, add new content, or write a blog post or case study
|
||||
- Create diagrams, graphics assets, and embeddable screencasts and videos
|
||||
|
||||
@@ -141,7 +141,7 @@ To add a label, leave a comment in one of the following formats:
|
||||
To remove a label, leave a comment in one of the following formats:
|
||||
|
||||
- `/remove-<label-to-remove>` (for example, `/remove-help`)
|
||||
- `/remove-<label-category> <label-to-remove>` (for example, `/remove-triage needs-information`)`
|
||||
- `/remove-<label-category> <label-to-remove>` (for example, `/remove-triage needs-information`)
|
||||
|
||||
In both cases, the label must already exist. If you try to add a label that does not exist, the command is
|
||||
silently ignored.
|
||||
@@ -181,7 +181,7 @@ If the dead link issue is in the API or `kubectl` documentation, assign them `/p
|
||||
|
||||
### Blog issues
|
||||
|
||||
We expect [Kubernetes Blog](https://kubernetes.io/blog/) entries to become
|
||||
We expect [Kubernetes Blog](/blog/) entries to become
|
||||
outdated over time. Therefore, we only maintain blog entries less than a year old.
|
||||
If an issue is related to a blog entry that is more than one year old,
|
||||
close the issue without fixing.
|
||||
|
||||
@@ -7,7 +7,8 @@ weight: 10
|
||||
|
||||
<!-- overview -->
|
||||
|
||||
Anyone can review a documentation pull request. Visit the [pull requests](https://github.com/kubernetes/website/pulls) section in the Kubernetes website repository to see open pull requests.
|
||||
Anyone can review a documentation pull request. Visit the [pull requests](https://github.com/kubernetes/website/pulls)
|
||||
section in the Kubernetes website repository to see open pull requests.
|
||||
|
||||
Reviewing documentation pull requests is a
|
||||
great way to introduce yourself to the Kubernetes community.
|
||||
@@ -27,7 +28,9 @@ Before reviewing, it's a good idea to:
|
||||
|
||||
Before you start a review:
|
||||
|
||||
- Read the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md) and ensure that you abide by it at all times.
|
||||
|
||||
- Read the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md)
|
||||
and ensure that you abide by it at all times.
|
||||
- Be polite, considerate, and helpful.
|
||||
- Comment on positive aspects of PRs as well as changes.
|
||||
- Be empathetic and mindful of how your review may be received.
|
||||
@@ -36,7 +39,8 @@ Before you start a review:
|
||||
|
||||
## Review process
|
||||
|
||||
In general, review pull requests for content and style in English. Figure 1 outlines the steps for the review process. The details for each step follow.
|
||||
In general, review pull requests for content and style in English. Figure 1 outlines the steps for
|
||||
the review process. The details for each step follow.
|
||||
|
||||
<!-- See https://github.com/kubernetes/website/issues/28808 for live-editor URL to this figure -->
|
||||
<!-- You can also cut/paste the mermaid code into the live editor at https://mermaid-js.github.io/mermaid-live-editor to play around with it -->
|
||||
@@ -69,32 +73,39 @@ class third,fourth white
|
||||
|
||||
Figure 1. Review process steps.
|
||||
|
||||
1. Go to
|
||||
[https://github.com/kubernetes/website/pulls](https://github.com/kubernetes/website/pulls).
|
||||
You see a list of every open pull request against the Kubernetes website and
|
||||
docs.
|
||||
1. Go to [https://github.com/kubernetes/website/pulls](https://github.com/kubernetes/website/pulls).
|
||||
You see a list of every open pull request against the Kubernetes website and docs.
|
||||
|
||||
2. Filter the open PRs using one or all of the following labels:
|
||||
- `cncf-cla: yes` (Recommended): PRs submitted by contributors who have not signed the CLA cannot be merged. See [Sign the CLA](/docs/contribute/new-content/overview/#sign-the-cla) for more information.
|
||||
- `language/en` (Recommended): Filters for english language PRs only.
|
||||
- `size/<size>`: filters for PRs of a certain size. If you're new, start with smaller PRs.
|
||||
2. Filter the open PRs using one or all of the following labels:
|
||||
|
||||
Additionally, ensure the PR isn't marked as a work in progress. PRs using the `work in progress` label are not ready for review yet.
|
||||
- `cncf-cla: yes` (Recommended): PRs submitted by contributors who have not signed the CLA
|
||||
cannot be merged. See [Sign the CLA](/docs/contribute/new-content/#sign-the-cla)
|
||||
for more information.
|
||||
- `language/en` (Recommended): Filters for english language PRs only.
|
||||
- `size/<size>`: filters for PRs of a certain size. If you're new, start with smaller PRs.
|
||||
|
||||
3. Once you've selected a PR to review, understand the change by:
|
||||
- Reading the PR description to understand the changes made, and read any linked issues
|
||||
- Reading any comments by other reviewers
|
||||
- Clicking the **Files changed** tab to see the files and lines changed
|
||||
- Previewing the changes in the Netlify preview build by scrolling to the PR's build check section at the bottom of the **Conversation** tab.
|
||||
Here's a screenshot (this shows GitHub's desktop site; if you're reviewing
|
||||
on a tablet or smartphone device, the GitHub web UI is slightly different):
|
||||
{{< figure src="/images/docs/github_netlify_deploy_preview.png" alt="GitHub pull request details including link to Netlify preview" >}}
|
||||
To open the preview, click on the **Details** link of the **deploy/netlify** line in the list of checks.
|
||||
Additionally, ensure the PR isn't marked as a work in progress. PRs using the `work in
|
||||
progress` label are not ready for review yet.
|
||||
|
||||
4. Go to the **Files changed** tab to start your review.
|
||||
1. Click on the `+` symbol beside the line you want to comment on.
|
||||
2. Fill in any comments you have about the line and click either **Add single comment** (if you have only one comment to make) or **Start a review** (if you have multiple comments to make).
|
||||
3. When finished, click **Review changes** at the top of the page. Here, you can add
|
||||
3. Once you've selected a PR to review, understand the change by:
|
||||
|
||||
- Reading the PR description to understand the changes made, and read any linked issues
|
||||
- Reading any comments by other reviewers
|
||||
- Clicking the **Files changed** tab to see the files and lines changed
|
||||
- Previewing the changes in the Netlify preview build by scrolling to the PR's build check
|
||||
section at the bottom of the **Conversation** tab.
|
||||
Here's a screenshot (this shows GitHub's desktop site; if you're reviewing
|
||||
on a tablet or smartphone device, the GitHub web UI is slightly different):
|
||||
{{< figure src="/images/docs/github_netlify_deploy_preview.png" alt="GitHub pull request details including link to Netlify preview" >}}
|
||||
To open the preview, click on the **Details** link of the **deploy/netlify** line in the
|
||||
list of checks.
|
||||
|
||||
4. Go to the **Files changed** tab to start your review.
|
||||
|
||||
1. Click on the `+` symbol beside the line you want to comment on.
|
||||
1. Fill in any comments you have about the line and click either **Add single comment** (if you
|
||||
have only one comment to make) or **Start a review** (if you have multiple comments to make).
|
||||
1. When finished, click **Review changes** at the top of the page. Here, you can add
|
||||
a summary of your review (and leave some positive comments for the contributor!),
|
||||
approve the PR, comment or request changes as needed. New contributors should always
|
||||
choose **Comment**.
|
||||
@@ -119,14 +130,22 @@ When reviewing, use the following as a starting point.
|
||||
|
||||
### Website
|
||||
|
||||
- Did this PR change or remove a page title, slug/alias or anchor link? If so, are there broken links as a result of this PR? Is there another option, like changing the page title without changing the slug?
|
||||
- Did this PR change or remove a page title, slug/alias or anchor link? If so, are there broken
|
||||
links as a result of this PR? Is there another option, like changing the page title without
|
||||
changing the slug?
|
||||
|
||||
- Does the PR introduce a new page? If so:
|
||||
- Is the page using the right [page content type](/docs/contribute/style/page-content-types/) and associated Hugo shortcodes?
|
||||
|
||||
- Is the page using the right [page content type](/docs/contribute/style/page-content-types/)
|
||||
and associated Hugo shortcodes?
|
||||
- Does the page appear correctly in the section's side navigation (or at all)?
|
||||
- Should the page appear on the [Docs Home](/docs/home/) listing?
|
||||
- Do the changes show up in the Netlify preview? Be particularly vigilant about lists, code blocks, tables, notes and images.
|
||||
|
||||
- Do the changes show up in the Netlify preview? Be particularly vigilant about lists, code
|
||||
blocks, tables, notes and images.
|
||||
|
||||
### Other
|
||||
|
||||
For small issues with a PR, like typos or whitespace, prefix your comments with `nit:`. This lets the author know the issue is non-critical.
|
||||
For small issues with a PR, like typos or whitespace, prefix your comments with `nit:`.
|
||||
This lets the author know the issue is non-critical.
|
||||
|
||||
|
||||
@@ -242,7 +242,7 @@ Figure 17. A to B
|
||||
more text
|
||||
```
|
||||
{{< note >}}
|
||||
You must include the `{{</* mermaid */>}}`, `{{</* /mermaid */>}}` shortcode
|
||||
You must include the Hugo Mermaid shortcode
|
||||
tags at the start and end of the Mermaid code block. You should add a diagram
|
||||
caption below the diagram.
|
||||
{{< /note >}}
|
||||
@@ -429,7 +429,7 @@ Don't forget to check that your diagram renders correctly using the
|
||||
This section shows several examples of Mermaid diagrams.
|
||||
|
||||
{{< note >}}
|
||||
The code block examples omit the Hugo `{{</* mermaid */>}}`, `{{</* /mermaid */>}}`
|
||||
The code block examples omit the Hugo Mermaid
|
||||
shortcode tags. This allows you to copy the code block into the live editor
|
||||
to experiment on your own.
|
||||
Note that the live editor doesn't recognize Hugo shortcodes.
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
---
|
||||
title: Suggesting content improvements
|
||||
slug: suggest-improvements
|
||||
content_type: concept
|
||||
weight: 10
|
||||
card:
|
||||
|
||||
@@ -27,7 +27,7 @@ each Pod in the scheduling queue according to constraints and available
|
||||
resources. The scheduler then ranks each valid Node and binds the Pod to a
|
||||
suitable Node. Multiple different schedulers may be used within a cluster;
|
||||
kube-scheduler is the reference implementation.
|
||||
See [scheduling](https://kubernetes.io/docs/concepts/scheduling-eviction/)
|
||||
See [scheduling](/docs/concepts/scheduling-eviction/)
|
||||
for more information about scheduling and the kube-scheduler component.
|
||||
|
||||
```
|
||||
|
||||
@@ -555,7 +555,7 @@ by kubeadm during <code>kubeadm join</code>.</p>
|
||||
<code>int32</code>
|
||||
</td>
|
||||
<td>
|
||||
<p><code>bindPorti</code> sets the secure port for the API Server to bind to.
|
||||
<p><code>bindPort</code> sets the secure port for the API Server to bind to.
|
||||
Defaults to 6443.</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -16,7 +16,4 @@ tags:
|
||||
|
||||
Some examples of Managed Services are AWS EC2, Azure SQL Database, and
|
||||
GCP Pub/Sub, but they can be any software offering that can be used by an application.
|
||||
[Service Catalog](/docs/concepts/extend-kubernetes/service-catalog/) provides a way to
|
||||
list, provision, and bind with Managed Services offered by
|
||||
{{< glossary_tooltip text="Service Brokers" term_id="service-broker" >}}.
|
||||
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
---
|
||||
title: Service Broker
|
||||
id: service-broker
|
||||
date: 2018-04-12
|
||||
full_link:
|
||||
short_description: >
|
||||
An endpoint for a set of Managed Services offered and maintained by a third-party.
|
||||
|
||||
aka:
|
||||
tags:
|
||||
- extension
|
||||
---
|
||||
An endpoint for a set of {{< glossary_tooltip text="Managed Services" term_id="managed-service" >}} offered and maintained by a third-party.
|
||||
|
||||
<!--more-->
|
||||
|
||||
{{< glossary_tooltip text="Service Brokers" term_id="service-broker" >}} implement the
|
||||
[Open Service Broker API spec](https://github.com/openservicebrokerapi/servicebroker/blob/v2.13/spec.md)
|
||||
and provide a standard interface for applications to use their Managed Services.
|
||||
[Service Catalog](/docs/concepts/extend-kubernetes/service-catalog/) provides a way to
|
||||
list, provision, and bind with Managed Services offered by Service Brokers.
|
||||
|
||||
@@ -4,15 +4,15 @@ id: service-catalog
|
||||
date: 2018-04-12
|
||||
full_link:
|
||||
short_description: >
|
||||
An extension API that enables applications running in Kubernetes clusters to easily use external managed software offerings, such as a datastore service offered by a cloud provider.
|
||||
A former extension API that enabled applications running in Kubernetes clusters to easily use external managed software offerings, such as a datastore service offered by a cloud provider.
|
||||
|
||||
aka:
|
||||
tags:
|
||||
- extension
|
||||
---
|
||||
An extension API that enables applications running in Kubernetes clusters to easily use external managed software offerings, such as a datastore service offered by a cloud provider.
|
||||
A former extension API that enabled applications running in Kubernetes clusters to easily use external managed software offerings, such as a datastore service offered by a cloud provider.
|
||||
|
||||
<!--more-->
|
||||
|
||||
It provides a way to list, provision, and bind with external {{< glossary_tooltip text="Managed Services" term_id="managed-service" >}} from {{< glossary_tooltip text="Service Brokers" term_id="service-broker" >}} without needing detailed knowledge about how those services are created or managed.
|
||||
It provided a way to list, provision, and bind with external {{< glossary_tooltip text="Managed Services" term_id="managed-service" >}} without needing detailed knowledge about how those services would be created or managed.
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ complete -o default -F __start_kubectl k
|
||||
|
||||
```bash
|
||||
source <(kubectl completion zsh) # setup autocomplete in zsh into the current shell
|
||||
echo "[[ $commands[kubectl] ]] && source <(kubectl completion zsh)" >> ~/.zshrc # add autocomplete permanently to your zsh shell
|
||||
echo '[[ $commands[kubectl] ]] && source <(kubectl completion zsh)' >> ~/.zshrc # add autocomplete permanently to your zsh shell
|
||||
```
|
||||
### A Note on --all-namespaces
|
||||
|
||||
@@ -381,6 +381,9 @@ kubectl cluster-info # Display
|
||||
kubectl cluster-info dump # Dump current cluster state to stdout
|
||||
kubectl cluster-info dump --output-directory=/path/to/cluster-state # Dump current cluster state to /path/to/cluster-state
|
||||
|
||||
# View existing taints on which exist on current nodes.
|
||||
kubectl get nodes -o=custom-columns=NodeName:.metadata.name,TaintKey:.spec.taints[*].key,TaintValue:.spec.taints[*].value,TaintEffect:.spec.taints[*].effect
|
||||
|
||||
# If a taint with that key and effect already exists, its value is replaced as specified.
|
||||
kubectl taint nodes foo dedicated=special-user:NoSchedule
|
||||
```
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ Generate keys and certificate signing requests
|
||||
|
||||
Generates keys and certificate signing requests (CSRs) for all the certificates required to run the control plane. This command also generates partial kubeconfig files with private key data in the "users > user > client-key-data" field, and for each kubeconfig file an accompanying ".csr" file is created.
|
||||
|
||||
This command is designed for use in [Kubeadm External CA Mode](https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/#external-ca-mode). It generates CSRs which you can then submit to your external certificate authority for signing.
|
||||
This command is designed for use in [Kubeadm External CA Mode](/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/#external-ca-mode). It generates CSRs which you can then submit to your external certificate authority for signing.
|
||||
|
||||
The PEM encoded signed certificates should then be saved alongside the key files, using ".crt" as the file extension, or in the case of kubeconfig files, the PEM encoded signed certificate should be base64 encoded and added to the kubeconfig file in the "users > user > client-certificate-data" field.
|
||||
|
||||
|
||||
@@ -28,14 +28,17 @@ The following client libraries are officially maintained by
|
||||
[Kubernetes SIG API Machinery](https://github.com/kubernetes/community/tree/master/sig-api-machinery).
|
||||
|
||||
|
||||
| Language | Client Library | Sample Programs |
|
||||
|----------|----------------|-----------------|
|
||||
| dotnet | [github.com/kubernetes-client/csharp](https://github.com/kubernetes-client/csharp) | [browse](https://github.com/kubernetes-client/csharp/tree/master/examples/simple)
|
||||
| Go | [github.com/kubernetes/client-go/](https://github.com/kubernetes/client-go/) | [browse](https://github.com/kubernetes/client-go/tree/master/examples)
|
||||
| Haskell | [github.com/kubernetes-client/haskell](https://github.com/kubernetes-client/haskell) | [browse](https://github.com/kubernetes-client/haskell/tree/master/kubernetes-client/example)
|
||||
| Java | [github.com/kubernetes-client/java](https://github.com/kubernetes-client/java/) | [browse](https://github.com/kubernetes-client/java#installation)
|
||||
| JavaScript | [github.com/kubernetes-client/javascript](https://github.com/kubernetes-client/javascript) | [browse](https://github.com/kubernetes-client/javascript/tree/master/examples)
|
||||
| Python | [github.com/kubernetes-client/python/](https://github.com/kubernetes-client/python/) | [browse](https://github.com/kubernetes-client/python/tree/master/examples)
|
||||
| Language | Client Library | Sample Programs |
|
||||
|------------|----------------|-----------------|
|
||||
| C | [github.com/kubernetes-client/c](https://github.com/kubernetes-client/c/) | [browse](https://github.com/kubernetes-client/c/tree/master/examples)
|
||||
| dotnet | [github.com/kubernetes-client/csharp](https://github.com/kubernetes-client/csharp) | [browse](https://github.com/kubernetes-client/csharp/tree/master/examples/simple)
|
||||
| Go | [github.com/kubernetes/client-go/](https://github.com/kubernetes/client-go/) | [browse](https://github.com/kubernetes/client-go/tree/master/examples)
|
||||
| Haskell | [github.com/kubernetes-client/haskell](https://github.com/kubernetes-client/haskell) | [browse](https://github.com/kubernetes-client/haskell/tree/master/kubernetes-client/example)
|
||||
| Java | [github.com/kubernetes-client/java](https://github.com/kubernetes-client/java/) | [browse](https://github.com/kubernetes-client/java#installation)
|
||||
| JavaScript | [github.com/kubernetes-client/javascript](https://github.com/kubernetes-client/javascript) | [browse](https://github.com/kubernetes-client/javascript/tree/master/examples)
|
||||
| Perl | [github.com/kubernetes-client/perl/](https://github.com/kubernetes-client/perl/) | [browse](https://github.com/kubernetes-client/perl/tree/master/examples)
|
||||
| Python | [github.com/kubernetes-client/python/](https://github.com/kubernetes-client/python/) | [browse](https://github.com/kubernetes-client/python/tree/master/examples)
|
||||
| Ruby | [github.com/kubernetes-client/ruby/](https://github.com/kubernetes-client/ruby/) | [browse](https://github.com/kubernetes-client/ruby/tree/master/examples)
|
||||
|
||||
## Community-maintained client libraries
|
||||
|
||||
|
||||
@@ -330,7 +330,7 @@ For example:
|
||||
|
||||
### Locate use of deprecated APIs
|
||||
|
||||
Use [client warnings, metrics, and audit information available in 1.19+](https://kubernetes.io/blog/2020/09/03/warnings/#deprecation-warnings)
|
||||
Use [client warnings, metrics, and audit information available in 1.19+](/blog/2020/09/03/warnings/#deprecation-warnings)
|
||||
to locate use of deprecated APIs.
|
||||
|
||||
### Migrate to non-deprecated APIs
|
||||
@@ -340,11 +340,11 @@ to locate use of deprecated APIs.
|
||||
|
||||
You can use the `kubectl-convert` command (`kubectl convert` prior to v1.20)
|
||||
to automatically convert an existing object:
|
||||
|
||||
|
||||
`kubectl-convert -f <file> --output-version <group>/<version>`.
|
||||
|
||||
For example, to convert an older Deployment to `apps/v1`, you can run:
|
||||
|
||||
|
||||
`kubectl-convert -f ./my-deployment.yaml --output-version apps/v1`
|
||||
|
||||
Note that this may use non-ideal default values. To learn more about a specific
|
||||
|
||||
@@ -67,4 +67,5 @@ for deploying Kubernetes is [kubeadm](/docs/setup/production-environment/tools/k
|
||||
Kubernetes is designed for its {{< glossary_tooltip term_id="control-plane" text="control plane" >}} to
|
||||
run on Linux. Within your cluster you can run applications on Linux or other operating systems, including
|
||||
Windows.
|
||||
- Learn to [set up clusters with Windows nodes](/docs/setup/production-environment/windows/)
|
||||
|
||||
- Learn to [set up clusters with Windows nodes](/docs/concepts/windows/)
|
||||
|
||||
@@ -28,47 +28,47 @@ on or hand to others, consider how your requirements for a Kubernetes cluster
|
||||
are influenced by the following issues:
|
||||
|
||||
- *Availability*: A single-machine Kubernetes [learning environment](/docs/setup/#learning-environment)
|
||||
has a single point of failure. Creating a highly available cluster means considering:
|
||||
has a single point of failure. Creating a highly available cluster means considering:
|
||||
- Separating the control plane from the worker nodes.
|
||||
- Replicating the control plane components on multiple nodes.
|
||||
- Load balancing traffic to the cluster’s {{< glossary_tooltip term_id="kube-apiserver" text="API server" >}}.
|
||||
- Having enough worker nodes available, or able to quickly become available, as changing workloads warrant it.
|
||||
|
||||
- *Scale*: If you expect your production Kubernetes environment to receive a stable amount of
|
||||
demand, you might be able to set up for the capacity you need and be done. However,
|
||||
if you expect demand to grow over time or change dramatically based on things like
|
||||
season or special events, you need to plan how to scale to relieve increased
|
||||
pressure from more requests to the control plane and worker nodes or scale down to reduce unused
|
||||
resources.
|
||||
demand, you might be able to set up for the capacity you need and be done. However,
|
||||
if you expect demand to grow over time or change dramatically based on things like
|
||||
season or special events, you need to plan how to scale to relieve increased
|
||||
pressure from more requests to the control plane and worker nodes or scale down to reduce unused
|
||||
resources.
|
||||
|
||||
- *Security and access management*: You have full admin privileges on your own
|
||||
Kubernetes learning cluster. But shared clusters with important workloads, and
|
||||
more than one or two users, require a more refined approach to who and what can
|
||||
access cluster resources. You can use role-based access control
|
||||
([RBAC](/docs/reference/access-authn-authz/rbac/)) and other
|
||||
security mechanisms to make sure that users and workloads can get access to the
|
||||
resources they need, while keeping workloads, and the cluster itself, secure.
|
||||
You can set limits on the resources that users and workloads can access
|
||||
by managing [policies](/docs/concepts/policy/) and
|
||||
[container resources](/docs/concepts/configuration/manage-resources-containers/).
|
||||
Kubernetes learning cluster. But shared clusters with important workloads, and
|
||||
more than one or two users, require a more refined approach to who and what can
|
||||
access cluster resources. You can use role-based access control
|
||||
([RBAC](/docs/reference/access-authn-authz/rbac/)) and other
|
||||
security mechanisms to make sure that users and workloads can get access to the
|
||||
resources they need, while keeping workloads, and the cluster itself, secure.
|
||||
You can set limits on the resources that users and workloads can access
|
||||
by managing [policies](/docs/concepts/policy/) and
|
||||
[container resources](/docs/concepts/configuration/manage-resources-containers/).
|
||||
|
||||
Before building a Kubernetes production environment on your own, consider
|
||||
handing off some or all of this job to
|
||||
[Turnkey Cloud Solutions](/docs/setup/production-environment/turnkey-solutions/)
|
||||
providers or other [Kubernetes Partners](https://kubernetes.io/partners/).
|
||||
providers or other [Kubernetes Partners](/partners/).
|
||||
Options include:
|
||||
|
||||
- *Serverless*: Just run workloads on third-party equipment without managing
|
||||
a cluster at all. You will be charged for things like CPU usage, memory, and
|
||||
disk requests.
|
||||
a cluster at all. You will be charged for things like CPU usage, memory, and
|
||||
disk requests.
|
||||
- *Managed control plane*: Let the provider manage the scale and availability
|
||||
of the cluster's control plane, as well as handle patches and upgrades.
|
||||
of the cluster's control plane, as well as handle patches and upgrades.
|
||||
- *Managed worker nodes*: Configure pools of nodes to meet your needs,
|
||||
then the provider makes sure those nodes are available and ready to implement
|
||||
upgrades when needed.
|
||||
then the provider makes sure those nodes are available and ready to implement
|
||||
upgrades when needed.
|
||||
- *Integration*: There are providers that integrate Kubernetes with other
|
||||
services you may need, such as storage, container registries, authentication
|
||||
methods, and development tools.
|
||||
services you may need, such as storage, container registries, authentication
|
||||
methods, and development tools.
|
||||
|
||||
Whether you build a production Kubernetes cluster yourself or work with
|
||||
partners, review the following sections to evaluate your needs as they relate
|
||||
@@ -99,52 +99,52 @@ and ensuring that it can be repaired if something goes wrong is important,
|
||||
consider these steps:
|
||||
|
||||
- *Choose deployment tools*: You can deploy a control plane using tools such
|
||||
as kubeadm, kops, and kubespray. See
|
||||
[Installing Kubernetes with deployment tools](/docs/setup/production-environment/tools/)
|
||||
to learn tips for production-quality deployments using each of those deployment
|
||||
methods. Different [Container Runtimes](/docs/setup/production-environment/container-runtimes/)
|
||||
are available to use with your deployments.
|
||||
as kubeadm, kops, and kubespray. See
|
||||
[Installing Kubernetes with deployment tools](/docs/setup/production-environment/tools/)
|
||||
to learn tips for production-quality deployments using each of those deployment
|
||||
methods. Different [Container Runtimes](/docs/setup/production-environment/container-runtimes/)
|
||||
are available to use with your deployments.
|
||||
- *Manage certificates*: Secure communications between control plane services
|
||||
are implemented using certificates. Certificates are automatically generated
|
||||
during deployment or you can generate them using your own certificate authority.
|
||||
See [PKI certificates and requirements](/docs/setup/best-practices/certificates/) for details.
|
||||
are implemented using certificates. Certificates are automatically generated
|
||||
during deployment or you can generate them using your own certificate authority.
|
||||
See [PKI certificates and requirements](/docs/setup/best-practices/certificates/) for details.
|
||||
- *Configure load balancer for apiserver*: Configure a load balancer
|
||||
to distribute external API requests to the apiserver service instances running on different nodes. See
|
||||
[Create an External Load Balancer](/docs/tasks/access-application-cluster/create-external-load-balancer/)
|
||||
for details.
|
||||
to distribute external API requests to the apiserver service instances running on different nodes. See
|
||||
[Create an External Load Balancer](/docs/tasks/access-application-cluster/create-external-load-balancer/)
|
||||
for details.
|
||||
- *Separate and backup etcd service*: The etcd services can either run on the
|
||||
same machines as other control plane services or run on separate machines, for
|
||||
extra security and availability. Because etcd stores cluster configuration data,
|
||||
backing up the etcd database should be done regularly to ensure that you can
|
||||
repair that database if needed.
|
||||
See the [etcd FAQ](https://etcd.io/docs/v3.4/faq/) for details on configuring and using etcd.
|
||||
See [Operating etcd clusters for Kubernetes](/docs/tasks/administer-cluster/configure-upgrade-etcd/)
|
||||
and [Set up a High Availability etcd cluster with kubeadm](/docs/setup/production-environment/tools/kubeadm/setup-ha-etcd-with-kubeadm/)
|
||||
for details.
|
||||
same machines as other control plane services or run on separate machines, for
|
||||
extra security and availability. Because etcd stores cluster configuration data,
|
||||
backing up the etcd database should be done regularly to ensure that you can
|
||||
repair that database if needed.
|
||||
See the [etcd FAQ](https://etcd.io/docs/v3.4/faq/) for details on configuring and using etcd.
|
||||
See [Operating etcd clusters for Kubernetes](/docs/tasks/administer-cluster/configure-upgrade-etcd/)
|
||||
and [Set up a High Availability etcd cluster with kubeadm](/docs/setup/production-environment/tools/kubeadm/setup-ha-etcd-with-kubeadm/)
|
||||
for details.
|
||||
- *Create multiple control plane systems*: For high availability, the
|
||||
control plane should not be limited to a single machine. If the control plane
|
||||
services are run by an init service (such as systemd), each service should run on at
|
||||
least three machines. However, running control plane services as pods in
|
||||
Kubernetes ensures that the replicated number of services that you request
|
||||
will always be available.
|
||||
The scheduler should be fault tolerant,
|
||||
but not highly available. Some deployment tools set up [Raft](https://raft.github.io/)
|
||||
consensus algorithm to do leader election of Kubernetes services. If the
|
||||
primary goes away, another service elects itself and take over.
|
||||
control plane should not be limited to a single machine. If the control plane
|
||||
services are run by an init service (such as systemd), each service should run on at
|
||||
least three machines. However, running control plane services as pods in
|
||||
Kubernetes ensures that the replicated number of services that you request
|
||||
will always be available.
|
||||
The scheduler should be fault tolerant,
|
||||
but not highly available. Some deployment tools set up [Raft](https://raft.github.io/)
|
||||
consensus algorithm to do leader election of Kubernetes services. If the
|
||||
primary goes away, another service elects itself and take over.
|
||||
- *Span multiple zones*: If keeping your cluster available at all times is
|
||||
critical, consider creating a cluster that runs across multiple data centers,
|
||||
referred to as zones in cloud environments. Groups of zones are referred to as regions.
|
||||
By spreading a cluster across
|
||||
multiple zones in the same region, it can improve the chances that your
|
||||
cluster will continue to function even if one zone becomes unavailable.
|
||||
See [Running in multiple zones](/docs/setup/best-practices/multiple-zones/) for details.
|
||||
critical, consider creating a cluster that runs across multiple data centers,
|
||||
referred to as zones in cloud environments. Groups of zones are referred to as regions.
|
||||
By spreading a cluster across
|
||||
multiple zones in the same region, it can improve the chances that your
|
||||
cluster will continue to function even if one zone becomes unavailable.
|
||||
See [Running in multiple zones](/docs/setup/best-practices/multiple-zones/) for details.
|
||||
- *Manage on-going features*: If you plan to keep your cluster over time,
|
||||
there are tasks you need to do to maintain its health and security. For example,
|
||||
if you installed with kubeadm, there are instructions to help you with
|
||||
[Certificate Management](/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/)
|
||||
and [Upgrading kubeadm clusters](/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/).
|
||||
See [Administer a Cluster](/docs/tasks/administer-cluster/)
|
||||
for a longer list of Kubernetes administrative tasks.
|
||||
there are tasks you need to do to maintain its health and security. For example,
|
||||
if you installed with kubeadm, there are instructions to help you with
|
||||
[Certificate Management](/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/)
|
||||
and [Upgrading kubeadm clusters](/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/).
|
||||
See [Administer a Cluster](/docs/tasks/administer-cluster/)
|
||||
for a longer list of Kubernetes administrative tasks.
|
||||
|
||||
To learn about available options when you run control plane services, see
|
||||
[kube-apiserver](/docs/reference/command-line-tools-reference/kube-apiserver/),
|
||||
@@ -166,39 +166,36 @@ consider how you want to manage your worker nodes (also referred to
|
||||
simply as *nodes*).
|
||||
|
||||
- *Configure nodes*: Nodes can be physical or virtual machines. If you want to
|
||||
create and manage your own nodes, you can install a supported operating system,
|
||||
then add and run the appropriate
|
||||
[Node services](/docs/concepts/overview/components/#node-components). Consider:
|
||||
create and manage your own nodes, you can install a supported operating system,
|
||||
then add and run the appropriate
|
||||
[Node services](/docs/concepts/overview/components/#node-components). Consider:
|
||||
- The demands of your workloads when you set up nodes by having appropriate memory, CPU, and disk speed and storage capacity available.
|
||||
- Whether generic computer systems will do or you have workloads that need GPU processors, Windows nodes, or VM isolation.
|
||||
- *Validate nodes*: See [Valid node setup](/docs/setup/best-practices/node-conformance/)
|
||||
for information on how to ensure that a node meets the requirements to join
|
||||
a Kubernetes cluster.
|
||||
for information on how to ensure that a node meets the requirements to join
|
||||
a Kubernetes cluster.
|
||||
- *Add nodes to the cluster*: If you are managing your own cluster you can
|
||||
add nodes by setting up your own machines and either adding them manually or
|
||||
having them register themselves to the cluster’s apiserver. See the
|
||||
[Nodes](/docs/concepts/architecture/nodes/) section for information on how to set up Kubernetes to add nodes in these ways.
|
||||
- *Add Windows nodes to the cluster*: Kubernetes offers support for Windows
|
||||
worker nodes, allowing you to run workloads implemented in Windows containers. See
|
||||
[Windows in Kubernetes](/docs/setup/production-environment/windows/) for details.
|
||||
add nodes by setting up your own machines and either adding them manually or
|
||||
having them register themselves to the cluster’s apiserver. See the
|
||||
[Nodes](/docs/concepts/architecture/nodes/) section for information on how to set up Kubernetes to add nodes in these ways.
|
||||
- *Scale nodes*: Have a plan for expanding the capacity your cluster will
|
||||
eventually need. See [Considerations for large clusters](/docs/setup/best-practices/cluster-large/)
|
||||
to help determine how many nodes you need, based on the number of pods and
|
||||
containers you need to run. If you are managing nodes yourself, this can mean
|
||||
purchasing and installing your own physical equipment.
|
||||
eventually need. See [Considerations for large clusters](/docs/setup/best-practices/cluster-large/)
|
||||
to help determine how many nodes you need, based on the number of pods and
|
||||
containers you need to run. If you are managing nodes yourself, this can mean
|
||||
purchasing and installing your own physical equipment.
|
||||
- *Autoscale nodes*: Most cloud providers support
|
||||
[Cluster Autoscaler](https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler#readme)
|
||||
to replace unhealthy nodes or grow and shrink the number of nodes as demand requires. See the
|
||||
[Frequently Asked Questions](https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/FAQ.md)
|
||||
for how the autoscaler works and
|
||||
[Deployment](https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler#deployment)
|
||||
for how it is implemented by different cloud providers. For on-premises, there
|
||||
are some virtualization platforms that can be scripted to spin up new nodes
|
||||
based on demand.
|
||||
[Cluster Autoscaler](https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler#readme)
|
||||
to replace unhealthy nodes or grow and shrink the number of nodes as demand requires. See the
|
||||
[Frequently Asked Questions](https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/FAQ.md)
|
||||
for how the autoscaler works and
|
||||
[Deployment](https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler#deployment)
|
||||
for how it is implemented by different cloud providers. For on-premises, there
|
||||
are some virtualization platforms that can be scripted to spin up new nodes
|
||||
based on demand.
|
||||
- *Set up node health checks*: For important workloads, you want to make sure
|
||||
that the nodes and pods running on those nodes are healthy. Using the
|
||||
[Node Problem Detector](/docs/tasks/debug/debug-cluster/monitor-node-health/)
|
||||
daemon, you can ensure your nodes are healthy.
|
||||
that the nodes and pods running on those nodes are healthy. Using the
|
||||
[Node Problem Detector](/docs/tasks/debug/debug-cluster/monitor-node-health/)
|
||||
daemon, you can ensure your nodes are healthy.
|
||||
|
||||
## Production user management
|
||||
|
||||
@@ -215,39 +212,51 @@ cluster (authentication) and deciding if they have permissions to do what they
|
||||
are asking (authorization):
|
||||
|
||||
- *Authentication*: The apiserver can authenticate users using client
|
||||
certificates, bearer tokens, an authenticating proxy, or HTTP basic auth.
|
||||
You can choose which authentication methods you want to use.
|
||||
Using plugins, the apiserver can leverage your organization’s existing
|
||||
authentication methods, such as LDAP or Kerberos. See
|
||||
[Authentication](/docs/reference/access-authn-authz/authentication/)
|
||||
for a description of these different methods of authenticating Kubernetes users.
|
||||
- *Authorization*: When you set out to authorize your regular users, you will probably choose between RBAC and ABAC authorization. See [Authorization Overview](/docs/reference/access-authn-authz/authorization/) to review different modes for authorizing user accounts (as well as service account access to your cluster):
|
||||
- *Role-based access control* ([RBAC](/docs/reference/access-authn-authz/rbac/)): Lets you assign access to your cluster by allowing specific sets of permissions to authenticated users. Permissions can be assigned for a specific namespace (Role) or across the entire cluster (ClusterRole). Then using RoleBindings and ClusterRoleBindings, those permissions can be attached to particular users.
|
||||
- *Attribute-based access control* ([ABAC](/docs/reference/access-authn-authz/abac/)): Lets you create policies based on resource attributes in the cluster and will allow or deny access based on those attributes. Each line of a policy file identifies versioning properties (apiVersion and kind) and a map of spec properties to match the subject (user or group), resource property, non-resource property (/version or /apis), and readonly. See [Examples](/docs/reference/access-authn-authz/abac/#examples) for details.
|
||||
certificates, bearer tokens, an authenticating proxy, or HTTP basic auth.
|
||||
You can choose which authentication methods you want to use.
|
||||
Using plugins, the apiserver can leverage your organization’s existing
|
||||
authentication methods, such as LDAP or Kerberos. See
|
||||
[Authentication](/docs/reference/access-authn-authz/authentication/)
|
||||
for a description of these different methods of authenticating Kubernetes users.
|
||||
- *Authorization*: When you set out to authorize your regular users, you will probably choose
|
||||
between RBAC and ABAC authorization. See [Authorization Overview](/docs/reference/access-authn-authz/authorization/)
|
||||
to review different modes for authorizing user accounts (as well as service account access to
|
||||
your cluster):
|
||||
- *Role-based access control* ([RBAC](/docs/reference/access-authn-authz/rbac/)): Lets you
|
||||
assign access to your cluster by allowing specific sets of permissions to authenticated users.
|
||||
Permissions can be assigned for a specific namespace (Role) or across the entire cluster
|
||||
(ClusterRole). Then using RoleBindings and ClusterRoleBindings, those permissions can be attached
|
||||
to particular users.
|
||||
- *Attribute-based access control* ([ABAC](/docs/reference/access-authn-authz/abac/)): Lets you
|
||||
create policies based on resource attributes in the cluster and will allow or deny access
|
||||
based on those attributes. Each line of a policy file identifies versioning properties (apiVersion
|
||||
and kind) and a map of spec properties to match the subject (user or group), resource property,
|
||||
non-resource property (/version or /apis), and readonly. See
|
||||
[Examples](/docs/reference/access-authn-authz/abac/#examples) for details.
|
||||
|
||||
As someone setting up authentication and authorization on your production Kubernetes cluster, here are some things to consider:
|
||||
|
||||
- *Set the authorization mode*: When the Kubernetes API server
|
||||
([kube-apiserver](/docs/reference/command-line-tools-reference/kube-apiserver/))
|
||||
starts, the supported authentication modes must be set using the *--authorization-mode*
|
||||
flag. For example, that flag in the *kube-adminserver.yaml* file (in */etc/kubernetes/manifests*)
|
||||
could be set to Node,RBAC. This would allow Node and RBAC authorization for authenticated requests.
|
||||
([kube-apiserver](/docs/reference/command-line-tools-reference/kube-apiserver/))
|
||||
starts, the supported authentication modes must be set using the *--authorization-mode*
|
||||
flag. For example, that flag in the *kube-adminserver.yaml* file (in */etc/kubernetes/manifests*)
|
||||
could be set to Node,RBAC. This would allow Node and RBAC authorization for authenticated requests.
|
||||
- *Create user certificates and role bindings (RBAC)*: If you are using RBAC
|
||||
authorization, users can create a CertificateSigningRequest (CSR) that can be
|
||||
signed by the cluster CA. Then you can bind Roles and ClusterRoles to each user.
|
||||
See [Certificate Signing Requests](/docs/reference/access-authn-authz/certificate-signing-requests/)
|
||||
for details.
|
||||
authorization, users can create a CertificateSigningRequest (CSR) that can be
|
||||
signed by the cluster CA. Then you can bind Roles and ClusterRoles to each user.
|
||||
See [Certificate Signing Requests](/docs/reference/access-authn-authz/certificate-signing-requests/)
|
||||
for details.
|
||||
- *Create policies that combine attributes (ABAC)*: If you are using ABAC
|
||||
authorization, you can assign combinations of attributes to form policies to
|
||||
authorize selected users or groups to access particular resources (such as a
|
||||
pod), namespace, or apiGroup. For more information, see
|
||||
[Examples](/docs/reference/access-authn-authz/abac/#examples).
|
||||
authorization, you can assign combinations of attributes to form policies to
|
||||
authorize selected users or groups to access particular resources (such as a
|
||||
pod), namespace, or apiGroup. For more information, see
|
||||
[Examples](/docs/reference/access-authn-authz/abac/#examples).
|
||||
- *Consider Admission Controllers*: Additional forms of authorization for
|
||||
requests that can come in through the API server include
|
||||
[Webhook Token Authentication](/docs/reference/access-authn-authz/authentication/#webhook-token-authentication).
|
||||
Webhooks and other special authorization types need to be enabled by adding
|
||||
[Admission Controllers](/docs/reference/access-authn-authz/admission-controllers/)
|
||||
to the API server.
|
||||
requests that can come in through the API server include
|
||||
[Webhook Token Authentication](/docs/reference/access-authn-authz/authentication/#webhook-token-authentication).
|
||||
Webhooks and other special authorization types need to be enabled by adding
|
||||
[Admission Controllers](/docs/reference/access-authn-authz/admission-controllers/)
|
||||
to the API server.
|
||||
|
||||
## Set limits on workload resources
|
||||
|
||||
@@ -256,38 +265,45 @@ of the Kubernetes control plane. Consider these items when setting up for the
|
||||
needs of your cluster's workloads:
|
||||
|
||||
- *Set namespace limits*: Set per-namespace quotas on things like memory and CPU. See
|
||||
[Manage Memory, CPU, and API Resources](/docs/tasks/administer-cluster/manage-resources/)
|
||||
for details. You can also set
|
||||
[Hierarchical Namespaces](/blog/2020/08/14/introducing-hierarchical-namespaces/)
|
||||
for inheriting limits.
|
||||
[Manage Memory, CPU, and API Resources](/docs/tasks/administer-cluster/manage-resources/)
|
||||
for details. You can also set
|
||||
[Hierarchical Namespaces](/blog/2020/08/14/introducing-hierarchical-namespaces/)
|
||||
for inheriting limits.
|
||||
- *Prepare for DNS demand*: If you expect workloads to massively scale up,
|
||||
your DNS service must be ready to scale up as well. See
|
||||
[Autoscale the DNS service in a Cluster](/docs/tasks/administer-cluster/dns-horizontal-autoscaling/).
|
||||
your DNS service must be ready to scale up as well. See
|
||||
[Autoscale the DNS service in a Cluster](/docs/tasks/administer-cluster/dns-horizontal-autoscaling/).
|
||||
- *Create additional service accounts*: User accounts determine what users can
|
||||
do on a cluster, while a service account defines pod access within a particular
|
||||
namespace. By default, a pod takes on the default service account from its namespace.
|
||||
See [Managing Service Accounts](/docs/reference/access-authn-authz/service-accounts-admin/)
|
||||
for information on creating a new service account. For example, you might want to:
|
||||
- Add secrets that a pod could use to pull images from a particular container registry. See [Configure Service Accounts for Pods](/docs/tasks/configure-pod-container/configure-service-account/) for an example.
|
||||
- Assign RBAC permissions to a service account. See [ServiceAccount permissions](/docs/reference/access-authn-authz/rbac/#service-account-permissions) for details.
|
||||
do on a cluster, while a service account defines pod access within a particular
|
||||
namespace. By default, a pod takes on the default service account from its namespace.
|
||||
See [Managing Service Accounts](/docs/reference/access-authn-authz/service-accounts-admin/)
|
||||
for information on creating a new service account. For example, you might want to:
|
||||
- Add secrets that a pod could use to pull images from a particular container registry. See
|
||||
[Configure Service Accounts for Pods](/docs/tasks/configure-pod-container/configure-service-account/)
|
||||
for an example.
|
||||
- Assign RBAC permissions to a service account. See
|
||||
[ServiceAccount permissions](/docs/reference/access-authn-authz/rbac/#service-account-permissions)
|
||||
for details.
|
||||
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
- Decide if you want to build your own production Kubernetes or obtain one from
|
||||
available [Turnkey Cloud Solutions](/docs/setup/production-environment/turnkey-solutions/)
|
||||
or [Kubernetes Partners](https://kubernetes.io/partners/).
|
||||
available [Turnkey Cloud Solutions](/docs/setup/production-environment/turnkey-solutions/)
|
||||
or [Kubernetes Partners](/partners/).
|
||||
- If you choose to build your own cluster, plan how you want to
|
||||
handle [certificates](/docs/setup/best-practices/certificates/)
|
||||
and set up high availability for features such as
|
||||
[etcd](/docs/setup/production-environment/tools/kubeadm/setup-ha-etcd-with-kubeadm/)
|
||||
and the
|
||||
[API server](/docs/setup/production-environment/tools/kubeadm/ha-topology/).
|
||||
- Choose from [kubeadm](/docs/setup/production-environment/tools/kubeadm/), [kops](/docs/setup/production-environment/tools/kops/) or [Kubespray](/docs/setup/production-environment/tools/kubespray/)
|
||||
deployment methods.
|
||||
handle [certificates](/docs/setup/best-practices/certificates/)
|
||||
and set up high availability for features such as
|
||||
[etcd](/docs/setup/production-environment/tools/kubeadm/setup-ha-etcd-with-kubeadm/)
|
||||
and the
|
||||
[API server](/docs/setup/production-environment/tools/kubeadm/ha-topology/).
|
||||
- Choose from [kubeadm](/docs/setup/production-environment/tools/kubeadm/),
|
||||
[kops](/docs/setup/production-environment/tools/kops/) or
|
||||
[Kubespray](/docs/setup/production-environment/tools/kubespray/)
|
||||
deployment methods.
|
||||
- Configure user management by determining your
|
||||
[Authentication](/docs/reference/access-authn-authz/authentication/) and
|
||||
[Authorization](/docs/reference/access-authn-authz/authorization/) methods.
|
||||
[Authentication](/docs/reference/access-authn-authz/authentication/) and
|
||||
[Authorization](/docs/reference/access-authn-authz/authorization/) methods.
|
||||
- Prepare for application workloads by setting up
|
||||
[resource limits](/docs/tasks/administer-cluster/manage-resources/),
|
||||
[DNS autoscaling](/docs/tasks/administer-cluster/dns-horizontal-autoscaling/)
|
||||
and [service accounts](/docs/reference/access-authn-authz/service-accounts-admin/).
|
||||
[resource limits](/docs/tasks/administer-cluster/manage-resources/),
|
||||
[DNS autoscaling](/docs/tasks/administer-cluster/dns-horizontal-autoscaling/)
|
||||
and [service accounts](/docs/reference/access-authn-authz/service-accounts-admin/).
|
||||
|
||||
|
||||
@@ -36,8 +36,8 @@ part of Kubernetes (this removal was
|
||||
[announced](/blog/2020/12/08/kubernetes-1-20-release-announcement/#dockershim-deprecation)
|
||||
as part of the v1.20 release).
|
||||
You can read
|
||||
[Check whether Dockershim deprecation affects you](/docs/tasks/administer-cluster/migrating-from-dockershim/check-if-dockershim-deprecation-affects-you/) to understand how this removal might
|
||||
affect you. To learn about migrating from using dockershim, see
|
||||
[Check whether Dockershim removal affects you](/docs/tasks/administer-cluster/migrating-from-dockershim/check-if-dockershim-removal-affects-you/)
|
||||
to understand how this removal might affect you. To learn about migrating from using dockershim, see
|
||||
[Migrating from dockershim](/docs/tasks/administer-cluster/migrating-from-dockershim/).
|
||||
|
||||
If you are running a version of Kubernetes other than v{{< skew currentVersion >}},
|
||||
|
||||
+13
-8
@@ -11,7 +11,7 @@ weight: 30
|
||||
<img src="/images/kubeadm-stacked-color.png" align="right" width="150px"></img>
|
||||
Using `kubeadm`, you can create a minimum viable Kubernetes cluster that conforms to best practices.
|
||||
In fact, you can use `kubeadm` to set up a cluster that will pass the
|
||||
[Kubernetes Conformance tests](https://kubernetes.io/blog/2017/10/software-conformance-certification).
|
||||
[Kubernetes Conformance tests](/blog/2017/10/software-conformance-certification/).
|
||||
`kubeadm` also supports other cluster lifecycle functions, such as
|
||||
[bootstrap tokens](/docs/reference/access-authn-authz/bootstrap-tokens/) and cluster upgrades.
|
||||
|
||||
@@ -76,8 +76,9 @@ Install a {{< glossary_tooltip term_id="container-runtime" text="container runti
|
||||
For detailed instructions and other prerequisites, see [Installing kubeadm](/docs/setup/production-environment/tools/kubeadm/install-kubeadm/).
|
||||
|
||||
{{< note >}}
|
||||
If you have already installed kubeadm, run `apt-get update &&
|
||||
apt-get upgrade` or `yum update` to get the latest version of kubeadm.
|
||||
If you have already installed kubeadm, run
|
||||
`apt-get update && apt-get upgrade` or
|
||||
`yum update` to get the latest version of kubeadm.
|
||||
|
||||
When you upgrade, the kubelet restarts every few seconds as it waits in a crashloop for
|
||||
kubeadm to tell it what to do. This crashloop is expected and normal.
|
||||
@@ -91,7 +92,8 @@ to not download the default container images which are hosted at `k8s.gcr.io`.
|
||||
|
||||
Kubeadm has commands that can help you pre-pull the required images
|
||||
when creating a cluster without an internet connection on its nodes.
|
||||
See [Running kubeadm without an internet connection](/docs/reference/setup-tools/kubeadm/kubeadm-init#without-internet-connection) for more details.
|
||||
See [Running kubeadm without an internet connection](/docs/reference/setup-tools/kubeadm/kubeadm-init#without-internet-connection)
|
||||
for more details.
|
||||
|
||||
Kubeadm allows you to use a custom image repository for the required images.
|
||||
See [Using custom images](/docs/reference/setup-tools/kubeadm/kubeadm-init#custom-images)
|
||||
@@ -360,7 +362,8 @@ The output is similar to this:
|
||||
5didvk.d09sbcov8ph2amjw
|
||||
```
|
||||
|
||||
If you don't have the value of `--discovery-token-ca-cert-hash`, you can get it by running the following command chain on the control-plane node:
|
||||
If you don't have the value of `--discovery-token-ca-cert-hash`, you can get it by running the
|
||||
following command chain on the control-plane node:
|
||||
|
||||
```bash
|
||||
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | \
|
||||
@@ -501,7 +504,7 @@ options.
|
||||
* Verify that your cluster is running properly with [Sonobuoy](https://github.com/heptio/sonobuoy)
|
||||
* <a id="lifecycle" />See [Upgrading kubeadm clusters](/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/)
|
||||
for details about upgrading your cluster using `kubeadm`.
|
||||
* Learn about advanced `kubeadm` usage in the [kubeadm reference documentation](/docs/reference/setup-tools/kubeadm/kubeadm)
|
||||
* Learn about advanced `kubeadm` usage in the [kubeadm reference documentation](/docs/reference/setup-tools/kubeadm/)
|
||||
* Learn more about Kubernetes [concepts](/docs/concepts/) and [`kubectl`](/docs/reference/kubectl/).
|
||||
* See the [Cluster Networking](/docs/concepts/cluster-administration/networking/) page for a bigger list
|
||||
of Pod network add-ons.
|
||||
@@ -575,7 +578,7 @@ Example for `kubeadm upgrade`:
|
||||
or {{< skew currentVersion >}}
|
||||
|
||||
To learn more about the version skew between the different Kubernetes component see
|
||||
the [Version Skew Policy](https://kubernetes.io/releases/version-skew-policy/).
|
||||
the [Version Skew Policy](/releases/version-skew-policy/).
|
||||
|
||||
## Limitations {#limitations}
|
||||
|
||||
@@ -608,4 +611,6 @@ supports your chosen platform.
|
||||
|
||||
## Troubleshooting {#troubleshooting}
|
||||
|
||||
If you are running into difficulties with kubeadm, please consult our [troubleshooting docs](/docs/setup/production-environment/tools/kubeadm/troubleshooting-kubeadm/).
|
||||
If you are running into difficulties with kubeadm, please consult our
|
||||
[troubleshooting docs](/docs/setup/production-environment/tools/kubeadm/troubleshooting-kubeadm/).
|
||||
|
||||
|
||||
@@ -182,7 +182,6 @@ name=Kubernetes
|
||||
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch
|
||||
enabled=1
|
||||
gpgcheck=1
|
||||
repo_gpgcheck=1
|
||||
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
|
||||
exclude=kubelet kubeadm kubectl
|
||||
EOF
|
||||
|
||||
@@ -6,7 +6,7 @@ weight: 30
|
||||
|
||||
<!-- overview -->
|
||||
|
||||
This quickstart helps to install a Kubernetes cluster hosted on GCE, Azure, OpenStack, AWS, vSphere, Packet (bare metal), Oracle Cloud Infrastructure (Experimental) or Baremetal with [Kubespray](https://github.com/kubernetes-sigs/kubespray).
|
||||
This quickstart helps to install a Kubernetes cluster hosted on GCE, Azure, OpenStack, AWS, vSphere, Equinix Metal (formerly Packet), Oracle Cloud Infrastructure (Experimental) or Baremetal with [Kubespray](https://github.com/kubernetes-sigs/kubespray).
|
||||
|
||||
Kubespray is a composition of [Ansible](https://docs.ansible.com/) playbooks, [inventory](https://github.com/kubernetes-sigs/kubespray/blob/master/docs/ansible.md), provisioning tools, and domain knowledge for generic OS/Kubernetes clusters configuration management tasks. Kubespray provides:
|
||||
|
||||
@@ -46,7 +46,7 @@ Kubespray provides the following utilities to help provision your environment:
|
||||
* [Terraform](https://www.terraform.io/) scripts for the following cloud providers:
|
||||
* [AWS](https://github.com/kubernetes-sigs/kubespray/tree/master/contrib/terraform/aws)
|
||||
* [OpenStack](https://github.com/kubernetes-sigs/kubespray/tree/master/contrib/terraform/openstack)
|
||||
* [Packet](https://github.com/kubernetes-sigs/kubespray/tree/master/contrib/terraform/packet)
|
||||
* [Equinix Metal](https://github.com/kubernetes-sigs/kubespray/tree/master/contrib/terraform/metal)
|
||||
|
||||
### (2/5) Compose an inventory file
|
||||
|
||||
|
||||
+1
-1
@@ -127,7 +127,7 @@ the shared Volume is lost.
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
|
||||
* Learn more about [patterns for composite containers](https://kubernetes.io/blog/2015/06/the-distributed-system-toolkit-patterns).
|
||||
* Learn more about [patterns for composite containers](/blog/2015/06/the-distributed-system-toolkit-patterns/).
|
||||
|
||||
* Learn about [composite containers for modular architecture](https://www.slideshare.net/Docker/slideshare-burns).
|
||||
|
||||
|
||||
@@ -4,124 +4,156 @@ content_type: task
|
||||
weight: 20
|
||||
---
|
||||
|
||||
|
||||
<!-- overview -->
|
||||
|
||||
When using client certificate authentication, you can generate certificates
|
||||
manually through `easyrsa`, `openssl` or `cfssl`.
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- body -->
|
||||
|
||||
### easyrsa
|
||||
|
||||
**easyrsa** can manually generate certificates for your cluster.
|
||||
|
||||
1. Download, unpack, and initialize the patched version of easyrsa3.
|
||||
1. Download, unpack, and initialize the patched version of `easyrsa3`.
|
||||
|
||||
curl -LO https://storage.googleapis.com/kubernetes-release/easy-rsa/easy-rsa.tar.gz
|
||||
tar xzf easy-rsa.tar.gz
|
||||
cd easy-rsa-master/easyrsa3
|
||||
./easyrsa init-pki
|
||||
1. Generate a new certificate authority (CA). `--batch` sets automatic mode;
|
||||
`--req-cn` specifies the Common Name (CN) for the CA's new root certificate.
|
||||
```shell
|
||||
curl -LO https://storage.googleapis.com/kubernetes-release/easy-rsa/easy-rsa.tar.gz
|
||||
tar xzf easy-rsa.tar.gz
|
||||
cd easy-rsa-master/easyrsa3
|
||||
./easyrsa init-pki
|
||||
```
|
||||
1. Generate a new certificate authority (CA). `--batch` sets automatic mode;
|
||||
`--req-cn` specifies the Common Name (CN) for the CA's new root certificate.
|
||||
|
||||
./easyrsa --batch "--req-cn=${MASTER_IP}@`date +%s`" build-ca nopass
|
||||
1. Generate server certificate and key.
|
||||
The argument `--subject-alt-name` sets the possible IPs and DNS names the API server will
|
||||
be accessed with. The `MASTER_CLUSTER_IP` is usually the first IP from the service CIDR
|
||||
that is specified as the `--service-cluster-ip-range` argument for both the API server and
|
||||
the controller manager component. The argument `--days` is used to set the number of days
|
||||
after which the certificate expires.
|
||||
The sample below also assumes that you are using `cluster.local` as the default
|
||||
DNS domain name.
|
||||
```shell
|
||||
./easyrsa --batch "--req-cn=${MASTER_IP}@`date +%s`" build-ca nopass
|
||||
```
|
||||
|
||||
./easyrsa --subject-alt-name="IP:${MASTER_IP},"\
|
||||
"IP:${MASTER_CLUSTER_IP},"\
|
||||
"DNS:kubernetes,"\
|
||||
"DNS:kubernetes.default,"\
|
||||
"DNS:kubernetes.default.svc,"\
|
||||
"DNS:kubernetes.default.svc.cluster,"\
|
||||
"DNS:kubernetes.default.svc.cluster.local" \
|
||||
--days=10000 \
|
||||
build-server-full server nopass
|
||||
1. Copy `pki/ca.crt`, `pki/issued/server.crt`, and `pki/private/server.key` to your directory.
|
||||
1. Fill in and add the following parameters into the API server start parameters:
|
||||
1. Generate server certificate and key.
|
||||
|
||||
--client-ca-file=/yourdirectory/ca.crt
|
||||
--tls-cert-file=/yourdirectory/server.crt
|
||||
--tls-private-key-file=/yourdirectory/server.key
|
||||
The argument `--subject-alt-name` sets the possible IPs and DNS names the API server will
|
||||
be accessed with. The `MASTER_CLUSTER_IP` is usually the first IP from the service CIDR
|
||||
that is specified as the `--service-cluster-ip-range` argument for both the API server and
|
||||
the controller manager component. The argument `--days` is used to set the number of days
|
||||
after which the certificate expires.
|
||||
The sample below also assumes that you are using `cluster.local` as the default
|
||||
DNS domain name.
|
||||
|
||||
```shell
|
||||
./easyrsa --subject-alt-name="IP:${MASTER_IP},"\
|
||||
"IP:${MASTER_CLUSTER_IP},"\
|
||||
"DNS:kubernetes,"\
|
||||
"DNS:kubernetes.default,"\
|
||||
"DNS:kubernetes.default.svc,"\
|
||||
"DNS:kubernetes.default.svc.cluster,"\
|
||||
"DNS:kubernetes.default.svc.cluster.local" \
|
||||
--days=10000 \
|
||||
build-server-full server nopass
|
||||
```
|
||||
|
||||
1. Copy `pki/ca.crt`, `pki/issued/server.crt`, and `pki/private/server.key` to your directory.
|
||||
|
||||
1. Fill in and add the following parameters into the API server start parameters:
|
||||
|
||||
```shell
|
||||
--client-ca-file=/yourdirectory/ca.crt
|
||||
--tls-cert-file=/yourdirectory/server.crt
|
||||
--tls-private-key-file=/yourdirectory/server.key
|
||||
```
|
||||
|
||||
### openssl
|
||||
|
||||
**openssl** can manually generate certificates for your cluster.
|
||||
|
||||
1. Generate a ca.key with 2048bit:
|
||||
1. Generate a ca.key with 2048bit:
|
||||
|
||||
openssl genrsa -out ca.key 2048
|
||||
1. According to the ca.key generate a ca.crt (use -days to set the certificate effective time):
|
||||
```shell
|
||||
openssl genrsa -out ca.key 2048
|
||||
```
|
||||
|
||||
openssl req -x509 -new -nodes -key ca.key -subj "/CN=${MASTER_IP}" -days 10000 -out ca.crt
|
||||
1. Generate a server.key with 2048bit:
|
||||
1. According to the ca.key generate a ca.crt (use `-days` to set the certificate effective time):
|
||||
|
||||
openssl genrsa -out server.key 2048
|
||||
1. Create a config file for generating a Certificate Signing Request (CSR).
|
||||
Be sure to substitute the values marked with angle brackets (e.g. `<MASTER_IP>`)
|
||||
with real values before saving this to a file (e.g. `csr.conf`).
|
||||
Note that the value for `MASTER_CLUSTER_IP` is the service cluster IP for the
|
||||
API server as described in previous subsection.
|
||||
The sample below also assumes that you are using `cluster.local` as the default
|
||||
DNS domain name.
|
||||
```shell
|
||||
openssl req -x509 -new -nodes -key ca.key -subj "/CN=${MASTER_IP}" -days 10000 -out ca.crt
|
||||
```
|
||||
|
||||
[ req ]
|
||||
default_bits = 2048
|
||||
prompt = no
|
||||
default_md = sha256
|
||||
req_extensions = req_ext
|
||||
distinguished_name = dn
|
||||
1. Generate a server.key with 2048bit:
|
||||
|
||||
[ dn ]
|
||||
C = <country>
|
||||
ST = <state>
|
||||
L = <city>
|
||||
O = <organization>
|
||||
OU = <organization unit>
|
||||
CN = <MASTER_IP>
|
||||
```shell
|
||||
openssl genrsa -out server.key 2048
|
||||
```
|
||||
|
||||
[ req_ext ]
|
||||
subjectAltName = @alt_names
|
||||
1. Create a config file for generating a Certificate Signing Request (CSR).
|
||||
|
||||
[ alt_names ]
|
||||
DNS.1 = kubernetes
|
||||
DNS.2 = kubernetes.default
|
||||
DNS.3 = kubernetes.default.svc
|
||||
DNS.4 = kubernetes.default.svc.cluster
|
||||
DNS.5 = kubernetes.default.svc.cluster.local
|
||||
IP.1 = <MASTER_IP>
|
||||
IP.2 = <MASTER_CLUSTER_IP>
|
||||
Be sure to substitute the values marked with angle brackets (e.g. `<MASTER_IP>`)
|
||||
with real values before saving this to a file (e.g. `csr.conf`).
|
||||
Note that the value for `MASTER_CLUSTER_IP` is the service cluster IP for the
|
||||
API server as described in previous subsection.
|
||||
The sample below also assumes that you are using `cluster.local` as the default
|
||||
DNS domain name.
|
||||
|
||||
[ v3_ext ]
|
||||
authorityKeyIdentifier=keyid,issuer:always
|
||||
basicConstraints=CA:FALSE
|
||||
keyUsage=keyEncipherment,dataEncipherment
|
||||
extendedKeyUsage=serverAuth,clientAuth
|
||||
subjectAltName=@alt_names
|
||||
1. Generate the certificate signing request based on the config file:
|
||||
```ini
|
||||
[ req ]
|
||||
default_bits = 2048
|
||||
prompt = no
|
||||
default_md = sha256
|
||||
req_extensions = req_ext
|
||||
distinguished_name = dn
|
||||
|
||||
openssl req -new -key server.key -out server.csr -config csr.conf
|
||||
1. Generate the server certificate using the ca.key, ca.crt and server.csr:
|
||||
[ dn ]
|
||||
C = <country>
|
||||
ST = <state>
|
||||
L = <city>
|
||||
O = <organization>
|
||||
OU = <organization unit>
|
||||
CN = <MASTER_IP>
|
||||
|
||||
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \
|
||||
-CAcreateserial -out server.crt -days 10000 \
|
||||
-extensions v3_ext -extfile csr.conf
|
||||
1. View the certificate signing request:
|
||||
[ req_ext ]
|
||||
subjectAltName = @alt_names
|
||||
|
||||
openssl req -noout -text -in ./server.csr
|
||||
1. View the certificate:
|
||||
[ alt_names ]
|
||||
DNS.1 = kubernetes
|
||||
DNS.2 = kubernetes.default
|
||||
DNS.3 = kubernetes.default.svc
|
||||
DNS.4 = kubernetes.default.svc.cluster
|
||||
DNS.5 = kubernetes.default.svc.cluster.local
|
||||
IP.1 = <MASTER_IP>
|
||||
IP.2 = <MASTER_CLUSTER_IP>
|
||||
|
||||
openssl x509 -noout -text -in ./server.crt
|
||||
[ v3_ext ]
|
||||
authorityKeyIdentifier=keyid,issuer:always
|
||||
basicConstraints=CA:FALSE
|
||||
keyUsage=keyEncipherment,dataEncipherment
|
||||
extendedKeyUsage=serverAuth,clientAuth
|
||||
subjectAltName=@alt_names
|
||||
```
|
||||
|
||||
1. Generate the certificate signing request based on the config file:
|
||||
|
||||
```shell
|
||||
openssl req -new -key server.key -out server.csr -config csr.conf
|
||||
```
|
||||
|
||||
1. Generate the server certificate using the ca.key, ca.crt and server.csr:
|
||||
|
||||
```shell
|
||||
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \
|
||||
-CAcreateserial -out server.crt -days 10000 \
|
||||
-extensions v3_ext -extfile csr.conf
|
||||
```
|
||||
|
||||
1. View the certificate signing request:
|
||||
|
||||
```shell
|
||||
openssl req -noout -text -in ./server.csr
|
||||
```
|
||||
|
||||
1. View the certificate:
|
||||
|
||||
```shell
|
||||
openssl x509 -noout -text -in ./server.crt
|
||||
```
|
||||
|
||||
Finally, add the same parameters into the API server start parameters.
|
||||
|
||||
@@ -129,101 +161,121 @@ Finally, add the same parameters into the API server start parameters.
|
||||
|
||||
**cfssl** is another tool for certificate generation.
|
||||
|
||||
1. Download, unpack and prepare the command line tools as shown below.
|
||||
Note that you may need to adapt the sample commands based on the hardware
|
||||
architecture and cfssl version you are using.
|
||||
1. Download, unpack and prepare the command line tools as shown below.
|
||||
|
||||
curl -L https://github.com/cloudflare/cfssl/releases/download/v1.5.0/cfssl_1.5.0_linux_amd64 -o cfssl
|
||||
chmod +x cfssl
|
||||
curl -L https://github.com/cloudflare/cfssl/releases/download/v1.5.0/cfssljson_1.5.0_linux_amd64 -o cfssljson
|
||||
chmod +x cfssljson
|
||||
curl -L https://github.com/cloudflare/cfssl/releases/download/v1.5.0/cfssl-certinfo_1.5.0_linux_amd64 -o cfssl-certinfo
|
||||
chmod +x cfssl-certinfo
|
||||
1. Create a directory to hold the artifacts and initialize cfssl:
|
||||
Note that you may need to adapt the sample commands based on the hardware
|
||||
architecture and cfssl version you are using.
|
||||
|
||||
mkdir cert
|
||||
cd cert
|
||||
../cfssl print-defaults config > config.json
|
||||
../cfssl print-defaults csr > csr.json
|
||||
1. Create a JSON config file for generating the CA file, for example, `ca-config.json`:
|
||||
```shell
|
||||
curl -L https://github.com/cloudflare/cfssl/releases/download/v1.5.0/cfssl_1.5.0_linux_amd64 -o cfssl
|
||||
chmod +x cfssl
|
||||
curl -L https://github.com/cloudflare/cfssl/releases/download/v1.5.0/cfssljson_1.5.0_linux_amd64 -o cfssljson
|
||||
chmod +x cfssljson
|
||||
curl -L https://github.com/cloudflare/cfssl/releases/download/v1.5.0/cfssl-certinfo_1.5.0_linux_amd64 -o cfssl-certinfo
|
||||
chmod +x cfssl-certinfo
|
||||
```
|
||||
|
||||
{
|
||||
"signing": {
|
||||
"default": {
|
||||
"expiry": "8760h"
|
||||
},
|
||||
"profiles": {
|
||||
"kubernetes": {
|
||||
"usages": [
|
||||
"signing",
|
||||
"key encipherment",
|
||||
"server auth",
|
||||
"client auth"
|
||||
],
|
||||
"expiry": "8760h"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1. Create a JSON config file for CA certificate signing request (CSR), for example,
|
||||
`ca-csr.json`. Be sure to replace the values marked with angle brackets with
|
||||
real values you want to use.
|
||||
1. Create a directory to hold the artifacts and initialize cfssl:
|
||||
|
||||
{
|
||||
"CN": "kubernetes",
|
||||
"key": {
|
||||
"algo": "rsa",
|
||||
"size": 2048
|
||||
},
|
||||
"names":[{
|
||||
"C": "<country>",
|
||||
"ST": "<state>",
|
||||
"L": "<city>",
|
||||
"O": "<organization>",
|
||||
"OU": "<organization unit>"
|
||||
}]
|
||||
}
|
||||
1. Generate CA key (`ca-key.pem`) and certificate (`ca.pem`):
|
||||
```shell
|
||||
mkdir cert
|
||||
cd cert
|
||||
../cfssl print-defaults config > config.json
|
||||
../cfssl print-defaults csr > csr.json
|
||||
```
|
||||
|
||||
../cfssl gencert -initca ca-csr.json | ../cfssljson -bare ca
|
||||
1. Create a JSON config file for generating keys and certificates for the API
|
||||
server, for example, `server-csr.json`. Be sure to replace the values in angle brackets with
|
||||
real values you want to use. The `MASTER_CLUSTER_IP` is the service cluster
|
||||
IP for the API server as described in previous subsection.
|
||||
The sample below also assumes that you are using `cluster.local` as the default
|
||||
DNS domain name.
|
||||
1. Create a JSON config file for generating the CA file, for example, `ca-config.json`:
|
||||
|
||||
{
|
||||
"CN": "kubernetes",
|
||||
"hosts": [
|
||||
"127.0.0.1",
|
||||
"<MASTER_IP>",
|
||||
"<MASTER_CLUSTER_IP>",
|
||||
"kubernetes",
|
||||
"kubernetes.default",
|
||||
"kubernetes.default.svc",
|
||||
"kubernetes.default.svc.cluster",
|
||||
"kubernetes.default.svc.cluster.local"
|
||||
],
|
||||
"key": {
|
||||
"algo": "rsa",
|
||||
"size": 2048
|
||||
},
|
||||
"names": [{
|
||||
"C": "<country>",
|
||||
"ST": "<state>",
|
||||
"L": "<city>",
|
||||
"O": "<organization>",
|
||||
"OU": "<organization unit>"
|
||||
}]
|
||||
}
|
||||
1. Generate the key and certificate for the API server, which are by default
|
||||
saved into file `server-key.pem` and `server.pem` respectively:
|
||||
```json
|
||||
{
|
||||
"signing": {
|
||||
"default": {
|
||||
"expiry": "8760h"
|
||||
},
|
||||
"profiles": {
|
||||
"kubernetes": {
|
||||
"usages": [
|
||||
"signing",
|
||||
"key encipherment",
|
||||
"server auth",
|
||||
"client auth"
|
||||
],
|
||||
"expiry": "8760h"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
../cfssl gencert -ca=ca.pem -ca-key=ca-key.pem \
|
||||
1. Create a JSON config file for CA certificate signing request (CSR), for example,
|
||||
`ca-csr.json`. Be sure to replace the values marked with angle brackets with
|
||||
real values you want to use.
|
||||
|
||||
```json
|
||||
{
|
||||
"CN": "kubernetes",
|
||||
"key": {
|
||||
"algo": "rsa",
|
||||
"size": 2048
|
||||
},
|
||||
"names":[{
|
||||
"C": "<country>",
|
||||
"ST": "<state>",
|
||||
"L": "<city>",
|
||||
"O": "<organization>",
|
||||
"OU": "<organization unit>"
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
1. Generate CA key (`ca-key.pem`) and certificate (`ca.pem`):
|
||||
|
||||
```shell
|
||||
../cfssl gencert -initca ca-csr.json | ../cfssljson -bare ca
|
||||
```
|
||||
|
||||
1. Create a JSON config file for generating keys and certificates for the API
|
||||
server, for example, `server-csr.json`. Be sure to replace the values in angle brackets with
|
||||
real values you want to use. The `<MASTER_CLUSTER_IP>` is the service cluster
|
||||
IP for the API server as described in previous subsection.
|
||||
The sample below also assumes that you are using `cluster.local` as the default
|
||||
DNS domain name.
|
||||
|
||||
```json
|
||||
{
|
||||
"CN": "kubernetes",
|
||||
"hosts": [
|
||||
"127.0.0.1",
|
||||
"<MASTER_IP>",
|
||||
"<MASTER_CLUSTER_IP>",
|
||||
"kubernetes",
|
||||
"kubernetes.default",
|
||||
"kubernetes.default.svc",
|
||||
"kubernetes.default.svc.cluster",
|
||||
"kubernetes.default.svc.cluster.local"
|
||||
],
|
||||
"key": {
|
||||
"algo": "rsa",
|
||||
"size": 2048
|
||||
},
|
||||
"names": [{
|
||||
"C": "<country>",
|
||||
"ST": "<state>",
|
||||
"L": "<city>",
|
||||
"O": "<organization>",
|
||||
"OU": "<organization unit>"
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
1. Generate the key and certificate for the API server, which are by default
|
||||
saved into file `server-key.pem` and `server.pem` respectively:
|
||||
|
||||
```shell
|
||||
../cfssl gencert -ca=ca.pem -ca-key=ca-key.pem \
|
||||
--config=ca-config.json -profile=kubernetes \
|
||||
server-csr.json | ../cfssljson -bare server
|
||||
|
||||
```
|
||||
|
||||
## Distributing Self-Signed CA Certificate
|
||||
|
||||
@@ -234,12 +286,12 @@ refresh the local list for valid certificates.
|
||||
|
||||
On each client, perform the following operations:
|
||||
|
||||
```bash
|
||||
```shell
|
||||
sudo cp ca.crt /usr/local/share/ca-certificates/kubernetes.crt
|
||||
sudo update-ca-certificates
|
||||
```
|
||||
|
||||
```
|
||||
```none
|
||||
Updating certificates in /etc/ssl/certs...
|
||||
1 added, 0 removed; done.
|
||||
Running hooks in /etc/ca-certificates/update.d....
|
||||
@@ -250,6 +302,6 @@ done.
|
||||
|
||||
You can use the `certificates.k8s.io` API to provision
|
||||
x509 certificates to use for authentication as documented
|
||||
[here](/docs/tasks/tls/managing-tls-in-a-cluster).
|
||||
|
||||
in the [Managing TLS in a cluster](/docs/tasks/tls/managing-tls-in-a-cluster)
|
||||
task page.
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ content_type: task
|
||||
|
||||
## Background
|
||||
|
||||
As part of the [cloud provider extraction effort](https://kubernetes.io/blog/2019/04/17/the-future-of-cloud-providers-in-kubernetes/), all cloud specific controllers must be moved out of the `kube-controller-manager`. All existing clusters that run cloud controllers in the `kube-controller-manager` must migrate to instead run the controllers in a cloud provider specific `cloud-controller-manager`.
|
||||
As part of the [cloud provider extraction effort](/blog/2019/04/17/the-future-of-cloud-providers-in-kubernetes/), all cloud specific controllers must be moved out of the `kube-controller-manager`. All existing clusters that run cloud controllers in the `kube-controller-manager` must migrate to instead run the controllers in a cloud provider specific `cloud-controller-manager`.
|
||||
|
||||
Leader Migration provides a mechanism in which HA clusters can safely migrate "cloud specific" controllers between the `kube-controller-manager` and the `cloud-controller-manager` via a shared resource lock between the two components while upgrading the replicated control plane. For a single-node control plane, or if unavailability of controller managers can be tolerated during the upgrade, Leader Migration is not needed and this guide can be ignored.
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ To use `cgroupfs` and to prevent `kubeadm upgrade` from modifying the
|
||||
about its value. This applies to a case where you do not wish future versions
|
||||
of kubeadm to apply the `systemd` driver by default.
|
||||
|
||||
See the below section on "Modify the kubelet ConfigMap" for details on
|
||||
See the below section on "[Modify the kubelet ConfigMap](#modify-the-kubelet-configmap)" for details on
|
||||
how to be explicit about the value.
|
||||
|
||||
If you wish to configure a container runtime to use the `cgroupfs` driver,
|
||||
|
||||
@@ -11,7 +11,7 @@ weight: 20
|
||||
This page explains how to upgrade a Kubernetes cluster created with kubeadm from version
|
||||
{{< skew currentVersionAddMinor -1 >}}.x to version {{< skew currentVersion >}}.x, and from version
|
||||
{{< skew currentVersion >}}.x to {{< skew currentVersion >}}.y (where `y > x`). Skipping MINOR versions
|
||||
when upgrading is unsupported. For more details, please visit [Version Skew Policy](https://kubernetes.io/releases/version-skew-policy/).
|
||||
when upgrading is unsupported. For more details, please visit [Version Skew Policy](/releases/version-skew-policy/).
|
||||
|
||||
To see information about upgrading clusters created using older versions of kubeadm,
|
||||
please refer to following pages instead:
|
||||
|
||||
@@ -29,7 +29,7 @@ configuration.
|
||||
|
||||
These tasks will help you to migrate:
|
||||
|
||||
* [Check whether Dockershim deprecation affects you](/docs/tasks/administer-cluster/migrating-from-dockershim/check-if-dockershim-deprecation-affects-you/)
|
||||
* [Check whether Dockershim removal affects you](/docs/tasks/administer-cluster/migrating-from-dockershim/check-if-dockershim-removal-affects-you/)
|
||||
* [Migrate Docker Engine nodes from dockershim to cri-dockerd](/docs/tasks/administer-cluster/migrating-from-dockershim/migrate-dockershim-dockerd/)
|
||||
* [Migrating telemetry and security agents from dockershim](/docs/tasks/administer-cluster/migrating-from-dockershim/migrating-telemetry-and-security-agents/)
|
||||
|
||||
|
||||
+100
-13
@@ -8,24 +8,33 @@ weight: 70
|
||||
|
||||
<!-- overview -->
|
||||
|
||||
Kubernetes' support for direct integration with Docker Engine is deprecated, and will be removed. Most apps do not have a direct dependency on runtime hosting containers. However, there are still a lot of telemetry and monitoring agents that has a dependency on docker to collect containers metadata, logs and metrics. This document aggregates information on how to detect these dependencies and links on how to migrate these agents to use generic tools or alternative runtimes.
|
||||
{{% thirdparty-content %}}
|
||||
|
||||
Kubernetes' support for direct integration with Docker Engine is deprecated and
|
||||
has been removed. Most apps do not have a direct dependency on runtime hosting
|
||||
containers. However, there are still a lot of telemetry and monitoring agents
|
||||
that have a dependency on Docker to collect containers metadata, logs, and
|
||||
metrics. This document aggregates information on how to detect these
|
||||
dependencies as well as links on how to migrate these agents to use generic tools or
|
||||
alternative runtimes.
|
||||
|
||||
## Telemetry and security agents
|
||||
|
||||
Within a Kubernetes cluster there are a few different ways to run telemetry or security agents.
|
||||
Some agents have a direct dependency on Docker Engine when they run as DaemonSets or
|
||||
directly on nodes.
|
||||
Within a Kubernetes cluster there are a few different ways to run telemetry or
|
||||
security agents. Some agents have a direct dependency on Docker Engine when
|
||||
they run as DaemonSets or directly on nodes.
|
||||
|
||||
### Why do some telemetry agents communicate with Docker Engine?
|
||||
|
||||
Historically, Kubernetes was written to work specifically with Docker Engine.
|
||||
Kubernetes took care of networking and scheduling, relying on Docker Engine for launching
|
||||
and running containers (within Pods) on a node. Some information that is relevant to telemetry,
|
||||
such as a pod name, is only available from Kubernetes components. Other data, such as container
|
||||
metrics, is not the responsibility of the container runtime. Early telemetry agents needed to query the
|
||||
container runtime **and** Kubernetes to report an accurate picture. Over time, Kubernetes gained
|
||||
the ability to support multiple runtimes, and now supports any runtime that is compatible with
|
||||
the container runtime interface.
|
||||
Kubernetes took care of networking and scheduling, relying on Docker Engine for
|
||||
launching and running containers (within Pods) on a node. Some information that
|
||||
is relevant to telemetry, such as a pod name, is only available from Kubernetes
|
||||
components. Other data, such as container metrics, is not the responsibility of
|
||||
the container runtime. Early telemetry agents needed to query the container
|
||||
runtime *and* Kubernetes to report an accurate picture. Over time, Kubernetes
|
||||
gained the ability to support multiple runtimes, and now supports any runtime
|
||||
that is compatible with the [container runtime interface](/docs/concepts/architecture/cri/).
|
||||
|
||||
Some telemetry agents rely specifically on Docker Engine tooling. For example, an agent
|
||||
might run a command such as
|
||||
@@ -68,12 +77,90 @@ The script above only detects the most common uses.
|
||||
|
||||
### Detecting Docker dependency from node agents
|
||||
|
||||
In case your cluster nodes are customized and install additional security and
|
||||
telemetry agents on the node, make sure to check with the vendor of the agent whether it has dependency on Docker.
|
||||
If your cluster nodes are customized and install additional security and
|
||||
telemetry agents on the node, check with the agent vendor
|
||||
to verify whether it has any dependency on Docker.
|
||||
|
||||
### Telemetry and security agent vendors
|
||||
|
||||
This section is intended to aggregate information about various telemetry and
|
||||
security agents that may have a dependency on container runtimes.
|
||||
|
||||
We keep the work in progress version of migration instructions for various telemetry and security agent vendors
|
||||
in [Google doc](https://docs.google.com/document/d/1ZFi4uKit63ga5sxEiZblfb-c23lFhvy6RXVPikS8wf0/edit#).
|
||||
Please contact the vendor to get up to date instructions for migrating from dockershim.
|
||||
|
||||
## Migration from dockershim
|
||||
|
||||
### [Aqua](https://www.aquasec.com)
|
||||
|
||||
No changes are needed: everything should work seamlessly on the runtime switch.
|
||||
|
||||
### [Datadog](https://www.datadoghq.com/product/)
|
||||
|
||||
How to migrate:
|
||||
[Docker deprecation in Kubernetes](https://docs.datadoghq.com/agent/guide/docker-deprecation/)
|
||||
The pod that accesses Docker Engine may have a name containing any of:
|
||||
|
||||
- `datadog-agent`
|
||||
- `datadog`
|
||||
- `dd-agent`
|
||||
|
||||
### [Dynatrace](https://www.dynatrace.com/)
|
||||
|
||||
How to migrate:
|
||||
[Migrating from Docker-only to generic container metrics in Dynatrace](https://community.dynatrace.com/t5/Best-practices/Migrating-from-Docker-only-to-generic-container-metrics-in/m-p/167030#M49)
|
||||
|
||||
Containerd support announcement: [Get automated full-stack visibility into
|
||||
containerd-based Kubernetes
|
||||
environments](https://www.dynatrace.com/news/blog/get-automated-full-stack-visibility-into-containerd-based-kubernetes-environments/)
|
||||
|
||||
CRI-O support announcement: [Get automated full-stack visibility into your CRI-O Kubernetes containers (Beta)](https://www.dynatrace.com/news/blog/get-automated-full-stack-visibility-into-your-cri-o-kubernetes-containers-beta/)
|
||||
|
||||
The pod accessing Docker may have name containing:
|
||||
- `dynatrace-oneagent`
|
||||
|
||||
### [Falco](https://falco.org)
|
||||
|
||||
How to migrate:
|
||||
|
||||
[Migrate Falco from dockershim](https://falco.org/docs/getting-started/deployment/#docker-deprecation-in-kubernetes)
|
||||
Falco supports any CRI-compatible runtime (containerd is used in the default configuration); the documentation explains all details.
|
||||
The pod accessing Docker may have name containing:
|
||||
- `falco`
|
||||
|
||||
### [Prisma Cloud Compute](https://docs.paloaltonetworks.com/prisma/prisma-cloud.html)
|
||||
|
||||
Check [documentation for Prisma Cloud](https://docs.paloaltonetworks.com/prisma/prisma-cloud/prisma-cloud-admin-compute/install/install_kubernetes.html),
|
||||
under the "Install Prisma Cloud on a CRI (non-Docker) cluster" section.
|
||||
The pod accessing Docker may be named like:
|
||||
- `twistlock-defender-ds`
|
||||
|
||||
### [SignalFx (Splunk)](https://www.splunk.com/en_us/investor-relations/acquisitions/signalfx.html)
|
||||
|
||||
The SignalFx Smart Agent (deprecated) uses several different monitors for Kubernetes including
|
||||
`kubernetes-cluster`, `kubelet-stats/kubelet-metrics`, and `docker-container-stats`.
|
||||
The `kubelet-stats` monitor was previously deprecated by the vendor, in favor of `kubelet-metrics`.
|
||||
The `docker-container-stats` monitor is the one affected by dockershim removal.
|
||||
Do not use the `docker-container-stats` with container runtimes other than Docker Engine.
|
||||
|
||||
|
||||
How to migrate from dockershim-dependent agent:
|
||||
1. Remove `docker-container-stats` from the list of [configured monitors](https://github.com/signalfx/signalfx-agent/blob/main/docs/monitor-config.md).
|
||||
Note, keeping this monitor enabled with non-dockershim runtime will result in incorrect metrics
|
||||
being reported when docker is installed on node and no metrics when docker is not installed.
|
||||
2. [Enable and configure `kubelet-metrics`](https://github.com/signalfx/signalfx-agent/blob/main/docs/monitors/kubelet-metrics.md) monitor.
|
||||
|
||||
|
||||
{{< note >}}
|
||||
The set of collected metrics will change. Review your alerting rules and dashboards.
|
||||
{{< /note >}}
|
||||
|
||||
The Pod accessing Docker may be named something like:
|
||||
|
||||
- `signalfx-agent`
|
||||
|
||||
### Yahoo Kubectl Flame
|
||||
|
||||
Flame does not support container runtimes other than Docker. See
|
||||
[https://github.com/yahoo/kubectl-flame/issues/51](https://github.com/yahoo/kubectl-flame/issues/51)
|
||||
|
||||
+1
-1
@@ -88,7 +88,7 @@ would provision a network resource like a Google Compute Engine persistent disk,
|
||||
an NFS share, or an Amazon Elastic Block Store volume. Cluster administrators can also
|
||||
use [StorageClasses](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#storageclass-v1-storage)
|
||||
to set up
|
||||
[dynamic provisioning](https://kubernetes.io/blog/2016/10/dynamic-provisioning-and-storage-in-kubernetes).
|
||||
[dynamic provisioning](/blog/2016/10/dynamic-provisioning-and-storage-in-kubernetes).
|
||||
|
||||
Here is the configuration file for the hostPath PersistentVolume:
|
||||
|
||||
|
||||
@@ -323,7 +323,7 @@ configuration of the API server:
|
||||
|
||||
To verify that the PodSecurityPolicy admission controller is no longer enabled, you can manually run
|
||||
a test by impersonating a user without access to any PodSecurityPolicies (see the
|
||||
[PodSecurityPolicy example](/docs/concepts/policy/pod-security-policy/#example)), or by verifying in
|
||||
[PodSecurityPolicy example](/docs/concepts/security/pod-security-policy/#example)), or by verifying in
|
||||
the API server logs. At startup, the API server outputs log lines listing the loaded admission
|
||||
controller plugins:
|
||||
|
||||
|
||||
@@ -36,7 +36,13 @@ kubectl cluster-info dump
|
||||
|
||||
### Example: debugging a down/unreachable node
|
||||
|
||||
Sometimes when debugging it can be useful to look at the status of a node -- for example, because you've noticed strange behavior of a Pod that's running on the node, or to find out why a Pod won't schedule onto the node. As with Pods, you can use `kubectl describe node` and `kubectl get node -o yaml` to retrieve detailed information about nodes. For example, here's what you'll see if a node is down (disconnected from the network, or kubelet dies and won't restart, etc.). Notice the events that show the node is NotReady, and also notice that the pods are no longer running (they are evicted after five minutes of NotReady status).
|
||||
Sometimes when debugging it can be useful to look at the status of a node -- for example, because
|
||||
you've noticed strange behavior of a Pod that's running on the node, or to find out why a Pod
|
||||
won't schedule onto the node. As with Pods, you can use `kubectl describe node` and `kubectl get
|
||||
node -o yaml` to retrieve detailed information about nodes. For example, here's what you'll see if
|
||||
a node is down (disconnected from the network, or kubelet dies and won't restart, etc.). Notice
|
||||
the events that show the node is NotReady, and also notice that the pods are no longer running
|
||||
(they are evicted after five minutes of NotReady status).
|
||||
|
||||
```shell
|
||||
kubectl get nodes
|
||||
@@ -222,14 +228,16 @@ of the relevant log files. On systemd-based systems, you may need to use `journ
|
||||
|
||||
### Control Plane nodes
|
||||
|
||||
* `/var/log/kube-apiserver.log` - API Server, responsible for serving the API
|
||||
* `/var/log/kube-scheduler.log` - Scheduler, responsible for making scheduling decisions
|
||||
* `/var/log/kube-controller-manager.log` - a component that runs most Kubernetes built-in {{<glossary_tooltip text="controllers" term_id="controller">}}, with the notable exception of scheduling (the kube-scheduler handles scheduling).
|
||||
* `/var/log/kube-apiserver.log` - API Server, responsible for serving the API
|
||||
* `/var/log/kube-scheduler.log` - Scheduler, responsible for making scheduling decisions
|
||||
* `/var/log/kube-controller-manager.log` - a component that runs most Kubernetes built-in
|
||||
{{<glossary_tooltip text="controllers" term_id="controller">}}, with the notable exception of scheduling
|
||||
(the kube-scheduler handles scheduling).
|
||||
|
||||
### Worker Nodes
|
||||
|
||||
* `/var/log/kubelet.log` - logs from the kubelet, responsible for running containers on the node
|
||||
* `/var/log/kube-proxy.log` - logs from `kube-proxy`, which is responsible for directing traffic to Service endpoints
|
||||
* `/var/log/kubelet.log` - logs from the kubelet, responsible for running containers on the node
|
||||
* `/var/log/kube-proxy.log` - logs from `kube-proxy`, which is responsible for directing traffic to Service endpoints
|
||||
|
||||
## Cluster failure modes
|
||||
|
||||
@@ -237,45 +245,46 @@ This is an incomplete list of things that could go wrong, and how to adjust your
|
||||
|
||||
### Contributing causes
|
||||
|
||||
- VM(s) shutdown
|
||||
- Network partition within cluster, or between cluster and users
|
||||
- Crashes in Kubernetes software
|
||||
- Data loss or unavailability of persistent storage (e.g. GCE PD or AWS EBS volume)
|
||||
- Operator error, for example misconfigured Kubernetes software or application software
|
||||
- VM(s) shutdown
|
||||
- Network partition within cluster, or between cluster and users
|
||||
- Crashes in Kubernetes software
|
||||
- Data loss or unavailability of persistent storage (e.g. GCE PD or AWS EBS volume)
|
||||
- Operator error, for example misconfigured Kubernetes software or application software
|
||||
|
||||
### Specific scenarios
|
||||
|
||||
- API server VM shutdown or apiserver crashing
|
||||
- Results
|
||||
- unable to stop, update, or start new pods, services, replication controller
|
||||
- existing pods and services should continue to work normally, unless they depend on the Kubernetes API
|
||||
- API server backing storage lost
|
||||
- Results
|
||||
- the kube-apiserver component fails to start successfully and become healthy
|
||||
- kubelets will not be able to reach it but will continue to run the same pods and provide the same service proxying
|
||||
- manual recovery or recreation of apiserver state necessary before apiserver is restarted
|
||||
- Supporting services (node controller, replication controller manager, scheduler, etc) VM shutdown or crashes
|
||||
- currently those are colocated with the apiserver, and their unavailability has similar consequences as apiserver
|
||||
- in future, these will be replicated as well and may not be co-located
|
||||
- they do not have their own persistent state
|
||||
- Individual node (VM or physical machine) shuts down
|
||||
- Results
|
||||
- pods on that Node stop running
|
||||
- Network partition
|
||||
- Results
|
||||
- partition A thinks the nodes in partition B are down; partition B thinks the apiserver is down. (Assuming the master VM ends up in partition A.)
|
||||
- Kubelet software fault
|
||||
- Results
|
||||
- crashing kubelet cannot start new pods on the node
|
||||
- kubelet might delete the pods or not
|
||||
- node marked unhealthy
|
||||
- replication controllers start new pods elsewhere
|
||||
- Cluster operator error
|
||||
- Results
|
||||
- loss of pods, services, etc
|
||||
- lost of apiserver backing store
|
||||
- users unable to read API
|
||||
- etc.
|
||||
- API server VM shutdown or apiserver crashing
|
||||
- Results
|
||||
- unable to stop, update, or start new pods, services, replication controller
|
||||
- existing pods and services should continue to work normally, unless they depend on the Kubernetes API
|
||||
- API server backing storage lost
|
||||
- Results
|
||||
- the kube-apiserver component fails to start successfully and become healthy
|
||||
- kubelets will not be able to reach it but will continue to run the same pods and provide the same service proxying
|
||||
- manual recovery or recreation of apiserver state necessary before apiserver is restarted
|
||||
- Supporting services (node controller, replication controller manager, scheduler, etc) VM shutdown or crashes
|
||||
- currently those are colocated with the apiserver, and their unavailability has similar consequences as apiserver
|
||||
- in future, these will be replicated as well and may not be co-located
|
||||
- they do not have their own persistent state
|
||||
- Individual node (VM or physical machine) shuts down
|
||||
- Results
|
||||
- pods on that Node stop running
|
||||
- Network partition
|
||||
- Results
|
||||
- partition A thinks the nodes in partition B are down; partition B thinks the apiserver is down.
|
||||
(Assuming the master VM ends up in partition A.)
|
||||
- Kubelet software fault
|
||||
- Results
|
||||
- crashing kubelet cannot start new pods on the node
|
||||
- kubelet might delete the pods or not
|
||||
- node marked unhealthy
|
||||
- replication controllers start new pods elsewhere
|
||||
- Cluster operator error
|
||||
- Results
|
||||
- loss of pods, services, etc
|
||||
- lost of apiserver backing store
|
||||
- users unable to read API
|
||||
- etc.
|
||||
|
||||
### Mitigations
|
||||
|
||||
@@ -308,9 +317,13 @@ This is an incomplete list of things that could go wrong, and how to adjust your
|
||||
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
* Learn about the metrics available in the [Resource Metrics Pipeline](resource-metrics-pipeline)
|
||||
* Discover additional tools for [monitoring resource usage](resource-usage-monitoring)
|
||||
* Use Node Problem Detector to [monitor node health](monitor-node-health)
|
||||
* Use `crictl` to [debug Kubernetes nodes](crictl)
|
||||
* Get more information about [Kubernetes auditing](audit)
|
||||
* Use `telepresence` to [develop and debug services locally](local-debugging)
|
||||
* Learn about the metrics available in the
|
||||
[Resource Metrics Pipeline](/docs/tasks/debug/debug-cluster/resource-metrics-pipeline/)
|
||||
* Discover additional tools for
|
||||
[monitoring resource usage](/docs/tasks/debug/debug-cluster/resource-usage-monitoring/)
|
||||
* Use Node Problem Detector to
|
||||
[monitor node health](/docs/tasks/debug/debug-cluster/monitor-node-health/)
|
||||
* Use `crictl` to [debug Kubernetes nodes](/docs/tasks/debug/debug-cluster/crictl/)
|
||||
* Get more information about [Kubernetes auditing](/docs/tasks/debug/debug-cluster/audit/)
|
||||
* Use `telepresence` to [develop and debug services locally](/docs/tasks/debug/debug-cluster/local-debugging/)
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ content_type: concept
|
||||
1. My Pods are stuck at "Container Creating" or restarting over and over
|
||||
|
||||
Ensure that your pause image is compatible with your Windows OS version.
|
||||
See [Pause container](/docs/setup/production-environment/windows/intro-windows-in-kubernetes#pause-container)
|
||||
See [Pause container](/docs/concepts/windows/intro/#pause-container)
|
||||
to see the latest / recommended pause image and/or get more information.
|
||||
|
||||
{{< note >}}
|
||||
@@ -32,7 +32,7 @@ content_type: concept
|
||||
Windows Node.
|
||||
|
||||
More information on how to specify a compatible node for your Pod can be found in
|
||||
[this guide](/docs/setup/production-environment/windows/user-guide-windows-containers/#ensuring-os-specific-workloads-land-on-the-appropriate-container-host).
|
||||
[this guide](/docs/concepts/windows/user-guide/#ensuring-os-specific-workloads-land-on-the-appropriate-container-host).
|
||||
|
||||
## Network troubleshooting {#troubleshooting-network}
|
||||
|
||||
@@ -102,8 +102,8 @@ content_type: concept
|
||||
Get-NetAdapter | ? Name -Like "vEthernet (Ethernet*"
|
||||
```
|
||||
|
||||
Often it is worthwhile to modify the [InterfaceName](https://github.com/microsoft/SDN/blob/master/Kubernetes/flannel/start.ps1#L7) parameter of the `start.ps1` script,
|
||||
in cases where the host's network adapter isn't "Ethernet".
|
||||
Often it is worthwhile to modify the [InterfaceName](https://github.com/microsoft/SDN/blob/master/Kubernetes/flannel/start.ps1#L7)
|
||||
parameter of the `start.ps1` script, in cases where the host's network adapter isn't "Ethernet".
|
||||
Otherwise, consult the output of the `start-kubelet.ps1` script to see if there are errors during virtual network creation.
|
||||
|
||||
1. DNS resolution is not properly working
|
||||
@@ -112,9 +112,11 @@ content_type: concept
|
||||
|
||||
1. `kubectl port-forward` fails with "unable to do port forwarding: wincat not found"
|
||||
|
||||
This was implemented in Kubernetes 1.15 by including `wincat.exe` in the pause infrastructure container `mcr.microsoft.com/oss/kubernetes/pause:3.6`.
|
||||
This was implemented in Kubernetes 1.15 by including `wincat.exe` in the pause infrastructure container
|
||||
`mcr.microsoft.com/oss/kubernetes/pause:3.6`.
|
||||
Be sure to use a supported version of Kubernetes.
|
||||
If you would like to build your own pause infrastructure container be sure to include [wincat](https://github.com/kubernetes/kubernetes/tree/master/build/pause/windows/wincat).
|
||||
If you would like to build your own pause infrastructure container be sure to include
|
||||
[wincat](https://github.com/kubernetes/kubernetes/tree/master/build/pause/windows/wincat).
|
||||
|
||||
1. My Kubernetes installation is failing because my Windows Server node is behind a proxy
|
||||
|
||||
@@ -170,4 +172,5 @@ If these steps don't resolve your problem, you can get help running Windows cont
|
||||
|
||||
* StackOverflow [Windows Server Container](https://stackoverflow.com/questions/tagged/windows-server-container) topic
|
||||
* Kubernetes Official Forum [discuss.kubernetes.io](https://discuss.kubernetes.io/)
|
||||
* Kubernetes Slack [#SIG-Windows Channel](https://kubernetes.slack.com/messages/sig-windows)
|
||||
* Kubernetes Slack [#SIG-Windows Channel](https://kubernetes.slack.com/messages/sig-windows)
|
||||
|
||||
|
||||
+28
@@ -353,6 +353,34 @@ spec:
|
||||
{{< /tabs >}}
|
||||
|
||||
|
||||
### Version removal
|
||||
|
||||
An older API version cannot be dropped from a CustomResourceDefinition manifest until existing persisted data has been migrated to the newer API version for all clusters that served the older version of the custom resource, and the old version is removed from the `status.storedVersions` of the CustomResourceDefinition.
|
||||
|
||||
```yaml
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
name: crontabs.example.com
|
||||
spec:
|
||||
group: example.com
|
||||
names:
|
||||
plural: crontabs
|
||||
singular: crontab
|
||||
kind: CronTab
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1beta1
|
||||
# This indicates the v1beta1 version of the custom resource is no longer served.
|
||||
# API requests to this version receive a not found error in the server response.
|
||||
served: false
|
||||
schema: ...
|
||||
- name: v1
|
||||
served: true
|
||||
# The new served version should be set as the storage version
|
||||
storage: true
|
||||
schema: ...
|
||||
```
|
||||
|
||||
## Webhook conversion
|
||||
|
||||
{{< feature-state state="stable" for_k8s_version="v1.16" >}}
|
||||
|
||||
+91
-45
@@ -28,11 +28,12 @@ the documentation for that version to see advice that is relevant for your clust
|
||||
## Create a CustomResourceDefinition
|
||||
|
||||
When you create a new CustomResourceDefinition (CRD), the Kubernetes API Server
|
||||
creates a new RESTful resource path for each version you specify. The CRD can be
|
||||
either namespaced or cluster-scoped, as specified in the CRD's `scope` field. As
|
||||
with existing built-in objects, deleting a namespace deletes all custom objects
|
||||
in that namespace. CustomResourceDefinitions themselves are non-namespaced and
|
||||
are available to all namespaces.
|
||||
creates a new RESTful resource path for each version you specify. The custom
|
||||
resource created from a CRD object can be either namespaced or cluster-scoped,
|
||||
as specified in the CRD's `spec.scope` field. As with existing built-in
|
||||
objects, deleting a namespace deletes all custom objects in that namespace.
|
||||
CustomResourceDefinitions themselves are non-namespaced and are available to
|
||||
all namespaces.
|
||||
|
||||
For example, if you save the following CustomResourceDefinition to `resourcedefinition.yaml`:
|
||||
|
||||
@@ -187,7 +188,8 @@ kubectl get crontabs
|
||||
```
|
||||
|
||||
```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)
|
||||
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)
|
||||
```
|
||||
|
||||
If you later recreate the same CustomResourceDefinition, it will start out empty.
|
||||
@@ -206,22 +208,28 @@ CustomResourceDefinition, the structural schema was optional.
|
||||
|
||||
A structural schema is an [OpenAPI v3.0 validation schema](#validation) which:
|
||||
|
||||
1. specifies a non-empty type (via `type` in OpenAPI) for the root, for each specified field of an object node (via `properties` or `additionalProperties` in OpenAPI) and for each item in an array node (via `items` in OpenAPI), with the exception of:
|
||||
1. specifies a non-empty type (via `type` in OpenAPI) for the root, for each specified field of an object node
|
||||
(via `properties` or `additionalProperties` in OpenAPI) and for each item in an array node
|
||||
(via `items` in OpenAPI), with the exception of:
|
||||
* a node with `x-kubernetes-int-or-string: true`
|
||||
* a node with `x-kubernetes-preserve-unknown-fields: true`
|
||||
2. for each field in an object and each item in an array which is specified within any of `allOf`, `anyOf`, `oneOf` or `not`, the schema also specifies the field/item outside of those logical junctors (compare example 1 and 2).
|
||||
3. does not set `description`, `type`, `default`, `additionalProperties`, `nullable` within an `allOf`, `anyOf`, `oneOf` or `not`, with the exception of the two pattern for `x-kubernetes-int-or-string: true` (see below).
|
||||
2. for each field in an object and each item in an array which is specified within any of `allOf`, `anyOf`,
|
||||
`oneOf` or `not`, the schema also specifies the field/item outside of those logical junctors (compare example 1 and 2).
|
||||
3. does not set `description`, `type`, `default`, `additionalProperties`, `nullable` within an `allOf`, `anyOf`,
|
||||
`oneOf` or `not`, with the exception of the two pattern for `x-kubernetes-int-or-string: true` (see below).
|
||||
4. if `metadata` is specified, then only restrictions on `metadata.name` and `metadata.generateName` are allowed.
|
||||
|
||||
|
||||
Non-structural example 1:
|
||||
|
||||
```yaml
|
||||
allOf:
|
||||
- properties:
|
||||
foo:
|
||||
...
|
||||
```
|
||||
|
||||
conflicts with rule 2. The following would be correct:
|
||||
|
||||
```yaml
|
||||
properties:
|
||||
foo:
|
||||
@@ -313,10 +321,13 @@ Violations of the structural schema rules are reported in the `NonStructural` co
|
||||
|
||||
### Field pruning
|
||||
|
||||
CustomResourceDefinitions store validated resource data in the cluster's persistence store, {{< glossary_tooltip term_id="etcd" text="etcd">}}. As with native Kubernetes resources such as {{< glossary_tooltip text="ConfigMap" term_id="configmap" >}}, if you specify a field that the API server does not recognize, the unknown field is _pruned_ (removed) before being persisted.
|
||||
CustomResourceDefinitions store validated resource data in the cluster's persistence store, {{< glossary_tooltip term_id="etcd" text="etcd">}}.
|
||||
As with native Kubernetes resources such as {{< glossary_tooltip text="ConfigMap" term_id="configmap" >}},
|
||||
if you specify a field that the API server does not recognize, the unknown field is _pruned_ (removed) before being persisted.
|
||||
|
||||
{{< note >}}
|
||||
CRDs converted from `apiextensions.k8s.io/v1beta1` to `apiextensions.k8s.io/v1` might lack structural schemas, and `spec.preserveUnknownFields` might be `true`.
|
||||
CRDs converted from `apiextensions.k8s.io/v1beta1` to `apiextensions.k8s.io/v1` might lack structural schemas,
|
||||
and `spec.preserveUnknownFields` might be `true`.
|
||||
|
||||
For legacy CustomResourceDefinition objects created as
|
||||
`apiextensions.k8s.io/v1beta1` with `spec.preserveUnknownFields` set to
|
||||
@@ -376,7 +387,10 @@ to clients, `kubectl` also checks for unknown fields and rejects those objects w
|
||||
|
||||
#### Controlling pruning
|
||||
|
||||
By default, all unspecified fields for a custom resource, across all versions, are pruned. It is possible though to opt-out of that for specifc sub-trees of fields by adding `x-kubernetes-preserve-unknown-fields: true` in the [structural OpenAPI v3 validation schema](#specifying-a-structural-schema).
|
||||
By default, all unspecified fields for a custom resource, across all versions, are pruned. It is possible though to
|
||||
opt-out of that for specifc sub-trees of fields by adding `x-kubernetes-preserve-unknown-fields: true` in the
|
||||
[structural OpenAPI v3 validation schema](#specifying-a-structural-schema).
|
||||
|
||||
For example:
|
||||
|
||||
```yaml
|
||||
@@ -455,7 +469,8 @@ properties:
|
||||
x-kubernetes-int-or-string: true
|
||||
```
|
||||
|
||||
Also those nodes are partially excluded from rule 3 in the sense that the following two patterns are allowed (exactly those, without variations in order to additional fields):
|
||||
Also those nodes are partially excluded from rule 3 in the sense that the following two patterns are allowed
|
||||
(exactly those, without variations in order to additional fields):
|
||||
|
||||
```yaml
|
||||
x-kubernetes-int-or-string: true
|
||||
@@ -488,7 +503,8 @@ RawExtensions (as in `runtime.RawExtension` defined in
|
||||
[k8s.io/apimachinery](https://github.com/kubernetes/apimachinery/blob/03ac7a9ade429d715a1a46ceaa3724c18ebae54f/pkg/runtime/types.go#L94))
|
||||
holds complete Kubernetes objects, i.e. with `apiVersion` and `kind` fields.
|
||||
|
||||
It is possible to specify those embedded objects (both completely without constraints or partially specified) by setting `x-kubernetes-embedded-resource: true`. For example:
|
||||
It is possible to specify those embedded objects (both completely without constraints or partially specified)
|
||||
by setting `x-kubernetes-embedded-resource: true`. For example:
|
||||
|
||||
```yaml
|
||||
type: object
|
||||
@@ -508,7 +524,8 @@ foo:
|
||||
...
|
||||
```
|
||||
|
||||
Because `x-kubernetes-preserve-unknown-fields: true` is specified alongside, nothing is pruned. The use of `x-kubernetes-preserve-unknown-fields: true` is optional though.
|
||||
Because `x-kubernetes-preserve-unknown-fields: true` is specified alongside, nothing is pruned.
|
||||
The use of `x-kubernetes-preserve-unknown-fields: true` is optional though.
|
||||
|
||||
With `x-kubernetes-embedded-resource: true`, the `apiVersion`, `kind` and `metadata` are implicitly specified and validated.
|
||||
|
||||
@@ -771,6 +788,7 @@ The CronTab "my-new-cron-object" is invalid:
|
||||
The `rule` under `x-kubernetes-validations` represents the expression which will be evaluated by CEL.
|
||||
|
||||
The `message` represents the message displayed when validation fails. If message is unset, the above response would be:
|
||||
|
||||
```
|
||||
The CronTab "my-new-cron-object" is invalid:
|
||||
* spec: Invalid value: map[string]interface {}{"maxReplicas":10, "minReplicas":0, "replicas":20}: failed rule: self.replicas <= self.maxReplicas
|
||||
@@ -781,16 +799,19 @@ The request of CRDs create/update will fail if compilation of validation rules f
|
||||
Compilation process includes type checking as well.
|
||||
|
||||
The compilation failure:
|
||||
|
||||
- `no_matching_overload`: this function has no overload for the types of the arguments.
|
||||
|
||||
e.g. Rule like `self == true` against a field of integer type will get error:
|
||||
e.g. Rule like `self == true` against a field of integer type will get error:
|
||||
|
||||
```
|
||||
Invalid value: apiextensions.ValidationRule{Rule:"self == true", Message:""}: compilation failed: ERROR: \<input>:1:6: found no matching overload for '_==_' applied to '(int, bool)'
|
||||
```
|
||||
|
||||
- `no_such_field`: does not contain the desired field.
|
||||
|
||||
e.g. Rule like `self.nonExistingField > 0` against a non-existing field will return the error:
|
||||
e.g. Rule like `self.nonExistingField > 0` against a non-existing field will return the error:
|
||||
|
||||
```
|
||||
Invalid value: apiextensions.ValidationRule{Rule:"self.nonExistingField > 0", Message:""}: compilation failed: ERROR: \<input>:1:5: undefined field 'nonExistingField'
|
||||
```
|
||||
@@ -798,11 +819,11 @@ The compilation failure:
|
||||
- `invalid argument`: invalid argument to macros.
|
||||
|
||||
e.g. Rule like `has(self)` will return error:
|
||||
|
||||
```
|
||||
Invalid value: apiextensions.ValidationRule{Rule:"has(self)", Message:""}: compilation failed: ERROR: <input>:1:4: invalid argument to has() macro
|
||||
```
|
||||
|
||||
|
||||
Validation Rules Examples:
|
||||
|
||||
| Rule | Purpose |
|
||||
@@ -994,16 +1015,18 @@ Here is the declarations type mapping between OpenAPIv3 and CEL type:
|
||||
| 'string' with format=datetime | timestamp (google.protobuf.Timestamp) |
|
||||
| 'string' with format=duration | duration (google.protobuf.Duration) |
|
||||
|
||||
xref: [CEL types](https://github.com/google/cel-spec/blob/v0.6.0/doc/langdef.md#values), [OpenAPI
|
||||
types](https://swagger.io/specification/#data-types), [Kubernetes Structural Schemas](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#specifying-a-structural-schema).
|
||||
xref: [CEL types](https://github.com/google/cel-spec/blob/v0.6.0/doc/langdef.md#values),
|
||||
[OpenAPI types](https://swagger.io/specification/#data-types),
|
||||
[Kubernetes Structural Schemas](/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#specifying-a-structural-schema).
|
||||
|
||||
#### Validation functions {#available-validation-functions}
|
||||
|
||||
Functions available include:
|
||||
- CEL standard functions, defined in the [list of standard definitions](https://github.com/google/cel-spec/blob/v0.7.0/doc/langdef.md#list-of-standard-definitions)
|
||||
- CEL standard [macros](https://github.com/google/cel-spec/blob/v0.7.0/doc/langdef.md#macros)
|
||||
- CEL [extended string function library](https://pkg.go.dev/github.com/google/cel-go@v0.11.2/ext#Strings)
|
||||
- Kubernetes [CEL extension library](https://pkg.go.dev/k8s.io/apiextensions-apiserver@v0.24.0/pkg/apiserver/schema/cel/library#pkg-functions)
|
||||
|
||||
- CEL standard functions, defined in the [list of standard definitions](https://github.com/google/cel-spec/blob/v0.7.0/doc/langdef.md#list-of-standard-definitions)
|
||||
- CEL standard [macros](https://github.com/google/cel-spec/blob/v0.7.0/doc/langdef.md#macros)
|
||||
- CEL [extended string function library](https://pkg.go.dev/github.com/google/cel-go@v0.11.2/ext#Strings)
|
||||
- Kubernetes [CEL extension library](https://pkg.go.dev/k8s.io/apiextensions-apiserver@v0.24.0/pkg/apiserver/schema/cel/library#pkg-functions)
|
||||
|
||||
#### Transition rules
|
||||
|
||||
@@ -1038,7 +1061,8 @@ applied, e.g. "*path*: update rule *rule* cannot be set on schema because the sc
|
||||
schema is not mergeable".
|
||||
|
||||
Transition rules are only allowed on _correlatable portions_ of a schema.
|
||||
A portion of the schema is correlatable if all `array` parent schemas are of type `x-kubernetes-list-type=map`; any `set`or `atomic`array parent schemas make it impossible to unambiguously correlate a `self` with `oldSelf`.
|
||||
A portion of the schema is correlatable if all `array` parent schemas are of type `x-kubernetes-list-type=map`;
|
||||
any `set`or `atomic`array parent schemas make it impossible to unambiguously correlate a `self` with `oldSelf`.
|
||||
|
||||
Here are some examples for transition rules:
|
||||
|
||||
@@ -1070,12 +1094,13 @@ For example, a rule that asserts that `self.foo == 1` does not by itself have an
|
||||
risk of rejection on validation resource budget groups.
|
||||
But if `foo` is a string and you define a validation rule `self.foo.contains("someString")`, that rule takes
|
||||
longer to execute depending on how long `foo` is.
|
||||
Another example would be if `foo` were an array, and you specified a validation rule `self.foo.all(x, x > 5)`. The cost system always assumes the worst-case scenario if
|
||||
a limit on the length of `foo` is not given, and this will happen for anything that can be iterated
|
||||
over (lists, maps, etc.).
|
||||
Another example would be if `foo` were an array, and you specified a validation rule `self.foo.all(x, x > 5)`.
|
||||
The cost system always assumes the worst-case scenario if a limit on the length of `foo` is not
|
||||
given, and this will happen for anything that can be iterated over (lists, maps, etc.).
|
||||
|
||||
Because of this, it is considered best practice to put a limit via `maxItems`, `maxProperties`, and
|
||||
`maxLength` for anything that will be processed in a validation rule in order to prevent validation errors during cost estimation. For example, given this schema with one rule:
|
||||
`maxLength` for anything that will be processed in a validation rule in order to prevent validation
|
||||
errors during cost estimation. For example, given this schema with one rule:
|
||||
|
||||
```yaml
|
||||
openAPIV3Schema:
|
||||
@@ -1090,10 +1115,11 @@ openAPIV3Schema:
|
||||
```
|
||||
|
||||
then the API server rejects this rule on validation budget grounds with error:
|
||||
|
||||
```
|
||||
spec.validation.openAPIV3Schema.properties[spec].properties[foo].x-kubernetes-validations[0].rule: Forbidden:
|
||||
CEL rule exceeded budget by more than 100x (try simplifying the rule, or adding maxItems, maxProperties, and
|
||||
maxLength where arrays, maps, and strings are used)
|
||||
spec.validation.openAPIV3Schema.properties[spec].properties[foo].x-kubernetes-validations[0].rule: Forbidden:
|
||||
CEL rule exceeded budget by more than 100x (try simplifying the rule, or adding maxItems, maxProperties, and
|
||||
maxLength where arrays, maps, and strings are used)
|
||||
```
|
||||
|
||||
The rejection happens because `self.all` implies calling `contains()` on every string in `foo`,
|
||||
@@ -1136,7 +1162,8 @@ openAPIV3Schema:
|
||||
```
|
||||
|
||||
If a list inside of a list has a validation rule that uses `self.all`, that is significantly more expensive
|
||||
than a non-nested list with the same rule. A rule that would have been allowed on a non-nested list might need lower limits set on both nested lists in order to be allowed. For example, even without having limits set,
|
||||
than a non-nested list with the same rule. A rule that would have been allowed on a non-nested list might need
|
||||
lower limits set on both nested lists in order to be allowed. For example, even without having limits set,
|
||||
the following rule is allowed:
|
||||
|
||||
```yaml
|
||||
@@ -1247,15 +1274,20 @@ Defaulting happens on the object
|
||||
* when reading from etcd using the storage version defaults,
|
||||
* after mutating admission plugins with non-empty patches using the admission webhook object version defaults.
|
||||
|
||||
Defaults applied when reading data from etcd are not automatically written back to etcd. An update request via the API is required to persist those defaults back into etcd.
|
||||
Defaults applied when reading data from etcd are not automatically written back to etcd.
|
||||
An update request via the API is required to persist those defaults back into etcd.
|
||||
|
||||
Default values must be pruned (with the exception of defaults for `metadata` fields) and must validate against a provided schema.
|
||||
|
||||
Default values for `metadata` fields of `x-kubernetes-embedded-resources: true` nodes (or parts of a default value covering `metadata`) are not pruned during CustomResourceDefinition creation, but through the pruning step during handling of requests.
|
||||
Default values for `metadata` fields of `x-kubernetes-embedded-resources: true` nodes (or parts of
|
||||
a default value covering `metadata`) are not pruned during CustomResourceDefinition creation, but
|
||||
through the pruning step during handling of requests.
|
||||
|
||||
#### Defaulting and Nullable
|
||||
|
||||
**New in 1.20:** null values for fields that either don't specify the nullable flag, or give it a `false` value, will be pruned before defaulting happens. If a default is present, it will be applied. When nullable is `true`, null values will be conserved and won't be defaulted.
|
||||
**New in 1.20:** null values for fields that either don't specify the nullable flag, or give it a
|
||||
`false` value, will be pruned before defaulting happens. If a default is present, it will be
|
||||
applied. When nullable is `true`, null values will be conserved and won't be defaulted.
|
||||
|
||||
For example, given the OpenAPI schema below:
|
||||
|
||||
@@ -1293,13 +1325,20 @@ spec:
|
||||
bar: null
|
||||
```
|
||||
|
||||
with `foo` pruned and defaulted because the field is non-nullable, `bar` maintaining the null value due to `nullable: true`, and `baz` pruned because the field is non-nullable and has no default.
|
||||
with `foo` pruned and defaulted because the field is non-nullable, `bar` maintaining the null
|
||||
value due to `nullable: true`, and `baz` pruned because the field is non-nullable and has no
|
||||
default.
|
||||
|
||||
### Publish Validation Schema in OpenAPI v2
|
||||
|
||||
CustomResourceDefinition [OpenAPI v3 validation schemas](#validation) which are [structural](#specifying-a-structural-schema) and [enable pruning](#field-pruning) are published as part of the [OpenAPI v2 spec](/docs/concepts/overview/kubernetes-api/#openapi-and-swagger-definitions) from Kubernetes API server.
|
||||
CustomResourceDefinition [OpenAPI v3 validation schemas](#validation) which are
|
||||
[structural](#specifying-a-structural-schema) and [enable pruning](#field-pruning) are published
|
||||
as part of the [OpenAPI v2 spec](/docs/concepts/overview/kubernetes-api/#openapi-and-swagger-definitions)
|
||||
from Kubernetes API server.
|
||||
|
||||
The [kubectl](/docs/reference/kubectl/) command-line tool consumes the published schema to perform client-side validation (`kubectl create` and `kubectl apply`), schema explanation (`kubectl explain`) on custom resources. The published schema can be consumed for other purposes as well, like client generation or documentation.
|
||||
The [kubectl](/docs/reference/kubectl/) command-line tool consumes the published schema to perform
|
||||
client-side validation (`kubectl create` and `kubectl apply`), schema explanation (`kubectl explain`)
|
||||
on custom resources. The published schema can be consumed for other purposes as well, like client generation or documentation.
|
||||
|
||||
The OpenAPI v3 validation schema is converted to OpenAPI v2 schema, and
|
||||
show up in `definitions` and `paths` fields in the [OpenAPI v2 spec](/docs/concepts/overview/kubernetes-api/#openapi-and-swagger-definitions).
|
||||
@@ -1309,9 +1348,13 @@ kubectl in previous 1.13 version. These modifications prevent kubectl from being
|
||||
valid OpenAPI schemas that it doesn't understand. The conversion won't modify the validation schema defined in CRD,
|
||||
and therefore won't affect [validation](#validation) in the API server.
|
||||
|
||||
1. The following fields are removed as they aren't supported by OpenAPI v2 (in future versions OpenAPI v3 will be used without these restrictions)
|
||||
1. The following fields are removed as they aren't supported by OpenAPI v2
|
||||
(in future versions OpenAPI v3 will be used without these restrictions)
|
||||
|
||||
- The fields `allOf`, `anyOf`, `oneOf` and `not` are removed
|
||||
2. If `nullable: true` is set, we drop `type`, `nullable`, `items` and `properties` because OpenAPI v2 is not able to express nullable. To avoid kubectl to reject good objects, this is necessary.
|
||||
|
||||
2. If `nullable: true` is set, we drop `type`, `nullable`, `items` and `properties` because OpenAPI v2 is
|
||||
not able to express nullable. To avoid kubectl to reject good objects, this is necessary.
|
||||
|
||||
### Additional printer columns
|
||||
|
||||
@@ -1402,7 +1445,8 @@ differentiates between columns shown in standard view or wide view (using the `-
|
||||
|
||||
#### Type
|
||||
|
||||
A column's `type` field can be any of the following (compare [OpenAPI v3 data types](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#dataTypes)):
|
||||
A column's `type` field can be any of the following (compare
|
||||
[OpenAPI v3 data types](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#dataTypes)):
|
||||
|
||||
- `integer` – non-floating-point numbers
|
||||
- `number` – floating point numbers
|
||||
@@ -1495,8 +1539,9 @@ the status replica value in the `/scale` subresource will default to 0.
|
||||
- It must be set to work with HPA.
|
||||
- Only JSONPaths under `.status` or `.spec` and with the dot notation are allowed.
|
||||
- If there is no value under the `labelSelectorPath` in the custom resource,
|
||||
the status selector value in the `/scale` subresource will default to the empty string.
|
||||
- The field pointed by this JSON path must be a string field (not a complex selector struct) which contains a serialized label selector in string form.
|
||||
the status selector value in the `/scale` subresource will default to the empty string.
|
||||
- The field pointed by this JSON path must be a string field (not a complex selector struct)
|
||||
which contains a serialized label selector in string form.
|
||||
|
||||
In the following example, both status and scale subresources are enabled.
|
||||
|
||||
@@ -1703,3 +1748,4 @@ crontabs/my-new-cron-object 3s
|
||||
|
||||
* Serve [multiple versions](/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definition-versioning/) of a
|
||||
CustomResourceDefinition.
|
||||
|
||||
|
||||
@@ -13,7 +13,8 @@ CronJobs was promoted to general availability in Kubernetes v1.21. If you are us
|
||||
Kubernetes, please refer to the documentation for the version of Kubernetes that you are using,
|
||||
so that you see accurate information. Older Kubernetes versions do not support the `batch/v1` CronJob API.
|
||||
|
||||
You can use a {{< glossary_tooltip text="CronJob" term_id="cronjob" >}} to run {{< glossary_tooltip text="Jobs" term_id="job" >}} on a time-based schedule.
|
||||
You can use a {{< glossary_tooltip text="CronJob" term_id="cronjob" >}} to run {{< glossary_tooltip text="Jobs" term_id="job" >}}
|
||||
on a time-based schedule.
|
||||
These automated jobs run like [Cron](https://en.wikipedia.org/wiki/Cron) tasks on a Linux or UNIX system.
|
||||
|
||||
Cron jobs are useful for creating periodic and recurring tasks, like running backups or sending emails.
|
||||
@@ -87,6 +88,7 @@ You can stop watching the job and view the cron job again to see that it schedul
|
||||
```shell
|
||||
kubectl get cronjob hello
|
||||
```
|
||||
|
||||
The output is similar to this:
|
||||
|
||||
```
|
||||
@@ -94,7 +96,8 @@ NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
|
||||
hello */1 * * * * False 0 50s 75s
|
||||
```
|
||||
|
||||
You should see that the cron job `hello` successfully scheduled a job at the time specified in `LAST SCHEDULE`. There are currently 0 active jobs, meaning that the job has completed or failed.
|
||||
You should see that the cron job `hello` successfully scheduled a job at the time specified in
|
||||
`LAST SCHEDULE`. There are currently 0 active jobs, meaning that the job has completed or failed.
|
||||
|
||||
Now, find the pods that the last scheduled job created and view the standard output of one of the pods.
|
||||
|
||||
@@ -127,7 +130,7 @@ kubectl delete cronjob hello
|
||||
```
|
||||
|
||||
Deleting the cron job removes all the jobs and pods it created and stops it from creating additional jobs.
|
||||
You can read more about removing jobs in [garbage collection](/docs/concepts/workloads/controllers/garbage-collection/).
|
||||
You can read more about removing jobs in [garbage collection](/docs/concepts/architecture/garbage-collection/).
|
||||
|
||||
## Writing a Cron Job Spec
|
||||
|
||||
@@ -144,7 +147,8 @@ All modifications to a cron job, especially its `.spec`, are applied only to the
|
||||
### Schedule
|
||||
|
||||
The `.spec.schedule` is a required field of the `.spec`.
|
||||
It takes a [Cron](https://en.wikipedia.org/wiki/Cron) format string, such as `0 * * * *` or `@hourly`, as schedule time of its jobs to be created and executed.
|
||||
It takes a [Cron](https://en.wikipedia.org/wiki/Cron) format string, such as `0 * * * *` or `@hourly`,
|
||||
as schedule time of its jobs to be created and executed.
|
||||
|
||||
The format also includes extended "Vixie cron" step values. As explained in the
|
||||
[FreeBSD manual](https://www.freebsd.org/cgi/man.cgi?crontab%285%29):
|
||||
@@ -157,13 +161,15 @@ The format also includes extended "Vixie cron" step values. As explained in the
|
||||
> asterisk, so if you want to say "every two hours", just use `*/2`.
|
||||
|
||||
{{< note >}}
|
||||
A question mark (`?`) in the schedule has the same meaning as an asterisk `*`, that is, it stands for any of available value for a given field.
|
||||
A question mark (`?`) in the schedule has the same meaning as an asterisk `*`, that is,
|
||||
it stands for any of available value for a given field.
|
||||
{{< /note >}}
|
||||
|
||||
### Job Template
|
||||
|
||||
The `.spec.jobTemplate` is the template for the job, and it is required.
|
||||
It has exactly the same schema as a [Job](/docs/concepts/workloads/controllers/job/), except that it is nested and does not have an `apiVersion` or `kind`.
|
||||
It has exactly the same schema as a [Job](/docs/concepts/workloads/controllers/job/), except that
|
||||
it is nested and does not have an `apiVersion` or `kind`.
|
||||
For information about writing a job `.spec`, see [Writing a Job Spec](/docs/concepts/workloads/controllers/job/#writing-a-job-spec).
|
||||
|
||||
### Starting Deadline
|
||||
@@ -188,8 +194,10 @@ It specifies how to treat concurrent executions of a job that is created by this
|
||||
The spec may specify only one of the following concurrency policies:
|
||||
|
||||
* `Allow` (default): The cron job allows concurrently running jobs
|
||||
* `Forbid`: The cron job does not allow concurrent runs; if it is time for a new job run and the previous job run hasn't finished yet, the cron job skips the new job run
|
||||
* `Replace`: If it is time for a new job run and the previous job run hasn't finished yet, the cron job replaces the currently running job run with a new job run
|
||||
* `Forbid`: The cron job does not allow concurrent runs; if it is time for a new job run and the
|
||||
previous job run hasn't finished yet, the cron job skips the new job run
|
||||
* `Replace`: If it is time for a new job run and the previous job run hasn't finished yet, the
|
||||
cron job replaces the currently running job run with a new job run
|
||||
|
||||
Note that concurrency policy only applies to the jobs created by the same cron job.
|
||||
If there are multiple cron jobs, their respective jobs are always allowed to run concurrently.
|
||||
@@ -203,13 +211,15 @@ Defaults to false.
|
||||
|
||||
{{< caution >}}
|
||||
Executions that are suspended during their scheduled time count as missed jobs.
|
||||
When `.spec.suspend` changes from `true` to `false` on an existing cron job without a [starting deadline](#starting-deadline), the missed jobs are scheduled immediately.
|
||||
When `.spec.suspend` changes from `true` to `false` on an existing cron job without a
|
||||
[starting deadline](#starting-deadline), the missed jobs are scheduled immediately.
|
||||
{{< /caution >}}
|
||||
|
||||
### Jobs History Limits
|
||||
|
||||
The `.spec.successfulJobsHistoryLimit` and `.spec.failedJobsHistoryLimit` fields are optional.
|
||||
These fields specify how many completed and failed jobs should be kept.
|
||||
By default, they are set to 3 and 1 respectively. Setting a limit to `0` corresponds to keeping none of the corresponding kind of jobs after they finish.
|
||||
By default, they are set to 3 and 1 respectively. Setting a limit to `0` corresponds to keeping
|
||||
none of the corresponding kind of jobs after they finish.
|
||||
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ Pods may also enter these states when the user attempts graceful deletion of a P
|
||||
on an unreachable Node.
|
||||
The only ways in which a Pod in such a state can be removed from the apiserver are as follows:
|
||||
|
||||
* The Node object is deleted (either by you, or by the [Node Controller](/docs/concepts/architecture/nodes/)).
|
||||
* The Node object is deleted (either by you, or by the [Node Controller](/docs/concepts/architecture/nodes/#node-controller)).
|
||||
* The kubelet on the unresponsive Node starts responding, kills the Pod and removes the entry from the apiserver.
|
||||
* Force deletion of the Pod by the user.
|
||||
|
||||
|
||||
@@ -206,7 +206,7 @@ Ready before starting Pod `N+1`.
|
||||
After the init containers complete successfully, the regular containers run.
|
||||
The MySQL Pods consist of a `mysql` container that runs the actual `mysqld`
|
||||
server, and an `xtrabackup` container that acts as a
|
||||
[sidecar](https://kubernetes.io/blog/2015/06/the-distributed-system-toolkit-patterns).
|
||||
[sidecar](/blog/2015/06/the-distributed-system-toolkit-patterns).
|
||||
|
||||
The `xtrabackup` sidecar looks at the cloned data files and determines if
|
||||
it's necessary to initialize MySQL replication on the replica.
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
title: "Service Catalog"
|
||||
description: Install the Service Catalog extension API.
|
||||
weight: 150
|
||||
---
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
---
|
||||
title: Install Service Catalog using Helm
|
||||
reviewers:
|
||||
- chenopis
|
||||
content_type: task
|
||||
---
|
||||
|
||||
<!-- overview -->
|
||||
{{< glossary_definition term_id="service-catalog" length="all" prepend="Service Catalog is" >}}
|
||||
|
||||
Use [Helm](https://helm.sh/) to install Service Catalog on your Kubernetes cluster.
|
||||
Up to date information on this process can be found at the
|
||||
[kubernetes-sigs/service-catalog](https://github.com/kubernetes-sigs/service-catalog/blob/master/docs/install.md) repo.
|
||||
|
||||
## {{% heading "prerequisites" %}}
|
||||
|
||||
* Understand the key concepts of [Service Catalog](/docs/concepts/extend-kubernetes/service-catalog/).
|
||||
* Service Catalog requires a Kubernetes cluster running version 1.7 or higher.
|
||||
* You must have a Kubernetes cluster with cluster DNS enabled.
|
||||
* If you are using a cloud-based Kubernetes cluster or {{< glossary_tooltip text="Minikube" term_id="minikube" >}}, you may already have cluster DNS enabled.
|
||||
* If you are using `hack/local-up-cluster.sh`, ensure that the `KUBE_ENABLE_CLUSTER_DNS` environment variable is set, then run the install script.
|
||||
* [Install and setup kubectl](/docs/tasks/tools/) v1.7 or higher. Make sure it is configured to connect to the Kubernetes cluster.
|
||||
* Install [Helm](https://helm.sh/) v2.7.0 or newer.
|
||||
* Follow the [Helm install instructions](https://helm.sh/docs/intro/install/).
|
||||
* If you already have an appropriate version of Helm installed, execute `helm init` to install Tiller, the server-side component of Helm.
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- steps -->
|
||||
## Add the service-catalog Helm repository
|
||||
|
||||
Once Helm is installed, add the *service-catalog* Helm repository to your local machine by executing the following command:
|
||||
|
||||
```shell
|
||||
helm repo add svc-cat https://kubernetes-sigs.github.io/service-catalog
|
||||
```
|
||||
|
||||
Check to make sure that it installed successfully by executing the following command:
|
||||
|
||||
```shell
|
||||
helm search repo service-catalog
|
||||
```
|
||||
|
||||
If the installation was successful, the command should output the following:
|
||||
|
||||
```
|
||||
NAME CHART VERSION APP VERSION DESCRIPTION
|
||||
svc-cat/catalog 0.2.1 service-catalog API server and controller-manager helm chart
|
||||
svc-cat/catalog-v0.2 0.2.2 service-catalog API server and controller-manager helm chart
|
||||
```
|
||||
|
||||
## Enable RBAC
|
||||
|
||||
Your Kubernetes cluster must have RBAC enabled, which requires your Tiller Pod(s) to have `cluster-admin` access.
|
||||
|
||||
When using Minikube v0.25 or older, you must run Minikube with RBAC explicitly enabled:
|
||||
|
||||
```shell
|
||||
minikube start --extra-config=apiserver.Authorization.Mode=RBAC
|
||||
```
|
||||
|
||||
When using Minikube v0.26+, run:
|
||||
|
||||
```shell
|
||||
minikube start
|
||||
```
|
||||
|
||||
With Minikube v0.26+, do not specify `--extra-config`. The flag has since been changed to --extra-config=apiserver.authorization-mode and Minikube now uses RBAC by default. Specifying the older flag may cause the start command to hang.
|
||||
|
||||
If you are using `hack/local-up-cluster.sh`, set the `AUTHORIZATION_MODE` environment variable with the following values:
|
||||
|
||||
```
|
||||
AUTHORIZATION_MODE=Node,RBAC hack/local-up-cluster.sh -O
|
||||
```
|
||||
|
||||
By default, `helm init` installs the Tiller Pod into the `kube-system` namespace, with Tiller configured to use the `default` service account.
|
||||
|
||||
{{< note >}}
|
||||
If you used the `--tiller-namespace` or `--service-account` flags when running `helm init`, the `--serviceaccount` flag in the following command needs to be adjusted to reference the appropriate namespace and ServiceAccount name.
|
||||
{{< /note >}}
|
||||
|
||||
Configure Tiller to have `cluster-admin` access:
|
||||
|
||||
```shell
|
||||
kubectl create clusterrolebinding tiller-cluster-admin \
|
||||
--clusterrole=cluster-admin \
|
||||
--serviceaccount=kube-system:default
|
||||
```
|
||||
|
||||
|
||||
## Install Service Catalog in your Kubernetes cluster
|
||||
|
||||
Install Service Catalog from the root of the Helm repository using the following command:
|
||||
|
||||
{{< tabs name="helm-versions" >}}
|
||||
{{% tab name="Helm version 3" %}}
|
||||
```shell
|
||||
helm install catalog svc-cat/catalog --namespace catalog
|
||||
```
|
||||
{{% /tab %}}
|
||||
{{% tab name="Helm version 2" %}}
|
||||
```shell
|
||||
helm install svc-cat/catalog --name catalog --namespace catalog
|
||||
```
|
||||
{{% /tab %}}
|
||||
{{< /tabs >}}
|
||||
|
||||
|
||||
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
* View [sample service brokers](https://github.com/openservicebrokerapi/servicebroker/blob/master/gettingStarted.md#sample-service-brokers).
|
||||
* Explore the [kubernetes-sigs/service-catalog](https://github.com/kubernetes-sigs/service-catalog) project.
|
||||
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
---
|
||||
title: Install Service Catalog using SC
|
||||
reviewers:
|
||||
- chenopis
|
||||
content_type: task
|
||||
---
|
||||
|
||||
<!-- overview -->
|
||||
{{< glossary_definition term_id="service-catalog" length="all" prepend="Service Catalog is" >}}
|
||||
|
||||
You can use the GCP [Service Catalog Installer](https://github.com/GoogleCloudPlatform/k8s-service-catalog#installation)
|
||||
tool to easily install or uninstall Service Catalog on your Kubernetes cluster, linking it to
|
||||
Google Cloud projects.
|
||||
|
||||
Service Catalog can work with any kind of managed service, not only Google Cloud.
|
||||
|
||||
## {{% heading "prerequisites" %}}
|
||||
|
||||
* Understand the key concepts of [Service Catalog](/docs/concepts/extend-kubernetes/service-catalog/).
|
||||
* Install [Go 1.6+](https://golang.org/dl/) and set the `GOPATH`.
|
||||
* Install the [cfssl](https://github.com/cloudflare/cfssl) tool needed for generating SSL artifacts.
|
||||
* Service Catalog requires Kubernetes version 1.7+.
|
||||
* [Install and setup kubectl](/docs/tasks/tools/) so that it is configured to connect to a Kubernetes v1.7+ cluster.
|
||||
* The kubectl user must be bound to the *cluster-admin* role for it to install Service Catalog. To ensure that this is true, run the following command:
|
||||
|
||||
kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user=<user-name>
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- steps -->
|
||||
## Install `sc` in your local environment
|
||||
|
||||
The installer runs on your local computer as a CLI tool named `sc`.
|
||||
|
||||
Install using `go get`:
|
||||
|
||||
```shell
|
||||
go get github.com/GoogleCloudPlatform/k8s-service-catalog/installer/cmd/sc
|
||||
```
|
||||
|
||||
`sc` should now be installed in your `GOPATH/bin` directory.
|
||||
|
||||
## Install Service Catalog in your Kubernetes cluster
|
||||
|
||||
First, verify that all dependencies have been installed. Run:
|
||||
|
||||
```shell
|
||||
sc check
|
||||
```
|
||||
|
||||
If the check is successful, it should return:
|
||||
|
||||
```
|
||||
Dependency check passed. You are good to go.
|
||||
```
|
||||
|
||||
Next, run the install command and specify the `storageclass` that you want to use for the backup:
|
||||
|
||||
```shell
|
||||
sc install --etcd-backup-storageclass "standard"
|
||||
```
|
||||
|
||||
## Uninstall Service Catalog
|
||||
|
||||
If you would like to uninstall Service Catalog from your Kubernetes cluster using the `sc` tool, run:
|
||||
|
||||
```shell
|
||||
sc uninstall
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
* View [sample service brokers](https://github.com/openservicebrokerapi/servicebroker/blob/master/gettingStarted.md#sample-service-brokers).
|
||||
* Explore the [kubernetes-sigs/service-catalog](https://github.com/kubernetes-sigs/service-catalog) project.
|
||||
|
||||
|
||||
@@ -161,7 +161,7 @@ Configurations with a single API server will experience unavailability while the
|
||||
|
||||
1. Check the logs from control plane components, along with the kubelet and the kube-proxy.
|
||||
Ensure those components are not reporting any TLS errors; see
|
||||
[looking at the logs](/docs/tasks/debug-application-cluster/debug-cluster/#looking-at-logs) for more details.
|
||||
[looking at the logs](/docs/tasks/debug/debug-cluster/#looking-at-logs) for more details.
|
||||
|
||||
1. Validate logs from any aggregated api servers and pods using in-cluster config.
|
||||
|
||||
|
||||
@@ -141,7 +141,6 @@ name=Kubernetes
|
||||
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch
|
||||
enabled=1
|
||||
gpgcheck=1
|
||||
repo_gpgcheck=1
|
||||
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
|
||||
EOF
|
||||
sudo yum install -y kubectl
|
||||
|
||||
@@ -19,12 +19,15 @@ to all namespaces in a cluster.
|
||||
|
||||
To apply Pod Security Standards to specific namespaces, refer to [Apply Pod Security Standards at the namespace level](/docs/tutorials/security/ns-level-pss).
|
||||
|
||||
If you are running a version of Kubernetes other than v{{< skew currentVersion >}},
|
||||
check the documentation for that version.
|
||||
|
||||
## {{% heading "prerequisites" %}}
|
||||
|
||||
Install the following on your workstation:
|
||||
|
||||
- [KinD](https://kind.sigs.k8s.io/docs/user/quick-start/#installation)
|
||||
- [kubectl](https://kubernetes.io/docs/tasks/tools/)
|
||||
- [kubectl](/docs/tasks/tools/)
|
||||
|
||||
## Choose the right Pod Security Standard to apply
|
||||
|
||||
@@ -38,12 +41,12 @@ that are most appropriate for your configuration, do the following:
|
||||
1. Create a cluster with no Pod Security Standards applied:
|
||||
|
||||
```shell
|
||||
kind create cluster --name psa-wo-cluster-pss --image kindest/node:v1.23.0
|
||||
kind create cluster --name psa-wo-cluster-pss --image kindest/node:v1.24.0
|
||||
```
|
||||
The output is similar to this:
|
||||
```
|
||||
Creating cluster "psa-wo-cluster-pss" ...
|
||||
✓ Ensuring node image (kindest/node:v1.23.0) 🖼
|
||||
✓ Ensuring node image (kindest/node:v1.24.0) 🖼
|
||||
✓ Preparing nodes 📦
|
||||
✓ Writing configuration 📜
|
||||
✓ Starting control-plane 🕹️
|
||||
@@ -245,12 +248,12 @@ following:
|
||||
these Pod Security Standards:
|
||||
|
||||
```shell
|
||||
kind create cluster --name psa-with-cluster-pss --image kindest/node:v1.23.0 --config /tmp/pss/cluster-config.yaml
|
||||
kind create cluster --name psa-with-cluster-pss --image kindest/node:v1.24.0 --config /tmp/pss/cluster-config.yaml
|
||||
```
|
||||
The output is similar to this:
|
||||
```
|
||||
Creating cluster "psa-with-cluster-pss" ...
|
||||
✓ Ensuring node image (kindest/node:v1.23.0) 🖼
|
||||
✓ Ensuring node image (kindest/node:v1.24.0) 🖼
|
||||
✓ Preparing nodes 📦
|
||||
✓ Writing configuration 📜
|
||||
✓ Starting control-plane 🕹️
|
||||
|
||||
@@ -8,10 +8,11 @@ spec:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
nodeSelectorTerms:
|
||||
- matchExpressions:
|
||||
- key: kubernetes.io/os
|
||||
- key: topology.kubernetes.io/zone
|
||||
operator: In
|
||||
values:
|
||||
- linux
|
||||
- antarctica-east1
|
||||
- antarctica-west1
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
- weight: 1
|
||||
preference:
|
||||
@@ -29,4 +30,4 @@ spec:
|
||||
- key-2
|
||||
containers:
|
||||
- name: with-node-affinity
|
||||
image: k8s.gcr.io/pause:2.0
|
||||
image: k8s.gcr.io/pause:2.0
|
||||
|
||||
@@ -4,5 +4,5 @@ cluster, you can create one by using
|
||||
[minikube](https://minikube.sigs.k8s.io/docs/tutorials/multi_node/)
|
||||
or you can use one of these Kubernetes playgrounds:
|
||||
|
||||
* [Katacoda](https://www.katacoda.com/courses/kubernetes/playground)
|
||||
* [Killercoda](https://killercoda.com/playgrounds/scenario/kubernetes)
|
||||
* [Play with Kubernetes](http://labs.play-with-k8s.com/)
|
||||
|
||||
@@ -78,10 +78,10 @@ releases may also occur in between these.
|
||||
|
||||
| Monthly Patch Release | Cherry Pick Deadline | Target date |
|
||||
| --------------------- | -------------------- | ----------- |
|
||||
| June 2022 | 2022-06-10 | 2022-06-15 |
|
||||
| July 2022 | 2022-07-08 | 2022-07-13 |
|
||||
| August 2022 | 2022-08-12 | 2022-08-17 |
|
||||
| September 2022 | 2022-09-09 | 2022-09-14 |
|
||||
| October 2022 | 2022-10-07 | 2022-10-12 |
|
||||
|
||||
## Detailed Release History for Active Branches
|
||||
|
||||
@@ -93,6 +93,7 @@ End of Life for **1.24** is **2023-09-29**
|
||||
|
||||
| PATCH RELEASE | CHERRY PICK DEADLINE | TARGET DATE | NOTE |
|
||||
|---------------|----------------------|-------------|------|
|
||||
| 1.24.3 | 2022-07-08 | 2022-07-13 | |
|
||||
| 1.24.2 | 2022-06-10 | 2022-06-15 | |
|
||||
| 1.24.1 | 2022-05-20 | 2022-05-24 | |
|
||||
|
||||
@@ -104,6 +105,7 @@ End of Life for **1.23** is **2023-02-28**.
|
||||
|
||||
| Patch Release | Cherry Pick Deadline | Target Date | Note |
|
||||
|---------------|----------------------|-------------|------|
|
||||
| 1.23.9 | 2022-07-08 | 2022-07-13 | |
|
||||
| 1.23.8 | 2022-06-10 | 2022-06-15 | |
|
||||
| 1.23.7 | 2022-05-20 | 2022-05-24 | |
|
||||
| 1.23.6 | 2022-04-08 | 2022-04-13 | |
|
||||
@@ -121,6 +123,7 @@ End of Life for **1.22** is **2022-10-28**
|
||||
|
||||
| Patch Release | Cherry Pick Deadline | Target Date | Note |
|
||||
|---------------|----------------------|-------------|------|
|
||||
| 1.22.12 | 2022-07-08 | 2022-07-13 | |
|
||||
| 1.22.11 | 2022-06-10 | 2022-06-15 | |
|
||||
| 1.22.10 | 2022-05-20 | 2022-05-24 | |
|
||||
| 1.22.9 | 2022-04-08 | 2022-04-13 | |
|
||||
@@ -133,35 +136,13 @@ End of Life for **1.22** is **2022-10-28**
|
||||
| 1.22.2 | 2021-09-10 | 2021-09-15 | |
|
||||
| 1.22.1 | 2021-08-16 | 2021-08-19 | |
|
||||
|
||||
### 1.21
|
||||
|
||||
**1.21** enters maintenance mode on **2022-04-28**
|
||||
|
||||
End of Life for **1.21** is **2022-06-28**
|
||||
|
||||
| Patch Release | Cherry Pick Deadline | Target Date | Note |
|
||||
| ------------- | -------------------- | ----------- | ------------------------------------------------------------------------ |
|
||||
| 1.21.14 | 2022-06-10 | 2022-06-15 | If there is any critical issues to be released otherwise will be skipped |
|
||||
| 1.21.13 | 2022-05-20 | 2022-05-24 | |
|
||||
| 1.21.12 | 2022-04-08 | 2022-04-13 | |
|
||||
| 1.21.11 | 2022-03-11 | 2022-03-16 | |
|
||||
| 1.21.10 | 2022-02-11 | 2022-02-16 | |
|
||||
| 1.21.9 | 2022-01-14 | 2022-01-19 | |
|
||||
| 1.21.8 | 2021-12-10 | 2021-12-15 | |
|
||||
| 1.21.7 | 2021-11-12 | 2021-11-17 | |
|
||||
| 1.21.6 | 2021-10-22 | 2021-10-27 | |
|
||||
| 1.21.5 | 2021-09-10 | 2021-09-15 | |
|
||||
| 1.21.4 | 2021-08-07 | 2021-08-11 | |
|
||||
| 1.21.3 | 2021-07-10 | 2021-07-14 | |
|
||||
| 1.21.2 | 2021-06-12 | 2021-06-16 | |
|
||||
| 1.21.1 | 2021-05-07 | 2021-05-12 | [Regression](https://groups.google.com/g/kubernetes-dev/c/KuF8s2zueFs) |
|
||||
|
||||
## Non-Active Branch History
|
||||
|
||||
These releases are no longer supported.
|
||||
|
||||
| Minor Version | Final Patch Release | EOL Date | Note |
|
||||
| ------------- | ------------------- | ---------- | ---------------------------------------------------------------------- |
|
||||
| 1.21 | 1.21.14 | 2022-06-28 | |
|
||||
| 1.20 | 1.20.15 | 2022-02-28 | |
|
||||
| 1.19 | 1.19.16 | 2021-10-28 | |
|
||||
| 1.18 | 1.18.20 | 2021-06-18 | Created to resolve regression introduced in 1.18.19 |
|
||||
|
||||
@@ -69,7 +69,7 @@ Release Managers are responsible for:
|
||||
- Reviewing cherry picks
|
||||
- Ensuring the release branch stays healthy and that no unintended patch
|
||||
gets merged
|
||||
- Mentoring the [Release Manager Associates](#associates) group
|
||||
- Mentoring the [Release Manager Associates](#release-manager-associates) group
|
||||
- Actively developing features and maintaining the code in k/release
|
||||
- Supporting Release Manager Associates and contributors through actively
|
||||
participating in the Buddy program
|
||||
@@ -212,7 +212,7 @@ Example: [1.15 Release Team](https://git.k8s.io/sig-release/releases/release-1.1
|
||||
[handbook-packaging]: https://git.k8s.io/sig-release/release-engineering/packaging.md
|
||||
[handbook-patch-release]: https://git.k8s.io/sig-release/release-engineering/role-handbooks/patch-release-team.md
|
||||
[k-sig-release-releases]: https://git.k8s.io/sig-release/releases
|
||||
[patches]: /patch-releases.md
|
||||
[patches]: /releases/patch-releases/
|
||||
[src]: https://git.k8s.io/community/committee-security-response/README.md
|
||||
[release-team]: https://git.k8s.io/sig-release/release-team/README.md
|
||||
[security-release-process]: https://git.k8s.io/security/security-release-process.md
|
||||
|
||||
@@ -281,7 +281,7 @@ Issues are marked as targeting a milestone via the Prow "/milestone" command.
|
||||
The Release Team's [Bug Triage Lead](https://git.k8s.io/sig-release/release-team/role-handbooks/bug-triage/README.md)
|
||||
and overall community watch incoming issues and triage them, as described in
|
||||
the contributor guide section on
|
||||
[issue triage](/contributors/guide/issue-triage.md).
|
||||
[issue triage](https://k8s.dev/docs/guide/issue-triage/).
|
||||
|
||||
Marking issues with the milestone provides the community better visibility
|
||||
regarding when an issue was observed and by when the community feels it must be
|
||||
@@ -355,11 +355,11 @@ issue kind labels must be set:
|
||||
- `kind/feature`: New functionality.
|
||||
- `kind/flake`: CI test case is showing intermittent failures.
|
||||
|
||||
[cherry-picks]: /contributors/devel/sig-release/cherry-picks.md
|
||||
[cherry-picks]: https://git.k8s.io/community/contributors/devel/sig-release/cherry-picks.md
|
||||
[code-freeze]: https://git.k8s.io/sig-release/releases/release_phases.md#code-freeze
|
||||
[enhancements-freeze]: https://git.k8s.io/sig-release/releases/release_phases.md#enhancements-freeze
|
||||
[exceptions]: https://git.k8s.io/sig-release/releases/release_phases.md#exceptions
|
||||
[keps]: https://git.k8s.io/enhancements/keps
|
||||
[release-managers]: https://kubernetes.io/releases/release-managers/
|
||||
[release-managers]: /releases/release-managers/
|
||||
[release-team]: https://git.k8s.io/sig-release/release-team
|
||||
[sig-list]: /sig-list.md
|
||||
[sig-list]: https://k8s.dev/sigs
|
||||
|
||||
@@ -26,7 +26,7 @@ For more information, see [Kubernetes Release Versioning](https://git.k8s.io/des
|
||||
The Kubernetes project maintains release branches for the most recent three minor releases ({{< skew currentVersion >}}, {{< skew currentVersionAddMinor -1 >}}, {{< skew currentVersionAddMinor -2 >}}). Kubernetes 1.19 and newer receive approximately 1 year of patch support. Kubernetes 1.18 and older received approximately 9 months of patch support.
|
||||
|
||||
Applicable fixes, including security fixes, may be backported to those three release branches, depending on severity and feasibility.
|
||||
Patch releases are cut from those branches at a [regular cadence](https://kubernetes.io/releases/patch-releases/#cadence), plus additional urgent releases, when required.
|
||||
Patch releases are cut from those branches at a [regular cadence](/releases/patch-releases/#cadence), plus additional urgent releases, when required.
|
||||
|
||||
The [Release Managers](/releases/release-managers/) group owns this decision.
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ FOO_SERVICE_HOST=<El host donde está funcionando el servicio>
|
||||
FOO_SERVICE_PORT=<El puerto dónde está funcionando el servicio>
|
||||
```
|
||||
Los servicios tienen direcciones IP dedicadas y están disponibles para el Container a través de DNS,
|
||||
si el [complemento para DNS](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/dns/) está habilitado.
|
||||
si el [complemento para DNS](http://releases.k8s.io/master/cluster/addons/dns/) está habilitado.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ Para aplicaciones no nativas, Kubernetes ofrece una manera de colocar un puerto
|
||||
Un Service en Kubernetes es un objeto REST, similar a un Pod. Como todos los objetos REST, puedes hacer un `Post` a una definición de un Service al servidor API para crear una nueva instancia.
|
||||
EL nombre de un objeto Service debe ser un [nombre RFC 1035 válido](/docs/concepts/overview/working-with-objects/names#rfc-1035-label-names).
|
||||
|
||||
Por ejemplo, supongamos que tienes un conjunto de Pods en el que cada uno escucha el puerto TCP 9376 y contiene la etiqueta `app=MyApp`:
|
||||
Por ejemplo, supongamos que tienes un conjunto de Pods en el que cada uno escucha el puerto TCP 9376 y contiene la etiqueta `app.kubernetes.io/name=MyApp`:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
@@ -63,14 +63,14 @@ metadata:
|
||||
name: mi-servicio
|
||||
spec:
|
||||
selector:
|
||||
app: MyApp
|
||||
app.kubernetes.io/name: MyApp
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 80
|
||||
targetPort: 9376
|
||||
```
|
||||
|
||||
Esta especificación crea un nuevo objeto Service llamado "mi-servicio", que apunta via TCP al puerto 9376 de cualquier Pod con la etiqueta `app=MyApp`.
|
||||
Esta especificación crea un nuevo objeto Service llamado "mi-servicio", que apunta via TCP al puerto 9376 de cualquier Pod con la etiqueta `app.kubernetes.io/name=MyApp`.
|
||||
|
||||
Kubernetes asigna una dirección IP a este Service (Algunas veces llamado "Cluster IP"), la cual es usada por los proxies de los Services (mira [IPs Virtuales y proxies de servicios](#virtual-ips-and-service-proxies) abajo).
|
||||
|
||||
@@ -297,7 +297,7 @@ spec:
|
||||
{{< note >}}
|
||||
Como con los {{< glossary_tooltip term_id="name" text="nombres">}} de Kubernetes en general, los nombres para los puertos deben contener alfanuméricos en minúsculas y `-`. Los nombres de puertos deben comenzar y terminar con un carácter alfanumérico.
|
||||
|
||||
Por ejemplo, los nombres `123-abc` and `web` son válidos, pero `123_abc` y `-web` no lo son.
|
||||
Por ejemplo, los nombres `123-abc` and `web` son válidos, pero `123_abc` y `-web` no lo son.
|
||||
{{< /note >}}
|
||||
|
||||
## Eligiendo tu propia dirección IP
|
||||
@@ -799,11 +799,11 @@ NLB solo funciona con ciertas clases de instancias; mira la [documentación AWS]
|
||||
A diferencia de los balanceadores de cargas, el balanceador de carga de red (NLB) reenvía la dirección IP del cliente a través del nodo. Si el campo `.spec.externalTrafficPolicy` está fijado a `clúster`, la dirección IP del cliente no es propagada a los Pods finales.
|
||||
|
||||
Al fijar `.spec.externalTrafficPolicy` en `Local`, la dirección IP del cliente se propaga a los Pods finales,
|
||||
pero esto puede resultar a una distribución de tráfico desigual. Los nodos sin ningún Pod para un Service particular de tipo LoadBalancer fallarán en la comprobación de estado del grupo objetivo del NLB en el puerto `.spec.healthCheckNodePort` y no recibirán ningún tráfico.
|
||||
pero esto puede resultar a una distribución de tráfico desigual. Los nodos sin ningún Pod para un Service particular de tipo LoadBalancer fallarán en la comprobación de estado del grupo objetivo del NLB en el puerto `.spec.healthCheckNodePort` y no recibirán ningún tráfico.
|
||||
|
||||
Para conseguir trafico equilibrado, usa un DaemonSet o especifica [pod anti-affinity](/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity) para no localizar en el mismo nodo.
|
||||
Para conseguir trafico equilibrado, usa un DaemonSet o especifica [pod anti-affinity](/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity) para no localizar en el mismo nodo.
|
||||
|
||||
También puedes usar Services NLB con la anotación del [balanceador de carga interno](/docs/concepts/services-networking/service/#internal-load-balancer)
|
||||
También puedes usar Services NLB con la anotación del [balanceador de carga interno](/docs/concepts/services-networking/service/#internal-load-balancer)
|
||||
|
||||
Para permitir que el tráfico del cliente alcance las instancias detrás del NLB, los grupos de seguridad del Nodo se modifican con las siguientes reglas de IP:
|
||||
|
||||
@@ -822,7 +822,7 @@ spec:
|
||||
```
|
||||
|
||||
{{< note >}}
|
||||
Si no se establece `.spec.loadBalancerSourceRanges`, Kubernetes permite el tráfico
|
||||
Si no se establece `.spec.loadBalancerSourceRanges`, Kubernetes permite el tráfico
|
||||
desde `0.0.0.0/0` a los Grupos de Seguridad del Nodo. Si los nodos tienen direcciones IP públicas, ten en cuenta que el tráfico que no viene del NLB
|
||||
también puede alcanzar todas las instancias en esos grupos de seguridad modificados.
|
||||
{{< /note >}}
|
||||
@@ -865,9 +865,9 @@ Hay otras anotaciones para administrar balanceadores de carga en la nube en TKE
|
||||
|
||||
### Tipo ExternalName {#externalname}
|
||||
|
||||
Los Services de tipo ExternalName mapean un Service a un nombre DNS, no a un selector típico como `mi-servicio` o `cassandra`. Estos Services se especifican con el parámetro `spec.externalName`.
|
||||
Los Services de tipo ExternalName mapean un Service a un nombre DNS, no a un selector típico como `mi-servicio` o `cassandra`. Estos Services se especifican con el parámetro `spec.externalName`.
|
||||
|
||||
Esta definición de Service, por ejemplo, mapea el Service `mi-Servicio` en el namespace `prod` a `my.database.example.com`:
|
||||
Esta definición de Service, por ejemplo, mapea el Service `mi-Servicio` en el namespace `prod` a `my.database.example.com`:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
@@ -884,7 +884,7 @@ spec:
|
||||
ExternalName acepta una cadena de texto IPv4, pero como un nombre DNS compuesto de dígitos, no como una dirección IP. ExternalNames que se parecen a direcciones IPv4 no se resuelven por el CoreDNS o ingress-nginx, ya que ExternalName se usa para especificar un nombre DNS canónico. Al fijar una dirección IP, considera usar [headless Services](#headless-services).
|
||||
{{< /note >}}
|
||||
|
||||
Cuando busca el host `mi-servicio.prod.svc.cluster.local`, el Service DNS del clúster devuelve un registro `CNAME` con el valor `my.database.example.com`. Acceder a `mi-servicio` funciona de la misma manera que otros Services, pero con la diferencia crucial de que la redirección ocurre a nivel del DNS en lugar reenviarlo o redirigirlo. Si posteriormente decides mover tu base de datos al clúster, puedes iniciar sus Pods, agregar selectores apropiados o endpoints, y cambiar el `type` del Service.
|
||||
Cuando busca el host `mi-servicio.prod.svc.cluster.local`, el Service DNS del clúster devuelve un registro `CNAME` con el valor `my.database.example.com`. Acceder a `mi-servicio` funciona de la misma manera que otros Services, pero con la diferencia crucial de que la redirección ocurre a nivel del DNS en lugar reenviarlo o redirigirlo. Si posteriormente decides mover tu base de datos al clúster, puedes iniciar sus Pods, agregar selectores apropiados o endpoints, y cambiar el `type` del Service.
|
||||
|
||||
|
||||
{{< warning >}}
|
||||
@@ -894,15 +894,15 @@ Para protocolos que usan el nombre del host esta diferencia puede llevar a error
|
||||
{{< /warning >}}
|
||||
|
||||
{{< note >}}
|
||||
Esta sección está en deuda con el artículo de blog [Kubernetes Tips - Part 1](https://akomljen.com/kubernetes-tips-part-1/) de [Alen Komljen](https://akomljen.com/).
|
||||
Esta sección está en deuda con el artículo de blog [Kubernetes Tips - Part 1](https://akomljen.com/kubernetes-tips-part-1/) de [Alen Komljen](https://akomljen.com/).
|
||||
{{< /note >}}
|
||||
|
||||
### IPs Externas
|
||||
|
||||
Si existen IPs externas que enrutan hacia uno o más nodos del clúster, los Services de Kubernetes pueden ser expuestos en esas `externalIPs`. El tráfico que ingresa al clúster con la IP externa (como IP de destino), en el puerto del Service, será enrutado a uno de estos endpoints del Service. Las `externalIPs` no son administradas por Kubernetes y son responsabilidad del administrador del clúster.
|
||||
Si existen IPs externas que enrutan hacia uno o más nodos del clúster, los Services de Kubernetes pueden ser expuestos en esas `externalIPs`. El tráfico que ingresa al clúster con la IP externa (como IP de destino), en el puerto del Service, será enrutado a uno de estos endpoints del Service. Las `externalIPs` no son administradas por Kubernetes y son responsabilidad del administrador del clúster.
|
||||
|
||||
En la especificación del Service, las `externalIPs` se pueden especificar junto con cualquiera de los `ServiceTypes`.
|
||||
En el ejemplo de abajo, "`mi-servicio`" puede ser accedido por clientes en "`80.11.12.10:80`" (`externalIP:port`)
|
||||
En el ejemplo de abajo, "`mi-servicio`" puede ser accedido por clientes en "`80.11.12.10:80`" (`externalIP:port`)
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
@@ -911,7 +911,7 @@ metadata:
|
||||
name: mi-servicio
|
||||
spec:
|
||||
selector:
|
||||
app: MyApp
|
||||
app.kubernetes.io/name: MyApp
|
||||
ports:
|
||||
- name: http
|
||||
protocol: TCP
|
||||
@@ -925,21 +925,21 @@ spec:
|
||||
|
||||
Usar el proxy del userspace for VIPs funciona en pequeña y mediana escala, pero no escalará a clústeres muy grandes con miles de Services. El tópico [original design proposal for portals](https://github.com/kubernetes/kubernetes/issues/1107) tiene más detalles sobre esto.
|
||||
|
||||
Usar el proxy del userspace oculta la dirección IP de origen de un paquete que accede al Service. Esto hace que algún tipo de filtrado (firewalling) sea imposible. El modo proxy iptables no oculta IPs de origen en el clúster, pero aún tiene impacto en clientes que vienen desde un balanceador de carga o un node-port.
|
||||
Usar el proxy del userspace oculta la dirección IP de origen de un paquete que accede al Service. Esto hace que algún tipo de filtrado (firewalling) sea imposible. El modo proxy iptables no oculta IPs de origen en el clúster, pero aún tiene impacto en clientes que vienen desde un balanceador de carga o un node-port.
|
||||
|
||||
El campo `Type` está diseñado como una funcionalidad anidada - cada nivel se agrega al anterior. Esto no es estrictamente requerido en todos los proveedores de la nube (ej. Google Compute Engine no necesita asignar un `NodePort` para que funcione el `LoadBalancer`, pero AWS si) pero la API actual lo requiere.
|
||||
El campo `Type` está diseñado como una funcionalidad anidada - cada nivel se agrega al anterior. Esto no es estrictamente requerido en todos los proveedores de la nube (ej. Google Compute Engine no necesita asignar un `NodePort` para que funcione el `LoadBalancer`, pero AWS si) pero la API actual lo requiere.
|
||||
|
||||
## Implementación de IP Virtual {#the-gory-details-of-virtual-ips}
|
||||
|
||||
La información previa sería suficiente para muchas personas que quieren usar Services. Sin embargo, ocurren muchas cosas detrás de bastidores que valdría la pena entender.
|
||||
|
||||
### Evitar colisiones
|
||||
### Evitar colisiones
|
||||
|
||||
Una de las principales filosofías de Kubernetes es que no debe estar expuesto a situaciones que podrían hacer que sus acciones fracasen por su propia culpa. Para el diseño del recurso de Service, esto significa no obligarlo a elegir su propio número de puerto si esa elección puede colisionar con la de otra persona. Eso es un fracaso de aislamiento.
|
||||
|
||||
Para permitirte elegir un número de puerto en tus Services, debemos asegurarnos que dos Services no puedan colisionar. Kubernetes lo hace asignando a cada Service su propia dirección IP.
|
||||
|
||||
Para asegurarse que cada Service recibe una IP única, un asignador interno actualiza atómicamente el mapa global de asignaciones en {{< glossary_tooltip term_id="etcd" >}} antes de crear cada Service. El objeto mapa debe existir en el registro para que los Services obtengan asignaciones de dirección IP, de lo contrario las creaciones fallarán con un mensaje indicando que la dirección IP no pudo ser asignada.
|
||||
Para asegurarse que cada Service recibe una IP única, un asignador interno actualiza atómicamente el mapa global de asignaciones en {{< glossary_tooltip term_id="etcd" >}} antes de crear cada Service. El objeto mapa debe existir en el registro para que los Services obtengan asignaciones de dirección IP, de lo contrario las creaciones fallarán con un mensaje indicando que la dirección IP no pudo ser asignada.
|
||||
|
||||
En el plano de control, un controlador de trasfondo es responsable de crear el mapa (requerido para soportar la migración desde versiones más antiguas de Kubernetes que usaban bloqueo en memoria). Kubernetes también utiliza controladores para revisar asignaciones inválidas (ej. debido a la intervención de un administrador) y para limpiar las direcciones IP que ya no son usadas por ningún Service.
|
||||
|
||||
@@ -947,7 +947,7 @@ En el plano de control, un controlador de trasfondo es responsable de crear el m
|
||||
|
||||
A diferencia de direcciones IP del Pod, que enrutan a un destino fijo, las IPs del Service no son respondidas por ningún host. En lugar de ello, El kube-proxy usa iptables (lógica de procesamiento de paquetes en Linux) para definir direcciones IP _virtuales_ que se redirigen de forma transparente cuando se necesita. Cuando el cliente se conecta con la VIP, su tráfico es transportado automáticamente al endpoint apropiado. Las variables de entorno y DNS para los Services son pobladas en términos de la dirección IP virtual del Service (y el puerto).
|
||||
|
||||
Kube-proxy soporta tres modos — userspace, iptables e IPVS — los cuales operan ligeramente diferente cada uno.
|
||||
Kube-proxy soporta tres modos — userspace, iptables e IPVS — los cuales operan ligeramente diferente cada uno.
|
||||
|
||||
#### Userspace
|
||||
|
||||
@@ -955,11 +955,11 @@ Por ejemplo, considera la aplicación de procesamiento de imágenes descrita arr
|
||||
|
||||
Cuando un cliente se conecta a la dirección IP virtual del Service, la regla de iptables entra en acción, y redirige los paquetes al propio puerto del proxy. El "proxy del Service" elige un backend, y comienza a redirigir el tráfico desde el cliente al backend.
|
||||
|
||||
Esto quiere decir que los dueños del Service pueden elegir cualquier puerto que quieran sin riesgo de colisión. Los clientes pueden conectarse a una IP y un puerto, sin estar conscientes de a cuáles Pods están accediendo.
|
||||
Esto quiere decir que los dueños del Service pueden elegir cualquier puerto que quieran sin riesgo de colisión. Los clientes pueden conectarse a una IP y un puerto, sin estar conscientes de a cuáles Pods están accediendo.
|
||||
|
||||
#### iptables
|
||||
|
||||
Nuevamente, considera la aplicación de procesamiento de imágenes descrita arriba. Cuando se crea el Service Backend, el plano de control de Kubernetes asigna una dirección IP virtual, por ejemplo 10.0.0.1. Asumiendo que el puerto del servicio es 1234, el Service es observado por todas las instancias del kube-proxy en el clúster. Cuando un proxy mira un nuevo Service, instala una serie de reglas de iptables que redirigen desde la dirección IP virtual a las reglas del Service. Las reglas del Service enlazan a las reglas del Endpoint que redirigen el tráfico (usando NAT de destino) a los backends.
|
||||
Nuevamente, considera la aplicación de procesamiento de imágenes descrita arriba. Cuando se crea el Service Backend, el plano de control de Kubernetes asigna una dirección IP virtual, por ejemplo 10.0.0.1. Asumiendo que el puerto del servicio es 1234, el Service es observado por todas las instancias del kube-proxy en el clúster. Cuando un proxy mira un nuevo Service, instala una serie de reglas de iptables que redirigen desde la dirección IP virtual a las reglas del Service. Las reglas del Service enlazan a las reglas del Endpoint que redirigen el tráfico (usando NAT de destino) a los backends.
|
||||
|
||||
Cuando un cliente se conecta a la dirección IP virtual del Service la regla de iptables son aplicadas. A diferencia del modo proxy userspace, el kube-proxy no tiene que estar corriendo para que funcione la dirección IP virtual, y los nodos observan el tráfico que viene desde la dirección IP del cliente sin alteraciones.
|
||||
|
||||
@@ -1014,11 +1014,11 @@ El kube-proxy no soporta la administración de asociaciones SCTP cuando está en
|
||||
Si tu proveedor de la nube lo soporta, puedes usar un Service en modo LoadBalancer para configurar un proxy invertido HTTP/HTTPS, redirigido a los Endpoints del Service.
|
||||
|
||||
{{< note >}}
|
||||
También puedes usar {{< glossary_tooltip term_id="ingress" >}} en lugar de un Service para exponer Services HTTP/HTTPS.
|
||||
También puedes usar {{< glossary_tooltip term_id="ingress" >}} en lugar de un Service para exponer Services HTTP/HTTPS.
|
||||
{{< /note >}}
|
||||
|
||||
### Protocolo PROXY
|
||||
Si tu proveedor de la nube lo soporta, puedes usar un Service en modo LoadBalancer para configurar un balanceador de carga fuera de Kubernetes mismo, que redirigirá las conexiones prefijadas con [protocolo PROXY](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt).
|
||||
Si tu proveedor de la nube lo soporta, puedes usar un Service en modo LoadBalancer para configurar un balanceador de carga fuera de Kubernetes mismo, que redirigirá las conexiones prefijadas con [protocolo PROXY](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt).
|
||||
|
||||
El balanceador de carga enviará una serie inicial de octetos describiendo la conexión entrante, similar a este ejemplo
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ kind: Pod
|
||||
metadata:
|
||||
name: myapp-pod
|
||||
labels:
|
||||
app: myapp
|
||||
app.kubernetes.io/name: MyApp
|
||||
spec:
|
||||
containers:
|
||||
- name: myapp-container
|
||||
@@ -165,7 +165,7 @@ El resultado es similar a esto:
|
||||
Name: myapp-pod
|
||||
Namespace: default
|
||||
[...]
|
||||
Labels: app=myapp
|
||||
Labels: app.kubernetes.io/name=MyApp
|
||||
Status: Pending
|
||||
[...]
|
||||
Init Containers:
|
||||
|
||||
@@ -30,7 +30,7 @@ cd kubernetes
|
||||
make release
|
||||
```
|
||||
|
||||
Para más detalles sobre el proceso de compilación de una release, visita la carpeta kubernetes/kubernetes [`build`](http://releases.k8s.io/{{< param "githubbranch" >}}/build/)
|
||||
Para más detalles sobre el proceso de compilación de una release, visita la carpeta kubernetes/kubernetes [`build`](http://releases.k8s.io/master/build/)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Debes tener un cluster Kubernetes a tu dispocición, y la herramienta de línea de comandos `kubectl` debe estar configurada. Si no tienes un cluster, puedes crear uno utilizando [Minikube](/docs/setup/minikube),
|
||||
o puedes utilizar una de las siguientes herramientas en línea:
|
||||
|
||||
* [Katacoda](https://www.katacoda.com/courses/kubernetes/playground)
|
||||
* [Killercoda](https://killercoda.com/playgrounds/scenario/kubernetes)
|
||||
* [Play with Kubernetes](http://labs.play-with-k8s.com/)
|
||||
|
||||
@@ -49,7 +49,7 @@ FOO_SERVICE_PORT=<le port sur lequel le service fonctionne>
|
||||
```
|
||||
|
||||
Les services ont des adresses IP dédiées et sont disponibles pour le conteneur avec le DNS,
|
||||
si le [module DNS](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/dns/) est activé.
|
||||
si le [module DNS](http://releases.k8s.io/master/cluster/addons/dns/) est activé.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ C'est pourquoi Kubernetes a également été conçu pour servir de plate-forme e
|
||||
|
||||
De plus, le [plan de contrôle Kubernetes (control
|
||||
plane)](/docs/concepts/overview/components/) est construit sur les mêmes [APIs](/docs/reference/using-api/api-overview/) que celles accessibles aux développeurs et utilisateurs.
|
||||
Les utilisateurs peuvent écrire leurs propres contrôleurs (controllers), tels que les [ordonnanceurs (schedulers)](https://github.com/kubernetes/community/blob/{{< param "githubbranch" >}}/contributors/devel/scheduler.md),
|
||||
Les utilisateurs peuvent écrire leurs propres contrôleurs (controllers), tels que les [ordonnanceurs (schedulers)](https://github.com/kubernetes/community/blob/master/contributors/devel/scheduler.md),
|
||||
avec [leurs propres APIs](/docs/concepts/api-extension/custom-resources/) qui peuvent être utilisés par un [outil en ligne de commande](/docs/user-guide/kubectl-overview/).
|
||||
|
||||
Ce choix de [conception](https://git.k8s.io/community/contributors/design-proposals/architecture/architecture.md) a permis de construire un ensemble d'autres systèmes par dessus Kubernetes.
|
||||
|
||||
@@ -289,7 +289,7 @@ Kubernetes prend en charge 2 modes principaux de recherche d'un service: les var
|
||||
### Variables d'environnement
|
||||
|
||||
Lorsqu'un pod est exécuté sur un nœud, le kubelet ajoute un ensemble de variables d'environnement pour chaque service actif.
|
||||
Il prend en charge à la fois les variables [Docker links](https://docs.docker.com/userguide/dockerlinks/) (voir [makeLinkVariables](http://releases.k8s.io/{{< param "githubbranch" >}}/pkg/kubelet/envvars/envvars.go#L49)) et plus simplement les variables `{SVCNAME}_SERVICE_HOST` et `{SVCNAME}_SERVICE_PORT`, où le nom du service est en majuscules et les tirets sont convertis en underscore.
|
||||
Il prend en charge à la fois les variables [Docker links](https://docs.docker.com/userguide/dockerlinks/) (voir [makeLinkVariables](http://releases.k8s.io/master/pkg/kubelet/envvars/envvars.go#L49)) et plus simplement les variables `{SVCNAME}_SERVICE_HOST` et `{SVCNAME}_SERVICE_PORT`, où le nom du service est en majuscules et les tirets sont convertis en underscore.
|
||||
|
||||
Par exemple, le service `redis-master` qui expose le port TCP 6379 et a reçu l'adresse IP de cluster 10.0.0.11, produit les variables d'environnement suivantes:
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@ Afin d'utiliser cette fonctionnalité, le [Pilote AWS EBS CSI](https://github.co
|
||||
|
||||
Un type de volume `azureDisk` est utilisé pour monter un disque de données ([Data Disk](https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-linux-about-disks-vhds/)) dans un Pod.
|
||||
|
||||
Plus de détails sont disponibles [ici](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/volumes/azure_disk/README.md).
|
||||
Plus de détails sont disponibles [ici](https://github.com/kubernetes/examples/tree/master/staging/volumes/azure_disk/README.md).
|
||||
|
||||
#### Migration CSI
|
||||
|
||||
@@ -150,7 +150,7 @@ Afin d'utiliser cette fonctionnalité, le [Pilote Azure Disk CSI](https://github
|
||||
|
||||
Un type de volume `azureFile` est utilisé pour monter un volume de fichier Microsoft Azure (SMB 2.1 et 3.0) dans un Pod.
|
||||
|
||||
Plus de détails sont disponibles [ici](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/volumes/azure_file/README.md).
|
||||
Plus de détails sont disponibles [ici](https://github.com/kubernetes/examples/tree/master/staging/volumes/azure_file/README.md).
|
||||
|
||||
#### Migration CSI
|
||||
|
||||
@@ -170,7 +170,7 @@ CephFS peut être monté plusieurs fois en écriture simultanément.
|
||||
Vous devez exécuter votre propre serveur Ceph avec le partage exporté avant de pouvoir l'utiliser.
|
||||
{{< /caution >}}
|
||||
|
||||
Voir [l'exemple CephFS](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/volumes/cephfs/) pour plus de détails.
|
||||
Voir [l'exemple CephFS](https://github.com/kubernetes/examples/tree/master/volumes/cephfs/) pour plus de détails.
|
||||
|
||||
### cinder {#cinder}
|
||||
|
||||
@@ -315,7 +315,7 @@ Si plusieurs WWNs sont spécifiés, targetWWNs s'attend à ce que ces WWNs provi
|
||||
Vous devez configurer un zonage FC SAN pour allouer et masquer au préalable ces LUNs (volumes) aux cibles WWNs afin que les hôtes Kubernetes puissent y accéder.
|
||||
{{< /caution >}}
|
||||
|
||||
Voir [l'exemple FC](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/volumes/fibre_channel) pour plus de détails.
|
||||
Voir [l'exemple FC](https://github.com/kubernetes/examples/tree/master/staging/volumes/fibre_channel) pour plus de détails.
|
||||
|
||||
### flocker {#flocker}
|
||||
|
||||
@@ -330,7 +330,7 @@ Cela signifie que les données peuvent être transmises entre les Pods selon les
|
||||
Vous devez exécuter votre propre installation de Flocker avant de pouvoir l'utiliser.
|
||||
{{< /caution >}}
|
||||
|
||||
Voir [l'exemple Flocker](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/volumes/flocker) pour plus de détails.
|
||||
Voir [l'exemple Flocker](https://github.com/kubernetes/examples/tree/master/staging/volumes/flocker) pour plus de détails.
|
||||
|
||||
### gcePersistentDisk {#gcepersistentdisk}
|
||||
|
||||
@@ -465,7 +465,7 @@ GlusterFS peut être monté plusieurs fois en écriture simultanément.
|
||||
Vous devez exécuter votre propre installation de GlusterFS avant de pouvoir l'utiliser.
|
||||
{{< /caution >}}
|
||||
|
||||
Voir [l'exemple GlusterFS](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/volumes/glusterfs) pour plus de détails.
|
||||
Voir [l'exemple GlusterFS](https://github.com/kubernetes/examples/tree/master/volumes/glusterfs) pour plus de détails.
|
||||
|
||||
### hostPath {#hostpath}
|
||||
|
||||
@@ -537,7 +537,7 @@ Une fonctionnalité de iSCSI est qu'il peut être monté en lecture seule par pl
|
||||
Cela signifie que vous pouvez préremplir un volume avec votre jeu de données et l'exposer en parallèle à partir d'autant de Pods que nécessaire.
|
||||
Malheureusement, les volumes iSCSI peuvent seulement être montés par un seul consommateur en mode lecture-écriture - les écritures simultanées ne sont pas autorisées.
|
||||
|
||||
Voir [l'exemple iSCSI](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/volumes/iscsi) pour plus de détails.
|
||||
Voir [l'exemple iSCSI](https://github.com/kubernetes/examples/tree/master/volumes/iscsi) pour plus de détails.
|
||||
|
||||
### local {#local}
|
||||
|
||||
@@ -605,7 +605,7 @@ Cela signifie qu'un volume NFS peut être prérempli avec des données et que le
|
||||
Vous devez exécuter votre propre serveur NFS avec le partage exporté avant de pouvoir l'utiliser.
|
||||
{{< /caution >}}
|
||||
|
||||
Voir [l'exemple NFS](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/volumes/nfs) pour plus de détails.
|
||||
Voir [l'exemple NFS](https://github.com/kubernetes/examples/tree/master/staging/volumes/nfs) pour plus de détails.
|
||||
|
||||
### persistentVolumeClaim {#persistentvolumeclaim}
|
||||
|
||||
@@ -624,7 +624,7 @@ Actuellement, les types de sources de volume suivantes peuvent être projetés :
|
||||
- [`configMap`](#configmap)
|
||||
- `serviceAccountToken`
|
||||
|
||||
Toutes les sources doivent se trouver dans le même namespace que celui du Pod. Pour plus de détails, voir le [document de conception tout-en-un ](https://github.com/kubernetes/community/blob/{{< param "githubbranch" >}}/contributors/design-proposals/node/all-in-one-volume.md).
|
||||
Toutes les sources doivent se trouver dans le même namespace que celui du Pod. Pour plus de détails, voir le [document de conception tout-en-un ](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/node/all-in-one-volume.md).
|
||||
|
||||
La projection des jetons de compte de service (service account) est une fonctionnalité introduite dans Kubernetes 1.11 et promue en Beta dans la version 1.12.
|
||||
Pour activer cette fonctionnalité dans la version 1.11, il faut configurer explicitement la ["feature gate" `TokenRequestProjection`](/docs/reference/command-line-tools-reference/feature-gates/) à "True".
|
||||
@@ -776,7 +776,7 @@ spec:
|
||||
Il faut s'assurer d'avoir un PortworxVolume existant avec le nom `pxvol` avant de l'utiliser dans le Pod.
|
||||
{{< /caution >}}
|
||||
|
||||
Plus de détails et d'exemples peuvent être trouvé [ici](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/volumes/portworx/README.md).
|
||||
Plus de détails et d'exemples peuvent être trouvé [ici](https://github.com/kubernetes/examples/tree/master/staging/volumes/portworx/README.md).
|
||||
|
||||
### quobyte {#quobyte}
|
||||
|
||||
@@ -804,7 +804,7 @@ Une fonctionnalité de RBD est qu'il peut être monté en lecture seule par plus
|
||||
Cela signifie que vous pouvez préremplir un volume avec votre jeu de données et l'exposer en parallèle à partir d'autant de Pods que nécessaire.
|
||||
Malheureusement, les volumes RBD peuvent seulement être montés par un seul consommateur en mode lecture-écriture - les écritures simultanées ne sont pas autorisées.
|
||||
|
||||
Voir [l'exemple RBD](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/volumes/rbd) pour plus de détails.
|
||||
Voir [l'exemple RBD](https://github.com/kubernetes/examples/tree/master/volumes/rbd) pour plus de détails.
|
||||
|
||||
### scaleIO {#scaleio}
|
||||
|
||||
@@ -842,7 +842,7 @@ spec:
|
||||
fsType: xfs
|
||||
```
|
||||
|
||||
Pour plus de détails, consulter [les exemples ScaleIO](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/volumes/scaleio).
|
||||
Pour plus de détails, consulter [les exemples ScaleIO](https://github.com/kubernetes/examples/tree/master/staging/volumes/scaleio).
|
||||
|
||||
### secret {#secret}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ Un [Deployment](/fr/docs/concepts/workloads/controllers/deployment/) ou
|
||||
|
||||
## Limitations
|
||||
|
||||
* Le stockage pour un Pod donné doit être provisionné soit par un [approvisionneur de PersistentVolume](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/persistent-volume-provisioning/README.md) basé sur un `storage class` donné, soit pré-provisionné par un admin.
|
||||
* Le stockage pour un Pod donné doit être provisionné soit par un [approvisionneur de PersistentVolume](https://github.com/kubernetes/examples/tree/master/staging/persistent-volume-provisioning/README.md) basé sur un `storage class` donné, soit pré-provisionné par un admin.
|
||||
* Supprimer et/ou réduire l'échelle d'un StatefulSet à zéro ne supprimera *pas* les volumes associés avec le StatefulSet. Ceci est fait pour garantir la sécurité des données, ce qui a généralement plus de valeur qu'une purge automatique de toutes les ressources relatives à un StatefulSet.
|
||||
* Les StatefulSets nécessitent actuellement un [Service Headless](/fr/docs/concepts/services-networking/service/#headless-services) qui est responsable de l'identité réseau des Pods. Vous êtes responsable de la création de ce Service.
|
||||
* Les StatefulSets ne fournissent aucune garantie de la terminaison des pods lorsqu'un StatefulSet est supprimé. Pour avoir une terminaison ordonnée et maîtrisée des pods du StatefulSet, il est possible de réduire l'échelle du StatefulSet à 0 avant de le supprimer.
|
||||
|
||||
@@ -147,7 +147,7 @@ La dernière version est **{{< latest-version >}}**, donc la branche de la relea
|
||||
|
||||
### Chaînes de sites en i18n/
|
||||
|
||||
Les localisations doivent inclure le contenu des éléments suivants [`i18n/en.toml`](https://github.com/kubernetes/website/blob/master/i18n/en.toml) dans un nouveau fichier spécifique à la langue.
|
||||
Les localisations doivent inclure le contenu des éléments suivants [`i18n/en.toml`](https://github.com/kubernetes/website/blob/main/i18n/en.toml) dans un nouveau fichier spécifique à la langue.
|
||||
Prenons l'allemand comme exemple : `i18n/de.toml`.
|
||||
|
||||
Ajouter un nouveau fichier de localisation dans `i18n/`. Par exemple, avec l'allemand (de) :
|
||||
@@ -230,5 +230,3 @@ Une fois qu'une traduction répond aux exigences de logistique et à une couvert
|
||||
|
||||
- Activer la sélection de la langue sur le site Web
|
||||
- Publier la disponibilité de la traduction via les canaux de la [Cloud Native Computing Foundation](https://www.cncf.io/), y compris sur le blog de [Kubernetes](https://kubernetes.io/blog/).
|
||||
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ Pour en savoir plus sur comment devenir un relecteur SIG Docs et sur les respons
|
||||
Lorsque vous remplissez les [conditions requises](https://github.com/kubernetes/community/blob/master/community-membership.md#reviewer), vous pouvez devenir un relecteur SIG Docs.
|
||||
Les relecteurs d'autres SIG doivent demander séparément le statut de relecteur dans le SIG Docs.
|
||||
|
||||
Pour postuler, ouvrez une pull request et ajoutez vous à la section `reviewers` du fichier [top-level OWNERS](https://github.com/kubernetes/website/blob/master/OWNERS) dans le dépôt `kubernetes/website`.
|
||||
Pour postuler, ouvrez une pull request et ajoutez vous à la section `reviewers` du fichier [top-level OWNERS](https://github.com/kubernetes/website/blob/main/OWNERS) dans le dépôt `kubernetes/website`.
|
||||
Affectez la PR à un ou plusieurs approbateurs SIG Docs.
|
||||
|
||||
Si votre pull request est approuvée, vous êtes maintenant un relecteur SIG Docs.
|
||||
@@ -130,7 +130,7 @@ Pour en savoir plus sur comment devenir un approbateur SIG Docs et sur les respo
|
||||
Lorsque vous remplissez les [conditions requises](https://github.com/kubernetes/community/blob/master/community-membership.md#approver), vous pouvez devenir un approbateur SIG Docs.
|
||||
Les approbateurs appartenant à d'autres SIG doivent demander séparément le statut d'approbateur dans SIG Docs.
|
||||
|
||||
Pour postuler, ouvrez une pull request pour vous ajouter à la section `approvers` du fichier [top-level OWNERS](https://github.com/kubernetes/website/blob/master/OWNERS) dans le dépot `kubernetes/website`.
|
||||
Pour postuler, ouvrez une pull request pour vous ajouter à la section `approvers` du fichier [top-level OWNERS](https://github.com/kubernetes/website/blob/main/OWNERS) dans le dépot `kubernetes/website`.
|
||||
Affectez la PR à un ou plusieurs approbateurs SIG Docs.
|
||||
|
||||
Si votre Pull Request est approuvée, vous êtes à présent approbateur SIG Docs.
|
||||
@@ -184,9 +184,9 @@ Le [dépôt du site web Kubernetes](https://github.com/kubernetes/website) utili
|
||||
- blunderbuss
|
||||
- approve
|
||||
|
||||
Ces deux plugins utilisent les fichiers [OWNERS](https://github.com/kubernetes/website/blob/master/OWNERS) et [OWNERS_ALIASES](https://github.com/kubernetes/website/blob/master/OWNERS_ALIASES) à la racine du dépôt Github `kubernetes/website` pour contrôler comment prow fonctionne.
|
||||
Ces deux plugins utilisent les fichiers [OWNERS](https://github.com/kubernetes/website/blob/main/OWNERS) et [OWNERS_ALIASES](https://github.com/kubernetes/website/blob/main/OWNERS_ALIASES) à la racine du dépôt Github `kubernetes/website` pour contrôler comment prow fonctionne.
|
||||
|
||||
Un fichier [OWNERS](https://github.com/kubernetes/website/blob/master/OWNERS) contient une liste de personnes qui sont des relecteurs et des approbateurs SIG Docs.
|
||||
Un fichier [OWNERS](https://github.com/kubernetes/website/blob/main/OWNERS) contient une liste de personnes qui sont des relecteurs et des approbateurs SIG Docs.
|
||||
Les fichiers OWNERS existent aussi dans les sous-dossiers, et peuvent ignorer qui peut agir en tant que relecteur ou approbateur des fichiers de ce sous-répertoire et de ses descendants.
|
||||
Pour plus d'informations sur les fichiers OWNERS en général, voir [OWNERS](https://github.com/kubernetes/community/blob/master/contributors/guide/owners.md).
|
||||
|
||||
@@ -203,5 +203,3 @@ Pour plus d'informations sur la contribution à la documentation Kubernetes, voi
|
||||
|
||||
- [Commencez à contribuer](/docs/contribute/start/)
|
||||
- [Documentation style](/docs/contribute/style/)
|
||||
|
||||
|
||||
|
||||
@@ -29,6 +29,6 @@ cd kubernetes
|
||||
make release
|
||||
```
|
||||
|
||||
Pour plus de détails sur le processus de release, voir le repertoire [`build`](http://releases.k8s.io/{{< param "githubbranch" >}}/build/) dans kubernetes/kubernetes.
|
||||
Pour plus de détails sur le processus de release, voir le repertoire [`build`](http://releases.k8s.io/master/build/) dans kubernetes/kubernetes.
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Vous devez disposer d'un cluster Kubernetes et l'outil de ligne de commande kubectl doit être configuré pour communiquer avec votre cluster.
|
||||
Si vous ne possédez pas déjà de cluster, vous pouvez en créer un en utilisant [Minikube](/docs/setup/minikube), ou vous pouvez utiliser l'un de ces environnements Kubernetes:
|
||||
|
||||
* [Katacoda](https://www.katacoda.com/courses/kubernetes/playground)
|
||||
* [Killercoda](https://killercoda.com/playgrounds/scenario/kubernetes)
|
||||
* [Play with Kubernetes](http://labs.play-with-k8s.com/)
|
||||
|
||||
@@ -125,7 +125,7 @@ TLS経由のアクセスのみ | コードがTCP通信を必要とする場合
|
||||
関連するKubernetesセキュリティについて学びます。
|
||||
|
||||
* [Podセキュリティの標準](/ja/docs/concepts/security/pod-security-standards/)
|
||||
* [Podのネットワークポリシー]](/ja/docs/concepts/services-networking/network-policies/)
|
||||
* [Podのネットワークポリシー](/ja/docs/concepts/services-networking/network-policies/)
|
||||
* [Kubernetes APIへのアクセスを制御する](/docs/concepts/security/controlling-access)
|
||||
* [クラスターの保護](/docs/tasks/administer-cluster/securing-a-cluster/)
|
||||
* コントロールプレーンとの[通信時のデータ暗号化](/docs/tasks/tls/managing-tls-in-a-cluster/)
|
||||
|
||||
@@ -13,4 +13,4 @@ tags:
|
||||
Kubernetesクラスターで稼働するアプリケーションが、クラウドプロバイダーによって提供されるデータストアサービスのように、外部のマネージドソフトウェアを容易に使えるようにするための拡張APIです。
|
||||
|
||||
<!--more-->
|
||||
サービスカタログを使用することで{{< glossary_tooltip text="サービスブローカー" term_id="service-broker" >}}が提供する{{< glossary_tooltip text="マネージドサービス" term_id="managed-service" >}}を、それらのサービスがどのように作成されるか、また管理されるかについての知識を無しに、一覧表示したり、プロビジョニングや使用をすることができます。
|
||||
サービスカタログを使用することで、提供されている{{< glossary_tooltip text="マネージドサービス" term_id="managed-service" >}}を、それらのサービスがどのように作成されるか、また管理されるかについての知識を無しに、一覧表示したり、プロビジョニングや使用をすることができます。
|
||||
|
||||
@@ -59,7 +59,7 @@ reviewers:
|
||||
|
||||
## コンフィギュレーションを上書きします
|
||||
|
||||
`Node Problem Detector`の Dockerイメージをビルドする際に、[default configuration(https://github.com/kubernetes/node-problem-detector/tree/v0.1/config)が埋め込まれます。
|
||||
`Node Problem Detector`の Dockerイメージをビルドする際に、[default configuration](https://github.com/kubernetes/node-problem-detector/tree/v0.1/config)が埋め込まれます。
|
||||
|
||||
[`ConfigMap`](/ja/docs/tasks/configure-pod-container/configure-pod-configmap/) を使用することで設定を上書きすることができます。
|
||||
|
||||
|
||||
@@ -4,15 +4,14 @@ metadata:
|
||||
name: mysql
|
||||
labels:
|
||||
app: mysql
|
||||
app.kubernetes.io/name: mysql
|
||||
data:
|
||||
primary.cnf: |
|
||||
# Apply this config only on the primary.
|
||||
[mysqld]
|
||||
log-bin
|
||||
datadir=/var/lib/mysql/mysql
|
||||
replica.cnf: |
|
||||
# Apply this config only on replicas.
|
||||
[mysqld]
|
||||
super-read-only
|
||||
datadir=/var/lib/mysql/mysql
|
||||
|
||||
|
||||
@@ -15,159 +15,182 @@ weight: 20
|
||||
{{< glossary_tooltip text="파드" term_id="pod" >}}를 제한할 수 있다.
|
||||
이를 수행하는 방법에는 여러 가지가 있으며 권장되는 접근 방식은 모두
|
||||
[레이블 셀렉터](/ko/docs/concepts/overview/working-with-objects/labels/)를 사용하여 선택을 용이하게 한다.
|
||||
보통 스케줄러가 자동으로 합리적인 배치(예: 자원이 부족한 노드에 파드를 배치하지 않도록
|
||||
노드 간에 파드를 분배하는 등)를 수행하기에 이러한 제약 조건은 필요하지 않지만
|
||||
간혹 파드가 배포될 노드를 제어해야 하는 경우가 있다.
|
||||
예를 들어 SSD가 장착된 머신에 파드가 배포되도록 하거나 또는 많은 통신을 하는 두 개의 서로 다른 서비스의 파드를
|
||||
동일한 가용성 영역(availability zone)에 배치할 수 있다.
|
||||
|
||||
보통은 스케줄러가 자동으로 합리적인 배치(예: 자원이 부족한 노드에 파드를 배치하지 않도록
|
||||
노드 간에 파드를 분배)를 수행하기에 이러한 제약 조건은 필요하지 않다.
|
||||
그러나, 예를 들어 SSD가 장착된 머신에 파드가 배포되도록 하거나 또는
|
||||
많은 통신을 하는 두 개의 서로 다른 서비스의 파드를 동일한 가용성 영역(availability zone)에 배치하는 경우와 같이,
|
||||
파드가 어느 노드에 배포될지를 제어해야 하는 경우도 있다.
|
||||
|
||||
<!-- body -->
|
||||
|
||||
## 노드 셀렉터(nodeSelector)
|
||||
쿠버네티스가 특정 파드를 어느 노드에 스케줄링할지 고르는
|
||||
다음의 방법 중 하나를 골라 사용할 수 있다.
|
||||
|
||||
`nodeSelector` 는 가장 간단하고 권장되는 노드 선택 제약 조건의 형태이다.
|
||||
`nodeSelector` 는 PodSpec의 필드이다. 이는 키-값 쌍의 매핑으로 지정한다. 파드가 노드에서 동작할 수 있으려면,
|
||||
노드는 키-값의 쌍으로 표시되는 레이블을 각자 가지고 있어야 한다(이는 추가 레이블을 가지고 있을 수 있다).
|
||||
일반적으로 하나의 키-값 쌍이 사용된다.
|
||||
* [노드 레이블](#built-in-node-labels)에 매칭되는 [nodeSelector](#nodeselector) 필드
|
||||
* [어피니티 / 안티 어피니티](#affinity-and-anti-affinity)
|
||||
* [nodeName](#nodename) 필드
|
||||
|
||||
`nodeSelector` 를 어떻게 사용하는지 예시를 통해 알아보도록 하자.
|
||||
## 노드 레이블 {#built-in-node-labels}
|
||||
|
||||
### 0 단계: 사전 준비
|
||||
다른 쿠버네티스 오브젝트와 마찬가지로, 노드도 [레이블](/ko/docs/concepts/overview/working-with-objects/labels/)을 가진다.
|
||||
[레이블을 수동으로 추가](/ko/docs/tasks/configure-pod-container/assign-pods-nodes/#노드에-레이블-추가)할 수 있다.
|
||||
또한 쿠버네티스도 클러스터의 모든 노드에 표준화된 레이블 집합을 적용한다.
|
||||
[잘 알려진 레이블, 어노테이션, 테인트](/ko/docs/reference/labels-annotations-taints/)에서 널리 사용되는 노드 레이블의 목록을 확인한다.
|
||||
|
||||
이 예시는 쿠버네티스 파드에 대한 기본적인 이해를 하고 있고 [쿠버네티스 클러스터가 설정](/ko/docs/setup/)되어 있다고 가정한다.
|
||||
{{<note>}}
|
||||
이러한 레이블에 대한 값은 클라우드 제공자별로 다르며 정확하지 않을 수 있다.
|
||||
예를 들어, `kubernetes.io/hostname`에 대한 값은 특정 환경에서는 노드 이름과 동일할 수 있지만
|
||||
다른 환경에서는 다른 값일 수도 있다.
|
||||
{{</note>}}
|
||||
|
||||
### 1 단계: 노드에 레이블 붙이기
|
||||
### 노드 격리/제한 {#node-isolation-restriction}
|
||||
|
||||
`kubectl get nodes` 를 실행해서 클러스터 노드 이름을 가져온다. 이 중에 레이블을 추가하기 원하는 것 하나를 선택한 다음에 `kubectl label nodes <노드 이름> <레이블 키>=<레이블 값>` 을 실행해서 선택한 노드에 레이블을 추가한다. 예를 들어 노드의 이름이 'kubernetes-foo-node-1.c.a-robinson.internal' 이고, 원하는 레이블이 'disktype=ssd' 라면, `kubectl label nodes kubernetes-foo-node-1.c.a-robinson.internal disktype=ssd` 를 실행한다.
|
||||
노드에 레이블을 추가하여
|
||||
파드를 특정 노드 또는 노드 그룹에 스케줄링되도록 지정할 수 있다.
|
||||
이 기능을 사용하여 특정 파드가 특정 격리/보안/규제 속성을 만족하는 노드에서만
|
||||
실행되도록 할 수 있다.
|
||||
|
||||
`kubectl get nodes --show-labels` 를 다시 실행해서 노드가 현재 가진 레이블을 확인하여, 이 작업을 검증할 수 있다. 또한 `kubectl describe node "노드 이름"` 을 사용해서 노드에 주어진 레이블의 전체 목록을 확인할 수 있다.
|
||||
노드 격리를 위해 레이블을 사용할 때, {{<glossary_tooltip text="kubelet" term_id="kubelet">}}이 변경할 수 없는 레이블 키를 선택한다.
|
||||
그렇지 않으면 kubelet이 해당 레이블을 변경하여 노드가 사용 불가능(compromised) 상태로 빠지고
|
||||
스케줄러가 이 노드에 워크로드를 스케줄링하는 일이 발생할 수 있다.
|
||||
|
||||
### 2 단계: 파드 설정에 nodeSelector 필드 추가하기
|
||||
[`NodeRestriction` 어드미션 플러그인](/docs/reference/access-authn-authz/admission-controllers/#noderestriction)은
|
||||
kubelet이 `node-restriction.kubernetes.io/` 접두사를 갖는 레이블을
|
||||
설정하거나 변경하지 못하도록 한다.
|
||||
|
||||
실행하고자 하는 파드의 설정 파일을 가져오고, 이처럼 nodeSelector 섹션을 추가한다. 예를 들어 이것이 파드 설정이라면,
|
||||
노드 격리를 위해 레이블 접두사를 사용하려면,
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: nginx
|
||||
labels:
|
||||
env: test
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx
|
||||
```
|
||||
1. [노드 인가자(authorizer)](/docs/reference/access-authn-authz/node/)를 사용하고 있는지, 그리고 `NodeRestriction` 어드미션 플러그인을 **활성화** 했는지 확인한다.
|
||||
1. 노드에 `node-restriction.kubernetes.io/` 접두사를 갖는 레이블을 추가하고, [노드 셀렉터](#nodeselector)에서 해당 레이블을 사용한다.
|
||||
예: `example.com.node-restriction.kubernetes.io/fips=true` 또는 `example.com.node-restriction.kubernetes.io/pci-dss=true`
|
||||
|
||||
이 다음에 nodeSelector 를 다음과 같이 추가한다.
|
||||
## 노드셀렉터(nodeSelector) {#nodeselector}
|
||||
|
||||
{{< codenew file="pods/pod-nginx.yaml" >}}
|
||||
`nodeSelector`는 노드 선택 제약사항의 가장 간단하면서도 추천하는 형태이다.
|
||||
파드 스펙에 `nodeSelector` 필드를 추가하고,
|
||||
타겟으로 삼고 싶은 노드가 갖고 있는 [노드 레이블](#built-in-node-labels)을 명시한다.
|
||||
쿠버네티스는 사용자가 명시한 레이블을 갖고 있는 노드에만
|
||||
파드를 스케줄링한다.
|
||||
|
||||
그런 다음에 `kubectl apply -f https://k8s.io/examples/pods/pod-nginx.yaml` 을
|
||||
실행하면, 레이블이 붙여진 노드에 파드가 스케줄된다.
|
||||
`kubectl get pods -o wide` 를 실행해서 파드가 할당된
|
||||
"NODE" 를 보면 작동하는지 검증할 수 있다.
|
||||
[노드에 파드 할당](/ko/docs/tasks/configure-pod-container/assign-pods-nodes)에서
|
||||
더 많은 정보를 확인한다.
|
||||
|
||||
## 넘어가기 전에: 내장 노드 레이블들 {#built-in-node-labels}
|
||||
## 어피니티(affinity)와 안티-어피니티(anti-affinity) {#affinity-and-anti-affinity}
|
||||
|
||||
[붙인](#1-단계-노드에-레이블-붙이기) 레이블뿐만 아니라, 노드에는
|
||||
표준 레이블 셋이 미리 채워져 있다. 이들 목록은 [잘 알려진 레이블, 어노테이션 및 테인트](/ko/docs/reference/labels-annotations-taints/)를 참고한다.
|
||||
`nodeSelector` 는 파드를 특정 레이블이 있는 노드로 제한하는 가장 간단한 방법이다.
|
||||
어피니티/안티-어피니티 기능은 표현할 수 있는 제약 종류를 크게 확장한다.
|
||||
주요 개선 사항은 다음과 같다.
|
||||
|
||||
{{< note >}}
|
||||
이 레이블들의 값은 클라우드 공급자에 따라 다르고 신뢰성이 보장되지 않는다.
|
||||
예를 들어 `kubernetes.io/hostname` 은 어떤 환경에서는 노드 이름과 같지만,
|
||||
다른 환경에서는 다른 값일 수 있다.
|
||||
{{< /note >}}
|
||||
* 어피니티/안티-어피니티 언어가 더 표현적이다.
|
||||
`nodeSelector`로는 명시한 레이블이 있는 노드만 선택할 수 있다.
|
||||
어피니티/안티-어피니티는 선택 로직에 대한 좀 더 많은 제어권을 제공한다.
|
||||
* 규칙이 "소프트(soft)" 또는 "선호사항(preference)" 임을 나타낼 수 있으며,
|
||||
이 덕분에 스케줄러는 매치되는 노드를 찾지 못한 경우에도 파드를 스케줄링할 수 있다.
|
||||
* 다른 노드 (또는 다른 토폴로지 도메인)에서 실행 중인
|
||||
다른 파드의 레이블을 사용하여 파드를 제한할 수 있으며,
|
||||
이를 통해 어떤 파드들이 노드에 함께 위치할 수 있는지에 대한 규칙을 정의할 수 있다.
|
||||
|
||||
## 노드 격리(isolation)/제한(restriction)
|
||||
어피니티 기능은 다음의 두 가지 종류로 구성된다.
|
||||
|
||||
노드 오브젝트에 레이블을 추가하면 파드가 특정 노드 또는 노드 그룹을 목표 대상으로 할 수 있게 된다.
|
||||
이는 특정 파드가 어떤 격리, 보안, 또는 규제 속성이 있는 노드에서만 실행되도록 사용할 수 있다.
|
||||
이 목적으로 레이블을 사용하는 경우, 노드에서 kubelet 프로세스로 수정할 수 없는 레이블 키를 선택하는 것을 권장한다.
|
||||
이렇게 하면 손상된 노드가 해당 kubelet 자격 증명을 사용해서 해당 레이블을 자체 노드 오브젝트에 설정하고,
|
||||
스케줄러가 손상된 노드로 워크로드를 스케줄 하는 것을 방지할 수 있다.
|
||||
* *노드 어피니티* 기능은 `nodeSelector` 필드와 비슷하지만
|
||||
더 표현적이고 소프트(soft) 규칙을 지정할 수 있게 해 준다.
|
||||
* *파드 간 어피니티/안티-어피니티* 는 다른 파드의 레이블을 이용하여
|
||||
해당 파드를 제한할 수 있게 해 준다.
|
||||
|
||||
`NodeRestriction` 어드미션 플러그인은 kubelet이 `node-restriction.kubernetes.io/` 접두사로 레이블을 설정 또는 수정하지 못하게 한다.
|
||||
노드 격리에 해당 레이블 접두사를 사용하려면 다음과 같이 한다.
|
||||
### 노드 어피니티 {#node-affinity}
|
||||
|
||||
1. [노드 권한부여자](/docs/reference/access-authn-authz/node/)를 사용하고 있고, [NodeRestriction 어드미션 플러그인](/docs/reference/access-authn-authz/admission-controllers/#noderestriction)을 _활성화_ 해야 한다.
|
||||
2. 노드 오브젝트의 `node-restriction.kubernetes.io/` 접두사 아래에 레이블을 추가하고, 해당 레이블을 노드 셀렉터에서 사용한다.
|
||||
예를 들어, `example.com.node-restriction.kubernetes.io/fips=true` 또는 `example.com.node-restriction.kubernetes.io/pci-dss=true` 이다.
|
||||
노드 어피니티는 개념적으로 `nodeSelector` 와 비슷하며,
|
||||
노드의 레이블을 기반으로 파드가 스케줄링될 수 있는 노드를 제한할 수 있다.
|
||||
노드 어피니티에는 다음의 두 종류가 있다.
|
||||
|
||||
## 어피니티(affinity)와 안티-어피니티(anti-affinity)
|
||||
* `requiredDuringSchedulingIgnoredDuringExecution`:
|
||||
규칙이 만족되지 않으면 스케줄러가 파드를 스케줄링할 수 없다.
|
||||
이 기능은 `nodeSelector`와 유사하지만, 좀 더 표현적인 문법을 제공한다.
|
||||
* `preferredDuringSchedulingIgnoredDuringExecution`:
|
||||
스케줄러는 조건을 만족하는 노드를 찾으려고 노력한다.
|
||||
해당되는 노드가 없더라도, 스케줄러는 여전히 파드를 스케줄링한다.
|
||||
|
||||
`nodeSelector` 는 파드를 특정 레이블이 있는 노드로 제한하는 매우 간단한 방법을 제공한다.
|
||||
어피니티/안티-어피니티 기능은 표현할 수 있는 제약 종류를 크게 확장한다. 주요 개선 사항은 다음과 같다.
|
||||
{{<note>}}
|
||||
앞의 두 유형에서, `IgnoredDuringExecution`는
|
||||
쿠버네티스가 파드를 스케줄링한 뒤에 노드 레이블이 변경되어도 파드는 계속 해당 노드에서 실행됨을 의미한다.
|
||||
{{</note>}}
|
||||
|
||||
1. 어피니티/안티-어피니티 언어가 더 표현적이다. 언어는 논리 연산자인 AND 연산으로 작성된
|
||||
정확한 매칭 항목 이외에 더 많은 매칭 규칙을 제공한다.
|
||||
2. 규칙이 엄격한 요구 사항이 아니라 "유연한(soft)"/"선호(preference)" 규칙을 나타낼 수 있기에 스케줄러가 규칙을 만족할 수 없더라도,
|
||||
파드가 계속 스케줄되도록 한다.
|
||||
3. 노드 자체에 레이블을 붙이기보다는 노드(또는 다른 토폴로지 도메인)에서 실행 중인 다른 파드의 레이블을 제한할 수 있다.
|
||||
이를 통해 어떤 파드가 함께 위치할 수 있는지와 없는지에 대한 규칙을 적용할 수 있다.
|
||||
파드 스펙의 `.spec.affinity.nodeAffinity` 필드에
|
||||
노드 어피니티를 명시할 수 있다.
|
||||
|
||||
어피니티 기능은 "노드 어피니티" 와 "파드 간 어피니티/안티-어피니티" 두 종류의 어피니티로 구성된다.
|
||||
노드 어피니티는 기존 `nodeSelector` 와 비슷하지만(그러나 위에서 나열된 첫째와 두 번째 이점이 있다.),
|
||||
파드 간 어피니티/안티-어피니티는 위에서 나열된 세번째 항목에 설명된 대로
|
||||
노드 레이블이 아닌 파드 레이블에 대해 제한되고 위에서 나열된 첫 번째와 두 번째 속성을 가진다.
|
||||
|
||||
### 노드 어피니티
|
||||
|
||||
노드 어피니티는 개념적으로 `nodeSelector` 와 비슷하다 -- 이는 노드의 레이블을 기반으로 파드를
|
||||
스케줄할 수 있는 노드를 제한할 수 있다.
|
||||
|
||||
여기에 현재 `requiredDuringSchedulingIgnoredDuringExecution` 와 `preferredDuringSchedulingIgnoredDuringExecution` 로 부르는
|
||||
두 가지 종류의 노드 어피니티가 있다. 전자는 파드가 노드에 스케줄되도록 *반드시*
|
||||
규칙을 만족해야 하는 것(`nodeSelector` 와 비슷하나 보다 표현적인 구문을 사용해서)을 지정하고,
|
||||
후자는 스케줄러가 시도하려고는 하지만, 보증하지 않는 *선호(preferences)* 를 지정한다는 점에서
|
||||
이를 각각 "엄격함(hard)" 과 "유연함(soft)" 으로 생각할 수 있다.
|
||||
이름의 "IgnoredDuringExecution" 부분은 `nodeSelector` 작동 방식과 유사하게 노드의
|
||||
레이블이 런타임 중에 변경되어 파드의 어피니티 규칙이 더 이상 충족되지 않으면 파드가 그 노드에서
|
||||
동작한다는 의미이다. 향후에는 파드의 노드 어피니티 요구 사항을 충족하지 않는 노드에서 파드를 제거한다는
|
||||
점을 제외하고는 `requiredDuringSchedulingIgnoredDuringExecution` 와 동일한 `requiredDuringSchedulingRequiredDuringExecution` 를 제공할 계획이다.
|
||||
|
||||
따라서 `requiredDuringSchedulingIgnoredDuringExecution` 의 예로는 "인텔 CPU가 있는 노드에서만 파드 실행"이
|
||||
될 수 있고, `preferredDuringSchedulingIgnoredDuringExecution` 의 예로는 "장애 조치 영역 XYZ에 파드 집합을 실행하려고
|
||||
하지만, 불가능하다면 다른 곳에서 일부를 실행하도록 허용"이 있을 것이다.
|
||||
|
||||
노드 어피니티는 PodSpec의 `affinity` 필드의 `nodeAffinity` 필드에서 지정된다.
|
||||
|
||||
여기에 노드 어피니티를 사용하는 파드 예시가 있다.
|
||||
예를 들어, 다음과 같은 파드 스펙이 있다고 하자.
|
||||
|
||||
{{< codenew file="pods/pod-with-node-affinity.yaml" >}}
|
||||
|
||||
이 노드 어피니티 규칙은 키가 `kubernetes.io/e2e-az-name` 이고 값이 `e2e-az1` 또는 `e2e-az2` 인
|
||||
레이블이 있는 노드에만 파드를 배치할 수 있다고 말한다. 또한, 이 기준을 충족하는 노드들
|
||||
중에서 키가 `another-node-label-key` 이고 값이 `another-node-label-value` 인 레이블이 있는 노드를
|
||||
선호하도록 한다.
|
||||
이 예시에서는 다음의 규칙이 적용된다.
|
||||
|
||||
예시에서 연산자 `In` 이 사용되고 있는 것을 볼 수 있다. 새로운 노드 어피니티 구문은 다음의 연산자들을 지원한다. `In`, `NotIn`, `Exists`, `DoesNotExist`, `Gt`, `Lt`.
|
||||
`NotIn` 과 `DoesNotExist` 를 사용해서 안티-어피니티를 수행하거나,
|
||||
특정 노드에서 파드를 쫓아내는 [노드 테인트(taint)](/ko/docs/concepts/scheduling-eviction/taint-and-toleration/)를 설정할 수 있다.
|
||||
* 노드는 키가 `kubernetes.io/os`이고 값이 `linux`인 레이블을
|
||||
갖고 *있어야 한다* .
|
||||
* 키가 `another-node-label-key`이고 값이 `another-node-label-value`인 레이블을
|
||||
갖고 있는 노드를 *선호한다* .
|
||||
|
||||
`nodeSelector` 와 `nodeAffinity` 를 모두 지정한다면 파드가 후보 노드에 스케줄되기 위해서는
|
||||
*둘 다* 반드시 만족해야 한다.
|
||||
`operator` 필드를 사용하여
|
||||
쿠버네티스가 규칙을 해석할 때 사용할 논리 연산자를 지정할 수 있다.
|
||||
`In`, `NotIn`, `Exists`, `DoesNotExist`, `Gt` 및 `Lt` 연산자를 사용할 수 있다.
|
||||
|
||||
`nodeAffinity` 유형과 연관된 `nodeSelectorTerms` 를 지정하면, `nodeSelectorTerms` 중 **하나라도** 만족시키는 노드에 파드가 스케줄된다.
|
||||
`NotIn` 및 `DoesNotExist` 연산자를 사용하여 노드 안티-어피니티 규칙을 정의할 수 있다.
|
||||
또는, 특정 노드에서 파드를 쫓아내는
|
||||
[노드 테인트(taint)](/ko/docs/concepts/scheduling-eviction/taint-and-toleration/)를 설정할 수 있다.
|
||||
|
||||
`nodeSelectorTerms` 와 연관된 여러 `matchExpressions` 를 지정하면, 파드는 `matchExpressions` 를 **모두** 만족하는 노드에만 스케줄된다.
|
||||
{{<note>}}
|
||||
`nodeSelector`와 `nodeAffinity`를 모두 사용하는 경우,
|
||||
파드가 노드에 스케줄링되려면 두 조건 *모두* 만족되어야 한다.
|
||||
|
||||
파드가 스케줄된 노드의 레이블을 지우거나 변경해도 파드는 제거되지 않는다. 다시 말해서 어피니티 선택은 파드를 스케줄링 하는 시점에만 작동한다.
|
||||
`nodeAffinity`에 연결된 `nodeSelectorTerms`를 여러 개 명시한 경우,
|
||||
명시된 `nodeSelectorTerms` 중 하나를 만족하는 노드에도
|
||||
파드가 스케줄링될 수 있다.
|
||||
|
||||
`preferredDuringSchedulingIgnoredDuringExecution` 의 `weight` 필드의 범위는 1-100이다. 모든 스케줄링 요구 사항 (리소스 요청, RequiredDuringScheduling 어피니티 표현식 등)을 만족하는 각 노드들에 대해 스케줄러는 이 필드의 요소들을 반복해서 합계를 계산하고 노드가 MatchExpressions 에 일치하는 경우 합계에 "가중치(weight)"를 추가한다. 이후에 이 점수는 노드에 대한 다른 우선순위 함수의 점수와 합쳐진다. 전체 점수가 가장 높은 노드를 가장 선호한다.
|
||||
단일 `nodeSelectorTerms`와 연결된 `matchExpressions`를 여러 개 명시한 경우,
|
||||
모든 `matchExpressions`를 만족하는 노드에만
|
||||
파드가 스케줄링될 수 있다.
|
||||
{{</note>}}
|
||||
|
||||
#### 스케줄링 프로파일당 노드 어피니티
|
||||
[노드 어피니티를 사용해 노드에 파드 할당](/ko/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/)에서
|
||||
더 많은 정보를 확인한다.
|
||||
|
||||
#### 노드 어피니티 가중치(weight) {#node-affinity-weight}
|
||||
|
||||
각 `preferredDuringSchedulingIgnoredDuringExecution` 어피니티 타입 인스턴스에 대해
|
||||
1-100 범위의 `weight`를 명시할 수 있다.
|
||||
스케줄러가 다른 모든 파드 스케줄링 요구 사항을 만족하는 노드를 찾으면,
|
||||
스케줄러는 노드가 만족한 모든 선호하는(preferred) 규칙에 대해
|
||||
합계 계산을 위한 `weight` 값을 각각 추가한다.
|
||||
|
||||
최종 합계는 해당 노드에 대한 다른 우선 순위 함수 점수에 더해진다.
|
||||
스케줄러가 파드에 대한 스케줄링 판단을 할 때,
|
||||
총 점수가 가장 높은 노드가 우선 순위를 갖는다.
|
||||
|
||||
예를 들어, 다음과 같은 파드 스펙이 있다고 하자.
|
||||
|
||||
{{< codenew file="pods/pod-with-affinity-anti-affinity.yaml" >}}
|
||||
|
||||
`requiredDuringSchedulingIgnoredDuringExecution` 규칙을 만족하는 노드가 2개 있고,
|
||||
하나에는 `label-1:key-1` 레이블이 있고 다른 하나에는 `label-2:key-2` 레이블이 있으면,
|
||||
스케줄러는 각 노드의 `weight`를 확인한 뒤
|
||||
해당 노드에 대한 다른 점수에 가중치를 더하고,
|
||||
최종 점수가 가장 높은 노드에 해당 파드를 스케줄링한다.
|
||||
|
||||
{{<note>}}
|
||||
이 예시에서 쿠버네티스가 정상적으로 파드를 스케줄링하려면,
|
||||
보유하고 있는 노드에 `kubernetes.io/os=linux` 레이블이 있어야 한다.
|
||||
{{</note>}}
|
||||
|
||||
#### 스케줄링 프로파일당 노드 어피니티 {#node-affinity-per-scheduling-profile}
|
||||
|
||||
{{< feature-state for_k8s_version="v1.20" state="beta" >}}
|
||||
|
||||
여러 [스케줄링 프로파일](/ko/docs/reference/scheduling/config/#여러-프로파일)을 구성할 때
|
||||
노드 어피니티가 있는 프로파일을 연결할 수 있는데, 이는 프로파일이 특정 노드 집합에만 적용되는 경우 유용하다.
|
||||
이렇게 하려면 [스케줄러 구성](/ko/docs/reference/scheduling/config/)에 있는
|
||||
[`NodeAffinity` 플러그인](/ko/docs/reference/scheduling/config/#스케줄링-플러그인-1)의 인수에 `addedAffinity`를 추가한다. 예를 들면
|
||||
이렇게 하려면 다음과 같이 [스케줄러 구성](/ko/docs/reference/scheduling/config/)에 있는
|
||||
[`NodeAffinity` 플러그인](/ko/docs/reference/scheduling/config/#스케줄링-플러그인-1)의 `args` 필드에 `addedAffinity`를 추가한다.
|
||||
|
||||
```yaml
|
||||
apiVersion: kubescheduler.config.k8s.io/v1beta1
|
||||
apiVersion: kubescheduler.config.k8s.io/v1beta3
|
||||
kind: KubeSchedulerConfiguration
|
||||
|
||||
profiles:
|
||||
@@ -188,29 +211,41 @@ profiles:
|
||||
|
||||
`addedAffinity`는 `.spec.schedulerName`을 `foo-scheduler`로 설정하는 모든 파드에 적용되며
|
||||
PodSpec에 지정된 NodeAffinity도 적용된다.
|
||||
즉, 파드를 매칭시키려면, 노드가 `addedAffinity`와 파드의 `.spec.NodeAffinity`를 충족해야 한다.
|
||||
즉, 파드를 매칭시키려면, 노드가 `addedAffinity`와
|
||||
파드의 `.spec.NodeAffinity`를 충족해야 한다.
|
||||
|
||||
`addedAffinity`는 엔드 유저에게 표시되지 않으므로, 예상치 못한 동작이 일어날 수 있다. 프로파일의
|
||||
스케줄러 이름과 명확한 상관 관계가 있는 노드 레이블을 사용하는 것이 좋다.
|
||||
`addedAffinity`는 엔드 유저에게 표시되지 않으므로,
|
||||
예상치 못한 동작이 일어날 수 있다.
|
||||
스케줄러 프로파일 이름과 명확한 상관 관계가 있는 노드 레이블을 사용한다.
|
||||
|
||||
{{< note >}}
|
||||
[데몬셋용 파드를 생성](/ko/docs/concepts/workloads/controllers/daemonset/#기본-스케줄러로-스케줄)하는 데몬셋 컨트롤러는
|
||||
스케줄링 프로파일을 인식하지 못한다.
|
||||
따라서 `addedAffinity`없이 `default-scheduler`와 같은 스케줄러 프로파일을 유지하는 것이 좋다. 그런 다음 데몬셋의 파드 템플릿이 스케줄러 이름을 사용해야 한다.
|
||||
그렇지 않으면, 데몬셋 컨트롤러에 의해 생성된 일부 파드가 스케줄되지 않은 상태로 유지될 수 있다.
|
||||
[데몬셋 파드를 생성](/ko/docs/concepts/workloads/controllers/daemonset/#기본-스케줄러로-스케줄)하는 데몬셋 컨트롤러는
|
||||
스케줄링 프로파일을 지원하지 않는다.
|
||||
데몬셋 컨트롤러가 파드를 생성할 때, 기본 쿠버네티스 스케줄러는 해당 파드를 배치하고
|
||||
데몬셋 컨트롤러의 모든 `nodeAffinity` 규칙을 준수한다.
|
||||
{{< /note >}}
|
||||
|
||||
### 파드간 어피니티와 안티-어피니티
|
||||
### 파드간 어피니티와 안티-어피니티 {#inter-pod-affinity-and-anti-affinity}
|
||||
|
||||
파드간 어피니티와 안티-어피니티를 사용하면 노드의 레이블을 기반으로 하지 않고, *노드에서 이미 실행 중인 파드 레이블을 기반으로*
|
||||
파드가 스케줄될 수 있는 노드를 제한할 수 있다. 규칙은 "X가 규칙 Y를 충족하는 하나 이상의 파드를 이미 실행중인 경우
|
||||
이 파드는 X에서 실행해야 한다(또는 안티-어피니티가 없는 경우에는 동작하면 안된다)"는 형태이다. Y는
|
||||
선택적으로 연관된 네임스페이스 목록을 가진 LabelSelector로 표현된다. 노드와는 다르게 파드는 네임스페이스이기에
|
||||
(그리고 따라서 파드의 레이블은 암암리에 네임스페이스이다) 파드 레이블위의 레이블 셀렉터는 반드시
|
||||
셀렉터가 적용될 네임스페이스를 지정해야만 한다. 개념적으로 X는 노드, 랙,
|
||||
클라우드 공급자 영역, 클라우드 공급자 지역 등과 같은 토폴로지 도메인이다. 시스템이 이런 토폴로지
|
||||
도메인을 나타내는 데 사용하는 노드 레이블 키인 `topologyKey` 를 사용하여 이를 표현한다.
|
||||
예: [넘어가기 전에: 빌트인 노드 레이블](#built-in-node-labels) 섹션 위에 나열된 레이블 키를 본다.
|
||||
파드간 어피니티와 안티-어피니티를 사용하여,
|
||||
노드 레이블 대신, 각 노드에 이미 실행 중인 다른 **파드** 의 레이블을 기반으로
|
||||
파드가 스케줄링될 노드를 제한할 수 있다.
|
||||
|
||||
파드간 어피니티와 안티-어피니티 규칙은
|
||||
"X가 규칙 Y를 충족하는 하나 이상의 파드를 이미 실행중인 경우 이 파드는 X에서 실행해야 한다(또는
|
||||
안티-어피니티의 경우에는 "실행하면 안 된다")"의 형태이며,
|
||||
여기서 X는 노드, 랙, 클라우드 제공자 존 또는 리전 등이며
|
||||
Y는 쿠버네티스가 충족할 규칙이다.
|
||||
|
||||
이러한 규칙(Y)은 [레이블 셀렉터](/ko/docs/concepts/overview/working-with-objects/labels/#레이블-셀렉터) 형태로 작성하며,
|
||||
연관된 네임스페이스 목록을 선택적으로 명시할 수도 있다.
|
||||
쿠버네티스에서 파드는 네임스페이스에 속하는(namespaced) 오브젝트이므로,
|
||||
파드 레이블도 암묵적으로 특정 네임스페이스에 속하게 된다.
|
||||
파드 레이블에 대한 모든 레이블 셀렉터는 쿠버네티스가 해당 레이블을 어떤 네임스페이스에서 탐색할지를 명시해야 한다.
|
||||
|
||||
`topologyKey`를 사용하여 토폴로지 도메인(X)를 나타낼 수 있으며,
|
||||
이는 시스템이 도메인을 표시하기 위해 사용하는 노드 레이블의 키이다.
|
||||
이에 대한 예시는 [잘 알려진 레이블, 어노테이션, 테인트](/ko/docs/reference/labels-annotations-taints/)를 참고한다.
|
||||
|
||||
{{< note >}}
|
||||
파드간 어피니티와 안티-어피니티에는 상당한 양의 프로세싱이 필요하기에
|
||||
@@ -219,80 +254,100 @@ PodSpec에 지정된 NodeAffinity도 적용된다.
|
||||
{{< /note >}}
|
||||
|
||||
{{< note >}}
|
||||
파드 안티-어피니티에서는 노드에 일관된 레이블을 지정해야 한다. 즉, 클러스터의 모든 노드는 `topologyKey` 와 매칭되는 적절한 레이블을 가지고 있어야 한다. 일부 또는 모든 노드에 지정된 `topologyKey` 레이블이 없는 경우에는 의도하지 않은 동작이 발생할 수 있다.
|
||||
파드 안티-어피니티에서는 노드에 일관된 레이블을 지정해야 한다.
|
||||
즉, 클러스터의 모든 노드는 `topologyKey` 와 매칭되는 적절한 레이블을 가지고 있어야 한다.
|
||||
일부 또는 모든 노드에 지정된 `topologyKey` 레이블이 없는 경우에는
|
||||
의도하지 않은 동작이 발생할 수 있다.
|
||||
{{< /note >}}
|
||||
|
||||
노드 어피니티와 마찬가지로 현재 파드 어피니티와 안티-어피니티로 부르는 "엄격함" 대 "유연함"의 요구사항을 나타내는 `requiredDuringSchedulingIgnoredDuringExecution` 와
|
||||
`preferredDuringSchedulingIgnoredDuringExecution` 두 가지 종류가 있다.
|
||||
앞의 노드 어피니티 섹션의 설명을 본다.
|
||||
`requiredDuringSchedulingIgnoredDuringExecution` 어피니티의 예시는
|
||||
"서로 많은 통신을 하기 때문에 서비스 A와 서비스 B를 같은 영역에 함께 위치시키는 것"이고,
|
||||
`preferredDuringSchedulingIgnoredDuringExecution` 안티-어피니티의 예시는 "서비스를 여러 영역에 걸쳐서 분배하는 것"이다
|
||||
(엄격한 요구사항은 영역보다 파드가 더 많을 수 있기 때문에 엄격한 요구사항은 의미가 없다).
|
||||
#### 파드간 어피니티 및 안티-어피니티 종류 {#types-of-inter-pod-affinity-and-anti-affinity}
|
||||
|
||||
파드간 어피니티는 PodSpec에서 `affinity` 필드 중 `podAffinity` 필드로 지정한다.
|
||||
그리고 파드간 안티-어피니티는 PodSpec에서 `affinity` 필드 중 `podAntiAffinity` 필드로 지정한다.
|
||||
노드 어피니티와 마찬가지로
|
||||
파드 어피니티 및 안티-어피니티에는 다음의 2 종류가 있다.
|
||||
|
||||
#### 파드 어피니티를 사용하는 파드의 예시
|
||||
* `requiredDuringSchedulingIgnoredDuringExecution`
|
||||
* `preferredDuringSchedulingIgnoredDuringExecution`
|
||||
|
||||
예를 들어, `requiredDuringSchedulingIgnoredDuringExecution` 어피니티를 사용하여
|
||||
서로 통신을 많이 하는 두 서비스의 파드를
|
||||
동일 클라우드 제공자 존에 배치하도록 스케줄러에게 지시할 수 있다.
|
||||
비슷하게, `preferredDuringSchedulingIgnoredDuringExecution` 안티-어피니티를 사용하여
|
||||
서비스의 파드를
|
||||
여러 클라우드 제공자 존에 퍼뜨릴 수 있다.
|
||||
|
||||
파드간 어피니티를 사용하려면, 파드 스펙에 `affinity.podAffinity` 필드를 사용한다.
|
||||
파드간 안티-어피니티를 사용하려면,
|
||||
파드 스펙에 `affinity.podAntiAffinity` 필드를 사용한다.
|
||||
|
||||
#### 파드 어피니티 예시 {#an-example-of-a-pod-that-uses-pod-affinity}
|
||||
|
||||
다음과 같은 파드 스펙을 가정한다.
|
||||
|
||||
{{< codenew file="pods/pod-with-pod-affinity.yaml" >}}
|
||||
|
||||
이 파드의 어피니티는 하나의 파드 어피니티 규칙과 하나의 파드 안티-어피니티 규칙을 정의한다.
|
||||
이 예시에서 `podAffinity` 는 `requiredDuringSchedulingIgnoredDuringExecution` 이고 `podAntiAffinity` 는
|
||||
`preferredDuringSchedulingIgnoredDuringExecution` 이다. 파드 어피니티 규칙에 의하면 키 "security" 와 값
|
||||
"S1"인 레이블이 있는 하나 이상의 이미 실행 중인 파드와 동일한 영역에 있는 경우에만 파드를 노드에 스케줄할 수 있다.
|
||||
(보다 정확하게는, 클러스터에 키 "security"와 값 "S1"인 레이블을 가지고 있는 실행 중인 파드가 있는 키
|
||||
`topology.kubernetes.io/zone` 와 값 V인 노드가 최소 하나 이상 있고,
|
||||
노드 N이 키 `topology.kubernetes.io/zone` 와
|
||||
일부 값이 V인 레이블을 가진다면 파드는 노드 N에서 실행할 수 있다.)
|
||||
파드 안티-어피니티 규칙에 의하면 파드는 키 "security"와 값 "S2"인 레이블을 가진 파드와
|
||||
동일한 영역의 노드에 스케줄되지 않는다.
|
||||
[디자인 문서](https://git.k8s.io/community/contributors/design-proposals/scheduling/podaffinity.md)를 통해
|
||||
`requiredDuringSchedulingIgnoredDuringExecution` 와 `preferredDuringSchedulingIgnoredDuringExecution` 의
|
||||
파드 어피니티와 안티-어피니티에 대한 많은 예시를 맛볼 수 있다.
|
||||
이 예시는 하나의 파드 어피니티 규칙과
|
||||
하나의 파드 안티-어피니티 규칙을 정의한다.
|
||||
파드 어피니티 규칙은 "하드" `requiredDuringSchedulingIgnoredDuringExecution`을,
|
||||
안티-어피니티 규칙은 "소프트" `preferredDuringSchedulingIgnoredDuringExecution`을 사용한다.
|
||||
|
||||
파드 어피니티와 안티-어피니티의 적합한 연산자는 `In`, `NotIn`, `Exists`, `DoesNotExist` 이다.
|
||||
위의 어피니티 규칙은 `security=S1` 레이블이 있는 하나 이상의 기존 파드의 존와 동일한 존에 있는 노드에만
|
||||
파드를 스케줄링하도록 스케줄러에 지시한다.
|
||||
더 정확히 말하면, 만약 `security=S1` 파드 레이블이 있는 하나 이상의 기존 파드를 실행하고 있는 노드가
|
||||
`zone=V`에 하나 이상 존재한다면,
|
||||
스케줄러는 파드를 `topology.kubernetes.io/zone=V` 레이블이 있는 노드에 배치해야 한다.
|
||||
|
||||
원칙적으로, `topologyKey` 는 적법한 어느 레이블-키도 될 수 있다.
|
||||
하지만, 성능과 보안상의 이유로 topologyKey에는 몇 가지 제약조건이 있다.
|
||||
위의 안티-어피니티 규칙은 `security=S2` 레이블이 있는 하나 이상의 기존 파드의 존와 동일한 존에 있는 노드에는
|
||||
가급적 파드를 스케줄링하지 않도록 스케줄러에 지시한다.
|
||||
더 정확히 말하면, 만약 `security=S2` 파드 레이블이 있는 파드가 실행되고 있는 `zone=R`에
|
||||
다른 노드도 존재한다면,
|
||||
스케줄러는 `topology.kubernetes.io/zone=R` 레이블이 있는 노드에는 가급적 해당 파드를 스케줄링하지 않야아 한다.
|
||||
|
||||
1. 파드 어피니티에서 `requiredDuringSchedulingIgnoredDuringExecution` 와 `preferredDuringSchedulingIgnoredDuringExecution` 는
|
||||
`topologyKey` 의 빈 값을 허용하지 않는다.
|
||||
2. 파드 안티-어피니티에서도 `requiredDuringSchedulingIgnoredDuringExecution` 와 `preferredDuringSchedulingIgnoredDuringExecution` 는
|
||||
`topologyKey` 의 빈 값을 허용하지 않는다.
|
||||
3. `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티에서 `topologyKey` 를 `kubernetes.io/hostname` 로 제한하기 위해 어드미션 컨트롤러 `LimitPodHardAntiAffinityTopology` 가 도입되었다. 사용자 지정 토폴로지를 사용할 수 있도록 하려면, 어드미션 컨트롤러를 수정하거나 아니면 이를 비활성화해야 한다.
|
||||
4. 위의 경우를 제외하고, `topologyKey` 는 적법한 어느 레이블-키도 가능하다.
|
||||
[디자인 문서](https://git.k8s.io/community/contributors/design-proposals/scheduling/podaffinity.md)에서
|
||||
파드 어피니티와 안티-어피니티에 대한
|
||||
많은 예시를 볼 수 있다.
|
||||
|
||||
`labelSelector` 와 `topologyKey` 외에도 `labelSelector` 와 일치해야 하는 네임스페이스 목록 `namespaces` 를
|
||||
선택적으로 지정할 수 있다(이것은 `labelSelector` 와 `topologyKey` 와 같은 수준의 정의이다).
|
||||
생략되어 있거나 비어있을 경우 어피니티/안티-어피니티 정의가 있는 파드의 네임스페이스가 기본 값이다.
|
||||
파드 어피니티와 안티-어피니티의 `operator` 필드에
|
||||
`In`, `NotIn`, `Exists` 및 `DoesNotExist` 값을 사용할 수 있다.
|
||||
|
||||
파드를 노드에 스케줄하려면 `requiredDuringSchedulingIgnoredDuringExecution` 어피니티와 안티-어피니티와
|
||||
연관된 `matchExpressions` 가 모두 충족되어야 한다.
|
||||
원칙적으로, `topologyKey` 에는 성능과 보안상의 이유로 다음의 예외를 제외하면
|
||||
어느 레이블 키도 사용할 수 있다.
|
||||
|
||||
#### 네임스페이스 셀렉터
|
||||
{{< feature-state for_k8s_version="v1.22" state="beta" >}}
|
||||
* 파드 어피니티 및 안티-어피니티에 대해, 빈 `topologyKey` 필드는
|
||||
`requiredDuringSchedulingIgnoredDuringExecution` 및 `preferredDuringSchedulingIgnoredDuringExecution` 내에 허용되지 않는다.
|
||||
* `requiredDuringSchedulingIgnoredDuringExecution` 파드 안티-어피니티 규칙에 대해,
|
||||
`LimitPodHardAntiAffinityTopology` 어드미션 컨트롤러는
|
||||
`topologyKey`를 `kubernetes.io/hostname`으로 제한한다.
|
||||
커스텀 토폴로지를 허용하고 싶다면 어드미션 컨트롤러를 수정하거나 비활성화할 수 있다.
|
||||
|
||||
사용자는 네임스페이스 집합에 대한 레이블 쿼리인 `namespaceSelector` 를 사용하여 일치하는 네임스페이스를 선택할 수도 있다.
|
||||
어피니티 용어는 `namespaceSelector` 에서 선택한 네임스페이스와 `namespaces` 필드에 나열된 네임스페이스의 결합에 적용된다.
|
||||
빈 `namespaceSelector` ({})는 모든 네임스페이스와 일치하는 반면, null 또는 빈 `namespaces` 목록과
|
||||
null `namespaceSelector` 는 "이 파드의 네임스페이스"를 의미한다.
|
||||
`labelSelector`와 `topologyKey`에 더하여 선택적으로,
|
||||
`labelSelector`가 비교해야 하는 네임스페이스의 목록을
|
||||
`labelSelector` 및 `topologyKey` 필드와 동일한 계위의 `namespaces` 필드에 명시할 수 있다.
|
||||
생략하거나 비워 두면,
|
||||
해당 어피니티/안티-어피니티 정의가 있는 파드의 네임스페이스를 기본값으로 사용한다.
|
||||
|
||||
이 기능은 베타이며 기본으로 활성화되어 있다. kube-apiserver 및 kube-scheduler 모두에서
|
||||
[기능 게이트](/ko/docs/reference/command-line-tools-reference/feature-gates/)
|
||||
`PodAffinityNamespaceSelector` 를 사용하여 비활성화할 수 있다.
|
||||
#### 네임스페이스 셀렉터 {#namespace-selector}
|
||||
{{< feature-state for_k8s_version="v1.24" state="stable" >}}
|
||||
|
||||
#### 더 실용적인 유스케이스
|
||||
네임스페이스 집합에 대한 레이블 쿼리인 `namespaceSelector` 를 사용하여 일치하는 네임스페이스를 선택할 수도 있다.
|
||||
`namespaceSelector` 또는 `namespaces` 필드에 의해 선택된 네임스페이스 모두에 적용된다.
|
||||
빈 `namespaceSelector` ({})는 모든 네임스페이스와 일치하는 반면,
|
||||
null 또는 빈 `namespaces` 목록과 null `namespaceSelector` 는 규칙이 적용된 파드의 네임스페이스에 매치된다.
|
||||
|
||||
파드간 어피니티와 안티-어피니티는 레플리카셋, 스테이트풀셋, 디플로이먼트 등과 같은
|
||||
상위 레벨 모음과 함께 사용할 때 더욱 유용할 수 있다. 워크로드 집합이 동일한 노드와 같이
|
||||
#### 더 실제적인 유스케이스 {#more-practical-use-cases}
|
||||
|
||||
파드간 어피니티와 안티-어피니티는 레플리카셋, 스테이트풀셋, 디플로이먼트 등과 같은
|
||||
상위 레벨 모음과 함께 사용할 때 더욱 유용할 수 있다.
|
||||
이러한 규칙을 사용하여, 워크로드 집합이 예를 들면 '동일한 노드'와 같이
|
||||
동일하게 정의된 토폴로지와 같은 위치에 배치되도록 쉽게 구성할 수 있다.
|
||||
|
||||
##### 항상 같은 노드에 위치시키기
|
||||
redis와 같은 인-메모리 캐시를 사용하는 웹 애플리케이션을 실행하는 세 개의 노드로 구성된 클러스터를 가정한다.
|
||||
이 때 웹 서버를 가능한 한 캐시와 같은 위치에서 실행되도록 하기 위해
|
||||
파드간 어피니티/안티-어피니티를 사용할 수 있다.
|
||||
|
||||
세 개의 노드가 있는 클러스터에서 웹 애플리케이션에는 redis와 같은 인-메모리 캐시가 있다. 웹 서버가 가능한 캐시와 함께 위치하기를 원한다.
|
||||
|
||||
다음은 세 개의 레플리카와 셀렉터 레이블이 `app=store` 가 있는 간단한 redis 디플로이먼트의 yaml 스니펫이다. 디플로이먼트에는 스케줄러가 단일 노드에서 레플리카를 함께 배치하지 않도록 `PodAntiAffinity` 가 구성되어 있다.
|
||||
다음의 redis 캐시 디플로이먼트 예시에서, 레플리카는 `app=store` 레이블을 갖는다.
|
||||
`podAntiAffinity` 규칙은 스케줄러로 하여금
|
||||
`app=store` 레이블이 있는 레플리카를 한 노드에 여러 개 배치하지 못하도록 한다.
|
||||
이렇게 하여 캐시 파드를 각 노드에 분산하여 생성한다.
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
@@ -324,7 +379,10 @@ spec:
|
||||
image: redis:3.2-alpine
|
||||
```
|
||||
|
||||
아래 yaml 스니펫의 웹서버 디플로이먼트는 `podAntiAffinity` 와 `podAffinity` 설정을 가지고 있다. 이렇게 하면 스케줄러에 모든 레플리카는 셀렉터 레이블이 `app=store` 인 파드와 함께 위치해야 한다. 또한 각 웹 서버 레플리카가 단일 노드의 같은 위치에 있지 않도록 한다.
|
||||
웹 서버를 위한 다음의 디플로이먼트는 `app=web-store` 레이블을 갖는 레플리카를 생성한다.
|
||||
파드 어피니티 규칙은 스케줄러로 하여금 `app=store` 레이블이 있는 파드를 실행 중인 노드에 각 레플리카를 배치하도록 한다.
|
||||
파드 안티-어피니티 규칙은 스케줄러로 하여금 `app=web-store` 레이블이 있는 서버 파드를
|
||||
한 노드에 여러 개 배치하지 못하도록 한다.
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
@@ -365,44 +423,25 @@ spec:
|
||||
image: nginx:1.16-alpine
|
||||
```
|
||||
|
||||
만약 위의 두 디플로이먼트를 생성하면 세 개의 노드가 있는 클러스터는 다음과 같아야 한다.
|
||||
위의 두 디플로이먼트를 생성하면 다음과 같은 클러스터 형상이 나타나는데,
|
||||
세 노드에 각 웹 서버가 캐시와 함께 있는 형상이다.
|
||||
|
||||
| node-1 | node-2 | node-3 |
|
||||
|:--------------------:|:-------------------:|:------------------:|
|
||||
| *webserver-1* | *webserver-2* | *webserver-3* |
|
||||
| *cache-1* | *cache-2* | *cache-3* |
|
||||
|
||||
여기서 볼 수 있듯이 `web-server` 의 세 레플리카들이 기대했던 것처럼 자동으로 캐시와 함께 위치하게 된다.
|
||||
[ZooKeeper 튜토리얼](/ko/docs/tutorials/stateful-application/zookeeper/#노드-실패-방지)에서
|
||||
위 예시와 동일한 기술을 사용해
|
||||
고 가용성을 위한 안티-어피니티로 구성된 스테이트풀셋의 예시를 확인한다.
|
||||
|
||||
```
|
||||
kubectl get pods -o wide
|
||||
```
|
||||
출력은 다음과 유사할 것이다.
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE IP NODE
|
||||
redis-cache-1450370735-6dzlj 1/1 Running 0 8m 10.192.4.2 kube-node-3
|
||||
redis-cache-1450370735-j2j96 1/1 Running 0 8m 10.192.2.2 kube-node-1
|
||||
redis-cache-1450370735-z73mh 1/1 Running 0 8m 10.192.3.1 kube-node-2
|
||||
web-server-1287567482-5d4dz 1/1 Running 0 7m 10.192.2.3 kube-node-1
|
||||
web-server-1287567482-6f7v5 1/1 Running 0 7m 10.192.4.3 kube-node-3
|
||||
web-server-1287567482-s330j 1/1 Running 0 7m 10.192.3.2 kube-node-2
|
||||
```
|
||||
## nodeName {#nodename}
|
||||
|
||||
##### 절대 동일한 노드에 위치시키지 않게 하기
|
||||
|
||||
위의 예시에서 `topologyKey:"kubernetes.io/hostname"` 과 함께 `PodAntiAffinity` 규칙을 사용해서
|
||||
두 개의 인스터스가 동일한 호스트에 있지 않도록 redis 클러스터를 배포한다.
|
||||
같은 기술을 사용해서 고 가용성을 위해 안티-어피니티로 구성된 스테이트풀셋의 예시는
|
||||
[ZooKeeper 튜토리얼](/ko/docs/tutorials/stateful-application/zookeeper/#노드-실패-방지)을 본다.
|
||||
|
||||
## nodeName
|
||||
|
||||
`nodeName` 은 가장 간단한 형태의 노트 선택 제약 조건이지만,
|
||||
한계로 인해 일반적으로는 사용하지 않는다.
|
||||
`nodeName` 은 PodSpec의 필드이다. 만약 비어있지 않으면, 스케줄러는
|
||||
파드를 무시하고 명명된 노드에서 실행 중인 kubelet이
|
||||
파드를 실행하려고 한다. 따라서 만약 PodSpec에 `nodeName` 가
|
||||
제공된 경우, 노드 선택을 위해 위의 방법보다 우선한다.
|
||||
`nodeName`은 어피니티 또는 `nodeSelector`보다 더 직접적인 형태의 노드 선택 방법이다.
|
||||
`nodeName`은 파드 스펙의 필드 중 하나이다.
|
||||
`nodeName` 필드가 비어 있지 않으면, 스케줄러는 파드를 무시하고,
|
||||
명명된 노드의 kubelet이 해당 파드를 자기 노드에 배치하려고 시도한다.
|
||||
`nodeName`은 `nodeSelector` 또는 어피니티/안티-어피니티 규칙보다 우선적으로 적용(overrule)된다.
|
||||
|
||||
`nodeName` 을 사용해서 노드를 선택할 때의 몇 가지 제한은 다음과 같다.
|
||||
|
||||
@@ -414,7 +453,7 @@ web-server-1287567482-s330j 1/1 Running 0 7m 10.192.3
|
||||
- 클라우드 환경의 노드 이름은 항상 예측 가능하거나
|
||||
안정적인 것은 아니다.
|
||||
|
||||
여기에 `nodeName` 필드를 사용하는 파드 설정 파일 예시가 있다.
|
||||
다음은 `nodeName` 필드를 사용하는 파드 스펙 예시이다.
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
@@ -428,19 +467,14 @@ spec:
|
||||
nodeName: kube-01
|
||||
```
|
||||
|
||||
위 파드는 kube-01 노드에서 실행될 것이다.
|
||||
|
||||
|
||||
위 파드는 `kube-01` 노드에서만 실행될 것이다.
|
||||
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
|
||||
[테인트](/ko/docs/concepts/scheduling-eviction/taint-and-toleration/)는 노드가 특정 파드들을 *쫓아낼* 수 있다.
|
||||
|
||||
[노드 어피니티](https://git.k8s.io/community/contributors/design-proposals/scheduling/nodeaffinity.md)와
|
||||
[파드간 어피니티/안티-어피니티](https://git.k8s.io/community/contributors/design-proposals/scheduling/podaffinity.md)에 대한 디자인 문서에는
|
||||
이러한 기능에 대한 추가 배경 정보가 있다.
|
||||
|
||||
파드가 노드에 할당되면 kubelet은 파드를 실행하고 노드의 로컬 리소스를 할당한다.
|
||||
[토폴로지 매니저](/docs/tasks/administer-cluster/topology-manager/)는
|
||||
노드 수준의 리소스 할당 결정에 참여할 수 있다.
|
||||
* [테인트 및 톨러레이션](/ko/docs/concepts/scheduling-eviction/taint-and-toleration/)에 대해 더 읽어본다.
|
||||
* [노드 어피니티](https://git.k8s.io/community/contributors/design-proposals/scheduling/nodeaffinity.md)와
|
||||
[파드간 어피니티/안티-어피니티](https://git.k8s.io/community/contributors/design-proposals/scheduling/podaffinity.md)에 대한 디자인 문서를 읽어본다.
|
||||
* [토폴로지 매니저](/docs/tasks/administer-cluster/topology-manager/)가
|
||||
노드 수준 리소스 할당 결정에 어떻게 관여하는지 알아본다.
|
||||
* [노드셀렉터(nodeSelector)](/ko/docs/tasks/configure-pod-container/assign-pods-nodes/)를 어떻게 사용하는지 알아본다.
|
||||
* [어피니티/안티-어피니티](/ko/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/)를 어떻게 사용하는지 알아본다.
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: with-affinity-anti-affinity
|
||||
spec:
|
||||
affinity:
|
||||
nodeAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
nodeSelectorTerms:
|
||||
- matchExpressions:
|
||||
- key: topology.kubernetes.io/zone
|
||||
operator: In
|
||||
values:
|
||||
- antarctica-east1
|
||||
- antarctica-west1
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
- weight: 1
|
||||
preference:
|
||||
matchExpressions:
|
||||
- key: label-1
|
||||
operator: In
|
||||
values:
|
||||
- key-1
|
||||
- weight: 50
|
||||
preference:
|
||||
matchExpressions:
|
||||
- key: label-2
|
||||
operator: In
|
||||
values:
|
||||
- key-2
|
||||
containers:
|
||||
- name: with-node-affinity
|
||||
image: k8s.gcr.io/pause:2.0
|
||||
@@ -4,5 +4,5 @@
|
||||
[minikube](/ko/docs/tasks/tools/#minikube)를 사용해서 생성하거나
|
||||
다음의 쿠버네티스 플레이그라운드 중 하나를 사용할 수 있다.
|
||||
|
||||
* [Katacoda](https://www.katacoda.com/courses/kubernetes/playground)
|
||||
* [Killercoda](https://killercoda.com/playgrounds/scenario/kubernetes)
|
||||
* [Play with Kubernetes](https://labs.play-with-k8s.com/)
|
||||
|
||||
@@ -75,7 +75,7 @@ kubectl config view --minify | grep namespace:
|
||||
Quando você cria um [Serviço](/docs/concepts/services-networking/service/), ele cria uma
|
||||
[entrada DNS](/docs/concepts/services-networking/dns-pod-service/) correspondente.
|
||||
Esta entrada possui o formato: `<service-name>.<namespace-name>.svc.cluster.local`, de forma que se um contêiner utilizar apenas `<service-name>` ele será resolvido para um serviço que é local ao namespace.
|
||||
Isso é útil para utilizar a mesma configuração em vários namespaces, por exemplo em Desenvolvimento, `Staging` e Produç. Se você quiser acessar múltiplos namespaces, precisará utilizar um _Fully Qualified Domain Name_ (FQDN).
|
||||
Isso é útil para utilizar a mesma configuração em vários namespaces, por exemplo em Desenvolvimento, `Staging` e Produção. Se você quiser acessar múltiplos namespaces, precisará utilizar um _Fully Qualified Domain Name_ (FQDN).
|
||||
|
||||
## Nem todos os objetos pertencem a algum Namespace
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ vulnerável a um ataque de exaustão de recursos e, por consequência, o risco d
|
||||
Autorização RBAC (acesso à API Kubernetes) | https://kubernetes.io/docs/reference/access-authn-authz/rbac/
|
||||
Autenticação | https://kubernetes.io/docs/concepts/security/controlling-access/
|
||||
Gerenciamento de segredos na aplicação (e encriptando-os no etcd em repouso) | https://kubernetes.io/docs/concepts/configuration/secret/ <br> https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/
|
||||
Políticas de segurança do Pod | https://kubernetes.io/docs/concepts/policy/pod-security-policy/
|
||||
Garantir que os Pods atendem aos padrões de segurança do Pod | https://kubernetes.io/docs/concepts/security/pod-security-standards/#policy-instantiation
|
||||
Qualidade de serviço (e gerenciamento de recursos de cluster) | https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/
|
||||
Políticas de Rede | https://kubernetes.io/docs/concepts/services-networking/network-policies/
|
||||
TLS para Kubernetes Ingress | https://kubernetes.io/docs/concepts/services-networking/ingress/#tls
|
||||
|
||||
@@ -22,7 +22,7 @@ O gerenciamento de armazenamento é uma questão bem diferente do gerenciamento
|
||||
|
||||
Um _PersistentVolume_ (PV) é uma parte do armazenamento dentro do cluster que tenha sido provisionada por um administrador, ou dinamicamente utilizando [Classes de Armazenamento](/docs/concepts/storage/storage-classes/). Isso é um recurso dentro do cluster da mesma forma que um nó também é. PVs são plugins de volume da mesma forma que Volumes, porém eles têm um ciclo de vida independente de qualquer Pod que utilize um PV. Essa API tem por objetivo mostrar os detalhes da implementação do armazenamento, seja ele NFS, iSCSI, ou um armazenamento específico de um provedor de cloud pública.
|
||||
|
||||
Uma_PersistentVolumeClaim_ (PVC) é uma requisição para armazenamento por um usuário. É similar a um Pod. Pods utilizam recursos do nó e PVCs utilizam recursos do PV. Pods podem solicitar níveis específicos de recursos (CPU e Memória). Claims podem solicitar tamanho e modos de acesso específicos (exemplo: montagem como ReadWriteOnce, ReadOnlyMany ou ReadWriteMany, veja [Modos de Acesso](#modos-de-acesso)).
|
||||
Uma _PersistentVolumeClaim_ (PVC) é uma requisição para armazenamento por um usuário. É similar a um Pod. Pods utilizam recursos do nó e PVCs utilizam recursos do PV. Pods podem solicitar níveis específicos de recursos (CPU e Memória). Claims podem solicitar tamanho e modos de acesso específicos (exemplo: montagem como ReadWriteOnce, ReadOnlyMany ou ReadWriteMany, veja [Modos de Acesso](#modos-de-acesso)).
|
||||
|
||||
Enquanto as PersistentVolumeClaims permitem que um usuário utilize recursos de armazenamento de forma limitada, é comum que usuários precisem de PersistentVolumes com diversas propriedades, como desempenho, para problemas diversos. Os administradores de cluster precisam estar aptos a oferecer uma variedade de PersistentVolumes que difiram em tamanho e modo de acesso, sem expor os usuários a detalhes de como esses volumes são implementados. Para necessidades como essas, temos o recurso de _StorageClass_.
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user