Merge branch 'main' into zh-secure-cluster
This commit is contained in:
+22
-9
@@ -4,29 +4,42 @@
|
||||
# change is that the Hugo version is now an overridable argument rather than a fixed
|
||||
# environment variable.
|
||||
|
||||
FROM golang:1.15-alpine
|
||||
FROM golang:1.16-alpine
|
||||
|
||||
LABEL maintainer="Luc Perkins <lperkins@linuxfoundation.org>"
|
||||
|
||||
RUN apk add --no-cache \
|
||||
curl \
|
||||
git \
|
||||
openssh-client \
|
||||
rsync \
|
||||
gcc \
|
||||
g++ \
|
||||
musl-dev \
|
||||
build-base \
|
||||
libc6-compat \
|
||||
npm && \
|
||||
npm install -D autoprefixer postcss-cli
|
||||
libc6-compat
|
||||
|
||||
ARG HUGO_VERSION
|
||||
|
||||
RUN mkdir $HOME/src && \
|
||||
cd $HOME/src && \
|
||||
curl -L https://github.com/gohugoio/hugo/archive/refs/tags/v${HUGO_VERSION}.tar.gz | tar -xz && \
|
||||
cd "hugo-${HUGO_VERSION}" && \
|
||||
go install --tags extended
|
||||
|
||||
FROM golang:1.16-alpine
|
||||
|
||||
RUN apk add --no-cache \
|
||||
git \
|
||||
openssh-client \
|
||||
rsync \
|
||||
npm && \
|
||||
npm install -D autoprefixer postcss-cli
|
||||
|
||||
RUN mkdir -p /usr/local/src && \
|
||||
cd /usr/local/src && \
|
||||
curl -L https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_Linux-64bit.tar.gz | tar -xz && \
|
||||
mv hugo /usr/local/bin/hugo && \
|
||||
addgroup -Sg 1000 hugo && \
|
||||
adduser -Sg hugo -u 1000 -h /src hugo
|
||||
|
||||
COPY --from=0 /go/bin/hugo /usr/local/bin/hugo
|
||||
|
||||
WORKDIR /src
|
||||
|
||||
USER hugo:hugo
|
||||
|
||||
@@ -24,12 +24,14 @@ aliases:
|
||||
- jimangel
|
||||
- jlbutler
|
||||
- kbhawkey
|
||||
- natalisucks
|
||||
- onlydole
|
||||
- pi-victor
|
||||
- reylejano
|
||||
- savitharaghunathan
|
||||
- sftim
|
||||
- tengqm
|
||||
- zacharysarah
|
||||
sig-docs-en-reviews: # PR reviews for English content
|
||||
- bradtopol
|
||||
- celestehorgan
|
||||
@@ -38,11 +40,13 @@ aliases:
|
||||
- jimangel
|
||||
- kbhawkey
|
||||
- mehabhalodiya
|
||||
- natalisucks
|
||||
- onlydole
|
||||
- rajeshdeshpande02
|
||||
- sftim
|
||||
- shannonxtreme
|
||||
- tengqm
|
||||
- zacharysarah
|
||||
sig-docs-es-owners: # Admins for Spanish content
|
||||
- raelga
|
||||
- electrocucaracha
|
||||
|
||||
@@ -167,6 +167,14 @@ For more information about contributing to the Kubernetes documentation, see:
|
||||
- [Documentation Style Guide](https://kubernetes.io/docs/contribute/style/style-guide/)
|
||||
- [Localizing Kubernetes Documentation](https://kubernetes.io/docs/contribute/localization/)
|
||||
|
||||
### New contributor ambassadors
|
||||
|
||||
If you need help at any point when contributing, the [New Contributor Ambassadors](https://kubernetes.io/docs/contribute/advanced/#serve-as-a-new-contributor-ambassador) are a good point of contact. These are SIG Docs approvers whose responsibilities include mentoring new contributors and helping them through their first few pull requests. The best place to contact the New Contributors Ambassadors would be on the [Kubernetes Slack](https://slack.k8s.io/). Current New Contributors Ambassadors for SIG Docs:
|
||||
|
||||
| Name | Slack | GitHub |
|
||||
| -------------------------- | -------------------------- | -------------------------- |
|
||||
| Arsh Sharma | @arsh | @RinkiyaKeDad |
|
||||
|
||||
## Localization `README.md`'s
|
||||
|
||||
| Language | Language |
|
||||
|
||||
@@ -566,7 +566,8 @@ main.content {
|
||||
}
|
||||
}
|
||||
|
||||
/* COMMUNITY */
|
||||
/* COMMUNITY legacy styles */
|
||||
/* Leave these in place until localizations are caught up */
|
||||
|
||||
.newcommunitywrapper {
|
||||
.news {
|
||||
|
||||
@@ -3,6 +3,9 @@ title: " Faster than a speeding Latte "
|
||||
date: 2015-04-06
|
||||
slug: faster-than-speeding-latte
|
||||
url: /blog/2015/04/Faster-Than-Speeding-Latte
|
||||
evergreen: true
|
||||
---
|
||||
|
||||
Check out Brendan Burns racing Kubernetes.
|
||||
[](https://www.youtube.com/watch?v=?7vZ9dRKRMyc)
|
||||
|
||||
{{< youtube id="7vZ9dRKRMyc" title="Latte vs. Kubernetes setup - which is faster?">}}
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
---
|
||||
title: Runc and CVE-2019-5736
|
||||
date: 2019-02-11
|
||||
evergreen: false # mentions PodSecurityPolicy
|
||||
---
|
||||
|
||||
Authors: Kubernetes Product Security Committee
|
||||
|
||||
This morning [a container escape vulnerability in runc was announced](https://www.openwall.com/lists/oss-security/2019/02/11/2). We wanted to provide some guidance to Kubernetes users to ensure everyone is safe and secure.
|
||||
|
||||
## What Is Runc?
|
||||
## What is runc?
|
||||
|
||||
Very briefly, runc is the low-level tool which does the heavy lifting of spawning a Linux container. Other tools like Docker, Containerd, and CRI-O sit on top of runc to deal with things like data formatting and serialization, but runc is at the heart of all of these systems.
|
||||
|
||||
Kubernetes in turn sits on top of those tools, and so while no part of Kubernetes itself is vulnerable, most Kubernetes installations are using runc under the hood.
|
||||
|
||||
### What Is The Vulnerability?
|
||||
### What is the vulnerability?
|
||||
|
||||
While full details are still embargoed to give people time to patch, the rough version is that when running a process as root (UID 0) inside a container, that process can exploit a bug in runc to gain root privileges on the host running the container. This then allows them unlimited access to the server as well as any other containers on that server.
|
||||
|
||||
@@ -19,13 +22,14 @@ If the process inside the container is either trusted (something you know is not
|
||||
|
||||
The most common source of risk is attacker-controller container images, such as unvetted images from public repositories.
|
||||
|
||||
### What Should I Do?
|
||||
### What should i do?
|
||||
|
||||
As with all security issues, the two main options are to mitigate the vulnerability or upgrade your version of runc to one that includes the fix.
|
||||
|
||||
As the exploit requires UID 0 within the container, a direct mitigation is to ensure all your containers are running as a non-0 user. This can be set within the container image, or via your pod specification:
|
||||
|
||||
```yaml
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
@@ -39,6 +43,7 @@ spec:
|
||||
This can also be enforced globally using a PodSecurityPolicy:
|
||||
|
||||
```yaml
|
||||
---
|
||||
apiVersion: policy/v1beta1
|
||||
kind: PodSecurityPolicy
|
||||
metadata:
|
||||
@@ -89,7 +94,7 @@ We don't have specific confirmation that Docker for Mac and Docker for Windows a
|
||||
|
||||
If you are unable to upgrade Docker, the Rancher team has provided backports of the fix for many older versions at [github.com/rancher/runc-cve](https://github.com/rancher/runc-cve).
|
||||
|
||||
## Getting More Information
|
||||
## Getting more information
|
||||
|
||||
If you have any further questions about how this vulnerability impacts Kubernetes, please join us at [discuss.kubernetes.io](https://discuss.kubernetes.io/).
|
||||
|
||||
|
||||
@@ -30,15 +30,15 @@ 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/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/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/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/references/spec/#networking.x-k8s.io/v1alpha1.TCPRoute), [UDPRoutes](https://gateway-api.sigs.k8s.io/references/spec/#networking.x-k8s.io/v1alpha1.UDPRoute), and [TLSRoutes](https://gateway-api.sigs.k8s.io/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/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.
|
||||
|
||||

|
||||
|
||||
### Gateway Controller Implementations
|
||||
|
||||
The good news is that although Gateway is in [Alpha](https://github.com/kubernetes-sigs/gateway-api/releases), there are already several [Gateway controller implementations](https://gateway-api.sigs.k8s.io/references/implementations/) that you can run. Since it’s a standardized spec, the following example could be run on any of them and should function the exact same way. Check out [getting started](https://gateway-api.sigs.k8s.io/guides/getting-started/) to see how to install and use one of these Gateway controllers.
|
||||
The good news is that although Gateway is in [Alpha](https://github.com/kubernetes-sigs/gateway-api/releases), there are already several [Gateway controller implementations](https://gateway-api.sigs.k8s.io/implementations/) that you can run. Since it’s a standardized spec, the following example could be run on any of them and should function the exact same way. Check out [getting started](https://gateway-api.sigs.k8s.io/v1alpha1/guides/getting-started/) to see how to install and use one of these Gateway controllers.
|
||||
|
||||
## Getting Hands-on with the Gateway API
|
||||
|
||||
@@ -134,7 +134,7 @@ spec:
|
||||
|
||||
So we have two HTTPRoutes matching and routing traffic to different Services. You might be wondering, where are these Services accessible? Through which networks or IPs are they exposed?
|
||||
|
||||
How Routes are exposed to clients is governed by [Route binding](https://gateway-api.sigs.k8s.io/concepts/api-overview/#route-binding), which describes how Routes and Gateways create a bidirectional relationship between each other. When Routes are bound to a Gateway it means their collective routing rules are configured on the underlying load balancers or proxies and the Routes are accessible through the Gateway. Thus, a Gateway is a logical representation of a networking data plane that can be configured through Routes.
|
||||
How Routes are exposed to clients is governed by [Route binding](https://gateway-api.sigs.k8s.io/concepts/api-overview/#route-resources), which describes how Routes and Gateways create a bidirectional relationship between each other. When Routes are bound to a Gateway it means their collective routing rules are configured on the underlying load balancers or proxies and the Routes are accessible through the Gateway. Thus, a Gateway is a logical representation of a networking data plane that can be configured through Routes.
|
||||
|
||||
|
||||

|
||||
@@ -192,6 +192,6 @@ When you put it all together, you have a single load balancing infrastructure th
|
||||
|
||||
There are many resources to check out to learn more.
|
||||
|
||||
* Check out the [user guides](https://gateway-api.sigs.k8s.io/guides/getting-started/) to see what use-cases can be addressed.
|
||||
* Try out one of the [existing Gateway controllers ](https://gateway-api.sigs.k8s.io/references/implementations/)
|
||||
* Check out the [user guides](https://gateway-api.sigs.k8s.io/v1alpha1/guides/getting-started/) to see what use-cases can be addressed.
|
||||
* Try out one of the [existing Gateway controllers ](https://gateway-api.sigs.k8s.io/implementations/)
|
||||
* Or [get involved](https://gateway-api.sigs.k8s.io/contributing/community/) and help design and influence the future of Kubernetes service networking!
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "Meet Our Contributors - APAC (Aus-NZ region)"
|
||||
date: 2022-03-16T12:00:00+0000
|
||||
slug: meet-our-contributors-au-nz-ep-02
|
||||
canonicalUrl: https://www.kubernetes.dev/blog/2022/03/14/meet-our-contributors-au-nz-ep-02/
|
||||
---
|
||||
|
||||
**Authors & Interviewers:** [Anubhav Vardhan](https://github.com/anubha-v-ardhan), [Atharva Shinde](https://github.com/Atharva-Shinde), [Avinesh Tripathi](https://github.com/AvineshTripathi), [Brad McCoy](https://github.com/bradmccoydev), [Debabrata Panigrahi](https://github.com/Debanitrkl), [Jayesh Srivastava](https://github.com/jayesh-srivastava), [Kunal Verma](https://github.com/verma-kunal), [Pranshu Srivastava](https://github.com/PranshuSrivastava), [Priyanka Saggu](github.com/Priyankasaggu11929/), [Purneswar Prasad](https://github.com/PurneswarPrasad), [Vedant Kakde](https://github.com/vedant-kakde)
|
||||
|
||||
---
|
||||
|
||||
Good day, everyone 👋
|
||||
|
||||
Welcome back to the second episode of the "Meet Our Contributors" blog post series for APAC.
|
||||
|
||||
This post will feature four outstanding contributors from the Australia and New Zealand regions, who have played diverse leadership and community roles in the Upstream Kubernetes project.
|
||||
|
||||
So, without further ado, let's get straight to the blog.
|
||||
|
||||
## [Caleb Woodbine](https://github.com/BobyMCbobs)
|
||||
|
||||
Caleb Woodbine is currently a member of the ii.nz organisation.
|
||||
|
||||
He began contributing to the Kubernetes project in 2018 as a member of the Kubernetes Conformance working group. His experience was positive, and he benefited from early guidance from [Hippie Hacker](https://github.com/hh), a fellow contributor from New Zealand.
|
||||
|
||||
He has made major contributions to Kubernetes project since then through `SIG k8s-infra` and `k8s-conformance` working group.
|
||||
|
||||
Caleb is also a co-organizer of the [CloudNative NZ](https://www.meetup.com/cloudnative-nz/) community events, which aim to expand the reach of Kubernetes project throughout New Zealand in order to encourage technical education and improved employment opportunities.
|
||||
|
||||
> _There need to be more outreach in APAC and the educators and universities must pick up Kubernetes, as they are very slow and about 8+ years out of date. NZ tends to rather pay overseas than educate locals on the latest cloud tech Locally._
|
||||
|
||||
## [Dylan Graham](https://github.com/DylanGraham)
|
||||
|
||||
Dylan Graham is a cloud engineer from Adeliade, Australia. He has been contributing to the upstream Kubernetes project since 2018.
|
||||
|
||||
He stated that being a part of such a large-scale project was initially overwhelming, but that the community's friendliness and openness assisted him in getting through it.
|
||||
|
||||
He began by contributing to the project documentation and is now mostly focused on the community support for the APAC region.
|
||||
|
||||
He believes that consistent attendance at community/project meetings, taking on project tasks, and seeking community guidance as needed can help new aspiring developers become effective contributors.
|
||||
|
||||
> _The feeling of being a part of a large community is really special. I've met some amazing people, even some before the pandemic in real life :)_
|
||||
|
||||
## [Hippie Hacker](https://github.com/hh)
|
||||
|
||||
Hippie has worked for the CNCF.io as a Strategic Initiatives contractor from New Zealand for almost 5+ years. He is an active contributor to k8s-infra, API conformance testing, Cloud provider conformance submissions, and apisnoop.cncf.io domains of the upstream Kubernetes & CNCF projects.
|
||||
|
||||
He recounts their early involvement with the Kubernetes project, which began roughly 5 years ago when their firm, ii.nz, demonstrated [network booting from a Raspberry Pi using PXE and running Gitlab in-cluster to install Kubernetes on servers](https://ii.nz/post/bringing-the-cloud-to-your-community/).
|
||||
|
||||
He describes their own contributing experience as someone who, at first, tried to do all of the hard lifting on their own, but eventually saw the benefit of group contributions which reduced burnout and task division which allowed folks to keep moving forward on their own momentum.
|
||||
|
||||
He recommends that new contributors use pair programming.
|
||||
|
||||
> _The cross pollination of approaches and two pairs of eyes on the same work can often yield a much more amplified effect than a PR comment / approval alone can afford._
|
||||
|
||||
## [Nick Young](https://github.com/youngnick)
|
||||
|
||||
Nick Young works at VMware as a technical lead for Contour, a CNCF ingress controller. He was active with the upstream Kubernetes project from the beginning, and eventually became the chair of the LTS working group, where he advocated user concerns. He is currently the SIG Network Gateway API subproject's maintainer.
|
||||
|
||||
His contribution path was notable in that he began working on major areas of the Kubernetes project early on, skewing his trajectory.
|
||||
|
||||
He asserts the best thing a new contributor can do is to "start contributing". Naturally, if it is relevant to their employment, that is excellent; however, investing non-work time in contributing can pay off in the long run in terms of work. He believes that new contributors, particularly those who are currently Kubernetes users, should be encouraged to participate in higher-level project discussions.
|
||||
|
||||
> _Just being active and contributing will get you a long way. Once you've been active for a while, you'll find that you're able to answer questions, which will mean you're asked questions, and before you know it you are an expert._
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
If you have any recommendations/suggestions for who we should interview next, please let us know in #sig-contribex. Your suggestions would be much appreciated. We're thrilled to have additional folks assisting us in reaching out to even more wonderful individuals of the community.
|
||||
|
||||
|
||||
We'll see you all in the next one. Everyone, till then, have a happy contributing! 👋
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "Is Your Cluster Ready for v1.24?"
|
||||
date: 2022-03-31
|
||||
slug: ready-for-dockershim-removal
|
||||
---
|
||||
|
||||
**Author:** Kat Cosgrove
|
||||
|
||||
|
||||
Way back in December of 2020, Kubernetes announced the [deprecation of Dockershim](/blog/2020/12/02/dont-panic-kubernetes-and-docker/). In Kubernetes, dockershim is a software shim that allows you to use the entire Docker engine as your container runtime within Kubernetes. In the upcoming v1.24 release, we are removing Dockershim - the delay between deprecation and removal in line with the [project’s policy](https://kubernetes.io/docs/reference/using-api/deprecation-policy/) of supporting features for at least one year after deprecation. If you are a cluster operator, this guide includes the practical realities of what you need to know going into this release. Also, what do you need to do to ensure your cluster doesn’t fall over!
|
||||
|
||||
## First, does this even affect you?
|
||||
|
||||
If you are rolling your own cluster or are otherwise unsure whether or not this removal affects you, stay on the safe side and [check to see if you have any dependencies on Docker Engine](/docs/tasks/administer-cluster/migrating-from-dockershim/check-if-dockershim-deprecation-affects-you/). Please note that using Docker Desktop to build your application containers is not a Docker dependency for your cluster. Container images created by Docker are compliant with the [Open Container Initiative (OCI)](https://opencontainers.org/), a Linux Foundation governance structure that defines industry standards around container formats and runtimes. They will work just fine on any container runtime supported by Kubernetes.
|
||||
|
||||
If you are using a managed Kubernetes service from a cloud provider, and you haven’t explicitly changed the container runtime, there may be nothing else for you to do. Amazon EKS, Azure AKS, and Google GKE all default to containerd now, though you should make sure they do not need updating if you have any node customizations. To check the runtime of your nodes, follow [Find Out What Container Runtime is Used on a Node](/docs/tasks/administer-cluster/migrating-from-dockershim/find-out-runtime-you-use/).
|
||||
|
||||
Regardless of whether you are rolling your own cluster or using a managed Kubernetes service from a cloud provider, you may need to [migrate telemetry or security agents that rely on Docker Engine](/docs/tasks/administer-cluster/migrating-from-dockershim/migrating-telemetry-and-security-agents/).
|
||||
|
||||
## I have a Docker dependency. What now?
|
||||
|
||||
If your Kubernetes cluster depends on Docker Engine and you intend to upgrade to Kubernetes v1.24 (which you should eventually do for security and similar reasons), you will need to change your container runtime from Docker Engine to something else or use [cri-dockerd](https://github.com/Mirantis/cri-dockerd). Since [containerd](https://containerd.io/) is a graduated CNCF project and the runtime within Docker itself, it’s a safe bet as an alternative container runtime. Fortunately, the Kubernetes project has already documented the process of [changing a node’s container runtime](/docs/tasks/administer-cluster/migrating-from-dockershim/change-runtime-containerd/), using containerd as an example. Instructions are similar for switching to one of the other supported runtimes.
|
||||
|
||||
## I want to upgrade Kubernetes, and I need to maintain compatibility with Docker as a runtime. What are my options?
|
||||
|
||||
Fear not, you aren’t being left out in the cold and you don’t have to take the security risk of staying on an old version of Kubernetes. Mirantis and Docker have jointly released, and are maintaining, a replacement for dockershim. That replacement is called [cri-dockerd](https://github.com/Mirantis/cri-dockerd). If you do need to maintain compatibility with Docker as a runtime, install cri-dockerd following the instructions in the project’s documentation.
|
||||
|
||||
## Is that it?
|
||||
|
||||
|
||||
Yes. As long as you go into this release aware of the changes being made and the details of your own clusters, and you make sure to communicate clearly with your development teams, it will be minimally dramatic. You may have some changes to make to your cluster, application code, or scripts, but all of these requirements are documented. Switching from using Docker Engine as your runtime to using [one of the other supported container runtimes](/docs/setup/production-environment/container-runtimes/) effectively means removing the middleman, since the purpose of dockershim is to access the container runtime used by Docker itself. From a practical perspective, this removal is better both for you and for Kubernetes maintainers in the long-run.
|
||||
|
||||
If you still have questions, please first check the [Dockershim Removal FAQ](/blog/2022/02/17/dockershim-faq/).
|
||||
+120
-194
@@ -2,256 +2,182 @@
|
||||
title: Community
|
||||
layout: basic
|
||||
cid: community
|
||||
community_styles_migrated: true
|
||||
---
|
||||
<img
|
||||
id="banner"
|
||||
srcset="/images/community/kubernetes-community-final-02.jpg 1500w, /images/community/kubernetes-community-02-mobile.jpg 900w"
|
||||
sizes="(max-width: 900px) 900px, (max-width: 1920px) 1500px"
|
||||
src="/images/community/kubernetes-community-final-02.jpg"
|
||||
alt="Kubernetes conference photo">
|
||||
|
||||
<div class="newcommunitywrapper">
|
||||
<div class="banner1">
|
||||
<img src="/images/community/kubernetes-community-final-02.jpg" alt="Kubernetes Conference Gallery" style="width:100%;padding-left:0px" class="desktop">
|
||||
<img src="/images/community/kubernetes-community-02-mobile.jpg" alt="Kubernetes Conference Gallery" style="width:100%;padding-left:0px" class="mobile">
|
||||
<div class="community-section" id="introduction">
|
||||
<p>The Kubernetes community — users, contributors, and the culture we've
|
||||
built together — is one of the biggest reasons for the meteoric rise of
|
||||
this open source project. Our culture and values continue to grow and change
|
||||
as the project itself grows and changes. We all work together toward constant
|
||||
improvement of the project and the ways we work on it.</p>
|
||||
<p> We are the people who file issues and pull requests, attend SIG meetings,
|
||||
Kubernetes meetups, and KubeCon, advocate for its adoption and innovation,
|
||||
run <code>kubectl get pods</code>, and contribute in a thousand other vital
|
||||
ways. Read on to learn how you can get involved and become part of this amazing
|
||||
community.</p>
|
||||
</div>
|
||||
|
||||
<div class="intro">
|
||||
<br class="mobile">
|
||||
<p>The Kubernetes community -- users, contributors, and the culture we've built together -- is one of the biggest reasons for the meteoric rise of this open source project. Our culture and values continue to grow and change as the project itself grows and changes. We all work together toward constant improvement of the project and the ways we work on it.
|
||||
<br><br>We are the people who file issues and pull requests, attend SIG meetings, Kubernetes meetups, and KubeCon, advocate for its adoption and innovation, run <code>kubectl get pods</code>, and contribute in a thousand other vital ways. Read on to learn how you can get involved and become part of this amazing community.</p>
|
||||
<br class="mobile">
|
||||
<div id="navigation-items">
|
||||
<div class="community-nav-item external-link">
|
||||
<a href="https://www.kubernetes.dev/">Contributor community</a>
|
||||
</div>
|
||||
|
||||
<div class="community__navbar">
|
||||
|
||||
<a href="https://www.kubernetes.dev/">Contributor Community</a>
|
||||
<a href="#values">Community Values</a>
|
||||
<a href="#conduct">Code of conduct </a>
|
||||
<a href="#videos">Videos</a>
|
||||
<a href="#discuss">Discussions</a>
|
||||
<a href="#events">Events and meetups</a>
|
||||
<a href="#news">News</a>
|
||||
<div class="community-nav-item">
|
||||
<a href="#values">Community values</a>
|
||||
</div>
|
||||
<div class="community-nav-item">
|
||||
<a href="#conduct">Code of conduct</a>
|
||||
</div>
|
||||
<div class="community-nav-item">
|
||||
<a href="#videos">Videos</a>
|
||||
</div>
|
||||
<div class="community-nav-item">
|
||||
<a href="#discuss">Discussions</a>
|
||||
</div>
|
||||
<div class="community-nav-item">
|
||||
<a href="#meetups">Meetups</a>
|
||||
</div>
|
||||
<div class="community-nav-item">
|
||||
<a href="#news">News</a>
|
||||
</div>
|
||||
<div class="community-nav-item">
|
||||
<a href="/releases">Releases</a>
|
||||
|
||||
</div>
|
||||
<br class="mobile"><br class="mobile">
|
||||
<div class="imagecols">
|
||||
<br class="mobile">
|
||||
<div class="imagecol">
|
||||
<img src="/images/community/kubernetes-community-final-03.jpg" alt="Kubernetes Conference Gallery" style="width:100%" class="desktop">
|
||||
</div>
|
||||
|
||||
<div class="imagecol">
|
||||
<img src="/images/community/kubernetes-community-final-04.jpg" alt="Kubernetes Conference Gallery" style="width:100%" class="desktop">
|
||||
<div class="community-section" id="gallery">
|
||||
<img src="/images/community/kubernetes-community-final-03.jpg" alt="Kubernetes conference gallery photo" class="community-gallery-desktop">
|
||||
<img src="/images/community/kubernetes-community-final-04.jpg" alt="Kubernetes conference gallery photo" class="community-gallery-desktop">
|
||||
<img src="/images/community/kubernetes-community-final-05.jpg" alt="Kubernetes conference gallery photo" class="community-gallery-desktop">
|
||||
<img src="/images/community/kubernetes-community-04-mobile.jpg" alt="Kubernetes conference gallery photo" class="community-gallery-mobile">
|
||||
</div>
|
||||
|
||||
<div class="imagecol" style="margin-right:0% important">
|
||||
<img src="/images/community/kubernetes-community-final-05.jpg" alt="Kubernetes Conference Gallery" style="width:100%;margin-right:0% important" class="desktop">
|
||||
</div>
|
||||
<img src="/images/community/kubernetes-community-04-mobile.jpg" alt="Kubernetes Conference Gallery" style="width:100%;margin-bottom:3%" class="mobile">
|
||||
<a name="values"></a>
|
||||
</div>
|
||||
|
||||
<div><a name="values"></a></div>
|
||||
<div class="conduct">
|
||||
<div class="conducttext">
|
||||
<br class="mobile"><br class="mobile">
|
||||
<br class="tablet"><br class="tablet">
|
||||
<div class="conducttextnobutton" style="margin-bottom:2%"><h1>Community Values</h1>
|
||||
The Kubernetes Community values are the keystone to the ongoing success of the project.<br>
|
||||
These principles guide every aspect of the Kubernetes project.
|
||||
<br>
|
||||
<a href="/community/values/">
|
||||
<br class="mobile"><br class="mobile">
|
||||
<span class="fullbutton">
|
||||
READ MORE
|
||||
</span>
|
||||
<div class="community-section" id="values">
|
||||
<h2>Community Values</h2>
|
||||
<p>The Kubernetes Community values are the keystone to the ongoing success of the project.<br class="optional"/>
|
||||
These principles guide every aspect of the Kubernetes project.</p>
|
||||
<a href="https://www.kubernetes.dev/community/values/" class="community-cta-button">
|
||||
<span class="community-cta">Read more</span>
|
||||
</a>
|
||||
</div><a name="conduct"></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="conduct">
|
||||
<div class="conducttext">
|
||||
<br class="mobile"><br class="mobile">
|
||||
<br class="tablet"><br class="tablet">
|
||||
<div class="conducttextnobutton" style="margin-bottom:2%"><h1>Code of Conduct</h1>
|
||||
The Kubernetes community values respect and inclusiveness, and enforces a Code of Conduct in all interactions. If you notice a violation of the Code of Conduct at an event or meeting, in Slack, or in another communication mechanism, reach out to the Kubernetes Code of Conduct Committee at <a href="mailto:conduct@kubernetes.io" style="color:#0662EE;font-weight:300">conduct@kubernetes.io</a>. All reports are kept confidential. You can read about the committee <a href="https://github.com/kubernetes/community/tree/master/committee-code-of-conduct" style="color:#0662EE;font-weight:300">here</a>.
|
||||
<br>
|
||||
<a href="https://kubernetes.io/community/code-of-conduct/">
|
||||
<br class="mobile"><br class="mobile">
|
||||
|
||||
<span class="fullbutton">
|
||||
READ MORE
|
||||
</span>
|
||||
<div class="community-section" id="conduct">
|
||||
<h2>Code of Conduct</h2>
|
||||
<p>The Kubernetes community values respect and inclusiveness, and enforces a Code of Conduct in all interactions.</p>
|
||||
<p>If you notice a violation of the Code of Conduct at an event or meeting, in <a href="#slack">Slack</a>, or in another communication mechanism, reach out to the Kubernetes Code of Conduct Committee at <a href="mailto:conduct@kubernetes.io">conduct@kubernetes.io</a>. All reports are kept confidential. You can read <a href="https://github.com/kubernetes/community/tree/master/committee-code-of-conduct">about the committee</a> in the Kubernetes community repository on GitHub.</p>
|
||||
<a href="/community/code-of-conduct/" class="community-cta-button">
|
||||
<span class="community-cta">Read more</span>
|
||||
</a>
|
||||
</div><a name="videos"></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="videos" class="community-section">
|
||||
<h2>Videos</h2>
|
||||
|
||||
<p class="community-simple">Kubernetes is on YouTube, a lot. Subscribe for a wide range of topics.</p>
|
||||
|
||||
<div class="videos">
|
||||
<br class="mobile"><br class="mobile">
|
||||
<br class="tablet"><br class="tablet">
|
||||
<h1 style="margin-top:0px">Videos</h1>
|
||||
|
||||
<div style="margin-bottom:4%;font-weight:300;text-align:center;padding-left:10%;padding-right:10%">We're on YouTube, a lot. Subscribe for a wide range of topics.</div>
|
||||
|
||||
<div class="videocontainer">
|
||||
|
||||
<div class="video">
|
||||
|
||||
<iframe width="100%" height="250" src="https://www.youtube.com/embed/videoseries?list=PL69nYSiGNLP3azFUvYJjGn45YbF6C-uIg" title="Monthly office hours" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
|
||||
|
||||
<div class="container">
|
||||
<div class="video youtube">
|
||||
<iframe src="https://www.youtube.com/embed/videoseries?list=PL69nYSiGNLP3azFUvYJjGn45YbF6C-uIg" title="Monthly office hours" allow="camera 'none'; microphone 'none'; geolocation 'none'; fullscreen https://www.youtube.com/" ></iframe>
|
||||
<a href="https://www.youtube.com/playlist?list=PL69nYSiGNLP3azFUvYJjGn45YbF6C-uIg">
|
||||
<div class="videocta">
|
||||
Watch monthly office hours ▶</div>
|
||||
<span class="videocta">Watch monthly office hours ▶</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="video">
|
||||
<iframe width="100%" height="250" src="https://www.youtube.com/embed/videoseries?list=PL69nYSiGNLP1pkHsbPjzAewvMgGUpkCnJ" title="Weekly community meetings" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
|
||||
<div class="video youtube">
|
||||
<iframe src="https://www.youtube.com/embed/videoseries?list=PL69nYSiGNLP1pkHsbPjzAewvMgGUpkCnJ" title="Weekly community meetings" allow="camera 'none'; microphone 'none'; geolocation 'none'; fullscreen https://www.youtube.com/"></iframe>
|
||||
<a href="https://www.youtube.com/playlist?list=PL69nYSiGNLP1pkHsbPjzAewvMgGUpkCnJ">
|
||||
<div class="videocta">
|
||||
Watch weekly community meetings ▶
|
||||
</div>
|
||||
<span class="videocta">Watch weekly community meetings ▶</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="video">
|
||||
|
||||
<iframe width="100%" height="250" src="https://www.youtube.com/embed/videoseries?list=PL69nYSiGNLP3QpQrhZq_sLYo77BVKv09F" title="Talk from a community member" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
|
||||
|
||||
<div class="video youtube" id="discuss">
|
||||
<iframe src="https://www.youtube.com/embed/videoseries?list=PL69nYSiGNLP3QpQrhZq_sLYo77BVKv09F" title="Talk from a community member" allow="camera 'none'; microphone 'none'; geolocation 'none'; fullscreen https://www.youtube.com/"></iframe>
|
||||
<a href="https://www.youtube.com/playlist?list=PL69nYSiGNLP3QpQrhZq_sLYo77BVKv09F">
|
||||
<div class="videocta">
|
||||
Watch a talk from a community member ▶
|
||||
</div>
|
||||
|
||||
<span class="videocta">Watch a talk from a community member ▶</span>
|
||||
</a>
|
||||
<a name="discuss"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="resources" class="community-section">
|
||||
<h2>Discussions</h2>
|
||||
|
||||
<div class="resources">
|
||||
<br class="mobile"><br class="mobile">
|
||||
<br class="tablet"><br class="tablet">
|
||||
<h1 style="padding-top:1%">Discussions</h1>
|
||||
<p class="community-simple">We talk a lot. Find us and join the conversation on any of these platforms.</p>
|
||||
|
||||
<div style="font-weight:300;text-align:center">We talk a lot. Find us and join the conversation on any of these platforms.</div>
|
||||
|
||||
<div class="resourcecontainer">
|
||||
|
||||
<div class="resourcebox">
|
||||
<img src="/images/community/discuss.png" alt=Forum" style="width:80%;padding-bottom:2%">
|
||||
<a href="https://discuss.kubernetes.io/" style="color:#0662EE;display:block;margin-top:1%">
|
||||
forum ▶
|
||||
<div class="container">
|
||||
<div class="community-resource">
|
||||
<a href="https://discuss.kubernetes.io/">
|
||||
<img src="/images/community/discuss.png" alt="Forum">
|
||||
</a>
|
||||
<div class="resourceboxtext" style="font-size:12px;text-transform:none !important;font-weight:300;line-height:1.4em;color:#333333;margin-top:4%">
|
||||
Topic-based technical discussions that bridge docs, StackOverflow, and so much more
|
||||
</div>
|
||||
<a href="https://discuss.kubernetes.io/">Community forums ▶</a>
|
||||
<p>Topic-based technical discussions that bridge docs,
|
||||
troubleshooting, and so much more.</p>
|
||||
</div>
|
||||
|
||||
<div class="resourcebox">
|
||||
<img src="/images/community/twitter.png" alt="Twitter" style="width:80%;padding-bottom:2%">
|
||||
<a href="https://twitter.com/kubernetesio" style="color:#0662EE;display:block;margin-top:1%">
|
||||
twitter ▶
|
||||
<div id="twitter" class="community-resource">
|
||||
<a href="https://twitter.com/kubernetesio">
|
||||
<img src="/images/community/twitter.png" alt="Twitter">
|
||||
</a>
|
||||
<div class="resourceboxtext" style="font-size:12px;text-transform:none !important;font-weight:300;line-height:1.4em;color:#333333;margin-top:4%">Real-time announcements of blog posts, events, news, ideas
|
||||
</div>
|
||||
<a href="https://twitter.com/kubernetesio">Twitter ▶</a>
|
||||
<p><em>#kubernetesio</em></p>
|
||||
<p>Real-time announcements of blog posts, events, news, ideas.</p>
|
||||
</div>
|
||||
|
||||
<div class="resourcebox">
|
||||
<img src="/images/community/github.png" alt="GitHub" style="width:80%;padding-bottom:2%">
|
||||
<a href="https://github.com/kubernetes/kubernetes" style="color:#0662EE;display:block;margin-top:1%">
|
||||
github ▶
|
||||
<div id="github" class="community-resource">
|
||||
<a href="https://github.com/kubernetes/kubernetes">
|
||||
<img src="/images/community/github.png" alt="GitHub">
|
||||
</a>
|
||||
<div class="resourceboxtext" style="font-size:12px;text-transform:none !important;font-weight:300;line-height:1.4em;color:#333333;margin-top:4%">
|
||||
All the project and issue tracking, plus of course code
|
||||
</div>
|
||||
<a href="https://github.com/kubernetes/kubernetes">GitHub ▶</a>
|
||||
<p>All the project and issue tracking, plus of course code.</p>
|
||||
</div>
|
||||
|
||||
<div class="resourcebox">
|
||||
<img src="/images/community/stack.png" alt="Stack Overflow" style="width:80%;padding-bottom:2%">
|
||||
<a href="https://stackoverflow.com/search?q=kubernetes" style="color:#0662EE;display:block;margin-top:1%">
|
||||
stack overflow ▶
|
||||
<div id="server-fault" class="community-resource">
|
||||
<a href="https://serverfault.com/questions/tagged/kubernetes">
|
||||
<img src="/images/community/serverfault.png" alt="Server Fault">
|
||||
</a>
|
||||
<div class="resourceboxtext" style="font-size:12px;text-transform:none !important;font-weight:300;line-height:1.4em;color:#333333;margin-top:4%">
|
||||
Technical troubleshooting for any use case
|
||||
<a name="events"></a>
|
||||
<a href="https://serverfault.com/questions/tagged/kubernetes">Server Fault ▶</a>
|
||||
<p>Kubernetes-related discussion on Server Fault. Ask a question, or answer one.</p>
|
||||
</div>
|
||||
|
||||
<div id="slack" class="community-resource">
|
||||
<a href="https://kubernetes.slack.com/">
|
||||
<img src="/images/community/slack.png" alt="Slack">
|
||||
</a>
|
||||
<a href="https://kubernetes.slack.com/">Slack ▶</a>
|
||||
<p>With 170+ channels, you'll find one that fits your needs.</p>
|
||||
<details><summary><em>Need an invitation?</em></summary>
|
||||
Visit <a href="https://slack.k8s.io/">https://slack.k8s.io/</a>
|
||||
for an invitation.</details>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<div class="resourcebox">
|
||||
|
||||
<img src="/images/community/slack.png" style="width:80%">
|
||||
|
||||
slack ▶
|
||||
|
||||
<div class="resourceboxtext" style="font-size:11px;text-transform:none !important;font-weight:200;line-height:1.4em;color:#333333;margin-top:4%">
|
||||
With 170+ channels, you'll find one that fits your needs.
|
||||
</div>
|
||||
|
||||
</div>-->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="events">
|
||||
<br class="mobile"><br class="mobile">
|
||||
<br class="tablet"><br class="tablet">
|
||||
<div class="eventcontainer">
|
||||
<h1 style="color:white !important">Upcoming Events</h1>
|
||||
<div class="community-section" id="events">
|
||||
<div class="container">
|
||||
<h2>Upcoming Events</h2>
|
||||
{{< upcoming-events >}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="meetups">
|
||||
<div class="meetupcol">
|
||||
<div class="meetuptext">
|
||||
<h1 style="text-align:left">Global Community</h1>
|
||||
<div class="community-section" id="meetups">
|
||||
<h2>Global community</h2>
|
||||
<p>
|
||||
With over 150 meetups in the world and growing, go find your local kube people. If one isn't near, take charge and create your own.
|
||||
</div>
|
||||
<a href="https://www.meetup.com/topics/kubernetes/">
|
||||
<div class="button">
|
||||
FIND A MEETUP
|
||||
</div>
|
||||
</p>
|
||||
<a href="https://www.meetup.com/topics/kubernetes/" class="community-cta-button">
|
||||
<span class="community-cta">Find a meetup</span>
|
||||
</a>
|
||||
<a name="news"></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!--
|
||||
<div class="contributor">
|
||||
<div class="contributortext">
|
||||
<br>
|
||||
<h1 style="text-align:left">
|
||||
New Contributors Site
|
||||
</h1>
|
||||
Text about new contributors site.
|
||||
|
||||
<br><br>
|
||||
|
||||
<div class="button">
|
||||
VISIT SITE
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
-->
|
||||
|
||||
<div class="news">
|
||||
<br class="mobile"><br class="mobile">
|
||||
<br class="tablet"><br class="tablet">
|
||||
<h1 style="margin-bottom:2%">Recent News</h1>
|
||||
|
||||
<br>
|
||||
<div class="community-section community-frame" id="news">
|
||||
<h2>Recent News</h2>
|
||||
<div class="twittercol1">
|
||||
<a class="twitter-timeline" data-tweet-limit="1" href="https://twitter.com/kubernetesio?ref_src=twsrc%5Etfw">Tweets by kubernetesio</a> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
|
||||
<a class="twitter-timeline" data-tweet-limit="1" href="https://twitter.com/kubernetesio?ref_src=twsrc%5Etfw">Tweets by kubernetesio</a>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<br><br><br><br>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,27 +1,29 @@
|
||||
---
|
||||
title: Community
|
||||
title: Kubernetes Community Code of Conduct
|
||||
layout: basic
|
||||
cid: community
|
||||
css: /css/community.css
|
||||
community_styles_migrated: true
|
||||
---
|
||||
|
||||
<div class="community_main">
|
||||
<h1>Kubernetes Community Code of Conduct</h1>
|
||||
|
||||
<div class="community-section" id="cncf-code-of-conduct-intro">
|
||||
<p>
|
||||
Kubernetes follows the
|
||||
<a href="https://github.com/cncf/foundation/blob/master/code-of-conduct.md">CNCF Code of Conduct</a>.
|
||||
The text of the CNCF CoC is replicated below, as of
|
||||
<a href="https://github.com/cncf/foundation/blob/214585e24aab747fb85c2ea44fbf4a2442e30de6/code-of-conduct.md">commit 214585e</a>.
|
||||
If you notice that this is out of date, please
|
||||
<a href="https://github.com/kubernetes/website/issues/new">file an issue</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If you notice a violation of the Code of Conduct at an event or meeting, in
|
||||
Slack, or in another communication mechanism, reach out to
|
||||
the <a href="https://git.k8s.io/community/committee-code-of-conduct">Kubernetes Code of Conduct Committee</a>.
|
||||
You can reach us by email at <a href="mailto:conduct@kubernetes.io">conduct@kubernetes.io</a>.
|
||||
Your anonymity will be protected.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="cncf_coc_container">
|
||||
<div id="cncf-code-of-conduct">
|
||||
{{< include "/static/cncf-code-of-conduct.md" >}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
# See the OWNERS docs at https://go.k8s.io/owners
|
||||
|
||||
# Disable inheritance to encourage careful review of any changes here.
|
||||
options:
|
||||
no_parent_owners: true
|
||||
approvers:
|
||||
- sig-docs-leads
|
||||
@@ -1,2 +1,5 @@
|
||||
The files in this directory have been imported from other sources. Do not
|
||||
edit them directly, except by replacing them with new versions.
|
||||
|
||||
Localization note: you do not need to create localized versions of any of
|
||||
the files in this directory.
|
||||
@@ -1,13 +1,18 @@
|
||||
---
|
||||
title: Community
|
||||
title: Kubernetes Community Values
|
||||
layout: basic
|
||||
cid: community
|
||||
css: /css/community.css
|
||||
community_styles_migrated: true
|
||||
|
||||
# this page is deprecated
|
||||
# canonical page is https://www.kubernetes.dev/community/values/
|
||||
sitemap:
|
||||
priority: 0.1
|
||||
---
|
||||
|
||||
<div class="community_main">
|
||||
|
||||
<div class="cncf_coc_container">
|
||||
<div class="community-section" id="values-legacy">
|
||||
{{< include "/static/community-values.md" >}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- no need to localize this file, nor the contents of the static directory -->
|
||||
<!-- if localizing, find the appropriate localized version of the CNCF code of
|
||||
conduct, and link directly to that -->
|
||||
|
||||
@@ -33,9 +33,9 @@ There are two main ways to have Nodes added to the {{< glossary_tooltip text="AP
|
||||
1. The kubelet on a node self-registers to the control plane
|
||||
2. You (or another human user) manually add a Node object
|
||||
|
||||
After you create a Node {{< glossary_tooltip text="object" term_id="object" >}}, or the kubelet on a node self-registers, the
|
||||
control plane checks whether the new Node object is valid. For example, if you
|
||||
try to create a Node from the following JSON manifest:
|
||||
After you create a Node {{< glossary_tooltip text="object" term_id="object" >}},
|
||||
or the kubelet on a node self-registers, the control plane checks whether the new Node object is
|
||||
valid. For example, if you try to create a Node from the following JSON manifest:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -86,18 +86,22 @@ register itself with the API server. This is the preferred pattern, used by mos
|
||||
For self-registration, the kubelet is started with the following options:
|
||||
|
||||
- `--kubeconfig` - Path to credentials to authenticate itself to the API server.
|
||||
- `--cloud-provider` - How to talk to a {{< glossary_tooltip text="cloud provider" term_id="cloud-provider" >}} to read metadata about itself.
|
||||
- `--cloud-provider` - How to talk to a {{< glossary_tooltip text="cloud provider" term_id="cloud-provider" >}}
|
||||
to read metadata about itself.
|
||||
- `--register-node` - Automatically register with the API server.
|
||||
- `--register-with-taints` - Register the node with the given list of {{< glossary_tooltip text="taints" term_id="taint" >}} (comma separated `<key>=<value>:<effect>`).
|
||||
- `--register-with-taints` - Register the node with the given list of
|
||||
{{< glossary_tooltip text="taints" term_id="taint" >}} (comma separated `<key>=<value>:<effect>`).
|
||||
|
||||
No-op if `register-node` is false.
|
||||
- `--node-ip` - IP address of the node.
|
||||
- `--node-labels` - {{< glossary_tooltip text="Labels" term_id="label" >}} to add when registering the node in the cluster (see label restrictions enforced by the [NodeRestriction admission plugin](/docs/reference/access-authn-authz/admission-controllers/#noderestriction)).
|
||||
- `--node-labels` - {{< glossary_tooltip text="Labels" term_id="label" >}} to add when registering the node
|
||||
in the cluster (see label restrictions enforced by the
|
||||
[NodeRestriction admission plugin](/docs/reference/access-authn-authz/admission-controllers/#noderestriction)).
|
||||
- `--node-status-update-frequency` - Specifies how often kubelet posts its node status to the API server.
|
||||
|
||||
When the [Node authorization mode](/docs/reference/access-authn-authz/node/) and
|
||||
[NodeRestriction admission plugin](/docs/reference/access-authn-authz/admission-controllers/#noderestriction) are enabled,
|
||||
kubelets are only authorized to create/modify their own Node resource.
|
||||
[NodeRestriction admission plugin](/docs/reference/access-authn-authz/admission-controllers/#noderestriction)
|
||||
are enabled, kubelets are only authorized to create/modify their own Node resource.
|
||||
|
||||
{{< note >}}
|
||||
As mentioned in the [Node name uniqueness](#node-name-uniqueness) section,
|
||||
@@ -168,8 +172,10 @@ Each section of the output is described below.
|
||||
|
||||
The usage of these fields varies depending on your cloud provider or bare metal configuration.
|
||||
|
||||
* HostName: The hostname as reported by the node's kernel. Can be overridden via the kubelet `--hostname-override` parameter.
|
||||
* ExternalIP: Typically the IP address of the node that is externally routable (available from outside the cluster).
|
||||
* HostName: The hostname as reported by the node's kernel. Can be overridden via the kubelet
|
||||
`--hostname-override` parameter.
|
||||
* ExternalIP: Typically the IP address of the node that is externally routable (available from
|
||||
outside the cluster).
|
||||
* InternalIP: Typically the IP address of the node that is routable only within the cluster.
|
||||
|
||||
|
||||
@@ -289,7 +295,6 @@ and for updating their related Leases.
|
||||
updates to the Node's `.status`. If the Lease update fails, the kubelet retries,
|
||||
using exponential backoff that starts at 200 milliseconds and capped at 7 seconds.
|
||||
|
||||
|
||||
## Node controller
|
||||
|
||||
The node {{< glossary_tooltip text="controller" term_id="controller" >}} is a
|
||||
@@ -306,6 +311,7 @@ controller deletes the node from its list of nodes.
|
||||
|
||||
The third is monitoring the nodes' health. The node controller is
|
||||
responsible for:
|
||||
|
||||
- In the case that a node becomes unreachable, updating the NodeReady condition
|
||||
of within the Node's `.status`. In this case the node controller sets the
|
||||
NodeReady condition to `ConditionUnknown`.
|
||||
@@ -327,6 +333,7 @@ The node eviction behavior changes when a node in a given availability zone
|
||||
becomes unhealthy. The node controller checks what percentage of nodes in the zone
|
||||
are unhealthy (NodeReady condition is `ConditionUnknown` or `ConditionFalse`) at
|
||||
the same time:
|
||||
|
||||
- If the fraction of unhealthy nodes is at least `--unhealthy-zone-threshold`
|
||||
(default 0.55), then the eviction rate is reduced.
|
||||
- If the cluster is small (i.e. has less than or equal to
|
||||
@@ -391,7 +398,9 @@ for more information.
|
||||
|
||||
The kubelet attempts to detect node system shutdown and terminates pods running on the node.
|
||||
|
||||
Kubelet ensures that pods follow the normal [pod termination process](/docs/concepts/workloads/pods/pod-lifecycle/#pod-termination) during the node shutdown.
|
||||
Kubelet ensures that pods follow the normal
|
||||
[pod termination process](/docs/concepts/workloads/pods/pod-lifecycle/#pod-termination)
|
||||
during the node shutdown.
|
||||
|
||||
The Graceful node shutdown feature depends on systemd since it takes advantage of
|
||||
[systemd inhibitor locks](https://www.freedesktop.org/wiki/Software/systemd/inhibit/) to
|
||||
@@ -404,18 +413,26 @@ enabled by default in 1.21.
|
||||
Note that by default, both configuration options described below,
|
||||
`shutdownGracePeriod` and `shutdownGracePeriodCriticalPods` are set to zero,
|
||||
thus not activating Graceful node shutdown functionality.
|
||||
To activate the feature, the two kubelet config settings should be configured appropriately and set to non-zero values.
|
||||
To activate the feature, the two kubelet config settings should be configured appropriately and
|
||||
set to non-zero values.
|
||||
|
||||
During a graceful shutdown, kubelet terminates pods in two phases:
|
||||
|
||||
1. Terminate regular pods running on the node.
|
||||
2. Terminate [critical pods](/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods/#marking-pod-as-critical) running on the node.
|
||||
2. Terminate [critical pods](/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods/#marking-pod-as-critical)
|
||||
running on the node.
|
||||
|
||||
Graceful node shutdown feature is configured with two
|
||||
[`KubeletConfiguration`](/docs/tasks/administer-cluster/kubelet-config-file/) options:
|
||||
|
||||
Graceful node shutdown feature is configured with two [`KubeletConfiguration`](/docs/tasks/administer-cluster/kubelet-config-file/) options:
|
||||
* `shutdownGracePeriod`:
|
||||
* Specifies the total duration that the node should delay the shutdown by. This is the total grace period for pod termination for both regular and [critical pods](/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods/#marking-pod-as-critical).
|
||||
* Specifies the total duration that the node should delay the shutdown by. This is the total
|
||||
grace period for pod termination for both regular and
|
||||
[critical pods](/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods/#marking-pod-as-critical).
|
||||
* `shutdownGracePeriodCriticalPods`:
|
||||
* Specifies the duration used to terminate [critical pods](/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods/#marking-pod-as-critical) during a node shutdown. This value should be less than `shutdownGracePeriod`.
|
||||
* Specifies the duration used to terminate
|
||||
[critical pods](/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods/#marking-pod-as-critical)
|
||||
during a node shutdown. This value should be less than `shutdownGracePeriod`.
|
||||
|
||||
For example, if `shutdownGracePeriod=30s`, and
|
||||
`shutdownGracePeriodCriticalPods=10s`, kubelet will delay the node shutdown by
|
||||
@@ -443,8 +460,8 @@ To provide more flexibility during graceful node shutdown around the ordering
|
||||
of pods during shutdown, graceful node shutdown honors the PriorityClass for
|
||||
Pods, provided that you enabled this feature in your cluster. The feature
|
||||
allows cluster administers to explicitly define the ordering of pods
|
||||
during graceful node shutdown based on [priority
|
||||
classes](docs/concepts/scheduling-eviction/pod-priority-preemption/#priorityclass).
|
||||
during graceful node shutdown based on
|
||||
[priority classes](/docs/concepts/scheduling-eviction/pod-priority-preemption/#priorityclass).
|
||||
|
||||
The [Graceful Node Shutdown](#graceful-node-shutdown) feature, as described
|
||||
above, shuts down pods in two phases, non-critical pods, followed by critical
|
||||
@@ -457,8 +474,8 @@ graceful node shutdown in multiple phases, each phase shutting down a
|
||||
particular priority class of pods. The kubelet can be configured with the exact
|
||||
phases and shutdown time per phase.
|
||||
|
||||
Assuming the following custom pod [priority
|
||||
classes](docs/concepts/scheduling-eviction/pod-priority-preemption/#priorityclass)
|
||||
Assuming the following custom pod
|
||||
[priority classes](/docs/concepts/scheduling-eviction/pod-priority-preemption/#priorityclass)
|
||||
in a cluster,
|
||||
|
||||
|Pod priority class name|Pod priority class value|
|
||||
@@ -492,7 +509,7 @@ shutdownGracePeriodByPodPriority:
|
||||
shutdownGracePeriodSeconds: 60
|
||||
```
|
||||
|
||||
The above table implies that any pod with priority value >= 100000 will get
|
||||
The above table implies that any pod with `priority` value >= 100000 will get
|
||||
just 10 seconds to stop, any pod with value >= 10000 and < 100000 will get 180
|
||||
seconds to stop, any pod with value >= 1000 and < 10000 will get 120 seconds to stop.
|
||||
Finally, all other pods will get 60 seconds to stop.
|
||||
@@ -507,8 +524,8 @@ example, you could instead use these settings:
|
||||
| 0 |60 seconds |
|
||||
|
||||
|
||||
In the above case, the pods with custom-class-b will go into the same bucket
|
||||
as custom-class-c for shutdown.
|
||||
In the above case, the pods with `custom-class-b` will go into the same bucket
|
||||
as `custom-class-c` for shutdown.
|
||||
|
||||
If there are no pods in a particular range, then the kubelet does not wait
|
||||
for pods in that priority range. Instead, the kubelet immediately skips to the
|
||||
@@ -577,3 +594,4 @@ see [KEP-2400](https://github.com/kubernetes/enhancements/issues/2400) and its
|
||||
* Read the [Node](https://git.k8s.io/community/contributors/design-proposals/architecture/architecture.md#the-kubernetes-node)
|
||||
section of the architecture design document.
|
||||
* Read about [taints and tolerations](/docs/concepts/scheduling-eviction/taint-and-toleration/).
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ that lets you store configuration for other objects to use. Unlike most
|
||||
Kubernetes objects that have a `spec`, a ConfigMap has `data` and `binaryData`
|
||||
fields. These fields accept key-value pairs as their values. Both the `data`
|
||||
field and the `binaryData` are optional. The `data` field is designed to
|
||||
contain UTF-8 byte sequences while the `binaryData` field is designed to
|
||||
contain UTF-8 strings while the `binaryData` field is designed to
|
||||
contain binary data as base64-encoded strings.
|
||||
|
||||
The name of a ConfigMap must be a valid
|
||||
|
||||
@@ -148,7 +148,28 @@ File references on the command line are relative to the current working director
|
||||
In `$HOME/.kube/config`, relative paths are stored relatively, and absolute paths
|
||||
are stored absolutely.
|
||||
|
||||
## Proxy
|
||||
|
||||
You can configure `kubectl` to use proxy by setting `proxy-url` in the kubeconfig file, like:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Config
|
||||
|
||||
proxy-url: https://proxy.host:3128
|
||||
|
||||
clusters:
|
||||
- cluster:
|
||||
name: development
|
||||
|
||||
users:
|
||||
- name: developer
|
||||
|
||||
contexts:
|
||||
- context:
|
||||
name: development
|
||||
|
||||
```
|
||||
|
||||
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -29,8 +29,7 @@ and possibly a port number as well; for example: `fictional.registry.example:104
|
||||
|
||||
If you don't specify a registry hostname, Kubernetes assumes that you mean the Docker public registry.
|
||||
|
||||
After the image name part you can add a _tag_ (as also using with commands such
|
||||
as `docker` and `podman`).
|
||||
After the image name part you can add a _tag_ (in the same way you would when using with commands like `docker` or `podman`).
|
||||
Tags let you identify different versions of the same series of images.
|
||||
|
||||
Image tags consist of lowercase and uppercase letters, digits, underscores (`_`),
|
||||
@@ -91,7 +90,7 @@ the image's digest;
|
||||
replace `<image-name>:<tag>` with `<image-name>@<digest>`
|
||||
(for example, `image@sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2`).
|
||||
|
||||
When using image tags, if the image registry were to change the code that the tag on that image represents, you might end up with a mix of Pods running the old and new code. An image digest uniquely identifies a specific version of the image, so Kubernetes runs the same code every time it starts a container with that image name and digest specified. Specifying an image fixes the code that you run so that a change at the registry cannot lead to that mix of versions.
|
||||
When using image tags, if the image registry were to change the code that the tag on that image represents, you might end up with a mix of Pods running the old and new code. An image digest uniquely identifies a specific version of the image, so Kubernetes runs the same code every time it starts a container with that image name and digest specified. Specifying an image by digest fixes the code that you run so that a change at the registry cannot lead to that mix of versions.
|
||||
|
||||
There are third-party [admission controllers](/docs/reference/access-authn-authz/admission-controllers/)
|
||||
that mutate Pods (and pod templates) when they are created, so that the
|
||||
@@ -175,95 +174,11 @@ These options are explained in more detail below.
|
||||
|
||||
### Configuring nodes to authenticate to a private registry
|
||||
|
||||
If you run Docker on your nodes, you can configure the Docker container
|
||||
runtime to authenticate to a private container registry.
|
||||
Specific instructions for setting credentials depends on the container runtime and registry you chose to use. You should refer to your solution's documentation for the most accurate information.
|
||||
|
||||
This approach is suitable if you can control node configuration.
|
||||
|
||||
{{< note >}}
|
||||
Default Kubernetes only supports the `auths` and `HttpHeaders` section in Docker configuration.
|
||||
Docker credential helpers (`credHelpers` or `credsStore`) are not supported.
|
||||
{{< /note >}}
|
||||
|
||||
|
||||
Docker stores keys for private registries in the `$HOME/.dockercfg` or `$HOME/.docker/config.json` file. If you put the same file
|
||||
in the search paths list below, kubelet uses it as the credential provider when pulling images.
|
||||
|
||||
* `{--root-dir:-/var/lib/kubelet}/config.json`
|
||||
* `{cwd of kubelet}/config.json`
|
||||
* `${HOME}/.docker/config.json`
|
||||
* `/.docker/config.json`
|
||||
* `{--root-dir:-/var/lib/kubelet}/.dockercfg`
|
||||
* `{cwd of kubelet}/.dockercfg`
|
||||
* `${HOME}/.dockercfg`
|
||||
* `/.dockercfg`
|
||||
|
||||
{{< note >}}
|
||||
You may have to set `HOME=/root` explicitly in the environment of the kubelet process.
|
||||
{{< /note >}}
|
||||
|
||||
Here are the recommended steps to configuring your nodes to use a private registry. In this
|
||||
example, run these on your desktop/laptop:
|
||||
|
||||
1. Run `docker login [server]` for each set of credentials you want to use. This updates `$HOME/.docker/config.json` on your PC.
|
||||
1. View `$HOME/.docker/config.json` in an editor to ensure it contains only the credentials you want to use.
|
||||
1. Get a list of your nodes; for example:
|
||||
- if you want the names: `nodes=$( kubectl get nodes -o jsonpath='{range.items[*].metadata}{.name} {end}' )`
|
||||
- if you want to get the IP addresses: `nodes=$( kubectl get nodes -o jsonpath='{range .items[*].status.addresses[?(@.type=="ExternalIP")]}{.address} {end}' )`
|
||||
1. Copy your local `.docker/config.json` to one of the search paths list above.
|
||||
- for example, to test this out: `for n in $nodes; do scp ~/.docker/config.json root@"$n":/var/lib/kubelet/config.json; done`
|
||||
|
||||
{{< note >}}
|
||||
For production clusters, use a configuration management tool so that you can apply this
|
||||
setting to all the nodes where you need it.
|
||||
{{< /note >}}
|
||||
|
||||
Verify by creating a Pod that uses a private image; for example:
|
||||
|
||||
```shell
|
||||
kubectl apply -f - <<EOF
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: private-image-test-1
|
||||
spec:
|
||||
containers:
|
||||
- name: uses-private-image
|
||||
image: $PRIVATE_IMAGE_NAME
|
||||
imagePullPolicy: Always
|
||||
command: [ "echo", "SUCCESS" ]
|
||||
EOF
|
||||
```
|
||||
```
|
||||
pod/private-image-test-1 created
|
||||
```
|
||||
|
||||
If everything is working, then, after a few moments, you can run:
|
||||
|
||||
```shell
|
||||
kubectl logs private-image-test-1
|
||||
```
|
||||
and see that the command outputs:
|
||||
```
|
||||
SUCCESS
|
||||
```
|
||||
|
||||
If you suspect that the command failed, you can run:
|
||||
```shell
|
||||
kubectl describe pods/private-image-test-1 | grep 'Failed'
|
||||
```
|
||||
In case of failure, the output is similar to:
|
||||
```
|
||||
Fri, 26 Jun 2015 15:36:13 -0700 Fri, 26 Jun 2015 15:39:13 -0700 19 {kubelet node-i2hq} spec.containers{uses-private-image} failed Failed to pull image "user/privaterepo:v1": Error: image user/privaterepo:v1 not found
|
||||
```
|
||||
|
||||
|
||||
You must ensure all nodes in the cluster have the same `.docker/config.json`. Otherwise, pods will run on
|
||||
some nodes and fail to run on others. For example, if you use node autoscaling, then each instance
|
||||
template needs to include the `.docker/config.json` or mount a drive that contains it.
|
||||
|
||||
All pods will have read access to images in any private registry once private
|
||||
registry keys are added to the `.docker/config.json`.
|
||||
For an example of configuring a private container image registry, see the
|
||||
[Pull an Image from a Private Registry](/docs/tasks/configure-pod-container/pull-image-private-registry)
|
||||
task. That example uses a private registry in Docker Hub.
|
||||
|
||||
### Interpretation of config.json {#config-json}
|
||||
|
||||
@@ -332,6 +247,7 @@ If now a container specifies an image `my-registry.io/images/subpath/my-image`
|
||||
to be pulled, then the kubelet will try to download them from both
|
||||
authentication sources if one of them fails.
|
||||
|
||||
|
||||
### Pre-pulled images
|
||||
|
||||
{{< note >}}
|
||||
@@ -362,6 +278,8 @@ Kubernetes supports specifying container image registry keys on a Pod.
|
||||
|
||||
#### Creating a Secret with a Docker config
|
||||
|
||||
You need to know the username, registry password and client email address for authenticating
|
||||
to the registry, as well as its hostname.
|
||||
Run the following command, substituting the appropriate uppercase values:
|
||||
|
||||
```shell
|
||||
@@ -426,14 +344,13 @@ There are a number of solutions for configuring private registries. Here are so
|
||||
common use cases and suggested solutions.
|
||||
|
||||
1. Cluster running only non-proprietary (e.g. open-source) images. No need to hide images.
|
||||
- Use public images on the Docker hub.
|
||||
- Use public images from a public registry
|
||||
- No configuration required.
|
||||
- Some cloud providers automatically cache or mirror public images, which improves availability and reduces the time to pull images.
|
||||
1. Cluster running some proprietary images which should be hidden to those outside the company, but
|
||||
visible to all cluster users.
|
||||
- Use a hosted private [Docker registry](https://docs.docker.com/registry/).
|
||||
- It may be hosted on the [Docker Hub](https://hub.docker.com/signup), or elsewhere.
|
||||
- Manually configure .docker/config.json on each node as described above.
|
||||
- Use a hosted private registry
|
||||
- Manual configuration may be required on the nodes that need to access to private registry
|
||||
- Or, run an internal private registry behind your firewall with open read access.
|
||||
- No Kubernetes configuration is required.
|
||||
- Use a hosted container image registry service that controls image access
|
||||
@@ -450,8 +367,6 @@ common use cases and suggested solutions.
|
||||
|
||||
|
||||
If you need access to multiple registries, you can create one secret for each registry.
|
||||
Kubelet will merge any `imagePullSecrets` into a single virtual `.docker/config.json`
|
||||
|
||||
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
|
||||
@@ -344,7 +344,7 @@ pluginapi.Device{ID: "25102017", Health: pluginapi.Healthy, Topology:&pluginapi.
|
||||
Here are some examples of device plugin implementations:
|
||||
|
||||
* The [AMD GPU device plugin](https://github.com/RadeonOpenCompute/k8s-device-plugin)
|
||||
* The [Intel device plugins](https://github.com/intel/intel-device-plugins-for-kubernetes) for Intel GPU, FPGA and QuickAssist devices
|
||||
* The [Intel device plugins](https://github.com/intel/intel-device-plugins-for-kubernetes) for Intel GPU, FPGA, QAT, VPU, SGX, DSA, DLB and IAA devices
|
||||
* The [KubeVirt device plugins](https://github.com/kubevirt/kubernetes-device-plugins) for hardware-assisted virtualization
|
||||
* The [NVIDIA GPU device plugin](https://github.com/NVIDIA/k8s-device-plugin)
|
||||
* Requires [nvidia-docker](https://github.com/NVIDIA/nvidia-docker) 2.0, which allows you to run GPU-enabled Docker containers.
|
||||
|
||||
@@ -12,158 +12,181 @@ weight: 20
|
||||
<!-- overview -->
|
||||
|
||||
You can constrain a {{< glossary_tooltip text="Pod" term_id="pod" >}} so that it can only run on particular set of
|
||||
{{< glossary_tooltip text="Node(s)" term_id="node" >}}.
|
||||
{{< glossary_tooltip text="node(s)" term_id="node" >}}.
|
||||
There are several ways to do this and the recommended approaches all use
|
||||
[label selectors](/docs/concepts/overview/working-with-objects/labels/) to facilitate the selection.
|
||||
Generally such constraints are unnecessary, as the scheduler will automatically do a reasonable placement
|
||||
(e.g. spread your pods across nodes so as not place the pod on a node with insufficient free resources, etc.)
|
||||
but there are some circumstances where you may want to control which node the pod deploys to - for example to ensure
|
||||
that a pod ends up on a machine with an SSD attached to it, or to co-locate pods from two different
|
||||
(for example, spreading your Pods across nodes so as not place Pods on a node with insufficient free resources).
|
||||
However, there are some circumstances where you may want to control which node
|
||||
the Pod deploys to, for example, to ensure that a Pod ends up on a node with an SSD attached to it, or to co-locate Pods from two different
|
||||
services that communicate a lot into the same availability zone.
|
||||
|
||||
|
||||
<!-- body -->
|
||||
|
||||
You can use any of the following methods to choose where Kubernetes schedules
|
||||
specific Pods:
|
||||
|
||||
* [nodeSelector](#nodeselector) field matching against [node labels](#built-in-node-labels)
|
||||
* [Affinity and anti-affinity](#affinity-and-anti-affinity)
|
||||
* [nodeName](#nodename) field
|
||||
|
||||
## Node labels {#built-in-node-labels}
|
||||
|
||||
Like many other Kubernetes objects, nodes have
|
||||
[labels](/docs/concepts/overview/working-with-objects/labels/). You can [attach labels manually](/docs/tasks/confiure-pod-container/assign-pods-nodes/#add-a-label-to-a-node).
|
||||
Kubernetes also populates a standard set of labels on all nodes in a cluster. See [Well-Known Labels, Annotations and Taints](/docs/reference/labels-annotations-taints/)
|
||||
for a list of common node labels.
|
||||
|
||||
{{<note>}}
|
||||
The value of these labels is cloud provider specific and is not guaranteed to be reliable.
|
||||
For example, the value of `kubernetes.io/hostname` may be the same as the node name in some environments
|
||||
and a different value in other environments.
|
||||
{{</note>}}
|
||||
|
||||
### Node isolation/restriction
|
||||
|
||||
Adding labels to nodes allows you to target Pods for scheduling on specific
|
||||
nodes or groups of nodes. You can use this functionality to ensure that specific
|
||||
Pods only run on nodes with certain isolation, security, or regulatory
|
||||
properties.
|
||||
|
||||
If you use labels for node isolation, choose label keys that the {{<glossary_tooltip text="kubelet" term_id="kubelet">}}
|
||||
cannot modify. This prevents a compromised node from setting those labels on
|
||||
itself so that the scheduler schedules workloads onto the compromised node.
|
||||
|
||||
The [`NodeRestriction` admission plugin](/docs/reference/access-authn-authz/admission-controllers/#noderestriction)
|
||||
prevents the kubelet from setting or modifying labels with a
|
||||
`node-restriction.kubernetes.io/` prefix.
|
||||
|
||||
To make use of that label prefix for node isolation:
|
||||
|
||||
1. Ensure you are using the [Node authorizer](/docs/reference/access-authn-authz/node/) and have _enabled_ the `NodeRestriction` admission plugin.
|
||||
2. Add labels with the `node-restriction.kubernetes.io/` prefix to your nodes, and use those labels in your [node selectors](#nodeselector).
|
||||
For example, `example.com.node-restriction.kubernetes.io/fips=true` or `example.com.node-restriction.kubernetes.io/pci-dss=true`.
|
||||
|
||||
## nodeSelector
|
||||
|
||||
`nodeSelector` is the simplest recommended form of node selection constraint.
|
||||
`nodeSelector` is a field of PodSpec. It specifies a map of key-value pairs. For the pod to be eligible
|
||||
to run on a node, the node must have each of the indicated key-value pairs as labels (it can have
|
||||
additional labels as well). The most common usage is one key-value pair.
|
||||
You can add the `nodeSelector` field to your Pod specification and specify the
|
||||
[node labels](#built-in-node-labels) you want the target node to have.
|
||||
Kubernetes only schedules the Pod onto nodes that have each of the labels you
|
||||
specify.
|
||||
|
||||
Let's walk through an example of how to use `nodeSelector`.
|
||||
|
||||
### Step Zero: Prerequisites
|
||||
|
||||
This example assumes that you have a basic understanding of Kubernetes pods and that you have [set up a Kubernetes cluster](/docs/setup/).
|
||||
|
||||
### Step One: Attach label to the node
|
||||
|
||||
Run `kubectl get nodes` to get the names of your cluster's nodes. Pick out the one that you want to add a label to, and then run `kubectl label nodes <node-name> <label-key>=<label-value>` to add a label to the node you've chosen. For example, if my node name is 'kubernetes-foo-node-1.c.a-robinson.internal' and my desired label is 'disktype=ssd', then I can run `kubectl label nodes kubernetes-foo-node-1.c.a-robinson.internal disktype=ssd`.
|
||||
|
||||
You can verify that it worked by re-running `kubectl get nodes --show-labels` and checking that the node now has a label. You can also use `kubectl describe node "nodename"` to see the full list of labels of the given node.
|
||||
|
||||
### Step Two: Add a nodeSelector field to your pod configuration
|
||||
|
||||
Take whatever pod config file you want to run, and add a nodeSelector section to it, like this. For example, if this is my pod config:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: nginx
|
||||
labels:
|
||||
env: test
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx
|
||||
```
|
||||
|
||||
Then add a nodeSelector like so:
|
||||
|
||||
{{< codenew file="pods/pod-nginx.yaml" >}}
|
||||
|
||||
When you then run `kubectl apply -f https://k8s.io/examples/pods/pod-nginx.yaml`,
|
||||
the Pod will get scheduled on the node that you attached the label to. You can
|
||||
verify that it worked by running `kubectl get pods -o wide` and looking at the
|
||||
"NODE" that the Pod was assigned to.
|
||||
|
||||
## Interlude: built-in node labels {#built-in-node-labels}
|
||||
|
||||
In addition to labels you [attach](#step-one-attach-label-to-the-node), nodes come pre-populated
|
||||
with a standard set of labels. See [Well-Known Labels, Annotations and Taints](/docs/reference/labels-annotations-taints/) for a list of these.
|
||||
|
||||
{{< note >}}
|
||||
The value of these labels is cloud provider specific and is not guaranteed to be reliable.
|
||||
For example, the value of `kubernetes.io/hostname` may be the same as the Node name in some environments
|
||||
and a different value in other environments.
|
||||
{{< /note >}}
|
||||
|
||||
## Node isolation/restriction
|
||||
|
||||
Adding labels to Node objects allows targeting pods to specific nodes or groups of nodes.
|
||||
This can be used to ensure specific pods only run on nodes with certain isolation, security, or regulatory properties.
|
||||
When using labels for this purpose, choosing label keys that cannot be modified by the kubelet process on the node is strongly recommended.
|
||||
This prevents a compromised node from using its kubelet credential to set those labels on its own Node object,
|
||||
and influencing the scheduler to schedule workloads to the compromised node.
|
||||
|
||||
The `NodeRestriction` admission plugin prevents kubelets from setting or modifying labels with a `node-restriction.kubernetes.io/` prefix.
|
||||
To make use of that label prefix for node isolation:
|
||||
|
||||
1. Ensure you are using the [Node authorizer](/docs/reference/access-authn-authz/node/) and have _enabled_ the [NodeRestriction admission plugin](/docs/reference/access-authn-authz/admission-controllers/#noderestriction).
|
||||
2. Add labels under the `node-restriction.kubernetes.io/` prefix to your Node objects, and use those labels in your node selectors.
|
||||
For example, `example.com.node-restriction.kubernetes.io/fips=true` or `example.com.node-restriction.kubernetes.io/pci-dss=true`.
|
||||
See [Assign Pods to Nodes](/docs/tasks/configure-pod-container/assign-pods-nodes) for more
|
||||
information.
|
||||
|
||||
## Affinity and anti-affinity
|
||||
|
||||
`nodeSelector` provides a very simple way to constrain pods to nodes with particular labels. The affinity/anti-affinity
|
||||
feature, greatly expands the types of constraints you can express. The key enhancements are
|
||||
`nodeSelector` is the simplest way to constrain Pods to nodes with specific
|
||||
labels. Affinity and anti-affinity expands the types of constraints you can
|
||||
define. Some of the benefits of affinity and anti-affinity include:
|
||||
|
||||
1. The affinity/anti-affinity language is more expressive. The language offers more matching rules
|
||||
besides exact matches created with a logical AND operation;
|
||||
2. you can indicate that the rule is "soft"/"preference" rather than a hard requirement, so if the scheduler
|
||||
can't satisfy it, the pod will still be scheduled;
|
||||
3. you can constrain against labels on other pods running on the node (or other topological domain),
|
||||
rather than against labels on the node itself, which allows rules about which pods can and cannot be co-located
|
||||
* The affinity/anti-affinity language is more expressive. `nodeSelector` only
|
||||
selects nodes with all the specified labels. Affinity/anti-affinity gives you
|
||||
more control over the selection logic.
|
||||
* You can indicate that a rule is *soft* or *preferred*, so that the scheduler
|
||||
still schedules the Pod even if it can't find a matching node.
|
||||
* You can constrain a Pod using labels on other Pods running on the node (or other topological domain),
|
||||
instead of just node labels, which allows you to define rules for which Pods
|
||||
can be co-located on a node.
|
||||
|
||||
The affinity feature consists of two types of affinity, "node affinity" and "inter-pod affinity/anti-affinity".
|
||||
Node affinity is like the existing `nodeSelector` (but with the first two benefits listed above),
|
||||
while inter-pod affinity/anti-affinity constrains against pod labels rather than node labels, as
|
||||
described in the third item listed above, in addition to having the first and second properties listed above.
|
||||
The affinity feature consists of two types of affinity:
|
||||
|
||||
* *Node affinity* functions like the `nodeSelector` field but is more expressive and
|
||||
allows you to specify soft rules.
|
||||
* *Inter-pod affinity/anti-affinity* allows you to constrain Pods against labels
|
||||
on other Pods.
|
||||
|
||||
### Node affinity
|
||||
|
||||
Node affinity is conceptually similar to `nodeSelector` -- it allows you to constrain which nodes your
|
||||
pod is eligible to be scheduled on, based on labels on the node.
|
||||
Node affinity is conceptually similar to `nodeSelector`, allowing you to constrain which nodes your
|
||||
Pod can be scheduled on based on node labels. There are two types of node
|
||||
affinity:
|
||||
|
||||
There are currently two types of node affinity, called `requiredDuringSchedulingIgnoredDuringExecution` and
|
||||
`preferredDuringSchedulingIgnoredDuringExecution`. You can think of them as "hard" and "soft" respectively,
|
||||
in the sense that the former specifies rules that *must* be met for a pod to be scheduled onto a node (similar to
|
||||
`nodeSelector` but using a more expressive syntax), while the latter specifies *preferences* that the scheduler
|
||||
will try to enforce but will not guarantee. The "IgnoredDuringExecution" part of the names means that, similar
|
||||
to how `nodeSelector` works, if labels on a node change at runtime such that the affinity rules on a pod are no longer
|
||||
met, the pod continues to run on the node. In the future we plan to offer
|
||||
`requiredDuringSchedulingRequiredDuringExecution` which will be identical to `requiredDuringSchedulingIgnoredDuringExecution`
|
||||
except that it will evict pods from nodes that cease to satisfy the pods' node affinity requirements.
|
||||
* `requiredDuringSchedulingIgnoredDuringExecution`: The scheduler can't
|
||||
schedule the Pod unless the rule is met. This functions like `nodeSelector`,
|
||||
but with a more expressive syntax.
|
||||
* `preferredDuringSchedulingIgnoredDuringExecution`: The scheduler tries to
|
||||
find a node that meets the rule. If a matching node is not available, the
|
||||
scheduler still schedules the Pod.
|
||||
|
||||
Thus an example of `requiredDuringSchedulingIgnoredDuringExecution` would be "only run the pod on nodes with Intel CPUs"
|
||||
and an example `preferredDuringSchedulingIgnoredDuringExecution` would be "try to run this set of pods in failure
|
||||
zone XYZ, but if it's not possible, then allow some to run elsewhere".
|
||||
{{<note>}}
|
||||
In the preceding types, `IgnoredDuringExecution` means that if the node labels
|
||||
change after Kubernetes schedules the Pod, the Pod continues to run.
|
||||
{{</note>}}
|
||||
|
||||
Node affinity is specified as field `nodeAffinity` of field `affinity` in the PodSpec.
|
||||
You can specify node affinities using the `.spec.affinity.nodeAffinity` field in
|
||||
your Pod spec.
|
||||
|
||||
Here's an example of a pod that uses node affinity:
|
||||
For example, consider the following Pod spec:
|
||||
|
||||
{{<codenew file="pods/pod-with-node-affinity.yaml">}}
|
||||
|
||||
This node affinity rule says the pod can only be placed on a node with a label whose key is
|
||||
`kubernetes.io/e2e-az-name` and whose value is either `e2e-az1` or `e2e-az2`. In addition,
|
||||
among nodes that meet that criteria, nodes with a label whose key is `another-node-label-key` and whose
|
||||
value is `another-node-label-value` should be preferred.
|
||||
In this example, the following rules apply:
|
||||
|
||||
You can see the operator `In` being used in the example. The new node affinity syntax supports the following operators: `In`, `NotIn`, `Exists`, `DoesNotExist`, `Gt`, `Lt`.
|
||||
You can use `NotIn` and `DoesNotExist` to achieve node anti-affinity behavior, or use
|
||||
[node taints](/docs/concepts/scheduling-eviction/taint-and-toleration/) to repel pods from specific nodes.
|
||||
* The node *must* have a label with the key `kubernetes.io/e2e-az-name` and
|
||||
the value is either `e2e-az1` or `e2e-az2`.
|
||||
* The node *preferably* has a label with the key `another-node-label-key` and
|
||||
the value `another-node-label-value`.
|
||||
|
||||
If you specify both `nodeSelector` and `nodeAffinity`, *both* must be satisfied for the pod
|
||||
to be scheduled onto a candidate node.
|
||||
You can use the `operator` field to specify a logical operator for Kubernetes to use when
|
||||
interpreting the rules. You can use `In`, `NotIn`, `Exists`, `DoesNotExist`,
|
||||
`Gt` and `Lt`.
|
||||
|
||||
If you specify multiple `nodeSelectorTerms` associated with `nodeAffinity` types, then the pod can be scheduled onto a node **if one of the** `nodeSelectorTerms` can be satisfied.
|
||||
`NotIn` and `DoesNotExist` allow you to define node anti-affinity behavior.
|
||||
Alternatively, you can use [node taints](/docs/concepts/scheduling-eviction/taint-and-toleration/)
|
||||
to repel Pods from specific nodes.
|
||||
|
||||
If you specify multiple `matchExpressions` associated with `nodeSelectorTerms`, then the pod can be scheduled onto a node **only if all** `matchExpressions` is satisfied.
|
||||
{{<note>}}
|
||||
If you specify both `nodeSelector` and `nodeAffinity`, *both* must be satisfied
|
||||
for the Pod to be scheduled onto a node.
|
||||
|
||||
If you remove or change the label of the node where the pod is scheduled, the pod won't be removed. In other words, the affinity selection works only at the time of scheduling the pod.
|
||||
If you specify multiple `nodeSelectorTerms` associated with `nodeAffinity`
|
||||
types, then the Pod can be scheduled onto a node if one of the specified `nodeSelectorTerms` can be
|
||||
satisfied.
|
||||
|
||||
The `weight` field in `preferredDuringSchedulingIgnoredDuringExecution` is in the range 1-100. For each node that meets all of the scheduling requirements (resource request, RequiredDuringScheduling affinity expressions, etc.), the scheduler will compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node matches the corresponding MatchExpressions. This score is then combined with the scores of other priority functions for the node. The node(s) with the highest total score are the most preferred.
|
||||
If you specify multiple `matchExpressions` associated with a single `nodeSelectorTerms`,
|
||||
then the Pod can be scheduled onto a node only if all the `matchExpressions` are
|
||||
satisfied.
|
||||
{{</note>}}
|
||||
|
||||
See [Assign Pods to Nodes using Node Affinity](/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/)
|
||||
for more information.
|
||||
|
||||
#### Node affinity weight
|
||||
|
||||
You can specify a `weight` between 1 and 100 for each instance of the
|
||||
`preferredDuringSchedulingIgnoredDuringExecution` affinity type. When the
|
||||
scheduler finds nodes that meet all the other scheduling requirements of the Pod, the
|
||||
scheduler iterates through every preferred rule that the node satisfies and adds the
|
||||
value of the `weight` for that expression to a sum.
|
||||
|
||||
The final sum is added to the score of other priority functions for the node.
|
||||
Nodes with the highest total score are prioritized when the scheduler makes a
|
||||
scheduling decision for the Pod.
|
||||
|
||||
For example, consider the following Pod spec:
|
||||
|
||||
{{<codenew file="pods/pod-with-affinity-anti-affinity.yaml">}}
|
||||
|
||||
If there are two possible nodes that match the
|
||||
`requiredDuringSchedulingIgnoredDuringExecution` rule, one with the
|
||||
`label-1:key-1` label and another with the `label-2:key-2` label, the scheduler
|
||||
considers the `weight` of each node and adds the weight to the other scores for
|
||||
that node, and schedules the Pod onto the node with the highest final score.
|
||||
|
||||
{{<note>}}
|
||||
If you want Kubernetes to successfully schedule the Pods in this example, you
|
||||
must have existing nodes with the `kubernetes.io/os=linux` label.
|
||||
{{</note>}}
|
||||
|
||||
#### Node affinity per scheduling profile
|
||||
|
||||
{{< feature-state for_k8s_version="v1.20" state="beta" >}}
|
||||
|
||||
When configuring multiple [scheduling profiles](/docs/reference/scheduling/config/#multiple-profiles), you can associate
|
||||
a profile with a Node affinity, which is useful if a profile only applies to a specific set of Nodes.
|
||||
To do so, add an `addedAffinity` to the args of the [`NodeAffinity` plugin](/docs/reference/scheduling/config/#scheduling-plugins)
|
||||
a profile with a node affinity, which is useful if a profile only applies to a specific set of nodes.
|
||||
To do so, add an `addedAffinity` to the `args` field of the [`NodeAffinity` plugin](/docs/reference/scheduling/config/#scheduling-plugins)
|
||||
in the [scheduler configuration](/docs/reference/scheduling/config/). For example:
|
||||
|
||||
```yaml
|
||||
@@ -188,29 +211,41 @@ profiles:
|
||||
|
||||
The `addedAffinity` is applied to all Pods that set `.spec.schedulerName` to `foo-scheduler`, in addition to the
|
||||
NodeAffinity specified in the PodSpec.
|
||||
That is, in order to match the Pod, Nodes need to satisfy `addedAffinity` and the Pod's `.spec.NodeAffinity`.
|
||||
That is, in order to match the Pod, nodes need to satisfy `addedAffinity` and
|
||||
the Pod's `.spec.NodeAffinity`.
|
||||
|
||||
Since the `addedAffinity` is not visible to end users, its behavior might be unexpected to them. We
|
||||
recommend to use node labels that have clear correlation with the profile's scheduler name.
|
||||
Since the `addedAffinity` is not visible to end users, its behavior might be
|
||||
unexpected to them. Use node labels that have a clear correlation to the
|
||||
scheduler profile name.
|
||||
|
||||
{{< note >}}
|
||||
The DaemonSet controller, which [creates Pods for DaemonSets](/docs/concepts/workloads/controllers/daemonset/#scheduled-by-default-scheduler)
|
||||
is not aware of scheduling profiles. For this reason, it is recommended that you keep a scheduler profile, such as the
|
||||
`default-scheduler`, without any `addedAffinity`. Then, the Daemonset's Pod template should use this scheduler name.
|
||||
Otherwise, some Pods created by the Daemonset controller might remain unschedulable.
|
||||
The DaemonSet controller, which [creates Pods for DaemonSets](/docs/concepts/workloads/controllers/daemonset/#scheduled-by-default-scheduler),
|
||||
does not support scheduling profiles. When the DaemonSet controller creates
|
||||
Pods, the default Kubernetes scheduler places those Pods and honors any
|
||||
`nodeAffinity` rules in the DaemonSet controller.
|
||||
{{< /note >}}
|
||||
|
||||
### Inter-pod affinity and anti-affinity
|
||||
|
||||
Inter-pod affinity and anti-affinity allow you to constrain which nodes your pod is eligible to be scheduled *based on
|
||||
labels on pods that are already running on the node* rather than based on labels on nodes. The rules are of the form
|
||||
"this pod should (or, in the case of anti-affinity, should not) run in an X if that X is already running one or more pods that meet rule Y".
|
||||
Y is expressed as a LabelSelector with an optional associated list of namespaces; unlike nodes, because pods are namespaced
|
||||
(and therefore the labels on pods are implicitly namespaced),
|
||||
a label selector over pod labels must specify which namespaces the selector should apply to. Conceptually X is a topology domain
|
||||
like node, rack, cloud provider zone, cloud provider region, etc. You express it using a `topologyKey` which is the
|
||||
key for the node label that the system uses to denote such a topology domain; for example, see the label keys listed above
|
||||
in the section [Interlude: built-in node labels](#built-in-node-labels).
|
||||
Inter-pod affinity and anti-affinity allow you to constrain which nodes your
|
||||
Pods can be scheduled on based on the labels of **Pods** already running on that
|
||||
node, instead of the node labels.
|
||||
|
||||
Inter-pod affinity and anti-affinity rules take the form "this
|
||||
Pod should (or, in the case of anti-affinity, should not) run in an X if that X
|
||||
is already running one or more Pods that meet rule Y", where X is a topology
|
||||
domain like node, rack, cloud provider zone or region, or similar and Y is the
|
||||
rule Kubernetes tries to satisfy.
|
||||
|
||||
You express these rules (Y) as [label selectors](/docs/concepts/overview/working-with-objects/labels/#label-selectors)
|
||||
with an optional associated list of namespaces. Pods are namespaced objects in
|
||||
Kubernetes, so Pod labels also implicitly have namespaces. Any label selectors
|
||||
for Pod labels should specify the namespaces in which Kubernetes should look for those
|
||||
labels.
|
||||
|
||||
You express the topology domain (X) using a `topologyKey`, which is the key for
|
||||
the node label that the system uses to denote the domain. For examples, see
|
||||
[Well-Known Labels, Annotations and Taints](/docs/reference/labels-annotations-taints/).
|
||||
|
||||
{{< note >}}
|
||||
Inter-pod affinity and anti-affinity require substantial amount of
|
||||
@@ -219,80 +254,106 @@ not recommend using them in clusters larger than several hundred nodes.
|
||||
{{< /note >}}
|
||||
|
||||
{{< note >}}
|
||||
Pod anti-affinity requires nodes to be consistently labelled, in other words every node in the cluster must have an appropriate label matching `topologyKey`. If some or all nodes are missing the specified `topologyKey` label, it can lead to unintended behavior.
|
||||
Pod anti-affinity requires nodes to be consistently labelled, in other words,
|
||||
every node in the cluster must have an appropriate label matching `topologyKey`.
|
||||
If some or all nodes are missing the specified `topologyKey` label, it can lead
|
||||
to unintended behavior.
|
||||
{{< /note >}}
|
||||
|
||||
As with node affinity, there are currently two types of pod affinity and anti-affinity, called `requiredDuringSchedulingIgnoredDuringExecution` and
|
||||
`preferredDuringSchedulingIgnoredDuringExecution` which denote "hard" vs. "soft" requirements.
|
||||
See the description in the node affinity section earlier.
|
||||
An example of `requiredDuringSchedulingIgnoredDuringExecution` affinity would be "co-locate the pods of service A and service B
|
||||
in the same zone, since they communicate a lot with each other"
|
||||
and an example `preferredDuringSchedulingIgnoredDuringExecution` anti-affinity would be "spread the pods from this service across zones"
|
||||
(a hard requirement wouldn't make sense, since you probably have more pods than zones).
|
||||
#### Types of inter-pod affinity and anti-affinity
|
||||
|
||||
Inter-pod affinity is specified as field `podAffinity` of field `affinity` in the PodSpec.
|
||||
And inter-pod anti-affinity is specified as field `podAntiAffinity` of field `affinity` in the PodSpec.
|
||||
Similar to [node affinity](#node-affinity) are two types of Pod affinity and
|
||||
anti-affinity as follows:
|
||||
|
||||
#### An example of a pod that uses pod affinity:
|
||||
* `requiredDuringSchedulingIgnoredDuringExecution`
|
||||
* `preferredDuringSchedulingIgnoredDuringExecution`
|
||||
|
||||
For example, you could use
|
||||
`requiredDuringSchedulingIgnoredDuringExecution` affinity to tell the scheduler to
|
||||
co-locate Pods of two services in the same cloud provider zone because they
|
||||
communicate with each other a lot. Similarly, you could use
|
||||
`preferredDuringSchedulingIgnoredDuringExecution` anti-affinity to spread Pods
|
||||
from a service across multiple cloud provider zones.
|
||||
|
||||
To use inter-pod affinity, use the `affinity.podAffinity` field in the Pod spec.
|
||||
For inter-pod anti-affinity, use the `affinity.podAntiAffinity` field in the Pod
|
||||
spec.
|
||||
|
||||
#### Pod affinity example {#an-example-of-a-pod-that-uses-pod-affinity}
|
||||
|
||||
Consider the following Pod spec:
|
||||
|
||||
{{< codenew file="pods/pod-with-pod-affinity.yaml" >}}
|
||||
|
||||
The affinity on this pod defines one pod affinity rule and one pod anti-affinity rule. In this example, the
|
||||
`podAffinity` is `requiredDuringSchedulingIgnoredDuringExecution`
|
||||
while the `podAntiAffinity` is `preferredDuringSchedulingIgnoredDuringExecution`. The
|
||||
pod affinity rule says that the pod can be scheduled onto a node only if that node is in the same zone
|
||||
as at least one already-running pod that has a label with key "security" and value "S1". (More precisely, the pod is eligible to run
|
||||
on node N if node N has a label with key `topology.kubernetes.io/zone` and some value V
|
||||
such that there is at least one node in the cluster with key `topology.kubernetes.io/zone` and
|
||||
value V that is running a pod that has a label with key "security" and value "S1".) The pod anti-affinity
|
||||
rule says that the pod should not be scheduled onto a node if that node is in the same zone as a pod with
|
||||
label having key "security" and value "S2". See the
|
||||
This example defines one Pod affinity rule and one Pod anti-affinity rule. The
|
||||
Pod affinity rule uses the "hard"
|
||||
`requiredDuringSchedulingIgnoredDuringExecution`, while the anti-affinity rule
|
||||
uses the "soft" `preferredDuringSchedulingIgnoredDuringExecution`.
|
||||
|
||||
The affinity rule says that the scheduler can only schedule a Pod onto a node if
|
||||
the node is in the same zone as one or more existing Pods with the label
|
||||
`security=S1`. More precisely, the scheduler must place the Pod on a node that has the
|
||||
`topology.kubernetes.io/zone=V` label, as long as there is at least one node in
|
||||
that zone that currently has one or more Pods with the Pod label `security=S1`.
|
||||
|
||||
The anti-affinity rule says that the scheduler should try to avoid scheduling
|
||||
the Pod onto a node that is in the same zone as one or more Pods with the label
|
||||
`security=S2`. More precisely, the scheduler should try to avoid placing the Pod on a node that has the
|
||||
`topology.kubernetes.io/zone=R` label if there are other nodes in the
|
||||
same zone currently running Pods with the `Security=S2` Pod label.
|
||||
|
||||
See the
|
||||
[design doc](https://git.k8s.io/community/contributors/design-proposals/scheduling/podaffinity.md)
|
||||
for many more examples of pod affinity and anti-affinity, both the `requiredDuringSchedulingIgnoredDuringExecution`
|
||||
flavor and the `preferredDuringSchedulingIgnoredDuringExecution` flavor.
|
||||
for many more examples of Pod affinity and anti-affinity.
|
||||
|
||||
The legal operators for pod affinity and anti-affinity are `In`, `NotIn`, `Exists`, `DoesNotExist`.
|
||||
You can use the `In`, `NotIn`, `Exists` and `DoesNotExist` values in the
|
||||
`operator` field for Pod affinity and anti-affinity.
|
||||
|
||||
In principle, the `topologyKey` can be any legal label-key. However,
|
||||
for performance and security reasons, there are some constraints on topologyKey:
|
||||
In principle, the `topologyKey` can be any allowed label key with the following
|
||||
exceptions for performance and security reasons:
|
||||
|
||||
1. For pod affinity, empty `topologyKey` is not allowed in both `requiredDuringSchedulingIgnoredDuringExecution`
|
||||
* For Pod affinity and anti-affinity, an empty `topologyKey` field is not allowed in both `requiredDuringSchedulingIgnoredDuringExecution`
|
||||
and `preferredDuringSchedulingIgnoredDuringExecution`.
|
||||
2. For pod anti-affinity, empty `topologyKey` is also not allowed in both `requiredDuringSchedulingIgnoredDuringExecution`
|
||||
and `preferredDuringSchedulingIgnoredDuringExecution`.
|
||||
3. For `requiredDuringSchedulingIgnoredDuringExecution` pod anti-affinity, the admission controller `LimitPodHardAntiAffinityTopology` was introduced to limit `topologyKey` to `kubernetes.io/hostname`. If you want to make it available for custom topologies, you may modify the admission controller, or disable it.
|
||||
4. Except for the above cases, the `topologyKey` can be any legal label-key.
|
||||
* For `requiredDuringSchedulingIgnoredDuringExecution` Pod anti-affinity rules,
|
||||
the admission controller `LimitPodHardAntiAffinityTopology` limits
|
||||
`topologyKey` to `kubernetes.io/hostname`. You can modify or disable the
|
||||
admission controller if you want to allow custom topologies.
|
||||
|
||||
In addition to `labelSelector` and `topologyKey`, you can optionally specify a list `namespaces`
|
||||
of namespaces which the `labelSelector` should match against (this goes at the same level of the definition as `labelSelector` and `topologyKey`).
|
||||
If omitted or empty, it defaults to the namespace of the pod where the affinity/anti-affinity definition appears.
|
||||
|
||||
All `matchExpressions` associated with `requiredDuringSchedulingIgnoredDuringExecution` affinity and anti-affinity
|
||||
must be satisfied for the pod to be scheduled onto a node.
|
||||
In addition to `labelSelector` and `topologyKey`, you can optionally specify a list
|
||||
of namespaces which the `labelSelector` should match against using the
|
||||
`namespaces` field at the same level as `labelSelector` and `topologyKey`.
|
||||
If omitted or empty, `namespaces` defaults to the namespace of the Pod where the
|
||||
affinity/anti-affinity definition appears.
|
||||
|
||||
#### Namespace selector
|
||||
{{< feature-state for_k8s_version="v1.22" state="beta" >}}
|
||||
|
||||
Users can also select matching namespaces using `namespaceSelector`, which is a label query over the set of namespaces.
|
||||
The affinity term is applied to the union of the namespaces selected by `namespaceSelector` and the ones listed in the `namespaces` field.
|
||||
You can also select matching namespaces using `namespaceSelector`, which is a label query over the set of namespaces.
|
||||
The affinity term is applied to namespaces selected by both `namespaceSelector` and the `namespaces` field.
|
||||
Note that an empty `namespaceSelector` ({}) matches all namespaces, while a null or empty `namespaces` list and
|
||||
null `namespaceSelector` means "this pod's namespace".
|
||||
null `namespaceSelector` matches the namespace of the Pod where the rule is defined.
|
||||
|
||||
{{<note>}}
|
||||
This feature is beta and enabled by default. You can disable it via the
|
||||
[feature gate](/docs/reference/command-line-tools-reference/feature-gates/)
|
||||
`PodAffinityNamespaceSelector` in both kube-apiserver and kube-scheduler.
|
||||
{{</note>}}
|
||||
|
||||
#### More Practical Use-cases
|
||||
#### More practical use-cases
|
||||
|
||||
Interpod Affinity and AntiAffinity can be even more useful when they are used with higher
|
||||
level collections such as ReplicaSets, StatefulSets, Deployments, etc. One can easily configure that a set of workloads should
|
||||
Inter-pod affinity and anti-affinity can be even more useful when they are used with higher
|
||||
level collections such as ReplicaSets, StatefulSets, Deployments, etc. These
|
||||
rules allow you to configure that a set of workloads should
|
||||
be co-located in the same defined topology, eg., the same node.
|
||||
|
||||
##### Always co-located in the same node
|
||||
Take, for example, a three-node cluster running a web application with an
|
||||
in-memory cache like redis. You could use inter-pod affinity and anti-affinity
|
||||
to co-locate the web servers with the cache as much as possible.
|
||||
|
||||
In a three node cluster, a web application has in-memory cache such as redis. We want the web-servers to be co-located with the cache as much as possible.
|
||||
|
||||
Here is the yaml snippet of a simple redis deployment with three replicas and selector label `app=store`. The deployment has `PodAntiAffinity` configured to ensure the scheduler does not co-locate replicas on a single node.
|
||||
In the following example Deployment for the redis cache, the replicas get the label `app=store`. The
|
||||
`podAntiAffinity` rule tells the scheduler to avoid placing multiple replicas
|
||||
with the `app=store` label on a single node. This creates each cache in a
|
||||
separate node.
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
@@ -324,7 +385,10 @@ spec:
|
||||
image: redis:3.2-alpine
|
||||
```
|
||||
|
||||
The below yaml snippet of the webserver deployment has `podAntiAffinity` and `podAffinity` configured. This informs the scheduler that all its replicas are to be co-located with pods that have selector label `app=store`. This will also ensure that each web-server replica does not co-locate on a single node.
|
||||
The following Deployment for the web servers creates replicas with the label `app=web-store`. The
|
||||
Pod affinity rule tells the scheduler to place each replica on a node that has a
|
||||
Pod with the label `app=store`. The Pod anti-affinity rule tells the scheduler
|
||||
to avoid placing multiple `app=web-store` servers on a single node.
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
@@ -365,56 +429,37 @@ spec:
|
||||
image: nginx:1.16-alpine
|
||||
```
|
||||
|
||||
If we create the above two deployments, our three node cluster should look like below.
|
||||
Creating the two preceding Deployments results in the following cluster layout,
|
||||
where each web server is co-located with a cache, on three separate nodes.
|
||||
|
||||
| node-1 | node-2 | node-3 |
|
||||
|:--------------------:|:-------------------:|:------------------:|
|
||||
| *webserver-1* | *webserver-2* | *webserver-3* |
|
||||
| *cache-1* | *cache-2* | *cache-3* |
|
||||
|
||||
As you can see, all the 3 replicas of the `web-server` are automatically co-located with the cache as expected.
|
||||
|
||||
```
|
||||
kubectl get pods -o wide
|
||||
```
|
||||
The output is similar to this:
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
##### Never co-located in the same node
|
||||
|
||||
The above example uses `PodAntiAffinity` rule with `topologyKey: "kubernetes.io/hostname"` to deploy the redis cluster so that
|
||||
no two instances are located on the same host.
|
||||
See [ZooKeeper tutorial](/docs/tutorials/stateful-application/zookeeper/#tolerating-node-failure)
|
||||
for an example of a StatefulSet configured with anti-affinity for high availability, using the same technique.
|
||||
See the [ZooKeeper tutorial](/docs/tutorials/stateful-application/zookeeper/#tolerating-node-failure)
|
||||
for an example of a StatefulSet configured with anti-affinity for high
|
||||
availability, using the same technique as this example.
|
||||
|
||||
## nodeName
|
||||
|
||||
`nodeName` is the simplest form of node selection constraint, but due
|
||||
to its limitations it is typically not used. `nodeName` is a field of
|
||||
PodSpec. If it is non-empty, the scheduler ignores the pod and the
|
||||
kubelet running on the named node tries to run the pod. Thus, if
|
||||
`nodeName` is provided in the PodSpec, it takes precedence over the
|
||||
above methods for node selection.
|
||||
`nodeName` is a more direct form of node selection than affinity or
|
||||
`nodeSelector`. `nodeName` is a field in the Pod spec. If the `nodeName` field
|
||||
is not empty, the scheduler ignores the Pod and the kubelet on the named node
|
||||
tries to place the Pod on that node. Using `nodeName` overrules using
|
||||
`nodeSelector` or affinity and anti-affinity rules.
|
||||
|
||||
Some of the limitations of using `nodeName` to select nodes are:
|
||||
|
||||
- If the named node does not exist, the pod will not be run, and in
|
||||
- If the named node does not exist, the Pod will not run, and in
|
||||
some cases may be automatically deleted.
|
||||
- If the named node does not have the resources to accommodate the
|
||||
pod, the pod will fail and its reason will indicate why,
|
||||
Pod, the Pod will fail and its reason will indicate why,
|
||||
for example OutOfmemory or OutOfcpu.
|
||||
- Node names in cloud environments are not always predictable or
|
||||
stable.
|
||||
|
||||
Here is an example of a pod config file using the `nodeName` field:
|
||||
Here is an example of a Pod spec using the `nodeName` field:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
@@ -428,21 +473,16 @@ spec:
|
||||
nodeName: kube-01
|
||||
```
|
||||
|
||||
The above pod will run on the node kube-01.
|
||||
|
||||
|
||||
The above Pod will only run on the node `kube-01`.
|
||||
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
|
||||
[Taints](/docs/concepts/scheduling-eviction/taint-and-toleration/) allow a Node to *repel* a set of Pods.
|
||||
|
||||
The design documents for
|
||||
[node affinity](https://git.k8s.io/community/contributors/design-proposals/scheduling/nodeaffinity.md)
|
||||
and for [inter-pod affinity/anti-affinity](https://git.k8s.io/community/contributors/design-proposals/scheduling/podaffinity.md) contain extra background information about these features.
|
||||
|
||||
Once a Pod is assigned to a Node, the kubelet runs the Pod and allocates node-local resources.
|
||||
The [topology manager](/docs/tasks/administer-cluster/topology-manager/) can take part in node-level
|
||||
* Read more about [taints and tolerations](/docs/concepts/scheduling-eviction/taint-and-toleration/) .
|
||||
* Read the design docs for [node affinity](https://git.k8s.io/community/contributors/design-proposals/scheduling/nodeaffinity.md)
|
||||
and for [inter-pod affinity/anti-affinity](https://git.k8s.io/community/contributors/design-proposals/scheduling/podaffinity.md).
|
||||
* Learn about how the [topology manager](/docs/tasks/administer-cluster/topology-manager/) takes part in node-level
|
||||
resource allocation decisions.
|
||||
* Learn how to use [nodeSelector](/docs/tasks/configure-pod-container/assign-pods-nodes/).
|
||||
* Learn how to use [affinity and anti-affinity](/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/).
|
||||
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ Kubernetes as a project supports and maintains [AWS](https://github.com/kubernet
|
||||
|
||||
{{% thirdparty-content %}}
|
||||
|
||||
* [AKS Application Gateway Ingress Controller](https://azure.github.io/application-gateway-kubernetes-ingress/) is an ingress controller that configures the [Azure Application Gateway](https://docs.microsoft.com/azure/application-gateway/overview).
|
||||
* [AKS Application Gateway Ingress Controller](https://docs.microsoft.com/azure/application-gateway/tutorial-ingress-controller-add-on-existing?toc=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Faks%2Ftoc.json&bc=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fbread%2Ftoc.json) is an ingress controller that configures the [Azure Application Gateway](https://docs.microsoft.com/azure/application-gateway/overview).
|
||||
* [Ambassador](https://www.getambassador.io/) API Gateway is an [Envoy](https://www.envoyproxy.io)-based ingress
|
||||
controller.
|
||||
* [Apache APISIX ingress controller](https://github.com/apache/apisix-ingress-controller) is an [Apache APISIX](https://github.com/apache/apisix)-based ingress controller.
|
||||
|
||||
@@ -118,8 +118,14 @@ match a path in the spec.
|
||||
|
||||
### DefaultBackend {#default-backend}
|
||||
|
||||
An Ingress with no rules sends all traffic to a single default backend. The `defaultBackend` is conventionally a configuration option
|
||||
of the [Ingress controller](/docs/concepts/services-networking/ingress-controllers) and is not specified in your Ingress resources.
|
||||
An Ingress with no rules sends all traffic to a single default backend and `.spec.defaultBackend`
|
||||
is the backend that should handle requests in that case.
|
||||
The `defaultBackend` is conventionally a configuration option of the
|
||||
[Ingress controller](/docs/concepts/services-networking/ingress-controllers) and
|
||||
is not specified in your Ingress resources.
|
||||
If no `.spec.rules` are specified, `.spec.defaultBackend` must be specified.
|
||||
If `defaultBackend` is not set, the handling of requests that do not match any of the rules will be up to the
|
||||
ingress controller (consult the documentation for your ingress controller to find out how it handles this case).
|
||||
|
||||
If none of the hosts or paths match the HTTP request in the Ingress objects, the traffic is
|
||||
routed to your default backend.
|
||||
@@ -310,7 +316,7 @@ spec:
|
||||
parameters:
|
||||
# The parameters for this IngressClass are specified in an
|
||||
# IngressParameter (API group k8s.example.com) named "external-config",
|
||||
# that's in the "external-configuration" configuration namespace.
|
||||
# that's in the "external-configuration" namespace.
|
||||
scope: Namespace
|
||||
apiGroup: k8s.example.com
|
||||
kind: IngressParameter
|
||||
|
||||
@@ -109,12 +109,45 @@ field.
|
||||
{{< /note >}}
|
||||
|
||||
Port definitions in Pods have names, and you can reference these names in the
|
||||
`targetPort` attribute of a Service. This works even if there is a mixture
|
||||
of Pods in the Service using a single configured name, with the same network
|
||||
protocol available via different port numbers.
|
||||
This offers a lot of flexibility for deploying and evolving your Services.
|
||||
For example, you can change the port numbers that Pods expose in the next
|
||||
version of your backend software, without breaking clients.
|
||||
`targetPort` attribute of a Service. For example, we can bind the `targetPort`
|
||||
of the Service to the Pod port in the following way:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: nginx
|
||||
labels:
|
||||
app.kubernetes.io/name: proxy
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:11.14.2
|
||||
ports:
|
||||
- containerPort: 80
|
||||
name: http-web-service
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: nginx-service
|
||||
spec:
|
||||
selector:
|
||||
app.kubernetes.io/name: proxy
|
||||
ports:
|
||||
- name: name-of-service-port
|
||||
protocol: TCP
|
||||
port: 80
|
||||
targetPort: http-web-service
|
||||
```
|
||||
|
||||
|
||||
This works even if there is a mixture of Pods in the Service using a single
|
||||
configured name, with the same network protocol available via different
|
||||
port numbers. This offers a lot of flexibility for deploying and evolving
|
||||
your Services. For example, you can change the port numbers that Pods expose
|
||||
in the next version of your backend software, without breaking clients.
|
||||
|
||||
The default protocol for Services is TCP; you can also use any other
|
||||
[supported protocol](#protocol-support).
|
||||
|
||||
@@ -19,6 +19,12 @@ those network endpoints can be routed closer to where it originated.
|
||||
For example, you can route traffic within a locality to reduce
|
||||
costs, or to improve network performance.
|
||||
|
||||
{{< note >}}
|
||||
The "topology-aware hints" feature is at Beta stage and it is **NOT** enabled
|
||||
by default. To try out this feature, you have to enable the `TopologyAwareHints`
|
||||
[feature gate](/docs/reference/command-line-tools-reference/feature-gates/).
|
||||
{{< /note >}}
|
||||
|
||||
<!-- body -->
|
||||
|
||||
## Motivation
|
||||
|
||||
@@ -87,7 +87,7 @@ for provisioning PVs. This field must be specified.
|
||||
You are not restricted to specifying the "internal" provisioners
|
||||
listed here (whose names are prefixed with "kubernetes.io" and shipped
|
||||
alongside Kubernetes). You can also run and specify external provisioners,
|
||||
which are independent programs that follow a [specification](https://git.k8s.io/community/contributors/design-proposals/storage/volume-provisioning.md)
|
||||
which are independent programs that follow a [specification](https://github.com/kubernetes/design-proposals-archive/blob/main/storage/volume-provisioning.md)
|
||||
defined by Kubernetes. Authors of external provisioners have full discretion
|
||||
over where their code lives, how the provisioner is shipped, how it needs to be
|
||||
run, what volume plugin it uses (including Flex), etc. The repository
|
||||
@@ -241,8 +241,8 @@ allowedTopologies:
|
||||
- matchLabelExpressions:
|
||||
- key: failure-domain.beta.kubernetes.io/zone
|
||||
values:
|
||||
- us-central1-a
|
||||
- us-central1-b
|
||||
- us-central-1a
|
||||
- us-central-1b
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
@@ -69,7 +69,7 @@ takes you through this example in more detail).
|
||||
# │ │ │ ┌───────────── month (1 - 12)
|
||||
# │ │ │ │ ┌───────────── day of the week (0 - 6) (Sunday to Saturday;
|
||||
# │ │ │ │ │ 7 is also Sunday on some systems)
|
||||
# │ │ │ │ │
|
||||
# │ │ │ │ │ OR sun, mon, tue, wed, thu, fri, sat
|
||||
# │ │ │ │ │
|
||||
# * * * * *
|
||||
```
|
||||
|
||||
@@ -107,7 +107,7 @@ If you do not specify either, then the DaemonSet controller will create Pods on
|
||||
|
||||
### Scheduled by default scheduler
|
||||
|
||||
{{< feature-state state="stable" for-kubernetes-version="1.17" >}}
|
||||
{{< feature-state for_kubernetes_version="1.17" state="stable" >}}
|
||||
|
||||
A DaemonSet ensures that all eligible nodes run a copy of a Pod. Normally, the
|
||||
node that a Pod runs on is selected by the Kubernetes scheduler. However,
|
||||
|
||||
@@ -136,7 +136,7 @@ completion or failed for some reason. When you use `kubectl` to query a Pod with
|
||||
a container that is `Terminated`, you see a reason, an exit code, and the start and
|
||||
finish time for that container's period of execution.
|
||||
|
||||
If a container has a `preStop` hook configured, that runs before the container enters
|
||||
If a container has a `preStop` hook configured, this hook runs before the container enters
|
||||
the `Terminated` state.
|
||||
|
||||
## Container restart policy {#restart-policy}
|
||||
|
||||
@@ -733,7 +733,7 @@ The following HTTP headers can be used to performing an impersonation request:
|
||||
|
||||
* `Impersonate-User`: The username to act as.
|
||||
* `Impersonate-Group`: A group name to act as. Can be provided multiple times to set multiple groups. Optional. Requires "Impersonate-User".
|
||||
* `Impersonate-Extra-( extra name )`: A dynamic header used to associate extra fields with the user. Optional. Requires "Impersonate-User". In order to be preserved consistently, `( extra name )` should be lower-case, and any characters which aren't [legal in HTTP header labels](https://tools.ietf.org/html/rfc7230#section-3.2.6) MUST be utf8 and [percent-encoded](https://tools.ietf.org/html/rfc3986#section-2.1).
|
||||
* `Impersonate-Extra-( extra name )`: A dynamic header used to associate extra fields with the user. Optional. Requires "Impersonate-User". In order to be preserved consistently, `( extra name )` must be lower-case, and any characters which aren't [legal in HTTP header labels](https://tools.ietf.org/html/rfc7230#section-3.2.6) MUST be utf8 and [percent-encoded](https://tools.ietf.org/html/rfc3986#section-2.1).
|
||||
* `Impersonate-Uid`: A unique identifier that represents the user being impersonated. Optional. Requires "Impersonate-User". Kubernetes does not impose any format requirements on this string.
|
||||
|
||||
{{< note >}}
|
||||
|
||||
@@ -163,14 +163,14 @@ kubelet [flags]
|
||||
<td colspan="2">--cloud-config string</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td><td style="line-height: 130%; word-wrap: break-word;">The path to the cloud provider configuration file. Empty string for no configuration file. (DEPRECATED: will be removed in 1.23, in favor of removing cloud providers code from Kubelet.)</td>
|
||||
<td></td><td style="line-height: 130%; word-wrap: break-word;">The path to the cloud provider configuration file. Empty string for no configuration file. (DEPRECATED: will be removed in 1.24 or later, in favor of removing cloud providers code from kubelet.)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td colspan="2">--cloud-provider string</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td><td style="line-height: 130%; word-wrap: break-word;">The provider for cloud services. Set to empty string for running with no cloud provider. If set, the cloud provider determines the name of the node (consult cloud provider documentation to determine if and how the hostname is used). (DEPRECATED: will be removed in 1.23, in favor of removing cloud provider code from Kubelet.)</td>
|
||||
<td></td><td style="line-height: 130%; word-wrap: break-word;">The provider for cloud services. Set to empty string for running with no cloud provider. If set, the cloud provider determines the name of the node (consult cloud provider documentation to determine if and how the hostname is used). (DEPRECATED: will be removed in 1.24 or later, in favor of removing cloud provider code from Kubelet.)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -297,7 +297,7 @@ kubelet [flags]
|
||||
<td colspan="2">--dynamic-config-dir string</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td><td style="line-height: 130%; word-wrap: break-word;">The Kubelet will use this directory for checkpointing downloaded configurations and tracking configuration health. The Kubelet will create this directory if it does not already exist. The path may be absolute or relative; relative paths start at the Kubelet's current working directory. Providing this flag enables dynamic Kubelet configuration. The <code>DynamicKubeletConfig</code> feature gate must be enabled to pass this flag. (DEPRECATED: Feature DynamicKubeletConfig is deprecated in 1.22 and will not move to GA. It is planned to be removed from Kubernetes in the version 1.23. Please use alternative ways to update kubelet configuration.)</td>
|
||||
<td></td><td style="line-height: 130%; word-wrap: break-word;">The Kubelet will use this directory for checkpointing downloaded configurations and tracking configuration health. The Kubelet will create this directory if it does not already exist. The path may be absolute or relative; relative paths start at the Kubelet's current working directory. Providing this flag enables dynamic Kubelet configuration. The <code>DynamicKubeletConfig</code> feature gate must be enabled to pass this flag. (DEPRECATED: Feature DynamicKubeletConfig is deprecated in 1.22 and will not move to GA. It is planned to be removed from Kubernetes in the version 1.24 or later. Please use alternative ways to update kubelet configuration.)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -395,21 +395,21 @@ kubelet [flags]
|
||||
<td colspan="2">--experimental-allocatable-ignore-eviction Default: <code>false</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td><td style="line-height: 130%; word-wrap: break-word;">When set to <code>true</code>, hard eviction thresholds will be ignored while calculating node allocatable. See https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/ for more details. (DEPRECATED: will be removed in 1.23)</td>
|
||||
<td></td><td style="line-height: 130%; word-wrap: break-word;">When set to <code>true</code>, hard eviction thresholds will be ignored while calculating node allocatable. See https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/ for more details. (DEPRECATED: will be removed in 1.24 or later)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td colspan="2">--experimental-check-node-capabilities-before-mount</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td><td style="line-height: 130%; word-wrap: break-word;">[Experimental] if set to <code>true</code>, the kubelet will check the underlying node for required components (binaries, etc.) before performing the mount (DEPRECATED: will be removed in 1.23, in favor of using CSI.)</td>
|
||||
<td></td><td style="line-height: 130%; word-wrap: break-word;">[Experimental] if set to <code>true</code>, the kubelet will check the underlying node for required components (binaries, etc.) before performing the mount (DEPRECATED: will be removed in 1.24 or later, in favor of using CSI.)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td colspan="2">--experimental-kernel-memcg-notification</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td><td style="line-height: 130%; word-wrap: break-word;">Use kernelMemcgNotification configuration, this flag will be removed in 1.23. (DEPRECATED: This parameter should be set via the config file specified by the Kubelet's <code>--config</code> flag. See https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/ for more information.)</td>
|
||||
<td></td><td style="line-height: 130%; word-wrap: break-word;">Use kernelMemcgNotification configuration, this flag will be removed in 1.24 or later. (DEPRECATED: This parameter should be set via the config file specified by the Kubelet's <code>--config</code> flag. See https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/ for more information.)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -423,7 +423,7 @@ kubelet [flags]
|
||||
<td colspan="2">--experimental-mounter-path string Default: <code>mount</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td><td style="line-height: 130%; word-wrap: break-word;">[Experimental] Path of mounter binary. Leave empty to use the default <code>mount</code>. (DEPRECATED: will be removed in 1.23, in favor of using CSI.)</td>
|
||||
<td></td><td style="line-height: 130%; word-wrap: break-word;">[Experimental] Path of mounter binary. Leave empty to use the default <code>mount</code>. (DEPRECATED: will be removed in 1.24 or later, in favor of using CSI.)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
@@ -264,6 +264,109 @@ node only (e.g. the node ip).</p>
|
||||
|
||||
|
||||
|
||||
## `BootstrapToken` {#BootstrapToken}
|
||||
|
||||
|
||||
**Appears in:**
|
||||
|
||||
- [InitConfiguration](#kubeadm-k8s-io-v1beta3-InitConfiguration)
|
||||
|
||||
|
||||
<p>BootstrapToken describes one bootstrap token, stored as a Secret in the cluster</p>
|
||||
|
||||
|
||||
<table class="table">
|
||||
<thead><tr><th width="30%">Field</th><th>Description</th></tr></thead>
|
||||
<tbody>
|
||||
|
||||
|
||||
<tr><td><code>token</code> <B>[Required]</B><br/>
|
||||
<a href="#BootstrapTokenString"><code>BootstrapTokenString</code></a>
|
||||
</td>
|
||||
<td>
|
||||
<p><code>token</code> is used for establishing bidirectional trust between nodes and control-planes.
|
||||
Used for joining nodes in the cluster.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><code>description</code><br/>
|
||||
<code>string</code>
|
||||
</td>
|
||||
<td>
|
||||
<p><code>description</code> sets a human-friendly message why this token exists and what it's used
|
||||
for, so other administrators can know its purpose.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><code>ttl</code><br/>
|
||||
<a href="https://pkg.go.dev/k8s.io/apimachinery/pkg/apis/meta/v1#Duration"><code>meta/v1.Duration</code></a>
|
||||
</td>
|
||||
<td>
|
||||
<p><code>ttl</code> defines the time to live for this token. Defaults to <code>24h</code>.
|
||||
<code>expires</code> and <code>ttl</code> are mutually exclusive.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><code>expires</code><br/>
|
||||
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#time-v1-meta"><code>meta/v1.Time</code></a>
|
||||
</td>
|
||||
<td>
|
||||
<p><code>expires</code> specifies the timestamp when this token expires. Defaults to being set
|
||||
dynamically at runtime based on the <code>ttl</code>. <code>expires</code> and <code>ttl</code> are mutually exclusive.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><code>usages</code><br/>
|
||||
<code>[]string</code>
|
||||
</td>
|
||||
<td>
|
||||
<p><code>usages</code> describes the ways in which this token can be used. Can by default be used
|
||||
for establishing bidirectional trust, but that can be changed here.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><code>groups</code><br/>
|
||||
<code>[]string</code>
|
||||
</td>
|
||||
<td>
|
||||
<p><code>groups</code> specifies the extra groups that this token will authenticate as when/if
|
||||
used for authentication</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## `BootstrapTokenString` {#BootstrapTokenString}
|
||||
|
||||
|
||||
**Appears in:**
|
||||
|
||||
- [BootstrapToken](#BootstrapToken)
|
||||
|
||||
|
||||
<p>BootstrapTokenString is a token of the format <code>abcdef.abcdef0123456789</code> that is used
|
||||
for both validation of the practically of the API server from a joining node's point
|
||||
of view and as an authentication method for the node in the bootstrap phase of
|
||||
"kubeadm join". This token is and should be short-lived.</p>
|
||||
|
||||
|
||||
<table class="table">
|
||||
<thead><tr><th width="30%">Field</th><th>Description</th></tr></thead>
|
||||
<tbody>
|
||||
|
||||
|
||||
<tr><td><code>-</code> <B>[Required]</B><br/>
|
||||
<code>string</code>
|
||||
</td>
|
||||
<td>
|
||||
<span class="text-muted">No description provided.</span></td>
|
||||
</tr>
|
||||
<tr><td><code>-</code> <B>[Required]</B><br/>
|
||||
<code>string</code>
|
||||
</td>
|
||||
<td>
|
||||
<span class="text-muted">No description provided.</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
## `ClusterConfiguration` {#kubeadm-k8s-io-v1beta3-ClusterConfiguration}
|
||||
|
||||
|
||||
@@ -1237,106 +1340,3 @@ first alpha-numerically.</p>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
|
||||
## `BootstrapToken` {#BootstrapToken}
|
||||
|
||||
|
||||
**Appears in:**
|
||||
|
||||
- [InitConfiguration](#kubeadm-k8s-io-v1beta3-InitConfiguration)
|
||||
|
||||
|
||||
<p>BootstrapToken describes one bootstrap token, stored as a Secret in the cluster</p>
|
||||
|
||||
|
||||
<table class="table">
|
||||
<thead><tr><th width="30%">Field</th><th>Description</th></tr></thead>
|
||||
<tbody>
|
||||
|
||||
|
||||
<tr><td><code>token</code> <B>[Required]</B><br/>
|
||||
<a href="#BootstrapTokenString"><code>BootstrapTokenString</code></a>
|
||||
</td>
|
||||
<td>
|
||||
<p><code>token</code> is used for establishing bidirectional trust between nodes and control-planes.
|
||||
Used for joining nodes in the cluster.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><code>description</code><br/>
|
||||
<code>string</code>
|
||||
</td>
|
||||
<td>
|
||||
<p><code>description</code> sets a human-friendly message why this token exists and what it's used
|
||||
for, so other administrators can know its purpose.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><code>ttl</code><br/>
|
||||
<a href="https://pkg.go.dev/k8s.io/apimachinery/pkg/apis/meta/v1#Duration"><code>meta/v1.Duration</code></a>
|
||||
</td>
|
||||
<td>
|
||||
<p><code>ttl</code> defines the time to live for this token. Defaults to <code>24h</code>.
|
||||
<code>expires</code> and <code>ttl</code> are mutually exclusive.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><code>expires</code><br/>
|
||||
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#time-v1-meta"><code>meta/v1.Time</code></a>
|
||||
</td>
|
||||
<td>
|
||||
<p><code>expires</code> specifies the timestamp when this token expires. Defaults to being set
|
||||
dynamically at runtime based on the <code>ttl</code>. <code>expires</code> and <code>ttl</code> are mutually exclusive.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><code>usages</code><br/>
|
||||
<code>[]string</code>
|
||||
</td>
|
||||
<td>
|
||||
<p><code>usages</code> describes the ways in which this token can be used. Can by default be used
|
||||
for establishing bidirectional trust, but that can be changed here.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td><code>groups</code><br/>
|
||||
<code>[]string</code>
|
||||
</td>
|
||||
<td>
|
||||
<p><code>groups</code> specifies the extra groups that this token will authenticate as when/if
|
||||
used for authentication</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## `BootstrapTokenString` {#BootstrapTokenString}
|
||||
|
||||
|
||||
**Appears in:**
|
||||
|
||||
- [BootstrapToken](#BootstrapToken)
|
||||
|
||||
|
||||
<p>BootstrapTokenString is a token of the format <code>abcdef.abcdef0123456789</code> that is used
|
||||
for both validation of the practically of the API server from a joining node's point
|
||||
of view and as an authentication method for the node in the bootstrap phase of
|
||||
"kubeadm join". This token is and should be short-lived.</p>
|
||||
|
||||
|
||||
<table class="table">
|
||||
<thead><tr><th width="30%">Field</th><th>Description</th></tr></thead>
|
||||
<tbody>
|
||||
|
||||
|
||||
<tr><td><code>-</code> <B>[Required]</B><br/>
|
||||
<code>string</code>
|
||||
</td>
|
||||
<td>
|
||||
<span class="text-muted">No description provided.</span></td>
|
||||
</tr>
|
||||
<tr><td><code>-</code> <B>[Required]</B><br/>
|
||||
<code>string</code>
|
||||
</td>
|
||||
<td>
|
||||
<span class="text-muted">No description provided.</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -4,7 +4,7 @@ id: namespace
|
||||
date: 2018-04-12
|
||||
full_link: /docs/concepts/overview/working-with-objects/namespaces
|
||||
short_description: >
|
||||
An abstraction used by Kubernetes to support multiple virtual clusters on the same physical cluster.
|
||||
An abstraction used by Kubernetes to support isolation of groups of resources within a single cluster.
|
||||
|
||||
aka:
|
||||
tags:
|
||||
|
||||
@@ -238,7 +238,7 @@ kubectl rollout status -w deployment/frontend # Watch rolling
|
||||
kubectl rollout restart deployment/frontend # Rolling restart of the "frontend" deployment
|
||||
|
||||
|
||||
cat pod.json | kubectl replace -f - # Replace a pod based on the JSON passed into std
|
||||
cat pod.json | kubectl replace -f - # Replace a pod based on the JSON passed into stdin
|
||||
|
||||
# Force replace, delete and then re-create the resource. Will cause a service outage.
|
||||
kubectl replace --force -f ./pod.json
|
||||
|
||||
@@ -184,6 +184,16 @@ Used on: PersistentVolumeClaim
|
||||
|
||||
This annotation has been deprecated.
|
||||
|
||||
### volume.beta.kubernetes.io/mount-options (deprecated) {#mount-options}
|
||||
|
||||
Example : `volume.beta.kubernetes.io/mount-options: "ro,soft"`
|
||||
|
||||
Used on: PersistentVolume
|
||||
|
||||
A Kubernetes administrator can specify additional [mount options](/docs/concepts/storage/persistent-volumes/#mount-options) for when a PersistentVolume is mounted on a node.
|
||||
|
||||
This annotation has been deprecated.
|
||||
|
||||
### volume.kubernetes.io/storage-provisioner
|
||||
|
||||
Used on: PersistentVolumeClaim
|
||||
@@ -475,10 +485,10 @@ The [`securityContext`](/docs/reference/kubernetes-api/workload-resources/pod-v1
|
||||
When you [specify the security context for a Pod](/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod),
|
||||
the settings you specify apply to all containers in that Pod.
|
||||
|
||||
### container.seccomp.security.alpha.kubernetes.io/[NAME] {#container-seccomp-security-alpha-kubernetes-io}
|
||||
### container.seccomp.security.alpha.kubernetes.io/[NAME] (deprecated) {#container-seccomp-security-alpha-kubernetes-io}
|
||||
|
||||
This annotation has been deprecated since Kubernetes v1.19 and will become non-functional in v1.25.
|
||||
The tutorial [Restrict a Container's Syscalls with seccomp](/docs/tutorials/clusters/seccomp/) takes
|
||||
The tutorial [Restrict a Container's Syscalls with seccomp](/docs/tutorials/security/seccomp/) takes
|
||||
you through the steps you follow to apply a seccomp profile to a Pod or to one of
|
||||
its containers. That tutorial covers the supported mechanism for configuring seccomp in Kubernetes,
|
||||
based on setting `securityContext` within the Pod's `.spec`.
|
||||
|
||||
@@ -22,6 +22,8 @@ This page explains the certificates that your cluster requires.
|
||||
Kubernetes requires PKI for the following operations:
|
||||
|
||||
* Client certificates for the kubelet to authenticate to the API server
|
||||
* Kubelet [server certificates](/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/#client-and-serving-certificates)
|
||||
for the the API server to talk to the kubelets
|
||||
* Server certificate for the API server endpoint
|
||||
* Client certificates for administrators of the cluster to authenticate to the API server
|
||||
* Client certificates for the API server to talk to the kubelets
|
||||
|
||||
@@ -208,6 +208,7 @@ The DEB and RPM packages shipped with the Kubernetes releases are:
|
||||
| Package name | Description |
|
||||
|--------------|-------------|
|
||||
| `kubeadm` | Installs the `/usr/bin/kubeadm` CLI tool and the [kubelet drop-in file](#the-kubelet-drop-in-file-for-systemd) for the kubelet. |
|
||||
| `kubelet` | Installs the kubelet binary in `/usr/bin` and CNI binaries in `/opt/cni/bin`. |
|
||||
| `kubelet` | Installs the `/usr/bin/kubelet` binary. |
|
||||
| `kubectl` | Installs the `/usr/bin/kubectl` binary. |
|
||||
| `cri-tools` | Installs the `/usr/bin/crictl` binary from the [cri-tools git repository](https://github.com/kubernetes-sigs/cri-tools). |
|
||||
| `kubernetes-cni` | Installs the `/opt/cni/bin` binaries from the [plugins git repository](https://github.com/containernetworking/plugins). |
|
||||
|
||||
@@ -237,7 +237,9 @@ In each case, the credentials of the pod are used to communicate securely with t
|
||||
|
||||
## Accessing services running on the cluster
|
||||
|
||||
The previous section describes how to connect to the Kubernetes API server. For information about connecting to other services running on a Kubernetes cluster, see [Access Cluster Services.](/docs/tasks/administer-cluster/access-cluster-services/)
|
||||
The previous section describes how to connect to the Kubernetes API server.
|
||||
For information about connecting to other services running on a Kubernetes cluster, see
|
||||
[Access Cluster Services](/docs/tasks/access-application-cluster/access-cluster-services/).
|
||||
|
||||
## Requesting redirects
|
||||
|
||||
|
||||
@@ -7,14 +7,10 @@ content_type: task
|
||||
This page shows how to change the reclaim policy of a Kubernetes
|
||||
PersistentVolume.
|
||||
|
||||
|
||||
## {{% heading "prerequisites" %}}
|
||||
|
||||
|
||||
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
|
||||
|
||||
|
||||
|
||||
<!-- steps -->
|
||||
|
||||
## Why change reclaim policy of a PersistentVolume
|
||||
@@ -39,10 +35,12 @@ Released phase, where all of its data can be manually recovered.
|
||||
|
||||
The output is similar to this:
|
||||
|
||||
```none
|
||||
NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE
|
||||
pvc-b6efd8da-b7b5-11e6-9d58-0ed433a7dd94 4Gi RWO Delete Bound default/claim1 manual 10s
|
||||
pvc-b95650f8-b7b5-11e6-9d58-0ed433a7dd94 4Gi RWO Delete Bound default/claim2 manual 6s
|
||||
pvc-bb3ca71d-b7b5-11e6-9d58-0ed433a7dd94 4Gi RWO Delete Bound default/claim3 manual 3s
|
||||
```
|
||||
|
||||
This list also includes the name of the claims that are bound to each volume
|
||||
for easier identification of dynamically provisioned volumes.
|
||||
@@ -56,12 +54,13 @@ Released phase, where all of its data can be manually recovered.
|
||||
where `<your-pv-name>` is the name of your chosen PersistentVolume.
|
||||
|
||||
{{< note >}}
|
||||
On Windows, you must _double_ quote any JSONPath template that contains spaces (not single quote as shown above for bash). This in turn means that you must use a single quote or escaped double quote around any literals in the template. For example:
|
||||
On Windows, you must _double_ quote any JSONPath template that contains spaces (not single
|
||||
quote as shown above for bash). This in turn means that you must use a single quote or escaped
|
||||
double quote around any literals in the template. For example:
|
||||
|
||||
```cmd
|
||||
kubectl patch pv <your-pv-name> -p "{\"spec\":{\"persistentVolumeReclaimPolicy\":\"Retain\"}}"
|
||||
```
|
||||
|
||||
{{< /note >}}
|
||||
|
||||
1. Verify that your chosen PersistentVolume has the right policy:
|
||||
@@ -72,17 +71,17 @@ kubectl patch pv <your-pv-name> -p "{\"spec\":{\"persistentVolumeReclaimPolicy\"
|
||||
|
||||
The output is similar to this:
|
||||
|
||||
```none
|
||||
NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE
|
||||
pvc-b6efd8da-b7b5-11e6-9d58-0ed433a7dd94 4Gi RWO Delete Bound default/claim1 manual 40s
|
||||
pvc-b95650f8-b7b5-11e6-9d58-0ed433a7dd94 4Gi RWO Delete Bound default/claim2 manual 36s
|
||||
pvc-bb3ca71d-b7b5-11e6-9d58-0ed433a7dd94 4Gi RWO Retain Bound default/claim3 manual 33s
|
||||
```
|
||||
|
||||
In the preceding output, you can see that the volume bound to claim
|
||||
`default/claim3` has reclaim policy `Retain`. It will not be automatically
|
||||
deleted when a user deletes claim `default/claim3`.
|
||||
|
||||
|
||||
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
* Learn more about [PersistentVolumes](/docs/concepts/storage/persistent-volumes/).
|
||||
@@ -91,8 +90,8 @@ kubectl patch pv <your-pv-name> -p "{\"spec\":{\"persistentVolumeReclaimPolicy\"
|
||||
### References {#reference}
|
||||
|
||||
* {{< api-reference page="config-and-storage-resources/persistent-volume-v1" >}}
|
||||
* Pay attention to the `.spec.persistentVolumeReclaimPolicy` [field](https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-v1/#PersistentVolumeSpec) of PersistentVolume.
|
||||
* Pay attention to the `.spec.persistentVolumeReclaimPolicy`
|
||||
[field](/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-v1/#PersistentVolumeSpec)
|
||||
of PersistentVolume.
|
||||
* {{< api-reference page="config-and-storage-resources/persistent-volume-claim-v1" >}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -19,11 +19,14 @@ This page describes the CoreDNS upgrade process and how to install CoreDNS inste
|
||||
|
||||
## About CoreDNS
|
||||
|
||||
[CoreDNS](https://coredns.io) is a flexible, extensible DNS server that can serve as the Kubernetes cluster DNS.
|
||||
Like Kubernetes, the CoreDNS project is hosted by the {{< glossary_tooltip text="CNCF" term_id="cncf" >}}.
|
||||
[CoreDNS](https://coredns.io) is a flexible, extensible DNS server
|
||||
that can serve as the Kubernetes cluster DNS.
|
||||
Like Kubernetes, the CoreDNS project is hosted by the
|
||||
{{< glossary_tooltip text="CNCF" term_id="cncf" >}}.
|
||||
|
||||
You can use CoreDNS instead of kube-dns in your cluster by replacing kube-dns in an existing
|
||||
deployment, or by using tools like kubeadm that will deploy and upgrade the cluster for you.
|
||||
You can use CoreDNS instead of kube-dns in your cluster by replacing
|
||||
kube-dns in an existing deployment, or by using tools like kubeadm
|
||||
that will deploy and upgrade the cluster for you.
|
||||
|
||||
## Installing CoreDNS
|
||||
|
||||
@@ -34,51 +37,44 @@ For manual deployment or replacement of kube-dns, see the documentation at the
|
||||
|
||||
### Upgrading an existing cluster with kubeadm
|
||||
|
||||
In Kubernetes version 1.10 and later, you can also move to CoreDNS when you use `kubeadm` to upgrade
|
||||
a cluster that is using `kube-dns`. In this case, `kubeadm` will generate the CoreDNS configuration
|
||||
In Kubernetes version 1.21, kubeadm removed its support for `kube-dns` as a DNS application.
|
||||
For `kubeadm` v{{< skew currentVersion >}}, the only supported cluster DNS application
|
||||
is CoreDNS.
|
||||
|
||||
You can move to CoreDNS when you use `kubeadm` to upgrade a cluster that is
|
||||
using `kube-dns`. In this case, `kubeadm` generates the CoreDNS configuration
|
||||
("Corefile") based upon the `kube-dns` ConfigMap, preserving configurations for
|
||||
stub domains, and upstream name server.
|
||||
|
||||
If you are moving from kube-dns to CoreDNS, make sure to set the `CoreDNS` feature gate to `true`
|
||||
during an upgrade. For example, here is what a `v1.11.0` upgrade would look like:
|
||||
```
|
||||
kubeadm upgrade apply v1.11.0 --feature-gates=CoreDNS=true
|
||||
```
|
||||
|
||||
In Kubernetes version 1.13 and later the `CoreDNS` feature gate is removed and CoreDNS
|
||||
is used by default.
|
||||
|
||||
In versions prior to 1.11 the Corefile will be **overwritten** by the one created during upgrade.
|
||||
**You should save your existing ConfigMap if you have customized it.** You may re-apply your
|
||||
customizations after the new ConfigMap is up and running.
|
||||
|
||||
If you are running CoreDNS in Kubernetes version 1.11 and later, during upgrade,
|
||||
your existing Corefile will be retained.
|
||||
|
||||
In Kubernetes version 1.21, support for `kube-dns` is removed from kubeadm.
|
||||
|
||||
## Upgrading CoreDNS
|
||||
|
||||
CoreDNS is available in Kubernetes since v1.9.
|
||||
You can check the version of CoreDNS shipped with Kubernetes and the changes made to CoreDNS [here](https://github.com/coredns/deployment/blob/master/kubernetes/CoreDNS-k8s_version.md).
|
||||
You can check the version of CoreDNS that kubeadm installs for each version of
|
||||
Kubernetes in the page
|
||||
[CoreDNS version in Kubernetes](https://github.com/coredns/deployment/blob/master/kubernetes/CoreDNS-k8s_version.md).
|
||||
|
||||
CoreDNS can be upgraded manually in case you want to only upgrade CoreDNS
|
||||
or use your own custom image.
|
||||
There is a helpful [guideline and walkthrough](https://github.com/coredns/deployment/blob/master/kubernetes/Upgrading_CoreDNS.md)
|
||||
available to ensure a smooth upgrade.
|
||||
Make sure the existing CoreDNS configuration ("Corefile") is retained when
|
||||
upgrading your cluster.
|
||||
|
||||
If you are upgrading your cluster using the `kubeadm` tool, `kubeadm`
|
||||
can take care of retaining the existing CoreDNS configuration automatically.
|
||||
|
||||
CoreDNS can be upgraded manually in case you want to only upgrade CoreDNS or use your own custom image.
|
||||
There is a helpful [guideline and walkthrough](https://github.com/coredns/deployment/blob/master/kubernetes/Upgrading_CoreDNS.md) available to ensure a smooth upgrade.
|
||||
|
||||
## Tuning CoreDNS
|
||||
|
||||
When resource utilisation is a concern, it may be useful to tune the configuration of CoreDNS. For more details, check out the
|
||||
When resource utilisation is a concern, it may be useful to tune the
|
||||
configuration of CoreDNS. For more details, check out the
|
||||
[documentation on scaling CoreDNS](https://github.com/coredns/deployment/blob/master/kubernetes/Scaling_CoreDNS.md).
|
||||
|
||||
|
||||
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
|
||||
You can configure [CoreDNS](https://coredns.io) to support many more use cases than
|
||||
kube-dns by modifying the `Corefile`. For more information, see the
|
||||
[CoreDNS site](https://coredns.io/2017/05/08/custom-dns-entries-for-kubernetes/).
|
||||
|
||||
|
||||
|
||||
kube-dns does by modifying the CoreDNS configuration ("Corefile").
|
||||
For more information, see the [documentation](https://coredns.io/plugins/kubernetes/)
|
||||
for the `kubernetes` CoreDNS plugin, or read the
|
||||
[Custom DNS Entries for Kubernetes](https://coredns.io/2017/05/08/custom-dns-entries-for-kubernetes/).
|
||||
in the CoreDNS blog.
|
||||
|
||||
|
||||
@@ -99,10 +99,10 @@ and a memory limit of 200 MiB.
|
||||
```yaml
|
||||
...
|
||||
resources:
|
||||
limits:
|
||||
memory: 200Mi
|
||||
requests:
|
||||
memory: 100Mi
|
||||
limits:
|
||||
memory: 200Mi
|
||||
...
|
||||
```
|
||||
|
||||
|
||||
+1
-1
@@ -50,7 +50,7 @@ plugins:
|
||||
# Array of authenticated usernames to exempt.
|
||||
usernames: []
|
||||
# Array of runtime class names to exempt.
|
||||
runtimeClassNames: []
|
||||
runtimeClasses: []
|
||||
# Array of namespaces to exempt.
|
||||
namespaces: []
|
||||
```
|
||||
|
||||
@@ -208,7 +208,6 @@ you need is an existing `docker-compose.yml` file.
|
||||
- CLI
|
||||
- [`kompose convert`](#kompose-convert)
|
||||
- Documentation
|
||||
- [Build and Push Docker Images](#build-and-push-docker-images)
|
||||
- [Alternative Conversions](#alternative-conversions)
|
||||
- [Labels](#labels)
|
||||
- [Restart](#restart)
|
||||
@@ -326,55 +325,6 @@ INFO OpenShift file "foo-buildconfig.yaml" created
|
||||
If you are manually pushing the OpenShift artifacts using ``oc create -f``, you need to ensure that you push the imagestream artifact before the buildconfig artifact, to workaround this OpenShift issue: https://github.com/openshift/origin/issues/4518 .
|
||||
{{< /note >}}
|
||||
|
||||
|
||||
|
||||
## Build and Push Docker Images
|
||||
|
||||
Kompose supports both building and pushing Docker images. When using the `build` key within your Docker Compose file, your image will:
|
||||
|
||||
- Automatically be built with Docker using the `image` key specified within your file
|
||||
- Be pushed to the correct Docker repository using local credentials (located at `.docker/config`)
|
||||
|
||||
Using an [example Docker Compose file](https://raw.githubusercontent.com/kubernetes/kompose/master/examples/buildconfig/docker-compose.yml):
|
||||
|
||||
```yaml
|
||||
version: "2"
|
||||
|
||||
services:
|
||||
foo:
|
||||
build: "./build"
|
||||
image: docker.io/foo/bar
|
||||
```
|
||||
|
||||
Using `kompose up` with a `build` key:
|
||||
|
||||
```none
|
||||
kompose up
|
||||
INFO Build key detected. Attempting to build and push image 'docker.io/foo/bar'
|
||||
INFO Building image 'docker.io/foo/bar' from directory 'build'
|
||||
INFO Image 'docker.io/foo/bar' from directory 'build' built successfully
|
||||
INFO Pushing image 'foo/bar:latest' to registry 'docker.io'
|
||||
INFO Attempting authentication credentials 'https://index.docker.io/v1/
|
||||
INFO Successfully pushed image 'foo/bar:latest' to registry 'docker.io'
|
||||
INFO We are going to create Kubernetes Deployments, Services and PersistentVolumeClaims for your Dockerized application. If you need different kind of resources, use the 'kompose convert' and 'kubectl apply -f' commands instead.
|
||||
|
||||
INFO Deploying application in "default" namespace
|
||||
INFO Successfully created Service: foo
|
||||
INFO Successfully created Deployment: foo
|
||||
|
||||
Your application has been deployed to Kubernetes. You can run 'kubectl get deployment,svc,pods,pvc' for details.
|
||||
```
|
||||
|
||||
In order to disable the functionality, or choose to use BuildConfig generation (with OpenShift) `--build (local|build-config|none)` can be passed.
|
||||
|
||||
```sh
|
||||
# Disable building/pushing Docker images
|
||||
kompose up --build none
|
||||
|
||||
# Generate Build Config artifacts for OpenShift
|
||||
kompose up --provider openshift --build build-config
|
||||
```
|
||||
|
||||
## Alternative Conversions
|
||||
|
||||
The default `kompose` transformation will generate Kubernetes [Deployments](/docs/concepts/workloads/controllers/deployment/) and [Services](/docs/concepts/services-networking/service/), in yaml format. You have alternative option to generate json with `-j`. Also, you can alternatively generate [Replication Controllers](/docs/concepts/workloads/controllers/replicationcontroller/) objects, [Daemon Sets](/docs/concepts/workloads/controllers/daemonset/), or [Helm](https://github.com/helm/helm) charts.
|
||||
|
||||
@@ -8,14 +8,19 @@ content_type: concept
|
||||
|
||||
<!-- overview -->
|
||||
|
||||
For Kubernetes, the _Metrics API_ offers a basic set of metrics to support automatic scaling and similar use cases.
|
||||
This API makes information available about resource usage for node and pod, including metrics for CPU and memory.
|
||||
If you deploy the Metrics API into your cluster, clients of the Kubernetes API can then query for this information, and
|
||||
you can use Kubernetes' access control mechanisms to manage permissions to do so.
|
||||
For Kubernetes, the _Metrics API_ offers a basic set of metrics to support automatic scaling and
|
||||
similar use cases. This API makes information available about resource usage for node and pod,
|
||||
including metrics for CPU and memory. If you deploy the Metrics API into your cluster, clients of
|
||||
the Kubernetes API can then query for this information, and you can use Kubernetes' access control
|
||||
mechanisms to manage permissions to do so.
|
||||
|
||||
The [HorizontalPodAutoscaler](/docs/tasks/run-application/horizontal-pod-autoscale/) (HPA) and [VerticalPodAutoscaler](https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler#readme) (VPA) use data from the metrics API to adjust workload replicas and resources to meet customer demand.
|
||||
The [HorizontalPodAutoscaler](/docs/tasks/run-application/horizontal-pod-autoscale/) (HPA) and
|
||||
[VerticalPodAutoscaler](https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler#readme) (VPA)
|
||||
use data from the metrics API to adjust workload replicas and resources to meet customer demand.
|
||||
|
||||
You can also view the resource metrics using the [`kubectl top`](https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#top) command.
|
||||
You can also view the resource metrics using the
|
||||
[`kubectl top`](/docs/reference/generated/kubectl/kubectl-commands#top)
|
||||
command.
|
||||
|
||||
{{< note >}}
|
||||
The Metrics API, and the metrics pipeline that it enables, only offers the minimum
|
||||
@@ -59,34 +64,51 @@ Figure 1. Resource Metrics Pipeline
|
||||
|
||||
The architecture components, from right to left in the figure, consist of the following:
|
||||
|
||||
* [cAdvisor](https://github.com/google/cadvisor): Daemon for collecting, aggregating and exposing container metrics included in Kubelet.
|
||||
* [kubelet](/docs/concepts/overview/components/#kubelet): Node agent for managing container resources. Resource metrics are accessible using the `/metrics/resource` and `/stats` kubelet API endpoints.
|
||||
* [Summary API](#summary-api-source): API provided by the kubelet for discovering and retrieving per-node summarized stats available through the `/stats` endpoint.
|
||||
* [metrics-server](#metrics-server): Cluster addon component that collects and aggregates resource metrics pulled from each kubelet. The API server serves Metrics API for use by HPA, VPA, and by the `kubectl top` command. Metrics Server is a reference implementation of the Metrics API.
|
||||
* [Metrics API](#metrics-api): Kubernetes API supporting access to CPU and memory used for workload autoscaling. To make this work in your cluster, you need an API extension server that provides the Metrics API.
|
||||
* [cAdvisor](https://github.com/google/cadvisor): Daemon for collecting, aggregating and exposing
|
||||
container metrics included in Kubelet.
|
||||
* [kubelet](/docs/concepts/overview/components/#kubelet): Node agent for managing container
|
||||
resources. Resource metrics are accessible using the `/metrics/resource` and `/stats` kubelet
|
||||
API endpoints.
|
||||
* [Summary API](#summary-api-source): API provided by the kubelet for discovering and retrieving
|
||||
per-node summarized stats available through the `/stats` endpoint.
|
||||
* [metrics-server](#metrics-server): Cluster addon component that collects and aggregates resource
|
||||
metrics pulled from each kubelet. The API server serves Metrics API for use by HPA, VPA, and by
|
||||
the `kubectl top` command. Metrics Server is a reference implementation of the Metrics API.
|
||||
* [Metrics API](#metrics-api): Kubernetes API supporting access to CPU and memory used for
|
||||
workload autoscaling. To make this work in your cluster, you need an API extension server that
|
||||
provides the Metrics API.
|
||||
|
||||
{{< note >}}
|
||||
cAdvisor supports reading metrics from cgroups, which works with typical container runtimes on Linux.
|
||||
If you use a container runtime that uses another resource isolation mechanism, for example virtualization, then that container runtime must support [CRI Container Metrics](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-node/cri-container-stats.md) in order for metrics to be available to the kubelet.
|
||||
If you use a container runtime that uses another resource isolation mechanism, for example
|
||||
virtualization, then that container runtime must support
|
||||
[CRI Container Metrics](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-node/cri-container-stats.md)
|
||||
in order for metrics to be available to the kubelet.
|
||||
{{< /note >}}
|
||||
|
||||
|
||||
<!-- body -->
|
||||
|
||||
## Metrics API
|
||||
|
||||
The metrics-server implements the Metrics API. This API allows you to access CPU and memory usage for the nodes and pods in your cluster. Its primary role is to feed resource usage metrics to K8s autoscaler components.
|
||||
The metrics-server implements the Metrics API. This API allows you to access CPU and memory usage
|
||||
for the nodes and pods in your cluster. Its primary role is to feed resource usage metrics to K8s
|
||||
autoscaler components.
|
||||
|
||||
Here is an example of the Metrics API request for a `minikube` node piped through `jq` for easier
|
||||
reading:
|
||||
|
||||
Here is an example of the Metrics API request for a `minikube` node piped through `jq` for easier reading:
|
||||
```shell
|
||||
kubectl get --raw "/apis/metrics.k8s.io/v1beta1/nodes/minikube" | jq '.'
|
||||
```
|
||||
|
||||
Here is the same API call using `curl`:
|
||||
|
||||
```shell
|
||||
curl http://localhost:8080/apis/metrics.k8s.io/v1beta1/nodes/minikube
|
||||
```
|
||||
Sample reply:
|
||||
|
||||
Sample response:
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": "NodeMetrics",
|
||||
@@ -104,16 +126,22 @@ Sample reply:
|
||||
}
|
||||
}
|
||||
```
|
||||
Here is an example of the Metrics API request for a `kube-scheduler-minikube` pod contained in the `kube-system` namespace and piped through `jq` for easier reading:
|
||||
|
||||
Here is an example of the Metrics API request for a `kube-scheduler-minikube` pod contained in the
|
||||
`kube-system` namespace and piped through `jq` for easier reading:
|
||||
|
||||
```shell
|
||||
kubectl get --raw "/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/kube-scheduler-minikube" | jq '.'
|
||||
```
|
||||
|
||||
Here is the same API call using `curl`:
|
||||
|
||||
```shell
|
||||
curl http://localhost:8080/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/kube-scheduler-minikube
|
||||
```
|
||||
Sample reply:
|
||||
|
||||
Sample response:
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": "PodMetrics",
|
||||
@@ -138,47 +166,72 @@ Sample reply:
|
||||
}
|
||||
```
|
||||
|
||||
The Metrics API is defined in the [k8s.io/metrics](https://github.com/kubernetes/metrics) repository. You must enable the [API aggregation layer](/docs/tasks/extend-kubernetes/configure-aggregation-layer/) and register an [APIService](/docs/reference/kubernetes-api/cluster-resources/api-service-v1/) for the `metrics.k8s.io` API.
|
||||
The Metrics API is defined in the [k8s.io/metrics](https://github.com/kubernetes/metrics)
|
||||
repository. You must enable the [API aggregation layer](/docs/tasks/extend-kubernetes/configure-aggregation-layer/)
|
||||
and register an [APIService](/docs/reference/kubernetes-api/cluster-resources/api-service-v1/)
|
||||
for the `metrics.k8s.io` API.
|
||||
|
||||
To learn more about the Metrics API, see [resource metrics API design](https://github.com/kubernetes/design-proposals-archive/blob/main/instrumentation/resource-metrics-api.md), the [metrics-server repository](https://github.com/kubernetes-sigs/metrics-server) and the [resource metrics API](https://github.com/kubernetes/metrics#resource-metrics-api).
|
||||
To learn more about the Metrics API, see [resource metrics API design](https://github.com/kubernetes/design-proposals-archive/blob/main/instrumentation/resource-metrics-api.md),
|
||||
the [metrics-server repository](https://github.com/kubernetes-sigs/metrics-server) and the
|
||||
[resource metrics API](https://github.com/kubernetes/metrics#resource-metrics-api).
|
||||
|
||||
|
||||
{{< note >}} You must deploy the metrics-server or alternative adapter that serves the Metrics API to be able to access it. {{< /note >}}
|
||||
{{< note >}}
|
||||
You must deploy the metrics-server or alternative adapter that serves the Metrics API to be able
|
||||
to access it.
|
||||
{{< /note >}}
|
||||
|
||||
## Measuring resource usage
|
||||
|
||||
### CPU
|
||||
|
||||
CPU is reported as the average core usage measured in cpu units. One cpu, in Kubernetes, is equivalent to 1 vCPU/Core for cloud providers, and 1 hyper-thread on bare-metal Intel processors.
|
||||
CPU is reported as the average core usage measured in cpu units. One cpu, in Kubernetes, is
|
||||
equivalent to 1 vCPU/Core for cloud providers, and 1 hyper-thread on bare-metal Intel processors.
|
||||
|
||||
This value is derived by taking a rate over a cumulative CPU counter provided by the kernel (in both Linux and Windows kernels). The time window used to calculate CPU is shown under window field in Metrics API.
|
||||
This value is derived by taking a rate over a cumulative CPU counter provided by the kernel (in
|
||||
both Linux and Windows kernels). The time window used to calculate CPU is shown under window field
|
||||
in Metrics API.
|
||||
|
||||
To learn more about how Kubernetes allocates and measures CPU resources, see [meaning of CPU](/docs/concepts/configuration/manage-compute-resources-container/#meaning-of-cpu).
|
||||
To learn more about how Kubernetes allocates and measures CPU resources, see
|
||||
[meaning of CPU](/docs/concepts/configuration/manage-resources-container/#meaning-of-cpu).
|
||||
|
||||
### Memory
|
||||
|
||||
Memory is reported as the working set, measured in bytes, at the instant the metric was collected.
|
||||
|
||||
In an ideal world, the "working set" is the amount of memory in-use that cannot be freed under memory pressure. However, calculation of the working set varies by host OS, and generally makes heavy use of heuristics to produce an estimate.
|
||||
In an ideal world, the "working set" is the amount of memory in-use that cannot be freed under
|
||||
memory pressure. However, calculation of the working set varies by host OS, and generally makes
|
||||
heavy use of heuristics to produce an estimate.
|
||||
|
||||
The Kubernetes model for a container's working set expects that the container runtime counts anonymous memory associated with the container in question. The working set metric typically also includes some cached (file-backed) memory, because the host OS cannot always reclaim pages.
|
||||
The Kubernetes model for a container's working set expects that the container runtime counts
|
||||
anonymous memory associated with the container in question. The working set metric typically also
|
||||
includes some cached (file-backed) memory, because the host OS cannot always reclaim pages.
|
||||
|
||||
To learn more about how Kubernetes allocates and measures memory resources, see [meaning of memory](/docs/concepts/configuration/manage-compute-resources-container/#meaning-of-memory).
|
||||
To learn more about how Kubernetes allocates and measures memory resources, see
|
||||
[meaning of memory](/docs/concepts/configuration/manage-resources-container/#meaning-of-memory).
|
||||
|
||||
## Metrics Server
|
||||
|
||||
The metrics-server fetches resource metrics from the kubelets and exposes them in the Kubernetes API server through the Metrics API for use by the HPA and VPA. You can also view these metrics using the `kubectl top` command.
|
||||
The metrics-server fetches resource metrics from the kubelets and exposes them in the Kubernetes
|
||||
API server through the Metrics API for use by the HPA and VPA. You can also view these metrics
|
||||
using the `kubectl top` command.
|
||||
|
||||
The metrics-server uses the Kubernetes API to track nodes and pods in your cluster. The metrics-server queries each node over HTTP to fetch metrics. The metrics-server also builds an internal view of pod metadata, and keeps a cache of pod health. That cached pod health information is available via the extension API that the metrics-server makes available.
|
||||
The metrics-server uses the Kubernetes API to track nodes and pods in your cluster. The
|
||||
metrics-server queries each node over HTTP to fetch metrics. The metrics-server also builds an
|
||||
internal view of pod metadata, and keeps a cache of pod health. That cached pod health information
|
||||
is available via the extension API that the metrics-server makes available.
|
||||
|
||||
For example with an HPA query, the metrics-server needs to identify which pods fulfill the label selectors in the deployment.
|
||||
For example with an HPA query, the metrics-server needs to identify which pods fulfill the label
|
||||
selectors in the deployment.
|
||||
|
||||
The metrics-server calls the [kubelet](/docs/reference/command-line-tools-reference/kubelet/) API
|
||||
to collect metrics from each node. Depending on the metrics-server version it uses:
|
||||
|
||||
The metrics-server calls the [kubelet](/docs/reference/command-line-tools-reference/kubelet/) API to collect metrics from each node. Depending on the metrics-server version it uses:
|
||||
* Metrics resource endpoint `/metrics/resource` in version v0.6.0+ or
|
||||
* Summary API endpoint `/stats/summary` in older versions
|
||||
|
||||
|
||||
To learn more about the metrics-server, see the [metrics-server repository](https://github.com/kubernetes-sigs/metrics-server).
|
||||
To learn more about the metrics-server, see the
|
||||
[metrics-server repository](https://github.com/kubernetes-sigs/metrics-server).
|
||||
|
||||
You can also check out the following:
|
||||
|
||||
@@ -190,20 +243,25 @@ You can also check out the following:
|
||||
|
||||
### Summary API source
|
||||
|
||||
The [kubelet](/docs/reference/command-line-tools-reference/kubelet/) gathers stats at the node, volume, pod and container level, and emits this information in
|
||||
The [kubelet](/docs/reference/command-line-tools-reference/kubelet/) gathers stats at the node,
|
||||
volume, pod and container level, and emits this information in
|
||||
the [Summary API](https://github.com/kubernetes/kubernetes/blob/7d309e0104fedb57280b261e5677d919cb2a0e2d/staging/src/k8s.io/kubelet/pkg/apis/stats/v1alpha1/types.go)
|
||||
for consumers to read.
|
||||
|
||||
Here is an example of a Summary API request for a `minikube` node:
|
||||
|
||||
|
||||
```shell
|
||||
kubectl get --raw "/api/v1/nodes/minikube/proxy/stats/summary"
|
||||
```
|
||||
|
||||
Here is the same API call using `curl`:
|
||||
|
||||
```shell
|
||||
curl http://localhost:8080/api/v1/nodes/minikube/proxy/stats/summary
|
||||
```
|
||||
|
||||
{{< note >}}
|
||||
The summary API `/stats/summary` endpoint will be replaced by the `/metrics/resource` endpoint beginning with metrics-server 0.6.x.
|
||||
The summary API `/stats/summary` endpoint will be replaced by the `/metrics/resource` endpoint
|
||||
beginning with metrics-server 0.6.x.
|
||||
{{< /note >}}
|
||||
|
||||
|
||||
+50
-46
@@ -6,20 +6,15 @@ weight: 40
|
||||
|
||||
<!-- overview -->
|
||||
|
||||
This page shows how a Pod can use a DownwardAPIVolumeFile to expose information
|
||||
about itself to Containers running in the Pod. A DownwardAPIVolumeFile can expose
|
||||
Pod fields and Container fields.
|
||||
|
||||
|
||||
|
||||
This page shows how a Pod can use a
|
||||
[`DownwardAPIVolumeFile`](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#downwardapivolumefile-v1-core)
|
||||
to expose information about itself to Containers running in the Pod.
|
||||
A `DownwardAPIVolumeFile` can expose Pod fields and Container fields.
|
||||
|
||||
## {{% heading "prerequisites" %}}
|
||||
|
||||
|
||||
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
|
||||
|
||||
|
||||
|
||||
<!-- steps -->
|
||||
|
||||
## The Downward API
|
||||
@@ -27,10 +22,10 @@ Pod fields and Container fields.
|
||||
There are two ways to expose Pod and Container fields to a running Container:
|
||||
|
||||
* [Environment variables](/docs/tasks/inject-data-application/environment-variable-expose-pod-information/#the-downward-api)
|
||||
* Volume Files
|
||||
* Volume files
|
||||
|
||||
Together, these two ways of exposing Pod and Container fields are called the
|
||||
*Downward API*.
|
||||
"Downward API".
|
||||
|
||||
## Store Pod fields
|
||||
|
||||
@@ -60,13 +55,13 @@ Create the Pod:
|
||||
kubectl apply -f https://k8s.io/examples/pods/inject/dapi-volume.yaml
|
||||
```
|
||||
|
||||
Verify that the Container in the Pod is running:
|
||||
Verify that the container in the Pod is running:
|
||||
|
||||
```shell
|
||||
kubectl get pods
|
||||
```
|
||||
|
||||
View the Container's logs:
|
||||
View the container's logs:
|
||||
|
||||
```shell
|
||||
kubectl logs kubernetes-downwardapi-volume-example
|
||||
@@ -83,7 +78,7 @@ build="two"
|
||||
builder="john-doe"
|
||||
```
|
||||
|
||||
Get a shell into the Container that is running in your Pod:
|
||||
Get a shell into the container that is running in your Pod:
|
||||
|
||||
```shell
|
||||
kubectl exec -it kubernetes-downwardapi-volume-example -- sh
|
||||
@@ -136,8 +131,7 @@ total 8
|
||||
|
||||
Using symbolic links enables dynamic atomic refresh of the metadata; updates are
|
||||
written to a new temporary directory, and the `..data` symlink is updated
|
||||
atomically using
|
||||
[rename(2)](http://man7.org/linux/man-pages/man2/rename.2.html).
|
||||
atomically using [rename(2)](http://man7.org/linux/man-pages/man2/rename.2.html).
|
||||
|
||||
{{< note >}}
|
||||
A container using Downward API as a
|
||||
@@ -153,17 +147,19 @@ Exit the shell:
|
||||
|
||||
## Store Container fields
|
||||
|
||||
The preceding exercise, you stored Pod fields in a DownwardAPIVolumeFile.
|
||||
The preceding exercise, you stored Pod fields in a
|
||||
[`DownwardAPIVolumeFile`](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#downwardapivolumefile-v1-core)..
|
||||
In this next exercise, you store Container fields. Here is the configuration
|
||||
file for a Pod that has one Container:
|
||||
|
||||
{{< codenew file="pods/inject/dapi-volume-resources.yaml" >}}
|
||||
|
||||
In the configuration file, you can see that the Pod has a `downwardAPI` Volume,
|
||||
and the Container mounts the Volume at `/etc/podinfo`.
|
||||
In the configuration file, you can see that the Pod has a
|
||||
[`downwardAPI` volume](/concepts/storage/volumes/#downwardapi),
|
||||
and the Container mounts the volume at `/etc/podinfo`.
|
||||
|
||||
Look at the `items` array under `downwardAPI`. Each element of the array is a
|
||||
DownwardAPIVolumeFile.
|
||||
[`DownwardAPIVolumeFile`](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#downwardapivolumefile-v1-core).
|
||||
|
||||
The first element specifies that in the Container named `client-container`,
|
||||
the value of the `limits.cpu` field in the format specified by `1m` should be
|
||||
@@ -176,7 +172,7 @@ Create the Pod:
|
||||
kubectl apply -f https://k8s.io/examples/pods/inject/dapi-volume-resources.yaml
|
||||
```
|
||||
|
||||
Get a shell into the Container that is running in your Pod:
|
||||
Get a shell into the container that is running in your Pod:
|
||||
|
||||
```shell
|
||||
kubectl exec -it kubernetes-downwardapi-volume-example-2 -- sh
|
||||
@@ -187,46 +183,56 @@ In your shell, view the `cpu_limit` file:
|
||||
```shell
|
||||
/# cat /etc/podinfo/cpu_limit
|
||||
```
|
||||
|
||||
You can use similar commands to view the `cpu_request`, `mem_limit` and
|
||||
`mem_request` files.
|
||||
|
||||
|
||||
|
||||
<!-- discussion -->
|
||||
|
||||
<!-- TODO: This section should be extracted out of the task page. -->
|
||||
## Capabilities of the Downward API
|
||||
|
||||
The following information is available to containers through environment
|
||||
variables and `downwardAPI` volumes:
|
||||
|
||||
* Information available via `fieldRef`:
|
||||
|
||||
* `metadata.name` - the pod's name
|
||||
* `metadata.namespace` - the pod's namespace
|
||||
* `metadata.uid` - the pod's UID
|
||||
* `metadata.labels['<KEY>']` - the value of the pod's label `<KEY>` (for example, `metadata.labels['mylabel']`)
|
||||
* `metadata.annotations['<KEY>']` - the value of the pod's annotation `<KEY>` (for example, `metadata.annotations['myannotation']`)
|
||||
* `metadata.labels['<KEY>']` - the value of the pod's label `<KEY>`
|
||||
(for example, `metadata.labels['mylabel']`)
|
||||
* `metadata.annotations['<KEY>']` - the value of the pod's annotation `<KEY>`
|
||||
(for example, `metadata.annotations['myannotation']`)
|
||||
|
||||
* Information available via `resourceFieldRef`:
|
||||
|
||||
* A Container's CPU limit
|
||||
* A Container's CPU request
|
||||
* A Container's memory limit
|
||||
* A Container's memory request
|
||||
* A Container's hugepages limit (providing that the `DownwardAPIHugePages` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/) is enabled)
|
||||
* A Container's hugepages request (providing that the `DownwardAPIHugePages` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/) is enabled)
|
||||
* A Container's hugepages limit (provided that the `DownwardAPIHugePages`
|
||||
[feature gate](/docs/reference/command-line-tools-reference/feature-gates/) is enabled)
|
||||
* A Container's hugepages request (provided that the `DownwardAPIHugePages`
|
||||
[feature gate](/docs/reference/command-line-tools-reference/feature-gates/) is enabled)
|
||||
* A Container's ephemeral-storage limit
|
||||
* A Container's ephemeral-storage request
|
||||
|
||||
In addition, the following information is available through
|
||||
`downwardAPI` volume `fieldRef`:
|
||||
|
||||
* `metadata.labels` - all of the pod's labels, formatted as `label-key="escaped-label-value"` with one label per line
|
||||
* `metadata.annotations` - all of the pod's annotations, formatted as `annotation-key="escaped-annotation-value"` with one annotation per line
|
||||
* `metadata.labels` - all of the pod's labels, formatted as `label-key="escaped-label-value"`
|
||||
with one label per line
|
||||
* `metadata.annotations` - all of the pod's annotations, formatted as
|
||||
`annotation-key="escaped-annotation-value"` with one annotation per line
|
||||
|
||||
The following information is available through environment variables:
|
||||
|
||||
* `status.podIP` - the pod's IP address
|
||||
* `spec.serviceAccountName` - the pod's service account name, available since v1.4.0-alpha.3
|
||||
* `spec.nodeName` - the node's name, available since v1.4.0-alpha.3
|
||||
* `status.hostIP` - the node's IP, available since v1.7.0-alpha.1
|
||||
* `spec.serviceAccountName` - the pod's service account name
|
||||
* `spec.nodeName` - the name of the node to which the scheduler always attempts to
|
||||
schedule the pod
|
||||
* `status.hostIP` - the IP of the node to which the Pod is assigned
|
||||
|
||||
{{< note >}}
|
||||
If CPU and memory limits are not specified for a Container, the
|
||||
@@ -241,7 +247,7 @@ basis. For more information, see
|
||||
|
||||
## Motivation for the Downward API
|
||||
|
||||
It is sometimes useful for a Container to have information about itself, without
|
||||
It is sometimes useful for a container to have information about itself, without
|
||||
being overly coupled to Kubernetes. The Downward API allows containers to consume
|
||||
information about themselves or the cluster without using the Kubernetes client
|
||||
or API server.
|
||||
@@ -252,19 +258,17 @@ application, but that is tedious and error prone, and it violates the goal of lo
|
||||
coupling. A better option would be to use the Pod's name as an identifier, and
|
||||
inject the Pod's name into the well-known environment variable.
|
||||
|
||||
|
||||
|
||||
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
|
||||
* [PodSpec](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podspec-v1-core)
|
||||
* [Volume](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#volume-v1-core)
|
||||
* [DownwardAPIVolumeSource](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#downwardapivolumesource-v1-core)
|
||||
* [DownwardAPIVolumeFile](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#downwardapivolumefile-v1-core)
|
||||
* [ResourceFieldSelector](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#resourcefieldselector-v1-core)
|
||||
|
||||
|
||||
|
||||
|
||||
* Check the [`PodSpec`](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podspec-v1-core)
|
||||
API definition which defines the desired state of a Pod.
|
||||
* Check the [`Volume`](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#volume-v1-core)
|
||||
API definition which defines a generic volume in a Pod for containers to access.
|
||||
* Check the [`DownwardAPIVolumeSource`](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#downwardapivolumesource-v1-core)
|
||||
API definition which defines a volume that contains Downward API information.
|
||||
* Check the [`DownwardAPIVolumeFile`](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#downwardapivolumefile-v1-core)
|
||||
API definition which contains references to object or resource fields for
|
||||
populating a file in the Downward API volume.
|
||||
* Check the [`ResourceFieldSelector`](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#resourcefieldselector-v1-core)
|
||||
API definition which specifies the container resources and their output format.
|
||||
|
||||
|
||||
@@ -35,9 +35,9 @@ To enable the rolling update feature of a DaemonSet, you must set its
|
||||
`.spec.updateStrategy.type` to `RollingUpdate`.
|
||||
|
||||
You may want to set
|
||||
[`.spec.updateStrategy.rollingUpdate.maxUnavailable`](/docs/concepts/workloads/controllers/deployment/#max-unavailable)
|
||||
[`.spec.updateStrategy.rollingUpdate.maxUnavailable`](/docs/reference/kubernetes-api/workload-resources/daemon-set-v1/#DaemonSetSpec)
|
||||
(default to 1),
|
||||
[`.spec.minReadySeconds`](/docs/concepts/workloads/controllers/deployment/#min-ready-seconds)
|
||||
[`.spec.minReadySeconds`](/docs/reference/kubernetes-api/workload-resources/daemon-set-v1/#DaemonSetSpec)
|
||||
(default to 0) and
|
||||
[`.spec.updateStrategy.rollingUpdate.maxSurge`](/docs/reference/kubernetes-api/workload-resources/daemon-set-v1/#DaemonSetSpec)
|
||||
(a beta feature and defaults to 0) as well.
|
||||
|
||||
@@ -308,7 +308,7 @@ metadata:
|
||||
type: Opaque
|
||||
```
|
||||
|
||||
Like ConfigMaps, generated Secrets can be used in Deployments by refering to the name of the secretGenerator:
|
||||
Like ConfigMaps, generated Secrets can be used in Deployments by referring to the name of the secretGenerator:
|
||||
|
||||
```shell
|
||||
# Create a password.txt file
|
||||
|
||||
@@ -189,7 +189,7 @@ kubectl get deployment patch-demo --output yaml
|
||||
|
||||
The output shows that the PodSpec in the Deployment has only one Toleration:
|
||||
|
||||
```shell
|
||||
```yaml
|
||||
tolerations:
|
||||
- effect: NoSchedule
|
||||
key: disktype
|
||||
|
||||
@@ -12,16 +12,11 @@ To do so in all your shell sessions, add the following to your `~/.zshrc` file:
|
||||
source <(kubectl completion zsh)
|
||||
```
|
||||
|
||||
If you have an alias for kubectl, you can extend shell completion to work with that alias:
|
||||
|
||||
```zsh
|
||||
echo 'alias k=kubectl' >>~/.zshrc
|
||||
echo 'compdef __start_kubectl k' >>~/.zshrc
|
||||
```
|
||||
If you have an alias for kubectl, kubectl autocompletion will automatically work with it.
|
||||
|
||||
After reloading your shell, kubectl autocompletion should be working.
|
||||
|
||||
If you get an error like `complete:13: command not found: compdef`, then add the following to the beginning of your `~/.zshrc` file:
|
||||
If you get an error like `2: command not found: compdef`, then add the following to the beginning of your `~/.zshrc` file:
|
||||
|
||||
```zsh
|
||||
autoload -Uz compinit
|
||||
|
||||
@@ -83,7 +83,7 @@ For example, to download version {{< param "fullversion" >}} on Linux, type:
|
||||
|
||||
```bash
|
||||
chmod +x kubectl
|
||||
mkdir -p ~/.local/bin/kubectl
|
||||
mkdir -p ~/.local/bin
|
||||
mv ./kubectl ~/.local/bin/kubectl
|
||||
# and then append (or prepend) ~/.local/bin to $PATH
|
||||
```
|
||||
|
||||
@@ -38,13 +38,13 @@ The following methods exist for installing kubectl on Windows:
|
||||
|
||||
1. Validate the binary (optional)
|
||||
|
||||
Download the kubectl checksum file:
|
||||
Download the `kubectl` checksum file:
|
||||
|
||||
```powershell
|
||||
curl -LO "https://dl.k8s.io/{{< param "fullversion" >}}/bin/windows/amd64/kubectl.exe.sha256"
|
||||
```
|
||||
|
||||
Validate the kubectl binary against the checksum file:
|
||||
Validate the `kubectl` binary against the checksum file:
|
||||
|
||||
- Using Command Prompt to manually compare `CertUtil`'s output to the checksum file downloaded:
|
||||
|
||||
@@ -59,7 +59,7 @@ The following methods exist for installing kubectl on Windows:
|
||||
$($(CertUtil -hashfile .\kubectl.exe SHA256)[1] -replace " ", "") -eq $(type .\kubectl.exe.sha256)
|
||||
```
|
||||
|
||||
1. Append or prepend the kubectl binary folder to your `PATH` environment variable.
|
||||
1. Append or prepend the `kubectl` binary folder to your `PATH` environment variable.
|
||||
|
||||
1. Test to ensure the version of `kubectl` is the same as downloaded:
|
||||
|
||||
@@ -156,13 +156,13 @@ Below are the procedures to set up autocompletion for PowerShell.
|
||||
|
||||
1. Validate the binary (optional)
|
||||
|
||||
Download the kubectl-convert checksum file:
|
||||
Download the `kubectl-convert` checksum file:
|
||||
|
||||
```powershell
|
||||
curl -LO "https://dl.k8s.io/{{< param "fullversion" >}}/bin/windows/amd64/kubectl-convert.exe.sha256"
|
||||
```
|
||||
|
||||
Validate the kubectl-convert binary against the checksum file:
|
||||
Validate the `kubectl-convert` binary against the checksum file:
|
||||
|
||||
- Using Command Prompt to manually compare `CertUtil`'s output to the checksum file downloaded:
|
||||
|
||||
@@ -177,7 +177,7 @@ Below are the procedures to set up autocompletion for PowerShell.
|
||||
$($(CertUtil -hashfile .\kubectl-convert.exe SHA256)[1] -replace " ", "") -eq $(type .\kubectl-convert.exe.sha256)
|
||||
```
|
||||
|
||||
1. Append or prepend the kubectl binary folder to your `PATH` environment variable.
|
||||
1. Append or prepend the `kubectl-convert` binary folder to your `PATH` environment variable.
|
||||
|
||||
1. Verify plugin is successfully installed
|
||||
|
||||
|
||||
@@ -382,27 +382,13 @@ If you do not want AppArmor to be available on your cluster, it can be disabled
|
||||
```
|
||||
|
||||
When disabled, any Pod that includes an AppArmor profile will fail validation with a "Forbidden"
|
||||
error. Note that by default docker always enables the "docker-default" profile on non-privileged
|
||||
pods (if the AppArmor kernel module is enabled), and will continue to do so even if the feature-gate
|
||||
is disabled. The option to disable AppArmor will be removed when AppArmor graduates to general
|
||||
error.
|
||||
|
||||
{{<note>}}
|
||||
Even if the Kubernetes feature is disabled, runtimes may still enforce the default profile. The
|
||||
option to disable the AppArmor feature will be removed when AppArmor graduates to general
|
||||
availability (GA).
|
||||
|
||||
### Upgrading to Kubernetes v1.4 with AppArmor
|
||||
|
||||
No action is required with respect to AppArmor to upgrade your cluster to v1.4. However, if any
|
||||
existing pods had an AppArmor annotation, they will not go through validation (or PodSecurityPolicy
|
||||
admission). If permissive profiles are loaded on the nodes, a malicious user could pre-apply a
|
||||
permissive profile to escalate the pod privileges above the docker-default. If this is a concern, it
|
||||
is recommended to scrub the cluster of any pods containing an annotation with
|
||||
`apparmor.security.beta.kubernetes.io`.
|
||||
|
||||
### Upgrade path to General Availability
|
||||
|
||||
When AppArmor is ready to be graduated to general availability (GA), the options currently specified
|
||||
through annotations will be converted to fields. Supporting all the upgrade and downgrade paths
|
||||
through the transition is very nuanced, and will be explained in detail when the transition
|
||||
occurs. We will commit to supporting both fields and annotations for at least 2 releases, and will
|
||||
explicitly reject the annotations for at least 2 releases after that.
|
||||
{{</note>}}
|
||||
|
||||
## Authoring Profiles
|
||||
|
||||
@@ -415,10 +401,6 @@ tools to help with that:
|
||||
* [bane](https://github.com/jfrazelle/bane) is an AppArmor profile generator for Docker that uses a
|
||||
simplified profile language.
|
||||
|
||||
It is recommended to run your application through Docker on a development workstation to generate
|
||||
the profiles, but there is nothing preventing running the tools on the Kubernetes node where your
|
||||
Pod is running.
|
||||
|
||||
To debug problems with AppArmor, you can check the system logs to see what, specifically, was
|
||||
denied. AppArmor logs verbose messages to `dmesg`, and errors can usually be found in the system
|
||||
logs or through `journalctl`. More information is provided in
|
||||
@@ -441,9 +423,8 @@ Specifying the profile a container will run with:
|
||||
- `runtime/default`: Refers to the default runtime profile.
|
||||
- Equivalent to not specifying a profile (without a PodSecurityPolicy default), except it still
|
||||
requires AppArmor to be enabled.
|
||||
- For Docker, this resolves to the
|
||||
[`docker-default`](https://docs.docker.com/engine/security/apparmor/) profile for non-privileged
|
||||
containers, and unconfined (no profile) for privileged containers.
|
||||
- In practice, many container runtimes use the same OCI default profile, defined here:
|
||||
https://github.com/containers/common/blob/main/pkg/apparmor/apparmor_linux_template.go
|
||||
- `localhost/<profile_name>`: Refers to a profile loaded on the node (localhost) by name.
|
||||
- The possible profile names are detailed in the
|
||||
[core policy reference](https://gitlab.com/apparmor/apparmor/wikis/AppArmor_Core_Policy_Reference#profile-names-and-attachment-specifications).
|
||||
@@ -474,5 +455,3 @@ Additional resources:
|
||||
|
||||
* [Quick guide to the AppArmor profile language](https://gitlab.com/apparmor/apparmor/wikis/QuickProfileLanguage)
|
||||
* [AppArmor core policy reference](https://gitlab.com/apparmor/apparmor/wikis/Policy_Layout)
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ Pod Security admission (PSA) is enabled by default in v1.23 and later, as it has
|
||||
[graduated to beta](/blog/2021/12/09/pod-security-admission-beta/).
|
||||
Pod Security
|
||||
is an admission controller that carries out checks against the Kubernetes
|
||||
[Pod Security Standards](docs/concepts/security/pod-security-standards/) when new pods are
|
||||
[Pod Security Standards](/docs/concepts/security/pod-security-standards/) when new pods are
|
||||
created. This tutorial shows you how to enforce the `baseline` Pod Security
|
||||
Standard at the cluster level which applies a standard configuration
|
||||
to all namespaces in a cluster.
|
||||
|
||||
@@ -243,7 +243,7 @@ pointing to. This IP address is accessible only within the cluster.
|
||||
|
||||
If you want guests to be able to access your guestbook, you must configure the
|
||||
frontend Service to be externally visible, so a client can request the Service
|
||||
from outside the Kubernetes cluster. However a Kubernetes user you can use
|
||||
from outside the Kubernetes cluster. However a Kubernetes user can use
|
||||
`kubectl port-forward` to access the service even though it uses a
|
||||
`ClusterIP`.
|
||||
|
||||
|
||||
@@ -556,6 +556,7 @@ func TestExampleObjectSchemas(t *testing.T) {
|
||||
"pod-projected-svc-token": {&api.Pod{}},
|
||||
"pod-rs": {&api.Pod{}, &api.Pod{}},
|
||||
"pod-single-configmap-env-variable": {&api.Pod{}},
|
||||
"pod-with-affinity-anti-affinity": {&api.Pod{}},
|
||||
"pod-with-node-affinity": {&api.Pod{}},
|
||||
"pod-with-pod-affinity": {&api.Pod{}},
|
||||
"pod-with-toleration": {&api.Pod{}},
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: with-affinity-anti-affinity
|
||||
spec:
|
||||
affinity:
|
||||
nodeAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
nodeSelectorTerms:
|
||||
- matchExpressions:
|
||||
- key: kubernetes.io/os
|
||||
operator: In
|
||||
values:
|
||||
- linux
|
||||
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
|
||||
@@ -8,11 +8,10 @@ spec:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
nodeSelectorTerms:
|
||||
- matchExpressions:
|
||||
- key: kubernetes.io/e2e-az-name
|
||||
- key: kubernetes.io/os
|
||||
operator: In
|
||||
values:
|
||||
- e2e-az1
|
||||
- e2e-az2
|
||||
- linux
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
- weight: 1
|
||||
preference:
|
||||
|
||||
@@ -8,9 +8,9 @@ spec:
|
||||
- name: memory-demo-3-ctr
|
||||
image: polinux/stress
|
||||
resources:
|
||||
limits:
|
||||
memory: "1000Gi"
|
||||
requests:
|
||||
memory: "1000Gi"
|
||||
limits:
|
||||
memory: "1000Gi"
|
||||
command: ["stress"]
|
||||
args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]
|
||||
|
||||
@@ -8,9 +8,9 @@ spec:
|
||||
- name: memory-demo-ctr
|
||||
image: polinux/stress
|
||||
resources:
|
||||
limits:
|
||||
memory: "200Mi"
|
||||
requests:
|
||||
memory: "100Mi"
|
||||
limits:
|
||||
memory: "200Mi"
|
||||
command: ["stress"]
|
||||
args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]
|
||||
|
||||
@@ -78,10 +78,10 @@ releases may also occur in between these.
|
||||
|
||||
| Monthly Patch Release | Cherry Pick Deadline | Target date |
|
||||
| --------------------- | -------------------- | ----------- |
|
||||
| March 2022 | 2022-03-11 | 2022-03-16 |
|
||||
| April 2022 | 2022-04-08 | 2022-04-13 |
|
||||
| May 2022 | 2022-05-13 | 2022-05-18 |
|
||||
| June 2022 | 2022-06-10 | 2022-06-15 |
|
||||
| July 2022 | 2022-07-08 | 2022-07-13 |
|
||||
|
||||
## Detailed Release History for Active Branches
|
||||
|
||||
@@ -93,6 +93,7 @@ End of Life for **1.23** is **2023-02-28**.
|
||||
|
||||
| Patch Release | Cherry Pick Deadline | Target Date | Note |
|
||||
|---------------|----------------------|-------------|------|
|
||||
| 1.23.6 | 2022-04-08 | 2022-04-13 | |
|
||||
| 1.23.5 | 2022-03-11 | 2022-03-16 | |
|
||||
| 1.23.4 | 2022-02-11 | 2022-02-16 | |
|
||||
| 1.23.3 | 2022-01-24 | 2022-01-25 | [Out-of-Band Release](https://groups.google.com/u/2/a/kubernetes.io/g/dev/c/Xl1sm-CItaY) |
|
||||
@@ -107,6 +108,7 @@ End of Life for **1.22** is **2022-10-28**
|
||||
|
||||
| Patch Release | Cherry Pick Deadline | Target Date | Note |
|
||||
|---------------|----------------------|-------------|------|
|
||||
| 1.22.9 | 2022-04-08 | 2022-04-13 | |
|
||||
| 1.22.8 | 2022-03-11 | 2022-03-16 | |
|
||||
| 1.22.7 | 2022-02-11 | 2022-02-16 | |
|
||||
| 1.22.6 | 2022-01-14 | 2022-01-19 | |
|
||||
@@ -124,6 +126,7 @@ End of Life for **1.21** is **2022-06-28**
|
||||
|
||||
| Patch Release | Cherry Pick Deadline | Target Date | Note |
|
||||
| ------------- | -------------------- | ----------- | ---------------------------------------------------------------------- |
|
||||
| 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 | |
|
||||
|
||||
@@ -121,22 +121,7 @@ En quelques étapes, nous vous emmenons de Docker Compose à Kubernetes. Tous do
|
||||
kompose.service.type: LoadBalancer
|
||||
```
|
||||
|
||||
2. Lancez la commande `kompose up` pour déployer directement sur Kubernetes, ou passez plutôt à l'étape suivante pour générer un fichier à utiliser avec `kubectl`.
|
||||
|
||||
```bash
|
||||
$ kompose up
|
||||
We are going to create Kubernetes Deployments, Services and PersistentVolumeClaims for your Dockerized application.
|
||||
If you need different kind of resources, use the 'kompose convert' and 'kubectl apply -f' commands instead.
|
||||
|
||||
INFO Successfully created Service: redis
|
||||
INFO Successfully created Service: web
|
||||
INFO Successfully created Deployment: redis
|
||||
INFO Successfully created Deployment: web
|
||||
|
||||
Your application has been deployed to Kubernetes. You can run 'kubectl get deployment,svc,pods,pvc' for details.
|
||||
```
|
||||
|
||||
3. Pour convertir le fichier `docker-compose.yml` en fichiers que vous pouvez utiliser avec `kubectl`, lancez `kompose convert` et ensuite `kubectl apply -f <output file>`.
|
||||
2. Pour convertir le fichier `docker-compose.yml` en fichiers que vous pouvez utiliser avec `kubectl`, lancez `kompose convert` et ensuite `kubectl apply -f <output file>`.
|
||||
|
||||
```bash
|
||||
$ kompose convert
|
||||
@@ -160,7 +145,7 @@ En quelques étapes, nous vous emmenons de Docker Compose à Kubernetes. Tous do
|
||||
|
||||
Vos déploiements fonctionnent sur Kubernetes.
|
||||
|
||||
4. Accédez à votre application.
|
||||
3. Accédez à votre application.
|
||||
|
||||
Si vous utilisez déjà `minikube` pour votre processus de développement :
|
||||
|
||||
@@ -201,10 +186,7 @@ En quelques étapes, nous vous emmenons de Docker Compose à Kubernetes. Tous do
|
||||
|
||||
- CLI
|
||||
- [`kompose convert`](#kompose-convert)
|
||||
- [`kompose up`](#kompose-up)
|
||||
- [`kompose down`](#kompose-down)
|
||||
- Documentation
|
||||
- [Construire et pousser des images de docker](#build-and-push-docker-images)
|
||||
- [Conversions alternatives](#alternative-conversions)
|
||||
- [Etiquettes](#labels)
|
||||
- [Redémarrage](#restart)
|
||||
@@ -301,152 +283,6 @@ INFO OpenShift file "foo-buildconfig.yaml" created
|
||||
Si vous poussez manuellement les artefacts OpenShift en utilisant ``oc create -f``, vous devez vous assurer que vous poussez l'artefact imagestream avant l'artefact buildconfig, pour contourner ce problème OpenShift : https://github.com/openshift/origin/issues/4518 .
|
||||
{{< /note >}}
|
||||
|
||||
## `kompose up`
|
||||
|
||||
Kompose propose un moyen simple de déployer votre application "composée" sur Kubernetes ou OpenShift via `kompose up`.
|
||||
|
||||
|
||||
### Kubernetes
|
||||
```sh
|
||||
$ kompose --file ./examples/docker-guestbook.yml up
|
||||
We are going to create Kubernetes deployments and services for your Dockerized application.
|
||||
If you need different kind of resources, use the 'kompose convert' and 'kubectl apply -f' commands instead.
|
||||
|
||||
INFO Successfully created service: redis-master
|
||||
INFO Successfully created service: redis-slave
|
||||
INFO Successfully created service: frontend
|
||||
INFO Successfully created deployment: redis-master
|
||||
INFO Successfully created deployment: redis-slave
|
||||
INFO Successfully created deployment: frontend
|
||||
|
||||
Your application has been deployed to Kubernetes. You can run 'kubectl get deployment,svc,pods' for details.
|
||||
|
||||
$ kubectl get deployment,svc,pods
|
||||
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
|
||||
deployment.extensions/frontend 1 1 1 1 4m
|
||||
deployment.extensions/redis-master 1 1 1 1 4m
|
||||
deployment.extensions/redis-slave 1 1 1 1 4m
|
||||
|
||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
service/frontend ClusterIP 10.0.174.12 <none> 80/TCP 4m
|
||||
service/kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 13d
|
||||
service/redis-master ClusterIP 10.0.202.43 <none> 6379/TCP 4m
|
||||
service/redis-slave ClusterIP 10.0.1.85 <none> 6379/TCP 4m
|
||||
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
pod/frontend-2768218532-cs5t5 1/1 Running 0 4m
|
||||
pod/redis-master-1432129712-63jn8 1/1 Running 0 4m
|
||||
pod/redis-slave-2504961300-nve7b 1/1 Running 0 4m
|
||||
```
|
||||
|
||||
**Note**:
|
||||
|
||||
- Vous devez avoir un cluster Kubernetes en cours d'exécution avec kubectl pré-configuré.
|
||||
- Seuls les déploiements et les services sont générés et déployés dans Kubernetes. Si vous avez besoin d'autres types de ressources, utilisez les commandes `kompose convert` et `kubectl apply -f` à la place.
|
||||
|
||||
### OpenShift
|
||||
```sh
|
||||
$ kompose --file ./examples/docker-guestbook.yml --provider openshift up
|
||||
We are going to create OpenShift DeploymentConfigs and Services for your Dockerized application.
|
||||
If you need different kind of resources, use the 'kompose convert' and 'oc create -f' commands instead.
|
||||
|
||||
INFO Successfully created service: redis-slave
|
||||
INFO Successfully created service: frontend
|
||||
INFO Successfully created service: redis-master
|
||||
INFO Successfully created deployment: redis-slave
|
||||
INFO Successfully created ImageStream: redis-slave
|
||||
INFO Successfully created deployment: frontend
|
||||
INFO Successfully created ImageStream: frontend
|
||||
INFO Successfully created deployment: redis-master
|
||||
INFO Successfully created ImageStream: redis-master
|
||||
|
||||
Your application has been deployed to OpenShift. You can run 'oc get dc,svc,is' for details.
|
||||
|
||||
$ oc get dc,svc,is
|
||||
NAME REVISION DESIRED CURRENT TRIGGERED BY
|
||||
dc/frontend 0 1 0 config,image(frontend:v4)
|
||||
dc/redis-master 0 1 0 config,image(redis-master:e2e)
|
||||
dc/redis-slave 0 1 0 config,image(redis-slave:v1)
|
||||
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
svc/frontend 172.30.46.64 <none> 80/TCP 8s
|
||||
svc/redis-master 172.30.144.56 <none> 6379/TCP 8s
|
||||
svc/redis-slave 172.30.75.245 <none> 6379/TCP 8s
|
||||
NAME DOCKER REPO TAGS UPDATED
|
||||
is/frontend 172.30.12.200:5000/fff/frontend
|
||||
is/redis-master 172.30.12.200:5000/fff/redis-master
|
||||
is/redis-slave 172.30.12.200:5000/fff/redis-slave v1
|
||||
```
|
||||
|
||||
**Note**:
|
||||
|
||||
- Vous devez avoir un cluster OpenShift en cours d'exécution avec `oc` pré-configuré (`oc login`)
|
||||
|
||||
## `kompose down`
|
||||
|
||||
Une fois que vous avez déployé l'application "composée" sur Kubernetes, `$ kompose down` vous
|
||||
facilitera la suppression de l'application en supprimant ses déploiements et services. Si vous avez besoin de supprimer d'autres ressources, utilisez la commande 'kubectl'.
|
||||
|
||||
```sh
|
||||
$ kompose --file docker-guestbook.yml down
|
||||
INFO Successfully deleted service: redis-master
|
||||
INFO Successfully deleted deployment: redis-master
|
||||
INFO Successfully deleted service: redis-slave
|
||||
INFO Successfully deleted deployment: redis-slave
|
||||
INFO Successfully deleted service: frontend
|
||||
INFO Successfully deleted deployment: frontend
|
||||
```
|
||||
|
||||
**Note**:
|
||||
|
||||
- Vous devez avoir un cluster Kubernetes en cours d'exécution avec kubectl pré-configuré.
|
||||
|
||||
## Construire et pousser des images de docker
|
||||
|
||||
Kompose permet de construire et de pousser des images Docker. Lorsque vous utilisez la clé `build` dans votre fichier Docker Compose, votre image sera :
|
||||
|
||||
- Automatiquement construite avec le Docker en utilisant la clé "image" spécifiée dans votre fichier
|
||||
- Être poussé vers le bon dépôt Docker en utilisant les identifiants locaux (situés dans `.docker/config`)
|
||||
|
||||
Utilisation d'un [exemple de fichier Docker Compose](https://raw.githubusercontent.com/kubernetes/kompose/master/examples/buildconfig/docker-compose.yml):
|
||||
|
||||
```yaml
|
||||
version: "2"
|
||||
|
||||
services:
|
||||
foo:
|
||||
build: "./build"
|
||||
image: docker.io/foo/bar
|
||||
```
|
||||
|
||||
En utilisant `kompose up` avec une clé `build` :
|
||||
|
||||
```none
|
||||
$ kompose up
|
||||
INFO Build key detected. Attempting to build and push image 'docker.io/foo/bar'
|
||||
INFO Building image 'docker.io/foo/bar' from directory 'build'
|
||||
INFO Image 'docker.io/foo/bar' from directory 'build' built successfully
|
||||
INFO Pushing image 'foo/bar:latest' to registry 'docker.io'
|
||||
INFO Attempting authentication credentials 'https://index.docker.io/v1/
|
||||
INFO Successfully pushed image 'foo/bar:latest' to registry 'docker.io'
|
||||
INFO We are going to create Kubernetes Deployments, Services and PersistentVolumeClaims for your Dockerized application. If you need different kind of resources, use the 'kompose convert' and 'kubectl apply -f' commands instead.
|
||||
|
||||
INFO Deploying application in "default" namespace
|
||||
INFO Successfully created Service: foo
|
||||
INFO Successfully created Deployment: foo
|
||||
|
||||
Your application has been deployed to Kubernetes. You can run 'kubectl get deployment,svc,pods,pvc' for details.
|
||||
```
|
||||
|
||||
Afin de désactiver cette fonctionnalité, ou de choisir d'utiliser la génération de BuildConfig (avec OpenShift) `--build (local|build-config|none)` peut être passé.
|
||||
|
||||
```sh
|
||||
# Désactiver la construction/poussée d'images Docker
|
||||
$ kompose up --build none
|
||||
|
||||
# Générer des artefacts de Build Config pour OpenShift
|
||||
$ kompose up --provider openshift --build build-config
|
||||
```
|
||||
|
||||
## Autres conversions
|
||||
|
||||
La transformation par défaut `komposer` va générer des [Déploiements](/docs/concepts/workloads/controllers/deployment/) et [Services](/docs/concepts/services-networking/service/) de Kubernetes, au format yaml. Vous avez une autre option pour générer json avec `-j`. Vous pouvez aussi générer des objets de [Replication Controllers](/docs/concepts/workloads/controllers/replicationcontroller/), [Daemon Sets](/docs/concepts/workloads/controllers/daemonset/), ou [Helm](https://github.com/helm/helm) charts.
|
||||
|
||||
@@ -21,7 +21,6 @@ content_type: concept
|
||||
* [Canal](https://github.com/tigera/canal/tree/master/k8s-install)はFlannelとCalicoをあわせたもので、ネットワークとネットワークポリシーを提供します。
|
||||
* [Cilium](https://github.com/cilium/cilium)は、L3のネットワークとネットワークポリシーのプラグインで、HTTP/API/L7のポリシーを透過的に強制できます。ルーティングとoverlay/encapsulationモードの両方をサポートしており、他のCNIプラグイン上で機能できます。
|
||||
* [CNI-Genie](https://github.com/Huawei-PaaS/CNI-Genie)は、KubernetesをCalico、Canal、Flannel、Romana、Weaveなど選択したCNIプラグインをシームレスに接続できるようにするプラグインです。
|
||||
* [Contiv](https://contiv.github.io)は、さまざまなユースケースと豊富なポリシーフレームワーク向けに設定可能なネットワーク(BGPを使用したネイティブのL3、vxlanを使用したオーバーレイ、古典的なL2、Cisco-SDN/ACI)を提供します。Contivプロジェクトは完全に[オープンソース](https://github.com/contiv)です。[インストーラ](https://github.com/contiv/install)はkubeadmとkubeadm以外の両方をベースとしたインストールオプションがあります。
|
||||
* [Contrail](https://www.juniper.net/us/en/products-services/sdn/contrail/contrail-networking/)は、[Tungsten Fabric](https://tungsten.io)をベースにしている、オープンソースでマルチクラウドに対応したネットワーク仮想化およびポリシー管理プラットフォームです。ContrailおよびTungsten Fabricは、Kubernetes、OpenShift、OpenStack、Mesosなどのオーケストレーションシステムと統合されており、仮想マシン、コンテナ/Pod、ベアメタルのワークロードに隔離モードを提供します。
|
||||
* [Flannel](https://github.com/flannel-io/flannel#deploying-flannel-manually)は、Kubernetesで使用できるオーバーレイネットワークプロバイダーです。
|
||||
* [Knitter](https://github.com/ZTE/Knitter/)は、1つのKubernetes Podで複数のネットワークインターフェイスをサポートするためのプラグインです。
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
---
|
||||
title: Podのオーバーヘッド
|
||||
content_type: concept
|
||||
weight: 30
|
||||
---
|
||||
|
||||
<!-- overview -->
|
||||
|
||||
{{< feature-state for_k8s_version="v1.18" state="beta" >}}
|
||||
|
||||
|
||||
PodをNode上で実行する時に、Pod自身は大量のシステムリソースを消費します。これらのリソースは、Pod内のコンテナ(群)を実行するために必要なリソースとして追加されます。Podのオーバーヘッドは、コンテナの要求と制限に加えて、Podのインフラストラクチャで消費されるリソースを計算するための機能です。
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- body -->
|
||||
|
||||
Kubernetesでは、Podの[RuntimeClass](/docs/concepts/containers/runtime-class/)に関連するオーバーヘッドに応じて、[アドミッション](/ja/docs/reference/access-authn-authz/extensible-admission-controllers/#what-are-admission-webhooks)時にPodのオーバーヘッドが設定されます。
|
||||
|
||||
Podのオーバーヘッドを有効にした場合、Podのスケジューリング時にコンテナのリソース要求の合計に加えて、オーバーヘッドも考慮されます。同様に、Kubeletは、Podのcgroupのサイズ決定時およびPodの退役の順位付け時に、Podのオーバーヘッドを含めます。
|
||||
|
||||
## Podのオーバーヘッドの有効化 {#set-up}
|
||||
|
||||
クラスター全体で`PodOverhead`の[フィーチャーゲート](/ja/docs/reference/command-line-tools-reference/feature-gates/)が有効になっていること(1.18時点ではデフォルトでオンになっています)と、`overhead`フィールドを定義する`RuntimeClass`が利用されていることを確認する必要があります。
|
||||
|
||||
## 使用例
|
||||
|
||||
Podのオーバーヘッド機能を使用するためには、`overhead`フィールドが定義されたRuntimeClassが必要です。例として、仮想マシンとゲストOSにPodあたり約120MiBを使用する仮想化コンテナランタイムで、次のようなRuntimeClassを定義できます。
|
||||
|
||||
```yaml
|
||||
---
|
||||
kind: RuntimeClass
|
||||
apiVersion: node.k8s.io/v1
|
||||
metadata:
|
||||
name: kata-fc
|
||||
handler: kata-fc
|
||||
overhead:
|
||||
podFixed:
|
||||
memory: "120Mi"
|
||||
cpu: "250m"
|
||||
```
|
||||
|
||||
`kata-fc`RuntimeClassハンドラーを指定して作成されたワークロードは、リソースクォータの計算や、Nodeのスケジューリング、およびPodのcgroupのサイズ決定にメモリーとCPUのオーバーヘッドが考慮されます。
|
||||
|
||||
次のtest-podのワークロードの例を実行するとします。
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: test-pod
|
||||
spec:
|
||||
runtimeClassName: kata-fc
|
||||
containers:
|
||||
- name: busybox-ctr
|
||||
image: busybox
|
||||
stdin: true
|
||||
tty: true
|
||||
resources:
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 100Mi
|
||||
- name: nginx-ctr
|
||||
image: nginx
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1500m
|
||||
memory: 100Mi
|
||||
```
|
||||
|
||||
アドミッション時、RuntimeClass[アドミッションコントローラー](/docs/reference/access-authn-authz/admission-controllers/)は、RuntimeClass内に記述された`オーバーヘッド`を含むようにワークロードのPodSpecを更新します。もし既にPodSpec内にこのフィールドが定義済みの場合、そのPodは拒否されます。この例では、RuntimeClassの名前しか指定されていないため、アドミッションコントローラーは`オーバーヘッド`を含むようにPodを変更します。
|
||||
|
||||
RuntimeClassのアドミッションコントローラーの後、更新されたPodSpecを確認できます。
|
||||
|
||||
```bash
|
||||
kubectl get pod test-pod -o jsonpath='{.spec.overhead}'
|
||||
```
|
||||
|
||||
出力は次の通りです:
|
||||
```
|
||||
map[cpu:250m memory:120Mi]
|
||||
```
|
||||
ResourceQuotaが定義されている場合、コンテナ要求の合計と`オーバーヘッド`フィールドがカウントされます。
|
||||
|
||||
kube-schedulerが新しいPodを実行すべきNodeを決定する際、スケジューラーはそのPodの`オーバーヘッド`と、そのPodに対するコンテナ要求の合計を考慮します。この例だと、スケジューラーは、要求とオーバーヘッドを追加し、2.25CPUと320MiBのメモリを持つNodeを探します。
|
||||
|
||||
PodがNodeにスケジュールされると、そのNodeのkubeletはPodのために新しい{{< glossary_tooltip text="cgroup" term_id="cgroup" >}}を生成します。基盤となるコンテナランタイムがコンテナを作成するのは、このPod内です。
|
||||
|
||||
リソースにコンテナごとの制限が定義されている場合(制限が定義されているGuaranteed QoSまたはBustrable QoS)、kubeletはそのリソース(CPUはcpu.cfs_quota_us、メモリはmemory.limit_in_bytes)に関連するPodのcgroupの上限を設定します。この上限は、コンテナの制限とPodSpecで定義された`オーバーヘッド`の合計に基づきます。
|
||||
|
||||
CPUについては、PodがGuaranteedまたはBurstable QoSの場合、kubeletはコンテナの要求の合計とPodSpecに定義された`オーバーヘッド`に基づいて`cpu.share`を設定します。
|
||||
|
||||
次の例より、ワークロードに対するコンテナの要求を確認できます。
|
||||
```bash
|
||||
kubectl get pod test-pod -o jsonpath='{.spec.containers[*].resources.limits}'
|
||||
```
|
||||
|
||||
コンテナの要求の合計は、CPUは2000m、メモリーは200MiBです。
|
||||
```
|
||||
map[cpu: 500m memory:100Mi] map[cpu:1500m memory:100Mi]
|
||||
```
|
||||
|
||||
Nodeで観測される値と比較してみましょう。
|
||||
```bash
|
||||
kubectl describe node | grep test-pod -B2
|
||||
```
|
||||
|
||||
出力では、2250mのCPUと320MiBのメモリーが要求されており、Podのオーバーヘッドが含まれていることが分かります。
|
||||
```
|
||||
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits AGE
|
||||
--------- ---- ------------ ---------- --------------- ------------- ---
|
||||
default test-pod 2250m (56%) 2250m (56%) 320Mi (1%) 320Mi (1%) 36m
|
||||
```
|
||||
|
||||
## Podのcgroupの制限を確認
|
||||
|
||||
ワークロードで実行中のNode上にある、Podのメモリーのcgroupを確認します。次に示す例では、CRI互換のコンテナランタイムのCLIを提供するNodeで[`crictl`](https://github.com/kubernetes-sigs/cri-tools/blob/master/docs/crictl.md)を使用しています。これはPodのオーバーヘッドの動作を示すための高度な例であり、ユーザーがNode上で直接cgroupsを確認する必要はありません。
|
||||
|
||||
まず、特定のNodeで、Podの識別子を決定します。
|
||||
|
||||
```bash
|
||||
# PodがスケジュールされているNodeで実行
|
||||
POD_ID="$(sudo crictl pods --name test-pod -q)"
|
||||
```
|
||||
|
||||
ここから、Podのcgroupのパスが決定します。
|
||||
```bash
|
||||
# PodがスケジュールされているNodeで実行
|
||||
sudo crictl inspectp -o=json $POD_ID | grep cgroupsPath
|
||||
```
|
||||
|
||||
結果のcgroupパスにはPodの`ポーズ中`コンテナも含まれます。Podレベルのcgroupは1つ上のディレクトリです。
|
||||
```
|
||||
"cgroupsPath": "/kubepods/podd7f4b509-cf94-4951-9417-d1087c92a5b2/7ccf55aee35dd16aca4189c952d83487297f3cd760f1bbf09620e206e7d0c27a"
|
||||
```
|
||||
|
||||
今回のケースでは、Podのcgroupパスは、`kubepods/podd7f4b509-cf94-4951-9417-d1087c92a5b2`となります。メモリーのPodレベルのcgroupの設定を確認しましょう。
|
||||
```bash
|
||||
# PodがスケジュールされているNodeで実行
|
||||
# また、Podに割り当てられたcgroupと同じ名前に変更
|
||||
cat /sys/fs/cgroup/memory/kubepods/podd7f4b509-cf94-4951-9417-d1087c92a5b2/memory.limit_in_bytes
|
||||
```
|
||||
|
||||
予想通り320MiBです。
|
||||
```
|
||||
335544320
|
||||
```
|
||||
|
||||
### Observability
|
||||
|
||||
Podのオーバヘッドが利用されているタイミングを特定し、定義されたオーバーヘッドで実行されているワークロードの安定性を観察するため、[kube-state-metrics](https://github.com/kubernetes/kube-state-metrics)には`kube_pod_overhead`というメトリクスが用意されています。この機能はv1.9のkube-state-metricsでは利用できませんが、次のリリースで期待されています。それまでは、kube-state-metricsをソースからビルドする必要があります。
|
||||
|
||||
|
||||
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
|
||||
* [RuntimeClass](/ja/docs/concepts/containers/runtime-class/)
|
||||
* [Podのオーバーヘッドの設計](https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/688-pod-overhead)
|
||||
@@ -0,0 +1,174 @@
|
||||
---
|
||||
title: スケジューリングフレームワーク
|
||||
content_type: concept
|
||||
weight: 90
|
||||
---
|
||||
|
||||
<!-- overview -->
|
||||
|
||||
{{< feature-state for_k8s_version="v1.19" state="stable" >}}
|
||||
|
||||
スケジューリングフレームワークはKubernetesのスケジューラーに対してプラグイン可能なアーキテクチャです。
|
||||
このアーキテクチャは、既存のスケジューラーに新たに「プラグイン」としてAPI群を追加するもので、プラグインはスケジューラー内部にコンパイルされます。このAPI群により、スケジューリングの「コア」の軽量かつ保守しやすい状態に保ちながら、ほとんどのスケジューリングの機能をプラグインとして実装することができます。このフレームワークの設計に関する技術的な情報についてはこちらの[スケジューリングフレームワークの設計提案][kep]をご覧ください。
|
||||
|
||||
[kep]: https://github.com/kubernetes/enhancements/blob/master/keps/sig-scheduling/624-scheduling-framework/README.md
|
||||
|
||||
|
||||
<!-- body -->
|
||||
|
||||
# フレームワークのワークフロー
|
||||
|
||||
スケジューリングフレームワークは、いくつかの拡張点を定義しています。スケジューラープラグインは、1つ以上の拡張点で呼び出されるように登録します。これらのプラグインの中には、スケジューリングの決定を変更できるものから、単に情報提供のみを行うだけのものなどがあります。
|
||||
|
||||
この1つのPodをスケジュールしようとする各動作は**Scheduling Cycle**と**Binding Cycle**の2つのフェーズに分けられます。
|
||||
|
||||
## Scheduling Cycle & Binding Cycle
|
||||
|
||||
Scheduling CycleではPodが稼働するNodeを決定し、Binding Cycleではそれをクラスターに適用します。この2つのサイクルを合わせて「スケジューリングコンテキスト」と呼びます。
|
||||
|
||||
Scheduling CycleではPodに対して1つ1つが順番に実行され、Binding Cyclesでは並列に実行されます。
|
||||
|
||||
Podがスケジューリング不能と判断された場合や、内部エラーが発生した場合、Scheduling CycleまたはBinding Cycleを中断することができます。その際、Podはキューに戻され再試行されます。
|
||||
|
||||
## 拡張点
|
||||
|
||||
次の図はPodに対するスケジューリングコンテキストとスケジューリングフレームワークが公開する拡張点を示しています。この図では「Filter」がフィルタリングのための「Predicate」、「Scoring」がスコアリングのための「Priorities」機能に相当します。
|
||||
|
||||
1つのプラグインを複数の拡張点に登録することで、より複雑なタスクやステートフルなタスクを実行することができます。
|
||||
|
||||
{{< figure src="/images/docs/scheduling-framework-extensions.png" title="scheduling framework extension points" class="diagram-large">}}
|
||||
|
||||
### QueueSort {#queue-sort}
|
||||
|
||||
これらのプラグインはスケジューリングキュー内のPodをソートするために使用されます。このプラグインは、基本的に`Less(Pod1, Pod2)`という関数を提供します。また、このプラグインは、1つだけ有効化できます。
|
||||
|
||||
### PreFilter {#pre-filter}
|
||||
|
||||
これらのプラグインは、Podに関する情報を前処理したり、クラスターやPodが満たすべき特定の条件をチェックするために使用されます。もし、PreFilterプラグインのいずれかがエラーを返した場合、Scheduling Cycleは中断されます。
|
||||
|
||||
### Filter
|
||||
|
||||
FilterプラグインはPodを実行できないNodeを候補から除外します。各Nodeに対して、スケジューラーは設定された順番でFilterプラグインを呼び出します。もし、いずれかのFilterプラグインが途中でそのNodeを実行不可能とした場合、残りのプラグインではそのNodeは呼び出されません。Nodeは同時に評価されることがあります。
|
||||
|
||||
### PostFilter {#post-filter}
|
||||
|
||||
これらのプラグインはFilterフェーズで、Podに対して実行可能なNodeが見つからなかった場合にのみ呼び出されます。このプラグインは設定された順番で呼び出されます。もしいずれかのPostFilterプラグインが、あるNodeを「スケジュール可能(Schedulable)」と目星をつけた場合、残りのプラグインは呼び出されません。典型的なPostFilterの実装はプリエンプション方式で、他のPodを先取りして、Podをスケジューリングできるようにしようとします。
|
||||
|
||||
### PreScore {#pre-score}
|
||||
|
||||
これらのプラグインは、Scoreプラグインが使用する共有可能な状態を生成する「スコアリングの事前」作業を行うために使用されます。このプラグインがエラーを返した場合、Scheduling Cycleは中断されます。
|
||||
|
||||
### Score {#scoring}
|
||||
|
||||
これらのプラグインはフィルタリングのフェーズを通過したNodeをランク付けするために使用されます。スケジューラーはそれぞれのNodeに対して、それぞれのscoringプラグインを呼び出します。スコアの最小値と最大値の範囲が明確に定義されます。[NormalizeScore](#normalize-scoring)フェーズの後、スケジューラーは設定されたプラグインの重みに従って、全てのプラグインからNodeのスコアを足し合わせます。
|
||||
|
||||
### NormalizeScore {#normalize-scoring}
|
||||
|
||||
これらのプラグインはスケジューラーが最終的なNodeの順位を計算する前にスコアを修正するために使用されます。この拡張点に登録されたプラグインは、同じプラグインの[Score](#scoring)の結果を使用して呼び出されます。各プラグインはScheduling Cycle毎に、1回呼び出されます。
|
||||
|
||||
|
||||
例えば、`BlinkingLightScorer`というプラグインが、点滅する光の数に基づいてランク付けをするとします。
|
||||
|
||||
```go
|
||||
func ScoreNode(_ *v1.pod, n *v1.Node) (int, error) {
|
||||
return getBlinkingLightCount(n)
|
||||
}
|
||||
```
|
||||
|
||||
ただし、`NodeScoreMax`に比べ、点滅をカウントした最大値の方が小さい場合があります。これを解決するために、`BlinkingLightScorer`も拡張点に登録する必要があります。
|
||||
|
||||
```go
|
||||
func NormalizeScores(scores map[string]int) {
|
||||
highest := 0
|
||||
for _, score := range scores {
|
||||
highest = max(highest, score)
|
||||
}
|
||||
for node, score := range scores {
|
||||
scores[node] = score*NodeScoreMax/highest
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
NormalizeScoreプラグインが途中でエラーを返した場合、Scheduling Cycleは中断されます。
|
||||
|
||||
{{< note >}}
|
||||
「Reserveの事前」作業を行いたいプラグインは、NormalizeScore拡張点を使用してください。
|
||||
{{< /note >}}
|
||||
|
||||
### Reserve {#reserve}
|
||||
|
||||
Reserve拡張を実装したプラグインには、ReserveとUnreserve という2つのメソッドがあり、それぞれ`Reserve`
|
||||
と`Unreserve`と呼ばれる2つの情報スケジューリングフェーズを返します。
|
||||
実行状態を保持するプラグイン(別名「ステートフルプラグイン」)は、これらのフェーズを使用して、Podに対してNodeのリソースが予約されたり予約解除された場合に、スケジューラーから通知を受け取ります。
|
||||
|
||||
Reserveフェーズは、スケジューラーが実際にPodを指定されたNodeにバインドする前に発生します。このフェーズはスケジューラーがバインドが成功するのを待つ間にレースコンディションの発生を防ぐためにあります。
|
||||
各Reserveプラグインの`Reserve`メソッドは成功することも失敗することもあります。もしどこかの`Reserve`メソッドの呼び出しが失敗すると、後続のプラグインは実行されず、Reserveフェーズは失敗したものとみなされます。全てのプラグインの`Reserve`メソッドが成功した場合、Reserveフェーズは成功とみなされ、残りのScheduling CycleとBinding Cycleが実行されます。
|
||||
|
||||
Unreserveフェーズは、Reserveフェーズまたは後続のフェーズが失敗した場合に、呼び出されます。この時、**全ての**Reserveプラグインの`Unreserve`メソッドが、`Reserve`メソッドの呼び出された逆の順序で実行されます。このフェーズは予約されたPodに関連する状態をクリーンアップするためにあります。
|
||||
|
||||
{{< caution >}}
|
||||
`Unreserve`メソッドの実装は冪等性を持つべきであり、この処理で問題があった場合に失敗させてはなりません。
|
||||
{{< /caution >}}
|
||||
|
||||
<!-- ### Permit -->
|
||||
### Permit
|
||||
|
||||
_Permit_ プラグインは、各PodのScheduling Cycleの終了時に呼び出され、候補Nodeへのバインドを阻止もしくは遅延させるために使用されます。permitプラグインは次の3つのうちどれかを実行できます。
|
||||
|
||||
1. **承認(approve)** \
|
||||
全てのPermitプラグインから承認(approve)されたPodは、バインド処理へ送られます。
|
||||
|
||||
1. **拒否(deny)** \
|
||||
もしどれか1つのPermitプラグインがPodを拒否(deny)した場合、そのPodはスケジューリングキューに戻されます。
|
||||
これは[Reserveプラグイン](#reserve)内のUnreserveフェーズで呼び出されます。
|
||||
|
||||
1. **待機(wait)** (タイムアウトあり) \
|
||||
もしPermitプラグインが「待機(wait)」を返した場合、そのPodは内部の「待機中」Podリストに保持され、このPodに対するBinding Cycleは開始されるものの、承認(approve)されるまで直接ブロックされます。もしタイムアウトが発生した場合、この**待機(wait)**は**deny**へ変わり、対象のPodはスケジューリングキューに戻されると共に、[Reserveプラグイン](#reserve)のUnreserveフェーズが呼び出されます。
|
||||
|
||||
{{< note >}}
|
||||
どのプラグインも「待機中」Podリストにアクセスして、それらを承認(approve)することができますが(参考:[`FrameworkHandle`](https://git.k8s.io/enhancements/keps/sig-scheduling/624-scheduling-framework#frameworkhandle))、その中の予約済みPodのバインドを承認(approve)できるのはPermitプラグインだけであると予想します。承認(approve)されたPodは、[PreBind](#pre-bind)フェーズへ送られます。
|
||||
{{< /note >}}
|
||||
|
||||
### PreBind {#pre-bind}
|
||||
|
||||
これらのプラグインは、Podがバインドされる前に必要な作業を行うために使用されます。例えば、Podの実行を許可する前に、ネットワークボリュームをプロビジョニングし、Podを実行予定のNodeにマウントすることができます。
|
||||
|
||||
もし、いずれかのPreBindプラグインがエラーを返した場合、Podは[拒否](#reserve)され、スケジューリングキューに戻されます。
|
||||
|
||||
### Bind
|
||||
|
||||
これらのプラグインはPodをNodeにバインドするために使用されます。このプラグインは全てのPreBindプラグインの処理が完了するまで呼ばれません。それぞれのBindプラグインは設定された順序で呼び出されます。このプラグインは、与えられたPodを処理するかどうかを選択することができます。もしPodを処理することを選択した場合、**残りのBindプラグインは全てスキップされます。**
|
||||
|
||||
### PostBind {#post-bind}
|
||||
|
||||
これは単に情報提供のための拡張点です。Post-bindプラグインはPodのバインドが成功した後に呼び出されます。これはBinding Cycleの最後であり、関連するリソースのクリーンアップに使用されます。
|
||||
|
||||
## プラグインAPI
|
||||
|
||||
プラグインAPIには2つの段階があります。まず、プラグインを登録し設定することです。そして、拡張点インターフェースを使用することです。このインターフェースは次のような形式をとります。
|
||||
|
||||
```go
|
||||
type Plugin interface {
|
||||
Name() string
|
||||
}
|
||||
|
||||
type QueueSortPlugin interface {
|
||||
Plugin
|
||||
Less(*v1.pod, *v1.pod) bool
|
||||
}
|
||||
|
||||
type PreFilterPlugin interface {
|
||||
Plugin
|
||||
PreFilter(context.Context, *framework.CycleState, *v1.pod) error
|
||||
}
|
||||
|
||||
// ...
|
||||
```
|
||||
|
||||
## プラグインの設定
|
||||
|
||||
スケジューラーの設定でプラグインを有効化・無効化することができます。Kubernetes v1.18以降を使用しているなら、ほとんどのスケジューリング[プラグイン](/docs/reference/scheduling/config/#scheduling-plugins)は使用されており、デフォルトで有効になっています。
|
||||
|
||||
デフォルトのプラグインに加えて、独自のスケジューリングプラグインを実装し、デフォルトのプラグインと一緒に使用することも可能です。詳しくは[スケジューラープラグイン](https://github.com/kubernetes-sigs/scheduler-plugins)をご覧下さい。
|
||||
|
||||
Kubernetes v1.18以降を使用しているなら、プラグインのセットをスケジューラープロファイルとして設定し、様々な種類のワークロードに適合するように複数のプロファイルを定義することが可能です。詳しくは[複数のプロファイル](/docs/reference/scheduling/config/#multiple-profiles)をご覧下さい。
|
||||
@@ -59,7 +59,7 @@ cards:
|
||||
title: "K8sリリースノート"
|
||||
description: "もしKubernetesをインストールする、また最新バージョンにアップグレードする場合、最新のリリースノートを参照してください。"
|
||||
button: "Kubernetesをダウンロードする"
|
||||
button_path: "/docs/setup/release/notes"
|
||||
button_path: "/releases/download"
|
||||
- name: about
|
||||
title: ドキュメントについて
|
||||
description: このWebサイトには、Kubernetesの最新バージョンと過去4世代のドキュメントが含まれています。
|
||||
|
||||
@@ -63,8 +63,8 @@ CAの秘密鍵をクラスターにコピーしたくない場合、自身で全
|
||||
必要な証明書:
|
||||
|
||||
| デフォルトCN | 親認証局 | 組織 | 種類 | ホスト名 (SAN) |
|
||||
|-------------------------------|---------------------------|----------------|----------------------------------------|---------------------------------------------|
|
||||
| kube-etcd | etcd-ca | | server, client | `localhost`, `127.0.0.1` |
|
||||
|-------------------------------|---------------------------|----------------|----------------------------------------|-----------------------------------------------------|
|
||||
| kube-etcd | etcd-ca | | server, client | `<hostname>`, `<Host_IP>`, `localhost`, `127.0.0.1` |
|
||||
| kube-etcd-peer | etcd-ca | | server, client | `<hostname>`, `<Host_IP>`, `localhost`, `127.0.0.1` |
|
||||
| kube-etcd-healthcheck-client | etcd-ca | | client | |
|
||||
| kube-apiserver-etcd-client | etcd-ca | system:masters | client | |
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
---
|
||||
title: クラスターのセキュリティ
|
||||
content_type: task
|
||||
---
|
||||
|
||||
<!-- overview -->
|
||||
|
||||
このドキュメントでは、偶発的または悪意のあるアクセスからクラスターを保護するためのトピックについて説明します。
|
||||
また、全体的なセキュリティに関する推奨事項を提供します。
|
||||
|
||||
|
||||
## {{% heading "prerequisites" %}}
|
||||
|
||||
|
||||
* {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
|
||||
|
||||
|
||||
|
||||
<!-- steps -->
|
||||
|
||||
## Kubernetes APIへのアクセスの制御
|
||||
|
||||
Kubernetesは完全にAPI駆動であるため、誰がクラスターにアクセスできるか、どのようなアクションを実行できるかを制御・制限することが第一の防御策となります。
|
||||
|
||||
### すべてのAPIトラフィックにTLS(Transport Layer Security)を使用する
|
||||
|
||||
Kubernetesは、クラスター内のすべてのAPI通信がデフォルトでTLSにより暗号化されていることを期待しており、大半のインストール方法では、必要な証明書を作成してクラスターコンポーネントに配布することができます。
|
||||
|
||||
コンポーネントやインストール方法によっては、HTTP上のローカルポートを有効にする場合があることに注意してください。管理者は、潜在的に保護されていないトラフィックを特定するために、各コンポーネントの設定に精通している必要があります。
|
||||
|
||||
### APIの認証
|
||||
|
||||
クラスターのインストール時に、共通のアクセスパターンに合わせて、APIサーバーが使用する認証メカニズムを選択します。
|
||||
例えば、シングルユーザーの小規模なクラスターでは、シンプルな証明書や静的なBearerトークンを使用することができます。
|
||||
大規模なクラスターでは、ユーザーをグループに細分化できる既存のOIDCまたはLDAPサーバーを統合することができます。
|
||||
|
||||
ノード、プロキシー、スケジューラー、ボリュームプラグインなど、インフラの一部であるものも含めて、すべてのAPIクライアントを認証する必要があります。
|
||||
これらのクライアントは通常、[service accounts](/docs/reference/access-authn-authz/service-accounts-admin/)であるか、またはx509クライアント証明書を使用しており、クラスター起動時に自動的に作成されるか、クラスターインストールの一部として設定されます。
|
||||
|
||||
詳細については、[認証](/ja/docs/reference/access-authn-authz/authentication/)を参照してください。
|
||||
|
||||
### APIの認可
|
||||
|
||||
認証されると、すべてのAPIコールは認可チェックを通過することになります。
|
||||
|
||||
Kubernetesには、統合された[RBAC](/ja/docs/reference/access-authn-authz/rbac/)コンポーネントが搭載されており、入力されたユーザーやグループを、ロールにまとめられたパーミッションのセットにマッチさせます。
|
||||
これらのパーミッションは、動詞(get, create, delete)とリソース(pods, services, nodes)を組み合わせたもので、ネームスペース・スコープまたはクラスター・スコープに対応しています。
|
||||
すぐに使えるロールのセットが提供されており、クライアントが実行したいアクションに応じて、デフォルトで適切な責任の分離を提供します。
|
||||
|
||||
[Node](/docs/reference/access-authn-authz/node/)と[RBAC](/ja/docs/reference/access-authn-authz/rbac/)の承認者は、[NodeRestriction](/docs/reference/access-authn-authz/admission-controllers/#noderestriction)のアドミッションプラグインと組み合わせて使用することをお勧めします。
|
||||
|
||||
認証の場合と同様に、小規模なクラスターにはシンプルで幅広い役割が適切かもしれません。
|
||||
しかし、より多くのユーザーがクラスターに関わるようになるとチームを別の名前空間に分け、より限定的な役割を持たせることが必要になるかもしれません。
|
||||
認可においては、あるオブジェクトの更新が、他の場所でどのようなアクションを起こすかを理解することが重要です。
|
||||
|
||||
たとえば、ユーザーは直接Podを作成することはできませんが、ユーザーに代わってPodを作成するDeploymentの作成を許可することで、間接的にそれらのPodを作成することができます。
|
||||
同様に、APIからノードを削除すると、そのノードにスケジューリングされていたPodが終了し、他のノードに再作成されます。
|
||||
すぐに使えるロールは、柔軟性と一般的なユースケースのバランスを表していますが、より限定的なロールは、偶発的なエスカレーションを防ぐために慎重に検討する必要があります。
|
||||
すぐに使えるロールがニーズを満たさない場合は、ユースケースに合わせてロールを作成することができます。
|
||||
|
||||
詳しくは[authorization reference section](/docs/reference/access-authn-authz/authorization/)に参照してください。
|
||||
|
||||
## Kubeletへのアクセスの制御
|
||||
|
||||
Kubeletsは、ノードやコンテナの強力な制御を可能にするHTTPSエンドポイントを公開しています。
|
||||
デフォルトでは、KubeletsはこのAPIへの認証されていないアクセスを許可しています。
|
||||
|
||||
本番環境のクラスターでは、Kubeletの認証と認可を有効にする必要があります。
|
||||
|
||||
詳細は、[Kubelet 認証/認可](/ja/docs/reference/command-line-tools-reference/kubelet-authentication-authorization)に参照してください。
|
||||
|
||||
## ワークロードやユーザーのキャパシティーを実行時に制御
|
||||
|
||||
Kubernetesにおける権限付与は、意図的にハイレベルであり、リソースに対する粗いアクションに焦点を当てています。
|
||||
|
||||
より強力なコントロールは**policies**として存在し、それらのオブジェクトがクラスタや自身、その他のリソースにどのように作用するかをユースケースによって制限します。
|
||||
|
||||
### クラスターのリソース使用量の制限
|
||||
|
||||
[リソースクォータ](/ja/docs/concepts/policy/resource-quotas/)は、ネームスペースに付与されるリソースの数や容量を制限するものです。
|
||||
|
||||
これは、ネームスペースが割り当てることのできるCPU、メモリー、永続的なディスクの量を制限するためによく使われますが、各ネームスペースに存在するPod、サービス、ボリュームの数を制御することもできます。
|
||||
|
||||
[Limit ranges](/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/)は、上記のリソースの一部の最大または最小サイズを制限することで、ユーザーがメモリーなどの一般的に予約されたリソースに対して不当に高いまたは低い値を要求するのを防いだり、何も指定されていない場合にデフォルトの制限を提供したりします。
|
||||
|
||||
### コンテナが利用する特権の制御
|
||||
|
||||
Podの定義には、[security context](/docs/tasks/configure-pod-container/security-context/)が含まれており、ノード上の特定の Linux ユーザー(rootなど)として実行するためのアクセス、特権的に実行するためのアクセス、ホストネットワークにアクセスするためのアクセス、その他の制御を要求することができます。
|
||||
[Pod security policies](/docs/concepts/policy/pod-security-policy/)は、危険なセキュリティコンテキスト設定を提供できるユーザーやサービスアカウントを制限することができます。
|
||||
|
||||
たとえば、Podのセキュリティポリシーでは、ボリュームマウント、特に`hostPath`を制限することができ、これはPodの制御すべき側面です。
|
||||
一般に、ほとんどのアプリケーションワークロードでは、ホストリソースへのアクセスを制限する必要があります。
|
||||
ホスト情報にアクセスすることなく、ルートプロセス(uid 0)として正常に実行できます。
|
||||
ただし、ルートユーザーに関連する権限を考慮して、非ルートユーザーとして実行するようにアプリケーションコンテナを記述する必要があります。
|
||||
|
||||
## コンテナが不要なカーネルモジュールをロードしないようにします
|
||||
|
||||
Linuxカーネルは、ハードウェアが接続されたときやファイルシステムがマウントされたときなど、特定の状況下で必要となるカーネルモジュールをディスクから自動的にロードします。
|
||||
特にKubernetesでは、非特権プロセスであっても、適切なタイプのソケットを作成するだけで、特定のネットワークプロトコル関連のカーネルモジュールをロードさせることができます。これにより、管理者が使用されていないと思い込んでいるカーネルモジュールのセキュリティホールを攻撃者が利用できる可能性があります。
|
||||
特定のモジュールが自動的にロードされないようにするには、そのモジュールをノードからアンインストールしたり、ルールを追加してブロックしたりします。
|
||||
|
||||
ほとんどのLinuxディストリビューションでは、`/etc/modprobe.d/kubernetes-blacklist.conf`のような内容のファイルを作成することで実現できます。
|
||||
|
||||
```
|
||||
# DCCPは必要性が低く、複数の深刻な脆弱性があり、保守も十分ではありません。
|
||||
blacklist dccp
|
||||
|
||||
# SCTPはほとんどのKubernetesクラスタでは使用されておらず、また過去には脆弱性がありました。
|
||||
blacklist sctp
|
||||
```
|
||||
|
||||
モジュールのロードをより一般的にブロックするには、SELinuxなどのLinuxセキュリティモジュールを使って、コンテナに対する `module_request`権限を完全に拒否し、いかなる状況下でもカーネルがコンテナ用のモジュールをロードできないようにすることができます。
|
||||
(Podは、手動でロードされたモジュールや、より高い権限を持つプロセスに代わってカーネルがロードしたモジュールを使用することはできます)。
|
||||
|
||||
|
||||
### ネットワークアクセスの制限
|
||||
|
||||
名前空間の[ネットワークポリシー](/ja/docs/tasks/administer-cluster/declare-network-policy/)により、アプリケーション作成者は、他の名前空間のPodが自分の名前空間内のPodやポートにアクセスすることを制限することができます。
|
||||
|
||||
サポートされている[Kubernetes networking providers](/ja/docs/concepts/cluster-administration/networking/)の多くは、ネットワークポリシーを尊重するようになりました。
|
||||
クォータやリミットの範囲は、ユーザーがノードポートや負荷分散サービスを要求するかどうかを制御するためにも使用でき、多くのクラスターでは、ユーザーのアプリケーションがクラスターの外で見えるかどうかを制御できます。
|
||||
ノードごとのファイアウォール、クロストークを防ぐための物理的なクラスタノードの分離、高度なネットワークポリシーなど、プラグインや環境ごとにネットワークルールを制御する追加の保護機能が利用できる場合もあります。
|
||||
|
||||
### クラウドメタデータのAPIアクセスを制限
|
||||
|
||||
クラウドプラットフォーム(AWS、Azure、GCEなど)では、しばしばメタデータサービスをインスタンスローカルに公開しています。
|
||||
デフォルトでは、これらのAPIはインスタンス上で実行されているPodからアクセスでき、そのノードのクラウド認証情報や、kubelet認証情報などのプロビジョニングデータを含むことができます。
|
||||
これらの認証情報は、クラスター内でのエスカレーションや、同じアカウントの他のクラウドサービスへのエスカレーションに使用できます。
|
||||
|
||||
クラウドプラットフォーム上でKubernetesを実行する場合は、インスタンスの認証情報に与えられるパーミッションを制限し、[ネットワークポリシー](/ja/docs/tasks/administer-cluster/declare-network-policy/)を使用してメタデータAPIへのPodのアクセスを制限し、プロビジョニングデータを使用してシークレットを配信することは避けてください。
|
||||
|
||||
### Podのアクセス可能ノードを制御
|
||||
|
||||
デフォルトでは、どのノードがPodを実行できるかについての制限はありません。
|
||||
Kubernetesは、エンドユーザーが利用できる[Node上へのPodのスケジューリング](/ja/docs/concepts/scheduling-eviction/assign-pod-node/)と[TaintとToleration](/ja/docs/concepts/scheduling-eviction/taint-and-toleration/)を提供します。
|
||||
多くのクラスターでは、ワークロードを分離するためにこれらのポリシーを使用することは、作者が採用したり、ツールを使って強制したりする慣習になっています。
|
||||
|
||||
管理者としては、ベータ版のアドミッションプラグイン「PodNodeSelector」を使用して、ネームスペース内のPodをデフォルトまたは特定のノードセレクタを必要とするように強制することができます。
|
||||
エンドユーザーがネームスペースを変更できない場合は、特定のワークロード内のすべてのPodの配置を強く制限することができます。
|
||||
|
||||
## クラスターのコンポーネントの保護
|
||||
|
||||
このセクションでは、クラスターを危険から守るための一般的なパターンを説明します。
|
||||
|
||||
### etcdへのアクセスの制限
|
||||
|
||||
API用のetcdバックエンドへの書き込みアクセスは、クラスタ全体のrootを取得するのと同等であり、読み取りアクセスはかなり迅速にエスカレートするために使用できます。
|
||||
管理者は、TLSクライアント証明書による相互認証など、APIサーバーからetcdサーバーへの強力な認証情報を常に使用すべきであり、API サーバーのみがアクセスできるファイアウォールの後ろにetcdサーバーを隔離することがしばしば推奨されます。
|
||||
|
||||
{{< caution >}}
|
||||
クラスター内の他のコンポーネントが、完全なキースペースへの読み取りまたは書き込みアクセスを持つマスターetcdインスタンスへのアクセスを許可することは、クラスター管理者のアクセスを許可することと同じです。
|
||||
マスター以外のコンポーネントに別のetcdインスタンスを使用するか、またはetcd ACLを使用してキースペースのサブセットへの読み取りおよび書き込みアクセスを制限することを強く推奨します。
|
||||
{{< /caution >}}
|
||||
|
||||
### 監査ログの有効
|
||||
|
||||
[audit logger](/docs/tasks/debug-application-cluster/audit/)はベータ版の機能で、APIによって行われたアクションを記録し、侵害があった場合に後から分析できるようにするものです。
|
||||
|
||||
監査ログを有効にして、ログファイルを安全なサーバーにアーカイブすることをお勧めします。
|
||||
|
||||
### アルファまたはベータ機能へのアクセスの制限
|
||||
|
||||
アルファ版およびベータ版のKubernetesの機能は活発に開発が行われており、セキュリティ上の脆弱性をもたらす制限やバグがある可能性があります。
|
||||
常に、アルファ版またはベータ版の機能が提供する価値と、セキュリティ体制に起こりうるリスクを比較して評価してください。
|
||||
疑問がある場合は、使用しない機能を無効にしてください。
|
||||
|
||||
### インフラの認証情報を頻繁に交換
|
||||
|
||||
秘密やクレデンシャルの有効期間が短いほど、攻撃者がそのクレデンシャルを利用することは難しくなります。
|
||||
証明書の有効期間を短く設定し、そのローテーションを自動化します。
|
||||
発行されたトークンの利用可能期間を制御できる認証プロバイダーを使用し、可能な限り短いライフタイムを使用します。
|
||||
外部統合でサービス・アカウント・トークンを使用する場合、これらのトークンを頻繁にローテーションすることを計画します。
|
||||
例えば、ブートストラップ・フェーズが完了したら、ノードのセットアップに使用したブートストラップ・トークンを失効させるか、その認証を解除する必要があります。
|
||||
|
||||
### サードパーティの統合を有効にする前に確認
|
||||
|
||||
Kubernetesへの多くのサードパーティの統合は、クラスターのセキュリティプロファイルを変更する可能性があります。
|
||||
統合を有効にする際には、アクセスを許可する前に、拡張機能が要求するパーミッションを常に確認してください。
|
||||
|
||||
例えば、多くのセキュリティ統合は、事実上そのコンポーネントをクラスター管理者にしているクラスター上のすべての秘密を見るためのアクセスを要求するかもしれません。
|
||||
疑問がある場合は、可能な限り単一の名前空間で機能するように統合を制限してください。
|
||||
Podを作成するコンポーネントも、`kube-system`名前空間のような名前空間内で行うことができれば、予想外に強力になる可能性があります。これは、サービスアカウントのシークレットにアクセスしたり、サービスアカウントに寛容な[pod security policies](/docs/concepts/policy/pod-security-policy/)へのアクセスが許可されている場合に、昇格したパーミッションでPodが実行される可能性があるからです。
|
||||
|
||||
### etcdにあるSecretを暗号化
|
||||
|
||||
一般的に、etcdデータベースにはKubernetes APIを介してアクセス可能なあらゆる情報が含まれており、クラスターの状態に対する大きな可視性を攻撃者へ与える可能性があります。
|
||||
よく吟味されたバックアップおよび暗号化ソリューションを使用して、常にバックアップを暗号化し、可能な場合はフルディスク暗号化の使用を検討してください。
|
||||
|
||||
Kubernetesは1.7で導入された機能である[encryption at rest](/docs/tasks/administer-cluster/encrypt-data/)をサポートしており、これは1.13からはベータ版となっています。
|
||||
これは、etcdの`Secret`リソースを暗号化し、etcdのバックアップにアクセスした人が、それらのシークレットの内容を見ることを防ぎます。
|
||||
この機能は現在ベータ版ですが、バックアップが暗号化されていない場合や、攻撃者がetcdへの読み取りアクセスを得た場合に、追加の防御レベルを提供します。
|
||||
|
||||
### セキュリティアップデートのアラートの受信と脆弱性の報告
|
||||
|
||||
[kubernetes-announce](https://groups.google.com/forum/#!forum/kubernetes-announce)に参加してください。
|
||||
グループに参加すると、セキュリティアナウンスに関するメールを受け取ることができます。
|
||||
脆弱性の報告方法については、[security reporting](/docs/reference/issues-security/security/)ページを参照してください。
|
||||
@@ -49,13 +49,15 @@ spec:
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 10251
|
||||
port: 10259
|
||||
scheme: HTTPS
|
||||
initialDelaySeconds: 15
|
||||
name: kube-second-scheduler
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 10251
|
||||
port: 10259
|
||||
scheme: HTTPS
|
||||
resources:
|
||||
requests:
|
||||
cpu: '0.1'
|
||||
|
||||
@@ -1131,7 +1131,7 @@ API 버전 `apps/v1` 에서는 `.spec.selector` 와 `.metadata.labels` 이 설
|
||||
|
||||
`.spec.strategy.rollingUpdate.maxUnavailable` 은 업데이트 프로세스 중에 사용할 수 없는 최대 파드의 수를 지정하는 선택적 필드이다.
|
||||
이 값은 절대 숫자(예: 5) 또는 의도한 파드 비율(예: 10%)이 될 수 있다.
|
||||
절대 값은 반올림해서 백분율로 계산한다.
|
||||
절대 값은 내림해서 백분율로 계산한다.
|
||||
만약 `.spec.strategy.rollingUpdate.maxSurge` 가 0이면 값이 0이 될 수 없다. 기본 값은 25% 이다.
|
||||
|
||||
예를 들어 이 값을 30%로 설정하면 롤링업데이트 시작시 즉각 이전 레플리카셋의 크기를
|
||||
@@ -1144,7 +1144,7 @@ API 버전 `apps/v1` 에서는 `.spec.selector` 와 `.metadata.labels` 이 설
|
||||
`.spec.strategy.rollingUpdate.maxSurge` 는 의도한 파드의 수에 대해 생성할 수 있는 최대 파드의 수를 지정하는 선택적 필드이다.
|
||||
이 값은 절대 숫자(예: 5) 또는 의도한 파드 비율(예: 10%)이 될 수 있다.
|
||||
`MaxUnavailable` 값이 0이면 이 값은 0이 될 수 없다.
|
||||
절대 값은 반올림해서 백분율로 계산한다. 기본 값은 25% 이다.
|
||||
절대 값은 올림해서 백분율로 계산한다. 기본 값은 25% 이다.
|
||||
|
||||
예를 들어 이 값을 30%로 설정하면 롤링업데이트 시작시 새 레플리카셋의 크기를 즉시 조정해서
|
||||
기존 및 새 파드의 전체 갯수를 의도한 파드의 130%를 넘지 않도록 한다.
|
||||
|
||||
@@ -51,7 +51,7 @@ Horizontal Pod Autoscaling을 활용하는
|
||||
|
||||
쿠버네티스는 Horizontal Pod Autoscaling을
|
||||
간헐적으로(intermittently) 실행되는
|
||||
컨트롤 루프 형태로 구현했다(지숙적인 프로세스가 아니다).
|
||||
컨트롤 루프 형태로 구현했다(지속적인 프로세스가 아니다).
|
||||
실행 주기는 [`kube-controller-manager`](/docs/reference/command-line-tools-reference/kube-controller-manager/)의
|
||||
`--horizontal-pod-autoscaler-sync-period` 파라미터에 의해 설정된다(기본 주기는 15초이다).
|
||||
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "Atualizado: Perguntas frequentes (FAQ) sobre a remoção do Dockershim"
|
||||
date: 2022-02-17
|
||||
slug: dockershim-faq
|
||||
aliases: [ '/dockershim' ]
|
||||
---
|
||||
|
||||
**Esta é uma atualização do artigo original [FAQ sobre a depreciação do Dockershim](/blog/2020/12/02/dockershim-faq/),
|
||||
publicado no final de 2020.**
|
||||
|
||||
Este documento aborda algumas perguntas frequentes sobre a
|
||||
descontinuação e remoção do _dockershim_, que foi
|
||||
[anunciado](/blog/2020/12/08/kubernetes-1-20-release-announcement/)
|
||||
como parte do lançamento do Kubernetes v1.20. Para obter mais detalhes sobre
|
||||
o que isso significa, confira a postagem do blog
|
||||
[Não entre em pânico: Kubernetes e Docker](/pt-br/blog/2020/12/02/dont-panic-kubernetes-and-docker/).
|
||||
|
||||
Além disso, você pode ler [verifique se a remoção do dockershim afeta você](/docs/tasks/administer-cluster/migrating-from-dockershim/check-if-dockershim-deprecation-affects-you/)
|
||||
para determinar qual impacto a remoção do _dockershim_ teria para você
|
||||
ou para sua organização.
|
||||
|
||||
Como o lançamento do Kubernetes 1.24 se tornou iminente, estamos trabalhando bastante para tentar fazer uma transição suave.
|
||||
|
||||
- Escrevemos uma postagem no blog detalhando nosso [compromisso e os próximos passos](/blog/2022/01/07/kubernetes-is-moving-on-from-dockershim/).
|
||||
- Acreditamos que não há grandes obstáculos para a migração para [outros agentes de execução de contêiner](/docs/setup/production-environment/container-runtimes/#container-runtimes).
|
||||
- Há também um guia [Migrando do dockershim](/docs/tasks/administer-cluster/migrating-from-dockershim/) disponível.
|
||||
- Também criamos uma página para listar
|
||||
[artigos sobre a remoção do dockershim e sobre o uso de agentes de execução compatíveis com CRI](/docs/reference/node/topics-on-dockershim-and-cri-compatible-runtimes/). Essa lista inclui alguns dos documentos já mencionados e também
|
||||
abrange fontes externas selecionadas (incluindo guias de fornecedores).
|
||||
|
||||
### Por que o _dockershim_ está sendo removido do Kubernetes?
|
||||
|
||||
As primeiras versões do Kubernetes funcionavam apenas com um ambiente de execução de contêiner específico:
|
||||
Docker Engine. Mais tarde, o Kubernetes adicionou suporte para trabalhar com outros agentes de execução de contêiner.
|
||||
O padrão CRI (_Container Runtime Interface_ ou Interface de Agente de Execução de Containers) foi [criado](/blog/2016/12/container-runtime-interface-cri-in-kubernetes/) para
|
||||
habilitar a interoperabilidade entre orquestradores (como Kubernetes) e diferentes agentes
|
||||
de execução de contêiner.
|
||||
O Docker Engine não implementa essa interface (CRI), então o projeto Kubernetes criou um
|
||||
código especial para ajudar na transição, e tornou esse código _dockershim_ parte do projeto
|
||||
Kubernetes.
|
||||
|
||||
O código _dockershim_ sempre foi destinado a ser uma solução temporária (daí o nome: _shim_).
|
||||
Você pode ler mais sobre a discussão e o planejamento da comunidade na
|
||||
[Proposta de remoção do Dockershim para aprimoramento do Kubernetes][drkep].
|
||||
Na verdade, manter o _dockershim_ se tornou um fardo pesado para os mantenedores do Kubernetes.
|
||||
|
||||
Além disso, recursos que são amplamente incompatíveis com o _dockershim_, como
|
||||
_cgroups v2_ e _namespaces_ de usuário estão sendo implementados nos agentes de execução de CRI
|
||||
mais recentes. A remoção do suporte para o _dockershim_ permitirá um maior
|
||||
desenvolvimento nessas áreas.
|
||||
|
||||
[drkep]: https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/2221-remove-dockershim
|
||||
|
||||
### Ainda posso usar o Docker Engine no Kubernetes 1.23?
|
||||
|
||||
Sim, a única coisa que mudou na versão 1.20 é a presença de um aviso no log de inicialização
|
||||
do [kubelet] se estiver usando o Docker Engine como agente de execução de contêiner.
|
||||
Você verá este aviso em todas as versões até 1.23. A remoção do _dockershim_ ocorre no Kubernetes 1.24.
|
||||
|
||||
[kubelet]: /docs/reference/command-line-tools-reference/kubelet/
|
||||
|
||||
### Quando o _dockershim_ será removido?
|
||||
|
||||
Dado o impacto dessa mudança, estamos definindo um cronograma de depreciação mais longo.
|
||||
A remoção do _dockershim_ está agendada para o Kubernetes v1.24, consulte a
|
||||
[Proposta de remoção do Dockershim para aprimoramento do Kubernetes][drkep].
|
||||
O projeto Kubernetes trabalhará em estreita colaboração com fornecedores e outros ecossistemas para garantir
|
||||
uma transição suave e avaliará os acontecimentos à medida que a situação for evoluindo.
|
||||
|
||||
### Ainda posso usar o Docker Engine como meu agente de execução do contêiner?
|
||||
|
||||
Primeiro, se você usa o Docker em seu próprio PC para desenvolver ou testar contêineres: nada muda.
|
||||
Você ainda pode usar o Docker localmente, independentemente dos agentes de execução de contêiner que
|
||||
você usa em seus Clusters Kubernetes. Os contêineres tornam esse tipo de interoperabilidade possível.
|
||||
|
||||
Mirantis e Docker [comprometeram-se][mirantis] a manter um adaptador substituto para o
|
||||
Docker Engine, e a manter este adaptador mesmo após o _dockershim_ ser removido
|
||||
do Kubernetes. O adaptador substituto é chamado [`cri-dockerd`](https://github.com/Mirantis/cri-dockerd).
|
||||
|
||||
[mirantis]: https://www.mirantis.com/blog/mirantis-to-take-over-support-of-kubernetes-dockershim-2/
|
||||
|
||||
### Minhas imagens de contêiner existentes ainda funcionarão?
|
||||
|
||||
Sim, as imagens produzidas a partir do `docker build` funcionarão com todas as implementações do CRI.
|
||||
Todas as suas imagens existentes ainda funcionarão exatamente da mesma forma.
|
||||
|
||||
#### E as imagens privadas?
|
||||
|
||||
Sim. Todos os agentes de execução de CRI são compatíveis com as mesmas configurações de segredos usadas no
|
||||
Kubernetes, seja por meio do PodSpec ou ServiceAccount.
|
||||
|
||||
### Docker e contêineres são a mesma coisa?
|
||||
|
||||
Docker popularizou o padrão de contêineres Linux e tem sido fundamental no
|
||||
desenvolvimento desta tecnologia. No entanto, os contêineres já existiam
|
||||
no Linux há muito tempo. O ecossistema de contêineres cresceu para ser muito
|
||||
mais abrangente do que apenas Docker. Padrões como o OCI e o CRI ajudaram muitas
|
||||
ferramentas a crescer e prosperar no nosso ecossistema, alguns substituindo
|
||||
aspectos do Docker, enquanto outros aprimoram funcionalidades já existentes.
|
||||
|
||||
### Existem exemplos de pessoas que usam outros agentes de execução de contêineres em produção hoje?
|
||||
|
||||
Todos os artefatos produzidos pelo projeto Kubernetes (binários Kubernetes) são validados
|
||||
a cada lançamento de versão.
|
||||
|
||||
Além disso, o projeto [kind] vem usando containerd há algum tempo e tem
|
||||
visto uma melhoria na estabilidade para seu caso de uso. Kind e containerd são executados
|
||||
várias vezes todos os dias para validar quaisquer alterações na base de código do Kubernetes.
|
||||
Outros projetos relacionados seguem um padrão semelhante, demonstrando a estabilidade e
|
||||
usabilidade de outros agentes de execução de contêiner. Como exemplo, o OpenShift 4.x utiliza
|
||||
o agente de execução [CRI-O] em produção desde junho de 2019.
|
||||
|
||||
Para outros exemplos e referências, dê uma olhada em projetos adeptos do containerd e
|
||||
CRI-O, dois agentes de execução de contêineres sob o controle da _Cloud Native Computing Foundation_
|
||||
([CNCF]).
|
||||
|
||||
- [containerd](https://github.com/containerd/containerd/blob/master/ADOPTERS.md)
|
||||
- [CRI-O](https://github.com/cri-o/cri-o/blob/master/ADOPTERS.md)
|
||||
|
||||
[CRI-O]: https://cri-o.io/
|
||||
[kind]: https://kind.sigs.k8s.io/
|
||||
[CNCF]: https://cncf.io
|
||||
|
||||
### As pessoas continuam referenciando OCI, o que é isso?
|
||||
|
||||
OCI significa _[Open Container Initiative]_ (ou Iniciativa Open Source de Contêineres), que padronizou muitas das
|
||||
interfaces entre ferramentas e tecnologias de contêiner. Eles mantêm uma
|
||||
especificação padrão para imagens de contêiner (OCI image-spec) e para
|
||||
contêineres em execução (OCI runtime-spec). Eles também mantêm uma implementação real
|
||||
da especificação do agente de execução na forma de [runc], que é o agente de execução padrão
|
||||
para ambos [containerd] e [CRI-O]. O CRI baseia-se nessas especificações de baixo nível para
|
||||
fornecer um padrão de ponta a ponta para gerenciar contêineres.
|
||||
|
||||
[Open Container Initiative]: https://opencontainers.org/about/overview/
|
||||
[runc]: https://github.com/opencontainers/runc
|
||||
[containerd]: https://containerd.io/
|
||||
|
||||
### Qual implementação de CRI devo usar?
|
||||
|
||||
Essa é uma pergunta complexa e depende de muitos fatores. Se você estiver
|
||||
trabalhando com Docker, mudar para containerd deve ser uma troca relativamente fácil e
|
||||
terá um desempenho estritamente melhor e menos sobrecarga. No entanto, nós encorajamos você a
|
||||
explorar todas as opções do [cenário CNCF], pois outro agente de execução de contêiner
|
||||
pode funcionar ainda melhor para o seu ambiente.
|
||||
|
||||
[cenário CNCF]: https://landscape.cncf.io/card-mode?category=container-runtime&grouping=category
|
||||
|
||||
### O que devo ficar atento ao mudar a minha implementação de CRI utilizada?
|
||||
|
||||
Embora o código de conteinerização base seja o mesmo entre o Docker e a maioria dos
|
||||
CRIs (incluindo containerd), existem algumas poucas diferenças. Alguns
|
||||
pontos a se considerar ao migrar são:
|
||||
|
||||
- Configuração de _log_
|
||||
- Limitações de recursos de agentes de execução
|
||||
- Scripts de provisionamento que chamam o docker ou usam o docker por meio de seu soquete de controle
|
||||
- Plugins kubectl que exigem CLI do docker ou o soquete de controle
|
||||
- Ferramentas do projeto Kubernetes que requerem acesso direto ao Docker Engine
|
||||
(por exemplo: a ferramenta depreciada `kube-imagepuller`)
|
||||
- Configuração de funcionalidades como `registry-mirrors` e _registries_ inseguros
|
||||
- Outros scripts de suporte ou _daemons_ que esperam que o Docker Engine esteja disponível e seja executado
|
||||
fora do Kubernetes (por exemplo, agentes de monitoramento ou segurança)
|
||||
- GPUs ou hardware especial e como eles se integram ao seu agente de execução e ao Kubernetes
|
||||
|
||||
Se você usa solicitações ou limites de recursos do Kubernetes ou usa DaemonSets para coleta de logs
|
||||
em arquivos, eles continuarão a funcionar da mesma forma. Mas se você personalizou
|
||||
sua configuração `dockerd`, você precisará adaptá-la para seu novo agente de execução de
|
||||
contêiner assim que possível.
|
||||
|
||||
Outro aspecto a ser observado é que ferramentas para manutenção do sistema ou execuções dentro de um
|
||||
contêiner no momento da criação de imagens podem não funcionar mais. Para o primeiro, a ferramenta
|
||||
[`crictl`][cr] pode ser utilizada como um substituto natural (veja
|
||||
[migrando do docker cli para o crictl](https://kubernetes.io/docs/tasks/debug-application-cluster/crictl/#mapping-from-docker-cli-to-crictl))
|
||||
e para o último, você pode usar novas opções de construções de contêiner, como [img], [buildah],
|
||||
[kaniko], ou [buildkit-cli-for-kubectl] que não requerem Docker.
|
||||
|
||||
[cr]: https://github.com/kubernetes-sigs/cri-tools
|
||||
[img]: https://github.com/genuinetools/img
|
||||
[buildah]: https://github.com/containers/buildah
|
||||
[kaniko]: https://github.com/GoogleContainerTools/kaniko
|
||||
[buildkit-cli-for-kubectl]: https://github.com/vmware-tanzu/buildkit-cli-for-kubectl
|
||||
|
||||
Para containerd, você pode começar com sua [documentação] para ver quais opções de configuração
|
||||
estão disponíveis à medida que você vá realizando a migração.
|
||||
|
||||
[documentação]: https://github.com/containerd/cri/blob/master/docs/registry.md
|
||||
|
||||
Para obter instruções sobre como usar containerd e CRI-O com Kubernetes, consulte o
|
||||
documentação do Kubernetes em [Agentes de execução de contêineres]
|
||||
|
||||
[Agentes de execução de contêineres]: /docs/setup/production-environment/container-runtimes/
|
||||
|
||||
### E se eu tiver mais perguntas?
|
||||
|
||||
Se você usa uma distribuição do Kubernetes com suporte do fornecedor, pode perguntar a eles sobre
|
||||
planos de atualização para seus produtos. Para perguntas de usuário final, poste-as
|
||||
no nosso fórum da comunidade de usuários: https://discuss.kubernetes.io/.
|
||||
|
||||
Você também pode conferir a excelente postagem do blog
|
||||
[Espere, o Docker está depreciado no Kubernetes agora?][dep], uma discussão técnica mais aprofundada
|
||||
sobre as mudanças.
|
||||
|
||||
[dep]: https://dev.to/inductor/wait-docker-is-deprecated-in-kubernetes-now-what-do-i-do-e4m
|
||||
|
||||
### Posso ganhar um abraço?
|
||||
|
||||
Sim, ainda estamos dando abraços se solicitado. 🤗🤗🤗
|
||||
@@ -0,0 +1,58 @@
|
||||
---
|
||||
title: Intervalos de limite
|
||||
content_type: concept
|
||||
weight: 10
|
||||
---
|
||||
|
||||
<!-- overview -->
|
||||
|
||||
Por padrão, os cointêineres são executados com [recursos computacionais](/docs/concepts/configuration/manage-resources-containers/) ilimitados em um cluster Kubernetes. Com cotas de recursos, os administradores de cluster podem restringir o consumo e a criação de recursos baseado no {{< glossary_tooltip text="namespace" term_id="namespace" >}}. Dentro de um _namespace_, pod ou contêiner pode haver o consumo de quantidade de CPU e memória definidos de acordo com a cota de recursos do _namespace_. Existe a preocupação de que um Pod ou contêiner possa monopolizar todos os recursos disponíveis, justamente por conta disso existe o conceito de _Limit Range_, ou intervalos de limite, que pode ser definido como uma política utilizada para a restrição de alocação de recursos (para pods ou contêineres) em um _namespace_.
|
||||
|
||||
<!-- body -->
|
||||
|
||||
Um _LimitRange_ fornece restrições que podem:
|
||||
|
||||
- Aplicar o uso mínimo e máximo de recursos computacionais por pod ou contêiner em um _namespace_.
|
||||
- Impor a solicitação de armazenamento mínimo e máximo por _PersistentVolumeClaim_ em um _namespace_.
|
||||
- Impor a proporção entre solicitação e limite para um recurso em um _namespace_.
|
||||
- Definir a solicitação/limite padrão para recursos computacionais em um _namespace_ e utilizá-los automaticamente nos contêineres em tempo de execução.
|
||||
|
||||
## Ativando o LimitRange
|
||||
|
||||
O suporte ao _LimitRange_ foi ativado por padrão desde o Kubernetes 1.10.
|
||||
|
||||
Um _LimitRange_ é aplicado em um _namespace_ específico quando há um objeto _LimitRange_ nesse _namespace_.
|
||||
|
||||
O nome de um objeto _LimitRange_ deve ser um [nome de subdomínio DNS](/docs/concepts/overview/working-with-objects/names#dns-subdomain-names) válido.
|
||||
|
||||
### Visão geral do Limit Range
|
||||
|
||||
- O administrador cria um _LimitRange_ em um _namespace_.
|
||||
- Os usuários criam recursos como pods, contêineres e _PersistentVolumeClaims_ no _namespace_.
|
||||
- O controlador de admissão `LimitRanger` impõe padrões e limites para todos os pods e contêineres que não definem os requisitos de recursos computacionais e rastreia o uso para garantir que não exceda o mínimo, o máximo e a proporção de recursos definidos em qualquer _LimitRange_ presente no _namespace_.
|
||||
- Se estiver criando ou atualizando um recurso (Pod, Container, _PersistentVolumeClaim_) que viola uma restrição _LimitRange_, a solicitação ao servidor da API falhará com um código de status HTTP `403 FORBIDDEN` e uma mensagem explicando a restrição violada.
|
||||
- Se um _LimitRange_ for ativado em um _namespace_ para recursos computacionais como `cpu` e `memória`, os usuários deverão especificar solicitações ou limites para esses valores. Caso contrário, o sistema pode rejeitar a criação do pod.
|
||||
- As validações de _LimitRange_ ocorrem apenas no estágio de Admissão de Pod, não em Pods em Execução.
|
||||
|
||||
Alguns exemplos de políticas que podem ser criadas utilizando os intervalos de limite são:
|
||||
|
||||
- Em um cluster de 2 nós com capacidade de 8 GiB de RAM e 16 núcleos, restrinja os Pods em um namespace para solicitar 100m de CPU com um limite máximo de 500m para CPU e solicitar 200Mi para memória com um limite máximo de 600Mi para memória.
|
||||
- Defina o limite e a solicitação de CPU padrão para 150m e a solicitação padrão de memória para 300Mi para contêineres iniciados sem solicitações de CPU e memória em suas especificações.
|
||||
|
||||
Caso os limites totais do namespace sejam menores que a soma dos limites dos Pods/Contêineres, pode haver contenção por recursos. Nesse caso, os contêineres ou Pods não serão criados.
|
||||
|
||||
Nem a contenção nem as alterações em um _LimitRange_ afetarão os recursos já criados.
|
||||
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
Consulte o [documento de design LimitRanger](https://git.k8s.io/community/contributors/design-proposals/resource-management/admission_control_limit_range.md) para obter mais informações.
|
||||
|
||||
Para exemplos de uso de limites, leia:
|
||||
|
||||
- [Como configurar restrições mínimas e máximas de CPU por _namespace_](/docs/tasks/administer-cluster/manage-resources/cpu-constraint-namespace/).
|
||||
- [Como configurar restrições de memória mínima e máxima por _namespace_](/docs/tasks/administer-cluster/manage-resources/memory-constraint-namespace/).
|
||||
- [como configurar solicitações e limites de CPU padrão por _namespace_](/docs/tasks/administer-cluster/manage-resources/cpu-default-namespace/).
|
||||
- [como configurar solicitações e limites de memória padrão por _namespace_](/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/).
|
||||
- [como configurar o consumo mínimo e máximo de armazenamento por _namespace_](/docs/tasks/administer-cluster/limit-storage-consumption/#limitrange-to-limit-requests-for-storage).
|
||||
- Um [exemplo detalhado de configuração de cota por _namespace_](/docs/tasks/administer-cluster/manage-resources/quota-memory-cpu-namespace/).
|
||||
|
||||
@@ -0,0 +1,649 @@
|
||||
---
|
||||
title: Cotas de Recursos
|
||||
content_type: concept
|
||||
weight: 20
|
||||
---
|
||||
|
||||
<!-- overview -->
|
||||
|
||||
Quando vários usuários ou equipes compartilham um cluster com um número fixo de nós,
|
||||
há uma preocupação de que uma equipe possa usar mais do que é justo durante o compartilhamento de recursos.
|
||||
|
||||
As cotas de recursos são uma ferramenta para os administradores resolverem essa preocupação.
|
||||
|
||||
<!-- body -->
|
||||
|
||||
Uma cota de recurso, definida por um objeto `ResourceQuota`, fornece restrições que limitam
|
||||
consumo de recursos agregados por _namespace_. Pode limitar a quantidade de objetos que podem
|
||||
ser criado em um _namespace_ por tipo, bem como a quantidade total de recursos computacionais que podem
|
||||
ser consumidos por recursos nesse _namespace_.
|
||||
|
||||
As cotas de recursos funcionam assim:
|
||||
|
||||
- Diferentes equipes trabalham em diferentes _namespaces_. Atualmente, isso é voluntário, mas o suporte para tornar isso obrigatório por meio de ACLs está planejado.
|
||||
|
||||
- O administrador cria uma `ResourceQuota` para cada _namespace_.
|
||||
|
||||
- Os usuários criam recursos (pods, serviços, etc.) no _namespace_ e o sistema de cotas rastreia o uso para garantir que ele não exceda os limites de recursos definidos em um `ResourceQuota`.
|
||||
|
||||
|
||||
- Se a criação ou atualização de um recurso violar uma restrição de cota, a solicitação falhará com código de status HTTP `403 FORBIDDEN` acompanhado de uma mensagem explicando a restrição que foi violada.
|
||||
|
||||
- Se a cota estiver habilitada em um _namespace_ para recursos computacionais como `cpu` e `memória`, os usuários devem especificar solicitações ou limites para esses valores; caso contrário, o sistema de cotas poderá rejeitar a criação de pods. Dica: use o controlador de admissão `LimitRanger` para forçar padrões para pods que não exigem recursos computacionais.
|
||||
|
||||
Veja o [passo a passo](/docs/tasks/administer-cluster/manage-resources/quota-memory-cpu-namespace/)
|
||||
para um exemplo de como evitar este problema.
|
||||
|
||||
O nome de um objeto `ResourceQuota` deve ser um [nome do subdomínio DNS](/docs/concepts/overview/working-with-objects/names#dns-subdomain-names) válido.
|
||||
|
||||
Exemplos de políticas que podem ser criadas usando _namespaces_ e cotas são:
|
||||
|
||||
- Em um cluster com capacidade de 32 GiB de RAM e 16 núcleos, deixe a equipe A usar 20 GiB e 10 núcleos, deixe B usar 10GiB e 4 núcleos e mantenha 2GiB e 2 núcleos em reserva para alocação futura.
|
||||
- Limite o _namespace_ "testing" para usar 1 núcleo e 1GiB de RAM. Deixe o namespace "produção" usar qualquer quantia.
|
||||
|
||||
Caso a capacidade total do cluster seja menor que a soma das cotas dos _namespaces_, pode haver contenção de recursos. Isso é tratado por ordem de chegada.
|
||||
|
||||
Nem a contenção nem as alterações na cota afetarão os recursos já criados.
|
||||
|
||||
## Ativando a cota de recursos
|
||||
|
||||
O suporte à cota de recursos é ativado por padrão para muitas distribuições do Kubernetes. Isto é
|
||||
ativado quando a flag {{< glossary_tooltip text="API server" term_id="kube-apiserver" >}} `--enable-admission-plugins=` tem `ResourceQuota` como
|
||||
um de seus argumentos.
|
||||
|
||||
Uma cota de recurso é aplicada em um _namespace_ específico quando há um `ResourceQuota` nesse _namespace_.
|
||||
|
||||
## Cota de recursos computacionais
|
||||
|
||||
Você pode limitar a soma total de [recursos computacionais](/docs/concepts/configuration/manage-resources-containers/) que pode ser solicitado em um determinado _namespace_.
|
||||
|
||||
Os seguintes tipos de recursos são suportados:
|
||||
|
||||
| Nome do Recurso | Descrição |
|
||||
| --------------------- | ----------------------------------------------------------- |
|
||||
| `limits.cpu` | Em todos os pods em um estado não terminal, a soma dos limites de CPU não pode exceder esse valor. |
|
||||
| `limits.memory` | Em todos os pods em um estado não terminal, a soma dos limites de memória não pode exceder esse valor.|
|
||||
| `requests.cpu` | Em todos os pods em um estado não terminal, a soma das solicitações da CPU não pode exceder esse valor. |
|
||||
| `requests.memory` | Em todos os pods em um estado não terminal, a soma das solicitações de memória não pode exceder esse valor. |
|
||||
| `hugepages-<size>` | Em todos os pods em um estado não terminal, o número de solicitações de grandes páginas do tamanho especificado não pode exceder esse valor. |
|
||||
| `cpu` | O mesmo que `requests.cpu` |
|
||||
| `memory` | O mesmo que `requests.memory` |
|
||||
|
||||
### Cota de recursos para recursos estendidos
|
||||
|
||||
Além dos recursos mencionados acima, na versão 1.10, suporte a cotas para [recursos estendidos](/docs/concepts/configuration/manage-resources-containers/#extended-resources) foi adicionado.
|
||||
|
||||
Como o `overcommit` não é permitido para recursos estendidos, não faz sentido especificar tanto `requests` e `limits` para o mesmo recurso estendido em uma cota. Portanto, para recursos estendidos, apenas itens de cota com prefixo `requests.` é permitido por enquanto.
|
||||
|
||||
Tome o recurso GPU como exemplo, se o nome do recurso for `nvidia.com/gpu` e você quiser limitar o número total de GPUs solicitadas em um _namespace_ para 4, você pode definir uma cota da seguinte maneira:
|
||||
|
||||
* `requests.nvidia.com/gpu: 4`
|
||||
|
||||
Veja [como visualizar e definir cotas](#viewing-and-setting-quotas) para mais informações.
|
||||
|
||||
|
||||
## Cota de recursos de armazenamento
|
||||
|
||||
Você pode limitar a soma total de [recursos de armazenamento](/docs/concepts/storage/persistent-volumes/) que podem ser solicitados em um determinado _namespace_.
|
||||
|
||||
Além disso, você pode limitar o consumo de recursos de armazenamento com base na classe de armazenamento associada.
|
||||
|
||||
| Nome do recurso | Descrição |
|
||||
| --------------------- | ----------------------------------------------------------- |
|
||||
| `requests.storage` | Em todas as solicitações de volume persistentes, a soma das solicitações de armazenamento não pode exceder esse valor.|
|
||||
| `persistentvolumeclaims` | O número total de [PersistentVolumeClaims](/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims) que podem existir no namespace. |
|
||||
| `<storage-class-name>.storageclass.storage.k8s.io/requests.storage` | Em todas as solicitações de volume persistentes associadas ao `<storage-class-name>`, a soma das solicitações de armazenamento não pode exceder esse valor. |
|
||||
| `<storage-class-name>.storageclass.storage.k8s.io/persistentvolumeclaims` | Em todas as declarações de volume persistentes associadas ao storage-class-name, o número total de [declarações de volume persistente](/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims) que podem existir no namespace. |
|
||||
|
||||
Por exemplo, se um operador deseja cotar armazenamento com classe de armazenamento `gold` separada da classe de armazenamento `bronze`, o operador pode definir uma cota da seguinte forma:
|
||||
|
||||
* `gold.storageclass.storage.k8s.io/requests.storage: 500Gi`
|
||||
* `bronze.storageclass.storage.k8s.io/requests.storage: 100Gi`
|
||||
|
||||
Na versão 1.8, o suporte de cota para armazenamento temporário local foi adicionado como um recurso alfa:
|
||||
|
||||
| Nome do Recurso | Descrição |
|
||||
| ------------------------------- |----------------------------------------------------------- |
|
||||
| `requests.ephemeral-storage` | Em todos os pods no _namespace_, a soma das solicitações de armazenamento local efêmero não pode exceder esse valor.|
|
||||
| `limits.ephemeral-storage` | Em todos os pods no _namespace_, a soma dos limites de armazenamento temporário local não pode exceder esse valor. |
|
||||
| `ephemeral-storage` | O mesmo que `requests.ephemeral-storage`. |
|
||||
|
||||
{{< note >}}
|
||||
Ao usar um tempo de execução do contêiner CRI, os logs do contêiner serão contabilizados na cota de armazenamento efêmero. Isso pode resultar no despejo inesperado de pods que esgotaram suas cotas de armazenamento. Consulte [Arquitetura de registro](/docs/concepts/cluster-administration/logging/) para mais detalhes.
|
||||
{{< /note >}}
|
||||
|
||||
## Cota de contagem de objetos
|
||||
|
||||
Você pode definir cotas para o número total de determinados recursos de todos os padrões, tipos de recursos com _namespace_ usando a seguinte sintaxe:
|
||||
|
||||
* `count/<resource>.<group>` para recursos de grupos não principais
|
||||
* `count/<resource>` para recursos do grupo principal
|
||||
|
||||
Exemplo de conjunto de recursos que os usuários podem querer colocar na cota de contagem de objetos:
|
||||
|
||||
* `count/persistentvolumeclaims`
|
||||
* `count/services`
|
||||
* `count/secrets`
|
||||
* `count/configmaps`
|
||||
* `count/replicationcontrollers`
|
||||
* `count/deployments.apps`
|
||||
* `count/replicasets.apps`
|
||||
* `count/statefulsets.apps`
|
||||
* `count/jobs.batch`
|
||||
* `count/cronjobs.batch`
|
||||
|
||||
A mesma sintaxe pode ser usada para recursos personalizados. Por exemplo, para criar uma cota em um recurso personalizado `widgets` no grupo de API `example.com`, use `count/widgets.example.com`.
|
||||
|
||||
Ao usar a cota de recurso `count/*`, um objeto é cobrado na cota se existir no armazenamento do servidor. Esses tipos de cotas são úteis para proteger contra o esgotamento dos recursos de armazenamento. Por exemplo, você pode desejar limitar o número de segredos em um servidor devido ao seu grande tamanho. Muitos segredos em um cluster podem
|
||||
na verdade, impedir que servidores e controladores sejam iniciados. Você pode definir uma cota para projetos para proteger contra um `CronJob` mal configurado. `CronJobs` que criam muitos `Jobs` em um _namespace_ podem levar a uma negação de serviço.
|
||||
|
||||
Também é possível fazer uma cota de contagem de objetos genéricos em um conjunto limitado de recursos.
|
||||
Os seguintes tipos são suportados:
|
||||
|
||||
| Nome do Recurso | Descrição |
|
||||
| ------------------------------- | ------------------------------------------------- |
|
||||
| `configmaps` | O número total de `ConfigMaps` que podem existir no namespace. |
|
||||
| `persistentvolumeclaims` | O número total de [PersistentVolumeClaims](/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims) que podem existir no namespace. |
|
||||
| `pods` | O número total de pods em um estado não terminal que pode existir no namespace. Um pod está em um estado terminal se `.status.phase in (Failed, Succeeded)` for verdadeiro. |
|
||||
| `replicationcontrollers` | O número total de `ReplicationControllers` que podem existir no _namespace_. |
|
||||
| `resourcequotas` | O número total de `ResourceQuotas` que podem existir no _namespace_. |
|
||||
| `services` | O número total de Serviços que podem existir no _namespace_. |
|
||||
| `services.loadbalancers` | O número total de serviços do tipo `LoadBalancer` que podem existir no _namespace_. |
|
||||
| `services.nodeports` | O número total de serviços do tipo `NodePort` que podem existir no _namespace_. |
|
||||
| `secrets` | O número total de segredos que podem existir no _namespace_. |
|
||||
|
||||
Por exemplo, a cota de `pods` conta e impõe um número máximo de `pods` criados em um único _namespace_ que não é terminal. Você pode querer definir uma cota `pods`em um _namespace_ para evitar o caso em que um usuário cria muitos `pods` pequenos e esgota o fornecimento de IPs de pod do cluster.
|
||||
|
||||
## Escopos de cota
|
||||
|
||||
Cada cota pode ter um conjunto associado de `scopes`. Uma cota só medirá o uso de um recurso se corresponder
|
||||
a interseção de escopos enumerados.
|
||||
|
||||
Quando um escopo é adicionado à cota, ele limita o número de recursos aos quais ele dá suporte a aqueles que pertencem ao escopo. Os recursos especificados na cota fora do conjunto permitido resultam em um erro de validação.
|
||||
|
||||
| Escopo | Descrição |
|
||||
| ----- | ----------- |
|
||||
| `Terminating` | Pods correspondentes onde `.spec.activeDeadlineSeconds >= 0` |
|
||||
| `NotTerminating` | Pods correspondentes onde `.spec.activeDeadlineSeconds is nil` |
|
||||
| `BestEffort` | Pods correspondentes que tenham a qualidade de serviço de melhor esforço. |
|
||||
| `NotBestEffort` | Pods correspondentes que não têm qualidade de serviço de melhor esforço. |
|
||||
| `PriorityClass` | Corresponde aos pods que fazem referência à [classe de prioridade](/docs/concepts/scheduling-eviction/pod-priority-preemption) especificada. |
|
||||
| `CrossNamespacePodAffinity` | Corresponde a pods que tenham [termos de (anti)afinidade](/docs/concepts/scheduling-eviction/assign-pod-node) de _namespace_ cruzado. |
|
||||
|
||||
O escopo `BestEffort` restringe uma cota ao rastreamento do seguinte recurso:
|
||||
|
||||
* `pods`
|
||||
|
||||
Os escopos `Termination`, `NotTerminate`, `NotBestEffort` e `PriorityClass`restringem uma cota para rastrear os seguintes recursos:
|
||||
|
||||
* `pods`
|
||||
* `cpu`
|
||||
* `memory`
|
||||
* `requests.cpu`
|
||||
* `requests.memory`
|
||||
* `limits.cpu`
|
||||
* `limits.memory`
|
||||
|
||||
Observe que você não pode especificar os escopos `Terminate` e o `NotTerminate`na mesma cota, e você também não pode especificar o `BestEffort` e`NotBestEffort` na mesma cota.
|
||||
|
||||
O `scopeSelector` suporta os seguintes valores no campo `operator`:
|
||||
|
||||
* `In`
|
||||
* `NotIn`
|
||||
* `Exists`
|
||||
* `DoesNotExist`
|
||||
|
||||
Ao usar um dos seguintes valores como o `scopeName` ao definir o`scopeSelector`, o `operator` deve ser `Exists`.
|
||||
|
||||
* `Terminating`
|
||||
* `NotTerminating`
|
||||
* `BestEffort`
|
||||
* `NotBestEffort`
|
||||
|
||||
Se o `operator` for `In` ou `NotIn`, o campo `values` deve ter pelo menos um valor. Por exemplo:
|
||||
|
||||
```yaml
|
||||
scopeSelector:
|
||||
matchExpressions:
|
||||
- scopeName: PriorityClass
|
||||
operator: In
|
||||
values:
|
||||
- middle
|
||||
```
|
||||
|
||||
Se o `operator` for `Exists` ou `DoesNotExist`, o campo `values` *NÃO* deve ser especificado.
|
||||
|
||||
### Cota de recursos por classe de prioridade
|
||||
|
||||
{{< feature-state for_k8s_version="v1.17" state="stable" >}}
|
||||
|
||||
Os pods podem ser criados em uma [prioridade](/docs/concepts/scheduling-eviction/pod-priority-preemption/#pod-priority) específica. Você pode controlar o consumo de recursos do sistema de um pod com base na prioridade de um pod, usando o `scopeSelector`
|
||||
campo na especificação de cota.
|
||||
|
||||
Uma cota é correspondida e consumida apenas se `scopeSelector` na especificação de cota selecionar o pod.
|
||||
|
||||
Quando a cota está no escopo da classe de prioridade usando o campo `scopeSelector`, objeto de cota
|
||||
está restrito a rastrear apenas os seguintes recursos:
|
||||
|
||||
* `pods`
|
||||
* `cpu`
|
||||
* `memory`
|
||||
* `ephemeral-storage`
|
||||
* `limits.cpu`
|
||||
* `limits.memory`
|
||||
* `limits.ephemeral-storage`
|
||||
* `requests.cpu`
|
||||
* `requests.memory`
|
||||
* `requests.ephemeral-storage`
|
||||
|
||||
Este exemplo cria um objeto de cota e o corresponde a pods em prioridades específicas. O exemplo
|
||||
funciona da seguinte forma:
|
||||
|
||||
- Os pods no cluster têm uma das três classes de prioridade, "baixa", "média", "alta".
|
||||
- Um objeto de cota é criado para cada prioridade.
|
||||
|
||||
Salve o seguinte YAML em um arquivo `quota.yml`.
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: List
|
||||
items:
|
||||
- apiVersion: v1
|
||||
kind: ResourceQuota
|
||||
metadata:
|
||||
name: pods-high
|
||||
spec:
|
||||
hard:
|
||||
cpu: "1000"
|
||||
memory: 200Gi
|
||||
pods: "10"
|
||||
scopeSelector:
|
||||
matchExpressions:
|
||||
- operator : In
|
||||
scopeName: PriorityClass
|
||||
values: ["high"]
|
||||
- apiVersion: v1
|
||||
kind: ResourceQuota
|
||||
metadata:
|
||||
name: pods-medium
|
||||
spec:
|
||||
hard:
|
||||
cpu: "10"
|
||||
memory: 20Gi
|
||||
pods: "10"
|
||||
scopeSelector:
|
||||
matchExpressions:
|
||||
- operator : In
|
||||
scopeName: PriorityClass
|
||||
values: ["medium"]
|
||||
- apiVersion: v1
|
||||
kind: ResourceQuota
|
||||
metadata:
|
||||
name: pods-low
|
||||
spec:
|
||||
hard:
|
||||
cpu: "5"
|
||||
memory: 10Gi
|
||||
pods: "10"
|
||||
scopeSelector:
|
||||
matchExpressions:
|
||||
- operator : In
|
||||
scopeName: PriorityClass
|
||||
values: ["low"]
|
||||
```
|
||||
|
||||
Aplique o YAML usando `kubectl create`.
|
||||
|
||||
```shell
|
||||
kubectl create -f ./quota.yml
|
||||
```
|
||||
|
||||
```
|
||||
resourcequota/pods-high created
|
||||
resourcequota/pods-medium created
|
||||
resourcequota/pods-low created
|
||||
```
|
||||
|
||||
Verifique se a cota `Used` é `0` usando `kubectl describe quota`.
|
||||
|
||||
```shell
|
||||
kubectl describe quota
|
||||
```
|
||||
|
||||
```
|
||||
Name: pods-high
|
||||
Namespace: default
|
||||
Resource Used Hard
|
||||
-------- ---- ----
|
||||
cpu 0 1k
|
||||
memory 0 200Gi
|
||||
pods 0 10
|
||||
|
||||
|
||||
Name: pods-low
|
||||
Namespace: default
|
||||
Resource Used Hard
|
||||
-------- ---- ----
|
||||
cpu 0 5
|
||||
memory 0 10Gi
|
||||
pods 0 10
|
||||
|
||||
|
||||
Name: pods-medium
|
||||
Namespace: default
|
||||
Resource Used Hard
|
||||
-------- ---- ----
|
||||
cpu 0 10
|
||||
memory 0 20Gi
|
||||
pods 0 10
|
||||
```
|
||||
|
||||
Crie um pod com prioridade "high". Salve o seguinte YAML em um arquivo `high-priority-pod.yml`.
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: high-priority
|
||||
spec:
|
||||
containers:
|
||||
- name: high-priority
|
||||
image: ubuntu
|
||||
command: ["/bin/sh"]
|
||||
args: ["-c", "while true; do echo hello; sleep 10;done"]
|
||||
resources:
|
||||
requests:
|
||||
memory: "10Gi"
|
||||
cpu: "500m"
|
||||
limits:
|
||||
memory: "10Gi"
|
||||
cpu: "500m"
|
||||
priorityClassName: high
|
||||
```
|
||||
|
||||
Applique com `kubectl create`.
|
||||
|
||||
```shell
|
||||
kubectl create -f ./high-priority-pod.yml
|
||||
```
|
||||
|
||||
Verifique se as estatísticas "Used" para a cota de prioridade "high", `pods-high` foram alteradas e se
|
||||
as outras duas cotas permanecem inalteradas.
|
||||
|
||||
```shell
|
||||
kubectl describe quota
|
||||
```
|
||||
|
||||
```
|
||||
Name: pods-high
|
||||
Namespace: default
|
||||
Resource Used Hard
|
||||
-------- ---- ----
|
||||
cpu 500m 1k
|
||||
memory 10Gi 200Gi
|
||||
pods 1 10
|
||||
|
||||
|
||||
Name: pods-low
|
||||
Namespace: default
|
||||
Resource Used Hard
|
||||
-------- ---- ----
|
||||
cpu 0 5
|
||||
memory 0 10Gi
|
||||
pods 0 10
|
||||
|
||||
|
||||
Name: pods-medium
|
||||
Namespace: default
|
||||
Resource Used Hard
|
||||
-------- ---- ----
|
||||
cpu 0 10
|
||||
memory 0 20Gi
|
||||
pods 0 10
|
||||
```
|
||||
|
||||
### Cota de afinidade de pod entre _namespaces_
|
||||
|
||||
{{< feature-state for_k8s_version="v1.22" state="beta" >}}
|
||||
|
||||
Os operadores podem usar o escopo de cota `CrossNamespacePodAffinity` para limitar quais _namespaces_ têm permissão para ter pods com termos de afinidade que cruzam _namespaces_. Especificamente, ele controla quais pods são permitidos para definir os campos `namespaces` ou `namespaceSelector` em termos de afinidade de pod.
|
||||
|
||||
Impedir que os usuários usem termos de afinidade entre _namespaces_ pode ser desejável, pois um pod
|
||||
com restrições antiafinidade pode bloquear pods de todos os outros _namespaces_ de ser agendado em um domínio de falha.
|
||||
|
||||
O uso desses operadores de escopo pode impedir certos _namespaces_ (`foo-ns` no exemplo abaixo) de ter pods que usam afinidade de pod entre _namespaces_ criando um objeto de cota de recurso nesse _namespace_ com escopo `CrossNamespaceAffinity` e limite rígido de 0:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ResourceQuota
|
||||
metadata:
|
||||
name: disable-cross-namespace-affinity
|
||||
namespace: foo-ns
|
||||
spec:
|
||||
hard:
|
||||
pods: "0"
|
||||
scopeSelector:
|
||||
matchExpressions:
|
||||
- scopeName: CrossNamespaceAffinity
|
||||
```
|
||||
|
||||
Se os operadores quiserem proibir o uso de `namespaces` e `namespaceSelector` por padrão, e
|
||||
permitir apenas para _namespaces_ específicos, eles podem configurar `CrossNamespaceAffinity`como um recurso limitado definindo o sinalizador kube-apiserver --admission-control-config-file
|
||||
para o caminho do seguinte arquivo de configuração:
|
||||
|
||||
```yaml
|
||||
apiVersion: apiserver.config.k8s.io/v1
|
||||
kind: AdmissionConfiguration
|
||||
plugins:
|
||||
- name: "ResourceQuota"
|
||||
configuration:
|
||||
apiVersion: apiserver.config.k8s.io/v1
|
||||
kind: ResourceQuotaConfiguration
|
||||
limitedResources:
|
||||
- resource: pods
|
||||
matchScopes:
|
||||
- scopeName: CrossNamespaceAffinity
|
||||
```
|
||||
|
||||
Com a configuração acima, os pods podem usar `namespaces` e `namespaceSelector` apenas na afinidade do pod se o _namespace_ em que foram criados tiver um objeto de cota de recurso com escopo `CrossNamespaceAffinity` e um limite rígido maior ou igual ao número de pods usando esses campos.
|
||||
|
||||
Esse recurso é beta e ativado por padrão. Você pode desativá-lo usando o [feature gate](/docs/reference/command-line-tools-reference/feature-gates/) `PodAffinityNamespaceSelector` no kube-apiserver e no kube-scheduler.
|
||||
|
||||
## Solicitações comparadas aos limites {#requests-vs-limits}
|
||||
|
||||
Ao alocar recursos computacionais, cada contêiner pode especificar uma solicitação e um valor limite para CPU ou memória. A cota pode ser configurada para cotar qualquer valor.
|
||||
|
||||
Se a cota tiver um valor especificado para `requests.cpu` ou `requests.memory`, ela exigirá que cada container faça uma solicitação explícita para esses recursos. Se a cota tiver um valor especificado para `limits.cpu` ou `limits.memory`, em seguida exige que cada contêiner de entrada especifique um limite explícito para esses recursos.
|
||||
|
||||
## Como visualizar e definir cotas
|
||||
|
||||
O Kubectl é compatível com a criação, atualização e visualização de cotas:
|
||||
|
||||
```shell
|
||||
kubectl create namespace myspace
|
||||
```
|
||||
|
||||
```shell
|
||||
cat <<EOF > compute-resources.yaml
|
||||
apiVersion: v1
|
||||
kind: ResourceQuota
|
||||
metadata:
|
||||
name: compute-resources
|
||||
spec:
|
||||
hard:
|
||||
requests.cpu: "1"
|
||||
requests.memory: 1Gi
|
||||
limits.cpu: "2"
|
||||
limits.memory: 2Gi
|
||||
requests.nvidia.com/gpu: 4
|
||||
EOF
|
||||
```
|
||||
|
||||
```shell
|
||||
kubectl create -f ./compute-resources.yaml --namespace=myspace
|
||||
```
|
||||
|
||||
```shell
|
||||
cat <<EOF > object-counts.yaml
|
||||
apiVersion: v1
|
||||
kind: ResourceQuota
|
||||
metadata:
|
||||
name: object-counts
|
||||
spec:
|
||||
hard:
|
||||
configmaps: "10"
|
||||
persistentvolumeclaims: "4"
|
||||
pods: "4"
|
||||
replicationcontrollers: "20"
|
||||
secrets: "10"
|
||||
services: "10"
|
||||
services.loadbalancers: "2"
|
||||
EOF
|
||||
```
|
||||
|
||||
```shell
|
||||
kubectl create -f ./object-counts.yaml --namespace=myspace
|
||||
```
|
||||
|
||||
```shell
|
||||
kubectl get quota --namespace=myspace
|
||||
```
|
||||
|
||||
```none
|
||||
NAME AGE
|
||||
compute-resources 30s
|
||||
object-counts 32s
|
||||
```
|
||||
|
||||
```shell
|
||||
kubectl describe quota compute-resources --namespace=myspace
|
||||
```
|
||||
|
||||
```none
|
||||
Name: compute-resources
|
||||
Namespace: myspace
|
||||
Resource Used Hard
|
||||
-------- ---- ----
|
||||
limits.cpu 0 2
|
||||
limits.memory 0 2Gi
|
||||
requests.cpu 0 1
|
||||
requests.memory 0 1Gi
|
||||
requests.nvidia.com/gpu 0 4
|
||||
```
|
||||
|
||||
```shell
|
||||
kubectl describe quota object-counts --namespace=myspace
|
||||
```
|
||||
|
||||
```none
|
||||
Name: object-counts
|
||||
Namespace: myspace
|
||||
Resource Used Hard
|
||||
-------- ---- ----
|
||||
configmaps 0 10
|
||||
persistentvolumeclaims 0 4
|
||||
pods 0 4
|
||||
replicationcontrollers 0 20
|
||||
secrets 1 10
|
||||
services 0 10
|
||||
services.loadbalancers 0 2
|
||||
```
|
||||
|
||||
Kubectl also supports object count quota for all standard namespaced resources
|
||||
using the syntax `count/<resource>.<group>`:
|
||||
|
||||
```shell
|
||||
kubectl create namespace myspace
|
||||
```
|
||||
|
||||
```shell
|
||||
kubectl create quota test --hard=count/deployments.apps=2,count/replicasets.apps=4,count/pods=3,count/secrets=4 --namespace=myspace
|
||||
```
|
||||
|
||||
```shell
|
||||
kubectl create deployment nginx --image=nginx --namespace=myspace --replicas=2
|
||||
```
|
||||
|
||||
```shell
|
||||
kubectl describe quota --namespace=myspace
|
||||
```
|
||||
|
||||
```
|
||||
Name: test
|
||||
Namespace: myspace
|
||||
Resource Used Hard
|
||||
-------- ---- ----
|
||||
count/deployments.apps 1 2
|
||||
count/pods 2 3
|
||||
count/replicasets.apps 1 4
|
||||
count/secrets 1 4
|
||||
```
|
||||
|
||||
## Capacidade e cota de Cluster
|
||||
|
||||
`ResourceQuotas` são independentes da capacidade do cluster. Eles estão expresso em unidades absolutas. Portanto, se você adicionar nós ao cluster, isso *não*
|
||||
dá automaticamente a cada _namespace_ a capacidade de consumir mais recursos.
|
||||
|
||||
Às vezes, políticas mais complexas podem ser necessárias, como:
|
||||
|
||||
- Divida proporcionalmente os recursos totais do cluster entre várias equipes.
|
||||
- Permita que cada locatário aumente o uso de recursos conforme necessário, mas tenha um generoso limite para evitar o esgotamento acidental de recursos.
|
||||
- Detecte a demanda de um _namespace_, adicione nós e aumente a cota.
|
||||
|
||||
Tais políticas podem ser implementadas usando `ResourceQuotas` como blocos de construção, por
|
||||
escrevendo um "controlador" que observa o uso da cota e ajusta os limites rígidos da cota de cada _namespace_ de acordo com outros sinais.
|
||||
|
||||
Observe que a cota de recursos divide os recursos agregados do cluster, mas não cria restrições em torno dos nós: pods de vários _namespaces_ podem ser executados no mesmo nó.
|
||||
|
||||
## Limite de consumo de classe de prioridade por padrão
|
||||
|
||||
Pode ser desejado que os pods com uma prioridade particular, por exemplo. "cluster-services",
|
||||
deve ser permitido em um _namespace_, se, e somente se, existir um objeto de cota correspondente.
|
||||
|
||||
Com este mecanismo, os operadores podem restringir o uso de certas classes de prioridade para um número limitado de _namespaces_ , e nem todos poderão consumir essas classes de prioridade por padrão.
|
||||
|
||||
Para impor isso, a flag `kube-apiserver` `--admission-control-config-file` deve ser
|
||||
usada para passar o caminho para o seguinte arquivo de configuração:
|
||||
|
||||
```yaml
|
||||
apiVersion: apiserver.config.k8s.io/v1
|
||||
kind: AdmissionConfiguration
|
||||
plugins:
|
||||
- name: "ResourceQuota"
|
||||
configuration:
|
||||
apiVersion: apiserver.config.k8s.io/v1
|
||||
kind: ResourceQuotaConfiguration
|
||||
limitedResources:
|
||||
- resource: pods
|
||||
matchScopes:
|
||||
- scopeName: PriorityClass
|
||||
operator: In
|
||||
values: ["cluster-services"]
|
||||
```
|
||||
|
||||
Em seguida, crie um objeto de cota de recurso no _namespace_ `kube-system`:
|
||||
|
||||
{{< codenew file="policy/priority-class-resourcequota.yaml" >}}
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/policy/priority-class-resourcequota.yaml -n kube-system
|
||||
```
|
||||
|
||||
```none
|
||||
resourcequota/pods-cluster-services created
|
||||
```
|
||||
|
||||
Nesse caso, a criação de um pod será permitida se:
|
||||
|
||||
1. O `priorityClassName` do pod não foi especificado.
|
||||
1. O `priorityClassName` do pod é especificado com um valor diferente de `cluster-services`.
|
||||
1. O `priorityClassName` do pod está definido como `cluster-services`, ele deve ser criado no namespace `kube-system` e passou na verificação de cota de recursos.
|
||||
|
||||
Uma solicitação de criação de pod é rejeitada caso seu `priorityClassName` estiver definido como `cluster-services` e deve ser criado em um _namespace_ diferente de `kube-system`.
|
||||
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
- Veja o [documento de design de cota de recursos](https://git.k8s.io/community/contributors/design-proposals/resource-management/admission_control_resource_quota.md) para mais informações.
|
||||
- Veja um [exemplo detalhado de como usar a cota de recursos](/docs/tasks/administer-cluster/quota-api-object/).
|
||||
- Leia o [documento de design de suporte de cota para prioridade de classe](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/scheduling/pod-priority-resourcequota.md).
|
||||
- Veja [recursos limitados](https://github.com/kubernetes/kubernetes/pull/36765)
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: v1
|
||||
kind: ResourceQuota
|
||||
metadata:
|
||||
name: pods-cluster-services
|
||||
spec:
|
||||
scopeSelector:
|
||||
matchExpressions:
|
||||
- operator : In
|
||||
scopeName: PriorityClass
|
||||
values: ["cluster-services"]
|
||||
@@ -11,7 +11,7 @@ weight: 30
|
||||
Вот один из примеров контура управления: термостат в помещении.
|
||||
|
||||
Когда вы устанавливаете температуру, это говорит термостату о вашем *желаемом состоянии*. Фактическая температура в помещении - это
|
||||
*текущее состояние*. Термостат действует так, чтобы приблизить текущее состояние к елаемому состоянию, путем включения или выключения оборудования.
|
||||
*текущее состояние*. Термостат действует так, чтобы приблизить текущее состояние к желаемому состоянию, путем включения или выключения оборудования.
|
||||
|
||||
{{< glossary_definition term_id="controller" length="short">}}
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ content_type: concept
|
||||
* [Canal](https://github.com/tigera/canal/tree/master/k8s-install) объединяет Flannel и Calico, обеспечивая сеть и сетевую политик.
|
||||
* [Cilium](https://github.com/cilium/cilium) - это плагин сети L3 и сетевой политики, который может прозрачно применять политики HTTP/API/L7. Поддерживаются как режим маршрутизации, так и режим наложения/инкапсуляции, и он может работать поверх других подключаемых модулей CNI.
|
||||
* [CNI-Genie](https://github.com/Huawei-PaaS/CNI-Genie) позволяет Kubernetes легко подключаться к выбору плагинов CNI, таких как Calico, Canal, Flannel, Romana или Weave.
|
||||
* [Contiv](https://contiv.github.io) предоставляет настраиваемую сеть (собственный L3 с использованием BGP, слоя с использованием vxlan, классический L2 и Cisco-SDN/ACI) для различных вариантов использования и обширную структуру политик. Проект Contiv имеет полностью [открытый исходный код](https://github.com/contiv). [Установка](https://github.com/contiv/install) обеспечивает варианты на основе как kubeadm так и без kubeadm.
|
||||
* [Contrail](https://www.juniper.net/us/en/products-services/sdn/contrail/contrail-networking/), основан на [Tungsten Fabric](https://tungsten.io), представляет собой платформу для виртуализации мультиоблачных сетей с открытым исходным кодом и управления политиками. Contrail и Tungsten Fabric are интегрированы с системами оркестровки, такими как Kubernetes, OpenShift, OpenStack и Mesos, и обеспечивают режимы изоляции для виртуальных машин, контейнеров/pod-ов и рабочих нагрузок без операционной системы.
|
||||
* [Flannel](https://github.com/flannel-io/flannel#deploying-flannel-manually) - это поставщик оверлейной сети, который можно использовать с Kubernetes.
|
||||
* [Knitter](https://github.com/ZTE/Knitter/) - это плагин для поддержки нескольких сетевых интерфейсов Kubernetes pod-ов.
|
||||
|
||||
@@ -17,7 +17,7 @@ card:
|
||||
<!-- body -->
|
||||
Kubernetes — это портативная расширяемая платформа с открытым исходным кодом для управления контейнеризованными рабочими нагрузками и сервисами, которая облегчает как декларативную настройку, так и автоматизацию. У платформы есть большая, быстро растущая экосистема. Сервисы, поддержка и инструменты Kubernetes широко доступны.
|
||||
|
||||
Название Kubernetes происходит от греческого, что означает рулевой или штурман. Google открыл исходный код Kubernetes в 2014 году. Kubernetes основывается на [десятилетнем опыте работе Google с масштабными рабочими нагрузками](https://research.google/pubs/pub43438), в сочетании с лучшими в своем классе идеями и практиками сообщества.
|
||||
Название Kubernetes происходит от греческого, что означает рулевой или штурман. Google открыл исходный код Kubernetes в 2014 году. Kubernetes основывается на [десятилетнем опыте работы Google с масштабными рабочими нагрузками](https://research.google/pubs/pub43438), в сочетании с лучшими в своем классе идеями и практиками сообщества.
|
||||
|
||||
## История
|
||||
Давайте вернемся назад и посмотрим, почему Kubernetes так полезен.
|
||||
|
||||
Executable → Regular
@@ -0,0 +1,373 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "更新:弃用 Dockershim 的常见问题"
|
||||
date: 2022-02-17
|
||||
slug: dockershim-faq
|
||||
aliases: [ '/dockershim' ]
|
||||
---
|
||||
<!--
|
||||
layout: blog
|
||||
title: "Updated: Dockershim Removal FAQ"
|
||||
date: 2022-02-17
|
||||
slug: dockershim-faq
|
||||
aliases: [ '/dockershim' ]
|
||||
-->
|
||||
|
||||
<!--
|
||||
**This is an update to the original [Dockershim Deprecation FAQ](/blog/2020/12/02/dockershim-faq/) article,
|
||||
published in late 2020.**
|
||||
-->
|
||||
**本文是针对2020年末发布的[弃用 Dockershim 的常见问题](/zh/blog/2020/12/02/dockershim-faq/)的博客更新。**
|
||||
|
||||
<!--
|
||||
This document goes over some frequently asked questions regarding the
|
||||
deprecation and removal of _dockershim_, that was
|
||||
[announced](/blog/2020/12/08/kubernetes-1-20-release-announcement/)
|
||||
as a part of the Kubernetes v1.20 release. For more detail
|
||||
on what that means, check out the blog post
|
||||
[Don't Panic: Kubernetes and Docker](/blog/2020/12/02/dont-panic-kubernetes-and-docker/).
|
||||
-->
|
||||
本文回顾了自 Kubernetes v1.20 版本[宣布](/zh/blog/2020/12/08/kubernetes-1-20-release-announcement/)弃用
|
||||
Dockershim 以来所引发的一些常见问题。关于弃用细节以及这些细节背后的含义,请参考博文
|
||||
[别慌: Kubernetes 和 Docker](/zh/blog/2020/12/02/dont-panic-kubernetes-and-docker/)。
|
||||
|
||||
<!--
|
||||
Also, you can read [check whether dockershim removal affects you](/docs/tasks/administer-cluster/migrating-from-dockershim/check-if-dockershim-deprecation-affects-you/)
|
||||
to determine how much impact the removal of dockershim would have for you
|
||||
or for your organization.
|
||||
-->
|
||||
你还可以查阅:[检查弃用 Dockershim 对你的影响](/zh/docs/tasks/administer-cluster/migrating-from-dockershim/check-if-dockershim-deprecation-affects-you/)这篇文章,
|
||||
以确定弃用 dockershim 会对你或你的组织带来多大的影响。
|
||||
|
||||
<!--
|
||||
As the Kubernetes 1.24 release has become imminent, we've been working hard to try to make this a smooth transition.
|
||||
-->
|
||||
随着 Kubernetes 1.24 版本的发布迫在眉睫,我们一直在努力尝试使其能够平稳升级顺利过渡。
|
||||
|
||||
<!--
|
||||
- We've written a blog post detailing our [commitment and next steps](/blog/2022/01/07/kubernetes-is-moving-on-from-dockershim/).
|
||||
- We believe there are no major blockers to migration to [other container runtimes](/docs/setup/production-environment/container-runtimes/#container-runtimes).
|
||||
- There is also a [Migrating from dockershim](/docs/tasks/administer-cluster/migrating-from-dockershim/) guide available.
|
||||
- We've also created a page to list
|
||||
[articles on dockershim removal and on using CRI-compatible runtimes](/docs/reference/node/topics-on-dockershim-and-cri-compatible-runtimes/).
|
||||
That list includes some of the already mentioned docs, and also covers selected external sources
|
||||
(including vendor guides).
|
||||
-->
|
||||
- 我们已经写了一篇博文,详细说明了我们的[承诺和后续操作](/blog/2022/01/07/kubernetes-is-moving-on-from-dockershim/)。
|
||||
- 我们我们相信可以无障碍的迁移到其他[容器运行时](/zh/docs/setup/production-environment/container-runtimes/#container-runtimes)。
|
||||
- 我们撰写了 [dockershim 迁移指南](/docs/tasks/administer-cluster/migrating-from-dockershim/)供你参考。
|
||||
- 我们还创建了一个页面来列出[有关 dockershim 移除和使用 CRI 兼容运行时的文章](/zh/docs/reference/node/topics-on-dockershim-and-cri-compatible-runtimes/)。
|
||||
该列表包括一些已经提到的文档,还涵盖了选定的外部资源(包括供应商指南)。
|
||||
|
||||
<!--
|
||||
### Why is the dockershim being removed from Kubernetes?
|
||||
-->
|
||||
### 为什么会从 Kubernetes 中移除 dockershim ?
|
||||
|
||||
<!--
|
||||
Early versions of Kubernetes only worked with a specific container runtime:
|
||||
Docker Engine. Later, Kubernetes added support for working with other container runtimes.
|
||||
The CRI standard was [created](/blog/2016/12/container-runtime-interface-cri-in-kubernetes/) to
|
||||
enable interoperability between orchestrators (like Kubernetes) and many different container
|
||||
runtimes.
|
||||
Docker Engine doesn't implement that interface (CRI), so the Kubernetes project created
|
||||
special code to help with the transition, and made that _dockershim_ code part of Kubernetes
|
||||
itself.
|
||||
-->
|
||||
Kubernetes 的早期版本仅适用于特定的容器运行时:Docker Engine。
|
||||
后来,Kubernetes 增加了对使用其他容器运行时的支持。[创建](/blog/2016/12/container-runtime-interface-cri-in-kubernetes/) CRI
|
||||
标准是为了实现编排器(如 Kubernetes)和许多不同的容器运行时之间交互操作。
|
||||
Docker Engine 没有实现(CRI)接口,因此 Kubernetes 项目创建了特殊代码来帮助过渡,
|
||||
并使 dockershim 代码成为 Kubernetes 的一部分。
|
||||
|
||||
<!--
|
||||
The dockershim code was always intended to be a temporary solution (hence the name: shim).
|
||||
You can read more about the community discussion and planning in the
|
||||
[Dockershim Removal Kubernetes Enhancement Proposal][drkep].
|
||||
In fact, maintaining dockershim had become a heavy burden on the Kubernetes maintainers.
|
||||
-->
|
||||
dockershim 代码一直是一个临时解决方案(因此得名:shim)。
|
||||
你可以阅读 [Kubernetes 移除 Dockershim 增强方案](https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/2221-remove-dockershim)
|
||||
以了解相关的社区讨论和计划。
|
||||
事实上,维护 dockershim 已经成为 Kubernetes 维护者的沉重负担。
|
||||
|
||||
<!--
|
||||
Additionally, features that were largely incompatible with the dockershim, such
|
||||
as cgroups v2 and user namespaces are being implemented in these newer CRI
|
||||
runtimes. Removing support for the dockershim will allow further development in
|
||||
those areas.
|
||||
-->
|
||||
此外,在较新的 CRI 运行时中实现了与 dockershim 不兼容的功能,例如 cgroups v2 和用户命名空间。
|
||||
取消对 dockershim 的支持将加速这些领域的发展。
|
||||
|
||||
<!--
|
||||
### Can I still use Docker Engine in Kubernetes 1.23?
|
||||
-->
|
||||
### 在 Kubernetes 1.23 版本中还可以使用 Docker Engine 吗?
|
||||
|
||||
<!--
|
||||
Yes, the only thing changed in 1.20 is a single warning log printed at [kubelet]
|
||||
startup if using Docker Engine as the runtime. You'll see this warning in all versions up to 1.23. The dockershim removal occurs in Kubernetes 1.24.
|
||||
-->
|
||||
可以使用,在 1.20 版本中唯一的改动是,如果使用 Docker Engine,
|
||||
在 [kubelet](/zh/docs/reference/command-line-tools-reference/kubelet/)
|
||||
启动时会打印一个警告日志。
|
||||
你将在 1.23 版本及以前版本看到此警告。dockershim 将在 Kubernetes 1.24 版本中移除 。
|
||||
|
||||
<!--
|
||||
### When will dockershim be removed?
|
||||
-->
|
||||
### 什么时候移除 dockershim ?
|
||||
|
||||
<!--
|
||||
Given the impact of this change, we are using an extended deprecation timeline.
|
||||
Removal of dockershim is scheduled for Kubernetes v1.24, see [Dockershim Removal Kubernetes Enhancement Proposal][drkep].
|
||||
The Kubernetes project will be working closely with vendors and other ecosystem groups to ensure
|
||||
a smooth transition and will evaluate things as the situation evolves.
|
||||
-->
|
||||
考虑到此变更带来的影响,我们使用了一个加长的废弃时间表。
|
||||
dockershim 计划在 Kubernetes v1.24 中进行移除,
|
||||
参见 [Kubernetes 移除 Dockershim 增强方案](https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/2221-remove-dockershim)。
|
||||
Kubernetes 项目将与供应商和其他生态系统组织密切合作,以确保平稳过渡,并将依据事态的发展评估后续事项。
|
||||
|
||||
<!--
|
||||
### Can I still use Docker Engine as my container runtime?
|
||||
-->
|
||||
### 我还可以使用 Docker Engine 作为我的容器运行时吗?
|
||||
|
||||
<!--
|
||||
First off, if you use Docker on your own PC to develop or test containers: nothing changes.
|
||||
You can still use Docker locally no matter what container runtime(s) you use for your
|
||||
Kubernetes clusters. Containers make this kind of interoperability possible.
|
||||
-->
|
||||
首先,如果你在自己的电脑上使用 Docker 用来做开发或测试容器:它将与之前没有任何变化。
|
||||
无论你为 Kubernetes 集群使用什么容器运行时,你都可以在本地使用 Docker。容器使这种交互成为可能。
|
||||
|
||||
<!--
|
||||
Mirantis and Docker have [committed][mirantis] to maintaining a replacement adapter for
|
||||
Docker Engine, and to maintain that adapter even after the in-tree dockershim is removed
|
||||
from Kubernetes. The replacement adapter is named [`cri-dockerd`](https://github.com/Mirantis/cri-dockerd).
|
||||
-->
|
||||
Mirantis 和 Docker 已[承诺](https://www.mirantis.com/blog/mirantis-to-take-over-support-of-kubernetes-dockershim-2/)
|
||||
为 Docker Engine 维护一个替代适配器,
|
||||
并在 dockershim 从 Kubernetes 移除后维护该适配器。
|
||||
替代适配器名为 [`cri-dockerd`](https://github.com/Mirantis/cri-dockerd)。
|
||||
|
||||
<!--
|
||||
### Will my existing container images still work?
|
||||
-->
|
||||
### 我现有的容器镜像还能正常工作吗?
|
||||
|
||||
<!--
|
||||
Yes, the images produced from `docker build` will work with all CRI implementations.
|
||||
All your existing images will still work exactly the same.
|
||||
-->
|
||||
当然可以,`docker build` 创建的镜像适用于任何 CRI 实现。
|
||||
所有你的现有镜像将和往常一样工作。
|
||||
|
||||
<!--
|
||||
#### What about private images?
|
||||
-->
|
||||
### 私有镜像呢?
|
||||
|
||||
<!--
|
||||
Yes. All CRI runtimes support the same pull secrets configuration used in
|
||||
Kubernetes, either via the PodSpec or ServiceAccount.
|
||||
-->
|
||||
当然可以。所有 CRI 运行时均支持在 Kubernetes 中相同的拉取(pull)Secret 配置,
|
||||
无论是通过 PodSpec 还是 ServiceAccount。
|
||||
|
||||
<!--
|
||||
### Are Docker and containers the same thing?
|
||||
-->
|
||||
### Docker 和容器是一回事吗?
|
||||
|
||||
<!--
|
||||
Docker popularized the Linux containers pattern and has been instrumental in
|
||||
developing the underlying technology, however containers in Linux have existed
|
||||
for a long time. The container ecosystem has grown to be much broader than just
|
||||
Docker. Standards like OCI and CRI have helped many tools grow and thrive in our
|
||||
ecosystem, some replacing aspects of Docker while others enhance existing
|
||||
functionality.
|
||||
-->
|
||||
Docker 普及了 Linux 容器模式,并在开发底层技术方面发挥了重要作用,
|
||||
但是 Linux 中的容器已经存在了很长时间。容器的生态相比于 Docker 具有更宽广的领域。
|
||||
OCI 和 CRI 等标准帮助许多工具在我们的生态系统中发展壮大,
|
||||
其中一些替代了 Docker 的某些方面,而另一些则增强了现有功能。
|
||||
|
||||
<!--
|
||||
### Are there examples of folks using other runtimes in production today?
|
||||
-->
|
||||
### 现在是否有在生产系统中使用其他运行时的例子?
|
||||
|
||||
<!--
|
||||
All Kubernetes project produced artifacts (Kubernetes binaries) are validated
|
||||
with each release.
|
||||
-->
|
||||
Kubernetes 所有项目在所有版本中出产的工件(Kubernetes 二进制文件)都经过了验证。
|
||||
|
||||
<!--
|
||||
Additionally, the [kind] project has been using containerd for some time and has
|
||||
seen an improvement in stability for its use case. Kind and containerd are leveraged
|
||||
multiple times every day to validate any changes to the Kubernetes codebase. Other
|
||||
related projects follow a similar pattern as well, demonstrating the stability and
|
||||
usability of other container runtimes. As an example, OpenShift 4.x has been
|
||||
using the [CRI-O] runtime in production since June 2019.
|
||||
-->
|
||||
此外,[kind](https://kind.sigs.k8s.io/) 项目使用 containerd 已经有一段时间了,并且提高了其用例的稳定性。
|
||||
Kind 和 containerd 每天都会被多次使用来验证对 Kubernetes 代码库的任何更改。
|
||||
其他相关项目也遵循同样的模式,从而展示了其他容器运行时的稳定性和可用性。
|
||||
例如,OpenShift 4.x 从 2019 年 6 月以来,就一直在生产环境中使用 [CRI-O](https://cri-o.io/) 运行时。
|
||||
|
||||
<!--
|
||||
For other examples and references you can look at the adopters of containerd and
|
||||
CRI-O, two container runtimes under the Cloud Native Computing Foundation ([CNCF]).
|
||||
-->
|
||||
至于其他示例和参考资料,你可以查看 containerd 和 CRI-O 的使用者列表,
|
||||
这两个容器运行时是云原生基金会([CNCF](https://cncf.io))下的项目。
|
||||
|
||||
- [containerd](https://github.com/containerd/containerd/blob/master/ADOPTERS.md)
|
||||
- [CRI-O](https://github.com/cri-o/cri-o/blob/master/ADOPTERS.md)
|
||||
|
||||
<!--
|
||||
### People keep referencing OCI, what is that?
|
||||
-->
|
||||
### 人们总在谈论 OCI,它是什么?
|
||||
|
||||
<!--
|
||||
OCI stands for the [Open Container Initiative], which standardized many of the
|
||||
interfaces between container tools and technologies. They maintain a standard
|
||||
specification for packaging container images (OCI image-spec) and running containers
|
||||
(OCI runtime-spec). They also maintain an actual implementation of the runtime-spec
|
||||
in the form of [runc], which is the underlying default runtime for both
|
||||
[containerd] and [CRI-O]. The CRI builds on these low-level specifications to
|
||||
provide an end-to-end standard for managing containers.
|
||||
-->
|
||||
OCI 是 [Open Container Initiative](https://opencontainers.org/about/overview/) 的缩写,
|
||||
它标准化了容器工具和底层实现之间的大量接口。
|
||||
它们维护了打包容器镜像(OCI image)和运行时(OCI runtime)的标准规范。
|
||||
它们还以 [runc](https://github.com/opencontainers/runc) 的形式维护了一个 runtime-spec 的真实实现,
|
||||
这也是 [containerd](https://containerd.io/) 和 [CRI-O](https://cri-o.io/) 依赖的默认运行时。
|
||||
CRI 建立在这些底层规范之上,为管理容器提供端到端的标准。
|
||||
|
||||
<!--
|
||||
### Which CRI implementation should I use?
|
||||
-->
|
||||
### 我应该用哪个 CRI 实现?
|
||||
|
||||
<!--
|
||||
That’s a complex question and it depends on a lot of factors. If Docker is
|
||||
working for you, moving to containerd should be a relatively easy swap and
|
||||
will have strictly better performance and less overhead. However, we encourage you
|
||||
to explore all the options from the [CNCF landscape] in case another would be an
|
||||
even better fit for your environment.
|
||||
-->
|
||||
这是一个复杂的问题,依赖于许多因素。
|
||||
如果你正在使用 Docker,迁移到 containerd 应该是一个相对容易地转换,并将获得更好的性能和更少的开销。
|
||||
然而,我们鼓励你探索 [CNCF landscape](https://landscape.cncf.io/card-mode?category=container-runtime&grouping=category)
|
||||
提供的所有选项,做出更适合你的选择。
|
||||
|
||||
<!--
|
||||
### What should I look out for when changing CRI implementations?
|
||||
-->
|
||||
### 当切换 CRI 实现时,应该注意什么?
|
||||
|
||||
<!--
|
||||
While the underlying containerization code is the same between Docker and most
|
||||
CRIs (including containerd), there are a few differences around the edges. Some
|
||||
common things to consider when migrating are:
|
||||
-->
|
||||
虽然 Docker 和大多数 CRI(包括 containerd)之间的底层容器化代码是相同的,
|
||||
但其周边部分却存在差异。迁移时要考虑如下常见事项:
|
||||
|
||||
<!--
|
||||
- Logging configuration
|
||||
- Runtime resource limitations
|
||||
- Node provisioning scripts that call docker or use docker via it's control socket
|
||||
- Kubectl plugins that require docker CLI or the control socket
|
||||
- Tools from the Kubernetes project that require direct access to Docker Engine
|
||||
(for example: the deprecated `kube-imagepuller` tool)
|
||||
- Configuration of functionality like `registry-mirrors` and insecure registries
|
||||
- Other support scripts or daemons that expect Docker Engine to be available and are run
|
||||
outside of Kubernetes (for example, monitoring or security agents)
|
||||
- GPUs or special hardware and how they integrate with your runtime and Kubernetes
|
||||
-->
|
||||
- 日志配置
|
||||
- 运行时的资源限制
|
||||
- 调用 docker 或通过其控制套接字使用 docker 的节点配置脚本
|
||||
- 需要访问 docker 命令或控制套接字的 kubectl 插件
|
||||
- 需要直接访问 Docker Engine 的 Kubernetes 工具(例如:已弃用的 'kube-imagepuller' 工具)
|
||||
- `registry-mirrors` 和不安全注册表等功能的配置
|
||||
- 保障 Docker Engine 可用、且运行在 Kubernetes 之外的脚本或守护进程(例如:监视或安全代理)
|
||||
- GPU 或特殊硬件,以及它们如何与你的运行时和 Kubernetes 集成
|
||||
|
||||
<!--
|
||||
If you use Kubernetes resource requests/limits or file-based log collection
|
||||
DaemonSets then they will continue to work the same, but if you’ve customized
|
||||
your `dockerd` configuration, you’ll need to adapt that for your new container
|
||||
runtime where possible.
|
||||
-->
|
||||
如果你只是用了 Kubernetes 资源请求/限制或基于文件的日志收集 DaemonSet,它们将继续稳定工作,
|
||||
但是如果你用了自定义了 dockerd 配置,则可能需要为新的容器运行时做一些适配工作。
|
||||
|
||||
<!--
|
||||
Another thing to look out for is anything expecting to run for system maintenance
|
||||
or nested inside a container when building images will no longer work. For the
|
||||
former, you can use the [`crictl`][cr] tool as a drop-in replacement (see [mapping from docker cli to crictl](https://kubernetes.io/docs/tasks/debug-application-cluster/crictl/#mapping-from-docker-cli-to-crictl)) and for the
|
||||
latter you can use newer container build options like [img], [buildah],
|
||||
[kaniko], or [buildkit-cli-for-kubectl] that don’t require Docker.
|
||||
-->
|
||||
另外还有一个需要关注的点,那就是当创建镜像时,系统维护或嵌入容器方面的任务将无法工作。
|
||||
对于前者,可以用 [`crictl`](https://github.com/kubernetes-sigs/cri-tools) 工具作为临时替代方案
|
||||
(参阅[从 docker cli 到 crictl 的映射](/zh/docs/tasks/debug-application-cluster/crictl/#mapping-from-docker-cli-to-crictl))。
|
||||
对于后者,可以用新的容器创建选项,例如
|
||||
[img](https://github.com/genuinetools/img)、
|
||||
[buildah](https://github.com/containers/buildah)、
|
||||
[kaniko](https://github.com/GoogleContainerTools/kaniko) 或
|
||||
[buildkit-cli-for-kubectl](https://github.com/vmware-tanzu/buildkit-cli-for-kubectl),
|
||||
他们都不需要 Docker。
|
||||
|
||||
<!--
|
||||
For containerd, you can start with their [documentation] to see what configuration
|
||||
options are available as you migrate things over.
|
||||
-->
|
||||
对于 containerd,你可查阅有关它的[文档](https://github.com/containerd/cri/blob/master/docs/registry.md),
|
||||
获取迁移时可用的配置选项。
|
||||
|
||||
<!--
|
||||
For instructions on how to use containerd and CRI-O with Kubernetes, see the
|
||||
Kubernetes documentation on [Container Runtimes]
|
||||
-->
|
||||
有关如何在 Kubernetes 中使用 containerd 和 CRI-O 的说明,
|
||||
请参阅 [Kubernetes 相关文档](/docs/setup/production-environment/container-runtimes/)
|
||||
|
||||
<!--
|
||||
### What if I have more questions?
|
||||
-->
|
||||
### 我还有其他问题怎么办?
|
||||
|
||||
<!--
|
||||
If you use a vendor-supported Kubernetes distribution, you can ask them about
|
||||
upgrade plans for their products. For end-user questions, please post them
|
||||
to our end user community forum: https://discuss.kubernetes.io/.
|
||||
-->
|
||||
如果你使用了供应商支持的 Kubernetes 发行版,你可以咨询供应商他们产品的升级计划。
|
||||
对于最终用户的问题,请把问题发到我们的最终用户社区的论坛:https://discuss.kubernetes.io/。
|
||||
|
||||
<!--
|
||||
You can also check out the excellent blog post
|
||||
[Wait, Docker is deprecated in Kubernetes now?][dep] a more in-depth technical
|
||||
discussion of the changes.
|
||||
-->
|
||||
你也可以看看这篇优秀的博客文章:[等等,Docker 被 Kubernetes 弃用了?](https://dev.to/inductor/wait-docker-is-deprecated-in-kubernetes-now-what-do-i-do-e4m)
|
||||
对这些变化进行更深入的技术讨论。
|
||||
|
||||
<!--
|
||||
### Can I have a hug?
|
||||
-->
|
||||
### 我可以加入吗?
|
||||
|
||||
<!--
|
||||
Yes, we're still giving hugs as requested. 🤗🤗🤗
|
||||
-->
|
||||
当然,只要你愿意,随时随地欢迎。🤗🤗🤗
|
||||
@@ -31,7 +31,6 @@ Add-ons 扩展了 Kubernetes 的功能。
|
||||
* [Canal](https://github.com/tigera/canal/tree/master/k8s-install) unites Flannel and Calico, providing networking and network policy.
|
||||
* [Cilium](https://github.com/cilium/cilium) is a L3 network and network policy plugin that can enforce HTTP/API/L7 policies transparently. Both routing and overlay/encapsulation mode are supported.
|
||||
* [CNI-Genie](https://github.com/Huawei-PaaS/CNI-Genie) enables Kubernetes to seamlessly connect to a choice of CNI plugins, such as Calico, Canal, Flannel, Romana, or Weave.
|
||||
* [Contiv](http://contiv.github.io) provides configurable networking (native L3 using BGP, overlay using vxlan, classic L2, and Cisco-SDN/ACI) for various use cases and a rich policy framework. Contiv project is fully [open sourced](http://github.com/contiv). The [installer](http://github.com/contiv/install) provides both kubeadm and non-kubeadm based installation options.
|
||||
* [Contrail](http://www.juniper.net/us/en/products-services/sdn/contrail/contrail-networking/), based on [Tungsten Fabric](https://tungsten.io), is an open source, multi-cloud network virtualization and policy management platform. Contrail and Tungsten Fabric are integrated with orchestration systems such as Kubernetes, OpenShift, OpenStack and Mesos, and provide isolation modes for virtual machines, containers/pods and bare metal workloads.
|
||||
* [Flannel](https://github.com/flannel-io/flannel#deploying-flannel-manually) is an overlay network provider that can be used with Kubernetes.
|
||||
* [Knitter](https://github.com/ZTE/Knitter/) is a network solution supporting multiple networking in Kubernetes.
|
||||
@@ -55,9 +54,6 @@ Add-ons 扩展了 Kubernetes 的功能。
|
||||
同时支持路由(routing)和覆盖/封装(overlay/encapsulation)模式。
|
||||
* [CNI-Genie](https://github.com/Huawei-PaaS/CNI-Genie) 使 Kubernetes 无缝连接到一种 CNI 插件,
|
||||
例如:Flannel、Calico、Canal、Romana 或者 Weave。
|
||||
* [Contiv](https://contiv.github.io) 为多种用例提供可配置网络(使用 BGP 的原生 L3,使用 vxlan 的覆盖网络,
|
||||
经典 L2 和 Cisco-SDN/ACI)和丰富的策略框架。Contiv 项目完全[开源](https://github.com/contiv)。
|
||||
[安装工具](https://github.com/contiv/install)同时提供基于和不基于 kubeadm 的安装选项。
|
||||
* 基于 [Tungsten Fabric](https://tungsten.io) 的
|
||||
[Contrail](https://www.juniper.net/us/en/products-services/sdn/contrail/contrail-networking/)
|
||||
是一个开源的多云网络虚拟化和策略管理平台,Contrail 和 Tungsten Fabric 与业务流程系统
|
||||
|
||||
@@ -236,10 +236,10 @@ persistentvolumeclaim/my-pvc created
|
||||
```
|
||||
|
||||
<!--
|
||||
If you're interested in learning more about `kubectl`, go ahead and read [kubectl Overview](/docs/reference/kubectl/overview/).
|
||||
If you're interested in learning more about `kubectl`, go ahead and read [Command line tool (kubectl)](/docs/reference/kubectl/).
|
||||
-->
|
||||
如果你有兴趣进一步学习关于 `kubectl` 的内容,请阅读
|
||||
[kubectl 概述](/zh/docs/reference/kubectl/overview/)。
|
||||
[命令行工具(kubectl)](/zh/docs/reference/kubectl/)。
|
||||
|
||||
<!--
|
||||
## Using labels effectively
|
||||
|
||||
@@ -1,43 +1,47 @@
|
||||
---
|
||||
title: 为容器管理资源
|
||||
title: 为 Pod 和容器管理资源
|
||||
content_type: concept
|
||||
weight: 40
|
||||
feature:
|
||||
title: 自动装箱
|
||||
description: >
|
||||
根据资源需求和其他约束自动放置容器,同时避免影响可用性。将关键性工作负载和尽力而为性质的服务工作负载进行混合放置,以提高资源利用率并节省更多资源。
|
||||
根据资源需求和其他约束自动放置容器,同时避免影响可用性。
|
||||
将关键性的和尽力而为性质的工作负载进行混合放置,以提高资源利用率并节省更多资源。
|
||||
---
|
||||
|
||||
<!--
|
||||
title: Managing Resources for Containers
|
||||
title: Resource Management for Pods and Containers
|
||||
content_type: concept
|
||||
weight: 40
|
||||
feature:
|
||||
title: Automatic binpacking
|
||||
description: >
|
||||
Automatically places containers based on their resource requirements and other constraints, while not sacrificing availability. Mix critical and best-effort workloads in order to drive up utilization and save even more resources.
|
||||
Automatically places containers based on their resource requirements and other constraints, while not sacrificing availability.
|
||||
Mix critical and best-effort workloads in order to drive up utilization and save even more resources.
|
||||
-->
|
||||
|
||||
<!-- overview -->
|
||||
|
||||
<!--
|
||||
When you specify a {{< glossary_tooltip term_id="pod" >}}, you can optionally specify how
|
||||
much of each resource a {{< glossary_tooltip text="Container" term_id="container" >}} needs.
|
||||
much of each resource a {{< glossary_tooltip text="container" term_id="container" >}} needs.
|
||||
The most common resources to specify are CPU and memory (RAM); there are others.
|
||||
|
||||
When you specify the resource _request_ for Containers in a Pod, the scheduler uses this
|
||||
When you specify the resource _request_ for Containers in a Pod, the
|
||||
{{< glossary_tooltip text="kube-scheduler" term_id="kube-scheduler" >}} uses this
|
||||
information to decide which node to place the Pod on. When you specify a resource _limit_
|
||||
for a Container, the kubelet enforces those limits so that the running container is not
|
||||
allowed to use more of that resource than the limit you set. The kubelet also reserves
|
||||
at least the _request_ amount of that system resource specifically for that container
|
||||
to use.
|
||||
-->
|
||||
|
||||
当你定义 {{< glossary_tooltip text="Pod" term_id="pod" >}} 时可以选择性地为每个
|
||||
{{< glossary_tooltip text="容器" term_id="container" >}}设定所需要的资源数量。
|
||||
最常见的可设定资源是 CPU 和内存(RAM)大小;此外还有其他类型的资源。
|
||||
|
||||
当你为 Pod 中的 Container 指定了资源 __请求__ 时,调度器就利用该信息决定将 Pod 调度到哪个节点上。
|
||||
当你为 Pod 中的 Container 指定了资源 __请求__ 时,
|
||||
{{< glossary_tooltip text="kube-scheduler" term_id="kube-scheduler" >}}
|
||||
就利用该信息决定将 Pod 调度到哪个节点上。
|
||||
当你还为 Container 指定了资源 __约束__ 时,kubelet 就可以确保运行的容器不会使用超出所设约束的资源。
|
||||
kubelet 还会为容器预留所 __请求__ 数量的系统资源,供其使用。
|
||||
|
||||
@@ -65,7 +69,7 @@ more RAM.
|
||||
运行,那么该容器就可以尝试使用更多的内存。
|
||||
|
||||
<!--
|
||||
If you set a `memory` limit of 4GiB for that Container, the kubelet (and
|
||||
If you set a `memory` limit of 4GiB for that container, the kubelet (and
|
||||
{{< glossary_tooltip text="container runtime" term_id="container-runtime" >}}) enforce the limit.
|
||||
The runtime prevents the container from using more than the configured resource limit. For example:
|
||||
when a process in the container tries to consume more than the allowed amount of memory,
|
||||
@@ -88,15 +92,15 @@ runtimes can have different ways to implement the same restrictions.
|
||||
|
||||
{{< note >}}
|
||||
<!--
|
||||
If a Container specifies its own memory limit, but does not specify a memory request, Kubernetes
|
||||
automatically assigns a memory request that matches the limit. Similarly, if a Container specifies its own
|
||||
If a container specifies its own memory limit, but does not specify a memory request, Kubernetes
|
||||
automatically assigns a memory request that matches the limit. Similarly, if a container specifies its own
|
||||
CPU limit, but does not specify a CPU request, Kubernetes automatically assigns a CPU request that matches
|
||||
the limit.
|
||||
-->
|
||||
如果某 Container 设置了自己的内存限制但未设置内存请求,Kubernetes
|
||||
如果某容器设置了自己的内存限制但未设置内存请求,Kubernetes
|
||||
自动为其设置与内存限制相匹配的请求值。类似的,如果某 Container 设置了
|
||||
CPU 限制值但未设置 CPU 请求值,则 Kubernetes 自动为其设置 CPU 请求
|
||||
并使之与 CPU 限制值匹配。
|
||||
CPU 限制值但未设置 CPU 请求值,则 Kubernetes 自动为其设置 CPU
|
||||
请求并使之与 CPU 限制值匹配。
|
||||
{{< /note >}}
|
||||
|
||||
<!--
|
||||
@@ -105,7 +109,7 @@ CPU 限制值但未设置 CPU 请求值,则 Kubernetes 自动为其设置 CPU
|
||||
*CPU* and *memory* are each a *resource type*. A resource type has a base unit.
|
||||
CPU represents compute processing and is specified in units of [Kubernetes CPUs](#meaning-of-cpu).
|
||||
Memory is specified in units of bytes.
|
||||
If you're using Kubernetes v1.14 or newer, you can specify _huge page_ resources.
|
||||
For Linux workloads, you can specify _huge page_ resources.
|
||||
Huge pages are a Linux-specific feature where the node kernel allocates blocks of memory
|
||||
that are much larger than the default page size.
|
||||
|
||||
@@ -118,7 +122,7 @@ total of 80 MiB), that allocation fails.
|
||||
*CPU* 和 *内存* 都是 *资源类型*。每种资源类型具有其基本单位。
|
||||
CPU 表达的是计算处理能力,其单位是 [Kubernetes CPUs](#meaning-of-cpu)。
|
||||
内存的单位是字节。
|
||||
如果你使用的是 Kubernetes v1.14 或更高版本,则可以指定巨页(Huge Page)资源。
|
||||
对于 Linux 负载,则可以指定巨页(Huge Page)资源。
|
||||
巨页是 Linux 特有的功能,节点内核在其中分配的内存块比默认页大小大得多。
|
||||
|
||||
例如,在默认页面大小为 4KiB 的系统上,你可以指定约束 `hugepages-2Mi: 80Mi`。
|
||||
@@ -141,16 +145,21 @@ consumed. They are distinct from
|
||||
[Services](/docs/concepts/services-networking/service/) are objects that can be read and modified
|
||||
through the Kubernetes API server.
|
||||
-->
|
||||
CPU 和内存统称为*计算资源*,或简称为*资源*。
|
||||
CPU 和内存统称为“计算资源”,或简称为“资源”。
|
||||
计算资源的数量是可测量的,可以被请求、被分配、被消耗。
|
||||
它们与 [API 资源](/zh/docs/concepts/overview/kubernetes-api/) 不同。
|
||||
API 资源(如 Pod 和 [Service](/zh/docs/concepts/services-networking/service/))是可通过
|
||||
Kubernetes API 服务器读取和修改的对象。
|
||||
|
||||
<!--
|
||||
## Resource requests and limits of Pod and Container
|
||||
## Resource requests and limits of Pod and container
|
||||
|
||||
Each Container of a Pod can specify one or more of the following:
|
||||
For each container, you can specify resource limits and requests,
|
||||
including the following:
|
||||
-->
|
||||
## Pod 和 容器的资源请求和约束
|
||||
|
||||
针对每个容器,你都可以指定其资源约束和请求,包括如下选项:
|
||||
|
||||
* `spec.containers[].resources.limits.cpu`
|
||||
* `spec.containers[].resources.limits.memory`
|
||||
@@ -159,93 +168,114 @@ Each Container of a Pod can specify one or more of the following:
|
||||
* `spec.containers[].resources.requests.memory`
|
||||
* `spec.containers[].resources.requests.hugepages-<size>`
|
||||
|
||||
Although requests and limits can only be specified on individual Containers, it
|
||||
is convenient to talk about Pod resource requests and limits. A
|
||||
*Pod resource request/limit* for a particular resource type is the sum of the
|
||||
resource requests/limits of that type for each Container in the Pod.
|
||||
<!--
|
||||
Although you can only specify requests and limits for individual containers,
|
||||
it is also useful to think about the overall resource requests and limits for
|
||||
a Pod.
|
||||
A
|
||||
For a particular resource, a *Pod resource request/limit* is the sum of the
|
||||
resource requests/limits of that type for each container in the Pod.
|
||||
-->
|
||||
|
||||
## Pod 和 容器的资源请求和约束
|
||||
|
||||
Pod 中的每个容器都可以指定以下的一个或者多个值:
|
||||
|
||||
- `spec.containers[].resources.limits.cpu`
|
||||
- `spec.containers[].resources.limits.memory`
|
||||
- `spec.containers[].resources.limits.hugepages-<size>`
|
||||
- `spec.containers[].resources.requests.cpu`
|
||||
- `spec.containers[].resources.requests.memory`
|
||||
- `spec.containers[].resources.requests.hugepages-<size>`
|
||||
|
||||
尽管请求和限制值只能在单个容器上指定,我们仍可方便地计算出 Pod 的资源请求和约束。
|
||||
Pod 对特定资源类型的请求/约束值是 Pod 中各容器对该类型资源的请求/约束值的总和。
|
||||
尽管你只能逐个容器地指定请求和限制值,考虑 Pod 的总体资源请求和约束也是有用的。
|
||||
对特定资源而言,Pod 的资源请求/约束值是 Pod 中各容器对该类型资源的请求/约束值的总和。
|
||||
|
||||
<!--
|
||||
## Resource units in Kubernetes
|
||||
|
||||
### Meaning of CPU
|
||||
### CPU resource units {#meaning-of-cpu}
|
||||
|
||||
Limits and requests for CPU resources are measured in *cpu* units.
|
||||
One cpu, in Kubernetes, is equivalent to **1 vCPU/Core** for cloud providers and **1 hyperthread** on bare-metal Intel processors.
|
||||
|
||||
Fractional requests are allowed. A Container with
|
||||
`spec.containers[].resources.requests.cpu` of `0.5` is guaranteed half as much
|
||||
CPU as one that asks for 1 CPU. The expression `0.1` is equivalent to the
|
||||
expression `100m`, which can be read as "one hundred millicpu". Some people say
|
||||
"one hundred millicores", and this is understood to mean the same thing. A
|
||||
request with a decimal point, like `0.1`, is converted to `100m` by the API, and
|
||||
precision finer than `1m` is not allowed. For this reason, the form `100m` might
|
||||
be preferred.
|
||||
CPU is always requested as an absolute quantity, never as a relative quantity;
|
||||
0.1 is the same amount of CPU on a single-core, dual-core, or 48-core machine.
|
||||
In Kubernetes, 1 CPU unit is equivalent to **1 physical CPU core**,
|
||||
or **1 virtual core**, depending on whether the node is a physical host
|
||||
or a virtual machine running inside a physical machine.
|
||||
-->
|
||||
## Kubernetes 中的资源单位 {#resource-units-in-kubernetes}
|
||||
|
||||
### CPU 的含义 {#meaning-of-cpu}
|
||||
### CPU 资源单位 {#meaning-of-cpu}
|
||||
|
||||
CPU 资源的约束和请求以 *CPU* 为单位。
|
||||
|
||||
Kubernetes 中的一个 CPU 等于云平台上的 **1 个 vCPU/核**和裸机 Intel
|
||||
处理器上的 **1 个超线程**。
|
||||
|
||||
你也可以表达带小数 CPU 的请求。`spec.containers[].resources.requests.cpu` 为 0.5
|
||||
的 Container 肯定能够获得请求 1 CPU 的容器的一半 CPU 资源。表达式 `0.1` 等价于表达式 `100m`,
|
||||
可以看作 “100 millicpu”。有些人说成是“一百毫 cpu”,其实说的是同样的事情。
|
||||
具有小数点(如 `0.1`)的请求由 API 转换为 `100m`;最大精度是 `1m`。
|
||||
因此,或许你应该优先考虑使用 `100m` 的形式。
|
||||
|
||||
CPU 总是按绝对数量来请求的,不可以使用相对数量;
|
||||
0.1 的 CPU 在单核、双核、48 核的机器上的意义是一样的。
|
||||
CPU 资源的约束和请求以 “cpu” 为单位。
|
||||
在 Kubernetes 中,一个 CPU 等于**1 个物理 CPU 核** 或者 **一个虚拟核**,
|
||||
取决于节点是一台物理主机还是运行在某物理主机上的虚拟机。
|
||||
|
||||
<!--
|
||||
## Meaning of memory
|
||||
Fractional requests are allowed. When you define a container with
|
||||
`spec.containers[].resources.requests.cpu` set to `0.5`, you are requesting half
|
||||
as much CPU time compared to if you asked for `1.0` CPU.
|
||||
For CPU resource units, the [quantity](/docs/reference/kubernetes-api/common-definitions/quantity/) expression `0.1` is equivalent to the
|
||||
expression `100m`, which can be read as "one hundred millicpu". Some people say
|
||||
"one hundred millicores", and this is understood to mean the same thing.
|
||||
-->
|
||||
你也可以表达带小数 CPU 的请求。
|
||||
当你定义一个容器,将其 `spec.containers[].resources.requests.cpu` 设置为 0.5 时,
|
||||
你所请求的 CPU 是你请求 `1.0` CPU 时的一半。
|
||||
对于 CPU 资源单位,[数量](/docs/reference/kubernetes-api/common-definitions/quantity/)
|
||||
表达式 `0.1` 等价于表达式 `100m`,可以看作 “100 millicpu”。
|
||||
有些人说成是“一百毫核”,其实说的是同样的事情。
|
||||
|
||||
<!--
|
||||
CPU resource is always specified as an absolute amount of resource, never as a relative amount. For example,
|
||||
`500m` CPU represents the roughly same amount of computing power whether that container
|
||||
runs on a single-core, dual-core, or 48-core machine.
|
||||
-->
|
||||
CPU 资源总是设置为资源的绝对数量而非相对数量值。
|
||||
例如,无论容器运行在单核、双核或者 48-核的机器上,`500m` CPU 表示的是大约相同的计算能力。
|
||||
|
||||
{{< note >}}
|
||||
<!--
|
||||
Kubernetes doesn't allow you to specify CPU resources with a precision finer than
|
||||
`1m`. Because of this, it's useful to specify CPU units less than `1.0` or `1000m` using
|
||||
the milliCPU form; for example, `5m` rather than `0.005`.
|
||||
-->
|
||||
Kubernetes 不允许设置精度小于 `1m` 的 CPU 资源。
|
||||
因此,当 CPU 单位小于 `1` 或 `1000m` 时,使用毫核的形式是有用的;
|
||||
例如 `5m` 而不是 `0.005`。
|
||||
{{< /note >}}
|
||||
|
||||
<!--
|
||||
### Memory resource units {#meaning-of-memory}
|
||||
|
||||
Limits and requests for `memory` are measured in bytes. You can express memory as
|
||||
a plain integer or as a fixed-point number using one of these suffixes:
|
||||
a plain integer or as a fixed-point number using one of these
|
||||
[quantity](/docs/reference/kubernetes-api/common-definitions/quantity/) suffixes:
|
||||
E, P, T, G, M, K. You can also use the power-of-two equivalents: Ei, Pi, Ti, Gi,
|
||||
Mi, Ki. For example, the following represent roughly the same value:
|
||||
-->
|
||||
## 内存的含义 {#meaning-of-memory}
|
||||
## 内存资源单位 {#meaning-of-memory}
|
||||
|
||||
内存的约束和请求以字节为单位。你可以使用以下后缀之一以一般整数或定点数字形式来表示内存:
|
||||
E、P、T、G、M、k。你也可以使用对应的 2 的幂数:Ei、Pi、Ti、Gi、Mi、Ki。
|
||||
`memory` 的约束和请求以字节为单位。
|
||||
你可以使用普通的证书,或者带有以下
|
||||
[数量](/docs/reference/kubernetes-api/common-definitions/quantity/)后缀
|
||||
的定点数字来表示内存:E、P、T、G、M、k。
|
||||
你也可以使用对应的 2 的幂数:Ei、Pi、Ti、Gi、Mi、Ki。
|
||||
例如,以下表达式所代表的是大致相同的值:
|
||||
|
||||
```
|
||||
128974848、129e6、129M、123Mi
|
||||
128974848、129e6、129M、128974848000m、123Mi
|
||||
```
|
||||
|
||||
<!--
|
||||
Here's an example.
|
||||
The following Pod has two Containers. Each Container has a request of 0.25 cpu
|
||||
and 64MiB (2<sup>26</sup> bytes) of memory. Each Container has a limit of 0.5
|
||||
cpu and 128MiB of memory. You can say the Pod has a request of 0.5 cpu and 128
|
||||
MiB of memory, and a limit of 1 cpu and 256MiB of memory.
|
||||
Take care about case for suffixes. If you request `400m` of memory, this is a request
|
||||
for 0.4 bytes. Someone who types that probably meant to ask for 400 mebibytes (`400Mi`)
|
||||
or 400 megabytes (`400M`).
|
||||
-->
|
||||
下面是个例子。
|
||||
请注意后缀的大小写。如果你请求 `400m` 内存,实际上请求的是 0.4 字节。
|
||||
如果有人这样设定资源请求或限制,可能他的实际想法是申请 400 兆字节(`400Mi`)
|
||||
或者 400M 字节。
|
||||
|
||||
以下 Pod 有两个 Container。每个 Container 的请求为 0.25 cpu 和 64MiB(2<sup>26</sup> 字节)内存,
|
||||
每个容器的资源约束为 0.5 cpu 和 128MiB 内存。
|
||||
你可以认为该 Pod 的资源请求为 0.5 cpu 和 128 MiB 内存,资源限制为 1 cpu 和 256MiB 内存。
|
||||
<!--
|
||||
## Container resources example {#example-1}
|
||||
|
||||
The following Pod has two containers. Both containers are defined with a request for
|
||||
0.25 CPU
|
||||
and 64MiB (2<sup>26</sup> bytes) of memory. Each container has a limit of 0.5
|
||||
CPU and 128MiB of memory. You can say the Pod has a request of 0.5 CPU and 128
|
||||
MiB of memory, and a limit of 1 CPU and 256MiB of memory.
|
||||
-->
|
||||
## 容器资源示例 {#example-1}
|
||||
|
||||
以下 Pod 有两个容器。每个容器的请求为 0.25 CPU 和 64MiB(2<sup>26</sup> 字节)内存,
|
||||
每个容器的资源约束为 0.5 CPU 和 128MiB 内存。
|
||||
你可以认为该 Pod 的资源请求为 0.5 CPU 和 128 MiB 内存,资源限制为 1 CPU 和 256MiB 内存。
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
@@ -256,9 +286,6 @@ spec:
|
||||
containers:
|
||||
- name: app
|
||||
image: images.my-company.example/app:v4
|
||||
env:
|
||||
- name: MYSQL_ROOT_PASSWORD
|
||||
value: "password"
|
||||
resources:
|
||||
requests:
|
||||
memory: "64Mi"
|
||||
@@ -284,7 +311,8 @@ When you create a Pod, the Kubernetes scheduler selects a node for the Pod to
|
||||
run on. Each node has a maximum capacity for each of the resource types: the
|
||||
amount of CPU and memory it can provide for Pods. The scheduler ensures that,
|
||||
for each resource type, the sum of the resource requests of the scheduled
|
||||
Containers is less than the capacity of the node. Note that although actual memory
|
||||
containers is less than the capacity of the node.
|
||||
Note that although actual memory
|
||||
or CPU resource usage on nodes is very low, the scheduler still refuses to place
|
||||
a Pod on a node if the capacity check fails. This protects against a resource
|
||||
shortage on a node when resource usage later increases, for example, during a
|
||||
@@ -300,84 +328,88 @@ daily peak in request rate.
|
||||
当稍后节点上资源用量增加,例如到达请求率的每日峰值区间时,节点上也不会出现资源不足的问题。
|
||||
|
||||
<!--
|
||||
## How Pods with resource limits are run
|
||||
## How Kubernetes applies resource requests and limits {#how-pods-with-resource-limits-are-run}
|
||||
|
||||
When the kubelet starts a Container of a Pod, it passes the CPU and memory limits
|
||||
to the container runtime.
|
||||
When the kubelet starts a container of a Pod, the kubelet passes that container's
|
||||
requests and limits for memory and CPU to the container runtime.
|
||||
|
||||
When using Docker:
|
||||
On Linux, the container runtime typically configures
|
||||
kernel {{< glossary_tooltip text="cgroups" term_id="cgroup" >}} that apply and enforce the
|
||||
limits you defined.
|
||||
-->
|
||||
## 带资源约束的 Pod 如何运行
|
||||
## Kubernetes 应用资源请求与约束的方式 {#how-pods-with-resource-limits-are-run}
|
||||
|
||||
当 kubelet 启动 Pod 中的 Container 时,它会将 CPU 和内存约束信息传递给容器运行时。
|
||||
当 kubelet 启动 Pod 中的容器时,它会将容器的 CPU 和内存请求与约束信息传递给容器运行时。
|
||||
|
||||
当使用 Docker 时:
|
||||
在 Linux 系统上,容器运行时通常会配置内核
|
||||
{{< glossary_tooltip text="CGroups" term_id="cgroup" >}},负责应用并实施所定义的请求。
|
||||
|
||||
<!--
|
||||
- The `spec.containers[].resources.requests.cpu` is converted to its core value,
|
||||
which is potentially fractional, and multiplied by 1024. The greater of this number
|
||||
or 2 is used as the value of the
|
||||
[`--cpu-shares`](https://docs.docker.com/engine/reference/run/#cpu-share-constraint)
|
||||
flag in the `docker run` command.
|
||||
|
||||
- The `spec.containers[].resources.limits.cpu` is converted to its millicore value and
|
||||
multiplied by 100. The resulting value is the total amount of CPU time in microseconds
|
||||
that a container can use every 100ms. A container cannot use more than its share of
|
||||
CPU time during this interval.
|
||||
|
||||
The default quota period is 100ms. The minimum resolution of CPU quota is 1ms.
|
||||
|
||||
- The `spec.containers[].resources.limits.memory` is converted to an integer, and
|
||||
used as the value of the
|
||||
[`--memory`](https://docs.docker.com/engine/reference/run/#/user-memory-constraints)
|
||||
flag in the `docker run` command.
|
||||
- The CPU limit defines a hard ceiling on how much CPU time that the container can use.
|
||||
During each scheduling interval (time slice), the Linux kernel checks to see if this
|
||||
limit is exceeded; if so, the kernel waits before allowing that cgroup to resume execution.
|
||||
-->
|
||||
|
||||
- `spec.containers[].resources.requests.cpu` 先被转换为可能是小数的基础值,再乘以 1024。
|
||||
这个数值和 2 的较大者用作 `docker run` 命令中的
|
||||
[`--cpu-shares`](https://docs.docker.com/engine/reference/run/#/cpu-share-constraint)
|
||||
标志的值。
|
||||
- `spec.containers[].resources.limits.cpu` 先被转换为 millicore 值,再乘以 100。
|
||||
其结果就是每 100 毫秒内容器可以使用的 CPU 时间总量,单位为微秒。在此期间(100ms),
|
||||
容器所使用的 CPU 时间不可以超过它被分配的时间。
|
||||
|
||||
{{< note >}}
|
||||
默认的配额(Quota)周期为 100 毫秒。CPU 配额的最小精度为 1 毫秒。
|
||||
{{</ note >}}
|
||||
|
||||
- `spec.containers[].resources.limits.memory` 被转换为整数值,作为 `docker run` 命令中的
|
||||
[`--memory`](https://docs.docker.com/engine/reference/run/#/user-memory-constraints)
|
||||
参数值。
|
||||
- CPU 约束值定义的是容器可使用的 CPU 时间的硬性上限。
|
||||
在每个调度周期(时间片)期间,Linux 内核检查是否已经超出该约束值;
|
||||
内核会在允许该 cgroup 恢复执行之前会等待。
|
||||
<!--
|
||||
- The CPU request typically defines a weighting. If several different containers (cgroups)
|
||||
want to run on a contended system, workloads with larger CPU requests are allocated more
|
||||
CPU time than workloads with small requests.
|
||||
-->
|
||||
- CPU 请求值定义的是一个权重值。如果若干不同的容器(CGroups)需要在一个共享的系统上竞争运行,
|
||||
CPU 请求值大的负载会获得比请求值小的负载更多的 CPU 时间。
|
||||
<!--
|
||||
- The memory request is mainly used during (Kubernetes) Pod scheduling. On a node that uses
|
||||
cgroups v2, the container runtime might use the memory request as a hint to set
|
||||
`memory.min` and `memory.low`.
|
||||
-->
|
||||
- 内存请求值主要用于(Kubernetes)Pod 调度期间。在一个启用了 CGroup v2 的节点上,
|
||||
容器运行时可能会使用内存请求值作为设置 `memory.min` 和 `memory.low` 的提示值。
|
||||
<!--
|
||||
- The memory limit defines a memory limit for that cgroup. If the container tries to
|
||||
allocate more memory than this limit, the Linux kernel out-of-memory subsystem activates
|
||||
and, typically, intervenes by stopping one of the processes in the container that tried
|
||||
to allocate memory. If that process is the container's PID 1, and the container is marked
|
||||
as restartable, Kubernetes restarts the container.
|
||||
-->
|
||||
- 内存约束值定义的是 CGroup 的内存约束。如果容器尝试分配的内存量超出约束值,
|
||||
则 Linux 内核的内存不足处理子系统会被激活,并停止尝试分配内存的容器中的某个进程。
|
||||
如果该进程在容器中 PID 为 1,而容器被标记为可重新启动,则 Kubernetes
|
||||
会重新启动该容器。
|
||||
<!--
|
||||
- The memory limit for the Pod or container can also apply to pages in memory backed
|
||||
volumes, such as an `emptyDir`. The kubelet tracks `tmpfs` emptyDir volumes as container
|
||||
memory use, rather than as local ephemeral storage.
|
||||
-->
|
||||
- Pod 或容器的内存约束值也适用于通过内存供应的卷,例如 `emptyDir` 卷。
|
||||
kubelet 会跟踪 `tmpfs` 形式的 emptyDir 卷用量,将其作为容器的内存用量,
|
||||
而不是临时存储用量。
|
||||
|
||||
<!--
|
||||
If a Container exceeds its memory limit, it might be terminated. If it is
|
||||
restartable, the kubelet will restart it, as with any other type of runtime
|
||||
failure.
|
||||
If a container exceeds its memory request, and the node that it runs on becomes short of
|
||||
memory overall, it is likely that the Pod the container belongs to will be
|
||||
{{< glossary_tooltip text="evicted" term_id="eviction" >}}.
|
||||
|
||||
If a Container exceeds its memory request, it is likely that its Pod will
|
||||
be evicted whenever the node runs out of memory.
|
||||
A container might or might not be allowed to exceed its CPU limit for extended periods of time.
|
||||
However, container runtimes don't terminate Pods or containers for excessive CPU usage.
|
||||
|
||||
A Container might or might not be allowed to exceed its CPU limit for extended
|
||||
periods of time. However, it will not be killed for excessive CPU usage.
|
||||
|
||||
To determine whether a Container cannot be scheduled or is being killed due to
|
||||
resource limits, see the
|
||||
[Troubleshooting](#troubleshooting) section.
|
||||
To determine whether a container cannot be scheduled or is being killed due to resource limits,
|
||||
see the [Troubleshooting](#troubleshooting) section.
|
||||
-->
|
||||
如果 Container 超过其内存限制,则可能会被终止。如果容器可重新启动,则与所有其他类型的
|
||||
运行时失效一样,kubelet 将重新启动容器。
|
||||
如果某容器内存用量超过其内存请求值并且所在节点内存不足时,容器所处的 Pod
|
||||
可能被{{< glossary_tooltip text="逐出" term_id="eviction" >}}.
|
||||
|
||||
如果一个 Container 内存用量超过其内存请求值,那么当节点内存不足时,容器所处的 Pod 可能被逐出。
|
||||
每个容器可能被允许也可能不被允许使用超过其 CPU 约束的处理时间。
|
||||
但是,容器运行时不会由于 CPU 使用率过高而杀死 Pod 或容器。
|
||||
|
||||
每个 Container 可能被允许也可能不被允许使用超过其 CPU 约束的处理时间。
|
||||
但是,容器不会由于 CPU 使用率过高而被杀死。
|
||||
|
||||
要确定 Container 是否会由于资源约束而无法调度或被杀死,请参阅[疑难解答](#troubleshooting) 部分。
|
||||
要确定某容器是否会由于资源约束而无法调度或被杀死,请参阅[疑难解答](#troubleshooting)节。
|
||||
|
||||
<!--
|
||||
## Monitoring compute & memory resource usage
|
||||
|
||||
The resource usage of a Pod is reported as part of the Pod status.
|
||||
The kubelet reports the resource usage of a Pod as part of the Pod
|
||||
[`status`](/docs/concepts/overview/working-with-objects/kubernetes-objects/#object-spec-and-status).
|
||||
|
||||
If optional [tools for monitoring](/docs/tasks/debug-application-cluster/resource-usage-monitoring/)
|
||||
are available in your cluster, then Pod resource usage can be retrieved either
|
||||
@@ -386,12 +418,12 @@ directly or from your monitoring tools.
|
||||
-->
|
||||
## 监控计算和内存资源用量
|
||||
|
||||
Pod 的资源使用情况是作为 Pod 状态的一部分来报告的。
|
||||
kubelet 会将 Pod 的资源使用情况作为 Pod
|
||||
[`status`](/zh/docs/concepts/overview/working-with-objects/kubernetes-objects/#object-spec-and-status)
|
||||
的一部分来报告的。
|
||||
|
||||
如果为集群配置了可选的
|
||||
[监控工具](/zh/docs/tasks/debug-application-cluster/resource-usage-monitoring/),
|
||||
则可以直接从
|
||||
[指标 API](/zh/docs/tasks/debug-application-cluster/resource-metrics-pipeline/#the-metrics-api)
|
||||
如果为集群配置了可选的[监控工具](/zh/docs/tasks/debug-application-cluster/resource-usage-monitoring/),
|
||||
则可以直接从[指标 API](/zh/docs/tasks/debug-application-cluster/resource-metrics-pipeline/#the-metrics-api)
|
||||
或者监控工具获得 Pod 的资源使用情况。
|
||||
|
||||
<!--
|
||||
@@ -409,6 +441,7 @@ mount [`emptyDir`](https://kubernetes.io/docs/concepts/storage/volumes/#emptydir
|
||||
## 本地临时存储 {#local-ephemeral-storage}
|
||||
|
||||
<!-- feature gate LocalStorageCapacityIsolation -->
|
||||
|
||||
{{< feature-state for_k8s_version="v1.10" state="beta" >}}
|
||||
|
||||
节点通常还可以具有本地的临时性存储,由本地挂接的可写入设备或者有时也用 RAM
|
||||
@@ -569,43 +602,44 @@ kubelet 会将 `tmpfs` emptyDir 卷的用量当作容器内存用量,而不是
|
||||
<!--
|
||||
### Setting requests and limits for local ephemeral storage
|
||||
|
||||
You can use _ephemeral-storage_ for managing local ephemeral storage. Each Container of a Pod can specify one or more of the following:
|
||||
You can use `ephemeral-storage` for managing local ephemeral storage. Each
|
||||
container of a Pod can specify either or both of the following:
|
||||
|
||||
* `spec.containers[].resources.limits.ephemeral-storage`
|
||||
* `spec.containers[].resources.requests.ephemeral-storage`
|
||||
|
||||
Limits and requests for `ephemeral-storage` are measured in bytes. You can express storage as
|
||||
a plain integer or as a fixed-point number using one of these suffixes:
|
||||
Limits and requests for `ephemeral-storage` are measured in quantities.
|
||||
You can express storage as a plain integer or as a fixed-point number using one of these suffixes:
|
||||
E, P, T, G, M, K. You can also use the power-of-two equivalents: Ei, Pi, Ti, Gi,
|
||||
Mi, Ki. For example, the following represent roughly the same value:
|
||||
|
||||
```shell
|
||||
128974848, 129e6, 129M, 123Mi
|
||||
```
|
||||
-->
|
||||
### 为本地临时性存储设置请求和约束值
|
||||
|
||||
你可以使用 _ephemeral-storage_ 来管理本地临时性存储。
|
||||
Pod 中的每个 Container 可以设置以下属性:
|
||||
你可以使用 `ephemeral-storage` 来管理本地临时性存储。
|
||||
Pod 中的每个容器可以设置以下属性:
|
||||
|
||||
* `spec.containers[].resources.limits.ephemeral-storage`
|
||||
* `spec.containers[].resources.requests.ephemeral-storage`
|
||||
|
||||
`ephemeral-storage` 的请求和约束值是按字节计量的。你可以使用一般整数或者定点数字
|
||||
`ephemeral-storage` 的请求和约束值是按量纲计量的。你可以使用一般整数或者定点数字
|
||||
加上下面的后缀来表达存储量:E、P、T、G、M、K。
|
||||
你也可以使用对应的 2 的幂级数来表达:Ei、Pi、Ti、Gi、Mi、Ki。
|
||||
例如,下面的表达式所表达的大致是同一个值:
|
||||
|
||||
```
|
||||
128974848, 129e6, 129M, 123Mi
|
||||
```
|
||||
- `128974848`
|
||||
- `129e6`
|
||||
- `129M`
|
||||
- `123Mi`
|
||||
|
||||
<!--
|
||||
In the following example, the Pod has two Containers. Each Container has a request of 2GiB of local ephemeral storage. Each Container has a limit of 4GiB of local ephemeral storage. Therefore, the Pod has a request of 4GiB of local ephemeral storage, and a limit of 8GiB of local ephemeral storage.
|
||||
In the following example, the Pod has two containers. Each container has a request of
|
||||
2GiB of local ephemeral storage. Each container has a limit of 4GiB of local ephemeral
|
||||
storage. Therefore, the Pod has a request of 4GiB of local ephemeral storage, and a
|
||||
limit of 8GiB of local ephemeral storage.
|
||||
-->
|
||||
|
||||
在下面的例子中,Pod 包含两个 Container。每个 Container 请求 2 GiB 大小的本地临时性存储。
|
||||
每个 Container 都设置了 4 GiB 作为其本地临时性存储的约束值。
|
||||
在下面的例子中,Pod 包含两个容器。每个容器请求 2 GiB 大小的本地临时性存储。
|
||||
每个容器都设置了 4 GiB 作为其本地临时性存储的约束值。
|
||||
因此,整个 Pod 的本地临时性存储请求是 4 GiB,且其本地临时性存储的约束为 8 GiB。
|
||||
|
||||
```yaml
|
||||
@@ -644,9 +678,11 @@ spec:
|
||||
### How Pods with ephemeral-storage requests are scheduled
|
||||
|
||||
When you create a Pod, the Kubernetes scheduler selects a node for the Pod to
|
||||
run on. Each node has a maximum amount of local ephemeral storage it can provide for Pods. For more information, see [Node Allocatable](/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable).
|
||||
run on. Each node has a maximum amount of local ephemeral storage it can provide for Pods.
|
||||
For more information, see
|
||||
[Node Allocatable](/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable).
|
||||
|
||||
The scheduler ensures that the sum of the resource requests of the scheduled Containers is less than the capacity of the node.
|
||||
The scheduler ensures that the sum of the resource requests of the scheduled containers is less than the capacity of the node.
|
||||
-->
|
||||
|
||||
### 带临时性存储的 Pods 的调度行为
|
||||
@@ -657,7 +693,7 @@ The scheduler ensures that the sum of the resource requests of the scheduled Con
|
||||
[节点可分配资源](/zh/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable)
|
||||
节。
|
||||
|
||||
调度器会确保所调度的 Containers 的资源请求总和不会超出节点的资源容量。
|
||||
调度器会确保所调度的容器的资源请求总和不会超出节点的资源容量。
|
||||
|
||||
<!--
|
||||
### Ephemeral storage consumption management {#resource-emphemeralstorage-consumption}
|
||||
@@ -672,7 +708,7 @@ kubelet measures storage use in:
|
||||
If a Pod is using more ephemeral storage than you allow it to, the kubelet
|
||||
sets an eviction signal that triggers Pod eviction.
|
||||
|
||||
For container-level isolation, if a Container's writable layer and log
|
||||
For container-level isolation, if a container's writable layer and log
|
||||
usage exceeds its storage limit, the kubelet marks the Pod for eviction.
|
||||
|
||||
For pod-level isolation the kubelet works out an overall Pod storage limit by
|
||||
@@ -885,6 +921,7 @@ Extended Resource in Pods.
|
||||
Node-level extended resources are tied to nodes.
|
||||
|
||||
##### Device plugin managed resources
|
||||
|
||||
See [Device
|
||||
Plugin](/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/)
|
||||
for how to advertise device plugin managed resources on each node.
|
||||
@@ -902,15 +939,13 @@ for how to advertise device plugin managed resources on each node.
|
||||
|
||||
<!--
|
||||
##### Other resources
|
||||
|
||||
To advertise a new node-level extended resource, the cluster operator can
|
||||
submit a `PATCH` HTTP request to the API server to specify the available
|
||||
quantity in the `status.capacity` for a node in the cluster. After this
|
||||
operation, the node's `status.capacity` will include a new resource. The
|
||||
`status.allocatable` field is updated automatically with the new resource
|
||||
asynchronously by the kubelet. Note that because the scheduler uses the node
|
||||
`status.allocatable` value when evaluating Pod fitness, there may be a short
|
||||
delay between patching the node capacity with a new resource and the first Pod
|
||||
that requests the resource to be scheduled on that node.
|
||||
asynchronously by the kubelet.
|
||||
-->
|
||||
##### 其他资源 {#other-resources}
|
||||
|
||||
@@ -918,7 +953,16 @@ that requests the resource to be scheduled on that node.
|
||||
以在集群中节点的 `status.capacity` 中为其配置可用数量。
|
||||
完成此操作后,节点的 `status.capacity` 字段中将包含新资源。
|
||||
kubelet 会异步地对 `status.allocatable` 字段执行自动更新操作,使之包含新资源。
|
||||
请注意,由于调度器在评估 Pod 是否适合在某节点上执行时会使用节点的 `status.allocatable` 值,
|
||||
|
||||
<!--
|
||||
Because the scheduler uses the node `status.allocatable` value when
|
||||
evaluating Pod fitness, the shceduler only takes account of the new value after
|
||||
the asynchronous update. There may be a short delay between patching the
|
||||
node capacity with a new resource and the time when the first Pod that requests
|
||||
the resource to be scheduled on that node.
|
||||
-->
|
||||
由于调度器在评估 Pod 是否适合在某节点上执行时会使用节点的 `status.allocatable` 值,
|
||||
调度器只会考虑异步更新之后的新值。
|
||||
在更新节点容量使之包含新资源之后和请求该资源的第一个 Pod 被调度到该节点之间,
|
||||
可能会有短暂的延迟。
|
||||
|
||||
@@ -929,7 +973,6 @@ Here is an example showing how to use `curl` to form an HTTP request that
|
||||
advertises five "example.com/foo" resources on node `k8s-node-1` whose master
|
||||
is `k8s-master`.
|
||||
-->
|
||||
|
||||
**示例:**
|
||||
|
||||
这是一个示例,显示了如何使用 `curl` 构造 HTTP 请求,公告主节点为 `k8s-master`
|
||||
@@ -963,14 +1006,14 @@ Cluster-level extended resources are not tied to nodes. They are usually managed
|
||||
by scheduler extenders, which handle the resource consumption and resource quota.
|
||||
|
||||
You can specify the extended resources that are handled by scheduler extenders
|
||||
in [scheduler policy configuration](/docs/reference/config-api/kube-scheduler-policy-config.v1/)
|
||||
in [scheduler policy configuration](/docs/reference/config-api/kube-scheduler-config.v1beta3/)
|
||||
-->
|
||||
#### 集群层面的扩展资源 {#cluster-level-extended-resources}
|
||||
|
||||
集群层面的扩展资源并不绑定到具体节点。
|
||||
它们通常由调度器扩展程序(Scheduler Extenders)管理,这些程序处理资源消耗和资源配额。
|
||||
|
||||
你可以在[调度器策略配置](/zh/docs/reference/config-api/kube-scheduler-policy-config.v1/)
|
||||
你可以在[调度器策略配置](/zh/docs/reference/config-api/kube-scheduler-config.v1beta3/)
|
||||
中指定由调度器扩展程序处理的扩展资源。
|
||||
|
||||
<!--
|
||||
@@ -1091,9 +1134,10 @@ spec:
|
||||
<!--
|
||||
## PID limiting
|
||||
|
||||
Process ID (PID) limits allow for the configuration of a kubelet to limit the number of PIDs that a given Pod can consume. See [Pid Limiting](/docs/concepts/policy/pid-limiting/) for information.
|
||||
Process ID (PID) limits allow for the configuration of a kubelet
|
||||
to limit the number of PIDs that a given Pod can consume. See
|
||||
[PID Limiting](/docs/concepts/policy/pid-limiting/) for information.
|
||||
-->
|
||||
|
||||
## PID 限制 {#pid-limiting}
|
||||
|
||||
进程 ID(PID)限制允许对 kubelet 进行配置,以限制给定 Pod 可以消耗的 PID 数量。
|
||||
@@ -1102,43 +1146,52 @@ Process ID (PID) limits allow for the configuration of a kubelet to limit the nu
|
||||
<!--
|
||||
## Troubleshooting
|
||||
|
||||
### My Pods are pending with event message failedScheduling
|
||||
### My Pods are pending with event message `FailedScheduling`
|
||||
|
||||
If the scheduler cannot find any node where a Pod can fit, the Pod remains
|
||||
unscheduled until a place can be found. An event is produced each time the
|
||||
scheduler fails to find a place for the Pod, like this:
|
||||
unscheduled until a place can be found. An
|
||||
[Event](/docs/reference/kubernetes-api/cluster-resources/event-v1/) is produced
|
||||
each time the scheduler fails to find a place for the Pod, You can use `kubectl`
|
||||
to view the events for a Pod; for example:
|
||||
-->
|
||||
## 疑难解答
|
||||
|
||||
### 我的 Pod 处于悬决状态且事件信息显示 failedScheduling
|
||||
### 我的 Pod 处于悬决状态且事件信息显示 `FailedScheduling`
|
||||
|
||||
如果调度器找不到该 Pod 可以匹配的任何节点,则该 Pod 将保持未被调度状态,
|
||||
直到找到一个可以被调度到的位置。每当调度器找不到 Pod 可以调度的地方时,
|
||||
会产生一个事件,如下所示:
|
||||
会产生一个 [Event](/docs/reference/kubernetes-api/cluster-resources/event-v1/)。
|
||||
你可以使用 `kubectl` 来查看 Pod 的事件;例如:
|
||||
|
||||
```shell
|
||||
kubectl describe pod frontend | grep -A 3 Events
|
||||
kubectl describe pod frontend | grep -A 9999999999 Events
|
||||
```
|
||||
|
||||
```
|
||||
Events:
|
||||
FirstSeen LastSeen Count From Subobject PathReason Message
|
||||
36s 5s 6 {scheduler} FailedScheduling Failed for reason PodExceedsFreeCPU and possibly others
|
||||
Type Reason Age From Message
|
||||
---- ------ ---- ---- -------
|
||||
Warning FailedScheduling 23s default-scheduler 0/42 nodes available: insufficient cpu
|
||||
```
|
||||
|
||||
<!--
|
||||
In the preceding example, the Pod named "frontend" fails to be scheduled due to
|
||||
insufficient CPU resource on the node. Similar error messages can also suggest
|
||||
insufficient CPU resource on any node. Similar error messages can also suggest
|
||||
failure due to insufficient memory (PodExceedsFreeMemory). In general, if a Pod
|
||||
is pending with a message of this type, there are several things to try:
|
||||
|
||||
- Add more nodes to the cluster.
|
||||
- Terminate unneeded Pods to make room for pending Pods.
|
||||
- Check that the Pod is not larger than all the nodes. For example, if all the
|
||||
nodes have a capacity of `cpu: 1`, then a Pod with a request of `cpu: 1.1` will
|
||||
never be scheduled.
|
||||
- Check for node taints. If most of your nodes are tainted, and the new Pod does
|
||||
not tolerate that taint, the scheduler only considers placements onto the
|
||||
remaining nodes that don't have that taint.
|
||||
|
||||
You can check node capacities and amounts allocated with the
|
||||
`kubectl describe nodes` command. For example:
|
||||
-->
|
||||
|
||||
在上述示例中,由于节点上的 CPU 资源不足,名为 “frontend” 的 Pod 无法被调度。
|
||||
由于内存不足(PodExceedsFreeMemory)而导致失败时,也有类似的错误消息。
|
||||
一般来说,如果 Pod 处于悬决状态且有这种类型的消息时,你可以尝试如下几件事情:
|
||||
@@ -1147,12 +1200,15 @@ You can check node capacities and amounts allocated with the
|
||||
- 终止不需要的 Pod,为悬决的 Pod 腾出空间。
|
||||
- 检查 Pod 所需的资源是否超出所有节点的资源容量。例如,如果所有节点的容量都是`cpu:1`,
|
||||
那么一个请求为 `cpu: 1.1` 的 Pod 永远不会被调度。
|
||||
- 检查节点上的污点设置。如果集群中节点上存在污点,而新的 Pod 不能容忍污点,
|
||||
调度器只会考虑将 Pod 调度到不带有该污点的节点上。
|
||||
|
||||
你可以使用 `kubectl describe nodes` 命令检查节点容量和已分配的资源数量。 例如:
|
||||
|
||||
```shell
|
||||
kubectl describe nodes e2e-test-node-pool-4lw4
|
||||
```
|
||||
|
||||
```
|
||||
Name: e2e-test-node-pool-4lw4
|
||||
[ ... 这里忽略了若干行以便阅读 ...]
|
||||
@@ -1184,34 +1240,60 @@ Allocated resources:
|
||||
In the preceding output, you can see that if a Pod requests more than 1120m
|
||||
CPUs or 6.23Gi of memory, it will not fit on the node.
|
||||
|
||||
By looking at the `Pods` section, you can see which Pods are taking up space on
|
||||
By looking at the "Pods" section, you can see which Pods are taking up space on
|
||||
the node.
|
||||
|
||||
The amount of resources available to Pods is less than the node capacity, because
|
||||
system daemons use a portion of the available resources. The `allocatable` field
|
||||
[NodeStatus](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#nodestatus-v1-core)
|
||||
gives the amount of resources that are available to Pods. For more information, see
|
||||
[Node Allocatable Resources](https://git.k8s.io/community/contributors/design-proposals/node/node-allocatable.md).
|
||||
The [resource quota](/docs/concepts/policy/resource-quotas/) feature can be configured
|
||||
to limit the total amount of resources that can be consumed. If used in conjunction
|
||||
with namespaces, it can prevent one team from hogging all the resources.
|
||||
-->
|
||||
在上面的输出中,你可以看到如果 Pod 请求超过 1120m CPU 或者 6.23Gi 内存,节点将无法满足。
|
||||
|
||||
通过查看 `Pods` 部分,你将看到哪些 Pod 占用了节点上的资源。
|
||||
通过查看 "Pods" 部分,你将看到哪些 Pod 占用了节点上的资源。
|
||||
|
||||
可供 Pod 使用的资源量小于节点容量,因为系统守护程序也会使用一部分可用资源。
|
||||
[NodeStatus](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#nodestatus-v1-core)
|
||||
的 `allocatable` 字段给出了可用于 Pod 的资源量。
|
||||
有关更多信息,请参阅 [节点可分配资源](https://git.k8s.io/community/contributors/design-proposals/node-allocatable.md)。
|
||||
<!--
|
||||
The amount of resources available to Pods is less than the node capacity, because
|
||||
system daemons use a portion of the available resources. Within the Kubernetes API,
|
||||
each Node has a `.status.allocatable` field
|
||||
(see [NodeStatus](/docs/reference/kubernetes-api/cluster-resources/node-v1/#NodeStatus)
|
||||
for details).
|
||||
-->
|
||||
Pods 可用的资源量低于节点的资源总量,因为系统守护进程也会使用一部分可用资源。
|
||||
在 Kubernetes API 中,每个 Node 都有一个 `.status.allocatable` 字段
|
||||
(详情参见 [NodeStatus](/docs/reference/kubernetes-api/cluster-resources/node-v1/#NodeStatus))。
|
||||
|
||||
可以配置 [资源配额](/zh/docs/concepts/policy/resource-quotas/) 功能特性
|
||||
以限制可以使用的资源总量。
|
||||
如果与名字空间配合一起使用,就可以防止一个团队占用所有资源。
|
||||
<!--
|
||||
The `.status.allocatable` field describes the amount of resources that are available
|
||||
to Pods on that node (for example: 15 virtual CPUs and 7538 MiB of memory).
|
||||
For more information on node allocatable resources in Kubernetes, see
|
||||
[Reserve Compute Resources for System Daemons](/docs/tasks/administer-cluster/reserve-compute-resources/).
|
||||
-->
|
||||
字段 `.status.allocatable` 描述节点上可以用于 Pod 的资源总量(例如:15 个虚拟
|
||||
CPU、7538 MiB 内存)。关于 Kubernetes 中节点可分配资源的信息,可参阅
|
||||
[为系统守护进程预留计算资源](/zh/docs/tasks/administer-cluster/reserve-compute-resources/)。
|
||||
|
||||
<!--
|
||||
You can configure [resource quotas](/docs/concepts/policy/resource-quotas/)
|
||||
to limit the total amount of resources that a namespace can consume.
|
||||
Kubernetes enforces quotas for objects in particular namespace when there is a
|
||||
ResourceQuota in that namespace.
|
||||
For example, if you assign specific namespaces to different teams, you
|
||||
can add ResourceQuotas into those namespaces. Setting resource quotas helps to
|
||||
prevent one team from using so much of any resource that this over-use affects other teams.
|
||||
|
||||
You should also consider what access you grant to that namespace:
|
||||
**full** write access to a namespace allows someone with that access to remove any
|
||||
resource, include a configured ResourceQuota.
|
||||
-->
|
||||
你可以配置[资源配额](/zh/docs/concepts/policy/resource-quotas/)功能特性以限制每个名字空间可以使用的资源总量。
|
||||
当某名字空间中存在 ResourceQuota 时,Kubernetes 会在该名字空间中的对象强制实施配额。
|
||||
例如,如果你为不同的团队分配名字空间,你可以为这些名字空间添加 ResourceQuota。
|
||||
设置资源配额有助于防止一个团队占用太多资源,以至于这种占用会影响其他团队。
|
||||
|
||||
你还需要考虑为这些名字空间设置授权访问:
|
||||
为名字空间提供 **全部** 的写权限时,具有合适权限的人可能删除所有资源,
|
||||
包括所配置的 ResourceQuota。
|
||||
|
||||
<!--
|
||||
### My Container is terminated
|
||||
Your Container might get terminated because it is resource-starved. To check
|
||||
|
||||
Your container might get terminated because it is resource-starved. To check
|
||||
whether a Container is being killed because it is hitting a resource limit, call
|
||||
`kubectl describe pod` on the Pod of interest:
|
||||
-->
|
||||
@@ -1225,6 +1307,11 @@ whether a Container is being killed because it is hitting a resource limit, call
|
||||
kubectl describe pod simmemleak-hra99
|
||||
```
|
||||
|
||||
<!--
|
||||
The output is similar to:
|
||||
-->
|
||||
输出类似于:
|
||||
|
||||
```
|
||||
Name: simmemleak-hra99
|
||||
Namespace: default
|
||||
@@ -1235,7 +1322,6 @@ Status: Running
|
||||
Reason:
|
||||
Message:
|
||||
IP: 10.244.2.75
|
||||
Replication Controllers: simmemleak (1/1 replicas created)
|
||||
Containers:
|
||||
simmemleak:
|
||||
Image: saadali/simmemleak
|
||||
@@ -1254,57 +1340,47 @@ Conditions:
|
||||
Type Status
|
||||
Ready False
|
||||
Events:
|
||||
FirstSeen LastSeen Count From SubobjectPath Reason Message
|
||||
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {scheduler } scheduled Successfully assigned simmemleak-hra99 to kubernetes-node-tf0f
|
||||
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD pulled Pod container image "k8s.gcr.io/pause:0.8.0" already present on machine
|
||||
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD created Created with docker id 6a41280f516d
|
||||
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD started Started with docker id 6a41280f516d
|
||||
Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} spec.containers{simmemleak} created Created with docker id 87348f12526a
|
||||
Type Reason Age From Message
|
||||
---- ------ ---- ---- -------
|
||||
Normal Scheduled 42s default-scheduler Successfully assigned simmemleak-hra99 to kubernetes-node-tf0f
|
||||
Normal Pulled 41s kubelet Container image "saadali/simmemleak:latest" already present on machine
|
||||
Normal Created 41s kubelet Created container simmemleak
|
||||
Normal Started 40s kubelet Started container simmemleak
|
||||
Normal Killing 32s kubelet Killing container with id ead3fb35-5cf5-44ed-9ae1-488115be66c6: Need to kill Pod
|
||||
```
|
||||
|
||||
<!--
|
||||
In the preceding example, the `Restart Count: 5` indicates that the `simmemleak`
|
||||
Container in the Pod was terminated and restarted five times.
|
||||
|
||||
You can call `kubectl get pod` with the `-o go-template=...` option to fetch the status
|
||||
of previously terminated Containers:
|
||||
Container in the Pod was terminated and restarted five times (so far).
|
||||
The `OOMKilled` reason shows that the container tried to use more memory than its limit.
|
||||
-->
|
||||
在上面的例子中,`Restart Count: 5` 意味着 Pod 中的 `simmemleak` 容器被终止并重启了五次。
|
||||
|
||||
你可以使用 `kubectl get pod` 命令加上 `-o go-template=...` 选项来获取之前终止容器的状态。
|
||||
|
||||
```shell
|
||||
kubectl get pod -o go-template='{{range.status.containerStatuses}}{{"Container Name: "}}{{.name}}{{"\r\nLastState: "}}{{.lastState}}{{end}}' simmemleak-hra99
|
||||
```
|
||||
```
|
||||
Container Name: simmemleak
|
||||
LastState: map[terminated:map[exitCode:137 reason:OOM Killed startedAt:2015-07-07T20:58:43Z finishedAt:2015-07-07T20:58:43Z containerID:docker://0e4095bba1feccdfe7ef9fb6ebffe972b4b14285d5acdec6f0d3ae8a22fad8b2]]
|
||||
```
|
||||
在上面的例子中,`Restart Count: 5` 意味着 Pod 中的 `simmemleak`
|
||||
容器被终止并且(到目前为止)重启了五次。
|
||||
原因 `OOMKilled` 显示容器尝试使用超出其限制的内存量。
|
||||
|
||||
<!--
|
||||
You can see that the Container was terminated because of `reason:OOM Killed`, where `OOM` stands for Out Of Memory.
|
||||
Your next step might be to check the application code for a memory leak. If you
|
||||
find that the application is behaving how you expect, consider setting a higher
|
||||
memory limit (and possibly request) for that container.
|
||||
-->
|
||||
|
||||
你可以看到容器因为 `reason:OOM killed` 而被终止,`OOM` 表示内存不足(Out Of Memory)。
|
||||
你接下来要做的或许是检查应用代码,看看是否存在内存泄露。
|
||||
如果你发现应用的行为与你所预期的相同,则可以考虑为该容器设置一个更高的内存约束
|
||||
(也可能需要设置请求值)。
|
||||
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
<!--
|
||||
* 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/).
|
||||
* For more details about the difference between requests and limits, see
|
||||
[Resource QoS](https://git.k8s.io/community/contributors/design-proposals/node/resource-qos.md).
|
||||
* Read the [Container](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#container-v1-core) API reference
|
||||
* Read the [ResourceRequirements](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#resourcerequirements-v1-core) API reference
|
||||
* Read about [project quotas](http://xfs.org/docs/xfsdocs-xml-dev/XFS_User_Guide/tmp/en-US/html/xfs-quotas.html) in XFS
|
||||
* Read more about the [kube-scheduler Policy reference (v1)](/docs/reference/config-api/kube-scheduler-policy-config.v1/)
|
||||
* 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)
|
||||
* Read about [project quotas](https://xfs.org/docs/xfsdocs-xml-dev/XFS_User_Guide/tmp/en-US/html/xfs-quotas.html) in XFS
|
||||
* Read more about the [kube-scheduler configuration reference (v1beta3)](/docs/reference/config-api/kube-scheduler-config.v1beta3/)
|
||||
-->
|
||||
|
||||
* 获取[分配内存资源给容器和 Pod ](/zh/docs/tasks/configure-pod-container/assign-memory-resource/) 的实践经验
|
||||
* 获取[分配 CPU 资源给容器和 Pod ](/zh/docs/tasks/configure-pod-container/assign-cpu-resource/) 的实践经验
|
||||
* 关于请求和约束之间的区别,细节信息可参见[资源服务质量](https://git.k8s.io/community/contributors/design-proposals/node/resource-qos.md)
|
||||
* 阅读 API 参考文档中 [Container](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#container-v1-core) 部分。
|
||||
* 阅读 API 参考文档中 [ResourceRequirements](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#resourcerequirements-v1-core) 部分。
|
||||
* 阅读 XFS 中关于[项目配额](https://xfs.org/docs/xfsdocs-xml-dev/XFS_User_Guide/tmp/en-US/html/xfs-quotas.html) 的文档。
|
||||
* 阅读更多关于[kube-scheduler 策略参考 (v1)](/zh/docs/reference/config-api/kube-scheduler-policy-config.v1/) 的文档。
|
||||
* 阅读 API 参考中 [Container](/docs/reference/kubernetes-api/workload-resources/pod-v1/#Container)
|
||||
和其[资源请求](/docs/reference/kubernetes-api/workload-resources/pod-v1/#resources)定义。
|
||||
* 阅读 XFS 中[配额](https://xfs.org/docs/xfsdocs-xml-dev/XFS_User_Guide/tmp/en-US/html/xfs-quotas.html)的文档
|
||||
* 进一步阅读 [kube-scheduler 配置参考 (v1beta3)](/zh/docs/reference/config-api/kube-scheduler-config.v1beta3/)
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ title: Pod 安全策略
|
||||
content_type: concept
|
||||
weight: 30
|
||||
---
|
||||
|
||||
<!--
|
||||
reviewers:
|
||||
- pweil-
|
||||
@@ -1236,13 +1237,13 @@ denoted as the string `Unmasked`.
|
||||
### AppArmor
|
||||
|
||||
Controlled via annotations on the PodSecurityPolicy. Refer to the [AppArmor
|
||||
documentation](/docs/tutorials/clusters/apparmor/#podsecuritypolicy-annotations).
|
||||
documentation](/docs/tutorials/policy/apparmor/#podsecuritypolicy-annotations).
|
||||
-->
|
||||
### AppArmor
|
||||
|
||||
通过 PodSecurityPolicy 上的注解来控制。
|
||||
详情请参阅
|
||||
[AppArmor 文档](/zh/docs/tutorials/clusters/apparmor/#podsecuritypolicy-annotations)。
|
||||
[AppArmor 文档](/zh/docs/tutorials/policy/apparmor/#podsecuritypolicy-annotations)。
|
||||
|
||||
|
||||
<!--
|
||||
|
||||
@@ -185,15 +185,13 @@ To make use of that label prefix for node isolation:
|
||||
前缀设置或修改标签。要使用该标签前缀进行节点隔离:
|
||||
|
||||
<!--
|
||||
1. Check that you're using Kubernetes v1.11+ so that NodeRestriction is available.
|
||||
2. Ensure you are using the [Node authorizer](/docs/reference/access-authn-authz/node/) and have _enabled_ the [NodeRestriction admission plugin](/docs/reference/access-authn-authz/admission-controllers/#noderestriction).
|
||||
3. Add labels under the `node-restriction.kubernetes.io/` prefix to your Node objects, and use those labels in your node selectors.
|
||||
1. Ensure you are using the [Node authorizer](/docs/reference/access-authn-authz/node/) and have _enabled_ the [NodeRestriction admission plugin](/docs/reference/access-authn-authz/admission-controllers/#noderestriction).
|
||||
2. Add labels under the `node-restriction.kubernetes.io/` prefix to your Node objects, and use those labels in your node selectors.
|
||||
For example, `example.com.node-restriction.kubernetes.io/fips=true` or `example.com.node-restriction.kubernetes.io/pci-dss=true`.
|
||||
-->
|
||||
1. 检查是否在使用 Kubernetes v1.11+,以便 NodeRestriction 功能可用。
|
||||
2. 确保你在使用[节点授权](/zh/docs/reference/access-authn-authz/node/)并且已经_启用_
|
||||
1. 确保你在使用[节点授权](/zh/docs/reference/access-authn-authz/node/)并且已经 _启用_
|
||||
[NodeRestriction 准入插件](/zh/docs/reference/access-authn-authz/admission-controllers/#noderestriction)。
|
||||
3. 将 `node-restriction.kubernetes.io/` 前缀下的标签添加到 Node 对象,
|
||||
2. 将 `node-restriction.kubernetes.io/` 前缀下的标签添加到 Node 对象,
|
||||
然后在节点选择器中使用这些标签。
|
||||
例如,`example.com.node-restriction.kubernetes.io/fips=true` 或
|
||||
`example.com.node-restriction.kubernetes.io/pci-dss=true`。
|
||||
@@ -216,7 +214,7 @@ feature, greatly expands the types of constraints you can express. The key enhan
|
||||
3. you can constrain against labels on other pods running on the node (or other topological domain),
|
||||
rather than against labels on the node itself, which allows rules about which pods can and cannot be co-located
|
||||
-->
|
||||
1. 语言更具表现力(不仅仅是“对完全匹配规则的 AND”)
|
||||
1. 语言表达能力更强(不仅仅是“对完全匹配规则的 AND”)
|
||||
2. 你可以发现规则是“软需求”/“偏好”,而不是硬性要求,因此,
|
||||
如果调度器无法满足该要求,仍然调度该 Pod
|
||||
3. 你可以使用节点上(或其他拓扑域中)的 Pod 的标签来约束,而不是使用
|
||||
@@ -369,7 +367,7 @@ in the [scheduler configuration](/docs/reference/scheduling/config/). For exampl
|
||||
例如:
|
||||
|
||||
```yaml
|
||||
apiVersion: kubescheduler.config.k8s.io/v1beta1
|
||||
apiVersion: kubescheduler.config.k8s.io/v1beta3
|
||||
kind: KubeSchedulerConfiguration
|
||||
|
||||
profiles:
|
||||
|
||||
@@ -32,11 +32,6 @@ _POD 开销_ 是一个特性,用于计算 Pod 基础设施在容器请求和
|
||||
|
||||
<!-- body -->
|
||||
|
||||
<!--
|
||||
## Pod Overhead
|
||||
-->
|
||||
|
||||
## Pod 开销
|
||||
|
||||
<!--
|
||||
In Kubernetes, the Pod's overhead is set at
|
||||
|
||||
@@ -9,30 +9,25 @@ weight: 30
|
||||
<!--
|
||||
## The Kubernetes model for connecting containers
|
||||
|
||||
Now that you have a continuously running, replicated application you can expose it on a network. Before discussing the Kubernetes approach to networking, it is worthwhile to contrast it with the "normal" way networking works with Docker.
|
||||
Now that you have a continuously running, replicated application you can expose it on a network.
|
||||
|
||||
By default, Docker uses host-private networking, so containers can talk to other containers only if they are on the same machine. In order for Docker containers to communicate across nodes, there must be allocated ports on the machine's own IP address, which are then forwarded or proxied to the containers. This obviously means that containers must either coordinate which ports they use very carefully or ports must be allocated dynamically.
|
||||
|
||||
Coordinating port allocations across multiple developers or teams that provide containers is very difficult to do at scale, and exposes users to cluster-level issues outside of their control. Kubernetes assumes that pods can communicate with other pods, regardless of which host they land on. Kubernetes gives every pod its own cluster-private IP address, so you do not need to explicitly create links between pods or map container ports to host ports. This means that containers within a Pod can all reach each other's ports on localhost, and all pods in a cluster can see each other without NAT. The rest of this document elaborates on how you can run reliable services on such a networking model.
|
||||
Kubernetes assumes that pods can communicate with other pods, regardless of which host they land on. Kubernetes gives every pod its own cluster-private IP address, so you do not need to explicitly create links between pods or map container ports to host ports. This means that containers within a Pod can all reach each other's ports on localhost, and all pods in a cluster can see each other without NAT. The rest of this document elaborates on how you can run reliable services on such a networking model.
|
||||
|
||||
This guide uses a simple nginx server to demonstrate proof of concept.
|
||||
-->
|
||||
|
||||
## Kubernetes 连接容器模型
|
||||
## Kubernetes 连接容器的模型
|
||||
|
||||
既然有了一个持续运行、可复制的应用,我们就能够将它暴露到网络上。
|
||||
在讨论 Kubernetes 网络连接的方式之前,非常值得与 Docker 中 “正常” 方式的网络进行对比。
|
||||
|
||||
默认情况下,Docker 使用私有主机网络连接,只能与同在一台机器上的容器进行通信。
|
||||
为了实现容器的跨节点通信,必须在机器自己的 IP 上为这些容器分配端口,为容器进行端口转发或者代理。
|
||||
|
||||
多个开发人员或是提供容器的团队之间协调端口的分配很难做到规模化,那些难以控制的集群级别的问题,都会交由用户自己去处理。
|
||||
Kubernetes 假设 Pod 可与其它 Pod 通信,不管它们在哪个主机上。
|
||||
Kubernetes 给 Pod 分配属于自己的集群私有 IP 地址,所以没必要在 Pod 或映射到的容器的端口和主机端口之间显式地创建连接。
|
||||
这表明了在 Pod 内的容器都能够连接到本地的每个端口,集群中的所有 Pod 不需要通过 NAT 转换就能够互相看到。
|
||||
文档的剩余部分详述如何在一个网络模型之上运行可靠的服务。
|
||||
Kubernetes 给每一个 Pod 分配一个集群私有 IP 地址,所以没必要在
|
||||
Pod 与 Pod 之间创建连接或将容器的端口映射到主机端口。
|
||||
这意味着同一个 Pod 内的所有容器能通过 localhost 上的端口互相连通,集群中的所有 Pod
|
||||
也不需要通过 NAT 转换就能够互相看到。
|
||||
本文档的剩余部分详述如何在上述网络模型之上运行可靠的服务。
|
||||
|
||||
该指南使用一个简单的 Nginx server 来演示并证明谈到的概念。
|
||||
本指南使用一个简单的 Nginx 服务器来演示概念验证原型。
|
||||
|
||||
<!-- body -->
|
||||
|
||||
@@ -45,7 +40,7 @@ Create an nginx Pod, and note that it has a container port specification:
|
||||
## 在集群中暴露 Pod
|
||||
|
||||
我们在之前的示例中已经做过,然而让我们以网络连接的视角再重做一遍。
|
||||
创建一个 Nginx Pod,并且注意,它有一个容器端口的规范:
|
||||
创建一个 Nginx Pod,注意其中包含一个容器端口的规约:
|
||||
|
||||
{{< codenew file="service/networking/run-my-nginx.yaml" >}}
|
||||
|
||||
@@ -77,16 +72,17 @@ kubectl get pods -l run=my-nginx -o yaml | grep podIP
|
||||
```
|
||||
|
||||
<!--
|
||||
You should be able to ssh into any node in your cluster and curl both IPs. Note that the containers are *not* using port 80 on the node, nor are there any special NAT rules to route traffic to the pod. This means you can run multiple nginx pods on the same node all using the same containerPort and access them from any other pod or node in your cluster using IP. Like Docker, ports can still be published to the host node's interfaces, but the need for this is radically diminished because of the networking model.
|
||||
You should be able to ssh into any node in your cluster and use a tool such as `curl` to make queries against both IPs. Note that the containers are *not* using port 80 on the node, nor are there any special NAT rules to route traffic to the pod. This means you can run multiple nginx pods on the same node all using the same `containerPort`, and access them from any other pod or node in your cluster using the assigned IP address for the Service. If you want to arrange for a specific port on the host Node to be forwarded to backing Pods, you can - but the networking model should mean that you do not need to do so.
|
||||
|
||||
You can read more about [how we achieve this](/docs/concepts/cluster-administration/networking/#how-to-achieve-this) if you're curious.
|
||||
You can read more about the [Kubernetes Networking Model](/docs/concepts/cluster-administration/networking/#the-kubernetes-network-model) if you're curious.
|
||||
-->
|
||||
应该能够通过 ssh 登录到集群中的任何一个节点上,使用 curl 也能调通所有 IP 地址。
|
||||
你应该能够通过 ssh 登录到集群中的任何一个节点上,并使用诸如 `curl` 之类的工具向这两个 IP 地址发出查询请求。
|
||||
需要注意的是,容器不会使用该节点上的 80 端口,也不会使用任何特定的 NAT 规则去路由流量到 Pod 上。
|
||||
这意味着可以在同一个节点上运行多个 Pod,使用相同的容器端口,并且可以从集群中任何其他的 Pod 或节点上使用 IP 的方式访问到它们。
|
||||
像 Docker 一样,端口能够被发布到主机节点的接口上,但是出于网络模型的原因应该从根本上减少这种用法。
|
||||
这意味着可以在同一个节点上运行多个 Nginx Pod,使用相同的 `containerPort`,并且可以从集群中任何其他的
|
||||
Pod 或节点上使用 IP 的方式访问到它们。
|
||||
如果你想的话,你依然可以将宿主节点的某个端口的流量转发到 Pod 中,但是出于网络模型的原因,你不必这么做。
|
||||
|
||||
如果对此好奇,可以获取更多关于 [如何实现网络模型](/zh/docs/concepts/cluster-administration/networking/#how-to-achieve-this) 的内容。
|
||||
如果对此好奇,请参考 [Kubernetes 网络模型](/zh/docs/concepts/cluster-administration/networking/#the-kubernetes-network-model)。
|
||||
|
||||
<!--
|
||||
## Creating a Service
|
||||
@@ -99,12 +95,13 @@ You can create a Service for your 2 nginx replicas with `kubectl expose`:
|
||||
-->
|
||||
## 创建 Service
|
||||
|
||||
我们有 Pod 在一个扁平的、集群范围的地址空间中运行 Nginx 服务,可以直接连接到这些 Pod,但如果某个节点死掉了会发生什么呢?
|
||||
我们有一组在一个扁平的、集群范围的地址空间中运行 Nginx 服务的 Pod。
|
||||
理论上,你可以直接连接到这些 Pod,但如果某个节点死掉了会发生什么呢?
|
||||
Pod 会终止,Deployment 将创建新的 Pod,且使用不同的 IP。这正是 Service 要解决的问题。
|
||||
|
||||
Kubernetes Service 从逻辑上定义了运行在集群中的一组 Pod,这些 Pod 提供了相同的功能。
|
||||
Kubernetes Service 是集群中提供相同功能的一组 Pod 的抽象表达。
|
||||
当每个 Service 创建时,会被分配一个唯一的 IP 地址(也称为 clusterIP)。
|
||||
这个 IP 地址与一个 Service 的生命周期绑定在一起,当 Service 存在的时候它也不会改变。
|
||||
这个 IP 地址与 Service 的生命周期绑定在一起,只要 Service 存在,它就不会改变。
|
||||
可以配置 Pod 使它与 Service 进行通信,Pod 知道与 Service 通信将被自动地负载均衡到该 Service 中的某些 Pod 上。
|
||||
|
||||
可以使用 `kubectl expose` 命令为 2个 Nginx 副本创建一个 Service:
|
||||
@@ -120,7 +117,7 @@ service/my-nginx exposed
|
||||
This is equivalent to `kubectl apply -f` the following yaml:
|
||||
-->
|
||||
|
||||
这等价于使用 `kubectl create -f` 命令创建,对应如下的 yaml 文件:
|
||||
这等价于使用 `kubectl create -f` 命令及如下的 yaml 文件创建:
|
||||
|
||||
{{< codenew file="service/networking/nginx-svc.yaml" >}}
|
||||
|
||||
@@ -134,11 +131,11 @@ View [Service](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/
|
||||
API object to see the list of supported fields in service definition.
|
||||
Check your Service:
|
||||
-->
|
||||
上述规约将创建一个 Service,对应具有标签 `run: my-nginx` 的 Pod,目标 TCP 端口 80,
|
||||
并且在一个抽象的 Service 端口(`targetPort`:容器接收流量的端口;`port`:抽象的 Service
|
||||
端口,可以使任何其它 Pod 访问该 Service 的端口)上暴露。
|
||||
查看 [Service API 对象](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#service-v1-core)
|
||||
了解 Service 定义支持的字段列表。
|
||||
上述规约将创建一个 Service,该 Service 会将所有具有标签 `run: my-nginx` 的 Pod 的 TCP
|
||||
80 端口暴露到一个抽象的 Service 端口上(`targetPort`:容器接收流量的端口;`port`:可任意取值的抽象的 Service
|
||||
端口,其他 Pod 通过该端口访问 Service)。
|
||||
查看 [Service](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#service-v1-core)
|
||||
API 对象以了解 Service 所能接受的字段列表。
|
||||
查看你的 Service 资源:
|
||||
|
||||
```shell
|
||||
@@ -158,7 +155,7 @@ matching the Service's selector will automatically get added to the endpoints.
|
||||
Check the endpoints, and note that the IPs are the same as the Pods created in
|
||||
the first step:
|
||||
-->
|
||||
正如前面所提到的,一个 Service 由一组 backend Pod 组成。这些 Pod 通过 `endpoints` 暴露出来。
|
||||
正如前面所提到的,一个 Service 由一组 Pod 提供支撑。这些 Pod 通过 `endpoints` 暴露出来。
|
||||
Service Selector 将持续评估,结果被 POST 到一个名称为 `my-nginx` 的 Endpoint 对象上。
|
||||
当 Pod 终止后,它会自动从 Endpoint 中移除,新的能够匹配上 Service Selector 的 Pod 将自动地被添加到 Endpoint 中。
|
||||
检查该 Endpoint,注意到 IP 地址与在第一步创建的 Pod 是相同的。
|
||||
@@ -194,7 +191,7 @@ never hits the wire. If you're curious about how this works you can read more
|
||||
about the [service proxy](/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies).
|
||||
-->
|
||||
|
||||
现在,能够从集群中任意节点上使用 curl 命令请求 Nginx Service `<CLUSTER-IP>:<PORT>` 。
|
||||
现在,你应该能够从集群中任意节点上使用 curl 命令向 `<CLUSTER-IP>:<PORT>` 发送请求以访问 Nginx Service。
|
||||
注意 Service IP 完全是虚拟的,它从来没有走过网络,如果对它如何工作的原理感到好奇,
|
||||
可以进一步阅读[服务代理](/zh/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies)
|
||||
的内容。
|
||||
@@ -204,12 +201,12 @@ about the [service proxy](/docs/concepts/services-networking/service/#virtual-ip
|
||||
|
||||
Kubernetes supports 2 primary modes of finding a Service - environment variables
|
||||
and DNS. The former works out of the box while the latter requires the
|
||||
[CoreDNS cluster addon](https://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/dns/coredns).
|
||||
[CoreDNS cluster addon](https://releases.k8s.io/{{< param "fullversion" >}}/cluster/addons/dns/coredns).
|
||||
-->
|
||||
## 访问 Service
|
||||
|
||||
Kubernetes支持两种查找服务的主要模式: 环境变量和DNS。 前者开箱即用,而后者则需要[CoreDNS集群插件]
|
||||
[CoreDNS 集群插件](https://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/dns/coredns).
|
||||
Kubernetes支持两种查找服务的主要模式: 环境变量和 DNS。前者开箱即用,而后者则需要
|
||||
[CoreDNS 集群插件](https://releases.k8s.io/{{< param "fullversion" >}}/cluster/addons/dns/coredns).
|
||||
|
||||
<!--
|
||||
If the service environment variables are not desired (because possible clashing with expected program ones,
|
||||
@@ -231,8 +228,9 @@ the environment of your running nginx Pods (your Pod name will be different):
|
||||
-->
|
||||
### 环境变量
|
||||
|
||||
当 Pod 在 Node 上运行时,kubelet 会为每个活跃的 Service 添加一组环境变量。
|
||||
这会有一个顺序的问题。想了解为何,检查正在运行的 Nginx Pod 的环境变量(Pod 名称将不会相同):
|
||||
当 Pod 在节点上运行时,kubelet 会针对每个活跃的 Service 为 Pod 添加一组环境变量。
|
||||
这就引入了一个顺序的问题。为解释这个问题,让我们先检查正在运行的 Nginx Pod
|
||||
的环境变量(你的环境中的 Pod 名称将会与下面示例命令中的不同):
|
||||
|
||||
```shell
|
||||
kubectl exec my-nginx-3800858182-jr4a2 -- printenv | grep SERVICE
|
||||
@@ -254,10 +252,11 @@ replicas. This will give you scheduler-level Service spreading of your Pods
|
||||
variables:
|
||||
-->
|
||||
|
||||
注意,还没有谈及到 Service。这是因为创建副本先于 Service。
|
||||
这样做的另一个缺点是,调度器可能在同一个机器上放置所有 Pod,如果该机器宕机则所有的 Service 都会挂掉。
|
||||
正确的做法是,我们杀掉 2 个 Pod,等待 Deployment 去创建它们。
|
||||
这次 Service 会 *先于* 副本存在。这将实现调度器级别的 Service,能够使 Pod 分散创建(假定所有的 Node 都具有同样的容量),以及正确的环境变量:
|
||||
能看到环境变量中并没有你创建的 Service 相关的值。这是因为副本的创建先于 Service。
|
||||
这样做的另一个缺点是,调度器可能会将所有 Pod 部署到同一台机器上,如果该机器宕机则整个 Service 都会离线。
|
||||
要改正的话,我们可以先终止这 2 个 Pod,然后等待 Deployment 去重新创建它们。
|
||||
这次 Service 会*先于*副本存在。这将实现调度器级别的 Pod 按 Service
|
||||
分布(假定所有的节点都具有同样的容量),并提供正确的环境变量:
|
||||
|
||||
```shell
|
||||
kubectl scale deployment my-nginx --replicas=0; kubectl scale deployment my-nginx --replicas=2;
|
||||
@@ -274,7 +273,7 @@ my-nginx-3800858182-j4rm4 1/1 Running 0 5s 10.244.3.8
|
||||
You may notice that the pods have different names, since they are killed and recreated.
|
||||
-->
|
||||
|
||||
可能注意到,Pod 具有不同的名称,因为它们被杀掉后并被重新创建。
|
||||
你可能注意到,Pod 具有不同的名称,这是因为它们是被重新创建的。
|
||||
|
||||
```shell
|
||||
kubectl exec my-nginx-3800858182-e9ihh -- printenv | grep SERVICE
|
||||
@@ -293,8 +292,8 @@ KUBERNETES_SERVICE_PORT_HTTPS=443
|
||||
Kubernetes offers a DNS cluster addon Service that automatically assigns dns names to other Services. You can check if it's running on your cluster:
|
||||
-->
|
||||
|
||||
Kubernetes 提供了一个 DNS 插件 Service,它使用 skydns 自动为其它 Service 指派 DNS 名字。
|
||||
如果它在集群中处于运行状态,可以通过如下命令来检查:
|
||||
Kubernetes 提供了一个自动为其它 Service 分配 DNS 名字的 DNS 插件 Service。
|
||||
你可以通过如下命令检查它是否在工作:
|
||||
|
||||
```shell
|
||||
kubectl get services kube-dns --namespace=kube-system
|
||||
@@ -305,18 +304,15 @@ kube-dns ClusterIP 10.0.0.10 <none> 53/UDP,53/TCP 8m
|
||||
```
|
||||
|
||||
<!--
|
||||
If it isn't running, you can [enable it](http://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/dns/kube-dns/README.md#how-do-i-configure-it).
|
||||
|
||||
The rest of this section will assume you have a Service with a long lived IP
|
||||
(my-nginx), and a DNS server that has assigned a name to that IP. Here we use the CoreDNS cluster addon (application name `kube-dns`), so you can talk to the Service from any pod in your cluster using standard methods (e.g. `gethostbyname()`). If CoreDNS isn't running, you can enable it referring to the [CoreDNS README](https://github.com/coredns/deployment/tree/master/kubernetes) or [Installing CoreDNS](/docs/tasks/administer-cluster/coredns/#installing-coredns). Let's run another curl application to test this:
|
||||
-->
|
||||
如果没有在运行,可以[启用它](https://releases.k8s.io/{{< param "githubbranch" >}}/cluster/addons/dns/kube-dns/README.md#how-do-i-configure-it)。
|
||||
本段剩余的内容,将假设已经有一个 Service,它具有一个长久存在的 IP(my-nginx),
|
||||
一个为该 IP 指派名称的 DNS 服务器。 这里我们使用 CoreDNS 集群插件(应用名为 `kube-dns`),
|
||||
所以可以通过标准做法,使在集群中的任何 Pod 都能与该 Service 通信(例如:`gethostbyname()`)。
|
||||
本段剩余的内容假设你已经有一个拥有持久 IP 地址的 Service(my-nginx),以及一个为其
|
||||
IP 分配名称的 DNS 服务器。 这里我们使用 CoreDNS 集群插件(应用名为 `kube-dns`),
|
||||
所以在集群中的任何 Pod 中,你都可以使用标准方法(例如:`gethostbyname()`)与该 Service 通信。
|
||||
如果 CoreDNS 没有在运行,你可以参照
|
||||
[CoreDNS README](https://github.com/coredns/deployment/tree/master/kubernetes) 或者
|
||||
[安装 CoreDNS](/zh/docs/tasks/administer-cluster/coredns/#installing-coredns) 来启用它。
|
||||
[CoreDNS README](https://github.com/coredns/deployment/tree/master/kubernetes)
|
||||
或者[安装 CoreDNS](/zh/docs/tasks/administer-cluster/coredns/#installing-coredns) 来启用它。
|
||||
让我们运行另一个 curl 应用来进行测试:
|
||||
|
||||
```shell
|
||||
@@ -351,21 +347,21 @@ Till now we have only accessed the nginx server from within the cluster. Before
|
||||
* An nginx server configured to use the certificates
|
||||
* A [secret](/docs/concepts/configuration/secret/) that makes the certificates accessible to pods
|
||||
|
||||
You can acquire all these from the [nginx https example](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/https-nginx/). This requires having go and make tools installed. If you don't want to install those, then follow the manual steps later. In short:
|
||||
You can acquire all these from the [nginx https example](https://github.com/kubernetes/examples/tree/master/staging/https-nginx/). This requires having go and make tools installed. If you don't want to install those, then follow the manual steps later. In short:
|
||||
-->
|
||||
|
||||
## 保护 Service {#securing-the-service}
|
||||
|
||||
到现在为止,我们只在集群内部访问了 Nginx 服务器。在将 Service 暴露到因特网之前,我们希望确保通信信道是安全的。
|
||||
为实现这一目的,可能需要:
|
||||
为实现这一目的,需要:
|
||||
|
||||
* 用于 HTTPS 的自签名证书(除非已经有了一个识别身份的证书)
|
||||
* 用于 HTTPS 的自签名证书(除非已经有了一个身份证书)
|
||||
* 使用证书配置的 Nginx 服务器
|
||||
* 使证书可以访问 Pod 的 [Secret](/zh/docs/concepts/configuration/secret/)
|
||||
* 使 Pod 可以访问证书的 [Secret](/zh/docs/concepts/configuration/secret/)
|
||||
|
||||
你可以从 [Nginx https 示例](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/https-nginx/)
|
||||
获取所有上述内容。你需要安装 go 和 make 工具。如果你不想安装这些软件,可以按照
|
||||
后文所述的手动执行步骤执行操作。简要过程如下:
|
||||
你可以从
|
||||
[Nginx https 示例](https://github.com/kubernetes/examples/tree/master/staging/https-nginx/)获取所有上述内容。
|
||||
你需要安装 go 和 make 工具。如果你不想安装这些软件,可以按照后文所述的手动执行步骤执行操作。简要过程如下:
|
||||
|
||||
```shell
|
||||
make keys KEY=/tmp/nginx.key CERT=/tmp/nginx.crt
|
||||
@@ -385,19 +381,6 @@ nginxsecret kubernetes.io/tls 2 1m
|
||||
|
||||
<!--
|
||||
And also the configmap:
|
||||
```shell
|
||||
kubectl create configmap nginxconfigmap --from-file=default.conf
|
||||
```
|
||||
```
|
||||
configmap/nginxconfigmap created
|
||||
```
|
||||
```shell
|
||||
kubectl get configmaps
|
||||
```
|
||||
```
|
||||
NAME DATA AGE
|
||||
nginxconfigmap 1 114s
|
||||
```
|
||||
-->
|
||||
以下是 configmap:
|
||||
```shell
|
||||
@@ -420,9 +403,9 @@ Following are the manual steps to follow in case you run into problems running m
|
||||
以下是你在运行 make 时遇到问题时要遵循的手动步骤(例如,在 Windows 上):
|
||||
|
||||
```shell
|
||||
# Create a public private key pair
|
||||
# 创建公钥和相对应的私钥
|
||||
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /d/tmp/nginx.key -out /d/tmp/nginx.crt -subj "/CN=my-nginx/O=my-nginx"
|
||||
# Convert the keys to base64 encoding
|
||||
# 对密钥实施 base64 编码
|
||||
cat /d/tmp/nginx.crt | base64
|
||||
cat /d/tmp/nginx.key | base64
|
||||
```
|
||||
@@ -447,7 +430,7 @@ data:
|
||||
<!--
|
||||
Now create the secrets using the file:
|
||||
-->
|
||||
现在使用文件创建 Secrets:
|
||||
现在使用文件创建 Secret:
|
||||
|
||||
```shell
|
||||
kubectl apply -f nginxsecrets.yaml
|
||||
@@ -462,7 +445,7 @@ nginxsecret kubernetes.io/tls 2 1m
|
||||
<!--
|
||||
Now modify your nginx replicas to start an https server using the certificate in the secret, and the Service, to expose both ports (80 and 443):
|
||||
-->
|
||||
现在修改 nginx 副本,启动一个使用在秘钥中的证书的 HTTPS 服务器和 Service,暴露端口(80 和 443):
|
||||
现在修改 nginx 副本以启动一个使用 Secret 中的证书的 HTTPS 服务器以及相应的用于暴露其端口(80 和 443)的 Service:
|
||||
|
||||
{{< codenew file="service/networking/nginx-secure-app.yaml" >}}
|
||||
|
||||
@@ -470,7 +453,7 @@ Now modify your nginx replicas to start an https server using the certificate in
|
||||
Noteworthy points about the nginx-secure-app manifest:
|
||||
|
||||
- It contains both Deployment and Service specification in the same file.
|
||||
- The [nginx server](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/https-nginx/default.conf)
|
||||
- The [nginx server](https://github.com/kubernetes/examples/tree/master/staging/https-nginx/default.conf)
|
||||
serves HTTP traffic on port 80 and HTTPS traffic on 443, and nginx Service
|
||||
exposes both ports.
|
||||
- Each container has access to the keys through a volume mounted at `/etc/nginx/ssl`.
|
||||
@@ -478,10 +461,10 @@ Noteworthy points about the nginx-secure-app manifest:
|
||||
-->
|
||||
关于 nginx-secure-app 清单,值得注意的几点如下:
|
||||
|
||||
- 它在相同的文件中包含了 Deployment 和 Service 的规约
|
||||
- [nginx 服务器](https://github.com/kubernetes/kubernetes/tree/{{< param "githubbranch" >}}/staging/https-nginx/default.conf)
|
||||
处理 80 端口上的 HTTP 流量,以及 443 端口上的 HTTPS 流量,Nginx Service 暴露了这两个端口。
|
||||
- 每个容器访问挂载在 /etc/nginx/ssl 卷上的秘钥。这需要在 Nginx 服务器启动之前安装好。
|
||||
- 它将 Deployment 和 Service 的规约放在了同一个文件中。
|
||||
- [Nginx 服务器](https://github.com/kubernetes/examples/tree/master/staging/https-nginx/default.conf)通过
|
||||
80 端口处理 HTTP 流量,通过 443 端口处理 HTTPS 流量,而 Nginx Service 则暴露了这两个端口。
|
||||
- 每个容器能通过挂载在 `/etc/nginx/ssl` 的卷访问秘钥。卷和密钥需要在 Nginx 服务器启动*之前*配置好。
|
||||
|
||||
```shell
|
||||
kubectl delete deployments,svc my-nginx; kubectl create -f ./nginx-secure-app.yaml
|
||||
@@ -508,7 +491,7 @@ Let's test this from a pod (the same secret is being reused for simplicity, the
|
||||
注意最后一步我们是如何提供 `-k` 参数执行 curl 命令的,这是因为在证书生成时,
|
||||
我们不知道任何关于运行 nginx 的 Pod 的信息,所以不得不在执行 curl 命令时忽略 CName 不匹配的情况。
|
||||
通过创建 Service,我们连接了在证书中的 CName 与在 Service 查询时被 Pod 使用的实际 DNS 名字。
|
||||
让我们从一个 Pod 来测试(为了简化使用同一个秘钥,Pod 仅需要使用 nginx.crt 去访问 Service):
|
||||
让我们从一个 Pod 来测试(为了方便,这里使用同一个 Secret,Pod 仅需要使用 nginx.crt 去访问 Service):
|
||||
|
||||
{{< codenew file="service/networking/curlpod.yaml" >}}
|
||||
|
||||
@@ -538,10 +521,10 @@ node has a public IP.
|
||||
-->
|
||||
## 暴露 Service
|
||||
|
||||
对我们应用的某些部分,可能希望将 Service 暴露在一个外部 IP 地址上。
|
||||
对应用的某些部分,你可能希望将 Service 暴露在一个外部 IP 地址上。
|
||||
Kubernetes 支持两种实现方式:NodePort 和 LoadBalancer。
|
||||
在上一段创建的 Service 使用了 `NodePort`,因此 Nginx https 副本已经就绪,
|
||||
如果使用一个公网 IP,能够处理 Internet 上的流量。
|
||||
在上一段创建的 Service 使用了 `NodePort`,因此,如果你的节点有一个公网
|
||||
IP,那么 Nginx HTTPS 副本已经能够处理因特网上的流量。
|
||||
|
||||
```shell
|
||||
kubectl get svc my-nginx -o yaml | grep nodePort -C 5
|
||||
@@ -579,18 +562,18 @@ kubectl get nodes -o yaml | grep ExternalIP -C 1
|
||||
type: ExternalIP
|
||||
allocatable:
|
||||
...
|
||||
$ curl https://<EXTERNAL-IP>:<NODE-PORT> -k
|
||||
|
||||
$ curl https://<EXTERNAL-IP>:<NODE-PORT> -k
|
||||
...
|
||||
<h1>Welcome to nginx!</h1>
|
||||
```
|
||||
|
||||
<!--
|
||||
Let's now recreate the Service to use a cloud load balancer, just change the `Type` of `my-nginx` Service from `NodePort` to `LoadBalancer`:
|
||||
Let's now recreate the Service to use a cloud load balancer. Change the `Type` of `my-nginx` Service from `NodePort` to `LoadBalancer`:
|
||||
-->
|
||||
|
||||
让我们重新创建一个 Service,使用一个云负载均衡器,只需要将 `my-nginx` Service 的 `Type`
|
||||
由 `NodePort` 改成 `LoadBalancer`。
|
||||
让我们重新创建一个 Service 以使用云负载均衡器。
|
||||
将 `my-nginx` Service 的 `Type` 由 `NodePort` 改成 `LoadBalancer`:
|
||||
|
||||
```shell
|
||||
kubectl edit svc my-nginx
|
||||
@@ -616,17 +599,15 @@ output, in fact, so you'll need to do `kubectl describe service my-nginx` to
|
||||
see it. You'll see something like this:
|
||||
-->
|
||||
|
||||
在 `EXTERNAL-IP` 列指定的 IP 地址是在公网上可用的。`CLUSTER-IP` 只在集群/私有云网络中可用。
|
||||
在 `EXTERNAL-IP` 列中的 IP 地址能在公网上被访问到。`CLUSTER-IP` 只能从集群/私有云网络中访问。
|
||||
|
||||
注意,在 AWS 上类型 `LoadBalancer` 创建一个 ELB,它使用主机名(比较长),而不是 IP。
|
||||
它太长以至于不能适配标准 `kubectl get svc` 的输出,事实上需要通过执行 `kubectl describe service my-nginx` 命令来查看它。
|
||||
注意,在 AWS 上,类型 `LoadBalancer` 的服务会创建一个 ELB,且 ELB 使用主机名(比较长),而不是 IP。
|
||||
ELB 的主机名太长以至于不能适配标准 `kubectl get svc` 的输出,所以需要通过执行
|
||||
`kubectl describe service my-nginx` 命令来查看它。
|
||||
可以看到类似如下内容:
|
||||
|
||||
```shell
|
||||
kubectl describe service my-nginx
|
||||
```
|
||||
|
||||
```
|
||||
...
|
||||
LoadBalancer Ingress: a320587ffd19711e5a37606cf4a74574-1142138393.us-east-1.elb.amazonaws.com
|
||||
...
|
||||
|
||||
@@ -29,9 +29,9 @@ Ingress 控制器不是随集群自动启动的。
|
||||
基于此页面,你可选择最适合你的集群的 ingress 控制器实现。
|
||||
|
||||
Kubernetes 作为一个项目,目前支持和维护
|
||||
[AWS](https://github.com/kubernetes-sigs/aws-load-balancer-controller#readme),
|
||||
[AWS](https://github.com/kubernetes-sigs/aws-load-balancer-controller#readme)、
|
||||
[GCE](https://git.k8s.io/ingress-gce/README.md)
|
||||
和 [nginx](https://git.k8s.io/ingress-nginx/README.md#readme) Ingress 控制器。
|
||||
和 [Nginx](https://git.k8s.io/ingress-nginx/README.md#readme) Ingress 控制器。
|
||||
|
||||
<!-- body -->
|
||||
|
||||
@@ -46,32 +46,37 @@ Kubernetes 作为一个项目,目前支持和维护
|
||||
* [AKS Application Gateway Ingress Controller](https://azure.github.io/application-gateway-kubernetes-ingress/) is an ingress controller that configures the [Azure Application Gateway](https://docs.microsoft.com/azure/application-gateway/overview).
|
||||
* [Ambassador](https://www.getambassador.io/) API Gateway is an [Envoy](https://www.envoyproxy.io)-based ingress
|
||||
controller.
|
||||
* [Apache APISIX ingress controller](https://github.com/apache/apisix-ingress-controller) is an [Apache APISIX](https://github.com/apache/apisix)-based ingress controller.
|
||||
* [Avi Kubernetes Operator](https://github.com/vmware/load-balancer-and-ingress-services-for-kubernetes) provides L4-L7 load-balancing using [VMware NSX Advanced Load Balancer](https://avinetworks.com/).
|
||||
* [BFE Ingress Controller](https://github.com/bfenetworks/ingress-bfe) is a [BFE](https://www.bfe-networks.net)-based ingress controller.
|
||||
* The [Citrix ingress controller](https://github.com/citrix/citrix-k8s-ingress-controller#readme) works with
|
||||
Citrix Application Delivery Controller.
|
||||
* [Contour](https://projectcontour.io/) is an [Envoy](https://www.envoyproxy.io/) based ingress controller.
|
||||
* [EnRoute](https://getenroute.io/) is an [Envoy](https://www.envoyproxy.io) based API gateway that can run as an ingress controller.
|
||||
-->
|
||||
* [AKS 应用程序网关 Ingress 控制器](https://azure.github.io/application-gateway-kubernetes-ingress/)
|
||||
是一个配置 [Azure 应用程序网关](https://docs.microsoft.com/azure/application-gateway/overview)
|
||||
的 Ingress 控制器。
|
||||
* [Ambassador](https://www.getambassador.io/) API 网关是一个基于
|
||||
[Envoy](https://www.envoyproxy.io) 的 Ingress
|
||||
控制器。
|
||||
[Envoy](https://www.envoyproxy.io) 的 Ingress 控制器。
|
||||
* [Apache APISIX Ingress 控制器](https://github.com/apache/apisix-ingress-controller)
|
||||
是一个基于 [Apache APISIX 网关](https://github.com/apache/apisix) 的 Ingress 控制器。
|
||||
* [Avi Kubernetes Operator](https://github.com/vmware/load-balancer-and-ingress-services-for-kubernetes)
|
||||
使用 [VMware NSX Advanced Load Balancer](https://avinetworks.com/)
|
||||
提供第 4 到第 7 层的负载均衡。
|
||||
* [BFE Ingress 控制器](https://github.com/bfenetworks/ingress-bfe) 是一个基于 [BFE](https://www.bfe-networks.net) 的 Ingress 控制器。
|
||||
<!--
|
||||
* [BFE Ingress Controller](https://github.com/bfenetworks/ingress-bfe) is a [BFE](https://www.bfe-networks.net)-based ingress controller.
|
||||
* The [Citrix ingress controller](https://github.com/citrix/citrix-k8s-ingress-controller#readme) works with
|
||||
Citrix Application Delivery Controller.
|
||||
* [Contour](https://projectcontour.io/) is an [Envoy](https://www.envoyproxy.io/) based ingress controller.
|
||||
* [EnRoute](https://getenroute.io/) is an [Envoy](https://www.envoyproxy.io) based API gateway that can run as an ingress controller.
|
||||
* [Easegress IngressController](https://github.com/megaease/easegress/blob/main/doc/reference/ingresscontroller.md) is an [Easegress](https://megaease.com/easegress/) based API gateway that can run as an ingress controller.
|
||||
-->
|
||||
* [BFE Ingress 控制器](https://github.com/bfenetworks/ingress-bfe)是一个基于
|
||||
[BFE](https://www.bfe-networks.net) 的 Ingress 控制器。
|
||||
* [Citrix Ingress 控制器](https://github.com/citrix/citrix-k8s-ingress-controller#readme)
|
||||
可以用来与 Citrix Application Delivery Controller 一起使用。
|
||||
* [Contour](https://projectcontour.io/) 是一个基于 [Envoy](https://www.envoyproxy.io/)
|
||||
的 Ingress 控制器。
|
||||
* [EnRoute](https://getenroute.io/) 是一个基于 [Envoy](https://www.envoyproxy.io) API 网关,
|
||||
可以作为 Ingress 控制器来执行。
|
||||
* [Easegress IngressController](https://github.com/megaease/easegress/blob/main/doc/ingresscontroller.md) 是一个基于 [Easegress](https://megaease.com/easegress/) API 网关,可以作为 Ingress 控制器来执行。
|
||||
* [EnRoute](https://getenroute.io/) 是一个基于 [Envoy](https://www.envoyproxy.io)
|
||||
的 API 网关,可以用作 Ingress 控制器。
|
||||
* [Easegress IngressController](https://github.com/megaease/easegress/blob/main/doc/reference/ingresscontroller.md)
|
||||
是一个基于 [Easegress](https://megaease.com/easegress/) 的 API 网关,可以用作 Ingress 控制器。
|
||||
<!--
|
||||
* F5 BIG-IP [Container Ingress Services for Kubernetes](https://clouddocs.f5.com/containers/latest/userguide/kubernetes/)
|
||||
lets you use an Ingress to configure F5 BIG-IP virtual servers.
|
||||
@@ -88,10 +93,9 @@ Kubernetes 作为一个项目,目前支持和维护
|
||||
[用于 Kubernetes 的容器 Ingress 服务](https://clouddocs.f5.com/products/connectors/k8s-bigip-ctlr/latest)
|
||||
让你能够使用 Ingress 来配置 F5 BIG-IP 虚拟服务器。
|
||||
* [Gloo](https://gloo.solo.io) 是一个开源的、基于 [Envoy](https://www.envoyproxy.io) 的
|
||||
Ingress 控制器,能够提供 API 网关功能,
|
||||
* [HAProxy Ingress](https://haproxy-ingress.github.io/) 针对
|
||||
[HAProxy](https://www.haproxy.org/#desc)
|
||||
的 Ingress 控制器。
|
||||
Ingress 控制器,能够提供 API 网关功能。
|
||||
* [HAProxy Ingress](https://haproxy-ingress.github.io/) 是一个针对
|
||||
[HAProxy](https://www.haproxy.org/#desc) 的 Ingress 控制器。
|
||||
* [用于 Kubernetes 的 HAProxy Ingress 控制器](https://github.com/haproxytech/kubernetes-ingress#readme)
|
||||
也是一个针对 [HAProxy](https://www.haproxy.org/#desc) 的 Ingress 控制器。
|
||||
* [Istio Ingress](https://istio.io/latest/docs/tasks/traffic-management/ingress/kubernetes-ingress/)
|
||||
@@ -101,21 +105,26 @@ Kubernetes 作为一个项目,目前支持和维护
|
||||
is an ingress controller driving [Kong Gateway](https://konghq.com/kong/).
|
||||
* The [NGINX Ingress Controller for Kubernetes](https://www.nginx.com/products/nginx-ingress-controller/)
|
||||
works with the [NGINX](https://www.nginx.com/resources/glossary/nginx/) webserver (as a proxy).
|
||||
* The [Pomerium Ingress Controller](https://www.pomerium.com/docs/k8s/ingress.html) is based on [Pomerium](https://pomerium.com/), which offers context-aware access policy.
|
||||
* [Skipper](https://opensource.zalando.com/skipper/kubernetes/ingress-controller/) HTTP router and reverse proxy for service composition, including use cases like Kubernetes Ingress, designed as a library to build your custom proxy.
|
||||
-->
|
||||
* [用于 Kubernetes 的 Kong Ingress 控制器](https://github.com/Kong/kubernetes-ingress-controller#readme)
|
||||
是一个用来驱动 [Kong Gateway](https://konghq.com/kong/) 的 Ingress 控制器。
|
||||
* [用于 Kubernetes 的 NGINX Ingress 控制器](https://www.nginx.com/products/nginx-ingress-controller/)
|
||||
能够与 [NGINX](https://www.nginx.com/resources/glossary/nginx/)
|
||||
网页服务器(作为代理)一起使用。
|
||||
* [Pomerium Ingress 控制器](https://www.pomerium.com/docs/k8s/ingress.html)
|
||||
基于 [Pomerium](https://pomerium.com/),能提供上下文感知的准入策略。
|
||||
* [Skipper](https://opensource.zalando.com/skipper/kubernetes/ingress-controller/) HTTP
|
||||
路由器和反向代理可用于服务组装,支持包括 Kubernetes Ingress
|
||||
这类使用场景,是一个用以构造你自己的定制代理的库。
|
||||
<!--
|
||||
* The [Traefik Kubernetes Ingress provider](https://doc.traefik.io/traefik/providers/kubernetes-ingress/) is an
|
||||
ingress controller for the [Traefik](https://traefik.io/traefik/) proxy.
|
||||
* [Tyk Operator](https://github.com/TykTechnologies/tyk-operator) extends Ingress with Custom Resources to bring API Management capabilities to Ingress. Tyk Operator works with the Open Source Tyk Gateway & Tyk Cloud control plane.
|
||||
* [Voyager](https://appscode.com/products/voyager) is an ingress controller for
|
||||
[HAProxy](https://www.haproxy.org/#desc).
|
||||
-->
|
||||
* [用于 Kubernetes 的 Kong Ingress 控制器](https://github.com/Kong/kubernetes-ingress-controller#readme)
|
||||
是一个用来驱动 [Kong Gateway](https://konghq.com/kong/) 的 Ingress 控制器。
|
||||
* [用于 Kubernetes 的 NGINX Ingress 控制器](https://www.nginx.com/products/nginx-ingress-controller/)
|
||||
能够与 [NGINX](https://www.nginx.com/resources/glossary/nginx/) Web 服务器(作为代理)
|
||||
一起使用。
|
||||
* [Skipper](https://opensource.zalando.com/skipper/kubernetes/ingress-controller/) HTTP
|
||||
路由器和反向代理可用于服务组装,支持包括 Kubernetes Ingress 这类使用场景,
|
||||
设计用来作为构造你自己的定制代理的库。
|
||||
* [Traefik Kubernetes Ingress 提供程序](https://doc.traefik.io/traefik/providers/kubernetes-ingress/)
|
||||
是一个用于 [Traefik](https://traefik.io/traefik/) 代理的 Ingress 控制器。
|
||||
* [Tyk Operator](https://github.com/TykTechnologies/tyk-operator)
|
||||
@@ -130,23 +139,31 @@ Kubernetes 作为一个项目,目前支持和维护
|
||||
## 使用多个 Ingress 控制器
|
||||
|
||||
<!--
|
||||
You may deploy [any number of ingress controllers](https://git.k8s.io/ingress-nginx/docs/user-guide/multiple-ingress.md#multiple-ingress-controllers)
|
||||
within a cluster. When you create an ingress, you should annotate each ingress with the appropriate
|
||||
[`ingress.class`](https://git.k8s.io/ingress-gce/docs/faq/README.md#how-do-i-run-multiple-ingress-controllers-in-the-same-cluster)
|
||||
to indicate which ingress controller should be used if more than one exists within your cluster.
|
||||
You may deploy any number of ingress controllers using [ingress class](/docs/concepts/services-networking/ingress/#ingress-class)
|
||||
within a cluster. Note the `.metadata.name` of your ingress class resource. When you create an ingress you would need that name to specify the `ingressClassName` field on your Ingress object (refer to [IngressSpec v1 reference](/docs/reference/kubernetes-api/service-resources/ingress-v1/#IngressSpec). `ingressClassName` is a replacement of the older [annotation method](/docs/concepts/services-networking/ingress/#deprecated-annotation).
|
||||
-->
|
||||
你可以使用
|
||||
[Ingress 类](/zh/docs/concepts/services-networking/ingress/#ingress-class)在集群中部署任意数量的
|
||||
Ingress 控制器。
|
||||
请注意你的 Ingress 类资源的 `.metadata.name` 字段。
|
||||
当你创建 Ingress 时,你需要用此字段的值来设置 Ingress 对象的 `ingressClassName` 字段(请参考
|
||||
[IngressSpec v1 reference](/docs/reference/kubernetes-api/service-resources/ingress-v1/#IngressSpec))。
|
||||
`ingressClassName`
|
||||
是之前的[注解](/zh/docs/concepts/services-networking/ingress/#deprecated-annotation)做法的替代。
|
||||
|
||||
If you do not define a class, your cloud provider may use a default ingress controller.
|
||||
<!--
|
||||
If you do not specify an IngressClass for an Ingress, and your cluster has exactly one IngressClass marked as default, then Kubernetes [applies](/docs/concepts/services-networking/ingress/#default-ingress-class) the cluster's default IngressClass to the Ingress.
|
||||
You mark an IngressClass as default by setting the [`ingressclass.kubernetes.io/is-default-class` annotation](/docs/reference/labels-annotations-taints/#ingressclass-kubernetes-io-is-default-class) on that IngressClass, with the string value `"true"`.
|
||||
|
||||
Ideally, all ingress controllers should fulfill this specification, but the various ingress
|
||||
controllers operate slightly differently.
|
||||
-->
|
||||
|
||||
你可以在集群中部署[任意数量的 ingress 控制器](https://git.k8s.io/ingress-nginx/docs/user-guide/multiple-ingress.md#multiple-ingress-controllers)。
|
||||
创建 ingress 时,应该使用适当的
|
||||
[`ingress.class`](https://git.k8s.io/ingress-gce/docs/faq/README.md#how-do-i-run-multiple-ingress-controllers-in-the-same-cluster)
|
||||
注解每个 Ingress 以表明在集群中如果有多个 Ingress 控制器时,应该使用哪个 Ingress 控制器。
|
||||
|
||||
如果不定义 `ingress.class`,云提供商可能使用默认的 Ingress 控制器。
|
||||
如果你不为 Ingress 指定一个 IngressClass,并且你的集群中只有一个 IngressClass 被标记为了集群默认,那么
|
||||
Kubernetes 会[应用](/zh/docs/concepts/services-networking/ingress/#default-ingress-class)此默认
|
||||
IngressClass。
|
||||
你可以通过将
|
||||
[`ingressclass.kubernetes.io/is-default-class` 注解](/zh/docs/reference/labels-annotations-taints/#ingressclass-kubernetes-io-is-default-class)
|
||||
的值设置为 `"true"` 来将一个 IngressClass 标记为集群默认。
|
||||
|
||||
理想情况下,所有 Ingress 控制器都应满足此规范,但各种 Ingress 控制器的操作略有不同。
|
||||
|
||||
|
||||
@@ -31,15 +31,14 @@ For clarity, this guide defines the following terms:
|
||||
* Cluster network: A set of links, logical or physical, that facilitate communication within a cluster according to the Kubernetes [networking model](/docs/concepts/cluster-administration/networking/).
|
||||
* Service: A Kubernetes {{< glossary_tooltip term_id="service" >}} that identifies a set of Pods using {{< glossary_tooltip text="label" term_id="label" >}} selectors. Unless mentioned otherwise, Services are assumed to have virtual IPs only routable within the cluster network.
|
||||
-->
|
||||
* 节点(Node): Kubernetes 集群中其中一台工作机器,是集群的一部分。
|
||||
* 节点(Node): Kubernetes 集群中的一台工作机器,是集群的一部分。
|
||||
* 集群(Cluster): 一组运行由 Kubernetes 管理的容器化应用程序的节点。
|
||||
在此示例和在大多数常见的 Kubernetes 部署环境中,集群中的节点都不在公共网络中。
|
||||
* 边缘路由器(Edge router): 在集群中强制执行防火墙策略的路由器(router)。
|
||||
可以是由云提供商管理的网关,也可以是物理硬件。
|
||||
* 集群网络(Cluster network): 一组逻辑的或物理的连接,根据 Kubernetes
|
||||
* 边缘路由器(Edge Router): 在集群中强制执行防火墙策略的路由器。可以是由云提供商管理的网关,也可以是物理硬件。
|
||||
* 集群网络(Cluster Network): 一组逻辑的或物理的连接,根据 Kubernetes
|
||||
[网络模型](/zh/docs/concepts/cluster-administration/networking/)在集群内实现通信。
|
||||
* 服务(Service):Kubernetes {{< glossary_tooltip text="服务" term_id="service" >}}使用
|
||||
{{< glossary_tooltip text="标签" term_id="label" >}}选择算符(selectors)标识的一组 Pod。
|
||||
* 服务(Service):Kubernetes {{< glossary_tooltip term_id="service" >}},
|
||||
使用{{< glossary_tooltip text="标签" term_id="label" >}}选择器(selectors)辨认一组 Pod。
|
||||
除非另有说明,否则假定服务只具有在集群网络中可路由的虚拟 IP。
|
||||
|
||||
<!--
|
||||
@@ -80,20 +79,20 @@ graph LR;
|
||||
<!--
|
||||
An Ingress may be configured to give Services externally-reachable URLs, load balance traffic, terminate SSL / TLS, and offer name based virtual hosting. An [Ingress controller](/docs/concepts/services-networking/ingress-controllers) is responsible for fulfilling the Ingress, usually with a load balancer, though it may also configure your edge router or additional frontends to help handle the traffic.
|
||||
-->
|
||||
可以将 Ingress 配置为服务提供外部可访问的 URL、负载均衡流量、终止 SSL/TLS,以及提供基于名称的虚拟主机等能力。
|
||||
Ingress 可为 Service 提供外部可访问的 URL、负载均衡流量、终止 SSL/TLS,以及基于名称的虚拟托管。
|
||||
[Ingress 控制器](/zh/docs/concepts/services-networking/ingress-controllers)
|
||||
通常负责通过负载均衡器来实现 Ingress,尽管它也可以配置边缘路由器或其他前端来帮助处理流量。
|
||||
|
||||
<!--
|
||||
An Ingress does not expose arbitrary ports or protocols. Exposing services other than HTTP and HTTPS to the internet typically
|
||||
uses a service of type [Service.Type=NodePort](/docs/concepts/services-networking/service/#nodeport) or
|
||||
uses a service of type [Service.Type=NodePort](/docs/concepts/services-networking/service/#type-nodeport) or
|
||||
[Service.Type=LoadBalancer](/docs/concepts/services-networking/service/#loadbalancer).
|
||||
-->
|
||||
Ingress 不会公开任意端口或协议。
|
||||
将 HTTP 和 HTTPS 以外的服务公开到 Internet 时,通常使用
|
||||
[Service.Type=NodePort](/zh/docs/concepts/services-networking/service/#nodeport)
|
||||
[Service.Type=NodePort](/zh/docs/concepts/services-networking/service/#type-nodeport)
|
||||
或 [Service.Type=LoadBalancer](/zh/docs/concepts/services-networking/service/#loadbalancer)
|
||||
类型的服务。
|
||||
类型的 Service。
|
||||
|
||||
<!--
|
||||
## Prerequisites
|
||||
@@ -102,7 +101,7 @@ You must have an [ingress controller](/docs/concepts/services-networking/ingress
|
||||
-->
|
||||
## 环境准备
|
||||
|
||||
你必须具有 [Ingress 控制器](/zh/docs/concepts/services-networking/ingress-controllers) 才能满足 Ingress 的要求。
|
||||
你必须拥有一个 [Ingress 控制器](/zh/docs/concepts/services-networking/ingress-controllers) 才能满足 Ingress 的要求。
|
||||
仅创建 Ingress 资源本身没有任何效果。
|
||||
|
||||
<!--
|
||||
@@ -144,29 +143,47 @@ The name of an Ingress object must be a valid
|
||||
For general information about working with config files, see [deploying applications](/docs/tasks/run-application/run-stateless-application-deployment/), [configuring containers](/docs/tasks/configure-pod-container/configure-pod-configmap/), [managing resources](/docs/concepts/cluster-administration/manage-deployment/).
|
||||
Ingress frequently uses annotations to configure some options depending on the Ingress controller, an example of which
|
||||
is the [rewrite-target annotation](https://github.com/kubernetes/ingress-nginx/blob/master/docs/examples/rewrite/README.md).
|
||||
Different [Ingress controller](/docs/concepts/services-networking/ingress-controllers) support different annotations. Review the documentation for
|
||||
Different [Ingress controllers](/docs/concepts/services-networking/ingress-controllers) support different annotations. Review the documentation for
|
||||
your choice of Ingress controller to learn which annotations are supported.
|
||||
-->
|
||||
与所有其他 Kubernetes 资源一样,Ingress 需要使用 `apiVersion`、`kind` 和 `metadata` 字段。
|
||||
与所有其他 Kubernetes 资源一样,Ingress 需要指定 `apiVersion`、`kind` 和 `metadata` 字段。
|
||||
Ingress 对象的命名必须是合法的 [DNS 子域名名称](/zh/docs/concepts/overview/working-with-objects/names#dns-subdomain-names)。
|
||||
有关使用配置文件的一般信息,请参见[部署应用](/zh/docs/tasks/run-application/run-stateless-application-deployment/)、
|
||||
关于如何使用配置文件,请参见[部署应用](/zh/docs/tasks/run-application/run-stateless-application-deployment/)、
|
||||
[配置容器](/zh/docs/tasks/configure-pod-container/configure-pod-configmap/)、
|
||||
[管理资源](/zh/docs/concepts/cluster-administration/manage-deployment/)。
|
||||
Ingress 经常使用注解(annotations)来配置一些选项,具体取决于 Ingress 控制器,例如
|
||||
[重写目标注解](https://github.com/kubernetes/ingress-nginx/blob/master/docs/examples/rewrite/README.md)。
|
||||
不同的 [Ingress 控制器](/zh/docs/concepts/services-networking/ingress-controllers)
|
||||
支持不同的注解。查看文档以供你选择 Ingress 控制器,以了解支持哪些注解。
|
||||
Ingress 经常使用注解(annotations)来配置一些选项,具体取决于 Ingress
|
||||
控制器,例如[重写目标注解](https://github.com/kubernetes/ingress-nginx/blob/master/docs/examples/rewrite/README.md)。
|
||||
不同的 [Ingress 控制器](/zh/docs/concepts/services-networking/ingress-controllers)支持不同的注解。
|
||||
查看你所选的 Ingress 控制器的文档,以了解其支持哪些注解。
|
||||
|
||||
<!--
|
||||
The Ingress [spec](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status)
|
||||
has all the information needed to configure a load balancer or proxy server. Most importantly, it
|
||||
contains a list of rules matched against all incoming requests. Ingress resource only supports rules
|
||||
for directing HTTP traffic.
|
||||
for directing HTTP(S) traffic.
|
||||
-->
|
||||
Ingress [规约](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status)
|
||||
提供了配置负载均衡器或者代理服务器所需的所有信息。
|
||||
最重要的是,其中包含与所有传入请求匹配的规则列表。
|
||||
Ingress 资源仅支持用于转发 HTTP 流量的规则。
|
||||
Ingress 资源仅支持用于转发 HTTP(S) 流量的规则。
|
||||
|
||||
<!--
|
||||
If the `ingressClassName` is omitted, a [default Ingress class](#default-ingress-class)
|
||||
should be defined.
|
||||
|
||||
There are some ingress controllers, that work without the definition of a
|
||||
default `IngressClass`. For example, the Ingress-NGINX controller can be
|
||||
configured with a [flag](https://kubernetes.github.io/ingress-nginx/#what-is-the-flag-watch-ingress-without-class)
|
||||
`--watch-ingress-without-class`. It is [recommended](https://kubernetes.github.io/ingress-nginx/#i-have-only-one-instance-of-the-ingresss-nginx-controller-in-my-cluster-what-should-i-do) though, to specify the
|
||||
default `IngressClass` as shown [below](#default-ingress-class).
|
||||
-->
|
||||
如果 `ingressClassName` 被省略,那么你应该定义一个[默认 Ingress 类](#default-ingress-class)。
|
||||
|
||||
有一些 Ingress 控制器不需要定义默认的 `IngressClass`。比如:Ingress-NGINX
|
||||
控制器可以通过[参数](https://kubernetes.github.io/ingress-nginx/#what-is-the-flag-watch-ingress-without-class)
|
||||
`--watch-ingress-without-class` 来配置。
|
||||
不过仍然[推荐](https://kubernetes.github.io/ingress-nginx/#i-have-only-one-instance-of-the-ingresss-nginx-controller-in-my-cluster-what-should-i-do)
|
||||
按[下文](#default-ingress-class)所示来设置默认的 `IngressClass`。
|
||||
|
||||
<!--
|
||||
### Ingress rules
|
||||
@@ -199,24 +216,35 @@ Each HTTP rule contains the following information:
|
||||
A `defaultBackend` is often configured in an Ingress controller to service any requests that do not
|
||||
match a path in the spec.
|
||||
-->
|
||||
通常在 Ingress 控制器中会配置 `defaultBackend`(默认后端),以服务于任何不符合规约中 `path` 的请求。
|
||||
通常在 Ingress 控制器中会配置 `defaultBackend`(默认后端),以服务于无法与规约中 `path` 匹配的所有请求。
|
||||
|
||||
<!--
|
||||
### DefaultBackend {#default-backend}
|
||||
|
||||
An Ingress with no rules sends all traffic to a single default backend. The `defaultBackend` is conventionally a configuration option of the [Ingress controller](/docs/concepts/services-networking/ingress-controllers) and is not specified in your Ingress resources.
|
||||
-->
|
||||
### DefaultBackend {#default-backend}
|
||||
An Ingress with no rules sends all traffic to a single default backend and `.spec.defaultBackend`
|
||||
is the backend that should handle requests in that case.
|
||||
The `defaultBackend` is conventionally a configuration option of the
|
||||
[Ingress controller](/docs/concepts/services-networking/ingress-controllers) and
|
||||
is not specified in your Ingress resources.
|
||||
If no `.spec.rules` are specified, `.spec.defaultBackend` must be specified.
|
||||
If `defaultBackend` is not set, the handling of requests that do not match any of the rules will be up to the
|
||||
ingress controller (consult the documentation for your ingress controller to find out how it handles this case).
|
||||
|
||||
没有 `rules` 的 Ingress 将所有流量发送到同一个默认后端。
|
||||
`defaultBackend` 通常是 [Ingress 控制器](/zh/docs/concepts/services-networking/ingress-controllers)
|
||||
的配置选项,而非在 Ingress 资源中指定。
|
||||
|
||||
<!--
|
||||
If none of the hosts or paths match the HTTP request in the Ingress objects, the traffic is
|
||||
routed to your default backend.
|
||||
-->
|
||||
如果 `hosts` 或 `paths` 都没有与 Ingress 对象中的 HTTP 请求匹配,则流量将路由到默认后端。
|
||||
### 默认后端 {#default-backend}
|
||||
|
||||
没有设置规则的 Ingress 将所有流量发送到同一个默认后端,而
|
||||
`.spec.defaultBackend` 则是在这种情况下处理请求的那个默认后端。
|
||||
`defaultBackend` 通常是
|
||||
[Ingress 控制器](/zh/docs/concepts/services-networking/ingress-controllers)的配置选项,而非在
|
||||
Ingress 资源中指定。
|
||||
如果未设置任何的 `.spec.rules`,那么必须指定 `.spec.defaultBackend`。
|
||||
如果未设置 `defaultBackend`,那么如何处理所有与规则不匹配的流量将交由
|
||||
Ingress 控制器决定(请参考你的 Ingress 控制器的文档以了解它是如何处理那些流量的)。
|
||||
|
||||
如果没有 `hosts` 或 `paths` 与 Ingress 对象中的 HTTP 请求匹配,则流量将被路由到默认后端。
|
||||
|
||||
<!--
|
||||
### Resource backends {#resource-backend}
|
||||
@@ -229,9 +257,8 @@ with static assets.
|
||||
-->
|
||||
### 资源后端 {#resource-backend}
|
||||
|
||||
`Resource` 后端是一个 `ObjectRef`,指向同一名字空间中的另一个
|
||||
Kubernetes,将其作为 Ingress 对象。`Resource` 与 `Service` 配置是互斥的,在
|
||||
二者均被设置时会无法通过合法性检查。
|
||||
`Resource` 后端是一个引用,指向同一命名空间中的另一个 Kubernetes 资源,将其作为 Ingress 对象。
|
||||
`Resource` 后端与 Service 后端是互斥的,在二者均被设置时会无法通过合法性检查。
|
||||
`Resource` 后端的一种常见用法是将所有入站数据导向带有静态资产的对象存储后端。
|
||||
|
||||
{{< codenew file="service/networking/ingress-resource-backend.yaml" >}}
|
||||
@@ -410,41 +437,140 @@ IngressClass 资源包含额外的配置,其中包括应当实现该类的控
|
||||
{{< codenew file="service/networking/external-lb.yaml" >}}
|
||||
|
||||
<!--
|
||||
IngressClass resources contain an optional parameters field. This can be used to
|
||||
reference additional implementation-specific configuration for this class.
|
||||
The `.spec.parameters` field of an IngressClass lets you reference another
|
||||
resource that provides configuration related to that IngressClass.
|
||||
|
||||
The specific type of parameters to use depends on the ingress controller
|
||||
that you specify in the `.spec.controller` field of the IngressClass.
|
||||
-->
|
||||
IngressClass 资源包含一个可选的 `parameters` 字段,可用于为该类引用额外的、
|
||||
特定于具体实现的配置。
|
||||
IngressClass 中的 `.spec.parameters` 字段可用于引用其他资源以提供额外的相关配置。
|
||||
|
||||
参数(`parameters`)的具体类型取决于你在 `.spec.controller` 字段中指定的 Ingress 控制器。
|
||||
|
||||
<!--
|
||||
#### Namespace-scoped parameters
|
||||
-->
|
||||
#### 名字空间域的参数
|
||||
### IngressClass scope
|
||||
|
||||
{{< feature-state for_k8s_version="v1.22" state="beta" >}}
|
||||
Depending on your ingress controller, you may be able to use parameters
|
||||
that you set cluster-wide, or just for one namespace.
|
||||
-->
|
||||
### IngressClass 的作用域
|
||||
|
||||
取决于你的 Ingress 控制器,你可能可以使用集群范围设置的参数或某个名字空间范围的参数。
|
||||
|
||||
{{< tabs name="tabs_ingressclass_parameter_scope" >}}
|
||||
{{% tab name="集群作用域" %}}
|
||||
<!--
|
||||
The default scope for IngressClass parameters is cluster-wide.
|
||||
|
||||
If you set the `.spec.parameters` field and don't set
|
||||
`.spec.parameters.scope`, or if you set `.spec.parameters.scope` to
|
||||
`Cluster`, then the IngressClass refers to a cluster-scoped resource.
|
||||
The `kind` (in combination the `apiGroup`) of the parameters
|
||||
refers to a cluster-scoped API (possibly a custom resource), and
|
||||
the `name` of the parameters identifies a specific cluster scoped
|
||||
resource for that API.
|
||||
|
||||
For example:
|
||||
-->
|
||||
IngressClass 的参数默认是集群范围的。
|
||||
|
||||
如果你设置了 `.spec.parameters` 字段且未设置 `.spec.parameters.scope`
|
||||
字段,或是将 `.spec.parameters.scope` 字段设为了 `Cluster`,那么该
|
||||
IngressClass 所指代的即是一个集群作用域的资源。
|
||||
参数的 `kind`(和 `apiGroup` 一起)指向一个集群作用域的
|
||||
API(可能是一个定制资源(Custom Resource)),而它的
|
||||
`name` 则为此 API 确定了一个具体的集群作用域的资源。
|
||||
|
||||
示例:
|
||||
```yaml
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: IngressClass
|
||||
metadata:
|
||||
name: external-lb-1
|
||||
spec:
|
||||
controller: example.com/ingress-controller
|
||||
parameters:
|
||||
# 此 IngressClass 的配置定义在一个名为 “external-config-1” 的
|
||||
# ClusterIngressParameter(API 组为 k8s.example.net)资源中。
|
||||
# 这项定义告诉 Kubernetes 去寻找一个集群作用域的参数资源。
|
||||
scope: Cluster
|
||||
apiGroup: k8s.example.net
|
||||
kind: ClusterIngressParameter
|
||||
name: external-config-1
|
||||
```
|
||||
{{% /tab %}}
|
||||
{{% tab name="命名空间作用域" %}}
|
||||
{{< feature-state for_k8s_version="v1.23" state="stable" >}}
|
||||
|
||||
<!--
|
||||
`Parameters` field has a `scope` and `namespace` field that can be used to
|
||||
reference a namespace-specific resource for configuration of an Ingress class.
|
||||
`Scope` field defaults to `Cluster`, meaning, the default is cluster-scoped
|
||||
resource. Setting `Scope` to `Namespace` and setting the `Namespace` field
|
||||
will reference a parameters resource in a specific namespace:
|
||||
If you set the `.spec.parameters` field and set
|
||||
`.spec.parameters.scope` to `Namespace`, then the IngressClass refers
|
||||
to a namespaced-scoped resource. You must also set the `namespace`
|
||||
field within `.spec.parameters` to the namespace that contains
|
||||
the parameters you want to use.
|
||||
|
||||
Namespace-scoped parameters avoid the need for a cluster-scoped CustomResourceDefinition
|
||||
for a parameters resource. This further avoids RBAC-related resources
|
||||
that would otherwise be required to grant permissions to cluster-scoped
|
||||
resources.
|
||||
The `kind` (in combination the `apiGroup`) of the parameters
|
||||
refers to a namespaced API (for example: ConfigMap), and
|
||||
the `name` of the parameters identifies a specific resource
|
||||
in the namespace you specified in `namespace`.
|
||||
-->
|
||||
`parameters` 字段有一个 `scope` 和 `namespace` 字段,可用来引用特定
|
||||
于名字空间的资源,对 Ingress 类进行配置。
|
||||
`scope` 字段默认为 `Cluster`,表示默认是集群作用域的资源。
|
||||
将 `scope` 设置为 `Namespace` 并设置 `namespace` 字段就可以引用某特定
|
||||
名字空间中的参数资源。
|
||||
如果你设置了 `.spec.parameters` 字段且将 `.spec.parameters.scope`
|
||||
字段设为了 `Namespace`,那么该 IngressClass 将会引用一个命名空间作用域的资源。
|
||||
`.spec.parameters.namespace` 必须和此资源所处的命名空间相同。
|
||||
|
||||
有了名字空间域的参数,就不再需要为一个参数资源配置集群范围的 CustomResourceDefinition。
|
||||
除此之外,之前对访问集群范围的资源进行授权,需要用到 RBAC 相关的资源,现在也不再需要了。
|
||||
参数的 `kind`(和 `apiGroup`
|
||||
一起)指向一个命名空间作用域的 API(例如:ConfigMap),而它的
|
||||
`name` 则确定了一个位于你指定的命名空间中的具体的资源。
|
||||
|
||||
{{< codenew file="service/networking/namespaced-params.yaml" >}}
|
||||
<!--
|
||||
Namespace-scoped parameters help the cluster operator delegate control over the
|
||||
configuration (for example: load balancer settings, API gateway definition)
|
||||
that is used for a workload. If you used a cluster-scoped parameter then either:
|
||||
|
||||
- the cluster operator team needs to approve a different team's changes every
|
||||
time there's a new configuration change being applied.
|
||||
- the cluster operator must define specific access controls, such as
|
||||
[RBAC](/docs/reference/access-authn-authz/rbac/) roles and bindings, that let
|
||||
the application team make changes to the cluster-scoped parameters resource.
|
||||
-->
|
||||
命名空间作用域的参数帮助集群操作者将控制细分到用于工作负载的各种配置中(比如:负载均衡设置、API
|
||||
网关定义)。如果你使用集群作用域的参数,那么你必须从以下两项中选择一项执行:
|
||||
|
||||
- 每次修改配置,集群操作团队需要批准其他团队的修改。
|
||||
- 集群操作团队定义具体的准入控制,比如 [RBAC](/zh/docs/reference/access-authn-authz/rbac/)
|
||||
角色与角色绑定,以使得应用程序团队可以修改集群作用域的配置参数资源。
|
||||
|
||||
<!--
|
||||
The IngressClass API itself is always cluster-scoped.
|
||||
|
||||
Here is an example of an IngressClass that refers to parameters that are
|
||||
namespaced:
|
||||
-->
|
||||
IngressClass API 本身是集群作用域的。
|
||||
|
||||
这里是一个引用命名空间作用域的配置参数的 IngressClass 的示例:
|
||||
```yaml
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: IngressClass
|
||||
metadata:
|
||||
name: external-lb-2
|
||||
spec:
|
||||
controller: example.com/ingress-controller
|
||||
parameters:
|
||||
# 此 IngressClass 的配置定义在一个名为 “external-config” 的
|
||||
# IngressParameter(API 组为 k8s.example.com)资源中,
|
||||
# 该资源位于 “external-configuration” 命名空间中。
|
||||
scope: Namespace
|
||||
apiGroup: k8s.example.com
|
||||
kind: IngressParameter
|
||||
namespace: external-configuration
|
||||
name: external-config
|
||||
```
|
||||
|
||||
{{% /tab %}}
|
||||
{{< /tabs >}}
|
||||
|
||||
<!--
|
||||
### Deprecated Annotation
|
||||
@@ -456,8 +582,8 @@ never formally defined, but was widely supported by Ingress controllers.
|
||||
-->
|
||||
### 废弃的注解 {#deprecated-annotation}
|
||||
|
||||
在 Kubernetes 1.18 版本引入 IngressClass 资源和 `ingressClassName` 字段之前,
|
||||
Ingress 类是通过 Ingress 中的一个 `kubernetes.io/ingress.class` 注解来指定的。
|
||||
在 Kubernetes 1.18 版本引入 IngressClass 资源和 `ingressClassName` 字段之前,Ingress
|
||||
类是通过 Ingress 中的一个 `kubernetes.io/ingress.class` 注解来指定的。
|
||||
这个注解从未被正式定义过,但是得到了 Ingress 控制器的广泛支持。
|
||||
|
||||
<!--
|
||||
@@ -468,9 +594,8 @@ Ingress, the field is a reference to an IngressClass resource that contains
|
||||
additional Ingress configuration, including the name of the Ingress controller.
|
||||
-->
|
||||
Ingress 中新的 `ingressClassName` 字段是该注解的替代品,但并非完全等价。
|
||||
该注解通常用于引用实现该 Ingress 的控制器的名称,
|
||||
而这个新的字段则是对一个包含额外 Ingress 配置的 IngressClass 资源的引用,
|
||||
包括 Ingress 控制器的名称。
|
||||
该注解通常用于引用实现该 Ingress 的控制器的名称,而这个新的字段则是对一个包含额外
|
||||
Ingress 配置的 IngressClass 资源的引用,包括 Ingress 控制器的名称。
|
||||
|
||||
<!--
|
||||
### Default IngressClass {#default-ingress-class}
|
||||
@@ -499,6 +624,21 @@ IngressClasess are marked as default in your cluster.
|
||||
解决这个问题只需确保集群中最多只能有一个 IngressClass 被标记为默认。
|
||||
{{< /caution >}}
|
||||
|
||||
<!--
|
||||
There are some ingress controllers, that work without the definition of a
|
||||
default `IngressClass`. For example, the Ingress-NGINX controller can be
|
||||
configured with a [flag](https://kubernetes.github.io/ingress-nginx/#what-is-the-flag-watch-ingress-without-class)
|
||||
`--watch-ingress-without-class`. It is [recommended](https://kubernetes.github.io/ingress-nginx/#i-have-only-one-instance-of-the-ingresss-nginx-controller-in-my-cluster-what-should-i-do) though, to specify the
|
||||
default `IngressClass`:
|
||||
-->
|
||||
有一些 Ingress 控制器不需要定义默认的 `IngressClass`。比如:Ingress-NGINX
|
||||
控制器可以通过[参数](https://kubernetes.github.io/ingress-nginx/#what-is-the-flag-watch-ingress-without-class)
|
||||
`--watch-ingress-without-class` 来配置。
|
||||
不过仍然[推荐](https://kubernetes.github.io/ingress-nginx/#i-have-only-one-instance-of-the-ingresss-nginx-controller-in-my-cluster-what-should-i-do)
|
||||
设置默认的 `IngressClass`。
|
||||
|
||||
{{< codenew file="service/networking/default-ingressclass.yaml" >}}
|
||||
|
||||
<!--
|
||||
## Types of Ingress
|
||||
|
||||
@@ -682,14 +822,10 @@ Ingress 控制器 IP 地址的任何网络流量,而无需基于名称的虚
|
||||
|
||||
<!--
|
||||
For example, the following Ingress routes traffic
|
||||
requested for `first.bar.com` to `service1`, `second.bar.com` to `service2`, and any traffic
|
||||
to the IP address without a hostname defined in request (that is, without a request header being
|
||||
presented) to `service3`.
|
||||
requested for `first.bar.com` to `service1`, `second.bar.com` to `service2`, and any traffic whose request host header doesn't match `first.bar.com` and `second.bar.com` to `service3`.
|
||||
-->
|
||||
例如,以下 Ingress 会将针对 `first.bar.com` 的请求流量路由到 `service1`,
|
||||
将针对 `second.bar.com` 的请求流量路由到 `service2`,
|
||||
而针对该 IP 地址的、没有在请求中定义主机名的请求流量会被路由(即,不提供请求标头)
|
||||
到 `service3`。
|
||||
例如,以下 Ingress 会将请求 `first.bar.com` 的流量路由到 `service1`,将请求
|
||||
`second.bar.com` 的流量路由到 `service2`,而所有其他流量都会被路由到 `service3`。
|
||||
|
||||
{{< codenew file="service/networking/name-virtual-host-ingress-no-third-host.yaml" >}}
|
||||
|
||||
@@ -710,12 +846,12 @@ and private key to use for TLS. For example:
|
||||
|
||||
你可以通过设定包含 TLS 私钥和证书的{{< glossary_tooltip text="Secret" term_id="secret" >}}
|
||||
来保护 Ingress。
|
||||
Ingress 只支持单个 TLS 端口 443,并假定 TLS 连接终止于 Ingress 节点
|
||||
(与 Service 及其 Pod 之间的流量都以明文传输)。
|
||||
如果 Ingress 中的 TLS 配置部分指定了不同的主机,那么它们将根据通过 SNI TLS 扩展指定的主机名
|
||||
(如果 Ingress 控制器支持 SNI)在同一端口上进行复用。
|
||||
TLS Secret 必须包含名为 `tls.crt` 和 `tls.key` 的键名。
|
||||
这些数据包含用于 TLS 的证书和私钥。例如:
|
||||
Ingress 只支持单个 TLS 端口 443,并假定 TLS 连接终止于
|
||||
Ingress 节点(与 Service 及其 Pod 之间的流量都以明文传输)。
|
||||
如果 Ingress 中的 TLS 配置部分指定了不同的主机,那么它们将根据通过
|
||||
SNI TLS 扩展指定的主机名(如果 Ingress 控制器支持 SNI)在同一端口上进行复用。
|
||||
TLS Secret 的数据中必须包含用于 TLS 的以键名 `tls.crt` 保存的证书和以键名 `tls.key` 保存的私钥。
|
||||
例如:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
@@ -724,8 +860,8 @@ metadata:
|
||||
name: testsecret-tls
|
||||
namespace: default
|
||||
data:
|
||||
tls.crt: base64 编码的 cert
|
||||
tls.key: base64 编码的 key
|
||||
tls.crt: base64 编码的证书
|
||||
tls.key: base64 编码的私钥
|
||||
type: kubernetes.io/tls
|
||||
```
|
||||
|
||||
@@ -747,8 +883,7 @@ certificates would have to be issued for all the possible sub-domains. Therefore
|
||||
section.
|
||||
-->
|
||||
注意,默认规则上无法使用 TLS,因为需要为所有可能的子域名发放证书。
|
||||
因此,`tls` 节区的 `hosts` 的取值需要域 `rules` 节区的 `host`
|
||||
完全匹配。
|
||||
因此,`tls` 字段中的 `hosts` 的取值需要与 `rules` 字段中的 `host` 完全匹配。
|
||||
{{< /note >}}
|
||||
|
||||
{{< codenew file="service/networking/tls-example-ingress.yaml" >}}
|
||||
@@ -779,8 +914,8 @@ a Service.
|
||||
-->
|
||||
### 负载均衡 {#load-balancing}
|
||||
|
||||
Ingress 控制器启动引导时使用一些适用于所有 Ingress 的负载均衡策略设置,
|
||||
例如负载均衡算法、后端权重方案和其他等。
|
||||
Ingress 控制器启动引导时使用一些适用于所有 Ingress
|
||||
的负载均衡策略设置,例如负载均衡算法、后端权重方案等。
|
||||
更高级的负载均衡概念(例如持久会话、动态权重)尚未通过 Ingress 公开。
|
||||
你可以通过用于服务的负载均衡器来获取这些功能。
|
||||
|
||||
@@ -797,10 +932,8 @@ specific documentation to see how they handle health checks (
|
||||
中存在并行的概念,比如
|
||||
[就绪检查](/zh/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/),
|
||||
允许你实现相同的目的。
|
||||
请检查特定控制器的说明文档(
|
||||
[nginx](https://git.k8s.io/ingress-nginx/README.md),
|
||||
[GCE](https://git.k8s.io/ingress-gce/README.md#health-checks))
|
||||
以了解它们是怎样处理健康检查的。
|
||||
请检查特定控制器的说明文档([nginx](https://git.k8s.io/ingress-nginx/README.md)、
|
||||
[GCE](https://git.k8s.io/ingress-gce/README.md#health-checks))以了解它们是怎样处理健康检查的。
|
||||
|
||||
<!--
|
||||
## Updating an Ingress
|
||||
@@ -916,8 +1049,7 @@ Please check the documentation of the relevant [Ingress controller](/docs/concep
|
||||
## 跨可用区失败 {#failing-across-availability-zones}
|
||||
|
||||
不同的云厂商使用不同的技术来实现跨故障域的流量分布。详情请查阅相关 Ingress 控制器的文档。
|
||||
请查看相关 [Ingress 控制器](/zh/docs/concepts/services-networking/ingress-controllers)
|
||||
的文档以了解详细信息。
|
||||
请查看相关 [Ingress 控制器](/zh/docs/concepts/services-networking/ingress-controllers)的文档以了解详细信息。
|
||||
|
||||
<!--
|
||||
## Alternatives
|
||||
@@ -938,11 +1070,11 @@ You can expose a Service in multiple ways that don't directly involve the Ingres
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
<!--
|
||||
* Learn about the [Ingress API](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#ingress-v1-networking-k8s-io)
|
||||
* Learn about the [Ingress](/docs/reference/kubernetes-api/service-resources/ingress-v1/) API
|
||||
* Learn about [Ingress Controllers](/docs/concepts/services-networking/ingress-controllers/)
|
||||
* [Set up Ingress on Minikube with the NGINX Controller](/docs/tasks/access-application-cluster/ingress-minikube/)
|
||||
-->
|
||||
* 进一步了解 [Ingress API](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#ingress-v1beta1-networking-k8s-io)
|
||||
* 进一步了解 [Ingress](/docs/reference/kubernetes-api/service-resources/ingress-v1/) API
|
||||
* 进一步了解 [Ingress 控制器](/zh/docs/concepts/services-networking/ingress-controllers/)
|
||||
* [使用 NGINX 控制器在 Minikube 上安装 Ingress](/zh/docs/tasks/access-application-cluster/ingress-minikube/)
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ services are often limited by memory size and can move infrequently
|
||||
used data into storage that is slower than memory with little impact
|
||||
on overall performance.
|
||||
-->
|
||||
有些应用程序需要额外的存储,但并不关心数据在重启后仍然可用,既是否被持久地保存。
|
||||
有些应用程序需要额外的存储,但并不关心数据在重启后仍然可用。
|
||||
例如,缓存服务经常受限于内存大小,将不常用的数据转移到比内存慢、但对总体性能的影响很小的存储中。
|
||||
|
||||
<!--
|
||||
@@ -219,15 +219,7 @@ As a cluster administrator, you can use a [PodSecurityPolicy](/docs/concepts/pol
|
||||
-->
|
||||
### 通用临时卷 {#generic-ephemeral-volumes}
|
||||
|
||||
{{< feature-state for_k8s_version="v1.21" state="beta" >}}
|
||||
|
||||
<!--
|
||||
This feature requires the `GenericEphemeralVolume` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/) to be
|
||||
enabled. Because this is a beta feature, it is enabled by default.
|
||||
-->
|
||||
这个特性需要启用 `GenericEphemeralVolume`
|
||||
[特性门控](/zh/docs/reference/command-line-tools-reference/feature-gates/)。
|
||||
因为这是一个 beta 特性,默认情况下启用。
|
||||
{{< feature-state for_k8s_version="v1.23" state="stable" >}}
|
||||
|
||||
<!--
|
||||
Generic ephemeral volumes are similar to `emptyDir` volumes in the
|
||||
@@ -419,7 +411,6 @@ two choices:
|
||||
如果这不符合他们的安全模型,他们有如下选择:
|
||||
|
||||
<!--
|
||||
- Explicitly disable the feature through the feature gate.
|
||||
- Use a [Pod Security
|
||||
Policy](/docs/concepts/policy/pod-security-policy/) where the
|
||||
`volumes` list does not contain the `ephemeral` volume type
|
||||
@@ -473,11 +464,8 @@ See [local ephemeral storage](/docs/concepts/configuration/manage-resources-cont
|
||||
|
||||
- For more information on the design, see the
|
||||
[Generic ephemeral inline volumes KEP](https://github.com/kubernetes/enhancements/blob/master/keps/sig-storage/1698-generic-ephemeral-volumes/README.md).
|
||||
- For more information on further development of this feature, see the [enhancement tracking issue #1698](https://github.com/kubernetes/enhancements/issues/1698).
|
||||
-->
|
||||
### 通用临时卷 {#generic-ephemeral-volumes}
|
||||
|
||||
- 有关设计的更多信息,参阅
|
||||
[Generic ephemeral inline volumes KEP](https://github.com/kubernetes/enhancements/blob/master/keps/sig-storage/1698-generic-ephemeral-volumes/README.md)。
|
||||
- 关于本特性下一步开发的更多信息,参阅
|
||||
[enhancement tracking issue #1698](https://github.com/kubernetes/enhancements/issues/1698)。
|
||||
|
||||
@@ -666,7 +666,7 @@ size that is within the capacity limits of underlying storage provider. You can
|
||||
|
||||
<!--
|
||||
Note that,
|
||||
although you can a specify a lower amount of storage than what was requested previously,
|
||||
although you can specify a lower amount of storage than what was requested previously,
|
||||
the new value must still be higher than `.status.capacity`.
|
||||
Kubernetes does not support shrinking a PVC to less than its current size.
|
||||
-->
|
||||
@@ -810,7 +810,7 @@ Helper programs relating to the volume type may be required for consumption of a
|
||||
<!--
|
||||
### Capacity
|
||||
|
||||
Generally, a PV will have a specific storage capacity. This is set using the PV's `capacity` attribute. See the Kubernetes [Resource Model](https://git.k8s.io/community/contributors/design-proposals/scheduling/resources.md) to understand the units expected by `capacity`.
|
||||
Generally, a PV will have a specific storage capacity. This is set using the PV's `capacity` attribute. Read the glossary term [Quantity](/docs/reference/glossary/?all=true#term-quantity) to understand the units expected by `capacity`.
|
||||
|
||||
Currently, storage size is the only resource that can be set or requested. Future attributes may include IOPS, throughput, etc.
|
||||
-->
|
||||
@@ -818,9 +818,9 @@ Currently, storage size is the only resource that can be set or requested. Futu
|
||||
|
||||
一般而言,每个 PV 卷都有确定的存储容量。
|
||||
容量属性是使用 PV 对象的 `capacity` 属性来设置的。
|
||||
参考 Kubernetes
|
||||
[资源模型(Resource Model)](https://git.k8s.io/community/contributors/design-proposals/scheduling/resources.md)
|
||||
设计提案,了解 `capacity` 字段可以接受的单位。
|
||||
参考词汇表中的
|
||||
[量纲(Quantity)](/zh/docs/reference/glossary/?all=true#term-quantity)
|
||||
词条,了解 `capacity` 字段可以接受的单位。
|
||||
|
||||
目前,存储大小是可以设置和请求的唯一资源。
|
||||
未来可能会包含 IOPS、吞吐量等属性。
|
||||
@@ -1038,19 +1038,19 @@ The following volume types support mount options:
|
||||
-->
|
||||
以下卷类型支持挂载选项:
|
||||
|
||||
* AWSElasticBlockStore
|
||||
* AzureDisk
|
||||
* AzureFile
|
||||
* CephFS
|
||||
* Cinder (OpenStack 块存储)
|
||||
* GCEPersistentDisk
|
||||
* Glusterfs
|
||||
* NFS
|
||||
* Quobyte 卷
|
||||
* RBD (Ceph 块设备)
|
||||
* StorageOS
|
||||
* VsphereVolume
|
||||
* iSCSI
|
||||
* `awsElasticBlockStore`
|
||||
* `azureDisk`
|
||||
* `azureFile`
|
||||
* `cephfs`
|
||||
* `cinder` (**已弃用**于 v1.18)
|
||||
* `gcePersistentDisk`
|
||||
* `glusterfs`
|
||||
* `iscsi`
|
||||
* `nfs`
|
||||
* `quobyte` (**已弃用**于 v1.22)
|
||||
* `rbd`
|
||||
* `storageos` (**已弃用**于 v1.22)
|
||||
* `vsphereVolume`
|
||||
|
||||
<!--
|
||||
Mount options are not validated, If a mount option is invalid, the mount fails.
|
||||
|
||||
@@ -26,15 +26,15 @@ between containers running together in a `Pod`.
|
||||
The Kubernetes {{< glossary_tooltip text="volume" term_id="volume" >}} abstraction
|
||||
solves both of these problems.
|
||||
-->
|
||||
Container 中的文件在磁盘上是临时存放的,这给 Container 中运行的较重要的应用
|
||||
程序带来一些问题。问题之一是当容器崩溃时文件丢失。kubelet 会重新启动容器,
|
||||
但容器会以干净的状态重启。
|
||||
Container 中的文件在磁盘上是临时存放的,这给 Container 中运行的较重要的应用程序带来一些问题。
|
||||
问题之一是当容器崩溃时文件丢失。
|
||||
kubelet 会重新启动容器,但容器会以干净的状态重启。
|
||||
第二个问题会在同一 `Pod` 中运行多个容器并共享文件时出现。
|
||||
Kubernetes {{< glossary_tooltip text="卷(Volume)" term_id="volume" >}}
|
||||
这一抽象概念能够解决这两个问题。
|
||||
|
||||
<!--
|
||||
Familiarity with [Pods](/docs/user-guide/pods) is suggested.
|
||||
Familiarity with [Pods](/docs/concepts/workloads/pods/) is suggested.
|
||||
-->
|
||||
阅读本文前建议你熟悉一下 [Pods](/zh/docs/concepts/workloads/pods)。
|
||||
|
||||
@@ -66,8 +66,8 @@ For any kind of volume in a given pod, data is preserved across container restar
|
||||
Kubernetes 支持很多类型的卷。
|
||||
{{< glossary_tooltip term_id="pod" text="Pod" >}} 可以同时使用任意数目的卷类型。
|
||||
临时卷类型的生命周期与 Pod 相同,但持久卷可以比 Pod 的存活期长。
|
||||
当 Pod 不再存在时,Kubernetes 也会销毁临时卷;不过 Kubernetes 不会销毁
|
||||
持久卷。对于给定 Pod 中任何类型的卷,在容器重启期间数据都不会丢失。
|
||||
当 Pod 不再存在时,Kubernetes 也会销毁临时卷;不过 Kubernetes 不会销毁持久卷。
|
||||
对于给定 Pod 中任何类型的卷,在容器重启期间数据都不会丢失。
|
||||
|
||||
<!--
|
||||
At its core, a volume is just a directory, possibly with some data in it, which
|
||||
@@ -76,27 +76,41 @@ medium that backs it, and the contents of it are determined by the particular
|
||||
volume type used.
|
||||
-->
|
||||
卷的核心是一个目录,其中可能存有数据,Pod 中的容器可以访问该目录中的数据。
|
||||
所采用的特定的卷类型将决定该目录如何形成的、使用何种介质保存数据以及目录中存放
|
||||
的内容。
|
||||
所采用的特定的卷类型将决定该目录如何形成的、使用何种介质保存数据以及目录中存放的内容。
|
||||
|
||||
<!--
|
||||
To use a volume, specify the volumes to provide for the Pod in `.spec.volumes`
|
||||
and declare where to mount those volumes into containers in `.spec.containers[*].volumeMounts`.
|
||||
A process in a container sees a filesystem view composed from their Docker
|
||||
image and volumes. The [Docker image](https://docs.docker.com/userguide/dockerimages/)
|
||||
is at the root of the filesystem hierarchy. Volumes mount at the specified paths within
|
||||
the image. Volumes can not mount onto other volumes or have hard links to
|
||||
other volumes. Each Container in the Pod's configuration must independently specify where to
|
||||
mount each volume.
|
||||
A process in a container sees a filesystem view composed from the initial contents of
|
||||
the {{< glossary_tooltip text="container image" term_id="image" >}}, plus volumes
|
||||
(if defined) mounted inside the container.
|
||||
The process sees a root filesystem that initially matches the contents of the container
|
||||
image.
|
||||
Any writes to within that filesystem hierarchy, if allowed, affect what that process views
|
||||
when it performs a subsequent filesystem access.
|
||||
-->
|
||||
使用卷时, 在 `.spec.volumes` 字段中设置为 Pod 提供的卷,并在
|
||||
`.spec.containers[*].volumeMounts` 字段中声明卷在容器中的挂载位置。
|
||||
容器中的进程看到的是由它们的 Docker 镜像和卷组成的文件系统视图。
|
||||
[Docker 镜像](https://docs.docker.com/userguide/dockerimages/)
|
||||
位于文件系统层次结构的根部。各个卷则挂载在镜像内的指定路径上。
|
||||
卷不能挂载到其他卷之上,也不能与其他卷有硬链接。
|
||||
容器中的进程看到的文件系统视图是由它们的 {{< glossary_tooltip text="容器镜像" term_id="image" >}}
|
||||
的初始内容以及挂载在容器中的卷(如果定义了的话)所组成的。
|
||||
其中根文件系统同容器镜像的内容相吻合。
|
||||
任何在该文件系统下的写入操作,如果被允许的话,都会影响接下来容器中进程访问文件系统时所看到的内容。
|
||||
|
||||
<!--
|
||||
Volumes mount at the [specified paths](#using-subpath) within
|
||||
the image.
|
||||
For each container defined within a Pod, you must independently specify where
|
||||
to mount each volume that the container uses.
|
||||
|
||||
Volumes cannot mount within other volumes (but see [Using subPath](#using-subpath)
|
||||
for a related mechanism). Also, a volume cannot contain a hard link to anything in
|
||||
a different volume.
|
||||
-->
|
||||
卷挂载在镜像中的[指定路径](#using-subpath)下。
|
||||
Pod 配置中的每个容器必须独立指定各个卷的挂载位置。
|
||||
|
||||
卷不能挂载到其他卷之上(不过存在一种[使用 subPath](#using-subpath) 的相关机制),也不能与其他卷有硬链接。
|
||||
|
||||
<!--
|
||||
## Types of Volumes
|
||||
|
||||
@@ -116,8 +130,8 @@ volume are persisted and the volume is unmounted. This means that an
|
||||
EBS volume can be pre-populated with data, and that data can be shared between pods.
|
||||
-->
|
||||
`awsElasticBlockStore` 卷将 Amazon Web服务(AWS)[EBS 卷](https://aws.amazon.com/ebs/)
|
||||
挂载到你的 Pod 中。与 `emptyDir` 在 Pod 被删除时也被删除不同,EBS 卷的内容在删除 Pod 时
|
||||
会被保留,卷只是被卸载掉了。
|
||||
挂载到你的 Pod 中。与 `emptyDir` 在 Pod 被删除时也被删除不同,EBS 卷的内容在删除 Pod
|
||||
时会被保留,卷只是被卸载掉了。
|
||||
这意味着 EBS 卷可以预先填充数据,并且该数据可以在 Pod 之间共享。
|
||||
|
||||
<!--
|
||||
@@ -204,9 +218,10 @@ driver](https://github.com/kubernetes-sigs/aws-ebs-csi-driver)
|
||||
must be installed on the cluster and the `CSIMigration` and `CSIMigrationAWS`
|
||||
beta features must be enabled.
|
||||
-->
|
||||
如果启用了对 `awsElasticBlockStore` 的 `CSIMigration` 特性支持,所有插件操作都
|
||||
不再指向树内插件(In-Tree Plugin),转而指向 `ebs.csi.aws.com` 容器存储接口
|
||||
(Container Storage Interface,CSI)驱动。为了使用此特性,必须在集群中安装
|
||||
如果启用了对 `awsElasticBlockStore` 的 `CSIMigration`
|
||||
特性支持,所有插件操作都不再指向树内插件(In-Tree Plugin),转而指向
|
||||
`ebs.csi.aws.com` 容器存储接口(Container Storage Interface,CSI)驱动。
|
||||
为了使用此特性,必须在集群中安装
|
||||
[AWS EBS CSI 驱动](https://github.com/kubernetes-sigs/aws-ebs-csi-driver),
|
||||
并确保 `CSIMigration` 和 `CSIMigrationAWS` Beta 功能特性被启用。
|
||||
|
||||
@@ -308,8 +323,9 @@ that data can be shared between Pods. The `cephfs` can be mounted by multiple
|
||||
writers simultaneously.
|
||||
-->
|
||||
`cephfs` 卷允许你将现存的 CephFS 卷挂载到 Pod 中。
|
||||
不像 `emptyDir` 那样会在 Pod 被删除的同时也会被删除,`cephfs` 卷的内容在 Pod 被删除
|
||||
时会被保留,只是卷被卸载了。这意味着 `cephfs` 卷可以被预先填充数据,且这些数据可以在
|
||||
不像 `emptyDir` 那样会在 Pod 被删除的同时也会被删除,`cephfs`
|
||||
卷的内容在 Pod 被删除时会被保留,只是卷被卸载了。
|
||||
这意味着 `cephfs` 卷可以被预先填充数据,且这些数据可以在
|
||||
Pod 之间共享。同一 `cephfs` 卷可同时被多个写者挂载。
|
||||
|
||||
<!--
|
||||
@@ -399,10 +415,9 @@ provides a way to inject configuration data into Pods.
|
||||
The data stored in a ConfigMap object can be referenced in a volume of type
|
||||
`configMap` and then consumed by containerized applications running in a Pod.
|
||||
-->
|
||||
[`configMap`](/zh/docs/tasks/configure-pod-container/configure-pod-configmap/) 卷
|
||||
提供了向 Pod 注入配置数据的方法。
|
||||
ConfigMap 对象中存储的数据可以被 `configMap` 类型的卷引用,然后被 Pod 中运行的
|
||||
容器化应用使用。
|
||||
[`configMap`](/zh/docs/tasks/configure-pod-container/configure-pod-configmap/)
|
||||
卷提供了向 Pod 注入配置数据的方法。
|
||||
ConfigMap 对象中存储的数据可以被 `configMap` 类型的卷引用,然后被 Pod 中运行的容器化应用使用。
|
||||
|
||||
<!--
|
||||
When referencing a ConfigMap, you provide the name of the ConfigMap in the
|
||||
@@ -442,8 +457,8 @@ its `log_level` entry are mounted into the Pod at path "`/etc/config/log_level`"
|
||||
Note that this path is derived from the volume's `mountPath` and the `path`
|
||||
keyed with `log_level`.
|
||||
-->
|
||||
`log-config` ConfigMap 以卷的形式挂载,并且存储在 `log_level` 条目中的所有内容
|
||||
都被挂载到 Pod 的 `/etc/config/log_level` 路径下。
|
||||
`log-config` ConfigMap 以卷的形式挂载,并且存储在 `log_level`
|
||||
条目中的所有内容都被挂载到 Pod 的 `/etc/config/log_level` 路径下。
|
||||
请注意,这个路径来源于卷的 `mountPath` 和 `log_level` 键对应的 `path`。
|
||||
|
||||
<!--
|
||||
@@ -544,8 +559,8 @@ backed volumes are sized to 50% of the memory on a Linux host.
|
||||
-->
|
||||
|
||||
{{< note >}}
|
||||
当启用 `SizeMemoryBackedVolumes` [特性门控](/zh/docs/reference/command-line-tools-reference/feature-gates/)时,
|
||||
你可以为基于内存提供的卷指定大小。
|
||||
当启用 `SizeMemoryBackedVolumes` [特性门控](/zh/docs/reference/command-line-tools-reference/feature-gates/)
|
||||
时,你可以为基于内存提供的卷指定大小。
|
||||
如果未指定大小,则基于内存的卷的大小为 Linux 主机上内存的 50%。
|
||||
{{< /note>}}
|
||||
|
||||
@@ -589,8 +604,8 @@ targetWWNs expect that those WWNs are from multi-path connections.
|
||||
You must configure FC SAN Zoning to allocate and mask those LUNs (volumes) to the target WWNs beforehand so that Kubernetes hosts can access them.
|
||||
-->
|
||||
{{< note >}}
|
||||
你必须配置 FC SAN Zoning,以便预先向目标 WWN 分配和屏蔽这些 LUN(卷),
|
||||
这样 Kubernetes 主机才可以访问它们。
|
||||
你必须配置 FC SAN Zoning,以便预先向目标 WWN 分配和屏蔽这些 LUN(卷),这样
|
||||
Kubernetes 主机才可以访问它们。
|
||||
{{< /note >}}
|
||||
|
||||
<!--
|
||||
@@ -737,10 +752,10 @@ feature allows the creation of Persistent Disks that are available in two zones
|
||||
within the same region. In order to use this feature, the volume must be provisioned
|
||||
as a PersistentVolume; referencing the volume directly from a Pod is not supported.
|
||||
-->
|
||||
[区域持久盘](https://cloud.google.com/compute/docs/disks/#repds) 功能允许你创建能在
|
||||
同一区域的两个可用区中使用的持久盘。
|
||||
要使用这个功能,必须以持久卷(PersistentVolume)的方式提供卷;直接从 Pod 引用这种卷
|
||||
是不可以的。
|
||||
[区域持久盘](https://cloud.google.com/compute/docs/disks/#repds)
|
||||
功能允许你创建能在同一区域的两个可用区中使用的持久盘。
|
||||
要使用这个功能,必须以持久卷(PersistentVolume)的方式提供卷;直接从
|
||||
Pod 引用这种卷是不可以的。
|
||||
|
||||
<!--
|
||||
#### Manually provisioning a Regional PD PersistentVolume
|
||||
@@ -750,8 +765,8 @@ Before creating a PersistentVolume, you must create the PD:
|
||||
-->
|
||||
#### 手动供应基于区域 PD 的 PersistentVolume {#manually-provisioning-regional-pd-pv}
|
||||
|
||||
使用[为 GCE PD 定义的存储类](/zh/docs/concepts/storage/storage-classes/#gce) 可以
|
||||
实现动态供应。在创建 PersistentVolume 之前,你首先要创建 PD。
|
||||
使用[为 GCE PD 定义的存储类](/zh/docs/concepts/storage/storage-classes/#gce)
|
||||
可以实现动态供应。在创建 PersistentVolume 之前,你首先要创建 PD。
|
||||
|
||||
```shell
|
||||
gcloud beta compute disks create --size=500GB my-data-disk
|
||||
@@ -824,8 +839,8 @@ and the kubelet, set the `InTreePluginGCEUnregister` flag to `true`.
|
||||
|
||||
{{< feature-state for_k8s_version="v1.21" state="alpha" >}}
|
||||
|
||||
要禁止控制器管理器和 kubelet 加载 `gcePersistentDisk` 存储插件,
|
||||
请将 `InTreePluginGCEUnregister` 标志设置为 `true`。
|
||||
要禁止控制器管理器和 kubelet 加载 `gcePersistentDisk` 存储插件,请将
|
||||
`InTreePluginGCEUnregister` 标志设置为 `true`。
|
||||
|
||||
<!--
|
||||
### gitRepo (deprecated) {#gitrepo}
|
||||
@@ -838,8 +853,8 @@ The gitRepo volume type is deprecated. To provision a container with a git repo,
|
||||
-->
|
||||
{{< warning >}}
|
||||
`gitRepo` 卷类型已经被废弃。如果需要在容器中提供 git 仓库,请将一个
|
||||
[EmptyDir](#emptydir) 卷挂载到 InitContainer 中,使用 git 命令完成仓库的克隆操作,
|
||||
然后将 [EmptyDir](#emptydir) 卷挂载到 Pod 的容器中。
|
||||
[EmptyDir](#emptydir) 卷挂载到 InitContainer 中,使用 git
|
||||
命令完成仓库的克隆操作,然后将 [EmptyDir](#emptydir) 卷挂载到 Pod 的容器中。
|
||||
{{< /warning >}}
|
||||
|
||||
<!--
|
||||
@@ -916,8 +931,8 @@ be required to use `readOnly` mounts for the policy to be effective.
|
||||
HostPath 卷存在许多安全风险,最佳做法是尽可能避免使用 HostPath。
|
||||
当必须使用 HostPath 卷时,它的范围应仅限于所需的文件或目录,并以只读方式挂载。
|
||||
|
||||
如果通过 AdmissionPolicy 限制 HostPath 对特定目录的访问,
|
||||
则必须要求 `volumeMounts` 使用 `readOnly` 挂载以使策略生效。
|
||||
如果通过 AdmissionPolicy 限制 HostPath 对特定目录的访问,则必须要求
|
||||
`volumeMounts` 使用 `readOnly` 挂载以使策略生效。
|
||||
{{< /warning >}}
|
||||
|
||||
<!--
|
||||
@@ -990,10 +1005,10 @@ Watch out when using this type of volume, because:
|
||||
-->
|
||||
当使用这种类型的卷时要小心,因为:
|
||||
|
||||
* HostPath 卷可能会暴露特权系统凭据(例如 Kubelet)或特权 API(例如容器运行时套接字),
|
||||
可用于容器逃逸或攻击集群的其他部分。
|
||||
* 具有相同配置(例如基于同一 PodTemplate 创建)的多个 Pod 会由于节点上文件的不同
|
||||
而在不同节点上有不同的行为。
|
||||
* HostPath 卷可能会暴露特权系统凭据(例如 Kubelet)或特权
|
||||
API(例如容器运行时套接字),可用于容器逃逸或攻击集群的其他部分。
|
||||
* 具有相同配置(例如基于同一 PodTemplate 创建)的多个 Pod
|
||||
会由于节点上文件的不同而在不同节点上有不同的行为。
|
||||
* 下层主机上创建的文件或目录只能由 root 用户写入。你需要在
|
||||
[特权容器](/zh/docs/tasks/configure-pod-container/security-context/)
|
||||
中以 root 身份运行进程,或者修改主机上的文件权限以便容器能够写入 `hostPath` 卷。
|
||||
@@ -1078,8 +1093,8 @@ unmounted. This means that an iscsi volume can be pre-populated with data, and
|
||||
that data can be shared between pods.
|
||||
-->
|
||||
`iscsi` 卷能将 iSCSI (基于 IP 的 SCSI) 卷挂载到你的 Pod 中。
|
||||
不像 `emptyDir` 那样会在删除 Pod 的同时也会被删除,`iscsi` 卷的内容在删除 Pod 时
|
||||
会被保留,卷只是被卸载。
|
||||
不像 `emptyDir` 那样会在删除 Pod 的同时也会被删除,`iscsi`
|
||||
卷的内容在删除 Pod 时会被保留,卷只是被卸载。
|
||||
这意味着 `iscsi` 卷可以被预先填充数据,并且这些数据可以在 Pod 之间共享。
|
||||
|
||||
<!--
|
||||
@@ -1141,8 +1156,7 @@ The following is an example of PersistentVolume spec using a `local` volume and
|
||||
-->
|
||||
然而,`local` 卷仍然取决于底层节点的可用性,并不适合所有应用程序。
|
||||
如果节点变得不健康,那么 `local` 卷也将变得不可被 Pod 访问。使用它的 Pod 将不能运行。
|
||||
使用 `local` 卷的应用程序必须能够容忍这种可用性的降低,以及因底层磁盘的耐用性特征
|
||||
而带来的潜在的数据丢失风险。
|
||||
使用 `local` 卷的应用程序必须能够容忍这种可用性的降低,以及因底层磁盘的耐用性特征而带来的潜在的数据丢失风险。
|
||||
|
||||
下面是一个使用 `local` 卷和 `nodeAffinity` 的持久卷示例:
|
||||
|
||||
@@ -1198,9 +1212,8 @@ such as node resource requirements, node selectors, Pod affinity, and Pod anti-a
|
||||
使用 `local` 卷时,建议创建一个 StorageClass 并将其 `volumeBindingMode` 设置为
|
||||
`WaitForFirstConsumer`。要了解更多详细信息,请参考
|
||||
[local StorageClass 示例](/zh/docs/concepts/storage/storage-classes/#local)。
|
||||
延迟卷绑定的操作可以确保 Kubernetes 在为 PersistentVolumeClaim 作出绑定决策时,
|
||||
会评估 Pod 可能具有的其他节点约束,例如:如节点资源需求、节点选择器、Pod
|
||||
亲和性和 Pod 反亲和性。
|
||||
延迟卷绑定的操作可以确保 Kubernetes 在为 PersistentVolumeClaim 作出绑定决策时,会评估
|
||||
Pod 可能具有的其他节点约束,例如:如节点资源需求、节点选择器、Pod亲和性和 Pod 反亲和性。
|
||||
|
||||
<!--
|
||||
An external static provisioner can be run separately for improved management of
|
||||
@@ -1258,10 +1271,9 @@ A `persistentVolumeClaim` volume is used to mount a
|
||||
are a way for users to "claim" durable storage (such as a GCE PersistentDisk or an
|
||||
iSCSI volume) without knowing the details of the particular cloud environment.
|
||||
-->
|
||||
`persistentVolumeClaim` 卷用来将[持久卷](/zh/docs/concepts/storage/persistent-volumes/)(PersistentVolume)
|
||||
挂载到 Pod 中。
|
||||
持久卷申领(PersistentVolumeClaim)是用户在不知道特定云环境细节的情况下"申领"持久存储
|
||||
(例如 GCE PersistentDisk 或者 iSCSI 卷)的一种方法。
|
||||
`persistentVolumeClaim` 卷用来将[持久卷](/zh/docs/concepts/storage/persistent-volumes/)(PersistentVolume)挂载到 Pod 中。
|
||||
持久卷申领(PersistentVolumeClaim)是用户在不知道特定云环境细节的情况下“申领”持久存储(例如
|
||||
GCE PersistentDisk 或者 iSCSI 卷)的一种方法。
|
||||
|
||||
<!--
|
||||
See the [PersistentVolumes example](/docs/concepts/storage/persistent-volumes/) for more
|
||||
@@ -1277,8 +1289,8 @@ Kubernetes. [Portworx](https://portworx.com/use-case/kubernetes-storage/) finger
|
||||
and aggregates capacity across multiple servers. Portworx runs in-guest in virtual machines or on bare metal Linux nodes.
|
||||
-->
|
||||
`portworxVolume` 是一个可伸缩的块存储层,能够以超融合(hyperconverged)的方式与 Kubernetes 一起运行。
|
||||
[Portworx](https://portworx.com/use-case/kubernetes-storage/) 支持对服务器上存储的指纹处理、
|
||||
基于存储能力进行分层以及跨多个服务器整合存储容量。
|
||||
[Portworx](https://portworx.com/use-case/kubernetes-storage/)
|
||||
支持对服务器上存储的指纹处理、基于存储能力进行分层以及跨多个服务器整合存储容量。
|
||||
Portworx 可以以 in-guest 方式在虚拟机中运行,也可以在裸金属 Linux 节点上运行。
|
||||
|
||||
<!--
|
||||
@@ -1324,192 +1336,13 @@ For more details, see the [Portworx volume](https://github.com/kubernetes/exampl
|
||||
|
||||
更多详情可以参考 [Portworx 卷](https://github.com/kubernetes/examples/tree/master/staging/volumes/portworx/README.md)。
|
||||
|
||||
### projected
|
||||
### projected (投射)
|
||||
|
||||
<!--
|
||||
A `projected` volume maps several existing volume sources into the same directory.
|
||||
|
||||
Currently, the following types of volume sources can be projected:
|
||||
A projected volume maps several existing volume sources into the same
|
||||
directory. For more details, see [projected volumes](/docs/concepts/storage/projected-volumes/).
|
||||
-->
|
||||
`projected` 卷类型能将若干现有的卷来源映射到同一目录上。
|
||||
|
||||
目前,可以映射的卷来源类型如下:
|
||||
|
||||
- [`secret`](#secret)
|
||||
- [`downwardAPI`](#downwardapi)
|
||||
- [`configMap`](#configmap)
|
||||
- `serviceAccountToken`
|
||||
|
||||
<!--
|
||||
All sources are required to be in the same namespace as the Pod. For more details,
|
||||
see the [all-in-one volume design document](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/node/all-in-one-volume.md).
|
||||
-->
|
||||
所有的卷来源需要和 Pod 处于相同的命名空间。
|
||||
更多详情请参考[一体化卷设计文档](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/node/all-in-one-volume.md)。
|
||||
|
||||
<!--
|
||||
#### Example configuration with a secret, a downwardAPI, and a configMap {#example-configuration-secret-downwardapi-configmap}
|
||||
-->
|
||||
|
||||
#### 包含 Secret、downwardAPI 和 configMap 的 Pod 示例 {#example-configuration-secret-downwardapi-configmap}
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: volume-test
|
||||
spec:
|
||||
containers:
|
||||
- name: container-test
|
||||
image: busybox
|
||||
volumeMounts:
|
||||
- name: all-in-one
|
||||
mountPath: "/projected-volume"
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: all-in-one
|
||||
projected:
|
||||
sources:
|
||||
- secret:
|
||||
name: mysecret
|
||||
items:
|
||||
- key: username
|
||||
path: my-group/my-username
|
||||
- downwardAPI:
|
||||
items:
|
||||
- path: "labels"
|
||||
fieldRef:
|
||||
fieldPath: metadata.labels
|
||||
- path: "cpu_limit"
|
||||
resourceFieldRef:
|
||||
containerName: container-test
|
||||
resource: limits.cpu
|
||||
- configMap:
|
||||
name: myconfigmap
|
||||
items:
|
||||
- key: config
|
||||
path: my-group/my-config
|
||||
```
|
||||
|
||||
<!--
|
||||
#### Example configuration: secrets with a non-default permission mode set {#example-configuration-secrets-nondefault-permission-mode}
|
||||
-->
|
||||
|
||||
下面是一个带有非默认访问权限设置的多个 secret 的 Pod 示例:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: volume-test
|
||||
spec:
|
||||
containers:
|
||||
- name: container-test
|
||||
image: busybox
|
||||
volumeMounts:
|
||||
- name: all-in-one
|
||||
mountPath: "/projected-volume"
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: all-in-one
|
||||
projected:
|
||||
sources:
|
||||
- secret:
|
||||
name: mysecret
|
||||
items:
|
||||
- key: username
|
||||
path: my-group/my-username
|
||||
- secret:
|
||||
name: mysecret2
|
||||
items:
|
||||
- key: password
|
||||
path: my-group/my-password
|
||||
mode: 511
|
||||
```
|
||||
<!--
|
||||
Each projected volume source is listed in the spec under `sources`. The
|
||||
parameters are nearly the same with two exceptions:
|
||||
|
||||
* For secrets, the `secretName` field has been changed to `name` to be consistent
|
||||
with ConfigMap naming.
|
||||
* The `defaultMode` can only be specified at the projected level and not for each
|
||||
volume source. However, as illustrated above, you can explicitly set the `mode`
|
||||
for each individual projection.
|
||||
-->
|
||||
每个被投射的卷来源都在规约中的 `sources` 内列出。参数几乎相同,除了两处例外:
|
||||
|
||||
* 对于 `secret`,`secretName` 字段已被变更为 `name` 以便与 ConfigMap 命名一致。
|
||||
* `defaultMode` 只能在整个投射卷级别指定,而无法针对每个卷来源指定。
|
||||
不过,如上所述,你可以显式地为每个投射项设置 `mode` 值。
|
||||
|
||||
<!--
|
||||
When the `TokenRequestProjection` feature is enabled, you can inject the token
|
||||
for the current [service account](/docs/reference/access-authn-authz/authentication/#service-account-tokens)
|
||||
into a Pod at a specified path. Below is an example:
|
||||
-->
|
||||
|
||||
当开启 `TokenRequestProjection` 功能时,可以将当前
|
||||
[服务帐号](/zh/docs/reference/access-authn-authz/authentication/#service-account-tokens)
|
||||
的令牌注入 Pod 中的指定路径。
|
||||
下面是一个例子:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: sa-token-test
|
||||
spec:
|
||||
containers:
|
||||
- name: container-test
|
||||
image: busybox
|
||||
volumeMounts:
|
||||
- name: token-vol
|
||||
mountPath: "/service-account"
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: token-vol
|
||||
projected:
|
||||
sources:
|
||||
- serviceAccountToken:
|
||||
audience: api
|
||||
expirationSeconds: 3600
|
||||
path: token
|
||||
```
|
||||
|
||||
<!--
|
||||
The example Pod has a projected volume containing the injected service account
|
||||
token. This token can be used by a Pod's containers to access the Kubernetes API
|
||||
server. The `audience` field contains the intended audience of the
|
||||
token. A recipient of the token must identify itself with an identifier specified
|
||||
in the audience of the token, and otherwise should reject the token. This field
|
||||
is optional and it defaults to the identifier of the API server.
|
||||
-->
|
||||
示例 Pod 具有包含注入服务帐户令牌的映射卷。
|
||||
该令牌可以被 Pod 中的容器用来访问 Kubernetes API 服务器。
|
||||
`audience` 字段包含令牌的预期受众。
|
||||
令牌的接收者必须使用令牌的受众中指定的标识符来标识自己,否则应拒绝令牌。
|
||||
此字段是可选的,默认值是 API 服务器的标识符。
|
||||
|
||||
<!--
|
||||
The `expirationSeconds` is the expected duration of validity of the service account
|
||||
token. It defaults to 1 hour and must be at least 10 minutes (600 seconds). An administrator
|
||||
can also limit its maximum value by specifying the `-service-account-max-token-expiration`
|
||||
option for the API server. The `path` field specifies a relative path to the mount point
|
||||
of the projected volume.
|
||||
-->
|
||||
`expirationSeconds` 是服务帐户令牌的有效期时长。
|
||||
默认值为 1 小时,必须至少 10 分钟(600 秒)。
|
||||
管理员还可以通过设置 API 服务器的 `--service-account-max-token-expiration` 选项来
|
||||
限制其最大值。
|
||||
`path` 字段指定相对于映射卷的挂载点的相对路径。
|
||||
|
||||
{{< note >}}
|
||||
<!--
|
||||
A container using a projected volume source as a [subPath](#using-subpath) volume mount will not
|
||||
receive updates for those volume sources.
|
||||
-->
|
||||
使用投射卷源作为 [subPath](#using-subpath) 卷挂载的容器将不会接收这些卷源的更新。
|
||||
{{< /note >}}
|
||||
投射卷能将若干现有的卷来源映射到同一目录上。更多详情请参考[投射卷](/zh/docs/concepts/storage/projected-volumes/)。
|
||||
|
||||
### quobyte (已弃用) {#quobyte}
|
||||
|
||||
@@ -1542,32 +1375,32 @@ Quobyte 的 GitHub 项目包含以 CSI 形式部署 Quobyte 的
|
||||
|
||||
<!--
|
||||
An `rbd` volume allows a
|
||||
[Rados Block Device](https://docs.ceph.com/en/latest/rbd/) volume to mount into your
|
||||
Pod. Unlike `emptyDir`, which is erased when a Pod is removed, the contents of
|
||||
a `rbd` volume are preserved and the volume is merely unmounted. This
|
||||
means that a RBD volume can be pre-populated with data, and that data can
|
||||
be shared between pods.
|
||||
[Rados Block Device](https://docs.ceph.com/en/latest/rbd/) (RBD) volume to mount
|
||||
into your Pod. Unlike `emptyDir`, which is erased when a pod is removed, the
|
||||
contents of an `rbd` volume are preserved and the volume is unmounted. This
|
||||
means that a RBD volume can be pre-populated with data, and that data can be
|
||||
shared between pods.
|
||||
-->
|
||||
`rbd` 卷允许将 [Rados 块设备](https://docs.ceph.com/en/latest/rbd/) 卷挂载到你的 Pod 中.
|
||||
不像 `emptyDir` 那样会在删除 Pod 的同时也会被删除,`rbd` 卷的内容在删除 Pod 时
|
||||
会被保存,卷只是被卸载。
|
||||
`rbd` 卷允许将 [Rados 块设备](https://docs.ceph.com/en/latest/rbd/)卷挂载到你的 Pod 中。
|
||||
不像 `emptyDir` 那样会在删除 Pod 的同时也会被删除,`rbd` 卷的内容在删除 Pod 时会被保存,卷只是被卸载。
|
||||
这意味着 `rbd` 卷可以被预先填充数据,并且这些数据可以在 Pod 之间共享。
|
||||
|
||||
<!--
|
||||
You must have your own Ceph installation running before you can use RBD.
|
||||
You must have a Ceph installation running before you can use RBD.
|
||||
-->
|
||||
{{< caution >}}
|
||||
{{< note >}}
|
||||
在使用 RBD 之前,你必须安装运行 Ceph。
|
||||
{{< /caution >}}
|
||||
{{< /note >}}
|
||||
|
||||
<!--
|
||||
A feature of RBD is that it can be mounted as read-only by multiple consumers
|
||||
simultaneously. This means that you can pre-populate a volume with your dataset
|
||||
and then serve it in parallel from as many Pods as you need. Unfortunately,
|
||||
and then serve it in parallel from as many pods as you need. Unfortunately,
|
||||
RBD volumes can only be mounted by a single consumer in read-write mode.
|
||||
Simultaneous writers are not allowed.
|
||||
|
||||
See the [RBD example](https://github.com/kubernetes/examples/tree/master/volumes/rbd) for more details.
|
||||
See the [RBD example](https://github.com/kubernetes/examples/tree/master/volumes/rbd)
|
||||
for more details.
|
||||
-->
|
||||
RBD 的一个特性是它可以同时被多个用户以只读方式挂载。
|
||||
这意味着你可以用数据集预先填充卷,然后根据需要在尽可能多的 Pod 中并行地使用卷。
|
||||
@@ -1576,6 +1409,59 @@ RBD 的一个特性是它可以同时被多个用户以只读方式挂载。
|
||||
更多详情请参考
|
||||
[RBD 示例](https://github.com/kubernetes/examples/tree/master/volumes/rbd)。
|
||||
|
||||
<!--
|
||||
#### RBD CSI migration
|
||||
-->
|
||||
#### RBD CSI 迁移 {#rbd-csi-migration}
|
||||
|
||||
{{< feature-state for_k8s_version="v1.23" state="alpha" >}}
|
||||
|
||||
<!--
|
||||
The `CSIMigration` feature for `RBD`, when enabled, redirects all plugin
|
||||
operations from the existing in-tree plugin to the `rbd.csi.ceph.com` {{<
|
||||
glossary_tooltip text="CSI" term_id="csi" >}} driver. In order to use this
|
||||
feature, the
|
||||
[Ceph CSI driver](https://github.com/ceph/ceph-csi)
|
||||
must be installed on the cluster and the `CSIMigration` and `csiMigrationRBD`
|
||||
[feature gates](/docs/reference/command-line-tools-reference/feature-gates/)
|
||||
must be enabled.
|
||||
-->
|
||||
启用 RBD 的 `CSIMigration` 功能后,所有插件操作从现有的树内插件重定向到
|
||||
`rbd.csi.ceph.com` {{<glossary_tooltip text="CSI" term_id="csi" >}} 驱动程序。
|
||||
要使用该功能,必须在集群内安装
|
||||
[Ceph CSI 驱动](https://github.com/ceph/ceph-csi),并启用 `CSIMigration` 和 `csiMigrationRBD`
|
||||
[特性门控](/zh/docs/reference/command-line-tools-reference/feature-gates/)。
|
||||
|
||||
<!--
|
||||
As a Kubernetes cluster operator that administers storage, here are the
|
||||
prerequisites that you must complete before you attempt migration to the
|
||||
RBD CSI driver:
|
||||
|
||||
* You must install the Ceph CSI driver (`rbd.csi.ceph.com`), v3.5.0 or above,
|
||||
into your Kubernetes cluster.
|
||||
* considering the `clusterID` field is a required parameter for CSI driver for
|
||||
its operations, but in-tree StorageClass has `monitors` field as a required
|
||||
parameter, a Kubernetes storage admin has to create a clusterID based on the
|
||||
monitors hash ( ex:`#echo -n
|
||||
'<monitors_string>' | md5sum`) in the CSI config map and keep the monitors
|
||||
under this clusterID configuration.
|
||||
* Also, if the value of `adminId` in the in-tree Storageclass is different from
|
||||
`admin`, the `adminSecretName` mentioned in the in-tree Storageclass has to be
|
||||
patched with the base64 value of the `adminId` parameter value, otherwise this
|
||||
step can be skipped.
|
||||
-->
|
||||
{{< note >}}
|
||||
作为一位管理存储的 Kubernetes 集群操作者,在尝试迁移到 RBD CSI 驱动前,你必须完成下列先决事项:
|
||||
|
||||
* 你必须在集群中安装 v3.5.0 或更高版本的 Ceph CSI 驱动(`rbd.csi.ceph.com`)。
|
||||
* 因为 `clusterID` 是 CSI 驱动程序必需的参数,而树内存储类又将 `monitors`
|
||||
作为一个必需的参数,所以 Kubernetes 存储管理者需要根据 `monitors`
|
||||
的哈希值(例:`#echo -n '<monitors_string>' | md5sum`)来创建
|
||||
`clusterID`,并保持该 `monitors` 存在于该 `clusterID` 的配置中。
|
||||
* 同时,如果树内存储类的 `adminId` 的值不是 `admin`,那么其 `adminSecretName`
|
||||
就需要被修改成 `adminId` 参数的 base64 编码值。
|
||||
{{< /note >}}
|
||||
|
||||
### secret
|
||||
|
||||
<!--
|
||||
@@ -1587,8 +1473,7 @@ non-volatile storage.
|
||||
-->
|
||||
`secret` 卷用来给 Pod 传递敏感信息,例如密码。你可以将 Secret 存储在 Kubernetes
|
||||
API 服务器上,然后以文件的形式挂在到 Pod 中,无需直接与 Kubernetes 耦合。
|
||||
`secret` 卷由 tmpfs(基于 RAM 的文件系统)提供存储,因此它们永远不会被写入非易失性
|
||||
(持久化的)存储器。
|
||||
`secret` 卷由 tmpfs(基于 RAM 的文件系统)提供存储,因此它们永远不会被写入非易失性(持久化的)存储器。
|
||||
|
||||
<!--
|
||||
You must create a secret in the Kubernetes API before you can use it.
|
||||
@@ -1790,8 +1675,8 @@ must be installed on the cluster and the `CSIMigration` and `CSIMigrationvSphere
|
||||
当 `vsphereVolume` 的 `CSIMigration` 特性被启用时,所有插件操作都被从树内插件重定向到
|
||||
`csi.vsphere.vmware.com` {{< glossary_tooltip text="CSI" term_id="csi" >}} 驱动。
|
||||
为了使用此功能特性,必须在集群中安装
|
||||
[vSphere CSI 驱动](https://github.com/kubernetes-sigs/vsphere-csi-driver),
|
||||
并启用 `CSIMigration` 和 `CSIMigrationvSphere`
|
||||
[vSphere CSI 驱动](https://github.com/kubernetes-sigs/vsphere-csi-driver),并启用
|
||||
`CSIMigration` 和 `CSIMigrationvSphere`
|
||||
[特性门控](/zh/docs/reference/command-line-tools-reference/feature-gates/)。
|
||||
|
||||
<!--
|
||||
@@ -1837,6 +1722,28 @@ To turn off the `vsphereVolume` plugin from being loaded by the controller manag
|
||||
`InTreePluginvSphereUnregister` 特性设置为 `true`。你还必须在所有工作节点上安装
|
||||
`csi.vsphere.vmware.com` {{< glossary_tooltip text="CSI" term_id="csi" >}} 驱动。
|
||||
|
||||
<!--
|
||||
#### Portworx CSI migration
|
||||
-->
|
||||
#### Portworx CSI 迁移
|
||||
|
||||
{{< feature-state for_k8s_version="v1.23" state="alpha" >}}
|
||||
|
||||
<!--
|
||||
The `CSIMigration` feature for Portworx has been added but disabled by default in Kubernetes 1.23 since it's in alpha state.
|
||||
It redirects all plugin operations from the existing in-tree plugin to the
|
||||
`pxd.portworx.com` Container Storage Interface (CSI) Driver.
|
||||
[Portworx CSI Driver](https://docs.portworx.com/portworx-install-with-kubernetes/storage-operations/csi/)
|
||||
must be installed on the cluster.
|
||||
To enable the feature, set `CSIMigrationPortworx=true` in kube-controller-manager and kubelet.
|
||||
-->
|
||||
Kubernetes 1.23 中加入了 Portworx 的 `CSIMigration` 功能,但默认不会启用,因为该功能仍处于 alpha 阶段。
|
||||
该功能会将所有的插件操作从现有的树内插件重定向到
|
||||
`pxd.portworx.com` 容器存储接口(Container Storage Interface, CSI)驱动程序。
|
||||
集群中必须安装
|
||||
[Portworx CSI 驱动](https://docs.portworx.com/portworx-install-with-kubernetes/storage-operations/csi/)。
|
||||
要启用此功能,请在 kube-controller-manager 和 kubelet 中设置 `CSIMigrationPortworx=true`。
|
||||
|
||||
<!--
|
||||
## Using subPath {#using-subpath}
|
||||
|
||||
@@ -1844,7 +1751,7 @@ Sometimes, it is useful to share one volume for multiple uses in a single Pod.
|
||||
The `volumeMounts.subPath` property specifies a sub-path inside the referenced volume
|
||||
instead of its root.
|
||||
-->
|
||||
## 使用 subPath {#using-path}
|
||||
## 使用 subPath {#using-subpath}
|
||||
|
||||
有时,在单个 Pod 中共享卷以供多方使用是很有用的。
|
||||
`volumeMounts.subPath` 属性可用于指定所引用的卷内的子路径,而不是其根路径。
|
||||
@@ -1934,6 +1841,7 @@ spec:
|
||||
volumeMounts:
|
||||
- name: workdir1
|
||||
mountPath: /logs
|
||||
# 包裹变量名的是小括号,而不是大括号
|
||||
subPathExpr: $(POD_NAME)
|
||||
restartPolicy: Never
|
||||
volumes:
|
||||
@@ -1953,10 +1861,9 @@ Pods.
|
||||
-->
|
||||
## 资源 {#resources}
|
||||
|
||||
`emptyDir` 卷的存储介质(磁盘、SSD 等)是由保存 kubelet 数据的根目录
|
||||
(通常是 `/var/lib/kubelet`)的文件系统的介质确定。
|
||||
Kubernetes 对 `emptyDir` 卷或者 `hostPath` 卷可以消耗的空间没有限制,
|
||||
容器之间或 Pod 之间也没有隔离。
|
||||
`emptyDir` 卷的存储介质(磁盘、SSD 等)是由保存 kubelet
|
||||
数据的根目录(通常是 `/var/lib/kubelet`)的文件系统的介质确定。
|
||||
Kubernetes 对 `emptyDir` 卷或者 `hostPath` 卷可以消耗的空间没有限制,容器之间或 Pod 之间也没有隔离。
|
||||
|
||||
<!--
|
||||
To learn about requesting space using a resource specification, see
|
||||
@@ -1970,16 +1877,15 @@ To learn about requesting space using a resource specification, see
|
||||
## Out-of-Tree Volume Plugins
|
||||
|
||||
The out-of-tree volume plugins include
|
||||
{{< glossary_tooltip text="Container Storage Interface" term_id="csi" >}} (CSI)
|
||||
and FlexVolume. They enable storage vendors to create custom storage plugins
|
||||
without adding them to the Kubernetes repository.
|
||||
{{< glossary_tooltip text="Container Storage Interface" term_id="csi" >}} (CSI), and also FlexVolume (which is deprecated). These plugins enable storage vendors to create custom storage plugins
|
||||
without adding their plugin source code to the Kubernetes repository.
|
||||
-->
|
||||
## 树外(Out-of-Tree)卷插件 {#out-of-tree-volume-plugins}
|
||||
|
||||
Out-of-Tree 卷插件包括
|
||||
{{< glossary_tooltip text="容器存储接口(CSI)" term_id="csi" >}} (CSI)
|
||||
和 FlexVolume。
|
||||
它们使存储供应商能够创建自定义存储插件,而无需将它们添加到 Kubernetes 代码仓库。
|
||||
{{< glossary_tooltip text="容器存储接口(CSI)" term_id="csi" >}}
|
||||
和 FlexVolume(已弃用)。
|
||||
它们使存储供应商能够创建自定义存储插件,而无需将插件源码添加到 Kubernetes 代码仓库。
|
||||
|
||||
<!--
|
||||
Previously, all volume plugins were "in-tree". The "in-tree" plugins were built, linked, compiled,
|
||||
@@ -1998,8 +1904,7 @@ extensions.
|
||||
For storage vendors looking to create an out-of-tree volume plugin, please refer
|
||||
to [this FAQ](https://github.com/kubernetes/community/blob/master/sig-storage/volume-plugin-faq.md).
|
||||
-->
|
||||
CSI 和 FlexVolume 都允许独立于 Kubernetes 代码库开发卷插件,并作为扩展部署
|
||||
(安装)在 Kubernetes 集群上。
|
||||
CSI 和 FlexVolume 都允许独立于 Kubernetes 代码库开发卷插件,并作为扩展部署(安装)在 Kubernetes 集群上。
|
||||
|
||||
对于希望创建树外(Out-Of-Tree)卷插件的存储供应商,请参考
|
||||
[卷插件常见问题](https://github.com/kubernetes/community/blob/master/sig-storage/volume-plugin-faq.md)。
|
||||
@@ -2053,8 +1958,8 @@ A `csi` volume can be used in a Pod in three different ways:
|
||||
* with a [CSI ephemeral volume](/docs/concepts/storage/ephemeral-volumes/#csi-ephemeral-volume)
|
||||
if the driver supports that (beta feature)
|
||||
-->
|
||||
一旦在 Kubernetes 集群上部署了 CSI 兼容卷驱动程序,用户就可以使用 `csi` 卷类型来
|
||||
挂接、挂载 CSI 驱动所提供的卷。
|
||||
一旦在 Kubernetes 集群上部署了 CSI 兼容卷驱动程序,用户就可以使用
|
||||
`csi` 卷类型来挂接、挂载 CSI 驱动所提供的卷。
|
||||
|
||||
`csi` 卷可以在 Pod 中以三种方式使用:
|
||||
|
||||
@@ -2078,10 +1983,10 @@ persistent volume:
|
||||
CSI driver components to identify which PV objects belong to the CSI driver.
|
||||
-->
|
||||
- `driver`:指定要使用的卷驱动名称的字符串值。
|
||||
这个值必须与 CSI 驱动程序在 `GetPluginInfoResponse` 中返回的值相对应;
|
||||
该接口定义在 [CSI 规范](https://github.com/container-storage-interface/spec/blob/master/spec.md#getplugininfo)中。
|
||||
Kubernetes 使用所给的值来标识要调用的 CSI 驱动程序;CSI 驱动程序也使用该值来辨识
|
||||
哪些 PV 对象属于该 CSI 驱动程序。
|
||||
这个值必须与 CSI 驱动程序在 `GetPluginInfoResponse` 中返回的值相对应;该接口定义在
|
||||
[CSI 规范](https://github.com/container-storage-interface/spec/blob/master/spec.md#getplugininfo)中。
|
||||
Kubernetes 使用所给的值来标识要调用的 CSI 驱动程序;CSI
|
||||
驱动程序也使用该值来辨识哪些 PV 对象属于该 CSI 驱动程序。
|
||||
|
||||
<!--
|
||||
- `volumeHandle`: A string value that uniquely identifies the volume. This value
|
||||
@@ -2091,8 +1996,8 @@ persistent volume:
|
||||
referencing the volume.
|
||||
-->
|
||||
- `volumeHandle`:唯一标识卷的字符串值。
|
||||
该值必须与 CSI 驱动在 `CreateVolumeResponse` 的 `volume_id` 字段中返回的值相对应;
|
||||
接口定义在 [CSI spec](https://github.com/container-storage-interface/spec/blob/master/spec.md#createvolume) 中。
|
||||
该值必须与 CSI 驱动在 `CreateVolumeResponse` 的 `volume_id` 字段中返回的值相对应;接口定义在
|
||||
[CSI 规范](https://github.com/container-storage-interface/spec/blob/master/spec.md#createvolume) 中。
|
||||
在所有对 CSI 卷驱动程序的调用中,引用该 CSI 卷时都使用此值作为 `volume_id` 参数。
|
||||
|
||||
<!--
|
||||
@@ -2101,8 +2006,7 @@ persistent volume:
|
||||
passed to the CSI driver via the `readonly` field in the
|
||||
`ControllerPublishVolumeRequest`.
|
||||
-->
|
||||
- `readOnly`:一个可选的布尔值,指示通过 `ControllerPublished` 关联该卷时是否设置
|
||||
该卷为只读。默认值是 false。
|
||||
- `readOnly`:一个可选的布尔值,指示通过 `ControllerPublished` 关联该卷时是否设置该卷为只读。默认值是 false。
|
||||
该值通过 `ControllerPublishVolumeRequest` 中的 `readonly` 字段传递给 CSI 驱动。
|
||||
|
||||
<!--
|
||||
@@ -2131,7 +2035,8 @@ persistent volume:
|
||||
- `volumeAttributes`:一个字符串到字符串的映射表,用来设置卷的静态属性。
|
||||
该映射必须与 CSI 驱动程序返回的 `CreateVolumeResponse` 中的 `volume.attributes`
|
||||
字段的映射相对应;
|
||||
[CSI 规范](https://github.com/container-storage-interface/spec/blob/master/spec.md#createvolume) 中有相应的定义。
|
||||
[CSI 规范](https://github.com/container-storage-interface/spec/blob/master/spec.md#createvolume)
|
||||
中有相应的定义。
|
||||
该映射通过`ControllerPublishVolumeRequest`、`NodeStageVolumeRequest`、和
|
||||
`NodePublishVolumeRequest` 中的 `volume_attributes` 字段传递给 CSI 驱动。
|
||||
|
||||
@@ -2239,10 +2144,8 @@ provisioning/delete, attach/detach, mount/unmount and resizing of volumes.
|
||||
In-tree plugins that support `CSIMigration` and have a corresponding CSI driver implemented
|
||||
are listed in [Types of Volumes](#volume-types).
|
||||
-->
|
||||
启用 `CSIMigration` 功能后,针对现有树内插件的操作会被重定向到相应的 CSI 插件
|
||||
(应已安装和配置)。
|
||||
因此,操作员在过渡到取代树内插件的 CSI 驱动时,无需对现有存储类、PV 或 PVC
|
||||
(指树内插件)进行任何配置更改。
|
||||
启用 `CSIMigration` 功能后,针对现有树内插件的操作会被重定向到相应的 CSI 插件(应已安装和配置)。
|
||||
因此,操作员在过渡到取代树内插件的 CSI 驱动时,无需对现有存储类、PV 或 PVC(指树内插件)进行任何配置更改。
|
||||
|
||||
所支持的操作和功能包括:配备(Provisioning)/删除、挂接(Attach)/解挂(Detach)、
|
||||
挂载(Mount)/卸载(Unmount)和调整卷大小。
|
||||
@@ -2252,22 +2155,35 @@ are listed in [Types of Volumes](#volume-types).
|
||||
|
||||
### flexVolume
|
||||
|
||||
{{< feature-state for_k8s_version="v1.23" state="deprecated" >}}
|
||||
|
||||
<!--
|
||||
FlexVolume is an out-of-tree plugin interface that has existed in Kubernetes
|
||||
since version 1.2 (before CSI). It uses an exec-based model to interface with
|
||||
drivers. The FlexVolume driver binaries must be installed in a pre-defined volume
|
||||
plugin path on each node (and in some cases master).
|
||||
FlexVolume is an out-of-tree plugin interface that uses an exec-based model to interface
|
||||
with storage drivers. The FlexVolume driver binaries must be installed in a pre-defined
|
||||
volume plugin path on each node and in some cases the control plane nodes as well.
|
||||
|
||||
Pods interact with FlexVolume drivers through the `flexvolume` in-tree plugin.
|
||||
More details can be found [here](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-storage/flexvolume.md).
|
||||
Pods interact with FlexVolume drivers through the `flexVolume` in-tree volume plugin.
|
||||
For more details, see the FlexVolume [README](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-storage/flexvolume.md#readme) document.
|
||||
-->
|
||||
FlexVolume 是一个自 1.2 版本(在 CSI 之前)以来在 Kubernetes 中一直存在的树外插件接口。
|
||||
它使用基于 exec 的模型来与驱动程序对接。
|
||||
用户必须在每个节点(在某些情况下是主控节点)上的预定义卷插件路径中安装
|
||||
FlexVolume 驱动程序可执行文件。
|
||||
FlexVolume 是一个使用基于 exec 的模型来与驱动程序对接的树外插件接口。
|
||||
用户必须在每个节点上的预定义卷插件路径中安装 FlexVolume
|
||||
驱动程序可执行文件,在某些情况下,控制平面节点中也要安装。
|
||||
|
||||
Pod 通过 `flexvolume` 树内插件与 Flexvolume 驱动程序交互。
|
||||
更多详情请参考 [FlexVolume](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-storage/flexvolume.md) 示例。
|
||||
Pod 通过 `flexvolume` 树内插件与 FlexVolume 驱动程序交互。
|
||||
更多详情请参考 FlexVolume [README](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-storage/flexvolume.md#readme) 文档。
|
||||
|
||||
<!--
|
||||
FlexVolume is deprecated. Using an out-of-tree CSI driver is the recommended way to integrate external storage with Kubernetes.
|
||||
|
||||
Maintainers of FlexVolume driver should implement a CSI Driver and help to migrate users of FlexVolume drivers to CSI.
|
||||
Users of FlexVolume should move their workloads to use the equivalent CSI Driver.
|
||||
-->
|
||||
{{< note >}}
|
||||
FlexVolume 已弃用。推荐使用树外 CSI 驱动来将外部存储整合进 Kubernetes。
|
||||
|
||||
FlexVolume 驱动的维护者应开发一个 CSI 驱动并帮助用户从 FlexVolume 驱动迁移到 CSI。
|
||||
FlexVolume 用户应迁移工作负载以使用对等的 CSI 驱动。
|
||||
{{< /note >}}
|
||||
|
||||
<!--
|
||||
## Mount propagation
|
||||
@@ -2280,8 +2196,7 @@ Its values are:
|
||||
-->
|
||||
## 挂载卷的传播 {#mount-propagation}
|
||||
|
||||
挂载卷的传播能力允许将容器安装的卷共享到同一 Pod 中的其他容器,
|
||||
甚至共享到同一节点上的其他 Pod。
|
||||
挂载卷的传播能力允许将容器安装的卷共享到同一 Pod 中的其他容器,甚至共享到同一节点上的其他 Pod。
|
||||
|
||||
卷的挂载传播特性由 `Container.volumeMounts` 中的 `mountPropagation` 字段控制。
|
||||
它的值包括:
|
||||
@@ -2320,8 +2235,8 @@ Its values are:
|
||||
|
||||
换句话说,如果主机在此挂载卷中挂载任何内容,容器将能看到它被挂载在那里。
|
||||
|
||||
类似的,配置了 `Bidirectional` 挂载传播选项的 Pod 如果在同一卷上挂载了内容,
|
||||
挂载传播设置为 `HostToContainer` 的容器都将能看到这一变化。
|
||||
类似的,配置了 `Bidirectional` 挂载传播选项的 Pod 如果在同一卷上挂载了内容,挂载传播设置为
|
||||
`HostToContainer` 的容器都将能看到这一变化。
|
||||
|
||||
该模式等同于 [Linux 内核文档](https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt)
|
||||
中描述的 `rslave` 挂载传播选项。
|
||||
@@ -2366,8 +2281,7 @@ Docker as shown below.
|
||||
-->
|
||||
### 配置 {#configuration}
|
||||
|
||||
在某些部署环境中,挂载传播正常工作前,必须在 Docker 中正确配置挂载共享(mount share),
|
||||
如下所示。
|
||||
在某些部署环境中,挂载传播正常工作前,必须在 Docker 中正确配置挂载共享(mount share),如下所示。
|
||||
|
||||
<!--
|
||||
Edit your Docker's `systemd` service file. Set `MountFlags` as follows:
|
||||
|
||||
@@ -115,19 +115,7 @@ This example CronJob manifest prints the current time and a hello message every
|
||||
# │ │ ┌───────────── 月的某天 (1 - 31)
|
||||
# │ │ │ ┌───────────── 月份 (1 - 12)
|
||||
# │ │ │ │ ┌───────────── 周的某天 (0 - 6)(周日到周一;在某些系统上,7 也是星期日)
|
||||
# │ │ │ │ │
|
||||
# │ │ │ │ │
|
||||
# │ │ │ │ │
|
||||
# * * * * *
|
||||
```
|
||||
|
||||
```
|
||||
# ┌───────────── 分钟 (0 - 59)
|
||||
# │ ┌───────────── 小时 (0 - 23)
|
||||
# │ │ ┌───────────── 月的某天 (1 - 31)
|
||||
# │ │ │ ┌───────────── 月份 (1 - 12)
|
||||
# │ │ │ │ ┌───────────── 周的某天 (0 - 6) (周日到周一;在某些系统上,7 也是星期日)
|
||||
# │ │ │ │ │
|
||||
# │ │ │ │ │ 或者是 sun,mon,tue,web,thu,fri,sat
|
||||
# │ │ │ │ │
|
||||
# │ │ │ │ │
|
||||
# * * * * *
|
||||
|
||||
@@ -35,7 +35,7 @@ template.
|
||||
-->
|
||||
## ReplicaSet 的工作原理 {#how-a-replicaset-works}
|
||||
|
||||
RepicaSet 是通过一组字段来定义的,包括一个用来识别可获得的 Pod
|
||||
ReplicaSet 是通过一组字段来定义的,包括一个用来识别可获得的 Pod
|
||||
的集合的选择算符、一个用来标明应该维护的副本个数的数值、一个用来指定应该创建新 Pod
|
||||
以满足副本个数条件时要使用的 Pod 模板等等。
|
||||
每个 ReplicaSet 都通过根据需要创建和 删除 Pod 以使得副本个数达到期望值,
|
||||
|
||||
@@ -331,7 +331,7 @@ kubectl 将 ReplicationController 缩放为 0 并等待以便在删除 Replicati
|
||||
|
||||
You can delete a ReplicationController without affecting any of its pods.
|
||||
|
||||
Using kubectl, specify the `--cascade=false` option to [`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete).
|
||||
Using kubectl, specify the `--cascade=orphan` option to [`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete).
|
||||
|
||||
When using the REST API or Go client library, simply delete the ReplicationController object.
|
||||
-->
|
||||
@@ -339,7 +339,7 @@ When using the REST API or Go client library, simply delete the ReplicationContr
|
||||
|
||||
你可以删除一个 ReplicationController 而不影响它的任何 Pod。
|
||||
|
||||
使用 kubectl,为 [`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete) 指定 `--cascade=false` 选项。
|
||||
使用 kubectl,为 [`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete) 指定 `--cascade=orphan` 选项。
|
||||
|
||||
当使用 REST API 或 Go 客户端库时,只需删除 ReplicationController 对象。
|
||||
|
||||
@@ -501,12 +501,12 @@ ReplicationController 永远被限制在这个狭隘的职责范围内。
|
||||
我们甚至计划考虑批量创建 Pod 的机制(查阅 [#170](https://issue.k8s.io/170))。
|
||||
|
||||
<!--
|
||||
The ReplicationController is intended to be a composable building-block primitive. We expect higher-level APIs and/or tools to be built on top of it and other complementary primitives for user convenience in the future. The "macro" operations currently supported by kubectl (run, scale, rolling-update) are proof-of-concept examples of this. For instance, we could imagine something like [Asgard](http://techblog.netflix.com/2012/06/asgard-web-based-cloud-management-and.html) managing ReplicationControllers, auto-scalers, services, scheduling policies, canaries, etc.
|
||||
The ReplicationController is intended to be a composable building-block primitive. We expect higher-level APIs and/or tools to be built on top of it and other complementary primitives for user convenience in the future. The "macro" operations currently supported by kubectl (run, scale, rolling-update) are proof-of-concept examples of this. For instance, we could imagine something like [Asgard](https://netflixtechblog.com/asgard-web-based-cloud-management-and-deployment-2c9fc4e4d3a1) managing ReplicationControllers, auto-scalers, services, scheduling policies, canaries, etc.
|
||||
-->
|
||||
ReplicationController 旨在成为可组合的构建基元。
|
||||
我们希望在它和其他补充原语的基础上构建更高级别的 API 或者工具,以便于将来的用户使用。
|
||||
kubectl 目前支持的 "macro" 操作(运行、缩放、滚动更新)就是这方面的概念示例。
|
||||
例如,我们可以想象类似于 [Asgard](https://techblog.netflix.com/2012/06/asgaard-web-based-cloud-management-and.html)
|
||||
例如,我们可以想象类似于 [Asgard](https://netflixtechblog.com/asgard-web-based-cloud-management-and-deployment-2c9fc4e4d3a1)
|
||||
的东西管理 ReplicationController、自动定标器、服务、调度策略、金丝雀发布等。
|
||||
|
||||
<!--
|
||||
@@ -544,16 +544,14 @@ Note that we recommend using Deployments instead of directly using Replica Sets,
|
||||
<!--
|
||||
### Deployment (Recommended)
|
||||
|
||||
[`Deployment`](/docs/concepts/workloads/controllers/deployment/) is a higher-level API object that updates its underlying Replica Sets and their Pods
|
||||
in a similar fashion as `kubectl rolling-update`. Deployments are recommended if you want this rolling update functionality,
|
||||
because unlike `kubectl rolling-update`, they are declarative, server-side, and have additional features.
|
||||
[`Deployment`](/docs/concepts/workloads/controllers/deployment/) is a higher-level API object that updates its underlying Replica Sets and their Pods.
|
||||
Deployments are recommended if you want the rolling update functionality,
|
||||
because they are declarative, server-side, and have additional features.
|
||||
-->
|
||||
### Deployment (推荐)
|
||||
|
||||
[`Deployment`](/zh/docs/concepts/workloads/controllers/deployment/) 是一种更高级别的 API 对象,
|
||||
它以类似于 `kubectl rolling-update` 的方式更新其底层 ReplicaSet 及其 Pod。
|
||||
如果你想要这种滚动更新功能,那么推荐使用 Deployment,因为与 `kubectl rolling-update` 不同,
|
||||
它们是声明式的、服务端的,并且具有其它特性。
|
||||
[`Deployment`](/zh/docs/concepts/workloads/controllers/deployment/) 是一种更高级别的 API 对象,用于更新其底层 ReplicaSet 及其 Pod。
|
||||
如果你想要这种滚动更新功能,那么推荐使用 Deployment,因为它们是声明式的、服务端的,并且具有其它特性。
|
||||
|
||||
<!--
|
||||
### Bare Pods
|
||||
@@ -596,11 +594,19 @@ ReplicationController。
|
||||
并且在机器准备重新启动或者关闭时安全地终止。
|
||||
|
||||
<!--
|
||||
## For more information
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
Read [Run Stateless AP Replication Controller](/docs/tutorials/stateless-application/run-stateless-ap-replication-controller/).
|
||||
* Learn about [Pods](/docs/concepts/workloads/pods).
|
||||
* Learn about [Deployment](/docs/concepts/workloads/controllers/deployment/), the replacement
|
||||
for ReplicationController.
|
||||
* `ReplicationController` is part of the Kubernetes REST API.
|
||||
Read the {{< api-reference page="workload-resources/replication-controller-v1" >}}
|
||||
object definition to understand the API for replication controllers.
|
||||
-->
|
||||
## 更多信息
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
请阅读[运行无状态的 ReplicationController](/zh/docs/tasks/run-application/run-stateless-application-deployment/)。
|
||||
- 了解 [Pods](/zh/docs/concepts/workloads/pods)。
|
||||
- 了解 [Depolyment](/zh/docs/concepts/workloads/controllers/deployment/),ReplicationController 的替代品。
|
||||
- `ReplicationController` 是 Kubernetes REST API 的一部分,阅读 {{< api-reference page="workload-resources/replication-controller-v1" >}}
|
||||
对象定义以了解 replication controllers 的 API。
|
||||
|
||||
|
||||
@@ -1,65 +1,54 @@
|
||||
---
|
||||
title: 已完成资源的 TTL 控制器
|
||||
title: 已完成 Job 的自动清理
|
||||
content_type: concept
|
||||
weight: 70
|
||||
---
|
||||
<!--
|
||||
title: TTL Controller for Finished Resources
|
||||
title: Automatic Clean-up for Finished Jobs
|
||||
content_type: concept
|
||||
weight: 70
|
||||
-->
|
||||
|
||||
<!-- overview -->
|
||||
|
||||
{{< feature-state for_k8s_version="v1.21" state="beta" >}}
|
||||
{{< feature-state for_k8s_version="v1.23" state="stable" >}}
|
||||
|
||||
<!--
|
||||
The TTL controller provides a TTL mechanism to limit the lifetime of resource
|
||||
objects that have finished execution. TTL controller only handles
|
||||
{{< glossary_tooltip text="Jobs" term_id="job" >}} for now,
|
||||
and may be expanded to handle other resources that will finish execution,
|
||||
such as Pods and custom resources.
|
||||
TTL-after-finished {{<glossary_tooltip text="controller" term_id="controller">}} provides a
|
||||
TTL (time to live) mechanism to limit the lifetime of resource objects that
|
||||
have finished execution. TTL controller only handles
|
||||
{{< glossary_tooltip text="Jobs" term_id="job" >}}.
|
||||
-->
|
||||
TTL 控制器提供了一种 TTL 机制来限制已完成执行的资源对象的生命周期。
|
||||
TTL 控制器目前只处理 {{< glossary_tooltip text="Job" term_id="job" >}},
|
||||
可能以后会扩展以处理将完成执行的其他资源,例如 Pod 和自定义资源。
|
||||
TTL-after-finished {{<glossary_tooltip text="控制器" term_id="controller">}} 提供了一种 TTL 机制来限制已完成执行的资源对象的生命周期。
|
||||
TTL 控制器目前只处理 {{< glossary_tooltip text="Job" term_id="job" >}}。
|
||||
|
||||
<!--
|
||||
This feature is currently beta and enabled by default, and can be disabled via
|
||||
[feature gate](/docs/reference/command-line-tools-reference/feature-gates/)
|
||||
`TTLAfterFinished` in both kube-apiserver and kube-controller-manager.
|
||||
-->
|
||||
此功能目前是 Beta 版而自动启用,并且可以通过 `kube-apiserver` 和
|
||||
`kube-controller-manager` 上的
|
||||
[特性门控](/zh/docs/reference/command-line-tools-reference/feature-gates/)
|
||||
`TTLAfterFinished` 禁用。
|
||||
|
||||
<!-- body -->
|
||||
|
||||
<!--
|
||||
## TTL Controller
|
||||
## TTL-after-finished Controller
|
||||
|
||||
The TTL controller only supports Jobs for now. A cluster operator can use this feature to clean
|
||||
The TTL-after-finished controller is only supported for Jobs. A cluster operator can use this feature to clean
|
||||
up finished Jobs (either `Complete` or `Failed`) automatically by specifying the
|
||||
`.spec.ttlSecondsAfterFinished` field of a Job, as in this
|
||||
[example](/docs/concepts/workloads/controllers/job/#clean-up-finished-jobs-automatically).
|
||||
-->
|
||||
## TTL 控制器
|
||||
## TTL-after-finished 控制器
|
||||
|
||||
TTL 控制器现在只支持 Job。集群操作员可以通过指定 Job 的 `.spec.ttlSecondsAfterFinished`
|
||||
TTL-after-finished 控制器只支持 Job。集群操作员可以通过指定 Job 的 `.spec.ttlSecondsAfterFinished`
|
||||
字段来自动清理已结束的作业(`Complete` 或 `Failed`),如
|
||||
[示例](/zh/docs/concepts/workloads/controllers/job/#clean-up-finished-jobs-automatically)
|
||||
所示。
|
||||
|
||||
<!--
|
||||
The TTL controller will assume that a resource is eligible to be cleaned up
|
||||
TTL seconds after the resource has finished, in other words, when the TTL has expired. When the
|
||||
TTL controller cleans up a resource, it will delete it cascadingly, i.e. delete
|
||||
its dependent objects together with it. Note that when the resource is deleted,
|
||||
The TTL-after-finished controller will assume that a job is eligible to be cleaned up
|
||||
TTL seconds after the job has finished, in other words, when the TTL has expired. When the
|
||||
TTL-after-finished controller cleans up a job, it will delete it cascadingly, that is to say it will delete
|
||||
its dependent objects together with it. Note that when the job is deleted,
|
||||
its lifecycle guarantees, such as finalizers, will be honored.
|
||||
-->
|
||||
TTL 控制器假设资源能在执行完成后的 TTL 秒内被清理,也就是当 TTL 过期后。
|
||||
当 TTL 控制器清理资源时,它将做级联删除操作,即删除资源对象的同时也删除其依赖对象。
|
||||
TTL-after-finished 控制器假设作业能在执行完成后的 TTL 秒内被清理,也就是当 TTL 过期后。
|
||||
当 TTL 控制器清理作业时,它将做级联删除操作,即删除资源对象的同时也删除其依赖对象。
|
||||
注意,当资源被删除时,由该资源的生命周期保证其终结器(Finalizers)等被执行。
|
||||
|
||||
<!--
|
||||
@@ -69,24 +58,24 @@ The TTL seconds can be set at any time. Here are some examples for setting the
|
||||
可以随时设置 TTL 秒。以下是设置 Job 的 `.spec.ttlSecondsAfterFinished` 字段的一些示例:
|
||||
|
||||
<!--
|
||||
* Specify this field in the resource manifest, so that a Job can be cleaned up
|
||||
* Specify this field in the job manifest, so that a Job can be cleaned up
|
||||
automatically some time after it finishes.
|
||||
* Set this field of existing, already finished resources, to adopt this new feature.
|
||||
* Set this field of existing, already finished jobs, to adopt this new feature.
|
||||
* Use a
|
||||
[mutating admission webhook](/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks)
|
||||
to set this field dynamically at resource creation time. Cluster administrators can
|
||||
use this to enforce a TTL policy for finished resources.
|
||||
to set this field dynamically at job creation time. Cluster administrators can
|
||||
use this to enforce a TTL policy for finished jobs.
|
||||
* Use a
|
||||
[mutating admission webhook](/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks)
|
||||
to set this field dynamically after the resource has finished, and choose
|
||||
different TTL values based on resource status, labels, etc.
|
||||
to set this field dynamically after the job has finished, and choose
|
||||
different TTL values based on job status, labels, etc.
|
||||
-->
|
||||
* 在资源清单(manifest)中指定此字段,以便 Job 在完成后的某个时间被自动清除。
|
||||
* 将此字段设置为现有的、已完成的资源,以采用此新功能。
|
||||
* 在创建资源时使用 [mutating admission webhook](/zh/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks)
|
||||
动态设置该字段。集群管理员可以使用它对完成的资源强制执行 TTL 策略。
|
||||
* 在作业清单(manifest)中指定此字段,以便 Job 在完成后的某个时间被自动清除。
|
||||
* 将此字段设置为现有的、已完成的作业,以采用此新功能。
|
||||
* 在创建作业时使用 [mutating admission webhook](/zh/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks)
|
||||
动态设置该字段。集群管理员可以使用它对完成的作业强制执行 TTL 策略。
|
||||
* 使用 [mutating admission webhook](/zh/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks)
|
||||
在资源完成后动态设置该字段,并根据资源状态、标签等选择不同的 TTL 值。
|
||||
在作业完成后动态设置该字段,并根据作业状态、标签等选择不同的 TTL 值。
|
||||
|
||||
<!--
|
||||
## Caveat
|
||||
@@ -94,16 +83,16 @@ The TTL seconds can be set at any time. Here are some examples for setting the
|
||||
### Updating TTL Seconds
|
||||
|
||||
Note that the TTL period, e.g. `.spec.ttlSecondsAfterFinished` field of Jobs,
|
||||
can be modified after the resource is created or has finished. However, once the
|
||||
can be modified after the job is created or has finished. However, once the
|
||||
Job becomes eligible to be deleted (when the TTL has expired), the system won't
|
||||
guarantee that the Jobs will be kept, even if an update to extend the TTL
|
||||
returns a successful API response.
|
||||
-->
|
||||
## 警告
|
||||
|
||||
### 更新 TTL 秒
|
||||
### 更新 TTL 秒数
|
||||
|
||||
请注意,在创建资源或已经执行结束后,仍可以修改其 TTL 周期,例如 Job 的
|
||||
请注意,在创建 Job 或已经执行结束后,仍可以修改其 TTL 周期,例如 Job 的
|
||||
`.spec.ttlSecondsAfterFinished` 字段。
|
||||
但是一旦 Job 变为可被删除状态(当其 TTL 已过期时),即使您通过 API 增加其 TTL
|
||||
时长得到了成功的响应,系统也不保证 Job 将被保留。
|
||||
@@ -111,25 +100,21 @@ returns a successful API response.
|
||||
<!--
|
||||
### Time Skew
|
||||
|
||||
Because TTL controller uses timestamps stored in the Kubernetes resources to
|
||||
Because TTL-after-finished controller uses timestamps stored in the Kubernetes resources to
|
||||
determine whether the TTL has expired or not, this feature is sensitive to time
|
||||
skew in the cluster, which may cause TTL controller to clean up resource objects
|
||||
skew in the cluster, which may cause TTL-after-finished controller to clean up resource objects
|
||||
at the wrong time.
|
||||
-->
|
||||
### 时间偏差 {#time-skew}
|
||||
|
||||
由于 TTL 控制器使用存储在 Kubernetes 资源中的时间戳来确定 TTL 是否已过期,
|
||||
因此该功能对集群中的时间偏差很敏感,这可能导致 TTL 控制器在错误的时间清理资源对象。
|
||||
由于 TTL-after-finished 控制器使用存储在 Kubernetes 资源中的时间戳来确定 TTL 是否已过期,
|
||||
因此该功能对集群中的时间偏差很敏感,这可能导致 TTL-after-finished 控制器在错误的时间清理资源对象。
|
||||
|
||||
<!--
|
||||
In Kubernetes, it's required to run NTP on all nodes
|
||||
(see [#6159](https://github.com/kubernetes/kubernetes/issues/6159#issuecomment-93844058))
|
||||
to avoid time skew. Clocks aren't always correct, but the difference should be
|
||||
Clocks aren't always correct, but the difference should be
|
||||
very small. Please be aware of this risk when setting a non-zero TTL.
|
||||
-->
|
||||
在 Kubernetes 中,需要在所有节点上运行 NTP(参见
|
||||
[#6159](https://github.com/kubernetes/kubernetes/issues/6159#issuecomment-93844058))
|
||||
以避免时间偏差。时钟并不总是如此正确,但差异应该很小。
|
||||
时钟并不总是如此正确,但差异应该很小。
|
||||
设置非零 TTL 时请注意避免这种风险。
|
||||
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
@@ -44,7 +44,7 @@ the documentation, the website style, the processes for reviewing and merging
|
||||
pull requests, or other aspects of the documentation. For maximum transparency,
|
||||
these types of proposals need to be discussed in a SIG Docs meeting or on the
|
||||
[kubernetes-sig-docs mailing list](https://groups.google.com/forum/#!forum/kubernetes-sig-docs).
|
||||
In addition, it can really help to have some context about the way things
|
||||
In addition, it can help to have some context about the way things
|
||||
currently work and why past decisions have been made before proposing sweeping
|
||||
changes. The quickest way to get answers to questions about how the documentation
|
||||
currently works is to ask in the `#sig-docs` Slack channel on
|
||||
@@ -55,7 +55,7 @@ currently works is to ask in the `#sig-docs` Slack channel on
|
||||
评审和合并 PR 的流程或者文档的其他方面产生改进的想法。
|
||||
为了尽可能透明化,这些提议都需要在 SIG Docs 会议或
|
||||
[kubernetes-sig-docs 邮件列表](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)上讨论。
|
||||
此外,在提出全面的改进之前,这些讨论能真正帮助我们了解有关“当前工作如何运作”和“以往的决定是为何做出”的背景。
|
||||
此外,在提出全面的改进之前,这些讨论能帮助我们了解有关“当前工作如何运作”和“以往的决定是为何做出”的背景。
|
||||
想了解文档的当前运作方式,最快的途径是咨询 [kubernetes.slack.com](https://kubernetes.slack.com)
|
||||
中的 `#sig-docs` 聊天群组。
|
||||
|
||||
@@ -96,7 +96,7 @@ refer to
|
||||
The SIG Docs representative for a given release coordinates the following tasks:
|
||||
|
||||
- Monitor the feature-tracking spreadsheet for new or changed features with an
|
||||
impact on documentation. If documentation for a given feature won't be ready
|
||||
impact on documentation. If the documentation for a given feature won't be ready
|
||||
for the release, the feature may not be allowed to go into the release.
|
||||
- Attend sig-release meetings regularly and give updates on the status of the
|
||||
docs for the release.
|
||||
@@ -151,19 +151,21 @@ SIG Docs [批准人(Approvers)](/zh/docs/contribute/participating/#approvers
|
||||
|
||||
<!--
|
||||
- Being available on the [Kubernetes #sig-docs channel](https://kubernetes.slack.com) to answer questions from new contributors.
|
||||
- Working with PR wranglers to identify good first issues for new contributors.
|
||||
- Working with PR wranglers to identify [good first issues](https://kubernetes.dev/docs/guide/help-wanted/#good-first-issue) for new contributors.
|
||||
- Mentoring new contributors through their first few PRs to the docs repo.
|
||||
- Helping new contributors create the more complex PRs they need to become Kubernetes members.
|
||||
-[Sponsoring contributors](/docs/contribute/advanced/#sponsor-a-new-contributor) on their path to becoming Kubernetes members.
|
||||
- Hosting a monthly meeting to help and mentor new contributors.
|
||||
-->
|
||||
- 监听 [Kubernetes #sig-docs 频道](https://kubernetes.slack.com) 上新贡献者的 Issue。
|
||||
- 与 PR 管理者合作为新参与者寻找合适的第一个 issues。
|
||||
- 与 PR 管理者合作为新参与者寻找[合适的第一个 issues](https://kubernetes.dev/docs/guide/help-wanted/#good-first-issue) 。
|
||||
- 通过前几个 PR 指导新贡献者为文档存储库作贡献。
|
||||
- 帮助新的贡献者创建成为 Kubernetes 成员所需的更复杂的 PR。
|
||||
- [为贡献者提供保荐](#sponsor-a-new-contributor),使其成为 Kubernetes 成员。
|
||||
- 每月召开一次会议,帮助和指导新的贡献者。
|
||||
|
||||
<!--
|
||||
Current New Contributor Ambassadors are announced at each SIG-Docs meeting, and in the [Kubernetes #sig-docs channel](https://kubernetes.slack.com).
|
||||
Current New Contributor Ambassadors are announced at each SIG-Docs meeting and in the [Kubernetes #sig-docs channel](https://kubernetes.slack.com).
|
||||
-->
|
||||
当前新贡献者大使将在每次 SIG 文档会议上以及 [Kubernetes #sig-docs 频道](https://kubernetes.slack.com)中宣布。
|
||||
|
||||
@@ -205,37 +207,37 @@ membership in the Kubernetes organization.
|
||||
<!--
|
||||
## Serve as a SIG Co-chair
|
||||
|
||||
SIG Docs [approvers](/docs/contribute/participating/#approvers) can serve a term as a co-chair of SIG Docs.
|
||||
SIG Docs [members](/docs/contribute/participate/roles-and-responsibilities/#members)
|
||||
can serve a term as a co-chair of SIG Docs.
|
||||
|
||||
### Prerequisites
|
||||
-->
|
||||
## 担任 SIG 联合主席
|
||||
|
||||
SIG Docs [批准人(Approvers)](/zh/docs/contribute/participate/roles-and-responsibilities/#approvers)
|
||||
SIG Docs [成员(Members)](/zh/docs/contribute/participate/roles-and-responsibilities/#members)
|
||||
可以担任 SIG Docs 的联合主席。
|
||||
|
||||
### 前提条件
|
||||
|
||||
<!--
|
||||
Approvers must meet the following requirements to be a co-chair:
|
||||
A Kubernetes member must meet the following requirements to be a co-chair:
|
||||
|
||||
- Have been a SIG Docs approver for at least 6 months
|
||||
- Have [led a Kubernetes docs release](/docs/contribute/advanced/#coordinate-docs-for-a-kubernetes-release) or shadowed two releases
|
||||
- Understand SIG Docs workflows and tooling: git, Hugo, localization, blog subproject
|
||||
- Understand how other Kubernetes SIGs and repositories affect the SIG Docs workflow, including: [teams in k/org](https://github.com/kubernetes/org/blob/master/config/kubernetes/sig-docs/teams.yaml), [process in k/community](https://github.com/kubernetes/community/tree/master/sig-docs), plugins in [k/test-infra](https://github.com/kubernetes/test-infra/), and the role of [SIG Architecture](https://github.com/kubernetes/community/tree/master/sig-architecture).
|
||||
- Understand how other Kubernetes SIGs and repositories affect the SIG Docs workflow, including: [teams in k/org](https://github.com/kubernetes/org/blob/master/config/kubernetes/sig-docs/teams.yaml), the [process in k/community](https://github.com/kubernetes/community/tree/master/sig-docs), plugins in [k/test-infra](https://github.com/kubernetes/test-infra/), and the role of [SIG Architecture](https://github.com/kubernetes/community/tree/master/sig-architecture).
|
||||
In addition, understand how the [Kubernetes docs release process](/docs/contribute/advanced/#coordinate-docs-for-a-kubernetes-release) works.
|
||||
- Approved by the SIG Docs community either directly or via lazy consensus.
|
||||
- Commit at least 5 hours per week (and often more) to the role for a minimum of 6 months
|
||||
-->
|
||||
Approvers 必须满足以下要求才能成为联合主席:
|
||||
Kubernetes 成员必须满足以下要求才能成为联合主席:
|
||||
|
||||
- 已维持 SIG Docs approver 身份至少 6 个月
|
||||
- [曾领导 Kubernetes 文档发布](/zh/docs/contribute/advanced/#coordinate-docs-for-a-kubernetes-release)
|
||||
或者在两个版本发布中有实习经历
|
||||
- 理解 SIG Docs 工作流程和工具:git、Hugo、本地化、博客子项目
|
||||
- 理解其他 Kubernetes SIG 和仓库会如何影响 SIG Docs 工作流程,包括:
|
||||
[k/org 中的团队](https://github.com/kubernetes/org/blob/master/config/kubernetes/sig-docs/teams.yaml)、
|
||||
[k/community 中的流程](https://github.com/kubernetes/community/tree/master/sig-docs)、
|
||||
[k/test-infra](https://github.com/kubernetes/test-infra/) 中的插件、
|
||||
[SIG Architecture](https://github.com/kubernetes/community/tree/master/sig-architecture) 中的角色。
|
||||
此外,了解 [Kubernetes 文档发布流程](/docs/contribute/advanced/#coordinate-docs-for-a-kubernetes-release) 的工作原理。
|
||||
- 由 SIG Docs 社区直接或通过惰性共识批准。
|
||||
- 在至少 6 个月的时段内,确保每周至少投入 5 个小时(通常更多)
|
||||
|
||||
<!--
|
||||
|
||||
@@ -493,6 +493,7 @@ 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
|
||||
Releases | [All heading and subheading URLs](/releases)
|
||||
-->
|
||||
描述 | 网址
|
||||
-----|-----
|
||||
@@ -500,7 +501,7 @@ Site strings | [All site strings](#Site-strings-in-i18n) in a new localized TOML
|
||||
安装 | [所有标题和副标题网址](/zh/docs/setup/)
|
||||
教程 | [Kubernetes 基础](/zh/docs/tutorials/kubernetes-basics/), [Hello Minikube](/zh/docs/tutorials/hello-minikube/)
|
||||
网站字符串 | [所有网站字符串](#Site-strings-in-i18n)
|
||||
|
||||
发行版本 | [所有标题和副标题 URL](/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:
|
||||
-->
|
||||
@@ -616,6 +617,24 @@ Some language teams have their own language-specific style guide and glossary. F
|
||||
一些语言团队有自己的特定语言样式指南和词汇表。
|
||||
例如,请参见[中文本地化指南](/zh/docs/contribute/localization_zh/)。
|
||||
|
||||
<!--
|
||||
### 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.
|
||||
|
||||
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.
|
||||
|
||||
-->
|
||||
|
||||
### 特定语言的 Zoom 会议
|
||||
|
||||
如果本地化项目需要单独的会议时间,
|
||||
请联系 SIG Docs 联合主席或技术主管以创建新的重复 Zoom 会议和日历邀请。
|
||||
仅当团队维持在足够大的规模并需要单独的会议时才需要这样做。
|
||||
|
||||
根据 CNCF 政策,本地化团队必须将他们的会议上传到 SIG Docs YouTube 播放列表。
|
||||
SIG Docs 联合主席或技术主管可以帮助完成该过程,直到 SIG Docs 实现自动化。
|
||||
|
||||
<!--
|
||||
## Branching strategy
|
||||
|
||||
@@ -685,7 +704,7 @@ Teams must merge localized content into the same branch from which the content w
|
||||
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 >}}`.
|
||||
|
||||
@@ -352,7 +352,7 @@ Website 的仓库中 `scripts/linkchecker.py` 是一个工具,可用来检查
|
||||
- attach,挂接
|
||||
- autoscale,自动扩缩容
|
||||
- bearer token,持有者令牌
|
||||
- capabilities权能字
|
||||
- capabilities
|
||||
* 当泛指某主体执行某操作的能力时,可直译为“能力”
|
||||
* 当特指 Linux 操作系统上的[权限控制](http://man7.org/linux/man-pages/man7/capabilities.7.html)机制时,译为“权能字”
|
||||
- certificate authority,证书机构
|
||||
|
||||
@@ -153,7 +153,7 @@ Prow 命令。
|
||||
{{< table caption="Prow commands for reviewing" >}}
|
||||
Prow Command | Role Restrictions | Description
|
||||
:------------|:------------------|:-----------
|
||||
`/lgtm` | Anyone, but triggers automation if a Reviewer or Approver uses it | Signals that you've finished reviewing a PR and are satisfied with the changes.
|
||||
`/lgtm` | Organization members | Signals that you've finished reviewing a PR and are satisfied with the changes.
|
||||
`/approve` | Approvers | Approves a PR for merging.
|
||||
`/assign` | Reviewers or Approvers | Assigns a person to review or approve a PR
|
||||
`/close` | Reviewers or Approvers | Closes an issue or PR.
|
||||
@@ -167,7 +167,7 @@ of commands you can use in a PR.
|
||||
{{< table caption="评阅用 Prow 命令" >}}
|
||||
Prow 命令 | 角色限制 | 描述
|
||||
:------------|:------------------|:-----------
|
||||
`/lgtm` | 任何人均可使用,但只有评阅人和批准人使用此命令的时候才会触发自动化操作 | 用来表明你已经完成 PR 的评阅并对其所作变更表示满意
|
||||
`/lgtm` | 组织成员 | 用来表明你已经完成 PR 的评阅并对其所作变更表示满意
|
||||
`/approve` | 批准人 | 批准某 PR 可以合并
|
||||
`/assign` |评阅人或批准人 | 指派某人来评阅或批准某 PR
|
||||
`/close` | 评阅人或批准人 | 关闭 Issue 或 PR
|
||||
@@ -233,7 +233,7 @@ finds issues that might need triage.
|
||||
`priority/important-longterm` | Do this within 6 months.
|
||||
`priority/backlog` | Deferrable indefinitely. Do when resources are available.
|
||||
`priority/awaiting-more-evidence` | Placeholder for a potentially good issue so it doesn't get lost.
|
||||
`help` or `good first issue` | Suitable for someone with very little Kubernetes or SIG Docs experience. See [Help Wanted and Good First Issue Labels](https://github.com/kubernetes/community/blob/master/contributors/guide/help-wanted.md) for more information.
|
||||
`help` or `good first issue` | Suitable for someone with very little Kubernetes or SIG Docs experience. See [Help Wanted and Good First Issue Labels](https://kubernetes.dev/docs/guide/help-wanted/) for more information.
|
||||
|
||||
At your discretion, take ownership of an issue and submit a PR for it
|
||||
(especially if it's quick or relates to work you're already doing).
|
||||
@@ -252,7 +252,7 @@ the [kubernetes-sig-docs mailing list](https://groups.google.com/forum/#!forum/k
|
||||
`priority/important-longterm` | 应在 6 个月内处理
|
||||
`priority/backlog` | 可无限期地推迟,可在人手充足时处理
|
||||
`priority/awaiting-more-evidence` | 占位符,标示 Issue 可能是一个不错的 Issue,避免该 Issue 被忽略或遗忘
|
||||
`help` or `good first issue` | 适合对 Kubernetes 或 SIG Docs 经验较少的贡献者来处理。更多信息可参考[需要帮助和入门候选 Issue 标签](https://github.com/kubernetes/community/blob/master/contributors/guide/help-wanted.md)。
|
||||
`help` or `good first issue` | 适合对 Kubernetes 或 SIG Docs 经验较少的贡献者来处理。更多信息可参考[需要帮助和入门候选 Issue 标签](https://kubernetes.dev/docs/guide/help-wanted/)。
|
||||
{{< /table >}}
|
||||
|
||||
基于你自己的判断,你可以选择某 Issue 来处理,为之发起 PR
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user