From 7c75b157ac5323ef44bd0eb20c17fe72461b9b2a Mon Sep 17 00:00:00 2001 From: RA489 Date: Tue, 6 Apr 2021 16:52:44 +0530 Subject: [PATCH 001/115] Improvement for other tools --- content/en/docs/reference/tools/_index.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/content/en/docs/reference/tools/_index.md b/content/en/docs/reference/tools/_index.md index 7194ab83bd533..48a9b20f411c2 100644 --- a/content/en/docs/reference/tools/_index.md +++ b/content/en/docs/reference/tools/_index.md @@ -8,14 +8,14 @@ no_list: true --- -Kubernetes contains several built-in tools to help you work with the Kubernetes system. +Kubernetes contains several built-in as well as third party tools to help you work with the Kubernetes system. ## Minikube -[`minikube`](https://minikube.sigs.k8s.io/docs/) is a tool that +[`minikube`](https://minikube.sigs.k8s.io/docs/) is a built-in tool that runs a single-node Kubernetes cluster locally on your workstation for development and testing purposes. @@ -26,7 +26,7 @@ to a Kubernetes cluster, troubleshoot them, and manage the cluster and its resou ## Helm -[`Kubernetes Helm`](https://github.com/kubernetes/helm) is a tool for managing packages of pre-configured +[`Kubernetes Helm`](https://github.com/kubernetes/helm) is a third party managed tool for managing packages of pre-configured Kubernetes resources, aka Kubernetes charts. Use Helm to: @@ -39,7 +39,7 @@ Use Helm to: ## Kompose -[`Kompose`](https://github.com/kubernetes/kompose) is a tool to help Docker Compose users move to Kubernetes. +[`Kompose`](https://github.com/kubernetes/kompose) is a built-in tool to help Docker Compose users move to Kubernetes. Use Kompose to: From c1dc2b074f04a5b124de019c82df932820bcc148 Mon Sep 17 00:00:00 2001 From: kartik494 Date: Thu, 1 Jul 2021 13:05:52 +0530 Subject: [PATCH 002/115] Add docker server registry --- content/en/docs/concepts/configuration/secret.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/content/en/docs/concepts/configuration/secret.md b/content/en/docs/concepts/configuration/secret.md index 48ac53ed4746d..2fab83d67aef5 100644 --- a/content/en/docs/concepts/configuration/secret.md +++ b/content/en/docs/concepts/configuration/secret.md @@ -201,7 +201,8 @@ to create a Docker registry Secret, you can do: kubectl create secret docker-registry secret-tiger-docker \ --docker-username=tiger \ --docker-password=pass113 \ - --docker-email=tiger@acme.com + --docker-email=tiger@acme.com \ + --docker-server=my-registry:5000 ``` This command creates a Secret of type `kubernetes.io/dockerconfigjson`. From 6158a7f9260acc508e8829ccf0a42264e8459c9a Mon Sep 17 00:00:00 2001 From: sgpinkus Date: Fri, 9 Jul 2021 00:00:03 +1000 Subject: [PATCH 003/115] Update persistent-volumes.md Makes option 3 for "reclaiming" a released PV a bit clearer. Used to be: > Manually delete the associated storage asset, or if you want to reuse the same storage asset, create a new PersistentVolume with the same storage asset definition. But the 2nd part applies more to reclamation option 1 and is kind of contradictory with option 3 (which isn't really "reclaiming" anything AFAICT). So just move to it's own stand alone sentence. --- content/en/docs/concepts/storage/persistent-volumes.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/content/en/docs/concepts/storage/persistent-volumes.md b/content/en/docs/concepts/storage/persistent-volumes.md index f45d17ff54e36..b41fdcd069cad 100644 --- a/content/en/docs/concepts/storage/persistent-volumes.md +++ b/content/en/docs/concepts/storage/persistent-volumes.md @@ -131,7 +131,9 @@ The `Retain` reclaim policy allows for manual reclamation of the resource. When 1. Delete the PersistentVolume. The associated storage asset in external infrastructure (such as an AWS EBS, GCE PD, Azure Disk, or Cinder volume) still exists after the PV is deleted. 1. Manually clean up the data on the associated storage asset accordingly. -1. Manually delete the associated storage asset, or if you want to reuse the same storage asset, create a new PersistentVolume with the storage asset definition. +1. Manually delete the associated storage asset. + +If you want to reuse the same storage asset, create a new PersistentVolume with the same storage asset definition. #### Delete From cb712cdcd190a354f6dd055aa2a1ae7a01e3214b Mon Sep 17 00:00:00 2001 From: kartik494 Date: Fri, 2 Jul 2021 10:43:58 +0530 Subject: [PATCH 004/115] Add commit for hostname --- .../en/docs/concepts/configuration/secret.md | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/content/en/docs/concepts/configuration/secret.md b/content/en/docs/concepts/configuration/secret.md index 2fab83d67aef5..ba12fea86454a 100644 --- a/content/en/docs/concepts/configuration/secret.md +++ b/content/en/docs/concepts/configuration/secret.md @@ -202,7 +202,7 @@ kubectl create secret docker-registry secret-tiger-docker \ --docker-username=tiger \ --docker-password=pass113 \ --docker-email=tiger@acme.com \ - --docker-server=my-registry:5000 + --docker-server=my-registry.example:5000 ``` This command creates a Secret of type `kubernetes.io/dockerconfigjson`. @@ -212,15 +212,21 @@ on the fly: ```json { - "auths": { - "https://index.docker.io/v1/": { - "username": "tiger", - "password": "pass113", - "email": "tiger@acme.com", - "auth": "dGlnZXI6cGFzczExMw==" - } - } + "apiVersion": "v1", + "data": { + ".dockerconfigjson": "eyJhdXRocyI6eyJteS1yZWdpc3RyeTo1MDAwIjp7InVzZXJuYW1lIjoidGlnZXIiLCJwYXNzd29yZCI6InBhc3MxMTMiLCJlbWFpbCI6InRpZ2VyQGFjbWUuY29tIiwiYXV0aCI6ImRHbG5aWEk2Y0dGemN6RXhNdz09In19fQ==" + }, + "kind": "Secret", + "metadata": { + "creationTimestamp": "2021-07-01T07:30:59Z", + "name": "secret-tiger-docker", + "namespace": "default", + "resourceVersion": "566718", + "uid": "e15c1d7b-9071-4100-8681-f3a7a2ce89ca" + }, + "type": "kubernetes.io/dockerconfigjson" } + ``` ### Basic authentication Secret From 570757a47a64b61780d1fdc337ea0703d1d7f271 Mon Sep 17 00:00:00 2001 From: Ritikaa96 Date: Wed, 21 Jul 2021 16:46:18 +0530 Subject: [PATCH 005/115] updatnig flannel link address Signed-off-by: Ritikaa96 --- content/en/docs/concepts/cluster-administration/networking.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/docs/concepts/cluster-administration/networking.md b/content/en/docs/concepts/cluster-administration/networking.md index c517b13175c81..05a4a7e95207f 100644 --- a/content/en/docs/concepts/cluster-administration/networking.md +++ b/content/en/docs/concepts/cluster-administration/networking.md @@ -269,7 +269,7 @@ Lars Kellogg-Stedman. [Multus](https://github.com/Intel-Corp/multus-cni) is a Multi CNI plugin to support the Multi Networking feature in Kubernetes using CRD based network objects in Kubernetes. -Multus supports all [reference plugins](https://github.com/containernetworking/plugins) (eg. [Flannel](https://github.com/containernetworking/plugins/tree/master/plugins/meta/flannel), [DHCP](https://github.com/containernetworking/plugins/tree/master/plugins/ipam/dhcp), [Macvlan](https://github.com/containernetworking/plugins/tree/master/plugins/main/macvlan)) that implement the CNI specification and 3rd party plugins (eg. [Calico](https://github.com/projectcalico/cni-plugin), [Weave](https://github.com/weaveworks/weave), [Cilium](https://github.com/cilium/cilium), [Contiv](https://github.com/contiv/netplugin)). In addition to it, Multus supports [SRIOV](https://github.com/hustcat/sriov-cni), [DPDK](https://github.com/Intel-Corp/sriov-cni), [OVS-DPDK & VPP](https://github.com/intel/vhost-user-net-plugin) workloads in Kubernetes with both cloud native and NFV based applications in Kubernetes. +Multus supports all [reference plugins](https://github.com/containernetworking/plugins) (eg. [Flannel](https://github.com/containernetworking/cni.dev/blob/main/content/plugins/v0.9/meta/flannel.md), [DHCP](https://github.com/containernetworking/plugins/tree/master/plugins/ipam/dhcp), [Macvlan](https://github.com/containernetworking/plugins/tree/master/plugins/main/macvlan)) that implement the CNI specification and 3rd party plugins (eg. [Calico](https://github.com/projectcalico/cni-plugin), [Weave](https://github.com/weaveworks/weave), [Cilium](https://github.com/cilium/cilium), [Contiv](https://github.com/contiv/netplugin)). In addition to it, Multus supports [SRIOV](https://github.com/hustcat/sriov-cni), [DPDK](https://github.com/Intel-Corp/sriov-cni), [OVS-DPDK & VPP](https://github.com/intel/vhost-user-net-plugin) workloads in Kubernetes with both cloud native and NFV based applications in Kubernetes. ### OVN4NFV-K8s-Plugin (OVN based CNI controller & plugin) From ff636956661b848ba2919bb8e2fc6de6df8dab99 Mon Sep 17 00:00:00 2001 From: Abhijit Hoskeri Date: Fri, 23 Jul 2021 13:03:33 -0700 Subject: [PATCH 006/115] encrypt-data: Don't recommend AES-CBC CBC is not recommended any more due to vulnerability to padding oracle attacks. Promote secretbox instead. --- content/en/docs/tasks/administer-cluster/encrypt-data.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/content/en/docs/tasks/administer-cluster/encrypt-data.md b/content/en/docs/tasks/administer-cluster/encrypt-data.md index 8499855bb0fd0..36d1517f85d64 100644 --- a/content/en/docs/tasks/administer-cluster/encrypt-data.md +++ b/content/en/docs/tasks/administer-cluster/encrypt-data.md @@ -58,8 +58,7 @@ resources: Each `resources` array item is a separate config and contains a complete configuration. The `resources.resources` field is an array of Kubernetes resource names (`resource` or `resource.group`) that should be encrypted. The `providers` array is an ordered list of the possible encryption -providers. Only one provider type may be specified per entry (`identity` or `aescbc` may be provided, -but not both in the same item). +providers. Only one provider type may be specified per entry (`identity` or `aescbc` may be provided, but not both in the same item). The first provider in the list is used to encrypt resources going into storage. When reading resources from storage each provider that matches the stored data attempts to decrypt the data in @@ -78,9 +77,9 @@ read that resource will fail until it is deleted or a valid decryption key is pr Name | Encryption | Strength | Speed | Key Length | Other Considerations -----|------------|----------|-------|------------|--------------------- `identity` | None | N/A | N/A | N/A | Resources written as-is without encryption. When set as the first provider, the resource will be decrypted as new values are written. -`aescbc` | AES-CBC with PKCS#7 padding | Strongest | Fast | 32-byte | The recommended choice for encryption at rest but may be slightly slower than `secretbox`. `secretbox` | XSalsa20 and Poly1305 | Strong | Faster | 32-byte | A newer standard and may not be considered acceptable in environments that require high levels of review. `aesgcm` | AES-GCM with random nonce | Must be rotated every 200k writes | Fastest | 16, 24, or 32-byte | Is not recommended for use except when an automated key rotation scheme is implemented. +`aescbc` | AES-CBC with PKCS#7 padding | Weak | Fast | 32-byte | Not recommended due to CBC's vulnerability to padding oracle attacks. `kms` | Uses envelope encryption scheme: Data is encrypted by data encryption keys (DEKs) using AES-CBC with PKCS#7 padding, DEKs are encrypted by key encryption keys (KEKs) according to configuration in Key Management Service (KMS) | Strongest | Fast | 32-bytes | The recommended choice for using a third party tool for key management. Simplifies key rotation, with a new DEK generated for each encryption, and KEK rotation controlled by the user. [Configure the KMS provider](/docs/tasks/administer-cluster/kms-provider/) Each provider supports multiple keys - the keys are tried in order for decryption, and if the provider @@ -215,5 +214,3 @@ and restart all `kube-apiserver` processes. Then run: kubectl get secrets --all-namespaces -o json | kubectl replace -f - ``` to force all secrets to be decrypted. - - From 0032199ed69d08825bbbbdd0773b41b425694baa Mon Sep 17 00:00:00 2001 From: Sanu Satyadarshi Date: Mon, 2 Aug 2021 12:55:33 +0530 Subject: [PATCH 007/115] Add missing ServiceAccount Added missing ServiceAccount, ClusterRole and ClusterRoleBinding. https://github.com/kubernetes/website/issues/15280 https://github.com/kubernetes/kubernetes/blob/master/cluster/addons/dns-horizontal-autoscaler/dns-horizontal-autoscaler.yaml --- .../admin/dns/dns-horizontal-autoscaler.yaml | 95 +++++++++++++++---- 1 file changed, 78 insertions(+), 17 deletions(-) diff --git a/content/en/examples/admin/dns/dns-horizontal-autoscaler.yaml b/content/en/examples/admin/dns/dns-horizontal-autoscaler.yaml index dff87cf851f19..ada91c1a350d8 100644 --- a/content/en/examples/admin/dns/dns-horizontal-autoscaler.yaml +++ b/content/en/examples/admin/dns/dns-horizontal-autoscaler.yaml @@ -1,33 +1,94 @@ +kind: ServiceAccount +apiVersion: v1 +metadata: + name: kube-dns-autoscaler + namespace: kube-system + labels: + addonmanager.kubernetes.io/mode: Reconcile +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: system:kube-dns-autoscaler + labels: + addonmanager.kubernetes.io/mode: Reconcile +rules: + - apiGroups: [""] + resources: ["nodes"] + verbs: ["list", "watch"] + - apiGroups: [""] + resources: ["replicationcontrollers/scale"] + verbs: ["get", "update"] + - apiGroups: ["apps"] + resources: ["deployments/scale", "replicasets/scale"] + verbs: ["get", "update"] +# Remove the configmaps rule once below issue is fixed: +# kubernetes-incubator/cluster-proportional-autoscaler#16 + - apiGroups: [""] + resources: ["configmaps"] + verbs: ["get", "create"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: system:kube-dns-autoscaler + labels: + addonmanager.kubernetes.io/mode: Reconcile +subjects: + - kind: ServiceAccount + name: kube-dns-autoscaler + namespace: kube-system +roleRef: + kind: ClusterRole + name: system:kube-dns-autoscaler + apiGroup: rbac.authorization.k8s.io + +--- apiVersion: apps/v1 kind: Deployment metadata: - name: dns-autoscaler + name: kube-dns-autoscaler namespace: kube-system labels: - k8s-app: dns-autoscaler + k8s-app: kube-dns-autoscaler + kubernetes.io/cluster-service: "true" + addonmanager.kubernetes.io/mode: Reconcile spec: selector: matchLabels: - k8s-app: dns-autoscaler + k8s-app: kube-dns-autoscaler template: metadata: labels: - k8s-app: dns-autoscaler + k8s-app: kube-dns-autoscaler spec: + priorityClassName: system-cluster-critical + securityContext: + seccompProfile: + type: RuntimeDefault + supplementalGroups: [ 65534 ] + fsGroup: 65534 + nodeSelector: + kubernetes.io/os: linux containers: - name: autoscaler - image: k8s.gcr.io/cluster-proportional-autoscaler-amd64:1.6.0 + image: k8s.gcr.io/cpa/cluster-proportional-autoscaler:1.8.4 resources: - requests: - cpu: 20m - memory: 10Mi + requests: + cpu: "20m" + memory: "10Mi" command: - - /cluster-proportional-autoscaler - - --namespace=kube-system - - --configmap=dns-autoscaler - - --target= - # When cluster is using large nodes(with more cores), "coresPerReplica" should dominate. - # If using small nodes, "nodesPerReplica" should dominate. - - --default-params={"linear":{"coresPerReplica":256,"nodesPerReplica":16,"min":1}} - - --logtostderr=true - - --v=2 + - /cluster-proportional-autoscaler + - --namespace=kube-system + - --configmap=kube-dns-autoscaler + # Should keep target in sync with cluster/addons/dns/kube-dns.yaml.base + - --target= + # When cluster is using large nodes(with more cores), "coresPerReplica" should dominate. + # If using small nodes, "nodesPerReplica" should dominate. + - --default-params={"linear":{"coresPerReplica":256,"nodesPerReplica":16,"preventSinglePointFailure":true,"includeUnschedulableNodes":true}} + - --logtostderr=true + - --v=2 + tolerations: + - key: "CriticalAddonsOnly" + operator: "Exists" + serviceAccountName: kube-dns-autoscaler From 3571016b3c3a27da5a404f2275873e2505f6680f Mon Sep 17 00:00:00 2001 From: Dewan Ahmed Date: Fri, 13 Aug 2021 11:47:50 -0300 Subject: [PATCH 008/115] v0.1 for sig node spotlight --- .../2021-08-13-SIG-Node-Spotlight/index.md | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md diff --git a/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md b/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md new file mode 100644 index 0000000000000..a3bb3367add16 --- /dev/null +++ b/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md @@ -0,0 +1,76 @@ +--- +layout: blog +title: "Spotlight on SIG Node" +date: 2021-08-13 +slug: sig-node-spotlight-2021 +--- + +**Author:** Dewan Ahmed, Red Hat + +## Introduction + +Are you interested in learning about what [SIG Node](https://github.com/kubernetes/community/tree/master/sig-node) does and how you can get involved? Well, you're at the right place. SIG Node is responsible for the components that support the controlled interactions between pods and host resources. In this blog, we have summarized our conversation with [Elana Hashman](https://twitter.com/ehashdn) & [Sergey Kanzhelev](https://twitter.com/SergeyKanzhelev), who walks us through the various aspects of being a part of the SIG and shares some insights about how others can get involved. + + +## A summary of our conversation + +### DA. Could you tell us a little about what SIG Node does? + +SK: SIG Node is a vertical SIG responsible for the components that support the controlled interactions between the pods and host resources. We manage the lifecycle of pods that are scheduled to a node. This SIGs focus is to enable a broad set of workload types, including workloads with hardware specific or performance sensitive requirements. All while maintaining isolation boundaries between pods on a node, as well as the pod and the host. SIG maintains quite a few components and has many external dependencies (like container runtimes or operating system features), which makes the complexity we deal with huge. We tame the complexity and aim to continuously improve node reliability. + + + +### DA. "SIG Node is a vertical SIG" could you explain a bit more? + +EH: There are two kinds of SIGs: horizontal and vertical. Horizontal SIGs are concerned with a particular function of every component in Kubernetes: for example, SIG Security considers security aspects of every component in Kubernetes, or SIG Instrumentation looks at the logs, metrics, traces and events of every component in Kubernetes. Such SIGs don't tend to own a lot of code. + +Vertical SIGs, on the other hand, own a single component, and are responsible for approving and merging patches to that code base. SIG Node owns the "Node" vertical, pertaining to the kubelet and its lifecycle. This includes the code for the kubelet itself, as well as the node controller, the container runtime interface, and related subprojects like the node problem detector. + +### DA. How did the CI subproject start? Is this specific to SIG Node and how does it help the SIG? + +SK: The subproject started as a follow up after one of the releases was blocked by numerous test failures of critical tests. These tests haven’t started falling all at once, rather continuous lack of attention led to slow degradation of tests quality. SIG Node was always prioritizing quality and reliability, and forming of the subproject was a way to highlight this priority. + +### DA. As the 3rd largest SIG in terms of number of issues and PRs, how does your SIG juggle so much work? + +EH: It helps to be organized. When I increased my contributions to the SIG in January of 2021, I found myself overwhelmed by the volume of pull requests and issues and wasn't sure where to start. We were already tracking test-related issues and pull requests on the CI subproject board, but that was missing a lot of our bugfixes and feature work. So I began putting together a triage board for the rest of our pull requests, which allowed me to sort each one by status and what actions to take, and documented its use for other contributors. We closed or merged over 500 issues and pull requests tracked by our two boards in each of the past two releases. The Kubernetes devstats showed that we have significantly increased our velocity as a result. + +In June, we ran our first bug scrub event to work through the backlog of issues filed against SIG Node, ensuring they were properly categorized. We closed over 130 issues over the course of this 48 hour global event, but as of writing we still have 333 open issues. + +### DA. Why should new and existing contributors consider joining SIG Node? + +SK: Being a SIG Node contributor gives you skills and recognition that are rewarding and useful. Understanding under the hood of a kubelet helps architecting better apps, tune and optimize those apps, and gives leg up in issues troubleshooting. If you are a new contributor, SIG Node gives you foundational knowledge that is key to understanding why other Kubernetes components are designed the way they are. Existing contributors may benefit as many features will require SIG Node changes one way or another. So being a SIG Node contributor helps building features in other SIGs faster. + +The benefits of SIG Node is also this SIG challenge. SIG maintains numerous components, many of which have dependency on external projects or OS features. This makes the onboarding process quite lengthy and demanding. But if you are up for a challenge, there is always a place for you, and a group of people to support. + +### DA. What do you do to help new contributors get started? + +EH: Getting started in SIG Node can be intimidating, since there is so much work to be done, our SIG meetings are very large, and it can be hard to find a place to start. + +I always encourage new contributors to work on things that they have some investment in already. In SIG Node, that might mean volunteering to help fix a bug that you have personally been affected by, or helping to triage bugs you care about by priority. + +To come up to speed on any open source code base, there are two strategies you can take: start by exploring a particular issue deeply, and follow that to expand the edges of your knowledge as needed, or briefly review as many issues and change requests as you possibly can to get a higher level picture of how the component works. Ultimately, you will need to do both if you want to become a Node reviewer or approver. + +[Davanum Srinivas](https://twitter.com/@dims) and I each ran a cohort of group mentoring to help teach new contributors the skills to become Node reviewers, and if there's interest we can work to find a mentor to run another session. I also encourage new contributors to attend our Node CI Subproject meeting: it's a smaller audience and we don't record the triage sessions, so it can be a less intimidating way to get started with the SIG. + + +### DA. Are there any particular skills you’d like to recruit for? What skills are contributors to SIG Usability likely to learn? + +SK: SIG Node works on many workstreams in very different areas. All of these areas are on system level. For the typical code contributions you need to have a passion for building and utilizing low level APIs and writing performant and reliable components. Being a contributor you will learn how to debug and troubleshoot, profile, and monitor these components, as well as user workload that is run by these components. Often, with the limited to no access to Nodes, as they are running production workloads. + +The other way of contribution is to help document SIG node features. This type of contribution requires a deep understanding of features, and ability to explain them in simple terms. + +Finally, we are always looking for feedback on how best to run your workload. Come and explain specifics of it, and what features in SIG Node components may help to run it better. + +### DA. What are you getting positive feedback on, and what’s coming up next for SIG Node? + +EH: Over the past year SIG Node has adopted some new processes to help manage our feature development and Kubernetes enhancement proposals, and other SIGs have looked to us for inspiration in managing large workloads. I hope that this is an area we can continue to provide leadership in and further iterate on. + +We have a great balance of new features and deprecations in flight right now. Deprecations of unused or difficult to maintain features help us keep technical debt and maintenance load under control, and examples include the dockershim and DynamicKubeletConfiguration deprecations. New features will unlock additional functionality in end users' clusters, and include exciting features like support for cgroups v2, swap memory, graceful node shutdowns, and device management policies. + +### DA: Any closing thoughts/resources you’d like to share? + +SK/EH: It takes time and effort to get to any open source community. SIG Node may overwhelm you at first with the number of participants, volume of work, and project scope. But it is totally worth it. Join our welcoming community! [SIG Node GitHub Repo](https://github.com/kubernetes/community/tree/master/sig-node) contains many useful resources including Slack, mailing list and other contact info. + +## Wrap Up + +SIG Node hosted a [KubeCon + CloudNativeCon Europe 2021 talk](https://www.youtube.com/watch?v=z5aY4e2RENA) with an intro and deep dive to their awesome SIG. Join the SIG's meetings to find out about the most recent research results, what the plans are for the forthcoming year, and how to get involved in the upstream Node team as a contributor! \ No newline at end of file From ad05f090e7f2c572236fbc84a1c994bf6b61c5b8 Mon Sep 17 00:00:00 2001 From: Dewan Ahmed Date: Fri, 13 Aug 2021 11:50:13 -0300 Subject: [PATCH 009/115] Removing interviewer initials --- .../2021-08-13-SIG-Node-Spotlight/index.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md b/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md index a3bb3367add16..51c1e5486f851 100644 --- a/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md +++ b/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md @@ -14,35 +14,35 @@ Are you interested in learning about what [SIG Node](https://github.com/kubernet ## A summary of our conversation -### DA. Could you tell us a little about what SIG Node does? +### Could you tell us a little about what SIG Node does? SK: SIG Node is a vertical SIG responsible for the components that support the controlled interactions between the pods and host resources. We manage the lifecycle of pods that are scheduled to a node. This SIGs focus is to enable a broad set of workload types, including workloads with hardware specific or performance sensitive requirements. All while maintaining isolation boundaries between pods on a node, as well as the pod and the host. SIG maintains quite a few components and has many external dependencies (like container runtimes or operating system features), which makes the complexity we deal with huge. We tame the complexity and aim to continuously improve node reliability. -### DA. "SIG Node is a vertical SIG" could you explain a bit more? +### "SIG Node is a vertical SIG" could you explain a bit more? EH: There are two kinds of SIGs: horizontal and vertical. Horizontal SIGs are concerned with a particular function of every component in Kubernetes: for example, SIG Security considers security aspects of every component in Kubernetes, or SIG Instrumentation looks at the logs, metrics, traces and events of every component in Kubernetes. Such SIGs don't tend to own a lot of code. Vertical SIGs, on the other hand, own a single component, and are responsible for approving and merging patches to that code base. SIG Node owns the "Node" vertical, pertaining to the kubelet and its lifecycle. This includes the code for the kubelet itself, as well as the node controller, the container runtime interface, and related subprojects like the node problem detector. -### DA. How did the CI subproject start? Is this specific to SIG Node and how does it help the SIG? +### How did the CI subproject start? Is this specific to SIG Node and how does it help the SIG? SK: The subproject started as a follow up after one of the releases was blocked by numerous test failures of critical tests. These tests haven’t started falling all at once, rather continuous lack of attention led to slow degradation of tests quality. SIG Node was always prioritizing quality and reliability, and forming of the subproject was a way to highlight this priority. -### DA. As the 3rd largest SIG in terms of number of issues and PRs, how does your SIG juggle so much work? +### As the 3rd largest SIG in terms of number of issues and PRs, how does your SIG juggle so much work? EH: It helps to be organized. When I increased my contributions to the SIG in January of 2021, I found myself overwhelmed by the volume of pull requests and issues and wasn't sure where to start. We were already tracking test-related issues and pull requests on the CI subproject board, but that was missing a lot of our bugfixes and feature work. So I began putting together a triage board for the rest of our pull requests, which allowed me to sort each one by status and what actions to take, and documented its use for other contributors. We closed or merged over 500 issues and pull requests tracked by our two boards in each of the past two releases. The Kubernetes devstats showed that we have significantly increased our velocity as a result. In June, we ran our first bug scrub event to work through the backlog of issues filed against SIG Node, ensuring they were properly categorized. We closed over 130 issues over the course of this 48 hour global event, but as of writing we still have 333 open issues. -### DA. Why should new and existing contributors consider joining SIG Node? +### Why should new and existing contributors consider joining SIG Node? SK: Being a SIG Node contributor gives you skills and recognition that are rewarding and useful. Understanding under the hood of a kubelet helps architecting better apps, tune and optimize those apps, and gives leg up in issues troubleshooting. If you are a new contributor, SIG Node gives you foundational knowledge that is key to understanding why other Kubernetes components are designed the way they are. Existing contributors may benefit as many features will require SIG Node changes one way or another. So being a SIG Node contributor helps building features in other SIGs faster. The benefits of SIG Node is also this SIG challenge. SIG maintains numerous components, many of which have dependency on external projects or OS features. This makes the onboarding process quite lengthy and demanding. But if you are up for a challenge, there is always a place for you, and a group of people to support. -### DA. What do you do to help new contributors get started? +### What do you do to help new contributors get started? EH: Getting started in SIG Node can be intimidating, since there is so much work to be done, our SIG meetings are very large, and it can be hard to find a place to start. @@ -53,7 +53,7 @@ To come up to speed on any open source code base, there are two strategies you c [Davanum Srinivas](https://twitter.com/@dims) and I each ran a cohort of group mentoring to help teach new contributors the skills to become Node reviewers, and if there's interest we can work to find a mentor to run another session. I also encourage new contributors to attend our Node CI Subproject meeting: it's a smaller audience and we don't record the triage sessions, so it can be a less intimidating way to get started with the SIG. -### DA. Are there any particular skills you’d like to recruit for? What skills are contributors to SIG Usability likely to learn? +### Are there any particular skills you’d like to recruit for? What skills are contributors to SIG Usability likely to learn? SK: SIG Node works on many workstreams in very different areas. All of these areas are on system level. For the typical code contributions you need to have a passion for building and utilizing low level APIs and writing performant and reliable components. Being a contributor you will learn how to debug and troubleshoot, profile, and monitor these components, as well as user workload that is run by these components. Often, with the limited to no access to Nodes, as they are running production workloads. @@ -61,13 +61,13 @@ The other way of contribution is to help document SIG node features. This type o Finally, we are always looking for feedback on how best to run your workload. Come and explain specifics of it, and what features in SIG Node components may help to run it better. -### DA. What are you getting positive feedback on, and what’s coming up next for SIG Node? +### What are you getting positive feedback on, and what’s coming up next for SIG Node? EH: Over the past year SIG Node has adopted some new processes to help manage our feature development and Kubernetes enhancement proposals, and other SIGs have looked to us for inspiration in managing large workloads. I hope that this is an area we can continue to provide leadership in and further iterate on. We have a great balance of new features and deprecations in flight right now. Deprecations of unused or difficult to maintain features help us keep technical debt and maintenance load under control, and examples include the dockershim and DynamicKubeletConfiguration deprecations. New features will unlock additional functionality in end users' clusters, and include exciting features like support for cgroups v2, swap memory, graceful node shutdowns, and device management policies. -### DA: Any closing thoughts/resources you’d like to share? +### Any closing thoughts/resources you’d like to share? SK/EH: It takes time and effort to get to any open source community. SIG Node may overwhelm you at first with the number of participants, volume of work, and project scope. But it is totally worth it. Join our welcoming community! [SIG Node GitHub Repo](https://github.com/kubernetes/community/tree/master/sig-node) contains many useful resources including Slack, mailing list and other contact info. From df8f30b1209a6d7b3a69cee8ef61c9ba30781af3 Mon Sep 17 00:00:00 2001 From: Dewan Ahmed Date: Fri, 13 Aug 2021 12:26:24 -0300 Subject: [PATCH 010/115] Fixing minor typos. --- .../en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md b/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md index 51c1e5486f851..335344f9e65f6 100644 --- a/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md +++ b/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md @@ -16,7 +16,7 @@ Are you interested in learning about what [SIG Node](https://github.com/kubernet ### Could you tell us a little about what SIG Node does? -SK: SIG Node is a vertical SIG responsible for the components that support the controlled interactions between the pods and host resources. We manage the lifecycle of pods that are scheduled to a node. This SIGs focus is to enable a broad set of workload types, including workloads with hardware specific or performance sensitive requirements. All while maintaining isolation boundaries between pods on a node, as well as the pod and the host. SIG maintains quite a few components and has many external dependencies (like container runtimes or operating system features), which makes the complexity we deal with huge. We tame the complexity and aim to continuously improve node reliability. +SK: SIG Node is a vertical SIG responsible for the components that support the controlled interactions between the pods and host resources. We manage the lifecycle of pods that are scheduled to a node. This SIG's focus is to enable a broad set of workload types, including workloads with hardware specific or performance sensitive requirements. All while maintaining isolation boundaries between pods on a node, as well as the pod and the host. This SIG maintains quite a few components and has many external dependencies (like container runtimes or operating system features), which makes the complexity we deal with huge. We tame the complexity and aim to continuously improve node reliability. @@ -38,9 +38,9 @@ In June, we ran our first bug scrub event to work through the backlog of issues ### Why should new and existing contributors consider joining SIG Node? -SK: Being a SIG Node contributor gives you skills and recognition that are rewarding and useful. Understanding under the hood of a kubelet helps architecting better apps, tune and optimize those apps, and gives leg up in issues troubleshooting. If you are a new contributor, SIG Node gives you foundational knowledge that is key to understanding why other Kubernetes components are designed the way they are. Existing contributors may benefit as many features will require SIG Node changes one way or another. So being a SIG Node contributor helps building features in other SIGs faster. +SK: Being a SIG Node contributor gives you skills and recognition that are rewarding and useful. Understanding under the hood of a kubelet helps architecting better apps, tune and optimize those apps, and gives leg up in issues troubleshooting. If you are a new contributor, SIG Node gives you the foundational knowledge that is key to understanding why other Kubernetes components are designed the way they are. Existing contributors may benefit as many features will require SIG Node changes one way or another. So being a SIG Node contributor helps building features in other SIGs faster. -The benefits of SIG Node is also this SIG challenge. SIG maintains numerous components, many of which have dependency on external projects or OS features. This makes the onboarding process quite lengthy and demanding. But if you are up for a challenge, there is always a place for you, and a group of people to support. +SIG Node maintains numerous components, many of which have dependency on external projects or OS features. This makes the onboarding process quite lengthy and demanding. But if you are up for a challenge, there is always a place for you, and a group of people to support. ### What do you do to help new contributors get started? @@ -50,7 +50,7 @@ I always encourage new contributors to work on things that they have some invest To come up to speed on any open source code base, there are two strategies you can take: start by exploring a particular issue deeply, and follow that to expand the edges of your knowledge as needed, or briefly review as many issues and change requests as you possibly can to get a higher level picture of how the component works. Ultimately, you will need to do both if you want to become a Node reviewer or approver. -[Davanum Srinivas](https://twitter.com/@dims) and I each ran a cohort of group mentoring to help teach new contributors the skills to become Node reviewers, and if there's interest we can work to find a mentor to run another session. I also encourage new contributors to attend our Node CI Subproject meeting: it's a smaller audience and we don't record the triage sessions, so it can be a less intimidating way to get started with the SIG. +[Davanum Srinivas](https://twitter.com/dims) and I each ran a cohort of group mentoring to help teach new contributors the skills to become Node reviewers, and if there's interest we can work to find a mentor to run another session. I also encourage new contributors to attend our Node CI Subproject meeting: it's a smaller audience and we don't record the triage sessions, so it can be a less intimidating way to get started with the SIG. ### Are there any particular skills you’d like to recruit for? What skills are contributors to SIG Usability likely to learn? From 5b34d70e92a10347180bf5da761d687e757ede5f Mon Sep 17 00:00:00 2001 From: Dewan Ahmed Date: Fri, 13 Aug 2021 14:24:53 -0300 Subject: [PATCH 011/115] Post-PR grammatical fixes --- content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md b/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md index 335344f9e65f6..1dbf20eed75d0 100644 --- a/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md +++ b/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md @@ -9,7 +9,7 @@ slug: sig-node-spotlight-2021 ## Introduction -Are you interested in learning about what [SIG Node](https://github.com/kubernetes/community/tree/master/sig-node) does and how you can get involved? Well, you're at the right place. SIG Node is responsible for the components that support the controlled interactions between pods and host resources. In this blog, we have summarized our conversation with [Elana Hashman](https://twitter.com/ehashdn) & [Sergey Kanzhelev](https://twitter.com/SergeyKanzhelev), who walks us through the various aspects of being a part of the SIG and shares some insights about how others can get involved. +Are you interested in learning about what [SIG Node](https://github.com/kubernetes/community/tree/master/sig-node) does and how you can get involved? Well, you're at the right place. SIG Node is responsible for the components that support the controlled interactions between pods and host resources. In this blog, we have summarized our conversation with [Elana Hashman](https://twitter.com/ehashdn) & [Sergey Kanzhelev](https://twitter.com/SergeyKanzhelev), who walk us through the various aspects of being a part of the SIG and share some insights about how others can get involved. ## A summary of our conversation From 3f51160e89ea5c67a8b1f884e299a69afa27b48a Mon Sep 17 00:00:00 2001 From: Dewan Ishtiaque Ahmed <30604461+dewan-ahmed@users.noreply.github.com> Date: Wed, 25 Aug 2021 17:28:13 -0300 Subject: [PATCH 012/115] Update content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md Co-authored-by: Rey Lejano --- content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md b/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md index 1dbf20eed75d0..f09527f9777b3 100644 --- a/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md +++ b/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md @@ -55,7 +55,7 @@ To come up to speed on any open source code base, there are two strategies you c ### Are there any particular skills you’d like to recruit for? What skills are contributors to SIG Usability likely to learn? -SK: SIG Node works on many workstreams in very different areas. All of these areas are on system level. For the typical code contributions you need to have a passion for building and utilizing low level APIs and writing performant and reliable components. Being a contributor you will learn how to debug and troubleshoot, profile, and monitor these components, as well as user workload that is run by these components. Often, with the limited to no access to Nodes, as they are running production workloads. +SK: SIG Node works on many workstreams in very different areas. All of these areas are on system level. For the typical code contributions you need to have a passion for building and utilizing low level APIs and writing performant and reliable components. Being a contributor you will learn how to debug and troubleshoot, profile, and monitor these components, as well as user workload that is run by these components. Often, with the limited to no access to Nodes, as they are running production workloads. The other way of contribution is to help document SIG node features. This type of contribution requires a deep understanding of features, and ability to explain them in simple terms. From f93e3cb2bec9d5f004c3d305fbd9625918dcada7 Mon Sep 17 00:00:00 2001 From: Dewan Ishtiaque Ahmed <30604461+dewan-ahmed@users.noreply.github.com> Date: Wed, 25 Aug 2021 17:28:41 -0300 Subject: [PATCH 013/115] Update content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md Co-authored-by: Rey Lejano --- content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md | 1 - 1 file changed, 1 deletion(-) diff --git a/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md b/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md index f09527f9777b3..4d05fe0790f58 100644 --- a/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md +++ b/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md @@ -52,7 +52,6 @@ To come up to speed on any open source code base, there are two strategies you c [Davanum Srinivas](https://twitter.com/dims) and I each ran a cohort of group mentoring to help teach new contributors the skills to become Node reviewers, and if there's interest we can work to find a mentor to run another session. I also encourage new contributors to attend our Node CI Subproject meeting: it's a smaller audience and we don't record the triage sessions, so it can be a less intimidating way to get started with the SIG. - ### Are there any particular skills you’d like to recruit for? What skills are contributors to SIG Usability likely to learn? SK: SIG Node works on many workstreams in very different areas. All of these areas are on system level. For the typical code contributions you need to have a passion for building and utilizing low level APIs and writing performant and reliable components. Being a contributor you will learn how to debug and troubleshoot, profile, and monitor these components, as well as user workload that is run by these components. Often, with the limited to no access to Nodes, as they are running production workloads. From 2b09e539efcb84283df79dccc85c20dbdfbab927 Mon Sep 17 00:00:00 2001 From: Dewan Ishtiaque Ahmed <30604461+dewan-ahmed@users.noreply.github.com> Date: Wed, 25 Aug 2021 17:28:56 -0300 Subject: [PATCH 014/115] Update content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md Co-authored-by: Rey Lejano --- content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md b/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md index 4d05fe0790f58..269b6cc140040 100644 --- a/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md +++ b/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md @@ -1,7 +1,7 @@ --- layout: blog title: "Spotlight on SIG Node" -date: 2021-08-13 +date: 2021-09-06 slug: sig-node-spotlight-2021 --- From 25a7c8f02e76128bdc270475c73123e45810daad Mon Sep 17 00:00:00 2001 From: Dewan Ishtiaque Ahmed <30604461+dewan-ahmed@users.noreply.github.com> Date: Wed, 25 Aug 2021 17:29:05 -0300 Subject: [PATCH 015/115] Update content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md Co-authored-by: Rey Lejano --- content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md b/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md index 269b6cc140040..8a9b07c5141ad 100644 --- a/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md +++ b/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md @@ -18,8 +18,6 @@ Are you interested in learning about what [SIG Node](https://github.com/kubernet SK: SIG Node is a vertical SIG responsible for the components that support the controlled interactions between the pods and host resources. We manage the lifecycle of pods that are scheduled to a node. This SIG's focus is to enable a broad set of workload types, including workloads with hardware specific or performance sensitive requirements. All while maintaining isolation boundaries between pods on a node, as well as the pod and the host. This SIG maintains quite a few components and has many external dependencies (like container runtimes or operating system features), which makes the complexity we deal with huge. We tame the complexity and aim to continuously improve node reliability. - - ### "SIG Node is a vertical SIG" could you explain a bit more? EH: There are two kinds of SIGs: horizontal and vertical. Horizontal SIGs are concerned with a particular function of every component in Kubernetes: for example, SIG Security considers security aspects of every component in Kubernetes, or SIG Instrumentation looks at the logs, metrics, traces and events of every component in Kubernetes. Such SIGs don't tend to own a lot of code. From a0d63d1125776e25195ba503de02ee542543661a Mon Sep 17 00:00:00 2001 From: Vaibhav Date: Wed, 1 Sep 2021 01:49:22 +0530 Subject: [PATCH 016/115] Remove the --record flag in https://kubernetes.io/docs/concepts/workloads/controllers/deployment.md --- .../workloads/controllers/deployment.md | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/content/en/docs/concepts/workloads/controllers/deployment.md b/content/en/docs/concepts/workloads/controllers/deployment.md index 22b95255c50bf..abe88d928123b 100644 --- a/content/en/docs/concepts/workloads/controllers/deployment.md +++ b/content/en/docs/concepts/workloads/controllers/deployment.md @@ -75,11 +75,6 @@ Follow the steps given below to create the above Deployment: kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml ``` - {{< note >}} - You can specify the `--record` flag to write the command executed in the resource annotation `kubernetes.io/change-cause`. - The recorded change is useful for future introspection. For example, to see the commands executed in each Deployment revision. - {{< /note >}} - 2. Run `kubectl get deployments` to check if the Deployment was created. @@ -169,13 +164,13 @@ Follow the steps given below to update your Deployment: 1. Let's update the nginx Pods to use the `nginx:1.16.1` image instead of the `nginx:1.14.2` image. ```shell - kubectl --record deployment.apps/nginx-deployment set image deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1 + kubectl deployment.apps/nginx-deployment set image deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1 ``` or use the following command: ```shell - kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1 --record + kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1 ``` The output is similar to: @@ -370,7 +365,7 @@ rolled back. * Suppose that you made a typo while updating the Deployment, by putting the image name as `nginx:1.161` instead of `nginx:1.16.1`: ```shell - kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.161 --record=true + kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.161 ``` The output is similar to this: @@ -485,9 +480,9 @@ Follow the steps given below to check the rollout history: ``` deployments "nginx-deployment" REVISION CHANGE-CAUSE - 1 kubectl apply --filename=https://k8s.io/examples/controllers/nginx-deployment.yaml --record=true - 2 kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1 --record=true - 3 kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.161 --record=true + 1 kubectl apply --filename=https://k8s.io/examples/controllers/nginx-deployment.yaml + 2 kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1 + 3 kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.161 ``` `CHANGE-CAUSE` is copied from the Deployment annotation `kubernetes.io/change-cause` to its revisions upon creation. You can specify the`CHANGE-CAUSE` message by: @@ -506,7 +501,7 @@ Follow the steps given below to check the rollout history: deployments "nginx-deployment" revision 2 Labels: app=nginx pod-template-hash=1159050644 - Annotations: kubernetes.io/change-cause=kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1 --record=true + Annotations: kubernetes.io/change-cause=kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1 Containers: nginx: Image: nginx:1.16.1 @@ -567,7 +562,7 @@ Follow the steps given below to rollback the Deployment from the current version CreationTimestamp: Sun, 02 Sep 2018 18:17:55 -0500 Labels: app=nginx Annotations: deployment.kubernetes.io/revision=4 - kubernetes.io/change-cause=kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1 --record=true + kubernetes.io/change-cause=kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1 Selector: app=nginx Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable StrategyType: RollingUpdate From f6c813de44bf12934125684d7ddeee48cbd668ad Mon Sep 17 00:00:00 2001 From: Vaibhav Date: Wed, 1 Sep 2021 15:21:31 +0530 Subject: [PATCH 017/115] Remove the remaining last flag --record from deployment.md --- content/en/docs/concepts/workloads/controllers/deployment.md | 1 - 1 file changed, 1 deletion(-) diff --git a/content/en/docs/concepts/workloads/controllers/deployment.md b/content/en/docs/concepts/workloads/controllers/deployment.md index abe88d928123b..541b72b24514f 100644 --- a/content/en/docs/concepts/workloads/controllers/deployment.md +++ b/content/en/docs/concepts/workloads/controllers/deployment.md @@ -488,7 +488,6 @@ Follow the steps given below to check the rollout history: `CHANGE-CAUSE` is copied from the Deployment annotation `kubernetes.io/change-cause` to its revisions upon creation. You can specify the`CHANGE-CAUSE` message by: * Annotating the Deployment with `kubectl annotate deployment.v1.apps/nginx-deployment kubernetes.io/change-cause="image updated to 1.16.1"` - * Append the `--record` flag to save the `kubectl` command that is making changes to the resource. * Manually editing the manifest of the resource. 2. To see the details of each revision, run: From 2e55433aec3a83c28b804ffc70bead5da69ee694 Mon Sep 17 00:00:00 2001 From: bhumijgupta Date: Wed, 8 Sep 2021 19:01:08 +0530 Subject: [PATCH 018/115] Fix release cadence in deprecation policy page Signed-off-by: bhumijgupta --- content/en/docs/reference/using-api/deprecation-policy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/docs/reference/using-api/deprecation-policy.md b/content/en/docs/reference/using-api/deprecation-policy.md index eed4341628cb2..d3677b031e8d4 100644 --- a/content/en/docs/reference/using-api/deprecation-policy.md +++ b/content/en/docs/reference/using-api/deprecation-policy.md @@ -109,7 +109,7 @@ objects. All of this is best illustrated by examples. Imagine a Kubernetes release, version X, which introduces a new API group. A new Kubernetes release is made -every approximately 3 months (4 per year). The following table describes which +every approximately 4 months (3 per year). The following table describes which API versions are supported in a series of subsequent releases. From d3dcda21a5a14da0cec7495c17075af0892bbfc9 Mon Sep 17 00:00:00 2001 From: bhumijgupta Date: Wed, 8 Sep 2021 19:05:01 +0530 Subject: [PATCH 019/115] Revert change to double spacing Signed-off-by: bhumijgupta --- content/en/docs/reference/using-api/deprecation-policy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/docs/reference/using-api/deprecation-policy.md b/content/en/docs/reference/using-api/deprecation-policy.md index d3677b031e8d4..6bbd9be9e1771 100644 --- a/content/en/docs/reference/using-api/deprecation-policy.md +++ b/content/en/docs/reference/using-api/deprecation-policy.md @@ -109,7 +109,7 @@ objects. All of this is best illustrated by examples. Imagine a Kubernetes release, version X, which introduces a new API group. A new Kubernetes release is made -every approximately 4 months (3 per year). The following table describes which +every approximately 4 months (3 per year). The following table describes which API versions are supported in a series of subsequent releases.
From 0506656da1859035fd23b7145ab27392397ddb48 Mon Sep 17 00:00:00 2001 From: Arhell Date: Wed, 15 Sep 2021 00:17:28 +0300 Subject: [PATCH 020/115] [ja] Improvement: Runtime Class --- content/ja/docs/concepts/containers/runtime-class.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ja/docs/concepts/containers/runtime-class.md b/content/ja/docs/concepts/containers/runtime-class.md index bc4e285c66bc2..15cf7446f0e69 100644 --- a/content/ja/docs/concepts/containers/runtime-class.md +++ b/content/ja/docs/concepts/containers/runtime-class.md @@ -100,7 +100,7 @@ Kubernetesのビルトインのdockershim CRIは、ランタイムハンドラ 正しいハンドラーは、その`runtime`セクションで設定されます。 ``` -[plugins.cri.containerd.runtimes.${HANDLER_NAME}] +[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.${HANDLER_NAME}] ``` containerdの設定に関する詳細なドキュメントは下記を参照してください。 From 4b2661e932d8a55d7c70dd095306fe70944c3c8a Mon Sep 17 00:00:00 2001 From: Pushkar Joglekar <3390906+PushkarJ@users.noreply.github.com> Date: Mon, 13 Sep 2021 13:28:50 -0700 Subject: [PATCH 021/115] Replace k/security with k/committee-security-response Co-authored-by: Rey Lejano --- content/en/releases/release-managers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/releases/release-managers.md b/content/en/releases/release-managers.md index 0b68ca0b879f8..e8b75492bcd24 100644 --- a/content/en/releases/release-managers.md +++ b/content/en/releases/release-managers.md @@ -31,7 +31,7 @@ The responsibilities of each role are described below. ### Security Embargo Policy -Some information about releases is subject to embargo and we have defined policy about how those embargos are set. Please refer [Security Embargo Policy](https://github.com/kubernetes/security/blob/master/private-distributors-list.md#embargo-policy) here for more information. +Some information about releases is subject to embargo and we have defined policy about how those embargoes are set. Please refer to the [Security Embargo Policy](https://github.com/kubernetes/committee-security-response/blob/master/private-distributors-list.md#embargo-policy) for more information. ## Handbooks From 49d7b493bbf641d0764a28d26f9466eaaea13124 Mon Sep 17 00:00:00 2001 From: Andrey Regentov Date: Wed, 15 Sep 2021 15:46:26 +0700 Subject: [PATCH 022/115] semantic fix use "latest" => "Always" use nothing => "Always" use any but "latest" => "IfNotPresent" --- content/en/docs/concepts/containers/images.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/docs/concepts/containers/images.md b/content/en/docs/concepts/containers/images.md index 9300561e46c7c..5dfd349f80371 100644 --- a/content/en/docs/concepts/containers/images.md +++ b/content/en/docs/concepts/containers/images.md @@ -108,7 +108,7 @@ When you (or a controller) submit a new Pod to the API server, your cluster sets `:latest`, `imagePullPolicy` is automatically set to `Always`; - if you omit the `imagePullPolicy` field, and you don't specify the tag for the container image, `imagePullPolicy` is automatically set to `Always`; -- if you omit the `imagePullPolicy` field, and you don't specify the tag for the +- if you omit the `imagePullPolicy` field, and you specify the tag for the container image that isn't `:latest`, the `imagePullPolicy` is automatically set to `IfNotPresent`. From 6b610b8e33e8f02aaacced0cfee01009dd687424 Mon Sep 17 00:00:00 2001 From: Jacob Valdemar Date: Sun, 19 Sep 2021 17:55:11 +0200 Subject: [PATCH 023/115] Remove prefixed spaces in code environment --- .../kubeadm/kubeadm-upgrade.md | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade.md b/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade.md index da07ed672e14d..d3b2fd9c071d2 100644 --- a/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade.md +++ b/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade.md @@ -166,11 +166,10 @@ Also calling `kubeadm upgrade plan` and upgrading the CNI provider plugin is no ### Upgrade kubelet and kubectl -- Upgrade the kubelet and kubectl +- Upgrade the kubelet and kubectl: -{{< tabs name="k8s_install_kubelet" >}} -{{< tab name="Ubuntu, Debian or HypriotOS" >}} -
+{{< tabs name="k8s_kubelet_and_kubectl" >}}
+{{% tab name="Ubuntu, Debian or HypriotOS" %}}
     # replace x in {{< skew latestVersion >}}.x-00 with the latest patch version
     apt-mark unhold kubelet kubectl && \
     apt-get update && apt-get install -y kubelet={{< skew latestVersion >}}.x-00 kubectl={{< skew latestVersion >}}.x-00 && \
@@ -179,14 +178,11 @@ Also calling `kubeadm upgrade plan` and upgrading the CNI provider plugin is no
     # since apt-get version 1.1 you can also use the following method
     apt-get update && \
     apt-get install -y --allow-change-held-packages kubelet={{< skew latestVersion >}}.x-00 kubectl={{< skew latestVersion >}}.x-00
-    
-{{< /tab >}} -{{< tab name="CentOS, RHEL or Fedora" >}} -
+{{% /tab %}}
+{{% tab name="CentOS, RHEL or Fedora" %}}
     # replace x in {{< skew latestVersion >}}.x-0 with the latest patch version
     yum install -y kubelet-{{< skew latestVersion >}}.x-0 kubectl-{{< skew latestVersion >}}.x-0 --disableexcludes=kubernetes
-    
-{{< /tab >}} +{{% /tab %}} {{< /tabs >}} - Restart the kubelet: From 483779104b88b4297b2967d5a66c5f7ec5c8887a Mon Sep 17 00:00:00 2001 From: Jacob Valdemar Date: Sun, 19 Sep 2021 18:01:51 +0200 Subject: [PATCH 024/115] Undo accidental change to tabs name --- .../en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade.md b/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade.md index d3b2fd9c071d2..f855c2be5c6cf 100644 --- a/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade.md +++ b/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade.md @@ -168,7 +168,7 @@ Also calling `kubeadm upgrade plan` and upgrading the CNI provider plugin is no - Upgrade the kubelet and kubectl: -{{< tabs name="k8s_kubelet_and_kubectl" >}} +{{< tabs name="k8s_install_kubelet" >}} {{% tab name="Ubuntu, Debian or HypriotOS" %}} # replace x in {{< skew latestVersion >}}.x-00 with the latest patch version apt-mark unhold kubelet kubectl && \ From cc8bda3f410cfe51f2d04060a6e1da2389b24f98 Mon Sep 17 00:00:00 2001 From: Jacob Valdemar Date: Sun, 19 Sep 2021 22:07:09 +0200 Subject: [PATCH 025/115] Add another newline after the tab widgets --- .../docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade.md b/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade.md index f855c2be5c6cf..288852cd1f2eb 100644 --- a/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade.md +++ b/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade.md @@ -89,6 +89,7 @@ Pick a control plane node that you wish to upgrade first. It must have the `/etc {{% /tab %}} {{< /tabs >}} + - Verify that the download works and has the expected version: ```shell @@ -185,6 +186,7 @@ Also calling `kubeadm upgrade plan` and upgrading the CNI provider plugin is no {{% /tab %}} {{< /tabs >}} + - Restart the kubelet: ```shell @@ -265,6 +267,7 @@ without compromising the minimum required capacity for running your workloads. {{% /tab %}} {{< /tabs >}} + - Restart the kubelet: ```shell From 2cac383a7c373611f23804febc78edba49977d54 Mon Sep 17 00:00:00 2001 From: Jacob Valdemar Date: Sun, 19 Sep 2021 22:17:40 +0200 Subject: [PATCH 026/115] Undo "Add another newline after the tab widgets" --- .../docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade.md b/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade.md index 288852cd1f2eb..f855c2be5c6cf 100644 --- a/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade.md +++ b/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade.md @@ -89,7 +89,6 @@ Pick a control plane node that you wish to upgrade first. It must have the `/etc {{% /tab %}} {{< /tabs >}} - - Verify that the download works and has the expected version: ```shell @@ -186,7 +185,6 @@ Also calling `kubeadm upgrade plan` and upgrading the CNI provider plugin is no {{% /tab %}} {{< /tabs >}} - - Restart the kubelet: ```shell @@ -267,7 +265,6 @@ without compromising the minimum required capacity for running your workloads. {{% /tab %}} {{< /tabs >}} - - Restart the kubelet: ```shell From 54185d178df59c1981fd3ac9ce18f69b88ef3d5a Mon Sep 17 00:00:00 2001 From: august Date: Tue, 7 Sep 2021 16:41:52 +0300 Subject: [PATCH 027/115] add blog post on handling data duplication in data-heavy environments --- ...-data-duplication-in-data-heavy-k8s-env.md | 243 ++++++++++++++++++ .../create-volume-snapshot-gcp.png | Bin 0 -> 69860 bytes .../identify-volume-aws.png | Bin 0 -> 303818 bytes 3 files changed, 243 insertions(+) create mode 100644 content/en/blog/_posts/2021-09-07-data-duplication-in-data-heavy-k8s-env.md create mode 100644 static/images/blog/2021-09-07-data-duplication-in-data-heavy-k8s-env/create-volume-snapshot-gcp.png create mode 100644 static/images/blog/2021-09-07-data-duplication-in-data-heavy-k8s-env/identify-volume-aws.png diff --git a/content/en/blog/_posts/2021-09-07-data-duplication-in-data-heavy-k8s-env.md b/content/en/blog/_posts/2021-09-07-data-duplication-in-data-heavy-k8s-env.md new file mode 100644 index 0000000000000..bec8c0b892fa3 --- /dev/null +++ b/content/en/blog/_posts/2021-09-07-data-duplication-in-data-heavy-k8s-env.md @@ -0,0 +1,243 @@ +--- +layout: blog +title: "How to Handle Data Duplication in Data-Heavy Kubernetes Environments" +date: 2021-09-07 +slug: how-to-handle-data-duplication-in-data-heavy-kubernetes-environments +--- + +**Authors:** +Augustinas Stirbis (CAST AI) + +## Why Duplicate Data? + +It’s convenient to create a copy of your application with a copy of its state for each team. +For example, you might want a separate database copy to test some significant schema changes +or develop other disruptive operations like bulk insert/delete/update... + +**Duplicating data takes a lot of time.** That’s because you need first to download +all the data from a source block storage provider to compute and then send +it back to a storage provider again. There’s a lot of network traffic and CPU/RAM used in this process. +Hardware acceleration by offloading certain expensive operations to dedicated hardware is +**always a huge performance boost**. It reduces the time required to complete an operation by orders +of magnitude. + +## Volume Snapshots to the rescue + +Kubernetes introduced [VolumeSnapshots](/docs/concepts/storage/volume-snapshots/) as alpha in 1.12, +beta in 1.17, and the Generally Available version in 1.20. +VolumeSnapshots use specialized APIs from storage providers to duplicate volume of data. + +Since data is already in the same storage device (array of devices), duplicating data is usually +a metadata operation for storage providers with local snapshots (majority of on-premise storage providers). +All you need to do is point a new disk to an immutable snapshot and only +save deltas (or let it do a full-disk copy). As an operation that is inside the storage back-end, +it’s much quicker and usually doesn’t involve sending traffic over the network. +Public Clouds storage providers under the hood work a bit differently. They save snapshots +to Object Storage and then copy back from Object storage to Block storage when "duplicating" disk. +Technically there is a lot of Compute and network resources spent on Cloud providers side, +but from Kubernetes user perspective VolumeSnapshots work the same way whether is it local or +remote snapshot storage provider and no Compute and Network resources are involved in this operation. + +## Sounds like we have our solution, right? + +Actually, VolumeSnapshots are namespaced, and Kubernetes protects namespaced data from +being shared between tenants (Namespaces). This Kubernetes limitation is a conscious design +decision so that a Pod running in a different namespace can’t mount another application’s +[PersistentVolumeClaim](/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims) (PVC). + +One way around it would be to create multiple volumes with duplicate data in one namespace. +However, you could easily reference the wrong copy. + +So the idea is to separate teams/initiatives by namespaces to avoid that and generally +limit access to the production namespace. + +## Solution? Creating a Golden Snapshot externally + +Another way around this design limitation is to create Snapshot externally (not through Kubernetes). +This is also called pre-provisioning a snapshot manually. Next, I will import it +as a multi-tenant golden snapshot that can be used for many namespaces. Below illustration will be +for AWS EBS (Elastic Block Storage) and GCE PD (Persistent Disk) services. + +### High-level plan for preparing the Golden Snapshot + +1. Identify Disk (EBS/Persistent Disk) that you want to clone with data in the cloud provider +2. Make a Disk Snapshot (in cloud provider console) +3. Get Disk Snapshot ID + +### High-level plan for cloning data for each team + +1. Create Namespace “sandbox01” +2. Import Disk Snapshot (ID) as VolumeSnapshotContent to Kubernetes +3. Create VolumeSnapshot in the Namespace "sandbox01" mapped to VolumeSnapshotContent +4. Create the PersistentVolumeClaim from VolumeSnapshot +5. Install Deployment or StatefulSet with PVC + +## Step 1: Identify Disk + +First, you need to identify your golden source. In my case, it’s a PostgreSQL database +on PersistentVolumeClaim “postgres-pv-claim” in the “production” namespace. + +```terminal +kubectl -n get pvc -o jsonpath='{.spec.volumeName}' +``` + +The output will look similar to: +``` +pvc-3096b3ba-38b6-4fd1-a42f-ec99176ed0d90 +``` + +## Step 2: Prepare your golden source + +You need to do this once or every time you want to refresh your golden data. + +### Make a Disk Snapshot + +Go to AWS EC2 or GCP Compute Engine console and search for an EBS volume +(on AWS) or Persistent Disk (on GCP), that has a label matching the last output. +In this case I saw: `pvc-3096b3ba-38b6-4fd1-a42f-ec99176ed0d9`. + +Click on Create snapshot and give it a name. You can do it in Console manually, +in AWS CloudShell / Google Cloud Shell, or in the terminal. To create a snapshot in the +terminal you must have the AWS CLI tool (`aws`) or Google's CLI (`gcloud`) +installed and configured. + +Here’s the command to create snapshot on GCP: + +```terminal +gcloud compute disks snapshot --project= --snapshot-names= --zone= --storage-location= +``` +{{< figure src="/images/blog/2021-09-07-data-duplication-in-data-heavy-k8s-env/create-volume-snapshot-gcp.png" alt="Screenshot of a terminal showing volume snapshot creation on GCP" title="GCP snapshot creation" >}} + + +GCP identifies the disk by its PVC name, so it’s direct mapping. In AWS, you need to +find volume by the CSIVolumeName AWS tag with PVC name value first that will be used for snapshot creation. + +{{< figure src="/images/blog/2021-09-07-data-duplication-in-data-heavy-k8s-env/identify-volume-aws.png" alt="Screenshot of AWS web console, showing EBS volume identification" title="Identify disk ID on AWS" >}} + +Mark done Volume (volume-id) ```vol-00c7ecd873c6fb3ec``` and ether create EBS snapshot in AWS Console, or use ```aws cli```. + +```terminal +aws ec2 create-snapshot --volume-id '' --description '' --tag-specifications 'ResourceType=snapshot' +``` + +## Step 3: Get your Disk Snapshot ID + +In AWS, the command above will output something similar to: +```terminal +"SnapshotId": "snap-09ed24a70bc19bbe4" +``` + +If you’re using the GCP cloud, you can get the snapshot ID from the gcloud command by querying for the snapshot’s given name: + +```terminal +gcloud compute snapshots --project= describe | grep id: +``` +You should get similar output to: +``` +id: 6645363163809389170 +``` + +## Step 4: Create a development environment for each team + +Now I have my Golden Snapshot, which is immutable data. Each team will get a copy +of this data, and team members can modify it as they see fit, given that a new EBS/persistent +disk will be created for each team. + +Below I will define a manifest for each namespace. To save time, you can replace +the namespace name (such as changing “sandbox01” → “sandbox42”) using tools +such as `sed` or `yq`, with Kubernetes-aware templating tools like +[Kustomize](/docs/tasks/manage-kubernetes-objects/kustomization/), +or using variable substitution in a CI/CD pipeline. + +Here's an example manifest: + +```yaml +--- +apiVersion: snapshot.storage.k8s.io/v1 +kind: VolumeSnapshotContent +metadata: + name: postgresql-orders-db-sandbox01 + namespace: sandbox01 +spec: + deletionPolicy: Retain + driver: pd.csi.storage.gke.io + source: + snapshotHandle: 'gcp/projects/staging-eu-castai-vt5hy2/global/snapshots/6645363163809389170' + volumeSnapshotRef: + kind: VolumeSnapshot + name: postgresql-orders-db-snap + namespace: sandbox01 +--- +apiVersion: snapshot.storage.k8s.io/v1 +kind: VolumeSnapshot +metadata: + name: postgresql-orders-db-snap + namespace: sandbox01 +spec: + source: + volumeSnapshotContentName: postgresql-orders-db-sandbox01 +``` + +In Kubernetes, VolumeSnapshotContent (VSC) objects are not namespaced. +However, I need a separate VSC for each different namespace to use, so the +`metadata.name` of each VSC must also be different. To make that straightfoward, +I used the target namespace as part of the name. + +Now it’s time to replace the driver field with the CSI (Container Storage Interface) driver +installed in your K8s cluster. Major cloud providers have CSI driver for block storage that +support VolumeSnapshots but quite often CSI drivers are not installed by default, consult +with your Kubernetes provider. + +That manifest above defines a VSC that works on GCP. +On AWS, driver and SnashotHandle values might look like: + +```YAML + driver: ebs.csi.aws.com + source: + snapshotHandle: "snap-07ff83d328c981c98" +``` + +At this point, I need to use the *Retain* policy, so that the CSI driver doesn’t try to +delete my manually created EBS disk snapshot. + +For GCP, you will have to build this string by hand - add a full project ID and snapshot ID. +For AWS, it’s just a plain snapshot ID. + +VSC also requires specifying which VolumeSnapshot (VS) will use it, so VSC and VS are +referencing each other. + +Now I can create PersistentVolumeClaim from VS above. It’s important to set this first: + + +```yaml +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: postgres-pv-claim + namespace: sandbox01 +spec: + dataSource: + kind: VolumeSnapshot + name: postgresql-orders-db-snap + apiGroup: snapshot.storage.k8s.io + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 21Gi +``` + +If default StorageClass has [WaitForFirstConsumer](https://kubernetes.io/docs/concepts/storage/storage-classes/#volume-binding-mode) policy, +then the actual Cloud Disk will be created from the Golden Snapshot only when some Pod bounds that PVC. + +Now I assign that PVC to my Pod (in my case, it’s Postgresql) as I would with any other PVC. + +```terminal +kubectl -n get volumesnapshotContent,volumesnapshot,pvc,pod +``` + +Both VS and VSC should be *READYTOUSE* true, PVC bound, and the Pod (from Deployment or StatefulSet) running. + +**To keep on using data from my Golden Snapshot, I just need to repeat this for the +next namespace and voilà! No need to waste time and compute resources on the duplication process.** diff --git a/static/images/blog/2021-09-07-data-duplication-in-data-heavy-k8s-env/create-volume-snapshot-gcp.png b/static/images/blog/2021-09-07-data-duplication-in-data-heavy-k8s-env/create-volume-snapshot-gcp.png new file mode 100644 index 0000000000000000000000000000000000000000..795151cb538073b05ad8d6a54a85954620d71614 GIT binary patch literal 69860 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≷ITu_eIA-@dzs5ovbzV10 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 literal 0 HcmV?d00001 diff --git a/static/images/blog/2021-09-07-data-duplication-in-data-heavy-k8s-env/identify-volume-aws.png b/static/images/blog/2021-09-07-data-duplication-in-data-heavy-k8s-env/identify-volume-aws.png new file mode 100644 index 0000000000000000000000000000000000000000..538cbeeba5671febbe1cc6d3b8261dd71fc54147 GIT binary patch literal 303818 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 LMmLicFRy#) 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πg7FRvn@Gk-t`}*K70JrVSxVo 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°aET|(`+jAW0Dhqu7$zVXSzan|#i{5T;8#A-Sv0j2M5gG@Q}@(wC2=~-RPwUe z6o4GHDeK)cA!Cl_DWQ^AC%K8A!L=k|C7I;q6%OXH2B$ZMP)o2Rlj~yyNEWDKZZlG} zS4! zP+gSO=UqTiy)A5dS3a4h1$eH7>M4?5;kVZVeYBkOawR?*K(bAH?&jJL@N;>h@X_ydsPIS9`&xH}zX z(+ha2zTMruLVEtbUJBT5K%1|`s!f#1Nnl9rliG-vphZfbQho6OjLo}mM<)_UC>h8G z#OO%dRLoNRa>~0aW>QXLjz@m9cN|H*)23F1uDR{NFeD?aDYp_H6U2fwa>CtyJ5c^L zD(a~UK>7Vq$q6(?=&{v(k_(WIu+_;)YyH_o=2f;2Of=Sc));)9}r`N`sM{z4$j#w+1V2V)twL$}7KJ z5u4M4B!Hil9bKsB5|pV9w`wJpL~fBlYBrUM%Qv@nGAiyDD(B1QmXNago%${iO1znj zV(0hRFXg$rpbBUD1muD+r9>03>xHl~``U!cU5R?<4Xx|!!dn$_x^^Q!{K_8Su1Olem^6o?@h-zcD z*aKKEcgF)v-TPP%%;b9MXL}ZxaC${z%rD@x|4=>R5(j{Z^rY`il777Q35D=Z?592oZr4RJpFLYUvGYh_Z@WD9C$-fWY`UwERZ7wiQ=|*;L5=yBn z?~e&i15gW5g46!jd5Yn9WeieGj*=g=4p~llpPcD~mV1WR>2-np@PEcr6gjWxkt<#% z%e``K9>N2eJf+o7Edy!0trd{1)@tm1;hogXZZq6VZ6R=d->tKMgIZ$3whGGb9=~m0 zbwd;R#r(Nc@vRXZ4qcVrwfOs0`A;P%QEV?K$E)WD1s$7LmZ$D`>I;UkpTDfIZPEOR z=4^!XEeDx4Q}~v9Kmc1AVcgbniD}h+s!k8nBom6cg z)FdMNb}gl&b_qXtXH)?B{{Pr}�!lu3Z>JL_tACq{EGf2ndMuj?xqaLAjZ_ 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 T+Q+7;KTe-M?&(HxxpeE_0>H6p literal 0 HcmV?d00001 From c724a097bdbfdae8ccbd9f066896f56d89621d08 Mon Sep 17 00:00:00 2001 From: Jacob Valdemar Date: Tue, 21 Sep 2021 07:09:11 +0200 Subject: [PATCH 028/115] Add Line Break element after tab widget --- .../docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade.md b/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade.md index ad3587ad41d62..4cc9d1445bf69 100644 --- a/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade.md +++ b/content/en/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade.md @@ -88,6 +88,7 @@ Pick a control plane node that you wish to upgrade first. It must have the `/etc yum install -y kubeadm-{{< skew currentVersion >}}.x-0 --disableexcludes=kubernetes {{% /tab %}} {{< /tabs >}} +
- Verify that the download works and has the expected version: @@ -184,6 +185,7 @@ Also calling `kubeadm upgrade plan` and upgrading the CNI provider plugin is no yum install -y kubelet-{{< skew currentVersion >}}.x-0 kubectl-{{< skew currentVersion >}}.x-0 --disableexcludes=kubernetes {{% /tab %}} {{< /tabs >}} +
- Restart the kubelet: @@ -264,6 +266,7 @@ without compromising the minimum required capacity for running your workloads. yum install -y kubelet-{{< skew currentVersion >}}.x-0 kubectl-{{< skew currentVersion >}}.x-0 --disableexcludes=kubernetes {{% /tab %}} {{< /tabs >}} +
- Restart the kubelet: From 5d0c9eae0e4103e88cc550a2c29c5652a3dc524c Mon Sep 17 00:00:00 2001 From: radva <45208722+radva@users.noreply.github.com> Date: Tue, 21 Sep 2021 17:53:57 +0200 Subject: [PATCH 029/115] Update translate-compose-kubernetes.md update to latest release version since version 1.22 doesn't support 3.8 --- .../configure-pod-container/translate-compose-kubernetes.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/en/docs/tasks/configure-pod-container/translate-compose-kubernetes.md b/content/en/docs/tasks/configure-pod-container/translate-compose-kubernetes.md index 384b709720ee0..17fc9e1421eee 100644 --- a/content/en/docs/tasks/configure-pod-container/translate-compose-kubernetes.md +++ b/content/en/docs/tasks/configure-pod-container/translate-compose-kubernetes.md @@ -29,13 +29,13 @@ Kompose is released via GitHub on a three-week cycle, you can see all current re ```sh # Linux -curl -L https://github.com/kubernetes/kompose/releases/download/v1.22.0/kompose-linux-amd64 -o kompose +curl -L https://github.com/kubernetes/kompose/releases/download/v1.24.0/kompose-linux-amd64 -o kompose # macOS -curl -L https://github.com/kubernetes/kompose/releases/download/v1.22.0/kompose-darwin-amd64 -o kompose +curl -L https://github.com/kubernetes/kompose/releases/download/v1.24.0/kompose-darwin-amd64 -o kompose # Windows -curl -L https://github.com/kubernetes/kompose/releases/download/v1.22.0/kompose-windows-amd64.exe -o kompose.exe +curl -L https://github.com/kubernetes/kompose/releases/download/v1.24.0/kompose-windows-amd64.exe -o kompose.exe chmod +x kompose sudo mv ./kompose /usr/local/bin/kompose From 93c957e9a60b59556715a09744d719717aa9698b Mon Sep 17 00:00:00 2001 From: Mengjiao Liu Date: Wed, 22 Sep 2021 17:37:19 +0800 Subject: [PATCH 030/115] [zh] fix expiration of bound SA tokens --- .../docs/reference/access-authn-authz/service-accounts-admin.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/zh/docs/reference/access-authn-authz/service-accounts-admin.md b/content/zh/docs/reference/access-authn-authz/service-accounts-admin.md index 451c8d4b3b910..d3faacf58f8cb 100644 --- a/content/zh/docs/reference/access-authn-authz/service-accounts-admin.md +++ b/content/zh/docs/reference/access-authn-authz/service-accounts-admin.md @@ -143,7 +143,7 @@ ServiceAccount 准入控制器将添加如下投射卷,而不是为令牌控 defaultMode: 420 # 0644 sources: - serviceAccountToken: - expirationSeconds: 3600 + expirationSeconds: 3607 path: token - configMap: items: From 2cd822f120b7b2ea7bf2d22557946160669bc7e8 Mon Sep 17 00:00:00 2001 From: fabriziopandini Date: Wed, 22 Sep 2021 11:48:18 +0200 Subject: [PATCH 031/115] ClusterClass and managed topologies blog --- ...-04-clusterclass-and-managed-topologies.md | 143 ++++++++++++++++++ .../clusterclass.svg | 4 + .../create-cluster.svg | 4 + 3 files changed, 151 insertions(+) create mode 100644 content/en/blog/_posts/2021-10-04-clusterclass-and-managed-topologies.md create mode 100644 static/images/blog/2021-10-04-clusterclass-and-managed-topologies/clusterclass.svg create mode 100644 static/images/blog/2021-10-04-clusterclass-and-managed-topologies/create-cluster.svg diff --git a/content/en/blog/_posts/2021-10-04-clusterclass-and-managed-topologies.md b/content/en/blog/_posts/2021-10-04-clusterclass-and-managed-topologies.md new file mode 100644 index 0000000000000..b576b345e9a02 --- /dev/null +++ b/content/en/blog/_posts/2021-10-04-clusterclass-and-managed-topologies.md @@ -0,0 +1,143 @@ +--- +layout: blog +title: "Introducing ClusterClass and Managed Topologies in Cluster API" +date: 2021-10-04 +slug: capi-clusterclass-and-managed-topologies +--- + +**Author:** Fabrizio Pandini (VMware) + +The [Cluster API community](https://cluster-api.sigs.k8s.io/) is happy to announce the implementation of *ClusterClass and Managed Topologies*, a new feature that will greatly simplify how you can provision, upgrade, and operate multiple Kubernetes clusters in a declarative way. + +## A little bit of context… + +Before getting into the details, let's take a step back and look at the history of Cluster API. + +The [Cluster API project](https://github.com/kubernetes-sigs/cluster-api/) started three years ago, and the first releases focused on extensibility and implementing a declarative API that allows a seamless experience across infrastructure providers. This was a success with many cloud providers: AWS, Azure, Digital Ocean, GCP, Metal3, vSphere and still counting. + +With extensibility addressed, the focus shifted to features, like automatic control plane and etcd management, health-based machine remediation, machine rollout strategies and more. + +Fast forwarding to 2021, with lots of companies using Cluster API to manage fleets of Kubernetes clusters running workloads in production, the community focused its effort on stabilization of both code, APIs and documentation, and on extensive test signals which inform Kubernetes releases. + +With solid foundations in place, and a vibrant and welcoming community that still continues to grow, it was time to plan another iteration on our UX for both new and advanced users. + +Enter ClusterClass and manage topologies, tada! + +## ClusterClass + +As the name suggests, ClusterClass and managed topologies are built in two parts. + +The idea behind ClusterClass is simple: let’s define the shape of your cluster once, and then reuse it many times, abstracting the complexities and the internals of a Kubernetes cluster away. + +![Defining a ClusterClass](/images/blog/2021-10-04-clusterclass-and-managed-topologies/clusterclass.svg) + +ClusterClass, at its heart, is a collection of Cluster and Machine templates. You can use it as a “stamp” that can be leveraged to create many clusters of a similar shape. + +```yaml +--- +apiVersion: cluster.x-k8s.io/v1beta1 + kind: ClusterClass + metadata: + name: my-amazing-cluster-class + namespace: bar + spec: + controlPlane: + ref: + apiVersion: controlplane.cluster.x-k8s.io/v1beta1 + kind: KubeadmControlPlaneTemplate + name: high-availability-kcp + machineInfrastructure: + ref: + apiVersion: infrastructure.cluster.x-k8s.io/v1alpha4 + kind: VSphereMachineTemplate + name: controlplane-vsphere-machinetemplate + workers: + deployments: + - class: linux-worker + template: + bootstrap: + ref: + apiVersion: bootstrap.cluster.x-k8s.io/v1beta1 + kind: KubeadmConfigTemplate + name: linux-bootstrap + infrastructure: + ref: + apiVersion: infrastructure.cluster.x-k8s.io/v1alpha4 + kind: VSphereMachineTemplate + name: linux-vsphere-template + - class: windows-worker + template: + bootstrap: + ref: + apiVersion: bootstrap.cluster.x-k8s.io/v1beta1 + kind: KubeadmConfigTemplate + name: windows-bootstrap + infrastructure: + ref: + apiVersion: infrastructure.cluster.x-k8s.io/v1alpha4 + kind: VSphereMachineTemplate + name: windows-vsphere-template + infrastructure: + ref: + apiVersion: infrastructure.cluster.x-k8s.io/v1alpha4 + kind: VSphereClusterTemplate + name: vsphere-cluster +``` + +The possibilities are endless; you can get a default ClusterClass from the community, “off-the shelf” classes from your vendor of choice, “certified” classes from the platform admin in your company, or even create custom ones for advanced scenarios. + +## Managed Topologies + +Managed topologies let you put the power that ClusterClass provides into action. + +Given a ClusterClass, you can create many Clusters of a similar shape by providing a single resource, the Cluster. + +![Create a Cluster with ClusterClass](/images/blog/2021-10-04-clusterclass-and-managed-topologies/create-cluster.svg) + +Here is an example: + +```yaml +--- +apiVersion: cluster.x-k8s.io/v1beta1 + kind: Cluster + metadata: + name: my-amazing-cluster + namespace: bar + spec: + topology: # define a managed topology + class: my-amazing-cluster-class # use the ClusterClass mentioned earlier + version: v1.21.2 + controlPlane: + replicas: 3 + workers: + machineDeployments: + - class: linux-worker + name: big-pool-of-linux-machines-1 + replicas: 5 + - class: linux-worker + name: small-pool-of-linux-machines-1 + replicas: 1 + - class: windows-worker + name: pool-of-windows-machines + replicas: 3 +``` + +But there is more than simplified cluster creation. Now the Cluster acts as a single control point for your entire topology. + +All the power of Cluster API, extensibility, lifecycle automation, stability, all the features required for managing an enterprise grade Kubernetes cluster on the infrastructure provider of your choice are now at your fingertips: you can create your Cluster, add new machines, upgrade to the next Kubernetes version, and all from a single place. + +It is just as simple as it looks! + +## What’s next + +While the amazing Cluster API community is working hard to deliver the first version of ClusterClass and managed topologies later this year, we are already looking forward to what comes next for the project and its ecosystem. + +There are a lot of great ideas and opportunities ahead! + +We want to make managed topologies even more powerful and flexible, allowing users to dynamically change bits of a ClusterClass according to the specific needs of a Cluster; this will ensure the same simple and intuitive UX for solving complex problems like e.g. selecting machine image for a specific Kubernetes version and for a specific region of your infrastructure provider, or injecting proxy configurations in the entire Cluster, and so on. + +Stay tuned for what comes next, and if you have any question, comment or suggestion: + +* Chat with us on the Kubernetes [Slack](http://slack.k8s.io/):[#cluster-api](https://kubernetes.slack.com/archives/C8TSNPY4T) +* Join the SIG Cluster Lifecycle [Google Group](https://groups.google.com/g/kubernetes-sig-cluster-lifecycle) to receive calendar invites and gain access to documents +* Join our [Zoom meeting](https://zoom.us/j/861487554), every Wednesday at 10:00 Pacific Time diff --git a/static/images/blog/2021-10-04-clusterclass-and-managed-topologies/clusterclass.svg b/static/images/blog/2021-10-04-clusterclass-and-managed-topologies/clusterclass.svg new file mode 100644 index 0000000000000..c22b4b9ff02ef --- /dev/null +++ b/static/images/blog/2021-10-04-clusterclass-and-managed-topologies/clusterclass.svg @@ -0,0 +1,4 @@ + + + +
ClusterClass
ClusterClass
KubeadmConfigTemplate
KubeadmConfigTemplate
VSphereMachineTemplate
VSphereMachineTemplate
VSphereClusterTemplate
VSphereClusterTemplate
MachineDeploymentClass
MachineDeploymentClass
VSphereMachineTemplate
VSphereMachineTemplate
KubeadmControlPlaneTemplate
KubeadmControlPlaneTemplate
Cluster
Cluster
Cluster
Cluster
Cluster
Cluster
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/static/images/blog/2021-10-04-clusterclass-and-managed-topologies/create-cluster.svg b/static/images/blog/2021-10-04-clusterclass-and-managed-topologies/create-cluster.svg new file mode 100644 index 0000000000000..d26d49d7bb271 --- /dev/null +++ b/static/images/blog/2021-10-04-clusterclass-and-managed-topologies/create-cluster.svg @@ -0,0 +1,4 @@ + + + +
ClusterClass
ClusterClass
Templates
Templates
Cluster
Cluster
Managed
Topology
Managed...
Cluster
Cluster
Managed
Topology
Managed...
Cluster
Cluster
Managed
Topology
Managed...
Viewer does not support full SVG 1.1
\ No newline at end of file From b4d1304c2ace4d9f9962eb1c578f2ab589a9ba8b Mon Sep 17 00:00:00 2001 From: Mengjiao Liu Date: Wed, 22 Sep 2021 18:25:20 +0800 Subject: [PATCH 032/115] [zh] Sync administer-cluster kubeadm-upgrade.md --- .../kubeadm/kubeadm-upgrade.md | 88 +++++++++---------- 1 file changed, 43 insertions(+), 45 deletions(-) diff --git a/content/zh/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade.md b/content/zh/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade.md index 81623a6b4c328..25f10b0fed8f5 100644 --- a/content/zh/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade.md +++ b/content/zh/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade.md @@ -16,13 +16,13 @@ min-kubernetes-server-version: 1.18 -本页介绍如何将 `kubeadm` 创建的 Kubernetes 集群从 {{< skew latestVersionAddMinor -1 >}}.x 版本 -升级到 {{< skew latestVersion >}}.x 版本以及从 {{< skew latestVersion >}}.x -升级到 {{< skew latestVersion >}}.y(其中 `y > x`)。略过次版本号的升级是 +本页介绍如何将 `kubeadm` 创建的 Kubernetes 集群从 {{< skew currentVersionAddMinor -1 >}}.x 版本 +升级到 {{< skew currentVersion >}}.x 版本以及从 {{< skew currentVersion >}}.x +升级到 {{< skew currentVersion >}}.y(其中 `y > x`)。略过次版本号的升级是 不被支持的。 -- [将 kubeadm 集群从 1.17 升级到 1.18](https://v1-18.docs.kubernetes.io/zh/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/) -- [将 kubeadm 集群从 1.16 升级到 1.17](https://v1-17.docs.kubernetes.io/zh/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/) -- [将 kubeadm 集群从 1.15 升级到 1.16](https://v1-16.docs.kubernetes.io/zh/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/) -- [将 kubeadm 集群从 1.14 升级到 1.15](https://v1-15.docs.kubernetes.io/zh/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-1-15/) -- [将 kubeadm 集群从 1.13 升级到 1.14](https://v1-15.docs.kubernetes.io/zh/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade-1-14/) +- [将 kubeadm 集群从 {{< skew currentVersionAddMinor -2 >}} 升级到 {{< skew currentVersionAddMinor -1 >}}](https://v{{< skew currentVersionAddMinor -1 "-" >}}.docs.kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/) +- [将 kubeadm 集群从 {{< skew currentVersionAddMinor -3 >}} 升级到 {{< skew currentVersionAddMinor -2 >}}](https://v{{< skew currentVersionAddMinor -2 "-" >}}.docs.kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/) +- [将 kubeadm 集群从 {{< skew currentVersionAddMinor -4 >}} 升级到 {{< skew currentVersionAddMinor -3 >}}](https://v{{< skew currentVersionAddMinor -3 "-" >}}.docs.kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/) +- [将 kubeadm 集群从 {{< skew currentVersionAddMinor -5 >}} 升级到 {{< skew currentVersionAddMinor -4 >}}](https://v{{< skew currentVersionAddMinor -4 "-" >}}.docs.kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/) ## 确定要升级到哪个版本 -使用操作系统的包管理器找到最新的稳定 {{< skew latestVersion >}}: +使用操作系统的包管理器找到最新的补丁版本 Kubernetes {{< skew currentVersion >}}: {{< tabs name="k8s_install_versions" >}} {{% tab name="Ubuntu、Debian 或 HypriotOS" %}} ``` apt update -apt-cache policy kubeadm -# 在列表中查找最新的 {{< skew latestVersion >}} 版本 -# 它看起来应该是 {{< skew latestVersion >}}.x-00,其中 x 是最新的补丁版本 +apt-cache madison kubeadm +# 在列表中查找最新的 {{< skew currentVersion >}} 版本 +# 它看起来应该是 {{< skew currentVersion >}}.x-00,其中 x 是最新的补丁版本 ``` {{% /tab %}} {{% tab name="CentOS、RHEL 或 Fedora" %}} ``` yum list --showduplicates kubeadm --disableexcludes=kubernetes -# 在列表中查找最新的 {{< skew latestVersion >}} 版本 -# 它看起来应该是 {{< skew latestVersion >}}.x-0,其中 x 是最新的补丁版本 +# 在列表中查找最新的 {{< skew currentVersion >}} 版本 +# 它看起来应该是 {{< skew currentVersion >}}.x-0,其中 x 是最新的补丁版本 ``` {{% /tab %}} {{< /tabs >}} @@ -143,20 +141,20 @@ Pick a control plane node that you wish to upgrade first. It must have the `/etc {{< tabs name="k8s_install_kubeadm_first_cp" >}} {{% tab name="Ubuntu、Debian 或 HypriotOS" %}} ```shell -# 用最新的补丁版本号替换 {{< skew latestVersion >}}.x-00 中的 x +# 用最新的补丁版本号替换 {{< skew currentVersion >}}.x-00 中的 x apt-mark unhold kubeadm && \ -apt-get update && apt-get install -y kubeadm={{< skew latestVersion >}}.x-00 && \ +apt-get update && apt-get install -y kubeadm={{< skew currentVersion >}}.x-00 && \ apt-mark hold kubeadm - # 从 apt-get 1.1 版本起,你也可以使用下面的方法 apt-get update && \ -apt-get install -y --allow-change-held-packages kubeadm={{< skew latestVersion >}}.x-00 +apt-get install -y --allow-change-held-packages kubeadm={{< skew currentVersion >}}.x-00 ``` {{% /tab %}} {{% tab name="CentOS、RHEL 或 Fedora" %}} ```shell -# 用最新的补丁版本号替换 {{< skew latestVersion >}}.x-0 中的 x -yum install -y kubeadm-{{< skew latestVersion >}}.x-0 --disableexcludes=kubernetes +# 用最新的补丁版本号替换 {{< skew currentVersion >}}.x-0 中的 x +yum install -y kubeadm-{{< skew currentVersion >}}.x-0 --disableexcludes=kubernetes ``` {{% /tab %}} {{< /tabs >}} @@ -213,14 +211,14 @@ yum install -y kubeadm-{{< skew latestVersion >}}.x-0 --disableexcludes=kubernet ```shell # replace x with the patch version you picked for this upgrade - sudo kubeadm upgrade apply v{{< skew latestVersion >}}.x + sudo kubeadm upgrade apply v{{< skew currentVersion >}}.x ``` --> 选择要升级到的目标版本,运行合适的命令。例如: ```shell # 将 x 替换为你为此次升级所选择的补丁版本号 - sudo kubeadm upgrade apply v{{< skew latestVersion >}}.x + sudo kubeadm upgrade apply v{{< skew currentVersion >}}.x ``` This page covers how to customize the components that kubeadm deploys. For control plane components -you can use flags in the `ClusteConfiguration` structure or patches per-node. For the kubelet +you can use flags in the `ClusterConfiguration` structure or patches per-node. For the kubelet and kube-proxy you can use `KubeletConfiguration` and `KubeProxyConfiguration`, accordingly. All of these options are possible via the kubeadm configuration API. From a6ed49bca93a3a8cfc5b9b360706fe9c917cf96b Mon Sep 17 00:00:00 2001 From: S Nitesh Singh Date: Thu, 23 Sep 2021 10:59:48 +0530 Subject: [PATCH 038/115] remove 'Tools Included' from sidebar of translated page --- layouts/partials/sidebar-tree.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layouts/partials/sidebar-tree.html b/layouts/partials/sidebar-tree.html index f1a3c9926a249..3b246d86f1da6 100644 --- a/layouts/partials/sidebar-tree.html +++ b/layouts/partials/sidebar-tree.html @@ -69,7 +69,7 @@ {{ range . }} {{ with (where $.section.Translations ".Lang" . ) -}} {{ $p := index . 0 -}} - {{ $pages = $pages | lang.Merge (union $p.Pages $p.Sections) -}} + {{ $pages = where ( $pages | lang.Merge (union $p.Pages $p.Sections)) ".Params.toc_hide" "!=" true -}} {{ end -}} {{ end -}} {{ end -}} From 02809ef886d87f0ead78e03c518471345fb100f2 Mon Sep 17 00:00:00 2001 From: fabriziopandini Date: Thu, 23 Sep 2021 16:01:08 +0200 Subject: [PATCH 039/115] address comments --- ...2021-10-04-clusterclass-and-managed-topologies.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/content/en/blog/_posts/2021-10-04-clusterclass-and-managed-topologies.md b/content/en/blog/_posts/2021-10-04-clusterclass-and-managed-topologies.md index b576b345e9a02..ec49d73e7d60c 100644 --- a/content/en/blog/_posts/2021-10-04-clusterclass-and-managed-topologies.md +++ b/content/en/blog/_posts/2021-10-04-clusterclass-and-managed-topologies.md @@ -17,17 +17,17 @@ The [Cluster API project](https://github.com/kubernetes-sigs/cluster-api/) start With extensibility addressed, the focus shifted to features, like automatic control plane and etcd management, health-based machine remediation, machine rollout strategies and more. -Fast forwarding to 2021, with lots of companies using Cluster API to manage fleets of Kubernetes clusters running workloads in production, the community focused its effort on stabilization of both code, APIs and documentation, and on extensive test signals which inform Kubernetes releases. +Fast forwarding to 2021, with lots of companies using Cluster API to manage fleets of Kubernetes clusters running workloads in production, the community focused its effort on stabilization of both code, APIs, documentation, and on extensive test signals which inform Kubernetes releases. With solid foundations in place, and a vibrant and welcoming community that still continues to grow, it was time to plan another iteration on our UX for both new and advanced users. -Enter ClusterClass and manage topologies, tada! +Enter ClusterClass and Managed Topologies, tada! ## ClusterClass As the name suggests, ClusterClass and managed topologies are built in two parts. -The idea behind ClusterClass is simple: let’s define the shape of your cluster once, and then reuse it many times, abstracting the complexities and the internals of a Kubernetes cluster away. +The idea behind ClusterClass is simple: define the shape of your cluster once, and reuse it many times, abstracting the complexities and the internals of a Kubernetes cluster away. ![Defining a ClusterClass](/images/blog/2021-10-04-clusterclass-and-managed-topologies/clusterclass.svg) @@ -84,11 +84,11 @@ apiVersion: cluster.x-k8s.io/v1beta1 name: vsphere-cluster ``` -The possibilities are endless; you can get a default ClusterClass from the community, “off-the shelf” classes from your vendor of choice, “certified” classes from the platform admin in your company, or even create custom ones for advanced scenarios. +The possibilities are endless; you can get a default ClusterClass from the community, “off-the-shelf” classes from your vendor of choice, “certified” classes from the platform admin in your company, or even create custom ones for advanced scenarios. ## Managed Topologies -Managed topologies let you put the power that ClusterClass provides into action. +Managed Topologies let you put the power of ClusterClass into action. Given a ClusterClass, you can create many Clusters of a similar shape by providing a single resource, the Cluster. @@ -136,7 +136,7 @@ There are a lot of great ideas and opportunities ahead! We want to make managed topologies even more powerful and flexible, allowing users to dynamically change bits of a ClusterClass according to the specific needs of a Cluster; this will ensure the same simple and intuitive UX for solving complex problems like e.g. selecting machine image for a specific Kubernetes version and for a specific region of your infrastructure provider, or injecting proxy configurations in the entire Cluster, and so on. -Stay tuned for what comes next, and if you have any question, comment or suggestion: +Stay tuned for what comes next, and if you have any questions, comments or suggestions: * Chat with us on the Kubernetes [Slack](http://slack.k8s.io/):[#cluster-api](https://kubernetes.slack.com/archives/C8TSNPY4T) * Join the SIG Cluster Lifecycle [Google Group](https://groups.google.com/g/kubernetes-sig-cluster-lifecycle) to receive calendar invites and gain access to documents From 09206415705983b30b19ee8795a816c30ecadb0b Mon Sep 17 00:00:00 2001 From: Dewan Ahmed Date: Thu, 23 Sep 2021 11:53:58 -0300 Subject: [PATCH 040/115] Update to the introduction --- content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md b/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md index 6d27839d18e2f..88c9fc890bbe2 100644 --- a/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md +++ b/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md @@ -9,8 +9,7 @@ slug: sig-node-spotlight-2021 ## Introduction -[SIG Node](https://github.com/kubernetes/community/tree/master/sig-node) is responsible for the components that support the controlled interactions between pods and host resources. The work of this group manages the lifecycle of pods that are scheduled to a node, and focuses on enabling a broad set of workload types, including workloads with hardware specific or performance sensitive requirements. In this blog, we have summarized our conversation with [Elana Hashman (EH)](https://twitter.com/ehashdn) & [Sergey Kanzhelev (SK)](https://twitter.com/SergeyKanzhelev), who walk us through the various aspects of being a part of the SIG and share some insights about how others can get involved. - +In Kubernetes, a _Node_ is a representation of a single machine in your cluster. [SIG Node](https://github.com/kubernetes/community/tree/master/sig-node) owns that very important Node component and supports various subprojects such as Kubelet, Container Runtime Interface (CRI) and more to support how the pods and host resources interact. In this blog, we have summarized our conversation with [Elana Hashman (EH)](https://twitter.com/ehashdn) & [Sergey Kanzhelev (SK)](https://twitter.com/SergeyKanzhelev), who walk us through the various aspects of being a part of the SIG and share some insights about how others can get involved. ## A summary of our conversation From 577e0c7ca53e282b4b3e655fddd5f379296e091f Mon Sep 17 00:00:00 2001 From: Dewan Ahmed Date: Thu, 23 Sep 2021 11:55:16 -0300 Subject: [PATCH 041/115] Match folder name with publication date --- .../index.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename content/en/blog/_posts/{2021-08-13-SIG-Node-Spotlight => 2021-09-27-SIG-Node-Spotlight}/index.md (100%) diff --git a/content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md b/content/en/blog/_posts/2021-09-27-SIG-Node-Spotlight/index.md similarity index 100% rename from content/en/blog/_posts/2021-08-13-SIG-Node-Spotlight/index.md rename to content/en/blog/_posts/2021-09-27-SIG-Node-Spotlight/index.md From 4ba25b088566c2f219f1211424ef015c3745c125 Mon Sep 17 00:00:00 2001 From: Arhell Date: Fri, 24 Sep 2021 00:23:51 +0300 Subject: [PATCH 042/115] [id] Add seccomp tutorial to index --- content/id/docs/tutorials/_index.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/content/id/docs/tutorials/_index.md b/content/id/docs/tutorials/_index.md index 9f3ec5afb34e9..041b7b62d2387 100644 --- a/content/id/docs/tutorials/_index.md +++ b/content/id/docs/tutorials/_index.md @@ -50,6 +50,8 @@ Sebelum melangkah lebih lanjut ke tutorial, sebaiknya tandai dulu halaman [Kamus * [AppArmor](/docs/tutorials/clusters/apparmor/) +* [seccomp](/docs/tutorials/clusters/seccomp/) + ## Servis * [Menggunakan Source IP](/docs/tutorials/services/source-ip/) From d8245b95be0a4b8c560977cc4f12e4aea6f14338 Mon Sep 17 00:00:00 2001 From: Mengjiao Liu Date: Fri, 24 Sep 2021 11:18:40 +0800 Subject: [PATCH 043/115] [zh] Update kep link and release version for dockershim removal in faq --- content/zh/blog/_posts/2020-12-02-dockershim-faq.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/content/zh/blog/_posts/2020-12-02-dockershim-faq.md b/content/zh/blog/_posts/2020-12-02-dockershim-faq.md index 65292d90ac312..d873fab0495bc 100644 --- a/content/zh/blog/_posts/2020-12-02-dockershim-faq.md +++ b/content/zh/blog/_posts/2020-12-02-dockershim-faq.md @@ -45,7 +45,7 @@ You can read more about the community discussion and planning in the --> Dockershim 向来都是一个临时解决方案(因此得名:shim)。 你可以进一步阅读 -[移除 Kubernetes 增强方案 Dockershim](https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/1985-remove-dockershim) +[移除 Kubernetes 增强方案 Dockershim][drkep] 以了解相关的社区讨论和计划。 @@ -78,12 +79,16 @@ startup if using Docker as the runtime. 考虑到此改变带来的影响,我们使用了一个加长的废弃时间表。 在 Kubernetes 1.22 版之前,它不会被彻底移除;换句话说,dockershim 被移除的最早版本会是 2021 年底发布的 1.23 版。 +_更新_:dockershim 计划在 Kubernetes 1.24 版被移除, +请参阅[移除 Kubernetes 增强方案 Dockershim][drkep]。 我们将与供应商以及其他生态团队紧密合作,确保顺利过渡,并将依据事态的发展评估后续事项。 * 提供程序对双协议栈网络的支持 (云供应商或其他方式必须能够为 Kubernetes 节点 提供可路由的 IPv4/IPv6 网络接口) -* 一个能够支持双协议栈的 +* 一个能够支持[双协议栈](/zh/docs/concepts/services-networking/dual-stack/)的 [网络插件](/zh/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/), - (如 kubenet 或 Calico)。 + (如 Calico,Cilium 或 Kubenet)。 * [启用双协议栈](/zh/docs/concepts/services-networking/dual-stack/) 集群 From 40d2fdbe65055ca2b78fe805849306b83d97ea04 Mon Sep 17 00:00:00 2001 From: superleo Date: Thu, 23 Sep 2021 23:37:00 +0800 Subject: [PATCH 045/115] Update content/zh/docs/tasks/configure-pod-container/configure-gmsa.md --- .../configure-pod-container/configure-gmsa.md | 146 +++++++++++++----- 1 file changed, 107 insertions(+), 39 deletions(-) diff --git a/content/zh/docs/tasks/configure-pod-container/configure-gmsa.md b/content/zh/docs/tasks/configure-pod-container/configure-gmsa.md index 3687f9b918d57..8e183745c6272 100644 --- a/content/zh/docs/tasks/configure-pod-container/configure-gmsa.md +++ b/content/zh/docs/tasks/configure-pod-container/configure-gmsa.md @@ -381,6 +381,85 @@ As Pod specs with GMSA fields populated (as described above) are applied in a cl 1. 容器运行时为每个 Windows 容器配置所指定的 GMSA 凭据规约,这样容器就可以以 活动目录中该 GMSA 所代表的身份来执行操作,使用该身份来访问域中的服务。 + +## Containerd +在 Windows Server 2019 上对 containerd 使用 GMSA,需要使用 Build 17763.1817(或更新的版本), +你可以安装补丁 [KB5000822](https://support.microsoft.com/en-us/topic/march-9-2021-kb5000822-os-build-17763-1817-2eb6197f-e3b1-4f42-ab51-84345e063564)。 + +containerd 场景从 Pod 连接 SMB 共享的时候有一个已知问题: +配置了 GMSA 以后,无法通过主机名或者 FQDN 访问 SMB共享,但是通过 IP 地址访问没有问题。 + +```PowerShell +ping adserver.ad.local +``` + + + +主机名可以被解析为 IPv4 地址,输出类似如下所示: + +``` +Pinging adserver.ad.local [192.168.111.18] with 32 bytes of data: +Reply from 192.168.111.18: bytes=32 time=6ms TTL=124 +Reply from 192.168.111.18: bytes=32 time=5ms TTL=124 +Reply from 192.168.111.18: bytes=32 time=5ms TTL=124 +Reply from 192.168.111.18: bytes=32 time=5ms TTL=124 +``` + + +但是,当尝试使用主机名浏览目录时: + +```PowerShell +cd \\adserver.ad.local\test +``` + + +你会看到一个错误,提示目标共享不存在: + +``` +cd : Cannot find path '\\adserver.ad.local\test' because it does not exist. +At line:1 char:1 ++ cd \\adserver.ad.local\test ++ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + CategoryInfo : ObjectNotFound: (\\adserver.ad.local\test:String) [Set-Location], ItemNotFoundException + + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.SetLocationCommand +``` + + +但是你会注意到,如果你改为使用其 IPv4 地址浏览共享,错误就会消失;例如: + +```PowerShell +cd \\192.168.111.18\test +``` + + +切换到共享中的目录后,你会看到类似于以下内容的提示: + +``` +Microsoft.PowerShell.Core\FileSystem::\\192.168.111.18\test> +``` + + +要解决问题,你需要在节点上运行以下命令以添加所需的注册表项 +`reg add "HKLM\SYSTEM\CurrentControlSet\Services\hns\State" /v EnableCompartmentNamespace /t REG_DWORD /d 1`。 +此更改只会在新创建的 Pod 中生效,这意味着你必须重新创建任何需要访问 SMB 共享的正在运行的 Pod。 ## 故障排查 -如果在你的环境中配置 GMSA 时遇到了困难,你可以采取若干步骤来排查可能 -的故障。 +如果在你的环境中配置 GMSA 时遇到了困难,你可以采取若干步骤来排查可能的故障。 -首先,确保凭据规约已经被传递到 Pod。要实现这点,你需要先通过 `exec` 进入到 -你的 Pod 之一,检查 `nltest.exe /parentdomain` 命令的输出。 +首先,确保 credspec 已传递给 Pod。为此,你需要先运行 `exec` 进入到你的一个 Pod 中并检查 `nltest.exe /parentdomain` 命令的输出。 在下面的例子中,Pod 未能正确地获得凭据规约: -```shell +```PowerShell kubectl exec -it iis-auth-7776966999-n5nzr powershell.exe +``` -Windows PowerShell -Copyright (C) Microsoft Corporation. All rights reserved. - -PS C:\> nltest.exe /parentdomain + +`nltest.exe /parentdomain` 导致以下错误: +``` Getting parent domain failed: Status = 1722 0x6ba RPC_S_SERVER_UNAVAILABLE -PS C:\> ``` -这一输出告诉我们,由于某些原因,Pod 无法使用凭据规约中的账号登录到域。 -你可以通过运行 `nltest.exe /sc_reset:domain.example` 命令尝试修复安全通道。 +这告诉我们,由于某种原因,Pod 无法使用 credspec 中指定的帐户登录到域。 +你可以尝试通过运行以下命令来修复安全通道: -```shell -PS C:\> nltest /sc_reset:domain.example +```PowerShell +nltest /sc_reset:domain.example +``` + + +如果命令成功,你将看到类似以下内容的输出: + +``` Flags: 30 HAS_IP HAS_TIMESERV Trusted DC Name \\dc10.domain.example Trusted DC Connection Status Status = 0 0x0 NERR_Success The command completed successfully -PS C:\> ``` -如果上述命令修复了错误,你就可以通过向你的 Pod 规约添加生命周期回调来将此操作 -自动化。如果上述命令未能奏效,你就需要再次检查凭据规约,以确保其数据时正确的 -而且是完整的。 +如果以上命令修复了错误,你可以通过将以下生命周期回调添加到你的 Pod 规约中来自动执行该步骤。 +如果这些操作没有修复错误,你将需要再次检查你的 credspec 并确认它是正确和完整的。 ```yaml image: registry.domain.example/iis-auth:1809v1 @@ -477,18 +560,3 @@ If you add the `lifecycle` section show above to your Pod spec, the Pod will exe 列举的命令来重启 `netlogon` 服务,直到 `nltest.exe /query` 命令返回时没有错误信息。 - -## GMSA 的局限 {#gmsa-limitations} - -在使用 [Windows 版本的 ContainerD 运行时](/zh/docs/setup/production-environment/windows/intro-windows-in-kubernetes/#cri-containerd) -时,通过 GMSA 域身份标识访问受限制的网络共享资源时会出错。 -容器会收到身份标识且 `nltest.exe /query` 调用也能正常工作。 -当需要访问网络共享资源时,建议使用 -[Docker EE 运行时](/zh/docs/setup/production-environment/windows/intro-windows-in-kubernetes/#docker-ee)。 -Windows Server 团队正在 Windows 内核中解决这一问题,并在将来发布解决此问题的补丁。 -你可以在 [Microsoft Windows Containers 问题跟踪列表](https://github.com/microsoft/Windows-Containers/issues/44) -中查找这类更新。 - From 548dee7af3b50994b6903546009d40a074829b1b Mon Sep 17 00:00:00 2001 From: Jumping Qu Date: Fri, 24 Sep 2021 16:28:56 +0800 Subject: [PATCH 046/115] Update debug-cluster.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit remove the ":" after "具体情况: " and "缓解措施:" --- .../zh/docs/tasks/debug-application-cluster/debug-cluster.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/zh/docs/tasks/debug-application-cluster/debug-cluster.md b/content/zh/docs/tasks/debug-application-cluster/debug-cluster.md index f97364dd4c46c..7f7ffff4e83ab 100644 --- a/content/zh/docs/tasks/debug-application-cluster/debug-cluster.md +++ b/content/zh/docs/tasks/debug-application-cluster/debug-cluster.md @@ -131,7 +131,7 @@ This is an incomplete list of things that could go wrong, and how to adjust your - kubelets will not be able to reach it but will continue to run the same pods and provide the same service proxying - manual recovery or recreation of apiserver state necessary before apiserver is restarted --> -### 具体情况: +### 具体情况 - API 服务器所在的 VM 关机或者 API 服务器崩溃 - 结果 @@ -208,7 +208,7 @@ This is an incomplete list of things that could go wrong, and how to adjust your - Mitigates: API server backing storage (i.e., etcd's data directory) lost - Assumes HA (highly-available) etcd configuration --> -### 缓解措施: +### 缓解措施 - 措施:对于 IaaS 上的 VMs,使用 IaaS 的自动 VM 重启功能 - 缓解:API 服务器 VM 关机或 API 服务器崩溃 From 6ce11bb1f869c63fae768019331baa05a8c75fa0 Mon Sep 17 00:00:00 2001 From: zhiguo-lu Date: Tue, 21 Sep 2021 21:45:01 +0800 Subject: [PATCH 047/115] [zh] translate concepts/Traces For Kubernetes System Components --- .../cluster-administration/system-traces.md | 156 ++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 content/zh/docs/concepts/cluster-administration/system-traces.md diff --git a/content/zh/docs/concepts/cluster-administration/system-traces.md b/content/zh/docs/concepts/cluster-administration/system-traces.md new file mode 100644 index 0000000000000..c829341afd275 --- /dev/null +++ b/content/zh/docs/concepts/cluster-administration/system-traces.md @@ -0,0 +1,156 @@ +--- +title: 追踪 Kubernetes 系统组件 +content_type: concept +weight: 60 +--- + + + + +{{< feature-state for_k8s_version="v1.22" state="alpha" >}} + + +系统组件追踪功能记录各个集群操作的时延信息和这些操作之间的关系。 + + +Kubernetes 组件基于 gRPC 导出器的 +[OpenTelemetry 协议](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/otlp.md#opentelemetry-protocol-specification) +发送追踪信息,并用 +[OpenTelemetry Collector](https://github.com/open-telemetry/opentelemetry-collector#-opentelemetry-collector) +收集追踪信息,再将其转交给追踪系统的后台。 + + + + +## 追踪信息的收集 {#trace-collection} + + +关于收集追踪信息、以及使用收集器的完整指南,可参见 +[Getting Started with the OpenTelemetry Collector](https://opentelemetry.io/docs/collector/getting-started/)。 +不过,还有一些特定于 Kubernetes 组件的事项值得注意。 + + +默认情况下,Kubernetes 组件使用 gRPC 的 OTLP 导出器来导出追踪信息,将信息写到 +[IANA OpenTelemetry 端口](https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?search=opentelemetry)。 +举例来说,如果收集器以 Kubernetes 组件的边车模式运行,以下接收器配置会收集 spans 信息,并将它们写入到标准输出。 + + +```yaml +receivers: + otlp: + protocols: + grpc: +exporters: + # 用适合你后端环境的导出器替换此处的导出器 + logging: + logLevel: debug +service: + pipelines: + traces: + receivers: [otlp] + exporters: [logging] +``` + + +## 组件追踪 {#component-traces} + +### kube-apiserver 追踪 {#kube-apiserver-traces} + + +kube-apiserver 为传入的 HTTP 请求、传出到 webhook 和 etcd 的请求以及重入的请求生成 spans。 +由于 kube-apiserver 通常是一个公开的端点,所以它通过出站的请求传播 +[W3C 追踪上下文](https://www.w3.org/TR/trace-context/), +但不使用入站请求的追踪上下文。 + + +#### 在 kube-apiserver 中启用追踪 {#enabling-tracing-in-the-kube-apiserver} + + +要启用追踪特性,需要启用 kube-apiserver 上的 `APIServerTracing` +[特性门控](/zh/docs/reference/command-line-tools-reference/feature-gates/)。 +然后,使用 `--tracing-config-file=<<配置文件路径>` 为 kube-apiserver 提供追踪配置文件。 +下面是一个示例配置,它为万分之一的请求记录 spans,并使用了默认的 OpenTelemetry 端口。 + +```yaml +apiVersion: apiserver.config.k8s.io/v1alpha1 +kind: TracingConfiguration +# default value +#endpoint: localhost:4317 +samplingRatePerMillion: 100 +``` + + +有关 TracingConfiguration 结构体的更多信息,请参阅 +[API 服务器配置 API (v1alpha1)](/docs/reference/config-api/apiserver-config.v1alpha1/#apiserver-k8s-io-v1alpha1-TracingConfiguration)。 + + +## 稳定性 {#stability} + + +追踪工具仍在积极开发中,未来它会以多种方式发生变化。 +这些变化包括:span 名称、附加属性、检测端点等等。 +此类特性在达到稳定版本之前,不能保证追踪工具的向后兼容性。 + +## {{% heading "whatsnext" %}} + + +* 阅读[Getting Started with the OpenTelemetry Collector](https://opentelemetry.io/docs/collector/getting-started/) \ No newline at end of file From e2448063df1b653aa9f4a061e5a985c2b0e6a24b Mon Sep 17 00:00:00 2001 From: Aaron Crickenberger Date: Fri, 24 Sep 2021 06:42:16 -0700 Subject: [PATCH 048/115] use k8s-staging-test-infra/gcb-docker-gcloud --- cloudbuild.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloudbuild.yaml b/cloudbuild.yaml index 61b5adc5f4c74..5039818482f3d 100644 --- a/cloudbuild.yaml +++ b/cloudbuild.yaml @@ -8,7 +8,7 @@ options: substitution_option: ALLOW_LOOSE steps: # It's fine to bump the tag to a recent version, as needed - - name: "gcr.io/k8s-testimages/gcb-docker-gcloud:v20190906-745fed4" + - name: "gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20210917-12df099d55" entrypoint: make env: - DOCKER_CLI_EXPERIMENTAL=enabled From eb65e4d9f56ed834909bf984c28a158dd789ae03 Mon Sep 17 00:00:00 2001 From: Carlos Panato Date: Sat, 18 Sep 2021 15:31:10 +0200 Subject: [PATCH 049/115] patches: update releases for October cycle Signed-off-by: Carlos Panato --- content/en/releases/patch-releases.md | 5 ++++- data/releases/schedule.yaml | 27 ++++++++++++++++++--------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/content/en/releases/patch-releases.md b/content/en/releases/patch-releases.md index c7597e332fcd4..91bd47bcd0d71 100644 --- a/content/en/releases/patch-releases.md +++ b/content/en/releases/patch-releases.md @@ -78,10 +78,10 @@ releases may also occur in between these. | Monthly Patch Release | Cherry Pick Deadline | Target date | | --------------------- | -------------------- | ----------- | -| September 2021 | 2021-09-10 | 2021-09-15 | | October 2021 | 2021-10-15 | 2021-10-20 | | November 2021 | 2021-11-12 | 2021-11-17 | | December 2021 | 2021-12-10 | 2021-12-15 | +| January 2022 | 2021-01-14 | 2021-01-19 | ## Detailed Release History for Active Branches @@ -93,6 +93,7 @@ End of Life for **1.22** is **2022-10-28** | PATCH RELEASE | CHERRY PICK DEADLINE | TARGET DATE | NOTE | |---------------|----------------------|-------------|------| +| 1.22.3 | 2021-10-15 | 2021-10-20 | | | 1.22.2 | 2021-09-10 | 2021-09-15 | | | 1.22.1 | 2021-08-16 | 2021-08-19 | | @@ -104,6 +105,7 @@ End of Life for **1.21** is **2022-06-28** | PATCH RELEASE | CHERRY PICK DEADLINE | TARGET DATE | NOTE | | ------------- | -------------------- | ----------- | ---------------------------------------------------------------------- | +| 1.21.6 | 2021-10-15 | 2021-10-20 | | | 1.21.5 | 2021-09-10 | 2021-09-15 | | | 1.21.4 | 2021-08-07 | 2021-08-11 | | | 1.21.3 | 2021-07-10 | 2021-07-14 | | @@ -118,6 +120,7 @@ End of Life for **1.20** is **2022-02-28** | PATCH RELEASE | CHERRY PICK DEADLINE | TARGET DATE | NOTE | | ------------- | -------------------- | ----------- | ----------------------------------------------------------------------------------- | +| 1.20.12 | 2021-10-15 | 2021-10-20 | | | 1.20.11 | 2021-09-10 | 2021-09-15 | | | 1.20.10 | 2021-08-07 | 2021-08-11 | | | 1.20.9 | 2021-07-10 | 2021-07-14 | | diff --git a/data/releases/schedule.yaml b/data/releases/schedule.yaml index 99abec370ed64..55d5b12633b11 100644 --- a/data/releases/schedule.yaml +++ b/data/releases/schedule.yaml @@ -1,19 +1,25 @@ schedules: - release: 1.22 - next: 1.22.2 - cherryPickDeadline: 2021-09-10 - targetDate: 2021-09-15 + next: 1.22.3 + cherryPickDeadline: 2021-10-15 + targetDate: 2021-10-20 endOfLifeDate: 2022-10-28 previousPatches: + - release: 1.22.2 + cherryPickDeadline: 2021-09-10 + targetDate: 2021-09-15 - release: 1.22.1 cherryPickDeadline: 2021-08-16 targetDate: 2021-08-19 - release: 1.21 - next: 1.21.5 - cherryPickDeadline: 2021-09-10 - targetDate: 2021-09-15 + next: 1.21.6 + cherryPickDeadline: 2021-10-15 + targetDate: 2021-10-20 endOfLifeDate: 2022-06-28 previousPatches: + - release: 1.21.5 + cherryPickDeadline: 2021-09-10 + targetDate: 2021-09-15 - release: 1.21.4 cherryPickDeadline: 2021-08-07 targetDate: 2021-08-11 @@ -28,11 +34,14 @@ schedules: targetDate: 2021-05-12 note: Regression https://groups.google.com/g/kubernetes-dev/c/KuF8s2zueFs - release: 1.20 - next: 1.20.11 - cherryPickDeadline: 2021-09-10 - targetDate: 2021-09-15 + next: 1.20.12 + cherryPickDeadline: 2021-10-15 + targetDate: 2021-10-20 endOfLifeDate: 2022-02-28 previousPatches: + - release: 1.20.11 + cherryPickDeadline: 2021-09-10 + targetDate: 2021-09-15 - release: 1.20.10 cherryPickDeadline: 2021-08-07 targetDate: 2021-08-11 From 391148fcd5180d624588a858716ec36b54300ab5 Mon Sep 17 00:00:00 2001 From: Pushkar Joglekar <3390906+PushkarJ@users.noreply.github.com> Date: Fri, 24 Sep 2021 15:02:56 -0700 Subject: [PATCH 050/115] Update content/en/releases/release-managers.md Co-authored-by: Bob Killen --- content/en/releases/release-managers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/releases/release-managers.md b/content/en/releases/release-managers.md index e8b75492bcd24..a25619c8c928d 100644 --- a/content/en/releases/release-managers.md +++ b/content/en/releases/release-managers.md @@ -31,7 +31,7 @@ The responsibilities of each role are described below. ### Security Embargo Policy -Some information about releases is subject to embargo and we have defined policy about how those embargoes are set. Please refer to the [Security Embargo Policy](https://github.com/kubernetes/committee-security-response/blob/master/private-distributors-list.md#embargo-policy) for more information. +Some information about releases is subject to embargo and we have defined policy about how those embargoes are set. Please refer to the [Security Embargo Policy](https://github.com/kubernetes/committee-security-response/blob/main/private-distributors-list.md#embargo-policy) for more information. ## Handbooks From 780dae2785d7553cf43a3d95c41f35dd1f8a6491 Mon Sep 17 00:00:00 2001 From: Richard Tweed Date: Sat, 25 Sep 2021 00:02:21 +0100 Subject: [PATCH 051/115] Clarified scenarios that could lead to privilege escalation (#29378) * Clarified scenarios that could lead to privilege escalation Made it clearer that it's not just creating pods which enables the privilege escalation. It's all workloads, all reconfiguration of workloads, and conceptually the creation and reconfiguration of custom resources which create workloads. * Allowing link to priv escalation heading if required * Update content/en/docs/reference/access-authn-authz/authorization.md Co-authored-by: Tim Bannister * Adding further clarifications * Retitled escalation section * Apply suggestions from vjftw Co-authored-by: VJ Patel * Clarified CRDs and reduced duplication * Updating caution based on Geoffrey's comments * Updating controller comment and linking out to reference docs Co-authored-by: Tim Bannister Co-authored-by: VJ Patel --- .../access-authn-authz/authorization.md | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/content/en/docs/reference/access-authn-authz/authorization.md b/content/en/docs/reference/access-authn-authz/authorization.md index af73a23350601..0292ad8130489 100644 --- a/content/en/docs/reference/access-authn-authz/authorization.md +++ b/content/en/docs/reference/access-authn-authz/authorization.md @@ -192,22 +192,33 @@ The following flags can be used: You can choose more than one authorization module. Modules are checked in order so an earlier module has higher priority to allow or deny a request. -## Privilege escalation via pod creation +## Privilege escalation via workload creation or edits {#privilege-escalation-via-pod-creation} -Users who have the ability to create pods in a namespace can potentially -escalate their privileges within that namespace. They can create pods that -access their privileges within that namespace. They can create pods that access -secrets the user cannot themselves read, or that run under a service account -with different/greater permissions. +Users who can create/edit pods in a namespace, either directly or through a [controller](/docs/concepts/architecture/controller/) +such as an operator, could escalate their privileges in that namespace. {{< caution >}} -System administrators, use care when granting access to pod creation. A user -granted permission to create pods (or controllers that create pods) in the -namespace can: read all secrets in the namespace; read all config maps in the -namespace; and impersonate any service account in the namespace and take any -action the account could take. This applies regardless of authorization mode. +System administrators, use care when granting access to create or edit workloads. +Details of how these can be misused are documented in [escalation paths](/docs/reference/access-authn-authz/authorization/#escalation-paths) {{< /caution >}} +### Escalation paths {#escalation-paths} +- Mounting arbitrary secrets in that namespace + - Can be used to access secrets meant for other workloads + - Can be used to obtain a more privileged service account's service account token +- Using arbitrary Service Accounts in that namespace + - Can perform Kubernetes API actions as another workload (impersonation) + - Can perform any privileged actions that Service Account has +- Mounting configmaps meant for other workloads in that namespace + - Can be used to obtain information meant for other workloads, such as DB host names. +- Mounting volumes meant for other workloads in that namespace + - Can be used to obtain information meant for other workloads, and change it. + +{{< caution >}} +System administrators should be cautious when deploying CRDs that +change the above areas. These may open privilege escalations paths. +This should be considered when deciding on your RBAC controls. +{{< /caution >}} ## {{% heading "whatsnext" %}} From 9bcd6a35793fca04e10e200d0b46370b38aa4eea Mon Sep 17 00:00:00 2001 From: Arhell Date: Sat, 25 Sep 2021 04:41:55 +0300 Subject: [PATCH 052/115] [it] Add seccomp tutorial to index --- content/it/docs/tutorials/_index.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/content/it/docs/tutorials/_index.md b/content/it/docs/tutorials/_index.md index 04069ff5eb31c..240fce078ce2e 100644 --- a/content/it/docs/tutorials/_index.md +++ b/content/it/docs/tutorials/_index.md @@ -50,6 +50,8 @@ Prima di procedere con vari tutorial, raccomandiamo di aggiungere il * [AppArmor](/docs/tutorials/clusters/apparmor/) +* [seccomp](/docs/tutorials/clusters/seccomp/) + ## Servizi * [Utilizzare Source IP](/docs/tutorials/services/source-ip/) From 461a0b4a6d3d4ec9ddcab8039928934c067e2d56 Mon Sep 17 00:00:00 2001 From: Anubhav Vardhan Date: Sat, 25 Sep 2021 15:29:46 +0530 Subject: [PATCH 053/115] Update OWNERS_ALIASES --- OWNERS_ALIASES | 1 + 1 file changed, 1 insertion(+) diff --git a/OWNERS_ALIASES b/OWNERS_ALIASES index ce45f0e7871c8..7764d5c04e530 100644 --- a/OWNERS_ALIASES +++ b/OWNERS_ALIASES @@ -79,6 +79,7 @@ aliases: - anubha-v-ardhan - divya-mohan0209 - mittalyashu + - verma-kunal sig-docs-id-owners: # Admins for Indonesian content - ariscahyadi - danninov From 24f5f7251bc69bdc34407fa00520f0e73d4314c6 Mon Sep 17 00:00:00 2001 From: Bigsmooth68 <57505439+Bigsmooth68@users.noreply.github.com> Date: Sat, 25 Sep 2021 16:19:54 +0200 Subject: [PATCH 054/115] Update nodes.md and => et --- content/fr/docs/concepts/architecture/nodes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/fr/docs/concepts/architecture/nodes.md b/content/fr/docs/concepts/architecture/nodes.md index b6718c6750ddd..f493fe5b17277 100644 --- a/content/fr/docs/concepts/architecture/nodes.md +++ b/content/fr/docs/concepts/architecture/nodes.md @@ -12,7 +12,7 @@ weight: 10 Un nœud est une machine de travail dans Kubernetes, connue auparavant sous le nom de `minion`. Un nœud peut être une machine virtuelle ou une machine physique, selon le cluster. Chaque nœud contient les services nécessaires à l'exécution de [pods](/docs/concepts/workloads/pods/pod/) et est géré par les composants du master. -Les services sur un nœud incluent le [container runtime](/docs/concepts/overview/components/#node-components), kubelet and kube-proxy. +Les services sur un nœud incluent le [container runtime](/docs/concepts/overview/components/#node-components), kubelet et kube-proxy. Consultez la section [Le Nœud Kubernetes](https://git.k8s.io/community/contributors/design-proposals/architecture/architecture.md#the-kubernetes-node) dans le document de conception de l'architecture pour plus de détails. From bd59a5fc2011edc9499f52d1e2ad579328bb057f Mon Sep 17 00:00:00 2001 From: Robert Martin Date: Sat, 25 Sep 2021 20:02:10 -0500 Subject: [PATCH 055/115] Update hello-minikube.md Fix minor typos --- content/en/docs/tutorials/hello-minikube.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/en/docs/tutorials/hello-minikube.md b/content/en/docs/tutorials/hello-minikube.md index 3911ff2de6c92..e6398d7c72486 100644 --- a/content/en/docs/tutorials/hello-minikube.md +++ b/content/en/docs/tutorials/hello-minikube.md @@ -69,13 +69,13 @@ By default, the dashboard is only accessible from within the internal Kubernetes The `dashboard` command creates a temporary proxy to make the dashboard accessible from outside the Kubernetes virtual network. To stop the proxy, run `Ctrl+C` to exit the process. -After the command exits, the dashboard remains running in Kubernetes cluster. +After the command exits, the dashboard remains running in the Kubernetes cluster. You can run the `dashboard` command again to create another proxy to access the dashboard. {{< /note >}} ## Open Dashboard with URL -If you don't want to open a web browser, run the dashboard command with the url flag to emit a URL: +If you don't want to open a web browser, run the dashboard command with the `--url` flag to emit a URL: ```shell minikube dashboard --url @@ -185,7 +185,7 @@ Kubernetes [*Service*](/docs/concepts/services-networking/service/). 4. Katacoda environment only: Click the plus sign, and then click **Select port to view on Host 1**. -5. Katacoda environment only: Note the 5 digit port number displayed opposite to `8080` in services output. This port number is randomly generated and it can be different for you. Type your number in the port number text box, then click Display Port. Using the example from earlier, you would type `30369`. +5. Katacoda environment only: Note the 5-digit port number displayed opposite to `8080` in services output. This port number is randomly generated and it can be different for you. Type your number in the port number text box, then click Display Port. Using the example from earlier, you would type `30369`. This opens up a browser window that serves your app and shows the app's response. From ea36ff4621bb5081b6abfb403f3384a839e648f6 Mon Sep 17 00:00:00 2001 From: Steven Yan Date: Fri, 24 Sep 2021 14:19:59 +0800 Subject: [PATCH 056/115] [zh] translation for admin 1 --- .../enabling-service-topology.md | 59 +++++++++------- .../administer-cluster/kubelet-config-file.md | 70 ++++++++----------- ...k-if-dockershim-deprecation-affects-you.md | 6 +- .../administer-cluster/safely-drain-node.md | 39 ++++++++++- 4 files changed, 104 insertions(+), 70 deletions(-) diff --git a/content/zh/docs/tasks/administer-cluster/enabling-service-topology.md b/content/zh/docs/tasks/administer-cluster/enabling-service-topology.md index d97171de3ea12..1307065c5a234 100644 --- a/content/zh/docs/tasks/administer-cluster/enabling-service-topology.md +++ b/content/zh/docs/tasks/administer-cluster/enabling-service-topology.md @@ -1,76 +1,83 @@ --- title: 开启服务拓扑 content_type: task +min-kubernetes-server-version: 1.17 --- +{{< feature-state for_k8s_version="v1.21" state="deprecated" >}} -本页面提供了在 Kubernetes 中启用服务拓扑的概述。 +这项功能,特别是 Alpha 状态的 `topologyKeys` 字段,在 kubernetes v1.21 中已经弃用。 +在 kubernetes v1.21 加入的[拓扑感知提示](/zh/docs/concepts/services-networking/topology-aware-hints/) +提供了类似的功能。 ## {{% heading "prerequisites" %}} {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} - - -## 介绍 -_服务拓扑(Service Topology)_ 使服务能够根据集群中的 Node 拓扑来路由流量。 +_服务拓扑(Service Topology)_ 使 {{< glossary_tooltip term_id="service" text="服务">}} +能够根据集群中的 Node 拓扑来路由流量。 比如,服务可以指定将流量优先路由到与客户端位于同一节点或者同一可用区域的端点上。 - -## 先决条件 - 需要下面列的先决条件,才能启用拓扑感知的服务路由: * Kubernetes 1.17 或更新版本 - * {{< glossary_tooltip text="Kube-proxy" term_id="kube-proxy" >}} 以 iptables 或者 IPVS 模式运行 - * 启用[端点切片](/zh/docs/concepts/services-networking/endpoint-slices/) + * 配置 {{< glossary_tooltip text="kube-proxy" term_id="kube-proxy" >}} 以 iptables 或者 IPVS 模式运行 + ## 启用服务拓扑 -{{< feature-state for_k8s_version="v1.17" state="alpha" >}} +{{< feature-state for_k8s_version="v1.21" state="deprecated" >}} -要启用服务拓扑功能,需要为所有 Kubernetes 组件启用 `ServiceTopology` 和 `EndpointSlice` 特性门控: +要启用服务拓扑功能,需要为所有 Kubernetes 组件启用 `ServiceTopology` +[特性门控](/zh/docs/reference/command-line-tools-reference/feature-gates/): ``` ---feature-gates="ServiceTopology=true,EndpointSlice=true" +--feature-gates="ServiceTopology=true` ``` ## {{% heading "whatsnext" %}} -* 阅读[服务拓扑](/zh/docs/concepts/services-networking/service-topology)概念 + +* 阅读[拓扑感知提示](/zh/docs/concepts/services-networking/topology-aware-hints/),该技术是用来替换 `topologyKeys` 字段的。 * 阅读[端点切片](/zh/docs/concepts/services-networking/endpoint-slices) +* 阅读[服务拓扑](/zh/docs/concepts/services-networking/service-topology)概念 * 阅读[通过服务来连接应用](/zh/docs/concepts/services-networking/connect-applications-service/) \ No newline at end of file diff --git a/content/zh/docs/tasks/administer-cluster/kubelet-config-file.md b/content/zh/docs/tasks/administer-cluster/kubelet-config-file.md index e41eb9e3d95e5..3f8ee37eb7c52 100644 --- a/content/zh/docs/tasks/administer-cluster/kubelet-config-file.md +++ b/content/zh/docs/tasks/administer-cluster/kubelet-config-file.md @@ -12,15 +12,11 @@ content_type: task -{{< feature-state for_k8s_version="v1.10" state="beta" >}} - 通过保存在硬盘的配置文件设置 kubelet 的部分配置参数,这可以作为命令行参数的替代。 -此功能在 v1.10 中为 beta 版。 建议通过配置文件的方式提供参数,因为这样可以简化节点部署和配置管理。 -## {{% heading "prerequisites" %}} - - -- 需要安装 1.10 或更高版本的 kubelet 可执行文件,才能使用此 beta 功能。 - ## 创建配置文件 -`KubeletConfiguration` 结构体定义了可以通过文件配置的 Kubelet 配置子集, -该结构体在 [这里(v1beta1)](https://github.com/kubernetes/kubernetes/blob/{{< param "docsbranch" >}}/staging/src/k8s.io/kubelet/config/v1beta1/types.go) -可以找到。 +[`KubeletConfiguration`](/zh/docs/reference/config-api/kubelet-config.v1beta1/) 结构体定义了可以通过文件配置的 Kubelet 配置子集, -在这个示例中, 当可用内存低于 200Mi 时, kubelet 将会开始驱逐 Pods。 +在这个示例中, Kubelet 被设置为在地址 192.168.0.8 端口 20250 上提供服务,以并行方式拖拽镜像, +当可用内存低于 200Mi 时, kubelet 将会开始驱逐 Pods。 没有声明的其余配置项都将使用默认值,除非使用命令行参数来重载。 命令行中的参数将会覆盖配置文件中的对应值。 -作为一个小技巧,你可以从活动节点生成配置文件,相关方法请查看 -[重新配置活动集群节点的 kubelet](/zh/docs/tasks/administer-cluster/reconfigure-kubelet)。 - ## 启动通过配置文件配置的 Kubelet 进程 +{{< note >}} +如果你使用 kubeadm 初始化你的集群,在使用 `kubeadmin init` 创建你的集群的时候请使用 kubelet-config。 +更多细节请阅读[使用 kubeadm 配置 kubelet](/zh/docs/setup/production-environment/tools/kubeadm/kubelet-integration/) +{{< /note >}} + 启动 Kubelet 需要将 `--config` 参数设置为 Kubelet 配置文件的路径。Kubelet 将从此文件加载其配置。 - -## 与动态 Kubelet 配置的关系 - -如果你正在使用[动态 kubelet 配置](/zh/docs/tasks/administer-cluster/reconfigure-kubelet)特性, -那么自动回滚机制将认为通过 `--config` 提供的配置与覆盖这些值的任何参数的组合是 - "最后已知正常(last known good)" 的配置。 - - +- 参阅 [`KubeletConfiguration`](/zh/docs/reference/config-api/kubelet-config.v1beta1/) + 进一步学习 kubelet 的配置。 diff --git a/content/zh/docs/tasks/administer-cluster/migrating-from-dockershim/check-if-dockershim-deprecation-affects-you.md b/content/zh/docs/tasks/administer-cluster/migrating-from-dockershim/check-if-dockershim-deprecation-affects-you.md index e3d8d89d9463b..c1cf73c96e809 100644 --- a/content/zh/docs/tasks/administer-cluster/migrating-from-dockershim/check-if-dockershim-deprecation-affects-you.md +++ b/content/zh/docs/tasks/administer-cluster/migrating-from-dockershim/check-if-dockershim-deprecation-affects-you.md @@ -99,14 +99,14 @@ Kubernetes 负责编排和调度 Pod;在每一个节点上, 使用抽象的容器运行时接口,所以你可以任意选用兼容的容器运行时。 -在早期版本中,Kubernetes 提供的兼容性只支持一个容器运行时:Docker。 +在早期版本中,Kubernetes 提供的兼容性支持一个容器运行时:Docker。 在 Kubernetes 发展历史中,集群运营人员希望采用更多的容器运行时。 于是 CRI 被设计出来满足这类灵活性需要 - 而 kubelet 亦开始支持 CRI。 然而,因为 Docker 在 CRI 规范创建之前就已经存在,Kubernetes 就创建了一个适配器组件:`dockershim`。 @@ -144,7 +144,7 @@ or execute something inside container using `docker exec`. {{< note >}} diff --git a/content/zh/docs/tasks/administer-cluster/safely-drain-node.md b/content/zh/docs/tasks/administer-cluster/safely-drain-node.md index 85de0215ca63e..c07c282b7850a 100644 --- a/content/zh/docs/tasks/administer-cluster/safely-drain-node.md +++ b/content/zh/docs/tasks/administer-cluster/safely-drain-node.md @@ -196,6 +196,39 @@ itself. To attempt an eviction (perhaps more REST-precisely, to attempt to Pod 的 Eviction 子资源可以看作是一种策略控制的 DELETE 操作,作用于 Pod 本身。 要尝试驱逐(更准确地说,尝试 *创建* 一个 Eviction),需要用 POST 发出所尝试的操作。这里有一个例子: +{{< tabs name="Eviction_example" >}} +{{% tab name="policy/v1" %}} + +{{< note >}} +`policy/v1` 驱逐在 v1.22+ 中可用。在之前版本中请使用 `policy/v1beta1` 。 +{{< /note >}} + + +```json +{ + "apiVersion": "policy/v1", + "kind": "Eviction", + "metadata": { + "name": "quux", + "namespace": "default" + } +} +``` +{{% /tab %}} +{{% tab name="policy/v1beta1" %}} + +{{< note >}} +在 v1.22 中已弃用,以 `policy/v1` 取代 +{{< /note >}} + ```json { "apiVersion": "policy/v1beta1", @@ -206,6 +239,8 @@ Pod 的 Eviction 子资源可以看作是一种策略控制的 DELETE 操作, } } ``` +{{% /tab %}} +{{< /tabs >}} 你首先需要有一个支持网络策略的 Kubernetes 集群。已经有许多支持 NetworkPolicy 的网络提供商,包括: +* [Antrea](/zh/docs/tasks/administer-cluster/network-policy-provider/antrea-network-policy/) * [Calico](/zh/docs/tasks/administer-cluster/network-policy-provider/calico-network-policy/) * [Cilium](/zh/docs/tasks/administer-cluster/network-policy-provider/cilium-network-policy/) * [Kube-router](/zh/docs/tasks/administer-cluster/network-policy-provider/kube-router-network-policy/) diff --git a/content/zh/docs/tasks/administer-cluster/extended-resource-node.md b/content/zh/docs/tasks/administer-cluster/extended-resource-node.md index 9eeb4e09bc6e3..5c1d54b590e33 100644 --- a/content/zh/docs/tasks/administer-cluster/extended-resource-node.md +++ b/content/zh/docs/tasks/administer-cluster/extended-resource-node.md @@ -67,13 +67,13 @@ Host: k8s-master:8080 注意:Kubernetes 不需要了解 dongle 资源的含义和用途。 -前面的 PATCH 请求仅仅告诉 Kubernetes 你的节点拥有四个你称之为 dongle 的东西。 +前面的 PATCH 请求告诉 Kubernetes 你的节点拥有四个你称之为 dongle 的东西。 启动一个代理(proxy),以便你可以很容易地向 Kubernetes API server 发送请求: diff --git a/content/zh/docs/tasks/administer-cluster/namespaces-walkthrough.md b/content/zh/docs/tasks/administer-cluster/namespaces-walkthrough.md index 7fbf132dcf840..39f3f017187cf 100644 --- a/content/zh/docs/tasks/administer-cluster/namespaces-walkthrough.md +++ b/content/zh/docs/tasks/administer-cluster/namespaces-walkthrough.md @@ -345,9 +345,9 @@ Apply the manifest to create a Deployment 应用清单文件来创建 Deployment。 -我们刚刚创建了一个副本大小为 2 的 Deployment,该 Deployment 运行名为 `snowflake` 的 Pod, +我们创建了一个副本大小为 2 的 Deployment,该 Deployment 运行名为 `snowflake` 的 Pod, 其中包含一个仅提供主机名服务的基本容器。 ```shell diff --git a/content/zh/docs/tasks/administer-cluster/network-policy-provider/antrea-network-policy.md b/content/zh/docs/tasks/administer-cluster/network-policy-provider/antrea-network-policy.md new file mode 100644 index 0000000000000..d8dbecfcce4c0 --- /dev/null +++ b/content/zh/docs/tasks/administer-cluster/network-policy-provider/antrea-network-policy.md @@ -0,0 +1,49 @@ + +--- +title: 使用 Antrea 提供 NetworkPolicy +content_type: task +weight: 10 +--- + + + +本页展示了如何在 kubernetes 中安装和使用 Antrea CNI 插件。 +要了解 Antrea 项目的背景,请阅读 [Antrea 介绍](https://antrea.io/docs/)。 + +## {{% heading "prerequisites" %}} + + +你需要拥有一个 kuernetes 集群。 +遵循 [kubeadm 入门指南](/zh/docs/reference/setup-tools/kubeadm/)自行创建一个。 + + + + +## 使用 kubeadm 部署 Antrea +遵循[入门](https://github.com/vmware-tanzu/antrea/blob/main/docs/getting-started.md)指南 +为 kubeadm 部署 Antrea 。 + +## {{% heading "whatsnext" %}} + + +一旦你的集群已经运行,你可以遵循 +[声明网络策略](/zh/docs/tasks/administer-cluster/declare-network-policy/) +来尝试 Kubernetes NetworkPolicy。 \ No newline at end of file diff --git a/content/zh/docs/tasks/administer-cluster/network-policy-provider/calico-network-policy.md b/content/zh/docs/tasks/administer-cluster/network-policy-provider/calico-network-policy.md index 2b5e260c5cd92..9c0dee6fbbc49 100644 --- a/content/zh/docs/tasks/administer-cluster/network-policy-provider/calico-network-policy.md +++ b/content/zh/docs/tasks/administer-cluster/network-policy-provider/calico-network-policy.md @@ -29,9 +29,9 @@ Decide whether you want to deploy a [cloud](#creating-a-calico-cluster-with-goog **先决条件**: [gcloud](https://cloud.google.com/sdk/docs/quickstarts) -1. 启动一个带有 Calico 的 GKE 集群,只需加上参数 `--enable-network-policy`。 +1. 启动一个带有 Calico 的 GKE 集群,需要加上参数 `--enable-network-policy`。 **语法** ```shell diff --git a/content/zh/docs/tasks/administer-cluster/network-policy-provider/cilium-network-policy.md b/content/zh/docs/tasks/administer-cluster/network-policy-provider/cilium-network-policy.md index d75203b71ee25..697e10275399a 100644 --- a/content/zh/docs/tasks/administer-cluster/network-policy-provider/cilium-network-policy.md +++ b/content/zh/docs/tasks/administer-cluster/network-policy-provider/cilium-network-policy.md @@ -33,25 +33,25 @@ For background on Cilium, read the [Introduction to Cilium](https://docs.cilium. ## Deploying Cilium on Minikube for Basic Testing To get familiar with Cilium easily you can follow the -[Cilium Kubernetes Getting Started Guide](https://docs.cilium.io/en/stable/gettingstarted/minikube/) +[Cilium Kubernetes Getting Started Guide](https://docs.cilium.io/en/stable/gettingstarted/k8s-install-default/) to perform a basic DaemonSet installation of Cilium in minikube. -To start minikube, minimal version required is >= v1.3.1, run the with the +To start minikube, minimal version required is >= v1.5.2, run the with the following arguments: --> ## 在 Minikube 上部署 Cilium 用于基本测试 为了轻松熟悉 Cilium 你可以根据 -[Cilium Kubernetes 入门指南](https://docs.cilium.io/en/stable/gettingstarted/minikube/) +[Cilium Kubernetes 入门指南](https://docs.cilium.io/en/stable/gettingstarted/k8s-install-default/s) 在 minikube 中执行一个 cilium 的基本 DaemonSet 安装。 -要启动 minikube,需要的最低版本为 1.3.1,使用下面的参数运行: +要启动 minikube,需要的最低版本为 1.5.2,使用下面的参数运行: ```shell minikube version ``` ``` -minikube version: v1.3.1 +minikube version: v1.5.2 ``` ```shell @@ -59,36 +59,45 @@ minikube start --network-plugin=cni --memory=4096 ``` -挂载 BPF 文件系统: +对于 minikube 你可以使用 Cilium 的 CLI 工具安装它。 +Cilium 将自动检测集群配置并为成功的集群部署选择合适的组件。 ```shell -minikube ssh -- sudo mount bpffs -t bpf /sys/fs/bpf +curl -LO https://github.com/cilium/cilium-cli/releases/latest/download/cilium-linux-amd64.tar.gz +sudo tar xzvfC cilium-linux-amd64.tar.gz /usr/local/bin +rm cilium-linux-amd64.tar.gz +cilium install ``` - - -在 minikube 环境中,你可以部署下面的"一体化" YAML 文件,其中包含 Cilium -的 DaemonSet 配置以及适当的 RBAC 配置: - - -```shell -kubectl create -f https://raw.githubusercontent.com/cilium/cilium/v1.8/install/kubernetes/quick-install.yaml -``` - ``` -configmap/cilium-config created -serviceaccount/cilium created -serviceaccount/cilium-operator created -clusterrole.rbac.authorization.k8s.io/cilium created -clusterrole.rbac.authorization.k8s.io/cilium-operator created -clusterrolebinding.rbac.authorization.k8s.io/cilium created -clusterrolebinding.rbac.authorization.k8s.io/cilium-operator created -daemonset.apps/cilium create -deployment.apps/cilium-operator created +🔮 Auto-detected Kubernetes kind: minikube +✨ Running "minikube" validation checks +✅ Detected minikube version "1.20.0" +ℹ️ Cilium version not set, using default version "v1.10.0" +🔮 Auto-detected cluster name: minikube +🔮 Auto-detected IPAM mode: cluster-pool +🔮 Auto-detected datapath mode: tunnel +🔑 Generating CA... +2021/05/27 02:54:44 [INFO] generate received request +2021/05/27 02:54:44 [INFO] received CSR +2021/05/27 02:54:44 [INFO] generating key: ecdsa-256 +2021/05/27 02:54:44 [INFO] encoded CSR +2021/05/27 02:54:44 [INFO] signed certificate with serial number 48713764918856674401136471229482703021230538642 +🔑 Generating certificates for Hubble... +2021/05/27 02:54:44 [INFO] generate received request +2021/05/27 02:54:44 [INFO] received CSR +2021/05/27 02:54:44 [INFO] generating key: ecdsa-256 +2021/05/27 02:54:44 [INFO] encoded CSR +2021/05/27 02:54:44 [INFO] signed certificate with serial number 3514109734025784310086389188421560613333279574 +🚀 Creating Service accounts... +🚀 Creating Cluster roles... +🚀 Creating ConfigMap... +🚀 Creating Agent DaemonSet... +🚀 Creating Operator Deployment... +⌛ Waiting for Cilium to be installed... ``` 你将看到像这样的 Pods 列表: ```console -NAME READY STATUS RESTARTS AGE -cilium-6rxbd 1/1 Running 0 1m +NAME READY STATUS RESTARTS AGE +cilium-kkdhz 1/1 Running 0 3m23s ... ``` diff --git a/content/zh/docs/tasks/administer-cluster/reserve-compute-resources.md b/content/zh/docs/tasks/administer-cluster/reserve-compute-resources.md index f03e2bde3087d..e0b2d8a6e8c30 100644 --- a/content/zh/docs/tasks/administer-cluster/reserve-compute-resources.md +++ b/content/zh/docs/tasks/administer-cluster/reserve-compute-resources.md @@ -26,7 +26,7 @@ itself. Unless resources are set aside for these system daemons, pods and system daemons compete for resources and lead to resource starvation issues on the node. -The `kubelet` exposes a feature named `Node Allocatable` that helps to reserve +The `kubelet` exposes a feature named 'Node Allocatable' that helps to reserve compute resources for system daemons. Kubernetes recommends cluster administrators to configure `Node Allocatable` based on their workload density on each node. @@ -35,12 +35,11 @@ Kubernetes 的节点可以按照 `Capacity` 调度。默认情况下 pod 能够 这是个问题,因为节点自己通常运行了不少驱动 OS 和 Kubernetes 的系统守护进程。 除非为这些系统守护进程留出资源,否则它们将与 pod 争夺资源并导致节点资源短缺问题。 -`kubelet` 公开了一个名为 `Node Allocatable` 的特性,有助于为系统守护进程预留计算资源。 +`kubelet` 公开了一个名为 'Node Allocatable' 的特性,有助于为系统守护进程预留计算资源。 Kubernetes 推荐集群管理员按照每个节点上的工作负载密度配置 `Node Allocatable`。 ## {{% heading "prerequisites" %}} - {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} 要想为系统守护进程上可选地实施 `system-reserved` 约束,请指定 kubelet 的 `--system-reserved-cgroup` 标志值为 OS 系统守护进程的父级控制组。 @@ -234,19 +232,19 @@ exist. Kubelet will fail if an invalid cgroup is specified. 推荐将 OS 系统守护进程放在一个顶级控制组之下(例如 systemd 机器上的 `system.slice`)。 -请注意,如果 `--system-reserved-cgroup` 不存在,Kubelet **不会** 创建它。 -如果指定了无效的 cgroup,Kubelet 将会失败。 +请注意,如果 `--system-reserved-cgroup` 不存在,`kubelet` **不会** 创建它。 +如果指定了无效的 cgroup,`kubelet` 将会失败。 ### 显式保留的 CPU 列表 {#explicitly-reserved-cpu-list} {{< feature-state for_k8s_version="v1.17" state="stable" >}} -- **Kubelet 标志**: `--reserved-cpus=0-3` +-**Kubelet 标志**: `--reserved-cpus=0-3` ### 实施节点可分配约束 {#enforcing-node-allocatable} -- **Kubelet 标志**: `--enforce-node-allocatable=pods[,][system-reserved][,][kube-reserved]` +-**Kubelet 标志**: `--enforce-node-allocatable=pods[,][system-reserved][,][kube-reserved]` -调度器将 `Allocatable` 视为 Pod 可用的 `capacity`(资源容量)。 +调度器将 'Allocatable' 视为 Pod 可用的 `capacity`(资源容量)。 -`kubelet` 默认对 Pod 执行 `Allocatable` 约束。 -无论何时,如果所有 Pod 的总用量超过了 `Allocatable`,驱逐 Pod 的措施将被执行。 +`kubelet` 默认对 Pod 执行 'Allocatable' 约束。 +无论何时,如果所有 Pod 的总用量超过了 'Allocatable',驱逐 Pod 的措施将被执行。 有关驱逐策略的更多细节可以在 -[这里](/zh/docs/tasks/administer-cluster/out-of-resource/#eviction-policy)找到。 +[节点压力驱逐](/zh/docs/concepts/scheduling-eviction/node-pressure-eviction/)页找到。 可通过设置 kubelet `--enforce-node-allocatable` 标志值为 `pods` 控制这个措施。 可选地,通过在同一标志中同时指定 `kube-reserved` 和 `system-reserved` 值, @@ -351,7 +351,7 @@ respectively. ## 一般原则 {#general-guidelines} -系统守护进程一般会被按照类似 `Guaranteed` Pod 一样对待。 +系统守护进程一般会被按照类似 'Guaranteed' Pod 一样对待。 系统守护进程可以在与其对应的控制组中出现突发资源用量,这一行为要作为 kubernetes 部署的一部分进行管理。 例如,`kubelet` 应该有它自己的控制组并和容器运行时共享 `Kube-reserved` 资源。 @@ -373,9 +373,9 @@ to critical system services being CPU starved, OOM killed, or unable to fork on the node. The recommendation is to enforce `system-reserved` only if a user has profiled their nodes exhaustively to come up with precise estimates and is confident in their -ability to recover if any process in that group is oom_killed. +ability to recover if any process in that group is oom-killed. -* To begin with enforce `Allocatable` on `pods`. +* To begin with enforce 'Allocatable' on `pods`. * Once adequate monitoring and alerting is in place to track kube system daemons, attempt to enforce `kube-reserved` based on usage heuristics. * If absolutely necessary, enforce `system-reserved` over time. @@ -386,7 +386,7 @@ ability to recover if any process in that group is oom_killed. 并且对该组中进程因内存不足而被杀死时,有足够的信心将其恢复时, 才可以强制执行 `system-reserved` 策略。 -* 作为起步,可以先针对 `pods` 上执行 `Allocatable` 约束。 +* 作为起步,可以先针对 `pods` 上执行 'Allocatable' 约束。 * 一旦用于追踪系统守护进程的监控和告警的机制到位,可尝试基于用量估计的 方式执行 `kube-reserved`策略。 * 随着时间推进,在绝对必要的时候可以执行 `system-reserved` 策略。 @@ -424,27 +424,27 @@ Here is an example to illustrate Node Allocatable computation: * `--eviction-hard` 被设置为 `memory.available<500Mi,nodefs.available<10%` -在这个场景下,`Allocatable` 将会是 `14.5 CPUs`、`28.5Gi` 内存以及 `88Gi` 本地存储。 -调度器保证这个节点上的所有 Pod 的内存 `requests` 总量不超过 `28.5Gi`, -存储不超过 `88Gi`。 -当 Pod 的内存使用总量超过 `28.5Gi` 或者磁盘使用总量超过 `88Gi` 时, +在这个场景下,'Allocatable' 将会是 14.5 CPUs、28.5Gi 内存以及 `88Gi` 本地存储。 +调度器保证这个节点上的所有 Pod 的内存 `requests` 总量不超过 28.5Gi, +存储不超过 '88Gi'。 +当 Pod 的内存使用总量超过 28.5Gi 或者磁盘使用总量超过 88Gi 时, kubelet 将会驱逐它们。 如果节点上的所有进程都尽可能多地使用 CPU,则 Pod 加起来不能使用超过 -`14.5 CPUs` 的资源。 +14.5 CPUs 的资源。 当没有执行 `kube-reserved` 和/或 `system-reserved` 策略且系统守护进程 -使用量超过其预留时,如果节点内存用量高于 `31.5Gi` 或`存储`大于 `90Gi`, +使用量超过其预留时,如果节点内存用量高于 31.5Gi 或`存储`大于 90Gi, kubelet 将会驱逐 Pod。 From 6aaf609db6526741d9c4bd933c5233309aa5e30e Mon Sep 17 00:00:00 2001 From: howieyuen Date: Mon, 27 Sep 2021 11:48:07 +0800 Subject: [PATCH 059/115] [zh]sync content/zh/docs/concepts/configuration/secret.md --- .../zh/docs/concepts/configuration/secret.md | 110 ++++++++++-------- 1 file changed, 64 insertions(+), 46 deletions(-) diff --git a/content/zh/docs/concepts/configuration/secret.md b/content/zh/docs/concepts/configuration/secret.md index 53a301f03ef87..0d018141a7e45 100644 --- a/content/zh/docs/concepts/configuration/secret.md +++ b/content/zh/docs/concepts/configuration/secret.md @@ -22,47 +22,58 @@ weight: 30 - - -`Secret` 对象类型用来保存敏感信息,例如密码、OAuth 令牌和 SSH 密钥。 -将这些信息放在 `secret` 中比放在 {{< glossary_tooltip term_id="pod" >}} 的定义或者 {{< glossary_tooltip text="容器镜像" term_id="image" >}} 中来说更加安全和灵活。 -参阅 [Secret 设计文档](https://git.k8s.io/community/contributors/design-proposals/auth/secrets.md) 获取更多详细信息。 - Secret 是一种包含少量敏感信息例如密码、令牌或密钥的对象。 -这样的信息可能会被放在 Pod 规约中或者镜像中。 -用户可以创建 Secret,同时系统也创建了一些 Secret。 +这样的信息可能会被放在 {{< glossary_tooltip term_id="pod" >}} 规约中或者镜像中。 +使用 Secret 意味着你不需要在应用程序代码中包含机密数据。 + + +由于创建 Secret 可以独立于使用它们的 Pod, +因此在创建、查看和编辑 Pod 的工作流程中暴露 Secret(及其数据)的风险较小。 +Kubernetes 和在集群中运行的应用程序也可以对 Secret 采取额外的预防措施, +例如避免将机密数据写入非易失性存储。 + +Secret 类似于 {{}} +但专门用于保存机密数据。 {{< caution >}} -Kubernetes Secret 默认情况下存储为 base64-编码的、非加密的字符串。 -默认情况下,能够访问 API 的任何人,或者能够访问 Kubernetes 下层数据存储(etcd) -的任何人都可以以明文形式读取这些数据。 -为了能够安全地使用 Secret,我们建议你(至少): +默认情况下,Kubernetes Secret 未加密地存储在 API 服务器的底层数据存储(etcd)中。 +任何拥有 API 访问权限的人都可以检索或修改 Secret,任何有权访问 etcd 的人也可以。 +此外,任何有权限在命名空间中创建 Pod 的人都可以使用该访问权限读取该命名空间中的任何 Secret; +这包括间接访问,例如创建 Deployment 的能力。 + +为了安全地使用 Secret,请至少执行以下步骤: 1. 为 Secret [启用静态加密](/zh/docs/tasks/administer-cluster/encrypt-data/); -2. [启用 或配置 RBAC 规则](/zh/docs/reference/access-authn-authz/authorization/)来限制对 Secret 的读写操作。 - 要注意,任何被允许创建 Pod 的人都默认地具有读取 Secret 的权限。 +2. 启用或配置 [RBAC 规则](/zh/docs/reference/access-authn-authz/authorization/)来限制读取 Secret 的数据(包括通过间接方式)。 +3. 在适当的情况下,还可以使用 RBAC 等机制来限制允许哪些主体创建新 Secret 或替换现有 Secret。 {{< /caution >}} @@ -89,6 +100,15 @@ Pod 可以用三种方式之一来使用 Secret: - 作为[容器的环境变量](#using-secrets-as-environment-variables) - 由 [kubelet 在为 Pod 拉取镜像时使用](#using-imagepullsecrets) + +Kubernetes 控制平面也使用 Secret; +例如,[引导令牌 Secret](#bootstrap-token-secrets) +是一种帮助自动化节点注册的机制。 + ## Secret 的类型 {#secret-types} -在创建 Secret 对象时,你可以使用 -[`Secret`](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#secret-v1-core) -资源的 `type` 字段,或者与其等价的 `kubectl` 命令行参数(如果有的话)为其设置类型。 -Secret 的类型用来帮助编写程序处理 Secret 数据。 +创建 Secret 时,你可以使用 Secret 资源的 `type` 字段, +或者与其等价的 `kubectl` 命令行参数(如果有的话)为其设置类型。 +Secret 的 `type` 有助于对不同类型机密数据的编程处理。 Kubernetes 提供若干种内置的类型,用于一些常见的使用场景。 针对这些类型,Kubernetes 所执行的合法性检查操作以及对其所实施的限制各不相同。 @@ -553,13 +572,13 @@ kubectl create secret tls my-tls-secret \ ``` 这里的公钥/私钥对都必须事先已存在。用于 `--cert` 的公钥证书必须是 .PEM 编码的 (Base64 编码的 DER 格式),且与 `--key` 所给定的私钥匹配。 @@ -1334,6 +1353,8 @@ This includes any pods created using kubectl, or indirectly via a replication controller. It does not include pods created via the kubelets `--manifest-url` flag, its `--config` flag, or its REST API (these are not common ways to create pods.) +The `spec` of a {{< glossary_tooltip text="static Pod" term_id="static-pod" >}} cannot refer to a Secret +or any other API objects. --> 每个 Secret 的大小限制为 1MB。这是为了防止创建非常大的 Secret 导致 API 服务器 和 kubelet 的内存耗尽。然而,创建过多较小的 Secret 也可能耗尽内存。 @@ -1343,6 +1364,8 @@ kubelet 仅支持从 API 服务器获得的 Pod 使用 Secret。 这包括使用 `kubectl` 创建的所有 Pod,以及间接通过副本控制器创建的 Pod。 它不包括通过 kubelet `--manifest-url` 标志,`--config` 标志或其 REST API 创建的 Pod(这些不是创建 Pod 的常用方法)。 +{{}} +的 `spec` 不能引用 Secret 或任何其他 API 对象。 ### 风险 @@ -1968,9 +1987,6 @@ for secret data, so that the secrets are not stored in the clear into {{< glossa - 如果您将 Secret 数据编码为 base64 的清单(JSON 或 YAML)文件,共享该文件或将其检入代码库,该密码将会被泄露。 Base64 编码不是一种加密方式,应该视同纯文本。 - 应用程序在从卷中读取 Secret 后仍然需要保护 Secret 的值,例如不会意外将其写入日志或发送给不信任方。 - 可以创建使用 Secret 的 Pod 的用户也可以看到该 Secret 的值。即使 API 服务器策略不允许用户读取 Secret 对象,用户也可以运行 Pod 导致 Secret 暴露。 -- 目前,任何节点的 root 用户都可以通过模拟 kubelet 来读取 API 服务器中的任何 Secret。 - 仅向实际需要 Secret 的节点发送 Secret 数据才能限制节点的 root 账号漏洞的影响, - 该功能还在计划中。 ## {{% heading "whatsnext" %}} @@ -1978,8 +1994,10 @@ for secret data, so that the secrets are not stored in the clear into {{< glossa - Learn how to [manage Secret using `kubectl`](/docs/tasks/configmap-secret/managing-secret-using-kubectl/) - Learn how to [manage Secret using config file](/docs/tasks/configmap-secret/managing-secret-using-config-file/) - Learn how to [manage Secret using kustomize](/docs/tasks/configmap-secret/managing-secret-using-kustomize/) +- Read the [API reference](/docs/reference/kubernetes-api/config-and-storage-resources/secret-v1/) for `Secret` --> - 学习如何[使用 `kubectl` 管理 Secret](/zh/docs/tasks/configmap-secret/managing-secret-using-kubectl/) - 学习如何[使用配置文件管理 Secret](/zh/docs/tasks/configmap-secret/managing-secret-using-config-file/) - 学习如何[使用 kustomize 管理 Secret](/zh/docs/tasks/configmap-secret/managing-secret-using-kustomize/) +- 阅读 [API 参考](/zh/docs/reference/kubernetes-api/config-and-storage-resources/secret-v1/)了解 `Secret` From 649cc1d25ad16a3476e9ccd0cb5d57a512413d8b Mon Sep 17 00:00:00 2001 From: chenxuc Date: Sat, 18 Sep 2021 10:20:11 +0800 Subject: [PATCH 060/115] [zh] sync admin cluster docs --- .../access-cluster-services.md | 6 ++-- .../tasks/administer-cluster/certificates.md | 7 ++++ ...aranteed-scheduling-critical-addon-pods.md | 24 +++++++------ .../administer-cluster/securing-a-cluster.md | 35 ++++++++++--------- .../administer-cluster/sysctl-cluster.md | 12 +++++-- .../administer-cluster/topology-manager.md | 16 +++++---- 6 files changed, 61 insertions(+), 39 deletions(-) diff --git a/content/zh/docs/tasks/administer-cluster/access-cluster-services.md b/content/zh/docs/tasks/administer-cluster/access-cluster-services.md index ee817c141fc5c..d87fb93758e47 100644 --- a/content/zh/docs/tasks/administer-cluster/access-cluster-services.md +++ b/content/zh/docs/tasks/administer-cluster/access-cluster-services.md @@ -46,7 +46,7 @@ You have several options for connecting to nodes, pods and services from outside - Use a service with type `NodePort` or `LoadBalancer` to make the service reachable outside the cluster. See the [services](/docs/concepts/services-networking/service/) and [kubectl expose](/docs/reference/generated/kubectl/kubectl-commands/#expose) documentation. - - Depending on your cluster environment, this may just expose the service to your corporate network, + - Depending on your cluster environment, this may only expose the service to your corporate network, or it may expose it to the internet. Think about whether the service being exposed is secure. Does it do its own authentication? - Place pods behind services. To access one specific pod from a set of replicas, such as for debugging, @@ -148,7 +148,7 @@ See [Access Clusters Using the Kubernetes API](/docs/tasks/administer-cluster/ac +1. 查看证书签名请求: + + openssl req -noout -text -in ./server.csr + diff --git a/content/zh/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods.md b/content/zh/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods.md index 0f6d8d1312e33..111d30d32d3ce 100644 --- a/content/zh/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods.md +++ b/content/zh/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods.md @@ -6,20 +6,25 @@ content_type: concept -除了在主机上运行的 Kubernetes 核心组件(如 api-server 、scheduler 、controller-manager)之外,还有许多插件,由于各种原因, -必须在常规集群节点(而不是 Kubernetes 主节点)上运行。 +Kubernetes 核心组件(如 API 服务器、调度器、控制器管理器)在控制平面节点上运行。 +但是插件必须在常规集群节点上运行。 其中一些插件对于功能完备的群集至关重要,例如 Heapster、DNS 和 UI。 如果关键插件被逐出(手动或作为升级等其他操作的副作用)或者变成挂起状态,群集可能会停止正常工作。 关键插件进入挂起状态的例子有:集群利用率过高;被逐出的关键插件 Pod 释放了空间,但该空间被之前悬决的 Pod 占用;由于其它原因导致节点上可用资源的总量发生变化。 - + +注意,把某个 Pod 标记为关键 Pod 并不意味着完全避免该 Pod 被逐出;它只能防止该 Pod 变成永久不可用。 +被标记为关键性的静态 Pod 不会被逐出。但是,被标记为关键性的非静态 Pod 总是会被重新调度。 @@ -29,12 +34,9 @@ vacated by the evicted critical add-on pod or the amount of resources available ### 标记关键 Pod -要将 pod 标记为关键性(critical),pod 必须在 kube-system 命名空间中运行(可通过参数配置)。 -同时,需要将 `priorityClassName` 设置为 `system-cluster-critical` 或 `system-node-critical` ,后者是整个群集的最高级别。 -或者,也可以为 Pod 添加名为 `scheduler.alpha.kubernetes.io/critical-pod`、值为空字符串的注解。 -不过,这一注解从 1.13 版本开始不再推荐使用,并将在 1.14 中删除。 +要将 Pod 标记为关键性(critical),设置 Pod 的 priorityClassName 为 `system-cluster-critical` 或者 `system-node-critical`。 +`system-node-critical` 是最高级别的可用性优先级,甚至比 `system-cluster-critical` 更高。 diff --git a/content/zh/docs/tasks/administer-cluster/securing-a-cluster.md b/content/zh/docs/tasks/administer-cluster/securing-a-cluster.md index ee3a9cf5fa7d1..5731d530b338d 100644 --- a/content/zh/docs/tasks/administer-cluster/securing-a-cluster.md +++ b/content/zh/docs/tasks/administer-cluster/securing-a-cluster.md @@ -29,7 +29,7 @@ and provides recommendations on overall security. ## 控制对 Kubernetes API 的访问 @@ -53,7 +53,7 @@ Kubernetes 期望集群中所有的 API 通信在默认情况下都使用 TLS ### API Authentication Choose an authentication mechanism for the API servers to use that matches the common access patterns -when you install a cluster. For instance, small single user clusters may wish to use a simple certificate +when you install a cluster. For instance, small single-user clusters may wish to use a simple certificate or static Bearer token approach. Larger clusters may wish to integrate an existing OIDC or LDAP server that allow users to be subdivided into groups. @@ -80,7 +80,7 @@ Consult the [authentication reference document](/docs/reference/access-authn-aut Once authenticated, every API call is also expected to pass an authorization check. Kubernetes ships an integrated [Role-Based Access Control (RBAC)](/docs/reference/access-authn-authz/rbac/) component that matches an incoming user or group to a set of permissions bundled into roles. These permissions combine verbs (get, create, delete) with -resources (pods, services, nodes) and can be namespace or cluster scoped. A set of out of the box +resources (pods, services, nodes) and can be namespace-scoped or cluster-scoped. A set of out-of-the-box roles are provided that offer reasonable default separation of responsibility depending on what actions a client might want to perform. It is recommended that you use the [Node](/docs/reference/access-authn-authz/node/) and [RBAC](/docs/reference/access-authn-authz/rbac/) authorizers together, in combination with the [NodeRestriction](/docs/reference/access-authn-authz/admission-controllers/#noderestriction) admission plugin. @@ -110,8 +110,8 @@ With authorization, it is important to understand how updates on one object may other places. For instance, a user may not be able to create pods directly, but allowing them to create a deployment, which creates pods on their behalf, will let them create those pods indirectly. Likewise, deleting a node from the API will result in the pods scheduled to that node -being terminated and recreated on other nodes. The out of the box roles represent a balance -between flexibility and the common use cases, but more limited roles should be carefully reviewed +being terminated and recreated on other nodes. The out-of-the-box roles represent a balance +between flexibility and common use cases, but more limited roles should be carefully reviewed to prevent accidental escalation. You can make roles specific to your use case if the out-of-box ones don't meet your needs. Consult the [authorization reference section](/docs/reference/access-authn-authz/authorization/) for more information. @@ -183,7 +183,7 @@ reserved resources like memory, or to provide default limits when none are speci ### Controlling what privileges containers run with A pod definition contains a [security context](/docs/tasks/configure-pod-container/security-context/) -that allows it to request access to running as a specific Linux user on a node (like root), +that allows it to request access to run as a specific Linux user on a node (like root), access to run privileged or access the host network, and other controls that would otherwise allow it to run unfettered on a hosting node. [Pod security policies](/docs/concepts/policy/pod-security-policy/) can limit which users or service accounts can provide dangerous security context settings. For example, pod security policies can limit volume mounts, especially `hostPath`, which are aspects of a pod that should be controlled. @@ -227,11 +227,11 @@ now respect network policy. 对于可以控制用户的应用程序是否在集群之外可见的许多集群,配额和限制范围也可用于 @@ -248,7 +248,7 @@ By default these APIs are accessible by pods running on an instance and can cont credentials for that node, or provisioning data such as kubelet credentials. These credentials can be used to escalate within the cluster or to other cloud services under the same account. -When running Kubernetes on a cloud platform limit permissions given to instance credentials, use +When running Kubernetes on a cloud platform, limit permissions given to instance credentials, use [network policies](/docs/tasks/administer-cluster/declare-network-policy/) to restrict pod access to the metadata API, and avoid using provisioning data to deliver secrets. --> @@ -268,7 +268,7 @@ to the metadata API, and avoid using provisioning data to deliver secrets. By default, there are no restrictions on which nodes may run a pod. Kubernetes offers a [rich set of policies for controlling placement of pods onto nodes](/docs/concepts/configuration/assign-pod-node/) -and the [taint based pod placement and eviction](/docs/concepts/configuration/taint-and-toleration/) +and the [taint-based pod placement and eviction](/docs/concepts/configuration/taint-and-toleration/) that are available to end users. For many clusters use of these policies to separate workloads can be a convention that authors adopt or enforce via tooling. @@ -360,7 +360,7 @@ Kubernetes 的 alpha 和 beta 特性还在努力开发中,可能存在导致 The shorter the lifetime of a secret or credential the harder it is for an attacker to make use of that credential. Set short lifetimes on certificates and automate their rotation. Use an authentication provider that can control how long issued tokens are available and use short -lifetimes where possible. If you use service account tokens in external integrations, plan to +lifetimes where possible. If you use service-account tokens in external integrations, plan to rotate those tokens frequently. For example, once the bootstrap phase is complete, a bootstrap token used for setting up nodes should be revoked or its authorization removed. --> ### 频繁回收基础设施证书 @@ -406,9 +406,10 @@ and may grant an attacker significant visibility into the state of your cluster. your backups using a well reviewed backup and encryption solution, and consider using full disk encryption where possible. -Kubernetes 1.7 contains [encryption at rest](/docs/tasks/administer-cluster/encrypt-data/), an alpha feature that will encrypt `Secret` resources in etcd, preventing +Kubernetes supports [encryption at rest](/docs/tasks/administer-cluster/encrypt-data/), a feature +introduced in 1.7, and beta since 1.13. This will encrypt `Secret` resources in etcd, preventing parties that gain access to your etcd backups from viewing the content of those secrets. While -this feature is currently experimental, it may offer an additional level of defense when backups +this feature is currently beta, it offers an additional level of defense when backups are not encrypted or an attacker gains read access to etcd. --> ### 对 Secret 进行静态加密 @@ -417,9 +418,9 @@ are not encrypted or an attacker gains read access to etcd. 并且可以授予攻击者对集群状态的可见性。 始终使用经过良好审查的备份和加密解决方案来加密备份,并考虑在可能的情况下使用全磁盘加密。 -Kubernetes 1.7 包含了[静态数据加密](/zh/docs/tasks/administer-cluster/encrypt-data/), -它是一个 alpha 特性,会加密 etcd 里面的 `Secret` 资源,以防止某一方通过查看 -etcd 的备份文件查看到这些 Secret 的内容。虽然目前这还只是实验性的功能, +Kubernetes 支持 [静态数据加密](/zh/docs/tasks/administer-cluster/encrypt-data/), +该功能在 1.7 版本引入,并在 1.13 版本成为 Beta。它会加密 etcd 里面的 `Secret` 资源,以防止某一方通过查看 +etcd 的备份文件查看到这些 Secret 的内容。虽然目前这还只是 Beta 阶段的功能, 但是在备份没有加密或者攻击者获取到 etcd 的读访问权限的时候,它能提供额外的防御层级。 - +{{< feature-state for_k8s_version="v1.21" state="stable" >}} +对一些步骤,你需要能够重新配置在你的集群里运行的 kubelet 命令行的选项。 @@ -272,6 +278,8 @@ to schedule those pods onto the right nodes. ## PodSecurityPolicy +{{< feature-state for_k8s_version="v1.21" state="deprecated" >}} + +{{< note >}} +为了将 Pod 规约中的 memory(和 hugepages)资源与所请求的其他资源对齐,需要启用内存管理器, +并且在节点配置适当的内存管理器策略。查看[内存管理器](/zh/docs/tasks/administer-cluster/memory-manager/) +文档。 +{{< /note >}} + ### 已知的局限性 1. 拓扑管理器所能处理的最大 NUMA 节点个数是 8。若 NUMA 节点数超过 8, 枚举可能的 NUMA 亲和性并为之生成提示时会发生状态爆炸。 -2. 调度器不支持拓扑功能,因此可能会由于拓扑管理器的原因而在节点上进行调度,然后在该节点上调度失败。 -3. 设备管理器和 CPU 管理器时能够采纳拓扑管理器 HintProvider 接口的唯一两个组件。 - 这意味着 NUMA 对齐只能针对 CPU 管理器和设备管理器所管理的资源实现。 - 内存和大页面在拓扑管理器决定 NUMA 对齐时都还不会被考虑在内。 +2. 调度器不是拓扑感知的,所以有可能一个 Pod 被调度到一个节点之后,会因为拓扑管理器的缘故在该节点上启动失败。 From 6d61d43ab084f1b14a5060575b77f07106c649e8 Mon Sep 17 00:00:00 2001 From: zhiguo-lu Date: Sun, 26 Sep 2021 17:56:02 +0800 Subject: [PATCH 061/115] [zh] translate glossary/Garbage Collection --- .../reference/glossary/garbage-collection.md | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 content/zh/docs/reference/glossary/garbage-collection.md diff --git a/content/zh/docs/reference/glossary/garbage-collection.md b/content/zh/docs/reference/glossary/garbage-collection.md new file mode 100644 index 0000000000000..effc51483ccf6 --- /dev/null +++ b/content/zh/docs/reference/glossary/garbage-collection.md @@ -0,0 +1,49 @@ +--- +title: 垃圾收集 +id: garbage-collection +date: 2021-07-07 +full_link: /zh/docs/concepts/workloads/controllers/garbage-collection/ +short_description: > + Kubernetes 用于清理集群资源的各种机制的统称。 + +aka: +tags: +- fundamental +- operation +--- + + + +垃圾收集是 Kubernetes 用于清理集群资源的各种机制的统称。 + + + + +Kubernetes 使用垃圾收集机制来清理资源,例如: +[未使用的容器和镜像](/zh/docs/concepts/workloads/controllers/garbage-collection/#containers-images)、 +[失败的 Pod](/zh/docs/concepts/workloads/pods/pod-lifecycle/#pod-garbage-collection)、 +[目标资源拥有的对象](/zh/docs/concepts/overview/working-with-objects/owners-dependents/)、 +[已完成的 Job](/zh/docs/concepts/workloads/controllers/ttlafterfinished/)、 +过期或出错的资源。 \ No newline at end of file From 740c8762e2c4d9ba934ef743c1f87a6b49a342cb Mon Sep 17 00:00:00 2001 From: Gilson Melo Date: Mon, 27 Sep 2021 11:08:02 -0500 Subject: [PATCH 062/115] Include Oracle Cloud Infrastructure Including Oracle Cloud Infrastructure Security page. --- content/en/docs/concepts/security/overview.md | 1 + 1 file changed, 1 insertion(+) diff --git a/content/en/docs/concepts/security/overview.md b/content/en/docs/concepts/security/overview.md index ce75653dfddf9..0506fbbab0787 100644 --- a/content/en/docs/concepts/security/overview.md +++ b/content/en/docs/concepts/security/overview.md @@ -60,6 +60,7 @@ Amazon Web Services | https://aws.amazon.com/security/ | Google Cloud Platform | https://cloud.google.com/security/ | IBM Cloud | https://www.ibm.com/cloud/security | Microsoft Azure | https://docs.microsoft.com/en-us/azure/security/azure-security | +Oracle Cloud Infrastructure | https://www.oracle.com/security/ | VMWare VSphere | https://www.vmware.com/security/hardening-guides.html | {{< /table >}} From 225f93c49e48780a2f498e36c49ccce5f43eef01 Mon Sep 17 00:00:00 2001 From: superleo Date: Sun, 26 Sep 2021 22:33:20 +0800 Subject: [PATCH 063/115] Sync 6 files under configure-pod-container/ with 1.22 version --- ...igure-liveness-readiness-startup-probes.md | 63 ++++++++++++------- .../configure-runasusername.md | 23 ++++--- .../configure-service-account.md | 23 ++++--- .../pull-image-private-registry.md | 4 +- .../quality-service-pod.md | 16 +++-- .../security-context.md | 39 +++++++++++- 6 files changed, 119 insertions(+), 49 deletions(-) diff --git a/content/zh/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes.md b/content/zh/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes.md index 7355e5c11e972..e180bbaea72f1 100644 --- a/content/zh/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes.md +++ b/content/zh/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes.md @@ -217,14 +217,14 @@ Any code greater than or equal to 200 and less than 400 indicates success. Any other code indicates failure. You can see the source code for the server in -[server.go](https://github.com/kubernetes/kubernetes/blob/{{< param "githubbranch" >}}/test/images/agnhost/liveness/server.go). +[server.go](https://github.com/kubernetes/kubernetes/blob/master/test/images/agnhost/liveness/server.go). For the first 10 seconds that the container is alive, the `/healthz` handler returns a status of 200. After that, the handler returns a status of 500. --> 任何大于或等于 200 并且小于 400 的返回代码标示成功,其它返回代码都标示失败。 -可以在这里看服务的源码 [server.go](https://github.com/kubernetes/kubernetes/blob/{{< param "githubbranch" >}}/test/images/agnhost/liveness/server.go)。 +可以在这里看服务的源码 [server.go](https://github.com/kubernetes/kubernetes/blob/master/test/images/agnhost/liveness/server.go)。 容器存活的最开始 10 秒中,`/healthz` 处理程序返回一个 200 的状态码。之后处理程序返回 500 的状态码。 @@ -672,35 +672,52 @@ to resolve it. --> ### 探测器级别 `terminationGracePeriodSeconds` -{{< feature-state for_k8s_version="v1.21" state="alpha" >}} +{{< feature-state for_k8s_version="v1.22" state="beta" >}} -在 1.21 版之前,pod 级别的 `terminationGracePeriodSeconds` 被用来终止 -未能成功处理活跃性探测或启动探测的容器。 -这种耦合是意料之外的,可能会导致在设置了 pod 级别的 `terminationGracePeriodSeconds` 后, -需要很长的时间来重新启动失败的容器。 +在 1.21 及更高版本中,当特性门控 `ProbeTerminationGracePeriod` 为 +启用状态时,用户可以指定一个探测级别的 `terminationGracePeriodSeconds` 作为 +探针规格的一部分。当特性门控被启用时,并且 +Pod 级和探针级的 `terminationGracePeriodSeconds` 都已设置,kubelet 将 +使用探针级设置的值。 +{{< note >}} +从 Kubernetes 1.22 开始,`ProbeTerminationGracePeriod` 特性门控只 +在 API 服务器上可用。 kubelet 始终遵守探针级别 +`terminationGracePeriodSeconds` 字段(如果它存在于 Pod 上)。 -For example, + -在1.21中,启用特性标志 `ProbeTerminationGracePeriod` 后, -用户可以指定一个探测器级别的 `terminationGracePeriodSeconds` 作为探测器规格的一部分。 -当该特性标志被启用时,若同时设置了 Pod 级别和探测器级别的 `terminationGracePeriodSeconds`, -kubelet 将使用探测器级的值。 +如果你已经为现有 Pod 设置了 “terminationGracePeriodSeconds” 字段并且 +不再希望使用针对每个探针的终止宽限期,则必须删除那些现有的 Pod。 + + +当你(或控制平面或某些其他组件)创建替换 +Pods,并且特性门控 “ProbeTerminationGracePeriod” 被禁用,那么 +API 服务器会忽略 Pod 级别的 `terminationGracePeriodSeconds` 字段,即使 +Pod 或 Pod 模板指定了它。 +{{< /note >}} -例如, +例如: ```yaml spec: diff --git a/content/zh/docs/tasks/configure-pod-container/configure-runasusername.md b/content/zh/docs/tasks/configure-pod-container/configure-runasusername.md index 19a9e4e71e2dc..4b4e05dd4bdd9 100644 --- a/content/zh/docs/tasks/configure-pod-container/configure-runasusername.md +++ b/content/zh/docs/tasks/configure-pod-container/configure-runasusername.md @@ -31,14 +31,17 @@ You need to have a Kubernetes cluster and the kubectl command-line tool must be ## 为 Pod 设置 Username -要指定运行 Pod 容器时所使用的用户名,请在 Pod 声明中包含 `securityContext` -([PodSecurityContext](/zh/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podsecuritycontext-v1-core))字段, -并在其内部包含 `windowsOptions` -([WindowsSecurityContextOptions](/zh/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#windowssecuritycontextoptions-v1-core)) +要指定运行 Pod 容器时所使用的用户名,请在 Pod 声明中包含 `securityContext` +([PodSecurityContext](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podsecuritycontext-v1-core)) 字段, +并在其内部包含 `windowsOptions` +([WindowsSecurityContextOptions](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#windowssecuritycontextoptions-v1-core)) 字段的 `runAsUserName` 字段。 ## 为容器设置 Username 要指定运行容器时所使用的用户名,请在容器清单中包含 `securityContext` -([SecurityContext](/zh/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#securitycontext-v1-core)) +([SecurityContext](/zh/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#securitycontext-v1-core)) 字段,并在其内部包含 `windowsOptions` -([WindowsSecurityContextOptions](/zh/docs/reference/generated/kubernetes-api/{{< param +([WindowsSecurityContextOptions](/zh/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#windowssecuritycontextoptions-v1-core)) 字段的 `runAsUserName` 字段。 diff --git a/content/zh/docs/tasks/configure-pod-container/configure-service-account.md b/content/zh/docs/tasks/configure-pod-container/configure-service-account.md index aba366f47eeca..e7bba36668b7d 100644 --- a/content/zh/docs/tasks/configure-pod-container/configure-service-account.md +++ b/content/zh/docs/tasks/configure-pod-container/configure-service-account.md @@ -262,8 +262,8 @@ The output is similar to this: Name: build-robot-secret Namespace: default Labels: -Annotations: kubernetes.io/service-account.name=build-robot - kubernetes.io/service-account.uid=da68f9c6-9d26-11e7-b84e-002dc52800da +Annotations: kubernetes.io/service-account.name: build-robot + kubernetes.io/service-account.uid: da68f9c6-9d26-11e7-b84e-002dc52800da Type: kubernetes.io/service-account-token @@ -540,15 +540,18 @@ JSON Web Key Set(JWKS)。 -集群包括一个默认的 RBAC ClusterRole, -名为 `system:service-account-issuer-discovery`。 -默认情况下不提供角色绑定对象。 -举例而言,管理员可以根据其安全性需要以及期望集成的外部系统选择是否将该角色绑定到 +集群包括一个的默认 RBAC ClusterRole, 名为 `system:service-account-issuer-discovery`。 +默认的 RBAC ClusterRoleBinding 将此角色分配给 `system:serviceaccounts` 组, +所有服务帐户隐式属于该组。这使得集群上运行的 Pod 能够通过它们所挂载的服务帐户令牌访问服务帐户发现文档。 +此外,管理员可以根据其安全性需要以及期望集成的外部系统选择是否将该角色绑定到 `system:authenticated` 或 `system:unauthenticated`。 另请参见: - [服务账号的集群管理员指南](/zh/docs/reference/access-authn-authz/service-accounts-admin/) -- [服务账号签署密钥检索 KEP](https://github.com/kubernetes/enhancements/blob/master/keps/sig-auth/20190730-oidc-discovery.md) +- [服务账号签署密钥检索 KEP](https://github.com/kubernetes/enhancements/tree/master/keps/sig-auth/1393-oidc-discovery) - [OIDC 发现规范](https://openid.net/specs/openid-connect-discovery-1_0.html) diff --git a/content/zh/docs/tasks/configure-pod-container/pull-image-private-registry.md b/content/zh/docs/tasks/configure-pod-container/pull-image-private-registry.md index 6ddd85537bef8..c3b896ec35ab9 100644 --- a/content/zh/docs/tasks/configure-pod-container/pull-image-private-registry.md +++ b/content/zh/docs/tasks/configure-pod-container/pull-image-private-registry.md @@ -110,7 +110,7 @@ kubectl create secret docker-registry regcred \ where: * `` is your Private Docker Registry FQDN. - Use `https://index.docker.io/v2/` for DockerHub. + Use `https://index.docker.io/v1/` for DockerHub. * `` is your Docker username. * `` is your Docker password. * `` is your Docker email. @@ -120,7 +120,7 @@ You have successfully set your Docker credentials in the cluster as a Secret cal 在这里: * `` 是你的私有 Docker 仓库全限定域名(FQDN)。 - DockerHub 使用 `https://index.docker.io/v2/`。 + DockerHub 使用 `https://index.docker.io/v1/`。 * `` 是你的 Docker 用户名。 * `` 是你的 Docker 密码。 * `` 是你的 Docker 邮箱。 diff --git a/content/zh/docs/tasks/configure-pod-container/quality-service-pod.md b/content/zh/docs/tasks/configure-pod-container/quality-service-pod.md index d2ae4a6b2f509..b2fdccf8fb47b 100644 --- a/content/zh/docs/tasks/configure-pod-container/quality-service-pod.md +++ b/content/zh/docs/tasks/configure-pod-container/quality-service-pod.md @@ -59,8 +59,12 @@ kubectl create namespace qos-example For a Pod to be given a QoS class of Guaranteed: -* Every Container, including init containers, in the Pod must have a memory limit and a memory request, and they must be the same. -* Every Container, including init containers, in the Pod must have a CPU limit and a CPU request, and they must be the same. +* Every Container in the Pod must have a memory limit and a memory request. +* For every Container in the Pod, the memory limit must equal the memory request. +* Every Container in the Pod must have a CPU limit and a CPU request. +* For every Container in the Pod, the CPU limit must equal the CPU request. + +These restrictions apply to init containers and app containers equally. Here is the configuration file for a Pod that has one Container. The Container has a memory limit and a memory request, both equal to 200 MiB. The Container has a CPU limit and a CPU request, both equal to 700 milliCPU: @@ -69,8 +73,12 @@ memory request, both equal to 200 MiB. The Container has a CPU limit and a CPU r 对于 QoS 类为 Guaranteed 的 Pod: -* Pod 中的每个容器,包含初始化容器,必须指定内存请求和内存限制,并且两者要相等。 -* Pod 中的每个容器,包含初始化容器,必须指定 CPU 请求和 CPU 限制,并且两者要相等。 +* Pod 中的每个容器都必须指定内存限制和内存请求。 +* 对于 Pod 中的每个容器,内存限制必须等于内存请求。 +* Pod 中的每个容器都必须指定 CPU 限制和 CPU 请求。 +* 对于 Pod 中的每个容器,CPU 限制必须等于 CPU 请求。 + +这些限制同样适用于初始化容器和应用程序容器。 下面是包含一个容器的 Pod 配置文件。 容器设置了内存请求和内存限制,值都是 200 MiB。 diff --git a/content/zh/docs/tasks/configure-pod-container/security-context.md b/content/zh/docs/tasks/configure-pod-container/security-context.md index 42f07b5ceb010..f05e678392a62 100644 --- a/content/zh/docs/tasks/configure-pod-container/security-context.md +++ b/content/zh/docs/tasks/configure-pod-container/security-context.md @@ -39,7 +39,7 @@ a Pod or Container. Security context settings include, but are not limited to: 为进程赋予 root 用户的部分特权而非全部特权。 * [AppArmor](/zh/docs/tutorials/clusters/apparmor/):使用程序框架来限制个别程序的权能。 -* [Seccomp](https://en.wikipedia.org/wiki/Seccomp):过滤进程的系统调用。 +* [Seccomp](/zh/docs/tutorials/clusters/seccomp/):过滤进程的系统调用。 * AllowPrivilegeEscalation:控制进程是否可以获得超出其父进程的特权。 此布尔值直接控制是否为容器进程设置 [`no_new_privs`](https://www.kernel.org/doc/Documentation/prctl/no_new_privs.txt)标志。 @@ -299,6 +299,41 @@ and [`emptydir`](/docs/concepts/storage/volumes/#emptydir). 这类临时性存储无效。 {{< /note >}} + +## 将卷权限和所有权更改委派给 CSI 驱动程序 +{{< feature-state for_k8s_version="v1.22" state="alpha" >}} + + +如果你部署了一个[容器存储接口 (CSI)](https://github.com/container-storage-interface/spec/blob/master/spec.md) +驱动支持 `VOLUME_MOUNT_GROUP` `NodeServiceCapability`, +在 `securityContext` 中指定 `fsGroup` 来设置文件所有权和权限的过程将由 CSI 驱动 +而不是 Kubernetes 来执行,前提是 Kubernetes 的 `DelegateFSGroupToCSIDriver` +特性门控已启用。在这种情况下,由于 Kubernetes 不执行任何 +所有权和权限更改,`fsGroupChangePolicy` 不会生效,并且 +按照 CSI 的规定,CSI 驱动应该使用所指定的 `fsGroup` 来挂载卷,从而生成了一个对 `fsGroup` 可读/可写的卷. + +更多的信息请参考 [KEP](https://github.com/gnufied/enhancements/blob/master/keps/sig-storage/2317-fsgroup-on-mount/README.md) +和 [CSI 规范](https://github.com/container-storage-interface/spec/blob/master/spec.md#createvolume) 中的字 +段 `VolumeCapability.MountVolume.volume_mount_group` 的描述 。 + ## Running an example Job @@ -638,6 +641,19 @@ driver, and then cleans up. An advantage of this approach is that the overall process gets the completion guarantee of a Job object, but maintains complete control over what Pods are created and how work is assigned to them. -## Cron Jobs {#cron-jobs} - -You can use a [`CronJob`](/docs/concepts/workloads/controllers/cron-jobs/) to create a Job that will run at specified times/dates, similar to the Unix tool `cron`. +## {{% heading "whatsnext" %}} + +* Learn about [Pods](/docs/concepts/workloads/pods). +* Read about different ways of running Jobs: + * [Coarse Parallel Processing Using a Work Queue](/docs/tasks/job/coarse-parallel-processing-work-queue/) + * [Fine Parallel Processing Using a Work Queue](/docs/tasks/job/fine-parallel-processing-work-queue/) + * Use an [indexed Job for parallel processing with static work assignment](/docs/tasks/job/indexed-parallel-processing-static/) (beta) + * Create multiple Jobs based on a template: [Parallel Processing using Expansions](/docs/tasks/job/parallel-processing-expansion/) +* Follow the links within [Clean up finished jobs automatically](#clean-up-finished-jobs-automatically) + to learn more about how your cluster can clean up completed and / or failed tasks. +* `Job` is part of the Kubernetes REST API. + Read the {{< api-reference page="workload-resources/job-v1" >}} + object definition to understand the API for jobs. +* Read about [`CronJob`](/docs/concepts/workloads/controllers/cron-jobs/), which you + can use to define a series of Jobs that will run based on a schedule, similar to + the Unix tool `cron`. diff --git a/content/en/docs/concepts/workloads/controllers/replicaset.md b/content/en/docs/concepts/workloads/controllers/replicaset.md index e7b36d1b4a014..70967853e8b13 100644 --- a/content/en/docs/concepts/workloads/controllers/replicaset.md +++ b/content/en/docs/concepts/workloads/controllers/replicaset.md @@ -410,3 +410,14 @@ selector requirements as described in the [labels user guide](/docs/concepts/ove As such, ReplicaSets are preferred over ReplicationControllers +## {{% heading "whatsnext" %}} + +* Learn about [Pods](/docs/concepts/workloads/pods). +* Learn about [Deployments](/docs/concepts/workloads/controllers/deployment/). +* [Run a Stateless Application Using a Deployment](/docs/tasks/run-application/run-stateless-application-deployment/), + which relies on ReplicaSets to work. +* `ReplicaSet` is a top-level resource in the Kubernetes REST API. + Read the {{< api-reference page="workload-resources/replica-set-v1" >}} + object definition to understand the API for replica sets. +* Read about [PodDisruptionBudget](/docs/concepts/workloads/pods/disruptions/) and how + you can use it to manage application availability during disruptions. diff --git a/content/en/docs/concepts/workloads/controllers/replicationcontroller.md b/content/en/docs/concepts/workloads/controllers/replicationcontroller.md index 5a10271b010e9..364df7dc7261a 100644 --- a/content/en/docs/concepts/workloads/controllers/replicationcontroller.md +++ b/content/en/docs/concepts/workloads/controllers/replicationcontroller.md @@ -284,6 +284,11 @@ machine-level function, such as machine monitoring or machine logging. These po to a machine lifetime: the pod needs to be running on the machine before other pods start, and are safe to terminate when the machine is otherwise ready to be rebooted/shutdown. -## For more information - -Read [Run Stateless Application Deployment](/docs/tasks/run-application/run-stateless-application-deployment/). +## {{% heading "whatsnext" %}} + +* 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. diff --git a/content/en/docs/concepts/workloads/controllers/statefulset.md b/content/en/docs/concepts/workloads/controllers/statefulset.md index 3f89da5989a70..6b65ba1f3b71c 100644 --- a/content/en/docs/concepts/workloads/controllers/statefulset.md +++ b/content/en/docs/concepts/workloads/controllers/statefulset.md @@ -297,7 +297,18 @@ Please note that this field only works if you enable the `StatefulSetMinReadySec ## {{% heading "whatsnext" %}} +* Learn about [Pods](/docs/concepts/workloads/pods). +* Find out how to use StatefulSets + * Follow an example of [deploying a stateful application](/docs/tutorials/stateful-application/basic-stateful-set/). + * Follow an example of [deploying Cassandra with Stateful Sets](/docs/tutorials/stateful-application/cassandra/). + * Follow an example of [running a replicated stateful application](/docs/tasks/run-application/run-replicated-stateful-application/). + * Learn how to [scale a StatefulSet](/docs/tasks/run-application/scale-stateful-set/). + * Learn what's involved when you [delete a StatefulSet](/docs/tasks/run-application/delete-stateful-set/). + * Learn how to [configure a Pod to use a volume for storage](/docs/tasks/configure-pod-container/configure-volume-storage/). + * Learn how to [configure a Pod to use a PersistentVolume for storage](/docs/tasks/configure-pod-container/configure-persistent-volume-storage/). +* `StatefulSet` is a top-level resource in the Kubernetes REST API. + Read the {{< api-reference page="workload-resources/stateful-set-v1" >}} + object definition to understand the API for stateful sets. +* Read about [PodDisruptionBudget](/docs/concepts/workloads/pods/disruptions/) and how + you can use it to manage application availability during disruptions. -* Follow an example of [deploying a stateful application](/docs/tutorials/stateful-application/basic-stateful-set/). -* Follow an example of [deploying Cassandra with Stateful Sets](/docs/tutorials/stateful-application/cassandra/). -* Follow an example of [running a replicated stateful application](/docs/tasks/run-application/run-replicated-stateful-application/). diff --git a/content/en/docs/concepts/workloads/pods/_index.md b/content/en/docs/concepts/workloads/pods/_index.md index 7132d195295e4..7246536eb009d 100644 --- a/content/en/docs/concepts/workloads/pods/_index.md +++ b/content/en/docs/concepts/workloads/pods/_index.md @@ -309,9 +309,9 @@ in the Pod Lifecycle documentation. * Read about [Pod topology spread constraints](/docs/concepts/workloads/pods/pod-topology-spread-constraints/). * Read about [PodDisruptionBudget](/docs/concepts/workloads/pods/disruptions/) and how you can use it to manage application availability during disruptions. * Pod is a top-level resource in the Kubernetes REST API. - The [Pod](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#pod-v1-core) + The {{< api-reference page="workload-resources/pod-v1" >}} object definition describes the object in detail. -* [The Distributed System Toolkit: Patterns for Composite Containers](https://kubernetes.io/blog/2015/06/the-distributed-system-toolkit-patterns) explains common layouts for Pods with more than one container. +* [The Distributed System Toolkit: Patterns for Composite Containers](/blog/2015/06/the-distributed-system-toolkit-patterns/) explains common layouts for Pods with more than one container. To understand the context for why Kubernetes wraps a common Pod API in other resources (such as {{< glossary_tooltip text="StatefulSets" term_id="statefulset" >}} or {{< glossary_tooltip text="Deployments" term_id="deployment" >}}), you can read about the prior art, including: From ba50c160da2069582bca15112ee22e2b390c7d10 Mon Sep 17 00:00:00 2001 From: Avinesh Tripathi Date: Tue, 28 Sep 2021 09:59:34 +0530 Subject: [PATCH 066/115] updated README-hi.md --- README-hi.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README-hi.md b/README-hi.md index 01d119a22b4d9..1c7c0bfc1f0a0 100644 --- a/README-hi.md +++ b/README-hi.md @@ -7,7 +7,7 @@ ## डॉक्स में योगदान देना -आप अपने GitHub खाते में इस रिपॉजिटरी की एक copy बनाने के लिए स्क्रीन के ऊपरी-दाएँ क्षेत्र में **Fork** बटन पर क्लिक करें। इस copy को *Fork* कहा जाता है। अपने fork में कोई भी परिवर्तन करना चाहते हैं, और जब आप उन परिवर्तनों को हमारे पास भेजने के लिए तैयार हों, तो अपने fork पर जाएं और हमें इसके बारे में बताने के लिए एक नया pull request बनाएं। +आप अपने GitHub खाते में इस रिपॉजिटरी की एक copy बनाने के लिए स्क्रीन के ऊपरी-दाएँ क्षेत्र में **Fork** बटन पर क्लिक करें। इस copy को *Fork* कहा जाता है। अपने fork में परिवर्तन करने के बाद जब आप उनको हमारे पास भेजने के लिए तैयार हों, तो अपने fork पर जाएं और हमें इसके बारे में बताने के लिए एक नया pull request बनाएं। एक बार जब आपका pull request बन जाता है, तो एक कुबरनेट्स समीक्षक स्पष्ट, कार्रवाई योग्य प्रतिक्रिया प्रदान करने की जिम्मेदारी लेगा। pull request के मालिक के रूप में, **यह आपकी जिम्मेदारी है कि आप कुबरनेट्स समीक्षक द्वारा प्रदान की गई प्रतिक्रिया को संबोधित करने के लिए अपने pull request को संशोधित करें।** From d3a5a71e884389abf4332f6152cca13744923cb3 Mon Sep 17 00:00:00 2001 From: Nitesh Seram Date: Tue, 28 Sep 2021 10:49:37 +0530 Subject: [PATCH 067/115] remove addonmanager.kubernetes.io labels --- .../en/examples/admin/dns/dns-horizontal-autoscaler.yaml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/content/en/examples/admin/dns/dns-horizontal-autoscaler.yaml b/content/en/examples/admin/dns/dns-horizontal-autoscaler.yaml index ada91c1a350d8..b4bf65834add7 100644 --- a/content/en/examples/admin/dns/dns-horizontal-autoscaler.yaml +++ b/content/en/examples/admin/dns/dns-horizontal-autoscaler.yaml @@ -3,15 +3,11 @@ apiVersion: v1 metadata: name: kube-dns-autoscaler namespace: kube-system - labels: - addonmanager.kubernetes.io/mode: Reconcile --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: system:kube-dns-autoscaler - labels: - addonmanager.kubernetes.io/mode: Reconcile rules: - apiGroups: [""] resources: ["nodes"] @@ -32,8 +28,6 @@ kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: system:kube-dns-autoscaler - labels: - addonmanager.kubernetes.io/mode: Reconcile subjects: - kind: ServiceAccount name: kube-dns-autoscaler @@ -52,7 +46,6 @@ metadata: labels: k8s-app: kube-dns-autoscaler kubernetes.io/cluster-service: "true" - addonmanager.kubernetes.io/mode: Reconcile spec: selector: matchLabels: From 9fe3e942ff632a41017c601919d4b075423e856e Mon Sep 17 00:00:00 2001 From: kartik494 Date: Wed, 22 Sep 2021 11:17:54 +0530 Subject: [PATCH 068/115] Added note to improve access modes documentation --- .../concepts/storage/persistent-volumes.md | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/content/en/docs/concepts/storage/persistent-volumes.md b/content/en/docs/concepts/storage/persistent-volumes.md index a029ceaeda17f..cd7137bedc9be 100644 --- a/content/en/docs/concepts/storage/persistent-volumes.md +++ b/content/en/docs/concepts/storage/persistent-volumes.md @@ -412,11 +412,22 @@ A PersistentVolume can be mounted on a host in any way supported by the resource The access modes are: -* ReadWriteOnce -- the volume can be mounted as read-write by a single node -* ReadOnlyMany -- the volume can be mounted read-only by many nodes -* ReadWriteMany -- the volume can be mounted as read-write by many nodes -* ReadWriteOncePod -- the volume can be mounted as read-write by a single Pod. - This is only supported for CSI volumes and Kubernetes version 1.22+. +`ReadWriteOnce` +: the volume can be mounted as read-write by a single node. ReadWriteOnce access mode still can allow multiple pods to access the volume when the pods are running on the same node. + +`ReadOnlyMany` +: the volume can be mounted as read-only by many nodes. + +`ReadWriteMany` +: the volume can be mounted as read-write by many nodes. + + `ReadWriteOncePod` +: the volume can be mounted as read-write by a single Pod. Use ReadWriteOncePod access mode if you want to ensure that only one pod across whole cluster can read that PVC or write to it. This is only supported for CSI volumes and Kubernetes version 1.22+. + + + +The blog article [Introducing Single Pod Access Mode for PersistentVolumes](/blog/2021/09/13/read-write-once-pod-access-mode-alpha/) covers this in more detail. + In the CLI, the access modes are abbreviated to: From a7662f40fc7837e7221595a21905dff2951fef39 Mon Sep 17 00:00:00 2001 From: Tim Bannister Date: Tue, 28 Sep 2021 18:22:54 +0100 Subject: [PATCH 069/115] Update publication date --- ....md => 2021-09-29-data-duplication-in-data-heavy-k8s-env.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename content/en/blog/_posts/{2021-09-07-data-duplication-in-data-heavy-k8s-env.md => 2021-09-29-data-duplication-in-data-heavy-k8s-env.md} (99%) diff --git a/content/en/blog/_posts/2021-09-07-data-duplication-in-data-heavy-k8s-env.md b/content/en/blog/_posts/2021-09-29-data-duplication-in-data-heavy-k8s-env.md similarity index 99% rename from content/en/blog/_posts/2021-09-07-data-duplication-in-data-heavy-k8s-env.md rename to content/en/blog/_posts/2021-09-29-data-duplication-in-data-heavy-k8s-env.md index bec8c0b892fa3..42e918669268c 100644 --- a/content/en/blog/_posts/2021-09-07-data-duplication-in-data-heavy-k8s-env.md +++ b/content/en/blog/_posts/2021-09-29-data-duplication-in-data-heavy-k8s-env.md @@ -1,7 +1,7 @@ --- layout: blog title: "How to Handle Data Duplication in Data-Heavy Kubernetes Environments" -date: 2021-09-07 +date: 2021-09-29 slug: how-to-handle-data-duplication-in-data-heavy-kubernetes-environments --- From 968dbbaaadb0ee778eb4a07b9f4a021158bd9cee Mon Sep 17 00:00:00 2001 From: Tim Bannister Date: Tue, 28 Sep 2021 18:44:42 +0100 Subject: [PATCH 070/115] Restrict width of blog figures for wide viewports Docsy uses Bootstrap to restrict the width of text paragraphs when the viewport is very wide. Also apply that to

elements within blog articles. --- assets/scss/_custom.scss | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/assets/scss/_custom.scss b/assets/scss/_custom.scss index e7f090234621a..7d6aa6784fbf8 100644 --- a/assets/scss/_custom.scss +++ b/assets/scss/_custom.scss @@ -635,6 +635,13 @@ body.td-documentation { } } +// Match Docsy-imposed max width on text body +@media (min-width: 1200px) { + body.td-blog main .td-content > figure { + max-width: 80%; + } +} + .td-content { table code { background-color: inherit !important; From 6a4dddd251f13f1c87a271544a048baaafe9a496 Mon Sep 17 00:00:00 2001 From: Jay Pipes Date: Thu, 12 Aug 2021 16:21:27 -0400 Subject: [PATCH 071/115] clarify declarative API in custom controller docs The content describing a declarative API in the custom controller section of the custom resources doc was confusing: > A declarative API allows you to declare or specify the desired state of your resource **and tries to keep the current state of Kubernetes objects in sync with the desired state**. The controller interprets the structured data as a record of the user's desired state, and continually maintains this state. (emphasis added) It is not the declarative API that tries to keep the current state of the objects in sync with the desired state. It's the controller that does that. I've reworded this paragraph to hopefully clarify this. Closes Issue #29348 Signed-off-by: Jay Pipes --- .../api-extension/custom-resources.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/content/en/docs/concepts/extend-kubernetes/api-extension/custom-resources.md b/content/en/docs/concepts/extend-kubernetes/api-extension/custom-resources.md index f37a71f278a39..0746e9f4f1702 100644 --- a/content/en/docs/concepts/extend-kubernetes/api-extension/custom-resources.md +++ b/content/en/docs/concepts/extend-kubernetes/api-extension/custom-resources.md @@ -35,11 +35,11 @@ On their own, custom resources let you store and retrieve structured data. When you combine a custom resource with a *custom controller*, custom resources provide a true _declarative API_. -A [declarative API](/docs/concepts/overview/kubernetes-api/) -allows you to _declare_ or specify the desired state of your resource and tries to -keep the current state of Kubernetes objects in sync with the desired state. -The controller interprets the structured data as a record of the user's -desired state, and continually maintains this state. +The Kubernetes [declarative API](/docs/concepts/overview/kubernetes-api/) +enforces a separation of responsibilities. You declare the desired state of +your resource. The Kubernetes controller keeps the current state of Kubernetes +objects in sync with your declared desired state. This is in contrast to an +imperative API, where you *instruct* a server what to do. You can deploy and update a custom controller on a running cluster, independently of the cluster's lifecycle. Custom controllers can work with any kind of resource, From 2cf2b1937e647f0d034053bc8929f7d8a60f26b7 Mon Sep 17 00:00:00 2001 From: "Khaled (Kal) Henidak" Date: Mon, 20 Sep 2021 18:00:47 +0000 Subject: [PATCH 072/115] add a note re selectorless services and proxy --- content/en/docs/concepts/services-networking/service.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/content/en/docs/concepts/services-networking/service.md b/content/en/docs/concepts/services-networking/service.md index db28918c983a5..24874355a5776 100644 --- a/content/en/docs/concepts/services-networking/service.md +++ b/content/en/docs/concepts/services-networking/service.md @@ -183,6 +183,13 @@ Accessing a Service without a selector works the same as if it had a selector. In the example above, traffic is routed to the single endpoint defined in the YAML: `192.0.2.42:9376` (TCP). +{{< note >}} +The Kubernetes API server does not allow proxying to endpoints that are not mapped to +pods. Actions such as `kubectl proxy ` where the service has no +selector will fail due to this constraint. This prevents the Kubernetes API server +from being used as a proxy to endpoints the caller may not be authorized to access. +{{< /note >}} + An ExternalName Service is a special case of Service that does not have selectors and uses DNS names instead. For more information, see the [ExternalName](#externalname) section later in this document. From ba6cfa2784f77bcc319039ba5aed92bf9f738fcb Mon Sep 17 00:00:00 2001 From: howieyuen Date: Sun, 26 Sep 2021 16:41:21 +0800 Subject: [PATCH 073/115] [zh]translate indexed-parallel-processing-static.md --- .../job/indexed-parallel-processing-static.md | 277 ++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100644 content/zh/docs/tasks/job/indexed-parallel-processing-static.md diff --git a/content/zh/docs/tasks/job/indexed-parallel-processing-static.md b/content/zh/docs/tasks/job/indexed-parallel-processing-static.md new file mode 100644 index 0000000000000..8b4e940373525 --- /dev/null +++ b/content/zh/docs/tasks/job/indexed-parallel-processing-static.md @@ -0,0 +1,277 @@ +--- +title: 使用索引作业完成静态工作分配下的并行处理 +content_type: task +min-kubernetes-server-version: v1.21 +weight: 30 +--- + + +{{< feature-state for_k8s_version="v1.22" state="beta" >}} + + + + + +在此示例中,你将运行一个使用多个并行工作进程的 Kubernetes Job。 +每个 worker 都是在自己的 Pod 中运行的不同容器。 +Pod 具有控制平面自动设置的 _索引编号(index number)_, +这些编号使得每个 Pod 能识别出要处理整个任务的哪个部分。 + + +Pod 索引在{{}} +`batch.kubernetes.io/job-completion-index` 中呈现,具体表示为一个十进制值字符串。 +为了让容器化的任务进程获得此索引,你可以使用 +[downward API](/zh/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/#the-downward-api) +机制发布注解的值。为方便起见, +控制平面自动设置 downward API 以在 `JOB_COMPLETION_INDEX` 环境变量中公开索引。 + + +以下是此示例中步骤的概述: + +1. **定义使用带索引完成信息的 Job 清单**。 + Downward API 使你可以将 Pod 索引注释作为环境变量或文件传递给容器。 +2. **根据该清单启动一个带索引(`Indexed`)的 Job**。 + +## {{% heading "prerequisites" %}} + + +你应该已经熟悉 [Job](/zh/docs/concepts/workloads/controllers/job/) 的基本的、非并行的用法。 + +{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} + + + + +## 选择一种方法 + + +要从工作程序访问工作项,你有几个选择: + +1. 读取 `JOB_COMPLETION_INDEX` 环境变量。Job + {{< glossary_tooltip text="控制器" term_id="controller" >}} + 自动将此变量链接到包含完成索引的注解。 +1. 读取包含完整索引的文件。 +1. 假设你无法修改程序,你可以使用脚本包装它, + 该脚本使用上述任意方法读取索引并将其转换为程序可以用作输入的内容。 + + +对于此示例,假设你选择了方法 3 并且想要运行 +[rev](https://man7.org/linux/man-pages/man1/rev.1.html) 实用程序。 +这个程序接受一个文件作为参数并按逆序打印其内容。 + +```shell +rev data.txt +``` + + +你将使用 [`busybox`](https://hub.docker.com/_/busybox) 容器映像中的 `rev` 工具。 + + +由于这只是一个例子,每个 Pod 只做一小部分工作(反转一个短字符串)。 +例如,在实际工作负载中,你可能会创建一个表示基于场景数据制作 60 秒视频的任务的 Job 。 +视频渲染 Job 中的每个工作项都将渲染该视频剪辑的特定帧。 +索引完成意味着 Job 中的每个 Pod 都知道通过从剪辑开始计算帧数,来确定渲染和发布哪一帧,。 + + +## 定义索引作业 + + +这是一个使用 `Indexed` 完成模式的示例 Job 清单: + +{{< codenew language="yaml" file="application/job/indexed-job.yaml" >}} + + +在上面的示例中,你使用 Job 控制器为所有容器设置的内置 `JOB_COMPLETION_INDEX` 环境变量。 +[Init 容器](/zh/docs/concepts/workloads/pods/init-containers/) +将索引映射到一个静态值,并将其写入一个文件,该文件通过 +[emptyDir 卷](/zh/docs/concepts/storage/volumes/#emptydir) +与运行 worker 的容器共享。或者,你可以 +[通过 Downward API 定义自己的环境变量](/zh/docs/tasks/inject-data-application/environment-variable-expose-pod-information/) +将索引发布到容器。你还可以选择从 +[包含 ConfigMap 的环境变量或文件](/zh/docs/tasks/configure-pod-container/configure-pod-configmap/) +加载值列表。 + + +或者也可以直接 +[使用 Downward API 将注解值作为卷文件传递](/zh/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/#store-pod-fields), +如下例所示: + +{{< codenew language="yaml" file="application/job/indexed-job-vol.yaml" >}} + + +## 执行 Job + + +现在执行 Job: + +```shell +# 使用第一种方法(依赖于 $JOB_COMPLETION_INDEX) +kubectl apply -f https://kubernetes.io/examples/application/job/indexed-job.yaml +``` + + +当你创建此 Job 时,控制平面会创建一系列 Pod,每个索引都由你指定。 +`.spec.parallelism` 的值决定了一次可以运行多少个, +而 `.spec.completions` 决定了 Job 总共创建了多少个 Pod。 + +因为 `.spec.parallelism` 小于 `.spec.completions`, +控制平面在启动更多 Pod 之前,等待部分第一批 Pod 完成。 + +创建 Job 后,稍等片刻,然后检查进度: + +```shell +kubectl describe jobs/indexed-job +``` + + +输出类似于: + +``` +Name: indexed-job +Namespace: default +Selector: controller-uid=bf865e04-0b67-483b-9a90-74cfc4c3e756 +Labels: controller-uid=bf865e04-0b67-483b-9a90-74cfc4c3e756 + job-name=indexed-job +Annotations: +Parallelism: 3 +Completions: 5 +Start Time: Thu, 11 Mar 2021 15:47:34 +0000 +Pods Statuses: 2 Running / 3 Succeeded / 0 Failed +Completed Indexes: 0-2 +Pod Template: + Labels: controller-uid=bf865e04-0b67-483b-9a90-74cfc4c3e756 + job-name=indexed-job + Init Containers: + input: + Image: docker.io/library/bash + Port: + Host Port: + Command: + bash + -c + items=(foo bar baz qux xyz) + echo ${items[$JOB_COMPLETION_INDEX]} > /input/data.txt + + Environment: + Mounts: + /input from input (rw) + Containers: + worker: + Image: docker.io/library/busybox + Port: + Host Port: + Command: + rev + /input/data.txt + Environment: + Mounts: + /input from input (rw) + Volumes: + input: + Type: EmptyDir (a temporary directory that shares a pod's lifetime) + Medium: + SizeLimit: +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal SuccessfulCreate 4s job-controller Created pod: indexed-job-njkjj + Normal SuccessfulCreate 4s job-controller Created pod: indexed-job-9kd4h + Normal SuccessfulCreate 4s job-controller Created pod: indexed-job-qjwsz + Normal SuccessfulCreate 1s job-controller Created pod: indexed-job-fdhq5 + Normal SuccessfulCreate 1s job-controller Created pod: indexed-job-ncslj +``` + + +在此示例中,你使用每个索引的自定义值运行 Job。 +你可以检查其中一个 Pod 的输出: + +```shell +kubectl logs indexed-job-fdhq5 # 更改它以匹配来自该 Job 的 Pod 的名称 +``` + + +输出类似于: + +``` +xuq +``` \ No newline at end of file From 640ca8aec89c8aee8a5150a1af541c13d5132f4f Mon Sep 17 00:00:00 2001 From: Tim Bannister Date: Tue, 24 Aug 2021 14:57:20 +0100 Subject: [PATCH 074/115] Tidy Windows node introduction Partial tidying to bring this page more in line with the Kubernetes documentation style guide. Co-authored-by: Shannon Kularathna --- .../windows/intro-windows-in-kubernetes.md | 1904 +++++++---------- 1 file changed, 767 insertions(+), 1137 deletions(-) diff --git a/content/en/docs/setup/production-environment/windows/intro-windows-in-kubernetes.md b/content/en/docs/setup/production-environment/windows/intro-windows-in-kubernetes.md index c3757824c5493..f395de9397c33 100644 --- a/content/en/docs/setup/production-environment/windows/intro-windows-in-kubernetes.md +++ b/content/en/docs/setup/production-environment/windows/intro-windows-in-kubernetes.md @@ -1,1335 +1,965 @@ --- -title: Intro to Windows support in Kubernetes -content_type: concept -weight: 65 reviewers: - jayunit100 - jsturtevant - marosset - perithompson +title: Windows containers in Kubernetes +content_type: concept +weight: 65 --- -Windows applications constitute a large portion of the services and -applications that run in many organizations. -[Windows containers](https://aka.ms/windowscontainers) provide a modern way to -encapsulate processes and package dependencies, making it easier to use DevOps -practices and follow cloud native patterns for Windows applications. -Kubernetes has become the defacto standard container orchestrator, and the -release of Kubernetes 1.14 includes production support for scheduling Windows -containers on Windows nodes in a Kubernetes cluster, enabling a vast ecosystem -of Windows applications to leverage the power of Kubernetes. Organizations -with investments in Windows-based applications and Linux-based applications -don't have to look for separate orchestrators to manage their workloads, -leading to increased operational efficiencies across their deployments, -regardless of operating system. +Windows applications constitute a large portion of the services and applications that +run in many organizations. [Windows containers](https://aka.ms/windowscontainers) +provide a way to encapsulate processes and package dependencies, making it easier +to use DevOps practices and follow cloud native patterns for Windows applications. + +Organizations with investments in Windows-based applications and Linux-based +applications don't have to look for separate orchestrators to manage their workloads, +leading to increased operational efficiencies across their deployments, regardless +of operating system. -## Windows containers in Kubernetes +## Windows nodes in Kubernetes -To enable the orchestration of Windows containers in Kubernetes, include -Windows nodes in your existing Linux cluster. Scheduling Windows containers in +To enable the orchestration of Windows containers in Kubernetes, include Windows nodes +in your existing Linux cluster. Scheduling Windows containers in {{< glossary_tooltip text="Pods" term_id="pod" >}} on Kubernetes is similar to scheduling Linux-based containers. In order to run Windows containers, your Kubernetes cluster must include -multiple operating systems, with control plane nodes running Linux and workers -running either Windows or Linux depending on your workload needs. Windows -Server 2019 is the only Windows operating system supported, enabling -[Kubernetes Node](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/architecture/architecture.md#the-kubernetes-node) -on Windows (including kubelet, -[container runtime](https://docs.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/containerd), -and kube-proxy). For a detailed explanation of Windows distribution channels -see the [Microsoft documentation](https://docs.microsoft.com/en-us/windows-server/get-started-19/servicing-channels-19). - -The Kubernetes control plane, including the -[master components](/docs/concepts/overview/components/), -continues to run on Linux. -There are no plans to have a Windows-only Kubernetes cluster. - -In this document, when we talk about Windows containers we mean Windows -containers with process isolation. Windows containers with -[Hyper-V isolation](https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/hyperv-container) -is planned for a future release. - -## Supported Functionality and Limitations - -### Supported Functionality - -#### Windows OS Version Support - -Refer to the following table for Windows operating system support in -Kubernetes. A single heterogeneous Kubernetes cluster can have both Windows -and Linux worker nodes. Windows containers have to be scheduled on Windows -nodes and Linux containers on Linux nodes. - -| Kubernetes version | Windows Server LTSC releases | Windows Server SAC releases | -| --- | --- | --- | --- | -| *Kubernetes v1.20* | Windows Server 2019 | Windows Server ver 1909, Windows Server ver 2004 | -| *Kubernetes v1.21* | Windows Server 2019 | Windows Server ver 2004, Windows Server ver 20H2 | -| *Kubernetes v1.22* | Windows Server 2019 | Windows Server ver 2004, Windows Server ver 20H2 | - -Information on the different Windows Server servicing channels including their -support models can be found at -[Windows Server servicing channels](https://docs.microsoft.com/en-us/windows-server/get-started-19/servicing-channels-19). - -We don't expect all Windows customers to update the operating system for their -apps frequently. Upgrading your applications is what dictates and necessitates -upgrading or introducing new nodes to the cluster. For the customers that -chose to upgrade their operating system for containers running on Kubernetes, -we will offer guidance and step-by-step instructions when we add support for a -new operating system version. This guidance will include recommended upgrade -procedures for upgrading user applications together with cluster nodes. -Windows nodes adhere to Kubernetes -[version-skew policy](/docs/setup/release/version-skew-policy/) (node to control plane -versioning) the same way as Linux nodes do today. - - -The Windows Server Host Operating System is subject to the -[Windows Server ](https://www.microsoft.com/en-us/cloud-platform/windows-server-pricing) -licensing. The Windows Container images are subject to the -[Supplemental License Terms for Windows containers](https://docs.microsoft.com/en-us/virtualization/windowscontainers/images-eula). - -Windows containers with process isolation have strict compatibility rules, -[where the host OS version must match the container base image OS version](https://docs.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/version-compatibility). -Once we support Windows containers with Hyper-V isolation in Kubernetes, the -limitation and compatibility rules will change. - -#### Pause Image +multiple operating systems. +While you can only run the {{< glossary_tooltip text="control plane" term_id="control-plane" >}} on Linux, you can deploy worker nodes running either Windows or Linux depending on your workload needs. + +Windows {{< glossary_tooltip text="nodes" term_id="node" >}} are +[supported](#windows-os-version-support) provided that the operating system is +Windows Server 2019. + +This document uses the term *Windows containers* to mean Windows containers with +process isolation. Kubernetes does not support running Windows containers with +[Hyper-V isolation](https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/hyperv-container). + +## Resource management + +On Linux nodes, {{< glossary_tooltip text="cgroups" term_id="cgroup" >}} are used +as a pod boundary for resource control. Containers are created within that boundary +for network, process and file system isolation. The Linux cgroup APIs can be used +to gather CPU, I/O, and memory use statistics. + +In contrast, Windows uses a _job object_ per container with a system namespace filter +to contain all processes in a container and provide logical isolation from the +host. +(Job objects are a Windows process isolation mechanism and are different from +what Kubernetes refers to as a {{< glossary_tooltip term_id="job" text="Job" >}}). + +There is no way to run a Windows container without the namespace filtering in +place. This means that system privileges cannot be asserted in the context of the +host, and thus privileged containers are not available on Windows. +Containers cannot assume an identity from the host because the Security Account Manager +(SAM) is separate. + +#### Memory reservations {#resource-management-memory} + +Windows does not have an out-of-memory process killer as Linux does. Windows always +treats all user-mode memory allocations as virtual, and pagefiles are mandatory +(on Linux, the kubelet will by default not start with swap space enabled). + +Windows nodes do not overcommit memory for processes running in containers. The +net effect is that Windows won't reach out of memory conditions the same way Linux +does, and processes page to disk instead of being subject to out of memory (OOM) +termination. If memory is over-provisioned and all physical memory is exhausted, +then paging can slow down performance. + +You can place bounds on memory use for workloads using the kubelet +parameters `--kubelet-reserve` and/or `--system-reserve`; these account +for memory usage on the node (outside of containers), and reduce +[NodeAllocatable](/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable)). +As you deploy workloads, set resource limits on containers. This also subtracts from +`NodeAllocatable` and prevents the scheduler from adding more pods once a node is full. + +{{< note >}} +When you set memory resource limits for Windows containers, you should either set a +limit and leave the memory request unspecified, or set the request equal to the limit. +{{< /note >}} + +On Windows, good practice to avoid over-provisioning is to configure the kubelet +with a system reserved memory of at least 2GiB to account for Windows, Kubernetes +and container runtime overheads. + +#### CPU reservations {#resource-management-cpu} + +To account for CPU use by the operating system, the container runtime, and by +Kubernetes host processes such as the kubelet, you can (and should) reserve a +percentage of total CPU. You should determine this CPU reservation taking account of +to the number of CPU cores available on the node. To decide on the CPU percentage to +reserve, identify the maximum pod density for each node and monitor the CPU usage of +the system services running there, then choose a value that meets your workload needs. + +You can place bounds on CPU usage for workloads using the +kubelet parameters `--kubelet-reserve` and/or `--system-reserve` to +account for CPU usage on the node (outside of containers). +This reduces `NodeAllocatable`. +The cluster-wide scheduler then takes this reservation into account when determining +pod placement. + +On Windows, the kubelet supports a command-line flag to set the priority of the +kubelet process: `--windows-priorityclass`. This flag allows the kubelet process to get +more CPU time slices when compared to other processes running on the Windows host. +More information on the allowable values and their meaning is available at +[Windows Priority Classes](https://docs.microsoft.com/en-us/windows/win32/procthread/scheduling-priorities#priority-class). +To ensure that running Pods do not starve the kubelet of CPU cycles, set this flag to `ABOVE_NORMAL_PRIORITY_CLASS` or above. + +## Compatibility and limitations {#limitations} + +Some node features are only available if you use a specific +[container runtime](#container-runtime); others are not available on Windows nodes, +including: + +* HugePages: not supported for Windows containers +* Privileged containers: not supported for Windows containers +* TerminationGracePeriod: not implemented -Kubernetes maintains a multi-architecture image that includes support for Windows. -For Kubernetes v1.22 the recommended pause image is `k8s.gcr.io/pause:3.5`. -The [source code](https://github.com/kubernetes/kubernetes/tree/master/build/pause) -is available on GitHub. +Not all features of shared namespaces are supported. See [API compatibility](#api) +for more details. -Microsoft maintains a multi-architecture image with Linux and Windows amd64 support at `mcr.microsoft.com/oss/kubernetes/pause:3.5`. -This image is built from the same source as the Kubernetes maintained image but all of the Windows binaries are [authenticode signed](https://docs.microsoft.com/en-us/windows-hardware/drivers/install/authenticode) by Microsoft. -The Microsoft maintained image is recommended for production environments when signed binaries are required. +See [Windows OS version compatibility](#windows-os-version-support) for details on +the Windows versions that Kubernetes is tested against. -#### Compute +From an API and kubectl perspective, Windows containers behave in much the same +way as Linux-based containers. However, there are some notable differences in key +functionality which are outlined in this section. -From an API and kubectl perspective, Windows containers behave in much the -same way as Linux-based containers. However, there are some notable -differences in key functionality which are outlined in the -[limitation section](#limitations). +### Comparison with Linux {#compatibility-linux-similarities} -Key Kubernetes elements work the same way in Windows as they do in Linux. In -this section, we talk about some of the key workload enablers and how they map -to Windows. +Key Kubernetes elements work the same way in Windows as they do in Linux. This +section refers to several key workload enablers and how they map to Windows. * [Pods](/docs/concepts/workloads/pods/) - A Pod is the basic building block of Kubernetes–the smallest and simplest - unit in the Kubernetes object model that you create or deploy. You may not - deploy Windows and Linux containers in the same Pod. All containers in a Pod - are scheduled onto a single Node where each Node represents a specific - platform and architecture. The following Pod capabilities, properties and - events are supported with Windows containers: + A Pod is the basic building block of Kubernetes–the smallest and simplest unit in + the Kubernetes object model that you create or deploy. You may not deploy Windows and + Linux containers in the same Pod. All containers in a Pod are scheduled onto a single + Node where each Node represents a specific platform and architecture. The following + Pod capabilities, properties and events are supported with Windows containers: * Single or multiple containers per Pod with process isolation and volume sharing - * Pod status fields + * Pod `status` fields * Readiness and Liveness probes * postStart & preStop container lifecycle events * ConfigMap, Secrets: as environment variables or volumes - * EmptyDir + * `emptyDir` volumes * Named pipe host mounts * Resource limits -* [Controllers](/docs/concepts/workloads/controllers/) - - Kubernetes controllers handle the desired state of Pods. The following - workload controllers are supported with Windows containers: - +* [Workload resources](/docs/concepts/workloads/controllers/) including: * ReplicaSet - * ReplicationController * Deployments * StatefulSets * DaemonSet * Job * CronJob + * ReplicationController +* {{< glossary_tooltip text="Services" term_id="service" >}} + See [Load balancing and Services](#load-balancing-and-services) for more details. -* [Services](/docs/concepts/services-networking/service/) - - A Kubernetes Service is an abstraction which defines a logical set of Pods - and a policy by which to access them - sometimes called a micro-service. You - can use services for cross-operating system connectivity. In Windows, services - can utilize the following types, properties and capabilities: - - * Service Environment variables - * NodePort - * ClusterIP - * LoadBalancer - * ExternalName - * Headless services - -Pods, Controllers and Services are critical elements to managing Windows +Pods, workload resources, and Services are critical elements to managing Windows workloads on Kubernetes. However, on their own they are not enough to enable the proper lifecycle management of Windows workloads in a dynamic cloud native -environment. We added support for the following features: +environment. Kubernetes also supports: +* `kubectl exec` * Pod and container metrics -* Horizontal Pod Autoscaler support -* kubectl Exec -* Resource Quotas +* {{< glossary_tooltip text="Horizontal pod autoscaling" term_id="horizontal-pod-autoscaler" >}} +* {{< glossary_tooltip text="Resource quotas" term_id="resource-quota" >}} * Scheduler preemption -#### Container Runtime - -##### Docker EE - -{{< feature-state for_k8s_version="v1.14" state="stable" >}} - -Docker EE-basic 19.03+ is the recommended container runtime for all Windows -Server versions. This works with the dockershim code included in the kubelet. - -##### CRI-ContainerD - -{{< feature-state for_k8s_version="v1.20" state="stable" >}} - -{{< glossary_tooltip term_id="containerd" text="ContainerD" >}} 1.4.0+ can -also be used as the container runtime for Windows Kubernetes nodes. - -Learn how to -[install ContainerD on a Windows](/docs/setup/production-environment/container-runtimes/#install-containerd). - -#### Persistent Storage - -Kubernetes [volumes](/docs/concepts/storage/volumes/) enable complex -applications, with data persistence and Pod volume sharing requirements, to be -deployed on Kubernetes. Management of persistent volumes associated with a -specific storage back-end or protocol includes actions such as: -provisioning/de-provisioning/resizing of volumes, attaching/detaching a volume -to/from a Kubernetes node and mounting/dismounting a volume to/from individual -containers in a pod that needs to persist data. The code implementing these -volume management actions for a specific storage back-end or protocol is -shipped in the form of a Kubernetes volume -[plugin](/docs/concepts/storage/volumes/#types-of-volumes). The following -broad classes of Kubernetes volume plugins are supported on Windows: - -##### In-tree Volume Plugins - -Code associated with in-tree volume plugins ship as part of the core -Kubernetes code base. Deployment of in-tree volume plugins do not require -installation of additional scripts or deployment of separate containerized -plugin components. These plugins can handle: provisioning/de-provisioning and -resizing of volumes in the storage backend, attaching/detaching of volumes -to/from a Kubernetes node and mounting/dismounting a volume to/from individual -containers in a pod. The following in-tree plugins support Windows nodes: - -* [awsElasticBlockStore](/docs/concepts/storage/volumes/#awselasticblockstore) -* [azureDisk](/docs/concepts/storage/volumes/#azuredisk) -* [azureFile](/docs/concepts/storage/volumes/#azurefile) -* [gcePersistentDisk](/docs/concepts/storage/volumes/#gcepersistentdisk) -* [vsphereVolume](/docs/concepts/storage/volumes/#vspherevolume) -##### FlexVolume Plugins - -Code associated with [FlexVolume](/docs/concepts/storage/volumes/#flexVolume) -plugins ship as out-of-tree scripts or binaries that need to be deployed -directly on the host. FlexVolume plugins handle attaching/detaching of volumes -to/from a Kubernetes node and mounting/dismounting a volume to/from individual -containers in a pod. Provisioning/De-provisioning of persistent volumes -associated with FlexVolume plugins may be handled through an external -provisioner that is typically separate from the FlexVolume plugins. The -following FlexVolume -[plugins](https://github.com/Microsoft/K8s-Storage-Plugins/tree/master/flexvolume/windows), -deployed as powershell scripts on the host, support Windows nodes: - -* [SMB](https://github.com/microsoft/K8s-Storage-Plugins/tree/master/flexvolume/windows/plugins/microsoft.com~smb.cmd) -* [iSCSI](https://github.com/microsoft/K8s-Storage-Plugins/tree/master/flexvolume/windows/plugins/microsoft.com~iscsi.cmd) - -##### CSI Plugins - -{{< feature-state for_k8s_version="v1.22" state="stable" >}} - -Code associated with {{< glossary_tooltip text="CSI" term_id="csi" >}} plugins -ship as out-of-tree scripts and binaries that are typically distributed as -container images and deployed using standard Kubernetes constructs like -DaemonSets and StatefulSets. CSI plugins handle a wide range of volume -management actions in Kubernetes: provisioning/de-provisioning/resizing of -volumes, attaching/detaching of volumes to/from a Kubernetes node and -mounting/dismounting a volume to/from individual containers in a pod, -backup/restore of persistent data using snapshots and cloning. - -CSI plugins communicate with a CSI node plugin which performs the local storage operations. -On Windows nodes CSI node plugins typically call APIs exposed by the community-managed -[csi-proxy](https://github.com/kubernetes-csi/csi-proxy) which handles the local storage operations. - -Please refer to the deployment guide of the environment where you wish to deploy a Windows CSI plugin -for further details around installation. -You may also refer to the following [installation steps](https://github.com/kubernetes-csi/csi-proxy#installation). - -#### Networking +### Networking on Windows nodes {#compatibility-networking} Networking for Windows containers is exposed through [CNI plugins](/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/). Windows containers function similarly to virtual machines in regards to -networking. Each container has a virtual network adapter (vNIC) which is -connected to a Hyper-V virtual switch (vSwitch). The Host Networking Service -(HNS) and the Host Compute Service (HCS) work together to create containers -and attach container vNICs to networks. HCS is responsible for the management -of containers whereas HNS is responsible for the management of networking -resources such as: +networking. Each container has a virtual network adapter (vNIC) which is connected +to a Hyper-V virtual switch (vSwitch). The Host Networking Service (HNS) and the +Host Compute Service (HCS) work together to create containers and attach container +vNICs to networks. HCS is responsible for the management of containers whereas HNS +is responsible for the management of networking resources such as: * Virtual networks (including creation of vSwitches) * Endpoints / vNICs * Namespaces -* Policies (Packet encapsulations, Load-balancing rules, ACLs, NAT'ing rules, etc.) - -The following service spec types are supported: - -* NodePort -* ClusterIP -* LoadBalancer -* ExternalName - -##### Network modes +* Policies including packet encapsulations, load-balancing rules, ACLs, and NAT rules. + +#### Container networking {#networking} + +The Windows HNS and vSwitch implement namespacing and can +create virtual NICs as needed for a pod or container. However, many configurations such +as DNS, routes, and metrics are stored in the Windows registry database rather than as +files inside `/etc`, which is how Linux stores those configurations. The Windows registry for the container +is separate from that of the host, so concepts like mapping `/etc/resolv.conf` from +the host into a container don't have the same effect they would on Linux. These must +be configured using Windows APIs run in the context of that container. Therefore +CNI implementations need to call the HNS instead of relying on file mappings to pass +network details into the pod or container. + +The following networking functionality is _not_ supported on Windows nodes: + +* Host networking mode +* Local NodePort access from the node itself (works for other nodes or external clients) +* More than 64 backend pods (or unique destination addresses) for a single Service +* IPv6 communication between Windows pods connected to overlay networks +* Local Traffic Policy in non-DSR mode +* Outbound communication using the ICMP protocol via the `win-overlay`, `win-bridge`, or using the Azure-CNI plugin.\ + Specifically, the Windows data plane ([VFP](https://www.microsoft.com/en-us/research/project/azure-virtual-filtering-platform/)) doesn't support ICMP packet transpositions, and this means: + * ICMP packets directed to destinations within the same network (such as pod to pod communication via ping) work as expected and without any limitations; + * TCP/UDP packets work as expected and without any limitations; + * ICMP packets directed to pass through a remote network (e.g. pod to external internet communication via ping) cannot be transposed and thus will not be routed back to their source; + * Since TCP/UDP packets can still be transposed, you can substitute `ping ` with `curl ` to get some debugging insight into connectivity with the outside world. + +Overlay networking support in kube-proxy is a beta feature. In addition, it requires +[KB4482887](https://support.microsoft.com/en-us/help/4482887/windows-10-update-kb4482887) +to be installed on Windows Server 2019. + +#### Network modes Windows supports five different networking drivers/modes: L2bridge, L2tunnel, -Overlay, Transparent, and NAT. In a heterogeneous cluster with Windows and -Linux worker nodes, you need to select a networking solution that is -compatible on both Windows and Linux. The following out-of-tree plugins are -supported on Windows, with recommendations on when to use each CNI: - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Network DriverDescriptionContainer Packet ModificationsNetwork PluginsNetwork Plugin Characteristics
L2bridgeContainers are attached to an external vSwitch. Containers are attached - to the underlay network, although the physical network doesn't need to learn - the container. MACs because they are rewritten on ingress/egress. - - MAC is rewritten to host MAC, IP may be rewritten to host IP using HNS - OutboundNAT policy. - - win-bridge, - Azure-CNI, - Flannel host-gateway uses win-bridge - - win-bridge uses L2bridge network mode, - connects containers to the underlay of hosts, offering best performance. - Requires user-defined routes (UDR) for inter-node connectivity. -
L2Tunnel - This is a special case of l2bridge, but only used on Azure. All packets - are sent to the virtualization host where SDN policy is applied. - - MAC rewritten, IP visible on the underlay network - - Azure-CNI - - Azure-CNI allows integration of containers with Azure vNET, and allows them - to leverage the set of capabilities that - Azure Virtual Network - provides. For example, securely connect to Azure services or use Azure NSGs. - See azure-cni - for some examples. -
Overlay (Overlay networking for Windows in Kubernetes is in Alpha stage) - Containers are given a vNIC connected to an external vSwitch. Each overlay - network gets its own IP subnet, defined by a custom IP prefix.The overlay - network driver uses VXLAN encapsulation. - - Encapsulated with an outer header. - - Win-overlay, - Flannel VXLAN (uses win-overlay) - - win-overlay should be used when virtual container networks are desired to - be isolated from underlay of hosts (e.g. for security reasons). Allows for IPs - to be re-used for different overlay networks (which have different VNID tags) - if you are restricted on IPs in your datacenter. This option requires - KB4489899 on Windows Server - 2019. -
- Transparent (special use case for ovn-kubernetes) - - Requires an external vSwitch. Containers are attached to an external - vSwitch which enables intra-pod communication via logical networks (logical - switches and routers). - - Packet is encapsulated either via - GENEVE, - STT tunneling to reach - pods which are not on the same host.
Packets are forwarded or dropped - via the tunnel metadata information supplied by the ovn network controller. -
- NAT is done for north-south communication. -
- ovn-kubernetes - - Deploy via Ansible. - Distributed ACLs can be applied via Kubernetes policies. IPAM support. - Load-balancing can be achieved without kube-proxy. NATing is done without - using iptables/netsh. -
NAT (not used in Kubernetes) - Containers are given a vNIC connected to an internal vSwitch. DNS/DHCP is - provided using an internal component called - WinNAT. - - MAC and IP is rewritten to host MAC/IP. - - nat - - Included here for completeness -
- -As outlined above, the [Flannel](https://github.com/coreos/flannel) CNI -[meta plugin](https://github.com/containernetworking/plugins/tree/master/plugins/meta/flannel) -is also supported on -[Windows](https://github.com/containernetworking/plugins/tree/master/plugins/meta/flannel#windows-support-experimental) -via the [VXLAN network backend](https://github.com/coreos/flannel/blob/master/Documentation/backends.md#vxlan) -(**alpha support** ; delegates to win-overlay) and -[host-gateway network backend](https://github.com/coreos/flannel/blob/master/Documentation/backends.md#host-gw) -(stable support; delegates to win-bridge). This plugin supports delegating to -one of the reference CNI plugins (win-overlay, win-bridge), to work in -conjunction with Flannel daemon on Windows (Flanneld) for automatic node -subnet lease assignment and HNS network creation. This plugin reads in its own -configuration file (cni.conf), and aggregates it with the environment -variables from the FlannelD generated subnet.env file. It then delegates to -one of the reference CNI plugins for network plumbing, and sends the correct -configuration containing the node-assigned subnet to the IPAM plugin (e.g. -host-local). - -For the node, pod, and service objects, the following network flows are -supported for TCP/UDP traffic: - -* Pod -> Pod (IP) -* Pod -> Pod (Name) -* Pod -> Service (Cluster IP) -* Pod -> Service (PQDN, but only if there are no ".") -* Pod -> Service (FQDN) -* Pod -> External (IP) -* Pod -> External (DNS) -* Node -> Pod -* Pod -> Node - -##### IP address management (IPAM) {#ipam} +Overlay (beta), Transparent, and NAT. In a heterogeneous cluster with Windows and Linux +worker nodes, you need to select a networking solution that is compatible on both +Windows and Linux. The following out-of-tree plugins are supported on Windows, +with recommendations on when to use each CNI: + +| Network Driver | Description | Container Packet Modifications | Network Plugins | Network Plugin Characteristics | +| -------------- | ----------- | ------------------------------ | --------------- | ------------------------------ | +| L2bridge | Containers are attached to an external vSwitch. Containers are attached to the underlay network, although the physical network doesn't need to learn the container MACs because they are rewritten on ingress/egress. | MAC is rewritten to host MAC, IP may be rewritten to host IP using HNS OutboundNAT policy. | [win-bridge](https://github.com/containernetworking/plugins/tree/master/plugins/main/windows/win-bridge), [Azure-CNI](https://github.com/Azure/azure-container-networking/blob/master/docs/cni.md), Flannel host-gateway uses win-bridge | win-bridge uses L2bridge network mode, connects containers to the underlay of hosts, offering best performance. Requires user-defined routes (UDR) for inter-node connectivity. | +| L2Tunnel | This is a special case of l2bridge, but only used on Azure. All packets are sent to the virtualization host where SDN policy is applied. | MAC rewritten, IP visible on the underlay network | [Azure-CNI](https://github.com/Azure/azure-container-networking/blob/master/docs/cni.md) | Azure-CNI allows integration of containers with Azure vNET, and allows them to leverage the set of capabilities that [Azure Virtual Network provides](https://azure.microsoft.com/en-us/services/virtual-network/). For example, securely connect to Azure services or use Azure NSGs. See [azure-cni for some examples](https://docs.microsoft.com/en-us/azure/aks/concepts-network#azure-cni-advanced-networking) | +| Overlay (Overlay networking for Windows in Kubernetes is in *alpha* stage) | Containers are given a vNIC connected to an external vSwitch. Each overlay network gets its own IP subnet, defined by a custom IP prefix.The overlay network driver uses VXLAN encapsulation. | Encapsulated with an outer header. | [Win-overlay](https://github.com/containernetworking/plugins/tree/master/plugins/main/windows/win-overlay), Flannel VXLAN (uses win-overlay) | win-overlay should be used when virtual container networks are desired to be isolated from underlay of hosts (e.g. for security reasons). Allows for IPs to be re-used for different overlay networks (which have different VNID tags) if you are restricted on IPs in your datacenter. This option requires [KB4489899](https://support.microsoft.com/help/4489899) on Windows Server 2019. | +| Transparent (special use case for [ovn-kubernetes](https://github.com/openvswitch/ovn-kubernetes)) | Requires an external vSwitch. Containers are attached to an external vSwitch which enables intra-pod communication via logical networks (logical switches and routers). | Packet is encapsulated either via [GENEVE](https://datatracker.ietf.org/doc/draft-gross-geneve/) or [STT](https://datatracker.ietf.org/doc/draft-davie-stt/) tunneling to reach pods which are not on the same host.
Packets are forwarded or dropped via the tunnel metadata information supplied by the ovn network controller.
NAT is done for north-south communication. | [ovn-kubernetes](https://github.com/openvswitch/ovn-kubernetes) | [Deploy via ansible](https://github.com/openvswitch/ovn-kubernetes/tree/master/contrib). Distributed ACLs can be applied via Kubernetes policies. IPAM support. Load-balancing can be achieved without kube-proxy. NATing is done without using iptables/netsh. | +| NAT (*not used in Kubernetes*) | Containers are given a vNIC connected to an internal vSwitch. DNS/DHCP is provided using an internal component called [WinNAT](https://blogs.technet.microsoft.com/virtualization/2016/05/25/windows-nat-winnat-capabilities-and-limitations/) | MAC and IP is rewritten to host MAC/IP. | [nat](https://github.com/Microsoft/windows-container-networking/tree/master/plugins/nat) | Included here for completeness | + +As outlined above, the [Flannel](https://github.com/coreos/flannel) +CNI [meta plugin](https://github.com/containernetworking/plugins/tree/master/plugins/meta/flannel) +is also [supported](https://github.com/containernetworking/plugins/tree/master/plugins/meta/flannel#windows-support-experimental) on Windows via the +[VXLAN network backend](https://github.com/coreos/flannel/blob/master/Documentation/backends.md#vxlan) (**alpha support** ; delegates to win-overlay) +and [host-gateway network backend](https://github.com/coreos/flannel/blob/master/Documentation/backends.md#host-gw) (stable support; delegates to win-bridge). + +This plugin supports delegating to one of the reference CNI plugins (win-overlay, +win-bridge), to work in conjunction with Flannel daemon on Windows (Flanneld) for +automatic node subnet lease assignment and HNS network creation. This plugin reads +in its own configuration file (cni.conf), and aggregates it with the environment +variables from the FlannelD generated subnet.env file. It then delegates to one of +the reference CNI plugins for network plumbing, and sends the correct configuration +containing the node-assigned subnet to the IPAM plugin (for example: `host-local`). + +For Node, Pod, and Service objects, the following network flows are supported for +TCP/UDP traffic: + +* Pod → Pod (IP) +* Pod → Pod (Name) +* Pod → Service (Cluster IP) +* Pod → Service (PQDN, but only if there are no ".") +* Pod → Service (FQDN) +* Pod → external (IP) +* Pod → external (DNS) +* Node → Pod +* Pod → Node + +#### CNI plugin limitations + +* Windows reference network plugins win-bridge and win-overlay do not implement + [CNI spec](https://github.com/containernetworking/cni/blob/master/SPEC.md) v0.4.0, + due to a missing `CHECK` implementation. +* The Flannel VXLAN CNI plugin has the following limitations on Windows: + +1. Node-pod connectivity isn't possible by design. It's only possible for local pods with Flannel v0.12.0 (or higher). +2. Flannel is restricted to using VNI 4096 and UDP port 4789. See the official + [Flannel VXLAN](https://github.com/coreos/flannel/blob/master/Documentation/backends.md#vxlan) + backend docs for more details on these parameters. + +#### IP address management (IPAM) {#ipam} The following IPAM options are supported on Windows: -* [Host-local](https://github.com/containernetworking/plugins/tree/master/plugins/ipam/host-local) +* [host-local](https://github.com/containernetworking/plugins/tree/master/plugins/ipam/host-local) * HNS IPAM (Inbox platform IPAM, this is a fallback when no IPAM is set) -* [Azure-vnet-ipam](https://github.com/Azure/azure-container-networking/blob/master/docs/ipam.md) (for azure-cni only) +* [azure-vnet-ipam](https://github.com/Azure/azure-container-networking/blob/master/docs/ipam.md) (for azure-cni only) + +#### Load balancing and Services + +A Kubernetes {{< glossary_tooltip text="Service" term_id="service" >}} is an abstraction +that defines a logical set of Pods and a means to access them over a network. +In a cluster that includes Windows nodes, you can use the following types of Service: + + * `NodePort` + * `ClusterIP` + * `LoadBalancer` + * `ExternalName` -##### Load balancing and Services +Windows container networking differs in some important ways from Linux networking. +The [Microsoft documentation for Windows Container Networking](https://docs.microsoft.com/en-us/virtualization/windowscontainers/container-networking/architecture) provides +additional details and background. On Windows, you can use the following settings to configure Services and load balancing behavior: {{< table caption="Windows Service Settings" >}} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureDescriptionSupported Kubernetes versionSupported Windows OS buildHow to enable
Session affinity - Ensures that connections from a particular client are passed to the same - Pod each time. - v1.20+ - Windows Server vNext Insider Preview Build 19551 (or higher) - - Set service.spec.sessionAffinity to "ClientIP" -
Direct Server Return (DSR) - Load balancing mode where the IP address fixups and the LBNAT occurs at - the container vSwitch port directly; service traffic arrives with the source - IP set as the originating pod IP. - v1.20+ - Windows Server 2019 - - Set the following flags in kube-proxy: - --feature-gates="WinDSR=true" --enable-dsr=true -
Preserve-Destination - Skips DNAT of service traffic, thereby preserving the virtual IP of the target - service in packets reaching the backend Pod. Also disables node-node forwarding. - v1.20+Windows Server, version 1903 (or higher) - Set "preserve-destination": "true" in service annotations - and enable DSR in kube-proxy. -
IPv4/IPv6 dual-stack networking - Native IPv4-to-IPv4 in parallel with IPv6-to-IPv6 communications to, from, - and within a cluster - v1.19+Windows Server, version 2004 (or higher) - See IPv4/IPv6 dual-stack -
Client IP preservation - Ensures that source IP of incoming ingress traffic gets preserved. Also - disables node-node forwarding. - v1.20+Windows Server, version 2019 (or higher) - Set service.spec.externalTrafficPolicy to "Local" and enable - DSR in kube-proxy. -
- +| Feature | Description | Supported Kubernetes version | Supported Windows OS build | How to enable | +| ------- | ----------- | ----------------------------- | -------------------------- | ------------- | +| Session affinity | Ensures that connections from a particular client are passed to the same Pod each time. | v1.20+ | [Windows Server vNext Insider Preview Build 19551](https://blogs.windows.com/windowsexperience/2020/01/28/announcing-windows-server-vnext-insider-preview-build-19551/) (or higher) | Set `service.spec.sessionAffinity` to "ClientIP" | +| Direct Server Return (DSR) | Load balancing mode where the IP address fixups and the LBNAT occurs at the container vSwitch port directly; service traffic arrives with the source IP set as the originating pod IP. | v1.20+ | Windows Server 2019 | Set the following flags in kube-proxy: `--feature-gates="WinDSR=true" --enable-dsr=true` | +| Preserve-Destination | Skips DNAT of service traffic, thereby preserving the virtual IP of the target service in packets reaching the backend Pod. Also disables node-node forwarding. | v1.20+ | Windows Server, version 1903 (or higher) | Set `"preserve-destination": "true"` in service annotations and enable DSR in kube-proxy. | +| IPv4/IPv6 dual-stack networking | Native IPv4-to-IPv4 in parallel with IPv6-to-IPv6 communications to, from, and within a cluster | v1.19+ | Windows Server, version 2019 | See [IPv4/IPv6 dual-stack](#ipv4ipv6-dual-stack) | +| Client IP preservation | Ensures that source IP of incoming ingress traffic gets preserved. Also disables node-node forwarding. | v1.20+ | Windows Server, version 2019 | Set `service.spec.externalTrafficPolicy` to "Local" and enable DSR in kube-proxy | {{< /table >}} -#### IPv4/IPv6 dual-stack - -You can enable IPv4/IPv6 dual-stack networking for `l2bridge` networks using -the `IPv6DualStack` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/). See -[enable IPv4/IPv6 dual stack](/docs/concepts/services-networking/dual-stack#enable-ipv4ipv6-dual-stack) -for more details. - -On Windows, using IPv6 with Kubernetes require Windows Server, version 2004 -(kernel version 10.0.19041.610) or later. - -Overlay (VXLAN) networks on Windows do not support dual-stack networking today. - -### Limitations - -Windows is only supported as a worker node in the Kubernetes architecture and -component matrix. This means that a Kubernetes cluster must always include -Linux master nodes, zero or more Linux worker nodes, and zero or more Windows -worker nodes. - -#### Resource Handling - -Linux cgroups are used as a pod boundary for resource controls in Linux. -Containers are created within that boundary for network, process and file -system isolation. The cgroups APIs can be used to gather cpu/io/memory stats. -In contrast, Windows uses a Job object per container with a system namespace -filter to contain all processes in a container and provide logical isolation -from the host. There is no way to run a Windows container without the -namespace filtering in place. This means that system privileges cannot be -asserted in the context of the host, and thus privileged containers are not -available on Windows. Containers cannot assume an identity from the host -because the Security Account Manager (SAM) is separate. - -#### Resource Reservations - -##### Memory Reservations - -Windows does not have an out-of-memory process killer as Linux does. Windows -always treats all user-mode memory allocations as virtual, and pagefiles are -mandatory. The net effect is that Windows won't reach out of memory conditions -the same way Linux does, and processes page to disk instead of being subject -to out of memory (OOM) termination. If memory is over-provisioned and all -physical memory is exhausted, then paging can slow down performance. - -Keeping memory usage within reasonable bounds is possible using the kubelet -parameters `--kubelet-reserve` and/or `--system-reserve` to account for memory -usage on the node (outside of containers). This reduces -[NodeAllocatable](/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable). - -As you deploy workloads, use resource limits (must set only limits or limits -must equal requests) on containers. This also subtracts from NodeAllocatable -and prevents the scheduler from adding more pods once a node is full. - -A best practice to avoid over-provisioning is to configure the kubelet with a -system reserved memory of at least 2GB to account for Windows, Docker, and -Kubernetes processes. - -##### CPU Reservations - -To account for Windows, Docker and other Kubernetes host processes it is -recommended to reserve a percentage of CPU so they are able to respond to -events. This value needs to be scaled based on the number of CPU cores -available on the Windows node.To determine this percentage a user should -identify the maximum pod density for each of their nodes and monitor the CPU -usage of the system services choosing a value that meets their workload needs. - -Keeping CPU usage within reasonable bounds is possible using the kubelet -parameters `--kubelet-reserve` and/or `--system-reserve` to account for CPU -usage on the node (outside of containers). This reduces -[NodeAllocatable](/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable). - -#### Feature Restrictions - -* TerminationGracePeriod: not implemented -* Single file mapping: to be implemented with CRI-ContainerD -* Termination message: to be implemented with CRI-ContainerD -* Privileged Containers: not currently supported in Windows containers -* HugePages: not currently supported in Windows containers -* The existing node problem detector is Linux-only and requires privileged - containers. In general, we don't expect this to be used on Windows because - privileged containers are not supported -* Not all features of shared namespaces are supported (see API section for - more details) - -#### Difference in behavior of flags when compared to Linux - -The behavior of the following kubelet flags is different on Windows nodes as described below: - -* `--kubelet-reserve`, `--system-reserve` , and `--eviction-hard` flags update - Node Allocatable - -* Eviction by using `--enforce-node-allocable` is not implemented. - -* Eviction by using `--eviction-hard` and `--eviction-soft` are not implemented. - -* `MemoryPressure` Condition is not implemented. - -* There are no OOM eviction actions taken by the kubelet. - -* Kubelet running on the windows node does not have memory restrictions. - `--kubelet-reserve` and `--system-reserve` do not set limits on kubelet or - processes running on the host. This means kubelet or a process on the host - could cause memory resource starvation outside the node-allocatable and - scheduler - -* An additional flag to set the priority of the kubelet process is available - on the Windows nodes called `--windows-priorityclass`. This flag allows - kubelet process to get more CPU time slices when compared to other processes - running on the Windows host. More information on the allowable values and - their meaning is available at - [Windows Priority Classes](https://docs.microsoft.com/en-us/windows/win32/procthread/scheduling-priorities#priority-class). - In order for kubelet to always have enough CPU cycles it is recommended to set - this flag to `ABOVE_NORMAL_PRIORITY_CLASS` and above. - -#### Storage - -Windows has a layered filesystem driver to mount container layers and create a -copy filesystem based on NTFS. All file paths in the container are resolved -only within the context of that container. - -* With Docker Volume mounts can only target a directory in the container, and - not an individual file. This limitation does not exist with CRI-containerD. - -* Volume mounts cannot project files or directories back to the host - filesystem +##### Session affinity -* Read-only filesystems are not supported because write access is always - required for the Windows registry and SAM database. However, read-only - volumes are supported +Setting the maximum session sticky time for Windows services using +`service.spec.sessionAffinityConfig.clientIP.timeoutSeconds` is not supported. -* Volume user-masks and permissions are not available. Because the SAM is not - shared between the host & container, there's no mapping between them. All - permissions are resolved within the context of the container +#### DNS {#dns-limitations} + +* ClusterFirstWithHostNet is not supported for DNS. Windows treats all names with a + `.` as a FQDN and skips FQDN resolution +* On Linux, you have a DNS suffix list, which is used when trying to resolve PQDNs. On + Windows, you can only have 1 DNS suffix, which is the DNS suffix associated with that + pod's namespace (mydns.svc.cluster.local for example). Windows can resolve FQDNs + and services or names resolvable with just that suffix. For example, a pod spawned + in the default namespace, will have the DNS suffix **default.svc.cluster.local**. + Inside a Windows pod, you can resolve both **kubernetes.default.svc.cluster.local** + and **kubernetes**, but not the in-betweens, like **kubernetes.default** or + **kubernetes.default.svc**. +* On Windows, there are multiple DNS resolvers that can be used. As these come with + slightly different behaviors, using the `Resolve-DNSName` utility for name query + resolutions is recommended. + +#### IPv6 networking + +Kubernetes on Windows does not support single-stack "IPv6-only" networking. However, +dual-stack IPv4/IPv6 networking for pods and nodes with single-family services +is supported. + +You can enable IPv4/IPv6 dual-stack networking for `l2bridge` networks using the +`IPv6DualStack` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/). +See [enable IPv4/IPv6 dual stack](/docs/concepts/services-networking/dual-stack#enable-ipv4ipv6-dual-stack) for more details. + +{{< note >}} +Overlay (VXLAN) networks on Windows do not support dual-stack networking. +{{< /note >}} + +### Persistent storage {#compatibility-storage} + +Windows has a layered filesystem driver to mount container layers and create a copy +filesystem based on NTFS. All file paths in the container are resolved only within +the context of that container. + +* With Docker, volume mounts can only target a directory in the container, and not + an individual file. This limitation does not exist with CRI-containerD runtime. +* Volume mounts cannot project files or directories back to the host filesystem. +* Read-only filesystems are not supported because write access is always required + for the Windows registry and SAM database. However, read-only volumes are supported. +* Volume user-masks and permissions are not available. Because the SAM is not shared + between the host & container, there's no mapping between them. All permissions are + resolved within the context of the container. As a result, the following storage functionality is not supported on Windows nodes: -* Volume subpath mounts. Only the entire volume can be mounted in a Windows container. +* Volume subpath mounts: only the entire volume can be mounted in a Windows container * Subpath volume mounting for Secrets * Host mount projection -* DefaultMode (due to UID/GID dependency) -* Read-only root filesystem. Mapped volumes still support readOnly +* Read-only root filesystem (mapped volumes still support `readOnly`) * Block device mapping -* Memory as the storage medium -* File system features like uui/guid, per-user Linux filesystem permissions +* Memory as the storage medium (for example, `emptyDir.medium` set to `Memory`) +* File system features like uid/gid; per-user Linux filesystem permissions +* DefaultMode (due to UID/GID dependency) * NFS based storage/volume support * Expanding the mounted volume (resizefs) -#### Networking {#networking-limitations} - -Windows Container Networking differs in some important ways from Linux -networking. The [Microsoft documentation for Windows Container Networking](https://docs.microsoft.com/en-us/virtualization/windowscontainers/container-networking/architecture) -contains additional details and background. - -The Windows host networking service and virtual switch implement namespacing -and can create virtual NICs as needed for a pod or container. However, many -configurations such as DNS, routes, and metrics are stored in the Windows -registry database rather than /etc/... files as they are on Linux. The Windows -registry for the container is separate from that of the host, so concepts like -mapping /etc/resolv.conf from the host into a container don't have the same -effect they would on Linux. These must be configured using Windows APIs run in -the context of that container. Therefore CNI implementations need to call the -HNS instead of relying on file mappings to pass network details into the pod -or container. - -The following networking functionality is not supported on Windows nodes - -* Host networking mode is not available for Windows pods. - -* Local NodePort access from the node itself fails (works for other nodes or - external clients). - -* Accessing service VIPs from nodes will be available with a future release of - Windows Server. - -* A single service can only support up to 64 backend pods / unique destination IPs. - -* Overlay networking support in kube-proxy is a beta feature. In addition, it - requires [KB4482887](https://support.microsoft.com/en-us/help/4482887/windows-10-update-kb4482887) - to be installed on Windows Server 2019. +Kubernetes {{< glossary_tooltip text="volumes" term_id="volume" >}} enable complex +applications, with data persistence and Pod volume sharing requirements, to be deployed +on Kubernetes. Management of persistent volumes associated with a specific storage +back-end or protocol includes actions such as provisioning/de-provisioning/resizing +of volumes, attaching/detaching a volume to/from a Kubernetes node and +mounting/dismounting a volume to/from individual containers in a pod that needs to +persist data. + +The code implementing these volume management actions for a specific storage back-end +or protocol is shipped in the form of a Kubernetes volume +[plugin](/docs/concepts/storage/volumes/#types-of-volumes). +The following broad classes of Kubernetes volume plugins are supported on Windows: + +##### In-tree volume plugins + +Code associated with in-tree volume plugins ship as part of the core Kubernetes code +base. Deployment of in-tree volume plugins do not require installation of additional +scripts or deployment of separate containerized plugin components. These plugins can +handle provisioning/de-provisioning and resizing of volumes in the storage backend, +attaching/detaching of volumes to/from a Kubernetes node and mounting/dismounting a +volume to/from individual containers in a pod. The following in-tree plugins support +persistent storage on Windows nodes: + +* [`awsElasticBlockStore`](/docs/concepts/storage/volumes/#awselasticblockstore) +* [`azureDisk`](/docs/concepts/storage/volumes/#azuredisk) +* [`azureFile`](/docs/concepts/storage/volumes/#azurefile) +* [`gcePersistentDisk`](/docs/concepts/storage/volumes/#gcepersistentdisk) +* [`vsphereVolume`](/docs/concepts/storage/volumes/#vspherevolume) + +#### FlexVolume plugins -* Local Traffic Policy in non-DSR mode. - -* Windows containers connected to overlay networks do not support - communicating over the IPv6 stack. There is outstanding Windows platform - work required to enable this network driver to consume IPv6 addresses and - subsequent Kubernetes work in kubelet, kube-proxy, and CNI plugins. - -* Outbound communication using the ICMP protocol via the win-overlay, - win-bridge, and Azure-CNI plugin. Specifically, the Windows data plane - ([VFP](https://www.microsoft.com/en-us/research/project/azure-virtual-filtering-platform/)) - doesn't support ICMP packet transpositions. This means: - - * ICMP packets directed to destinations within the same network (e.g. pod to - pod communication via ping) work as expected and without any limitations - - * TCP/UDP packets work as expected and without any limitations - - * ICMP packets directed to pass through a remote network (e.g. pod to - external internet communication via ping) cannot be transposed and thus - will not be routed back to their source - - * Since TCP/UDP packets can still be transposed, one can substitute - `ping ` with `curl ` to be able to debug connectivity - to the outside world. +Code associated with [FlexVolume](/docs/concepts/storage/volumes/#flexVolume) +plugins ship as out-of-tree scripts or binaries that need to be deployed directly +on the host. FlexVolume plugins handle attaching/detaching of volumes to/from a +Kubernetes node and mounting/dismounting a volume to/from individual containers +in a pod. Provisioning/De-provisioning of persistent volumes associated +with FlexVolume plugins may be handled through an external provisioner that +is typically separate from the FlexVolume plugins. The following FlexVolume +[plugins](https://github.com/Microsoft/K8s-Storage-Plugins/tree/master/flexvolume/windows), +deployed as PowerShell scripts on the host, support Windows nodes: -These features were added in Kubernetes v1.15: +* [SMB](https://github.com/microsoft/K8s-Storage-Plugins/tree/master/flexvolume/windows/plugins/microsoft.com~smb.cmd) +* [iSCSI](https://github.com/microsoft/K8s-Storage-Plugins/tree/master/flexvolume/windows/plugins/microsoft.com~iscsi.cmd) -* `kubectl port-forward` +#### CSI plugins -##### CNI Plugins +{{< feature-state for_k8s_version="v1.19" state="beta" >}} -* Windows reference network plugins `win-bridge` and `win-overlay` do not - currently implement [CNI spec](https://github.com/containernetworking/cni/blob/master/SPEC.md) - v0.4.0 due to missing "CHECK" implementation. +Code associated with {{< glossary_tooltip text="CSI" term_id="csi" >}} plugins ship +as out-of-tree scripts and binaries that are typically distributed as container +images and deployed using standard Kubernetes constructs like DaemonSets and +StatefulSets. +CSI plugins handle a wide range of volume management actions in Kubernetes: +provisioning/de-provisioning/resizing of volumes, attaching/detaching of volumes +to/from a Kubernetes node and mounting/dismounting a volume to/from individual +containers in a pod, backup/restore of persistent data using snapshots and cloning. +CSI plugins typically consist of node plugins (that run on each node as a DaemonSet) +and controller plugins. + +CSI node plugins (especially those associated with persistent volumes exposed as +either block devices or over a shared file-system) need to perform various privileged +operations like scanning of disk devices, mounting of file systems, etc. These +operations differ for each host operating system. For Linux worker nodes, containerized +CSI node plugins are typically deployed as privileged containers. For Windows worker +nodes, privileged operations for containerized CSI node plugins is supported using +[csi-proxy](https://github.com/kubernetes-csi/csi-proxy), a community-managed, +stand-alone binary that needs to be pre-installed on each Windows node. + +For more details, refer to the deployment guide of the CSI plugin you wish to deploy. + +### Command line options for the kubelet {#kubelet-compatibility} + +The behavior of some kubelet command line options behave differently on Windows, as described below: + +* The `--windows-priorityclass` lets you set the scheduling priority of the kubelet process (see [CPU resource management](#resource-management-cpu)) +* The `--kubelet-reserve`, `--system-reserve` , and `--eviction-hard` flags update [NodeAllocatable](/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable) +* Eviction by using `--enforce-node-allocable` is not implemented +* Eviction by using `--eviction-hard` and `--eviction-soft` are not implemented +* A kubelet running on a Windows node does not have memory + restrictions. `--kubelet-reserve` and `--system-reserve` do not set limits on + kubelet or processes running on the host. This means kubelet or a process on the host + could cause memory resource starvation outside the node-allocatable and scheduler. +* The `MemoryPressure` Condition is not implemented +* The kubelet does not take OOM eviction actions + +### API compatibility {#api} + +There are no differences in how most of the Kubernetes APIs work for Windows. The +subtleties around what's different come down to differences in the OS and container +runtime. In certain situations, some properties on workload resources were designed +under the assumption that they would be implemented on Linux, and fail to run on Windows. -* The Flannel VXLAN CNI has the following limitations on Windows: +At a high level, these OS concepts are different: - 1. Node-pod connectivity isn't possible by design. It's only possible for - local pods with Flannel v0.12.0 (or higher). +* Identity - Linux uses userID (UID) and groupID (GID) which + are represented as integer types. User and group names + are not canonical - they are just an alias in `/etc/groups` + or `/etc/passwd` back to UID+GID. Windows uses a larger binary + [security identifier](https://docs.microsoft.com/en-us/windows/security/identity-protection/access-control/security-identifiers) (SID) + which is stored in the Windows Security Access Manager (SAM) database. This + database is not shared between the host and containers, or between containers. +* File permissions - Windows uses an access control list based on (SIDs), whereas + POSIX systems such as Linux use a bitmask based on object permissions and UID+GID, + plus _optional_ access control lists. +* File paths - the convention on Windows is to use `\` instead of `/`. The Go IO + libraries typically accept both and just make it work, but when you're setting a + path or command line that's interpreted inside a container, `\` may be needed. +* Signals - Windows interactive apps handle termination differently, and can + implement one or more of these: + * A UI thread handles well-defined messages including `WM_CLOSE`. + * Console apps handle Ctrl-C or Ctrl-break using a Control Handler. + * Services register a Service Control Handler function that can accept + `SERVICE_CONTROL_STOP` control codes. + +Container exit codes follow the same convention where 0 is success, and nonzero is failure. +The specific error codes may differ across Windows and Linux. However, exit codes +passed from the Kubernetes components (kubelet, kube-proxy) are unchanged. + +##### Field compatibility for container specifications {#compatibility-v1-pod-spec-containers} + +The following list documents differences between how Pod container specifications +work between Windows and Linux: + +* `limits.cpu` and `limits.memory` - Windows doesn't use hard limits + for CPU allocations. Instead, a share system is used. + The fields based on millicores are scaled into + relative shares that are followed by the Windows scheduler + See [`kuberuntime/helpers_windows.go`](https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/kuberuntime/helpers_windows.go), + and [Implementing resource controls for Windows containers](https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/resource-controls) + in Microsoft's virtualization documentation. +* Huge pages are not implemented in the Windows container + runtime, and are not available. They require [asserting a user + privilege](https://docs.microsoft.com/en-us/windows/desktop/Memory/large-page-support) + that's not configurable for containers. +* `requests.cpu` and `requests.memory` - requests are subtracted + from node available resources, so they can be used to avoid overprovisioning a + node. However, they cannot be used to guarantee resources in an overprovisioned + node. They should be applied to all containers as a best practice if the operator + wants to avoid overprovisioning entirely. +* `securityContext.allowPrivilegeEscalation` - + not possible on Windows; none of the capabilities are hooked up +* `securityContext.capabilities` - + POSIX capabilities are not implemented on Windows +* `securityContext.privileged` - + Windows doesn't support privileged containers +* `securityContext.procMount` - + Windows doesn't have a `/proc` filesystem +* `securityContext.readOnlyRootFilesystem` - + not possible on Windows; write access is required for registry & system + processes to run inside the container +* `EcurityContext.runAsGroup` - + not possible on Windows as there is no GID support +* `ecurityContext.runAsNonRoot` - + Windows does not have a root user. The closest equivalent is `ContainerAdministrator` + which is an identity that doesn't exist on the node. +* `securityContext.runAsUser` - + use [`runAsUsername`](/docs/tasks/configure-pod-container/configure-runasusername) + instead +* `securityContext.seLinuxOptions` - + not possible on Windows as SELinux is Linux-specific +* `terminationMessagePath` - + this has some limitations in that Windows doesn't support mapping single files. The + default value is `/dev/termination-log`, which does work because it does not + exist on Windows by default. + +##### Field compatibility for Pod specifications {#compatibility-v1-pod} + +The following list documents differences between how Pod specifications work between Windows and Linux: + +* `hostIPC` and `hostpid` - host namespace sharing is not possible on Windows +* `hostNetwork` - There is no Windows OS support to share the host network +* `dnsPolicy` - setting the Pod `dnsPolicy` to `ClusterFirstWithHostNet` is + not supported on Windows because host networking is not provided. Pods always + run with a container network. +* `podSecurityContext` (see below) +* `shareProcessNamespace` - this is a beta feature, and depends on Linux namespaces + which are not implemented on Windows. Windows cannot share process namespaces or + the container's root filesystem. Only the network can be shared. +* `terminationGracePeriodSeconds` - this is not fully implemented in Docker on Windows, + see the [GitHub issue](https://github.com/moby/moby/issues/25982). + The behavior today is that the ENTRYPOINT process is sent CTRL_SHUTDOWN_EVENT, + then Windows waits 5 seconds by default, and finally shuts down + all processes using the normal Windows shutdown behavior. The 5 + second default is actually in the Windows registry + [inside the container](https://github.com/moby/moby/issues/25982#issuecomment-426441183), + so it can be overridden when the container is built. +* `volumeDevices` - this is a beta feature, and is not implemented on Windows. + Windows cannot attach raw block devices to pods. +* `volumes` + * If you define an `emptyDir` volume, you cannot set its volume source to `memory`. +* You cannot enable `mountPropagation` for volume mounts as this is not + supported on Windows. - 1. We are restricted to using VNI 4096 and UDP port 4789. The VNI limitation - is being worked on and will be overcome in a future release (open-source - flannel changes). See the official - [Flannel VXLAN](https://github.com/coreos/flannel/blob/master/Documentation/backends.md#vxlan) - backend docs for more details on these parameters. +##### Field compatibility for Pod security context {#compatibility-v1-pod-spec-containers-securitycontext} -##### DNS {#dns-limitations} +None of the Pod [`securityContext`](/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context) fields work on Windows. -* ClusterFirstWithHostNet is not supported for DNS. Windows treats all names - with a '.' as a FQDN and skips PQDN resolution +### Node problem detector -* On Linux, you have a DNS suffix list, which is used when trying to resolve - PQDNs. On Windows, we only have 1 DNS suffix, which is the DNS suffix - associated with that pod's namespace (mydns.svc.cluster.local for example). - Windows can resolve FQDNs and services or names resolvable with only that - suffix. For example, a pod spawned in the default namespace, will have the DNS - suffix `default.svc.cluster.local`. On a Windows pod, you can resolve both - `kubernetes.default.svc.cluster.local` and `kubernetes`, but not the - in-betweens, like `kubernetes.default` or `kubernetes.default.svc`. +The node problem detector (see +[Monitor Node Health](/docs/tasks/debug-application-cluster/monitor-node-health/)) +is not compatible with Windows. -* On Windows, there are multiple DNS resolvers that can be used. As these come - with slightly different behaviors, using the `Resolve-DNSName` utility for - name query resolutions is recommended. +### Pause container -##### IPv6 +In a Kubernetes Pod, an infrastructure or “pause” container is first created +to host the container. In Linux, the cgroups and namespaces that make up a pod +need a process to maintain their continued existence; the pause process provides +this. Containers that belong to the same pod, including infrastructure and worker +containers, share a common network endpoint (same IPv4 and / or IPv6 address, same +network port spaces). Kubernetes uses pause containers to allow for worker containers +crashing or restarting without losing any of the networking configuration. -Kubernetes on Windows does not support single-stack "IPv6-only" networking. -However,dual-stack IPv4/IPv6 networking for pods and nodes with single-family -services is supported. -See [IPv4/IPv6 dual-stack networking](#ipv4ipv6-dual-stack) for more details. +Kubernetes maintains a multi-architecture image that includes support for Windows. +For Kubernetes v1.22 the recommended pause image is `k8s.gcr.io/pause:3.5`. +The [source code](https://github.com/kubernetes/kubernetes/tree/master/build/pause) +is available on GitHub. -##### Session affinity +Microsoft maintains a different multi-architecture image, with Linux and Windows +amd64 support, that you can find as `mcr.microsoft.com/oss/kubernetes/pause:3.5`. +This image is built from the same source as the Kubernetes maintained image but +all of the Windows binaries are [authenticode signed](https://docs.microsoft.com/en-us/windows-hardware/drivers/install/authenticode) by Microsoft. +The Kubernetes project recommends using the Microsoft maintained image if you are +deploying to a production or production-like environment that requires signed +binaries. -Setting the maximum session sticky time for Windows services using -`service.spec.sessionAffinityConfig.clientIP.timeoutSeconds` is not supported. +### Container runtimes {#container-runtime} -##### Security +You need to install a +{{< glossary_tooltip text="container runtime" term_id="container-runtime" >}} +into each node in the cluster so that Pods can run there. -Secrets are written in clear text on the node's volume (as compared to -tmpfs/in-memory on linux). This means customers have to do two things: +The following container runtimes work with Windows: -1. Use file ACLs to secure the secrets file location -1. Use volume-level encryption using - [BitLocker](https://docs.microsoft.com/en-us/windows/security/information-protection/bitlocker/bitlocker-how-to-deploy-on-windows-server) +{{% thirdparty-content %}} -[RunAsUsername](/docs/tasks/configure-pod-container/configure-runasusername) -can be specified for Windows Pod's or Container's to execute the Container -processes as a node-default user. This is roughly equivalent to -[RunAsUser](/docs/concepts/policy/pod-security-policy/#users-and-groups). +#### cri-containerd -Linux specific pod security context privileges such as SELinux, AppArmor, -Seccomp, Capabilities (POSIX Capabilities), and others are not supported. +{{< feature-state for_k8s_version="v1.20" state="stable" >}} -In addition, as mentioned already, privileged containers are not supported on -Windows. +You can use {{< glossary_tooltip term_id="containerd" text="ContainerD" >}} 1.4.0+ +as the container runtime for Kubernetes nodes that run Windows. -#### API +Learn how to [install ContainerD on a Windows node](/docs/setup/production-environment/container-runtimes/#install-containerd). -There are no differences in how most of the Kubernetes APIs work for Windows. -The subtleties around what's different come down to differences in the OS and -container runtime. In certain situations, some properties on workload APIs -such as Pod or Container were designed with an assumption that they are -implemented on Linux, failing to run on Windows. +{{< note >}} +There is a [known limitation](/docs/tasks/configure-pod-container/configure-gmsa/#gmsa-limitations) +when using GMSA with containerd to access Windows network shares, which requires a +kernel patch. +{{< /note >}} -At a high level, these OS concepts are different: +#### Docker EE -* Identity - Linux uses userID (UID) and groupID (GID) which are represented - as integer types. User and group names are not canonical - they are an alias - in `/etc/groups` or `/etc/passwd` back to UID+GID. Windows uses a larger - binary security identifier (SID) which is stored in the Windows Security - Access Manager (SAM) database. This database is not shared between the host - and containers, or between containers. +{{< feature-state for_k8s_version="v1.14" state="stable" >}} -* File permissions - Windows uses an access control list based on SIDs, rather - than a bitmask of permissions and UID+GID +[Docker EE](https://docs.mirantis.com/containers/v3.0/dockeree-products/dee-intro.html)-basic 19.03+ is available as a container runtime for all Windows Server versions. This works with the legacy dockershim adapter. -* File paths - convention on Windows is to use `\` instead of `/`. The Go IO - libraries accept both types of file path separators. However, when you're - setting a path or command line that's interpreted inside a container, `\` may - be needed. +See [Install Docker](https://docs.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/deploy-containers-on-server#install-docker) for more information. -* Signals - Windows interactive apps handle termination differently, and can - implement one or more of these: +## Windows OS version compatibility {#windows-os-version-support} - * A UI thread handles well-defined messages including `WM_CLOSE` +On Windows nodes, strict compatibility rules apply where the host OS version must +match the container base image OS version. Only Windows containers with a container +operating system of Windows Server 2019 are fully supported. - * Console apps handle ctrl-c or ctrl-break using a Control Handler +For Kubernetes v1.22, operating system compatibility for Windows nodes (and Pods) +is as follows: - * Services register a Service Control Handler function that can accept - `SERVICE_CONTROL_STOP` control codes - -Exit Codes follow the same convention where 0 is success, nonzero is failure. -The specific error codes may differ across Windows and Linux. However, exit -codes passed from the Kubernetes components (kubelet, kube-proxy) are -unchanged. - -##### V1.Container - -* V1.Container.ResourceRequirements.limits.cpu and - V1.Container.ResourceRequirements.limits.memory - Windows doesn't use hard - limits for CPU allocations. Instead, a share system is used. The existing - fields based on millicores are scaled into relative shares that are followed - by the Windows scheduler. - See [kuberuntime/helpers_windows.go](https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/kuberuntime/helpers_windows.go), - and [resource controls in Microsoft docs](https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/resource-controls) - - * Huge pages are not implemented in the Windows container runtime, and are - not available. They require - [asserting a user privilege](https://docs.microsoft.com/en-us/windows/desktop/Memory/large-page-support) - that's not configurable for containers. - -* V1.Container.ResourceRequirements.requests.cpu and - V1.Container.ResourceRequirements.requests.memory - Requests are subtracted - from node available resources, so they can be used to avoid overprovisioning a - node. However, they cannot be used to guarantee resources in an - overprovisioned node. They should be applied to all containers as a best - practice if the operator wants to avoid overprovisioning entirely. +Windows Server LTSC release +: Windows Server 2019 -* V1.Container.SecurityContext.allowPrivilegeEscalation - not possible on - Windows, none of the capabilities are hooked up +Windows Server SAC release +: Windows Server version 2004, Windows Server version 20H2 -* V1.Container.SecurityContext.Capabilities - POSIX capabilities are not - implemented on Windows +The Kubernetes [version-skew policy](/docs/setup/release/version-skew-policy/) also applies. -* V1.Container.SecurityContext.privileged - Windows doesn't support privileged - containers +## Security for Windows nodes {#security} -* V1.Container.SecurityContext.procMount - Windows doesn't have a /proc filesystem +On Windows, data from Secrets are written out in clear text onto the node's local +storage (as compared to using tmpfs / in-memory filesystems on Linux). As a cluster +operator, you should take both of the following additional measures: -* V1.Container.SecurityContext.readOnlyRootFilesystem - not possible on - Windows, write access is required for registry & system processes to run - inside the container +1. Use file ACLs to secure the Secrets' file location. +1. Apply volume-level encryption using [BitLocker](https://docs.microsoft.com/en-us/windows/security/information-protection/bitlocker/bitlocker-how-to-deploy-on-windows-server). -* V1.Container.SecurityContext.runAsGroup - not possible on Windows, no GID support +[RunAsUsername](/docs/tasks/configure-pod-container/configure-runasusername) +can be specified for Windows Pods or containers to execute the container +processes as a node-default user. This is roughly equivalent to +[RunAsUser](/docs/concepts/policy/pod-security-policy/#users-and-groups). -* V1.Container.SecurityContext.runAsNonRoot - Windows does not have a root - user. The closest equivalent is ContainerAdministrator which is an identity - that doesn't exist on the node. +Linux-specific pod security context privileges such as SELinux, AppArmor, Seccomp, or capabilities (POSIX capabilities), and others are not supported. -* V1.Container.SecurityContext.runAsUser - not possible on Windows, no UID - support as int. +Privileged containers are [not supported](#compatibility-v1-pod-spec-containers-securitycontext) on Windows. -* V1.Container.SecurityContext.seLinuxOptions - not possible on Windows, no SELinux +## Getting help and troubleshooting {#troubleshooting} -* V1.Container.terminationMessagePath - this has some limitations in that - Windows doesn't support mapping single files. The default value is - `/dev/termination-log`, which does work because it does not exist on Windows by - default. +Your main source of help for troubleshooting your Kubernetes cluster should start +with the [Troubleshooting](/docs/tasks/debug-application-cluster/troubleshooting/) +page. -##### V1.Pod +Some additional, Windows-specific troubleshooting help is included +in this section. Logs are an important element of troubleshooting +issues in Kubernetes. Make sure to include them any time you seek +troubleshooting assistance from other contributors. Follow the +instructions in the +SIG Windows [contributing guide on gathering logs](https://github.com/kubernetes/community/blob/master/sig-windows/CONTRIBUTING.md#gathering-logs). -* V1.Pod.hostIPC, v1.pod.hostpid - host namespace sharing is not possible on Windows +### Node-level troubleshooting {#troubleshooting-node} -* V1.Pod.hostNetwork - There is no Windows OS support to share the host network +1. How do I know `start.ps1` completed successfully? -* V1.Pod.dnsPolicy - `ClusterFirstWithHostNet` is not supported because Host - Networking is not supported on Windows. + You should see kubelet, kube-proxy, and (if you chose Flannel as your networking + solution) flanneld host-agent processes running on your node, with running logs + being displayed in separate PowerShell windows. In addition to this, your Windows + node should be listed as "Ready" in your Kubernetes cluster. -* V1.Pod.podSecurityContext - see V1.PodSecurityContext below +1. Can I configure the Kubernetes node processes to run in the background as services? -* V1.Pod.shareProcessNamespace - this is a beta feature, and depends on Linux - namespaces which are not implemented on Windows. Windows cannot share - process namespaces or the container's root filesystem. Only the network can be - shared. + The kubelet and kube-proxy are already configured to run as native Windows Services, + offering resiliency by re-starting the services automatically in the event of + failure (for example a process crash). You have two options for configuring these + node components as services. -* V1.Pod.terminationGracePeriodSeconds - this is not fully implemented in - Docker on Windows, see: - [reference](https://github.com/moby/moby/issues/25982). The behavior today is - that the `ENTRYPOINT` process is sent `CTRL_SHUTDOWN_EVENT`, then Windows waits 5 - seconds by default, and finally shuts down all processes using the normal - Windows shutdown behavior. The 5 second default is actually in the Windows - registry [inside the container](https://github.com/moby/moby/issues/25982#issuecomment-426441183), - so it can be overridden when the container is built. + 1. As native Windows Services -* V1.Pod.volumeDevices - this is a beta feature, and is not implemented on - Windows. Windows cannot attach raw block devices to pods. + You can run the kubelet and kube-proxy as native Windows Services using `sc.exe`. -* V1.Pod.volumes - EmptyDir, Secret, ConfigMap, HostPath - all work and have - tests in TestGrid + ```powershell + # Create the services for kubelet and kube-proxy in two separate commands + sc.exe create binPath= " --service " - * V1.emptyDirVolumeSource - the Node default medium is disk on Windows. - Memory is not supported, as Windows does not have a built-in RAM disk. + # Please note that if the arguments contain spaces, they must be escaped. + sc.exe create kubelet binPath= "C:\kubelet.exe --service --hostname-override 'minion' " -* V1.VolumeMount.mountPropagation - mount propagation is not supported on Windows. + # Start the services + Start-Service kubelet + Start-Service kube-proxy -##### V1.PodSecurityContext + # Stop the service + Stop-Service kubelet (-Force) + Stop-Service kube-proxy (-Force) -None of the PodSecurityContext fields work on Windows. They're listed here for -reference. + # Query the service status + Get-Service kubelet + Get-Service kube-proxy + ``` -* V1.PodSecurityContext.SELinuxOptions - SELinux is not available on Windows + 1. Using `nssm.exe` + + You can also always use alternative service managers like + [nssm.exe](https://nssm.cc/) to run these processes (flanneld, + kubelet & kube-proxy) in the background for you. You can use this + [sample script](https://github.com/Microsoft/SDN/tree/master/Kubernetes/flannel/register-svc.ps1), + leveraging nssm.exe to register kubelet, kube-proxy, and flanneld.exe to run + as Windows services in the background. + + ```powershell + register-svc.ps1 -NetworkMode -ManagementIP -ClusterCIDR -KubeDnsServiceIP -LogDir + + # NetworkMode = The network mode l2bridge (flannel host-gw, also the default value) or overlay (flannel vxlan) chosen as a network solution + # ManagementIP = The IP address assigned to the Windows node. You can use ipconfig to find this + # ClusterCIDR = The cluster subnet range. (Default value 10.244.0.0/16) + # KubeDnsServiceIP = The Kubernetes DNS service IP (Default value 10.96.0.10) + # LogDir = The directory where kubelet and kube-proxy logs are redirected into their respective output files (Default value C:\k) + ``` -* V1.PodSecurityContext.RunAsUser - provides a UID, not available on Windows + If the above referenced script is not suitable, you can manually configure + `nssm.exe` using the following examples. + + ```powershell + # Register flanneld.exe + nssm install flanneld C:\flannel\flanneld.exe + nssm set flanneld AppParameters --kubeconfig-file=c:\k\config --iface= --ip-masq=1 --kube-subnet-mgr=1 + nssm set flanneld AppEnvironmentExtra NODE_NAME= + nssm set flanneld AppDirectory C:\flannel + nssm start flanneld -* V1.PodSecurityContext.RunAsGroup - provides a GID, not available on Windows + # Register kubelet.exe + # Microsoft releases the pause infrastructure container at mcr.microsoft.com/oss/kubernetes/pause:1.4.1 + nssm install kubelet C:\k\kubelet.exe + nssm set kubelet AppParameters --hostname-override= --v=6 --pod-infra-container-image=mcr.microsoft.com/oss/kubernetes/pause:1.4.1 --resolv-conf="" --allow-privileged=true --enable-debugging-handlers --cluster-dns= --cluster-domain=cluster.local --kubeconfig=c:\k\config --hairpin-mode=promiscuous-bridge --image-pull-progress-deadline=20m --cgroups-per-qos=false --log-dir= --logtostderr=false --enforce-node-allocatable="" --network-plugin=cni --cni-bin-dir=c:\k\cni --cni-conf-dir=c:\k\cni\config + nssm set kubelet AppDirectory C:\k + nssm start kubelet -* V1.PodSecurityContext.RunAsNonRoot - Windows does not have a root user. The - closest equivalent is ContainerAdministrator which is an identity that - doesn't exist on the node. + # Register kube-proxy.exe (l2bridge / host-gw) + nssm install kube-proxy C:\k\kube-proxy.exe + nssm set kube-proxy AppDirectory c:\k + nssm set kube-proxy AppParameters --v=4 --proxy-mode=kernelspace --hostname-override=--kubeconfig=c:\k\config --enable-dsr=false --log-dir= --logtostderr=false + nssm.exe set kube-proxy AppEnvironmentExtra KUBE_NETWORK=cbr0 + nssm set kube-proxy DependOnService kubelet + nssm start kube-proxy -* V1.PodSecurityContext.SupplementalGroups - provides GID, not available on Windows + # Register kube-proxy.exe (overlay / vxlan) + nssm install kube-proxy C:\k\kube-proxy.exe + nssm set kube-proxy AppDirectory c:\k + nssm set kube-proxy AppParameters --v=4 --proxy-mode=kernelspace --feature-gates="WinOverlay=true" --hostname-override= --kubeconfig=c:\k\config --network-name=vxlan0 --source-vip= --enable-dsr=false --log-dir= --logtostderr=false + nssm set kube-proxy DependOnService kubelet + nssm start kube-proxy + ``` + + For initial troubleshooting, you can use the following flags in [nssm.exe](https://nssm.cc/) to redirect stdout and stderr to a output file: + + ```powershell + nssm set AppStdout C:\k\mysvc.log + nssm set AppStderr C:\k\mysvc.log + ``` -* V1.PodSecurityContext.Sysctls - these are part of the Linux sysctl - interface. There's no equivalent on Windows. + For additional details, see [NSSM - the Non-Sucking Service Manager](https://nssm.cc/usage). -#### Operating System Version Restrictions +1. My Pods are stuck at "Container Creating" or restarting over and over -Windows has strict compatibility rules, where the host OS version must match -the container base image OS version. Only Windows containers with a container -operating system of Windows Server 2019 are supported. Hyper-V isolation of -containers, enabling some backward compatibility of Windows container image -versions, is planned for a future release. + Check that your pause image is compatible with your OS version. The + [instructions](https://docs.microsoft.com/en-us/virtualization/windowscontainers/kubernetes/deploying-resources) + assume that both the OS and the containers are version 1803. If you have a later + version of Windows, such as an Insider build, you need to adjust the images + accordingly. See [Pause container](#pause-container) for more details. + +### Network troubleshooting {#troubleshooting-network} + +1. My Windows Pods do not have network connectivity -## Getting Help and Troubleshooting {#troubleshooting} + If you are using virtual machines, ensure that MAC spoofing is **enabled** on all + the VM network adapter(s). -Your main source of help for troubleshooting your Kubernetes cluster should -start with this -[section](/docs/tasks/debug-application-cluster/troubleshooting/). Some -additional, Windows-specific troubleshooting help is included in this section. -Logs are an important element of troubleshooting issues in Kubernetes. Make -sure to include them any time you seek troubleshooting assistance from other -contributors. Follow the instructions in the SIG-Windows -[contributing guide on gathering logs](https://github.com/kubernetes/community/blob/master/sig-windows/CONTRIBUTING.md#gathering-logs). +1. My Windows Pods cannot ping external resources -* How do I know start.ps1 completed successfully? + Windows Pods do not have outbound rules programmed for the ICMP protocol. However, + TCP/UDP is supported. When trying to demonstrate connectivity to resources + outside of the cluster, substitute `ping ` with corresponding + `curl ` commands. - You should see kubelet, kube-proxy, and (if you chose Flannel as your - networking solution) flanneld host-agent processes running on your node, with - running logs being displayed in separate PowerShell windows. In addition to - this, your Windows node should be listed as "Ready" in your Kubernetes - cluster. + If you are still facing problems, most likely your network configuration in + [cni.conf](https://github.com/Microsoft/SDN/blob/master/Kubernetes/flannel/l2bridge/cni/config/cni.conf) + deserves some extra attention. You can always edit this static file. The + configuration update will apply to any new Kubernetes resources. -* Can I configure the Kubernetes node processes to run in the background as services? + One of the Kubernetes networking requirements + (see [Kubernetes model](/docs/concepts/cluster-administration/networking/)) is + for cluster communication to occur without + NAT internally. To honor this requirement, there is an + [ExceptionList](https://github.com/Microsoft/SDN/blob/master/Kubernetes/flannel/l2bridge/cni/config/cni.conf#L20) + for all the communication where you do not want outbound NAT to occur. However, + this also means that you need to exclude the external IP you are trying to query + from the `ExceptionList`. Only then will the traffic originating from your Windows + pods be SNAT'ed correctly to receive a response from the outside world. In this + regard, your `ExceptionList` in `cni.conf` should look as follows: - Kubelet and kube-proxy are already configured to run as native Windows - Services, offering resiliency by re-starting the services automatically in the - event of failure (for example a process crash). You have two options for - configuring these node components as services. + ```conf + "ExceptionList": [ + "10.244.0.0/16", # Cluster subnet + "10.96.0.0/12", # Service subnet + "10.127.130.0/24" # Management (host) subnet + ] + ``` - * As native Windows Services +1. My Windows node cannot access `NodePort` type Services - Kubelet & kube-proxy can be run as native Windows Services using `sc.exe`. + Local NodePort access from the node itself fails. This is a known + limitation. NodePort access works from other nodes or external clients. - ```powershell - # Create the services for kubelet and kube-proxy in two separate commands - sc.exe create binPath= " --service " +1. vNICs and HNS endpoints of containers are being deleted - # Please note that if the arguments contain spaces, they must be escaped. - sc.exe create kubelet binPath= "C:\kubelet.exe --service --hostname-override 'minion' " + This issue can be caused when the `hostname-override` parameter is not passed to + [kube-proxy](/docs/reference/command-line-tools-reference/kube-proxy/). To resolve + it, users need to pass the hostname to kube-proxy as follows: - # Start the services - Start-Service kubelet - Start-Service kube-proxy + ```powershell + C:\k\kube-proxy.exe --hostname-override=$(hostname) + ``` - # Stop the service - Stop-Service kubelet (-Force) - Stop-Service kube-proxy (-Force) +1. With flannel, my nodes are having issues after rejoining a cluster - # Query the service status - Get-Service kubelet - Get-Service kube-proxy - ``` + Whenever a previously deleted node is being re-joined to the cluster, flannelD + tries to assign a new pod subnet to the node. Users should remove the old pod + subnet configuration files in the following paths: - * Using nssm.exe + ```powershell + Remove-Item C:\k\SourceVip.json + Remove-Item C:\k\SourceVipRequest.json + ``` - You can also always use alternative service managers like - [`nssm.exe`](https://nssm.cc/) to run these processes (flanneld, kubelet & - kube-proxy) in the background for you. You can use this - [sample script](https://github.com/Microsoft/SDN/tree/master/Kubernetes/flannel/register-svc.ps1), - leveraging `nssm.exe` to register kubelet, kube-proxy, and `flanneld.exe` - to run as Windows services in the background. +1. After launching `start.ps1`, flanneld is stuck in "Waiting for the Network to be created" - ```powershell - register-svc.ps1 -NetworkMode -ManagementIP -ClusterCIDR -KubeDnsServiceIP -LogDir - ``` + There are numerous reports of this [issue](https://github.com/coreos/flannel/issues/1066); most likely it is a timing issue for when the management IP of the flannel network is set. A workaround is to relaunch `start.ps1` or relaunch it manually as follows: - The parameters are explained below: + ```powershell + [Environment]::SetEnvironmentVariable("NODE_NAME", "") + C:\flannel\flanneld.exe --kubeconfig-file=c:\k\config --iface= --ip-masq=1 --kube-subnet-mgr=1 + ``` - - `NetworkMode`: The network mode l2bridge (flannel host-gw, also the - default value) or overlay (flannel vxlan) chosen as a network solution - - `ManagementIP`: The IP address assigned to the Windows node. You can use - `ipconfig` to find this. - - `ClusterCIDR`: The cluster subnet range. (Default: 10.244.0.0/16) - - `KubeDnsServiceIP`: The Kubernetes DNS service IP. (Default: 10.96.0.10) - - `LogDir`: The directory where kubelet and kube-proxy logs are redirected - into their respective output files. (Default value C:\k) +1. My Windows Pods cannot launch because of missing `/run/flannel/subnet.env` - If the above referenced script is not suitable, you can manually configure - `nssm.exe` using the following examples. + This indicates that Flannel didn't launch correctly. You can either try + to restart `flanneld.exe` or you can copy the files over manually from + `/run/flannel/subnet.env` on the Kubernetes master to `C:\run\flannel\subnet.env` + on the Windows worker node and modify the `FLANNEL_SUBNET` row to a different + number. For example, if node subnet 10.244.4.1/24 is desired: - Register flanneld.exe: - - ```powershell - nssm install flanneld C:\flannel\flanneld.exe - nssm set flanneld AppParameters --kubeconfig-file=c:\k\config --iface= --ip-masq=1 --kube-subnet-mgr=1 - nssm set flanneld AppEnvironmentExtra NODE_NAME= - nssm set flanneld AppDirectory C:\flannel - nssm start flanneld - ``` - - Register kubelet.exe: - - ```powershell - nssm install kubelet C:\k\kubelet.exe - nssm set kubelet AppParameters --hostname-override= --v=6 --pod-infra-container-image=k8s.gcr.io/pause:3.5 --resolv-conf="" --allow-privileged=true --enable-debugging-handlers --cluster-dns= --cluster-domain=cluster.local --kubeconfig=c:\k\config --hairpin-mode=promiscuous-bridge --image-pull-progress-deadline=20m --cgroups-per-qos=false --log-dir= --logtostderr=false --enforce-node-allocatable="" --network-plugin=cni --cni-bin-dir=c:\k\cni --cni-conf-dir=c:\k\cni\config - nssm set kubelet AppDirectory C:\k - nssm start kubelet - ``` - - Register kube-proxy.exe (l2bridge / host-gw): - - ```powershell - nssm install kube-proxy C:\k\kube-proxy.exe - nssm set kube-proxy AppDirectory c:\k - nssm set kube-proxy AppParameters --v=4 --proxy-mode=kernelspace --hostname-override=--kubeconfig=c:\k\config --enable-dsr=false --log-dir= --logtostderr=false - nssm.exe set kube-proxy AppEnvironmentExtra KUBE_NETWORK=cbr0 - nssm set kube-proxy DependOnService kubelet - nssm start kube-proxy - ``` - - Register kube-proxy.exe (overlay / vxlan): - - ```powershell - nssm install kube-proxy C:\k\kube-proxy.exe - nssm set kube-proxy AppDirectory c:\k - nssm set kube-proxy AppParameters --v=4 --proxy-mode=kernelspace --feature-gates="WinOverlay=true" --hostname-override= --kubeconfig=c:\k\config --network-name=vxlan0 --source-vip= --enable-dsr=false --log-dir= --logtostderr=false - nssm set kube-proxy DependOnService kubelet - nssm start kube-proxy - ``` - - For initial troubleshooting, you can use the following flags in - [`nssm.exe`](https://nssm.cc/) to redirect stdout and stderr to a output file: - - ```powershell - nssm set AppStdout C:\k\mysvc.log - nssm set AppStderr C:\k\mysvc.log - ``` - - For additional details, see official [nssm usage](https://nssm.cc/usage) docs. - -* My Windows Pods do not have network connectivity - - If you are using virtual machines, ensure that MAC spoofing is enabled on - all the VM network adapter(s). - -* My Windows Pods cannot ping external resources - - Windows Pods do not have outbound rules programmed for the ICMP protocol - today. However, TCP/UDP is supported. When trying to demonstrate connectivity - to resources outside of the cluster, please substitute `ping ` with - corresponding `curl ` commands. - - If you are still facing problems, most likely your network configuration in - [cni.conf](https://github.com/Microsoft/SDN/blob/master/Kubernetes/flannel/l2bridge/cni/config/cni.conf) - deserves some extra attention. You can always edit this static file. The - configuration update will apply to any newly created Kubernetes resources. - - One of the Kubernetes networking requirements (see - [Kubernetes network model](/docs/concepts/cluster-administration/networking/)) - is for cluster communication to occur without NAT internally. To honor this - requirement, there is an - [ExceptionList](https://github.com/Microsoft/SDN/blob/master/Kubernetes/flannel/l2bridge/cni/config/cni.conf#L20) - for all the communication where we do not want outbound NAT to occur. However, - this also means that you need to exclude the external IP you are trying to - query from the ExceptionList. Only then will the traffic originating from your - Windows pods be SNAT'ed correctly to receive a response from the outside - world. In this regard, your ExceptionList in `cni.conf` should look as - follows: - - ```conf - "ExceptionList": [ - "10.244.0.0/16", # Cluster subnet - "10.96.0.0/12", # Service subnet - "10.127.130.0/24" # Management (host) subnet - ] - ``` - -* My Windows node cannot access NodePort service - - Local NodePort access from the node itself fails. This is a known - limitation. NodePort access works from other nodes or external clients. - -* vNICs and HNS endpoints of containers are being deleted - - This issue can be caused when the `hostname-override` parameter is not - passed to - [kube-proxy](/docs/reference/command-line-tools-reference/kube-proxy/). - To resolve it, users need to pass the hostname to kube-proxy as follows: - - ```powershell - C:\k\kube-proxy.exe --hostname-override=$(hostname) - ``` - -* With flannel my nodes are having issues after rejoining a cluster - - Whenever a previously deleted node is being re-joined to the cluster, - flannelD tries to assign a new pod subnet to the node. Users should remove the - old pod subnet configuration files in the following paths: - - ```powershell - Remove-Item C:\k\SourceVip.json - Remove-Item C:\k\SourceVipRequest.json - ``` - -* After launching `start.ps1`, flanneld is stuck in "Waiting for the Network - to be created" - - There are numerous reports of this - [issue](https://github.com/coreos/flannel/issues/1066); most likely it is a - timing issue for when the management IP of the flannel network is set. A - workaround is to relaunch start.ps1 or relaunch it manually as follows: - - ```powershell - PS C:> [Environment]::SetEnvironmentVariable("NODE_NAME", "") - PS C:> C:\flannel\flanneld.exe --kubeconfig-file=c:\k\config --iface= --ip-masq=1 --kube-subnet-mgr=1 - ``` - -* My Windows Pods cannot launch because of missing `/run/flannel/subnet.env` - - This indicates that Flannel didn't launch correctly. You can either try to - restart flanneld.exe or you can copy the files over manually from - `/run/flannel/subnet.env` on the Kubernetes master to - `C:\run\flannel\subnet.env` on the Windows worker node and modify the - `FLANNEL_SUBNET` row to a different number. For example, if node subnet - 10.244.4.1/24 is desired: - - ```none - FLANNEL_NETWORK=10.244.0.0/16 - FLANNEL_SUBNET=10.244.4.1/24 - FLANNEL_MTU=1500 - FLANNEL_IPMASQ=true - ``` + ```env + FLANNEL_NETWORK=10.244.0.0/16 + FLANNEL_SUBNET=10.244.4.1/24 + FLANNEL_MTU=1500 + FLANNEL_IPMASQ=true + ``` -* My Windows node cannot access my services using the service IP - - This is a known limitation of the current networking stack on Windows. - Windows Pods are able to access the service IP however. +1. My Windows node cannot access my services using the service IP -* No network adapter is found when starting kubelet + This is a known limitation of the networking stack on Windows. However, Windows Pods can access the Service IP. - The Windows networking stack needs a virtual adapter for Kubernetes - networking to work. If the following commands return no results (in an admin - shell), virtual network creation — a necessary prerequisite for Kubelet to - work — has failed: - - ```powershell - Get-HnsNetwork | ? Name -ieq "cbr0" - Get-NetAdapter | ? Name -Like "vEthernet (Ethernet*" - ``` - - Often it is worthwhile to modify the - [InterfaceName](https://github.com/microsoft/SDN/blob/master/Kubernetes/flannel/start.ps1#L7) - parameter of the start.ps1 script, in cases where the host's network adapter - isn't "Ethernet". Otherwise, consult the output of the `start-kubelet.ps1` - script to see if there are errors during virtual network creation. - -* My Pods are stuck at "Container Creating" or restarting over and over - - Check that your pause image is compatible with your OS version. The - [instructions](https://docs.microsoft.com/en-us/virtualization/windowscontainers/kubernetes/deploying-resources) - assume that both the OS and the containers are version 1803. If you have a - later version of Windows, such as an Insider build, you need to adjust the - images accordingly. Please refer to the Microsoft's - [Docker repository](https://hub.docker.com/u/microsoft/) for images. - Regardless, both the pause image Dockerfile and the sample service expect - the image to be tagged as :latest. +1. No network adapter is found when starting the kubelet -* DNS resolution is not properly working + The Windows networking stack needs a virtual adapter for Kubernetes networking to work. If the following commands return no results (in an admin shell), virtual network creation — a necessary prerequisite for the kubelet to work — has failed: - Check the [DNS limitations for Windows](#dns-limitations). + ```powershell + Get-HnsNetwork | ? Name -ieq "cbr0" + Get-NetAdapter | ? Name -Like "vEthernet (Ethernet*" + ``` -* `kubectl port-forward` fails with "unable to do port forwarding: wincat not found" + Often it is worthwhile to modify the [InterfaceName](https://github.com/microsoft/SDN/blob/master/Kubernetes/flannel/start.ps1#L7) parameter of the start.ps1 script, in cases where the host's network adapter isn't "Ethernet". Otherwise, consult the output of the `start-kubelet.ps1` script to see if there are errors during virtual network creation. - Port forwarding support for Windows requires wincat.exe to be available in the - [pause infrastructure container](#pause-image). - Ensure you are using a supported image that is compatable with your Windows OS version. - If you would like to build your own pause infrastructure container be sure to include - [wincat](https://github.com/kubernetes/kubernetes/tree/master/build/pause/windows/wincat). +1. DNS resolution is not properly working -* My Kubernetes installation is failing because my Windows Server node is - behind a proxy + Check the DNS limitations for Windows in this [section](#dns-limitations). - If you are behind a proxy, the following PowerShell environment variables - must be defined: +1. `kubectl port-forward` fails with "unable to do port forwarding: wincat not found" - ```PowerShell - [Environment]::SetEnvironmentVariable("HTTP_PROXY", "http://proxy.example.com:80/", [EnvironmentVariableTarget]::Machine) - [Environment]::SetEnvironmentVariable("HTTPS_PROXY", "http://proxy.example.com:443/", [EnvironmentVariableTarget]::Machine) - ``` + This was implemented in Kubernetes 1.15 by including `wincat.exe` in the pause infrastructure container `mcr.microsoft.com/oss/kubernetes/pause:1.4.1`. Be sure to use a supported version of Kubernetes. + If you would like to build your own pause infrastructure container be sure to include [wincat](https://github.com/kubernetes/kubernetes/tree/master/build/pause/windows/wincat). -* What is a `pause` container? +1. My Kubernetes installation is failing because my Windows Server node is behind a proxy - In a Kubernetes Pod, an infrastructure or "pause" container is first created - to host the container endpoint. Containers that belong to the same pod, - including infrastructure and worker containers, share a common network - namespace and endpoint (same IP and port space). Pause containers are needed - to accommodate worker containers crashing or restarting without losing any of - the networking configuration. + If you are behind a proxy, the following PowerShell environment variables must be defined: - Refer to the [pause image](#pause-image) section to find the recommended version - of the pause image. + ```PowerShell + [Environment]::SetEnvironmentVariable("HTTP_PROXY", "http://proxy.example.com:80/", [EnvironmentVariableTarget]::Machine) + [Environment]::SetEnvironmentVariable("HTTPS_PROXY", "http://proxy.example.com:443/", [EnvironmentVariableTarget]::Machine) + ``` ### Further investigation -If these steps don't resolve your problem, you can get help running Windows -containers on Windows nodes in Kubernetes through: +If these steps don't resolve your problem, you can get help running Windows containers on Windows nodes in Kubernetes through: * StackOverflow [Windows Server Container](https://stackoverflow.com/questions/tagged/windows-server-container) topic - * Kubernetes Official Forum [discuss.kubernetes.io](https://discuss.kubernetes.io/) - * Kubernetes Slack [#SIG-Windows Channel](https://kubernetes.slack.com/messages/sig-windows) -## Reporting Issues and Feature Requests +### Reporting issues and feature requests -If you have what looks like a bug, or you would like to make a feature -request, please use the +If you have what looks like a bug, or you would like to +make a feature request, please use the [GitHub issue tracking system](https://github.com/kubernetes/kubernetes/issues). You can open issues on -[GitHub](https://github.com/kubernetes/kubernetes/issues/new/choose) and -assign them to SIG-Windows. You should first search the list of issues in case -it was reported previously and comment with your experience on the issue and -add additional logs. SIG-Windows Slack is also a great avenue to get some -initial support and troubleshooting ideas prior to creating a ticket. - -If filing a bug, please include detailed information about how to reproduce -the problem, such as: - -* Kubernetes version: kubectl version -* Environment details: Cloud provider, OS distro, networking choice and - configuration, and Docker version -* Detailed steps to reproduce the problem -* [Relevant logs](https://github.com/kubernetes/community/blob/master/sig-windows/CONTRIBUTING.md#gathering-logs) -* Tag the issue sig/windows by commenting on the issue with `/sig windows` to - bring it to a SIG-Windows member's attention +[GitHub](https://github.com/kubernetes/kubernetes/issues/new/choose) and assign +them to SIG-Windows. You should first search the list of issues in case it was +reported previously and comment with your experience on the issue and add additional +logs. SIG-Windows Slack is also a great avenue to get some initial support and +troubleshooting ideas prior to creating a ticket. -## {{% heading "whatsnext" %}} +If filing a bug, please include detailed information about how to reproduce the problem, such as: -We have a lot of features in our roadmap. An abbreviated high level list is -included below, but we encourage you to view our -[roadmap project](https://github.com/orgs/kubernetes/projects/8) and help us make -Windows support better by -[contributing](https://github.com/kubernetes/community/blob/master/sig-windows/). +* Kubernetes version: output from `kubectl version` +* Environment details: Cloud provider, OS distro, networking choice and configuration, and Docker version +* Detailed steps to reproduce the problem +* [Relevant logs](https://github.com/kubernetes/community/blob/master/sig-windows/CONTRIBUTING.md#gathering-logs) -### Hyper-V isolation +It helps if you tag the issue as **sig/windows**, by commenting on the issue with `/sig windows`. This helps to bring +the issue to a SIG Windows member's attention -Hyper-V isolation is required to enable the following use cases for Windows -containers in Kubernetes: -* Hypervisor-based isolation between pods for additional security +## {{% heading "whatsnext" %}} -* Backwards compatibility allowing a node to run a newer Windows Server - version without requiring containers to be rebuilt +### Deployment tools -* Specific CPU/NUMA settings for a pod +The kubeadm tool helps you to deploy a Kubernetes cluster, providing the control +plane to manage the cluster it, and nodes to run your workloads. +[Adding Windows nodes](/docs/tasks/administer-cluster/kubeadm/adding-windows-nodes/) +explains how to deploy Windows nodes to your cluster using kubeadm. -* Memory isolation and reservations +The Kubernetes [cluster API](https://cluster-api.sigs.k8s.io/) project also provides means to automate deployment of Windows nodes. -Hyper-V isolation support will be added in a later release and will require -CRI-Containerd. +### Windows distribution channels -### Deployment with kubeadm and cluster API +For a detailed explanation of Windows distribution channels see the [Microsoft documentation](https://docs.microsoft.com/en-us/windows-server/get-started-19/servicing-channels-19). -Kubeadm is becoming the de facto standard for users to deploy a Kubernetes -cluster. Windows node support in kubeadm is currently a work-in-progress but a -guide is available -[here](/docs/tasks/administer-cluster/kubeadm/adding-windows-nodes/). We are -also making investments in cluster API to ensure Windows nodes are properly -provisioned. +Information on the different Windows Server servicing channels +including their support models can be found at +[Windows Server servicing channels](https://docs.microsoft.com/en-us/windows-server/get-started-19/servicing-channels-19). From 32b394f808c4fc29e3e237178094e1cb3a172ca1 Mon Sep 17 00:00:00 2001 From: Riita <42636694+riita10069@users.noreply.github.com> Date: Thu, 30 Sep 2021 00:20:06 +0900 Subject: [PATCH 075/115] Update running-cloud-controller.md --- .../docs/tasks/administer-cluster/running-cloud-controller.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ja/docs/tasks/administer-cluster/running-cloud-controller.md b/content/ja/docs/tasks/administer-cluster/running-cloud-controller.md index 04dfd62f8bec6..def14011657d8 100644 --- a/content/ja/docs/tasks/administer-cluster/running-cloud-controller.md +++ b/content/ja/docs/tasks/administer-cluster/running-cloud-controller.md @@ -79,4 +79,4 @@ cloud-controller-managerは、クラウドプロバイダーのAPIにクエリ ## {{% heading "whatsnext" %}} -独自のクラウドコントローラーマネージャーを構築および開発するには[クラウドコントローラーマネージャーの開発](/docs/tasks/administer-cluster/developing-cloud-controller-manager.md)を参照してください。 +独自のクラウドコントローラーマネージャーを構築および開発するには[クラウドコントローラーマネージャーの開発](/ja/docs/tasks/administer-cluster/developing-cloud-controller-manager/)を参照してください。 From c232ecfbb4ce684e7cb76f14d16c6e1b829171ad Mon Sep 17 00:00:00 2001 From: fabriziopandini Date: Wed, 29 Sep 2021 21:34:32 +0200 Subject: [PATCH 076/115] Postpone ClusterClass blog --- ...md => 2021-10-08-clusterclass-and-managed-topologies.md} | 6 +++--- .../clusterclass.svg | 0 .../create-cluster.svg | 0 3 files changed, 3 insertions(+), 3 deletions(-) rename content/en/blog/_posts/{2021-10-04-clusterclass-and-managed-topologies.md => 2021-10-08-clusterclass-and-managed-topologies.md} (97%) rename static/images/blog/{2021-10-04-clusterclass-and-managed-topologies => 2021-10-08-clusterclass-and-managed-topologies}/clusterclass.svg (100%) rename static/images/blog/{2021-10-04-clusterclass-and-managed-topologies => 2021-10-08-clusterclass-and-managed-topologies}/create-cluster.svg (100%) diff --git a/content/en/blog/_posts/2021-10-04-clusterclass-and-managed-topologies.md b/content/en/blog/_posts/2021-10-08-clusterclass-and-managed-topologies.md similarity index 97% rename from content/en/blog/_posts/2021-10-04-clusterclass-and-managed-topologies.md rename to content/en/blog/_posts/2021-10-08-clusterclass-and-managed-topologies.md index ec49d73e7d60c..af6349ecb8e9f 100644 --- a/content/en/blog/_posts/2021-10-04-clusterclass-and-managed-topologies.md +++ b/content/en/blog/_posts/2021-10-08-clusterclass-and-managed-topologies.md @@ -1,7 +1,7 @@ --- layout: blog title: "Introducing ClusterClass and Managed Topologies in Cluster API" -date: 2021-10-04 +date: 2021-10-08 slug: capi-clusterclass-and-managed-topologies --- @@ -29,7 +29,7 @@ As the name suggests, ClusterClass and managed topologies are built in two parts The idea behind ClusterClass is simple: define the shape of your cluster once, and reuse it many times, abstracting the complexities and the internals of a Kubernetes cluster away. -![Defining a ClusterClass](/images/blog/2021-10-04-clusterclass-and-managed-topologies/clusterclass.svg) +![Defining a ClusterClass](/images/blog/2021-10-08-clusterclass-and-managed-topologies/clusterclass.svg) ClusterClass, at its heart, is a collection of Cluster and Machine templates. You can use it as a “stamp” that can be leveraged to create many clusters of a similar shape. @@ -92,7 +92,7 @@ Managed Topologies let you put the power of ClusterClass into action. Given a ClusterClass, you can create many Clusters of a similar shape by providing a single resource, the Cluster. -![Create a Cluster with ClusterClass](/images/blog/2021-10-04-clusterclass-and-managed-topologies/create-cluster.svg) +![Create a Cluster with ClusterClass](/images/blog/2021-10-08-clusterclass-and-managed-topologies/create-cluster.svg) Here is an example: diff --git a/static/images/blog/2021-10-04-clusterclass-and-managed-topologies/clusterclass.svg b/static/images/blog/2021-10-08-clusterclass-and-managed-topologies/clusterclass.svg similarity index 100% rename from static/images/blog/2021-10-04-clusterclass-and-managed-topologies/clusterclass.svg rename to static/images/blog/2021-10-08-clusterclass-and-managed-topologies/clusterclass.svg diff --git a/static/images/blog/2021-10-04-clusterclass-and-managed-topologies/create-cluster.svg b/static/images/blog/2021-10-08-clusterclass-and-managed-topologies/create-cluster.svg similarity index 100% rename from static/images/blog/2021-10-04-clusterclass-and-managed-topologies/create-cluster.svg rename to static/images/blog/2021-10-08-clusterclass-and-managed-topologies/create-cluster.svg From d113a7066f8622d10d9f0bfe36f306fa07ab0690 Mon Sep 17 00:00:00 2001 From: Arhell Date: Thu, 30 Sep 2021 00:20:11 +0300 Subject: [PATCH 077/115] [ja] Add seccomp tutorial to index --- content/ja/docs/tutorials/_index.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/content/ja/docs/tutorials/_index.md b/content/ja/docs/tutorials/_index.md index 1c1d55300aa79..0cf5ed7f2fa11 100644 --- a/content/ja/docs/tutorials/_index.md +++ b/content/ja/docs/tutorials/_index.md @@ -46,6 +46,8 @@ content_type: concept * [AppArmor](/docs/tutorials/clusters/apparmor/) +* [seccomp](/docs/tutorials/clusters/seccomp/) + ## サービス * [Source IPを使う](/docs/tutorials/services/source-ip/) From c36a610e8e52a65adc70bd2318baad1bb639040a Mon Sep 17 00:00:00 2001 From: howieyuen Date: Thu, 30 Sep 2021 15:43:06 +0800 Subject: [PATCH 078/115] [zh] sync content/zh/docs/concepts/cluster-administration/flow-control.md --- .../cluster-administration/flow-control.md | 86 +++++++++++-------- 1 file changed, 48 insertions(+), 38 deletions(-) diff --git a/content/zh/docs/concepts/cluster-administration/flow-control.md b/content/zh/docs/concepts/cluster-administration/flow-control.md index c7805402f5332..473bdda4ae02c 100644 --- a/content/zh/docs/concepts/cluster-administration/flow-control.md +++ b/content/zh/docs/concepts/cluster-administration/flow-control.md @@ -128,12 +128,12 @@ APF 特性包含几个不同的功能。 ### 优先级 {#Priority-Levels} @@ -219,8 +219,9 @@ server. The Priority and Fairness feature ships with a suggested configuration that should suffice for experimentation; if your cluster is likely to -experience heavy load then you should consider what configuration will work best. -The suggested configuration groups requests into five priority classes: +experience heavy load then you should consider what configuration will work +best. The suggested configuration groups requests into five priority +classes: --> ## 默认值 {#defaults} @@ -418,8 +419,8 @@ to balance progress between request flows. 公平排队算法支持通过排队配置对优先级微调。 可以在[增强建议](#whats-next)中阅读算法的详细信息,但总之: @@ -450,7 +451,7 @@ proposal](#whats-next), but in short: a small number of flows can dominate the apiserver. A larger `handSize` also potentially increases the amount of latency that a single high-traffic flow can cause. The maximum number of queued requests possible from a - single flow is `handSize *queueLengthLimit`. + single flow is `handSize * queueLengthLimit`. {{< /note >}} --> * 修改 `handSize` 允许你调整过载情况下不同流之间的冲突概率以及单个流可用的整体并发性。 @@ -459,7 +460,7 @@ proposal](#whats-next), but in short: 较大的 `handSize` 使两个单独的流程发生碰撞的可能性较小(因此,一个流可以饿死另一个流), 但是更有可能的是少数流可以控制 apiserver。 较大的 `handSize` 还可能增加单个高并发流的延迟量。 - 单个流中可能排队的请求的最大数量为 `handSize *queueLengthLimit` 。 + 单个流中可能排队的请求的最大数量为 `handSize * queueLengthLimit` 。 {{< /note >}} * `apiserver_flowcontrol_rejected_requests_total` 是一个计数器向量, 记录被拒绝的请求数量(自服务器启动以来累计值), @@ -725,6 +727,14 @@ poorly-behaved workloads that may be harming system health. 记录包含执行中(不在队列中等待)请求的瞬时数量, 由标签 `priority_level` 和 `flow_schema` 进一步区分。 + +* `apiserver_flowcontrol_request_concurrency_in_use` 是一个规范向量, + 包含占用座位的瞬时数量,由标签 `priority_level` 和 `flow_schema` 进一步区分。 + ### 调试端点 {#Debug-endpoints} 启用 APF 特性后, kube-apiserver 会在其 HTTP/HTTPS 端口提供以下路径: - `/debug/api_priority_and_fairness/dump_priority_levels` —— 所有优先级及其当前状态的列表。你可以这样获取: @@ -856,7 +866,7 @@ You can fetch like this: 输出类似于: - ``` + ```none PriorityLevelName, ActiveQueues, IsIdle, IsQuiescing, WaitingRequests, ExecutingRequests, workload-low, 0, true, false, 0, 0, global-default, 0, true, false, 0, 0, @@ -868,8 +878,8 @@ You can fetch like this: ``` - `/debug/api_priority_and_fairness/dump_queues` —— 所有队列及其当前状态的列表。 你可以这样获取: @@ -881,7 +891,7 @@ You can fetch like this: 输出类似于: - ``` + ```none PriorityLevelName, Index, PendingRequests, ExecutingRequests, VirtualStart, workload-high, 0, 0, 0, 0.0000, workload-high, 1, 0, 0, 0.0000, @@ -892,8 +902,8 @@ You can fetch like this: ``` - `/debug/api_priority_and_fairness/dump_requests` ——当前正在队列中等待的所有请求的列表。 你可以这样获取: @@ -905,15 +915,15 @@ You can fetch like this: 输出类似于: - ``` + ```none PriorityLevelName, FlowSchemaName, QueueIndex, RequestIndexInQueue, FlowDistingsher, ArriveTime, exempt, , , , , , system, system-nodes, 12, 0, system:node:127.0.0.1, 2020-07-23T15:26:57.179170694Z, ``` 针对每个优先级别,输出中还包含一条虚拟记录,对应豁免限制。 @@ -925,8 +935,9 @@ You can fetch like this: ``` + 输出类似于: - ``` + ```none PriorityLevelName, FlowSchemaName, QueueIndex, RequestIndexInQueue, FlowDistingsher, ArriveTime, UserName, Verb, APIPath, Namespace, Name, APIVersion, Resource, SubResource, system, system-nodes, 12, 0, system:node:127.0.0.1, 2020-07-23T15:31:03.583823404Z, system:node:127.0.0.1, create, /api/v1/namespaces/scaletest/configmaps, system, system-nodes, 12, 1, system:node:127.0.0.1, 2020-07-23T15:31:03.594555947Z, system:node:127.0.0.1, create, /api/v1/namespaces/scaletest/configmaps, @@ -935,14 +946,13 @@ You can fetch like this: ## {{% heading "whatsnext" %}} 有关API优先级和公平性的设计细节的背景信息, -请参阅[增强建议](https://github.com/kubernetes/enhancements/blob/master/keps/sig-api-machinery/20190228-priority-and-fairness.md)。 +请参阅[增强建议](https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/1040-priority-and-fairness)。 你可以通过 [SIG APIMachinery](https://github.com/kubernetes/community/tree/master/sig-api-machinery/) 或特性的 [Slack 频道](https://kubernetes.slack.com/messages/api-priority-and-fairness/) 提出建议和特性请求。 From b033b85cd971c850683ce3c9052ea63ee7771c79 Mon Sep 17 00:00:00 2001 From: RA489 Date: Thu, 2 Sep 2021 10:13:27 +0530 Subject: [PATCH 079/115] Improvement for thirdparty tools --- content/en/docs/reference/tools/_index.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/content/en/docs/reference/tools/_index.md b/content/en/docs/reference/tools/_index.md index 48a9b20f411c2..c8d42be3527e0 100644 --- a/content/en/docs/reference/tools/_index.md +++ b/content/en/docs/reference/tools/_index.md @@ -8,14 +8,15 @@ no_list: true --- -Kubernetes contains several built-in as well as third party tools to help you work with the Kubernetes system. +Kubernetes contains several tools to help you work with the Kubernetes system. +{{% thirdparty-content %}} ## Minikube -[`minikube`](https://minikube.sigs.k8s.io/docs/) is a built-in tool that +[`minikube`](https://minikube.sigs.k8s.io/docs/) is a tool that runs a single-node Kubernetes cluster locally on your workstation for development and testing purposes. @@ -26,7 +27,10 @@ to a Kubernetes cluster, troubleshoot them, and manage the cluster and its resou ## Helm -[`Kubernetes Helm`](https://github.com/kubernetes/helm) is a third party managed tool for managing packages of pre-configured +[`Kubernetes Helm`](https://github.com/kubernetes/helm) is a tool for managing packages of pre-configured +Kubernetes resources, aka Kubernetes charts. + +Beware Helm is a third party managed tool for managing packages of pre-configured Kubernetes resources, aka Kubernetes charts. Use Helm to: @@ -39,7 +43,7 @@ Use Helm to: ## Kompose -[`Kompose`](https://github.com/kubernetes/kompose) is a built-in tool to help Docker Compose users move to Kubernetes. +[`Kompose`](https://github.com/kubernetes/kompose) is a tool to help Docker Compose users move to Kubernetes. Use Kompose to: From 7f88af518e42bcea151ddd24cffb4ce6af202273 Mon Sep 17 00:00:00 2001 From: Tim Bannister Date: Thu, 30 Sep 2021 18:09:26 +0100 Subject: [PATCH 080/115] Update compatibility statement for TerminationGracePeriod Co-authored-by: Mark Rossetti --- .../windows/intro-windows-in-kubernetes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/docs/setup/production-environment/windows/intro-windows-in-kubernetes.md b/content/en/docs/setup/production-environment/windows/intro-windows-in-kubernetes.md index f395de9397c33..7b8e24db6085c 100644 --- a/content/en/docs/setup/production-environment/windows/intro-windows-in-kubernetes.md +++ b/content/en/docs/setup/production-environment/windows/intro-windows-in-kubernetes.md @@ -120,7 +120,7 @@ including: * HugePages: not supported for Windows containers * Privileged containers: not supported for Windows containers -* TerminationGracePeriod: not implemented +* TerminationGracePeriod: requires containerD Not all features of shared namespaces are supported. See [API compatibility](#api) for more details. From 2284c9dcec8a6483eb0d0bc8785df1ccedd6a18f Mon Sep 17 00:00:00 2001 From: Victor Paredes Date: Thu, 30 Sep 2021 18:54:05 -0400 Subject: [PATCH 081/115] concepts/services-networking/service: Removed duplicate ProxyTerminatingEndpoints term. --- content/en/docs/concepts/services-networking/service.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/docs/concepts/services-networking/service.md b/content/en/docs/concepts/services-networking/service.md index db28918c983a5..71068be5fd74b 100644 --- a/content/en/docs/concepts/services-networking/service.md +++ b/content/en/docs/concepts/services-networking/service.md @@ -414,7 +414,7 @@ endpoints, the kube-proxy does not forward any traffic for the relevant Service. {{< feature-state for_k8s_version="v1.22" state="alpha" >}} If you enable the `ProxyTerminatingEndpoints` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/) -`ProxyTerminatingEndpoints` for the kube-proxy, the kube-proxy checks if the node +for the kube-proxy, the kube-proxy checks if the node has local endpoints and whether or not all the local endpoints are marked as terminating. If there are local endpoints and **all** of those are terminating, then the kube-proxy ignores any external traffic policy of `Local`. Instead, whilst the node-local endpoints remain as all From cd7fa760e04e60f41e97daa678ba453c688d67dc Mon Sep 17 00:00:00 2001 From: aychen99 <42681629+aychen99@users.noreply.github.com> Date: Fri, 1 Oct 2021 13:41:39 -0400 Subject: [PATCH 082/115] Update basic-stateful-set.md Fix syntax issue --- .../docs/tutorials/stateful-application/basic-stateful-set.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/zh/docs/tutorials/stateful-application/basic-stateful-set.md b/content/zh/docs/tutorials/stateful-application/basic-stateful-set.md index 8b7f166a69cdc..07f6302eaee16 100644 --- a/content/zh/docs/tutorials/stateful-application/basic-stateful-set.md +++ b/content/zh/docs/tutorials/stateful-application/basic-stateful-set.md @@ -19,7 +19,7 @@ This tutorial provides an introduction to managing applications with demonstrates how to create, delete, scale, and update the Pods of StatefulSets. --> -本教程介绍如何了使用 [StatefulSets](/zh/docs/concepts/workloads/controllers/statefulset/) 来管理应用。 +本教程介绍了如何使用 [StatefulSets](/zh/docs/concepts/workloads/controllers/statefulset/) 来管理应用。 演示了如何创建、删除、扩容/缩容和更新 StatefulSets 的 Pods。 From 7b07d97a0b0c20343c63f422f82959e738377a4a Mon Sep 17 00:00:00 2001 From: Toli Kuznets Date: Fri, 1 Oct 2021 12:21:42 -0700 Subject: [PATCH 083/115] Update job.md add a newline per bug #29840 --- content/en/docs/concepts/workloads/controllers/job.md | 1 + 1 file changed, 1 insertion(+) diff --git a/content/en/docs/concepts/workloads/controllers/job.md b/content/en/docs/concepts/workloads/controllers/job.md index 2ca81a5ca02c4..54a4104c5e920 100644 --- a/content/en/docs/concepts/workloads/controllers/job.md +++ b/content/en/docs/concepts/workloads/controllers/job.md @@ -207,6 +207,7 @@ Jobs with _fixed completion count_ - that is, jobs that have non null {{< glossary_tooltip term_id="Service" >}}, Pods within the Job can use the deterministic hostnames to address each other via DNS. - From the containarized task, in the environment variable `JOB_COMPLETION_INDEX`. + The Job is considered complete when there is one successfully completed Pod for each index. For more information about how to use this mode, see [Indexed Job for Parallel Processing with Static Work Assignment](/docs/tasks/job/indexed-parallel-processing-static/). From abadaf1ead4a36f08e8472e6854b3ada925efe9c Mon Sep 17 00:00:00 2001 From: "xiao.li" Date: Fri, 1 Oct 2021 13:54:04 -0700 Subject: [PATCH 084/115] Fix the page links to a section that doesn't exist --- .../en/docs/concepts/services-networking/dns-pod-service.md | 4 ++-- .../docs/tasks/administer-cluster/dns-debugging-resolution.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/content/en/docs/concepts/services-networking/dns-pod-service.md b/content/en/docs/concepts/services-networking/dns-pod-service.md index f43eeff22ba84..f1a085176e9de 100644 --- a/content/en/docs/concepts/services-networking/dns-pod-service.md +++ b/content/en/docs/concepts/services-networking/dns-pod-service.md @@ -217,13 +217,13 @@ following pod-specific DNS policies. These policies are specified in the - "`Default`": The Pod inherits the name resolution configuration from the node that the pods run on. - See [related discussion](/docs/tasks/administer-cluster/dns-custom-nameservers/#inheriting-dns-from-the-node) + See [related discussion](/docs/tasks/administer-cluster/dns-custom-nameservers) for more details. - "`ClusterFirst`": Any DNS query that does not match the configured cluster domain suffix, such as "`www.kubernetes.io`", is forwarded to the upstream nameserver inherited from the node. Cluster administrators may have extra stub-domain and upstream DNS servers configured. - See [related discussion](/docs/tasks/administer-cluster/dns-custom-nameservers/#effects-on-pods) + See [related discussion](/docs/tasks/administer-cluster/dns-custom-nameservers) for details on how DNS queries are handled in those cases. - "`ClusterFirstWithHostNet`": For Pods running with hostNetwork, you should explicitly set its DNS policy "`ClusterFirstWithHostNet`". diff --git a/content/en/docs/tasks/administer-cluster/dns-debugging-resolution.md b/content/en/docs/tasks/administer-cluster/dns-debugging-resolution.md index 6bc41d217026f..e9dd5459550a7 100644 --- a/content/en/docs/tasks/administer-cluster/dns-debugging-resolution.md +++ b/content/en/docs/tasks/administer-cluster/dns-debugging-resolution.md @@ -67,7 +67,7 @@ If the `nslookup` command fails, check the following: ### Check the local DNS configuration first Take a look inside the resolv.conf file. -(See [Inheriting DNS from the node](/docs/tasks/administer-cluster/dns-custom-nameservers/#inheriting-dns-from-the-node) and +(See [Customizing DNS Service](/docs/tasks/administer-cluster/dns-custom-nameservers) and [Known issues](#known-issues) below for more information) ```shell From 5e9d700ddb45a2a64c6115ccac1abf060d907885 Mon Sep 17 00:00:00 2001 From: learner0810 Date: Sat, 2 Oct 2021 15:30:34 +0800 Subject: [PATCH 085/115] fix/typo-command-line-tools-reference/kubelet --- .../en/docs/reference/command-line-tools-reference/kubelet.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/docs/reference/command-line-tools-reference/kubelet.md b/content/en/docs/reference/command-line-tools-reference/kubelet.md index 0531f0847a09c..75698b3966697 100644 --- a/content/en/docs/reference/command-line-tools-reference/kubelet.md +++ b/content/en/docs/reference/command-line-tools-reference/kubelet.md @@ -51,7 +51,7 @@ kubelet [flags] --address string     Default: 0.0.0.0 -The IP address for the Kubelet to serve on (set to 0.0.0.0 or :: for listening in gll interfaces and IP families) (DEPRECATED: This parameter should be set via the config file specified by the Kubelet's --config flag. See https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/ for more information.) +The IP address for the Kubelet to serve on (set to 0.0.0.0 or :: for listening in all interfaces and IP families) (DEPRECATED: This parameter should be set via the config file specified by the Kubelet's --config flag. See https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/ for more information.) From 8a736308a9039db3516f26619728e94e8c749f2f Mon Sep 17 00:00:00 2001 From: Tim Bannister Date: Sat, 2 Oct 2021 16:28:54 +0100 Subject: [PATCH 086/115] Revise third-party content warning --- data/i18n/en/en.toml | 12 +++++++++++- layouts/docs/baseof.html | 5 +++++ layouts/partials/docs/thirdparty-disclaimer.html | 3 +++ layouts/partials/page-meta-links.html | 4 ++++ layouts/shortcodes/thirdparty-content.html | 11 ++++++++--- 5 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 layouts/partials/docs/thirdparty-disclaimer.html diff --git a/data/i18n/en/en.toml b/data/i18n/en/en.toml index e32d8819d25ff..6ed8b8a7318bf 100644 --- a/data/i18n/en/en.toml +++ b/data/i18n/en/en.toml @@ -217,7 +217,17 @@ other = "Subscribe" other = "Synopsis" [thirdparty_message] -other = """This section links to third party projects that provide functionality required by Kubernetes. The Kubernetes project authors aren't responsible for these projects. This page follows
CNCF website guidelines by listing projects alphabetically. To add a project to this list, read the content guide before submitting a change.""" +other = """This section links to third party projects that provide functionality required by Kubernetes. The Kubernetes project authors aren't responsible for these projects, which are listed alphabetically. To add a project to this list, read the content guide before submitting a change. More information.""" + +[thirdparty_message_edit_disclaimer] +other="""Third party content advice""" + + +[thirdparty_message_single_item] +other = """🛇 This item links to a third party project or product that is not part of Kubernetes itself. More information""" + +[thirdparty_message_disclaimer] +other = """

Items on this page refer to third party products or projects that provide functionality required by Kubernetes. The Kubernetes project authors aren't responsible for those third-party products or projects. See the CNCF website guidelines for more details.

You should read the content guide before proposing a change that adds an extra third-party link.

""" [ui_search_placeholder] other = "Search" diff --git a/layouts/docs/baseof.html b/layouts/docs/baseof.html index cc6237938b7ee..7dae9a6e90602 100644 --- a/layouts/docs/baseof.html +++ b/layouts/docs/baseof.html @@ -22,6 +22,11 @@ {{ partial "deprecation-warning.html" . }} {{ end }} {{ block "main" . }}{{ end }} + {{- if .HasShortcode "thirdparty-content" -}} + {{ block "thirdparty-disclaimer" . }} + {{ partial "docs/thirdparty-disclaimer.html" . }} + {{- end -}} + {{- end -}} {{ if (and (not .Params.hide_feedback) (.Site.Params.ui.feedback.enable) (.Site.GoogleAnalytics)) }} {{ partial "feedback.html" .Site.Params.ui.feedback }} {{ end }} diff --git a/layouts/partials/docs/thirdparty-disclaimer.html b/layouts/partials/docs/thirdparty-disclaimer.html new file mode 100644 index 0000000000000..0eca49d0716c6 --- /dev/null +++ b/layouts/partials/docs/thirdparty-disclaimer.html @@ -0,0 +1,3 @@ +
+{{ T "thirdparty_message_disclaimer" | safeHTML }} +
diff --git a/layouts/partials/page-meta-links.html b/layouts/partials/page-meta-links.html index 529bcea29c0e7..83571db5257f0 100644 --- a/layouts/partials/page-meta-links.html +++ b/layouts/partials/page-meta-links.html @@ -24,6 +24,10 @@ {{ if not (.Param "auto_generated") }} {{ T "post_edit_this" }} + {{- if .HasShortcode "thirdparty-content" -}} + {{ T "thirdparty_message_edit_disclaimer" | safeHTML }} + {{- end }} + {{ T "post_create_child_page" }} {{ end }} diff --git a/layouts/shortcodes/thirdparty-content.html b/layouts/shortcodes/thirdparty-content.html index 5a98081e49967..36fbdef13e04b 100644 --- a/layouts/shortcodes/thirdparty-content.html +++ b/layouts/shortcodes/thirdparty-content.html @@ -1,4 +1,9 @@ - +{{- else -}} + {{ T "thirdparty_message_single_item" | safeHTML }} +{{- end -}} + From feb2785238a638cdb6ba00a0087d92f73c2c085f Mon Sep 17 00:00:00 2001 From: Tim Bannister Date: Sat, 2 Oct 2021 16:53:59 +0100 Subject: [PATCH 087/115] Highlight third party content disclaimer When the (new) third party content disclaimer is the current target, highlight it with a flash of yellow that fades to a yellow background, rather than the usual gray. --- assets/scss/_custom.scss | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/assets/scss/_custom.scss b/assets/scss/_custom.scss index 7d6aa6784fbf8..752af266cb02e 100644 --- a/assets/scss/_custom.scss +++ b/assets/scss/_custom.scss @@ -343,6 +343,26 @@ main { } } +// Highlight disclaimer when targeted as a fragment + +#third-party-content-disclaimer { + color: #000; + background: #f8f9fa; + transition: all 0.5s ease; +} + +@keyframes disclaimer-highlight { + from { background: #f8f922; color: #000; } + 50% { background: #f8f944; color: #000; } + to { background: #f8f9cb; color: #000; } +} + +#third-party-content-disclaimer:target { + color: #000; + animation: disclaimer-highlight 1.25s ease; + background: #f8f9cb; +} + .deprecation-warning { padding: 20px; margin: 20px 0; From bab43543f072053d5b0f68ca352c1abe722fba9f Mon Sep 17 00:00:00 2001 From: Tim Bannister Date: Sat, 2 Oct 2021 17:01:11 +0100 Subject: [PATCH 088/115] Set custom color for third-party-content alert --- assets/scss/_custom.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/assets/scss/_custom.scss b/assets/scss/_custom.scss index 752af266cb02e..20a36b617595b 100644 --- a/assets/scss/_custom.scss +++ b/assets/scss/_custom.scss @@ -338,11 +338,15 @@ main { border-left-color: #d9534f; } + h1:first-of-type + blockquote.callout { margin-top: 1.5em; } } +// Special color for third party content disclaimers +.alert.third-party-content { border-left-color: #222 }; + // Highlight disclaimer when targeted as a fragment #third-party-content-disclaimer { From a87f5070490bf7a3b1b0d9a8ae95f53a60b3bc78 Mon Sep 17 00:00:00 2001 From: Arhell Date: Sun, 3 Oct 2021 01:18:07 +0300 Subject: [PATCH 089/115] [pl] Add seccomp tutorial to index --- content/pl/docs/tutorials/_index.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/content/pl/docs/tutorials/_index.md b/content/pl/docs/tutorials/_index.md index c55fd9c3ff458..4dc176cd54e61 100644 --- a/content/pl/docs/tutorials/_index.md +++ b/content/pl/docs/tutorials/_index.md @@ -48,6 +48,8 @@ Przed zapoznaniem się z samouczkami warto stworzyć zakładkę do * [AppArmor](/docs/tutorials/clusters/apparmor/) +* [seccomp](/docs/tutorials/clusters/seccomp/) + ## Serwisy * [Using Source IP](/docs/tutorials/services/source-ip/) From 739a72185fbc31ea98896b01b2655bafd53fada4 Mon Sep 17 00:00:00 2001 From: Ali Yousefi Sabzevar Date: Sun, 3 Oct 2021 18:42:55 +0200 Subject: [PATCH 090/115] fix a grammar mistake - English version --- content/en/docs/concepts/services-networking/service.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/docs/concepts/services-networking/service.md b/content/en/docs/concepts/services-networking/service.md index e3f71c7d99d59..ff30adf088e65 100644 --- a/content/en/docs/concepts/services-networking/service.md +++ b/content/en/docs/concepts/services-networking/service.md @@ -1128,7 +1128,7 @@ spec: ``` {{< note >}} -ExternalName accepts an IPv4 address string, but as a DNS names comprised of digits, not as an IP address. ExternalNames that resemble IPv4 addresses are not resolved by CoreDNS or ingress-nginx because ExternalName +ExternalName accepts an IPv4 address string, but as a DNS name comprised of digits, not as an IP address. ExternalNames that resemble IPv4 addresses are not resolved by CoreDNS or ingress-nginx because ExternalName is intended to specify a canonical DNS name. To hardcode an IP address, consider using [headless Services](#headless-services). {{< /note >}} From 0b814897cb3ebb9cf6a46455f7a594cc24d0c8c9 Mon Sep 17 00:00:00 2001 From: Ali Yousefi Sabzevar Date: Sun, 3 Oct 2021 19:07:02 +0200 Subject: [PATCH 091/115] fix a grammar mistake - Chinese version --- content/zh/docs/concepts/services-networking/service.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/zh/docs/concepts/services-networking/service.md b/content/zh/docs/concepts/services-networking/service.md index 05b50c1ee16bd..722d5e1c70b78 100644 --- a/content/zh/docs/concepts/services-networking/service.md +++ b/content/zh/docs/concepts/services-networking/service.md @@ -1819,7 +1819,7 @@ spec: ``` From d4a08df1b94b492e1709b7443fa0e6632fc46f0d Mon Sep 17 00:00:00 2001 From: Shubham Kuchhal Date: Mon, 4 Oct 2021 12:40:03 +0530 Subject: [PATCH 092/115] Improvement: Correct the "code" link in Dynamic Admission Control. --- .../access-authn-authz/extensible-admission-controllers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/docs/reference/access-authn-authz/extensible-admission-controllers.md b/content/en/docs/reference/access-authn-authz/extensible-admission-controllers.md index aa714bdaa24c5..513c3d3352c20 100644 --- a/content/en/docs/reference/access-authn-authz/extensible-admission-controllers.md +++ b/content/en/docs/reference/access-authn-authz/extensible-admission-controllers.md @@ -79,7 +79,7 @@ The webhook server in the e2e test is deployed in the Kubernetes cluster, via the [deployment API](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#deployment-v1-apps). The test also creates a [service](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#service-v1-core) as the front-end of the webhook server. See -[code](https://github.com/kubernetes/kubernetes/blob/v1.15.0/test/e2e/apimachinery/webhook.go#L301). +[code](https://github.com/kubernetes/kubernetes/blob/master/test/e2e/apimachinery/webhook.go#L748). You may also deploy your webhooks outside of the cluster. You will need to update your webhook configurations accordingly. From 0540e157a5ca271e107608d53a42afa87b3ffa8e Mon Sep 17 00:00:00 2001 From: Maciej Filocha Date: Mon, 4 Oct 2021 11:54:25 +0200 Subject: [PATCH 093/115] Synchronize Polish localization for ver 1.22, part 4 Synchronize Polish localization with upstream up to 08d92f9137924abdf442e7d9fb7372901379b993. Part 4 --- .../kubernetes-basics/create-cluster/cluster-interactive.html | 3 ++- .../kubernetes-basics/deploy-app/deploy-interactive.html | 4 +++- .../kubernetes-basics/explore/explore-interactive.html | 4 +++- .../kubernetes-basics/expose/expose-interactive.html | 4 +++- .../tutorials/kubernetes-basics/scale/scale-interactive.html | 4 +++- .../kubernetes-basics/update/update-interactive.html | 3 ++- 6 files changed, 16 insertions(+), 6 deletions(-) diff --git a/content/pl/docs/tutorials/kubernetes-basics/create-cluster/cluster-interactive.html b/content/pl/docs/tutorials/kubernetes-basics/create-cluster/cluster-interactive.html index 72409e9238de3..43997fa58997d 100644 --- a/content/pl/docs/tutorials/kubernetes-basics/create-cluster/cluster-interactive.html +++ b/content/pl/docs/tutorials/kubernetes-basics/create-cluster/cluster-interactive.html @@ -25,7 +25,8 @@ diff --git a/content/pl/docs/tutorials/kubernetes-basics/deploy-app/deploy-interactive.html b/content/pl/docs/tutorials/kubernetes-basics/deploy-app/deploy-interactive.html index 954bad22b315c..39403ee0e9ed6 100644 --- a/content/pl/docs/tutorials/kubernetes-basics/deploy-app/deploy-interactive.html +++ b/content/pl/docs/tutorials/kubernetes-basics/deploy-app/deploy-interactive.html @@ -38,7 +38,9 @@ diff --git a/content/pl/docs/tutorials/kubernetes-basics/explore/explore-interactive.html b/content/pl/docs/tutorials/kubernetes-basics/explore/explore-interactive.html index 14afae5a3d204..35cfb12da87f8 100644 --- a/content/pl/docs/tutorials/kubernetes-basics/explore/explore-interactive.html +++ b/content/pl/docs/tutorials/kubernetes-basics/explore/explore-interactive.html @@ -29,7 +29,9 @@ diff --git a/content/pl/docs/tutorials/kubernetes-basics/expose/expose-interactive.html b/content/pl/docs/tutorials/kubernetes-basics/expose/expose-interactive.html index 1aefa3e7935c9..278fca5f89f5f 100644 --- a/content/pl/docs/tutorials/kubernetes-basics/expose/expose-interactive.html +++ b/content/pl/docs/tutorials/kubernetes-basics/expose/expose-interactive.html @@ -26,7 +26,9 @@ diff --git a/content/pl/docs/tutorials/kubernetes-basics/scale/scale-interactive.html b/content/pl/docs/tutorials/kubernetes-basics/scale/scale-interactive.html index 7990fbd1a66b9..028457a303482 100644 --- a/content/pl/docs/tutorials/kubernetes-basics/scale/scale-interactive.html +++ b/content/pl/docs/tutorials/kubernetes-basics/scale/scale-interactive.html @@ -26,7 +26,9 @@ diff --git a/content/pl/docs/tutorials/kubernetes-basics/update/update-interactive.html b/content/pl/docs/tutorials/kubernetes-basics/update/update-interactive.html index 5664abc0e654f..00e329ee0c3d1 100644 --- a/content/pl/docs/tutorials/kubernetes-basics/update/update-interactive.html +++ b/content/pl/docs/tutorials/kubernetes-basics/update/update-interactive.html @@ -26,7 +26,8 @@ From 1262222578f30230c3ff76f87fcacbc1c94845cb Mon Sep 17 00:00:00 2001 From: Shubham Kuchhal Date: Mon, 4 Oct 2021 15:52:46 +0530 Subject: [PATCH 094/115] Change master to v1.22.0 --- .../access-authn-authz/extensible-admission-controllers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/docs/reference/access-authn-authz/extensible-admission-controllers.md b/content/en/docs/reference/access-authn-authz/extensible-admission-controllers.md index 513c3d3352c20..30841587b3e0f 100644 --- a/content/en/docs/reference/access-authn-authz/extensible-admission-controllers.md +++ b/content/en/docs/reference/access-authn-authz/extensible-admission-controllers.md @@ -79,7 +79,7 @@ The webhook server in the e2e test is deployed in the Kubernetes cluster, via the [deployment API](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#deployment-v1-apps). The test also creates a [service](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#service-v1-core) as the front-end of the webhook server. See -[code](https://github.com/kubernetes/kubernetes/blob/master/test/e2e/apimachinery/webhook.go#L748). +[code](https://github.com/kubernetes/kubernetes/blob/v1.22.0/test/e2e/apimachinery/webhook.go#L748). You may also deploy your webhooks outside of the cluster. You will need to update your webhook configurations accordingly. From a72f7fac17f4df744234e882af02c573ef6fce91 Mon Sep 17 00:00:00 2001 From: Pushkar Joglekar <3390906+PushkarJ@users.noreply.github.com> Date: Mon, 4 Oct 2021 20:59:49 -0700 Subject: [PATCH 095/115] Blog post: A closer look at NSA / CISA Kubernetes Hardening Guidance (#29791) * Blog post: NSA / CISA Hardening This is a community response blog post that acts as complementary resource that takes a closer look at the guidance. This blog post is not a substitute for reading the guidance Apply suggestions from code review Co-authored-by: Jim Angel Co-authored-by: Savitha Raghunathan Co-authored-by: Tim Bannister Co-authored-by: Shannon Kularathna Co-authored-by: Robert Co-authored-by: Rey Lejano * Changes based on NSA/CISA initial feedback Co-authored-by: Jim Angel Co-authored-by: Savitha Raghunathan Co-authored-by: Tim Bannister Co-authored-by: Shannon Kularathna Co-authored-by: Robert Co-authored-by: Rey Lejano --- .../_posts/2021-10-05-nsa-cisa-hardening.md | 417 ++++++++++++++++++ 1 file changed, 417 insertions(+) create mode 100644 content/en/blog/_posts/2021-10-05-nsa-cisa-hardening.md diff --git a/content/en/blog/_posts/2021-10-05-nsa-cisa-hardening.md b/content/en/blog/_posts/2021-10-05-nsa-cisa-hardening.md new file mode 100644 index 0000000000000..84665c529422b --- /dev/null +++ b/content/en/blog/_posts/2021-10-05-nsa-cisa-hardening.md @@ -0,0 +1,417 @@ +--- +layout: blog +title: A Closer Look at NSA/CISA Kubernetes Hardening Guidance +date: 2021-10-05 +slug: nsa-cisa-kubernetes-hardening-guidance +--- + +**Authors:** Jim Angel (Google), Pushkar Joglekar (VMware), and Savitha +Raghunathan (Red Hat) + +{{% alert title="Disclaimer" %}} +The open source tools listed in this article are to serve as examples only +and are in no way a direct recommendation from the Kubernetes community or authors. +{{% /alert %}} + +## Background + +USA's National Security Agency (NSA) and the Cybersecurity and Infrastructure +Security Agency (CISA) +released, "[Kubernetes Hardening Guidance](https://media.defense.gov/2021/Aug/03/2002820425/-1/-1/1/CTR_KUBERNETES%20HARDENING%20GUIDANCE.PDF)" +on August 3rd, 2021. The guidance details threats to Kubernetes environments +and provides secure configuration guidance to minimize risk. + +The following sections of this blog correlate to the sections in the NSA/CISA guidance. +Any missing sections are skipped because of limited opportunities to add +anything new to the existing content. + +_Note_: This blog post is not a substitute for reading the guide. Reading the published +guidance is recommended before proceeding as the following content is +complementary. + +## Introduction and Threat Model + +Note that the threats identified as important by the NSA/CISA, or the intended audience of this guidance, may be different from the threats that other enterprise users of Kubernetes consider important. This section +is still useful for organizations that care about data, resource theft and +service unavailability. + +The guidance highlights the following three sources of compromises: + +- Supply chain risks +- Malicious threat actors +- Insider threats (administrators, users, or cloud service providers) + +The [threat model](https://en.wikipedia.org/wiki/Threat_model) tries to take a step back and review threats that not only +exist within the boundary of a Kubernetes cluster but also include the underlying +infrastructure and surrounding workloads that Kubernetes does not manage. + +For example, when a workload outside the cluster shares the same physical +network, it has access to the kubelet and to control plane components: etcd, controller manager, scheduler and API +server. Therefore, the guidance recommends having network level isolation +separating Kubernetes clusters from other workloads that do not need connectivity +to Kubernetes control plane nodes. Specifically, scheduler, controller-manager, +etcd only need to be accessible to the API server. Any interactions with Kubernetes +from outside the cluster can happen by providing access to API server port. + +List of ports and protocols for each of these components are +defined in [Ports and Protocols](/docs/reference/ports-and-protocols/) +within the Kubernetes documentation. + +> Special note: kube-scheduler and kube-controller-manager uses different ports than the ones mentioned in the guidance + +The [Threat modelling](https://cnsmap.netlify.app/threat-modelling) section +from the CNCF [Cloud Native Security Whitepaper + Map](https://github.com/cncf/tag-security/tree/main/security-whitepaper) +provides another perspective on approaching threat modelling Kubernetes, from a +cloud native lens. + +## Kubernetes Pod security + +Kubernetes by default does not guarantee strict workload isolation between pods +running in the same node in a cluster. However, the guidance provides several +techniques to enhance existing isolation and reduce the attack surface in case of a +compromise. + +### "Non-root" containers and "rootless" container engines + +Several best practices related to basic security principle of least privilege +i.e. provide only the permissions are needed; no more, no less, are worth a +second look. + +The guide recommends setting non-root user at build time instead of relying on +setting `runAsUser` at runtime in your Pod spec. This is a good practice and provides +some level of defense in depth. For example, if the container image is built with user `10001` +and the Pod spec misses adding the `runAsuser` field in its `Deployment` object. In this +case there are certain edge cases that are worth exploring for awareness: + +1. Pods can fail to start, if the user defined at build time is different from + the one defined in pod spec and some files are as a result inaccessible. +2. Pods can end up sharing User IDs unintentionally. This can be problematic + even if the User IDs are non-zero in a situation where a container escape to + host file system is possible. Once the attacker has access to the host file + system, they get access to all the file resources that are owned by other + unrelated pods that share the same UID. +3. Pods can end up sharing User IDs, with other node level processes not managed + by Kubernetes e.g. node level daemons for auditing, vulnerability scanning, + telemetry. The threat is similar to the one above where host file system + access can give attacker full access to these node level daemons without + needing to be root on the node. + +However, none of these cases will have as severe an impact as a container +running as root being able to escape as a root user on the host, which can provide +an attacker with complete control of the worker node, further allowing lateral +movement to other worker or control plane nodes. + +Kubernetes 1.22 introduced +an [alpha feature](/docs/tasks/administer-cluster/kubelet-in-userns/) +that specifically reduces the impact of such a control plane component running +as root user to a non-root user through user namespaces. + +That ([alpha stage](/docs/reference/command-line-tools-reference/feature-gates/#feature-stages)) support for user namespaces / rootless mode is available with +the following container runtimes: + +- [Docker Engine](https://docs.docker.com/engine/security/rootless/) +- [Podman](https://developers.redhat.com/blog/2020/09/25/rootless-containers-with-podman-the-basics) + +Some distributions support running in rootless mode, like the following: + +- [kind](https://kind.sigs.k8s.io/docs/user/rootless/) +- [k3s](https://rancher.com/docs/k3s/latest/en/advanced/#running-k3s-with-rootless-mode-experimental) +- [Usernetes](https://github.com/rootless-containers/usernetes) + +### Immutable container filesystems + +The NSA/CISA Kubernetes Hardening Guidance highlights an often overlooked feature `readOnlyRootFileSystem`, with a +working example in [Appendix B](https://media.defense.gov/2021/Aug/03/2002820425/-1/-1/1/CTR_KUBERNETES%20HARDENING%20GUIDANCE.PDF#page=42). This example limits execution and tampering of +containers at runtime. Any read/write activity can then be limited to few +directories by using `tmpfs` volume mounts. + +However, some applications that modify the container filesystem at runtime, like exploding a WAR or JAR file at container startup, +could face issues when enabling this feature. To avoid this issue, consider making minimal changes to the filesystem at runtime +when possible. + +### Building secure container images + +Kubernetes Hardening Guidance also recommends running a scanner at deploy time as an admission controller, +to prevent vulnerable or misconfigured pods from running in the cluster. +Theoretically, this sounds like a good approach but there are several caveats to +consider before this can be implemented in practice: + +- Depending on network bandwidth, available resources and scanner of choice, + scanning for vulnerabilities for an image can take an indeterminate amount of + time. This could lead to slower or unpredictable pod start up times, which + could result in spikes of unavailability when apps are serving peak load. +- If the policy that allows or denies pod startup is made using incorrect or + incomplete data it could result in several false positive or false negative + outcomes like the following: + - inside a container image, the `openssl` package is detected as vulnerable. However, + the application is written in Golang and uses the Go `crypto` package for TLS. Therefore, this vulnerability + is not in the code execution path and as such has minimal impact if it + remains unfixed. + - A vulnerability is detected in the `openssl` package for a Debian base image. + However, the upstream Debian community considers this as a Minor impact + vulnerability and as a result does not release a patch fix for this + vulnerability. The owner of this image is now stuck with a vulnerability that + cannot be fixed and a cluster that does not allow the image to run because + of predefined policy that does not take into account whether the fix for a + vulnerability is available or not + - A Golang app is built on top of a [distroless](https://github.com/GoogleContainerTools/distroless) + image, but it is compiled with a Golang version that uses a vulnerable [standard library](https://pkg.go.dev/std). + The scanner has + no visibility into golang version but only on OS level packages. So it + allows the pod to run in the cluster in spite of the image containing an + app binary built on vulnerable golang. + +To be clear, relying on vulnerability scanners is absolutely a good idea but +policy definitions should be flexible enough to allow: + +- Creation of exception lists for images or vulnerabilities through labelling +- Overriding the severity with a risk score based on impact of a vulnerability +- Applying the same policies at build time to catch vulnerable images with + fixable vulnerabilities before they can be deployed into Kubernetes clusters + +Special considerations like offline vulnerability database fetch, may also be +needed, if the clusters run in an air-gapped environment and the scanners +require internet access to update the vulnerability database. + +### Pod Security Policies + +Since Kubernetes v1.21, the [PodSecurityPolicy](/docs/concepts/policy/pod-security-policy/) +API and related features are [deprecated](/blog/2021/04/06/podsecuritypolicy-deprecation-past-present-and-future/), +but some of the guidance in this section will still apply for the next few years, until cluster operators +upgrade their clusters to newer Kubernetes versions. + +The Kubernetes project is working on a replacement for PodSecurityPolicy. +Kubernetes v1.22 includes an alpha feature called called [Pod Security Admission](/docs/concepts/security/pod-security-admission/) +that is intended to allow enforcing a minimum level of isolation between pods. + +The built-in isolation levels for Pod Security Admission are derived +from [Pod Security Standards](/docs/concepts/security/pod-security-standards/), which is a superset of all the components mentioned in Table I [page 10](https://media.defense.gov/2021/Aug/03/2002820425/-1/-1/1/CTR_KUBERNETES%20HARDENING%20GUIDANCE.PDF#page=17) of +the guidance. + +Information about migrating from PodSecurityPolicy to the Pod Security +Admission feature is available +in +[Migrate from PodSecurityPolicy to the Built-In PodSecurity Admission Controller](/docs/tasks/configure-pod-container/migrate-from-psp/). + +One important behavior mentioned in the guidance that remains the same between +Pod Security Policy and its replacement is that enforcing either of them does +not affect pods that are already running. With both PodSecurityPolicy and Pod Security Admission, +the enforcement happens during the pod creation +stage. + +### Hardening container engines + +Some container workloads are less trusted than others but may need to run in the +same cluster. In those cases, running them on dedicated nodes that include +hardened container runtimes that provide stricter pod isolation boundaries can +act as a useful security control. + +Kubernetes supports +an API called [RuntimeClass](/docs/concepts/containers/runtime-class/) that is +stable / GA (and, therefore, enabled by default) stage as of Kubernetes v1.20. +RuntimeClass allows you to ensure that Pods requiring strong isolation are scheduled onto +nodes that can offer it. + +Some third-party projects that you can use in conjunction with RuntimeClass are: + +- [kata containers](https://github.com/kata-containers/kata-containers/blob/main/docs/how-to/how-to-use-k8s-with-cri-containerd-and-kata.md#create-runtime-class-for-kata-containers) +- [gvisor](https://gvisor.dev/docs/user_guide/containerd/quick_start/) + +As discussed here and in the guidance, many features and tooling exist in and around +Kubernetes that can enhance the isolation boundaries between +pods. Based on relevant threats and risk posture, you should pick and choose +between them, instead of trying to apply all the recommendations. Having said that, cluster +level isolation i.e. running workloads in dedicated clusters, remains the strictest workload +isolation mechanism, in spite of improvements mentioned earlier here and in the guide. + +## Network Separation and Hardening + +Kubernetes Networking can be tricky and this section focuses on how to secure +and harden the relevant configurations. The guide identifies the following as key +takeaways: +- Using NetworkPolicies to create isolation between resources, +- Securing the control plane +- Encrypting traffic and sensitive data + +### Network Policies + +Network policies can be created with the help of network plugins. In order to +make the creation and visualization easier for users, Cilium supports +a [web GUI tool](https://editor.cilium.io). That web GUI lets you create Kubernetes +NetworkPolicies (a generic API that nevertheless requires a compatible CNI plugin), +and / or Cilium network policies (CiliumClusterwideNetworkPolicy and CiliumNetworkPolicy, +which only work in clusters that use the Cilium CNI plugin). +You can use these APIs to restrict network traffic between pods, and therefore minimize the +attack vector. + +Another scenario that is worth exploring is the usage of external IPs. Some +services, when misconfigured, can create random external IPs. An attacker can take +advantage of this misconfiguration and easily intercept traffic. This vulnerability +has been reported +in [CVE-2020-8554](https://www.cvedetails.com/cve/CVE-2020-8554/). +Using [externalip-webhook](https://github.com/kubernetes-sigs/externalip-webhook) +can mitigate this vulnerability by preventing the services from using random +external IPs. [externalip-webhook](https://github.com/kubernetes-sigs/externalip-webhook) +only allows creation of services that don't require external IPs or whose +external IPs are within the range specified by the administrator. + +> CVE-2020-8554 - Kubernetes API server in all versions allow an attacker +> who is able to create a ClusterIP service and set the `spec.externalIPs` field, +> to intercept traffic to that IP address. Additionally, an attacker who is able to +> patch the `status` (which is considered a privileged operation and should not +> typically be granted to users) of a LoadBalancer service can set the +> `status.loadBalancer.ingress.ip` to similar effect. + +### Resource Policies + +In addition to configuring ResourceQuotas and limits, consider restricting how many process +IDs (PIDs) a given Pod can use, and also to reserve some PIDs for node-level use to avoid +resource exhaustion. More details to apply these limits can be +found in [Process ID Limits And Reservations](/docs/concepts/policy/pid-limiting/). + +### Control Plane Hardening + +In the next section, the guide covers control plane hardening. It is worth +noting that +from [Kubernetes 1.20](https://github.com/kubernetes/kubernetes/issues/91506), +insecure port from API server, has been removed. + +### Etcd + +As a general rule, the etcd server should be configured to only trust +certificates assigned to the API server. It limits the attack surface and prevents a +malicious attacker from gaining access to the cluster. It might be beneficial to +use a separate CA for etcd, as it by default trusts all the certificates issued +by the root CA. + +### Kubeconfig Files + +In addition to specifying the token and certificates directly, `.kubeconfig` +supports dynamic retrieval of temporary tokens using auth provider plugins. +Beware of the possibility of malicious +shell [code execution](https://banzaicloud.com/blog/kubeconfig-security/) in a +`kubeconfig` file. Once attackers gain access to the cluster, they can steal ssh +keys/secrets or more. + +### Secrets +Kubernetes [Secrets](/docs/concepts/configuration/secret/) is the native way of managing secrets as a Kubernetes +API object. However, in some scenarios such as a desire to have a single source of truth for all app secrets, irrespective of whether they run on Kubernetes or not, secrets can be managed loosely coupled with +Kubernetes and consumed by pods through side-cars or init-containers with minimal usage of Kubernetes Secrets API. + +[External secrets providers](https://github.com/external-secrets/kubernetes-external-secrets) +and [csi-secrets-store](https://github.com/kubernetes-sigs/secrets-store-csi-driver) +are some of these alternatives to Kubernetes Secrets + +## Log Auditing + +The NSA/CISA guidance stresses monitoring and alerting based on logs. The key points +include logging at the host level, application level, and on the cloud. When +running Kubernetes in production, it's important to understand who's +responsible, and who's accountable, for each layer of logging. + +### Kubernetes API auditing + +One area that deserves more focus is what exactly should alert or be logged. The +document outlines a sample policy in [Appendix L: Audit Policy](https://media.defense.gov/2021/Aug/03/2002820425/-1/-1/1/CTR_KUBERNETES%20HARDENING%20GUIDANCE.PDF#page=55) that logs all +RequestResponse's including metadata and request / response bodies. While helpful for a demo, it may not be practical for production. + +Each organization needs to evaluate their +own threat model and build an audit policy that complements or helps troubleshooting incident response. Think +about how someone would attack your organization and what audit trail could identify it. Review more advanced options for tuning audit logs in the official [audit logging documentation](/docs/tasks/debug-application-cluster/audit/#audit-policy). +It's crucial to tune your audit logs to only include events that meet your threat model. A minimal audit policy that logs everything at `metadata` level can also be a good starting point. + +Audit logging configurations can also be tested with +kind following these [instructions](https://kind.sigs.k8s.io/docs/user/auditing). + +### Streaming logs and auditing + +Logging is important for threat and anomaly detection. As the document outlines, +it's a best practice to scan and alert on logs as close to real time as possible +and to protect logs from tampering if a compromise occurs. It's important to +reflect on the various levels of logging and identify the critical areas such as +API endpoints. + +Kubernetes API audit logging can stream to a webhook and there's an example in [Appendix N: Webhook configuration](https://media.defense.gov/2021/Aug/03/2002820425/-1/-1/1/CTR_KUBERNETES%20HARDENING%20GUIDANCE.PDF#page=58). Using a webhook could be a method that +stores logs off cluster and/or centralizes all audit logs. Once logs are +centrally managed, look to enable alerting based on critical events. Also ensure +you understand what the baseline is for normal activities. + +### Alert identification + +While the guide stressed the importance of notifications, there is not a blanket +event list to alert from. The alerting requirements vary based on your own +requirements and threat model. Examples include the following events: + +- Changes to the `securityContext` of a Pod +- Updates to admission controller configs +- Accessing certain files / URLs + +### Additional logging resources + +- [Seccomp Security Profiles and You: A Practical Guide - Duffie Cooley](https://www.youtube.com/watch?v=OPuu8wsu2Zc) +- [TGI Kubernetes 119: Gatekeeper and OPA](https://www.youtube.com/watch?v=ZJgaGJm9NJE) +- [Abusing The Lack of Kubernetes Auditing Policies](https://www.lacework.com/blog/hiding-in-plaintext-sight-abusing-the-lack-of-kubernetes-auditing-policies/) +- [Enable seccomp for all workloads with a new v1.22 alpha feature](https://kubernetes.io/blog/2021/08/25/seccomp-default/) +- [This Week in Cloud Native: Auditing / Pod Security](https://www.twitch.tv/videos/1147889860) + +## Upgrading and Application Security practices + +Kubernetes releases three times per year, so upgrade-related toil is a common problem for +people running production clusters. In addition to this, operators must +regularly upgrade the underlying node's operating system and running +applications. This is a best practice to ensure continued support and to reduce +the likelihood of bugs or vulnerabilities. + +Kubernetes supports the three most recent stable releases. While each Kubernetes +release goes through a large number of tests before being published, some +teams aren't comfortable running the latest stable release until some time has +passed. No matter what version you're running, ensure that patch upgrades +happen frequently or automatically. More information can be found in +the [version skew](/releases/version-skew-policy/) policy +pages. + +When thinking about how you'll manage node OS upgrades, consider ephemeral +nodes. Having the ability to destroy and add nodes allows your team to respond +quicker to node issues. In addition, having deployments that tolerate node +instability (and a culture that encourages frequent deployments) allows for +easier cluster upgrades. + +Additionally, it's worth reiterating from the guidance that periodic +vulnerability scans and penetration tests can be performed on the various system +components to proactively look for insecure configurations and vulnerabilities. + +### Finding release & security information + +To find the most recent Kubernetes supported versions, refer to +[https://k8s.io/releases](https://k8s.io/releases), which includes minor versions. It's good to stay up to date with +your minor version patches. + +If you're running a managed Kubernetes offering, look for their release +documentation and find their various security channels. + +Subscribe to +the [Kubernetes Announce mailing list](https://groups.google.com/g/kubernetes-announce). +The Kubernetes Announce mailing list is searchable for terms such +as "[Security Advisories](https://groups.google.com/g/kubernetes-announce/search?q=%5BSecurity%20Advisory%5D)". +You can set up alerts and email notifications as long as you know what key +words to alert on. + +## Conclusion + +In summary, it is fantastic to see security practitioners sharing this +level of detailed guidance in public. This guidance further highlights +Kubernetes going mainstream and how securing Kubernetes clusters and the +application containers running on Kubernetes continues to need attention and focus of +practitioners. Only a few weeks after the guidance was published, an open source +tool [kubescape](https://github.com/armosec/kubescape) to validate cluster +against this guidance became available. + +This tool can be a great starting point to check the current state of your +clusters, after which you can use the information in this blog post and in the guidance to assess +where improvements can be made. + +Finally, it is worth reiterating that not all controls in this guidance will +make sense for all practitioners. The best way to know which controls matter is +to rely on the threat model of your own Kubernetes environment. + +_A special shout out and thanks to Rory McCune (@raesene) for his inputs to this blog post_ From 3049f75a0127330084b29b512458607dc610d694 Mon Sep 17 00:00:00 2001 From: Christian Kotzbauer Date: Tue, 5 Oct 2021 09:00:53 +0200 Subject: [PATCH 096/115] fix: removed duplicate "called" --- content/en/blog/_posts/2021-10-05-nsa-cisa-hardening.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/blog/_posts/2021-10-05-nsa-cisa-hardening.md b/content/en/blog/_posts/2021-10-05-nsa-cisa-hardening.md index 84665c529422b..1af75e9ceb597 100644 --- a/content/en/blog/_posts/2021-10-05-nsa-cisa-hardening.md +++ b/content/en/blog/_posts/2021-10-05-nsa-cisa-hardening.md @@ -181,7 +181,7 @@ but some of the guidance in this section will still apply for the next few years upgrade their clusters to newer Kubernetes versions. The Kubernetes project is working on a replacement for PodSecurityPolicy. -Kubernetes v1.22 includes an alpha feature called called [Pod Security Admission](/docs/concepts/security/pod-security-admission/) +Kubernetes v1.22 includes an alpha feature called [Pod Security Admission](/docs/concepts/security/pod-security-admission/) that is intended to allow enforcing a minimum level of isolation between pods. The built-in isolation levels for Pod Security Admission are derived From 0d589766950787ab98764d9c7186f9431210c1d8 Mon Sep 17 00:00:00 2001 From: mehabhalodiya Date: Tue, 5 Oct 2021 17:43:17 +0530 Subject: [PATCH 097/115] Migrate Contributing new content overview into section index --- .../en/docs/contribute/new-content/_index.md | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/content/en/docs/contribute/new-content/_index.md b/content/en/docs/contribute/new-content/_index.md index 4992a3765442a..01677af0ede15 100644 --- a/content/en/docs/contribute/new-content/_index.md +++ b/content/en/docs/contribute/new-content/_index.md @@ -1,4 +1,64 @@ --- title: Contributing new content +content_type: concept +main_menu: true weight: 20 --- + + + +This section contains information you should know before contributing new content. + + + + + + +## Contributing basics + +- Write Kubernetes documentation in Markdown and build the Kubernetes site using [Hugo](https://gohugo.io/). +- The source is in [GitHub](https://github.com/kubernetes/website). You can find Kubernetes documentation at `/content/en/docs/`. Some of the reference documentation is automatically generated from scripts in the `update-imported-docs/` directory. +- [Page content types](/docs/contribute/style/page-content-types/) describe the presentation of documentation content in Hugo. +- In addition to the standard Hugo shortcodes, we use a number of + [custom Hugo shortcodes](/docs/contribute/style/hugo-shortcodes/) in our documentation to control the presentation of content. +- Documentation source is available in multiple languages in `/content/`. Each + language has its own folder with a two-letter code determined by the + [ISO 639-1 standard](https://www.loc.gov/standards/iso639-2/php/code_list.php). For + example, English documentation source is stored in `/content/en/docs/`. +- For more information about contributing to documentation in multiple languages or starting a new translation, see [localization](/docs/contribute/localization). + +## Before you begin {#before-you-begin} + +### Sign the CNCF CLA {#sign-the-cla} + +All Kubernetes contributors **must** read the [Contributor guide](https://github.com/kubernetes/community/blob/master/contributors/guide/README.md) and [sign the Contributor License Agreement (CLA)](https://github.com/kubernetes/community/blob/master/CLA.md). + +Pull requests from contributors who haven't signed the CLA fail the automated tests. The name and email you provide must match those found in your `git config`, and your git name and email must match those used for the CNCF CLA. + +### Choose which Git branch to use + +When opening a pull request, you need to know in advance which branch to base your work on. + +Scenario | Branch +:---------|:------------ +Existing or new English language content for the current release | `main` +Content for a feature change release | The branch which corresponds to the major and minor version the feature change is in, using the pattern `dev-`. For example, if a feature changes in the `v{{< skew nextMinorVersion >}}` release, then add documentation changes to the ``dev-{{< skew nextMinorVersion >}}`` branch. +Content in other languages (localizations) | Use the localization's convention. See the [Localization branching strategy](/docs/contribute/localization/#branching-strategy) for more information. + + +If you're still not sure which branch to choose, ask in `#sig-docs` on Slack. + +{{< note >}} +If you already submitted your pull request and you know that the base branch +was wrong, you (and only you, the submitter) can change it. +{{< /note >}} + +### Languages per PR + +Limit pull requests to one language per PR. If you need to make an identical change to the same code sample in multiple languages, open a separate PR for each language. + +## Tools for contributors + +The [doc contributors tools](https://github.com/kubernetes/website/tree/main/content/en/docs/doc-contributor-tools) directory in the `kubernetes/website` repository contains tools to help your contribution journey go more smoothly. + + From 716da39b217508ba71efea3d5b3351b3322e19a1 Mon Sep 17 00:00:00 2001 From: mehabhalodiya Date: Tue, 5 Oct 2021 17:51:45 +0530 Subject: [PATCH 098/115] Redirect overview to new content --- static/_redirects | 1 + 1 file changed, 1 insertion(+) diff --git a/static/_redirects b/static/_redirects index 3274c895a792d..6868f56b799a9 100644 --- a/static/_redirects +++ b/static/_redirects @@ -169,6 +169,7 @@ /docs/contribute/write-new-topic/ /docs/home/contribute/write-new-topic/ 301 /docs/contribute/start/ /docs/contribute/ 301 /docs/contribute/intermediate/ /docs/contribute/ 301 +/docs/contribute/new-content/overview/ /docs/contribute/new-content/ 301 /docs/deprecate/ /docs/reference/using-api/deprecation-policy/ 301 /docs/deprecated/ /docs/reference/using-api/deprecation-policy/ 301 From fb2cc8ed6d7bca5e16daa215645f7ae1a21b4951 Mon Sep 17 00:00:00 2001 From: mehabhalodiya Date: Tue, 5 Oct 2021 17:56:08 +0530 Subject: [PATCH 099/115] Delete overview.md --- .../docs/contribute/new-content/overview.md | 65 ------------------- 1 file changed, 65 deletions(-) delete mode 100644 content/en/docs/contribute/new-content/overview.md diff --git a/content/en/docs/contribute/new-content/overview.md b/content/en/docs/contribute/new-content/overview.md deleted file mode 100644 index 8b4da4970ab40..0000000000000 --- a/content/en/docs/contribute/new-content/overview.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: Contributing new content overview -linktitle: Overview -content_type: concept -main_menu: true -weight: 5 ---- - - - -This section contains information you should know before contributing new content. - - - - - - -## Contributing basics - -- Write Kubernetes documentation in Markdown and build the Kubernetes site using [Hugo](https://gohugo.io/). -- The source is in [GitHub](https://github.com/kubernetes/website). You can find Kubernetes documentation at `/content/en/docs/`. Some of the reference documentation is automatically generated from scripts in the `update-imported-docs/` directory. -- [Page content types](/docs/contribute/style/page-content-types/) describe the presentation of documentation content in Hugo. -- In addition to the standard Hugo shortcodes, we use a number of - [custom Hugo shortcodes](/docs/contribute/style/hugo-shortcodes/) in our documentation to control the presentation of content. -- Documentation source is available in multiple languages in `/content/`. Each - language has its own folder with a two-letter code determined by the - [ISO 639-1 standard](https://www.loc.gov/standards/iso639-2/php/code_list.php). For - example, English documentation source is stored in `/content/en/docs/`. -- For more information about contributing to documentation in multiple languages or starting a new translation, see [localization](/docs/contribute/localization). - -## Before you begin {#before-you-begin} - -### Sign the CNCF CLA {#sign-the-cla} - -All Kubernetes contributors **must** read the [Contributor guide](https://github.com/kubernetes/community/blob/master/contributors/guide/README.md) and [sign the Contributor License Agreement (CLA)](https://github.com/kubernetes/community/blob/master/CLA.md). - -Pull requests from contributors who haven't signed the CLA fail the automated tests. The name and email you provide must match those found in your `git config`, and your git name and email must match those used for the CNCF CLA. - -### Choose which Git branch to use - -When opening a pull request, you need to know in advance which branch to base your work on. - -Scenario | Branch -:---------|:------------ -Existing or new English language content for the current release | `main` -Content for a feature change release | The branch which corresponds to the major and minor version the feature change is in, using the pattern `dev-`. For example, if a feature changes in the `v{{< skew nextMinorVersion >}}` release, then add documentation changes to the ``dev-{{< skew nextMinorVersion >}}`` branch. -Content in other languages (localizations) | Use the localization's convention. See the [Localization branching strategy](/docs/contribute/localization/#branching-strategy) for more information. - - -If you're still not sure which branch to choose, ask in `#sig-docs` on Slack. - -{{< note >}} -If you already submitted your pull request and you know that the base branch -was wrong, you (and only you, the submitter) can change it. -{{< /note >}} - -### Languages per PR - -Limit pull requests to one language per PR. If you need to make an identical change to the same code sample in multiple languages, open a separate PR for each language. - -## Tools for contributors - -The [doc contributors tools](https://github.com/kubernetes/website/tree/main/content/en/docs/doc-contributor-tools) directory in the `kubernetes/website` repository contains tools to help your contribution journey go more smoothly. - - From ff517544eacfe5ea64a0033abae51f5496e56f73 Mon Sep 17 00:00:00 2001 From: Tim Bannister Date: Tue, 5 Oct 2021 17:11:24 +0100 Subject: [PATCH 100/115] Update to latest CC-BY 4.x license text Copied from https://creativecommons.org/licenses/by/4.0/legalcode.txt --- LICENSE | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/LICENSE b/LICENSE index b6988e7edcd3c..da6ab6cc8f333 100644 --- a/LICENSE +++ b/LICENSE @@ -33,7 +33,7 @@ exhaustive, and do not form part of our licenses. material not subject to the license. This includes other CC- licensed material, or material used under an exception or limitation to copyright. More considerations for licensors: - wiki.creativecommons.org/Considerations_for_licensors + wiki.creativecommons.org/Considerations_for_licensors Considerations for the public: By using one of our public licenses, a licensor grants the public permission to use the @@ -48,9 +48,9 @@ exhaustive, and do not form part of our licenses. rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to - respect those requests where reasonable. More_considerations - for the public: - wiki.creativecommons.org/Considerations_for_licensees + respect those requests where reasonable. More considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees ======================================================================= @@ -378,7 +378,7 @@ Section 8 -- Interpretation. Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances -will be considered the "Licensor." The text of the Creative Commons +will be considered the “Licensor.” The text of the Creative Commons public licenses is dedicated to the public domain under the CC0 Public Domain Dedication. Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as @@ -393,3 +393,4 @@ the avoidance of doubt, this paragraph does not form part of the public licenses. Creative Commons may be contacted at creativecommons.org. + From 053fb85c04b3d539d36cf06649b2427c47118149 Mon Sep 17 00:00:00 2001 From: Tim Bannister Date: Tue, 5 Oct 2021 17:14:41 +0100 Subject: [PATCH 101/115] Fix approval rules for GitHub workflows Only SIG Docs leads (chairs + tech leads) should be able to approve changes to workflows. --- .github/workflows/OWNERS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/OWNERS b/.github/workflows/OWNERS index 404875fc2eddc..c31fa3a256ed1 100644 --- a/.github/workflows/OWNERS +++ b/.github/workflows/OWNERS @@ -3,6 +3,9 @@ # When modifying this file, consider the security implications of # allowing listed reviewers / approvals to modify or remove any # configured GitHub Actions. +# +options: + no_parent_owners: true reviewers: - sig-docs-leads From 104f241aab3b932f27820bb04fbbbe5e4f9663ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Garc=C3=ADa=20Veytia=20=28Puerco=29?= Date: Tue, 5 Oct 2021 15:43:34 -0500 Subject: [PATCH 102/115] releng: Bump oct patch release one week later MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As the cherry pick deadline for october '21 lands right during kubecon week, SIG Release decided to move the patch releases one week later. This PR modifies the dates in the schedule data file. Signed-off-by: Adolfo García Veytia (Puerco) --- data/releases/schedule.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/data/releases/schedule.yaml b/data/releases/schedule.yaml index 55d5b12633b11..2393235733e18 100644 --- a/data/releases/schedule.yaml +++ b/data/releases/schedule.yaml @@ -1,8 +1,8 @@ schedules: - release: 1.22 next: 1.22.3 - cherryPickDeadline: 2021-10-15 - targetDate: 2021-10-20 + cherryPickDeadline: 2021-10-22 + targetDate: 2021-10-27 endOfLifeDate: 2022-10-28 previousPatches: - release: 1.22.2 @@ -13,8 +13,8 @@ schedules: targetDate: 2021-08-19 - release: 1.21 next: 1.21.6 - cherryPickDeadline: 2021-10-15 - targetDate: 2021-10-20 + cherryPickDeadline: 2021-10-22 + targetDate: 2021-10-27 endOfLifeDate: 2022-06-28 previousPatches: - release: 1.21.5 @@ -35,8 +35,8 @@ schedules: note: Regression https://groups.google.com/g/kubernetes-dev/c/KuF8s2zueFs - release: 1.20 next: 1.20.12 - cherryPickDeadline: 2021-10-15 - targetDate: 2021-10-20 + cherryPickDeadline: 2021-10-22 + targetDate: 2021-10-27 endOfLifeDate: 2022-02-28 previousPatches: - release: 1.20.11 From e5aca814aaf8e120ea39681ca0ab404c339015da Mon Sep 17 00:00:00 2001 From: Charles Pretzer Date: Tue, 5 Oct 2021 14:33:40 -0700 Subject: [PATCH 103/115] Update blog post to include the fix version and fix the link to the PR Signed-off-by: Charles Pretzer --- ...btleties-debugging-an-intermittent-connection-resets.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/content/en/blog/_posts/2019-03-29-kube-proxy-subtleties-debugging-an-intermittent-connection-resets.md b/content/en/blog/_posts/2019-03-29-kube-proxy-subtleties-debugging-an-intermittent-connection-resets.md index 12dd2d79a3fd2..bed35dabb5c52 100644 --- a/content/en/blog/_posts/2019-03-29-kube-proxy-subtleties-debugging-an-intermittent-connection-resets.md +++ b/content/en/blog/_posts/2019-03-29-kube-proxy-subtleties-debugging-an-intermittent-connection-resets.md @@ -144,10 +144,9 @@ ways to address it. - Specifically add an iptables rule to drop the packets that are marked as *INVALID*, so it won’t reach to client pod and cause harm. -The fix is drafted (https://github.com/kubernetes/kubernetes/pull/74840), but -unfortunately it didn’t catch the v1.14 release window. However, for the users -that are affected by this bug, there is a way to mitigate the problem by applying -the following rule in your cluster. +The [fix](https://github.com/kubernetes/kubernetes/pull/74840) is available in v1.15+. +However, for the users that are affected by this bug, there is a way to mitigate the +problem by applying the following rule in your cluster. ```yaml apiVersion: extensions/v1beta1 From c8300c0560a4b0ded7c4e7be683279f6d0e35069 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20Garc=C3=ADa=20Veytia=20=28Puerco=29?= Date: Tue, 5 Oct 2021 16:55:44 -0500 Subject: [PATCH 104/115] releng: Bump website dates one week later MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit moves the October '21 patch release dates one week later as the original dates for CP and release fell during KubeCon Week. Follow-up to https://github.com/kubernetes/website/pull/29937 Signed-off-by: Adolfo García Veytia (Puerco) --- content/en/releases/patch-releases.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/content/en/releases/patch-releases.md b/content/en/releases/patch-releases.md index 91bd47bcd0d71..88725d5b92ca8 100644 --- a/content/en/releases/patch-releases.md +++ b/content/en/releases/patch-releases.md @@ -78,7 +78,7 @@ releases may also occur in between these. | Monthly Patch Release | Cherry Pick Deadline | Target date | | --------------------- | -------------------- | ----------- | -| October 2021 | 2021-10-15 | 2021-10-20 | +| October 2021 | 2021-10-22 | 2021-10-27 | | November 2021 | 2021-11-12 | 2021-11-17 | | December 2021 | 2021-12-10 | 2021-12-15 | | January 2022 | 2021-01-14 | 2021-01-19 | @@ -93,7 +93,7 @@ End of Life for **1.22** is **2022-10-28** | PATCH RELEASE | CHERRY PICK DEADLINE | TARGET DATE | NOTE | |---------------|----------------------|-------------|------| -| 1.22.3 | 2021-10-15 | 2021-10-20 | | +| 1.22.3 | 2021-10-22 | 2021-10-27 | | | 1.22.2 | 2021-09-10 | 2021-09-15 | | | 1.22.1 | 2021-08-16 | 2021-08-19 | | @@ -105,7 +105,7 @@ End of Life for **1.21** is **2022-06-28** | PATCH RELEASE | CHERRY PICK DEADLINE | TARGET DATE | NOTE | | ------------- | -------------------- | ----------- | ---------------------------------------------------------------------- | -| 1.21.6 | 2021-10-15 | 2021-10-20 | | +| 1.21.6 | 2021-10-22 | 2021-10-27 | | | 1.21.5 | 2021-09-10 | 2021-09-15 | | | 1.21.4 | 2021-08-07 | 2021-08-11 | | | 1.21.3 | 2021-07-10 | 2021-07-14 | | @@ -120,7 +120,7 @@ End of Life for **1.20** is **2022-02-28** | PATCH RELEASE | CHERRY PICK DEADLINE | TARGET DATE | NOTE | | ------------- | -------------------- | ----------- | ----------------------------------------------------------------------------------- | -| 1.20.12 | 2021-10-15 | 2021-10-20 | | +| 1.20.12 | 2021-10-22 | 2021-10-27 | | | 1.20.11 | 2021-09-10 | 2021-09-15 | | | 1.20.10 | 2021-08-07 | 2021-08-11 | | | 1.20.9 | 2021-07-10 | 2021-07-14 | | @@ -141,6 +141,7 @@ End of Life for **1.19** is **2021-10-28** | PATCH RELEASE | CHERRY PICK DEADLINE | TARGET DATE | NOTE | | ------------- | -------------------- | ----------- | ------------------------------------------------------------------------- | +| 1.19.16 | 2021-10-22 | 2021-09-27 | | | 1.19.15 | 2021-09-10 | 2021-09-15 | | | 1.19.14 | 2021-08-07 | 2021-08-11 | | | 1.19.13 | 2021-07-10 | 2021-07-14 | | From 7994d24f5eb0d23b205cbc03586a03c0cff40d38 Mon Sep 17 00:00:00 2001 From: Carlos Panato Date: Wed, 6 Oct 2021 09:55:33 +0200 Subject: [PATCH 105/115] releng: update patch release dates for 1.19 Signed-off-by: Carlos Panato --- data/releases/schedule.yaml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/data/releases/schedule.yaml b/data/releases/schedule.yaml index 2393235733e18..dbbd69d999330 100644 --- a/data/releases/schedule.yaml +++ b/data/releases/schedule.yaml @@ -76,11 +76,14 @@ schedules: targetDate: 2020-12-18 note: "Tagging Issue https://groups.google.com/g/kubernetes-dev/c/dNH2yknlCBA" - release: 1.19 - next: 1.19.15 - cherryPickDeadline: 2021-09-10 - targetDate: 2021-09-15 + next: 1.19.16 + cherryPickDeadline: 2021-10-22 + targetDate: 2021-10-27 endOfLifeDate: 2021-10-28 previousPatches: + - release: 1.19.15 + cherryPickDeadline: 2021-09-10 + targetDate: 2021-09-15 - release: 1.19.14 cherryPickDeadline: 2021-08-07 targetDate: 2021-08-11 From 98834b63663e08ba6c50f074ee921fc3ff0edab3 Mon Sep 17 00:00:00 2001 From: Maciej Filocha Date: Mon, 4 Oct 2021 10:19:01 +0200 Subject: [PATCH 106/115] Synchronize Polish localization for ver 1.22, part 3 Synchronize Polish localization with upstream up to 08d92f9137924abdf442e7d9fb7372901379b993. Part 3. --- content/pl/docs/reference/_index.md | 52 +++++++++++++++---- content/pl/docs/reference/glossary/index.md | 2 +- .../docs/reference/glossary/kube-scheduler.md | 2 +- 3 files changed, 44 insertions(+), 12 deletions(-) diff --git a/content/pl/docs/reference/_index.md b/content/pl/docs/reference/_index.md index fd4ab2bff3bb3..8f97bfec604bc 100644 --- a/content/pl/docs/reference/_index.md +++ b/content/pl/docs/reference/_index.md @@ -14,36 +14,68 @@ Tutaj znajdziesz dokumentację źródłową Kubernetesa. ## Dokumentacja API +* [Glossary](/docs/reference/glossary/) - Pełna, zestandaryzowana lista terminologii Kubernetesa + * [Kubernetes API Reference](/docs/reference/kubernetes-api/) * [One-page API Reference for Kubernetes {{< param "version" >}}](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/) -* [Using The Kubernetes API](/docs/reference/using-api/) - ogólne informacje na temat API Kubernetesa. +* [Using The Kubernetes API](/docs/reference/using-api/) - ogólne informacje na temat API Kubernetesa +* [API access control](/docs/reference/access-authn-authz/) - szczegóły dotyczące kontroli dostępu do API Kubernetesa +* [Well-Known Labels, Annotations and Taints](/docs/reference/labels-annotations-taints/) -## Biblioteki klientów API +## Oficjalnie wspierane biblioteki klienckie Aby wywołać Kubernetes API z wybranego języka programowania, możesz skorzystać z [bibliotek klienckich](/docs/reference/using-api/client-libraries/). Oficjalnie wspierane biblioteki to: -* [Kubernetes Go client library](https://github.com/kubernetes/client-go/) * [Kubernetes Python client library](https://github.com/kubernetes-client/python) * [Kubernetes Java client library](https://github.com/kubernetes-client/java) * [Kubernetes JavaScript client library](https://github.com/kubernetes-client/javascript) +* [Kubernetes C# client library](https://github.com/kubernetes-client/csharp) +* [Kubernetes Haskell client library](https://github.com/kubernetes-client/haskell) -## Dokumentacja poleceń tekstowych *(CLI)* +## Polecenia tekstowe *(CLI)* * [kubectl](/docs/reference/kubectl/overview/) - Główne narzędzie tekstowe (linii poleceń) do zarządzania klastrem Kubernetes. * [JSONPath](/docs/reference/kubectl/jsonpath/) - Podręcznik składni [wyrażeń JSONPath](https://goessner.net/articles/JsonPath/) dla kubectl. * [kubeadm](/docs/reference/setup-tools/kubeadm/) - Narzędzie tekstowe do łatwego budowania klastra Kubernetes spełniającego niezbędne wymogi bezpieczeństwa. -## Dokumentacja komponentów +## Komponenty -* [kubelet](/docs/reference/command-line-tools-reference/kubelet/) - Główny agent działający na każdym węźle. Kubelet pobiera zestaw definicji PodSpecs i gwarantuje, że opisane przez nie kontenery poprawnie działają. -* [kube-apiserver](/docs/reference/command-line-tools-reference/kube-apiserver/) - REST API, które sprawdza poprawność i konfiguruje obiekty API, takie jak pody, serwisy czy kontrolery replikacji. +* [kubelet](/docs/reference/command-line-tools-reference/kubelet/) - Główny + agent działający na każdym węźle. Kubelet pobiera zestaw definicji PodSpecs + i gwarantuje, że opisane przez nie kontenery poprawnie działają. +* [kube-apiserver](/docs/reference/command-line-tools-reference/kube-apiserver/) - + REST API, które sprawdza poprawność i konfiguruje obiekty API, takie jak pody, serwisy czy kontrolery replikacji. * [kube-controller-manager](/docs/reference/command-line-tools-reference/kube-controller-manager/) - Proces wykonujący główne pętle sterowania Kubernetes. -* [kube-proxy](/docs/reference/command-line-tools-reference/kube-proxy/) - Przekazuje bezpośrednio dane przepływające w transmisji TCP/UDP lub dystrybuuje ruch TCP/UDP zgodnie ze schematem *round-robin* pomiędzy usługi back-endu. +* [kube-proxy](/docs/reference/command-line-tools-reference/kube-proxy/) - Przekazuje + bezpośrednio dane przepływające w transmisji TCP/UDP lub dystrybuuje ruch TCP/UDP + zgodnie ze schematem *round-robin* pomiędzy usługi back-endu. * [kube-scheduler](/docs/reference/command-line-tools-reference/kube-scheduler/) - Scheduler odpowiada za dostępność, wydajność i zasoby. -* [kube-scheduler Policies](/docs/reference/scheduling/policies) -* [kube-scheduler Profiles](/docs/reference/scheduling/config#profiles) +* [Scheduler Policies](/docs/reference/scheduling/policies) +* [Scheduler Profiles](/docs/reference/scheduling/config#profiles) + +## API konfiguracji + +W tej części zebrano "niepublikowane" API, które służą do konfiguracji komponentów +Kubernetesa lub innych narzędzi. Choć większość tych API nie jest udostępniane przez +serwer API w trybie RESTful, są one niezbędne dla użytkowników i administratorów +w korzystaniu i zarządzaniu klastrem. + +* [kube-apiserver configuration (v1alpha1)](/docs/reference/config-api/apiserver-config.v1alpha1/) +* [kubelet configuration (v1beta1)](/docs/reference/config-api/kubelet-config.v1beta1/) +* [kube-scheduler configuration (v1beta1)](/docs/reference/config-api/kube-scheduler-config.v1beta1/) +* [kube-scheduler configuration (v1beta2)](/docs/reference/config-api/kube-scheduler-config.v1beta2/) +* [kube-scheduler policy reference (v1)](/docs/reference/config-api/kube-scheduler-policy-config.v1/) +* [kube-proxy configuration (v1alpha1)](/docs/reference/config-api/kube-proxy-config.v1alpha1/) +* [`audit.k8s.io/v1` API](/docs/reference/config-api/apiserver-audit.v1/) +* [Client authentication API (v1beta1)](/docs/reference/config-api/client-authentication.v1beta1/) +* [WebhookAdmission configuration (v1)](/docs/reference/config-api/apiserver-webhookadmission.v1/) + +## API konfiguracji dla kubeadm + +* [v1beta2](/docs/reference/config-api/kubeadm-config.v1beta2/) +* [v1beta3](/docs/reference/config-api/kubeadm-config.v1beta3/) ## Dokumentacja projektowa diff --git a/content/pl/docs/reference/glossary/index.md b/content/pl/docs/reference/glossary/index.md index 1cdf5a1a3ef14..642bdbdfb2532 100644 --- a/content/pl/docs/reference/glossary/index.md +++ b/content/pl/docs/reference/glossary/index.md @@ -1,5 +1,5 @@ --- -title: Ujednolicony słownik +title: Słownik layout: glossary noedit: true default_active_tag: fundamental diff --git a/content/pl/docs/reference/glossary/kube-scheduler.md b/content/pl/docs/reference/glossary/kube-scheduler.md index 4bbcc99a0f5ed..f3f5e02d1056c 100644 --- a/content/pl/docs/reference/glossary/kube-scheduler.md +++ b/content/pl/docs/reference/glossary/kube-scheduler.md @@ -2,7 +2,7 @@ title: kube-scheduler id: kube-scheduler date: 2018-04-12 -full_link: /docs/reference/generated/kube-scheduler/ +full_link: /docs/reference/command-line-tools-reference/kube-scheduler/ short_description: > Składnik warstwy sterowania, który śledzi tworzenie nowych podów i przypisuje im węzły, na których powinny zostać uruchomione. From f268125675ebe01f1ed441cec3cbd5ef481e4b0d Mon Sep 17 00:00:00 2001 From: fabriziopandini Date: Wed, 6 Oct 2021 23:13:42 +0200 Subject: [PATCH 107/115] align ClusterClass blog to CAPI book tutorial --- ...-08-clusterclass-and-managed-topologies.md | 104 +++++++++--------- 1 file changed, 51 insertions(+), 53 deletions(-) diff --git a/content/en/blog/_posts/2021-10-08-clusterclass-and-managed-topologies.md b/content/en/blog/_posts/2021-10-08-clusterclass-and-managed-topologies.md index af6349ecb8e9f..cd65d69f8b35f 100644 --- a/content/en/blog/_posts/2021-10-08-clusterclass-and-managed-topologies.md +++ b/content/en/blog/_posts/2021-10-08-clusterclass-and-managed-topologies.md @@ -36,52 +36,52 @@ ClusterClass, at its heart, is a collection of Cluster and Machine templates. Yo ```yaml --- apiVersion: cluster.x-k8s.io/v1beta1 - kind: ClusterClass - metadata: - name: my-amazing-cluster-class - namespace: bar - spec: - controlPlane: - ref: - apiVersion: controlplane.cluster.x-k8s.io/v1beta1 - kind: KubeadmControlPlaneTemplate - name: high-availability-kcp - machineInfrastructure: - ref: - apiVersion: infrastructure.cluster.x-k8s.io/v1alpha4 - kind: VSphereMachineTemplate - name: controlplane-vsphere-machinetemplate - workers: - deployments: - - class: linux-worker - template: - bootstrap: - ref: - apiVersion: bootstrap.cluster.x-k8s.io/v1beta1 - kind: KubeadmConfigTemplate - name: linux-bootstrap - infrastructure: - ref: - apiVersion: infrastructure.cluster.x-k8s.io/v1alpha4 - kind: VSphereMachineTemplate - name: linux-vsphere-template - - class: windows-worker - template: - bootstrap: - ref: - apiVersion: bootstrap.cluster.x-k8s.io/v1beta1 - kind: KubeadmConfigTemplate - name: windows-bootstrap - infrastructure: - ref: - apiVersion: infrastructure.cluster.x-k8s.io/v1alpha4 - kind: VSphereMachineTemplate - name: windows-vsphere-template - infrastructure: - ref: - apiVersion: infrastructure.cluster.x-k8s.io/v1alpha4 - kind: VSphereClusterTemplate - name: vsphere-cluster +kind: ClusterClass +metadata: + name: my-amazing-cluster-class +spec: + controlPlane: + ref: + apiVersion: controlplane.cluster.x-k8s.io/v1beta1 + kind: KubeadmControlPlaneTemplate + name: high-availability-control-plane + machineInfrastructure: + ref: + apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 + kind: DockerMachineTemplate + name: control-plane-machine + workers: + machineDeployments: + - class: type1-workers + template: + bootstrap: + ref: + apiVersion: bootstrap.cluster.x-k8s.io/v1beta1 + kind: KubeadmConfigTemplate + name: type1-bootstrap + infrastructure: + ref: + apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 + kind: DockerMachineTemplate + name: type1-machine + - class: type2-workers + template: + bootstrap: + ref: + apiVersion: bootstrap.cluster.x-k8s.io/v1beta1 + kind: KubeadmConfigTemplate + name: type2-bootstrap + infrastructure: + ref: + kind: DockerMachineTemplate + apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 + name: type2-machine + infrastructure: + ref: + apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 + kind: DockerClusterTemplate + name: cluster-infrastructure + ``` The possibilities are endless; you can get a default ClusterClass from the community, “off-the-shelf” classes from your vendor of choice, “certified” classes from the platform admin in your company, or even create custom ones for advanced scenarios. @@ -111,15 +111,12 @@ apiVersion: cluster.x-k8s.io/v1beta1 replicas: 3 workers: machineDeployments: - - class: linux-worker - name: big-pool-of-linux-machines-1 + - class: type1-workers + name: big-pool-of-machines replicas: 5 - - class: linux-worker - name: small-pool-of-linux-machines-1 + - class: type2-workers + name: small-pool-of-machines replicas: 1 - - class: windows-worker - name: pool-of-windows-machines - replicas: 3 ``` But there is more than simplified cluster creation. Now the Cluster acts as a single control point for your entire topology. @@ -141,3 +138,4 @@ Stay tuned for what comes next, and if you have any questions, comments or sugge * Chat with us on the Kubernetes [Slack](http://slack.k8s.io/):[#cluster-api](https://kubernetes.slack.com/archives/C8TSNPY4T) * Join the SIG Cluster Lifecycle [Google Group](https://groups.google.com/g/kubernetes-sig-cluster-lifecycle) to receive calendar invites and gain access to documents * Join our [Zoom meeting](https://zoom.us/j/861487554), every Wednesday at 10:00 Pacific Time +* Check out the [ClusterClass tutorial](https://cluster-api.sigs.k8s.io/tasks/experimental-features/cluster-classes.html) in the Cluster API book. \ No newline at end of file From f57f004bd05e58eaa2f7c03dff0981dbb613120d Mon Sep 17 00:00:00 2001 From: Arhell Date: Thu, 7 Oct 2021 00:26:31 +0300 Subject: [PATCH 108/115] [ru] Add seccomp tutorial to index --- content/ru/docs/tutorials/_index.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/content/ru/docs/tutorials/_index.md b/content/ru/docs/tutorials/_index.md index e251975329ca7..6cbe48cbe440f 100644 --- a/content/ru/docs/tutorials/_index.md +++ b/content/ru/docs/tutorials/_index.md @@ -47,6 +47,8 @@ content_type: concept * [AppArmor](/docs/tutorials/clusters/apparmor/) +* [seccomp](/docs/tutorials/clusters/seccomp/) + ## Сервисы * [Использование IP](/docs/tutorials/services/source-ip/) From 78f125c2225e44a732bb943b5fe1dd90a007ac95 Mon Sep 17 00:00:00 2001 From: RA489 Date: Thu, 7 Oct 2021 11:24:04 +0530 Subject: [PATCH 109/115] Improvement for other tools --- content/en/docs/reference/tools/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/docs/reference/tools/_index.md b/content/en/docs/reference/tools/_index.md index f719515af7f8a..389e6e77d2a5e 100644 --- a/content/en/docs/reference/tools/_index.md +++ b/content/en/docs/reference/tools/_index.md @@ -23,8 +23,8 @@ development and testing purposes. [`Dashboard`](/docs/tasks/access-application-cluster/web-ui-dashboard/), the web-based user interface of Kubernetes, allows you to deploy containerized applications to a Kubernetes cluster, troubleshoot them, and manage the cluster and its resources itself. -{{% thirdparty-content %}} ## Helm +{{% thirdparty-content single="true" %}} [Helm](https://helm.sh/) is a tool for managing packages of pre-configured Kubernetes resources. These packages are known as _Helm charts_. From cb9e9352a075e78b720414bd00352ee062c4b4cc Mon Sep 17 00:00:00 2001 From: Pulkit Singh Date: Thu, 7 Oct 2021 12:44:21 +0530 Subject: [PATCH 110/115] Update intro-windows-in-kubernetes.md --- .../windows/intro-windows-in-kubernetes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/docs/setup/production-environment/windows/intro-windows-in-kubernetes.md b/content/en/docs/setup/production-environment/windows/intro-windows-in-kubernetes.md index 7b8e24db6085c..fa8733bbb7905 100644 --- a/content/en/docs/setup/production-environment/windows/intro-windows-in-kubernetes.md +++ b/content/en/docs/setup/production-environment/windows/intro-windows-in-kubernetes.md @@ -962,4 +962,4 @@ For a detailed explanation of Windows distribution channels see the [Microsoft d Information on the different Windows Server servicing channels including their support models can be found at -[Windows Server servicing channels](https://docs.microsoft.com/en-us/windows-server/get-started-19/servicing-channels-19). +[Windows Server servicing channels](https://docs.microsoft.com/en-us/windows-server/get-started/servicing-channels-comparison). From 0a50d3ed5382bfab4d20a003d35d593f47d282e3 Mon Sep 17 00:00:00 2001 From: Arhell Date: Fri, 8 Oct 2021 00:38:30 +0300 Subject: [PATCH 111/115] [uk] Add seccomp tutorial to index --- content/uk/docs/tutorials/_index.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/content/uk/docs/tutorials/_index.md b/content/uk/docs/tutorials/_index.md index c87a5155a0114..a249e4814ce93 100644 --- a/content/uk/docs/tutorials/_index.md +++ b/content/uk/docs/tutorials/_index.md @@ -63,6 +63,8 @@ Before walking through each tutorial, you may want to bookmark the * [AppArmor](/docs/tutorials/clusters/apparmor/) +* [seccomp](/docs/tutorials/clusters/seccomp/) + ## Сервіси * [Використання Source IP](/docs/tutorials/services/source-ip/) From 2a84b55424c511aec75e7839420490754dbc0fa4 Mon Sep 17 00:00:00 2001 From: Chris Negus Date: Thu, 7 Oct 2021 20:41:50 -0400 Subject: [PATCH 112/115] Add file paths to keys and certificates (#28367) * Adding diagrams to certificates page * Cropped diagrams * Changed diagrams to tree output * Formatting fix * Fixed text block markup and spacing * Changed tree view of files to full-path view * Changed order of two cert files * Broke up links into separate sentences, per review comment * More changes per review comments --- .../docs/setup/best-practices/certificates.md | 50 +++++++++++++++++-- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/content/en/docs/setup/best-practices/certificates.md b/content/en/docs/setup/best-practices/certificates.md index 1648cc4e9eb92..defa8b59f6557 100644 --- a/content/en/docs/setup/best-practices/certificates.md +++ b/content/en/docs/setup/best-practices/certificates.md @@ -38,11 +38,13 @@ etcd also implements mutual TLS to authenticate clients and peers. ## Where certificates are stored -If you install Kubernetes with kubeadm, certificates are stored in `/etc/kubernetes/pki`. All paths in this documentation are relative to that directory. +If you install Kubernetes with kubeadm, most certificates are stored in `/etc/kubernetes/pki`. All paths in this documentation are relative to that directory, with the exception of user account certificates which kubeadm places in `/etc/kubernetes`. ## Configure certificates manually -If you don't want kubeadm to generate the required certificates, you can create them in either of the following ways. +If you don't want kubeadm to generate the required certificates, you can create them using a single root CA or by providing all certificates. See [Certificates](/docs/tasks/administer-cluster/certificates/) for details on creating your own certificate authority. +See [Certificate Management with kubeadm](/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/) for more on managing certificates. + ### Single root CA @@ -57,7 +59,16 @@ Required CAs: | front-proxy-ca.crt,key | kubernetes-front-proxy-ca | For the [front-end proxy](/docs/tasks/extend-kubernetes/configure-aggregation-layer/) | On top of the above CAs, it is also necessary to get a public/private key pair for service account management, `sa.key` and `sa.pub`. +The following example illustrates the CA key and certificate files shown in the previous table: +``` +/etc/kubernetes/pki/ca.crt +/etc/kubernetes/pki/ca.key +/etc/kubernetes/pki/etcd/ca.crt +/etc/kubernetes/pki/etcd/ca.key +/etc/kubernetes/pki/front-proxy-ca.crt +/etc/kubernetes/pki/front-proxy-ca.key +``` ### All certificates If you don't wish to copy the CA private keys to your cluster, you can generate all certificates yourself. @@ -127,6 +138,32 @@ Same considerations apply for the service account key pair: | sa.key | | kube-controller-manager | --service-account-private-key-file | | | sa.pub | kube-apiserver | --service-account-key-file | +The following example illustrates the file paths [from the previous tables](/docs/setup/best-practices/certificates/#certificate-paths) you need to provide if you are generating all of your own keys and certificates: + +``` +/etc/kubernetes/pki/etcd/ca.key +/etc/kubernetes/pki/etcd/ca.crt +/etc/kubernetes/pki/apiserver-etcd-client.key +/etc/kubernetes/pki/apiserver-etcd-client.crt +/etc/kubernetes/pki/ca.key +/etc/kubernetes/pki/ca.crt +/etc/kubernetes/pki/apiserver.key +/etc/kubernetes/pki/apiserver.crt +/etc/kubernetes/pki/apiserver-kubelet-client.key +/etc/kubernetes/pki/apiserver-kubelet-client.crt +/etc/kubernetes/pki/front-proxy-ca.key +/etc/kubernetes/pki/front-proxy-ca.crt +/etc/kubernetes/pki/front-proxy-client.key +/etc/kubernetes/pki/front-proxy-client.crt +/etc/kubernetes/pki/etcd/server.key +/etc/kubernetes/pki/etcd/server.crt +/etc/kubernetes/pki/etcd/peer.key +/etc/kubernetes/pki/etcd/peer.crt +/etc/kubernetes/pki/etcd/healthcheck-client.key +/etc/kubernetes/pki/etcd/healthcheck-client.crt +/etc/kubernetes/pki/sa.key +/etc/kubernetes/pki/sa.pub +``` ## Configure certificates for user accounts You must manually configure these administrator account and service accounts: @@ -146,7 +183,7 @@ The value of `` for `kubelet.conf` **must** match precisely the value 1. Run `kubectl` as follows for each config: -```shell +``` KUBECONFIG= kubectl config set-cluster default-cluster --server=https://:6443 --certificate-authority --embed-certs KUBECONFIG= kubectl config set-credentials --client-key .pem --client-certificate .pem --embed-certs KUBECONFIG= kubectl config set-context default-system --cluster default-cluster --user @@ -162,4 +199,11 @@ These files are used as follows: | controller-manager.conf | kube-controller-manager | Must be added to manifest in `manifests/kube-controller-manager.yaml` | | scheduler.conf | kube-scheduler | Must be added to manifest in `manifests/kube-scheduler.yaml` | +The following files illustrate full paths to the files listed in the previous table: +``` +/etc/kubernetes/admin.conf +/etc/kubernetes/kubelet.conf +/etc/kubernetes/controller-manager.conf +/etc/kubernetes/scheduler.conf +``` From 583ead2dd6e3796587834102003819f63df528c2 Mon Sep 17 00:00:00 2001 From: Steven Yan Date: Sun, 26 Sep 2021 11:59:26 +0800 Subject: [PATCH 113/115] [zh] translation for admin3 --- .../docs/tasks/administer-cluster/coredns.md | 45 +++---------------- .../tasks/administer-cluster/namespaces.md | 22 ++++----- .../administer-cluster/reconfigure-kubelet.md | 6 ++- 3 files changed, 22 insertions(+), 51 deletions(-) diff --git a/content/zh/docs/tasks/administer-cluster/coredns.md b/content/zh/docs/tasks/administer-cluster/coredns.md index f68ce54759960..22ada210261e0 100644 --- a/content/zh/docs/tasks/administer-cluster/coredns.md +++ b/content/zh/docs/tasks/administer-cluster/coredns.md @@ -67,12 +67,12 @@ For manual deployment or replacement of kube-dns, see the documentation at the 在 Kubernetes 1.10 及更高版本中,当你使用 `kubeadm` 升级使用 `kube-dns` 的集群时,你还可以迁移到 CoreDNS。 在本例中 `kubeadm` 将生成 CoreDNS 配置("Corefile")基于 `kube-dns` ConfigMap, -保存联邦、存根域和上游名称服务器的配置。 +保存存根域和上游名称服务器的配置。 在 Kubernetes 版本 1.13 和更高版本中,`CoreDNS`特性门已经删除,CoreDNS 在默认情况下使用。 -如果你想升级集群以使用 kube-dns,请遵循 -[此处](/zh/docs/reference/setup-tools/kubeadm/kubeadm-init-phase#cmd-phase-addon) 。 -## 使用 kubeadm 安装 kube-dns 而不是 CoreDNS - - -{{< note >}} -在 Kubernetes 1.11 中,CoreDNS 已经升级到通用可用性(GA),并默认安装。 -{{< /note >}} - - -{{< warning >}} -在 Kubernetes 1.18 中,用 kubeadm 来安装 kube-dns 这一做法已经被废弃, -会在将来版本中移除。 -{{< /warning >}} - - -若要在 1.13 之前版本上安装 kube-dns,请将 `CoreDNS` 特性门控设置为 `false`: - -```shell -kubeadm init --feature-gates=CoreDNS=false -``` - - -对于 1.13 版和更高版本,请遵循 -[此处](/zh/docs/reference/setup-tools/kubeadm/kubeadm-init-phase#cmd-phase-addon)概述到指南。 +在 kubernetes 1.21 中,kubeadm 移除了对 `kube-dns` 的支持。 +For more details, see [Namespace](/docs/reference/kubernetes-api/cluster-resources/namespace-v1/) +in the API reference. + --> 名字空间可以处于下列两个阶段中的一个: * `Active` 名字空间正在被使用中 * `Terminating` 名字空间正在被删除,且不能被用于新对象。 -参见[设计文档](https://git.k8s.io/community/contributors/design-proposals/architecture/namespaces.md#phases) 查看更多细节。 +更多细节,参阅 API 参考中的[命名空间](/docs/reference/kubernetes-api/cluster-resources/namespace-v1/)。 ## 创建名字空间 @@ -312,11 +314,11 @@ kubectl delete namespaces ``` - 我们刚刚创建了一个副本个数为 2 的 Deployment,运行名为 `snowflake` 的 - Pod,其中包含一个仅负责提供主机名的基本容器。 + 我们创建了一个副本个数为 2 的 Deployment,运行名为 `snowflake` 的 + Pod,其中包含一个负责提供主机名的基本容器。 ```shell kubectl get deployment -n=development @@ -486,7 +488,7 @@ Use cases include: * 进一步了解[设置名字空间偏好](/zh/docs/concepts/overview/working-with-objects/namespaces/#setting-the-namespace-preference) * 进一步了解[设置请求的名字空间](/zh/docs/concepts/overview/working-with-objects/namespaces/#setting-the-namespace-for-a-request) -* 参阅[名字空间的设计文档](https://github.com/kubernetes/community/blob/{{< param "githubbranch" >}}/contributors/design-proposals/architecture/namespaces.md) +* 参阅[名字空间的设计文档](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/architecture/namespaces.md) diff --git a/content/zh/docs/tasks/administer-cluster/reconfigure-kubelet.md b/content/zh/docs/tasks/administer-cluster/reconfigure-kubelet.md index 7d34460c24f80..67d4f90a9d1b0 100644 --- a/content/zh/docs/tasks/administer-cluster/reconfigure-kubelet.md +++ b/content/zh/docs/tasks/administer-cluster/reconfigure-kubelet.md @@ -16,7 +16,11 @@ content_type: task {{< feature-state for_k8s_version="v1.22" state="deprecated" >}} {{< caution >}} [动态 kubelet 配置](https://github.com/kubernetes/enhancements/issues/281) From 26898c2495aeaed945f01f3170de4b7bf4a8c2d4 Mon Sep 17 00:00:00 2001 From: Andy Chen <42681629+aychen99@users.noreply.github.com> Date: Thu, 7 Oct 2021 23:41:58 -0700 Subject: [PATCH 114/115] Update zh basic-stateful-set.md with upstream --- .../docs/tutorials/stateful-application/basic-stateful-set.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/zh/docs/tutorials/stateful-application/basic-stateful-set.md b/content/zh/docs/tutorials/stateful-application/basic-stateful-set.md index 07f6302eaee16..02880bfbc8dc4 100644 --- a/content/zh/docs/tutorials/stateful-application/basic-stateful-set.md +++ b/content/zh/docs/tutorials/stateful-application/basic-stateful-set.md @@ -38,7 +38,7 @@ following Kubernetes concepts. * [Cluster DNS](/zh/docs/concepts/services-networking/dns-pod-service/) * [Headless Services](/zh/docs/concepts/services-networking/service/#headless-services) * [PersistentVolumes](/zh/docs/concepts/storage/persistent-volumes/) -* [PersistentVolume Provisioning](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/persistent-volume-provisioning/) +* [PersistentVolume Provisioning](https://github.com/kubernetes/examples/tree/master/staging/persistent-volume-provisioning/) * [StatefulSets](/zh/docs/concepts/workloads/controllers/statefulset/) * [kubectl CLI](/zh/docs/user-guide/kubectl/) From 6832778c9a954274e4852b4088f2251ce9483805 Mon Sep 17 00:00:00 2001 From: Sahil Vazirani Date: Fri, 8 Oct 2021 13:11:18 -0700 Subject: [PATCH 115/115] GA TTLAfterFinished --- .../docs/concepts/workloads/controllers/ttlafterfinished.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/content/en/docs/concepts/workloads/controllers/ttlafterfinished.md b/content/en/docs/concepts/workloads/controllers/ttlafterfinished.md index 266e72a79fd0f..1dcd7a873db28 100644 --- a/content/en/docs/concepts/workloads/controllers/ttlafterfinished.md +++ b/content/en/docs/concepts/workloads/controllers/ttlafterfinished.md @@ -8,7 +8,7 @@ weight: 70 -{{< feature-state for_k8s_version="v1.21" state="beta" >}} +{{< feature-state for_k8s_version="v1.23" state="stable" >}} The TTL controller provides a TTL (time to live) mechanism to limit the lifetime of resource objects that have finished execution. TTL controller only handles @@ -16,9 +16,6 @@ objects that have finished execution. TTL controller only handles and may be expanded to handle other resources that will finish execution, such as Pods and custom resources. -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.