From 1db59c85d7d81146179ba82d1fd463723f6ec5d9 Mon Sep 17 00:00:00 2001 From: "donatohorn@gmail.com" Date: Sun, 17 Jul 2022 20:42:31 -0300 Subject: [PATCH 001/279] [pt-br] add content/pt-br/docs/tasks/configure-pod-container/configure-runasusername.md --- .../configure-runasusername.md | 148 ++++++++++++++++++ .../windows/run-as-username-container.yaml | 17 ++ .../examples/windows/run-as-username-pod.yaml | 14 ++ 3 files changed, 179 insertions(+) create mode 100644 content/pt-br/docs/tasks/configure-pod-container/configure-runasusername.md create mode 100644 content/pt-br/examples/windows/run-as-username-container.yaml create mode 100644 content/pt-br/examples/windows/run-as-username-pod.yaml diff --git a/content/pt-br/docs/tasks/configure-pod-container/configure-runasusername.md b/content/pt-br/docs/tasks/configure-pod-container/configure-runasusername.md new file mode 100644 index 00000000000..f976f0aca99 --- /dev/null +++ b/content/pt-br/docs/tasks/configure-pod-container/configure-runasusername.md @@ -0,0 +1,148 @@ +--- +title: Configurando `RunAsUserName` Para Pods e Contêineres Windows +content_type: task +weight: 20 +update_date: 2022-07-17 +origin_version: 1.24 +contributors: DonatoHorn +reviewers: +--- + + + +{{< feature-state for_k8s_version="v1.18" state="stable" >}} + +Esta página mostra como usar a configuração `runAsUserName` para Pods +e contêineres que serão executados em nós Windows. Isso é aproximadamente +equivalente à configuração `runAsUser` específica do Linux, permitindo a você +executar aplicativos em um contêiner com um nome de usuário diferente do padrão. + +## {{% heading "prerequisites" %}} + +Você precisa ter um cluster Kubernetes, e a ferramenta de linha de comando Kubectl +deve ser configurada para se comunicar com o seu cluster. Espera-se que o cluster +tenha nós `worker Windows`, onde os Pods com contêineres executando as cargas de trabalho do Windows, +serão agendados. + + + +## Defina o nome de usuário para um Pod + +Para especificar o nome de usuário com o qual executar os processos de contêiner do Pod, +inclua o campo `securityContext` ([SecurityContext](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#securitycontext-v1-core)) +na especificação do Pod, e dentro dela, o campo `WindowsOptions` ([WindowsSecurityContextOptions](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#windowssecuritycontextoptions-v1-core)) +contendo o campo `runAsUserName`. + +As opções de contexto de segurança do Windows que você especificar para um Pod, +se aplicam a todos os Contêineres do Pod, inclusive os de inicialização. + +Aqui está um arquivo de configuração para um Pod do Windows que possui o campo +`runAsUserName` definido: + +{{< codenew file="windows/run-as-username-pod.yaml" >}} + +Crie o Pod: + +```shell +kubectl apply -f https://k8s.io/examples/windows/run-as-username-pod.yaml +``` + +Verifique se o contêiner do pod está em execução: + +```shell +kubectl get pod run-as-username-pod-demo +``` + +Abra um shell para o Contêiner em execução: + +```shell +kubectl exec -it run-as-username-pod-demo -- powershell +``` + +Verifique se o shell está executando com o nome de usuário correto: + +```powershell +echo $env:USERNAME +``` + +A saída deve ser: + +``` +ContainerUser +``` + +## Defina o nome de usuário para o Contêiner + +Para especificar o nome de usuário com o qual executar os processos de um Contêiner, +inclua o campo `SecurityContext` ([SecurityContext] +(/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#securitycontext-v1-core)) +no manifesto do Contêiner, e dentro dele, o campo `WindowsOptions` +([WindowsSecurityContextOptions] (/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#windowssecuritycontextoptions-v1-core)) +contendo o campo `runAsUserName`. + +As opções de contexto de segurança do Windows que você especificar para um Contêiner, +se aplicam apenas a esse Contêiner individual, e substituem as configurações feitas +no nível do Pod. + +Aqui está o arquivo de configuração para um pod que possui um Contêiner, +e o campo `runAsUserName` está definido no nível do Pod e no nível do Contêiner: + +{{< codenew file="windows/run-as-username-container.yaml" >}} + +Crie o Pod: + +```shell +kubectl apply -f https://k8s.io/examples/windows/run-as-username-container.yaml +``` + +Verifique se o Contêiner do Pod está em execução: + +```shell +kubectl get pod run-as-username-container-demo +``` + +Abra um shell para o contêiner em execução: + +```shell +kubectl exec -it run-as-username-container-demo -- powershell +``` + +Verifique se o shell está executando o usuário correto, (aquele definido no nível do Contêiner): + +```powershell +echo $env:USERNAME +``` + +A saída deve ser: + +``` +ContainerAdministrator +``` + +## Limitações de nomes de usuários no Windows + +Para usar esse recurso, o valor definido no campo `runAsUserName` deve ser um nome +de usuário válido. Deve ter o seguinte formato: `DOMAIN\USER`, onde ` DOMAIN\` +é opcional. Os nomes de usuário do Windows não diferenciam letras maiúsculas +e minúsculas. Além disso, existem algumas restrições em relação ao `DOMÍNIO` e `USUÁRIO`: +- O campo `runAsUserName`: não pode estar vazio, e não pode conter caracteres + de contrôle (Valores ASCII : `0x00-0x1F`, `0x7F`) +- O nome de `DOMÍNIO` NetBios, ou um nome de DNS: cada um com suas próprias restrições: + - Nomes NetBios: máximo de 15 caracteres, não podem iniciar com `.` (ponto), + e não podem conter os seguintes caracteres: `\ / : * ? " < > |` + - Nomes DNS: máximo de 255 caracteres, contendo apenas caracteres alfanuméricos, + pontos, e traços, e não podem iniciar ou terminar com um `.` (ponto) ou `-` (traço). +- O `USUÁRIO`: deve ter no máximo 20 caracteres, não pode conter *somente* pontos ou espaços, + e não pode conter os seguintes caracteres: `" / \ [ ] : ; | = , + * ? < > @`. + +Exemplos de valores aceitáveis para o campo `runAsUserName`: `ContainerAdministrator`, +`ContainerUser`, `NT AUTHORITY\NETWORK SERVICE`, `NT AUTHORITY\LOCAL SERVICE`. + +Para mais informações sobre estas limitações, verifique [aqui](https://support.microsoft.com/en-us/help/909264/naming-conventions-in-active-directory-for-computers-domains-sites-and) e [aqui](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.localaccounts/new-localuser?view=powershell-5.1). + +## {{% heading "whatsnext" %}} + +* [Guia para agendar contêineres Windows em Kubernetes](/docs/concepts/windows/user-guide/) +* [Gerenciando Identidade de Cargas de Trabalho com Contas de Serviço Gerenciadas em Grupo (GMSA)](/docs/concepts/windows/user-guide/#managing-workload-identity-with-group-managed-service-accounts) +* [Configure GMSA para pods e contêineres Windows](/docs/tasks/configure-pod-container/configure-gmsa/) + diff --git a/content/pt-br/examples/windows/run-as-username-container.yaml b/content/pt-br/examples/windows/run-as-username-container.yaml new file mode 100644 index 00000000000..77b7b2d1881 --- /dev/null +++ b/content/pt-br/examples/windows/run-as-username-container.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Pod +metadata: + name: run-as-username-container-demo +spec: + securityContext: + windowsOptions: + runAsUserName: "ContainerUser" + containers: + - name: run-as-username-demo + image: mcr.microsoft.com/windows/servercore:ltsc2019 + command: ["ping", "-t", "localhost"] + securityContext: + windowsOptions: + runAsUserName: "ContainerAdministrator" + nodeSelector: + kubernetes.io/os: windows diff --git a/content/pt-br/examples/windows/run-as-username-pod.yaml b/content/pt-br/examples/windows/run-as-username-pod.yaml new file mode 100644 index 00000000000..d62bf93efc9 --- /dev/null +++ b/content/pt-br/examples/windows/run-as-username-pod.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Pod +metadata: + name: run-as-username-pod-demo +spec: + securityContext: + windowsOptions: + runAsUserName: "ContainerUser" + containers: + - name: run-as-username-demo + image: mcr.microsoft.com/windows/servercore:ltsc2019 + command: ["ping", "-t", "localhost"] + nodeSelector: + kubernetes.io/os: windows \ No newline at end of file From 9b53715daa3cf596890f54c6308e158c65383902 Mon Sep 17 00:00:00 2001 From: "donatohorn@gmail.com" Date: Mon, 18 Jul 2022 00:13:38 -0300 Subject: [PATCH 002/279] [pt-br] add content/pt-br/docs/tasks/configure-pod-container/configure-volume-storage.md --- .../configure-volume-storage.md | 146 ++++++++++++++++++ .../pt-br/examples/pods/storage/redis.yaml | 14 ++ 2 files changed, 160 insertions(+) create mode 100644 content/pt-br/docs/tasks/configure-pod-container/configure-volume-storage.md create mode 100644 content/pt-br/examples/pods/storage/redis.yaml diff --git a/content/pt-br/docs/tasks/configure-pod-container/configure-volume-storage.md b/content/pt-br/docs/tasks/configure-pod-container/configure-volume-storage.md new file mode 100644 index 00000000000..396804ac8a3 --- /dev/null +++ b/content/pt-br/docs/tasks/configure-pod-container/configure-volume-storage.md @@ -0,0 +1,146 @@ +--- +title: Configurando um Pod Para Usar um Volume Para Armazenamento +content_type: task +weight: 50 +update_date: 2022-07-18 +origin_version: 1.24 +contributors: DonatoHorn +reviewers: +--- + + + +Esta página mostra como configurar um Pod para usar um Volume para armazenamento. + +O sistema de arquivos de um contêiner apenas existe enquanto o contêiner existir. +Então, quando um contêiner termina e reinicia, as alterações do sistema de arquivos +são perdidas. +Para um armazenamento mais consistente, independente do contêiner, você pode usar um +[Volume](/docs/concepts/storage/volumes/). Isso é especialmente importante para aplicações +`stateful`, tal como armazenamentos chave-valor (tal como Redis) e bancos de dados. + + + +## {{% heading "prerequisites" %}} + + +{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} + + + + + +## Configure um volume para um Pod + +Neste exercício, você cria um Pod que executa um contêiner. Este Pod tem um +Volume do tipo [emptyDir](/docs/concepts/storage/volumes/#emptydir) +que persiste durante a existência do Pod, mesmo que o contêiner termine e +reinicie. Aqui está o arquivo de configuração para o pod: + +{{< codenew file="pods/storage/redis.yaml" >}} + +1. Crie o Pod: + + ```shell + kubectl apply -f https://k8s.io/examples/pods/storage/redis.yaml + ``` + +1. Verifique se o contêiner do pod está funcionando, e então procure por mudanças no Pod: + + ```shell + kubectl get pod redis --watch + ``` + + A saída se parece com isso: + + ```shell + NAME READY STATUS RESTARTS AGE + redis 1/1 Running 0 13s + ``` + +1. Em outro terminal, pegue um shell para o contêiner em execução: + + ```shell + kubectl exec -it redis -- /bin/bash + ``` + +1. No seu shell, vá para `/data/redis`, e então crie um arquivo: + + ```shell + root@redis:/data# cd /data/redis/ + root@redis:/data/redis# echo Hello > test-file + ``` + +1. No seu shell, liste os processos em execução: + + ```shell + root@redis:/data/redis# apt-get update + root@redis:/data/redis# apt-get install procps + root@redis:/data/redis# ps aux + ``` + + A saída é semelhante a esta: + + ```shell + USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND + redis 1 0.1 0.1 33308 3828 ? Ssl 00:46 0:00 redis-server *:6379 + root 12 0.0 0.0 20228 3020 ? Ss 00:47 0:00 /bin/bash + root 15 0.0 0.0 17500 2072 ? R+ 00:48 0:00 ps aux + ``` + +1. Em seu shell, encerre o processo do Redis: + + ```shell + root@redis:/data/redis# kill + ``` + + Onde `` é o process ID (PID) do Redis. + +1. No seu terminal original, preste atenção nas mudanças no Pod do Redis. +Eventualmente, você vai ver algo assim: + + ```shell + NAME READY STATUS RESTARTS AGE + redis 1/1 Running 0 13s + redis 0/1 Completed 0 6m + redis 1/1 Running 1 6m + ``` + +Neste ponto, o Contêiner terminou e reiniciou. Isso porque o Pod do Redis tem uma +[`restartPolicy`](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podspec-v1-core) +de `Always`. + +1. Abra um shell dentro do Contêiner reiniciado: + + ```shell + kubectl exec -it redis -- /bin/bash + ``` + +1. No seu shell, vá para `/data/redis`, e verifique se `test-file` ainda está lá. + ```shell + root@redis:/data/redis# cd /data/redis/ + root@redis:/data/redis# ls + test-file + ``` + +1. Exclua o pod que você criou para este exercício: + + ```shell + kubectl delete pod redis + ``` + + + +## {{% heading "whatsnext" %}} + + +* Veja [Volume](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#volume-v1-core). + +* Veja [Pod](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#pod-v1-core). + +* Além do armazenamento de disco local fornecido por `emptyDir`, o Kubernetes +suporta muitas soluções de armazenamento diferentes, conectadas via rede, incluindo PD na +GCE e EBS na EC2, que são preferidos para dados críticos e vão lidar com os +detalhes, como montar e desmontar os dispositivos nos Nós. Veja +[Volumes](/docs/concepts/storage/volumes/) para mais detalhes. + diff --git a/content/pt-br/examples/pods/storage/redis.yaml b/content/pt-br/examples/pods/storage/redis.yaml new file mode 100644 index 00000000000..cb06456d4b3 --- /dev/null +++ b/content/pt-br/examples/pods/storage/redis.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Pod +metadata: + name: redis +spec: + containers: + - name: redis + image: redis + volumeMounts: + - name: redis-storage + mountPath: /data/redis + volumes: + - name: redis-storage + emptyDir: {} From ddd0dd77e1d07bc331a78dcf5e1ade1c8c7f5da9 Mon Sep 17 00:00:00 2001 From: "donatohorn@gmail.com" Date: Mon, 18 Jul 2022 23:33:17 -0300 Subject: [PATCH 003/279] [pt-br] add content/pt-br/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md --- .../enforce-standards-admission-controller.md | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 content/pt-br/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md diff --git a/content/pt-br/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md b/content/pt-br/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md new file mode 100644 index 00000000000..960478dabdb --- /dev/null +++ b/content/pt-br/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md @@ -0,0 +1,106 @@ +--- +title: Aplicando os Padrões de Segurança do Pod, Configurando o Controlador de Admissão Embutido +update_date: 2022-07-18 +origin_version: 1.24 +contributors: DonatoHorn +reviewers: +- tallclair +- liggitt +content_type: task +min-kubernetes-server-version: v1.22 +--- + +Desde a versão v1.22, o Kubernetes fornece um [controlador de admissão] +(/docs/reference/access-authn-authz/admission-controllers/#podsecurity) +embutido para fazer cumprir os [padrões de segurança do Pod] +(/docs/concepts/security/pod-security-standards). +Você pode configurar esse controlador de admissão para definir padrões em todo +o cluster e [excessões](/docs/concepts/security/pod-security-admission/#exemptions). + +## {{% heading "prerequisites" %}} + +{{% version-check %}} + +- Garanta que a `PodSecurity` do [portal de funcionalidade] +(/docs/reference/command-line-tools-reference/feature-gates/#feature-gates-for-alpha-or-beta-features) +está ativada. + +## Configure o Controlador de Admissão + +{{< tabs name="PodSecurityConfiguration_example_1" >}} +{{% tab name="pod-security.admission.config.k8s.io/v1beta1" %}} +```yaml +apiVersion: apiserver.config.k8s.io/v1 +kind: AdmissionConfiguration +plugins: +- name: PodSecurity + configuration: + apiVersion: pod-security.admission.config.k8s.io/v1beta1 + kind: PodSecurityConfiguration + # Defaults applied when a mode label is not set. + # + # Level label values must be one of: + # - "privileged" (default) + # - "baseline" + # - "restricted" + # + # Version label values must be one of: + # - "latest" (default) + # - specific version like "v{{< skew currentVersion >}}" + defaults: + enforce: "privileged" + enforce-version: "latest" + audit: "privileged" + audit-version: "latest" + warn: "privileged" + warn-version: "latest" + exemptions: + # `Array`de nomes de usuários autenticados para isentar. + usernames: [] + # `Array` de nomes de classe `runtime` para isentar. + runtimeClasses: [] + # `Array` de namespaces para isentar. + namespaces: [] +``` + +{{< note >}} +A v1beta1 de configuração requer v1.23+. Para v1.22, use v1alpha1. +{{< /note >}} + +{{% /tab %}} +{{% tab name="pod-security.admission.config.k8s.io/v1alpha1" %}} +```yaml +apiVersion: apiserver.config.k8s.io/v1 +kind: AdmissionConfiguration +plugins: +- name: PodSecurity + configuration: + apiVersion: pod-security.admission.config.k8s.io/v1alpha1 + kind: PodSecurityConfiguration + # Os padrões aplicados quando uma label de modo não está definida. + # + # Valor de nível de label precisa ser um dos: + # - "privileged" (default) + # - "baseline" + # - "restricted" + # + # Valor de versão de label precisa ser um dos: + # - "latest" (default) + # - Versão especifica como "v{{< skew currentVersion >}}" + defaults: + enforce: "privileged" + enforce-version: "latest" + audit: "privileged" + audit-version: "latest" + warn: "privileged" + warn-version: "latest" + exemptions: + # `Array` de nomes de usuários autenticados para isentar. + usernames: [] + # `Array` de nomes de calsses `runtime` para isentar. + runtimeClasses: [] + # `Array` de namespaces para isentar. + namespaces: [] +``` +{{% /tab %}} +{{< /tabs >}} From 0d0f270ec72265124a66e383af9a3afac29409bd Mon Sep 17 00:00:00 2001 From: "donatohorn@gmail.com" Date: Fri, 22 Jul 2022 16:02:51 -0300 Subject: [PATCH 004/279] [pt-br] add content/pt-br/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md --- .../enforce-standards-admission-controller.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/content/pt-br/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md b/content/pt-br/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md index 960478dabdb..cd61722679c 100644 --- a/content/pt-br/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md +++ b/content/pt-br/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md @@ -1,8 +1,5 @@ --- title: Aplicando os Padrões de Segurança do Pod, Configurando o Controlador de Admissão Embutido -update_date: 2022-07-18 -origin_version: 1.24 -contributors: DonatoHorn reviewers: - tallclair - liggitt From 0ccc0ffaa884ea8b7c1d2187a94fd779745f4f66 Mon Sep 17 00:00:00 2001 From: "donatohorn@gmail.com" Date: Fri, 22 Jul 2022 17:42:45 -0300 Subject: [PATCH 005/279] [pt-br] content/pt-br/docs/tasks/configure-pod-container/configure-volume-storage.md --- .../tasks/configure-pod-container/configure-volume-storage.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/content/pt-br/docs/tasks/configure-pod-container/configure-volume-storage.md b/content/pt-br/docs/tasks/configure-pod-container/configure-volume-storage.md index 396804ac8a3..8687c19ab74 100644 --- a/content/pt-br/docs/tasks/configure-pod-container/configure-volume-storage.md +++ b/content/pt-br/docs/tasks/configure-pod-container/configure-volume-storage.md @@ -2,10 +2,6 @@ title: Configurando um Pod Para Usar um Volume Para Armazenamento content_type: task weight: 50 -update_date: 2022-07-18 -origin_version: 1.24 -contributors: DonatoHorn -reviewers: --- From 545c2fddfe2d03cba5ff95cbed28a8c082265e9a Mon Sep 17 00:00:00 2001 From: "donatohorn@gmail.com" Date: Fri, 22 Jul 2022 17:51:14 -0300 Subject: [PATCH 006/279] [pt-br] content/pt-br/docs/tasks/configure-pod-container/configure-runasusername.md --- .../tasks/configure-pod-container/configure-runasusername.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/content/pt-br/docs/tasks/configure-pod-container/configure-runasusername.md b/content/pt-br/docs/tasks/configure-pod-container/configure-runasusername.md index f976f0aca99..16b1d01f747 100644 --- a/content/pt-br/docs/tasks/configure-pod-container/configure-runasusername.md +++ b/content/pt-br/docs/tasks/configure-pod-container/configure-runasusername.md @@ -2,10 +2,6 @@ title: Configurando `RunAsUserName` Para Pods e Contêineres Windows content_type: task weight: 20 -update_date: 2022-07-17 -origin_version: 1.24 -contributors: DonatoHorn -reviewers: --- From 075fc7e4abd75efa0232cad0971b3e434eaf614b Mon Sep 17 00:00:00 2001 From: "donatohorn@gmail.com" Date: Sat, 13 Aug 2022 13:46:44 -0300 Subject: [PATCH 007/279] [pt-br] add content/pt-br/docs/tasks/configure-pod-container/configure-runasusername.md --- .../configure-runasusername.md | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/content/pt-br/docs/tasks/configure-pod-container/configure-runasusername.md b/content/pt-br/docs/tasks/configure-pod-container/configure-runasusername.md index 16b1d01f747..4116a9c5f89 100644 --- a/content/pt-br/docs/tasks/configure-pod-container/configure-runasusername.md +++ b/content/pt-br/docs/tasks/configure-pod-container/configure-runasusername.md @@ -30,7 +30,7 @@ na especificação do Pod, e dentro dela, o campo `WindowsOptions` ([WindowsSecu contendo o campo `runAsUserName`. As opções de contexto de segurança do Windows que você especificar para um Pod, -se aplicam a todos os Contêineres do Pod, inclusive os de inicialização. +se aplicam a todos os contêineres do Pod, inclusive os de inicialização. Aqui está um arquivo de configuração para um Pod do Windows que possui o campo `runAsUserName` definido: @@ -49,7 +49,7 @@ Verifique se o contêiner do pod está em execução: kubectl get pod run-as-username-pod-demo ``` -Abra um shell para o Contêiner em execução: +Abra um shell para o contêiner em execução: ```shell kubectl exec -it run-as-username-pod-demo -- powershell @@ -67,21 +67,21 @@ A saída deve ser: ContainerUser ``` -## Defina o nome de usuário para o Contêiner +## Defina o nome de usuário para o contêiner -Para especificar o nome de usuário com o qual executar os processos de um Contêiner, +Para especificar o nome de usuário com o qual executar os processos de um contêiner, inclua o campo `SecurityContext` ([SecurityContext] (/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#securitycontext-v1-core)) -no manifesto do Contêiner, e dentro dele, o campo `WindowsOptions` +no manifesto do contêiner, e dentro dele, o campo `WindowsOptions` ([WindowsSecurityContextOptions] (/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#windowssecuritycontextoptions-v1-core)) contendo o campo `runAsUserName`. -As opções de contexto de segurança do Windows que você especificar para um Contêiner, -se aplicam apenas a esse Contêiner individual, e substituem as configurações feitas +As opções de contexto de segurança do Windows que você especificar para um contêiner, +se aplicam apenas a esse contêiner individual, e substituem as configurações feitas no nível do Pod. -Aqui está o arquivo de configuração para um pod que possui um Contêiner, -e o campo `runAsUserName` está definido no nível do Pod e no nível do Contêiner: +Aqui está o arquivo de configuração para um pod que possui um contêiner, +e o campo `runAsUserName` está definido no nível do Pod e no nível do contêiner: {{< codenew file="windows/run-as-username-container.yaml" >}} @@ -91,7 +91,7 @@ Crie o Pod: kubectl apply -f https://k8s.io/examples/windows/run-as-username-container.yaml ``` -Verifique se o Contêiner do Pod está em execução: +Verifique se o contêiner do Pod está em execução: ```shell kubectl get pod run-as-username-container-demo @@ -103,7 +103,7 @@ Abra um shell para o contêiner em execução: kubectl exec -it run-as-username-container-demo -- powershell ``` -Verifique se o shell está executando o usuário correto, (aquele definido no nível do Contêiner): +Verifique se o shell está executando o usuário correto, (aquele definido no nível do contêiner): ```powershell echo $env:USERNAME @@ -122,7 +122,7 @@ de usuário válido. Deve ter o seguinte formato: `DOMAIN\USER`, onde ` DOMAIN\` é opcional. Os nomes de usuário do Windows não diferenciam letras maiúsculas e minúsculas. Além disso, existem algumas restrições em relação ao `DOMÍNIO` e `USUÁRIO`: - O campo `runAsUserName`: não pode estar vazio, e não pode conter caracteres - de contrôle (Valores ASCII : `0x00-0x1F`, `0x7F`) + de controle (Valores ASCII : `0x00-0x1F`, `0x7F`) - O nome de `DOMÍNIO` NetBios, ou um nome de DNS: cada um com suas próprias restrições: - Nomes NetBios: máximo de 15 caracteres, não podem iniciar com `.` (ponto), e não podem conter os seguintes caracteres: `\ / : * ? " < > |` From c5ec34093dad53a70575c4035139aa55face6348 Mon Sep 17 00:00:00 2001 From: "donatohorn@gmail.com" Date: Wed, 17 Aug 2022 19:22:11 -0300 Subject: [PATCH 008/279] [pt-br] add content/pt-br/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md --- .../enforce-standards-admission-controller.md | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/content/pt-br/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md b/content/pt-br/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md index cd61722679c..b62131e5d55 100644 --- a/content/pt-br/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md +++ b/content/pt-br/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md @@ -1,8 +1,5 @@ --- title: Aplicando os Padrões de Segurança do Pod, Configurando o Controlador de Admissão Embutido -reviewers: -- tallclair -- liggitt content_type: task min-kubernetes-server-version: v1.22 --- @@ -52,11 +49,11 @@ plugins: warn: "privileged" warn-version: "latest" exemptions: - # `Array`de nomes de usuários autenticados para isentar. + # Array of authenticated usernames to exempt. usernames: [] - # `Array` de nomes de classe `runtime` para isentar. + # Array of runtime class names to exempt. runtimeClasses: [] - # `Array` de namespaces para isentar. + # Array of namespaces to exempt. namespaces: [] ``` @@ -66,6 +63,7 @@ A v1beta1 de configuração requer v1.23+. Para v1.22, use v1alpha1. {{% /tab %}} {{% tab name="pod-security.admission.config.k8s.io/v1alpha1" %}} + ```yaml apiVersion: apiserver.config.k8s.io/v1 kind: AdmissionConfiguration @@ -74,16 +72,16 @@ plugins: configuration: apiVersion: pod-security.admission.config.k8s.io/v1alpha1 kind: PodSecurityConfiguration - # Os padrões aplicados quando uma label de modo não está definida. + # Defaults applied when a mode label is not set. # - # Valor de nível de label precisa ser um dos: + # Level label values must be one of: # - "privileged" (default) # - "baseline" # - "restricted" # - # Valor de versão de label precisa ser um dos: + # Version label values must be one of: # - "latest" (default) - # - Versão especifica como "v{{< skew currentVersion >}}" + # - specific version like "v{{< skew currentVersion >}}" defaults: enforce: "privileged" enforce-version: "latest" @@ -92,12 +90,12 @@ plugins: warn: "privileged" warn-version: "latest" exemptions: - # `Array` de nomes de usuários autenticados para isentar. + # Array of authenticated usernames to exempt. usernames: [] - # `Array` de nomes de calsses `runtime` para isentar. + # Array of runtime class names to exempt. runtimeClasses: [] - # `Array` de namespaces para isentar. - namespaces: [] + # Array of namespaces to exempt. + namespaces: [] ``` {{% /tab %}} {{< /tabs >}} From f73467052e2c0832af25e08a0f5ddcec92eadd6e Mon Sep 17 00:00:00 2001 From: "donatohorn@gmail.com" Date: Wed, 17 Aug 2022 23:58:00 -0300 Subject: [PATCH 009/279] [pt-br] add content/pt-br/docs/tasks/configure-pod-container/configure-runasusername.md --- .../tasks/configure-pod-container/configure-runasusername.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/pt-br/docs/tasks/configure-pod-container/configure-runasusername.md b/content/pt-br/docs/tasks/configure-pod-container/configure-runasusername.md index 4116a9c5f89..76f5b5e30e3 100644 --- a/content/pt-br/docs/tasks/configure-pod-container/configure-runasusername.md +++ b/content/pt-br/docs/tasks/configure-pod-container/configure-runasusername.md @@ -138,7 +138,7 @@ Para mais informações sobre estas limitações, verifique [aqui](https://suppo ## {{% heading "whatsnext" %}} -* [Guia para agendar contêineres Windows em Kubernetes](/docs/concepts/windows/user-guide/) +* [Guia Para Agendar Contêineres Windows em Kubernetes](/docs/concepts/windows/user-guide/) * [Gerenciando Identidade de Cargas de Trabalho com Contas de Serviço Gerenciadas em Grupo (GMSA)](/docs/concepts/windows/user-guide/#managing-workload-identity-with-group-managed-service-accounts) -* [Configure GMSA para pods e contêineres Windows](/docs/tasks/configure-pod-container/configure-gmsa/) +* [Configure GMSA Para Pods e Contêineres Windows](/docs/tasks/configure-pod-container/configure-gmsa/) From 8139f34af7b9e78588023608d48b14f8a9e86381 Mon Sep 17 00:00:00 2001 From: Bishal Das Date: Sat, 20 Aug 2022 18:35:14 +0530 Subject: [PATCH 010/279] Add cronjob.md Signed-off-by: Bishal Das --- content/hi/docs/reference/glossary/cronjob.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 content/hi/docs/reference/glossary/cronjob.md diff --git a/content/hi/docs/reference/glossary/cronjob.md b/content/hi/docs/reference/glossary/cronjob.md new file mode 100644 index 00000000000..e25ad022eb7 --- /dev/null +++ b/content/hi/docs/reference/glossary/cronjob.md @@ -0,0 +1,19 @@ +--- +title: क्रोंजोब +id: cronjob +date: 2018-04-12 +full_link: /docs/concepts/workloads/controllers/cron-jobs/ +short_description: > + एक दोहराए जाने वाला कार्य (एक काम) जो नियमित समय पर चलता है। + +aka: +tags: + - core-object + - workload +--- + +एक [काम](/docs/concepts/workloads/controllers/job/) का प्रबंधन करता है जो एक आवधिक अनुसूची पर चलता है। + + + +एक _crontab_ फ़ाइल में एक पंक्ति के समान, एक क्रोंजोब ऑब्जेक्ट [क्रों](https://en.wikipedia.org/wiki/Cron) प्रारूप का उपयोग करके एक शेड्यूल निर्दिष्ट करता है। From 29c6da6c9083a947c6c977b690aeb0759d606398 Mon Sep 17 00:00:00 2001 From: Bishal Das Date: Sun, 21 Aug 2022 11:45:58 +0530 Subject: [PATCH 011/279] updated cronjob.md Signed-off-by: Bishal Das --- content/hi/docs/reference/glossary/cronjob.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/hi/docs/reference/glossary/cronjob.md b/content/hi/docs/reference/glossary/cronjob.md index e25ad022eb7..aa52bcb7f92 100644 --- a/content/hi/docs/reference/glossary/cronjob.md +++ b/content/hi/docs/reference/glossary/cronjob.md @@ -1,5 +1,5 @@ --- -title: क्रोंजोब +title: क्रोंजोब (CronJob) id: cronjob date: 2018-04-12 full_link: /docs/concepts/workloads/controllers/cron-jobs/ From eec03cf71ccd4ff96dd4cd38a9c01ea3fb29882a Mon Sep 17 00:00:00 2001 From: Bishal das <70086051+bishal7679@users.noreply.github.com> Date: Tue, 23 Aug 2022 06:31:40 +0530 Subject: [PATCH 012/279] Update content/hi/docs/reference/glossary/cronjob.md Co-authored-by: Tim Bannister --- content/hi/docs/reference/glossary/cronjob.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/hi/docs/reference/glossary/cronjob.md b/content/hi/docs/reference/glossary/cronjob.md index aa52bcb7f92..2938693549b 100644 --- a/content/hi/docs/reference/glossary/cronjob.md +++ b/content/hi/docs/reference/glossary/cronjob.md @@ -12,7 +12,7 @@ tags: - workload --- -एक [काम](/docs/concepts/workloads/controllers/job/) का प्रबंधन करता है जो एक आवधिक अनुसूची पर चलता है। +एक [Job (काम)](/docs/concepts/workloads/controllers/job/) का प्रबंधन करता है जो एक आवधिक अनुसूची पर चलता है। From a3cc3c7758091f6d55f6f89ffbb71608fec3ae2a Mon Sep 17 00:00:00 2001 From: Bishal das <70086051+bishal7679@users.noreply.github.com> Date: Tue, 23 Aug 2022 20:07:35 +0530 Subject: [PATCH 013/279] Update content/hi/docs/reference/glossary/cronjob.md Co-authored-by: Vitthal Sai Kaul --- content/hi/docs/reference/glossary/cronjob.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/hi/docs/reference/glossary/cronjob.md b/content/hi/docs/reference/glossary/cronjob.md index 2938693549b..7efb58d2039 100644 --- a/content/hi/docs/reference/glossary/cronjob.md +++ b/content/hi/docs/reference/glossary/cronjob.md @@ -16,4 +16,4 @@ tags: -एक _crontab_ फ़ाइल में एक पंक्ति के समान, एक क्रोंजोब ऑब्जेक्ट [क्रों](https://en.wikipedia.org/wiki/Cron) प्रारूप का उपयोग करके एक शेड्यूल निर्दिष्ट करता है। +एक _crontab_ फ़ाइल में एक पंक्ति के समान, एक क्रॉन्जॉब (CronJob) ऑब्जेक्ट [क्रॉन](https://en.wikipedia.org/wiki/Cron) प्रारूप का उपयोग करके एक शेड्यूल निर्दिष्ट करता है। From f15ab325931bef7772fd43e4a36dacd53dce8ae4 Mon Sep 17 00:00:00 2001 From: Qiming Teng Date: Wed, 24 Aug 2022 15:40:43 +0800 Subject: [PATCH 014/279] Revert "Updated kubectl completion configuration" --- .../tools/included/optional-kubectl-configs-bash-linux.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/en/docs/tasks/tools/included/optional-kubectl-configs-bash-linux.md b/content/en/docs/tasks/tools/included/optional-kubectl-configs-bash-linux.md index 2f4a759e4e6..2bda1de17ea 100644 --- a/content/en/docs/tasks/tools/included/optional-kubectl-configs-bash-linux.md +++ b/content/en/docs/tasks/tools/included/optional-kubectl-configs-bash-linux.md @@ -51,7 +51,7 @@ bash-completion sources all completion scripts in `/etc/bash_completion.d`. {{< /note >}} Both approaches are equivalent. After reloading your shell, kubectl autocompletion should be working. -To enable bash autocompletion in current session of shell, run `exec bash`: +To enable bash autocompletion in current session of shell, source the ~/.bashrc file: ```bash -exec bash +source ~/.bashrc ``` From 0d7fe9a4968e9047713e0d86ae3f0f145361a286 Mon Sep 17 00:00:00 2001 From: "donatohorn@gmail.com" Date: Wed, 31 Aug 2022 18:18:23 -0300 Subject: [PATCH 015/279] [pt-br] add content/pt-br/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md --- .../enforce-standards-admission-controller.md | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/content/pt-br/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md b/content/pt-br/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md index b62131e5d55..7762fc1cf55 100644 --- a/content/pt-br/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md +++ b/content/pt-br/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md @@ -1,22 +1,19 @@ --- -title: Aplicando os Padrões de Segurança do Pod, Configurando o Controlador de Admissão Embutido +title: Aplicando os Padrões de Segurança do Pod Através da Configuração do Controlador de Admissão Embutido content_type: task min-kubernetes-server-version: v1.22 --- -Desde a versão v1.22, o Kubernetes fornece um [controlador de admissão] -(/docs/reference/access-authn-authz/admission-controllers/#podsecurity) -embutido para fazer cumprir os [padrões de segurança do Pod] -(/docs/concepts/security/pod-security-standards). +Desde a versão v1.22, o Kubernetes fornece um [controlador de admissão](/docs/reference/access-authn-authz/admission-controllers/#podsecurity) +embutido para fazer cumprir os [padrões de segurança do Pod](/docs/concepts/security/pod-security-standards). Você pode configurar esse controlador de admissão para definir padrões em todo -o cluster e [excessões](/docs/concepts/security/pod-security-admission/#exemptions). +o cluster e [exceções](/docs/concepts/security/pod-security-admission/#exemptions). ## {{% heading "prerequisites" %}} {{% version-check %}} -- Garanta que a `PodSecurity` do [portal de funcionalidade] -(/docs/reference/command-line-tools-reference/feature-gates/#feature-gates-for-alpha-or-beta-features) +- Garanta que a `PodSecurity` do [`feature gate`](/docs/reference/command-line-tools-reference/feature-gates/#feature-gates-for-alpha-or-beta-features) está ativada. ## Configure o Controlador de Admissão @@ -58,7 +55,7 @@ plugins: ``` {{< note >}} -A v1beta1 de configuração requer v1.23+. Para v1.22, use v1alpha1. +A versão da configuração v1beta1 requer a versão v1.23 ou superior do Kubernetes. Para a versão v1.22 do Kubernetes, utilize v1alpha1. {{< /note >}} {{% /tab %}} From 1518132f9c320caf64603e464f221b9d7f0b77ce Mon Sep 17 00:00:00 2001 From: Joe McMahon Date: Mon, 24 Oct 2022 00:57:07 -0700 Subject: [PATCH 016/279] 31483: clarify monitoring language - Original wording seemed to be tacitly encouraging Prometheus as the preferred monitoring solution, and was confusing to non-native speakers as written. - Remove direct references to Prometheus. - Emphasize that the Kubernetes docs are not in the business of telling you how to monitor Kubernetes. - Note that any monitoring should understand OpenMetrics. - Link to the CNCF landscape site, picking out the options for anyone who isn't sure what options they have - Note that the specific choice is part of the overall design of the infrastructure platform. --- .../debug-cluster/resource-usage-monitoring.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/content/en/docs/tasks/debug/debug-cluster/resource-usage-monitoring.md b/content/en/docs/tasks/debug/debug-cluster/resource-usage-monitoring.md index 3c270b8122f..adc63ece409 100644 --- a/content/en/docs/tasks/debug/debug-cluster/resource-usage-monitoring.md +++ b/content/en/docs/tasks/debug/debug-cluster/resource-usage-monitoring.md @@ -57,10 +57,17 @@ respond to these metrics by automatically scaling or adapting the cluster based on its current state, using mechanisms such as the Horizontal Pod Autoscaler. The monitoring pipeline fetches metrics from the kubelet and then exposes them to Kubernetes via an adapter by implementing either the -`custom.metrics.k8s.io` or `external.metrics.k8s.io` API. +`custom.metrics.k8s.io` or `external.metrics.k8s.io` API. -[Prometheus](https://prometheus.io), a CNCF project, can natively monitor Kubernetes, nodes, and Prometheus itself. -Full metrics pipeline projects that are not part of the CNCF are outside the scope of Kubernetes documentation. +Integration of a full metrics pipeline into your Kubernetes implementation is outside +the scope of Kubernetes documentation because of the very wide scope of possible +solutions. + +The choice of monitoring platform depends heavily on your needs, budget, and technical resources. +Kubernetes does not recommend any specific metrics pipeline; [many options](https://landscape.cncf.io/card-mode?category=monitoring&project=graduated,incubating,member,no&grouping=category&sort=stars) are available. +Your monitoring system should be capable of handling the [OpenMetrics](https://openmetrics.io/) metrics +transmission standard, and needs to chosen to best fit in to your overall design and deployment of +your infrastructure platform. ## {{% heading "whatsnext" %}} From cf29a21c9d921b50a0ac650de66dfd4925fd0fc2 Mon Sep 17 00:00:00 2001 From: Atsushi Torikoshi Date: Tue, 15 Nov 2022 23:33:50 +0900 Subject: [PATCH 017/279] Update the explanation for `kubectl describe pod`. Commit b60aa414a0b updated the command output samples, but explanations for the output of `kubectl describe pod` seems not to be updated. --- .../en/docs/tasks/debug/debug-application/debug-running-pod.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/docs/tasks/debug/debug-application/debug-running-pod.md b/content/en/docs/tasks/debug/debug-application/debug-running-pod.md index f829b7821b7..41af33da52d 100644 --- a/content/en/docs/tasks/debug/debug-application/debug-running-pod.md +++ b/content/en/docs/tasks/debug/debug-application/debug-running-pod.md @@ -127,7 +127,7 @@ Restart Count tells you how many times the container has been restarted; this in Currently the only Condition associated with a Pod is the binary Ready condition, which indicates that the pod is able to service requests and should be added to the load balancing pools of all matching services. -Lastly, you see a log of recent events related to your Pod. The system compresses multiple identical events by indicating the first and last time it was seen and the number of times it was seen. "From" indicates the component that is logging the event, "SubobjectPath" tells you which object (e.g. container within the pod) is being referred to, and "Reason" and "Message" tell you what happened. +Lastly, you see a log of recent events related to your Pod. "From" indicates the component that is logging the event. "Reason" and "Message" tell you what happened. ## Example: debugging Pending Pods From 902b1202535cde107d716007d86d51102ed968f9 Mon Sep 17 00:00:00 2001 From: Bishal das <70086051+bishal7679@users.noreply.github.com> Date: Wed, 23 Nov 2022 11:41:23 +0530 Subject: [PATCH 018/279] Update content/hi/docs/reference/glossary/cronjob.md Co-authored-by: divya-mohan0209 --- content/hi/docs/reference/glossary/cronjob.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/hi/docs/reference/glossary/cronjob.md b/content/hi/docs/reference/glossary/cronjob.md index 7efb58d2039..dde3f3ca03e 100644 --- a/content/hi/docs/reference/glossary/cronjob.md +++ b/content/hi/docs/reference/glossary/cronjob.md @@ -1,5 +1,5 @@ --- -title: क्रोंजोब (CronJob) +title: क्रॉन्जॉब (CronJob) id: cronjob date: 2018-04-12 full_link: /docs/concepts/workloads/controllers/cron-jobs/ From b8c7d00c222f8e877fe5aeecc058bdd37599ace4 Mon Sep 17 00:00:00 2001 From: Bishal das <70086051+bishal7679@users.noreply.github.com> Date: Wed, 23 Nov 2022 11:41:41 +0530 Subject: [PATCH 019/279] Update content/hi/docs/reference/glossary/cronjob.md Co-authored-by: divya-mohan0209 --- content/hi/docs/reference/glossary/cronjob.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/hi/docs/reference/glossary/cronjob.md b/content/hi/docs/reference/glossary/cronjob.md index dde3f3ca03e..93ad931bbb8 100644 --- a/content/hi/docs/reference/glossary/cronjob.md +++ b/content/hi/docs/reference/glossary/cronjob.md @@ -12,7 +12,7 @@ tags: - workload --- -एक [Job (काम)](/docs/concepts/workloads/controllers/job/) का प्रबंधन करता है जो एक आवधिक अनुसूची पर चलता है। +एक [काम (Job)](/docs/concepts/workloads/controllers/job/) का प्रबंधन करता है जो आवधिक अनुसूची पर चलता है। From b592215c13565428baa94981055caafb42f1432d Mon Sep 17 00:00:00 2001 From: Shannon Kularathna Date: Tue, 15 Nov 2022 22:46:11 +0000 Subject: [PATCH 020/279] Move mounted Secrets sections verbatim to task page --- .../en/docs/concepts/configuration/secret.md | 156 ------------------ .../distribute-credentials-secure.md | 121 ++++++++++++++ .../en/examples/pods/inject/secret-pod.yaml | 1 + 3 files changed, 122 insertions(+), 156 deletions(-) diff --git a/content/en/docs/concepts/configuration/secret.md b/content/en/docs/concepts/configuration/secret.md index 52408e6022b..05680c9cbde 100644 --- a/content/en/docs/concepts/configuration/secret.md +++ b/content/en/docs/concepts/configuration/secret.md @@ -181,45 +181,6 @@ If you want to access data from a Secret in a Pod, one way to do that is to have Kubernetes make the value of that Secret be available as a file inside the filesystem of one or more of the Pod's containers. -To configure that, you: - -1. Create a secret or use an existing one. Multiple Pods can reference the same secret. -1. Modify your Pod definition to add a volume under `.spec.volumes[]`. Name the volume anything, - and have a `.spec.volumes[].secret.secretName` field equal to the name of the Secret object. -1. Add a `.spec.containers[].volumeMounts[]` to each container that needs the secret. Specify - `.spec.containers[].volumeMounts[].readOnly = true` and - `.spec.containers[].volumeMounts[].mountPath` to an unused directory name where you would like the - secrets to appear. -1. Modify your image or command line so that the program looks for files in that directory. Each - key in the secret `data` map becomes the filename under `mountPath`. - -This is an example of a Pod that mounts a Secret named `mysecret` in a volume: - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: mypod -spec: - containers: - - name: mypod - image: redis - volumeMounts: - - name: foo - mountPath: "/etc/foo" - readOnly: true - volumes: - - name: foo - secret: - secretName: mysecret - optional: false # default setting; "mysecret" must exist -``` - -Each Secret you want to use needs to be referred to in `.spec.volumes`. - -If there are multiple containers in the Pod, then each container needs its -own `volumeMounts` block, but only one `.spec.volumes` is needed per Secret. - {{< note >}} Versions of Kubernetes before v1.22 automatically created credentials for accessing the Kubernetes API. This older mechanism was based on creating token Secrets that @@ -238,123 +199,6 @@ You can use the [`kubectl create token`](/docs/reference/generated/kubectl/kubec command to obtain a token from the `TokenRequest` API. {{< /note >}} -#### Projection of Secret keys to specific paths - -You can also control the paths within the volume where Secret keys are projected. -You can use the `.spec.volumes[].secret.items` field to change the target path of each key: - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: mypod -spec: - containers: - - name: mypod - image: redis - volumeMounts: - - name: foo - mountPath: "/etc/foo" - readOnly: true - volumes: - - name: foo - secret: - secretName: mysecret - items: - - key: username - path: my-group/my-username -``` - -What will happen: - -* the `username` key from `mysecret` is available to the container at the path - `/etc/foo/my-group/my-username` instead of at `/etc/foo/username`. -* the `password` key from that Secret object is not projected. - -If `.spec.volumes[].secret.items` is used, only keys specified in `items` are projected. -To consume all keys from the Secret, all of them must be listed in the `items` field. - -If you list keys explicitly, then all listed keys must exist in the corresponding Secret. -Otherwise, the volume is not created. - -#### Secret files permissions - -You can set the POSIX file access permission bits for a single Secret key. -If you don't specify any permissions, `0644` is used by default. -You can also set a default mode for the entire Secret volume and override per key if needed. - -For example, you can specify a default mode like this: - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: mypod -spec: - containers: - - name: mypod - image: redis - volumeMounts: - - name: foo - mountPath: "/etc/foo" - volumes: - - name: foo - secret: - secretName: mysecret - defaultMode: 0400 -``` - -The secret is mounted on `/etc/foo`; all the files created by the -secret volume mount have permission `0400`. - -{{< note >}} -If you're defining a Pod or a Pod template using JSON, beware that the JSON -specification doesn't support octal notation. You can use the decimal value -for the `defaultMode` (for example, 0400 in octal is 256 in decimal) instead. -If you're writing YAML, you can write the `defaultMode` in octal. -{{< /note >}} - -#### Consuming Secret values from volumes - -Inside the container that mounts a secret volume, the secret keys appear as -files. The secret values are base64 decoded and stored inside these files. - -This is the result of commands executed inside the container from the example above: - -```shell -ls /etc/foo/ -``` - -The output is similar to: - -``` -username -password -``` - -```shell -cat /etc/foo/username -``` - -The output is similar to: - -``` -admin -``` - -```shell -cat /etc/foo/password -``` - -The output is similar to: - -``` -1f2d1e2e67df -``` - -The program in a container is responsible for reading the secret data from these -files, as needed. - #### Mounted Secrets are updated automatically When a volume contains data from a Secret, and that Secret is updated, Kubernetes tracks diff --git a/content/en/docs/tasks/inject-data-application/distribute-credentials-secure.md b/content/en/docs/tasks/inject-data-application/distribute-credentials-secure.md index d2ca2feabd1..203d2434f33 100644 --- a/content/en/docs/tasks/inject-data-application/distribute-credentials-secure.md +++ b/content/en/docs/tasks/inject-data-application/distribute-credentials-secure.md @@ -149,6 +149,127 @@ Here is a configuration file you can use to create a Pod: 39528$vdg7Jb ``` +Modify your image or command line so that the program looks for files in the +`mountPath` directory. Each key in the Secret `data` map becomes a file name +in this directory. + +#### Projection of Secret keys to specific paths + +You can also control the paths within the volume where Secret keys are projected. +You can use the `.spec.volumes[].secret.items` field to change the target path of each key: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: mypod +spec: + containers: + - name: mypod + image: redis + volumeMounts: + - name: foo + mountPath: "/etc/foo" + readOnly: true + volumes: + - name: foo + secret: + secretName: mysecret + items: + - key: username + path: my-group/my-username +``` + +What will happen: + +* the `username` key from `mysecret` is available to the container at the path + `/etc/foo/my-group/my-username` instead of at `/etc/foo/username`. +* the `password` key from that Secret object is not projected. + +If `.spec.volumes[].secret.items` is used, only keys specified in `items` are projected. +To consume all keys from the Secret, all of them must be listed in the `items` field. + +If you list keys explicitly, then all listed keys must exist in the corresponding Secret. +Otherwise, the volume is not created. + +#### Secret files permissions + +You can set the POSIX file access permission bits for a single Secret key. +If you don't specify any permissions, `0644` is used by default. +You can also set a default mode for the entire Secret volume and override per key if needed. + +For example, you can specify a default mode like this: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: mypod +spec: + containers: + - name: mypod + image: redis + volumeMounts: + - name: foo + mountPath: "/etc/foo" + volumes: + - name: foo + secret: + secretName: mysecret + defaultMode: 0400 +``` + +The secret is mounted on `/etc/foo`; all the files created by the +secret volume mount have permission `0400`. + +{{< note >}} +If you're defining a Pod or a Pod template using JSON, beware that the JSON +specification doesn't support octal notation. You can use the decimal value +for the `defaultMode` (for example, 0400 in octal is 256 in decimal) instead. +If you're writing YAML, you can write the `defaultMode` in octal. +{{< /note >}} + +#### Consuming Secret values from volumes + +Inside the container that mounts a secret volume, the secret keys appear as +files. The secret values are base64 decoded and stored inside these files. + +This is the result of commands executed inside the container from the example above: + +```shell +ls /etc/foo/ +``` + +The output is similar to: + +``` +username +password +``` + +```shell +cat /etc/foo/username +``` + +The output is similar to: + +``` +admin +``` + +```shell +cat /etc/foo/password +``` + +The output is similar to: + +``` +1f2d1e2e67df +``` + +The program in a container is responsible for reading the secret data from these +files, as needed. + ## Define container environment variables using Secret data ### Define a container environment variable with data from a single Secret diff --git a/content/en/examples/pods/inject/secret-pod.yaml b/content/en/examples/pods/inject/secret-pod.yaml index 8be694cddee..8487da8d1c1 100644 --- a/content/en/examples/pods/inject/secret-pod.yaml +++ b/content/en/examples/pods/inject/secret-pod.yaml @@ -10,6 +10,7 @@ spec: # name must match the volume name below - name: secret-volume mountPath: /etc/secret-volume + readOnly: true # The secret data is exposed to Containers in the Pod through a Volume. volumes: - name: secret-volume From 15e374d4f94e491be73e4488aa167e789ac60eea Mon Sep 17 00:00:00 2001 From: Shannon Kularathna Date: Tue, 15 Nov 2022 22:59:24 +0000 Subject: [PATCH 021/279] Edit mounted secrets wording - Change heading levels - Improve the intro sentence for the list - Style edit for the list items - Convert the limitations of explicit listing into a bullet list - In the bullet list, clean up phrasing - Remove the 'Read the secret data' bit. The existing steps on this page have the same instructions. --- .../distribute-credentials-secure.md | 66 ++++--------------- 1 file changed, 14 insertions(+), 52 deletions(-) diff --git a/content/en/docs/tasks/inject-data-application/distribute-credentials-secure.md b/content/en/docs/tasks/inject-data-application/distribute-credentials-secure.md index 203d2434f33..c6dc32043a1 100644 --- a/content/en/docs/tasks/inject-data-application/distribute-credentials-secure.md +++ b/content/en/docs/tasks/inject-data-application/distribute-credentials-secure.md @@ -153,10 +153,10 @@ Modify your image or command line so that the program looks for files in the `mountPath` directory. Each key in the Secret `data` map becomes a file name in this directory. -#### Projection of Secret keys to specific paths +### Project Secret keys to specific file paths -You can also control the paths within the volume where Secret keys are projected. -You can use the `.spec.volumes[].secret.items` field to change the target path of each key: +You can also control the paths within the volume where Secret keys are projected. Use the `.spec.volumes[].secret.items` field to change the target +path of each key: ```yaml apiVersion: v1 @@ -180,19 +180,22 @@ spec: path: my-group/my-username ``` -What will happen: +When you deploy this Pod, the following happens: -* the `username` key from `mysecret` is available to the container at the path +* The `username` key from `mysecret` is available to the container at the path `/etc/foo/my-group/my-username` instead of at `/etc/foo/username`. -* the `password` key from that Secret object is not projected. +* The `password` key from that Secret object is not projected. -If `.spec.volumes[].secret.items` is used, only keys specified in `items` are projected. -To consume all keys from the Secret, all of them must be listed in the `items` field. +If you list keys explicitly using `.spec.volumes[].secret.items`, consider the +following: -If you list keys explicitly, then all listed keys must exist in the corresponding Secret. -Otherwise, the volume is not created. +* Only keys specified in `items` are projected. +* To consume all keys from the Secret, all of them must be listed in the + `items` field. +* All listed keys must exist in the corresponding Secret. Otherwise, the volume + is not created. -#### Secret files permissions +### Set POSIX permissions for Secret keys You can set the POSIX file access permission bits for a single Secret key. If you don't specify any permissions, `0644` is used by default. @@ -229,47 +232,6 @@ for the `defaultMode` (for example, 0400 in octal is 256 in decimal) instead. If you're writing YAML, you can write the `defaultMode` in octal. {{< /note >}} -#### Consuming Secret values from volumes - -Inside the container that mounts a secret volume, the secret keys appear as -files. The secret values are base64 decoded and stored inside these files. - -This is the result of commands executed inside the container from the example above: - -```shell -ls /etc/foo/ -``` - -The output is similar to: - -``` -username -password -``` - -```shell -cat /etc/foo/username -``` - -The output is similar to: - -``` -admin -``` - -```shell -cat /etc/foo/password -``` - -The output is similar to: - -``` -1f2d1e2e67df -``` - -The program in a container is responsible for reading the secret data from these -files, as needed. - ## Define container environment variables using Secret data ### Define a container environment variable with data from a single Secret From 036695740e313400984e5953b01ae67b4ed56fa6 Mon Sep 17 00:00:00 2001 From: Qiming Teng Date: Mon, 22 Aug 2022 20:19:46 +0800 Subject: [PATCH 022/279] Format markdown on the ingress-minikube page This PR adjusts the indentation and line-wrapping on the ingress-minikube page. --- .../ingress-minikube.md | 182 ++++++++++-------- 1 file changed, 102 insertions(+), 80 deletions(-) diff --git a/content/en/docs/tasks/access-application-cluster/ingress-minikube.md b/content/en/docs/tasks/access-application-cluster/ingress-minikube.md index 251bebbaeff..9459b7b6653 100644 --- a/content/en/docs/tasks/access-application-cluster/ingress-minikube.md +++ b/content/en/docs/tasks/access-application-cluster/ingress-minikube.md @@ -7,20 +7,18 @@ min-kubernetes-server-version: 1.19 -An [Ingress](/docs/concepts/services-networking/ingress/) is an API object that defines rules which allow external access -to services in a cluster. An [Ingress controller](/docs/concepts/services-networking/ingress-controllers/) fulfills the rules set in the Ingress. - -This page shows you how to set up a simple Ingress which routes requests to Service web or web2 depending on the HTTP URI. - +An [Ingress](/docs/concepts/services-networking/ingress/) is an API object that defines rules +which allow external access to services in a cluster. An +[Ingress controller](/docs/concepts/services-networking/ingress-controllers/) +fulfills the rules set in the Ingress. +This page shows you how to set up a simple Ingress which routes requests to Service 'web' or +'web2' depending on the HTTP URI. ## {{% heading "prerequisites" %}} - {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} -If you are using an older Kubernetes version, switch to the documentation -for that version. - +If you are using an older Kubernetes version, switch to the documentation for that version. ### Create a Minikube cluster @@ -37,49 +35,60 @@ Locally 1. To enable the NGINX Ingress controller, run the following command: - ```shell - minikube addons enable ingress - ``` + ```shell + minikube addons enable ingress + ``` 1. Verify that the NGINX Ingress controller is running {{< tabs name="tab_with_md" >}} {{% tab name="minikube v1.19 or later" %}} -```shell -kubectl get pods -n ingress-nginx -``` - {{< note >}}It can take up to a minute before you see these pods running OK.{{< /note >}} + + ```shell + kubectl get pods -n ingress-nginx + ``` + + {{< note >}} + It can take up to a minute before you see these pods running OK. + {{< /note >}} The output is similar to: -``` -NAME READY STATUS RESTARTS AGE -ingress-nginx-admission-create-g9g49 0/1 Completed 0 11m -ingress-nginx-admission-patch-rqp78 0/1 Completed 1 11m -ingress-nginx-controller-59b45fb494-26npt 1/1 Running 0 11m -``` + ```none + NAME READY STATUS RESTARTS AGE + ingress-nginx-admission-create-g9g49 0/1 Completed 0 11m + ingress-nginx-admission-patch-rqp78 0/1 Completed 1 11m + ingress-nginx-controller-59b45fb494-26npt 1/1 Running 0 11m + ``` {{% /tab %}} + {{% tab name="minikube v1.18.1 or earlier" %}} -```shell -kubectl get pods -n kube-system -``` - {{< note >}}It can take up to a minute before you see these pods running OK.{{< /note >}} + + ```shell + kubectl get pods -n kube-system + ``` + + {{< note >}} + It can take up to a minute before you see these pods running OK. + {{< /note >}} The output is similar to: -``` -NAME READY STATUS RESTARTS AGE -default-http-backend-59868b7dd6-xb8tq 1/1 Running 0 1m -kube-addon-manager-minikube 1/1 Running 0 3m -kube-dns-6dcb57bcc8-n4xd4 3/3 Running 0 2m -kubernetes-dashboard-5498ccf677-b8p5h 1/1 Running 0 2m -nginx-ingress-controller-5984b97644-rnkrg 1/1 Running 0 1m -storage-provisioner 1/1 Running 0 2m -``` + ```none + NAME READY STATUS RESTARTS AGE + default-http-backend-59868b7dd6-xb8tq 1/1 Running 0 1m + kube-addon-manager-minikube 1/1 Running 0 3m + kube-dns-6dcb57bcc8-n4xd4 3/3 Running 0 2m + kubernetes-dashboard-5498ccf677-b8p5h 1/1 Running 0 2m + nginx-ingress-controller-5984b97644-rnkrg 1/1 Running 0 1m + storage-provisioner 1/1 Running 0 2m + ``` + + Make sure that you see a Pod with a name that starts with `nginx-ingress-controller-`. - Make sure that you see a Pod with a name that starts with `nginx-ingress-controller-`. {{% /tab %}} + {{< /tabs >}} ## Deploy a hello, world app @@ -92,7 +101,7 @@ storage-provisioner 1/1 Running 0 2m The output should be: - ``` + ```none deployment.apps/web created ``` @@ -104,19 +113,19 @@ storage-provisioner 1/1 Running 0 2m The output should be: - ``` + ```none service/web exposed ``` 1. Verify the Service is created and is available on a node port: - ```shell + ```shell kubectl get service web ``` The output is similar to: - ``` + ```none NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE web NodePort 10.104.133.249 8080:31637/TCP 12m ``` @@ -129,26 +138,31 @@ storage-provisioner 1/1 Running 0 2m The output is similar to: - ``` + ```none http://172.17.0.15:31637 ``` - {{< note >}}Katacoda environment only: at the top of the terminal panel, click the plus sign, and then click **Select port to view on Host 1**. Enter the NodePort, in this case `31637`, and then click **Display Port**.{{< /note >}} + {{< note >}} + Katacoda environment only: at the top of the terminal panel, click the plus sign, + and then click **Select port to view on Host 1**. Enter the NodePort value, + in this case `31637`, and then click **Display Port**. + {{< /note >}} The output is similar to: - ``` + ```none Hello, world! Version: 1.0.0 Hostname: web-55b8c6998d-8k564 ``` - You can now access the sample app via the Minikube IP address and NodePort. The next step lets you access - the app using the Ingress resource. + You can now access the sample application via the Minikube IP address and NodePort. + The next step lets you access the application using the Ingress resource. ## Create an Ingress -The following manifest defines an Ingress that sends traffic to your Service via hello-world.info. +The following manifest defines an Ingress that sends traffic to your Service via +`hello-world.info`. 1. Create `example-ingress.yaml` from the following file: @@ -162,7 +176,7 @@ The following manifest defines an Ingress that sends traffic to your Service via The output should be: - ``` + ```none ingress.networking.k8s.io/example-ingress created ``` @@ -172,11 +186,13 @@ The following manifest defines an Ingress that sends traffic to your Service via kubectl get ingress ``` - {{< note >}}This can take a couple of minutes.{{< /note >}} + {{< note >}} + This can take a couple of minutes. + {{< /note >}} - You should see an IPv4 address in the ADDRESS column; for example: + You should see an IPv4 address in the `ADDRESS` column; for example: - ``` + ```none NAME CLASS HOSTS ADDRESS PORTS AGE example-ingress hello-world.info 172.17.0.15 80 38s ``` @@ -184,30 +200,35 @@ The following manifest defines an Ingress that sends traffic to your Service via 1. Add the following line to the bottom of the `/etc/hosts` file on your computer (you will need administrator access): - ``` + ```none 172.17.0.15 hello-world.info ``` - {{< note >}}If you are running Minikube locally, use `minikube ip` to get the external IP. The IP address displayed within the ingress list will be the internal IP.{{< /note >}} + {{< note >}} + If you are running Minikube locally, use `minikube ip` to get the external IP. + The IP address displayed within the ingress list will be the internal IP. + {{< /note >}} - After you make this change, your web browser sends requests for - hello-world.info URLs to Minikube. + After you make this change, your web browser sends requests for + `hello-world.info` URLs to Minikube. 1. Verify that the Ingress controller is directing traffic: - ```shell - curl hello-world.info - ``` + ```shell + curl hello-world.info + ``` - You should see: + You should see: - ``` - Hello, world! - Version: 1.0.0 - Hostname: web-55b8c6998d-8k564 - ``` + ```none + Hello, world! + Version: 1.0.0 + Hostname: web-55b8c6998d-8k564 + ``` - {{< note >}}If you are running Minikube locally, you can visit hello-world.info from your browser.{{< /note >}} + {{< note >}} + If you are running Minikube locally, you can visit `hello-world.info` from your browser. + {{< /note >}} ## Create a second Deployment @@ -216,9 +237,10 @@ The following manifest defines an Ingress that sends traffic to your Service via ```shell kubectl create deployment web2 --image=gcr.io/google-samples/hello-app:2.0 ``` + The output should be: - ``` + ```none deployment.apps/web2 created ``` @@ -230,7 +252,7 @@ The following manifest defines an Ingress that sends traffic to your Service via The output should be: - ``` + ```none service/web2 exposed ``` @@ -240,13 +262,13 @@ The following manifest defines an Ingress that sends traffic to your Service via following lines at the end: ```yaml - - path: /v2 - pathType: Prefix - backend: - service: - name: web2 - port: - number: 8080 + - path: /v2 + pathType: Prefix + backend: + service: + name: web2 + port: + number: 8080 ``` 1. Apply the changes: @@ -257,7 +279,7 @@ The following manifest defines an Ingress that sends traffic to your Service via You should see: - ``` + ```none ingress.networking/example-ingress configured ``` @@ -271,7 +293,7 @@ The following manifest defines an Ingress that sends traffic to your Service via The output is similar to: - ``` + ```none Hello, world! Version: 1.0.0 Hostname: web-55b8c6998d-8k564 @@ -285,16 +307,16 @@ The following manifest defines an Ingress that sends traffic to your Service via The output is similar to: - ``` + ```none Hello, world! Version: 2.0.0 Hostname: web2-75cd47646f-t8cjk ``` - {{< note >}}If you are running Minikube locally, you can visit hello-world.info and hello-world.info/v2 from your browser.{{< /note >}} - - - + {{< note >}} + If you are running Minikube locally, you can visit `hello-world.info` and + `hello-world.info/v2` from your browser. + {{< /note >}} ## {{% heading "whatsnext" %}} From 7c283ba07a7b0ce2d7f4361de2f096c47294ede3 Mon Sep 17 00:00:00 2001 From: lakshmi Date: Mon, 5 Dec 2022 17:28:17 +0530 Subject: [PATCH 023/279] Updated service.md page --- .../docs/concepts/services-networking/service.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/content/en/docs/concepts/services-networking/service.md b/content/en/docs/concepts/services-networking/service.md index 9bd08bc8ac6..dd01d9e4bf6 100644 --- a/content/en/docs/concepts/services-networking/service.md +++ b/content/en/docs/concepts/services-networking/service.md @@ -429,7 +429,7 @@ the port number for `http`, as well as the IP address. The Kubernetes DNS server is the only way to access `ExternalName` Services. You can find more information about `ExternalName` resolution in -[DNS Pods and Services](/docs/concepts/services-networking/dns-pod-service/). +[DNS for Services and Pods](/docs/concepts/services-networking/dns-pod-service/). ## Headless Services @@ -1205,12 +1205,13 @@ mechanism Kubernetes provides to expose a Service with a virtual IP address. ## {{% heading "whatsnext" %}} +Learn more about the following: * Follow the [Connecting Applications with Services](/docs/tutorials/services/connect-applications-service/) tutorial -* Read about [Ingress](/docs/concepts/services-networking/ingress/) -* Read about [EndpointSlices](/docs/concepts/services-networking/endpoint-slices/) +* [Ingress](/docs/concepts/services-networking/ingress/) exposes HTTP and HTTPS routes from outside the cluster to services within the cluster. +* [EndpointSlices](/docs/concepts/services-networking/endpoint-slices/) For more context: -* Read [Virtual IPs and Service Proxies](/docs/reference/networking/virtual-ips/) -* Read the [API reference](/docs/reference/kubernetes-api/service-resources/service-v1/) for the Service API -* Read the [API reference](/docs/reference/kubernetes-api/service-resources/endpoints-v1/) for the Endpoints API -* Read the [API reference](/docs/reference/kubernetes-api/service-resources/endpoint-slice-v1/) for the EndpointSlice API +* [Virtual IPs and Service Proxies](/docs/reference/networking/virtual-ips/) +* [API reference](/docs/reference/kubernetes-api/service-resources/service-v1/) for the Service API +* [API reference](/docs/reference/kubernetes-api/service-resources/endpoints-v1/) for the Endpoints API +* [API reference](/docs/reference/kubernetes-api/service-resources/endpoint-slice-v1/) for the EndpointSlice API From 2a75a0d17be50292413b008ba3babbbaf44e8405 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulo=20Gon=C3=A7alves=20Lima?= Date: Thu, 15 Dec 2022 02:07:51 -0300 Subject: [PATCH 024/279] [pt-br] Translating page: Customizing DNS Service Done: + Introduction + CoreDNS TODO: - CoreDNS ConfigMap options - Configuration of Stub-domain and upstream nameserver using CoreDNS - Example kubernetes#13939 --- .../dns-custom-nameservers.md | 187 ++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 content/pt-br/docs/tasks/administer-cluster/dns-custom-nameservers.md diff --git a/content/pt-br/docs/tasks/administer-cluster/dns-custom-nameservers.md b/content/pt-br/docs/tasks/administer-cluster/dns-custom-nameservers.md new file mode 100644 index 00000000000..6e95c8bdaf0 --- /dev/null +++ b/content/pt-br/docs/tasks/administer-cluster/dns-custom-nameservers.md @@ -0,0 +1,187 @@ +--- +reviewers: +- bowei +- zihongz +title: Customizing DNS Service +content_type: task +min-kubernetes-server-version: v1.12 +--- + + +Essa pagina explica como configurar o seu DNS +{{< glossary_tooltip text="Pod(s)" term_id="pod" >}} e personalizar o processo de resolução de DNS no seu cluster. + +## {{% heading "prerequisites" %}} + +{{< include "task-tutorial-prereqs.md" >}} + +Seu cluster deve estar executando o complemento CoreDNS. + +{{% version-check %}} + + + +## Introdução + +DNS é um serviço integrado do Kubernetes que é integrado automaticamente usando o _gerenciador de complementos_ [cluster add-on](http://releases.k8s.io/master/cluster/addons/README.md). + +{{< note >}} +O Serviço CoreDNS é chamado de `kube-dns` no campo `metadata.name`. +O objetivo é garantir maior interoperabilidade com cargas de trabalho que dependiam do nome de serviço legado `kube-dns` para resolver endereços internos ao cluster. +Usando o serviço chamado `kube-dns` abstrai o detalhe de implementação de qual provedor de DNS está sendo executado por trás desse nome comum. +{{< /note >}} + +Se você estiver executando o CoreDNS como um Deployment, ele geralmente será exposto como um Serviço do Kubernetes com o endereço de IP estático. +O kubelet passa informações de resolução de DNS para cada contêiner com a flag `--cluster-dns=`. + +Os nomes DNS também precisam de domínios. Você configura o domínio local no kubelet com a flag `--cluster-domain=`. + +O servidor DNS suporta pesquisas de encaminhamento (registros A e AAAA), pesquisas de porta (registros SRV), pesquisas de endereço de IP reverso (registros PTR) e muito mais. Para mais informações, veja [DNS para Serviços e Pods](/docs/concepts/services-networking/dns-pod-service/). + +Se a `dnsPolicy` de um Pod estiver definida como `default`, ele herda a configuração de resolução de nome do nó em que o Pod é executado. A resolução de DNS do Pod deve se comportar da mesma forma que o nó. +Veja [Problemas conhecidos](/docs/tasks/administer-cluster/dns-debugging-resolution/#known-issues).. + +Se você não quiser isso, ou se quiser uma configuração de DNS diferente para os pods, pode usar a flag `--resolv-conf` do kubelet. Defina essa flag como "" para impedir que os Pods herdem a configuração do DNS. Defina-a como um caminho de arquivo válido para especificar um arquivo diferente de `/etc/resolv.conf` para a herança de DNS. + +## CoreDNS + +CoreDNS é um servidor oficial de DNS de propósito geral que pode atuar como DNS do cluster, +cumprindo com as [especificações DNS](https://github.com/kubernetes/dns/blob/master/docs/specification.md). + +### CoreDNS ConfigMap options + +CoreDNS is a DNS server that is modular and pluggable, with plugins adding new functionalities. +The CoreDNS server can be configured by maintaining a [Corefile](https://coredns.io/2017/07/23/corefile-explained/), +which is the CoreDNS configuration file. As a cluster administrator, you can modify the +{{< glossary_tooltip text="ConfigMap" term_id="configmap" >}} for the CoreDNS Corefile to +change how DNS service discovery behaves for that cluster. + +In Kubernetes, CoreDNS is installed with the following default Corefile configuration: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: coredns + namespace: kube-system +data: + Corefile: | + .:53 { + errors + health { + lameduck 5s + } + ready + kubernetes cluster.local in-addr.arpa ip6.arpa { + pods insecure + fallthrough in-addr.arpa ip6.arpa + ttl 30 + } + prometheus :9153 + forward . /etc/resolv.conf + cache 30 + loop + reload + loadbalance + } +``` + +The Corefile configuration includes the following [plugins](https://coredns.io/plugins/) of CoreDNS: + +* [errors](https://coredns.io/plugins/errors/): Errors are logged to stdout. +* [health](https://coredns.io/plugins/health/): Health of CoreDNS is reported to + `http://localhost:8080/health`. In this extended syntax `lameduck` will make theuprocess + unhealthy then wait for 5 seconds before the process is shut down. +* [ready](https://coredns.io/plugins/ready/): An HTTP endpoint on port 8181 will return 200 OK, + when all plugins that are able to signal readiness have done so. +* [kubernetes](https://coredns.io/plugins/kubernetes/): CoreDNS will reply to DNS queries + based on IP of the Services and Pods. You can find [more details](https://coredns.io/plugins/kubernetes/) + about this plugin on the CoreDNS website. + - `ttl` allows you to set a custom TTL for responses. The default is 5 seconds. + The minimum TTL allowed is 0 seconds, and the maximum is capped at 3600 seconds. + Setting TTL to 0 will prevent records from being cached. + - The `pods insecure` option is provided for backward compatibility with `kube-dns`. + - You can use the `pods verified` option, which returns an A record only if there exists a pod + in the same namespace with a matching IP. + - The `pods disabled` option can be used if you don't use pod records. +* [prometheus](https://coredns.io/plugins/metrics/): Metrics of CoreDNS are available at + `http://localhost:9153/metrics` in the [Prometheus](https://prometheus.io/) format + (also known as OpenMetrics). +* [forward](https://coredns.io/plugins/forward/): Any queries that are not within the Kubernetes + cluster domain are forwarded to predefined resolvers (/etc/resolv.conf). +* [cache](https://coredns.io/plugins/cache/): This enables a frontend cache. +* [loop](https://coredns.io/plugins/loop/): Detects simple forwarding loops and + halts the CoreDNS process if a loop is found. +* [reload](https://coredns.io/plugins/reload): Allows automatic reload of a changed Corefile. + After you edit the ConfigMap configuration, allow two minutes for your changes to take effect. +* [loadbalance](https://coredns.io/plugins/loadbalance): This is a round-robin DNS loadbalancer + that randomizes the order of A, AAAA, and MX records in the answer. + +You can modify the default CoreDNS behavior by modifying the ConfigMap. + +### Configuration of Stub-domain and upstream nameserver using CoreDNS + +CoreDNS has the ability to configure stub-domains and upstream nameservers +using the [forward plugin](https://coredns.io/plugins/forward/). + +#### Example + +If a cluster operator has a [Consul](https://www.consul.io/) domain server located at "10.150.0.1", +and all Consul names have the suffix ".consul.local". To configure it in CoreDNS, +the cluster administrator creates the following stanza in the CoreDNS ConfigMap. + +``` +consul.local:53 { + errors + cache 30 + forward . 10.150.0.1 +} +``` + +To explicitly force all non-cluster DNS lookups to go through a specific nameserver at 172.16.0.1, +point the `forward` to the nameserver instead of `/etc/resolv.conf` + +``` +forward . 172.16.0.1 +``` + +The final ConfigMap along with the default `Corefile` configuration looks like: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: coredns + namespace: kube-system +data: + Corefile: | + .:53 { + errors + health + kubernetes cluster.local in-addr.arpa ip6.arpa { + pods insecure + fallthrough in-addr.arpa ip6.arpa + } + prometheus :9153 + forward . 172.16.0.1 + cache 30 + loop + reload + loadbalance + } + consul.local:53 { + errors + cache 30 + forward . 10.150.0.1 + } +``` + +{{< note >}} +CoreDNS does not support FQDNs for stub-domains and nameservers (eg: "ns.foo.com"). +During translation, all FQDN nameservers will be omitted from the CoreDNS config. +{{< /note >}} + +## {{% heading "whatsnext" %}} + +- Read [Debugging DNS Resolution](/docs/tasks/administer-cluster/dns-debugging-resolution/) + From a17b10da26c59e9b77d2a49b093d33cb63b0e0f7 Mon Sep 17 00:00:00 2001 From: "donatohorn@gmail.com" Date: Thu, 15 Dec 2022 08:22:18 -0300 Subject: [PATCH 025/279] [pt-br] Add content/pt-br/docs/tasks/configure-pod-container/configure-runasusername.md --- .../configure-runasusername.md | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/content/pt-br/docs/tasks/configure-pod-container/configure-runasusername.md b/content/pt-br/docs/tasks/configure-pod-container/configure-runasusername.md index 76f5b5e30e3..ca8d0e1a9c3 100644 --- a/content/pt-br/docs/tasks/configure-pod-container/configure-runasusername.md +++ b/content/pt-br/docs/tasks/configure-pod-container/configure-runasusername.md @@ -1,5 +1,5 @@ --- -title: Configurando `RunAsUserName` Para Pods e Contêineres Windows +title: Configurando RunAsUserName Para Pods e Contêineres Windows content_type: task weight: 20 --- @@ -17,7 +17,7 @@ executar aplicativos em um contêiner com um nome de usuário diferente do padr Você precisa ter um cluster Kubernetes, e a ferramenta de linha de comando Kubectl deve ser configurada para se comunicar com o seu cluster. Espera-se que o cluster -tenha nós `worker Windows`, onde os Pods com contêineres executando as cargas de trabalho do Windows, +tenha nós de carga de trabalho Windows, onde os Pods com contêineres executando as cargas de trabalho do Windows, serão agendados. @@ -25,14 +25,14 @@ serão agendados. ## Defina o nome de usuário para um Pod Para especificar o nome de usuário com o qual executar os processos de contêiner do Pod, -inclua o campo `securityContext` ([SecurityContext](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#securitycontext-v1-core)) +inclua o campo `securityContext` ([PodSecurityContext](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#securitycontext-v1-core)) na especificação do Pod, e dentro dela, o campo `WindowsOptions` ([WindowsSecurityContextOptions](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#windowssecuritycontextoptions-v1-core)) contendo o campo `runAsUserName`. As opções de contexto de segurança do Windows que você especificar para um Pod, se aplicam a todos os contêineres do Pod, inclusive os de inicialização. -Aqui está um arquivo de configuração para um Pod do Windows que possui o campo +Veja abaixo um arquivo de configuração para um Pod do Windows que possui o campo `runAsUserName` definido: {{< codenew file="windows/run-as-username-pod.yaml" >}} @@ -43,7 +43,7 @@ Crie o Pod: kubectl apply -f https://k8s.io/examples/windows/run-as-username-pod.yaml ``` -Verifique se o contêiner do pod está em execução: +Verifique se o contêiner do Pod está em execução: ```shell kubectl get pod run-as-username-pod-demo @@ -70,10 +70,9 @@ ContainerUser ## Defina o nome de usuário para o contêiner Para especificar o nome de usuário com o qual executar os processos de um contêiner, -inclua o campo `SecurityContext` ([SecurityContext] -(/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#securitycontext-v1-core)) +inclua o campo `SecurityContext` ([SecurityContext](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#securitycontext-v1-core)) no manifesto do contêiner, e dentro dele, o campo `WindowsOptions` -([WindowsSecurityContextOptions] (/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#windowssecuritycontextoptions-v1-core)) +([WindowsSecurityContextOptions](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#windowssecuritycontextoptions-v1-core)) contendo o campo `runAsUserName`. As opções de contexto de segurança do Windows que você especificar para um contêiner, @@ -120,15 +119,15 @@ ContainerAdministrator Para usar esse recurso, o valor definido no campo `runAsUserName` deve ser um nome de usuário válido. Deve ter o seguinte formato: `DOMAIN\USER`, onde ` DOMAIN\` é opcional. Os nomes de usuário do Windows não diferenciam letras maiúsculas -e minúsculas. Além disso, existem algumas restrições em relação ao `DOMÍNIO` e `USUÁRIO`: +e minúsculas. Além disso, existem algumas restrições em relação ao `DOMAIN` e `USER`: - O campo `runAsUserName`: não pode estar vazio, e não pode conter caracteres de controle (Valores ASCII : `0x00-0x1F`, `0x7F`) -- O nome de `DOMÍNIO` NetBios, ou um nome de DNS: cada um com suas próprias restrições: +- O nome de `DOMAIN` NetBios, ou um nome de DNS, cada um com suas próprias restrições: - Nomes NetBios: máximo de 15 caracteres, não podem iniciar com `.` (ponto), e não podem conter os seguintes caracteres: `\ / : * ? " < > |` - Nomes DNS: máximo de 255 caracteres, contendo apenas caracteres alfanuméricos, pontos, e traços, e não podem iniciar ou terminar com um `.` (ponto) ou `-` (traço). -- O `USUÁRIO`: deve ter no máximo 20 caracteres, não pode conter *somente* pontos ou espaços, +- O `USER`: deve ter no máximo 20 caracteres, não pode conter *somente* pontos ou espaços, e não pode conter os seguintes caracteres: `" / \ [ ] : ; | = , + * ? < > @`. Exemplos de valores aceitáveis para o campo `runAsUserName`: `ContainerAdministrator`, From 92355c438e0f677e1343677594e58b144793fbd0 Mon Sep 17 00:00:00 2001 From: Ana Carolina Rodrigues Date: Sun, 18 Dec 2022 08:56:54 -0300 Subject: [PATCH 026/279] Add content/pt-br/docs/tasks/debug/debug-application/degub-init-containers.md --- .../debug-init-containers.md | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 content/pt-br/docs/tasks/debug/debug-application/debug-init-containers.md diff --git a/content/pt-br/docs/tasks/debug/debug-application/debug-init-containers.md b/content/pt-br/docs/tasks/debug/debug-application/debug-init-containers.md new file mode 100644 index 00000000000..65f023741f1 --- /dev/null +++ b/content/pt-br/docs/tasks/debug/debug-application/debug-init-containers.md @@ -0,0 +1,124 @@ +--- +reviewers: +- bprashanth +- enisoc +- erictune +- foxish +- janetkuo +- kow3ns +- smarterclayton +title: Debug Init Containers +content_type: task +weight: 40 +--- + + + +Esta página mostra como investigar problemas relacionados à execução de +inicialização de Contêineres. As linhas de comando de exemplo abaixo +referem-se ao pod como `` e a inicialização de contêineres como `` e +``. + +## {{% heading "prerequisites" %}} + + +{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} + +* Você deve estar familiarizado com os fundamentos da + [inicialização de Contêineres](/docs/concepts/workloads/pods/init-containers/). +* Você deve ter [Configurado uma Inicialização de Contêiner](/docs/tasks/configure-pod-container/configure-pod-initialization/#creating-a-pod-that-has-an-init-container/). + + + +## Verificando o status das inicializações de contêineres + +Exiba o status do seu pod: + +```shell +kubectl get pod +``` + +Por exemplo, um status de `Init:1/2` indica que uma das duas inicializações de contêineres +concluíram com sucesso: + +``` +NAME READY STATUS RESTARTS AGE + 0/1 Init:1/2 0 7s +``` + +Consulte [Entendendo sobre o status do pod](#understanding-pod-status) para obter mais exemplos de +valores de status e seus significados. + +## Obtendo detalhes sobre a Inicialização de Contêineres + +Veja informações mais detalhadas sobre a execução da Inicialização de Contêineres: + +```shell +kubectl describe pod +``` + +Por exemplo, um pod com duas inicializações de contêineres pode mostrar o seguinte: + +``` +Init Containers: + : + Container ID: ... + ... + State: Terminated + Reason: Completed + Exit Code: 0 + Started: ... + Finished: ... + Ready: True + Restart Count: 0 + ... + : + Container ID: ... + ... + State: Waiting + Reason: CrashLoopBackOff + Last State: Terminated + Reason: Error + Exit Code: 1 + Started: ... + Finished: ... + Ready: False + Restart Count: 3 + ... +``` + +Você também pode acessar programaticamente os status das inicializações de contêineres, +lendo o campo `status.initContainerStatuses` nas especificações do pod: + +```shell +kubectl get pod nginx --template '{{.status.initContainerStatuses}}' +``` + +Este comando retornará as mesmas informações acima em JSON bruto. + +## Acessando logs de inicialização de contêineres + +Passe o nome da inicialização de contêineres junto com o nome do Pod +para acessar seus logs. + +```shell +kubectl logs -c +``` + +Inicializações de contêineres que executam uma impressão de comandos de script de shell +à medida que são executados. Por exemplo, você pode fazer isso no Bash executando `set -x` no início do script. + + + +## Entendendo sobre o status do pod + +Um status do Pod começando com `Init:` resume o status da execução da inicialização de contêineres. +A tabela abaixo descreve alguns valores de status de exemplo que você pode ver durante a depuração de Init Containers. + +Status | Significado +------ | ------- +`Init:N/M` | O pod tem inicializações de contêineres `M` e `N` que foram concluídas até agora. +`Init:Error` | Uma inicialização de contêiner falhou ao executar. +`Init:CrashLoopBackOff` | Uma inicialização de contêiner falhou repetidamente. +`Pending` | O pod ainda não começou a executar a inicialização de contêineres. +`PodInitializing` ou `Running` | O pod já concluiu a execução das inicializações de contêineres. \ No newline at end of file From 8cb04691a3025d61c5e630a5636ec2e97d170f4a Mon Sep 17 00:00:00 2001 From: EuricoAbreu Date: Tue, 20 Dec 2022 02:38:52 -0300 Subject: [PATCH 027/279] [pt-br] Add /docs/concepts/security/windows-security.md --- .../concepts/security/windows-security.md | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 content/pt-br/docs/concepts/security/windows-security.md diff --git a/content/pt-br/docs/concepts/security/windows-security.md b/content/pt-br/docs/concepts/security/windows-security.md new file mode 100644 index 00000000000..4d6573afb29 --- /dev/null +++ b/content/pt-br/docs/concepts/security/windows-security.md @@ -0,0 +1,56 @@ +--- +reviewers: + - +title: Segurança para Nós Windows +content_type: concept +weight: 40 +--- + + + +Esta página descreve considerações de segurança e boas práticas específicas para o sistema operacional Windows. + + + +## Proteção para dados Secret nos Nós + +No Windows, os dados do Secret são escritos em texto claro no Nó local do +armazenamento (em comparação ao uso de tmpfs / in-memory filesystems no Linux). Como um cluster +operador, você deve tomar as duas medidas adicionais a seguir: + +1. Use arquivos ACLs para assegurar a localização do arquivo Secrets. +2. Aplicar criptografia à nível de volume usando + [BitLocker](https://docs.microsoft.com/windows/security/information-protection/bitlocker/bitlocker-how-to-deploy-on-windows-server). + +## Usuários dos Contêineres + +[RunAsUsername](/docs/tasks/configure-pod-container/configure-runasusername) +pode ser especificado para Pods com Windows ou contêiner para executar os processos do contêiner como usuário específico. Isto é aproximadamente equivalente a +[RunAsUser](/docs/concepts/security/pod-security-policy/#users-and-groups). + +Os contêineres Windows oferecem duas contas de usuário padrão, ContainerUser e ContainerAdministrator. As diferenças entre estas duas contas de usuário são cobertas em +[When to use ContainerAdmin and ContainerUser user accounts](https://docs.microsoft.com/virtualization/windowscontainers/manage-containers/container-security#when-to-use-containeradmin-and-containeruser-user-accounts) +dentro da documentação da Microsoft _Secure Windows containers_. + +Os usuários locais podem ser adicionados as imagens do contêiner durante o processo de construção do mesmo. + +{{< note >}} + +- Imagens baseadas no [Nano Server](https://hub.docker.com/_/microsoft-windows-nanoserver) rodam como + `ContainerUser` por padrão. +- Imagens baseadas no [Server Core](https://hub.docker.com/_/microsoft-windows-servercore) rodam como + `ContainerAdministrator` por padrão. + +{{< /note >}} + +Contêineres Windows também podem rodar como identidades do Active Directory usando +[Group Managed Service Accounts](/docs/tasks/configure-pod-container/configure-gmsa/) + +## Isolamento de segurança a nível do Pod + +Mecanismos de contexto de segurança de Pod específicos para Linux (como SELinux, AppArmor, Seccomp, ou capabilities customizados para POSIX) não são suportados nos nós do Windows. + +Contêineres privilegiados [não são suportados](/docs/concepts/windows/intro/#compatibility-v1-pod-spec-containers-securitycontext) +no Windows. +Em vez disso, [HostProcess containers](/docs/tasks/configure-pod-container/create-hostprocess-pod) +podem ser usados no Windows para realizar muitas das tarefas realizadas por contêineres privilegiados no Linux. From 820c2462c2a123263cb966fa0225c04bcd5a2439 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulo=20Gon=C3=A7alves=20Lima?= Date: Tue, 20 Dec 2022 14:34:12 -0300 Subject: [PATCH 028/279] [pt-br] Translating page: Customizing DNS Service Done: + CoreDNS ConfigMap options + Configuration of Stub-domain and upstream nameserver using CoreDNS + Example --- .../dns-custom-nameservers.md | 93 ++++++++----------- 1 file changed, 41 insertions(+), 52 deletions(-) diff --git a/content/pt-br/docs/tasks/administer-cluster/dns-custom-nameservers.md b/content/pt-br/docs/tasks/administer-cluster/dns-custom-nameservers.md index 6e95c8bdaf0..f2c72efedf4 100644 --- a/content/pt-br/docs/tasks/administer-cluster/dns-custom-nameservers.md +++ b/content/pt-br/docs/tasks/administer-cluster/dns-custom-nameservers.md @@ -2,7 +2,7 @@ reviewers: - bowei - zihongz -title: Customizing DNS Service +title: Personalizando o Serviço DNS content_type: task min-kubernetes-server-version: v1.12 --- @@ -50,13 +50,13 @@ cumprindo com as [especificações DNS](https://github.com/kubernetes/dns/blob/m ### CoreDNS ConfigMap options -CoreDNS is a DNS server that is modular and pluggable, with plugins adding new functionalities. -The CoreDNS server can be configured by maintaining a [Corefile](https://coredns.io/2017/07/23/corefile-explained/), -which is the CoreDNS configuration file. As a cluster administrator, you can modify the -{{< glossary_tooltip text="ConfigMap" term_id="configmap" >}} for the CoreDNS Corefile to -change how DNS service discovery behaves for that cluster. +CoreDNS é um servidor DNS que é modular e plugável, com plugins que adicionam novas funcionalidades. +O servidor CoreDNS pode ser configurado por um [Corefile](https://coredns.io/2017/07/23/corefile-explained/), +que é o arquivo de configuração do CoreDNS. Como administrador de cluster, você pode modificar o +{{< glossary_tooltip text="ConfigMap" term_id="configmap" >}} para o arquivo Corefile do CoreDNS para +mudar como o descobrimento de serviços DNS se comporta para esse cluster. -In Kubernetes, CoreDNS is installed with the following default Corefile configuration: +Em Kubernetes, o CoreDNS é instalado com a seguinte configuração padrão do Corefile: ```yaml apiVersion: v1 @@ -86,51 +86,42 @@ data: } ``` -The Corefile configuration includes the following [plugins](https://coredns.io/plugins/) of CoreDNS: +A configuração do Corefile inclui os seguintes [plugins](https://coredns.io/plugins/) do CoreDNS: -* [errors](https://coredns.io/plugins/errors/): Errors are logged to stdout. -* [health](https://coredns.io/plugins/health/): Health of CoreDNS is reported to - `http://localhost:8080/health`. In this extended syntax `lameduck` will make theuprocess - unhealthy then wait for 5 seconds before the process is shut down. -* [ready](https://coredns.io/plugins/ready/): An HTTP endpoint on port 8181 will return 200 OK, - when all plugins that are able to signal readiness have done so. -* [kubernetes](https://coredns.io/plugins/kubernetes/): CoreDNS will reply to DNS queries - based on IP of the Services and Pods. You can find [more details](https://coredns.io/plugins/kubernetes/) - about this plugin on the CoreDNS website. - - `ttl` allows you to set a custom TTL for responses. The default is 5 seconds. - The minimum TTL allowed is 0 seconds, and the maximum is capped at 3600 seconds. - Setting TTL to 0 will prevent records from being cached. - - The `pods insecure` option is provided for backward compatibility with `kube-dns`. - - You can use the `pods verified` option, which returns an A record only if there exists a pod - in the same namespace with a matching IP. - - The `pods disabled` option can be used if you don't use pod records. -* [prometheus](https://coredns.io/plugins/metrics/): Metrics of CoreDNS are available at - `http://localhost:9153/metrics` in the [Prometheus](https://prometheus.io/) format - (also known as OpenMetrics). -* [forward](https://coredns.io/plugins/forward/): Any queries that are not within the Kubernetes - cluster domain are forwarded to predefined resolvers (/etc/resolv.conf). -* [cache](https://coredns.io/plugins/cache/): This enables a frontend cache. -* [loop](https://coredns.io/plugins/loop/): Detects simple forwarding loops and - halts the CoreDNS process if a loop is found. -* [reload](https://coredns.io/plugins/reload): Allows automatic reload of a changed Corefile. - After you edit the ConfigMap configuration, allow two minutes for your changes to take effect. -* [loadbalance](https://coredns.io/plugins/loadbalance): This is a round-robin DNS loadbalancer - that randomizes the order of A, AAAA, and MX records in the answer. +* [errors](https://coredns.io/plugins/errors/): Erros são registrados para stdout. +* [health](https://coredns.io/plugins/health/): A saúde do CoreDNS é reportada para +`http://localhost:8080/health`. Nesta sintaxe estendida, `lameduck` fará o processo +insalubre, esperando por 5 segundos antes que o processo seja encerrado. +* [ready](https://coredns.io/plugins/ready/): Um endpoint HTTP na porta 8181 retornará 200 OK, quando todos os plugins que são capazes de sinalizar prontidão tiverem feito isso. +* [kubernetes](https://coredns.io/plugins/kubernetes/): O CoreDNS responderá a consultas DNS + baseado no IP dos Serviços e Pods. Você pode encontrar [mais detalhes em](https://coredns.io/plugins/kubernetes/). + sobre este plugin no site do CoreDNS. + * `ttl` permite que você defina um TTL personalizado para as respostas. O padrão é 5 segundos. O TTL mínimo permitido é de 0 segundos e o máximo é de 3600 segundos. Definir o TTL como 0 impedirá que os registros sejam armazenados em cache. + * A opção `pods insecure` é fornecida para retrocompatibilidade com o `kube-dns`. + * Você pode usar a opção `pods verified`, que retorna um registro A somente se houver um pod no mesmo namespace com um IP correspondente. + * A opção `pods disabled` pode ser usada se você não usar registros de pod. +* [prometheus](https://coredns.io/plugins/metrics/): As métricas do CoreDNS estão disponíveis em `http://localhost:9153/metrics` no formato [Prometheus](https://prometheus.io/) + (também conhecido como OpenMetrics). +* [forward](https://coredns.io/plugins/forward/): Qualquer consulta que não esteja no domínio do cluster do Kubernetes é encaminhada para resolutores predefinidos (/etc/resolv.conf). +* [cache](https://coredns.io/plugins/cache/): Habilita um cache de frontend. +* [loop](https://coredns.io/plugins/loop/): Detecta loops de encaminhamento simples e interrompe o processo do CoreDNS se um loop for encontrado. +* [reload](https://coredns.io/plugins/reload): Permite a recarga automática de um Corefile que foi alterado. + Depois de editar a configuração do ConfigMap, é necessario dois minutos para que as alterações entrem em vigor. +* [loadbalance](https://coredns.io/plugins/loadbalance): Este é um balanceador de carga DNS round-robin que randomiza a ordem dos registros A, AAAA e MX na resposta. -You can modify the default CoreDNS behavior by modifying the ConfigMap. +Você pode modificar o comportamento padrão do CoreDNS modificando o ConfigMap. -### Configuration of Stub-domain and upstream nameserver using CoreDNS +### Configuração de domínio Stub e upstream nameserver usando o CoreDNS -CoreDNS has the ability to configure stub-domains and upstream nameservers -using the [forward plugin](https://coredns.io/plugins/forward/). +O CoreDNS tem a capacidade de configurar domínios Stub e upstream nameservers usando o plugin [forward](https://coredns.io/plugins/forward/). -#### Example +#### Exemplo -If a cluster operator has a [Consul](https://www.consul.io/) domain server located at "10.150.0.1", -and all Consul names have the suffix ".consul.local". To configure it in CoreDNS, -the cluster administrator creates the following stanza in the CoreDNS ConfigMap. +Se um operador de cluster possui um servidor de domínio [Consul](https://www.consul.io/) localizado em "10.150.0.1" +e todos os nomes Consul possuem o sufixo ".consul.local". Para configurá-lo no CoreDNS, +o administrador do cluster cria a seguinte stanza no ConfigMap do CoreDNS. -``` +```config consul.local:53 { errors cache 30 @@ -138,14 +129,13 @@ consul.local:53 { } ``` -To explicitly force all non-cluster DNS lookups to go through a specific nameserver at 172.16.0.1, -point the `forward` to the nameserver instead of `/etc/resolv.conf` +Para forçar explicitamente que todas as pesquisas de DNS fora do cluster passem por um nameserver específico em 172.16.0.1, aponte o `forward` para o nameserver em vez de `/etc/resolv.conf`. -``` +```config forward . 172.16.0.1 ``` -The final ConfigMap along with the default `Corefile` configuration looks like: +O ConfigMap final, juntamente com a configuração padrão do `Corefile`, é: ```yaml apiVersion: v1 @@ -177,11 +167,10 @@ data: ``` {{< note >}} -CoreDNS does not support FQDNs for stub-domains and nameservers (eg: "ns.foo.com"). -During translation, all FQDN nameservers will be omitted from the CoreDNS config. +O CoreDNS não suporta FQDNs para domínios Stub e nameservers (por exemplo, "ns.foo.com"). Durante a tradução, todos os nameservers FQDN serão omitidos da configuração do CoreDNS. {{< /note >}} ## {{% heading "whatsnext" %}} -- Read [Debugging DNS Resolution](/docs/tasks/administer-cluster/dns-debugging-resolution/) +- Leia [Depurando a resolução DNS](/docs/tasks/administer-cluster/dns-debugging-resolution/) From 668c3fd39c4c412feec4d1134a9dec88188cdded Mon Sep 17 00:00:00 2001 From: "Mr. Erlison" Date: Sat, 24 Dec 2022 19:27:40 -0300 Subject: [PATCH 029/279] Add /pt-br/docs/reference/setup-tools/kubeadm/kubeadm-upgrade --- .../generated/kubeadm_upgrade_apply.md | 151 ++++++++++++++++++ .../kubeadm/generated/kubeadm_upgrade_diff.md | 100 ++++++++++++ .../kubeadm/generated/kubeadm_upgrade_node.md | 115 +++++++++++++ .../kubeadm/generated/kubeadm_upgrade_plan.md | 125 +++++++++++++++ .../setup-tools/kubeadm/kubeadm-upgrade.md | 41 +++++ 5 files changed, 532 insertions(+) create mode 100644 content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_apply.md create mode 100644 content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_diff.md create mode 100644 content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_node.md create mode 100644 content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_plan.md create mode 100644 content/pt-br/docs/reference/setup-tools/kubeadm/kubeadm-upgrade.md diff --git a/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_apply.md b/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_apply.md new file mode 100644 index 00000000000..6cb9bbe87aa --- /dev/null +++ b/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_apply.md @@ -0,0 +1,151 @@ + + +Atualiza o cluster Kubernetes para uma versão específica + +### Sinopse + +Atualiza o cluster Kubernetes para uma versão específica + +``` +kubeadm upgrade apply [versão] +``` + +### Opções + + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
--allow-experimental-upgrades

Exibe as versões instáveis do Kubernetes como uma alternativa de atualização e permite a atualização para versões candidatas alfa/beta/release do Kubernetes.

--allow-release-candidate-upgrades

Exibe as versões candidatas a lançamento do Kubernetes como uma alternativa de atualização e permite a atualização para versões candidatas a lançamento do Kubernetes.

--certificate-renewal     Padrão: true

Executa a renovação dos certificados usados pelo componente alterado durante as atualizações.

--config string

Caminho para um arquivo de configuração do kubeadm.

--dry-run

Não aplica as modificações; apenas exibe as alterações que seriam efetuadas.

--etcd-upgrade     Padrão: true

Atualiza o etcd.

--feature-gates string

Um conjunto de pares chave=valor que descreve feature gates para várias funcionalidades. As opções são:
+PublicKeysECDSA=true|false (ALPHA - padrão=false)
RootlessControlPlane=true|false (ALPHA - padrão=false)
UnversionedKubeletConfigMap=true|false (padrão=true) +

-f, --force

Força a atualização, embora alguns requisitos possam não ser atendidos. Isso também implica o modo não interativo.

-h, --help

ajuda para apply

--ignore-preflight-errors strings

Uma lista de verificações para as quais erros serão exibidos como avisos. Exemplos: 'IsPrivilegedUser,Swap'. O valor 'all' ignora erros de todas as verificações.

--kubeconfig string     Padrão: "/etc/kubernetes/admin.conf"

O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.

--patches string

Caminho para um diretório que contém os arquivos chamados "target[suffix][+patchtype].extension". Por exemplo, "kube-apiserver0+merge.yaml" ou apenas "etcd.json". "target" pode ser um dos "kube-apiserver", "kube-controller-manager", "kube-scheduler", "etcd", "kubeletconfiguration". "patchtype" pode ser um dos "strategic", "merge" ou "json" e eles correspondem aos formatos de patch suportados pelo kubectl. O padrão "patchtype" é "strategic". "extension" deve ser "json" ou "yaml". "suffix" é uma string opcional que pode ser usada para determinar quais patches alpha-numerically serão aplicados primeiro.

--print-config

Especifica se o arquivo de configuração que será usado na atualização deve ser exibido ou não.

-y, --yes

Executa a atualização e não solicita um prompt de confirmação (modo não interativo).

+ +### Opções herdadas de comandos superiores + + ++++ + + + + + + + + + + +
--rootfs string

[EXPERIMENTAL] O caminho para o sistema de arquivos raiz 'real' do host.

diff --git a/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_diff.md b/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_diff.md new file mode 100644 index 00000000000..475d78766bb --- /dev/null +++ b/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_diff.md @@ -0,0 +1,100 @@ + + +Mostra quais diferenças serão aplicadas aos manifestos dos Pods estáticos existentes. Veja também: kubeadm upgrade apply --dry-run + +### Sinopse + +Mostra quais diferenças serão aplicadas aos manifestos dos Pods estáticos existentes. Veja também: kubeadm upgrade apply --dry-run + +``` +kubeadm upgrade diff [versão] [flags] +``` + +### Opções + + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
--api-server-manifest string     Padrão: "/etc/kubernetes/manifests/kube-apiserver.yaml"

Caminho para o manifesto do servidor API

--config string

Caminho para um arquivo de configuração do kubeadm.

-c, --context-lines int     Padrão: 3

Quantidade de linhas de contexto do diff

--controller-manager-manifest string     Padrão: "/etc/kubernetes/manifests/kube-controller-manager.yaml"

Caminho para o manifesto do gerenciador

-h, --help

Ajuda para o diff

--kubeconfig string     Padrão: "/etc/kubernetes/admin.conf"

O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.

--scheduler-manifest string     Padrão: "/etc/kubernetes/manifests/kube-scheduler.yaml"

Caminho para o manifesto do scheduler

+ +### Opções herdadas de comandos superiores + + ++++ + + + + + + + + + + +
--rootfs string

[EXPERIMENTAL] O caminho para o sistema de arquivos raiz 'real' do host.

diff --git a/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_node.md b/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_node.md new file mode 100644 index 00000000000..03846f98b6c --- /dev/null +++ b/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_node.md @@ -0,0 +1,115 @@ + + +Comando para atualização de um nó no cluster + +### Sinopse + +Comando para atualização de um nó no cluster + +O comando "node" executa as seguintes fases: + +``` +preflight Executa as verificações de atualização pre-flight do nó +control-plane Atualiza a instância da camada de gerenciamento implantada neste nó, se houver +kubelet-config Atualiza a configuração do kubelet para este nó +``` + +``` +kubeadm upgrade node [flags] +``` + +### Opções + + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
--certificate-renewal     Padrão: true

Executa a renovação dos certificados usados pelo componente alterado durante as atualizações.

--dry-run

Não aplica as modificações; apenas exibe as alterações que seriam efetuadas.

--etcd-upgrade     Padrão: true

Atualiza o etcd.

-h, --help

ajuda para node

--ignore-preflight-errors strings

Uma lista de verificações para as quais erros serão exibidos como avisos. Exemplos: 'IsPrivilegedUser,Swap'. O valor 'all' ignora erros de todas as verificações.

--kubeconfig string     Padrão: "/etc/kubernetes/admin.conf"

O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.

--patches string

Caminho para um diretório que contém os arquivos chamados "target[suffix][+patchtype].extension". Por exemplo, "kube-apiserver0+merge.yaml" ou apenas "etcd.json". "target" pode ser um dos "kube-apiserver", "kube-controller-manager", "kube-scheduler", "etcd", "kubeletconfiguration". "patchtype" pode ser um dos "strategic", "merge" ou "json" e eles correspondem aos formatos de patch suportados pelo kubectl. O padrão "patchtype" é "strategic". "extension" deve ser "json" ou "yaml". "suffix" é uma string opcional que pode ser usada para determinar quais patches alpha-numerically serão aplicados primeiro.

--skip-phases strings

Exibe as fases a serem ignoradas

+ +### Opções herdadas de comandos superiores + + ++++ + + + + + + + + + + +
--rootfs string

[EXPERIMENTAL] O caminho para o sistema de arquivos raiz 'real' do host.

diff --git a/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_plan.md b/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_plan.md new file mode 100644 index 00000000000..5f97c80c797 --- /dev/null +++ b/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_plan.md @@ -0,0 +1,125 @@ + + +Verifique quais versões estão disponíveis para atualizar e verifique se o seu cluster atual é atualizável. +Para pular a verificação da Internet, passe o parâmetro opcional [versão] + +### Sinopse + +Verifique quais versões estão disponíveis para atualizar e verifique se o seu cluster atual é atualizável. +Para pular a verificação da Internet, passe o parâmetro opcional [versão] + +``` +kubeadm upgrade plan [versão] [flags] +``` + +### Opções + + ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
--allow-experimental-upgrades

Exibe as versões instáveis do Kubernetes como uma alternativa de atualização e permite a atualização para versões candidatas alfa/beta/release do Kubernetes.

--allow-release-candidate-upgrades

Exibe as versões candidatas a lançamento do Kubernetes como uma alternativa de atualização e permite a atualização para versões candidatas a lançamento do Kubernetes.

--config string

Caminho para um arquivo de configuração kubeadm.

--feature-gates string

Um conjunto de pares chave=valor que descreve feature gates para várias funcionalidades. As opções são:
+PublicKeysECDSA=true|false (ALPHA - padrão=false)
RootlessControlPlane=true|false (ALPHA - padrão=false)
UnversionedKubeletConfigMap=true|false (padrão=true) +

-h, --help

ajuda para plan

--ignore-preflight-errors strings

Uma lista de verificações para as quais erros serão exibidos como avisos. Exemplos: 'IsPrivilegedUser,Swap'. O valor 'all' ignora erros de todas as verificações.

--kubeconfig string     Padrão: "/etc/kubernetes/admin.conf"

O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.

-o, --output string     Padrão: "text"

EXPERIMENTAL: Formato de saída. Um dos: text|json|yaml.

--print-config

Especifica se o arquivo de configuração que será usado na atualização deve ser exibido ou não.

--show-managed-fields

Se verdadeiro, mentém os managedFields ao exibir os objetos no formato JSON ou YAML.

+ +### Opções herdadas de comandos superiores + + ++++ + + + + + + + + + + +
--rootfs string

[EXPERIMENTAL] O caminho para o sistema de arquivos raiz 'real' do host.

diff --git a/content/pt-br/docs/reference/setup-tools/kubeadm/kubeadm-upgrade.md b/content/pt-br/docs/reference/setup-tools/kubeadm/kubeadm-upgrade.md new file mode 100644 index 00000000000..b1073fcb2b0 --- /dev/null +++ b/content/pt-br/docs/reference/setup-tools/kubeadm/kubeadm-upgrade.md @@ -0,0 +1,41 @@ +--- +title: kubeadm upgrade +content_type: conceito +weight: 40 +--- + +`kubeadm upgrade` é um comando de fácil uso que envolve uma lógica de atualização complexa por trás de um comando, com suporte para planejar e executar de fato uma atualização. + + + +## Guia do kubeadm upgrade + +As etapas para realizar uma atualização usando kubeadm estão descritas [neste documento](/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/). +Para versões mais antigas do kubeadm, consulte os conjuntos de documentação mais antigos do site Kubernetes. + +Você pode usar o `kubeadm upgrade diff` para ver as alterações que seriam aplicadas aos manifestos de Pod estático. + +No Kubernetes v1.15.0 e posteriores, o `kubeadm upgrade apply` e `kubeadm upgrade node` também renovarão automaticamente os certificados gerenciados pelo kubeadm neste nó, incluindo aqueles armazenados nos arquivos do kubeconfig. +É possível optar por não renovar usando a flag `--certificate-renewal=false`. +Para mais detalhes sobre a renovação dos certificados, consulte a [documentação de gerenciamento de certificados](/docs/tasks/administer-cluster/kubeadm/kubeadm-certs). + +{{< note >}} +Os comandos `kubeadm upgrade apply` e `kubeadm upgrade plan` tem uma flag legada `--config` que possibilita reconfigurar o cluster enquanto realiza o planejamento ou a atualização do nó específico da camada de gerenciamento. +Esteja ciente de que o fluxo de trabalho da atualização não foi projetado para este cenário e existe relatos de resultados inesperados. +{{}} + +## kubeadm upgrade plan {#cmd-upgrade-plan} +{{< include "generated/kubeadm_upgrade_plan.md" >}} + +## kubeadm upgrade apply {#cmd-upgrade-apply} +{{< include "generated/kubeadm_upgrade_apply.md" >}} + +## kubeadm upgrade diff {#cmd-upgrade-diff} +{{< include "generated/kubeadm_upgrade_diff.md" >}} + +## kubeadm upgrade node {#cmd-upgrade-node} +{{< include "generated/kubeadm_upgrade_node.md" >}} + +## {{% heading "whatsnext" %}} + +* [kubeadm config](/docs/reference/setup-tools/kubeadm/kubeadm-config/) se você inicializou seu cluster usando kubeadm v1.7.x ou inferior, para configurar seu cluster para `kubeadm upgrade` From b8883b84db2b9c34755e1f8c4d0dd76b5fdf84a7 Mon Sep 17 00:00:00 2001 From: Daniel Shebib Date: Wed, 28 Dec 2022 20:02:50 -0600 Subject: [PATCH 030/279] Update privileged pod documentation to reflect GA feature --- content/en/docs/concepts/workloads/pods/_index.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/content/en/docs/concepts/workloads/pods/_index.md b/content/en/docs/concepts/workloads/pods/_index.md index 76c966757a3..0f4fad4ded0 100644 --- a/content/en/docs/concepts/workloads/pods/_index.md +++ b/content/en/docs/concepts/workloads/pods/_index.md @@ -289,9 +289,18 @@ section. ## Privileged mode for containers -In Linux, any container in a Pod can enable privileged mode using the `privileged` (Linux) flag on the [security context](/docs/tasks/configure-pod-container/security-context/) of the container spec. This is useful for containers that want to use operating system administrative capabilities such as manipulating the network stack or accessing hardware devices. +{{< feature-state for_k8s_version="v1.26" state="stable" >}} -If your cluster has the `WindowsHostProcessContainers` feature enabled, you can create a [Windows HostProcess pod](/docs/tasks/configure-pod-container/create-hostprocess-pod) by setting the `windowsOptions.hostProcess` flag on the security context of the pod spec. All containers in these pods must run as Windows HostProcess containers. HostProcess pods run directly on the host and can also be used to perform administrative tasks as is done with Linux privileged containers. +In Linux, any container in a Pod can enable privileged mode using the `privileged` (Linux) flag +on the [security context](/docs/tasks/configure-pod-container/security-context/) of the +container spec. This is useful for containers that want to use operating system administrative +capabilities such as manipulating the network stack or accessing hardware devices. + +In Windows, you can create a [Windows HostProcess pod](/docs/tasks/configure-pod-container/create-hostprocess-pod) +by setting the `windowsOptions.hostProcess` flag on the security context of the pod spec. All containers in these +pods must run as Windows HostProcess containers. HostProcess pods run directly on the host and can also be used +to perform administrative tasks as is done with Linux privileged containers. In order to use this feature, the +`WindowsHostProcessContainers`[feature gate](/docs/reference/command-line-tools-reference/feature-gates/) must be enabled. {{< note >}} Your {{< glossary_tooltip text="container runtime" term_id="container-runtime" >}} must support the concept of a privileged container for this setting to be relevant. From 39f15d694d1edda18b1a3588f144f65e51c4db6b Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 6 Jan 2023 20:20:38 +0800 Subject: [PATCH 031/279] [zh] sync kubectl-node-debug.md --- .../debug/debug-cluster/kubectl-node-debug.md | 172 ++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 content/zh-cn/docs/tasks/debug/debug-cluster/kubectl-node-debug.md diff --git a/content/zh-cn/docs/tasks/debug/debug-cluster/kubectl-node-debug.md b/content/zh-cn/docs/tasks/debug/debug-cluster/kubectl-node-debug.md new file mode 100644 index 00000000000..e0a3638215b --- /dev/null +++ b/content/zh-cn/docs/tasks/debug/debug-cluster/kubectl-node-debug.md @@ -0,0 +1,172 @@ +--- +title: 用 Kubectl 调试 Kubernetes 节点 +content_type: task +min-kubernetes-server-version: 1.20 +--- + + + + + +本页演示如何使用 `kubectl debug` 命令调试在 Kubernetes +集群上运行的[节点](/zh-cn/docs/concepts/architecture/nodes/)。 + +## {{% heading "prerequisites" %}} + +{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} + + +你需要有权限创建 Pod 并将这些新 Pod 分配到任意节点。 +你还需要被授权创建能够访问主机上文件系统的 Pod。 + + + + +## 使用 `kubectl debug node` 调试节点 {#debugging-a-node-using-kubectl-debug-node} + +使用 `kubectl debug node` 命令将 Pod 部署到要排查故障的节点上。 +此命令在你无法使用 SSH 连接节点时比较有用。 +当 Pod 被创建时,Pod 会在节点上打开一个交互的 Shell。 +要在名为 “mynode” 的节点上创建一个交互式 Shell,运行: + +```shell +kubectl debug node/mynode -it --image=ubuntu +``` + +```console +Creating debugging pod node-debugger-mynode-pdx84 with container debugger on node mynode. +If you don't see a command prompt, try pressing enter. +root@mynode:/# +``` + + +调试命令有助于收集信息和排查问题。 +你可能使用的命令包括 `ip`、`ifconfig`、`nc`、`ping` 和 `ps` 等等。 +你还可以从各种包管理器安装 `mtr`、`tcpdump` 和 `curl` 等其他工具。 + +{{< note >}} + +这些调试命令会因调试 Pod 所使用的镜像不同而有些差别,并且这些命令可能需要被安装。 +{{< /note >}} + + +用于调试的 Pod 可以访问节点的根文件系统,该文件系统挂载在 Pod 中的 `/host` 路径。 +如果你在 filesystem 名字空间中运行 kubelet, +则正调试的 Pod 将看到此名字空间的根,而不是整个节点的根。 +对于典型的 Linux 节点,你可以查看以下路径找到一些重要的日志: + + +`/host/var/log/kubelet.log` +: 负责在节点上运行容器的 `kubelet` 所产生的日志。 + +`/host/var/log/kube-proxy.log` +: 负责将流量导向到 Service 端点的 `kube-proxy` 所产生的日志。 + +`/host/var/log/containerd.log` +: 在节点上运行的 `containerd` 进程所产生的日志。 + +`/host/var/log/syslog` +: 显示常规消息以及系统相关信息。 + +`/host/var/log/kern.log` +: 显示内核日志。 + + +当在节点上创建一个调试会话时,需谨记: + +* `kubectl debug` 根据节点的名称自动生成新 Pod 的名称。 +* 节点的根文件系统将被挂载在 `/host`。 +* 尽管容器运行在主机 IPC、Network 和 PID 名字空间中,但 Pod 没有特权。 + 这意味着读取某些进程信息可能会失败,这是因为访问这些信息仅限于超级用户 (superuser)。 + 例如,`chroot /host` 将失败。如果你需要一个有特权的 Pod,请手动创建。 + +## {{% heading "cleanup" %}} + + +当你使用正调试的 Pod 完成时,将其删除: + +```shell +kubectl get pods +``` + +```none +NAME READY STATUS RESTARTS AGE +node-debugger-mynode-pdx84 0/1 Completed 0 8m1s +``` + + +```shell +# 相应更改 Pod 名称 +kubectl delete pod node-debugger-mynode-pdx84 --now +``` + +```none +pod "node-debugger-mynode-pdx84" deleted +``` + +{{< note >}} + +如果节点停机(网络断开或 kubelet 宕机且无法启动等),则 `kubectl debug node` 命令将不起作用。 +这种情况下请检查[调试关闭/无法访问的节点](/zh-cn/docs/tasks/debug/debug-cluster/#example-debugging-a-down-unreachable-node)。 +{{< /note >}} From 3390e6bf7d01a9f71315937831d7ced2860cb387 Mon Sep 17 00:00:00 2001 From: YAMADA Kazuaki Date: Sun, 8 Jan 2023 22:14:39 +0900 Subject: [PATCH 032/279] brash up expressions of explanation of controllers --- content/ja/docs/concepts/overview/components.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/content/ja/docs/concepts/overview/components.md b/content/ja/docs/concepts/overview/components.md index a1bdb4d5b14..1b56478efa4 100644 --- a/content/ja/docs/concepts/overview/components.md +++ b/content/ja/docs/concepts/overview/components.md @@ -58,11 +58,11 @@ Kubernetesをオンプレミスあるいは個人のPC内での学習環境で kube-controller-managerと同様に、cloud-controller-managerは複数の論理的に独立したコントロールループをシングルバイナリにまとめ、一つのプロセスとして動作します。パフォーマンスを向上させるあるいは障害に耐えるために水平方向にスケールする(一つ以上のコピーを動かす)ことができます。 -次のコントローラーは、クラウドプロバイダーへの依存関係を持つことがあります。 +次の各コントローラは、それぞれ以下に示すような目的のためにクラウドプロバイダへの依存関係を持つことができるようになっています。 - * Nodeコントローラー:ノードが応答を停止した後、クラウドで削除されたかどうかを判断するため、クラウドプロバイダーをチェックします。 - * Routeコントローラー:基盤であるクラウドインフラでルーティングを設定します。 - * Serviceコントローラー:クラウドプロバイダーのロードバランサーの作成、更新、削除を行います。 + * Nodeコントローラ: ノードが応答を停止した後、クラウドで当該ノードが削除されたかどうかを判断するため + * Route コントローラ: 基盤となるクラウドインフラのルートを設定するため + * Service コントローラ: クラウドプロバイダーのロードバランサの作成、更新、削除を行うため ## ノードコンポーネント {#node-components} From fc351cf8ce7e69621cb8bb3e7fef116c44832393 Mon Sep 17 00:00:00 2001 From: carolina valencia Date: Wed, 11 Jan 2023 17:33:10 -0300 Subject: [PATCH 033/279] feat: [es] Add content/es/docs/concepts/security/pod-security-policy.md --- .../concepts/security/pod-security-policy.md | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 content/es/docs/concepts/security/pod-security-policy.md diff --git a/content/es/docs/concepts/security/pod-security-policy.md b/content/es/docs/concepts/security/pod-security-policy.md new file mode 100644 index 00000000000..c92008db060 --- /dev/null +++ b/content/es/docs/concepts/security/pod-security-policy.md @@ -0,0 +1,27 @@ +--- +title: Políticas de Seguridad del Pod +content_type: concept +weight: 30 +--- + + + +{{% alert title="Función eliminada" color="warning" %}} +PodSecurityPolicy está en [deprecación](/blog/2021/04/08/kubernetes-1-21-release-announcement/#podsecuritypolicy-deprecation) +en Kubernetes v1.21, y removida desde Kubernetes v1.25. +{{% /alert %}} + +En vez de usar PodSecurityPolicy, puedes aplicar restricciones similares en Pods usando +cualquiera o los dos: + +- [Admisión de seguridad de pod](/docs/concepts/security/pod-security-admission/) +- Un plugin de admisión de terceros, que implementa y configura usted mismo + +Para obtener una guía de migración, consulte +[Migrar de PodSecurityPolicy al Controlador de Admisión de Seguridad de Pod Integrado](/docs/tasks/configure-pod-container/migrate-from-psp/). +Para obtener más información sobre la eliminación de esta API, consulte +[Deprecación de PodSecurityPolicy: Pasado, Presente y Futuro](/blog/2021/04/06/podsecuritypolicy-deprecation-past-present-and-future/). + +Si no está ejecutando Kubernetes v{{< skew currentVersion >}}, consulte la documentación para +su versión de Kubernetes. + From 87537d3b5b1e92d6e5ce0c2b65abb8a0477222f6 Mon Sep 17 00:00:00 2001 From: Daniel Shebib Date: Thu, 12 Jan 2023 18:52:21 -0600 Subject: [PATCH 034/279] document privileged containers as GC --- content/en/docs/concepts/workloads/pods/_index.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/content/en/docs/concepts/workloads/pods/_index.md b/content/en/docs/concepts/workloads/pods/_index.md index 0f4fad4ded0..21f339cca5e 100644 --- a/content/en/docs/concepts/workloads/pods/_index.md +++ b/content/en/docs/concepts/workloads/pods/_index.md @@ -289,13 +289,20 @@ section. ## Privileged mode for containers -{{< feature-state for_k8s_version="v1.26" state="stable" >}} +Any container in a pod can run in privileged mode to use operating system administrative capabilities +that would otherwise be inaccessible. This is available for both Windows and Linux. + +### Linux containers In Linux, any container in a Pod can enable privileged mode using the `privileged` (Linux) flag on the [security context](/docs/tasks/configure-pod-container/security-context/) of the container spec. This is useful for containers that want to use operating system administrative capabilities such as manipulating the network stack or accessing hardware devices. +### Windows containers + +{{< feature-state for_k8s_version="v1.26" state="stable" >}} + In Windows, you can create a [Windows HostProcess pod](/docs/tasks/configure-pod-container/create-hostprocess-pod) by setting the `windowsOptions.hostProcess` flag on the security context of the pod spec. All containers in these pods must run as Windows HostProcess containers. HostProcess pods run directly on the host and can also be used From bc12666f6896b95ddabcad4ec0160fe3cd987bb8 Mon Sep 17 00:00:00 2001 From: Daniel Shebib Date: Thu, 12 Jan 2023 19:09:14 -0600 Subject: [PATCH 035/279] document privileged containers as GC --- content/en/docs/concepts/workloads/pods/_index.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/content/en/docs/concepts/workloads/pods/_index.md b/content/en/docs/concepts/workloads/pods/_index.md index 21f339cca5e..93818c3dcd1 100644 --- a/content/en/docs/concepts/workloads/pods/_index.md +++ b/content/en/docs/concepts/workloads/pods/_index.md @@ -289,7 +289,11 @@ section. ## Privileged mode for containers -Any container in a pod can run in privileged mode to use operating system administrative capabilities +{{< note >}} +Your {{< glossary_tooltip text="container runtime" term_id="container-runtime" >}} must support the concept of a privileged container for this setting to be relevant. +{{< /note >}} + +Any container in a pod can run in priveleged mode to use operating system administrative capabilities that would otherwise be inaccessible. This is available for both Windows and Linux. ### Linux containers @@ -309,9 +313,6 @@ pods must run as Windows HostProcess containers. HostProcess pods run directly o to perform administrative tasks as is done with Linux privileged containers. In order to use this feature, the `WindowsHostProcessContainers`[feature gate](/docs/reference/command-line-tools-reference/feature-gates/) must be enabled. -{{< note >}} -Your {{< glossary_tooltip text="container runtime" term_id="container-runtime" >}} must support the concept of a privileged container for this setting to be relevant. -{{< /note >}} ## Static Pods From ba37aa6ba7464a35a8f31697fdd91f46b7ca2225 Mon Sep 17 00:00:00 2001 From: Daniel Shebib Date: Thu, 12 Jan 2023 19:09:46 -0600 Subject: [PATCH 036/279] document privileged containers as GC --- content/en/docs/concepts/workloads/pods/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/docs/concepts/workloads/pods/_index.md b/content/en/docs/concepts/workloads/pods/_index.md index 93818c3dcd1..874e85523f8 100644 --- a/content/en/docs/concepts/workloads/pods/_index.md +++ b/content/en/docs/concepts/workloads/pods/_index.md @@ -293,7 +293,7 @@ section. Your {{< glossary_tooltip text="container runtime" term_id="container-runtime" >}} must support the concept of a privileged container for this setting to be relevant. {{< /note >}} -Any container in a pod can run in priveleged mode to use operating system administrative capabilities +Any container in a pod can run in privileged mode to use operating system administrative capabilities that would otherwise be inaccessible. This is available for both Windows and Linux. ### Linux containers From 6dfa72861850188bec7ec40b5a38d8ac27d88663 Mon Sep 17 00:00:00 2001 From: EuricoAbreu Date: Sat, 14 Jan 2023 19:33:14 -0300 Subject: [PATCH 037/279] Minor fixes --- .../concepts/security/windows-security.md | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/content/pt-br/docs/concepts/security/windows-security.md b/content/pt-br/docs/concepts/security/windows-security.md index 4d6573afb29..e29706ece70 100644 --- a/content/pt-br/docs/concepts/security/windows-security.md +++ b/content/pt-br/docs/concepts/security/windows-security.md @@ -1,6 +1,4 @@ --- -reviewers: - - title: Segurança para Nós Windows content_type: concept weight: 40 @@ -14,25 +12,24 @@ Esta página descreve considerações de segurança e boas práticas específica ## Proteção para dados Secret nos Nós -No Windows, os dados do Secret são escritos em texto claro no Nó local do -armazenamento (em comparação ao uso de tmpfs / in-memory filesystems no Linux). Como um cluster -operador, você deve tomar as duas medidas adicionais a seguir: +No Windows, os dados do Secret são escritos em texto não-encriptado no Nó local do +armazenamento (em comparação ao uso de tmpfs / sistemas de arquivo em memória no Linux). Como um operador do cluster, você deve tomar as duas medidas adicionais a seguir: -1. Use arquivos ACLs para assegurar a localização do arquivo Secrets. -2. Aplicar criptografia à nível de volume usando +1. Use ACLs em arquivos para proteger a localização do arquivo Secrets. +2. Aplicar criptografia a nível de volume usando [BitLocker](https://docs.microsoft.com/windows/security/information-protection/bitlocker/bitlocker-how-to-deploy-on-windows-server). ## Usuários dos Contêineres [RunAsUsername](/docs/tasks/configure-pod-container/configure-runasusername) -pode ser especificado para Pods com Windows ou contêiner para executar os processos do contêiner como usuário específico. Isto é aproximadamente equivalente a +pode ser utilizado para Pods com Windows ou contêiner para executar os processos do contêiner como usuário específico. Isto é aproximadamente equivalente a [RunAsUser](/docs/concepts/security/pod-security-policy/#users-and-groups). -Os contêineres Windows oferecem duas contas de usuário padrão, ContainerUser e ContainerAdministrator. As diferenças entre estas duas contas de usuário são cobertas em +Os contêineres Windows oferecem duas contas de usuário padrão, ContainerUser e ContainerAdministrator. As diferenças entre estas duas contas de usuário são descritas em [When to use ContainerAdmin and ContainerUser user accounts](https://docs.microsoft.com/virtualization/windowscontainers/manage-containers/container-security#when-to-use-containeradmin-and-containeruser-user-accounts) dentro da documentação da Microsoft _Secure Windows containers_. -Os usuários locais podem ser adicionados as imagens do contêiner durante o processo de construção do mesmo. +Os usuários locais podem ser adicionados às imagens do contêiner durante o processo de criação do mesmo. {{< note >}} @@ -52,5 +49,5 @@ Mecanismos de contexto de segurança de Pod específicos para Linux (como SELinu Contêineres privilegiados [não são suportados](/docs/concepts/windows/intro/#compatibility-v1-pod-spec-containers-securitycontext) no Windows. -Em vez disso, [HostProcess containers](/docs/tasks/configure-pod-container/create-hostprocess-pod) +Em vez disso, [contêineres HostProcess](/docs/tasks/configure-pod-container/create-hostprocess-pod) podem ser usados no Windows para realizar muitas das tarefas realizadas por contêineres privilegiados no Linux. From e609b6e10e9d546d812ba543087017177dba0112 Mon Sep 17 00:00:00 2001 From: windsonsea Date: Fri, 13 Jan 2023 16:49:09 +0800 Subject: [PATCH 038/279] [zh] sync blog: 2023-01-05-retroactive-default-storage-class --- ...01-05-retroactive-default-storage-class.md | 293 ++++++++++++++++++ 1 file changed, 293 insertions(+) create mode 100644 content/zh-cn/blog/_posts/2023-01-05-retroactive-default-storage-class.md diff --git a/content/zh-cn/blog/_posts/2023-01-05-retroactive-default-storage-class.md b/content/zh-cn/blog/_posts/2023-01-05-retroactive-default-storage-class.md new file mode 100644 index 00000000000..9162281c74b --- /dev/null +++ b/content/zh-cn/blog/_posts/2023-01-05-retroactive-default-storage-class.md @@ -0,0 +1,293 @@ +--- +layout: blog +title: "Kubernetes 1.26:可追溯的默认 StorageClass" +date: 2023-01-05 +slug: retroactive-default-storage-class +--- + + + +**作者:** Roman Bednář (Red Hat) + +**译者:** Michael Yao (DaoCloud) + + +Kubernetes v1.25 引入了一个 Alpha 特性来更改默认 StorageClass 被分配到 PersistentVolumeClaim (PVC) 的方式。 +启用此特性后,你不再需要先创建默认 StorageClass,再创建 PVC 来分配类。 +此外,任何未分配 StorageClass 的 PVC 都可以在后续被更新。此特性在 Kubernetes 1.26 中已进阶至 Beta。 + + +有关如何使用的更多细节,请参阅 Kubernetes +文档[可追溯的默认 StorageClass 赋值](/zh-cn/docs/concepts/storage/persistent-volumes/#retroactive-default-storageclass-assignment), +你还可以阅读了解为什么 Kubernetes 项目做了此项变更。 + + +## 为什么 StorageClass 赋值需要改进 {#why-did-sc-assignment-need-improvements} + +用户可能已经熟悉在创建时将默认 StorageClasses 分配给**新** PVC 的这一类似特性。 +这个目前由[准入控制器](/zh-cn/docs/reference/access-authn-authz/admission-controllers/#defaultstorageclass)处理。 + + +但是,如果在创建 PVC 时没有定义默认 StorageClass 会怎样? +那用户最终将得到一个永远不会被赋予存储类的 PVC。结果是没有存储会被制备,而 PVC 有时也会“卡在”这里。 +一般而言,两个主要场景可能导致 PVC “卡住”,并在后续造成更多问题。让我们仔细看看这两个场景。 + + +### 更改默认 StorageClass {#changing-default-storageclass} + +启用这个 Alpha 特性后,管理员想要更改默认 StorageClass 时会有两个选项: + + +1. 在移除与 PVC 关联的旧 StorageClass 之前,创建一个新的 StorageClass 作为默认值。 + 这将导致在短时间内出现两个默认值。此时,如果用户要创建一个 PersistentVolumeClaim, + 并将 storageClassName 设置为 null(指代默认 StorageClass), + 则最新的默认 StorageClass 将被选中并指定给这个 PVC。 + + +2. 先移除旧的默认值再创建一个新的默认 StorageClass。这将导致短时间内没有默认值。 + 接下来如果用户创建一个 PersistentVolumeClaim,并将 storageClassName 设置为 null + (指代默认 StorageClass),则 PVC 将永远处于 Pending 状态。 + 一旦默认 StorageClass 可用,用户就不得不通过删除并重新创建 PVC 来修复这个问题。 + + +### 集群安装期间的资源顺序 {#resource-ordering-during-cluster-installation} + +如果集群安装工具需要创建镜像仓库这种有存储要求的资源,很难进行合适地排序。 +这是因为任何有存储要求的 Pod 都将依赖于默认 StorageClass 的存在与否。 +如果默认 StorageClass 未被定义,Pod 创建将失败。 + + +## 发生了什么变化 {#what-changed} + +我们更改了 PersistentVolume (PV) 控制器,以便将默认 StorageClass 指定给 +storageClassName 设置为 `null` 且未被绑定的所有 PersistentVolumeClaim。 +我们还修改了 API 服务器中的 PersistentVolumeClaim 准入机制,允许将取值从未设置值更改为实际的 StorageClass 名称。 + + +### Null `storageClassName` 与 `storageClassName: ""` - 有什么影响? {#null-vs-empty-string} + +此特性被引入之前,这两种赋值就其行为而言是相同的。storageClassName 设置为 `null` 或 `""` +的所有 PersistentVolumeClaim 都会被绑定到 storageClassName 也设置为 `null` 或 +`""` 的、已有的 PersistentVolume 资源。 + + +启用此新特性时,我们希望保持此行为,但也希望能够更新 StorageClass 名称。 +考虑到这些限制,此特性更改了 `null` 的语义。 +具体而言,如果有一个默认 StorageClass,`null` 将可被理解为 “给我一个默认值”, +而 `""` 表示 “给我 StorageClass 名称也是 `""` 的 PersistentVolume”, +所以行为将保持不变。 + + +综上所述,我们更改了 `null` 的语义,使其行为取决于默认 StorageClass 定义的存在或缺失。 + +下表显示了所有这些情况,更好地描述了 PVC 何时绑定及其 StorageClass 何时被更新。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
使用默认 StorageClass 时的 PVC 绑定行为
PVC storageClassName = ""PVC storageClassName = null
未设置默认存储类PV storageClassName = ""bindsbinds
PV without storageClassNamebindsbinds
设置了默认存储类PV storageClassName = ""binds存储类更新
PV without storageClassNamebinds存储类更新
+ + +## 如何使用 {#how-to-use-it} + +如果你想测试这个 Alpha 特性,你需要在 kube-controller-manager 和 kube-apiserver 中启用相关特性门控。 +你可以使用 `--feature-gates` 命令行参数: + +``` +--feature-gates="...,RetroactiveDefaultStorageClass=true" +``` + + +### 测试演练 {#test-drive} + +如果你想看到此特性发挥作用并验证它在集群中是否正常工作,你可以尝试以下步骤: + + +1. 定义一个基本的 PersistentVolumeClaim: + + ```yaml + apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: pvc-1 + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + ``` + + +2. 在没有默认 StorageClass 时创建 PersistentVolumeClaim。 + PVC 不会制备或绑定(除非当前已存在一个合适的 PV),PVC 将保持在 `Pending` 状态。 + + ``` + $ kc get pvc + NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE + pvc-1 Pending + ``` + + +3. 将某个 StorageClass 配置为默认值。 + + ``` + $ kc patch sc -p '{"metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}' + storageclass.storage.k8s.io/my-storageclass patched + ``` + + +4. 确认 PersistentVolumeClaims 现在已被正确制备,并且已使用新的默认 StorageClass 进行了可追溯的更新。 + + ``` + $ kc get pvc + NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE + pvc-1 Bound pvc-06a964ca-f997-4780-8627-b5c3bf5a87d8 1Gi RWO my-storageclass 87m + ``` + + +### 新指标 {#new-metrics} + +为了帮助你了解该特性是否按预期工作,我们还引入了一个新的 `retroactive_storageclass_total` +指标来显示 PV 控制器尝试更新 PersistentVolumeClaim 的次数,以及 +`retroactive_storageclass_errors_total` 来显示这些尝试失败了多少次。 + + +## 欢迎参与 {#getting-involved} + +我们始终欢迎新的贡献者,如果你想参与其中,欢迎加入 +[Kubernetes Storage Special Interest Group(存储特别兴趣小组)](https://github.com/kubernetes/community/tree/master/sig-storage) (SIG)。 + +如果你想分享反馈,可以在我们的[公开 Slack 频道](https://app.slack.com/client/T09NY5SBT/C09QZFCE5)上反馈。 + +特别感谢所有提供精彩评论、分享宝贵见解并帮助实现此特性的贡献者们(按字母顺序排列): + +- Deep Debroy ([ddebroy](https://github.com/ddebroy)) +- Divya Mohan ([divya-mohan0209](https://github.com/divya-mohan0209)) +- Jan Šafránek ([jsafrane](https://github.com/jsafrane/)) +- Joe Betz ([jpbetz](https://github.com/jpbetz)) +- Jordan Liggitt ([liggitt](https://github.com/liggitt)) +- Michelle Au ([msau42](https://github.com/msau42)) +- Seokho Son ([seokho-son](https://github.com/seokho-son)) +- Shannon Kularathna ([shannonxtreme](https://github.com/shannonxtreme)) +- Tim Bannister ([sftim](https://github.com/sftim)) +- Tim Hockin ([thockin](https://github.com/thockin)) +- Wojciech Tyczynski ([wojtek-t](https://github.com/wojtek-t)) +- Xing Yang ([xing-yang](https://github.com/xing-yang)) From 9d5fdac34bd11f8984cb80d6558d35c2c6397351 Mon Sep 17 00:00:00 2001 From: "Mr. Erlison" Date: Sun, 15 Jan 2023 05:52:31 -0300 Subject: [PATCH 039/279] Changes from code review. --- .../kubeadm/generated/kubeadm_upgrade_apply.md | 11 ++++++++--- .../kubeadm/generated/kubeadm_upgrade_diff.md | 8 ++++---- .../kubeadm/generated/kubeadm_upgrade_node.md | 11 ++++++++--- .../kubeadm/generated/kubeadm_upgrade_plan.md | 6 +++--- .../reference/setup-tools/kubeadm/kubeadm-upgrade.md | 6 +++--- 5 files changed, 26 insertions(+), 16 deletions(-) diff --git a/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_apply.md b/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_apply.md index 6cb9bbe87aa..d9de39d4eb5 100644 --- a/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_apply.md +++ b/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_apply.md @@ -32,7 +32,7 @@ kubeadm upgrade apply [versão] --allow-experimental-upgrades -

Exibe as versões instáveis do Kubernetes como uma alternativa de atualização e permite a atualização para versões candidatas alfa/beta/release do Kubernetes.

+

Exibe as versões instáveis do Kubernetes como uma alternativa de atualização e permite a atualização para versões alfa/beta/*release candidate* do Kubernetes.

@@ -83,7 +83,7 @@ PublicKeysECDSA=true|false (ALPHA - padrão=false)
RootlessControlPlane=true -f, --force -

Força a atualização, embora alguns requisitos possam não ser atendidos. Isso também implica o modo não interativo.

+

Força a atualização, embora alguns requisitos possam não estar sendo atendidos. Isso também implica o modo não interativo.

@@ -111,7 +111,12 @@ PublicKeysECDSA=true|false (ALPHA - padrão=false)
RootlessControlPlane=true --patches string -

Caminho para um diretório que contém os arquivos chamados "target[suffix][+patchtype].extension". Por exemplo, "kube-apiserver0+merge.yaml" ou apenas "etcd.json". "target" pode ser um dos "kube-apiserver", "kube-controller-manager", "kube-scheduler", "etcd", "kubeletconfiguration". "patchtype" pode ser um dos "strategic", "merge" ou "json" e eles correspondem aos formatos de patch suportados pelo kubectl. O padrão "patchtype" é "strategic". "extension" deve ser "json" ou "yaml". "suffix" é uma string opcional que pode ser usada para determinar quais patches alpha-numerically serão aplicados primeiro.

+

+Caminho para um diretório contendo arquivos nomeados no padrão "target[suffix][+patchtype].extension". Por exemplo, "kube-apiserver0+merge.yaml" ou somente "etcd.json". +"target" pode ser um dos seguintes valores: "kube-apiserver", "kube-controller-manager", "kube-scheduler", "etcd". +"patchtype" pode ser "strategic", "merge" ou "json" e corresponde aos formatos de patch suportados pelo kubectl. O valor padrão para "patchtype" é "strategic". +"extension" deve ser "json" ou "yaml". "suffix" é uma string opcional utilizada para determinar quais patches são aplicados primeiro em ordem alfanumérica. +

diff --git a/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_diff.md b/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_diff.md index 475d78766bb..e533129e13b 100644 --- a/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_diff.md +++ b/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_diff.md @@ -32,7 +32,7 @@ kubeadm upgrade diff [versão] [flags] --api-server-manifest string     Padrão: "/etc/kubernetes/manifests/kube-apiserver.yaml" -

Caminho para o manifesto do servidor API

+

Caminho para o manifesto do servidor da API

@@ -53,14 +53,14 @@ kubeadm upgrade diff [versão] [flags] --controller-manager-manifest string     Padrão: "/etc/kubernetes/manifests/kube-controller-manager.yaml" -

Caminho para o manifesto do gerenciador

+

Caminho para o manifesto do controlador de gerenciadores

-h, --help -

Ajuda para o diff

+

Ajuda para diff

@@ -74,7 +74,7 @@ kubeadm upgrade diff [versão] [flags] --scheduler-manifest string     Padrão: "/etc/kubernetes/manifests/kube-scheduler.yaml" -

Caminho para o manifesto do scheduler

+

Caminho para o manifesto do escalonador

diff --git a/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_node.md b/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_node.md index 03846f98b6c..aec5a9b0a09 100644 --- a/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_node.md +++ b/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_node.md @@ -18,7 +18,7 @@ Comando para atualização de um nó no cluster O comando "node" executa as seguintes fases: ``` -preflight Executa as verificações de atualização pre-flight do nó +preflight Executa as verificações de pré-atualização do nó control-plane Atualiza a instância da camada de gerenciamento implantada neste nó, se houver kubelet-config Atualiza a configuração do kubelet para este nó ``` @@ -82,14 +82,19 @@ kubeadm upgrade node [flags] --patches string -

Caminho para um diretório que contém os arquivos chamados "target[suffix][+patchtype].extension". Por exemplo, "kube-apiserver0+merge.yaml" ou apenas "etcd.json". "target" pode ser um dos "kube-apiserver", "kube-controller-manager", "kube-scheduler", "etcd", "kubeletconfiguration". "patchtype" pode ser um dos "strategic", "merge" ou "json" e eles correspondem aos formatos de patch suportados pelo kubectl. O padrão "patchtype" é "strategic". "extension" deve ser "json" ou "yaml". "suffix" é uma string opcional que pode ser usada para determinar quais patches alpha-numerically serão aplicados primeiro.

+

+Caminho para um diretório contendo arquivos nomeados no padrão "target[suffix][+patchtype].extension". Por exemplo, "kube-apiserver0+merge.yaml" ou somente "etcd.json". +"target" pode ser um dos seguintes valores: "kube-apiserver", "kube-controller-manager", "kube-scheduler", "etcd". +"patchtype" pode ser "strategic", "merge" ou "json" e corresponde aos formatos de patch suportados pelo kubectl. O valor padrão para "patchtype" é "strategic". +"extension" deve ser "json" ou "yaml". "suffix" é uma string opcional utilizada para determinar quais patches são aplicados primeiro em ordem alfanumérica. +

--skip-phases strings -

Exibe as fases a serem ignoradas

+

Lista de fases a serem ignoradas

diff --git a/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_plan.md b/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_plan.md index 5f97c80c797..57159cb4217 100644 --- a/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_plan.md +++ b/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_plan.md @@ -34,7 +34,7 @@ kubeadm upgrade plan [versão] [flags] --allow-experimental-upgrades -

Exibe as versões instáveis do Kubernetes como uma alternativa de atualização e permite a atualização para versões candidatas alfa/beta/release do Kubernetes.

+

Exibe as versões instáveis do Kubernetes como uma alternativa de atualização e permite a atualização para versões alfa/beta/*release candidate* do Kubernetes.

@@ -85,7 +85,7 @@ PublicKeysECDSA=true|false (ALPHA - padrão=false)
RootlessControlPlane=true -o, --output string     Padrão: "text" -

EXPERIMENTAL: Formato de saída. Um dos: text|json|yaml.

+

EXPERIMENTAL: Formato de saída. Opções válidas: text|json|yaml.

@@ -99,7 +99,7 @@ PublicKeysECDSA=true|false (ALPHA - padrão=false)
RootlessControlPlane=true --show-managed-fields -

Se verdadeiro, mentém os managedFields ao exibir os objetos no formato JSON ou YAML.

+

Se verdadeiro, mantém os managedFields ao exibir os objetos no formato JSON ou YAML.

diff --git a/content/pt-br/docs/reference/setup-tools/kubeadm/kubeadm-upgrade.md b/content/pt-br/docs/reference/setup-tools/kubeadm/kubeadm-upgrade.md index b1073fcb2b0..fc255dc5d6f 100644 --- a/content/pt-br/docs/reference/setup-tools/kubeadm/kubeadm-upgrade.md +++ b/content/pt-br/docs/reference/setup-tools/kubeadm/kubeadm-upgrade.md @@ -4,7 +4,7 @@ content_type: conceito weight: 40 --- -`kubeadm upgrade` é um comando de fácil uso que envolve uma lógica de atualização complexa por trás de um comando, com suporte para planejar e executar de fato uma atualização. +`kubeadm upgrade` é um comando amigável que envolve uma lógica de atualização complexa por trás de um comando, com suporte para planejar e executar de fato uma atualização. @@ -13,7 +13,7 @@ weight: 40 As etapas para realizar uma atualização usando kubeadm estão descritas [neste documento](/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/). Para versões mais antigas do kubeadm, consulte os conjuntos de documentação mais antigos do site Kubernetes. -Você pode usar o `kubeadm upgrade diff` para ver as alterações que seriam aplicadas aos manifestos de Pod estático. +Você pode usar `kubeadm upgrade diff` para ver as alterações que seriam aplicadas aos manifestos de Pod estático. No Kubernetes v1.15.0 e posteriores, o `kubeadm upgrade apply` e `kubeadm upgrade node` também renovarão automaticamente os certificados gerenciados pelo kubeadm neste nó, incluindo aqueles armazenados nos arquivos do kubeconfig. É possível optar por não renovar usando a flag `--certificate-renewal=false`. @@ -21,7 +21,7 @@ Para mais detalhes sobre a renovação dos certificados, consulte a [documentaç {{< note >}} Os comandos `kubeadm upgrade apply` e `kubeadm upgrade plan` tem uma flag legada `--config` que possibilita reconfigurar o cluster enquanto realiza o planejamento ou a atualização do nó específico da camada de gerenciamento. -Esteja ciente de que o fluxo de trabalho da atualização não foi projetado para este cenário e existe relatos de resultados inesperados. +Esteja ciente de que o fluxo de trabalho da atualização não foi projetado para este cenário e existem relatos de resultados inesperados. {{}} ## kubeadm upgrade plan {#cmd-upgrade-plan} From 52cb7250db2a2b9b0cfa3b0dd68bfa1d2d2793a3 Mon Sep 17 00:00:00 2001 From: "Mr. Erlison" Date: Sun, 15 Jan 2023 06:08:48 -0300 Subject: [PATCH 040/279] fix term release candidate --- .../setup-tools/kubeadm/generated/kubeadm_upgrade_apply.md | 2 +- .../setup-tools/kubeadm/generated/kubeadm_upgrade_plan.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_apply.md b/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_apply.md index d9de39d4eb5..606846387cb 100644 --- a/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_apply.md +++ b/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_apply.md @@ -32,7 +32,7 @@ kubeadm upgrade apply [versão] --allow-experimental-upgrades -

Exibe as versões instáveis do Kubernetes como uma alternativa de atualização e permite a atualização para versões alfa/beta/*release candidate* do Kubernetes.

+

Exibe as versões instáveis do Kubernetes como uma alternativa de atualização e permite a atualização para versões alfa/beta/release candidate do Kubernetes.

diff --git a/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_plan.md b/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_plan.md index 57159cb4217..b7e77702db7 100644 --- a/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_plan.md +++ b/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_plan.md @@ -34,7 +34,7 @@ kubeadm upgrade plan [versão] [flags] --allow-experimental-upgrades -

Exibe as versões instáveis do Kubernetes como uma alternativa de atualização e permite a atualização para versões alfa/beta/*release candidate* do Kubernetes.

+

Exibe as versões instáveis do Kubernetes como uma alternativa de atualização e permite a atualização para versões alfa/beta/release candidate do Kubernetes.

From 2d08c71c18f924df52053b5d3f2affd09ea3ac03 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 16 Jan 2023 12:54:41 +0800 Subject: [PATCH 041/279] [zh] sync blog: 2023-01-02-cross-namespace-data-sources-alpha.md --- ...1-02-cross-namespace-data-sources-alpha.md | 260 ++++++++++++++++++ 1 file changed, 260 insertions(+) create mode 100644 content/zh-cn/blog/_posts/2023-01-02-cross-namespace-data-sources-alpha.md diff --git a/content/zh-cn/blog/_posts/2023-01-02-cross-namespace-data-sources-alpha.md b/content/zh-cn/blog/_posts/2023-01-02-cross-namespace-data-sources-alpha.md new file mode 100644 index 00000000000..5053e5b5f63 --- /dev/null +++ b/content/zh-cn/blog/_posts/2023-01-02-cross-namespace-data-sources-alpha.md @@ -0,0 +1,260 @@ +--- +layout: blog +title: "Kubernetes v1.26:对跨名字空间存储数据源的 Alpha 支持" +date: 2023-01-02 +slug: cross-namespace-data-sources-alpha +--- + + + +**作者:** Takafumi Takahashi (Hitachi Vantara) + +**译者:** Michael Yao (DaoCloud) + + +上个月发布的 Kubernetes v1.26 引入了一个 Alpha 特性,允许你在源数据属于不同的名字空间时为 +PersistentVolumeClaim 指定数据源。启用这个新特性后,你在新 PersistentVolumeClaim 的 +`dataSourceRef` 字段中指定名字空间。一旦 Kubernetes 发现访问权限正常,新的 PersistentVolume +就可以从其他名字空间中指定的存储源填充其数据。在 Kubernetes v1.26 之前,如果集群已启用了 +`AnyVolumeDataSource` 特性,你可能已经从**相同的**名字空间中的数据源制备新卷。 +但这仅适用于同一名字空间中的数据源,因此用户无法基于一个名字空间中的数据源使用另一个名字空间中的声明来制备 +PersistentVolume。为了解决这个问题,Kubernetes v1.26 在 PersistentVolumeClaim API 的 +`dataSourceRef` 字段中添加了一个新的 Alpha `namespace` 字段。 + + +## 工作原理 {#how-it-works} + +一旦 csi-provisioner 发现数据源是使用具有非空名字空间名称的 `dataSourceRef` 指定的, +它就会检查由 PersistentVolumeClaim 的 `.spec.dataSourceRef.namespace` +字段指定的名字空间内所授予的所有引用,以便确定可以访问数据源。 +如果有 ReferenceGrant 允许访问,则 csi-provisioner 会基于数据源来制备卷。 + + +## 试用 {#trying-it-out} + +使用跨名字空间卷制备时以下事项是必需的: + +* 为 kube-apiserver 和 kube-controller-manager 启用 `AnyVolumeDataSource` 和 + `CrossNamespaceVolumeDataSource` [特性门控](/zh-cn/docs/reference/command-line-tools-reference/feature-gates/) +* 为特定的 `VolumeSnapShot` 控制器安装 CRD +* 安装 CSI Provisioner 控制器并启用 `CrossNamespaceVolumeDataSource` 特性门控 +* 安装 CSI 驱动程序 +* 为 ReferenceGrants 安装 CRD + + +## 完整演练 {#putting-it-all-together} + +要查看其工作方式,你可以安装样例并进行试用。 +此样例使用 prod 名字空间中的 VolumeSnapshot 在 dev 名字空间中创建 PVC。 +这是一个简单的例子。想要在真实世界中使用,你可能要用更复杂的方法。 + + +### 这个例子的假设 {#example-assumptions} + +* 部署你的 Kubernetes 集群时启用 `AnyVolumeDataSource` 和 `CrossNamespaceVolumeDataSource` 特性门控 +* 有两个名字空间:dev 和 prod +* CSI 驱动程序被部署 +* 在 **prod** 名字空间中存在一个名为 `new-snapshot-demo` 的 VolumeSnapshot +* ReferenceGrant CRD(源于 Gateway API 项目)已被部署 + + +### 为 CSI Provisioner 授予 ReferenceGrants 读取权限 {#grant-referencegrants-read-permission-to-csi-provisioner} + +仅当 CSI 驱动程序具有 `CrossNamespaceVolumeDataSource` 控制器功能时才需要访问 ReferenceGrants。 +对于此示例,外部制备器对于 `referencegrants`(API 组 `gateway.networking.k8s.io`)需要 +**get**、**list** 和 **watch** 权限。 + +```yaml + - apiGroups: ["gateway.networking.k8s.io"] + resources: ["referencegrants"] + verbs: ["get", "list", "watch"] +``` + + +### 为 CSI Provisioner 启用 CrossNamespaceVolumeDataSource 特性门控 {#enable-cnvds-feature-for-csi-provisioner} + +将 `--feature-gates=CrossNamespaceVolumeDataSource=true` 添加到 csi-provisioner 命令行。 +例如,使用此清单片段重新定义容器: + +```yaml + - args: + - -v=5 + - --csi-address=/csi/csi.sock + - --feature-gates=Topology=true + - --feature-gates=CrossNamespaceVolumeDataSource=true + image: csi-provisioner:latest + imagePullPolicy: IfNotPresent + name: csi-provisioner +``` + + +### 创建 ReferenceGrant {#create-a-referencegrant} + +以下是 ReferenceGrant 示例的清单。 + +```yaml +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: ReferenceGrant +metadata: + name: allow-prod-pvc + namespace: prod +spec: + from: + - group: "" + kind: PersistentVolumeClaim + namespace: dev + to: + - group: snapshot.storage.k8s.io + kind: VolumeSnapshot + name: new-snapshot-demo +``` + + +### 通过使用跨名字空间数据源创建 PersistentVolumeClaim {#create-a-pvc-by-using-cross-ns-data-source} + +Kubernetes 在 dev 上创建 PersistentVolumeClaim,CSI 驱动程序从 prod 上的快照填充在 +dev 上使用的 PersistentVolume。 + +```yaml +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: example-pvc + namespace: dev +spec: + storageClassName: example + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + dataSourceRef: + apiGroup: snapshot.storage.k8s.io + kind: VolumeSnapshot + name: new-snapshot-demo + namespace: prod + volumeMode: Filesystem +``` + + +## 怎样了解更多 {#how-can-i-learn-more} + +增强提案 +[Provision volumes from cross-namespace snapshots](https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/3294-provision-volumes-from-cross-namespace-snapshots) +包含了此特性的历史和技术实现的大量细节。 + +若想参与,请加入 +[Kubernetes 存储特别兴趣小组 (SIG)](https://github.com/kubernetes/community/tree/master/sig-storage) +帮助我们增强此特性。SIG 内有许多好点子,我们很高兴能有更多! + + +## 致谢 {#acknowledgments} + +制作出色的软件需要优秀的团队。 +特别感谢以下人员对 CrossNamespaceVolumeDataSouce 特性的深刻见解、周密考量和宝贵贡献: + +* Michelle Au (msau42) +* Xing Yang (xing-yang) +* Masaki Kimura (mkimuram) +* Tim Hockin (thockin) +* Ben Swartzlander (bswartz) +* Rob Scott (robscott) +* John Griffith (j-griffith) +* Michael Henriksen (mhenriks) +* Mustafa Elbehery (Elbehery) + + +很高兴与大家一起工作。 From 34af4da90aa0b9a66b01973d2155847ed1034f39 Mon Sep 17 00:00:00 2001 From: Bishal Das <70086051+bishal7679@users.noreply.github.com> Date: Tue, 17 Jan 2023 10:52:56 +0530 Subject: [PATCH 042/279] Update content/hi/docs/reference/glossary/cronjob.md Co-authored-by: divya-mohan0209 --- content/hi/docs/reference/glossary/cronjob.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/hi/docs/reference/glossary/cronjob.md b/content/hi/docs/reference/glossary/cronjob.md index 93ad931bbb8..ec04b996b15 100644 --- a/content/hi/docs/reference/glossary/cronjob.md +++ b/content/hi/docs/reference/glossary/cronjob.md @@ -16,4 +16,4 @@ tags: -एक _crontab_ फ़ाइल में एक पंक्ति के समान, एक क्रॉन्जॉब (CronJob) ऑब्जेक्ट [क्रॉन](https://en.wikipedia.org/wiki/Cron) प्रारूप का उपयोग करके एक शेड्यूल निर्दिष्ट करता है। +एक _crontab_ फ़ाइल में एक पंक्ति के समान, एक क्रॉन्जॉब (CronJob) ऑब्जेक्ट [क्रॉन](https://en.wikipedia.org/wiki/Cron) प्रारूप का उपयोग करके एक अनुसूची निर्दिष्ट करता है। From e2f0a8a112140f4f21738deba0f8d2df092ad7a8 Mon Sep 17 00:00:00 2001 From: Yuiko Mouri Date: Thu, 12 Jan 2023 08:42:09 +0900 Subject: [PATCH 043/279] [ja]Add note to ResourceQuota docs --- content/ja/docs/concepts/policy/resource-quotas.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/content/ja/docs/concepts/policy/resource-quotas.md b/content/ja/docs/concepts/policy/resource-quotas.md index 552b5184414..86fe7194ae4 100644 --- a/content/ja/docs/concepts/policy/resource-quotas.md +++ b/content/ja/docs/concepts/policy/resource-quotas.md @@ -25,6 +25,11 @@ weight: 10 - リソースの作成や更新がクォータの制約に違反しているとき、そのリクエストはHTTPステータスコード`403 FORBIDDEN`で失敗し、違反した制約を説明するメッセージが表示されます。 - `cpu`や`memory`といったコンピューターリソースに対するクォータが名前空間内で有効になっているとき、ユーザーはそれらの値に対する`requests`や`limits`を設定する必要があります。設定しないとクォータシステムがPodの作成を拒否します。 ヒント: コンピュートリソースの要求を設定しないPodに対してデフォルト値を強制するために、`LimitRanger`アドミッションコントローラーを使用してください。この問題を解決する例は[walkthrough](/docs/tasks/administer-cluster/manage-resources/quota-memory-cpu-namespace/)で参照できます。 +{{< note >}} +- `cpu`および`memory`リソースに関しては、ResourceQuotaはlimitを設定している名前空間内の**全ての**(新しい)Podに対して当該リソースのlimitの設定を強制します。名前空間内の`cpu`または`memory`どちらかに対してリソースクォータを適用する場合、ユーザーやクライアントは全ての新しいPodごとに、そのリソースの`requests`あるいは`limits`を指定**しなければなりません**。そうでない場合、コントロールプレーンがそのPodの作成を拒否する可能性があります。 +- その他のリソースに関して: ResourceQuotaはリソースのlimitまたはrequestを設定していないPodでも機能します。これは、名前空間内のリソースクォータにおいてエフェメラルストレージのlimitを設定している場合、エフェメラルストレージのlimit/requestsを設定していないPodでも新規作成できることを意味します。[LimitRange](/ja/docs/concepts/policy/limit-range/)を使うことで、リソースに対して自動的にデフォルト要求を設定することができます。 +{{< /note >}} + ResourceQuotaのオブジェクト名は、有効な[DNSサブドメイン名](/ja/docs/concepts/overview/working-with-objects/names#dns-subdomain-names)である必要があります. 名前空間とクォータを使用して作成できるポリシーの例は以下の通りです。 @@ -42,7 +47,7 @@ ResourceQuotaのオブジェクト名は、有効な[DNSサブドメイン名](/ 特定の名前空間にResourceQuotaがあるとき、そのリソースクォータはその名前空間に適用されます。 -## リソースクォータの計算 +## コンピュートリソースクォータ 特定の名前空間において、[コンピュートリソース](/ja/docs/concepts/configuration/manage-resources-containers/)の合計に上限を設定できます。 From 2d4569ebca1b43a73678093184b3e8d3e8971d9a Mon Sep 17 00:00:00 2001 From: "Mr. Erlison" Date: Sun, 22 Jan 2023 11:04:25 -0300 Subject: [PATCH 044/279] Changes from code review. --- .../setup-tools/kubeadm/generated/kubeadm_upgrade_apply.md | 7 ++----- .../setup-tools/kubeadm/generated/kubeadm_upgrade_node.md | 5 +---- .../setup-tools/kubeadm/generated/kubeadm_upgrade_plan.md | 2 +- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_apply.md b/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_apply.md index 606846387cb..81b1601e98a 100644 --- a/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_apply.md +++ b/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_apply.md @@ -75,7 +75,7 @@ kubeadm upgrade apply [versão]

Um conjunto de pares chave=valor que descreve feature gates para várias funcionalidades. As opções são:
-PublicKeysECDSA=true|false (ALPHA - padrão=false)
RootlessControlPlane=true|false (ALPHA - padrão=false)
UnversionedKubeletConfigMap=true|false (padrão=true) +PublicKeysECDSA=true|false (ALPHA - padrão=false)
RootlessControlPlane=true|false (ALPHA - padrão=false)

@@ -112,10 +112,7 @@ PublicKeysECDSA=true|false (ALPHA - padrão=false)
RootlessControlPlane=true

-Caminho para um diretório contendo arquivos nomeados no padrão "target[suffix][+patchtype].extension". Por exemplo, "kube-apiserver0+merge.yaml" ou somente "etcd.json". -"target" pode ser um dos seguintes valores: "kube-apiserver", "kube-controller-manager", "kube-scheduler", "etcd". -"patchtype" pode ser "strategic", "merge" ou "json" e corresponde aos formatos de patch suportados pelo kubectl. O valor padrão para "patchtype" é "strategic". -"extension" deve ser "json" ou "yaml". "suffix" é uma string opcional utilizada para determinar quais patches são aplicados primeiro em ordem alfanumérica. +Caminho para um diretório contendo arquivos nomeados no padrão "target[suffix][+patchtype].extension". Por exemplo, "kube-apiserver0+merge.yaml" ou somente "etcd.json". "target" pode ser um dos seguintes valores: "kube-apiserver", "kube-controller-manager", "kube-scheduler", "etcd", "kubeletconfiguration". "patchtype" pode ser "strategic", "merge" ou "json" e corresponde aos formatos de patch suportados pelo kubectl. O valor padrão para "patchtype" é "strategic". "extension" deve ser "json" ou "yaml". "suffix" é uma string opcional utilizada para determinar quais patches são aplicados primeiro em ordem alfanumérica.

diff --git a/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_node.md b/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_node.md index aec5a9b0a09..c38fa732c8f 100644 --- a/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_node.md +++ b/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_node.md @@ -83,10 +83,7 @@ kubeadm upgrade node [flags]

-Caminho para um diretório contendo arquivos nomeados no padrão "target[suffix][+patchtype].extension". Por exemplo, "kube-apiserver0+merge.yaml" ou somente "etcd.json". -"target" pode ser um dos seguintes valores: "kube-apiserver", "kube-controller-manager", "kube-scheduler", "etcd". -"patchtype" pode ser "strategic", "merge" ou "json" e corresponde aos formatos de patch suportados pelo kubectl. O valor padrão para "patchtype" é "strategic". -"extension" deve ser "json" ou "yaml". "suffix" é uma string opcional utilizada para determinar quais patches são aplicados primeiro em ordem alfanumérica. +Caminho para um diretório contendo arquivos nomeados no padrão "target[suffix][+patchtype].extension". Por exemplo, "kube-apiserver0+merge.yaml" ou somente "etcd.json". "target" pode ser um dos seguintes valores: "kube-apiserver", "kube-controller-manager", "kube-scheduler", "etcd", "kubeletconfiguration". "patchtype" pode ser "strategic", "merge" ou "json" e corresponde aos formatos de patch suportados pelo kubectl. O valor padrão para "patchtype" é "strategic". "extension" deve ser "json" ou "yaml". "suffix" é uma string opcional utilizada para determinar quais patches são aplicados primeiro em ordem alfanumérica.

diff --git a/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_plan.md b/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_plan.md index b7e77702db7..68e84df686c 100644 --- a/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_plan.md +++ b/content/pt-br/docs/reference/setup-tools/kubeadm/generated/kubeadm_upgrade_plan.md @@ -56,7 +56,7 @@ kubeadm upgrade plan [versão] [flags]

Um conjunto de pares chave=valor que descreve feature gates para várias funcionalidades. As opções são:
-PublicKeysECDSA=true|false (ALPHA - padrão=false)
RootlessControlPlane=true|false (ALPHA - padrão=false)
UnversionedKubeletConfigMap=true|false (padrão=true) +PublicKeysECDSA=true|false (ALPHA - padrão=false)
RootlessControlPlane=true|false (ALPHA - padrão=false)

From bb85d627527856fdeaa64c6f3e222e9617984d58 Mon Sep 17 00:00:00 2001 From: Tim Bannister Date: Sat, 5 Nov 2022 18:40:06 +0000 Subject: [PATCH 045/279] Update docs for PodSecurityPolicy removal --- .../security/pod-security-admission.md | 5 +++- .../admission-controllers.md | 22 +++++----------- .../enforce-standards-admission-controller.md | 26 ++++++++++++------- .../enforce-standards-namespace-labels.md | 7 ++--- 4 files changed, 31 insertions(+), 29 deletions(-) diff --git a/content/en/docs/concepts/security/pod-security-admission.md b/content/en/docs/concepts/security/pod-security-admission.md index 57e4fd98003..30335d39f71 100644 --- a/content/en/docs/concepts/security/pod-security-admission.md +++ b/content/en/docs/concepts/security/pod-security-admission.md @@ -131,4 +131,7 @@ current policy level: - [Enforcing Pod Security Standards](/docs/setup/best-practices/enforcing-pod-security-standards) - [Enforce Pod Security Standards by Configuring the Built-in Admission Controller](/docs/tasks/configure-pod-container/enforce-standards-admission-controller) - [Enforce Pod Security Standards with Namespace Labels](/docs/tasks/configure-pod-container/enforce-standards-namespace-labels) -- [Migrate from PodSecurityPolicy to the Built-In PodSecurity Admission Controller](/docs/tasks/configure-pod-container/migrate-from-psp) + +If you are running an older version of Kubernetes and want to upgrade +to a version of Kubernetes that does not include PodSecurityPolicies, +read [migrate from PodSecurityPolicy to the Built-In PodSecurity Admission Controller](/docs/tasks/configure-pod-container/migrate-from-psp). diff --git a/content/en/docs/reference/access-authn-authz/admission-controllers.md b/content/en/docs/reference/access-authn-authz/admission-controllers.md index 1e7022fa772..8e570f9d1f9 100644 --- a/content/en/docs/reference/access-authn-authz/admission-controllers.md +++ b/content/en/docs/reference/access-authn-authz/admission-controllers.md @@ -663,23 +663,15 @@ admission plugin, which allows preventing pods from running on specifically tain {{< feature-state for_k8s_version="v1.25" state="stable" >}} -This is the replacement for the deprecated [PodSecurityPolicy](#podsecuritypolicy) admission controller -defined in the next section. This admission controller acts on creation and modification of the pod and -determines if it should be admitted based on the requested security context and the -[Pod Security Standards](/docs/concepts/security/pod-security-standards/). +The PodSecurity admission controller checks new Pods before they are +admitted, determines if it should be admitted based on the requested security context and the restrictions on permitted +[Pod Security Standards](/docs/concepts/security/pod-security-standards/) +for the namespace that the Pod would be in. -See the [Pod Security Admission documentation](/docs/concepts/security/pod-security-admission/) -for more information. +See the [Pod Security Admission](/docs/concepts/security/pod-security-admission/) +documentation for more information. -### PodSecurityPolicy {#podsecuritypolicy} - -{{< feature-state for_k8s_version="v1.21" state="deprecated" >}} - -This admission controller acts on creation and modification of the pod and determines if it should be admitted -based on the requested security context and the available Pod Security Policies. - -See also the [PodSecurityPolicy](/docs/concepts/security/pod-security-policy/) documentation -for more information. +PodSecurity replaced an older admission controller named PodSecurityPolicy. ### PodTolerationRestriction {#podtolerationrestriction} diff --git a/content/en/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md b/content/en/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md index 802f38a651a..311a4d54759 100644 --- a/content/en/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md +++ b/content/en/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md @@ -4,23 +4,34 @@ reviewers: - tallclair - liggitt content_type: task -min-kubernetes-server-version: v1.22 --- -As of v1.22, Kubernetes provides a built-in [admission controller](/docs/reference/access-authn-authz/admission-controllers/#podsecurity) +Kubernetes provides a built-in [admission controller](/docs/reference/access-authn-authz/admission-controllers/#podsecurity) to enforce the [Pod Security Standards](/docs/concepts/security/pod-security-standards). You can configure this admission controller to set cluster-wide defaults and [exemptions](/docs/concepts/security/pod-security-admission/#exemptions). ## {{% heading "prerequisites" %}} -{{% version-check %}} +Following an alpha release in Kubernetes v1.22, +Pod Security Admission becaome available by default in Kubernetes v1.23, as +a beta. From version 1.25 onwards, Pod Security Admission is generally +available. {{% version-check %}} -- Ensure the `PodSecurity` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/#feature-gates-for-alpha-or-beta-features) is enabled. +If you are not running Kubernetes {{< skew currentVersion >}}, you can switch +to viewing this page in the documentation for the Kubernetes version that you +are running. ## Configure the Admission Controller +{{< note >}} +`pod-security.admission.config.k8s.io/v1` configuration requires v1.25+. +For v1.23 and v1.24, use [v1beta1](https://v1-24.docs.kubernetes.io/docs/tasks/configure-pod-container/enforce-standards-admission-controller/). +For v1.22, use [v1alpha1](https://v1-22.docs.kubernetes.io/docs/tasks/configure-pod-container/enforce-standards-admission-controller/). +{{< /note >}} + + ```yaml -apiVersion: apiserver.config.k8s.io/v1 +apiVersion: apiserver.config.k8s.io/v1 # see compatibility note kind: AdmissionConfiguration plugins: - name: PodSecurity @@ -56,8 +67,3 @@ plugins: The above manifest needs to be specified via the `--admission-control-config-file` to kube-apiserver. {{< /note >}} -{{< note >}} -`pod-security.admission.config.k8s.io/v1` configuration requires v1.25+. -For v1.23 and v1.24, use [v1beta1](https://v1-24.docs.kubernetes.io/docs/tasks/configure-pod-container/enforce-standards-admission-controller/). -For v1.22, use [v1alpha1](https://v1-22.docs.kubernetes.io/docs/tasks/configure-pod-container/enforce-standards-admission-controller/). -{{< /note >}} diff --git a/content/en/docs/tasks/configure-pod-container/enforce-standards-namespace-labels.md b/content/en/docs/tasks/configure-pod-container/enforce-standards-namespace-labels.md index 4157d6ba674..a9f767b269e 100644 --- a/content/en/docs/tasks/configure-pod-container/enforce-standards-namespace-labels.md +++ b/content/en/docs/tasks/configure-pod-container/enforce-standards-namespace-labels.md @@ -4,7 +4,6 @@ reviewers: - tallclair - liggitt content_type: task -min-kubernetes-server-version: v1.22 --- Namespaces can be labeled to enforce the [Pod Security Standards](/docs/concepts/security/pod-security-standards). The three policies @@ -15,9 +14,11 @@ text="admission controller" term_id="admission-controller" >}}. ## {{% heading "prerequisites" %}} -{{% version-check %}} +Pod Security Admission was available by default in Kubernetes v1.23, as +a beta. From version 1.25 onwards, Pod Security Admission is generally +available. -- Ensure the `PodSecurity` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/#feature-gates-for-alpha-or-beta-features) is enabled. +{{% version-check %}} ## Requiring the `baseline` Pod Security Standard with namespace labels From 09d013bbb608f40a04021109b3df3cbb83431f08 Mon Sep 17 00:00:00 2001 From: Sascha Grunert Date: Tue, 24 Jan 2023 10:42:58 +0100 Subject: [PATCH 046/279] Mentioned required cosign version for the `--certificate` flag Signed-off-by: Sascha Grunert --- .../docs/tasks/administer-cluster/verify-signed-artifacts.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/content/en/docs/tasks/administer-cluster/verify-signed-artifacts.md b/content/en/docs/tasks/administer-cluster/verify-signed-artifacts.md index e672779f75c..b666a776767 100644 --- a/content/en/docs/tasks/administer-cluster/verify-signed-artifacts.md +++ b/content/en/docs/tasks/administer-cluster/verify-signed-artifacts.md @@ -47,6 +47,9 @@ Then verify the blob by using `cosign`: cosign verify-blob "$BINARY" --signature "$BINARY".sig --certificate "$BINARY".cert ``` +cosign v1.9.0 is required to be able to use the `--certificate` flag. Please use +`--cert` for older versions of cosign. + {{< note >}} To learn more about keyless signing, please refer to [Keyless Signatures](https://github.com/sigstore/cosign/blob/main/KEYLESS.md#keyless-signatures). From 2657e7ae5f43ee0d767d0da71f3f5292916865d8 Mon Sep 17 00:00:00 2001 From: moriya Date: Thu, 26 Jan 2023 00:23:24 +0900 Subject: [PATCH 047/279] pod-priority-preemption-ja --- .../pod-priority-preemption.md | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) rename content/ja/docs/concepts/{configuration => scheduling-eviction}/pod-priority-preemption.md (92%) diff --git a/content/ja/docs/concepts/configuration/pod-priority-preemption.md b/content/ja/docs/concepts/scheduling-eviction/pod-priority-preemption.md similarity index 92% rename from content/ja/docs/concepts/configuration/pod-priority-preemption.md rename to content/ja/docs/concepts/scheduling-eviction/pod-priority-preemption.md index c06b3b41b0a..d674b40edf5 100644 --- a/content/ja/docs/concepts/configuration/pod-priority-preemption.md +++ b/content/ja/docs/concepts/scheduling-eviction/pod-priority-preemption.md @@ -1,7 +1,7 @@ --- title: Podの優先度とプリエンプション content_type: concept -weight: 70 +weight: 90 --- @@ -82,20 +82,20 @@ description: "この優先度クラスはXYZサービスのPodに対してのみ ## 非プリエンプトのPriorityClass {#non-preempting-priority-class} -{{< feature-state for_k8s_version="v1.19" state="beta" >}} +{{< feature-state for_k8s_version="v1.24" state="stable" >}} -`PreemptionPolicy: Never`と設定されたPodは、スケジューリングのキューにおいて他の優先度の低いPodよりも優先されますが、他のPodをプリエンプトすることはありません。 +`preemptionPolicy: Never`と設定されたPodは、スケジューリングのキューにおいて他の優先度の低いPodよりも優先されますが、他のPodをプリエンプトすることはありません。 スケジューリングされるのを待つ非プリエンプトのPodは、リソースが十分に利用可能になるまでスケジューリングキューに残ります。 非プリエンプトのPodは、他のPodと同様に、スケジューラーのバックオフの対象になります。これは、スケジューラーがPodをスケジューリングしようと試みたものの失敗した場合、低い頻度で再試行するようにして、より優先度の低いPodが先にスケジューリングされることを許します。 非プリエンプトのPodは、他の優先度の高いPodにプリエンプトされる可能性はあります。 -`PreemptionPolicy`はデフォルトでは`PreemptLowerPriority`に設定されており、これが設定されているPodは優先度の低いPodをプリエンプトすることを許容します。これは既存のデフォルトの挙動です。 -`PreemptionPolicy`を`Never`に設定すると、これが設定されたPodはプリエンプトを行わないようになります。 +`preemptionPolicy`はデフォルトでは`PreemptLowerPriority`に設定されており、これが設定されているPodは優先度の低いPodをプリエンプトすることを許容します。これは既存のデフォルトの挙動です。 +`preemptionPolicy`を`Never`に設定すると、これが設定されたPodはプリエンプトを行わないようになります。 ユースケースの例として、データサイエンスの処理を挙げます。 ユーザーは他の処理よりも優先度を高くしたいジョブを追加できますが、そのとき既存の実行中のPodの処理結果をプリエンプトによって破棄させたくはありません。 -`PreemptionPolicy: Never`が設定された優先度の高いジョブは、他の既にキューイングされたPodよりも先に、クラスターのリソースが「自然に」開放されたときにスケジューリングされます。 +`preemptionPolicy: Never`が設定された優先度の高いジョブは、他の既にキューイングされたPodよりも先に、クラスターのリソースが「自然に」開放されたときにスケジューリングされます。 ### 非プリエンプトのPriorityClassの例 @@ -143,14 +143,13 @@ Podが作成されると、スケジューリング待ちのキューに入り Pod PがノードNのPodをプリエンプトした場合、ノードNの名称がPのステータスの`nominatedNodeName`フィールドに設定されます。このフィールドはスケジューラーがPod Pのために予約しているリソースの追跡を助け、ユーザーにクラスターにおけるプリエンプトに関する情報を与えます。 -Pod Pは必ずしも「指名したノード」へスケジューリングされないことに注意してください。Podがプリエンプトされると、そのPodは終了までの猶予期間を得ます。スケジューラーがPodの終了を待つ間に他のノードが利用可能になると、スケジューラーは他のノードをPod Pのスケジューリング先にします。この結果、Podの`nominatedNodeName`と`nodeName`は必ずしも一致しません。また、スケジューラーがノードNのPodをプリエンプトさせた後に、Pod Pよりも優先度の高いPodが来た場合、スケジューラーはノードNをその新しい優先度の高いPodへ与えます。このような場合は、スケジューラーはPod Pの`nominatedNodeName`を消去します。これによって、スケジューラーはPod Pが他のノードのPodをプリエンプトさせられるようにします。 +Pod Pは必ずしも「指名したノード」へスケジューリングされないことに注意してください。Podがプリエンプトされると、そのPodは終了までの猶予期間を得ます。スケジューラーがPodの終了を待つ間に他のノードが利用可能になると、スケジューラーは他のノードをPod Pのスケジューリング先にする可能性があります。この結果、Podの`nominatedNodeName`と`nodeName`は必ずしも一致しません。また、スケジューラーがノードNのPodをプリエンプトさせた後に、Pod Pよりも優先度の高いPodが来た場合、スケジューラーはノードNをその新しい優先度の高いPodへ与えます。このような場合は、スケジューラーはPod Pの`nominatedNodeName`を消去します。これによって、スケジューラーはPod Pが他のノードのPodをプリエンプトさせられるようにします。 ### プリエンプトの制限 #### プリエンプトされるPodの正常終了 Podがプリエンプトされると、[猶予期間](/ja/docs/concepts/workloads/pods/pod-lifecycle/#pod-termination)が与えられます。 - Podは作業を完了し、終了するために十分な時間が与えられます。仮にそうでない場合、強制終了されます。この猶予期間によって、スケジューラーがPodをプリエンプトした時刻と、待機状態のPod Pがノード Nにスケジュール可能になるまでの時刻の間に間が開きます。この間、スケジューラーは他の待機状態のPodをスケジュールしようと試みます。プリエンプトされたPodが終了したら、スケジューラーは待ち行列にあるPodをスケジューリングしようと試みます。そのため、Podがプリエンプトされる時刻と、Pがスケジュールされた時刻には間が開くことが一般的です。この間を最小にするには、優先度の低いPodの猶予期間を0または小さい値にする方法があります。 #### PodDisruptionBudgetは対応するが、保証されない @@ -185,7 +184,7 @@ Pod PがノードNにスケジューリングできるよう、ノードNがプ Pod Qがそのノードから追い出されると、Podアンチアフィニティに違反しなくなるので、Pod PはノードNへスケジューリング可能になります。 -複数ノードに対するプリエンプションに関しては、十分な需要があり、合理的な性能を持つアルゴリズムを見つけられた場合に、追加することを検討する可能性があります。 +複数ノードに対するプリエンプションに関しては、十分な需要があり、合理的な性能を持つアルゴリズムを見つけられた場合に、将来的に機能追加を検討する可能性があります。 ## トラブルシューティング @@ -227,14 +226,22 @@ Podがその期間内に終了しない場合、強制終了されます。プ Podの優先度と{{< glossary_tooltip text="QoSクラス" term_id="qos-class" >}}は直交する機能で、わずかに相互作用がありますが、デフォルトではQoSクラスによる優先度の設定の制約はありません。スケジューラーのプリエンプションのロジックはプリエンプションの対象を決めるときにQoSクラスは考慮しません。 プリエンプションはPodの優先度を考慮し、優先度が最も低いものを候補とします。より優先度の高いPodは優先度の低いPodを追い出すだけではプリエンプトを起こしたPodのスケジューリングに不十分な場合と、`PodDisruptionBudget`により優先度の低いPodが保護されている場合のみ対象になります。 -QoSとPodの優先度の両方を考慮するコンポーネントは[リソース不足によりkubeletがPodを追い出す](/docs/tasks/administer-cluster/out-of-resource/)のみです。 -kubeletは追い出すPodの順位付けを次の順で行います。枯渇したリソースを要求以上に使用しているか、優先度、枯渇したリソースの消費量の複数のPodの要求に対する相対値。 -詳細は[エンドユーザーのPodの追い出し](/docs/tasks/administer-cluster/out-of-resource/#evicting-end-user-pods)を参照してください。 +kubeletは[node-pressureによる退避](/docs/concepts/scheduling-eviction/node-pressure-eviction/)を行うPodの順番を決めるために、優先度を利用します。 +kubeletは追い出すPodの順位付けを次の順で行います。 + 1. 枯渇したリソースを要求以上に使用しているか + 1. Podの優先度 + 1. 要求に対するリソースの使用量 + +詳細は[kubeletによるPodの退避](/docs/concepts/scheduling-eviction/node-pressure-eviction/#pod-selection-for-kubelet-eviction)を参照してください。 + kubeletによるリソース不足時のPodの追い出しでは、リソースの消費が要求を超えないPodは追い出されません。優先度の低いPodのリソースの利用量がその要求を超えていなければ、追い出されることはありません。より優先度が高く、要求を超えてリソースを使用しているPodが追い出されます。 ## {{% heading "whatsnext" %}} * PriorityClassと関連付けてResourceQuotaを使用することに関して [デフォルトで優先度クラスの消費を制限する](/ja/docs/concepts/policy/resource-quotas/#limit-priority-class-consumption-by-default) +* [Podの破壊](/docs/concepts/workloads/pods/disruptions/)を読む +* [APIを起点とした退避](/ja/docs/concepts/scheduling-eviction/api-eviction/)を読む +* [Node-pressureによる退避](/docs/concepts/scheduling-eviction/node-pressure-eviction/)を読む From a8c561986be32f54697bc742e177e7838d334cfe Mon Sep 17 00:00:00 2001 From: "Mr. Erlison" Date: Sat, 28 Jan 2023 13:08:09 -0300 Subject: [PATCH 048/279] [pt-br] Add pt-br/docs/tasks/tools/install-kubectl-linux --- .../included/kubectl-convert-overview.md | 14 + .../tools/included/kubectl-whats-next.md | 15 + .../optional-kubectl-configs-bash-linux.md | 61 ++++ .../included/optional-kubectl-configs-fish.md | 23 ++ .../included/optional-kubectl-configs-zsh.md | 28 ++ .../tasks/tools/included/verify-kubectl.md | 33 +++ .../docs/tasks/tools/install-kubectl-linux.md | 260 ++++++++++++++++++ 7 files changed, 434 insertions(+) create mode 100644 content/pt-br/docs/tasks/tools/included/kubectl-convert-overview.md create mode 100644 content/pt-br/docs/tasks/tools/included/kubectl-whats-next.md create mode 100644 content/pt-br/docs/tasks/tools/included/optional-kubectl-configs-bash-linux.md create mode 100644 content/pt-br/docs/tasks/tools/included/optional-kubectl-configs-fish.md create mode 100644 content/pt-br/docs/tasks/tools/included/optional-kubectl-configs-zsh.md create mode 100644 content/pt-br/docs/tasks/tools/included/verify-kubectl.md create mode 100644 content/pt-br/docs/tasks/tools/install-kubectl-linux.md diff --git a/content/pt-br/docs/tasks/tools/included/kubectl-convert-overview.md b/content/pt-br/docs/tasks/tools/included/kubectl-convert-overview.md new file mode 100644 index 00000000000..3920c64f31b --- /dev/null +++ b/content/pt-br/docs/tasks/tools/included/kubectl-convert-overview.md @@ -0,0 +1,14 @@ +--- +title: "Visão geral do kubectl-convert" +description: >- + Um plugin `kubectl` que permite converter manifestos entre diferentes versões da API. +headless: true +_build: + list: never + render: never + publishResources: false +--- + +Um plugin para a ferramenta Kubernetes de linha de comando `kubectl`, que permite converter manifestos entre diferentes versões da API. +Isso pode ser particularmente útil para migrar manifestos para uma versão não obsoleta com a versão mais recente da API Kubernetes. +Para mais informações, visite [Migrar para APIs não obsoletas](/docs/reference/using-api/deprecation-guide/#migrate-to-non-deprecated-apis) diff --git a/content/pt-br/docs/tasks/tools/included/kubectl-whats-next.md b/content/pt-br/docs/tasks/tools/included/kubectl-whats-next.md new file mode 100644 index 00000000000..1707d9812ff --- /dev/null +++ b/content/pt-br/docs/tasks/tools/included/kubectl-whats-next.md @@ -0,0 +1,15 @@ +--- +title: "Próximos passos" +description: "Próximos passos depois de instalar o kubectl." +headless: true +_build: + list: never + render: never + publishResources: false +--- + +* [Instale o Minikube](https://minikube.sigs.k8s.io/docs/start/) +* Veja os [guias de introdução](/pt-br/docs/setup/) para saber mais sobre a criação de clusters. +* [Saiba como iniciar e publicar sua aplicação.](/docs/tasks/access-application-cluster/service-access-application-cluster/) +* Se você precisar de acesso a um cluster que não criou, consulte [Compartilhamento de Acesso ao Cluster](/docs/tasks/access-application-cluster/configure-access-multiple-clusters/) +* Leia os [documentos de referência kubectl](/docs/reference/kubectl/kubectl/) diff --git a/content/pt-br/docs/tasks/tools/included/optional-kubectl-configs-bash-linux.md b/content/pt-br/docs/tasks/tools/included/optional-kubectl-configs-bash-linux.md new file mode 100644 index 00000000000..9f56cf51cf4 --- /dev/null +++ b/content/pt-br/docs/tasks/tools/included/optional-kubectl-configs-bash-linux.md @@ -0,0 +1,61 @@ +--- +title: "autocompletar do bash no Linux" +description: "Algumas configurações opcionais para o autocompletar do bash no Linux." +headless: true +_build: + list: never + render: never + publishResources: false +--- + +### Introdução + +O script de autocompletar do kubectl para Bash pode ser gerado com o comando `kubectl completion bash`. O script permite habilitar o kubectl autocompletar no seu shell. + +No entanto, o script autocompletar depende do [**bash-completion**](https://github.com/scop/bash-completion), o que significa que você precisa instalar este software primeiro (executando `type _init_completion` você pode testar se tem o bash-completion instalado). + +### Instale bash-completion + +O bash-completion é fornecido por muitos gerenciadores de pacotes (veja [aqui](https://github.com/scop/bash-completion#installation)). Você pode instalar com `apt-get install bash-completion` ou `yum install bash-completion`, etc. + +Os comandos acima criam `/usr/share/bash-completion/bash_completion`, que é o script principal de bash-completion. Dependendo do seu gerenciador de pacotes, você tem que adicionar manualmente ao seu arquivo `~/.bashrc`. + +Para descobrir, recarregue seu shell e execute `type _init_completion`. Se o comando for bem-sucedido, já está definido, caso contrário, adicione o seguinte ao seu arquivo `~/.bashrc`: + +```bash +source /usr/share/bash-completion/bash_completion +``` + +Recarregue o seu shell e verifique se o bash-completion está instalado corretamente digitando `type _init_completion`. + +### Ative o kubectl autocompletar + +#### Bash + +Agora você precisa garantir que o kubectl autocompletar esteja ativo em todas as suas sessões shell. Existem duas maneiras pelas quais você pode fazer isso: + +{{< tabs name="kubectl_bash_autocompletion" >}} +{{< tab name="User" codelang="bash" >}} +echo 'source <(kubectl completion bash)' >>~/.bashrc +{{< /tab >}} +{{< tab name="System" codelang="bash" >}} +kubectl completion bash | sudo tee /etc/bash_completion.d/kubectl > /dev/null +{{< /tab >}} +{{< /tabs >}} + +Se você tiver um alias para kubectl, você pode estender o autocompletar do shell para trabalhar com esse alias: + +```bash +echo 'alias k=kubectl' >>~/.bashrc +echo 'complete -o default -F __start_kubectl k' >>~/.bashrc +``` + +{{< note >}} +bash-completion fornece todos os scripts de autocompletar em `/etc/bash_completion.d`. +{{< /note >}} + +Todas as abordagens são equivalentes. Depois de recarregar seu shell, o kubectl autocompletar deve estar funcionando. Para ativar o autocompletar do bash na sessão atual do shell, execute `exec bash`: + +```bash +exec bash +``` diff --git a/content/pt-br/docs/tasks/tools/included/optional-kubectl-configs-fish.md b/content/pt-br/docs/tasks/tools/included/optional-kubectl-configs-fish.md new file mode 100644 index 00000000000..56d50a81088 --- /dev/null +++ b/content/pt-br/docs/tasks/tools/included/optional-kubectl-configs-fish.md @@ -0,0 +1,23 @@ +--- +title: "Autocompletar do fish" +description: "Configurações opcionais para ativar o autocompletar no shell fish." +headless: true +_build: + list: never + render: never + publishResources: false +--- + +{{< note >}} +O autocompletar para Fish requer kubectl 1.23 ou posterior. +{{< /note >}} + +O script de autocompletar do kubectl para Fish pode ser gerado com o comando `kubectl completion fish`. O script permite habilitar o kubectl autocompletar no seu shell. + +Para fazer isso em todas as suas sessões do shell, adicione a seguinte linha ao seu arquivo `~/.config/fish/config.fish`: + +```shell +kubectl completion fish | source +``` + +Depois de recarregar seu shell, o kubectl autocompletar deve estar funcionando. diff --git a/content/pt-br/docs/tasks/tools/included/optional-kubectl-configs-zsh.md b/content/pt-br/docs/tasks/tools/included/optional-kubectl-configs-zsh.md new file mode 100644 index 00000000000..caa0e485c50 --- /dev/null +++ b/content/pt-br/docs/tasks/tools/included/optional-kubectl-configs-zsh.md @@ -0,0 +1,28 @@ +--- +title: "Autocompletar zsh" +description: "Configurações opcionais para ativar o autocompletar no shell zsh." +headless: true +_build: + list: never + render: never + publishResources: false +--- + +O script de autocompletar do kubectl para Zsh pode ser gerado com o comando `kubectl completion zsh`. Este script habilita o kubectl autocompletar no seu shell. + +Para fazer isso em todas as suas sessões de shell, adicione a seguinte linha no arquivo ~/.zshrc: + +```zsh +source <(kubectl completion zsh) +``` + +Se você tiver um alias para kubectl, o autocompletar funcionará automaticamente com ele. + +Depois de recarregar seu shell, o kubectl autocompletar deve estar funcionando. + +Se você receber um erro como `2: command not found: compdef`, adicione o seguinte bloco ao início do seu arquivo `~/.zshrc`: + +```zsh +autoload -Uz compinit +compinit +``` diff --git a/content/pt-br/docs/tasks/tools/included/verify-kubectl.md b/content/pt-br/docs/tasks/tools/included/verify-kubectl.md new file mode 100644 index 00000000000..b9d4ec99c58 --- /dev/null +++ b/content/pt-br/docs/tasks/tools/included/verify-kubectl.md @@ -0,0 +1,33 @@ +--- +title: "Verifique a instalação do kubectl" +description: "Como verificar a instalação do kubectl." +headless: true +_build: + list: never + render: never + publishResources: false +--- + +Para que o kubectl encontre e acesse um cluster Kubernetes, ele precisa de um [arquivo kubeconfig](/pt-br//docs/concepts/configuration/organize-cluster-access-kubeconfig/), que é criado automaticamente quando você cria um cluster usando [kube-up.sh](https://github.com/kubernetes/kubernetes/blob/master/cluster/kube-up.sh) ou instala com sucesso um cluster Minikube. Por padrão, a configuração kubectl está localizada em `~/.kube/config`. + +Verifique se o kubectl está configurado corretamente obtendo o estado do cluster: + +```shell +kubectl cluster-info +``` + +Se você receber uma URL de resposta, o kubectl está configurado corretamente para acessar seu cluster. + +Se você receber uma mensagem semelhante à seguinte, o kubectl não está configurado corretamente ou não consegue se conectar a um cluster Kubernetes. + +``` +The connection to the server was refused - did you specify the right host or port? +``` + +Por exemplo, se você pretende executar um cluster Kubernetes no seu laptop (localmente), precisará que uma ferramenta como o Minikube seja instalada primeiro, para em seguida executar novamente os comandos indicados acima. + +Se o kubectl cluster-info retornar a URL de resposta, mas você não conseguir acessar seu cluster, para verificar se ele está configurado corretamente, use: + +```shell +kubectl cluster-info dump +``` diff --git a/content/pt-br/docs/tasks/tools/install-kubectl-linux.md b/content/pt-br/docs/tasks/tools/install-kubectl-linux.md new file mode 100644 index 00000000000..19538ac4feb --- /dev/null +++ b/content/pt-br/docs/tasks/tools/install-kubectl-linux.md @@ -0,0 +1,260 @@ +--- +title: Instale e configure o kubectl no Linux +content_type: task +weight: 10 +card: + name: tasks + weight: 20 + title: Install kubectl on Linux +--- + +## {{% heading "prerequisites" %}} + +Você deve usar uma versão kubectl que esteja próxima da versão do seu cluster. Por exemplo, um cliente v1.26 pode se comunicar com as versões v1.25, v1.26 e v1.27 da camada de gerenciamento. Usar a versão compatível mais recente do kubectl ajuda a evitar problemas inesperados. + +## Instale o kubectl no Linux + +Existem os seguintes métodos para instalar o kubectl no Linux: + +- [Instale o binário kubectl no Linux usando o curl](#instale-o-binário-kubectl-no-linux-usando-o-curl) +- [Instale usando o gerenciador de pacotes nativo](#instale-usando-o-gerenciador-de-pacotes-nativo) +- [Instale usando outro gerenciador de pacotes](#instale-usando-outro-gerenciador-de-pacotes) + + +### Instale o binário kubectl no Linux usando o curl + +1. Faça download da versão mais recente com o comando: + + ```bash + curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" + ``` + + {{< note >}} +Para fazer o download de uma versão específica, substitua a parte `$(curl -L -s https://dl.k8s.io/release/stable.txt)` do comando pela versão específica. + +Por exemplo, para fazer download da versão {{< param "fullversion" >}} no Linux, digite: + + ```bash + curl -LO https://dl.k8s.io/release/{{< param "fullversion" >}}/bin/linux/amd64/kubectl + ``` + {{< /note >}} + +1. Valide o binário (opcional) + + Faça download do arquivo checksum de verificação do kubectl: + + ```bash + curl -LO "https://dl.k8s.io/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl.sha256" + ``` + + Valide o binário kubectl em relação ao arquivo de verificação: + + ```bash + echo "$(cat kubectl.sha256) kubectl" | sha256sum --check + ``` + + Se válido, a saída será: + + ```console + kubectl: OK + ``` + + Se a verificação falhar, o `sha256` exibirá o status diferente de zero e a saída será semelhante a: + + ```bash + kubectl: FAILED + sha256sum: WARNING: 1 computed checksum did NOT match + ``` + + {{< note >}} + Faça download da mesma versão do binário e do arquivo de verificação. + {{< /note >}} + +1. Instale o kubectl + + ```bash + sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl + ``` + + {{< note >}} + Se você não tiver acesso root no sistema de destino, ainda poderá instalar o kubectl no diretório `~/.local/bin`: + + ```bash + chmod +x kubectl + mkdir -p ~/.local/bin + mv ./kubectl ~/.local/bin/kubectl + # e depois adicione ~/.local/bin na variável $PATH + ``` + + {{< /note >}} + +1. Teste para garantir que a versão que você instalou esteja atualizada: + + ```bash + kubectl version --client + ``` + + Ou use isso para visualizar mais detalhes da versão: + + ```cmd + kubectl version --client --output=yaml + ``` + +### Instale usando o gerenciador de pacotes nativo + +{{< tabs name="kubectl_install" >}} +{{% tab name="Distribuições baseadas no Debian" %}} + +1. Atualize o índice do `apt` e instale os pacotes necessários para utilizar o repositório `apt` do Kubernetes: + + ```shell + sudo apt-get update + sudo apt-get install -y ca-certificates curl + ``` + + Se você usa o Debian 9 (stretch) ou anterior, também precisará instalar o `apt-transport-https`: + ```shell + sudo apt-get install -y apt-transport-https + ``` + +2. Faça download da chave de assinatura pública do Google Cloud: + + ```shell + sudo curl -fsSLo /etc/apt/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg + ``` + +3. Adicione o repositório `apt` do Kubernetes: + + ```shell + echo "deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list + ``` + +4. Atualize o índice do `apt` com o novo repositório e instale o kubectl: + + ```shell + sudo apt-get update + sudo apt-get install -y kubectl + ``` +{{< note >}} +Em versões anteriores ao Debian 12 e Ubuntu 22.04, o `/etc/apt/keyrings` não existe por padrão. +Você pode criar este diretório se precisar, tornando-o visível para todos, mas com permissão de escrita apenas aos administradores. +{{< /note >}} + +{{% /tab %}} + +{{% tab name="Distribuições baseadas no Red Hat" %}} +```bash +cat <}} + +### Instale usando outro gerenciador de pacotes + +{{< tabs name="other_kubectl_install" >}} +{{% tab name="Snap" %}} +Se você estiver no Ubuntu ou em outra distribuição Linux que suporte o gerenciador de pacotes [snap](https://snapcraft.io/docs/core/install), o kubectl está disponível como um aplicativo [snap](https://snapcraft.io/). + +```shell +snap install kubectl --classic +kubectl version --client +``` + +{{% /tab %}} + +{{% tab name="Homebrew" %}} +Se você estiver no Linux e usando o gerenciador de pacotes [Homebrew](https://docs.brew.sh/Homebrew-on-Linux), o kubectl está disponível para [instalação](https://docs.brew.sh/Homebrew-on-Linux#install). + +```shell +brew install kubectl +kubectl version --client +``` + +{{% /tab %}} + +{{< /tabs >}} + +## Verifique a configuração kubectl + +{{< include "included/verify-kubectl.md" >}} + +## Configurações e plugins opcionais do kubectl +### Ative o autocompletar no shell + +O kubectl oferece recursos de autocompletar para Bash, Zsh, Fish e PowerShell, o que pode economizar muita digitação. + +Abaixo estão os procedimentos para configurar o autocompletar para Bash, Fish e Zsh. + +{{< tabs name="kubectl_autocompletion" >}} +{{< tab name="Bash" include="included/optional-kubectl-configs-bash-linux.md" />}} +{{< tab name="Fish" include="included/optional-kubectl-configs-fish.md" />}} +{{< tab name="Zsh" include="included/optional-kubectl-configs-zsh.md" />}} +{{< /tabs >}} + +### Instale o plugin `kubectl convert` + +{{< include "included/kubectl-convert-overview.md" >}} + +1. Faça download da versão mais recente com o comando: + + ```bash + curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl-convert" + ``` + +1. Valide o binário (opcional) + + Faça download do arquivo checksum de verificação do kubectl-convert: + + ```bash + curl -LO "https://dl.k8s.io/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl-convert.sha256" + ``` + + Valide o binário kubectl-convert com o arquivo de verificação: + + ```bash + echo "$(cat kubectl-convert.sha256) kubectl-convert" | sha256sum --check + ``` + + Se válido, a saída será: + + ```console + kubectl-convert: OK + ``` + + Se a verificação falhar, o `sha256` exibirá o status diferente de zero e a saída será semelhante a: + + ```bash + kubectl-convert: FAILED + sha256sum: WARNING: 1 computed checksum did NOT match + ``` + + {{< note >}} + Faça download da mesma versão do binário e do arquivo de verificação. + {{< /note >}} + +1. Instale o kubectl-convert + + ```bash + sudo install -o root -g root -m 0755 kubectl-convert /usr/local/bin/kubectl-convert + ``` + +1. Verifique se o plugin foi instalado com sucesso + + ```shell + kubectl convert --help + ``` + + Se não for exibido um erro, isso significa que o plugin foi instalado com sucesso. + +## {{% heading "whatsnext" %}} + +{{< include "included/kubectl-whats-next.md" >}} From 9b64a8f529756ba0cdaa15e9637b85ffe0ff8b58 Mon Sep 17 00:00:00 2001 From: Ana Carolina Rodrigues Date: Mon, 30 Jan 2023 13:29:39 -0300 Subject: [PATCH 049/279] Update content/pt-br/docs/tasks/debug/debug-application/debug-init-containers.md --- .../debug-init-containers.md | 35 +++++++------------ 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/content/pt-br/docs/tasks/debug/debug-application/debug-init-containers.md b/content/pt-br/docs/tasks/debug/debug-application/debug-init-containers.md index 65f023741f1..d79113520d2 100644 --- a/content/pt-br/docs/tasks/debug/debug-application/debug-init-containers.md +++ b/content/pt-br/docs/tasks/debug/debug-application/debug-init-containers.md @@ -1,22 +1,13 @@ --- -reviewers: -- bprashanth -- enisoc -- erictune -- foxish -- janetkuo -- kow3ns -- smarterclayton -title: Debug Init Containers +title: Contêineres de inicialização de depuração content_type: task weight: 40 --- -Esta página mostra como investigar problemas relacionados à execução de -inicialização de Contêineres. As linhas de comando de exemplo abaixo -referem-se ao pod como `` e a inicialização de contêineres como `` e +Esta página mostra como investigar problemas relacionados à execução de contêineres de inicialização. +As linhas de comando de exemplo abaixo referem-se ao pod como `` e aos contêineres de inicialização como `` e ``. ## {{% heading "prerequisites" %}} @@ -24,13 +15,13 @@ referem-se ao pod como `` e a inicialização de contêineres como `}} {{< version-check >}} -* Você deve estar familiarizado com os fundamentos da - [inicialização de Contêineres](/docs/concepts/workloads/pods/init-containers/). -* Você deve ter [Configurado uma Inicialização de Contêiner](/docs/tasks/configure-pod-container/configure-pod-initialization/#creating-a-pod-that-has-an-init-container/). +* Você deve estar familiarizado com os fundamentos de + [contêineres de inicialização](/docs/concepts/workloads/pods/init-containers/). +* Você deve ter [configurado um contêiner de inicialização](/docs/tasks/configure-pod-container/configure-pod-initialization/#creating-a-pod-that-has-an-init-container/). -## Verificando o status das inicializações de contêineres +## Verificando o status dos contêineres de inicialização Exiba o status do seu pod: @@ -49,7 +40,7 @@ NAME READY STATUS RESTARTS AGE Consulte [Entendendo sobre o status do pod](#understanding-pod-status) para obter mais exemplos de valores de status e seus significados. -## Obtendo detalhes sobre a Inicialização de Contêineres +## Obtendo detalhes sobre os contêineres de inicialização Veja informações mais detalhadas sobre a execução da Inicialização de Contêineres: @@ -87,7 +78,7 @@ Init Containers: ... ``` -Você também pode acessar programaticamente os status das inicializações de contêineres, +Você também pode acessar programaticamente os status dos contêineres de inicialização, lendo o campo `status.initContainerStatuses` nas especificações do pod: ```shell @@ -96,9 +87,9 @@ kubectl get pod nginx --template '{{.status.initContainerStatuses}}' Este comando retornará as mesmas informações acima em JSON bruto. -## Acessando logs de inicialização de contêineres +## Acessando logs de contêineres de inicialização -Passe o nome da inicialização de contêineres junto com o nome do Pod +Passe o nome do contêiner de inicialização junto com o nome do Pod para acessar seus logs. ```shell @@ -110,10 +101,10 @@ Inicializações de contêineres que executam uma impressão de comandos de scri -## Entendendo sobre o status do pod +## Entendendo sobre o status do pod { #understanding-pod-status } Um status do Pod começando com `Init:` resume o status da execução da inicialização de contêineres. -A tabela abaixo descreve alguns valores de status de exemplo que você pode ver durante a depuração de Init Containers. +A tabela abaixo descreve alguns valores de status de exemplo que você pode ver durante a depuração de contêineres de inicialização. Status | Significado ------ | ------- From e3325f1f593f0779625ae1a114841d8c1fce7ea0 Mon Sep 17 00:00:00 2001 From: Tim Bannister Date: Mon, 30 Jan 2023 18:22:23 +0000 Subject: [PATCH 050/279] Use SVG for blog article images --- .../index.md | 4 +- .../security_behavior_figure_1.svg | 499 +++++++++++++ .../security_behavior_figure_2.svg | 699 ++++++++++++++++++ 3 files changed, 1200 insertions(+), 2 deletions(-) create mode 100644 content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/security_behavior_figure_1.svg create mode 100644 content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/security_behavior_figure_2.svg diff --git a/content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/index.md b/content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/index.md index 8ecad96975d..d10abcd5f3a 100644 --- a/content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/index.md +++ b/content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/index.md @@ -22,7 +22,7 @@ In other words, consciously accept that you will never create completely invulne Being vulnerable does not necessarily mean that your service will be exploited. Though your services are vulnerable in some ways unknown to you, offenders still need to identify these vulnerabilities and then exploit them. If offenders fail to exploit your service vulnerabilities, you win! In other words, having a vulnerability that can’t be exploited, represents a risk that can’t be realized. -{{< figure src="Example.png" alt="Image of an example of offender gaining foothold in a service" class="diagram-large" caption="Figure 1. An Offender gaining foothold in a vulnerable service" >}} +{{< figure src="security_behavior_figure_1.svg" alt="Image of an example of offender gaining foothold in a service" class="diagram-large" caption="Figure 1. An Offender gaining foothold in a vulnerable service" >}} The above diagram shows an example in which the offender does not yet have a foothold in the service; that is, it is assumed that your service does not run code controlled by the offender on day 1. In our example the service has vulnerabilities in the API exposed to clients. To gain an initial foothold the offender uses a malicious client to try and exploit one of the service API vulnerabilities. The malicious client sends an exploit that triggers some unplanned behavior of the service. @@ -55,7 +55,7 @@ Fortunately, microservice architecture is well suited to security-behavior monit Kubernetes is often used to support workloads designed with microservice architecture. By design, microservices aim to follow the UNIX philosophy of "Do One Thing And Do It Well". Each microservice has a bounded context and a clear interface. In other words, you can expect the microservice clients to send relatively regular requests and the microservice to present a relatively regular behavior as a response to these requests. Consequently, a microservice architecture is an excellent candidate for security-behavior monitoring. -{{< figure src="Microservices.png" alt="Image showing why microservices are well suited for security-behavior monitoring" class="diagram-large" caption="Figure 2. Microservices are well suited for security-behavior monitoring" >}} +{{< figure src="security_behavior_figure_2.svg" alt="Image showing why microservices are well suited for security-behavior monitoring" class="diagram-large" caption="Figure 2. Microservices are well suited for security-behavior monitoring" >}} The diagram above clarifies how dividing a monolithic service to a set of microservices improves our ability to perform security-behavior monitoring and control. In a monolithic service approach, different client requests are intertwined, resulting in a diminished ability to identify irregular client behaviors. Without prior knowledge, an observer of the intertwined client requests will find it hard to distinguish between types of requests and their related characteristics. Further, internal client requests are not exposed to the observer. Lastly, the aggregated behavior of the monolithic service is a compound of the many different internal behaviors of its components, making it hard to identify irregular service behavior. diff --git a/content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/security_behavior_figure_1.svg b/content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/security_behavior_figure_1.svg new file mode 100644 index 00000000000..4cdccb94ddd --- /dev/null +++ b/content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/security_behavior_figure_1.svg @@ -0,0 +1,499 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Service + + API + + Data + Store + + API + + Kubernetes + + Benign clients + Malicious client + + + + + + Client makes + iregular request + + + + + Service makes + iregular request + + + + Service provides + iregular response + + + + Data Store provides + iregular response + + + + Data Store takes + iregular time to + respond + + + + + Service takes + iregular time + to respond + + + + REQ: username=tom+or+1%3D1 => “tom or 1=1” + RES: data about all users + + + REQ: username=tom => “tom” + RES: data about tom + + + + + + diff --git a/content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/security_behavior_figure_2.svg b/content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/security_behavior_figure_2.svg new file mode 100644 index 00000000000..d05bbf50307 --- /dev/null +++ b/content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/security_behavior_figure_2.svg @@ -0,0 +1,699 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Monolithic Service + + Microservices + + + + Client behavior + exposed to an observer + + + + + Service behavior + exposed to an observer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 07a16e199cd6d8ade4f2d614c6e7f3e89683b2d1 Mon Sep 17 00:00:00 2001 From: Tim Bannister Date: Mon, 30 Jan 2023 18:29:06 +0000 Subject: [PATCH 051/279] Fix typos in diagram --- .../security_behavior_figure_1.svg | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/security_behavior_figure_1.svg b/content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/security_behavior_figure_1.svg index 4cdccb94ddd..4b65906d944 100644 --- a/content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/security_behavior_figure_1.svg +++ b/content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/security_behavior_figure_1.svg @@ -247,7 +247,7 @@ id="text388">iregular request + y="0">irregular request iregular request + style="stroke-width:0.352778">irregular request iregular response + style="stroke-width:0.352778">irregular response iregular response + style="stroke-width:0.352778">irregular response iregular time to + style="stroke-width:0.352778">irregular time to iregular time + style="stroke-width:0.352778">irregular time RES: data about tom + id="tspan1041">RES: data about Tom Date: Mon, 30 Jan 2023 18:36:59 +0000 Subject: [PATCH 052/279] Convert image text to paths This avoids end users having to install the right fonts. --- .../security_behavior_figure_1.svg | 1768 ++++++++++++++--- .../security_behavior_figure_2.svg | 112 +- 2 files changed, 1471 insertions(+), 409 deletions(-) diff --git a/content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/security_behavior_figure_1.svg b/content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/security_behavior_figure_1.svg index 4b65906d944..36905d5a8d4 100644 --- a/content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/security_behavior_figure_1.svg +++ b/content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/security_behavior_figure_1.svg @@ -11,45 +11,58 @@ xmlns:svg="http://www.w3.org/2000/svg"> + + + + + + id="g4850"> + id="g23158" + transform="translate(-14.234061,-23.955893)"> + id="g22896" + transform="translate(-14.234061,-23.955893)"> + id="g22886" + transform="translate(-14.234061,-23.955893)"> + d="m 39.046105,46.488425 c -0.10656,-9.7e-4 -0.21337,0.006 -0.32039,0.0119 -0.53107,0.0303 -1.07509,0.12307 -1.59319,0.26303 -1.29868,0.37895 -2.45477,1.05911 -2.73523,1.6614 l -0.0956,0.20516 c -0.0314,0.20894 -0.0552,0.74423 -0.0563,1.28777 -2e-5,0.0107 0,0.0213 0,0.032 l -5.2e-4,1.13637 h 0.76791 v -1.08417 -0.007 -1.09141 l 0.0941,-0.18087 c 0.006,-0.0111 0.0121,-0.0228 0.0191,-0.0341 3.2e-4,-5.2e-4 7.3e-4,-10e-4 10e-4,-0.002 0.0635,-0.12356 0.16218,-0.20432 0.31574,-0.31677 0.52625,-0.38539 1.27434,-0.70024 2.04742,-0.89452 5.3e-4,-1.4e-4 9.5e-4,-3.9e-4 0.002,-5.2e-4 0.50168,-0.1414 1.01209,-0.22102 1.48983,-0.21187 0.52234,0.009 0.97095,0.0444 1.49552,0.21342 0.6718,0.16922 1.17019,0.33776 1.689,0.5836 0.0745,0.0206 0.10914,-0.0151 0.1105,-0.0683 l -0.0895,-0.69879 c -0.40713,-0.20572 -0.8726,-0.38879 -1.35754,-0.5302 -0.51765,-0.13974 -1.06108,-0.23222 -1.59164,-0.26252 -0.0664,-0.009 -0.13481,-0.008 -0.19173,-0.012 z m 12.16114,0 c 0.10656,-9.7e-4 0.21338,0.006 0.32039,0.0119 0.53107,0.0303 1.07509,0.12307 1.59319,0.26304 1.29868,0.37894 2.45477,1.0591 2.73523,1.66139 l 0.0956,0.20516 c 0.0314,0.20894 0.0552,0.74423 0.0563,1.28778 2e-5,0.0107 0,0.0213 0,0.032 l 5.2e-4,1.13636 h -0.76791 v -1.08417 -0.007 -1.09141 l -0.0941,-0.18087 c -0.006,-0.0111 -0.012,-0.0228 -0.0191,-0.0341 -3.3e-4,-5.2e-4 -7.4e-4,-10e-4 -10e-4,-0.002 -0.0635,-0.12356 -0.16219,-0.20432 -0.31575,-0.31677 -0.52625,-0.38539 -1.27434,-0.70024 -2.04742,-0.89452 -5.2e-4,-1.3e-4 -9.5e-4,-3.8e-4 -0.002,-5.2e-4 -0.50168,-0.14139 -1.01209,-0.22102 -1.48983,-0.21187 -0.52233,0.009 -0.97095,0.0444 -1.49551,0.21342 -0.67181,0.16922 -1.1702,0.33776 -1.68901,0.58361 -0.0745,0.0206 -0.10914,-0.0151 -0.1105,-0.0683 l 0.0895,-0.6988 c 0.40713,-0.20572 0.8726,-0.38879 1.35754,-0.5302 0.51765,-0.13974 1.06108,-0.23222 1.59164,-0.26252 0.0664,-0.009 0.13482,-0.008 0.19173,-0.012 z m -6.33661,3.53247 c -0.53107,0.0303 -1.07509,0.12307 -1.59319,0.26304 -1.29869,0.37894 -2.45477,1.0591 -2.73523,1.66139 l -0.0956,0.20516 c -0.0314,0.20894 -0.0552,0.74423 -0.0563,1.28778 -2e-5,0.0107 0,0.0213 0,0.032 l -5.2e-4,1.13636 h 0.76792 v -1.08417 -0.007 -1.09141 l 0.094,-0.18087 c 0.006,-0.0111 0.0121,-0.0228 0.0191,-0.0341 3.2e-4,-5.2e-4 7e-4,-10e-4 10e-4,-0.002 0.0635,-0.12356 0.16218,-0.20432 0.31574,-0.31677 0.52625,-0.38539 1.27434,-0.70024 2.04742,-0.89452 5.3e-4,-1.3e-4 0.001,-3.9e-4 0.002,-5.2e-4 0.50168,-0.14139 1.01209,-0.22102 1.48983,-0.21187 0.51716,-0.0153 1.03492,0.0873 1.49138,0.21239 0.001,3.4e-4 0.003,6.9e-4 0.004,0.001 0.77162,0.19436 1.51849,0.50878 2.0438,0.89348 0.15356,0.11245 0.25224,0.19322 0.31575,0.31678 2.8e-4,4.5e-4 2.3e-4,10e-4 5.1e-4,10e-4 0.007,0.0114 0.0138,0.0229 0.0196,0.0341 l 0.0935,0.18087 v 1.0914 0.007 1.08418 h 0.76843 l -10e-4,-1.16841 v -0.0491 c -0.002,-0.52642 -0.0258,-1.03612 -0.0563,-1.23868 l -0.0951,-0.20516 c -0.28055,-0.60251 -1.43752,-1.28305 -2.73678,-1.66191 -0.51765,-0.13974 -1.06108,-0.23222 -1.59163,-0.26252 -0.17118,-0.0208 -0.34089,-0.01 -0.51212,0 z m 6.4238,-8.75273 c -1.3466,0 -2.44531,1.09871 -2.44531,2.44531 0,1.3466 1.09871,2.44531 2.44531,2.44531 1.3466,0 2.44727,-1.09871 2.44727,-2.44531 0,-1.3466 -1.10067,-2.44531 -2.44727,-2.44531 z m 0,0.69921 c 0.96829,0 1.74609,0.77781 1.74609,1.7461 0,0.96829 -0.7778,1.74609 -1.74609,1.74609 -0.96829,0 -1.74414,-0.7778 -1.74414,-1.74609 0,-0.96829 0.77585,-1.7461 1.74414,-1.7461 z m -6.17187,2.83594 c -1.3466,0 -2.44532,1.09872 -2.44532,2.44531 0,1.3466 1.09872,2.44532 2.44532,2.44532 1.34659,0 2.44726,-1.09872 2.44726,-2.44532 0,-1.34659 -1.10067,-2.44531 -2.44726,-2.44531 z m 0,0.69922 c 0.96829,0 1.74609,0.7778 1.74609,1.74609 0,0.96829 -0.7778,1.7461 -1.74609,1.7461 -0.96829,0 -1.74414,-0.77781 -1.74414,-1.7461 0,-0.96829 0.77585,-1.74609 1.74414,-1.74609 z m -6.14844,-4.25195 c -1.3466,0 -2.44531,1.09871 -2.44531,2.44531 0,1.3466 1.09871,2.44531 2.44531,2.44531 1.3466,0 2.44531,-1.09871 2.44531,-2.44531 0,-1.3466 -1.09871,-2.44531 -2.44531,-2.44531 z m 0,0.69922 c 0.96829,0 1.74609,0.7778 1.74609,1.74609 0,0.96829 -0.7778,1.74609 -1.74609,1.74609 -0.96829,0 -1.7461,-0.7778 -1.7461,-1.74609 0,-0.96829 0.77781,-1.74609 1.7461,-1.74609 z" /> + transform="translate(-17.293455,-14.872465)"> + transform="translate(-17.293455,-14.872465)"> - Service + style="font-size:4.93995px;font-family:Carlito;-inkscape-font-specification:Carlito;stroke-width:0.352778"> + + + + + + + + - API + d="m 62.396775,45.167285 -2.10013,1.05058 2.10013,1.04955 v -0.96015 l 90.979975,0.0196 v 0.96066 l 2.10013,-1.05006 -2.10013,-1.05007 v 0.95963 l -90.979975,-0.0196 z" /> - Data - Store + aria-label="API" + id="text246" + style="font-size:4.93995px;font-family:Carlito;-inkscape-font-specification:Carlito;stroke-width:0.352778"> + + + - + + + + + + + + + + + API - - Kubernetes + style="font-size:4.93995px;font-family:Carlito;-inkscape-font-specification:Carlito;stroke-width:0.352778" + transform="translate(-14.234061,-23.955893)"> + + + + + + + + + + + + + + + + + - + Benign clients - + + + + + + + + + + + + + + + Malicious client + style="font-size:6.35px;font-family:Carlito;-inkscape-font-specification:Carlito;fill:#c00000;stroke-width:0.352778"> + + + + + + + + + + + + + + + + + d="m 62.136325,49.397515 -2.09962,1.05006 2.09962,1.05007 v -0.96015 l 91.290555,0.0202 v 0.95963 l 2.09961,-1.04955 -2.09961,-1.05006 v 0.96015 l -91.290555,-0.0202 z" /> + d="m 62.406595,54.257685 -2.10013,1.04955 2.10013,1.05058 v -0.96067 l 90.770165,0.0207 v 0.96015 l 2.09962,-1.05058 -2.09962,-1.04955 v 0.95963 l -90.770165,-0.0202 z" /> - - Client makes - irregular request - + id="g4172"> + + + + + + + + + + + + + + + + + + + + + + + + + + + - Service makes - irregular request + id="g3768" + transform="translate(-14.234061,-23.955893)"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + - Service provides - irregular response + id="g3457" + transform="translate(-14.234061,-23.955893)"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - Data Store provides - irregular response + id="g3652" + transform="translate(-14.234061,-23.955893)"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - Data Store takes - irregular time to - respond + id="g3913" + transform="translate(-14.234061,-23.955893)"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + transform="matrix(0.35277776,0,0,-0.35277778,-17.293465,175.62754)" /> - Service takes - irregular time - to respond + id="g4309" + transform="translate(-14.234061,-23.955893)"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + clip-path="url(#clipPath4463)" + transform="translate(-17.293455,-14.872465)" /> - REQ: username=tom+or+1%3D1 => “tom or 1=1” - RES: data about all users + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + clip-path="none" /> - REQ: username=tom => “tom” - RES: data about Tom + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + d="m 179.25683,49.637295 -2.10013,1.05006 2.10013,1.05007 v -0.96015 l 62.98995,0.0202 v 0.96015 l 2.09961,-1.05007 -2.09961,-1.05006 v 0.96015 l -62.98995,-0.0202 z" /> + d="m 179.25683,54.257685 -2.10013,1.04955 2.10013,1.05058 v -0.96067 l 62.98995,0.0207 v 0.96015 l 2.09961,-1.05058 -2.09961,-1.04955 v 0.95963 l -62.98995,-0.0202 z" /> + d="m 179.25683,44.637595 -2.10013,1.05007 2.10013,1.05006 v -0.96014 l 62.98995,0.0202 v 0.95963 l 2.09961,-1.04955 -2.09961,-1.05058 v 0.96066 l -62.98995,-0.0207 z" /> + d="m 181.91661,100.42747 -4.76973,2.38022 4.76973,2.39003 v -1.59577 l 57.32002,0.0413 v 1.5844 l 4.76973,-2.38021 -4.76973,-2.39004 v 1.59577 l -57.32002,-0.0408 z" /> diff --git a/content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/security_behavior_figure_2.svg b/content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/security_behavior_figure_2.svg index d05bbf50307..2079b94129e 100644 --- a/content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/security_behavior_figure_2.svg +++ b/content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/security_behavior_figure_2.svg @@ -11,8 +11,7 @@ xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"> - + id="defs16677" /> @@ -472,102 +471,37 @@ style="fill:#d0cece;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.398274" id="path900" clip-path="none" /> - - Monolithic Service + + + + - Microservices + - - - Client behavior - exposed to an observer - - + d="M 50.363465 59.490219 C 49.910023 59.490219 49.469044 59.61157 49.079964 59.830347 L 49.079964 59.832097 L 49.078213 59.832097 C 48.697691 60.052881 48.3698 60.381554 48.148258 60.773721 C 47.927606 61.153498 47.80638 61.593412 47.80638 62.046721 L 47.80638 67.939744 L 47.80638 71.28735 L 47.794712 71.28735 L 47.794712 71.484542 C 47.794712 71.93799 47.917778 72.378328 48.13659 72.76746 L 48.13659 72.769794 C 48.357338 73.149822 48.685823 73.477929 49.078213 73.699166 C 49.457875 73.919698 49.898355 74.041044 50.351797 74.041044 L 91.863157 74.041044 L 110.66004 74.041044 L 120.84346 74.041044 C 121.29691 74.041044 121.73789 73.920277 122.12696 73.7015 L 122.12696 73.699166 L 122.12871 73.699166 C 122.50923 73.478383 122.83712 73.150293 123.05866 72.758126 C 123.24545 72.436625 123.31623 72.05941 123.34745 71.679984 L 168.06057 71.051069 L 168.07048 70.6561 L 168.05473 70.65435 L 168.04306 70.65435 L 123.40054 67.753636 L 123.40054 62.058389 C 123.40054 61.605065 123.27983 61.164644 123.061 60.775471 L 123.05866 60.775471 L 123.05866 60.773138 C 122.83735 60.392887 122.50925 60.065337 122.11704 59.843766 C 121.73701 59.623278 121.29736 59.500137 120.84404 59.500137 L 110.66004 59.500137 L 91.863157 59.500137 L 50.363465 59.490219 z M 69.215771 61.091679 L 69.763009 61.091679 L 69.763009 65.512759 L 69.215771 65.512759 L 69.215771 61.091679 z M 82.163969 61.091679 L 82.711207 61.091679 L 82.711207 62.904334 C 82.835574 62.757174 82.977494 62.641018 83.137096 62.556038 C 83.296686 62.468993 83.479985 62.425354 83.687252 62.425354 C 83.863427 62.425354 84.022374 62.459634 84.163314 62.528034 C 84.304254 62.596433 84.424402 62.694737 84.523862 62.82324 C 84.623344 62.951745 84.698988 63.108418 84.750808 63.292885 C 84.804668 63.475277 84.831318 63.682079 84.831318 63.914216 C 84.831318 64.160863 84.801643 64.385257 84.741473 64.586304 C 84.681344 64.787352 84.594904 64.959869 84.483023 65.104956 C 84.371097 65.247967 84.235394 65.359323 84.075803 65.438083 C 83.916213 65.516843 83.736868 65.555931 83.537899 65.555931 C 83.338919 65.555931 83.172064 65.518527 83.037333 65.443917 C 82.904691 65.367228 82.786842 65.261848 82.683203 65.127125 L 82.652283 65.397244 C 82.644008 65.473929 82.598928 65.512759 82.518098 65.512759 L 82.163969 65.512759 L 82.163969 61.091679 z M 88.680657 61.091679 L 89.227895 61.091679 L 89.227895 62.87283 C 89.354339 62.736034 89.49458 62.627533 89.64795 62.546703 C 89.803408 62.465876 89.98273 62.425354 90.185854 62.425354 C 90.351665 62.425354 90.496711 62.453405 90.621078 62.509365 C 90.747511 62.563255 90.852859 62.640584 90.937869 62.742146 C 91.022824 62.841633 91.086047 62.963181 91.127477 63.106193 C 91.170947 63.247133 91.192819 63.403809 91.192819 63.575838 L 91.192819 65.512759 L 90.645581 65.512759 L 90.645581 63.575838 C 90.645581 63.34992 90.594805 63.173702 90.493311 63.047269 C 90.39175 62.920841 90.236509 62.857661 90.027167 62.857661 C 89.87172 62.857661 89.727503 62.894482 89.59486 62.969092 C 89.462207 63.043709 89.339775 63.146557 89.227895 63.277133 L 89.227895 65.512759 L 88.680657 65.512759 L 88.680657 61.091679 z M 70.944998 61.131935 C 70.996821 61.131935 71.04524 61.142125 71.09085 61.162855 C 71.138455 61.183585 71.179896 61.211626 71.215116 61.246866 C 71.252486 61.282092 71.281384 61.323453 71.302044 61.371133 C 71.322254 61.416722 71.333549 61.466586 71.333549 61.520486 C 71.333549 61.572309 71.322704 61.62217 71.302044 61.669838 C 71.281384 61.715438 71.252486 61.755948 71.215116 61.791188 C 71.179921 61.824348 71.13849 61.850968 71.09085 61.871698 C 71.045239 61.892478 70.996818 61.903202 70.944998 61.903202 C 70.893181 61.903202 70.844172 61.892428 70.798562 61.871698 C 70.75296 61.850968 70.712432 61.824348 70.677212 61.791188 C 70.644012 61.755948 70.617362 61.715438 70.596702 61.669838 C 70.575932 61.622173 70.565781 61.572306 70.565781 61.520486 C 70.565781 61.466594 70.576042 61.416733 70.596702 61.371133 C 70.617362 61.323457 70.644022 61.282106 70.677212 61.246866 C 70.712424 61.211626 70.752952 61.183575 70.798562 61.162855 C 70.844173 61.142095 70.893178 61.131935 70.944998 61.131935 z M 98.068888 61.131935 C 98.120716 61.131935 98.169714 61.142125 98.215324 61.162855 C 98.26293 61.183585 98.30437 61.211626 98.33959 61.246866 C 98.37696 61.282092 98.405858 61.323453 98.426518 61.371133 C 98.447288 61.416722 98.457439 61.466586 98.457439 61.520486 C 98.457439 61.572309 98.447178 61.62217 98.426518 61.669838 C 98.405858 61.715438 98.37696 61.755948 98.33959 61.791188 C 98.304404 61.824348 98.262964 61.850968 98.215324 61.871698 C 98.169703 61.892478 98.120708 61.903202 98.068888 61.903202 C 98.017077 61.903202 97.968645 61.892428 97.923035 61.871698 C 97.877432 61.850968 97.836906 61.824348 97.801686 61.791188 C 97.768496 61.755948 97.741252 61.715438 97.720592 61.669838 C 97.699822 61.622173 97.689671 61.572306 97.689671 61.520486 C 97.689671 61.466594 97.699932 61.416733 97.720592 61.371133 C 97.741252 61.323457 97.768496 61.282106 97.801686 61.246866 C 97.836899 61.211626 97.877425 61.183575 97.923035 61.162855 C 97.968634 61.142095 98.017068 61.131935 98.068888 61.131935 z M 67.376863 61.380467 C 67.640093 61.380467 67.871559 61.427216 68.070537 61.520486 C 68.271583 61.613753 68.446379 61.740108 68.595606 61.899702 L 68.409498 62.16107 C 68.397078 62.17972 68.381456 62.195302 68.362826 62.207742 C 68.344086 62.220212 68.320086 62.226411 68.291066 62.226411 C 68.255865 62.226411 68.216797 62.207714 68.173217 62.170404 C 68.131739 62.133095 68.076532 62.092575 68.008112 62.049055 C 67.939699 62.003458 67.854656 61.962099 67.753162 61.924789 C 67.6516 61.887479 67.525251 61.868781 67.373946 61.868781 C 67.195694 61.868781 67.031941 61.904757 66.882715 61.977295 C 66.735554 62.049835 66.608397 62.155802 66.500581 62.29467 C 66.394889 62.431466 66.311525 62.599179 66.251465 62.798153 C 66.193435 62.995056 66.164537 63.218866 66.164537 63.469658 C 66.164537 63.722522 66.195673 63.948604 66.257883 64.14758 C 66.320044 64.346554 66.405016 64.514267 66.512833 64.651063 C 66.620615 64.787858 66.746968 64.892971 66.892049 64.965521 C 67.03921 65.038068 67.196725 65.074035 67.364611 65.074035 C 67.468239 65.074035 67.560318 65.066959 67.641148 65.052449 C 67.724059 65.037939 67.799674 65.016127 67.868094 64.987107 C 67.938542 64.956016 68.00395 64.917775 68.06412 64.872175 C 68.126292 64.824502 68.187834 64.768403 68.247894 64.704153 C 68.281084 64.675133 68.313107 64.660397 68.344157 64.660397 C 68.373055 64.660397 68.399717 64.672866 68.424667 64.697736 L 68.648696 64.940434 C 68.501537 65.135264 68.319929 65.286545 68.104375 65.394327 C 67.888822 65.502102 67.630732 65.555931 67.33019 65.555931 C 67.064894 65.555931 66.824648 65.505223 66.609096 65.403661 C 66.395609 65.302104 66.21231 65.160167 66.05894 64.977772 C 65.907635 64.793306 65.790597 64.573457 65.707727 64.318519 C 65.626907 64.06151 65.586378 63.778485 65.586378 63.469658 C 65.586378 63.160832 65.630022 62.879234 65.717062 62.624297 C 65.804105 62.367288 65.925921 62.146593 66.083443 61.962127 C 66.240957 61.777661 66.429643 61.634299 66.649351 61.532737 C 66.869048 61.431178 67.111567 61.380467 67.376863 61.380467 z M 79.009472 61.486064 L 79.288925 61.486064 L 79.288925 62.528034 L 80.125535 62.528034 L 80.125535 62.92592 L 79.288925 62.92592 L 79.288925 64.741491 C 79.288925 64.86585 79.316936 64.959348 79.372936 65.021528 C 79.430964 65.083718 79.505747 65.11429 79.596965 65.11429 C 79.650857 65.11429 79.696807 65.107214 79.734067 65.092704 C 79.773477 65.078184 79.806266 65.061764 79.833246 65.043114 C 79.860226 65.024464 79.882875 65.008034 79.901505 64.993524 C 79.922165 64.979054 79.940913 64.971355 79.957513 64.971355 C 79.976253 64.971355 79.991108 64.97599 80.001268 64.98419 C 80.013678 64.99249 80.02553 65.005795 80.03569 65.024445 L 80.197294 65.285813 C 80.10403 65.372865 79.994099 65.440012 79.867668 65.487672 C 79.741235 65.535342 79.609496 65.558848 79.472699 65.558848 C 79.238495 65.558848 79.057739 65.491712 78.931295 65.356989 C 78.804916 65.222266 78.741687 65.029619 78.741687 64.778829 L 78.741687 62.92592 L 78.393974 62.92592 C 78.362924 62.92592 78.33568 62.915729 78.31288 62.894999 C 78.29211 62.874269 78.28196 62.843951 78.28196 62.804571 L 78.28196 62.586959 L 78.760356 62.524534 L 78.888122 61.588745 C 78.892642 61.557655 78.905141 61.532718 78.925461 61.514068 C 78.948261 61.495468 78.976282 61.486064 79.009472 61.486064 z M 93.176996 62.418937 C 93.346951 62.418937 93.498236 62.446988 93.630889 62.502948 C 93.763532 62.556837 93.874946 62.63475 93.964016 62.736312 C 94.053092 62.837872 94.120266 62.958836 94.165876 63.099776 C 94.213516 63.240717 94.237052 63.397389 94.237052 63.569421 L 94.237052 65.512759 L 93.994937 65.512759 C 93.941011 65.512759 93.899689 65.504262 93.870671 65.487672 C 93.841651 65.471093 93.821323 65.436812 93.811163 65.384992 L 93.742904 65.102039 C 93.664148 65.174576 93.5862 65.240024 93.50954 65.298064 C 93.434949 65.354019 93.356239 65.40162 93.273259 65.441 C 93.190359 65.48038 93.101457 65.509268 93.006057 65.527928 C 92.910716 65.548688 92.806174 65.558848 92.692183 65.558848 C 92.574036 65.558848 92.463278 65.543849 92.359639 65.512759 C 92.258077 65.479598 92.167737 65.429736 92.088937 65.363406 C 92.012201 65.295005 91.951356 65.210863 91.905746 65.111373 C 91.862166 65.009812 91.840404 64.890537 91.840404 64.753743 C 91.840404 64.633528 91.872427 64.518797 91.936667 64.408948 C 92.002971 64.297025 92.109787 64.197292 92.256959 64.110242 C 92.404131 64.023191 92.595931 63.952937 92.832201 63.899047 C 93.068494 63.843079 93.358586 63.810985 93.702648 63.802785 L 93.702648 63.569421 C 93.702648 63.333138 93.651984 63.156074 93.550379 63.037935 C 93.450894 62.917722 93.304414 62.857661 93.111654 62.857661 C 92.983155 62.857661 92.874598 62.874091 92.785528 62.907251 C 92.698484 62.940407 92.622822 62.976375 92.558582 63.015765 C 92.49431 63.055147 92.4382 63.091703 92.39056 63.124863 C 92.344925 63.158023 92.298181 63.174452 92.250541 63.174452 C 92.213171 63.174452 92.181259 63.165099 92.154279 63.146449 C 92.127289 63.127799 92.105527 63.104283 92.088937 63.075273 L 91.989757 62.900833 C 92.157635 62.739166 92.337819 62.619046 92.530578 62.540286 C 92.725404 62.459457 92.940714 62.418937 93.176996 62.418937 z M 103.91757 62.418937 C 103.98184 62.418937 104.04184 62.426013 104.09784 62.440523 C 104.15381 62.452953 104.20451 62.474775 104.25011 62.505865 L 104.20694 62.910168 C 104.20104 62.961988 104.17201 62.987761 104.12001 62.987761 C 104.09103 62.987761 104.04975 62.982983 103.99575 62.972593 C 103.94398 62.960123 103.88551 62.953924 103.82131 62.953924 C 103.72804 62.953924 103.64538 62.968076 103.57278 62.997096 C 103.50234 63.024045 103.43767 63.065986 103.37967 63.121946 C 103.32371 63.175835 103.2744 63.242128 103.2309 63.320888 C 103.18735 63.399649 103.14695 63.489446 103.10955 63.591007 L 103.10955 65.512759 L 102.56231 65.512759 L 102.56231 62.472027 L 102.87618 62.472027 C 102.93423 62.472027 102.97473 62.483075 102.99753 62.505865 C 103.02233 62.52866 103.03629 62.56749 103.04129 62.62138 L 103.07804 63.068855 C 103.17132 62.867806 103.28662 62.709445 103.42342 62.593376 C 103.5602 62.477307 103.72481 62.418937 103.91757 62.418937 z M 73.35098 62.425354 C 73.533376 62.425354 73.702516 62.455089 73.857963 62.515199 C 74.013411 62.575305 74.148263 62.663415 74.262266 62.779484 C 74.376257 62.895553 74.465228 63.037488 74.529468 63.205373 C 74.593818 63.37326 74.62573 63.566487 74.62573 63.784116 C 74.62573 63.869095 74.616357 63.926045 74.597727 63.955055 C 74.578991 63.982005 74.544836 63.99531 74.495046 63.99531 L 72.461863 63.99531 C 72.466373 64.185995 72.492157 64.352862 72.539457 64.495876 C 72.587099 64.636816 72.652502 64.75381 72.735482 64.847088 C 72.82046 64.940358 72.921036 65.010603 73.037105 65.058283 C 73.153174 65.103883 73.282639 65.127125 73.425656 65.127125 C 73.558299 65.127125 73.673605 65.112379 73.771035 65.083369 C 73.868453 65.052279 73.951157 65.017999 74.019567 64.980689 C 74.090015 64.943379 74.149174 64.91052 74.196924 64.88151 C 74.244529 64.85042 74.28597 64.834837 74.32119 64.834837 C 74.34399 64.834837 74.363515 64.839617 74.380115 64.850005 C 74.396705 64.858285 74.41134 64.870764 74.42387 64.887344 L 74.579057 65.086286 C 74.510644 65.16712 74.430192 65.237954 74.336942 65.298064 C 74.245744 65.356106 74.146823 65.404537 74.041154 65.443917 C 73.935449 65.481217 73.826102 65.509278 73.71211 65.527928 C 73.600187 65.546538 73.488832 65.555931 73.378983 65.555931 C 73.167575 65.555931 72.972648 65.520804 72.794407 65.450334 C 72.616154 65.379864 72.461756 65.276172 72.331179 65.139377 C 72.20268 65.000508 72.10273 64.830522 72.03014 64.629477 C 71.957662 64.426356 71.921042 64.193197 71.921042 63.929968 C 71.921042 63.718558 71.953065 63.521952 72.017305 63.339557 C 72.083609 63.155093 72.177958 62.9953 72.300259 62.860578 C 72.424613 62.723783 72.575061 62.616976 72.751234 62.540286 C 72.929475 62.463594 73.129206 62.425354 73.35098 62.425354 z M 76.779679 62.425354 C 76.945479 62.425354 77.090547 62.453405 77.214903 62.509365 C 77.341347 62.563255 77.447268 62.640585 77.532278 62.742146 C 77.617221 62.841634 77.681223 62.963181 77.724803 63.106193 C 77.768383 63.247133 77.790145 63.40381 77.790145 63.575838 L 77.790145 65.512759 L 77.242907 65.512759 L 77.242907 63.575838 C 77.242907 63.349921 77.190775 63.173702 77.087136 63.047269 C 76.985585 62.920841 76.830325 62.857661 76.620992 62.857661 C 76.465533 62.857661 76.320487 62.894482 76.185768 62.969092 C 76.051048 63.041632 75.927766 63.143635 75.815886 63.274216 L 75.815886 65.512759 L 75.268648 65.512759 L 75.268648 62.472027 L 75.594774 62.472027 C 75.634174 62.472027 75.66667 62.481371 75.69162 62.500031 C 75.71646 62.516611 75.730292 62.544662 75.734792 62.584042 L 75.781465 62.907251 C 75.912041 62.762165 76.058521 62.646005 76.220189 62.558955 C 76.381857 62.469834 76.568259 62.425354 76.779679 62.425354 z M 86.72215 62.425354 C 86.904546 62.425354 87.073675 62.455089 87.229133 62.515199 C 87.384581 62.575305 87.519433 62.663415 87.633436 62.779484 C 87.747427 62.895553 87.836398 63.037488 87.900638 63.205373 C 87.964988 63.37326 87.9969 63.566487 87.9969 63.784116 C 87.9969 63.869095 87.987527 63.926045 87.968897 63.955055 C 87.950274 63.982005 87.916006 63.99531 87.866216 63.99531 L 85.833033 63.99531 C 85.837553 64.185995 85.863327 64.352862 85.910627 64.495876 C 85.95827 64.636816 86.023672 64.75381 86.106652 64.847088 C 86.19164 64.940358 86.292206 65.010603 86.408275 65.058283 C 86.524344 65.103883 86.65382 65.127125 86.796826 65.127125 C 86.929479 65.127125 87.044775 65.112379 87.142205 65.083369 C 87.239623 65.052279 87.322319 65.017999 87.390737 64.980689 C 87.461185 64.943379 87.520454 64.91052 87.568094 64.88151 C 87.615699 64.85042 87.65714 64.834837 87.69236 64.834837 C 87.71516 64.834837 87.734685 64.839617 87.751285 64.850005 C 87.767875 64.858285 87.78251 64.870764 87.79504 64.887344 L 87.950227 65.086286 C 87.881813 65.16712 87.801362 65.237954 87.708112 65.298064 C 87.616914 65.356106 87.517996 65.404537 87.412324 65.443917 C 87.306619 65.481217 87.196689 65.509278 87.082697 65.527928 C 86.970771 65.546538 86.860001 65.555931 86.750153 65.555931 C 86.538745 65.555931 86.343819 65.520804 86.165577 65.450334 C 85.987325 65.379864 85.832936 65.276172 85.702349 65.139377 C 85.573852 65.000508 85.473316 64.830522 85.400726 64.629477 C 85.328244 64.426356 85.292212 64.193197 85.292212 63.929968 C 85.292212 63.718558 85.324235 63.521952 85.388475 63.339557 C 85.45478 63.155093 85.549117 62.9953 85.671429 62.860578 C 85.795785 62.723783 85.946231 62.616976 86.122404 62.540286 C 86.300645 62.463594 86.500376 62.425354 86.72215 62.425354 z M 100.49412 62.425354 C 100.71589 62.425354 100.91621 62.462759 101.09445 62.537369 C 101.2727 62.609908 101.42397 62.714447 101.54834 62.851243 C 101.6727 62.985967 101.76791 63.149719 101.83421 63.342474 C 101.90275 63.535232 101.93689 63.750538 101.93689 63.988893 C 101.93689 64.229319 101.90261 64.446054 101.83421 64.638811 C 101.76791 64.831569 101.67272 64.996163 101.54834 65.132959 C 101.42397 65.267682 101.2727 65.372807 101.09445 65.447417 C 100.91621 65.519963 100.71589 65.555931 100.49412 65.555931 C 100.27234 65.555931 100.0712 65.519957 99.890877 65.447417 C 99.712624 65.372799 99.5605 65.267681 99.434067 65.132959 C 99.3097 64.996163 99.213115 64.831569 99.144695 64.638811 C 99.078305 64.446054 99.045516 64.229319 99.045516 63.988893 C 99.045516 63.750538 99.078425 63.535232 99.144695 63.342474 C 99.21311 63.149719 99.309723 62.985967 99.434067 62.851243 C 99.5605 62.71445 99.712624 62.609919 99.890877 62.537369 C 100.0712 62.462753 100.27234 62.425354 100.49412 62.425354 z M 70.680713 62.472027 L 71.227368 62.472027 L 71.227368 65.512759 L 70.680713 65.512759 L 70.680713 62.472027 z M 94.541592 62.472027 L 94.992568 62.472027 C 95.033996 62.472027 95.069155 62.483075 95.098165 62.505865 C 95.127175 62.528675 95.146929 62.555022 95.157089 62.584042 L 95.807008 64.530297 C 95.833988 64.602837 95.856637 64.673091 95.875267 64.741491 C 95.893897 64.80989 95.911757 64.879299 95.928357 64.949769 C 95.942807 64.881368 95.959317 64.812798 95.977947 64.744408 C 95.998607 64.673938 96.023603 64.602847 96.052623 64.530297 L 96.711876 62.584042 C 96.724296 62.552952 96.743821 62.526595 96.770801 62.505865 C 96.799811 62.483095 96.831723 62.472027 96.867063 62.472027 L 97.29937 62.472027 L 96.167555 65.512759 L 95.673407 65.512759 L 94.541592 62.472027 z M 97.804603 62.472027 L 98.351841 62.472027 L 98.351841 65.512759 L 97.804603 65.512759 L 97.804603 62.472027 z M 73.360314 62.82324 C 73.105384 62.82324 72.903378 62.898038 72.754151 63.047269 C 72.606992 63.1965 72.514402 63.400184 72.477032 63.659266 L 74.134499 63.659266 C 74.134499 63.53698 74.116629 63.425367 74.081409 63.323805 C 74.046185 63.220172 73.995519 63.132071 73.929139 63.059521 C 73.862823 62.984905 73.780953 62.927125 73.683523 62.885665 C 73.588182 62.844205 73.480538 62.82324 73.360314 62.82324 z M 86.731484 62.82324 C 86.476543 62.82324 86.274547 62.898038 86.125322 63.047269 C 85.978161 63.1965 85.885462 63.400184 85.848202 63.659266 L 87.505669 63.659266 C 87.505669 63.53698 87.487799 63.425367 87.452579 63.323805 C 87.417355 63.220172 87.366689 63.132071 87.300309 63.059521 C 87.234005 62.984905 87.152123 62.927125 87.054693 62.885665 C 86.959363 62.844205 86.851697 62.82324 86.731484 62.82324 z M 100.4667 62.851243 C 100.32898 62.854273 100.20753 62.880257 100.10265 62.928837 C 99.992812 62.980657 99.900155 63.055446 99.825535 63.152866 C 99.753021 63.25028 99.698263 63.369557 99.661013 63.510497 C 99.625793 63.651437 99.607923 63.812072 99.607923 63.992393 C 99.607923 64.172714 99.625793 64.33335 99.661013 64.47429 C 99.698348 64.61523 99.753055 64.733916 99.825535 64.831336 C 99.900126 64.928751 99.992812 65.003546 100.10265 65.055366 C 100.21458 65.105106 100.34489 65.130042 100.49412 65.130042 C 100.64129 65.130042 100.76991 65.105106 100.87976 65.055366 C 100.98961 65.003547 101.08078 64.928746 101.15338 64.831336 C 101.22791 64.733922 101.2827 64.61523 101.3179 64.47429 C 101.3553 64.33335 101.3739 64.172714 101.3739 63.992393 C 101.3739 63.812072 101.3553 63.651437 101.3179 63.510497 C 101.28267 63.369557 101.22798 63.250286 101.15338 63.152866 C 101.08082 63.05545 100.98961 62.980657 100.87976 62.928837 C 100.76991 62.877027 100.64129 62.851243 100.49412 62.851243 C 100.48482 62.851243 100.4757 62.851041 100.4667 62.851243 z M 83.472557 62.857661 C 83.317471 62.862277 83.179975 62.90167 83.059503 62.97551 C 82.93307 63.054271 82.816878 63.166469 82.711207 63.311554 L 82.711207 64.778829 C 82.806559 64.909407 82.91109 65.001476 83.025082 65.055366 C 83.139085 65.107186 83.264584 65.132959 83.401381 65.132959 C 83.681184 65.132959 83.895644 65.032384 84.044882 64.831336 C 84.194053 64.630291 84.268911 64.330835 84.268911 63.932885 C 84.268911 63.563954 84.202612 63.292548 84.069969 63.118445 C 83.937316 62.94434 83.748629 62.857661 83.504061 62.857661 C 83.493561 62.857661 83.482717 62.857353 83.472557 62.857661 z M 93.702648 64.144663 C 93.460148 64.155023 93.253615 64.175414 93.083651 64.206504 C 92.913697 64.235527 92.774913 64.275197 92.667096 64.324937 C 92.561391 64.37468 92.484871 64.433903 92.437233 64.502293 C 92.389593 64.568616 92.365473 64.642829 92.365473 64.725739 C 92.365473 64.804499 92.377971 64.873071 92.402811 64.931099 C 92.42968 64.987058 92.464939 65.033808 92.508409 65.071118 C 92.551962 65.106348 92.604009 65.132968 92.664179 65.151628 C 92.724308 65.168218 92.788284 65.176715 92.856704 65.176715 C 92.947902 65.176715 93.032077 65.167361 93.108737 65.148711 C 93.185428 65.130051 93.257929 65.104278 93.326349 65.071118 C 93.394764 65.03588 93.458814 64.993091 93.518874 64.943351 C 93.581034 64.891532 93.64248 64.834582 93.702648 64.772412 L 93.702648 64.144663 z M 75.910982 68.701094 L 76.458221 68.701094 L 76.458221 73.122174 L 76.131511 73.122174 C 76.092111 73.122174 76.060198 73.113667 76.035248 73.097087 C 76.010298 73.078437 75.995993 73.049549 75.991493 73.010159 L 75.935485 72.646111 C 75.806986 72.80156 75.661089 72.927072 75.497345 73.02241 C 75.333611 73.117745 75.144085 73.165346 74.92852 73.165346 C 74.756488 73.165346 74.599815 73.132496 74.458875 73.066166 C 74.320001 72.997767 74.200705 72.898034 74.101245 72.76746 C 74.00176 72.636884 73.925231 72.475404 73.871381 72.282647 C 73.817531 72.087817 73.790287 71.864007 73.790287 71.611142 C 73.790287 71.387295 73.819769 71.179066 73.877799 70.98631 C 73.937939 70.79148 74.023785 70.623186 74.135666 70.482244 C 74.247592 70.341303 74.383295 70.23053 74.542886 70.1497 C 74.704554 70.068872 74.887002 70.028351 75.090124 70.028351 C 75.274586 70.028351 75.432111 70.059517 75.562686 70.121697 C 75.693262 70.181803 75.809375 70.269067 75.910982 70.383064 L 75.910982 68.701094 z M 96.764383 68.701094 L 97.311622 68.701094 L 97.311622 70.513748 C 97.435989 70.36659 97.577909 70.250431 97.737511 70.165453 C 97.897102 70.0784 98.080972 70.034769 98.28825 70.034769 C 98.464414 70.034769 98.622789 70.069049 98.763729 70.137449 C 98.904669 70.20585 99.024816 70.304151 99.124276 70.432654 C 99.22376 70.561158 99.299403 70.717833 99.351223 70.902299 C 99.405071 71.084693 99.432316 71.291493 99.432316 71.523631 C 99.432316 71.770276 99.402058 71.99467 99.341888 72.195719 C 99.28176 72.396766 99.195902 72.569284 99.084021 72.71437 C 98.972095 72.857384 98.836403 72.968737 98.676801 73.047497 C 98.51721 73.126255 98.337877 73.165346 98.138897 73.165346 C 97.939928 73.165346 97.77305 73.127941 97.638331 73.053331 C 97.505688 72.976643 97.387257 72.871263 97.283618 72.73654 L 97.252697 73.006658 C 97.244422 73.083344 97.199926 73.122174 97.119096 73.122174 L 96.764383 73.122174 L 96.764383 68.701094 z M 79.157074 69.096062 C 79.161474 69.09577 79.164826 69.096062 79.169326 69.096062 L 79.449363 69.096062 L 79.449363 70.137449 L 80.285389 70.137449 L 80.285389 70.535334 L 79.449363 70.535334 L 79.449363 72.350906 C 79.449363 72.475266 79.477374 72.568764 79.533374 72.630942 C 79.591403 72.693142 79.6656 72.723705 79.75682 72.723705 C 79.810722 72.723705 79.856551 72.716628 79.893921 72.702118 C 79.933201 72.687598 79.966121 72.671179 79.993101 72.652529 C 80.020081 72.633869 80.04273 72.617449 80.06136 72.602939 C 80.08202 72.588469 80.100767 72.580769 80.117367 72.580769 C 80.135997 72.580769 80.150963 72.585404 80.161123 72.593604 C 80.173543 72.601904 80.185384 72.61521 80.195544 72.63386 L 80.357148 72.895227 C 80.263874 72.982278 80.153944 73.049407 80.027522 73.097087 C 79.901078 73.144757 79.769339 73.168846 79.632553 73.168846 L 79.632553 73.168263 C 79.39834 73.168263 79.217582 73.101126 79.091149 72.966403 C 78.964759 72.83168 78.901541 72.639036 78.901541 72.388244 L 78.901541 70.535334 L 78.553829 70.535334 C 78.522779 70.535334 78.495545 70.525144 78.472735 70.504414 C 78.451965 70.483684 78.441814 70.453365 78.441814 70.413985 L 78.441814 70.196373 L 78.92021 70.133948 L 79.047977 69.198159 C 79.052497 69.167069 79.064885 69.142133 79.085315 69.123483 C 79.105295 69.107123 79.129194 69.098062 79.157074 69.096062 z M 63.198482 70.028351 C 63.372591 70.028351 63.530104 70.062631 63.671044 70.131031 C 63.811984 70.197353 63.932131 70.295657 64.031591 70.426237 C 64.131075 70.556814 64.207606 70.718877 64.261454 70.911634 C 64.315304 71.10439 64.342548 71.326774 64.342548 71.579638 C 64.342548 71.803486 64.31229 72.013142 64.25212 72.20797 C 64.19198 72.400726 64.105294 72.568441 63.991336 72.711453 C 63.879411 72.852394 63.742283 72.963167 63.580615 73.043997 C 63.418947 73.124826 63.2365 73.165346 63.033377 73.165346 C 62.848915 73.165346 62.691391 73.13418 62.560815 73.072 C 62.430239 73.009824 62.314708 72.923142 62.213103 72.811216 L 62.213103 73.646659 L 61.665864 73.646659 L 61.665864 70.081441 L 61.99199 70.081441 C 62.03139 70.081441 62.063303 70.090795 62.088253 70.109445 C 62.113083 70.126025 62.127509 70.154076 62.132009 70.193456 L 62.185099 70.547586 C 62.313598 70.392136 62.460346 70.266627 62.626157 70.171287 C 62.791968 70.075952 62.982929 70.028351 63.198482 70.028351 z M 86.740819 70.028351 C 86.910774 70.028351 87.062058 70.056402 87.194712 70.112362 C 87.327354 70.166252 87.438175 70.244164 87.527255 70.345726 C 87.61633 70.447287 87.683505 70.568252 87.729115 70.70919 C 87.776755 70.850131 87.800875 71.006807 87.800875 71.178835 L 87.800875 73.122174 L 87.558176 73.122174 C 87.504251 73.122174 87.46292 73.113677 87.43391 73.097087 C 87.4049 73.080508 87.385145 73.046227 87.374985 72.994407 L 87.306143 72.711453 C 87.227386 72.784 87.150022 72.849449 87.073362 72.907479 C 86.998774 72.963435 86.92006 73.011024 86.837082 73.050414 C 86.754182 73.089794 86.664696 73.118682 86.569296 73.137342 C 86.473955 73.158102 86.369414 73.168263 86.255422 73.168263 C 86.137276 73.168263 86.026517 73.153264 85.922878 73.122174 C 85.821316 73.089012 85.730976 73.039151 85.652176 72.972821 C 85.575452 72.90442 85.514595 72.820276 85.468985 72.720788 C 85.425405 72.619227 85.403644 72.499951 85.403644 72.363157 C 85.403644 72.242942 85.435666 72.128211 85.499906 72.018362 C 85.56621 71.906439 85.673014 71.806706 85.820198 71.719656 C 85.967358 71.632604 86.159161 71.562352 86.39544 71.508462 C 86.631721 71.452492 86.921836 71.420399 87.265888 71.412199 L 87.265888 71.178835 C 87.265888 70.942555 87.215112 70.765491 87.113618 70.647349 C 87.014122 70.527136 86.868237 70.467075 86.675477 70.467075 C 86.546978 70.467075 86.437957 70.483505 86.348767 70.516665 C 86.261715 70.549822 86.186061 70.585801 86.121821 70.625179 C 86.057549 70.664541 86.001439 70.701117 85.953799 70.734277 C 85.90818 70.767427 85.862004 70.783867 85.814364 70.783867 C 85.776994 70.783867 85.744498 70.774523 85.717518 70.755863 C 85.690528 70.737213 85.668776 70.713717 85.652176 70.684687 L 85.552996 70.510248 C 85.720885 70.34858 85.90106 70.22846 86.093817 70.1497 C 86.288654 70.068873 86.504526 70.028351 86.740819 70.028351 z M 107.0254 70.028351 C 107.08968 70.028351 107.15025 70.036011 107.20625 70.050521 C 107.26223 70.062951 107.31292 70.084189 107.35852 70.115279 L 107.31477 70.519582 C 107.30887 70.571392 107.27994 70.597176 107.22784 70.597176 C 107.19888 70.597176 107.15757 70.592397 107.10357 70.582007 C 107.05178 70.569537 106.99333 70.563338 106.92913 70.563338 C 106.83586 70.563338 106.7532 70.5775 106.6806 70.60651 C 106.61016 70.633459 106.54606 70.6754 106.48808 70.73136 C 106.43212 70.78525 106.38222 70.851543 106.33872 70.930303 C 106.29527 71.009064 106.25477 71.09886 106.21737 71.200422 L 106.21737 73.122174 L 105.67013 73.122174 L 105.67013 70.081441 L 105.98401 70.081441 C 106.04206 70.081441 106.08256 70.092489 106.10536 70.115279 C 106.13016 70.138074 106.14411 70.176904 106.14911 70.230794 L 106.18645 70.67827 C 106.27972 70.477223 106.39447 70.31886 106.53125 70.202791 C 106.66805 70.086721 106.83264 70.028351 107.0254 70.028351 z M 115.25848 70.028351 C 115.32276 70.028351 115.38285 70.036011 115.43875 70.050521 C 115.49472 70.062951 115.54542 70.084189 115.59102 70.115279 L 115.54726 70.519582 C 115.54136 70.571392 115.51233 70.597176 115.46033 70.597176 C 115.43127 70.597176 115.38997 70.592397 115.33607 70.582007 C 115.28429 70.569537 115.22641 70.563338 115.16221 70.563338 C 115.06894 70.563338 114.9857 70.5775 114.9131 70.60651 C 114.84265 70.633459 114.77857 70.6754 114.72057 70.73136 C 114.66461 70.78525 114.61482 70.851543 114.57122 70.930303 C 114.52767 71.009064 114.48727 71.09886 114.44987 71.200422 L 114.44987 73.122174 L 113.90321 73.122174 L 113.90321 70.081441 L 114.21709 70.081441 C 114.27514 70.081441 114.31564 70.092489 114.33844 70.115279 C 114.36324 70.138074 114.37661 70.176904 114.38161 70.230794 L 114.41895 70.67827 C 114.51221 70.477223 114.62753 70.31886 114.76433 70.202791 C 114.90113 70.086721 115.06572 70.028351 115.25848 70.028351 z M 57.083763 70.034769 C 57.266159 70.034769 57.434704 70.064504 57.590163 70.124614 C 57.74561 70.18472 57.880474 70.27283 57.994466 70.388898 C 58.108469 70.504967 58.198011 70.646903 58.262251 70.814788 C 58.326601 70.982672 58.358514 71.175901 58.358514 71.39353 C 58.358514 71.478509 58.34914 71.535449 58.33051 71.564469 C 58.311774 71.591419 58.27762 71.604725 58.22783 71.604725 L 56.194647 71.604725 C 56.198377 71.795407 56.22426 71.962276 56.27224 72.10529 C 56.319882 72.246231 56.385286 72.363223 56.468266 72.456503 C 56.553244 72.549772 56.653809 72.620601 56.769889 72.668281 C 56.885947 72.713871 57.015434 72.73654 57.15844 72.73654 C 57.291094 72.73654 57.405805 72.721804 57.503235 72.692784 C 57.600654 72.661695 57.683348 72.627414 57.751768 72.590104 C 57.822213 72.552794 57.881484 72.519944 57.929124 72.490924 C 57.97673 72.459834 58.01817 72.444251 58.05339 72.444251 C 58.0762 72.444251 58.096298 72.44903 58.112898 72.45942 C 58.129388 72.4677 58.143541 72.480178 58.156071 72.496758 L 58.311841 72.695701 C 58.243426 72.776535 58.162392 72.847369 58.069142 72.907479 C 57.977946 72.965522 57.879608 73.013951 57.773937 73.053331 C 57.668232 73.090631 57.558301 73.118692 57.444311 73.137342 C 57.332385 73.155942 57.221616 73.165346 57.111767 73.165346 C 56.900357 73.165346 56.705442 73.130219 56.52719 73.059749 C 56.348948 72.989279 56.194551 72.885588 56.063963 72.748791 C 55.935465 72.609924 55.83493 72.439939 55.76234 72.238891 C 55.689861 72.035771 55.653242 71.802609 55.653242 71.539383 C 55.653242 71.327972 55.685848 71.131365 55.750088 70.948972 C 55.816392 70.764505 55.910741 70.604715 56.033042 70.469992 C 56.157408 70.333198 56.307271 70.22639 56.483435 70.1497 C 56.661686 70.073011 56.861988 70.034769 57.083763 70.034769 z M 66.252049 70.034769 C 66.473823 70.034769 66.673553 70.072173 66.851794 70.146783 C 67.030047 70.219324 67.18132 70.323859 67.305687 70.460658 C 67.430043 70.595379 67.525761 70.759133 67.592141 70.951889 C 67.660554 71.144646 67.694821 71.359951 67.694821 71.598307 C 67.694821 71.838735 67.660561 72.055468 67.592141 72.248226 C 67.525836 72.440981 67.430054 72.605579 67.305687 72.742374 C 67.18132 72.877096 67.030047 72.982222 66.851794 73.056832 C 66.673553 73.129378 66.473823 73.165346 66.252049 73.165346 C 66.030275 73.165346 65.829121 73.129372 65.648803 73.056832 C 65.47055 72.982215 65.318426 72.877095 65.191993 72.742374 C 65.067637 72.605579 64.971042 72.440981 64.902622 72.248226 C 64.836232 72.055468 64.803442 71.838735 64.803442 71.598307 C 64.803442 71.359951 64.836352 71.144646 64.902622 70.951889 C 64.971038 70.759133 65.067649 70.595379 65.191993 70.460658 C 65.318426 70.323861 65.47055 70.219333 65.648803 70.146783 C 65.829121 70.072167 66.030275 70.034769 66.252049 70.034769 z M 69.209353 70.034769 C 69.219623 70.034583 69.230114 70.034769 69.240274 70.034769 C 69.42889 70.034769 69.600305 70.065934 69.753675 70.128114 C 69.907045 70.19029 70.037327 70.276975 70.145143 70.388898 L 70.023793 70.584924 C 69.998959 70.630524 69.961569 70.653183 69.911779 70.653183 C 69.880623 70.653183 69.846469 70.642135 69.809099 70.619345 C 69.773838 70.596545 69.730818 70.572456 69.678998 70.547586 C 69.629245 70.520636 69.568591 70.495699 69.498141 70.472909 C 69.429726 70.450141 69.347806 70.439072 69.252526 70.439072 C 69.171692 70.439072 69.099154 70.450121 69.034914 70.472909 C 68.970642 70.495699 68.916002 70.526865 68.870392 70.566255 C 68.824783 70.605638 68.789635 70.652373 68.764795 70.706273 C 68.739845 70.758093 68.727457 70.814187 68.727457 70.874295 C 68.727457 70.953056 68.747868 71.017918 68.789298 71.069738 C 68.830765 71.121552 68.885983 71.166622 68.954403 71.203922 C 69.022818 71.241225 69.100727 71.274929 69.187767 71.306019 C 69.276899 71.335029 69.366666 71.365357 69.457886 71.396447 C 69.549084 71.427543 69.638631 71.463523 69.725671 71.504961 C 69.814791 71.54642 69.893532 71.597705 69.961952 71.657815 C 70.030395 71.717921 70.085044 71.791294 70.126474 71.878344 C 70.167904 71.963323 70.188898 72.067014 70.188898 72.189301 C 70.188898 72.330243 70.164779 72.460556 70.117139 72.580769 C 70.069496 72.698911 69.999195 72.80175 69.905945 72.88881 C 69.814747 72.975861 69.700863 73.04443 69.564066 73.09417 C 69.429349 73.14391 69.273512 73.168263 69.097339 73.168263 C 68.896293 73.168263 68.713006 73.134566 68.547183 73.066166 C 68.383449 72.997766 68.24463 72.908229 68.130629 72.798381 L 68.257812 72.593604 C 68.274412 72.566664 68.29451 72.545689 68.31732 72.531179 C 68.34013 72.516689 68.369028 72.509593 68.404248 72.509593 C 68.441617 72.509593 68.478419 72.523756 68.515679 72.552766 C 68.552987 72.579696 68.598043 72.610871 68.649863 72.646111 C 68.70376 72.679261 68.767769 72.710447 68.842389 72.739457 C 68.916966 72.766407 69.010432 72.779712 69.122425 72.779712 C 69.217778 72.779712 69.299631 72.766407 69.368041 72.739457 C 69.438489 72.712515 69.496287 72.677378 69.541897 72.63386 C 69.587623 72.588264 69.621767 72.535282 69.644577 72.475172 C 69.667377 72.415065 69.678998 72.351894 69.678998 72.285564 C 69.678998 72.202657 69.657126 72.134084 69.613656 72.080204 C 69.572178 72.024248 69.516971 71.978079 69.448551 71.940769 C 69.380136 71.90139 69.30134 71.867117 69.21227 71.838089 C 69.125226 71.809069 69.035402 71.77875 68.942152 71.74766 C 68.850954 71.714493 68.760519 71.678536 68.671449 71.639146 C 68.584396 71.597691 68.506504 71.545555 68.438086 71.483375 C 68.369659 71.419122 68.314117 71.341211 68.270647 71.250011 C 68.229217 71.158814 68.208222 71.048047 68.208222 70.917468 C 68.208222 70.799326 68.230871 70.687712 68.276481 70.582007 C 68.322091 70.474229 68.388384 70.379883 68.475424 70.299053 C 68.562479 70.21822 68.670717 70.153625 68.799216 70.105945 C 68.919699 70.061255 69.056085 70.037569 69.209353 70.034769 z M 72.078563 70.034769 C 72.260959 70.034769 72.429515 70.064504 72.584963 70.124614 C 72.740408 70.18472 72.875263 70.272829 72.989266 70.388898 C 73.103258 70.504967 73.192227 70.646902 73.256467 70.814788 C 73.320697 70.982671 73.353313 71.175901 73.353313 71.39353 C 73.353313 71.478509 73.34394 71.535459 73.32531 71.564469 C 73.306574 71.591419 73.27242 71.604725 73.22263 71.604725 L 71.189446 71.604725 C 71.193166 71.795407 71.21906 71.962276 71.26704 72.10529 C 71.314682 72.246232 71.380086 72.363233 71.463066 72.456503 C 71.548041 72.549772 71.648036 72.620601 71.764105 72.668281 C 71.880174 72.713871 72.010222 72.73654 72.153239 72.73654 C 72.285893 72.73654 72.400605 72.721794 72.498035 72.692784 C 72.595451 72.661694 72.678147 72.627414 72.746567 72.590104 C 72.817015 72.552794 72.876284 72.519944 72.923924 72.490924 C 72.971529 72.459834 73.01297 72.444251 73.04819 72.444251 C 73.071 72.444251 73.091098 72.44903 73.107698 72.45942 C 73.124188 72.4677 73.13834 72.480178 73.15087 72.496758 L 73.306641 72.695701 C 73.238226 72.776535 73.157192 72.847369 73.063942 72.907479 C 72.972744 72.965522 72.874408 73.013951 72.768737 73.053331 C 72.663032 73.090631 72.553102 73.118692 72.43911 73.137342 C 72.327184 73.155942 72.216414 73.165346 72.106567 73.165346 C 71.895157 73.165346 71.700242 73.130219 71.52199 73.059749 C 71.343748 72.989279 71.18935 72.885588 71.058762 72.748791 C 70.930265 72.609924 70.82973 72.439939 70.75714 72.238891 C 70.684662 72.035771 70.648042 71.802609 70.648042 71.539383 C 70.648042 71.327972 70.680648 71.131365 70.744888 70.948972 C 70.811203 70.764505 70.90553 70.604715 71.027842 70.469992 C 71.152198 70.333198 71.302059 70.22639 71.478234 70.1497 C 71.656475 70.073011 71.856789 70.034769 72.078563 70.034769 z M 82.049037 70.034769 C 82.270811 70.034769 82.471113 70.072173 82.649366 70.146783 C 82.827607 70.219324 82.978904 70.323859 83.103259 70.460658 C 83.227613 70.595379 83.322859 70.759133 83.389129 70.951889 C 83.457655 71.144646 83.49181 71.359951 83.49181 71.598307 C 83.49181 71.838735 83.457549 72.055468 83.389129 72.248226 C 83.322825 72.440981 83.227624 72.605579 83.103259 72.742374 C 82.978904 72.877096 82.827607 72.982222 82.649366 73.056832 C 82.471113 73.129378 82.270811 73.165346 82.049037 73.165346 C 81.827262 73.165346 81.626109 73.129372 81.445791 73.056832 C 81.267538 72.982215 81.115426 72.877095 80.988981 72.742374 C 80.864626 72.605579 80.76803 72.440981 80.69961 72.248226 C 80.63322 72.055468 80.60043 71.838735 80.60043 71.598307 C 80.60043 71.359951 80.63334 71.144646 80.69961 70.951889 C 80.768025 70.759133 80.864637 70.595379 80.988981 70.460658 C 81.115426 70.323861 81.267538 70.219333 81.445791 70.146783 C 81.626109 70.072167 81.827262 70.034769 82.049037 70.034769 z M 90.145015 70.034769 C 90.310826 70.034769 90.455883 70.06282 90.580239 70.11878 C 90.706672 70.172669 90.812604 70.249998 90.897614 70.35156 C 90.982558 70.451048 91.046559 70.572595 91.090139 70.715608 C 91.133719 70.856548 91.155481 71.013222 91.155481 71.185253 L 91.155481 73.122174 L 90.608243 73.122174 L 90.608243 71.185253 C 90.608243 70.959333 90.556111 70.783113 90.452472 70.656684 C 90.35091 70.530255 90.195661 70.467075 89.986328 70.467075 C 89.830869 70.467075 89.685824 70.503897 89.551104 70.578507 C 89.416385 70.651046 89.293102 70.75305 89.181222 70.88363 L 89.181222 73.122174 L 88.633984 73.122174 L 88.633984 70.081441 L 88.960693 70.081441 C 89.000093 70.081441 89.032006 70.090795 89.056956 70.109445 C 89.081796 70.126025 89.095628 70.154076 89.100128 70.193456 L 89.146801 70.516665 C 89.277377 70.37158 89.423857 70.255428 89.585525 70.16837 C 89.747193 70.079249 89.933605 70.034769 90.145015 70.034769 z M 94.65594 70.034769 C 94.877714 70.034769 95.078016 70.072173 95.256269 70.146783 C 95.434521 70.219324 95.585807 70.323859 95.710162 70.460658 C 95.834529 70.595379 95.929653 70.759133 95.996033 70.951889 C 96.064444 71.144646 96.098713 71.359951 96.098713 71.598307 C 96.098713 71.838735 96.064451 72.055468 95.996033 72.248226 C 95.929729 72.440981 95.834552 72.605579 95.710162 72.742374 C 95.585807 72.877096 95.434521 72.982222 95.256269 73.056832 C 95.078016 73.129378 94.877714 73.165346 94.65594 73.165346 C 94.434166 73.165346 94.233596 73.129372 94.053278 73.056832 C 93.875037 72.982215 93.722317 72.877095 93.595884 72.742374 C 93.471531 72.605579 93.375517 72.440981 93.307097 72.248226 C 93.240717 72.055468 93.207334 71.838735 93.207334 71.598307 C 93.207334 71.359951 93.240827 71.144646 93.307097 70.951889 C 93.375512 70.759133 93.471553 70.595379 93.595884 70.460658 C 93.722317 70.323861 93.875037 70.219333 94.053278 70.146783 C 94.233596 70.072167 94.434166 70.034769 94.65594 70.034769 z M 100.91826 70.034769 C 100.92846 70.034583 100.93898 70.034769 100.94918 70.034769 C 101.13779 70.034769 101.30862 70.065934 101.462 70.128114 C 101.61537 70.19029 101.74624 70.276975 101.85405 70.388898 L 101.7327 70.584924 C 101.70791 70.630524 101.67049 70.653183 101.62069 70.653183 C 101.58955 70.653183 101.55541 70.642135 101.51801 70.619345 C 101.48282 70.596545 101.43912 70.572456 101.38732 70.547586 C 101.33757 70.520636 101.27745 70.495699 101.20705 70.472909 C 101.13863 70.450141 101.05673 70.439072 100.96143 70.439072 C 100.8806 70.439072 100.80802 70.450121 100.74382 70.472909 C 100.67955 70.495699 100.6249 70.526865 100.5793 70.566255 C 100.53374 70.605638 100.4985 70.652373 100.4737 70.706273 C 100.4488 70.758093 100.43578 70.814187 100.43578 70.874295 C 100.43578 70.953056 100.45681 71.017918 100.49821 71.069738 C 100.53967 71.121552 100.59491 71.166622 100.66331 71.203922 C 100.73172 71.241225 100.80909 71.274929 100.89609 71.306019 C 100.98521 71.335029 101.07559 71.365357 101.16679 71.396447 C 101.25799 71.427543 101.3469 71.463523 101.434 71.504961 C 101.52313 71.54642 101.60188 71.597705 101.67028 71.657815 C 101.73879 71.717921 101.79398 71.791294 101.83538 71.878344 C 101.87698 71.963323 101.89722 72.067014 101.89722 72.189301 C 101.89722 72.330243 101.87365 72.460556 101.82605 72.580769 C 101.77841 72.698911 101.70757 72.80175 101.61427 72.88881 C 101.52307 72.975861 101.40918 73.04443 101.27239 73.09417 C 101.13765 73.14391 100.98243 73.168263 100.80625 73.168263 C 100.60521 73.168263 100.42191 73.134566 100.25609 73.066166 C 100.09235 72.997766 99.952956 72.908229 99.838953 72.798381 L 99.96672 72.593604 C 99.98332 72.566664 100.00284 72.545689 100.02564 72.531179 C 100.04844 72.516689 100.07737 72.509593 100.11257 72.509593 C 100.14996 72.509593 100.18729 72.523756 100.22459 72.552766 C 100.26189 72.579696 100.30639 72.610871 100.35819 72.646111 C 100.41208 72.679261 100.4767 72.710447 100.5513 72.739457 C 100.62588 72.766407 100.71876 72.779712 100.83075 72.779712 C 100.92608 72.779712 101.00797 72.766407 101.07637 72.739457 C 101.14684 72.712515 101.2052 72.677378 101.2508 72.63386 C 101.29643 72.588264 101.33069 72.535282 101.35349 72.475172 C 101.37609 72.415065 101.38732 72.351894 101.38732 72.285564 C 101.38732 72.202657 101.36548 72.134084 101.32198 72.080204 C 101.28051 72.024248 101.22586 71.978079 101.15746 71.940769 C 101.08905 71.90139 101.01028 71.867117 100.92118 71.838089 C 100.83412 71.809069 100.74368 71.77875 100.65048 71.74766 C 100.55928 71.714493 100.46956 71.678536 100.38036 71.639146 C 100.29332 71.597691 100.21539 71.545555 100.14699 71.483375 C 100.07855 71.419122 100.02243 71.341211 99.978971 71.250011 C 99.937533 71.158814 99.91713 71.048047 99.91713 70.917468 C 99.91713 70.799326 99.939779 70.687712 99.985389 70.582007 C 100.03099 70.474229 100.09733 70.379883 100.18433 70.299053 C 100.27138 70.21822 100.37903 70.153625 100.50754 70.105945 C 100.62801 70.061255 100.765 70.037569 100.91826 70.034769 z M 103.74897 70.034769 C 103.93136 70.034769 104.10051 70.064504 104.25595 70.124614 C 104.4114 70.18472 104.54568 70.27283 104.65967 70.388898 C 104.77367 70.504967 104.86325 70.646903 104.92745 70.814788 C 104.99185 70.982672 105.02372 71.175901 105.02372 71.39353 C 105.02372 71.478509 105.01431 71.535449 104.99571 71.564469 C 104.97698 71.591419 104.94283 71.604725 104.89303 71.604725 L 102.85985 71.604725 C 102.86445 71.795407 102.89014 71.962276 102.93744 72.10529 C 102.98508 72.246231 103.05047 72.363223 103.13347 72.456503 C 103.21844 72.549772 103.31902 72.620601 103.43509 72.668281 C 103.55116 72.713871 103.68063 72.73654 103.82364 72.73654 C 103.95629 72.73654 104.07104 72.721804 104.16844 72.692784 C 104.26585 72.661695 104.34915 72.627414 104.41755 72.590104 C 104.48796 72.552794 104.54673 72.519944 104.59433 72.490924 C 104.64191 72.459834 104.68339 72.444251 104.71859 72.444251 C 104.74139 72.444251 104.7615 72.44903 104.7781 72.45942 C 104.7946 72.4677 104.80887 72.480178 104.82127 72.496758 L 104.97704 72.695701 C 104.90863 72.776535 104.82753 72.847369 104.73435 72.907479 C 104.64315 72.965522 104.54481 73.013951 104.43914 73.053331 C 104.33342 73.090631 104.22352 73.118692 104.10951 73.137342 C 103.99759 73.155942 103.88681 73.165346 103.77697 73.165346 C 103.56556 73.165346 103.37064 73.130219 103.19239 73.059749 C 103.01413 72.989279 102.85975 72.885588 102.72917 72.748791 C 102.60066 72.609924 102.50014 72.439939 102.42754 72.238891 C 102.35509 72.035771 102.31844 71.802609 102.31844 71.539383 C 102.31844 71.327972 102.35109 71.131365 102.41529 70.948972 C 102.4816 70.764505 102.57594 70.604715 102.69824 70.469992 C 102.8226 70.333198 102.97247 70.22639 103.14864 70.1497 C 103.3269 70.073011 103.5272 70.034769 103.74897 70.034769 z M 112.01355 70.034769 C 112.19595 70.034769 112.36508 70.064504 112.52053 70.124614 C 112.67598 70.18472 112.81025 70.27283 112.92425 70.388898 C 113.03824 70.504967 113.12784 70.646903 113.19204 70.814788 C 113.25644 70.982672 113.2883 71.175901 113.2883 71.39353 C 113.2883 71.478509 113.2789 71.535449 113.2603 71.564469 C 113.24156 71.591419 113.20742 71.604725 113.15762 71.604725 L 111.12443 71.604725 C 111.12903 71.795407 111.15473 71.962276 111.20203 72.10529 C 111.24968 72.246231 111.31505 72.363223 111.39805 72.456503 C 111.48303 72.549772 111.58361 72.620601 111.69968 72.668281 C 111.81573 72.713871 111.94521 72.73654 112.08823 72.73654 C 112.22088 72.73654 112.33562 72.721804 112.43302 72.692784 C 112.53044 72.661695 112.61374 72.627414 112.68214 72.590104 C 112.75257 72.552794 112.81121 72.519944 112.85891 72.490924 C 112.90656 72.459834 112.94856 72.444251 112.98376 72.444251 C 113.00656 72.444251 113.02608 72.44903 113.04268 72.45942 C 113.05928 72.4677 113.07394 72.480178 113.08644 72.496758 L 113.24163 72.695701 C 113.17322 72.776535 113.09213 72.847369 112.99893 72.907479 C 112.90773 72.965522 112.8094 73.013951 112.70372 73.053331 C 112.59803 73.090631 112.48809 73.118692 112.3741 73.137342 C 112.26217 73.155942 112.1514 73.165346 112.04155 73.165346 C 111.83014 73.165346 111.63523 73.130219 111.45698 73.059749 C 111.27873 72.989279 111.12432 72.885588 110.99375 72.748791 C 110.86525 72.609924 110.76473 72.439939 110.69213 72.238891 C 110.61954 72.035771 110.58361 71.802609 110.58361 71.539383 C 110.58361 71.327972 110.61567 71.131365 110.67987 70.948972 C 110.74617 70.764505 110.84052 70.604715 110.96283 70.469992 C 111.08719 70.333198 111.23762 70.22639 111.4138 70.1497 C 111.59204 70.073011 111.79178 70.034769 112.01355 70.034769 z M 58.594795 70.081441 L 59.116947 70.081441 C 59.158377 70.081441 59.188745 70.088518 59.207375 70.103028 C 59.228035 70.117538 59.246782 70.137082 59.263382 70.161952 L 59.897549 71.265763 C 59.905789 71.242963 59.914736 71.221152 59.922636 71.200422 C 59.933016 71.177622 59.946291 71.154953 59.962891 71.132163 L 60.494377 70.174787 C 60.513007 70.145777 60.532642 70.122525 60.553302 70.105945 C 60.573962 70.089345 60.598968 70.081441 60.627978 70.081441 L 61.128544 70.081441 L 60.220758 71.532965 L 61.169382 73.122174 L 60.64373 73.122174 C 60.602184 73.122174 60.56803 73.110542 60.54105 73.087752 C 60.5161 73.062882 60.495807 73.037109 60.479209 73.010159 L 59.835124 71.859675 C 59.818524 71.907345 59.799887 71.947864 59.779117 71.981024 L 59.198041 73.010159 C 59.181451 73.039169 59.160566 73.064952 59.135616 73.087752 C 59.112816 73.110542 59.08167 73.122174 59.04227 73.122174 L 58.554539 73.122174 L 59.499663 71.560969 L 58.594795 70.081441 z M 107.58255 70.081441 L 108.03294 70.081441 C 108.0744 70.081441 108.10954 70.092489 108.13854 70.115279 C 108.16754 70.138079 108.18785 70.164426 108.19805 70.193456 L 108.84738 72.139711 C 108.87438 72.212251 108.89763 72.282506 108.91623 72.350906 C 108.93483 72.419306 108.95213 72.488713 108.96873 72.559183 C 108.98313 72.490783 109.00031 72.422213 109.01891 72.353823 C 109.03961 72.283353 109.064 72.212261 109.093 72.139711 L 109.75225 70.193456 C 109.76465 70.162366 109.78418 70.136009 109.81118 70.115279 C 109.84038 70.092509 109.87282 70.081441 109.90802 70.081441 L 110.33975 70.081441 L 109.20852 73.122174 L 108.71378 73.122174 L 107.58255 70.081441 z M 57.092514 70.432654 C 56.837573 70.432654 56.635577 70.507451 56.486352 70.656684 C 56.339191 70.805912 56.247185 71.009598 56.209815 71.268681 L 57.866699 71.268681 C 57.866699 71.146394 57.849412 71.034782 57.814192 70.93322 C 57.778968 70.829587 57.728302 70.741485 57.661922 70.668935 C 57.595617 70.594319 57.513737 70.536529 57.416307 70.495079 C 57.320965 70.453629 57.212726 70.432654 57.092514 70.432654 z M 72.087314 70.432654 C 71.832382 70.432654 71.630378 70.507451 71.481151 70.656684 C 71.333991 70.805912 71.241985 71.009598 71.204615 71.268681 L 72.861499 71.268681 C 72.861499 71.146394 72.844212 71.034782 72.808992 70.93322 C 72.773768 70.829587 72.723102 70.741485 72.656722 70.668935 C 72.590418 70.594319 72.508536 70.536529 72.411106 70.495079 C 72.315778 70.453629 72.207538 70.432654 72.087314 70.432654 z M 103.75772 70.432654 C 103.50279 70.432654 103.30077 70.507451 103.15155 70.656684 C 103.00439 70.805912 102.91242 71.009598 102.87502 71.268681 L 104.5319 71.268681 C 104.5319 71.146394 104.51459 71.034782 104.47939 70.93322 C 104.44419 70.829587 104.39351 70.741485 104.32713 70.668935 C 104.26081 70.594319 104.17891 70.536529 104.08151 70.495079 C 103.98617 70.453629 103.87793 70.432654 103.75772 70.432654 z M 112.02288 70.432654 C 111.76795 70.432654 111.56537 70.507451 111.41614 70.656684 C 111.26898 70.805912 111.1769 71.009598 111.1396 71.268681 L 112.79649 71.268681 C 112.79649 71.146394 112.77918 71.034782 112.74398 70.93322 C 112.70876 70.829587 112.65811 70.741485 112.59171 70.668935 C 112.52541 70.594319 112.44349 70.536529 112.34609 70.495079 C 112.25075 70.453629 112.14309 70.432654 112.02288 70.432654 z M 75.214391 70.448406 C 74.93872 70.448406 74.726534 70.54898 74.577307 70.750029 C 74.428125 70.951077 74.353278 71.238064 74.353278 71.611142 C 74.353278 71.808045 74.369678 71.976601 74.402868 72.117542 C 74.438091 72.258483 74.487981 72.374639 74.552221 72.465837 C 74.616493 72.554964 74.695252 72.62126 74.788502 72.66478 C 74.881764 72.70623 74.987731 72.727205 75.105877 72.727205 C 75.277907 72.727205 75.426919 72.687533 75.553352 72.608773 C 75.681851 72.527939 75.801133 72.416326 75.910982 72.273312 L 75.910982 70.802536 C 75.813575 70.671958 75.70761 70.580737 75.593607 70.528917 C 75.479615 70.475027 75.353254 70.448406 75.214391 70.448406 z M 66.224045 70.460658 C 66.086322 70.463688 65.964878 70.489671 65.859997 70.538251 C 65.750151 70.590071 65.658091 70.664871 65.583461 70.762281 C 65.510947 70.859696 65.4562 70.97897 65.41894 71.119911 C 65.38372 71.260851 65.365849 71.421487 65.365849 71.601808 C 65.365849 71.782128 65.38372 71.942763 65.41894 72.083704 C 65.456275 72.224644 65.510981 72.343914 65.583461 72.441334 C 65.658041 72.538749 65.750151 72.61296 65.859997 72.66478 C 65.971923 72.71452 66.102811 72.739457 66.252049 72.739457 C 66.39921 72.739457 66.527834 72.71452 66.637683 72.66478 C 66.747542 72.61296 66.838712 72.538744 66.911302 72.441334 C 66.985846 72.343919 67.040604 72.224644 67.075824 72.083704 C 67.113192 71.942763 67.131831 71.782128 67.131831 71.601808 C 67.131831 71.421487 67.113192 71.260851 67.075824 71.119911 C 67.0406 70.97897 66.985922 70.859701 66.911302 70.762281 C 66.838755 70.664866 66.747531 70.590071 66.637683 70.538251 C 66.527834 70.486431 66.39921 70.460658 66.252049 70.460658 C 66.242679 70.460658 66.233045 70.460454 66.224045 70.460658 z M 82.021033 70.460658 C 81.883311 70.463688 81.76245 70.489671 81.657569 70.538251 C 81.547709 70.590071 81.455069 70.664871 81.380449 70.762281 C 81.307935 70.859696 81.253188 70.97897 81.215928 71.119911 C 81.180708 71.260851 81.162837 71.421487 81.162837 71.601808 C 81.162837 71.782128 81.180708 71.942763 81.215928 72.083704 C 81.253263 72.224644 81.307969 72.343914 81.380449 72.441334 C 81.45504 72.538749 81.54772 72.61296 81.657569 72.66478 C 81.769483 72.71452 81.89981 72.739457 82.049037 72.739457 C 82.196197 72.739457 82.324823 72.71452 82.434671 72.66478 C 82.54452 72.61296 82.6357 72.538744 82.70829 72.441334 C 82.782835 72.343919 82.837592 72.224644 82.872812 72.083704 C 82.910182 71.942763 82.928819 71.782128 82.928819 71.601808 C 82.928819 71.421487 82.910182 71.260851 82.872812 71.119911 C 82.837588 70.97897 82.78291 70.859701 82.70829 70.762281 C 82.635732 70.664866 82.54452 70.590071 82.434671 70.538251 C 82.324811 70.486431 82.196197 70.460658 82.049037 70.460658 C 82.039667 70.460658 82.030033 70.460454 82.021033 70.460658 z M 94.62852 70.460658 C 94.490798 70.463688 94.369353 70.489671 94.264472 70.538251 C 94.154612 70.590071 94.062556 70.664871 93.987936 70.762281 C 93.915416 70.859696 93.860091 70.97897 93.822831 71.119911 C 93.787601 71.260851 93.770324 71.421487 93.770324 71.601808 C 93.770324 71.782128 93.787611 71.942763 93.822831 72.083704 C 93.860165 72.224644 93.915456 72.343914 93.987936 72.441334 C 94.062526 72.538749 94.154623 72.61296 94.264472 72.66478 C 94.376386 72.71452 94.506702 72.739457 94.65594 72.739457 C 94.803101 72.739457 94.931726 72.71452 95.041574 72.66478 C 95.151423 72.61296 95.242603 72.538744 95.315193 72.441334 C 95.389764 72.343919 95.445078 72.224644 95.480298 72.083704 C 95.517668 71.942763 95.536306 71.782128 95.536306 71.601808 C 95.536306 71.421487 95.517668 71.260851 95.480298 71.119911 C 95.445074 70.97897 95.389813 70.859701 95.315193 70.762281 C 95.242645 70.664866 95.151423 70.590071 95.041574 70.538251 C 94.931726 70.486431 94.803101 70.460658 94.65594 70.460658 C 94.64657 70.460658 94.63752 70.460454 94.62852 70.460658 z M 62.986121 70.467075 C 62.829104 70.47169 62.689645 70.511084 62.567232 70.584924 C 62.438721 70.663684 62.320336 70.775881 62.212519 70.920968 L 62.212519 72.388244 C 62.307872 72.518821 62.412985 72.61089 62.526977 72.66478 C 62.643046 72.7166 62.771671 72.742374 62.912611 72.742374 C 63.190348 72.742374 63.403385 72.642382 63.552612 72.441334 C 63.703915 72.240286 63.779558 71.952716 63.779558 71.579638 C 63.779558 71.382736 63.762271 71.214179 63.727051 71.073238 C 63.693859 70.932297 63.643968 70.81698 63.577698 70.72786 C 63.513426 70.636665 63.43378 70.570367 63.3385 70.528917 C 63.245237 70.487467 63.138432 70.467075 63.018208 70.467075 C 63.007598 70.467075 62.996281 70.466768 62.986121 70.467075 z M 98.073555 70.467075 C 97.918469 70.47169 97.780389 70.511094 97.659917 70.584924 C 97.533486 70.663684 97.417293 70.775881 97.311622 70.920968 L 97.311622 72.388244 C 97.406974 72.518821 97.512089 72.6109 97.62608 72.66478 C 97.740072 72.7166 97.864999 72.742374 98.001796 72.742374 C 98.281597 72.742374 98.496059 72.642383 98.645297 72.441334 C 98.794466 72.240287 98.869326 71.940248 98.869326 71.5423 C 98.869326 71.173367 98.803026 70.901961 98.670383 70.72786 C 98.53773 70.553756 98.349042 70.467075 98.104476 70.467075 C 98.093976 70.467075 98.083715 70.466768 98.073555 70.467075 z M 87.265888 71.754077 C 87.023386 71.764447 86.817427 71.784829 86.647473 71.815919 C 86.477518 71.844931 86.338735 71.884611 86.230919 71.934351 C 86.125214 71.984093 86.048112 72.043308 86.000472 72.111708 C 85.952822 72.178031 85.929296 72.252244 85.929296 72.335154 C 85.929296 72.413915 85.941684 72.482484 85.966634 72.540514 C 85.993503 72.596473 86.028761 72.643222 86.072231 72.680532 C 86.115763 72.715772 86.167248 72.742393 86.227418 72.761043 C 86.287558 72.777633 86.352107 72.786129 86.420527 72.786129 C 86.511725 72.786129 86.595317 72.776786 86.671977 72.758126 C 86.748654 72.739466 86.821168 72.713692 86.889588 72.680532 C 86.958003 72.645295 87.022637 72.602516 87.082697 72.552766 C 87.144869 72.500946 87.205828 72.443996 87.265888 72.381826 L 87.265888 71.754077 z " /> - - Service behavior - exposed to an observer - + id="path970" + clip-path="none" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.398274" + d="M 81.849511 39.122799 C 81.372229 39.122799 80.918538 39.257887 80.519336 39.488013 C 80.118686 39.718571 79.777727 40.048598 79.545042 40.452973 C 79.312454 40.856375 79.191496 41.31786 79.191496 41.781397 L 79.191496 45.462713 L 79.179827 51.603685 C 79.179827 52.081332 79.315011 52.534385 79.545042 52.93386 C 79.775634 53.334597 80.105329 53.674875 80.510002 53.908154 C 80.913509 54.140086 81.374161 54.2617 81.837843 54.2617 L 123.24827 54.2617 L 142.0469 54.2617 L 152.12706 54.2617 C 152.60434 54.2617 153.0577 54.12656 153.45723 53.896486 C 153.85798 53.6659 154.19861 53.338645 154.43153 52.93386 C 154.66393 52.530286 154.78683 52.067354 154.78683 51.603685 L 154.78683 45.654072 L 204.99974 44.417826 L 205.01374 44.417826 L 205.01783 44.023441 L 205.00383 44.023441 L 154.73257 41.590039 C 154.69837 41.19252 154.61718 40.801491 154.42219 40.462891 C 154.19161 40.062148 153.86202 39.720928 153.45723 39.488013 C 153.05357 39.255561 152.59061 39.13505 152.12706 39.13505 L 142.0469 39.13505 L 123.24827 39.13505 L 81.849511 39.122799 z M 115.3454 41.018297 L 115.89264 41.018297 L 115.89264 42.830951 C 116.017 42.683794 116.15894 42.567634 116.31853 42.482656 C 116.47812 42.395604 116.66142 42.351972 116.86869 42.351972 C 117.04487 42.351972 117.20323 42.386254 117.34417 42.454652 C 117.48511 42.52305 117.60523 42.621936 117.70471 42.750441 C 117.8042 42.878945 117.88042 43.035038 117.93224 43.219502 C 117.98611 43.401896 118.01275 43.609282 118.01275 43.841417 C 118.01275 44.088064 117.98246 44.311874 117.92232 44.512922 C 117.86219 44.71397 117.77636 44.887071 117.66446 45.032157 C 117.55254 45.17517 117.41683 45.285939 117.25724 45.3647 C 117.09764 45.443461 116.91831 45.483133 116.71933 45.483133 C 116.52036 45.483133 116.35349 45.445733 116.21877 45.371118 C 116.08612 45.294429 115.96827 45.188465 115.86464 45.053743 L 115.83313 45.324445 C 115.82487 45.401134 115.78039 45.439377 115.69953 45.439377 L 115.3454 45.439377 L 115.3454 41.018297 z M 121.83059 41.018297 L 122.37724 41.018297 L 122.37724 42.800031 C 122.50367 42.663235 122.64392 42.554154 122.7973 42.473321 C 122.95274 42.392487 123.13208 42.351972 123.3352 42.351972 C 123.50101 42.351972 123.64606 42.380023 123.77042 42.435983 C 123.89686 42.48987 124.00224 42.567784 124.08722 42.669347 C 124.1722 42.768835 124.23595 42.890381 124.27741 43.033395 C 124.32094 43.174335 124.34217 43.330426 124.34217 43.502456 L 124.34217 45.439377 L 123.79551 45.439377 L 123.79551 43.502456 C 123.79551 43.276536 123.74422 43.100319 123.64266 42.973887 C 123.5411 42.847455 123.38585 42.784279 123.17651 42.784279 C 123.02106 42.784279 122.87685 42.821678 122.74421 42.896293 C 122.61155 42.970909 122.48975 43.073757 122.37783 43.204334 L 122.37783 45.439377 L 121.83059 45.439377 L 121.83059 41.018297 z M 106.88946 41.059136 C 106.89584 41.058812 106.90224 41.059136 106.90871 41.059136 C 106.96051 41.059136 107.00895 41.069332 107.05457 41.090056 C 107.10223 41.110783 107.14359 41.138834 107.17883 41.174068 C 107.21617 41.209299 107.24503 41.250661 107.26576 41.298334 C 107.28649 41.343934 107.29726 41.393799 107.29726 41.447687 C 107.29726 41.499507 107.28649 41.549372 107.26576 41.59704 C 107.24503 41.64264 107.21617 41.682574 107.17883 41.717805 C 107.14357 41.750965 107.10221 41.778173 107.05457 41.798899 C 107.00897 41.819626 106.96053 41.82982 106.90871 41.82982 C 106.85691 41.82982 106.80789 41.819626 106.76228 41.798899 C 106.71668 41.778173 106.67616 41.750965 106.64093 41.717805 C 106.60773 41.682574 106.58108 41.64264 106.56042 41.59704 C 106.53968 41.549366 106.52891 41.499501 106.52891 41.447687 C 106.52891 41.3938 106.53968 41.343934 106.56042 41.298334 C 106.58115 41.250661 106.6078 41.209299 106.64093 41.174068 C 106.6762 41.138834 106.71671 41.110783 106.76228 41.090056 C 106.80218 41.071923 106.8448 41.061403 106.88946 41.059136 z M 131.23749 41.059136 C 131.24387 41.058812 131.25026 41.059136 131.25674 41.059136 C 131.30854 41.059136 131.35698 41.069332 131.40259 41.090056 C 131.45026 41.110783 131.49162 41.138834 131.52686 41.174068 C 131.56419 41.209299 131.59364 41.250661 131.61437 41.298334 C 131.6351 41.343934 131.64529 41.393799 131.64529 41.447687 C 131.64529 41.499507 131.6351 41.549372 131.61437 41.59704 C 131.59364 41.64264 131.56419 41.682574 131.52686 41.717805 C 131.49166 41.750965 131.4503 41.778173 131.40259 41.798899 C 131.35699 41.819626 131.30855 41.82982 131.25674 41.82982 C 131.20494 41.82982 131.15592 41.819626 131.1103 41.798899 C 131.0647 41.778173 131.02477 41.750965 130.98954 41.717805 C 130.9564 41.682574 130.92918 41.64264 130.90844 41.59704 C 130.88771 41.549366 130.87752 41.499501 130.87752 41.447687 C 130.87752 41.3938 130.88771 41.343934 130.90844 41.298334 C 130.92918 41.250661 130.9564 41.209299 130.98954 41.174068 C 131.0248 41.138834 131.06474 41.110783 131.1103 41.090056 C 131.1502 41.071923 131.19283 41.061403 131.23749 41.059136 z M 96.516434 41.307668 C 96.734063 41.307668 96.932943 41.343639 97.113262 41.416183 C 97.295656 41.488725 97.453174 41.59469 97.585824 41.733558 L 97.445806 41.997842 C 97.414719 42.055875 97.372515 42.08477 97.318623 42.08477 C 97.287529 42.08477 97.250131 42.069191 97.206608 42.038097 C 97.165155 42.00494 97.1136 41.96981 97.051421 41.9325 C 96.991314 41.89312 96.917361 41.857994 96.830309 41.826903 C 96.745329 41.793743 96.643066 41.777313 96.522852 41.777313 C 96.408855 41.777313 96.30828 41.793743 96.221229 41.826903 C 96.136249 41.857996 96.064569 41.902473 96.006534 41.960504 C 95.950574 42.016464 95.908369 42.082757 95.879351 42.159447 C 95.850331 42.234063 95.835595 42.315094 95.835595 42.402145 C 95.835595 42.516142 95.861368 42.610484 95.913188 42.685099 C 95.967075 42.759715 96.036484 42.823736 96.121466 42.877624 C 96.208518 42.929444 96.307406 42.975348 96.417254 43.014726 C 96.527105 43.054103 96.638719 43.094037 96.752715 43.135491 C 96.866711 43.176945 96.978908 43.224538 97.088759 43.278427 C 97.19861 43.330247 97.29607 43.397123 97.381047 43.477953 C 97.468099 43.556714 97.537508 43.653589 97.589325 43.769658 C 97.643211 43.885727 97.669835 44.028247 97.669835 44.19613 C 97.669835 44.376452 97.640941 44.545008 97.582907 44.70253 C 97.524874 44.857979 97.439882 44.993681 97.327957 45.10975 C 97.218106 45.225819 97.082404 45.317046 96.920737 45.383369 C 96.75907 45.449696 96.574347 45.483133 96.367081 45.483133 C 96.11629 45.483133 95.885401 45.435539 95.67399 45.340197 C 95.464654 45.242782 95.286163 45.111886 95.139003 44.948146 L 95.304108 44.680944 C 95.318615 44.658144 95.335889 44.640287 95.356615 44.627854 C 95.379415 44.613347 95.405779 44.606268 95.434792 44.606268 C 95.474172 44.606268 95.517221 44.628085 95.564893 44.671609 C 95.614639 44.713063 95.676127 44.759811 95.748667 44.811628 C 95.82121 44.861368 95.907891 44.908117 96.009451 44.951646 C 96.113084 44.993099 96.236903 45.013488 96.379916 45.013488 C 96.500131 45.013488 96.606356 44.995631 96.699625 44.960397 C 96.792895 44.925164 96.871654 44.875882 96.935906 44.811628 C 97.002232 44.747375 97.052097 44.670304 97.085259 44.581181 C 97.120492 44.489984 97.138349 44.389409 97.138349 44.279558 C 97.138349 44.157271 97.111142 44.057279 97.057255 43.978519 C 97.005435 43.899757 96.936026 43.834309 96.848978 43.782493 C 96.763998 43.728606 96.66654 43.684129 96.556689 43.648892 C 96.44684 43.611585 96.335225 43.572759 96.221229 43.533377 C 96.107232 43.493997 95.995035 43.44952 95.885185 43.399776 C 95.775333 43.347956 95.677031 43.280819 95.589979 43.197916 C 95.505 43.11501 95.435591 43.012163 95.381702 42.889876 C 95.329882 42.767589 95.304108 42.61546 95.304108 42.433066 C 95.304108 42.290053 95.330732 42.151235 95.384619 42.016511 C 95.438506 41.879716 95.51642 41.759597 95.617983 41.655964 C 95.721616 41.550258 95.84797 41.46611 95.997199 41.403931 C 96.148504 41.339678 96.321604 41.307668 96.516434 41.307668 z M 102.77992 42.346138 C 102.84419 42.346138 102.90425 42.353217 102.9602 42.367724 C 103.01613 42.380157 103.06684 42.401973 103.11247 42.433066 L 103.06871 42.837369 C 103.06271 42.889182 103.03385 42.914962 102.98178 42.914962 C 102.95278 42.914962 102.91142 42.909577 102.85752 42.89921 C 102.80572 42.886777 102.74793 42.880541 102.68366 42.880541 C 102.59039 42.880541 102.50708 42.895277 102.43454 42.924297 C 102.36407 42.951244 102.30005 42.992603 102.24202 43.048563 C 102.18608 43.10245 102.13622 43.168743 102.09267 43.247506 C 102.04913 43.326267 102.00862 43.416648 101.97132 43.518208 L 101.97132 45.439377 L 101.42408 45.439377 L 101.42408 42.398645 L 101.73854 42.398645 C 101.7966 42.398645 101.83711 42.410266 101.85988 42.433066 C 101.88475 42.455866 101.89892 42.494109 101.90306 42.547998 L 101.9404 42.996056 C 102.03366 42.795011 102.14897 42.636063 102.28577 42.519994 C 102.42257 42.403925 102.58716 42.346138 102.77992 42.346138 z M 126.32634 42.346138 C 126.4963 42.346138 126.64758 42.374189 126.78024 42.430149 C 126.91288 42.484035 127.02365 42.561369 127.11278 42.662929 C 127.2019 42.76449 127.26962 42.886037 127.31522 43.026977 C 127.36289 43.167918 127.3864 43.324592 127.3864 43.496622 L 127.3864 45.439377 L 127.14428 45.439377 C 127.09042 45.439377 127.04906 45.431454 127.02002 45.414874 C 126.99102 45.398294 126.97091 45.364011 126.96051 45.312193 L 126.89225 45.02924 C 126.81349 45.101783 126.73616 45.166648 126.65947 45.224682 C 126.58485 45.280642 126.50551 45.328818 126.42261 45.368201 C 126.3397 45.407581 126.25074 45.436476 126.1554 45.455129 C 126.06006 45.475856 125.95553 45.48605 125.84153 45.48605 C 125.72339 45.48605 125.61262 45.470463 125.50899 45.439377 C 125.40743 45.406217 125.31704 45.356352 125.23828 45.290024 C 125.16159 45.221626 125.10069 45.138061 125.05509 45.038574 C 125.01156 44.937014 124.98975 44.817739 124.98975 44.680944 C 124.98975 44.56073 125.02175 44.445417 125.08601 44.335565 C 125.15235 44.223644 125.25916 44.124495 125.40631 44.037443 C 125.55347 43.950392 125.74526 43.879554 125.98155 43.825665 C 126.21783 43.769705 126.50794 43.737696 126.852 43.729403 L 126.852 43.496622 C 126.852 43.26034 126.80129 43.082694 126.69973 42.964552 C 126.60024 42.844338 126.45376 42.784279 126.261 42.784279 C 126.1325 42.784279 126.024 42.800711 125.93488 42.833868 C 125.84782 42.867028 125.77218 42.903584 125.70793 42.942966 C 125.64366 42.982346 125.58756 43.018317 125.53991 43.05148 C 125.49431 43.08464 125.44756 43.101654 125.39989 43.101654 C 125.36256 43.101654 125.33056 43.092303 125.30363 43.07365 C 125.27669 43.054997 125.25488 43.030908 125.23828 43.001891 L 125.1391 42.828034 C 125.30699 42.666369 125.48717 42.546248 125.67993 42.467487 C 125.87474 42.386653 126.09006 42.346138 126.32634 42.346138 z M 137.10542 42.346138 C 137.16969 42.346138 137.22974 42.353217 137.2857 42.367724 C 137.34163 42.380157 137.39234 42.401973 137.43797 42.433066 L 137.39479 42.837369 C 137.38879 42.889182 137.35935 42.914962 137.30728 42.914962 C 137.27828 42.914962 137.23692 42.909577 137.18302 42.89921 C 137.13122 42.886777 137.07343 42.880541 137.00916 42.880541 C 136.91589 42.880541 136.83317 42.895277 136.76063 42.924297 C 136.69015 42.951244 136.62555 42.992603 136.56752 43.048563 C 136.51159 43.10245 136.46172 43.168743 136.41817 43.247506 C 136.37463 43.326267 136.33412 43.416648 136.29682 43.518208 L 136.29682 45.439377 L 135.75016 45.439377 L 135.75016 42.398645 L 136.06404 42.398645 C 136.1221 42.398645 136.16262 42.410266 136.18539 42.433066 C 136.21025 42.455866 136.22442 42.494109 136.22856 42.547998 L 136.2659 42.996056 C 136.35916 42.795011 136.47448 42.636063 136.61128 42.519994 C 136.74805 42.403925 136.91267 42.346138 137.10542 42.346138 z M 99.534997 42.351972 C 99.717388 42.351972 99.886529 42.382296 100.04198 42.4424 C 100.19743 42.502507 100.3317 42.590616 100.4457 42.706685 C 100.55969 42.822754 100.64923 42.964688 100.71348 43.132574 C 100.77775 43.300459 100.80975 43.493106 100.80975 43.710733 C 100.80975 43.795712 100.80041 43.852655 100.78174 43.881673 C 100.76308 43.908619 100.7288 43.922511 100.67906 43.922511 L 98.64588 43.922511 C 98.650013 44.113196 98.675787 44.280064 98.723474 44.423077 C 98.771145 44.564017 98.836595 44.68102 98.919499 44.77429 C 99.004478 44.867559 99.105054 44.937813 99.221122 44.985484 C 99.337191 45.031084 99.46666 45.053743 99.609673 45.053743 C 99.742323 45.053743 99.857053 45.039591 99.954468 45.010571 C 100.05188 44.979477 100.13519 44.945195 100.20358 44.90789 C 100.27406 44.870584 100.33268 44.837147 100.38036 44.808127 C 100.42802 44.777034 100.46997 44.761455 100.50521 44.761455 C 100.52801 44.761455 100.54753 44.76684 100.56413 44.777207 C 100.58073 44.7855 100.5949 44.797965 100.6073 44.814545 L 100.76307 45.013488 C 100.69468 45.094322 100.61365 45.164575 100.52038 45.224682 C 100.42918 45.282715 100.33088 45.331736 100.22517 45.371118 C 100.11946 45.408424 100.00954 45.436476 99.895544 45.455129 C 99.783621 45.473782 99.672852 45.483133 99.563 45.483133 C 99.351589 45.483133 99.15667 45.448005 98.978424 45.377535 C 98.800175 45.307065 98.645773 45.203373 98.515196 45.066578 C 98.386692 44.92771 98.286117 44.757726 98.213573 44.556678 C 98.14103 44.353557 98.105059 44.120397 98.105059 43.857169 C 98.105059 43.64576 98.137068 43.448569 98.201322 43.266175 C 98.267648 43.081709 98.361992 42.922502 98.484275 42.787779 C 98.608635 42.650983 98.758492 42.544175 98.934668 42.467487 C 99.112916 42.390799 99.313222 42.351972 99.534997 42.351972 z M 109.22777 42.351972 C 109.43503 42.351972 109.61664 42.387682 109.77209 42.458153 C 109.92754 42.526548 110.06551 42.622583 110.18573 42.74694 L 110.04221 42.945883 C 110.02561 42.968683 110.00915 42.98654 109.99262 42.998973 C 109.97808 43.00934 109.95628 43.014726 109.92728 43.014726 C 109.89621 43.014726 109.86421 43.002261 109.83101 42.977387 C 109.79788 42.952514 109.75652 42.925307 109.70675 42.896293 C 109.65701 42.865207 109.59611 42.837156 109.52356 42.812282 C 109.45308 42.787409 109.36582 42.774944 109.26219 42.774944 C 109.1254 42.774944 109.00385 42.802151 108.89814 42.856038 C 108.79451 42.907851 108.70782 42.983496 108.63736 43.082984 C 108.56896 43.180399 108.51598 43.299674 108.47867 43.440615 C 108.4434 43.581555 108.42558 43.739918 108.42558 43.916094 C 108.42558 44.098488 108.44425 44.261395 108.48159 44.404408 C 108.52099 44.545348 108.57624 44.664039 108.64669 44.761455 C 108.71716 44.858867 108.80215 44.933667 108.90164 44.985484 C 109.00113 45.035231 109.11274 45.06016 109.2371 45.06016 C 109.35732 45.06016 109.4562 45.044574 109.53289 45.013488 C 109.60958 44.982394 109.6736 44.94811 109.72542 44.910808 C 109.77722 44.873501 109.81942 44.839218 109.8526 44.808127 C 109.88787 44.777034 109.92442 44.761455 109.9617 44.761455 C 110.00316 44.761455 110.03601 44.779312 110.06088 44.814545 L 110.21956 45.013488 C 110.15323 45.094322 110.07986 45.164575 109.99904 45.224682 C 109.9182 45.282715 109.83093 45.331736 109.73767 45.371118 C 109.64439 45.408424 109.54694 45.436476 109.44538 45.455129 C 109.34589 45.473782 109.24447 45.483133 109.14084 45.483133 C 108.96259 45.483133 108.79572 45.448005 108.64027 45.377535 C 108.48482 45.307065 108.34912 45.205062 108.23305 45.072412 C 108.11905 44.93769 108.02867 44.773938 107.96235 44.581181 C 107.89809 44.386351 107.86609 44.164811 107.86609 43.916094 C 107.86609 43.690174 107.89638 43.481946 107.95652 43.291262 C 108.01665 43.098505 108.10334 42.932481 108.2173 42.793613 C 108.33338 42.654745 108.47531 42.547092 108.64319 42.470404 C 108.81315 42.391643 109.00807 42.351972 109.22777 42.351972 z M 111.98263 42.351972 C 112.16502 42.351972 112.33417 42.382296 112.48961 42.4424 C 112.64507 42.502507 112.77992 42.590616 112.89392 42.706685 C 113.00789 42.822754 113.09686 42.964688 113.16112 43.132574 C 113.22538 43.300459 113.25738 43.493106 113.25738 43.710733 C 113.25738 43.795712 113.24804 43.852655 113.22938 43.881673 C 113.21071 43.908619 113.17642 43.922511 113.1267 43.922511 L 111.09351 43.922511 C 111.09751 44.113196 111.12331 44.280064 111.17111 44.423077 C 111.21877 44.564017 111.28422 44.68102 111.36713 44.77429 C 111.45211 44.867559 111.55269 44.937813 111.66875 44.985484 C 111.78482 45.031084 111.91429 45.053743 112.05731 45.053743 C 112.18996 45.053743 112.30527 45.039591 112.40268 45.010571 C 112.5001 44.979477 112.58282 44.945195 112.65122 44.90789 C 112.72169 44.870584 112.78091 44.837147 112.82857 44.808127 C 112.87624 44.777034 112.9176 44.761455 112.95284 44.761455 C 112.97564 44.761455 112.99516 44.76684 113.01176 44.777207 C 113.02836 44.7855 113.04312 44.797965 113.05552 44.814545 L 113.21071 45.013488 C 113.14231 45.094322 113.06186 45.164575 112.96859 45.224682 C 112.87739 45.282715 112.77851 45.331736 112.6728 45.371118 C 112.5671 45.408424 112.45718 45.436476 112.34318 45.455129 C 112.23126 45.473782 112.12049 45.483133 112.01063 45.483133 C 111.79922 45.483133 111.6043 45.448005 111.42606 45.377535 C 111.24781 45.307065 111.09341 45.203373 110.96283 45.066578 C 110.83432 44.92771 110.73433 44.757726 110.66179 44.556678 C 110.58924 44.353557 110.55269 44.120397 110.55269 43.857169 C 110.55269 43.64576 110.58469 43.448569 110.64895 43.266175 C 110.71529 43.081709 110.80963 42.922502 110.93191 42.787779 C 111.05627 42.650983 111.20671 42.544175 111.38288 42.467487 C 111.56114 42.390799 111.76086 42.351972 111.98263 42.351972 z M 119.90358 42.351972 C 120.08598 42.351972 120.25511 42.382296 120.41057 42.4424 C 120.56601 42.502507 120.70088 42.590616 120.81487 42.706685 C 120.92887 42.822754 121.01782 42.964688 121.08207 43.132574 C 121.14634 43.300459 121.17833 43.493106 121.17833 43.710733 C 121.17833 43.795712 121.169 43.852655 121.15033 43.881673 C 121.13166 43.908619 121.09738 43.922511 121.04765 43.922511 L 119.01447 43.922511 C 119.01847 44.113196 119.04426 44.280064 119.09206 44.423077 C 119.13973 44.564017 119.20517 44.68102 119.28809 44.77429 C 119.37307 44.867559 119.47364 44.937813 119.58971 44.985484 C 119.70578 45.031084 119.83525 45.053743 119.97826 45.053743 C 120.11091 45.053743 120.22564 45.039591 120.32306 45.010571 C 120.42048 44.979477 120.50378 44.945195 120.57217 44.90789 C 120.64265 44.870584 120.70186 44.837147 120.74953 44.808127 C 120.7972 44.777034 120.83855 44.761455 120.87379 44.761455 C 120.89659 44.761455 120.91612 44.76684 120.93272 44.777207 C 120.94932 44.7855 120.96407 44.797965 120.97647 44.814545 L 121.13166 45.013488 C 121.06326 45.094322 120.98223 45.164575 120.88896 45.224682 C 120.79776 45.282715 120.69946 45.331736 120.59376 45.371118 C 120.48805 45.408424 120.37813 45.436476 120.26413 45.455129 C 120.15221 45.473782 120.04144 45.483133 119.93159 45.483133 C 119.72017 45.483133 119.52526 45.448005 119.34701 45.377535 C 119.16876 45.307065 119.01436 45.203373 118.88378 45.066578 C 118.75528 44.92771 118.6547 44.757726 118.58216 44.556678 C 118.50962 44.353557 118.47365 44.120397 118.47365 43.857169 C 118.47365 43.64576 118.50564 43.448569 118.56991 43.266175 C 118.63624 43.081709 118.73058 42.922502 118.85286 42.787779 C 118.97722 42.650983 119.12766 42.544175 119.30384 42.467487 C 119.48209 42.390799 119.68181 42.351972 119.90358 42.351972 z M 133.68197 42.351972 C 133.90375 42.351972 134.10347 42.389371 134.28172 42.463987 C 134.45997 42.53653 134.61125 42.641649 134.73561 42.778445 C 134.85997 42.913165 134.95574 43.076918 135.02207 43.269676 C 135.09047 43.462431 135.12416 43.677738 135.12416 43.916094 C 135.12416 44.15652 135.09047 44.373255 135.02207 44.566012 C 134.95573 44.758769 134.85997 44.923367 134.73561 45.06016 C 134.61125 45.194883 134.45997 45.299419 134.28172 45.374035 C 134.10347 45.446578 133.90375 45.483133 133.68197 45.483133 C 133.46019 45.483133 133.25905 45.446578 133.07873 45.374035 C 132.90048 45.299419 132.74835 45.194883 132.62192 45.06016 C 132.49756 44.923367 132.40094 44.758769 132.33255 44.566012 C 132.26621 44.373255 132.23278 44.15652 132.23278 43.916094 C 132.23278 43.677738 132.26621 43.462431 132.33255 43.269676 C 132.40094 43.076918 132.49756 42.913165 132.62192 42.778445 C 132.74835 42.641649 132.90048 42.53653 133.07873 42.463987 C 133.25905 42.389371 133.46019 42.351972 133.68197 42.351972 z M 103.38083 42.398645 L 103.83181 42.398645 C 103.87328 42.398645 103.90841 42.410266 103.93741 42.433066 C 103.96641 42.455866 103.98652 42.481646 103.99692 42.510659 L 104.64625 44.456915 C 104.67318 44.529458 104.69643 44.600295 104.71509 44.668692 C 104.73376 44.73709 104.751 44.806499 104.7676 44.87697 C 104.78213 44.808572 104.79859 44.740007 104.81719 44.671609 C 104.83792 44.601142 104.86287 44.529458 104.89187 44.456915 L 105.55112 42.510659 C 105.56352 42.479573 105.58304 42.453793 105.61004 42.433066 C 105.63904 42.410266 105.67162 42.398645 105.70689 42.398645 L 106.13861 42.398645 L 105.0068 45.439377 L 104.51265 45.439377 L 103.38083 42.398645 z M 106.64443 42.398645 L 107.19167 42.398645 L 107.19167 45.439377 L 106.64443 45.439377 L 106.64443 42.398645 z M 127.72944 42.398645 L 128.17984 42.398645 C 128.2213 42.398645 128.25702 42.410266 128.28602 42.433066 C 128.31502 42.455866 128.33454 42.481646 128.34494 42.510659 L 128.99486 44.456915 C 129.02179 44.529458 129.04445 44.600295 129.06312 44.668692 C 129.08179 44.73709 129.09961 44.806499 129.11621 44.87697 C 129.13074 44.808572 129.1472 44.740007 129.1658 44.671609 C 129.18653 44.601142 129.21148 44.529458 129.24048 44.456915 L 129.89914 42.510659 C 129.91161 42.479573 129.93172 42.453793 129.95865 42.433066 C 129.98765 42.410266 130.01965 42.398645 130.05492 42.398645 L 130.48722 42.398645 L 129.35541 45.439377 L 128.86068 45.439377 L 127.72944 42.398645 z M 130.99245 42.398645 L 131.53969 42.398645 L 131.53969 45.439377 L 130.99245 45.439377 L 130.99245 42.398645 z M 99.544331 42.750441 C 99.289395 42.750441 99.0874 42.824656 98.938168 42.973887 C 98.79101 43.123118 98.698357 43.327385 98.661049 43.586467 L 100.31852 43.586467 C 100.31852 43.464181 100.30069 43.352565 100.26543 43.251007 C 100.23023 43.147374 100.17952 43.059265 100.11316 42.986722 C 100.04682 42.912106 99.964942 42.853735 99.86754 42.812282 C 99.772198 42.770829 99.664546 42.750441 99.544331 42.750441 z M 111.99196 42.750441 C 111.73702 42.750441 111.53503 42.824656 111.3858 42.973887 C 111.23864 43.123118 111.14599 43.327385 111.10868 43.586467 L 112.76615 43.586467 C 112.76615 43.464181 112.74826 43.352565 112.71306 43.251007 C 112.67779 43.147374 112.62708 43.059265 112.56079 42.986722 C 112.49445 42.912106 112.41258 42.853735 112.31517 42.812282 C 112.21983 42.770829 112.11218 42.750441 111.99196 42.750441 z M 119.91234 42.750441 C 119.65767 42.750556 119.45529 42.824771 119.30617 42.973887 C 119.15902 43.123118 119.06695 43.327385 119.02964 43.586467 L 120.68652 43.586467 C 120.68652 43.464181 120.66928 43.352565 120.63401 43.251007 C 120.59881 43.147374 120.5481 43.059265 120.48174 42.986722 C 120.41541 42.912106 120.33353 42.853735 120.23613 42.812282 C 120.14094 42.770896 120.0329 42.750508 119.91292 42.750441 L 119.91234 42.750441 z M 133.68197 42.778445 C 133.53274 42.778445 133.40185 42.804225 133.28992 42.856038 C 133.18008 42.907851 133.08801 42.982066 133.01339 43.079484 C 132.94085 43.176899 132.88617 43.296173 132.84887 43.437114 C 132.8136 43.578055 132.79577 43.73869 132.79577 43.919011 C 132.79577 44.099332 132.8136 44.259967 132.84887 44.400907 C 132.8862 44.541848 132.94087 44.661122 133.01339 44.758538 C 133.08801 44.85595 133.18008 44.93075 133.28992 44.982567 C 133.40185 45.032314 133.53274 45.057243 133.68197 45.057243 C 133.82913 45.057243 133.95776 45.032314 134.06761 44.982567 C 134.17746 44.930747 134.26869 44.855947 134.34123 44.758538 C 134.41585 44.661122 134.47052 44.541848 134.50575 44.400907 C 134.54308 44.259967 134.56176 44.099332 134.56176 43.919011 C 134.56176 43.73869 134.54308 43.578055 134.50575 43.437114 C 134.47048 43.296173 134.41581 43.176899 134.34123 43.079484 C 134.26869 42.982069 134.17746 42.907854 134.06761 42.856038 C 133.95776 42.804225 133.82913 42.778445 133.68197 42.778445 z M 116.6855 42.784279 C 116.51761 42.784279 116.36944 42.82395 116.24094 42.902711 C 116.1145 42.981472 115.99835 43.093086 115.89264 43.238172 L 115.89264 44.706031 C 115.98798 44.836608 116.09252 44.928678 116.20652 44.982567 C 116.32051 45.03438 116.44602 45.06016 116.58282 45.06016 C 116.86262 45.06016 117.07708 44.959583 117.22632 44.758538 C 117.37554 44.55749 117.45035 44.258037 117.45035 43.860086 C 117.45035 43.491155 117.38347 43.219749 117.25082 43.045646 C 117.11817 42.871543 116.93007 42.784279 116.6855 42.784279 z M 126.852 44.071281 C 126.6095 44.081647 126.40296 44.102619 126.233 44.133706 C 126.06304 44.162726 125.92422 44.201813 125.81644 44.251554 C 125.71074 44.301294 125.63425 44.36051 125.58658 44.428911 C 125.53891 44.495238 125.51482 44.570036 125.51482 44.65294 C 125.51482 44.731702 125.52729 44.800266 125.55216 44.858301 C 125.57909 44.914261 125.61481 44.960426 125.65834 44.997736 C 125.70187 45.032969 125.75343 45.060176 125.81353 45.07883 C 125.87366 45.09541 125.93768 45.103916 126.00605 45.103916 C 126.09724 45.103916 126.18139 45.094566 126.25808 45.075912 C 126.33477 45.057261 126.4073 45.030902 126.4757 44.997736 C 126.54409 44.962502 126.6087 44.920298 126.6688 44.870552 C 126.731 44.818732 126.79191 44.76179 126.852 44.699613 L 126.852 44.071281 z M 107.2961 48.627712 L 107.84334 48.627712 L 107.84334 53.048791 L 107.51663 53.048791 C 107.47723 53.048791 107.44523 53.040868 107.42036 53.024288 C 107.3955 53.005635 107.38132 52.976157 107.37719 52.936777 L 107.32118 52.573312 C 107.19268 52.728761 107.0462 52.85427 106.88246 52.949612 C 106.71872 53.044954 106.52919 53.092547 106.31364 53.092547 C 106.1416 53.092547 105.98493 53.059111 105.84399 52.992784 C 105.70512 52.924387 105.58643 52.825237 105.48694 52.694662 C 105.38745 52.564084 105.31038 52.40202 105.2565 52.209265 C 105.20263 52.014435 105.17599 51.790624 105.17599 51.53776 C 105.17599 51.313913 105.20485 51.105685 105.26291 50.912928 C 105.32305 50.718098 105.40888 50.550386 105.52078 50.409445 C 105.6327 50.268505 105.76841 50.157736 105.928 50.076902 C 106.08967 49.996068 106.27212 49.955552 106.47524 49.955552 C 106.65971 49.955552 106.81722 49.986718 106.9478 50.048898 C 107.07838 50.109005 107.19454 50.195686 107.2961 50.309682 L 107.2961 48.627712 z M 128.15008 48.627712 L 128.69674 48.627712 L 128.69674 50.440366 C 128.8211 50.293207 128.96361 50.17705 129.12321 50.09207 C 129.2828 50.005019 129.4661 49.961386 129.67337 49.961386 C 129.84954 49.961386 130.0079 49.995669 130.14884 50.064067 C 130.28978 50.132465 130.4099 50.231353 130.50939 50.359855 C 130.60888 50.488361 130.68452 50.64445 130.73634 50.828917 C 130.7902 51.011311 130.81743 51.218694 130.81743 51.450832 C 130.81743 51.697478 130.78714 51.921291 130.727 52.122336 C 130.66687 52.323384 130.58103 52.496485 130.46914 52.641571 C 130.35721 52.784585 130.22151 52.895354 130.06192 52.974115 C 129.90232 53.052876 129.72299 53.092547 129.52401 53.092547 C 129.32503 53.092547 129.15817 53.055148 129.02345 52.980532 C 128.89079 52.903844 128.77237 52.797881 128.66873 52.663157 L 128.63781 52.93386 C 128.62955 53.010548 128.58507 53.048791 128.50421 53.048791 L 128.15008 53.048791 L 128.15008 48.627712 z M 110.55444 49.02268 L 110.83448 49.02268 L 110.83448 50.064067 L 111.6705 50.064067 L 111.6705 50.461952 L 110.83448 50.461952 L 110.83448 52.278107 C 110.83448 52.402466 110.86197 52.49538 110.91791 52.55756 C 110.97597 52.61974 111.05077 52.650906 111.14194 52.650906 C 111.1958 52.650906 111.24171 52.643826 111.27904 52.62932 C 111.31844 52.614813 111.35128 52.598383 111.37822 52.57973 C 111.40515 52.561076 111.42781 52.544063 111.44648 52.529557 C 111.46721 52.51505 111.48588 52.50797 111.50248 52.50797 C 111.52115 52.50797 111.5359 52.511929 111.54624 52.520222 C 111.5587 52.528515 111.57033 52.542407 111.58066 52.561061 L 111.74226 52.821845 C 111.649 52.908896 111.53907 52.976617 111.41264 53.024288 C 111.2862 53.071961 111.15446 53.095464 111.01767 53.095464 C 110.78346 53.095464 110.60328 53.028327 110.47685 52.893604 C 110.35041 52.758881 110.28724 52.566236 110.28724 52.315445 L 110.28724 50.461952 L 109.93894 50.461952 C 109.90788 50.461952 109.88065 50.451758 109.85785 50.431031 C 109.83712 50.410305 109.82693 50.380566 109.82693 50.341186 L 109.82693 50.123574 L 110.30591 50.06115 L 110.43309 49.12536 C 110.43709 49.094267 110.44956 49.069337 110.47043 49.050684 C 110.49323 49.03203 110.52124 49.02268 110.55444 49.02268 z M 94.583597 49.955552 C 94.7577 49.955552 94.915218 49.989837 95.056159 50.058232 C 95.1971 50.124559 95.317219 50.222862 95.416707 50.353438 C 95.516192 50.484016 95.592681 50.645496 95.64657 50.838251 C 95.700457 51.031009 95.727664 51.253975 95.727664 51.506839 C 95.727664 51.730686 95.697342 51.939758 95.637235 52.134588 C 95.577131 52.327345 95.490449 52.495641 95.376451 52.638654 C 95.264528 52.779595 95.127398 52.890365 94.965731 52.971198 C 94.804064 53.052032 94.621613 53.092547 94.418492 53.092547 C 94.234028 53.092547 94.076508 53.061381 93.94593 52.999201 C 93.815355 52.937024 93.699778 52.849757 93.598218 52.737834 L 93.598218 53.867315 L 93.05098 53.867315 L 93.05098 50.008059 L 93.377106 50.008059 C 93.416486 50.008059 93.448495 50.01741 93.473368 50.036063 C 93.498242 50.052643 93.512977 50.080694 93.517124 50.120074 L 93.570214 50.474787 C 93.698719 50.319338 93.84546 50.19383 94.011272 50.098488 C 94.177085 50.003146 94.368043 49.955552 94.583597 49.955552 z M 118.12593 49.955552 C 118.29589 49.955552 118.44717 49.983603 118.57983 50.039563 C 118.71247 50.09345 118.82324 50.170781 118.91237 50.272344 C 119.00149 50.373904 119.06863 50.495451 119.11423 50.636392 C 119.1619 50.777333 119.18599 50.934006 119.18599 51.106037 L 119.18599 53.048791 L 118.94329 53.048791 C 118.88943 53.048791 118.84807 53.040868 118.81903 53.024288 C 118.79003 53.007708 118.7705 52.973426 118.7601 52.921608 L 118.69126 52.638654 C 118.6125 52.711197 118.53517 52.776064 118.45848 52.834096 C 118.38386 52.890056 118.3051 52.938233 118.2222 52.977615 C 118.13929 53.016995 118.04975 53.04589 117.95441 53.064543 C 117.85907 53.08527 117.75453 53.095464 117.64054 53.095464 C 117.5224 53.095464 117.41163 53.079885 117.30799 53.048791 C 117.20643 53.015631 117.11605 52.965766 117.03729 52.899438 C 116.9606 52.831041 116.89969 52.747477 116.8541 52.647989 C 116.81057 52.546429 116.78876 52.427152 116.78876 52.290359 C 116.78876 52.170144 116.82076 52.05483 116.88502 51.94498 C 116.95136 51.833056 117.05817 51.733909 117.20531 51.646857 C 117.35247 51.559808 117.54428 51.488968 117.78056 51.43508 C 118.01684 51.37912 118.30694 51.34711 118.651 51.338817 L 118.651 51.106037 C 118.651 50.869753 118.60029 50.692108 118.49873 50.573967 C 118.39925 50.453752 118.25335 50.393693 118.06059 50.393693 C 117.93209 50.393693 117.82301 50.410123 117.73388 50.443283 C 117.64683 50.476443 117.57119 50.512997 117.50694 50.552381 C 117.44267 50.591761 117.38657 50.627732 117.33891 50.660895 C 117.29331 50.694055 117.24715 50.711068 117.19948 50.711068 C 117.16215 50.711068 117.12957 50.701718 117.10263 50.683064 C 117.0757 50.664411 117.05389 50.640325 117.03729 50.611305 L 116.93811 50.437449 C 117.106 50.275782 117.28618 50.155663 117.47893 50.076902 C 117.67377 49.996068 117.88965 49.955552 118.12593 49.955552 z M 138.41109 49.955552 C 138.47536 49.955552 138.53542 49.962632 138.59137 49.977139 C 138.64737 49.989572 138.69807 50.011387 138.74364 50.04248 L 138.69988 50.446783 C 138.69388 50.498603 138.66502 50.524377 138.61295 50.524377 C 138.58395 50.524377 138.54259 50.518992 138.48869 50.508625 C 138.43689 50.496192 138.37852 50.489956 138.31425 50.489956 C 138.22098 50.489956 138.13826 50.504692 138.06572 50.533712 C 137.99524 50.560656 137.93122 50.602019 137.87319 50.657978 C 137.81726 50.711864 137.76739 50.778157 137.72384 50.856921 C 137.6803 50.935679 137.63979 51.026062 137.60249 51.127623 L 137.60249 53.048791 L 137.05525 53.048791 L 137.05525 50.008059 L 137.36912 50.008059 C 137.42719 50.008059 137.46771 50.01968 137.49047 50.04248 C 137.51534 50.06528 137.5301 50.103524 137.53423 50.157412 L 137.57157 50.605471 C 137.66483 50.404423 137.77957 50.245477 137.91636 50.129408 C 138.05316 50.013342 138.21834 49.955552 138.41109 49.955552 z M 146.64359 49.955552 C 146.70786 49.955552 146.76792 49.962632 146.82386 49.977139 C 146.8798 49.989572 146.93051 50.011387 146.97613 50.04248 L 146.93296 50.446783 C 146.92696 50.498603 146.89752 50.524377 146.84545 50.524377 C 146.81645 50.524377 146.77509 50.518992 146.72118 50.508625 C 146.66938 50.496192 146.61159 50.489956 146.54733 50.489956 C 146.45405 50.489956 146.37134 50.504692 146.2988 50.533712 C 146.22832 50.560656 146.16372 50.602019 146.10569 50.657978 C 146.04975 50.711864 145.99989 50.778157 145.95633 50.856921 C 145.9128 50.935679 145.87287 51.026062 145.83557 51.127623 L 145.83557 53.048791 L 145.28833 53.048791 L 145.28833 50.008059 L 145.6022 50.008059 C 145.66027 50.008059 145.70079 50.01968 145.72355 50.04248 C 145.74842 50.06528 145.76259 50.103524 145.76673 50.157412 L 145.80406 50.605471 C 145.89733 50.404423 146.01264 50.245477 146.14944 50.129408 C 146.28624 50.013342 146.45083 49.955552 146.64359 49.955552 z M 88.468879 49.961386 C 88.651273 49.961386 88.820412 49.991708 88.975862 50.051815 C 89.131311 50.111922 89.265586 50.20003 89.379582 50.3161 C 89.493576 50.432169 89.583115 50.574104 89.647367 50.741989 C 89.71162 50.909874 89.743629 51.102519 89.743629 51.320148 C 89.743629 51.405127 89.734279 51.46207 89.715626 51.491087 C 89.696972 51.518034 89.662688 51.531926 89.612946 51.531926 L 87.579762 51.531926 C 87.583896 51.72261 87.609669 51.88948 87.657356 52.032491 C 87.705029 52.173432 87.770479 52.290435 87.853381 52.383704 C 87.93836 52.476974 88.038936 52.547229 88.155004 52.594898 C 88.271074 52.640498 88.400542 52.663157 88.543555 52.663157 C 88.676205 52.663157 88.790937 52.649005 88.88835 52.619985 C 88.985765 52.588898 89.069071 52.554616 89.137466 52.517305 C 89.207937 52.479998 89.267152 52.446562 89.314823 52.417542 C 89.362496 52.386449 89.403856 52.370869 89.439089 52.370869 C 89.461889 52.370869 89.481434 52.376254 89.498014 52.386621 C 89.514594 52.394914 89.52933 52.407379 89.54177 52.423959 L 89.696957 52.622902 C 89.628559 52.703736 89.547527 52.773991 89.454258 52.834096 C 89.363061 52.89213 89.264758 52.941151 89.159053 52.980532 C 89.053347 53.017839 88.943423 53.04589 88.829426 53.064543 C 88.717503 53.083197 88.606734 53.092547 88.496882 53.092547 C 88.285473 53.092547 88.090554 53.05742 87.912306 52.98695 C 87.734057 52.91648 87.579656 52.812788 87.449078 52.675992 C 87.320576 52.537127 87.219997 52.36714 87.147456 52.166092 C 87.074912 51.962972 87.038941 51.729812 87.038941 51.466584 C 87.038941 51.255173 87.070951 51.057981 87.135204 50.87559 C 87.201531 50.691123 87.295873 50.531914 87.418158 50.397194 C 87.542517 50.260398 87.692958 50.15359 87.869134 50.076902 C 88.047381 50.000214 88.247105 49.961386 88.468879 49.961386 z M 97.637164 49.961386 C 97.858939 49.961386 98.059245 49.998786 98.237493 50.073401 C 98.415742 50.145944 98.567027 50.251064 98.691386 50.387859 C 98.815746 50.522582 98.910932 50.686333 98.977257 50.87909 C 99.045655 51.071847 99.079937 51.287153 99.079937 51.525508 C 99.079937 51.765937 99.045655 51.98267 98.977257 52.175427 C 98.91093 52.368184 98.815744 52.53278 98.691386 52.669575 C 98.567027 52.804298 98.415742 52.908834 98.237493 52.983449 C 98.059245 53.055993 97.858939 53.092547 97.637164 53.092547 C 97.415392 53.092547 97.214238 53.055993 97.033919 52.983449 C 96.85567 52.908834 96.703541 52.804298 96.577109 52.669575 C 96.452749 52.53278 96.356135 52.368184 96.287737 52.175427 C 96.221413 51.98267 96.188558 51.765937 96.188558 51.525508 C 96.188558 51.287153 96.221413 51.071847 96.287737 50.87909 C 96.356135 50.686333 96.452749 50.522582 96.577109 50.387859 C 96.703541 50.251064 96.85567 50.145944 97.033919 50.073401 C 97.214238 49.998786 97.415392 49.961386 97.637164 49.961386 z M 100.62539 49.961386 C 100.814 49.961386 100.98542 49.992552 101.13879 50.054732 C 101.29217 50.116912 101.42248 50.204176 101.53026 50.3161 L 101.40891 50.512125 C 101.38404 50.557725 101.34665 50.580384 101.29689 50.580384 C 101.26583 50.580384 101.23212 50.568763 101.1948 50.545963 C 101.15953 50.523163 101.1159 50.49966 101.06411 50.474787 C 101.01438 50.44784 100.95432 50.422911 100.88384 50.400111 C 100.81544 50.377311 100.73356 50.365689 100.63822 50.365689 C 100.55739 50.365689 100.48487 50.377311 100.42061 50.400111 C 100.35635 50.422911 100.30109 50.454076 100.25551 50.493456 C 100.20991 50.532836 100.17478 50.579585 100.14991 50.633475 C 100.12504 50.685288 100.11257 50.740803 100.11257 50.800913 C 100.11257 50.879674 100.13353 50.945122 100.175 50.996939 C 100.21646 51.048759 100.27114 51.093235 100.33952 51.13054 C 100.40792 51.167846 100.48583 51.202129 100.57288 51.23322 C 100.662 51.26224 100.7518 51.292562 100.843 51.323648 C 100.9342 51.354742 101.02374 51.390713 101.11079 51.432163 C 101.19991 51.473616 101.27867 51.524326 101.34707 51.584433 C 101.41546 51.644539 101.47014 51.718493 101.51159 51.805545 C 101.55306 51.890524 101.57401 51.993632 101.57401 52.115919 C 101.57401 52.25686 101.54992 52.387758 101.50225 52.50797 C 101.45459 52.626112 101.38434 52.728375 101.29106 52.815427 C 101.19987 52.902479 101.08598 52.971044 100.94918 53.020788 C 100.81446 53.070534 100.65863 53.095464 100.48245 53.095464 C 100.28141 53.095464 100.09811 53.061182 99.932299 52.992784 C 99.768559 52.924387 99.62974 52.835433 99.515744 52.725582 L 99.642927 52.520222 C 99.659507 52.493275 99.679635 52.472887 99.702435 52.458381 C 99.725235 52.443874 99.75413 52.436211 99.789363 52.436211 C 99.82667 52.436211 99.864069 52.450947 99.901378 52.479967 C 99.938685 52.506913 99.983159 52.538079 100.03498 52.573312 C 100.08885 52.606472 100.15286 52.637638 100.2275 52.666658 C 100.30212 52.693605 100.39561 52.706913 100.50754 52.706913 C 100.60288 52.706913 100.68476 52.693605 100.75316 52.666658 C 100.82362 52.639711 100.88141 52.604584 100.92701 52.561061 C 100.97261 52.515461 101.00689 52.462479 101.02969 52.402373 C 101.05249 52.342267 101.06411 52.27909 101.06411 52.212765 C 101.06411 52.129858 101.04231 52.061293 100.99877 52.007405 C 100.95731 51.951445 100.90205 51.904696 100.83367 51.867386 C 100.76527 51.828006 100.68651 51.793724 100.59739 51.764706 C 100.51033 51.735693 100.42053 51.705954 100.32727 51.674861 C 100.23607 51.641701 100.14568 51.605145 100.05656 51.565764 C 99.969518 51.52431 99.892182 51.472756 99.823784 51.410576 C 99.755389 51.346325 99.699288 51.268407 99.655762 51.177213 C 99.614309 51.086016 99.593338 50.975246 99.593338 50.844669 C 99.593338 50.726527 99.615997 50.61433 99.661597 50.508625 C 99.707194 50.400846 99.773489 50.306504 99.860539 50.225671 C 99.947591 50.144837 100.05583 50.080817 100.18433 50.033146 C 100.31284 49.985473 100.45958 49.961386 100.62539 49.961386 z M 103.46368 49.961386 C 103.64607 49.961386 103.81522 49.991708 103.97066 50.051815 C 104.12611 50.111922 104.26039 50.20003 104.37438 50.3161 C 104.48837 50.432169 104.57791 50.574104 104.64217 50.741989 C 104.70643 50.909874 104.73843 51.102519 104.73843 51.320148 C 104.73843 51.405127 104.72909 51.46207 104.71043 51.491087 C 104.69176 51.518034 104.65748 51.531926 104.60775 51.531926 L 102.57456 51.531926 C 102.57856 51.72261 102.60436 51.88948 102.65216 52.032491 C 102.69982 52.173432 102.76527 52.290435 102.84818 52.383704 C 102.93315 52.476974 103.03373 52.547229 103.1498 52.594898 C 103.26587 52.640498 103.39536 52.663157 103.53835 52.663157 C 103.67101 52.663157 103.78574 52.649005 103.88315 52.619985 C 103.98056 52.588898 104.06387 52.554616 104.13227 52.517305 C 104.20273 52.479998 104.26137 52.446562 104.30904 52.417542 C 104.35671 52.386449 104.39865 52.370869 104.43389 52.370869 C 104.45669 52.370869 104.47621 52.376254 104.49281 52.386621 C 104.50941 52.394914 104.52359 52.407379 104.53599 52.423959 L 104.69176 52.622902 C 104.62336 52.703736 104.54232 52.773991 104.44906 52.834096 C 104.35786 52.89213 104.25956 52.941151 104.15385 52.980532 C 104.04815 53.017839 103.93822 53.04589 103.82423 53.064543 C 103.7123 53.083197 103.60153 53.092547 103.49168 53.092547 C 103.28027 53.092547 103.08535 53.05742 102.90711 52.98695 C 102.72885 52.91648 102.57445 52.812788 102.44388 52.675992 C 102.31537 52.537127 102.2148 52.36714 102.14226 52.166092 C 102.06971 51.962972 102.03374 51.729812 102.03374 51.466584 C 102.03374 51.255173 102.06574 51.057981 102.13 50.87559 C 102.19634 50.691123 102.29068 50.531914 102.41296 50.397194 C 102.53732 50.260398 102.68718 50.15359 102.86335 50.076902 C 103.0416 50.000214 103.2419 49.961386 103.46368 49.961386 z M 113.43415 49.961386 C 113.65593 49.961386 113.85623 49.998786 114.03448 50.073401 C 114.21273 50.145944 114.36401 50.251064 114.48837 50.387859 C 114.61273 50.522582 114.70795 50.686333 114.77424 50.87909 C 114.84264 51.071847 114.87693 51.287153 114.87693 51.525508 C 114.87693 51.765937 114.84264 51.98267 114.77424 52.175427 C 114.70793 52.368184 114.61272 52.53278 114.48837 52.669575 C 114.36401 52.804298 114.21273 52.908834 114.03448 52.983449 C 113.85623 53.055993 113.65593 53.092547 113.43415 53.092547 C 113.21238 53.092547 113.01123 53.055993 112.83091 52.983449 C 112.65265 52.908834 112.50053 52.804298 112.3741 52.669575 C 112.24974 52.53278 112.15312 52.368184 112.08473 52.175427 C 112.01839 51.98267 111.98555 51.765937 111.98555 51.525508 C 111.98555 51.287153 112.01839 51.071847 112.08473 50.87909 C 112.15312 50.686333 112.24974 50.522582 112.3741 50.387859 C 112.50053 50.251064 112.65265 50.145944 112.83091 50.073401 C 113.01123 49.998786 113.21238 49.961386 113.43415 49.961386 z M 121.53013 49.961386 C 121.69594 49.961386 121.84099 49.98944 121.96535 50.045397 C 122.09179 50.099284 122.19775 50.1772 122.28273 50.278761 C 122.36771 50.378249 122.43173 50.499796 122.47525 50.642809 C 122.51879 50.78375 122.5406 50.93984 122.5406 51.111871 L 122.5406 53.048791 L 121.99336 53.048791 L 121.99336 51.111871 C 121.99336 50.885951 121.9418 50.709733 121.83817 50.583301 C 121.73661 50.456869 121.58078 50.393693 121.37144 50.393693 C 121.21599 50.393693 121.07094 50.431092 120.93622 50.505708 C 120.80149 50.57825 120.67826 50.67967 120.56634 50.810248 L 120.56634 53.048791 L 120.0191 53.048791 L 120.0191 50.008059 L 120.34581 50.008059 C 120.38521 50.008059 120.4172 50.01741 120.44207 50.036063 C 120.46694 50.052643 120.48169 50.080694 120.48583 50.120074 L 120.53192 50.443283 C 120.66249 50.298197 120.80897 50.182623 120.97064 50.095571 C 121.13231 50.006447 121.31872 49.961386 121.53013 49.961386 z M 126.04106 49.961386 C 126.26283 49.961386 126.46314 49.998786 126.64138 50.073401 C 126.81963 50.145944 126.97092 50.251064 127.09528 50.387859 C 127.21964 50.522582 127.31482 50.686333 127.38115 50.87909 C 127.44955 51.071847 127.48383 51.287153 127.48383 51.525508 C 127.48383 51.765937 127.44955 51.98267 127.38115 52.175427 C 127.31481 52.368184 127.21963 52.53278 127.09528 52.669575 C 126.97092 52.804298 126.81963 52.908834 126.64138 52.983449 C 126.46314 53.055993 126.26283 53.092547 126.04106 53.092547 C 125.81928 53.092547 125.61871 53.055993 125.43839 52.983449 C 125.26015 52.908834 125.10743 52.804298 124.981 52.669575 C 124.85664 52.53278 124.76061 52.368184 124.69221 52.175427 C 124.62588 51.98267 124.59245 51.765937 124.59245 51.525508 C 124.59245 51.287153 124.62588 51.071847 124.69221 50.87909 C 124.76061 50.686333 124.85664 50.522582 124.981 50.387859 C 125.10743 50.251064 125.26015 50.145944 125.43839 50.073401 C 125.61871 49.998786 125.81928 49.961386 126.04106 49.961386 z M 132.3343 49.961386 C 132.52291 49.961386 132.69376 49.992552 132.84711 50.054732 C 133.00049 50.116912 133.13139 50.204176 133.23917 50.3161 L 133.11782 50.512125 C 133.09295 50.557725 133.05556 50.580384 133.0058 50.580384 C 132.97474 50.580384 132.94045 50.568763 132.90312 50.545963 C 132.86786 50.523163 132.82423 50.49966 132.77244 50.474787 C 132.72271 50.44784 132.66264 50.422911 132.59216 50.400111 C 132.52376 50.377311 132.44189 50.365689 132.34655 50.365689 C 132.26572 50.365689 132.19319 50.377311 132.12894 50.400111 C 132.06467 50.422911 132.01 50.454076 131.96442 50.493456 C 131.91882 50.532836 131.88369 50.579585 131.85882 50.633475 C 131.83395 50.685288 131.82148 50.740803 131.82148 50.800913 C 131.82148 50.879674 131.84186 50.945122 131.88332 50.996939 C 131.92479 51.048759 131.98004 51.093235 132.04843 51.13054 C 132.11682 51.167846 132.19415 51.202129 132.28121 51.23322 C 132.37033 51.26224 132.46072 51.292562 132.55191 51.323648 C 132.64311 51.354742 132.73206 51.390713 132.81911 51.432163 C 132.90823 51.473616 132.98699 51.524326 133.05539 51.584433 C 133.12379 51.644539 133.17904 51.718493 133.2205 51.805545 C 133.26196 51.890524 133.28234 51.993632 133.28234 52.115919 C 133.28234 52.25686 133.25883 52.387758 133.21116 52.50797 C 133.1635 52.626112 133.09266 52.728375 132.99938 52.815427 C 132.90818 52.902479 132.7943 52.971044 132.65751 53.020788 C 132.52278 53.070534 132.36754 53.095464 132.19136 53.095464 C 131.99032 53.095464 131.80702 53.061182 131.64121 52.992784 C 131.47747 52.924387 131.33865 52.835433 131.22465 52.725582 L 131.35184 52.520222 C 131.36844 52.493275 131.38796 52.472887 131.41076 52.458381 C 131.43356 52.443874 131.463 52.436211 131.49827 52.436211 C 131.5356 52.436211 131.573 52.450947 131.61029 52.479967 C 131.64762 52.506913 131.6921 52.538079 131.74389 52.573312 C 131.79775 52.606472 131.86177 52.637638 131.93641 52.666658 C 132.01103 52.693605 132.10453 52.706913 132.21645 52.706913 C 132.31179 52.706913 132.39366 52.693605 132.46206 52.666658 C 132.53254 52.639711 132.59033 52.604584 132.63592 52.561061 C 132.68152 52.515461 132.7158 52.462479 132.7386 52.402373 C 132.7614 52.342267 132.77302 52.27909 132.77302 52.212765 C 132.77302 52.129858 132.75121 52.061293 132.70768 52.007405 C 132.66621 51.951445 132.61095 51.904696 132.54257 51.867386 C 132.47417 51.828006 132.39542 51.793724 132.30629 51.764706 C 132.21924 51.735693 132.12944 51.705954 132.03618 51.674861 C 131.94498 51.641701 131.85459 51.605145 131.76547 51.565764 C 131.67842 51.52431 131.60051 51.472756 131.53211 51.410576 C 131.46372 51.346325 131.4082 51.268407 131.36467 51.177213 C 131.3232 51.086016 131.30225 50.975246 131.30225 50.844669 C 131.30225 50.726527 131.3249 50.61433 131.3705 50.508625 C 131.4161 50.400846 131.4824 50.306504 131.56945 50.225671 C 131.6565 50.144837 131.76415 50.080817 131.89266 50.033146 C 132.02116 49.985473 132.16848 49.961386 132.3343 49.961386 z M 135.13408 49.961386 C 135.31647 49.961386 135.48562 49.991708 135.64106 50.051815 C 135.79652 50.111922 135.93137 50.20003 136.04537 50.3161 C 136.15937 50.432169 136.24832 50.574104 136.31257 50.741989 C 136.37684 50.909874 136.40883 51.102519 136.40883 51.320148 C 136.40883 51.405127 136.39949 51.46207 136.38083 51.491087 C 136.36216 51.518034 136.32787 51.531926 136.27815 51.531926 L 134.24496 51.531926 C 134.24896 51.72261 134.27476 51.88948 134.32256 52.032491 C 134.37022 52.173432 134.43567 52.290435 134.51858 52.383704 C 134.60356 52.476974 134.70414 52.547229 134.82021 52.594898 C 134.93628 52.640498 135.06574 52.663157 135.20876 52.663157 C 135.3414 52.663157 135.45672 52.649005 135.55414 52.619985 C 135.65156 52.588898 135.73428 52.554616 135.80267 52.517305 C 135.87314 52.479998 135.93236 52.446562 135.98003 52.417542 C 136.02769 52.386449 136.06905 52.370869 136.10429 52.370869 C 136.12709 52.370869 136.14662 52.376254 136.16322 52.386621 C 136.17982 52.394914 136.19457 52.407379 136.20697 52.423959 L 136.36216 52.622902 C 136.29376 52.703736 136.21273 52.773991 136.11946 52.834096 C 136.02826 52.89213 135.92996 52.941151 135.82426 52.980532 C 135.71855 53.017839 135.60863 53.04589 135.49463 53.064543 C 135.38271 53.083197 135.27192 53.092547 135.16209 53.092547 C 134.95067 53.092547 134.75575 53.05742 134.57751 52.98695 C 134.39926 52.91648 134.24486 52.812788 134.11428 52.675992 C 133.98577 52.537127 133.8852 52.36714 133.81266 52.166092 C 133.74011 51.962972 133.70414 51.729812 133.70414 51.466584 C 133.70414 51.255173 133.73614 51.057981 133.80041 50.87559 C 133.86674 50.691123 133.96108 50.531914 134.08336 50.397194 C 134.20772 50.260398 134.35816 50.15359 134.53434 50.076902 C 134.71259 50.000214 134.91231 49.961386 135.13408 49.961386 z M 143.39867 49.961386 C 143.58104 49.961386 143.7502 49.991708 143.90565 50.051815 C 144.06109 50.111922 144.19595 50.20003 144.30995 50.3161 C 144.42394 50.432169 144.5129 50.574104 144.57715 50.741989 C 144.64142 50.909874 144.67342 51.102519 144.67342 51.320148 C 144.67342 51.405127 144.66408 51.46207 144.64541 51.491087 C 144.62675 51.518034 144.59247 51.531926 144.54273 51.531926 L 142.50955 51.531926 C 142.51355 51.72261 142.53934 51.88948 142.58714 52.032491 C 142.63481 52.173432 142.70026 52.290435 142.78317 52.383704 C 142.86815 52.476974 142.96872 52.547229 143.08479 52.594898 C 143.20086 52.640498 143.33033 52.663157 143.47334 52.663157 C 143.60599 52.663157 143.7213 52.649005 143.81872 52.619985 C 143.91613 52.588898 143.99885 52.554616 144.06725 52.517305 C 144.13772 52.479998 144.19694 52.446562 144.24461 52.417542 C 144.29228 52.386449 144.33364 52.370869 144.36888 52.370869 C 144.39168 52.370869 144.4112 52.376254 144.4278 52.386621 C 144.4444 52.394914 144.45916 52.407379 144.47156 52.423959 L 144.62674 52.622902 C 144.55835 52.703736 144.47732 52.773991 144.38404 52.834096 C 144.29285 52.89213 144.19455 52.941151 144.08884 52.980532 C 143.98313 53.017839 143.87321 53.04589 143.75921 53.064543 C 143.64729 53.083197 143.53652 53.092547 143.42667 53.092547 C 143.21526 53.092547 143.02035 53.05742 142.84209 52.98695 C 142.66385 52.91648 142.50944 52.812788 142.37886 52.675992 C 142.25036 52.537127 142.14979 52.36714 142.07724 52.166092 C 142.0047 51.962972 141.96873 51.729812 141.96873 51.466584 C 141.96873 51.255173 142.00072 51.057981 142.06499 50.87559 C 142.13132 50.691123 142.22567 50.531914 142.34794 50.397194 C 142.4723 50.260398 142.62274 50.15359 142.79892 50.076902 C 142.97717 50.000214 143.17689 49.961386 143.39867 49.961386 z M 89.97991 50.008059 L 90.502646 50.008059 C 90.544097 50.008059 90.573837 50.015722 90.592491 50.030229 C 90.613217 50.044735 90.631918 50.06428 90.648498 50.089153 L 91.282664 51.192965 C 91.290958 51.170165 91.299464 51.148349 91.307751 51.127623 C 91.318118 51.104823 91.331426 51.082164 91.348006 51.059364 L 91.879493 50.101405 C 91.898146 50.072385 91.918274 50.049726 91.939001 50.033146 C 91.959727 50.016566 91.984657 50.008059 92.013677 50.008059 L 92.514243 50.008059 L 91.605874 51.460166 L 92.554498 53.048791 L 92.028846 53.048791 C 91.987392 53.048791 91.953108 53.037754 91.926166 53.014954 C 91.901292 52.99008 91.880904 52.963723 91.864324 52.936777 L 91.220823 51.786876 C 91.204243 51.834549 91.185542 51.874481 91.164816 51.907642 L 90.583156 52.936777 C 90.566576 52.965797 90.546188 52.992154 90.521315 53.014954 C 90.498515 53.037754 90.467349 53.048791 90.427969 53.048791 L 89.939655 53.048791 L 90.884779 51.48817 L 89.97991 50.008059 z M 138.96767 50.008059 L 139.41806 50.008059 C 139.45953 50.008059 139.49524 50.01968 139.52424 50.04248 C 139.55324 50.06528 139.57276 50.091054 139.58316 50.120074 L 140.23308 52.066329 C 140.26002 52.138872 140.28268 52.209709 140.30134 52.278107 C 140.32001 52.346504 140.33732 52.415914 140.35385 52.486384 C 140.36838 52.417986 140.38536 52.349421 140.40402 52.281024 C 140.42476 52.210553 140.4497 52.138872 140.4787 52.066329 L 141.13737 50.120074 C 141.14977 50.088987 141.16988 50.063214 141.19688 50.04248 C 141.22588 50.01968 141.25787 50.008059 141.29314 50.008059 L 141.72545 50.008059 L 140.59363 53.048791 L 140.0989 53.048791 L 138.96767 50.008059 z M 88.478213 50.359855 C 88.223279 50.359855 88.02128 50.434069 87.872051 50.583301 C 87.724892 50.732533 87.632822 50.9368 87.595514 51.195882 L 89.252398 51.195882 C 89.252398 51.073595 89.234541 50.961981 89.199308 50.860421 C 89.164075 50.756788 89.113365 50.66868 89.047038 50.596136 C 88.980711 50.521521 88.898836 50.46315 88.801422 50.421697 C 88.706083 50.380244 88.598428 50.359855 88.478213 50.359855 z M 103.47243 50.359855 C 103.2175 50.359855 103.0155 50.434069 102.86627 50.583301 C 102.71911 50.732533 102.62704 50.9368 102.58973 51.195882 L 104.24661 51.195882 C 104.24661 51.073595 104.22931 50.961981 104.19411 50.860421 C 104.15884 50.756788 104.10813 50.66868 104.04184 50.596136 C 103.9755 50.521521 103.89363 50.46315 103.79622 50.421697 C 103.70088 50.380244 103.59264 50.359855 103.47243 50.359855 z M 135.14283 50.359855 C 134.88817 50.35997 134.68579 50.434185 134.53667 50.583301 C 134.38952 50.732533 134.29745 50.9368 134.26013 51.195882 L 135.91702 51.195882 C 135.91702 51.073595 135.89978 50.961981 135.86451 50.860421 C 135.82931 50.756788 135.7786 50.66868 135.71224 50.596136 C 135.64591 50.521521 135.56401 50.46315 135.46663 50.421697 C 135.37144 50.380311 135.26339 50.359923 135.14342 50.359855 L 135.14283 50.359855 z M 143.408 50.359855 C 143.15306 50.359855 142.95048 50.434069 142.80125 50.583301 C 142.65409 50.732533 142.56202 50.9368 142.52472 51.195882 L 144.18218 51.195882 C 144.18218 51.073595 144.16436 50.961981 144.12909 50.860421 C 144.09383 50.756788 144.04312 50.66868 143.97682 50.596136 C 143.91049 50.521521 143.82862 50.46315 143.73121 50.421697 C 143.63587 50.380244 143.52821 50.359855 143.408 50.359855 z M 106.59951 50.375024 C 106.32385 50.375024 106.11166 50.475599 105.96242 50.676647 C 105.81319 50.877695 105.73839 51.164682 105.73839 51.53776 C 105.73839 51.734662 105.75537 51.903802 105.78857 52.044743 C 105.82383 52.185684 105.87312 52.301842 105.93734 52.393039 C 106.0016 52.482163 106.08036 52.548455 106.17362 52.591981 C 106.26689 52.633435 106.37285 52.653823 106.49099 52.653823 C 106.66303 52.653823 106.81204 52.614735 106.93847 52.535974 C 107.06697 52.45514 107.18624 52.342943 107.2961 52.19993 L 107.2961 50.729737 C 107.19868 50.59916 107.09272 50.507935 106.97872 50.456118 C 106.86473 50.402231 106.73838 50.375024 106.59951 50.375024 z M 97.637164 50.387859 C 97.487935 50.387859 97.35762 50.413633 97.245696 50.465453 C 97.135848 50.517273 97.043193 50.591487 96.968577 50.688899 C 96.896034 50.786312 96.841363 50.905588 96.804055 51.046529 C 96.768822 51.187469 96.750965 51.348104 96.750965 51.528425 C 96.750965 51.708746 96.768822 51.869381 96.804055 52.010322 C 96.841362 52.151262 96.896033 52.270537 96.968577 52.367952 C 97.043193 52.465367 97.135848 52.540165 97.245696 52.591981 C 97.35762 52.641721 97.487935 52.666658 97.637164 52.666658 C 97.784323 52.666658 97.912947 52.641721 98.022798 52.591981 C 98.132649 52.540161 98.223874 52.465364 98.296418 52.367952 C 98.371031 52.270537 98.425704 52.151262 98.460939 52.010322 C 98.498246 51.869381 98.516946 51.708746 98.516946 51.528425 C 98.516946 51.348104 98.498246 51.187469 98.460939 51.046529 C 98.425706 50.905588 98.371033 50.786312 98.296418 50.688899 C 98.223874 50.591484 98.132649 50.517269 98.022798 50.465453 C 97.912947 50.413633 97.784323 50.387859 97.637164 50.387859 z M 113.43415 50.387859 C 113.28492 50.387859 113.1546 50.413633 113.04268 50.465453 C 112.93283 50.517273 112.84018 50.591487 112.76556 50.688899 C 112.69302 50.786312 112.63835 50.905588 112.60104 51.046529 C 112.56578 51.187469 112.54795 51.348104 112.54795 51.528425 C 112.54795 51.708746 112.56578 51.869381 112.60104 52.010322 C 112.63838 52.151262 112.69304 52.270537 112.76556 52.367952 C 112.84018 52.465367 112.93283 52.540165 113.04268 52.591981 C 113.1546 52.641721 113.28492 52.666658 113.43415 52.666658 C 113.58131 52.666658 113.70994 52.641721 113.81979 52.591981 C 113.92964 52.540161 114.02086 52.465364 114.09341 52.367952 C 114.16802 52.270537 114.22269 52.151262 114.25793 52.010322 C 114.29526 51.869381 114.31393 51.708746 114.31393 51.528425 C 114.31393 51.348104 114.29526 51.187469 114.25793 51.046529 C 114.22273 50.905588 114.16805 50.786312 114.09341 50.688899 C 114.02086 50.591484 113.92964 50.517269 113.81979 50.465453 C 113.70994 50.413633 113.58131 50.387859 113.43415 50.387859 z M 126.04106 50.387859 C 125.89182 50.387859 125.76151 50.413633 125.64959 50.465453 C 125.53974 50.517273 125.44767 50.591487 125.37305 50.688899 C 125.30051 50.786312 125.24525 50.905588 125.20795 51.046529 C 125.17268 51.187469 125.15544 51.348104 125.15544 51.528425 C 125.15544 51.708746 125.17268 51.869381 125.20795 52.010322 C 125.24528 52.151262 125.30054 52.270537 125.37305 52.367952 C 125.44767 52.465367 125.53974 52.540165 125.64959 52.591981 C 125.76151 52.641721 125.89182 52.666658 126.04106 52.666658 C 126.18821 52.666658 126.31684 52.641721 126.42669 52.591981 C 126.53654 52.540161 126.62777 52.465364 126.70031 52.367952 C 126.77492 52.270537 126.83017 52.151262 126.86541 52.010322 C 126.90275 51.869381 126.92142 51.708746 126.92142 51.528425 C 126.92142 51.348104 126.90275 51.187469 126.86541 51.046529 C 126.83015 50.905588 126.7749 50.786312 126.70031 50.688899 C 126.62777 50.591484 126.53654 50.517269 126.42669 50.465453 C 126.31684 50.413633 126.18821 50.387859 126.04106 50.387859 z M 94.403324 50.393693 C 94.233366 50.393693 94.082926 50.433364 93.952348 50.512125 C 93.823843 50.590886 93.705996 50.702499 93.598218 50.847586 L 93.598218 52.315445 C 93.69356 52.446022 93.798096 52.538092 93.912093 52.591981 C 94.028159 52.643795 94.156786 52.669575 94.297727 52.669575 C 94.575461 52.669575 94.788496 52.569 94.937727 52.367952 C 95.089031 52.166904 95.164674 51.879917 95.164674 51.506839 C 95.164674 51.309937 95.1474 51.140796 95.112167 50.999856 C 95.079007 50.858915 95.029141 50.744185 94.962814 50.655061 C 94.89856 50.563864 94.818957 50.497571 94.723616 50.456118 C 94.630346 50.414665 94.523538 50.393693 94.403324 50.393693 z M 129.48959 50.393693 C 129.3217 50.393693 129.17354 50.433364 129.04503 50.512125 C 128.9186 50.590886 128.80244 50.702499 128.69674 50.847586 L 128.69674 52.315445 C 128.79208 52.446022 128.8972 52.538092 129.0112 52.591981 C 129.1252 52.643795 129.2507 52.669575 129.38749 52.669575 C 129.6673 52.669575 129.88176 52.569 130.031 52.367952 C 130.18023 52.166904 130.25444 51.867449 130.25444 51.469501 C 130.25444 51.100568 130.18815 50.829164 130.0555 50.655061 C 129.92285 50.480958 129.73416 50.393693 129.48959 50.393693 z M 118.651 51.680695 C 118.4085 51.691062 118.20255 51.712033 118.03259 51.74312 C 117.86264 51.772133 117.72381 51.811805 117.61603 51.861552 C 117.51033 51.911299 117.43326 51.969933 117.38559 52.038325 C 117.33792 52.104652 117.31441 52.17945 117.31441 52.262355 C 117.31441 52.341115 117.32688 52.409681 117.35175 52.467715 C 117.37868 52.523675 117.41381 52.56984 117.45735 52.60715 C 117.50088 52.642383 117.55243 52.669591 117.61253 52.688244 C 117.67267 52.704824 117.73727 52.713331 117.80564 52.713331 C 117.89684 52.713331 117.9804 52.70398 118.05709 52.685327 C 118.13378 52.666674 118.20631 52.64031 118.2747 52.60715 C 118.3431 52.571917 118.40771 52.529713 118.46781 52.479967 C 118.53001 52.428147 118.59092 52.371204 118.651 52.309028 L 118.651 51.680695 z " /> From b9fb5e74d2f7220e8fef84e9ffbc5c1ccded33c1 Mon Sep 17 00:00:00 2001 From: Tim Bannister Date: Mon, 30 Jan 2023 18:45:38 +0000 Subject: [PATCH 053/279] Delete superseded raster versions of images --- .../Example.png | Bin 118529 -> 0 bytes .../Microservices.png | Bin 437391 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/Example.png delete mode 100644 content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/Microservices.png diff --git a/content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/Example.png b/content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/Example.png deleted file mode 100644 index 175c21a889626ce3f903b744ed9319a61cc5bae5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 118529 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 diff --git a/content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/Microservices.png b/content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/Microservices.png deleted file mode 100644 index da0f60a5054a481ef96453fb0d518046586bdac2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 437391 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 )#q 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 z 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

USN1JaX-nv9Dh&(iZq)ie)j=f?cERhx(Akt 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%0A4v5m$_FT0PzjN~JL7^< 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

_lF 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 ZgZ=Vf`A_^Ik3TQ~fv2mV%Q~loCIH(tZ{+|0 From 4129e0770389d1ee3f4a191a50c333593fed8108 Mon Sep 17 00:00:00 2001 From: Jun10ng Date: Tue, 31 Jan 2023 22:53:08 +0800 Subject: [PATCH 054/279] Update hello-minikube.md --- content/en/docs/tutorials/hello-minikube.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/content/en/docs/tutorials/hello-minikube.md b/content/en/docs/tutorials/hello-minikube.md index c3a48105148..dfaea661eb4 100644 --- a/content/en/docs/tutorials/hello-minikube.md +++ b/content/en/docs/tutorials/hello-minikube.md @@ -90,14 +90,17 @@ tutorial has only one Container. A Kubernetes Pod and restarts the Pod's Container if it terminates. Deployments are the recommended way to manage the creation and scaling of Pods. -1. Use the `kubectl create` command to create a Deployment that manages a Pod. The +1. Katacoda environment only: At the top of the terminal pane, click the plus sign, and then click open a new terminal. + +2. Use the `kubectl create` command to create a Deployment that manages a Pod. The Pod runs a Container based on the provided Docker image. + ```shell kubectl create deployment hello-node --image=registry.k8s.io/e2e-test-images/agnhost:2.39 -- /agnhost netexec --http-port=8080 ``` -2. View the Deployment: +3. View the Deployment: ```shell kubectl get deployments @@ -110,7 +113,7 @@ Pod runs a Container based on the provided Docker image. hello-node 1/1 1 1 1m ``` -3. View the Pod: +4. View the Pod: ```shell kubectl get pods @@ -123,13 +126,13 @@ Pod runs a Container based on the provided Docker image. hello-node-5f76cf6ccf-br9b5 1/1 Running 0 1m ``` -4. View cluster events: +5. View cluster events: ```shell kubectl get events ``` -5. View the `kubectl` configuration: +6. View the `kubectl` configuration: ```shell kubectl config view From 21093df2798e409dbd3a17c6e3bc8acc1c9b7b62 Mon Sep 17 00:00:00 2001 From: EuricoAbreu Date: Tue, 31 Jan 2023 12:56:00 -0300 Subject: [PATCH 055/279] Minor fixes --- content/pt-br/docs/concepts/security/windows-security.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/content/pt-br/docs/concepts/security/windows-security.md b/content/pt-br/docs/concepts/security/windows-security.md index e29706ece70..21332f6aecd 100644 --- a/content/pt-br/docs/concepts/security/windows-security.md +++ b/content/pt-br/docs/concepts/security/windows-security.md @@ -12,17 +12,16 @@ Esta página descreve considerações de segurança e boas práticas específica ## Proteção para dados Secret nos Nós -No Windows, os dados do Secret são escritos em texto não-encriptado no Nó local do -armazenamento (em comparação ao uso de tmpfs / sistemas de arquivo em memória no Linux). Como um operador do cluster, você deve tomar as duas medidas adicionais a seguir: +No Windows, os dados do Secret são escritos em texto não-encriptado no armazenamento local do nó (em comparação ao uso de tmpfs / sistemas de arquivo em memória no Linux). Como um operador do cluster, você deve tomar as duas medidas adicionais a seguir: -1. Use ACLs em arquivos para proteger a localização do arquivo Secrets. +1. Aplique ACLs em arquivos para proteger a localização do arquivo Secrets. 2. Aplicar criptografia a nível de volume usando [BitLocker](https://docs.microsoft.com/windows/security/information-protection/bitlocker/bitlocker-how-to-deploy-on-windows-server). ## Usuários dos Contêineres [RunAsUsername](/docs/tasks/configure-pod-container/configure-runasusername) -pode ser utilizado para Pods com Windows ou contêiner para executar os processos do contêiner como usuário específico. Isto é aproximadamente equivalente a +pode ser utilizado para Pods ou contêineres com Windows para executar os processos do contêiner como usuário específico. Isto é aproximadamente equivalente a [RunAsUser](/docs/concepts/security/pod-security-policy/#users-and-groups). Os contêineres Windows oferecem duas contas de usuário padrão, ContainerUser e ContainerAdministrator. As diferenças entre estas duas contas de usuário são descritas em @@ -45,7 +44,7 @@ Contêineres Windows também podem rodar como identidades do Active Directory us ## Isolamento de segurança a nível do Pod -Mecanismos de contexto de segurança de Pod específicos para Linux (como SELinux, AppArmor, Seccomp, ou capabilities customizados para POSIX) não são suportados nos nós do Windows. +Mecanismos de contexto de segurança de Pod específicos para Linux (como SELinux, AppArmor, Seccomp, ou capabilities customizados para POSIX) não são suportados nos nós com Windows. Contêineres privilegiados [não são suportados](/docs/concepts/windows/intro/#compatibility-v1-pod-spec-containers-securitycontext) no Windows. From 62ad84a1eba37049013d396fc59e57a3ee3f9a24 Mon Sep 17 00:00:00 2001 From: Jun10ng Date: Wed, 1 Feb 2023 15:52:12 +0800 Subject: [PATCH 056/279] Update hello-minikube.md --- content/en/docs/tutorials/hello-minikube.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/content/en/docs/tutorials/hello-minikube.md b/content/en/docs/tutorials/hello-minikube.md index dfaea661eb4..08e5b3a7d08 100644 --- a/content/en/docs/tutorials/hello-minikube.md +++ b/content/en/docs/tutorials/hello-minikube.md @@ -92,7 +92,7 @@ recommended way to manage the creation and scaling of Pods. 1. Katacoda environment only: At the top of the terminal pane, click the plus sign, and then click open a new terminal. -2. Use the `kubectl create` command to create a Deployment that manages a Pod. The +1. Use the `kubectl create` command to create a Deployment that manages a Pod. The Pod runs a Container based on the provided Docker image. @@ -100,7 +100,7 @@ Pod runs a Container based on the provided Docker image. kubectl create deployment hello-node --image=registry.k8s.io/e2e-test-images/agnhost:2.39 -- /agnhost netexec --http-port=8080 ``` -3. View the Deployment: +1. View the Deployment: ```shell kubectl get deployments @@ -113,7 +113,7 @@ Pod runs a Container based on the provided Docker image. hello-node 1/1 1 1 1m ``` -4. View the Pod: +1. View the Pod: ```shell kubectl get pods @@ -126,13 +126,13 @@ Pod runs a Container based on the provided Docker image. hello-node-5f76cf6ccf-br9b5 1/1 Running 0 1m ``` -5. View cluster events: +1. View cluster events: ```shell kubectl get events ``` -6. View the `kubectl` configuration: +1. View the `kubectl` configuration: ```shell kubectl config view From e18178b92919260838beb214a6b803eac9cf6997 Mon Sep 17 00:00:00 2001 From: moriya Date: Wed, 1 Feb 2023 23:25:42 +0900 Subject: [PATCH 057/279] reflect review comments --- .../concepts/scheduling-eviction/pod-priority-preemption.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/ja/docs/concepts/scheduling-eviction/pod-priority-preemption.md b/content/ja/docs/concepts/scheduling-eviction/pod-priority-preemption.md index d674b40edf5..2e3876e3509 100644 --- a/content/ja/docs/concepts/scheduling-eviction/pod-priority-preemption.md +++ b/content/ja/docs/concepts/scheduling-eviction/pod-priority-preemption.md @@ -143,7 +143,7 @@ Podが作成されると、スケジューリング待ちのキューに入り Pod PがノードNのPodをプリエンプトした場合、ノードNの名称がPのステータスの`nominatedNodeName`フィールドに設定されます。このフィールドはスケジューラーがPod Pのために予約しているリソースの追跡を助け、ユーザーにクラスターにおけるプリエンプトに関する情報を与えます。 -Pod Pは必ずしも「指名したノード」へスケジューリングされないことに注意してください。Podがプリエンプトされると、そのPodは終了までの猶予期間を得ます。スケジューラーがPodの終了を待つ間に他のノードが利用可能になると、スケジューラーは他のノードをPod Pのスケジューリング先にする可能性があります。この結果、Podの`nominatedNodeName`と`nodeName`は必ずしも一致しません。また、スケジューラーがノードNのPodをプリエンプトさせた後に、Pod Pよりも優先度の高いPodが来た場合、スケジューラーはノードNをその新しい優先度の高いPodへ与えます。このような場合は、スケジューラーはPod Pの`nominatedNodeName`を消去します。これによって、スケジューラーはPod Pが他のノードのPodをプリエンプトさせられるようにします。 +Pod Pは必ずしも「指名したノード」へスケジューリングされないことに注意してください。スケジューラーは、他のノードに対して処理を繰り返す前に、常に「指定したノード」に対して試行します。Podがプリエンプトされると、そのPodは終了までの猶予期間を得ます。スケジューラーがPodの終了を待つ間に他のノードが利用可能になると、スケジューラーは他のノードをPod Pのスケジューリング先にすることがあります。この結果、Podの`nominatedNodeName`と`nodeName`は必ずしも一致しません。また、スケジューラーがノードNのPodをプリエンプトさせた後に、Pod Pよりも優先度の高いPodが来た場合、スケジューラーはノードNをその新しい優先度の高いPodへ与えることもあります。このような場合は、スケジューラーはPod Pの`nominatedNodeName`を消去します。これによって、スケジューラーはPod Pが他のノードのPodをプリエンプトさせられるようにします。 ### プリエンプトの制限 @@ -167,7 +167,7 @@ Podは作業を完了し、終了するために十分な時間が与えられ このような場合であったとしても、上記の条件は真である必要があります。偽であれば、そのノードはプリエンプションの対象とはされません。 {{< /note >}} -待機状態のPodが、優先度の低いPodとの間でPod間のアフィニティを持つ場合、Pod間のアフィニティはそれらの優先度の低いPodがなければ満たされません。この場合、スケジューラーはノードのどのPodもプリエンプトしようとはせず、代わりに他のノードを探します。スケジューラーは適切なノードを探せる場合と探せない場合があります。この場合、待機状態のPodがスケジューリングされる保証はありません。 +待機状態のPodが、優先度の低いPodとの間でPod間の{{< glossary_tooltip text="アフィニティ" term_id="affinity" >}}を持つ場合、Pod間のアフィニティはそれらの優先度の低いPodがなければ満たされません。この場合、スケジューラーはノードのどのPodもプリエンプトしようとはせず、代わりに他のノードを探します。スケジューラーは適切なノードを探せる場合と探せない場合があります。この場合、待機状態のPodがスケジューリングされる保証はありません。 この問題に対して推奨される解決策は、優先度が同一または高いPodに対してのみPod間のアフィニティを作成することです。 @@ -226,7 +226,7 @@ Podがその期間内に終了しない場合、強制終了されます。プ Podの優先度と{{< glossary_tooltip text="QoSクラス" term_id="qos-class" >}}は直交する機能で、わずかに相互作用がありますが、デフォルトではQoSクラスによる優先度の設定の制約はありません。スケジューラーのプリエンプションのロジックはプリエンプションの対象を決めるときにQoSクラスは考慮しません。 プリエンプションはPodの優先度を考慮し、優先度が最も低いものを候補とします。より優先度の高いPodは優先度の低いPodを追い出すだけではプリエンプトを起こしたPodのスケジューリングに不十分な場合と、`PodDisruptionBudget`により優先度の低いPodが保護されている場合のみ対象になります。 -kubeletは[node-pressureによる退避](/docs/concepts/scheduling-eviction/node-pressure-eviction/)を行うPodの順番を決めるために、優先度を利用します。 +kubeletは[node-pressureによる退避](/docs/concepts/scheduling-eviction/node-pressure-eviction/)を行うPodの順番を決めるために、優先度を利用します。QoSクラスを使用して、最も退避される可能性の高いPodの順番を推定することができます。 kubeletは追い出すPodの順位付けを次の順で行います。 From 20461d6b7c6543f27e8d4669f2e78ae1aed96237 Mon Sep 17 00:00:00 2001 From: Yamori <41197469+Gekko0114@users.noreply.github.com> Date: Thu, 2 Feb 2023 22:34:52 +0900 Subject: [PATCH 058/279] Update content/ja/docs/concepts/scheduling-eviction/pod-priority-preemption.md Co-authored-by: nasa9084 --- .../docs/concepts/scheduling-eviction/pod-priority-preemption.md | 1 - 1 file changed, 1 deletion(-) diff --git a/content/ja/docs/concepts/scheduling-eviction/pod-priority-preemption.md b/content/ja/docs/concepts/scheduling-eviction/pod-priority-preemption.md index 2e3876e3509..9feea3e227d 100644 --- a/content/ja/docs/concepts/scheduling-eviction/pod-priority-preemption.md +++ b/content/ja/docs/concepts/scheduling-eviction/pod-priority-preemption.md @@ -229,7 +229,6 @@ Podの優先度と{{< glossary_tooltip text="QoSクラス" term_id="qos-class" > kubeletは[node-pressureによる退避](/docs/concepts/scheduling-eviction/node-pressure-eviction/)を行うPodの順番を決めるために、優先度を利用します。QoSクラスを使用して、最も退避される可能性の高いPodの順番を推定することができます。 kubeletは追い出すPodの順位付けを次の順で行います。 - 1. 枯渇したリソースを要求以上に使用しているか 1. Podの優先度 1. 要求に対するリソースの使用量 From ae6f1434e95a67470d425fb4b5f5bd17af51bd3a Mon Sep 17 00:00:00 2001 From: Ana Carolina Rodrigues Date: Thu, 2 Feb 2023 11:38:30 -0300 Subject: [PATCH 059/279] Update content/pt-br/docs/tasks/debug/debug-application/debug-init-containers.md --- .../debug-init-containers.md | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/content/pt-br/docs/tasks/debug/debug-application/debug-init-containers.md b/content/pt-br/docs/tasks/debug/debug-application/debug-init-containers.md index d79113520d2..79961462d0c 100644 --- a/content/pt-br/docs/tasks/debug/debug-application/debug-init-containers.md +++ b/content/pt-br/docs/tasks/debug/debug-application/debug-init-containers.md @@ -1,5 +1,5 @@ --- -title: Contêineres de inicialização de depuração +title: Depurando Contêineres de Inicialização content_type: task weight: 40 --- @@ -42,13 +42,13 @@ valores de status e seus significados. ## Obtendo detalhes sobre os contêineres de inicialização -Veja informações mais detalhadas sobre a execução da Inicialização de Contêineres: +Veja informações mais detalhadas sobre a execução de contêineres de inicialização: ```shell kubectl describe pod ``` -Por exemplo, um pod com duas inicializações de contêineres pode mostrar o seguinte: +Por exemplo, um pod com dois contêineres de inicialização pode mostrar o seguinte: ``` Init Containers: @@ -96,20 +96,20 @@ para acessar seus logs. kubectl logs -c ``` -Inicializações de contêineres que executam uma impressão de comandos de script de shell +Contêineres de inicialização que executam comandos de script de shell imprimem à medida que são executados. Por exemplo, você pode fazer isso no Bash executando `set -x` no início do script. ## Entendendo sobre o status do pod { #understanding-pod-status } -Um status do Pod começando com `Init:` resume o status da execução da inicialização de contêineres. +Um status do Pod começando com `Init:` resume o status da execução de contêineres de inicialização. A tabela abaixo descreve alguns valores de status de exemplo que você pode ver durante a depuração de contêineres de inicialização. Status | Significado ------ | ------- -`Init:N/M` | O pod tem inicializações de contêineres `M` e `N` que foram concluídas até agora. -`Init:Error` | Uma inicialização de contêiner falhou ao executar. -`Init:CrashLoopBackOff` | Uma inicialização de contêiner falhou repetidamente. -`Pending` | O pod ainda não começou a executar a inicialização de contêineres. -`PodInitializing` ou `Running` | O pod já concluiu a execução das inicializações de contêineres. \ No newline at end of file +`Init:N/M` | O pod tem contêineres de inicialização `M` e `N` que foram concluídas até agora. +`Init:Error` | Um contêiner de inicialização falhou ao executar. +`Init:CrashLoopBackOff` | Um contêiner de inicialização falhou repetidamente. +`Pending` | O pod ainda não começou a executar o contêiner de inicialização. +`PodInitializing` ou `Running` | O pod já concluiu a execução dos contêineres de inicialização. \ No newline at end of file From ca383c3239b825c8f71af9b96dff7062f64deeb4 Mon Sep 17 00:00:00 2001 From: Mike Spreitzer Date: Thu, 2 Feb 2023 17:36:05 -0500 Subject: [PATCH 060/279] Extended APF Observability with logging and response headers --- .../cluster-administration/flow-control.md | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/content/en/docs/concepts/cluster-administration/flow-control.md b/content/en/docs/concepts/cluster-administration/flow-control.md index 86fdcf9fb27..15456f2b91c 100644 --- a/content/en/docs/concepts/cluster-administration/flow-control.md +++ b/content/en/docs/concepts/cluster-administration/flow-control.md @@ -638,6 +638,10 @@ poorly-behaved workloads that may be harming system health. standard deviation of seat demand seen during the last concurrency borrowing adjustment period. +* `apiserver_flowcontrol_demand_seats_smoothed` is a gauge vector + holding, for each priority level, the smoothed enveloped seat demand + determined at the last concurrency adjustment. + * `apiserver_flowcontrol_target_seats` is a gauge vector holding, for each priority level, the concurrency target going into the borrowing allocation problem. @@ -761,7 +765,34 @@ serves the following additional paths at its HTTP[S] ports. 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, ``` - + +### Debug logging + +At `-v=3` or more verbose the server outputs an httplog line for every +request, and it includes the following attributes. + +- `apf_fs`: the name of the flow schema to which the request was classified. +- `apf_pl`: the name of the priority level for that flow schema. +- `apf_iseats`: the number of seats determined for the initial + (normal) stage of execution of the request. +- `apf_fseats`: the number of seats determined for the final stage of + execution (accounting for the associated WATCH notifications) of the + request. +- `apf_additionalLatency`: the duration of the final stage of + execution of the request. + +At higher levels of verbosity there will be log lines exposing details +of how APF handled the request, primarily for debug purposes. + +### Response headers + +APF adds the following two headers to each HTTP response message. + +- `X-Kubernetes-PF-FlowSchema-UID` holds the UID of the FlowSchema + object to which the corresponding request was classified. +- `X-Kubernetes-PF-PriorityLevel-UID` holds the UID of the + PriorityLevelConfiguration object associated with that FlowSchema. + ## {{% heading "whatsnext" %}} From 7dfb17ccb46cfc9b5978932b7e4a05a66375926c Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Fri, 3 Feb 2023 17:12:24 +0800 Subject: [PATCH 061/279] [zh] Resync kubeadm-config.v1beta2.md --- .../config-api/kubeadm-config.v1beta2.md | 103 +++++++++--------- 1 file changed, 51 insertions(+), 52 deletions(-) diff --git a/content/zh-cn/docs/reference/config-api/kubeadm-config.v1beta2.md b/content/zh-cn/docs/reference/config-api/kubeadm-config.v1beta2.md index 773ae3d0c37..c3b6b5d8007 100644 --- a/content/zh-cn/docs/reference/config-api/kubeadm-config.v1beta2.md +++ b/content/zh-cn/docs/reference/config-api/kubeadm-config.v1beta2.md @@ -13,11 +13,13 @@ auto_generated: true -->

概述

+

包 v1beta2 已被 v1beta3 所弃用。

包 v1beta2 定义 kubeadm 配置文件格式的 v1beta2 版本。 此版本改进了 v1beta1 的格式,修复了一些小问题并添加了一些新的字段。

@@ -43,7 +45,7 @@ This version improves on the v1beta1 format by fixing some minor issues and addi

参阅 Kubernetes 1.15 的变更记录以了解详细信息。

-

从老的 kubeadm 配置版本迁移:

+

从老的 kubeadm 配置版本迁移:

请使用 kubeadm v1.15.x 的 "kubeadm config migrate" 命令将 v1beta1 版本的配置文件转换为 v1beta2。 (从更老版本的 kubeadm 配置文件迁移需要使用更老版本的 kubeadm。例如:

@@ -169,7 +171,7 @@ use it to customize the node name, the CRI socket to use or any other settings t node only (e.g. the node ip).

  • -

    apiServer, that represents the endpoint of the instance of the API server to be deployed on this node; +

    localAPIEndpoint, that represents the endpoint of the instance of the API server to be deployed on this node; use it e.g. to customize the API server advertise address.

  • @@ -181,20 +183,20 @@ use it e.g. to customize the API server advertise address.

  • nodeRegistration:其中包含与向集群注册新节点相关的字段; 使用这个类型来定制节点名称、要使用的 CRI 套接字或者其他仅对当前节点起作用的设置 (例如节点 IP 地址)。
  • -
  • apiServer:代表的是要部署到此节点上的 API 服务器示例的端点; +
  • localAPIEndpoint:代表的是要部署到此节点上的 API 服务器示例的端点; 使用这个类型可以完成定制 API 服务器公告地址这类操作。
  • apiVersion: kubeadm.k8s.io/v1beta2
     kind: ClusterConfiguration
     networking:
    -    ...
    + ...
     etcd:
    -    ...
    + ...
     apiServer:
    -  extraArgs:
    -    ...
    -  extraVolumes:
    + extraArgs:
    + ...
    + extraVolumes:
         ...
     ...
     
    @@ -395,12 +397,12 @@ are the discovery method used for accessing the cluster info and all the setting to the node where kubeadm is executed, including:

    • -

      NodeRegistration, that holds fields that relate to registering the new node to the cluster; +

      nodeRegistration, that holds fields that relate to registering the new node to the cluster; use it to customize the node name, the CRI socket to use or any other settings that should apply to this node only (e.g. the node IP).

    • -

      APIEndpoint, that represents the endpoint of the instance of the API server to be eventually deployed on this node.

      +

      apiEndpoint, that represents the endpoint of the instance of the API server to be eventually deployed on this node.

    --> @@ -426,8 +428,8 @@ node only (e.g. the node IP).

    - [InitConfiguration](#kubeadm-k8s-io-v1beta2-InitConfiguration) - [JoinConfiguration](#kubeadm-k8s-io-v1beta2-JoinConfiguration) -## `ClusterConfiguration` {#kubeadm-k8s-io-v1beta2-ClusterConfiguration} - +## `ClusterConfiguration` {#kubeadm-k8s-io-v1beta2-ClusterConfiguration} + @@ -617,8 +619,8 @@ when this set to true, and at some point it may become ignored.

    -## `ClusterStatus` {#kubeadm-k8s-io-v1beta2-ClusterStatus} - +## `ClusterStatus` {#kubeadm-k8s-io-v1beta2-ClusterStatus} + @@ -838,8 +840,8 @@ Defaults to 6443.

    -## `APIServer` {#kubeadm-k8s-io-v1beta2-APIServer} - +## `APIServer` {#kubeadm-k8s-io-v1beta2-APIServer} + @@ -907,7 +909,6 @@ to appear.

    - [InitConfiguration](#kubeadm-k8s-io-v1beta2-InitConfiguration) -

    BootstrapToken 描述的是一个启动引导令牌,以 Secret 形式存储在集群中。

    @@ -946,7 +947,7 @@ for, so other administrators can know its purpose. expires [必需]
    -
    meta/v1.Time +meta/v1.Time @@ -1154,8 +1155,8 @@ without leading dash(es). -## `DNS` {#kubeadm-k8s-io-v1beta2-DNS} - +## `DNS` {#kubeadm-k8s-io-v1beta2-DNS} + @@ -1163,7 +1164,6 @@ without leading dash(es). - [ClusterConfiguration](#kubeadm-k8s-io-v1beta2-ClusterConfiguration) -

    DNSAddOnType 定义的是用来辨识 DNS 插件类型的字符串。

    -## `Discovery` {#kubeadm-k8s-io-v1beta2-Discovery} - +## `Discovery` {#kubeadm-k8s-io-v1beta2-Discovery} + @@ -1303,8 +1303,8 @@ contain any other authentication information. -## `Etcd` {#kubeadm-k8s-io-v1beta2-Etcd} - +## `Etcd` {#kubeadm-k8s-io-v1beta2-Etcd} + @@ -1354,8 +1354,8 @@ Etcd 包含用来描述 etcd 配置的元素。 -## `ExternalEtcd` {#kubeadm-k8s-io-v1beta2-ExternalEtcd} - +## `ExternalEtcd` {#kubeadm-k8s-io-v1beta2-ExternalEtcd} + @@ -1381,9 +1381,9 @@ kubeadm 不清楚证书文件的存放位置,因此必须单独提供证书信 -

    endpoints 包含一组 etcd 成员的列表。

    +

    endpoints 包含一组 etcd 成员的列表。外部 etcd 需要。

    caFile [必需]
    @@ -1426,8 +1426,8 @@ Required if using a TLS connection.

    -## `FileDiscovery` {#kubeadm-k8s-io-v1beta2-FileDiscovery} - +## `FileDiscovery` {#kubeadm-k8s-io-v1beta2-FileDiscovery} + @@ -1461,8 +1461,8 @@ file from which to load cluster information.

    -## `HostPathMount` {#kubeadm-k8s-io-v1beta2-HostPathMount} - +## `HostPathMount` {#kubeadm-k8s-io-v1beta2-HostPathMount} + @@ -1511,7 +1511,7 @@ file from which to load cluster information.

    pathType [必需]
    -core/v1.HostPathType +core/v1.HostPathType @@ -1521,8 +1521,8 @@ file from which to load cluster information.

    -## `ImageMeta` {#kubeadm-k8s-io-v1beta2-ImageMeta} - +## `ImageMeta` {#kubeadm-k8s-io-v1beta2-ImageMeta} + @@ -1609,8 +1609,8 @@ Secret 中的证书的秘钥。对应的加密秘钥在 InitConfiguration 结构 -## `LocalEtcd` {#kubeadm-k8s-io-v1beta2-LocalEtcd} - +## `LocalEtcd` {#kubeadm-k8s-io-v1beta2-LocalEtcd} + @@ -1693,8 +1693,8 @@ signing certificate.

    -## `Networking` {#kubeadm-k8s-io-v1beta2-Networking} - +## `Networking` {#kubeadm-k8s-io-v1beta2-Networking} + @@ -1742,8 +1742,8 @@ signing certificate.

    -## `NodeRegistrationOptions` {#kubeadm-k8s-io-v1beta2-NodeRegistrationOptions} - +## `NodeRegistrationOptions` {#kubeadm-k8s-io-v1beta2-NodeRegistrationOptions} + @@ -1793,7 +1793,7 @@ be annotated to the Node API object, for later re-use.

    taints [必需]
    -[]core/v1.Taint +[]core/v1.Taint @@ -30,31 +30,40 @@ kubectl 版本和集群之间的差异必须在一个小版本号之内。 v{{< skew currentVersionAddMinor 0 >}} 和 v{{< skew currentVersionAddMinor 1 >}} 版本的控制面通信。 用最新兼容版本的 kubectl 有助于避免不可预见的问题。 - ## 在 macOS 系统上安装 kubectl {#install-kubectl-on-macos} - 在 macOS 系统上安装 kubectl 有如下方法: -- [用 curl 在 macOS 系统上安装 kubectl](#install-kubectl-binary-with-curl-on-macos) -- [用 Homebrew 在 macOS 系统上安装](#install-with-homebrew-on-macos) -- [用 Macports 在 macOS 上安装](#install-with-macports-on-macos) - +- [在 macOS 系统上安装 kubectl](#install-kubectl-on-macos) + - [用 curl 在 macOS 系统上安装 kubectl](#install-kubectl-binary-with-curl-on-macos) + - [用 Homebrew 在 macOS 系统上安装](#install-with-homebrew-on-macos) + - [用 Macports 在 macOS 系统上安装](#install-with-macports-on-macos) +- [验证 kubectl 配置](#verify-kubectl-configuration) +- [可选的 kubectl 配置和插件](#optional-kubectl-configurations-and-plugins) + - [启用 shell 自动补全功能](#enable-shell-autocompletion) + - [安装 `kubectl convert` 插件](#install-kubectl-convert-plugin) ### 用 curl 在 macOS 系统上安装 kubectl {#install-kubectl-binary-with-curl-on-macos} - 1. 下载最新的发行版: @@ -69,7 +78,7 @@ The following methods exist for installing kubectl on macOS: {{< /tabs >}} {{< note >}} - 根据校验和文件,验证 kubectl: @@ -126,7 +135,7 @@ The following methods exist for installing kubectl on macOS: kubectl: OK ``` - 验证失败时,`shasum` 将以非零值退出,并打印如下输出: @@ -137,13 +146,13 @@ The following methods exist for installing kubectl on macOS: ``` {{< note >}} - 下载的 kubectl 与校验和文件版本要相同。 {{< /note >}} - 3. 将 kubectl 置为可执行文件: @@ -152,7 +161,7 @@ The following methods exist for installing kubectl on macOS: chmod +x ./kubectl ``` - 4. 将可执行文件 kubectl 移动到系统可寻址路径 `PATH` 内的一个位置: @@ -169,7 +178,7 @@ The following methods exist for installing kubectl on macOS: 确保 `/usr/local/bin` 在你的 PATH 环境变量中。 {{< /note >}} - 5. 测试一下,确保你安装的是最新的版本: @@ -187,33 +196,42 @@ The following methods exist for installing kubectl on macOS: kubectl version --client --output=yaml ``` + +1. 安装插件后,清理安装文件: + + ```bash + rm kubectl kubectl.sha256 + ``` ### 用 Homebrew 在 macOS 系统上安装 {#install-with-homebrew-on-macos} - 如果你是 macOS 系统,且用的是 [Homebrew](https://brew.sh/) 包管理工具, 则可以用 Homebrew 安装 kubectl。 - 1. 运行安装命令: ```bash - brew install kubectl + brew install kubectl ``` + 或 ```bash brew install kubernetes-cli ``` - 2. 测试一下,确保你安装的是最新的版本: @@ -222,17 +240,17 @@ If you are on macOS and using [Homebrew](https://brew.sh/) package manager, you kubectl version --client ``` - -### 用 Macports 在 macOS 上安装 {#install-with-macports-on-macos} +### 用 Macports 在 macOS 系统上安装 {#install-with-macports-on-macos} - -如果你用的是 macOS,且用 [Macports](https://macports.org/) 包管理工具,则你可以用 Macports 安装kubectl。 +如果你用的是 macOS,且用 [Macports](https://macports.org/) 包管理工具,则你可以用 Macports 安装 kubectl。 - 1. 运行安装命令: @@ -242,7 +260,7 @@ If you are on macOS and using [Macports](https://macports.org/) package manager, sudo port install kubectl ``` - 2. 测试一下,确保你安装的是最新的版本: @@ -251,14 +269,14 @@ If you are on macOS and using [Macports](https://macports.org/) package manager, kubectl version --client ``` - ## 验证 kubectl 配置 {#verify-kubectl-configuration} {{< include "included/verify-kubectl.md" >}} - 2. 验证该可执行文件(可选步骤) - + 下载 kubectl-convert 校验和文件: {{< tabs name="download_convert_checksum_macos" >}} @@ -329,7 +347,7 @@ kubectl 为 Bash、Zsh、Fish 和 PowerShell 提供自动补全功能,可以 ```bash echo "$(cat kubectl-convert.sha256) kubectl-convert" | shasum -a 256 --check ``` - + @@ -396,7 +414,15 @@ kubectl 为 Bash、Zsh、Fish 和 PowerShell 提供自动补全功能,可以 --> 如果你没有看到任何错误就代表插件安装成功了。 + +1. 安装插件后,清理安装文件: + + ```bash + rm kubectl kubectl.sha256 + ``` + ## {{% heading "whatsnext" %}} {{< include "included/kubectl-whats-next.md" >}} - From 85b9f7f6b7e318434cf47e0e63beb4b4d93f0066 Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Fri, 3 Feb 2023 17:58:37 +0800 Subject: [PATCH 063/279] Remove what-next in install-kubectl-macos.md --- content/en/docs/tasks/tools/install-kubectl-macos.md | 1 - 1 file changed, 1 deletion(-) diff --git a/content/en/docs/tasks/tools/install-kubectl-macos.md b/content/en/docs/tasks/tools/install-kubectl-macos.md index 5b4b3f8f85e..a02b027b280 100644 --- a/content/en/docs/tasks/tools/install-kubectl-macos.md +++ b/content/en/docs/tasks/tools/install-kubectl-macos.md @@ -27,7 +27,6 @@ The following methods exist for installing kubectl on macOS: - [Optional kubectl configurations and plugins](#optional-kubectl-configurations-and-plugins) - [Enable shell autocompletion](#enable-shell-autocompletion) - [Install `kubectl convert` plugin](#install-kubectl-convert-plugin) -- [{{% heading "whatsnext" %}}](#-heading-whatsnext-) ### Install kubectl binary with curl on macOS From cbe8d90c2bf6ea04cd722edfc0332eb1cd1258b6 Mon Sep 17 00:00:00 2001 From: sp-yduck Date: Fri, 3 Feb 2023 20:33:35 +0900 Subject: [PATCH 064/279] fix url link to cloud-controller-manager/main.go --- .../administer-cluster/developing-cloud-controller-manager.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ja/docs/tasks/administer-cluster/developing-cloud-controller-manager.md b/content/ja/docs/tasks/administer-cluster/developing-cloud-controller-manager.md index 36e28ea4554..d4f5a4e9fb8 100644 --- a/content/ja/docs/tasks/administer-cluster/developing-cloud-controller-manager.md +++ b/content/ja/docs/tasks/administer-cluster/developing-cloud-controller-manager.md @@ -22,7 +22,7 @@ Kubernetesプロジェクトは、(クラウドプロバイダーの)独自実 Kubernetesには登録されていない独自のクラウドプロバイダーのクラウドコントローラーマネージャーを構築するには、 1. [cloudprovider.Interface](https://github.com/kubernetes/cloud-provider/blob/master/cloud.go)を満たす go パッケージを実装します。 -2. Kubernetesのコアにある[cloud-controller-managerの`main.go`](https://github.com/kubernetes/kubernetes/blob/master/cmd/cloud-controller-manager/controller-manager.go)をあなたの`main.go`のテンプレートとして利用します。上で述べたように、唯一の違いはインポートされるクラウドパッケージのみです。 +2. Kubernetesのコアにある[cloud-controller-managerの`main.go`](https://github.com/kubernetes/kubernetes/blob/master/cmd/cloud-controller-manager/main.go)をあなたの`main.go`のテンプレートとして利用します。上で述べたように、唯一の違いはインポートされるクラウドパッケージのみです。 3. クラウドパッケージを `main.go` にインポートし、パッケージに [`cloudprovider.RegisterCloudProvider`](https://github.com/kubernetes/cloud-provider/blob/master/plugins.go) を実行するための `init` ブロックがあることを確認します。 多くのクラウドプロバイダーはオープンソースとしてコントローラーマネージャーのコードを公開しています。新たにcloud-controller-managerをスクラッチから開発する際には、既存のKubernetesには登録されていない独自クラウドプロバイダーのコントローラーマネージャーを開始地点とすることができます。 From 7f9f5f46c871acb94f4b7d0a2faa946c0daba46e Mon Sep 17 00:00:00 2001 From: YAMADA Kazuaki Date: Fri, 3 Feb 2023 22:21:13 +0900 Subject: [PATCH 065/279] fix: adapt the translation of 'er' to conventions --- content/ja/docs/concepts/overview/components.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/content/ja/docs/concepts/overview/components.md b/content/ja/docs/concepts/overview/components.md index 1b56478efa4..f28b248c2e1 100644 --- a/content/ja/docs/concepts/overview/components.md +++ b/content/ja/docs/concepts/overview/components.md @@ -58,11 +58,11 @@ Kubernetesをオンプレミスあるいは個人のPC内での学習環境で kube-controller-managerと同様に、cloud-controller-managerは複数の論理的に独立したコントロールループをシングルバイナリにまとめ、一つのプロセスとして動作します。パフォーマンスを向上させるあるいは障害に耐えるために水平方向にスケールする(一つ以上のコピーを動かす)ことができます。 -次の各コントローラは、それぞれ以下に示すような目的のためにクラウドプロバイダへの依存関係を持つことができるようになっています。 +次の各コントローラーは、それぞれ以下に示すような目的のためにクラウドプロバイダーへの依存関係を持つことができるようになっています。 - * Nodeコントローラ: ノードが応答を停止した後、クラウドで当該ノードが削除されたかどうかを判断するため - * Route コントローラ: 基盤となるクラウドインフラのルートを設定するため - * Service コントローラ: クラウドプロバイダーのロードバランサの作成、更新、削除を行うため + * Nodeコントローラー: ノードが応答を停止した後、クラウドで当該ノードが削除されたかどうかを判断するため + * Route コントローラー: 基盤となるクラウドインフラのルートを設定するため + * Service コントローラー: クラウドプロバイダーのロードバランサーの作成、更新、削除を行うため ## ノードコンポーネント {#node-components} From 0746ed56831aca0c3db15ccea62e45f64a51fda9 Mon Sep 17 00:00:00 2001 From: Tim Bannister Date: Fri, 3 Feb 2023 15:48:04 +0000 Subject: [PATCH 066/279] Replace k8s.gcr.io with registry.k8s.io --- .../concepts/overview/working-with-objects/labels.md | 2 +- .../ru/docs/setup/learning-environment/minikube.md | 2 +- .../configure-liveness-readiness-startup-probes.md | 12 ++++++------ content/ru/docs/tutorials/hello-minikube.md | 2 +- content/ru/examples/pods/probe/exec-liveness.yaml | 2 +- content/ru/examples/pods/probe/http-liveness.yaml | 2 +- .../examples/pods/probe/tcp-liveness-readiness.yaml | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/content/ru/docs/concepts/overview/working-with-objects/labels.md b/content/ru/docs/concepts/overview/working-with-objects/labels.md index 0114cd32d80..572454f1815 100644 --- a/content/ru/docs/concepts/overview/working-with-objects/labels.md +++ b/content/ru/docs/concepts/overview/working-with-objects/labels.md @@ -111,7 +111,7 @@ metadata: spec: containers: - name: cuda-test - image: "k8s.gcr.io/cuda-vector-add:v0.1" + image: "registry.k8s.io/cuda-vector-add:v0.1" resources: limits: nvidia.com/gpu: 1 diff --git a/content/ru/docs/setup/learning-environment/minikube.md b/content/ru/docs/setup/learning-environment/minikube.md index fea7e142528..449586f3188 100644 --- a/content/ru/docs/setup/learning-environment/minikube.md +++ b/content/ru/docs/setup/learning-environment/minikube.md @@ -58,7 +58,7 @@ Minikube поддерживает следующие возможности Kube Давайте создадим развёртывание (Deployment) в Kubernetes, используя существующий образ `echoserver`, представляющий простой HTTP-сервер, и сделаем его доступным на порту 8080 с помощью `--port`. ```shell - kubectl create deployment hello-minikube --image=k8s.gcr.io/echoserver:1.10 + kubectl create deployment hello-minikube --image=registry.k8s.io/echoserver:1.10 ``` Вывод будет примерно следующим: diff --git a/content/ru/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes.md b/content/ru/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes.md index fd99c78cd67..267f05a9e57 100644 --- a/content/ru/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes.md +++ b/content/ru/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes.md @@ -45,7 +45,7 @@ Kubelet использует startup пробы, чтобы понять, ког и могут быть восстановлены только перезапуском. Kubernetes предоставляет liveness пробы, чтобы обнаруживать и исправлять такие ситуации. -В этом упражнении вы создадите Pod, который запускает контейнер, основанный на образе `k8s.gcr.io/busybox`. Конфигурационный файл для Pod'а: +В этом упражнении вы создадите Pod, который запускает контейнер, основанный на образе `registry.k8s.io/busybox`. Конфигурационный файл для Pod'а: {{< codenew file="pods/probe/exec-liveness.yaml" >}} @@ -83,8 +83,8 @@ kubectl describe pod liveness-exec FirstSeen LastSeen Count From SubobjectPath Type Reason Message --------- -------- ----- ---- ------------- -------- ------ ------- 24s 24s 1 {default-scheduler } Normal Scheduled Successfully assigned liveness-exec to worker0 -23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Pulling pulling image "k8s.gcr.io/busybox" -23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Pulled Successfully pulled image "k8s.gcr.io/busybox" +23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Pulling pulling image "registry.k8s.io/busybox" +23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Pulled Successfully pulled image "registry.k8s.io/busybox" 23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Created Created container with docker id 86849c15382e; Security:[seccomp=unconfined] 23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Started Started container with docker id 86849c15382e ``` @@ -102,8 +102,8 @@ kubectl describe pod liveness-exec FirstSeen LastSeen Count From SubobjectPath Type Reason Message --------- -------- ----- ---- ------------- -------- ------ ------- 37s 37s 1 {default-scheduler } Normal Scheduled Successfully assigned liveness-exec to worker0 -36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Pulling pulling image "k8s.gcr.io/busybox" -36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Pulled Successfully pulled image "k8s.gcr.io/busybox" +36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Pulling pulling image "registry.k8s.io/busybox" +36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Pulled Successfully pulled image "registry.k8s.io/busybox" 36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Created Created container with docker id 86849c15382e; Security:[seccomp=unconfined] 36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Started Started container with docker id 86849c15382e 2s 2s 1 {kubelet worker0} spec.containers{liveness} Warning Unhealthy Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory @@ -124,7 +124,7 @@ liveness-exec 1/1 Running 1 1m ## Определение liveness HTTP запроса -Другой вид liveness пробы использует запрос HTTP GET. Ниже представлен файл конфигурации для Pod, который запускает контейнер, основанный на образе `k8s.gcr.io/liveness`. +Другой вид liveness пробы использует запрос HTTP GET. Ниже представлен файл конфигурации для Pod, который запускает контейнер, основанный на образе `registry.k8s.io/liveness`. {{< codenew file="pods/probe/http-liveness.yaml" >}} diff --git a/content/ru/docs/tutorials/hello-minikube.md b/content/ru/docs/tutorials/hello-minikube.md index 2888f1660f3..1c986a7234a 100644 --- a/content/ru/docs/tutorials/hello-minikube.md +++ b/content/ru/docs/tutorials/hello-minikube.md @@ -74,7 +74,7 @@ Katacoda предоставляет бесплатную, встроенную 1. Используйте команду `kubectl create` для создание деплоймента для управления подом. Под запускает контейнер на основе предоставленного Docker образа. ```shell - kubectl create deployment hello-node --image=k8s.gcr.io/echoserver:1.4 + kubectl create deployment hello-node --image=registry.k8s.io/echoserver:1.4 ``` 2. Посмотреть информацию о Deployment: diff --git a/content/ru/examples/pods/probe/exec-liveness.yaml b/content/ru/examples/pods/probe/exec-liveness.yaml index 6a9c9b32137..7d6ca96b3d6 100644 --- a/content/ru/examples/pods/probe/exec-liveness.yaml +++ b/content/ru/examples/pods/probe/exec-liveness.yaml @@ -7,7 +7,7 @@ metadata: spec: containers: - name: liveness - image: k8s.gcr.io/busybox + image: registry.k8s.io/busybox args: - /bin/sh - -c diff --git a/content/ru/examples/pods/probe/http-liveness.yaml b/content/ru/examples/pods/probe/http-liveness.yaml index 670af18399e..48ca861c142 100644 --- a/content/ru/examples/pods/probe/http-liveness.yaml +++ b/content/ru/examples/pods/probe/http-liveness.yaml @@ -7,7 +7,7 @@ metadata: spec: containers: - name: liveness - image: k8s.gcr.io/liveness + image: registry.k8s.io/liveness args: - /server livenessProbe: diff --git a/content/ru/examples/pods/probe/tcp-liveness-readiness.yaml b/content/ru/examples/pods/probe/tcp-liveness-readiness.yaml index 08fb77ff0f5..ef8a2f9500b 100644 --- a/content/ru/examples/pods/probe/tcp-liveness-readiness.yaml +++ b/content/ru/examples/pods/probe/tcp-liveness-readiness.yaml @@ -7,7 +7,7 @@ metadata: spec: containers: - name: goproxy - image: k8s.gcr.io/goproxy:0.1 + image: registry.k8s.io/goproxy:0.1 ports: - containerPort: 8080 readinessProbe: From 71bfd89b929d03b73dea753ae782a0aca1b16af7 Mon Sep 17 00:00:00 2001 From: Tim Bannister Date: Fri, 3 Feb 2023 15:55:02 +0000 Subject: [PATCH 067/279] Replace k8s.gcr.io with registry.k8s.io --- .../manage-resources-containers.md | 2 +- .../ja/docs/concepts/configuration/secret.md | 4 ++-- .../overview/working-with-objects/labels.md | 2 +- .../concepts/storage/persistent-volumes.md | 2 +- content/ja/docs/concepts/storage/volumes.md | 16 +++++++-------- .../workloads/controllers/statefulset.md | 2 +- .../ja/docs/reference/kubectl/cheatsheet.md | 4 ++-- .../setup/learning-environment/minikube.md | 2 +- .../kubeadm/setup-ha-etcd-with-kubeadm.md | 4 ++-- ...igure-liveness-readiness-startup-probes.md | 12 +++++------ .../debug/debug-application/debug-service.md | 4 ++-- .../docs/tasks/manage-gpus/scheduling-gpus.md | 4 ++-- content/ja/docs/tutorials/hello-minikube.md | 2 +- .../ja/docs/tutorials/services/source-ip.md | 2 +- .../basic-stateful-set.md | 20 +++++++++---------- .../ja/examples/admin/cloud/ccm-example.yaml | 4 ++-- .../admin/dns/dns-horizontal-autoscaler.yaml | 2 +- .../two-files-counter-pod-agent-sidecar.yaml | 2 +- content/ja/examples/admin/sched/pod1.yaml | 2 +- content/ja/examples/admin/sched/pod2.yaml | 2 +- content/ja/examples/admin/sched/pod3.yaml | 2 +- .../guestbook/redis-master-deployment.yaml | 2 +- .../ja/examples/application/php-apache.yaml | 2 +- .../application/web/web-parallel.yaml | 2 +- content/ja/examples/application/web/web.yaml | 2 +- .../application/zookeeper/zookeeper.yaml | 2 +- content/ja/examples/debug/event-exporter.yaml | 2 +- content/ja/examples/debug/fluentd-gcp-ds.yaml | 2 +- .../node-problem-detector-configmap.yaml | 2 +- .../examples/debug/node-problem-detector.yaml | 2 +- .../pods/inject/dapi-envars-container.yaml | 2 +- .../examples/pods/inject/dapi-envars-pod.yaml | 2 +- .../pods/inject/dapi-volume-resources.yaml | 2 +- .../ja/examples/pods/inject/dapi-volume.yaml | 2 +- .../pods/pod-configmap-env-var-valueFrom.yaml | 2 +- .../examples/pods/pod-configmap-envFrom.yaml | 2 +- .../pod-configmap-volume-specific-key.yaml | 2 +- .../examples/pods/pod-configmap-volume.yaml | 2 +- .../pod-multiple-configmap-env-variable.yaml | 2 +- .../pod-single-configmap-env-variable.yaml | 2 +- .../examples/pods/pod-with-node-affinity.yaml | 2 +- .../examples/pods/pod-with-pod-affinity.yaml | 2 +- .../ja/examples/pods/probe/exec-liveness.yaml | 2 +- .../ja/examples/pods/probe/http-liveness.yaml | 2 +- .../pods/probe/tcp-liveness-readiness.yaml | 2 +- 45 files changed, 72 insertions(+), 72 deletions(-) diff --git a/content/ja/docs/concepts/configuration/manage-resources-containers.md b/content/ja/docs/concepts/configuration/manage-resources-containers.md index 499e2a72149..62b01aa0dfe 100644 --- a/content/ja/docs/concepts/configuration/manage-resources-containers.md +++ b/content/ja/docs/concepts/configuration/manage-resources-containers.md @@ -601,7 +601,7 @@ Conditions: Events: FirstSeen LastSeen Count From SubobjectPath Reason Message Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {scheduler } scheduled Successfully assigned simmemleak-hra99 to kubernetes-node-tf0f - Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD pulled Pod container image "k8s.gcr.io/pause:0.8.0" already present on machine + Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD pulled Pod container image "registry.k8s.io/pause:0.8.0" already present on machine Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD created Created with docker id 6a41280f516d Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD started Started with docker id 6a41280f516d Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} spec.containers{simmemleak} created Created with docker id 87348f12526a diff --git a/content/ja/docs/concepts/configuration/secret.md b/content/ja/docs/concepts/configuration/secret.md index 978dd1591f5..0514eaa40c9 100644 --- a/content/ja/docs/concepts/configuration/secret.md +++ b/content/ja/docs/concepts/configuration/secret.md @@ -779,7 +779,7 @@ metadata: spec: containers: - name: test-container - image: k8s.gcr.io/busybox + image: registry.k8s.io/busybox command: [ "/bin/sh", "-c", "env" ] envFrom: - secretRef: @@ -994,7 +994,7 @@ spec: secretName: dotfile-secret containers: - name: dotfile-test-container - image: k8s.gcr.io/busybox + image: registry.k8s.io/busybox command: - ls - "-l" diff --git a/content/ja/docs/concepts/overview/working-with-objects/labels.md b/content/ja/docs/concepts/overview/working-with-objects/labels.md index 3c4ed0397a5..35f69e676bb 100644 --- a/content/ja/docs/concepts/overview/working-with-objects/labels.md +++ b/content/ja/docs/concepts/overview/working-with-objects/labels.md @@ -130,7 +130,7 @@ metadata: spec: containers: - name: cuda-test - image: "k8s.gcr.io/cuda-vector-add:v0.1" + image: "registry.k8s.io/cuda-vector-add:v0.1" resources: limits: nvidia.com/gpu: 1 diff --git a/content/ja/docs/concepts/storage/persistent-volumes.md b/content/ja/docs/concepts/storage/persistent-volumes.md index 292d21ea681..0a82b6a3cb2 100644 --- a/content/ja/docs/concepts/storage/persistent-volumes.md +++ b/content/ja/docs/concepts/storage/persistent-volumes.md @@ -154,7 +154,7 @@ spec: path: /any/path/it/will/be/replaced containers: - name: pv-recycler - image: "k8s.gcr.io/busybox" + image: "registry.k8s.io/busybox" command: ["/bin/sh", "-c", "test -e /scrub && rm -rf /scrub/..?* /scrub/.[!.]* /scrub/* && test -z \"$(ls -A /scrub)\" || exit 1"] volumeMounts: - name: vol diff --git a/content/ja/docs/concepts/storage/volumes.md b/content/ja/docs/concepts/storage/volumes.md index 65ab1fd67b0..c4445d49c49 100644 --- a/content/ja/docs/concepts/storage/volumes.md +++ b/content/ja/docs/concepts/storage/volumes.md @@ -76,7 +76,7 @@ metadata: name: test-ebs spec: containers: - - image: k8s.gcr.io/test-webserver + - image: registry.k8s.io/test-webserver name: test-container volumeMounts: - mountPath: /test-ebs @@ -163,7 +163,7 @@ metadata: name: test-cinder spec: containers: - - image: k8s.gcr.io/test-webserver + - image: registry.k8s.io/test-webserver name: test-cinder-container volumeMounts: - mountPath: /test-cinder @@ -274,7 +274,7 @@ metadata: name: test-pd spec: containers: - - image: k8s.gcr.io/test-webserver + - image: registry.k8s.io/test-webserver name: test-container volumeMounts: - mountPath: /cache @@ -349,7 +349,7 @@ metadata: name: test-pd spec: containers: - - image: k8s.gcr.io/test-webserver + - image: registry.k8s.io/test-webserver name: test-container volumeMounts: - mountPath: /test-pd @@ -507,7 +507,7 @@ metadata: name: test-pd spec: containers: - - image: k8s.gcr.io/test-webserver + - image: registry.k8s.io/test-webserver name: test-container volumeMounts: - mountPath: /test-pd @@ -536,7 +536,7 @@ metadata: spec: containers: - name: test-webserver - image: k8s.gcr.io/test-webserver:latest + image: registry.k8s.io/test-webserver:latest volumeMounts: - mountPath: /var/local/aaa name: mydir @@ -666,7 +666,7 @@ metadata: name: test-portworx-volume-pod spec: containers: - - image: k8s.gcr.io/test-webserver + - image: registry.k8s.io/test-webserver name: test-container volumeMounts: - mountPath: /mnt @@ -848,7 +848,7 @@ metadata: name: test-vmdk spec: containers: - - image: k8s.gcr.io/test-webserver + - image: registry.k8s.io/test-webserver name: test-container volumeMounts: - mountPath: /test-vmdk diff --git a/content/ja/docs/concepts/workloads/controllers/statefulset.md b/content/ja/docs/concepts/workloads/controllers/statefulset.md index b69e46af52a..a952c3bee85 100644 --- a/content/ja/docs/concepts/workloads/controllers/statefulset.md +++ b/content/ja/docs/concepts/workloads/controllers/statefulset.md @@ -72,7 +72,7 @@ spec: terminationGracePeriodSeconds: 10 containers: - name: nginx - image: k8s.gcr.io/nginx-slim:0.8 + image: registry.k8s.io/nginx-slim:0.8 ports: - containerPort: 80 name: web diff --git a/content/ja/docs/reference/kubectl/cheatsheet.md b/content/ja/docs/reference/kubectl/cheatsheet.md index 681eecf96a2..7b2d782882c 100644 --- a/content/ja/docs/reference/kubectl/cheatsheet.md +++ b/content/ja/docs/reference/kubectl/cheatsheet.md @@ -359,8 +359,8 @@ kubectl api-resources --api-group=extensions # "extensions" APIグループの # クラスター内で実行中のすべてのイメージ名を表示する kubectl get pods -A -o=custom-columns='DATA:spec.containers[*].image' -# "k8s.gcr.io/coredns:1.6.2"を除いたすべてのイメージ名を表示する -kubectl get pods -A -o=custom-columns='DATA:spec.containers[?(@.image!="k8s.gcr.io/coredns:1.6.2")].image' +# "registry.k8s.io/coredns:1.6.2"を除いたすべてのイメージ名を表示する +kubectl get pods -A -o=custom-columns='DATA:spec.containers[?(@.image!="registry.k8s.io/coredns:1.6.2")].image' # 名前に関係なくmetadata以下のすべてのフィールドを表示する kubectl get pods -A -o=custom-columns='DATA:metadata.*' diff --git a/content/ja/docs/setup/learning-environment/minikube.md b/content/ja/docs/setup/learning-environment/minikube.md index 58fce33a34a..f394897fcfd 100644 --- a/content/ja/docs/setup/learning-environment/minikube.md +++ b/content/ja/docs/setup/learning-environment/minikube.md @@ -54,7 +54,7 @@ MinikubeのサポートするKubernetesの機能: 単純なHTTPサーバーである`echoserver`という既存のイメージを使用して、Kubernetes Deploymentを作りましょう。そして`--port`を使用して8080番ポートで公開しましょう。 ```shell - kubectl create deployment hello-minikube --image=k8s.gcr.io/echoserver:1.10 + kubectl create deployment hello-minikube --image=registry.k8s.io/echoserver:1.10 ``` 出力はこのようになります: diff --git a/content/ja/docs/setup/production-environment/tools/kubeadm/setup-ha-etcd-with-kubeadm.md b/content/ja/docs/setup/production-environment/tools/kubeadm/setup-ha-etcd-with-kubeadm.md index 6c3dbecf387..7e76d713751 100644 --- a/content/ja/docs/setup/production-environment/tools/kubeadm/setup-ha-etcd-with-kubeadm.md +++ b/content/ja/docs/setup/production-environment/tools/kubeadm/setup-ha-etcd-with-kubeadm.md @@ -30,7 +30,7 @@ when using kubeadm to set up a kubernetes cluster. document assumes these default ports. However, they are configurable through the kubeadm config file. * Each host must [have docker, kubelet, and kubeadm installed](/ja/docs/setup/production-environment/tools/kubeadm/install-kubeadm/). -* Each host should have access to the Kubernetes container image registry (`k8s.gcr.io`) or list/pull the required etcd image using `kubeadm config images list/pull`. This guide will setup etcd instances as [static pods](/docs/tasks/configure-pod-container/static-pod/) managed by a kubelet. +* Each host should have access to the Kubernetes container image registry (`registry.k8s.io`) or list/pull the required etcd image using `kubeadm config images list/pull`. This guide will setup etcd instances as [static pods](/docs/tasks/configure-pod-container/static-pod/) managed by a kubelet. * Some infrastructure to copy files between hosts. For example `ssh` and `scp` can satisfy this requirement. @@ -251,7 +251,7 @@ this example. ```sh docker run --rm -it \ --net host \ - -v /etc/kubernetes:/etc/kubernetes k8s.gcr.io/etcd:${ETCD_TAG} etcdctl \ + -v /etc/kubernetes:/etc/kubernetes registry.k8s.io/etcd:${ETCD_TAG} etcdctl \ --cert /etc/kubernetes/pki/etcd/peer.crt \ --key /etc/kubernetes/pki/etcd/peer.key \ --cacert /etc/kubernetes/pki/etcd/ca.crt \ diff --git a/content/ja/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes.md b/content/ja/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes.md index 0fe0ffe410a..0c14c79bb6b 100644 --- a/content/ja/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes.md +++ b/content/ja/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes.md @@ -36,7 +36,7 @@ Readiness Probeによるチェックを無効にし、これらがアプリケ 長期間実行されているアプリケーションの多くは、再起動されるまで回復できないような異常な状態になることがあります。 Kubernetesはこのような状況を検知し、回復するためのLiveness Probeを提供します。 -この演習では、`k8s.gcr.io/busybox`イメージのコンテナを起動するPodを作成します。 +この演習では、`registry.k8s.io/busybox`イメージのコンテナを起動するPodを作成します。 Podの構成ファイルは次の通りです。 {{< codenew file="pods/probe/exec-liveness.yaml" >}} @@ -76,8 +76,8 @@ kubectl describe pod liveness-exec FirstSeen LastSeen Count From SubobjectPath Type Reason Message --------- -------- ----- ---- ------------- -------- ------ ------- 24s 24s 1 {default-scheduler } Normal Scheduled Successfully assigned liveness-exec to worker0 -23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Pulling pulling image "k8s.gcr.io/busybox" -23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Pulled Successfully pulled image "k8s.gcr.io/busybox" +23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Pulling pulling image "registry.k8s.io/busybox" +23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Pulled Successfully pulled image "registry.k8s.io/busybox" 23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Created Created container with docker id 86849c15382e; Security:[seccomp=unconfined] 23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Started Started container with docker id 86849c15382e ``` @@ -94,8 +94,8 @@ kubectl describe pod liveness-exec FirstSeen LastSeen Count From SubobjectPath Type Reason Message --------- -------- ----- ---- ------------- -------- ------ ------- 37s 37s 1 {default-scheduler } Normal Scheduled Successfully assigned liveness-exec to worker0 -36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Pulling pulling image "k8s.gcr.io/busybox" -36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Pulled Successfully pulled image "k8s.gcr.io/busybox" +36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Pulling pulling image "registry.k8s.io/busybox" +36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Pulled Successfully pulled image "registry.k8s.io/busybox" 36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Created Created container with docker id 86849c15382e; Security:[seccomp=unconfined] 36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Started Started container with docker id 86849c15382e 2s 2s 1 {kubelet worker0} spec.containers{liveness} Warning Unhealthy Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory @@ -117,7 +117,7 @@ liveness-exec 1/1 Running 1 1m ## HTTPリクエストによるLiveness Probeを定義する {#define-a-liveness-http-request} 別の種類のLiveness Probeでは、HTTP GETリクエストを使用します。 -次の構成ファイルは、`k8s.gcr.io/liveness`イメージを使用したコンテナを起動するPodを作成します。 +次の構成ファイルは、`registry.k8s.io/liveness`イメージを使用したコンテナを起動するPodを作成します。 {{< codenew file="pods/probe/http-liveness.yaml" >}} diff --git a/content/ja/docs/tasks/debug/debug-application/debug-service.md b/content/ja/docs/tasks/debug/debug-application/debug-service.md index 1cbe54b9cb4..24c98eee168 100644 --- a/content/ja/docs/tasks/debug/debug-application/debug-service.md +++ b/content/ja/docs/tasks/debug/debug-application/debug-service.md @@ -37,7 +37,7 @@ kubectl exec -c -- ```shell -kubectl create deployment hostnames --image=k8s.gcr.io/serve_hostname +kubectl create deployment hostnames --image=registry.k8s.io/serve_hostname ``` ```none deployment.apps/hostnames created @@ -76,7 +76,7 @@ spec: spec: containers: - name: hostnames - image: k8s.gcr.io/serve_hostname + image: registry.k8s.io/serve_hostname ``` "app"ラベルは`kubectl create deployment`によって、Deploymentの名前に自動的にセットされます。 diff --git a/content/ja/docs/tasks/manage-gpus/scheduling-gpus.md b/content/ja/docs/tasks/manage-gpus/scheduling-gpus.md index 5c51771cd7e..1bfbc65645e 100644 --- a/content/ja/docs/tasks/manage-gpus/scheduling-gpus.md +++ b/content/ja/docs/tasks/manage-gpus/scheduling-gpus.md @@ -46,7 +46,7 @@ spec: containers: - name: cuda-vector-add # https://github.com/kubernetes/kubernetes/blob/v1.7.11/test/images/nvidia-cuda/Dockerfile - image: "k8s.gcr.io/cuda-vector-add:v0.1" + image: "registry.k8s.io/cuda-vector-add:v0.1" resources: limits: nvidia.com/gpu: 1 # 1 GPUをリクエストしています @@ -173,7 +173,7 @@ spec: containers: - name: cuda-vector-add # https://github.com/kubernetes/kubernetes/blob/v1.7.11/test/images/nvidia-cuda/Dockerfile - image: "k8s.gcr.io/cuda-vector-add:v0.1" + image: "registry.k8s.io/cuda-vector-add:v0.1" resources: limits: nvidia.com/gpu: 1 diff --git a/content/ja/docs/tutorials/hello-minikube.md b/content/ja/docs/tutorials/hello-minikube.md index 35192a8ca97..b2c2ba0e4c9 100644 --- a/content/ja/docs/tutorials/hello-minikube.md +++ b/content/ja/docs/tutorials/hello-minikube.md @@ -70,7 +70,7 @@ Kubernetesの[*Pod*](/ja/docs/concepts/workloads/pods/) は、コンテナの管 1. `kubectl create` コマンドを使用してPodを管理するDeploymentを作成してください。Podは提供されたDockerイメージを元にコンテナを実行します。 ```shell - kubectl create deployment hello-node --image=k8s.gcr.io/echoserver:1.4 + kubectl create deployment hello-node --image=registry.k8s.io/echoserver:1.4 ``` 2. Deploymentを確認します: diff --git a/content/ja/docs/tutorials/services/source-ip.md b/content/ja/docs/tutorials/services/source-ip.md index 6e52a1c9b30..9a52cb9e6be 100644 --- a/content/ja/docs/tutorials/services/source-ip.md +++ b/content/ja/docs/tutorials/services/source-ip.md @@ -41,7 +41,7 @@ the target localization. 以下の例では、HTTPヘッダー経由で受け取ったリクエストの送信元IPをエコーバックする、小さなnginxウェブサーバーを使用します。次のコマンドでウェブサーバーを作成できます。 ```shell -kubectl create deployment source-ip-app --image=k8s.gcr.io/echoserver:1.4 +kubectl create deployment source-ip-app --image=registry.k8s.io/echoserver:1.4 ``` 出力は次のようになります。 diff --git a/content/ja/docs/tutorials/stateful-application/basic-stateful-set.md b/content/ja/docs/tutorials/stateful-application/basic-stateful-set.md index 81e67375c72..2afef728f19 100644 --- a/content/ja/docs/tutorials/stateful-application/basic-stateful-set.md +++ b/content/ja/docs/tutorials/stateful-application/basic-stateful-set.md @@ -500,9 +500,9 @@ Podを取得して、コンテナイメージを確認してみましょう。 for p in 0 1 2; do kubectl get pod "web-$p" --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'; echo; done ``` ``` -k8s.gcr.io/nginx-slim:0.8 -k8s.gcr.io/nginx-slim:0.8 -k8s.gcr.io/nginx-slim:0.8 +registry.k8s.io/nginx-slim:0.8 +registry.k8s.io/nginx-slim:0.8 +registry.k8s.io/nginx-slim:0.8 ``` @@ -528,7 +528,7 @@ statefulset.apps/web patched StatefulSetに再度patchを当てて、コンテナイメージを変更します。 ```shell -kubectl patch statefulset web --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"k8s.gcr.io/nginx-slim:0.7"}]' +kubectl patch statefulset web --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"registry.k8s.io/nginx-slim:0.7"}]' ``` ``` statefulset.apps/web patched @@ -562,7 +562,7 @@ Podのコンテナイメージを取得します。 kubectl get pod web-2 --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}' ``` ``` -k8s.gcr.io/nginx-slim:0.8 +registry.k8s.io/nginx-slim:0.8 ``` アップデート戦略が`RollingUpdate`であっても、StatefulSetが元のコンテナを持つPodをリストアしたことがわかります。これは、Podの順序インデックスが`updateStrategy`で指定した`partition`より小さいためです。 @@ -599,7 +599,7 @@ Podのコンテナを取得します。 kubectl get pod web-2 --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}' ``` ``` -k8s.gcr.io/nginx-slim:0.7 +registry.k8s.io/nginx-slim:0.7 ``` @@ -640,7 +640,7 @@ web-1 1/1 Running 0 18s kubectl get pod web-1 --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}' ``` ``` -k8s.gcr.io/nginx-slim:0.8 +registry.k8s.io/nginx-slim:0.8 ``` Podの順序インデックスがpartitionよりも小さいため、`web-1`は元の設定のコンテナイメージにリストアされました。partitionを指定すると、StatefulSetの`.spec.template`が更新されたときに、順序インデックスがそれ以上の値を持つすべてのPodがアップデートされます。partitionよりも小さな順序インデックスを持つPodが削除されたり終了されたりすると、元の設定のPodにリストアされます。 @@ -688,9 +688,9 @@ StatefulSet内のPodのコンテナイメージの詳細を取得します。 for p in 0 1 2; do kubectl get pod "web-$p" --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'; echo; done ``` ``` -k8s.gcr.io/nginx-slim:0.7 -k8s.gcr.io/nginx-slim:0.7 -k8s.gcr.io/nginx-slim:0.7 +registry.k8s.io/nginx-slim:0.7 +registry.k8s.io/nginx-slim:0.7 +registry.k8s.io/nginx-slim:0.7 ``` `partition`を`0`に移動することで、StatefulSetがアップデート処理を続けられるようにできます。 diff --git a/content/ja/examples/admin/cloud/ccm-example.yaml b/content/ja/examples/admin/cloud/ccm-example.yaml index 96b78331744..6f3d115993c 100644 --- a/content/ja/examples/admin/cloud/ccm-example.yaml +++ b/content/ja/examples/admin/cloud/ccm-example.yaml @@ -42,9 +42,9 @@ spec: serviceAccountName: cloud-controller-manager containers: - name: cloud-controller-manager - # for in-tree providers we use k8s.gcr.io/cloud-controller-manager + # for in-tree providers we use registry.k8s.io/cloud-controller-manager # this can be replaced with any other image for out-of-tree providers - image: k8s.gcr.io/cloud-controller-manager:v1.8.0 + image: registry.k8s.io/cloud-controller-manager:v1.8.0 command: - /usr/local/bin/cloud-controller-manager - --cloud-provider= # Add your own cloud provider here! diff --git a/content/ja/examples/admin/dns/dns-horizontal-autoscaler.yaml b/content/ja/examples/admin/dns/dns-horizontal-autoscaler.yaml index 5e6d55a6b28..fe50976460d 100644 --- a/content/ja/examples/admin/dns/dns-horizontal-autoscaler.yaml +++ b/content/ja/examples/admin/dns/dns-horizontal-autoscaler.yaml @@ -16,7 +16,7 @@ spec: spec: containers: - name: autoscaler - image: k8s.gcr.io/cluster-proportional-autoscaler-amd64:1.1.1 + image: registry.k8s.io/cluster-proportional-autoscaler-amd64:1.1.1 resources: requests: cpu: "20m" diff --git a/content/ja/examples/admin/logging/two-files-counter-pod-agent-sidecar.yaml b/content/ja/examples/admin/logging/two-files-counter-pod-agent-sidecar.yaml index b37b616e6f7..1053cac5772 100644 --- a/content/ja/examples/admin/logging/two-files-counter-pod-agent-sidecar.yaml +++ b/content/ja/examples/admin/logging/two-files-counter-pod-agent-sidecar.yaml @@ -22,7 +22,7 @@ spec: - name: varlog mountPath: /var/log - name: count-agent - image: k8s.gcr.io/fluentd-gcp:1.30 + image: registry.k8s.io/fluentd-gcp:1.30 env: - name: FLUENTD_ARGS value: -c /etc/fluentd-config/fluentd.conf diff --git a/content/ja/examples/admin/sched/pod1.yaml b/content/ja/examples/admin/sched/pod1.yaml index 560b6aa0fb3..7183dd62c0f 100644 --- a/content/ja/examples/admin/sched/pod1.yaml +++ b/content/ja/examples/admin/sched/pod1.yaml @@ -7,4 +7,4 @@ metadata: spec: containers: - name: pod-with-no-annotation-container - image: k8s.gcr.io/pause:2.0 \ No newline at end of file + image: registry.k8s.io/pause:2.0 \ No newline at end of file diff --git a/content/ja/examples/admin/sched/pod2.yaml b/content/ja/examples/admin/sched/pod2.yaml index 2f065efe65f..b78ab64a4bc 100644 --- a/content/ja/examples/admin/sched/pod2.yaml +++ b/content/ja/examples/admin/sched/pod2.yaml @@ -8,4 +8,4 @@ spec: schedulerName: default-scheduler containers: - name: pod-with-default-annotation-container - image: k8s.gcr.io/pause:2.0 + image: registry.k8s.io/pause:2.0 diff --git a/content/ja/examples/admin/sched/pod3.yaml b/content/ja/examples/admin/sched/pod3.yaml index a1b8db32008..66141438291 100644 --- a/content/ja/examples/admin/sched/pod3.yaml +++ b/content/ja/examples/admin/sched/pod3.yaml @@ -8,4 +8,4 @@ spec: schedulerName: my-scheduler containers: - name: pod-with-second-annotation-container - image: k8s.gcr.io/pause:2.0 + image: registry.k8s.io/pause:2.0 diff --git a/content/ja/examples/application/guestbook/redis-master-deployment.yaml b/content/ja/examples/application/guestbook/redis-master-deployment.yaml index fc6f418c39e..c7b12f8ed54 100644 --- a/content/ja/examples/application/guestbook/redis-master-deployment.yaml +++ b/content/ja/examples/application/guestbook/redis-master-deployment.yaml @@ -20,7 +20,7 @@ spec: spec: containers: - name: master - image: k8s.gcr.io/redis:e2e # or just image: redis + image: registry.k8s.io/redis:e2e # or just image: redis resources: requests: cpu: 100m diff --git a/content/ja/examples/application/php-apache.yaml b/content/ja/examples/application/php-apache.yaml index e8e1b5aeb43..d29d2b91593 100644 --- a/content/ja/examples/application/php-apache.yaml +++ b/content/ja/examples/application/php-apache.yaml @@ -14,7 +14,7 @@ spec: spec: containers: - name: php-apache - image: k8s.gcr.io/hpa-example + image: registry.k8s.io/hpa-example ports: - containerPort: 80 resources: diff --git a/content/ja/examples/application/web/web-parallel.yaml b/content/ja/examples/application/web/web-parallel.yaml index 4eab2dc2066..a6633f476c1 100644 --- a/content/ja/examples/application/web/web-parallel.yaml +++ b/content/ja/examples/application/web/web-parallel.yaml @@ -30,7 +30,7 @@ spec: spec: containers: - name: nginx - image: k8s.gcr.io/nginx-slim:0.8 + image: registry.k8s.io/nginx-slim:0.8 ports: - containerPort: 80 name: web diff --git a/content/ja/examples/application/web/web.yaml b/content/ja/examples/application/web/web.yaml index 37c1fabf9c5..95244cd72b8 100644 --- a/content/ja/examples/application/web/web.yaml +++ b/content/ja/examples/application/web/web.yaml @@ -29,7 +29,7 @@ spec: spec: containers: - name: nginx - image: k8s.gcr.io/nginx-slim:0.8 + image: registry.k8s.io/nginx-slim:0.8 ports: - containerPort: 80 name: web diff --git a/content/ja/examples/application/zookeeper/zookeeper.yaml b/content/ja/examples/application/zookeeper/zookeeper.yaml index 4afa806a541..4037f83dc86 100644 --- a/content/ja/examples/application/zookeeper/zookeeper.yaml +++ b/content/ja/examples/application/zookeeper/zookeeper.yaml @@ -68,7 +68,7 @@ spec: containers: - name: kubernetes-zookeeper imagePullPolicy: Always - image: "k8s.gcr.io/kubernetes-zookeeper:1.0-3.4.10" + image: "registry.k8s.io/kubernetes-zookeeper:1.0-3.4.10" resources: requests: memory: "1Gi" diff --git a/content/ja/examples/debug/event-exporter.yaml b/content/ja/examples/debug/event-exporter.yaml index 64a585b9a53..7d2fe2791ac 100644 --- a/content/ja/examples/debug/event-exporter.yaml +++ b/content/ja/examples/debug/event-exporter.yaml @@ -41,7 +41,7 @@ spec: serviceAccountName: event-exporter-sa containers: - name: event-exporter - image: k8s.gcr.io/event-exporter:v0.2.3 + image: registry.k8s.io/event-exporter:v0.2.3 command: - '/event-exporter' terminationGracePeriodSeconds: 30 diff --git a/content/ja/examples/debug/fluentd-gcp-ds.yaml b/content/ja/examples/debug/fluentd-gcp-ds.yaml index 4ffd5c00931..3e4f87f55e0 100644 --- a/content/ja/examples/debug/fluentd-gcp-ds.yaml +++ b/content/ja/examples/debug/fluentd-gcp-ds.yaml @@ -30,7 +30,7 @@ spec: dnsPolicy: Default containers: - name: fluentd-gcp - image: k8s.gcr.io/fluentd-gcp:2.0.2 + image: registry.k8s.io/fluentd-gcp:2.0.2 # If fluentd consumes its own logs, the following situation may happen: # fluentd fails to send a chunk to the server => writes it to the log => # tries to send this message to the server => fails to send a chunk and so on. diff --git a/content/ja/examples/debug/node-problem-detector-configmap.yaml b/content/ja/examples/debug/node-problem-detector-configmap.yaml index 654d35106a9..46bf1ea668a 100644 --- a/content/ja/examples/debug/node-problem-detector-configmap.yaml +++ b/content/ja/examples/debug/node-problem-detector-configmap.yaml @@ -23,7 +23,7 @@ spec: hostNetwork: true containers: - name: node-problem-detector - image: k8s.gcr.io/node-problem-detector:v0.1 + image: registry.k8s.io/node-problem-detector:v0.1 securityContext: privileged: true resources: diff --git a/content/ja/examples/debug/node-problem-detector.yaml b/content/ja/examples/debug/node-problem-detector.yaml index 6ffa19bcc3a..f106c327efc 100644 --- a/content/ja/examples/debug/node-problem-detector.yaml +++ b/content/ja/examples/debug/node-problem-detector.yaml @@ -23,7 +23,7 @@ spec: hostNetwork: true containers: - name: node-problem-detector - image: k8s.gcr.io/node-problem-detector:v0.1 + image: registry.k8s.io/node-problem-detector:v0.1 securityContext: privileged: true resources: diff --git a/content/ja/examples/pods/inject/dapi-envars-container.yaml b/content/ja/examples/pods/inject/dapi-envars-container.yaml index 55bd4dd263a..4267053a069 100644 --- a/content/ja/examples/pods/inject/dapi-envars-container.yaml +++ b/content/ja/examples/pods/inject/dapi-envars-container.yaml @@ -5,7 +5,7 @@ metadata: spec: containers: - name: test-container - image: k8s.gcr.io/busybox:1.24 + image: registry.k8s.io/busybox:1.24 command: [ "sh", "-c"] args: - while true; do diff --git a/content/ja/examples/pods/inject/dapi-envars-pod.yaml b/content/ja/examples/pods/inject/dapi-envars-pod.yaml index 071fa82bb3b..d5a646e0877 100644 --- a/content/ja/examples/pods/inject/dapi-envars-pod.yaml +++ b/content/ja/examples/pods/inject/dapi-envars-pod.yaml @@ -5,7 +5,7 @@ metadata: spec: containers: - name: test-container - image: k8s.gcr.io/busybox + image: registry.k8s.io/busybox command: [ "sh", "-c"] args: - while true; do diff --git a/content/ja/examples/pods/inject/dapi-volume-resources.yaml b/content/ja/examples/pods/inject/dapi-volume-resources.yaml index ee9677bec43..9162b602f87 100644 --- a/content/ja/examples/pods/inject/dapi-volume-resources.yaml +++ b/content/ja/examples/pods/inject/dapi-volume-resources.yaml @@ -5,7 +5,7 @@ metadata: spec: containers: - name: client-container - image: k8s.gcr.io/busybox:1.24 + image: registry.k8s.io/busybox:1.24 command: ["sh", "-c"] args: - while true; do diff --git a/content/ja/examples/pods/inject/dapi-volume.yaml b/content/ja/examples/pods/inject/dapi-volume.yaml index e7515afba58..78bad5e001a 100644 --- a/content/ja/examples/pods/inject/dapi-volume.yaml +++ b/content/ja/examples/pods/inject/dapi-volume.yaml @@ -12,7 +12,7 @@ metadata: spec: containers: - name: client-container - image: k8s.gcr.io/busybox + image: registry.k8s.io/busybox command: ["sh", "-c"] args: - while true; do diff --git a/content/ja/examples/pods/pod-configmap-env-var-valueFrom.yaml b/content/ja/examples/pods/pod-configmap-env-var-valueFrom.yaml index a72b4335ce3..c5c66daea1d 100644 --- a/content/ja/examples/pods/pod-configmap-env-var-valueFrom.yaml +++ b/content/ja/examples/pods/pod-configmap-env-var-valueFrom.yaml @@ -5,7 +5,7 @@ metadata: spec: containers: - name: test-container - image: k8s.gcr.io/busybox + image: registry.k8s.io/busybox command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ] env: - name: SPECIAL_LEVEL_KEY diff --git a/content/ja/examples/pods/pod-configmap-envFrom.yaml b/content/ja/examples/pods/pod-configmap-envFrom.yaml index 70ae7e5bcfa..e7b5b60841e 100644 --- a/content/ja/examples/pods/pod-configmap-envFrom.yaml +++ b/content/ja/examples/pods/pod-configmap-envFrom.yaml @@ -5,7 +5,7 @@ metadata: spec: containers: - name: test-container - image: k8s.gcr.io/busybox + image: registry.k8s.io/busybox command: [ "/bin/sh", "-c", "env" ] envFrom: - configMapRef: diff --git a/content/ja/examples/pods/pod-configmap-volume-specific-key.yaml b/content/ja/examples/pods/pod-configmap-volume-specific-key.yaml index 72e38fd8363..ec7a8fb541c 100644 --- a/content/ja/examples/pods/pod-configmap-volume-specific-key.yaml +++ b/content/ja/examples/pods/pod-configmap-volume-specific-key.yaml @@ -5,7 +5,7 @@ metadata: spec: containers: - name: test-container - image: k8s.gcr.io/busybox + image: registry.k8s.io/busybox command: [ "/bin/sh","-c","cat /etc/config/keys" ] volumeMounts: - name: config-volume diff --git a/content/ja/examples/pods/pod-configmap-volume.yaml b/content/ja/examples/pods/pod-configmap-volume.yaml index 10bc581ce6c..aa4829aebac 100644 --- a/content/ja/examples/pods/pod-configmap-volume.yaml +++ b/content/ja/examples/pods/pod-configmap-volume.yaml @@ -5,7 +5,7 @@ metadata: spec: containers: - name: test-container - image: k8s.gcr.io/busybox + image: registry.k8s.io/busybox command: [ "/bin/sh", "-c", "ls /etc/config/" ] volumeMounts: - name: config-volume diff --git a/content/ja/examples/pods/pod-multiple-configmap-env-variable.yaml b/content/ja/examples/pods/pod-multiple-configmap-env-variable.yaml index 4790a9c661c..c7b2b7abb82 100644 --- a/content/ja/examples/pods/pod-multiple-configmap-env-variable.yaml +++ b/content/ja/examples/pods/pod-multiple-configmap-env-variable.yaml @@ -5,7 +5,7 @@ metadata: spec: containers: - name: test-container - image: k8s.gcr.io/busybox + image: registry.k8s.io/busybox command: [ "/bin/sh", "-c", "env" ] env: - name: SPECIAL_LEVEL_KEY diff --git a/content/ja/examples/pods/pod-single-configmap-env-variable.yaml b/content/ja/examples/pods/pod-single-configmap-env-variable.yaml index 83f6a02b88f..db121fdc209 100644 --- a/content/ja/examples/pods/pod-single-configmap-env-variable.yaml +++ b/content/ja/examples/pods/pod-single-configmap-env-variable.yaml @@ -5,7 +5,7 @@ metadata: spec: containers: - name: test-container - image: k8s.gcr.io/busybox + image: registry.k8s.io/busybox command: [ "/bin/sh", "-c", "env" ] env: # 環境変数を定義します diff --git a/content/ja/examples/pods/pod-with-node-affinity.yaml b/content/ja/examples/pods/pod-with-node-affinity.yaml index 253d2b21ea9..549546dbf39 100644 --- a/content/ja/examples/pods/pod-with-node-affinity.yaml +++ b/content/ja/examples/pods/pod-with-node-affinity.yaml @@ -23,4 +23,4 @@ spec: - another-node-label-value containers: - name: with-node-affinity - image: k8s.gcr.io/pause:2.0 \ No newline at end of file + image: registry.k8s.io/pause:2.0 \ No newline at end of file diff --git a/content/ja/examples/pods/pod-with-pod-affinity.yaml b/content/ja/examples/pods/pod-with-pod-affinity.yaml index e3f38f1dd54..f5297b26563 100644 --- a/content/ja/examples/pods/pod-with-pod-affinity.yaml +++ b/content/ja/examples/pods/pod-with-pod-affinity.yaml @@ -26,4 +26,4 @@ spec: topologyKey: kubernetes.io/hostname containers: - name: with-pod-affinity - image: k8s.gcr.io/pause:2.0 + image: registry.k8s.io/pause:2.0 diff --git a/content/ja/examples/pods/probe/exec-liveness.yaml b/content/ja/examples/pods/probe/exec-liveness.yaml index 6a9c9b32137..7d6ca96b3d6 100644 --- a/content/ja/examples/pods/probe/exec-liveness.yaml +++ b/content/ja/examples/pods/probe/exec-liveness.yaml @@ -7,7 +7,7 @@ metadata: spec: containers: - name: liveness - image: k8s.gcr.io/busybox + image: registry.k8s.io/busybox args: - /bin/sh - -c diff --git a/content/ja/examples/pods/probe/http-liveness.yaml b/content/ja/examples/pods/probe/http-liveness.yaml index 23d37b480a0..92e2fc5d967 100644 --- a/content/ja/examples/pods/probe/http-liveness.yaml +++ b/content/ja/examples/pods/probe/http-liveness.yaml @@ -7,7 +7,7 @@ metadata: spec: containers: - name: liveness - image: k8s.gcr.io/liveness + image: registry.k8s.io/liveness args: - /server livenessProbe: diff --git a/content/ja/examples/pods/probe/tcp-liveness-readiness.yaml b/content/ja/examples/pods/probe/tcp-liveness-readiness.yaml index 08fb77ff0f5..ef8a2f9500b 100644 --- a/content/ja/examples/pods/probe/tcp-liveness-readiness.yaml +++ b/content/ja/examples/pods/probe/tcp-liveness-readiness.yaml @@ -7,7 +7,7 @@ metadata: spec: containers: - name: goproxy - image: k8s.gcr.io/goproxy:0.1 + image: registry.k8s.io/goproxy:0.1 ports: - containerPort: 8080 readinessProbe: From f4ac392cc09ba87bb56ff1e3151f02ce3686412f Mon Sep 17 00:00:00 2001 From: Tim Bannister Date: Fri, 3 Feb 2023 15:57:57 +0000 Subject: [PATCH 068/279] Update example manifests for Japanese Related to registry change, but also adopting any other changes from English upstream. --- .../ja/examples/admin/cloud/ccm-example.yaml | 14 ++-- .../admin/dns/dns-horizontal-autoscaler.yaml | 68 +++++++++++++++++-- .../two-files-counter-pod-agent-sidecar.yaml | 2 +- .../ja/examples/application/php-apache.yaml | 1 - .../application/zookeeper/zookeeper.yaml | 4 +- .../pods/inject/dapi-volume-resources.yaml | 1 - .../ja/examples/pods/inject/dapi-volume.yaml | 1 - .../pods/pod-configmap-env-var-valueFrom.yaml | 2 +- .../examples/pods/pod-with-node-affinity.yaml | 6 +- .../examples/pods/pod-with-pod-affinity.yaml | 2 +- .../ja/examples/pods/probe/http-liveness.yaml | 2 +- 11 files changed, 79 insertions(+), 24 deletions(-) diff --git a/content/ja/examples/admin/cloud/ccm-example.yaml b/content/ja/examples/admin/cloud/ccm-example.yaml index 6f3d115993c..91b7ef2b894 100644 --- a/content/ja/examples/admin/cloud/ccm-example.yaml +++ b/content/ja/examples/admin/cloud/ccm-example.yaml @@ -1,4 +1,4 @@ -# This is an example of how to setup cloud-controller-manager as a Daemonset in your cluster. +# This is an example of how to set up cloud-controller-manager as a Daemonset in your cluster. # It assumes that your masters can run pods and has the role node-role.kubernetes.io/master # Note that this Daemonset will not work straight out of the box for your cloud, this is # meant to be a guideline. @@ -10,8 +10,8 @@ metadata: name: cloud-controller-manager namespace: kube-system --- -kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding metadata: name: system:cloud-controller-manager roleRef: @@ -47,7 +47,7 @@ spec: image: registry.k8s.io/cloud-controller-manager:v1.8.0 command: - /usr/local/bin/cloud-controller-manager - - --cloud-provider= # Add your own cloud provider here! + - --cloud-provider=[YOUR_CLOUD_PROVIDER] # Add your own cloud provider here! - --leader-elect=true - --use-service-account-credentials # these flags will vary for every cloud provider @@ -59,9 +59,13 @@ spec: - key: node.cloudprovider.kubernetes.io/uninitialized value: "true" effect: NoSchedule - # this is to have the daemonset runnable on master nodes - # the taint may vary depending on your cluster setup + # these tolerations are to have the daemonset runnable on control plane nodes + # remove them if your control plane nodes should not run pods + - key: node-role.kubernetes.io/control-plane + operator: Exists + effect: NoSchedule - key: node-role.kubernetes.io/master + operator: Exists effect: NoSchedule # this is to restrict CCM to only run on master nodes # the node selector may vary depending on your cluster setup diff --git a/content/ja/examples/admin/dns/dns-horizontal-autoscaler.yaml b/content/ja/examples/admin/dns/dns-horizontal-autoscaler.yaml index fe50976460d..3182fed3c80 100644 --- a/content/ja/examples/admin/dns/dns-horizontal-autoscaler.yaml +++ b/content/ja/examples/admin/dns/dns-horizontal-autoscaler.yaml @@ -1,22 +1,71 @@ +kind: ServiceAccount +apiVersion: v1 +metadata: + name: kube-dns-autoscaler + namespace: kube-system +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: system:kube-dns-autoscaler +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 +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" 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: registry.k8s.io/cluster-proportional-autoscaler-amd64:1.1.1 + image: registry.k8s.io/cpa/cluster-proportional-autoscaler:1.8.4 resources: requests: cpu: "20m" @@ -24,10 +73,15 @@ spec: command: - /cluster-proportional-autoscaler - --namespace=kube-system - - --configmap=dns-autoscaler + - --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,"min":1}} + - --default-params={"linear":{"coresPerReplica":256,"nodesPerReplica":16,"preventSinglePointFailure":true,"includeUnschedulableNodes":true}} - --logtostderr=true - --v=2 + tolerations: + - key: "CriticalAddonsOnly" + operator: "Exists" + serviceAccountName: kube-dns-autoscaler diff --git a/content/ja/examples/admin/logging/two-files-counter-pod-agent-sidecar.yaml b/content/ja/examples/admin/logging/two-files-counter-pod-agent-sidecar.yaml index 1053cac5772..a621a9fb2ac 100644 --- a/content/ja/examples/admin/logging/two-files-counter-pod-agent-sidecar.yaml +++ b/content/ja/examples/admin/logging/two-files-counter-pod-agent-sidecar.yaml @@ -5,7 +5,7 @@ metadata: spec: containers: - name: count - image: busybox + image: busybox:1.28 args: - /bin/sh - -c diff --git a/content/ja/examples/application/php-apache.yaml b/content/ja/examples/application/php-apache.yaml index d29d2b91593..a194dce6f95 100644 --- a/content/ja/examples/application/php-apache.yaml +++ b/content/ja/examples/application/php-apache.yaml @@ -6,7 +6,6 @@ spec: selector: matchLabels: run: php-apache - replicas: 1 template: metadata: labels: diff --git a/content/ja/examples/application/zookeeper/zookeeper.yaml b/content/ja/examples/application/zookeeper/zookeeper.yaml index 4037f83dc86..0f3f6cf9d18 100644 --- a/content/ja/examples/application/zookeeper/zookeeper.yaml +++ b/content/ja/examples/application/zookeeper/zookeeper.yaml @@ -27,7 +27,7 @@ spec: selector: app: zk --- -apiVersion: policy/v1beta1 +apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: zk-pdb @@ -49,7 +49,7 @@ spec: replicas: 3 updateStrategy: type: RollingUpdate - podManagementPolicy: Parallel + podManagementPolicy: OrderedReady template: metadata: labels: diff --git a/content/ja/examples/pods/inject/dapi-volume-resources.yaml b/content/ja/examples/pods/inject/dapi-volume-resources.yaml index 9162b602f87..5b52bf8448f 100644 --- a/content/ja/examples/pods/inject/dapi-volume-resources.yaml +++ b/content/ja/examples/pods/inject/dapi-volume-resources.yaml @@ -30,7 +30,6 @@ spec: volumeMounts: - name: podinfo mountPath: /etc/podinfo - readOnly: false volumes: - name: podinfo downwardAPI: diff --git a/content/ja/examples/pods/inject/dapi-volume.yaml b/content/ja/examples/pods/inject/dapi-volume.yaml index 78bad5e001a..682098d27f3 100644 --- a/content/ja/examples/pods/inject/dapi-volume.yaml +++ b/content/ja/examples/pods/inject/dapi-volume.yaml @@ -25,7 +25,6 @@ spec: volumeMounts: - name: podinfo mountPath: /etc/podinfo - readOnly: false volumes: - name: podinfo downwardAPI: diff --git a/content/ja/examples/pods/pod-configmap-env-var-valueFrom.yaml b/content/ja/examples/pods/pod-configmap-env-var-valueFrom.yaml index c5c66daea1d..fa172abd371 100644 --- a/content/ja/examples/pods/pod-configmap-env-var-valueFrom.yaml +++ b/content/ja/examples/pods/pod-configmap-env-var-valueFrom.yaml @@ -6,7 +6,7 @@ spec: containers: - name: test-container image: registry.k8s.io/busybox - command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ] + command: [ "/bin/echo", "$(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ] env: - name: SPECIAL_LEVEL_KEY valueFrom: diff --git a/content/ja/examples/pods/pod-with-node-affinity.yaml b/content/ja/examples/pods/pod-with-node-affinity.yaml index 549546dbf39..5fedc554bfd 100644 --- a/content/ja/examples/pods/pod-with-node-affinity.yaml +++ b/content/ja/examples/pods/pod-with-node-affinity.yaml @@ -8,11 +8,11 @@ spec: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - - key: kubernetes.io/e2e-az-name + - key: topology.kubernetes.io/zone operator: In values: - - e2e-az1 - - e2e-az2 + - antarctica-east1 + - antarctica-west1 preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: diff --git a/content/ja/examples/pods/pod-with-pod-affinity.yaml b/content/ja/examples/pods/pod-with-pod-affinity.yaml index f5297b26563..1a4fd74fd7a 100644 --- a/content/ja/examples/pods/pod-with-pod-affinity.yaml +++ b/content/ja/examples/pods/pod-with-pod-affinity.yaml @@ -23,7 +23,7 @@ spec: operator: In values: - S2 - topologyKey: kubernetes.io/hostname + topologyKey: topology.kubernetes.io/zone containers: - name: with-pod-affinity image: registry.k8s.io/pause:2.0 diff --git a/content/ja/examples/pods/probe/http-liveness.yaml b/content/ja/examples/pods/probe/http-liveness.yaml index 92e2fc5d967..48ca861c142 100644 --- a/content/ja/examples/pods/probe/http-liveness.yaml +++ b/content/ja/examples/pods/probe/http-liveness.yaml @@ -15,7 +15,7 @@ spec: path: /healthz port: 8080 httpHeaders: - - name: X-Custom-Header + - name: Custom-Header value: Awesome initialDelaySeconds: 3 periodSeconds: 3 From f335df748cfb16e98a3b3825f075e2bfb1d3ce92 Mon Sep 17 00:00:00 2001 From: Tim Bannister Date: Fri, 3 Feb 2023 16:40:35 +0000 Subject: [PATCH 069/279] Replace k8s.gcr.io with registry.k8s.io --- .../manage-compute-resources-container.md | 2 +- .../id/docs/concepts/configuration/secret.md | 2 +- .../compute-storage-net/device-plugins.md | 2 +- .../overview/working-with-objects/labels.md | 2 +- .../concepts/policy/pod-security-policy.md | 8 ++++---- .../concepts/storage/persistent-volumes.md | 2 +- content/id/docs/concepts/storage/volumes.md | 16 +++++++-------- .../workloads/controllers/statefulset.md | 2 +- .../concepts/workloads/pods/pod-lifecycle.md | 2 +- .../id/docs/reference/kubectl/cheatsheet.md | 4 ++-- .../tasks/administer-cluster/namespaces.md | 4 ++-- ...igure-liveness-readiness-startup-probes.md | 12 +++++------ content/id/docs/tutorials/hello-minikube.md | 2 +- .../basic-stateful-set.md | 20 +++++++++---------- content/id/examples/admin/dns/dnsutils.yaml | 2 +- .../two-files-counter-pod-agent-sidecar.yaml | 2 +- .../id/examples/application/php-apache.yaml | 2 +- .../application/web/web-parallel.yaml | 2 +- content/id/examples/application/web/web.yaml | 2 +- .../pods/pod-configmap-env-var-valueFrom.yaml | 2 +- .../examples/pods/pod-configmap-envFrom.yaml | 2 +- .../pod-configmap-volume-specific-key.yaml | 2 +- .../examples/pods/pod-configmap-volume.yaml | 2 +- .../pod-multiple-configmap-env-variable.yaml | 2 +- .../pod-single-configmap-env-variable.yaml | 2 +- .../examples/pods/pod-with-node-affinity.yaml | 2 +- .../examples/pods/pod-with-pod-affinity.yaml | 2 +- .../id/examples/pods/probe/exec-liveness.yaml | 2 +- .../id/examples/pods/probe/http-liveness.yaml | 2 +- .../pods/probe/tcp-liveness-readiness.yaml | 2 +- .../one-constraint-with-nodeaffinity.yaml | 2 +- .../one-constraint.yaml | 2 +- .../two-constraints.yaml | 2 +- 33 files changed, 59 insertions(+), 59 deletions(-) diff --git a/content/id/docs/concepts/configuration/manage-compute-resources-container.md b/content/id/docs/concepts/configuration/manage-compute-resources-container.md index 600a4cc6cdf..c435b27c6e3 100644 --- a/content/id/docs/concepts/configuration/manage-compute-resources-container.md +++ b/content/id/docs/concepts/configuration/manage-compute-resources-container.md @@ -314,7 +314,7 @@ Conditions: Events: FirstSeen LastSeen Count From SubobjectPath Reason Message Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {scheduler } scheduled Successfully assigned simmemleak-hra99 to kubernetes-node-tf0f - Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD pulled Pod container image "k8s.gcr.io/pause:0.8.0" already present on machine + Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD pulled Pod container image "registry.k8s.io/pause:0.8.0" already present on machine Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD created Created with docker id 6a41280f516d Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} implicitly required container POD started Started with docker id 6a41280f516d Tue, 07 Jul 2015 12:53:51 -0700 Tue, 07 Jul 2015 12:53:51 -0700 1 {kubelet kubernetes-node-tf0f} spec.containers{simmemleak} created Created with docker id 87348f12526a diff --git a/content/id/docs/concepts/configuration/secret.md b/content/id/docs/concepts/configuration/secret.md index 4a30e2b28ce..c7d295702f2 100644 --- a/content/id/docs/concepts/configuration/secret.md +++ b/content/id/docs/concepts/configuration/secret.md @@ -920,7 +920,7 @@ spec: secretName: dotfile-secret containers: - name: dotfile-test-container - image: k8s.gcr.io/busybox + image: registry.k8s.io/busybox command: - ls - "-l" diff --git a/content/id/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins.md b/content/id/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins.md index 0ed2382212e..40263d5e355 100644 --- a/content/id/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins.md +++ b/content/id/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins.md @@ -67,7 +67,7 @@ metadata: spec: containers: - name: demo-container-1 - image: k8s.gcr.io/pause:2.0 + image: registry.k8s.io/pause:2.0 resources: limits: hardware-vendor.example/foo: 2 diff --git a/content/id/docs/concepts/overview/working-with-objects/labels.md b/content/id/docs/concepts/overview/working-with-objects/labels.md index 7b4b1250621..90f58d5a5a5 100644 --- a/content/id/docs/concepts/overview/working-with-objects/labels.md +++ b/content/id/docs/concepts/overview/working-with-objects/labels.md @@ -116,7 +116,7 @@ metadata: spec: containers: - name: cuda-test - image: "k8s.gcr.io/cuda-vector-add:v0.1" + image: "registry.k8s.io/cuda-vector-add:v0.1" resources: limits: nvidia.com/gpu: 1 diff --git a/content/id/docs/concepts/policy/pod-security-policy.md b/content/id/docs/concepts/policy/pod-security-policy.md index 991ebb44aa8..3646246150e 100644 --- a/content/id/docs/concepts/policy/pod-security-policy.md +++ b/content/id/docs/concepts/policy/pod-security-policy.md @@ -165,7 +165,7 @@ metadata: spec: containers: - name: pause - image: k8s.gcr.io/pause + image: registry.k8s.io/pause EOF Error from server (Forbidden): error when creating "STDIN": pods "pause" is forbidden: unable to validate against any pod security policy: [] ``` @@ -210,7 +210,7 @@ metadata: spec: containers: - name: pause - image: k8s.gcr.io/pause + image: registry.k8s.io/pause EOF pod "pause" created ``` @@ -226,7 +226,7 @@ metadata: spec: containers: - name: pause - image: k8s.gcr.io/pause + image: registry.k8s.io/pause securityContext: privileged: true EOF @@ -244,7 +244,7 @@ kubectl-user delete pod pause Mari coba lagi, dengan cara yang sedikit berbeda: ```shell -kubectl-user run pause --image=k8s.gcr.io/pause +kubectl-user run pause --image=registry.k8s.io/pause deployment "pause" created kubectl-user get pods diff --git a/content/id/docs/concepts/storage/persistent-volumes.md b/content/id/docs/concepts/storage/persistent-volumes.md index f77f60ef182..128a71892d8 100644 --- a/content/id/docs/concepts/storage/persistent-volumes.md +++ b/content/id/docs/concepts/storage/persistent-volumes.md @@ -155,7 +155,7 @@ spec: path: /any/path/it/will/be/replaced containers: - name: pv-recycler - image: "k8s.gcr.io/busybox" + image: "registry.k8s.io/busybox" command: ["/bin/sh", "-c", "test -e /scrub && rm -rf /scrub/..?* /scrub/.[!.]* /scrub/* && test -z \"$(ls -A /scrub)\" || exit 1"] volumeMounts: - name: vol diff --git a/content/id/docs/concepts/storage/volumes.md b/content/id/docs/concepts/storage/volumes.md index 702fecea706..3c963457583 100644 --- a/content/id/docs/concepts/storage/volumes.md +++ b/content/id/docs/concepts/storage/volumes.md @@ -94,7 +94,7 @@ metadata: name: test-ebs spec: containers: - - image: k8s.gcr.io/test-webserver + - image: registry.k8s.io/test-webserver name: test-container volumeMounts: - mountPath: /test-ebs @@ -164,7 +164,7 @@ metadata: name: test-cinder spec: containers: - - image: k8s.gcr.io/test-webserver + - image: registry.k8s.io/test-webserver name: test-cinder-container volumeMounts: - mountPath: /test-cinder @@ -258,7 +258,7 @@ metadata: name: test-pd spec: containers: - - image: k8s.gcr.io/test-webserver + - image: registry.k8s.io/test-webserver name: test-container volumeMounts: - mountPath: /cache @@ -325,7 +325,7 @@ metadata: name: test-pd spec: containers: - - image: k8s.gcr.io/test-webserver + - image: registry.k8s.io/test-webserver name: test-container volumeMounts: - mountPath: /test-pd @@ -462,7 +462,7 @@ metadata: name: test-pd spec: containers: - - image: k8s.gcr.io/test-webserver + - image: registry.k8s.io/test-webserver name: test-container volumeMounts: - mountPath: /test-pd @@ -697,7 +697,7 @@ metadata: name: test-portworx-volume-pod spec: containers: - - image: k8s.gcr.io/test-webserver + - image: registry.k8s.io/test-webserver name: test-container volumeMounts: - mountPath: /mnt @@ -757,7 +757,7 @@ metadata: name: pod-0 spec: containers: - - image: k8s.gcr.io/test-webserver + - image: registry.k8s.io/test-webserver name: pod-0 volumeMounts: - mountPath: /test-pd @@ -882,7 +882,7 @@ metadata: name: test-vmdk spec: containers: - - image: k8s.gcr.io/test-webserver + - image: registry.k8s.io/test-webserver name: test-container volumeMounts: - mountPath: /test-vmdk diff --git a/content/id/docs/concepts/workloads/controllers/statefulset.md b/content/id/docs/concepts/workloads/controllers/statefulset.md index aa99acd6e6a..a309e223a36 100644 --- a/content/id/docs/concepts/workloads/controllers/statefulset.md +++ b/content/id/docs/concepts/workloads/controllers/statefulset.md @@ -87,7 +87,7 @@ spec: terminationGracePeriodSeconds: 10 containers: - name: nginx - image: k8s.gcr.io/nginx-slim:0.8 + image: registry.k8s.io/nginx-slim:0.8 ports: - containerPort: 80 name: web diff --git a/content/id/docs/concepts/workloads/pods/pod-lifecycle.md b/content/id/docs/concepts/workloads/pods/pod-lifecycle.md index fdb3e7b71cc..adad4be97f8 100644 --- a/content/id/docs/concepts/workloads/pods/pod-lifecycle.md +++ b/content/id/docs/concepts/workloads/pods/pod-lifecycle.md @@ -268,7 +268,7 @@ spec: containers: - args: - /server - image: k8s.gcr.io/liveness + image: registry.k8s.io/liveness livenessProbe: httpGet: # ketika "host" tidak ditentukan, "PodIP" akan digunakan diff --git a/content/id/docs/reference/kubectl/cheatsheet.md b/content/id/docs/reference/kubectl/cheatsheet.md index 671ac6b77a2..7e0336c542f 100644 --- a/content/id/docs/reference/kubectl/cheatsheet.md +++ b/content/id/docs/reference/kubectl/cheatsheet.md @@ -360,8 +360,8 @@ Contoh-contoh yang menggunakan `-o=custom-columns`: # All images running in a cluster kubectl get pods -A -o=custom-columns='DATA:spec.containers[*].image' - # All images excluding "k8s.gcr.io/coredns:1.6.2" -kubectl get pods -A -o=custom-columns='DATA:spec.containers[?(@.image!="k8s.gcr.io/coredns:1.6.2")].image' + # All images excluding "registry.k8s.io/coredns:1.6.2" +kubectl get pods -A -o=custom-columns='DATA:spec.containers[?(@.image!="registry.k8s.io/coredns:1.6.2")].image' # All fields under metadata regardless of name kubectl get pods -A -o=custom-columns='DATA:metadata.*' diff --git a/content/id/docs/tasks/administer-cluster/namespaces.md b/content/id/docs/tasks/administer-cluster/namespaces.md index 409e42dd704..1b9133fb9b9 100644 --- a/content/id/docs/tasks/administer-cluster/namespaces.md +++ b/content/id/docs/tasks/administer-cluster/namespaces.md @@ -185,7 +185,7 @@ Proses penghapusan ini asinkron, jadi untuk beberapa waktu kamu akan melihat Nam Untuk menunjukkan hal ini, mari kita jalankan Deployment dan Pod sederhana di dalam Namespace `development`. ```shell - kubectl create deployment snowflake --image=k8s.gcr.io/serve_hostname -n=development + kubectl create deployment snowflake --image=registry.k8s.io/serve_hostname -n=development kubectl scale deployment snowflake --replicas=2 -n=development ``` Kita baru aja membuat sebuah Deployment yang memiliki ukuran replika dua yang menjalankan Pod dengan nama `snowflake` dengan sebuah Container dasar yang hanya melayani _hostname_. @@ -221,7 +221,7 @@ Proses penghapusan ini asinkron, jadi untuk beberapa waktu kamu akan melihat Nam `Production` Namespace ingin menjalankan `cattle`, mari kita buat beberapa Pod `cattle`. ```shell - kubectl create deployment cattle --image=k8s.gcr.io/serve_hostname -n=production + kubectl create deployment cattle --image=registry.k8s.io/serve_hostname -n=production kubectl scale deployment cattle --replicas=5 -n=production kubectl get deployment -n=production diff --git a/content/id/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes.md b/content/id/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes.md index 96b08d1aca0..d56f59a09a6 100644 --- a/content/id/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes.md +++ b/content/id/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes.md @@ -44,7 +44,7 @@ bertransisi ke _state_ yang rusak (_broken_), dan tidak dapat pulih kecuali diul Kubernetes menyediakan _probe liveness_ untuk mendeteksi dan memperbaiki situasi tersebut. Pada latihan ini, kamu akan membuat Pod yang menjalankan Container dari image -`k8s.gcr.io/busybox`. Berikut ini adalah berkas konfigurasi untuk Pod tersebut: +`registry.k8s.io/busybox`. Berikut ini adalah berkas konfigurasi untuk Pod tersebut: {{< codenew file="pods/probe/exec-liveness.yaml" >}} @@ -84,8 +84,8 @@ Keluaran dari perintah tersebut memperlihatkan bahwa belum ada _probe liveness_ FirstSeen LastSeen Count From SubobjectPath Type Reason Message --------- -------- ----- ---- ------------- -------- ------ ------- 24s 24s 1 {default-scheduler } Normal Scheduled Successfully assigned liveness-exec to worker0 -23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Pulling pulling image "k8s.gcr.io/busybox" -23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Pulled Successfully pulled image "k8s.gcr.io/busybox" +23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Pulling pulling image "registry.k8s.io/busybox" +23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Pulled Successfully pulled image "registry.k8s.io/busybox" 23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Created Created container with docker id 86849c15382e; Security:[seccomp=unconfined] 23s 23s 1 {kubelet worker0} spec.containers{liveness} Normal Started Started container with docker id 86849c15382e ``` @@ -103,8 +103,8 @@ mengalami kegagalan, dan Container telah dimatikan dan dibuat ulang. FirstSeen LastSeen Count From SubobjectPath Type Reason Message --------- -------- ----- ---- ------------- -------- ------ ------- 37s 37s 1 {default-scheduler } Normal Scheduled Successfully assigned liveness-exec to worker0 -36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Pulling pulling image "k8s.gcr.io/busybox" -36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Pulled Successfully pulled image "k8s.gcr.io/busybox" +36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Pulling pulling image "registry.k8s.io/busybox" +36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Pulled Successfully pulled image "registry.k8s.io/busybox" 36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Created Created container with docker id 86849c15382e; Security:[seccomp=unconfined] 36s 36s 1 {kubelet worker0} spec.containers{liveness} Normal Started Started container with docker id 86849c15382e 2s 2s 1 {kubelet worker0} spec.containers{liveness} Warning Unhealthy Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory @@ -126,7 +126,7 @@ liveness-exec 1/1 Running 1 1m ## Mendefinisikan probe liveness dengan permintaan HTTP Jenis kedua dari _probe liveness_ menggunakan sebuah permintaan GET HTTP. Berikut ini -berkas konfigurasi untuk Pod yang menjalankan Container dari image `k8s.gcr.io/liveness`. +berkas konfigurasi untuk Pod yang menjalankan Container dari image `registry.k8s.io/liveness`. {{< codenew file="pods/probe/http-liveness.yaml" >}} diff --git a/content/id/docs/tutorials/hello-minikube.md b/content/id/docs/tutorials/hello-minikube.md index 398c5a3a3f8..6790dbf47fb 100644 --- a/content/id/docs/tutorials/hello-minikube.md +++ b/content/id/docs/tutorials/hello-minikube.md @@ -77,7 +77,7 @@ Pod kamu dan melakukan restart saat Kontainer di dalam Pod tersebut mati. Pod menjalankan Kontainer sesuai dengan image Docker yang telah diberikan. ```shell - kubectl create deployment hello-node --image=k8s.gcr.io/echoserver:1.4 + kubectl create deployment hello-node --image=registry.k8s.io/echoserver:1.4 ``` 2. Lihat Deployment: diff --git a/content/id/docs/tutorials/stateful-application/basic-stateful-set.md b/content/id/docs/tutorials/stateful-application/basic-stateful-set.md index 0e15eceddb1..980e2ac793b 100644 --- a/content/id/docs/tutorials/stateful-application/basic-stateful-set.md +++ b/content/id/docs/tutorials/stateful-application/basic-stateful-set.md @@ -606,9 +606,9 @@ Dapatkan Pod untuk melihat _image_ Container-nya: for p in 0 1 2; do kubectl get pod "web-$p" --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'; echo; done ``` ``` -k8s.gcr.io/nginx-slim:0.8 -k8s.gcr.io/nginx-slim:0.8 -k8s.gcr.io/nginx-slim:0.8 +registry.k8s.io/nginx-slim:0.8 +registry.k8s.io/nginx-slim:0.8 +registry.k8s.io/nginx-slim:0.8 ``` @@ -640,7 +640,7 @@ statefulset.apps/web patched Lakukan _patch_ terhadap StatefulSet lagi, untuk mengubah _image_ Container: ```shell -kubectl patch statefulset web --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"k8s.gcr.io/nginx-slim:0.7"}]' +kubectl patch statefulset web --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"registry.k8s.io/nginx-slim:0.7"}]' ``` ``` statefulset.apps/web patched @@ -674,7 +674,7 @@ Dapatkan _image_ Container Pod: kubectl get pod web-2 --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}' ``` ``` -k8s.gcr.io/nginx-slim:0.8 +registry.k8s.io/nginx-slim:0.8 ``` Perhatikan, walaupun strategi pembaruan yang digunakan adalah `RollingUpdate`, @@ -714,7 +714,7 @@ Dapatkan _image_ Container Pod: kubectl get pod web-2 --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}' ``` ``` -k8s.gcr.io/nginx-slim:0.7 +registry.k8s.io/nginx-slim:0.7 ``` @@ -757,7 +757,7 @@ Dapatkan _image_ Container dari Pod `web-1`: kubectl get pod web-1 --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}' ``` ``` -k8s.gcr.io/nginx-slim:0.8 +registry.k8s.io/nginx-slim:0.8 ``` `web-1` dikembalikan ke konfigurasinya yang semula karena urutan Pod lebih kecil @@ -813,9 +813,9 @@ Dapatkan detail _image_ Container dari Pod pada StatefulSet: for p in 0 1 2; do kubectl get pod "web-$p" --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'; echo; done ``` ``` -k8s.gcr.io/nginx-slim:0.7 -k8s.gcr.io/nginx-slim:0.7 -k8s.gcr.io/nginx-slim:0.7 +registry.k8s.io/nginx-slim:0.7 +registry.k8s.io/nginx-slim:0.7 +registry.k8s.io/nginx-slim:0.7 ``` Dengan mengubah nilai `partition` menjadi `0`, kamu mengizinkan StatefulSet diff --git a/content/id/examples/admin/dns/dnsutils.yaml b/content/id/examples/admin/dns/dnsutils.yaml index 5be0791c034..cb333a2796f 100644 --- a/content/id/examples/admin/dns/dnsutils.yaml +++ b/content/id/examples/admin/dns/dnsutils.yaml @@ -6,7 +6,7 @@ metadata: spec: containers: - name: dnsutils - image: k8s.gcr.io/e2e-test-images/jessie-dnsutils:1.3 + image: registry.k8s.io/e2e-test-images/jessie-dnsutils:1.3 command: - sleep - "3600" diff --git a/content/id/examples/admin/logging/two-files-counter-pod-agent-sidecar.yaml b/content/id/examples/admin/logging/two-files-counter-pod-agent-sidecar.yaml index b37b616e6f7..1053cac5772 100644 --- a/content/id/examples/admin/logging/two-files-counter-pod-agent-sidecar.yaml +++ b/content/id/examples/admin/logging/two-files-counter-pod-agent-sidecar.yaml @@ -22,7 +22,7 @@ spec: - name: varlog mountPath: /var/log - name: count-agent - image: k8s.gcr.io/fluentd-gcp:1.30 + image: registry.k8s.io/fluentd-gcp:1.30 env: - name: FLUENTD_ARGS value: -c /etc/fluentd-config/fluentd.conf diff --git a/content/id/examples/application/php-apache.yaml b/content/id/examples/application/php-apache.yaml index e8e1b5aeb43..d29d2b91593 100644 --- a/content/id/examples/application/php-apache.yaml +++ b/content/id/examples/application/php-apache.yaml @@ -14,7 +14,7 @@ spec: spec: containers: - name: php-apache - image: k8s.gcr.io/hpa-example + image: registry.k8s.io/hpa-example ports: - containerPort: 80 resources: diff --git a/content/id/examples/application/web/web-parallel.yaml b/content/id/examples/application/web/web-parallel.yaml index 4eab2dc2066..a6633f476c1 100644 --- a/content/id/examples/application/web/web-parallel.yaml +++ b/content/id/examples/application/web/web-parallel.yaml @@ -30,7 +30,7 @@ spec: spec: containers: - name: nginx - image: k8s.gcr.io/nginx-slim:0.8 + image: registry.k8s.io/nginx-slim:0.8 ports: - containerPort: 80 name: web diff --git a/content/id/examples/application/web/web.yaml b/content/id/examples/application/web/web.yaml index c1950aecbf1..7b12d521a51 100644 --- a/content/id/examples/application/web/web.yaml +++ b/content/id/examples/application/web/web.yaml @@ -29,7 +29,7 @@ spec: spec: containers: - name: nginx - image: k8s.gcr.io/nginx-slim:0.8 + image: registry.k8s.io/nginx-slim:0.8 ports: - containerPort: 80 name: web diff --git a/content/id/examples/pods/pod-configmap-env-var-valueFrom.yaml b/content/id/examples/pods/pod-configmap-env-var-valueFrom.yaml index a72b4335ce3..c5c66daea1d 100644 --- a/content/id/examples/pods/pod-configmap-env-var-valueFrom.yaml +++ b/content/id/examples/pods/pod-configmap-env-var-valueFrom.yaml @@ -5,7 +5,7 @@ metadata: spec: containers: - name: test-container - image: k8s.gcr.io/busybox + image: registry.k8s.io/busybox command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ] env: - name: SPECIAL_LEVEL_KEY diff --git a/content/id/examples/pods/pod-configmap-envFrom.yaml b/content/id/examples/pods/pod-configmap-envFrom.yaml index 70ae7e5bcfa..e7b5b60841e 100644 --- a/content/id/examples/pods/pod-configmap-envFrom.yaml +++ b/content/id/examples/pods/pod-configmap-envFrom.yaml @@ -5,7 +5,7 @@ metadata: spec: containers: - name: test-container - image: k8s.gcr.io/busybox + image: registry.k8s.io/busybox command: [ "/bin/sh", "-c", "env" ] envFrom: - configMapRef: diff --git a/content/id/examples/pods/pod-configmap-volume-specific-key.yaml b/content/id/examples/pods/pod-configmap-volume-specific-key.yaml index 72e38fd8363..ec7a8fb541c 100644 --- a/content/id/examples/pods/pod-configmap-volume-specific-key.yaml +++ b/content/id/examples/pods/pod-configmap-volume-specific-key.yaml @@ -5,7 +5,7 @@ metadata: spec: containers: - name: test-container - image: k8s.gcr.io/busybox + image: registry.k8s.io/busybox command: [ "/bin/sh","-c","cat /etc/config/keys" ] volumeMounts: - name: config-volume diff --git a/content/id/examples/pods/pod-configmap-volume.yaml b/content/id/examples/pods/pod-configmap-volume.yaml index 16457e63c47..2758d49386f 100644 --- a/content/id/examples/pods/pod-configmap-volume.yaml +++ b/content/id/examples/pods/pod-configmap-volume.yaml @@ -5,7 +5,7 @@ metadata: spec: containers: - name: test-container - image: k8s.gcr.io/busybox + image: registry.k8s.io/busybox command: [ "/bin/sh", "-c", "ls /etc/config/" ] volumeMounts: - name: config-volume diff --git a/content/id/examples/pods/pod-multiple-configmap-env-variable.yaml b/content/id/examples/pods/pod-multiple-configmap-env-variable.yaml index 4790a9c661c..c7b2b7abb82 100644 --- a/content/id/examples/pods/pod-multiple-configmap-env-variable.yaml +++ b/content/id/examples/pods/pod-multiple-configmap-env-variable.yaml @@ -5,7 +5,7 @@ metadata: spec: containers: - name: test-container - image: k8s.gcr.io/busybox + image: registry.k8s.io/busybox command: [ "/bin/sh", "-c", "env" ] env: - name: SPECIAL_LEVEL_KEY diff --git a/content/id/examples/pods/pod-single-configmap-env-variable.yaml b/content/id/examples/pods/pod-single-configmap-env-variable.yaml index c2aacd2de00..4d0e9f842b4 100644 --- a/content/id/examples/pods/pod-single-configmap-env-variable.yaml +++ b/content/id/examples/pods/pod-single-configmap-env-variable.yaml @@ -5,7 +5,7 @@ metadata: spec: containers: - name: test-container - image: k8s.gcr.io/busybox + image: registry.k8s.io/busybox command: [ "/bin/sh", "-c", "env" ] env: # Tentukan variabel environment diff --git a/content/id/examples/pods/pod-with-node-affinity.yaml b/content/id/examples/pods/pod-with-node-affinity.yaml index 253d2b21ea9..549546dbf39 100644 --- a/content/id/examples/pods/pod-with-node-affinity.yaml +++ b/content/id/examples/pods/pod-with-node-affinity.yaml @@ -23,4 +23,4 @@ spec: - another-node-label-value containers: - name: with-node-affinity - image: k8s.gcr.io/pause:2.0 \ No newline at end of file + image: registry.k8s.io/pause:2.0 \ No newline at end of file diff --git a/content/id/examples/pods/pod-with-pod-affinity.yaml b/content/id/examples/pods/pod-with-pod-affinity.yaml index 35e645ef1f3..0eb4c441a4d 100644 --- a/content/id/examples/pods/pod-with-pod-affinity.yaml +++ b/content/id/examples/pods/pod-with-pod-affinity.yaml @@ -26,4 +26,4 @@ spec: topologyKey: failure-domain.beta.kubernetes.io/zone containers: - name: with-pod-affinity - image: k8s.gcr.io/pause:2.0 + image: registry.k8s.io/pause:2.0 diff --git a/content/id/examples/pods/probe/exec-liveness.yaml b/content/id/examples/pods/probe/exec-liveness.yaml index 6a9c9b32137..7d6ca96b3d6 100644 --- a/content/id/examples/pods/probe/exec-liveness.yaml +++ b/content/id/examples/pods/probe/exec-liveness.yaml @@ -7,7 +7,7 @@ metadata: spec: containers: - name: liveness - image: k8s.gcr.io/busybox + image: registry.k8s.io/busybox args: - /bin/sh - -c diff --git a/content/id/examples/pods/probe/http-liveness.yaml b/content/id/examples/pods/probe/http-liveness.yaml index 670af18399e..48ca861c142 100644 --- a/content/id/examples/pods/probe/http-liveness.yaml +++ b/content/id/examples/pods/probe/http-liveness.yaml @@ -7,7 +7,7 @@ metadata: spec: containers: - name: liveness - image: k8s.gcr.io/liveness + image: registry.k8s.io/liveness args: - /server livenessProbe: diff --git a/content/id/examples/pods/probe/tcp-liveness-readiness.yaml b/content/id/examples/pods/probe/tcp-liveness-readiness.yaml index 08fb77ff0f5..ef8a2f9500b 100644 --- a/content/id/examples/pods/probe/tcp-liveness-readiness.yaml +++ b/content/id/examples/pods/probe/tcp-liveness-readiness.yaml @@ -7,7 +7,7 @@ metadata: spec: containers: - name: goproxy - image: k8s.gcr.io/goproxy:0.1 + image: registry.k8s.io/goproxy:0.1 ports: - containerPort: 8080 readinessProbe: diff --git a/content/id/examples/pods/topology-spread-constraints/one-constraint-with-nodeaffinity.yaml b/content/id/examples/pods/topology-spread-constraints/one-constraint-with-nodeaffinity.yaml index 98823f9d869..12b117a8145 100644 --- a/content/id/examples/pods/topology-spread-constraints/one-constraint-with-nodeaffinity.yaml +++ b/content/id/examples/pods/topology-spread-constraints/one-constraint-with-nodeaffinity.yaml @@ -23,4 +23,4 @@ spec: - zoneC containers: - name: pause - image: k8s.gcr.io/pause:3.1 \ No newline at end of file + image: registry.k8s.io/pause:3.1 \ No newline at end of file diff --git a/content/id/examples/pods/topology-spread-constraints/one-constraint.yaml b/content/id/examples/pods/topology-spread-constraints/one-constraint.yaml index a0a41188ec3..02d2c6ca406 100644 --- a/content/id/examples/pods/topology-spread-constraints/one-constraint.yaml +++ b/content/id/examples/pods/topology-spread-constraints/one-constraint.yaml @@ -14,4 +14,4 @@ spec: foo: bar containers: - name: pause - image: k8s.gcr.io/pause:3.1 \ No newline at end of file + image: registry.k8s.io/pause:3.1 \ No newline at end of file diff --git a/content/id/examples/pods/topology-spread-constraints/two-constraints.yaml b/content/id/examples/pods/topology-spread-constraints/two-constraints.yaml index aa142b7abbd..c1111951559 100644 --- a/content/id/examples/pods/topology-spread-constraints/two-constraints.yaml +++ b/content/id/examples/pods/topology-spread-constraints/two-constraints.yaml @@ -20,4 +20,4 @@ spec: foo: bar containers: - name: pause - image: k8s.gcr.io/pause:3.1 \ No newline at end of file + image: registry.k8s.io/pause:3.1 \ No newline at end of file From f097433069c13ab7a9f4925c24a0a9c355a0c9c5 Mon Sep 17 00:00:00 2001 From: windsonsea Date: Sat, 4 Feb 2023 22:12:06 +0800 Subject: [PATCH 070/279] [zh] sync downward-api.md --- .../docs/concepts/workloads/pods/downward-api.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/content/zh-cn/docs/concepts/workloads/pods/downward-api.md b/content/zh-cn/docs/concepts/workloads/pods/downward-api.md index 198f353f205..825b67caa06 100644 --- a/content/zh-cn/docs/concepts/workloads/pods/downward-api.md +++ b/content/zh-cn/docs/concepts/workloads/pods/downward-api.md @@ -125,6 +125,12 @@ via either mechanism are: `metadata.labels['']` : Pod 的{{< glossary_tooltip text="标签" term_id="label" >}} `` 的值(例如:`metadata.labels['mylabel']`) + +以下信息可以通过环境变量获得,但**不能作为 `downwardAPI` 卷 `fieldRef`** 获得: + -此外,以下信息可以通过 `downwardAPI` 卷 `fieldRef` 获得,但**不能作为环境变量**获得: +以下信息可以通过 `downwardAPI` 卷 `fieldRef` 获得,但**不能作为环境变量**获得: @@ -148,7 +148,7 @@ Ingress 对象的命名必须是合法的 [DNS 子域名名称](/zh-cn/docs/conc [配置容器](/zh-cn/docs/tasks/configure-pod-container/configure-pod-configmap/)、 [管理资源](/zh-cn/docs/concepts/cluster-administration/manage-deployment/)。 Ingress 经常使用注解(annotations)来配置一些选项,具体取决于 Ingress -控制器,例如[重写目标注解](https://github.com/kubernetes/ingress-nginx/blob/master/docs/examples/rewrite/README.md)。 +控制器,例如[重写目标注解](https://github.com/kubernetes/ingress-nginx/blob/main/docs/examples/rewrite/README.md)。 不同的 [Ingress 控制器](/zh-cn/docs/concepts/services-networking/ingress-controllers)支持不同的注解。 查看你所选的 Ingress 控制器的文档,以了解其支持哪些注解。 From cbfdf382c5893346eb252a9dfa4b191ca1d15e39 Mon Sep 17 00:00:00 2001 From: Arhell Date: Sun, 5 Feb 2023 00:22:23 +0200 Subject: [PATCH 072/279] [id] updated nginx version to follow examples correctly --- content/id/examples/application/deployment-scale.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/id/examples/application/deployment-scale.yaml b/content/id/examples/application/deployment-scale.yaml index 84e326eee10..23692a4fe5b 100644 --- a/content/id/examples/application/deployment-scale.yaml +++ b/content/id/examples/application/deployment-scale.yaml @@ -14,6 +14,6 @@ spec: spec: containers: - name: nginx - image: nginx:1.14.2 + image: nginx:1.16.1 ports: - containerPort: 80 From d06d0d8a9b5a497590f6ec60e0435455ec7ca61b Mon Sep 17 00:00:00 2001 From: windsonsea Date: Sun, 5 Feb 2023 12:28:41 +0800 Subject: [PATCH 073/279] [zh] sync /config-and-storage-resources/volume.md --- .../config-and-storage-resources/volume.md | 41 ------------------- 1 file changed, 41 deletions(-) diff --git a/content/zh-cn/docs/reference/kubernetes-api/config-and-storage-resources/volume.md b/content/zh-cn/docs/reference/kubernetes-api/config-and-storage-resources/volume.md index 78014744bde..79fcc0faa80 100755 --- a/content/zh-cn/docs/reference/kubernetes-api/config-and-storage-resources/volume.md +++ b/content/zh-cn/docs/reference/kubernetes-api/config-and-storage-resources/volume.md @@ -1135,47 +1135,6 @@ Volume 表示 Pod 中一个有名字的卷,可以由 Pod 中的任意容器进 此处的 readOnly 将强制设置卷挂载中的 readOnly 属性。默认为 false。更多信息: https://kubernetes.io/zh-cn/docs/concepts/storage/volumes#gcepersistentdisk - -- **glusterfs** (GlusterfsVolumeSource) - - glusterfs 表示在与 Pod 共享生命周期的主机上挂载的 Glusterfs。更多信息: - https://examples.k8s.io/volumes/glusterfs/README.md - - - **表示在 Pod 的生命周期内持续的 Glusterfs 挂载。glusterfs 卷不支持所有权管理或 SELinux 重新打标签。** - - - - - **glusterfs.endpoints** (string),必需 - - endpoints 是详细说明 Glusterfs 拓扑的端点名称。更多信息: - https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod - - - **glusterfs.path** (string),必需 - - path 是 Glusterfs 卷路径。更多信息: - https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod - - - **glusterfs.readOnly** (boolean) - - 此处 readOnly 将强制使用只读权限挂载 Glusterfs 卷。默认为 false。更多信息: - https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod - ### 使用原始数据 - 执行以下命令: @@ -62,21 +62,21 @@ kubectl create secret generic db-user-pass \ --from-literal=password='S!B\*d$zDsb=' ``` - 你必须使用单引号 `''` 转义字符串中的特殊字符,如 `$`、`\`、`*`、`=`和`!` 。否则,你的 shell 将会解析这些字符。 - ### 使用源文件 - 1. 将凭据保存到文件: @@ -85,19 +85,19 @@ characters. echo -n 'S!B\*d$zDsb=' > ./password.txt ``` - - `-n` 标志用来确保生成文件的文末没有多余的换行符。这很重要,因为当 `kubectl` - 读取文件并将内容编码为 base64 字符串时,额外的换行符也会被编码。 - 你不需要对文件中包含的字符串中的特殊字符进行转义。 + + `-n` 标志用来确保生成文件的文末没有多余的换行符。这很重要,因为当 `kubectl` + 读取文件并将内容编码为 base64 字符串时,额外的换行符也会被编码。 + 你不需要对文件中包含的字符串中的特殊字符进行转义。 - 2. 在 `kubectl` 命令中传递文件路径: @@ -107,11 +107,11 @@ characters. --from-file=./password.txt ``` - - 默认键名为文件名。你也可以通过 `--from-file=[key=]source` 设置键名,例如: + + 默认键名为文件名。你也可以通过 `--from-file=[key=]source` 设置键名,例如: ```shell kubectl create secret generic db-user-pass \ @@ -119,8 +119,8 @@ characters. --from-file=password=./password.txt ``` - 无论使用哪种方法,输出都类似于: @@ -128,13 +128,13 @@ With either method, the output is similar to: secret/db-user-pass created ``` - ## 验证 Secret {#verify-the-secret} - 检查 Secret 是否已创建: @@ -152,8 +152,8 @@ NAME TYPE DATA AGE db-user-pass Opaque 2 51s ``` - 查看 Secret 的细节: @@ -161,8 +161,8 @@ View the details of the Secret: kubectl describe secret db-user-pass ``` - 输出类似于: @@ -188,13 +188,13 @@ accidentally, or from being stored in a terminal log. `kubectl get` 和 `kubectl describe` 命令默认不显示 `Secret` 的内容。 这是为了防止 `Secret` 被意外暴露或存储在终端日志中。 - ### 解码 Secret {#decoding-secret} - 1. 查看你所创建的 Secret 内容 @@ -208,7 +208,7 @@ accidentally, or from being stored in a terminal log. 输出类似于: ```json - {"password":"UyFCXCpkJHpEc2I9","username":"YWRtaW4="} + { "password": "UyFCXCpkJHpEc2I9", "username": "YWRtaW4=" } ``` ## 编辑 Secret {#edit-secret} - 你可以编辑一个现存的 `Secret` 对象,除非它是[不可改变的](/zh-cn/docs/concepts/configuration/secret/#secret-immutable)。 要想编辑一个 Secret,请执行以下命令: @@ -263,9 +263,9 @@ Secret, run the following command: kubectl edit secrets ``` - 这将打开默认编辑器,并允许你更新 `data` 字段中的 base64 编码的 Secret 值,示例如下: @@ -294,13 +294,13 @@ metadata: type: Opaque ``` - ## 清理 {#clean-up} - 要想删除一个 Secret,请执行以下命令: From 3aa5fe0cca9831b587ee10400c8983e49f770edc Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Sun, 5 Feb 2023 14:17:55 +0800 Subject: [PATCH 075/279] Cleanup node-pressure-eviction.md --- .../node-pressure-eviction.md | 140 +++++++++--------- 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/content/en/docs/concepts/scheduling-eviction/node-pressure-eviction.md b/content/en/docs/concepts/scheduling-eviction/node-pressure-eviction.md index f763f220813..91dba82b877 100644 --- a/content/en/docs/concepts/scheduling-eviction/node-pressure-eviction.md +++ b/content/en/docs/concepts/scheduling-eviction/node-pressure-eviction.md @@ -6,16 +6,16 @@ weight: 100 {{}}
    -The {{}} monitors resources -like memory, disk space, and filesystem inodes on your cluster's nodes. -When one or more of these resources reach specific consumption levels, the +The {{}} monitors resources +like memory, disk space, and filesystem inodes on your cluster's nodes. +When one or more of these resources reach specific consumption levels, the kubelet can proactively fail one or more pods on the node to reclaim resources -and prevent starvation. +and prevent starvation. During a node-pressure eviction, the kubelet sets the `PodPhase` for the -selected pods to `Failed`. This terminates the pods. +selected pods to `Failed`. This terminates the pods. -Node-pressure eviction is not the same as +Node-pressure eviction is not the same as [API-initiated eviction](/docs/concepts/scheduling-eviction/api-eviction/). The kubelet does not respect your configured `PodDisruptionBudget` or the pod's @@ -26,7 +26,7 @@ the kubelet respects your configured `eviction-max-pod-grace-period`. If you use If the pods are managed by a {{< glossary_tooltip text="workload" term_id="workload" >}} resource (such as {{< glossary_tooltip text="StatefulSet" term_id="statefulset" >}} or {{< glossary_tooltip text="Deployment" term_id="deployment" >}}) that -replaces failed pods, the control plane or `kube-controller-manager` creates new +replaces failed pods, the control plane or `kube-controller-manager` creates new pods in place of the evicted pods. {{}} @@ -37,16 +37,16 @@ images when disk resources are starved. The kubelet uses various parameters to make eviction decisions, like the following: - * Eviction signals - * Eviction thresholds - * Monitoring intervals +- Eviction signals +- Eviction thresholds +- Monitoring intervals ### Eviction signals {#eviction-signals} Eviction signals are the current state of a particular resource at a specific point in time. Kubelet uses eviction signals to make eviction decisions by -comparing the signals to eviction thresholds, which are the minimum amount of -the resource that should be available on the node. +comparing the signals to eviction thresholds, which are the minimum amount of +the resource that should be available on the node. Kubelet uses the following eviction signals: @@ -60,9 +60,9 @@ Kubelet uses the following eviction signals: | `pid.available` | `pid.available` := `node.stats.rlimit.maxpid` - `node.stats.rlimit.curproc` | In this table, the `Description` column shows how kubelet gets the value of the -signal. Each signal supports either a percentage or a literal value. Kubelet +signal. Each signal supports either a percentage or a literal value. Kubelet calculates the percentage value relative to the total capacity associated with -the signal. +the signal. The value for `memory.available` is derived from the cgroupfs instead of tools like `free -m`. This is important because `free -m` does not work in a @@ -78,7 +78,7 @@ memory is reclaimable under pressure. The kubelet supports the following filesystem partitions: 1. `nodefs`: The node's main filesystem, used for local disk volumes, emptyDir, - log storage, and more. For example, `nodefs` contains `/var/lib/kubelet/`. + log storage, and more. For example, `nodefs` contains `/var/lib/kubelet/`. 1. `imagefs`: An optional filesystem that container runtimes use to store container images and container writable layers. @@ -102,10 +102,10 @@ eviction decisions. Eviction thresholds have the form `[eviction-signal][operator][quantity]`, where: -* `eviction-signal` is the [eviction signal](#eviction-signals) to use. -* `operator` is the [relational operator](https://en.wikipedia.org/wiki/Relational_operator#Standard_relational_operators) +- `eviction-signal` is the [eviction signal](#eviction-signals) to use. +- `operator` is the [relational operator](https://en.wikipedia.org/wiki/Relational_operator#Standard_relational_operators) you want, such as `<` (less than). -* `quantity` is the eviction threshold amount, such as `1Gi`. The value of `quantity` +- `quantity` is the eviction threshold amount, such as `1Gi`. The value of `quantity` must match the quantity representation used by Kubernetes. You can use either literal values or percentages (`%`). @@ -120,22 +120,22 @@ You can configure soft and hard eviction thresholds. A soft eviction threshold pairs an eviction threshold with a required administrator-specified grace period. The kubelet does not evict pods until the grace period is exceeded. The kubelet returns an error on startup if there is no -specified grace period. +specified grace period. You can specify both a soft eviction threshold grace period and a maximum allowed pod termination grace period for kubelet to use during evictions. If you -specify a maximum allowed grace period and the soft eviction threshold is met, +specify a maximum allowed grace period and the soft eviction threshold is met, the kubelet uses the lesser of the two grace periods. If you do not specify a maximum allowed grace period, the kubelet kills evicted pods immediately without graceful termination. You can use the following flags to configure soft eviction thresholds: -* `eviction-soft`: A set of eviction thresholds like `memory.available<1.5Gi` +- `eviction-soft`: A set of eviction thresholds like `memory.available<1.5Gi` that can trigger pod eviction if held over the specified grace period. -* `eviction-soft-grace-period`: A set of eviction grace periods like `memory.available=1m30s` +- `eviction-soft-grace-period`: A set of eviction grace periods like `memory.available=1m30s` that define how long a soft eviction threshold must hold before triggering a Pod eviction. -* `eviction-max-pod-grace-period`: The maximum allowed grace period (in seconds) +- `eviction-max-pod-grace-period`: The maximum allowed grace period (in seconds) to use when terminating pods in response to a soft eviction threshold being met. #### Hard eviction thresholds {#hard-eviction-thresholds} @@ -144,20 +144,20 @@ A hard eviction threshold has no grace period. When a hard eviction threshold is met, the kubelet kills pods immediately without graceful termination to reclaim the starved resource. -You can use the `eviction-hard` flag to configure a set of hard eviction -thresholds like `memory.available<1Gi`. +You can use the `eviction-hard` flag to configure a set of hard eviction +thresholds like `memory.available<1Gi`. The kubelet has the following default hard eviction thresholds: -* `memory.available<100Mi` -* `nodefs.available<10%` -* `imagefs.available<15%` -* `nodefs.inodesFree<5%` (Linux nodes) +- `memory.available<100Mi` +- `nodefs.available<10%` +- `imagefs.available<15%` +- `nodefs.inodesFree<5%` (Linux nodes) -These default values of hard eviction thresholds will only be set if none -of the parameters is changed. If you changed the value of any parameter, -then the values of other parameters will not be inherited as the default -values and will be set to zero. In order to provide custom values, you +These default values of hard eviction thresholds will only be set if none +of the parameters is changed. If you changed the value of any parameter, +then the values of other parameters will not be inherited as the default +values and will be set to zero. In order to provide custom values, you should provide all the thresholds respectively. ### Eviction monitoring interval @@ -169,9 +169,9 @@ which defaults to `10s`. The kubelet reports node conditions to reflect that the node is under pressure because hard or soft eviction threshold is met, independent of configured grace -periods. +periods. -The kubelet maps eviction signals to node conditions as follows: +The kubelet maps eviction signals to node conditions as follows: | Node Condition | Eviction Signal | Description | |-------------------|---------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------| @@ -179,7 +179,7 @@ The kubelet maps eviction signals to node conditions as follows: | `DiskPressure` | `nodefs.available`, `nodefs.inodesFree`, `imagefs.available`, or `imagefs.inodesFree` | Available disk space and inodes on either the node's root filesystem or image filesystem has satisfied an eviction threshold | | `PIDPressure` | `pid.available` | Available processes identifiers on the (Linux) node has fallen below an eviction threshold | -The kubelet updates the node conditions based on the configured +The kubelet updates the node conditions based on the configured `--node-status-update-frequency`, which defaults to `10s`. #### Node condition oscillation @@ -197,17 +197,17 @@ condition to a different state. The transition period has a default value of `5m The kubelet tries to reclaim node-level resources before it evicts end-user pods. When a `DiskPressure` node condition is reported, the kubelet reclaims node-level -resources based on the filesystems on the node. +resources based on the filesystems on the node. #### With `imagefs` If the node has a dedicated `imagefs` filesystem for container runtimes to use, the kubelet does the following: - * If the `nodefs` filesystem meets the eviction thresholds, the kubelet garbage collects - dead pods and containers. - * If the `imagefs` filesystem meets the eviction thresholds, the kubelet - deletes all unused images. +- If the `nodefs` filesystem meets the eviction thresholds, the kubelet garbage collects + dead pods and containers. +- If the `imagefs` filesystem meets the eviction thresholds, the kubelet + deletes all unused images. #### Without `imagefs` @@ -220,7 +220,7 @@ the kubelet frees up disk space in the following order: ### Pod selection for kubelet eviction If the kubelet's attempts to reclaim node-level resources don't bring the eviction -signal below the threshold, the kubelet begins to evict end-user pods. +signal below the threshold, the kubelet begins to evict end-user pods. The kubelet uses the following parameters to determine the pod eviction order: @@ -238,7 +238,7 @@ As a result, kubelet ranks and evicts pods in the following order: {{}} The kubelet does not use the pod's QoS class to determine the eviction order. -You can use the QoS class to estimate the most likely pod eviction order when +You can use the QoS class to estimate the most likely pod eviction order when reclaiming resources like memory. QoS does not apply to EphemeralStorage requests, so the above scenario will not apply if the node is, for example, under `DiskPressure`. {{}} @@ -246,7 +246,7 @@ so the above scenario will not apply if the node is, for example, under `DiskPre `Guaranteed` pods are guaranteed only when requests and limits are specified for all the containers and they are equal. These pods will never be evicted because of another pod's resource consumption. If a system daemon (such as `kubelet` -and `journald`) is consuming more resources than were reserved via +and `journald`) is consuming more resources than were reserved via `system-reserved` or `kube-reserved` allocations, and the node only has `Guaranteed` or `Burstable` pods using less resources than requests left on it, then the kubelet must choose to evict one of these pods to preserve node stability @@ -277,14 +277,14 @@ disk usage (`local volumes + logs & writable layer of all containers`) In some cases, pod eviction only reclaims a small amount of the starved resource. This can lead to the kubelet repeatedly hitting the configured eviction thresholds -and triggering multiple evictions. +and triggering multiple evictions. You can use the `--eviction-minimum-reclaim` flag or a [kubelet config file](/docs/tasks/administer-cluster/kubelet-config-file/) to configure a minimum reclaim amount for each resource. When the kubelet notices that a resource is starved, it continues to reclaim that resource until it -reclaims the quantity you specify. +reclaims the quantity you specify. -For example, the following configuration sets minimum reclaim amounts: +For example, the following configuration sets minimum reclaim amounts: ```yaml apiVersion: kubelet.config.k8s.io/v1beta1 @@ -302,10 +302,10 @@ evictionMinimumReclaim: In this example, if the `nodefs.available` signal meets the eviction threshold, the kubelet reclaims the resource until the signal reaches the threshold of `1Gi`, and then continues to reclaim the minimum amount of `500Mi` it until the signal -reaches `1.5Gi`. +reaches `1.5Gi`. Similarly, the kubelet reclaims the `imagefs` resource until the `imagefs.available` -signal reaches `102Gi`. +signal reaches `102Gi`. The default `eviction-minimum-reclaim` is `0` for all resources. @@ -336,7 +336,7 @@ for each container. It then kills the container with the highest score. This means that containers in low QoS pods that consume a large amount of memory relative to their scheduling requests are killed first. -Unlike pod eviction, if a container is OOM killed, the `kubelet` can restart it +Unlike pod eviction, if a container is OOM killed, the `kubelet` can restart it based on its `RestartPolicy`. ### Best practices {#node-pressure-eviction-good-practices} @@ -351,9 +351,9 @@ immediately induce memory pressure. Consider the following scenario: -* Node memory capacity: `10Gi` -* Operator wants to reserve 10% of memory capacity for system daemons (kernel, `kubelet`, etc.) -* Operator wants to evict Pods at 95% memory utilization to reduce incidence of system OOM. +- Node memory capacity: `10Gi` +- Operator wants to reserve 10% of memory capacity for system daemons (kernel, `kubelet`, etc.) +- Operator wants to evict Pods at 95% memory utilization to reduce incidence of system OOM. For this to work, the kubelet is launched as follows: @@ -363,18 +363,18 @@ For this to work, the kubelet is launched as follows: ``` In this configuration, the `--system-reserved` flag reserves `1.5Gi` of memory -for the system, which is `10% of the total memory + the eviction threshold amount`. +for the system, which is `10% of the total memory + the eviction threshold amount`. The node can reach the eviction threshold if a pod is using more than its request, or if the system is using more than `1Gi` of memory, which makes the `memory.available` -signal fall below `500Mi` and triggers the threshold. +signal fall below `500Mi` and triggers the threshold. #### DaemonSet Pod Priority is a major factor in making eviction decisions. If you do not want the kubelet to evict pods that belong to a `DaemonSet`, give those pods a high enough `priorityClass` in the pod spec. You can also use a lower `priorityClass` -or the default to only allow `DaemonSet` pods to run when there are enough +or the default to only allow `DaemonSet` pods to run when there are enough resources. ### Known issues @@ -386,7 +386,7 @@ The following sections describe known issues related to out of resource handling By default, the kubelet polls `cAdvisor` to collect memory usage stats at a regular interval. If memory usage increases within that window rapidly, the kubelet may not observe `MemoryPressure` fast enough, and the `OOMKiller` -will still be invoked. +will still be invoked. You can use the `--kernel-memcg-notification` flag to enable the `memcg` notification API on the kubelet to get notified immediately when a threshold @@ -394,29 +394,29 @@ is crossed. If you are not trying to achieve extreme utilization, but a sensible measure of overcommit, a viable workaround for this issue is to use the `--kube-reserved` -and `--system-reserved` flags to allocate memory for the system. +and `--system-reserved` flags to allocate memory for the system. #### active_file memory is not considered as available memory -On Linux, the kernel tracks the number of bytes of file-backed memory on active +On Linux, the kernel tracks the number of bytes of file-backed memory on active LRU list as the `active_file` statistic. The kubelet treats `active_file` memory -areas as not reclaimable. For workloads that make intensive use of block-backed -local storage, including ephemeral local storage, kernel-level caches of file -and block data means that many recently accessed cache pages are likely to be -counted as `active_file`. If enough of these kernel block buffers are on the -active LRU list, the kubelet is liable to observe this as high resource use and +areas as not reclaimable. For workloads that make intensive use of block-backed +local storage, including ephemeral local storage, kernel-level caches of file +and block data means that many recently accessed cache pages are likely to be +counted as `active_file`. If enough of these kernel block buffers are on the +active LRU list, the kubelet is liable to observe this as high resource use and taint the node as experiencing memory pressure - triggering pod eviction. For more details, see [https://github.com/kubernetes/kubernetes/issues/43916](https://github.com/kubernetes/kubernetes/issues/43916) You can work around that behavior by setting the memory limit and memory request -the same for containers likely to perform intensive I/O activity. You will need +the same for containers likely to perform intensive I/O activity. You will need to estimate or measure an optimal memory limit value for that container. ## {{% heading "whatsnext" %}} -* Learn about [API-initiated Eviction](/docs/concepts/scheduling-eviction/api-eviction/) -* Learn about [Pod Priority and Preemption](/docs/concepts/scheduling-eviction/pod-priority-preemption/) -* Learn about [PodDisruptionBudgets](/docs/tasks/run-application/configure-pdb/) -* Learn about [Quality of Service](/docs/tasks/configure-pod-container/quality-service-pod/) (QoS) -* Check out the [Eviction API](/docs/reference/generated/kubernetes-api/{{}}/#create-eviction-pod-v1-core) +- Learn about [API-initiated Eviction](/docs/concepts/scheduling-eviction/api-eviction/) +- Learn about [Pod Priority and Preemption](/docs/concepts/scheduling-eviction/pod-priority-preemption/) +- Learn about [PodDisruptionBudgets](/docs/tasks/run-application/configure-pdb/) +- Learn about [Quality of Service](/docs/tasks/configure-pod-container/quality-service-pod/) (QoS) +- Check out the [Eviction API](/docs/reference/generated/kubernetes-api/{{}}/#create-eviction-pod-v1-core) From 2859d75e750abc3fd9845541ae89987f432fec4f Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Sun, 5 Feb 2023 14:32:57 +0800 Subject: [PATCH 076/279] [zh] Resync pod-overhead.md --- .../concepts/scheduling-eviction/pod-overhead.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/content/zh-cn/docs/concepts/scheduling-eviction/pod-overhead.md b/content/zh-cn/docs/concepts/scheduling-eviction/pod-overhead.md index fea91a658f8..75221b3d365 100644 --- a/content/zh-cn/docs/concepts/scheduling-eviction/pod-overhead.md +++ b/content/zh-cn/docs/concepts/scheduling-eviction/pod-overhead.md @@ -44,12 +44,12 @@ time according to the overhead associated with the Pod's 相关联的开销在[准入](/zh-cn/docs/reference/access-authn-authz/extensible-admission-controllers/#what-are-admission-webhooks)时设置的。 -如果启用了 Pod Overhead,在调度 Pod 时,除了考虑容器资源请求的总和外,还要考虑 Pod 开销。 +在调度 Pod 时,除了考虑容器资源请求的总和外,还要考虑 Pod 开销。 类似地,kubelet 将在确定 Pod cgroups 的大小和执行 Pod 驱逐排序时也会考虑 Pod 开销。 -在 RuntimeClass 准入控制器进行修改后,你可以查看更新后的 PodSpec: +在 RuntimeClass 准入控制器进行修改后,你可以查看更新后的 Pod 开销值: ```bash kubectl get pod test-pod -o jsonpath='{.spec.overhead}' ``` From afb5ef269ae67db735f32273cc7ccd8d138fcf3a Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Sun, 5 Feb 2023 14:43:36 +0800 Subject: [PATCH 077/279] [zh] Resync resource-bin-package.md --- .../resource-bin-packing.md | 47 +++++++++---------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/content/zh-cn/docs/concepts/scheduling-eviction/resource-bin-packing.md b/content/zh-cn/docs/concepts/scheduling-eviction/resource-bin-packing.md index 2b9908a9172..35e7a2b52a1 100644 --- a/content/zh-cn/docs/concepts/scheduling-eviction/resource-bin-packing.md +++ b/content/zh-cn/docs/concepts/scheduling-eviction/resource-bin-packing.md @@ -1,5 +1,5 @@ --- -title: 扩展资源的资源装箱 +title: 资源装箱 content_type: concept weight: 80 --- @@ -9,7 +9,7 @@ reviewers: - bsalamat - k82cn - ahg-g -title: Resource Bin Packing for Extended Resources +title: Resource Bin Packing content_type: concept weight: 80 --- @@ -18,7 +18,7 @@ weight: 80 在 kube-scheduler 的[调度插件](/zh-cn/docs/reference/scheduling/config/#scheduling-plugins) @@ -65,7 +65,7 @@ profiles: ``` 要进一步了解其它参数及其默认配置,请参阅 @@ -83,10 +83,10 @@ configured function of the allocated resources. The behavior of the `RequestedTo the `NodeResourcesFit` score function can be controlled by the [scoringStrategy](/docs/reference/config-api/kube-scheduler-config.v1beta3/#kubescheduler-config-k8s-io-v1beta3-ScoringStrategy) field. Within the `scoringStrategy` field, you can configure two parameters: `requestedToCapacityRatio` and -`resources`. The `shape` in `requestedToCapacityRatio` -parameter allows the user to tune the function as least requested or most -requested based on `utilization` and `score` values. The `resources` parameter -consists of `name` of the resource to be considered during scoring and `weight` +`resources`. The `shape` in the `requestedToCapacityRatio` +parameter allows the user to tune the function as least requested or most +requested based on `utilization` and `score` values. The `resources` parameter +consists of `name` of the resource to be considered during scoring and `weight` specify the weight of each resource. --> ## 使用 RequestedToCapacityRatio 策略来启用资源装箱 {#enabling-bin-packing-using-requestedtocapacityratio} @@ -133,15 +133,15 @@ profiles: ``` 使用 kube-scheduler 标志 `--config=/path/to/config/file` 引用 `KubeSchedulerConfiguration` 文件,可以将配置传递给调度器。 要进一步了解其它参数及其默认配置,可以参阅 @@ -159,10 +159,10 @@ To learn more about other parameters and their default configuration, see the AP ```yaml shape: - - utilization: 0 - score: 0 - - utilization: 100 - score: 10 + - utilization: 0 + score: 0 + - utilization: 100 + score: 10 ``` -`resources` 是一个可选参数,默认情况下设置为: +`resources` 是一个可选参数,默认值为: -``` yaml +```yaml resources: - name: cpu weight: 1 @@ -262,8 +262,8 @@ Node 1 spec: ``` 可用: - intel.com/foo : 4 - memory : 1 GB + intel.com/foo: 4 + memory: 1 GB cpu: 8 已用: @@ -282,8 +282,8 @@ intel.com/foo = resourceScoringFunction((2+1),4) = (100 - ((4-3)*100/4) = (100 - 25) = 75 # requested + used = 75% * available - = rawScoringFunction(75) - = 7 # floor(75/10) + = rawScoringFunction(75) + = 7 # floor(75/10) memory = resourceScoringFunction((256+256),1024) = (100 -((1024-512)*100/1024)) @@ -355,4 +355,3 @@ NodeScore = (5 * 5) + (7 * 1) + (10 * 3) / (5 + 1 + 3) --> - 继续阅读[调度器框架](/zh-cn/docs/concepts/scheduling-eviction/scheduling-framework/) - 继续阅读[调度器配置](/zh-cn/docs/reference/scheduling/config/) - From 87e8d214e1580b0f3998964ff7861980621ac3ac Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Sun, 5 Feb 2023 14:49:26 +0800 Subject: [PATCH 078/279] Tweak page style for resource-bin-packing.md --- .../resource-bin-packing.md | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/content/en/docs/concepts/scheduling-eviction/resource-bin-packing.md b/content/en/docs/concepts/scheduling-eviction/resource-bin-packing.md index 142a9de2932..8a4f36ce3fb 100644 --- a/content/en/docs/concepts/scheduling-eviction/resource-bin-packing.md +++ b/content/en/docs/concepts/scheduling-eviction/resource-bin-packing.md @@ -10,7 +10,7 @@ weight: 80 -In the [scheduling-plugin](/docs/reference/scheduling/config/#scheduling-plugins) `NodeResourcesFit` of kube-scheduler, there are two +In the [scheduling-plugin](/docs/reference/scheduling/config/#scheduling-plugins) `NodeResourcesFit` of kube-scheduler, there are two scoring strategies that support the bin packing of resources: `MostAllocated` and `RequestedToCapacityRatio`. @@ -42,7 +42,7 @@ profiles: name: NodeResourcesFit ``` -To learn more about other parameters and their default configuration, see the API documentation for +To learn more about other parameters and their default configuration, see the API documentation for [`NodeResourcesFitArgs`](/docs/reference/config-api/kube-scheduler-config.v1beta3/#kubescheduler-config-k8s-io-v1beta3-NodeResourcesFitArgs). ## Enabling bin packing using RequestedToCapacityRatio @@ -55,10 +55,10 @@ configured function of the allocated resources. The behavior of the `RequestedTo the `NodeResourcesFit` score function can be controlled by the [scoringStrategy](/docs/reference/config-api/kube-scheduler-config.v1beta3/#kubescheduler-config-k8s-io-v1beta3-ScoringStrategy) field. Within the `scoringStrategy` field, you can configure two parameters: `requestedToCapacityRatio` and -`resources`. The `shape` in the `requestedToCapacityRatio` -parameter allows the user to tune the function as least requested or most -requested based on `utilization` and `score` values. The `resources` parameter -consists of `name` of the resource to be considered during scoring and `weight` +`resources`. The `shape` in the `requestedToCapacityRatio` +parameter allows the user to tune the function as least requested or most +requested based on `utilization` and `score` values. The `resources` parameter +consists of `name` of the resource to be considered during scoring and `weight` specify the weight of each resource. Below is an example configuration that sets @@ -87,11 +87,11 @@ profiles: name: NodeResourcesFit ``` -Referencing the `KubeSchedulerConfiguration` file with the kube-scheduler -flag `--config=/path/to/config/file` will pass the configuration to the +Referencing the `KubeSchedulerConfiguration` file with the kube-scheduler +flag `--config=/path/to/config/file` will pass the configuration to the scheduler. -To learn more about other parameters and their default configuration, see the API documentation for +To learn more about other parameters and their default configuration, see the API documentation for [`NodeResourcesFitArgs`](/docs/reference/config-api/kube-scheduler-config.v1beta3/#kubescheduler-config-k8s-io-v1beta3-NodeResourcesFitArgs). ### Tuning the score function @@ -100,10 +100,10 @@ To learn more about other parameters and their default configuration, see the AP ```yaml shape: - - utilization: 0 - score: 0 - - utilization: 100 - score: 10 + - utilization: 0 + score: 0 + - utilization: 100 + score: 10 ``` The above arguments give the node a `score` of 0 if `utilization` is 0% and 10 for @@ -120,7 +120,7 @@ shape: `resources` is an optional parameter which defaults to: -``` yaml +```yaml resources: - name: cpu weight: 1 @@ -128,7 +128,7 @@ resources: weight: 1 ``` -It can be used to add extended resources as follows: +It can be used to add extended resources as follows: ```yaml resources: @@ -188,8 +188,8 @@ intel.com/foo = resourceScoringFunction((2+1),4) = (100 - ((4-3)*100/4) = (100 - 25) = 75 # requested + used = 75% * available - = rawScoringFunction(75) - = 7 # floor(75/10) + = rawScoringFunction(75) + = 7 # floor(75/10) memory = resourceScoringFunction((256+256),1024) = (100 -((1024-512)*100/1024)) @@ -251,4 +251,3 @@ NodeScore = (5 * 5) + (7 * 1) + (10 * 3) / (5 + 1 + 3) - Read more about the [scheduling framework](/docs/concepts/scheduling-eviction/scheduling-framework/) - Read more about [scheduler configuration](/docs/reference/scheduling/config/) - From f7ad6d685ea4565474f0a146c48a74f28ecd34fe Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Sun, 5 Feb 2023 15:33:00 +0800 Subject: [PATCH 079/279] [zh] Resync scheduler-perf-tuning.md --- .../scheduler-perf-tuning.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/content/zh-cn/docs/concepts/scheduling-eviction/scheduler-perf-tuning.md b/content/zh-cn/docs/concepts/scheduling-eviction/scheduler-perf-tuning.md index cb7a7fe8c8c..01574c7e077 100644 --- a/content/zh-cn/docs/concepts/scheduling-eviction/scheduler-perf-tuning.md +++ b/content/zh-cn/docs/concepts/scheduling-eviction/scheduler-perf-tuning.md @@ -15,7 +15,7 @@ weight: 70 -{{< feature-state for_k8s_version="1.14" state="beta" >}} +{{< feature-state for_k8s_version="v1.14" state="beta" >}} 要修改这个值,先编辑 [kube-scheduler 的配置文件](/zh-cn/docs/reference/config-api/kube-scheduler-config.v1beta3/) 然后重启调度器。 @@ -184,9 +184,9 @@ percentageOfNodesToScore: 50 ``` -### 调节 percentageOfNodesToScore 参数 +## 调节 percentageOfNodesToScore 参数 -### 调度器做调度选择的时候如何覆盖所有的 Node {#how-the-scheduler-iterates-over-nodes} +## 调度器做调度选择的时候如何覆盖所有的 Node {#how-the-scheduler-iterates-over-nodes} + * 参见 [kube-scheduler 配置参考 (v1beta3)](/zh-cn/docs/reference/config-api/kube-scheduler-config.v1beta3/) From b902cff2b1a2bf03852fbac6f36df33ef5c60f6e Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Sun, 5 Feb 2023 14:11:42 +0800 Subject: [PATCH 080/279] [zh] Cleanup node-pressure-eviction.md --- .../node-pressure-eviction.md | 244 +++++++++--------- 1 file changed, 123 insertions(+), 121 deletions(-) diff --git a/content/zh-cn/docs/concepts/scheduling-eviction/node-pressure-eviction.md b/content/zh-cn/docs/concepts/scheduling-eviction/node-pressure-eviction.md index 1ff97d3b0ae..401ca43d543 100644 --- a/content/zh-cn/docs/concepts/scheduling-eviction/node-pressure-eviction.md +++ b/content/zh-cn/docs/concepts/scheduling-eviction/node-pressure-eviction.md @@ -11,17 +11,17 @@ weight: 100 {{}}
    - {{}} @@ -33,7 +33,7 @@ kubelet 可以主动地使节点上一个或者多个 Pod 失效,以回收资 节点压力驱逐不同于 [API 发起的驱逐](/zh-cn/docs/concepts/scheduling-eviction/api-eviction/)。 - kubelet 并不理会你配置的 `PodDisruptionBudget` 或者是 Pod 的 `terminationGracePeriodSeconds`。 @@ -65,26 +65,26 @@ kubelet 在终止最终用户 Pod 之前会尝试[回收节点级资源](#reclai 例如,它会在磁盘资源不足时删除未使用的容器镜像。 {{
    }} - kubelet 使用各种参数来做出驱逐决定,如下所示: - * 驱逐信号 - * 驱逐条件 - * 监控间隔 +- 驱逐信号 +- 驱逐条件 +- 监控间隔 - @@ -105,11 +105,11 @@ kubelet 使用以下驱逐信号: | `imagefs.inodesFree` | `imagefs.inodesFree` := `node.stats.runtime.imagefs.inodesFree` | | `pid.available` | `pid.available` := `node.stats.rlimit.maxpid` - `node.stats.rlimit.curproc` | - 在上表中,`描述`列显示了 kubelet 如何获取信号的值。每个信号支持百分比值或者是字面值。 kubelet 计算相对于与信号有关的总量的百分比值。 @@ -117,14 +117,14 @@ kubelet 计算相对于与信号有关的总量的百分比值。 `memory.available` 的值来自 cgroupfs,而不是像 `free -m` 这样的工具。 这很重要,因为 `free -m` 在容器中不起作用,如果用户使用 @@ -139,12 +139,12 @@ kubelet 在其计算中排除了 inactive_file(即非活动 LRU 列表上基 The kubelet supports the following filesystem partitions: 1. `nodefs`: The node's main filesystem, used for local disk volumes, emptyDir, - log storage, and more. For example, `nodefs` contains `/var/lib/kubelet/`. + log storage, and more. For example, `nodefs` contains `/var/lib/kubelet/`. 1. `imagefs`: An optional filesystem that container runtimes use to store container images and container writable layers. Kubelet auto-discovers these filesystems and ignores other filesystems. Kubelet -does not support other configurations. +does not support other configurations. --> kubelet 支持以下文件系统分区: @@ -175,7 +175,7 @@ Some kubelet garbage collection features are deprecated in favor of eviction: | `--maximum-dead-containers-per-container` | - | 一旦旧的日志存储在容器的上下文之外就会被弃用 | | `--minimum-container-ttl-duration` | - | 一旦旧的日志存储在容器的上下文之外就会被弃用 | - @@ -208,7 +208,7 @@ For example, if a node has `10Gi` of total memory and you want trigger eviction the available memory falls below `1Gi`, you can define the eviction threshold as either `memory.available<10%` or `memory.available<1Gi`. You cannot use both. -You can configure soft and hard eviction thresholds. +You can configure soft and hard eviction thresholds. --> 例如,如果一个节点的总内存为 10Gi 并且你希望在可用内存低于 1Gi 时触发驱逐, 则可以将驱逐条件定义为 `memory.available<10%` 或 `memory.available< 1G`。 @@ -216,13 +216,13 @@ You can configure soft and hard eviction thresholds. 你可以配置软和硬驱逐条件。 - #### 软驱逐条件 {#soft-eviction-thresholds} @@ -230,10 +230,10 @@ specified grace period. 在超过宽限期之前,kubelet 不会驱逐 Pod。 如果没有指定的宽限期,kubelet 会在启动时返回错误。 - 你可以使用以下标志来配置软驱逐条件: @@ -260,15 +260,15 @@ You can use the following flags to configure soft eviction thresholds: 如 `memory.available=1m30s`,定义软驱逐条件在触发 Pod 驱逐之前必须保持多长时间。 * `eviction-max-pod-grace-period`:在满足软驱逐条件而终止 Pod 时使用的最大允许宽限期(以秒为单位)。 - #### 硬驱逐条件 {#hard-eviction-thresholds} @@ -278,13 +278,13 @@ kubelet 会立即杀死 pod,而不会正常终止以回收紧缺的资源。 你可以使用 `eviction-hard` 标志来配置一组硬驱逐条件, 例如 `memory.available<1Gi`。 - kubelet 具有以下默认硬驱逐条件: @@ -294,17 +294,17 @@ kubelet 具有以下默认硬驱逐条件: * `nodefs.inodesFree<5%`(Linux 节点) 只有在没有更改任何参数的情况下,硬驱逐阈值才会被设置成这些默认值。 如果你更改了任何参数的值,则其他参数的取值不会继承其默认值设置,而将被设置为零。 为了提供自定义值,你应该分别设置所有阈值。 - ### 节点条件 {#node-conditions} kubelet 报告节点状况以反映节点处于压力之下,因为满足硬或软驱逐条件,与配置的宽限期无关。 - kubelet 根据下表将驱逐信号映射为节点状况: @@ -347,7 +347,7 @@ kubelet 根据下表将驱逐信号映射为节点状况: kubelet 根据配置的 `--node-status-update-frequency` 更新节点条件,默认为 `10s`。 - ### 回收节点级资源 {#reclaim-node-resources} @@ -387,19 +387,19 @@ kubelet 在驱逐最终用户 Pod 之前会先尝试回收节点级资源。 If the node has a dedicated `imagefs` filesystem for container runtimes to use, the kubelet does the following: - * If the `nodefs` filesystem meets the eviction thresholds, the kubelet garbage collects - dead pods and containers. - * If the `imagefs` filesystem meets the eviction thresholds, the kubelet - deletes all unused images. +- If the `nodefs` filesystem meets the eviction thresholds, the kubelet garbage collects + dead pods and containers. +- If the `imagefs` filesystem meets the eviction thresholds, the kubelet + deletes all unused images. --> #### 有 `imagefs` 如果节点有一个专用的 `imagefs` 文件系统供容器运行时使用,kubelet 会执行以下操作: - * 如果 `nodefs` 文件系统满足驱逐条件,kubelet 垃圾收集死亡 Pod 和容器。 - * 如果 `imagefs` 文件系统满足驱逐条件,kubelet 将删除所有未使用的镜像。 +- 如果 `nodefs` 文件系统满足驱逐条件,kubelet 垃圾收集死亡 Pod 和容器。 +- 如果 `imagefs` 文件系统满足驱逐条件,kubelet 将删除所有未使用的镜像。 - @@ -467,11 +467,11 @@ QoS 不适用于临时存储(EphemeralStorage)请求, 因此如果节点在 `DiskPressure` 下,则上述场景将不适用。 {{}} - + #### 有 `imagefs` 如果 `nodefs` 触发驱逐, @@ -525,25 +526,26 @@ kubelet 会根据 `nodefs` 使用情况(`本地卷 + 所有容器的日志`) 如果 `nodefs` 触发驱逐, kubelet 会根据磁盘总用量(`本地卷 + 日志和所有容器的可写层`)对 Pod 进行排序。 - -### 最小驱逐回收 {#minimum-eviction-reclaim} + +### 最小驱逐回收 {#minimum-eviction-reclaim} 在某些情况下,驱逐 Pod 只会回收少量的紧俏资源。 这可能导致 kubelet 反复达到配置的驱逐条件并触发多次驱逐。 - 你可以使用 `--eviction-minimum-reclaim` 标志或 [kubelet 配置文件](/zh-cn/docs/tasks/administer-cluster/kubelet-config-file/) @@ -565,14 +567,14 @@ evictionMinimumReclaim: imagefs.available: "2Gi" ``` - @@ -584,7 +586,7 @@ kubelet 会回收资源,直到信号达到 `1Gi` 的条件, 对于所有资源,默认的 `eviction-minimum-reclaim` 为 `0`。 - 如果 kubelet 在节点遇到 OOM 之前无法回收内存, @@ -638,7 +640,7 @@ based on its `RestartPolicy`. 与 Pod 驱逐不同,如果容器被 OOM 杀死, `kubelet` 可以根据其 `RestartPolicy` 重新启动它。 - 考虑以下场景: @@ -672,7 +674,7 @@ Consider the following scenario: * 操作员希望为系统守护进程(内核、`kubelet` 等)保留 10% 的内存容量 * 操作员希望在节点内存利用率达到 95% 以上时驱逐 Pod,以减少系统 OOM 的概率。 - 为此,kubelet 启动设置如下: @@ -682,13 +684,13 @@ For this to work, the kubelet is launched as follows: --system-reserved=memory=1.5Gi ``` - 在此配置中,`--system-reserved` 标志为系统预留了 `1.5Gi` 的内存, 即 `总内存的 10% + 驱逐条件量`。 @@ -696,13 +698,13 @@ signal fall below `500Mi` and triggers the threshold. 如果 Pod 使用的内存超过其请求值或者系统使用的内存超过 `1Gi`, 则节点可以达到驱逐条件,这使得 `memory.available` 信号低于 `500Mi` 并触发条件。 - ### DaemonSet @@ -713,7 +715,7 @@ Pod 优先级是做出驱逐决定的主要因素。 你还可以使用优先级较低的 `priorityClass` 或默认配置, 仅在有足够资源时才运行 `DaemonSet` Pod。 - #### kubelet 可能不会立即观察到内存压力 @@ -736,14 +738,14 @@ will still be invoked. 如果该轮询时间窗口内内存使用量迅速增加,kubelet 可能无法足够快地观察到 `MemoryPressure`, 但是 `OOMKiller` 仍将被调用。 - 你可以使用 `--kernel-memcg-notification` 标志在 kubelet 上启用 `memcg` 通知 API,以便在超过条件时立即收到通知。 @@ -751,16 +753,16 @@ and `--system-reserved` flags to allocate memory for the system. 如果你不是追求极端利用率,而是要采取合理的过量使用措施, 则解决此问题的可行方法是使用 `--kube-reserved` 和 `--system-reserved` 标志为系统分配内存。 - #### active_file 内存未被视为可用内存 @@ -772,11 +774,11 @@ kubelet 将 `active_file` 内存区域视为不可回收。 如果这些内核块缓冲区中在活动 LRU 列表上有足够多, kubelet 很容易将其视为资源用量过量并为节点设置内存压力污点,从而触发 Pod 驱逐。 - 更多细节请参见 [https://github.com/kubernetes/kubernetes/issues/43916](https://github.com/kubernetes/kubernetes/issues/43916)。 @@ -786,12 +788,12 @@ to estimate or measure an optimal memory limit value for that container. ## {{% heading "whatsnext" %}} - * 了解 [API 发起的驱逐](/zh-cn/docs/concepts/scheduling-eviction/api-eviction/) * 了解 [Pod 优先级和抢占](/zh-cn/docs/concepts/scheduling-eviction/pod-priority-preemption/) From edcaac546418436242952c5f835f540906504c05 Mon Sep 17 00:00:00 2001 From: windsonsea Date: Sun, 5 Feb 2023 11:22:42 +0800 Subject: [PATCH 081/279] [zh] sync flow-control.md --- .../cluster-administration/flow-control.md | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/content/zh-cn/docs/concepts/cluster-administration/flow-control.md b/content/zh-cn/docs/concepts/cluster-administration/flow-control.md index c713975625e..aa0c1f0baef 100644 --- a/content/zh-cn/docs/concepts/cluster-administration/flow-control.md +++ b/content/zh-cn/docs/concepts/cluster-administration/flow-control.md @@ -1338,6 +1338,56 @@ serves the following additional paths at its HTTP[S] ports. 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, ``` + +### 调试日志生成行为 {#debug-logging} + +在 `-v=3` 或更详细的情况下,服务器会为每个请求输出一行 httplog,它包括以下属性。 + + +- `apf_fs`:请求被分类到的 FlowSchema 的名称。 +- `apf_pl`:该 FlowSchema 的优先级名称。 +- `apf_iseats`:为请求执行的初始(正常)阶段确定的席位数量。 +- `apf_fseats`:为请求的最后执行阶段(考虑关联的 WATCH 通知)确定的席位数量。 +- `apf_additionalLatency`:请求执行最后阶段的持续时间。 + + +在更高级别的精细度下,将有日志行揭示 APF 如何处理请求的详细信息,主要用于调试目的。 + + +### 响应头 {#response-headers} + +APF 将以下两个头添加到每个 HTTP 响应消息中。 + +- `X-Kubernetes-PF-FlowSchema-UID` 保存相应请求被分类到的 FlowSchema 对象的 UID。 +- `X-Kubernetes-PF-PriorityLevel-UID` 保存与该 FlowSchema 关联的 PriorityLevelConfiguration 对象的 UID。 + ## {{% heading "whatsnext" %}} - **template** (}}">PodTemplateSpec), 必需 template 是用来描述 Pod 的对象,检测到副本不足时将创建所描述的 Pod。 经由 StatefulSet 创建的每个 Pod 都将满足这个模板,但与 StatefulSet 的其余 Pod 相比,每个 Pod 具有唯一的标识。 + 每个 Pod 将以 \-\ 格式命名。 + 例如,名为 "web" 且索引号为 "3" 的 StatefulSet 中的 Pod 将被命名为 "web-3"。 + ordinals 控制 StatefulSet 中副本索引的编号。 + 默认序数行为是将索引 "0" 设置给第一个副本,对于每个额外请求的副本,该索引加一。 + 使用 ordinals 字段需要启用 Alpha 级别的 StatefulSetStartOrdinal 特性门控。 + + + + **StatefulSetOrdinals 描述此 StatefulSet 中用于副本序数赋值的策略。** + + - **ordinals.start** (int32) + + + start 是代表第一个副本索引的数字。它可用于从替代索引(例如:从 1 开始索引)而非默认的从 0 索引来为副本设置编号, + 还可用于编排从一个 StatefulSet 到另一个 StatefulSet 的渐进式副本迁移动作。如果设置了此值,副本索引范围为 + [.spec.ordinals.start, .spec.ordinals.start + .spec.replicas)。如果不设置,则默认为 0。 + 副本索引范围为 [0, .spec.replicas)。 + ## StatefulSetStatus {#StatefulSetStatus} -一致且高度可用的键值存储,用作 Kubernetes 的所有集群数据的后台数据库。 +一致且高可用的键值存储,用作 Kubernetes 所有集群数据的后台数据库。 From fdd049b2f93f9c8cd81aee17769775bd5dc91c9d Mon Sep 17 00:00:00 2001 From: suning0 Date: Mon, 6 Feb 2023 01:51:15 +0800 Subject: [PATCH 086/279] [zh-cn]Update mutating-webhook-configuration-v1.md --- .../mutating-webhook-configuration-v1.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/content/zh-cn/docs/reference/kubernetes-api/extend-resources/mutating-webhook-configuration-v1.md b/content/zh-cn/docs/reference/kubernetes-api/extend-resources/mutating-webhook-configuration-v1.md index fc66eac31a2..016a9d18f6c 100644 --- a/content/zh-cn/docs/reference/kubernetes-api/extend-resources/mutating-webhook-configuration-v1.md +++ b/content/zh-cn/docs/reference/kubernetes-api/extend-resources/mutating-webhook-configuration-v1.md @@ -384,33 +384,45 @@ MutatingWebhookConfiguration 描述准入 Webhook 的配置,该 Webhook 可接 - **webhooks.rules.apiGroups** ([]string) + *Atomic: 将在合并期间被替换* + apiGroups 是资源所属的 API 组列表。`*` 是所有组。 如果存在 `*`,则列表的长度必须为 1。必需。 - **webhooks.rules.apiVersions** ([]string) + *Atomic: 将在合并期间被替换* + apiVersions 是资源所属的 API 版本列表。`*` 是所有版本。 如果存在 `*`,则列表的长度必须为 1。必需。 - **webhooks.rules.operations** ([]string) + *Atomic: 将在合并期间被替换* + operations 是准入 Webhook 所关心的操作 —— CREATE、UPDATE、DELETE、CONNECT 或用来指代所有已知操作以及将来可能添加的准入操作的 `*`。 如果存在 `*`,则列表的长度必须为 1。必需。 @@ -418,6 +430,8 @@ MutatingWebhookConfiguration 描述准入 Webhook 的配置,该 Webhook 可接 From 55eefca5e92f0f38c15652a59134d15b570c12d2 Mon Sep 17 00:00:00 2001 From: Arhell Date: Mon, 6 Feb 2023 00:22:37 +0200 Subject: [PATCH 088/279] [ja] updated nginx version to follow examples correctly --- content/ja/examples/application/deployment-scale.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ja/examples/application/deployment-scale.yaml b/content/ja/examples/application/deployment-scale.yaml index 68801c971de..d1ba11ee811 100644 --- a/content/ja/examples/application/deployment-scale.yaml +++ b/content/ja/examples/application/deployment-scale.yaml @@ -14,6 +14,6 @@ spec: spec: containers: - name: nginx - image: nginx:1.14.2 + image: nginx:1.16.1 ports: - containerPort: 80 From aa173996ea1a7685365d3594cace8bedc879f90c Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Sun, 5 Feb 2023 16:55:10 +0800 Subject: [PATCH 089/279] [zh] Resync scheduling-framework.md --- .../scheduling-framework.md | 126 +++++++++++------- 1 file changed, 78 insertions(+), 48 deletions(-) diff --git a/content/zh-cn/docs/concepts/scheduling-eviction/scheduling-framework.md b/content/zh-cn/docs/concepts/scheduling-eviction/scheduling-framework.md index 5c4f5c4a4cc..2641362e0af 100644 --- a/content/zh-cn/docs/concepts/scheduling-eviction/scheduling-framework.md +++ b/content/zh-cn/docs/concepts/scheduling-eviction/scheduling-framework.md @@ -16,7 +16,7 @@ weight: 60 -{{< feature-state for_k8s_version="1.19" state="stable" >}} +{{< feature-state for_k8s_version="v1.19" state="stable" >}} 这些插件用于对调度队列中的 Pod 进行排序。 -队列排序插件本质上提供 `less(Pod1, Pod2)` 函数。 +队列排序插件本质上提供 `Less(Pod1, Pod2)` 函数。 一次只能启动一个队列插件。 如果任何 NormalizeScore 插件返回错误,则调度阶段将终止。 +{{< note >}} -{{< note >}} 希望执行“预保留”工作的插件应该使用 NormalizeScore 扩展点。 {{< /note >}} - -### Reserve +### Reserve {#reserve} -Reserve 是一个信息性的扩展点。 -管理运行时状态的插件(也成为“有状态插件”)应该使用此扩展点,以便 -调度器在节点给指定 Pod 预留了资源时能够通知该插件。 -这是在调度器真正将 Pod 绑定到节点之前发生的,并且它存在是为了防止 -在调度器等待绑定成功时发生竞争情况。 +实现了 Reserve 扩展的插件,拥有两个方法,即 `Reserve` 和 `Unreserve`, +他们分别支持两个名为 Reserve 和 Unreserve 的信息处理性质的调度阶段。 +维护运行时状态的插件(又称 "有状态插件")应该使用这两个阶段, +以便在节点上的资源被保留和未保留给特定的 Pod 时得到调度器的通知。 + + +Reserve 阶段发生在调度器实际将一个 Pod 绑定到其指定节点之前。 +它的存在是为了防止在调度器等待绑定成功时发生竞争情况。 +每个 Reserve 插件的 `Reserve` 方法可能成功,也可能失败; +如果一个 `Reserve` 方法调用失败,后面的插件就不会被执行,Reserve 阶段被认为失败。 +如果所有插件的 `Reserve` 方法都成功了,Reserve 阶段就被认为是成功的, +剩下的调度周期和绑定周期就会被执行。 + + +如果 Reserve 阶段或后续阶段失败了,则触发 Unreserve 阶段。 +发生这种情况时,**所有** Reserve 插件的 `Unreserve` 方法将按照 +`Reserve` 方法调用的相反顺序执行。 +这个阶段的存在是为了清理与保留的 Pod 相关的状态。 + +{{< caution >}} + +Reserve 插件中 `Unreserve` 方法的实现必须是幂等的,并且不能失败。 +{{< /caution >}} 1. **拒绝** \ 如果任何 Permit 插件拒绝 Pod,则该 Pod 将被返回到调度队列。 - 这将触发[Unreserve](#unreserve) 插件。 + 这将触发 [Reserve 插件](#reserve)中的 Unreserve 阶段。 1. **等待**(带有超时) \ 如果一个 Permit 插件返回 “等待” 结果,则 Pod 将保持在一个内部的 “等待中” - 的 Pod 列表,同时该 Pod 的绑定周期启动时即直接阻塞直到得到 - [批准](#frameworkhandle)。如果超时发生,**等待** 变成 **拒绝**,并且 Pod - 将返回调度队列,从而触发 [Unreserve](#unreserve) 插件。 - + 的 Pod 列表,同时该 Pod 的绑定周期启动时即直接阻塞直到得到批准。 + 如果超时发生,**等待** 变成 **拒绝**,并且 Pod + 将返回调度队列,从而触发 [Reserve 插件](#reserve)中的 Unreserve 阶段。 +{{< note >}} -{{< note >}} 尽管任何插件可以访问 “等待中” 状态的 Pod 列表并批准它们 (查看 [`FrameworkHandle`](https://git.k8s.io/enhancements/keps/sig-scheduling/624-scheduling-framework#frameworkhandle))。 我们期望只有允许插件可以批准处于 “等待中” 状态的预留 Pod 的绑定。 @@ -338,7 +370,7 @@ is approved, it is sent to the [PreBind](#pre-bind) phase. {{< /note >}} ### PreBind {#pre-bind} @@ -352,10 +384,10 @@ target node before allowing the Pod to run there. 将其挂载到目标节点上。 -如果任何 PreBind 插件返回错误,则 Pod 将被 [拒绝](#unreserve) 并且 +如果任何 PreBind 插件返回错误,则 Pod 将被 [拒绝](#reserve) 并且 退回到调度队列中。 -# 插件配置 +## 插件配置 - 你可以使用 **拓扑分布约束(Topology Spread Constraints)** 来控制 {{< glossary_tooltip text="Pod" term_id="Pod" >}} 在集群内故障域之间的分布, @@ -31,7 +31,7 @@ or configure topology spread constraints for individual workloads. - ## 动机 {#motivation} @@ -55,7 +55,7 @@ enable your workloads to benefit on high availability and cluster utilization. 除了这个基本的用法之外,还有一些高级的使用案例,能够让你的工作负载受益于高可用性并提高集群利用率。 - @@ -119,7 +119,7 @@ refer to [scheduling](/docs/reference/kubernetes-api/workload-resources/pod-v1/# 参考的[调度](/zh-cn/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling)一节, 了解有关此字段的更多信息。 - - **maxSkew** 描述这些 Pod 可能被均匀分布的程度。你必须指定此字段且该数值必须大于零。 其语义将随着 `whenUnsatisfiable` 的值发生变化: - + - 如果你选择 `whenUnsatisfiable: DoNotSchedule`,则 `maxSkew` 定义目标拓扑中匹配 Pod 的数量与 **全局最小值**(符合条件的域中匹配的最小 Pod 数量,如果符合条件的域数量小于 MinDomains 则为零) 之间的最大允许差值。例如,如果你有 3 个可用区,分别有 2、2 和 1 个匹配的 Pod,则 `MaxSkew` 设为 1, @@ -161,7 +161,7 @@ your cluster. Those fields are: --> - **minDomains** 表示符合条件的域的最小数量。此字段是可选的。域是拓扑的一个特定实例。 符合条件的域是其节点与节点选择器匹配的域。 - + {{< note >}} - `nodeAffinityPolicy` 是 1.25 中新增的一个 Alpha 级别字段。 + `nodeAffinityPolicy` 是 1.26 中默认启用的一个 Beta 级别字段。 你可以通过禁用 `NodeInclusionPolicyInPodTopologySpread` [特性门控](/zh-cn/docs/reference/command-line-tools-reference/feature-gates/)来禁用此字段。 {{< /note >}} @@ -727,7 +727,7 @@ There are some implicit conventions worth noting here: - 只有与新来的 Pod 具有相同命名空间的 Pod 才能作为匹配候选者。 - 调度器会忽略没有任何 `topologySpreadConstraints[*].topologyKey` 的节点。这意味着: - + 1. 位于这些节点上的 Pod 不影响 `maxSkew` 计算,在上面的例子中,假设节点 `node1` 没有标签 "zone", 则 2 个 Pod 将被忽略,因此新来的 Pod 将被调度到可用区 `A` 中。 2. 新的 Pod 没有机会被调度到这类节点上。在上面的例子中, @@ -904,8 +904,8 @@ Pod 彼此的调度方式(更密集或更分散)。 `podAntiAffinity` : 驱逐 Pod。如果将此设为 `requiredDuringSchedulingIgnoredDuringExecution` 模式, - 则只有单个 Pod 可以调度到单个拓扑域;如果你选择 `preferredDuringSchedulingIgnoredDuringExecution`, - 则你将丢失强制执行此约束的能力。 +则只有单个 Pod 可以调度到单个拓扑域;如果你选择 `preferredDuringSchedulingIgnoredDuringExecution`, +则你将丢失强制执行此约束的能力。 -The Kubernetes API server is the main point of entry to a cluster for external parties -(users and services) interacting with it. +The Kubernetes API server is the main point of entry to a cluster for external parties +(users and services) interacting with it. As part of this role, the API server has several key built-in security controls, such as audit logging and {{< glossary_tooltip text="admission controllers" term_id="admission-controller" >}}. @@ -48,13 +48,13 @@ API server. However, the Pod still runs on the node. For more information, refer ### Mitigations {#static-pods-mitigations} - Only [enable the kubelet static Pod manifest functionality](/docs/tasks/configure-pod-container/static-pod/#static-pod-creation) - if required by the node. + if required by the node. - If a node uses the static Pod functionality, restrict filesystem access to the static Pod manifest directory - or URL to users who need the access. + or URL to users who need the access. - Restrict access to kubelet configuration parameters and files to prevent an attacker setting - a static Pod path or URL. + a static Pod path or URL. - Regularly audit and centrally report all access to directories or web storage locations that host - static Pod manifests and kubelet configuration files. + static Pod manifests and kubelet configuration files. ## The kubelet API {#kubelet-api} @@ -73,7 +73,7 @@ Direct access to the kubelet API is not subject to admission control and is not by Kubernetes audit logging. An attacker with direct access to this API may be able to bypass controls that detect or prevent certain actions. -The kubelet API can be configured to authenticate requests in a number of ways. +The kubelet API can be configured to authenticate requests in a number of ways. By default, the kubelet configuration allows anonymous access. Most Kubernetes providers change the default to use webhook and certificate authentication. This lets the control plane ensure that the caller is authorized to access the `nodes` API resource or sub-resources. @@ -86,7 +86,7 @@ The default anonymous access doesn't make this assertion with the control plane. such as by monitoring services. - Restrict access to the kubelet port. Only allow specified and trusted IP address ranges to access the port. -- Ensure that [kubelet authentication](/docs/reference/access-authn-authz/kubelet-authn-authz/#kubelet-authentication). +- Ensure that [kubelet authentication](/docs/reference/access-authn-authz/kubelet-authn-authz/#kubelet-authentication). is set to webhook or certificate mode. - Ensure that the unauthenticated "read-only" Kubelet port is not enabled on the cluster. @@ -108,7 +108,7 @@ cluster admin rights by accessing cluster secrets or modifying access rules. Eve elevating their Kubernetes RBAC privileges, an attacker who can modify etcd can retrieve any API object or create new workloads inside the cluster. -Many Kubernetes providers configure +Many Kubernetes providers configure etcd to use mutual TLS (both client and server verify each other's certificate for authentication). There is no widely accepted implementation of authorization for the etcd API, although the feature exists. Since there is no authorization model, any certificate @@ -124,10 +124,9 @@ that are only used for health checking can also grant full read and write access - Consider restricting access to the etcd port at a network level, to only allow access from specified and trusted IP address ranges. - ## Container runtime socket {#runtime-socket} -On each node in a Kubernetes cluster, access to interact with containers is controlled +On each node in a Kubernetes cluster, access to interact with containers is controlled by the container runtime (or runtimes, if you have configured more than one). Typically, the container runtime exposes a Unix socket that the kubelet can access. An attacker with access to this socket can launch new containers or interact with running containers. @@ -139,12 +138,12 @@ control plane components. ### Mitigations {#runtime-socket-mitigations} -- Ensure that you tightly control filesystem access to container runtime sockets. - When possible, restrict this access to the `root` user. +- Ensure that you tightly control filesystem access to container runtime sockets. + When possible, restrict this access to the `root` user. - Isolate the kubelet from other components running on the node, using - mechanisms such as Linux kernel namespaces. + mechanisms such as Linux kernel namespaces. - Ensure that you restrict or forbid the use of [`hostPath` mounts](/docs/concepts/storage/volumes/#hostpath) - that include the container runtime socket, either directly or by mounting a parent - directory. Also `hostPath` mounts must be set as read-only to mitigate risks - of attackers bypassing directory restrictions. + that include the container runtime socket, either directly or by mounting a parent + directory. Also `hostPath` mounts must be set as read-only to mitigate risks + of attackers bypassing directory restrictions. - Restrict user access to nodes, and especially restrict superuser access to nodes. From 54752d0ad1b647230fba92412a93a00a1c3a2396 Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Mon, 6 Feb 2023 10:02:31 +0800 Subject: [PATCH 092/279] [zh] Resync api-server-bypass-risks.md --- .../security/api-server-bypass-risks.md | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/content/zh-cn/docs/concepts/security/api-server-bypass-risks.md b/content/zh-cn/docs/concepts/security/api-server-bypass-risks.md index 4b5cafc678c..2d0bc8e9a38 100644 --- a/content/zh-cn/docs/concepts/security/api-server-bypass-risks.md +++ b/content/zh-cn/docs/concepts/security/api-server-bypass-risks.md @@ -23,7 +23,8 @@ Kubernetes API 服务器是外部(用户和服务)与集群交互的主要 作为此角色的一部分,API 服务器有几个关键的内置安全控制, @@ -91,13 +92,13 @@ API server. However, the Pod still runs on the node. For more information, refer - 仅在节点需要时[启用 kubelet 静态 Pod 清单功能](/zh-cn/docs/tasks/configure-pod-container/static-pod/#static-pod-creation)。 - 如果节点使用静态 Pod 功能,请将对静态 Pod 清单目录或 URL 的文件系统的访问权限限制为需要访问的用户。 @@ -268,13 +269,13 @@ control plane components. - 确保严格控制对容器运行时套接字所在的文件系统访问。如果可能,限制为仅 `root` 用户可访问。 From 4e9007f1918faae4bdb22d4175db8acf800dd6a7 Mon Sep 17 00:00:00 2001 From: Daniel Shebib Date: Wed, 25 Jan 2023 21:31:52 -0600 Subject: [PATCH 093/279] Add new page for QoS class Co-authored-by: Qiming Teng Co-authored-by: Tim Bannister --- .../manage-resources-containers.md | 1 + .../docs/concepts/workloads/pods/pod-qos.md | 117 ++++++++++++++++++ .../en/docs/reference/glossary/qos-class.md | 2 +- .../quality-service-pod.md | 3 +- 4 files changed, 120 insertions(+), 3 deletions(-) create mode 100644 content/en/docs/concepts/workloads/pods/pod-qos.md diff --git a/content/en/docs/concepts/configuration/manage-resources-containers.md b/content/en/docs/concepts/configuration/manage-resources-containers.md index 2e8981e4b95..e7bd7a485aa 100644 --- a/content/en/docs/concepts/configuration/manage-resources-containers.md +++ b/content/en/docs/concepts/configuration/manage-resources-containers.md @@ -807,4 +807,5 @@ memory limit (and possibly request) for that container. and its [resource requirements](/docs/reference/kubernetes-api/workload-resources/pod-v1/#resources) * Read about [project quotas](https://xfs.org/index.php/XFS_FAQ#Q:_Quota:_Do_quotas_work_on_XFS.3F) in XFS * Read more about the [kube-scheduler configuration reference (v1beta3)](/docs/reference/config-api/kube-scheduler-config.v1beta3/) +* Read more about [Quality of Service classes for Pods](/docs/concepts/workloads/pods/pod-quality/) diff --git a/content/en/docs/concepts/workloads/pods/pod-qos.md b/content/en/docs/concepts/workloads/pods/pod-qos.md new file mode 100644 index 00000000000..d4378c621c4 --- /dev/null +++ b/content/en/docs/concepts/workloads/pods/pod-qos.md @@ -0,0 +1,117 @@ +--- +title: Pod Quality of Service Classes +content_type: concept +weight: 30 +--- + + + +This page introduces _Quality of Service (QoS) classes_ in Kubernetes, and explains +how Kubernetes assigns a QoS class to each Pods as a consequence of the resource +constraints that you specify for the containers in that Pod. Kubernetes relies on this +classification to make decisions about which Pods to evict when there are not enough +available resources on a Node. + + + +## Quality of Service classes + +Kubernetes classifies the Pods that you run and allocates each Pod into a specific +_quality of service (QoS) class_. Kubernetes uses that classification to influence how different +pods are handled. Kubernetes does this classification based on the +[resource requests](/docs/concepts/configuration/manage-resources-containers/) +of the {{< glossary_tooltip text="Containers" term_id="container" >}} in that Pod, along with +how those requests relate to resource limits. +This is known as {{< glossary_tooltip text="Quality of Service" term_id="qos-class" >}} +(QoS) class. Kubernetes assigns every Pod a QoS class based on the resource requests +and limits of its component Containers. QoS classes are used by Kubernetes to decide +which Pods to evict from a Node experiencing +[Node Pressure](/docs/concepts/scheduling-eviction/node-pressure-eviction/). The possible +QoS classes are `Guaranteed`, `Burstable`, and `BestEffort`. When a Node runs out of resources, +Kubernetes will first evict `BestEffort` Pods running on that Node, followed by `Burstable` and +finally `Guaranteed` Pods. When this eviction is due to resource pressure, only Pods exceeding +resource requests are candidates for eviction. + +### Guaranteed + +Pods that are `Guaranteed` have the strictest resource limits and are least likely +to face eviction. They are guaranteed not to be killed until they exceed their limits +or there are no lower-priority Pods that can be preempted from the Node. They may +not acquire resources beyond their specified limits. These Pods can also make +use of exclusive CPUs using the +[`static`](/docs/tasks/administer-cluster/cpu-management-policies/#static-policy) CPU management policy. + +#### Criteria + +For a Pod to be given a QoS class of `Guaranteed`: + +* 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. + +### Burstable + +Pods that are `Burstable` have some lower-bound resource guarantees based on the request, but +do not require a specific limit. If a limit is not specified, it defaults to a +limit equivalent to the capacity of the Node, which allows the Pods to flexibly increase +their resources if resources are available. In the event of Pod eviction due to Node +resource pressure, these Pods are evicted only after all `BestEffort` Pods are evicted. +Because a `Burstable` Pod can include a Container that has no resource limits or requests, a Pod +that is `Burstable` can try to use any amount of node resources. + +#### Criteria + +A Pod is given a QoS class of `Burstable` if: + +* The Pod does not meet the criteria for QoS class `Guaranteed`. +* At least one Container in the Pod has a memory or CPU request or limit. + +### BestEffort + +Pods in the `BestEffort` QoS class can use node resources that aren't specifically assigned +to Pods in other QoS classes. For example, if you have a node with 16 CPU cores available to the +kubelet, and you assign assign 4 CPU cores to a `Guaranteed` Pod, then a Pod in the `BestEffort` +QoS class can try to use any amount of the remaining 12 CPU cores. + +The kubelet prefers to evict `BestEffort` Pods if the node comes under resource pressure. + +#### Criteria + +A Pod has a QoS class of `BestEffort` if it doesn't meet the criteria for either `Guaranteed` +or `Burstable`. In other words, a Pod is `BestEffort` only if none of the Containers in the Pod have a +memory limit or a memory request, and none of the Containers in the Pod have a +CPU limit or a CPU request. +Containers in a Pod can request other resources (not CPU or memory) and still be classified as +`BestEffort`. + +### Some behavior is independent of QoS class + +Certain behavior is independent of the QoS class assigned by Kubernetes. For example: + +* Any Container exceeding a resource limit will be killed and restarted by the kubelet without + affecting other Containers in that Pod. + +* If a Container exceeds its resource request and the node it runs on faces + resource pressure, the Pod it is in becomes a candidate for [eviction](/docs/concepts/scheduling-eviction/node-pressure-eviction/). + If this occurs, all Containers in the Pod will be terminated. Kubernetes may create a + replacement Pod, usually on a different node. + +* The resource request of a Pod is equal to the sum of the resource requests of + its component Containers, and the resource limit of a Pod is equal to the sum of + the resource limits of its component Containers. + +* The kube-scheduler does not consider QoS class when selecting which Pods to + [preempt](/docs/concepts/scheduling-eviction/pod-priority-preemption/#preemption). + Preemption can occur when a cluster does not have enough resources to run all the Pods + you defined. + +## {{% heading "whatsnext" %}} + +* Learn about [resource management for Pods and Containers](/docs/concepts/configuration/manage-resources-containers/). +* Learn about [Node-pressure eviction](/docs/concepts/scheduling-eviction/node-pressure-eviction/). +* Learn about [Pod priority and preemption](/docs/concepts/scheduling-eviction/pod-priority-preemption/). +* Learn about [Pod disruptions](/docs/concepts/workload/pods/disruptions/). +* Learn how to [assign memory resources to containers and pods](/docs/tasks/configure-pod-container/assign-memory-resource/). +* Learn how to [assign CPU resources to containers and pods](/docs/tasks/configure-pod-container/assign-cpu-resource/). +* Learn how to [configure Quality of Service for Pods](/docs/tasks/configure-pod-container/quality-service-pod/). diff --git a/content/en/docs/reference/glossary/qos-class.md b/content/en/docs/reference/glossary/qos-class.md index 692afd47fa2..a8a66bbf024 100644 --- a/content/en/docs/reference/glossary/qos-class.md +++ b/content/en/docs/reference/glossary/qos-class.md @@ -2,7 +2,7 @@ title: QoS Class id: qos-class date: 2019-04-15 -full_link: +full_link: /docs/concepts/workloads/pods/pod-quality/ short_description: > QoS Class (Quality of Service Class) provides a way for Kubernetes to classify pods within the cluster into several classes and make decisions about scheduling and eviction. diff --git a/content/en/docs/tasks/configure-pod-container/quality-service-pod.md b/content/en/docs/tasks/configure-pod-container/quality-service-pod.md index abf0cb05b18..40227171551 100644 --- a/content/en/docs/tasks/configure-pod-container/quality-service-pod.md +++ b/content/en/docs/tasks/configure-pod-container/quality-service-pod.md @@ -8,8 +8,7 @@ weight: 30 This page shows how to configure Pods so that they will be assigned particular -Quality of Service (QoS) classes. Kubernetes uses QoS classes to make decisions about -scheduling and evicting Pods. +Quality of Service (QoS) classes. Kubernetes uses QoS classes to make decisions about evicting Pods when Node resources are exceeded. From 04ce79a5fccf1820b25e9be9f6c701763841986f Mon Sep 17 00:00:00 2001 From: Daniel Shebib Date: Sun, 5 Feb 2023 20:11:20 -0600 Subject: [PATCH 094/279] add new page for qos class --- content/en/docs/concepts/workloads/pods/pod-qos.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/docs/concepts/workloads/pods/pod-qos.md b/content/en/docs/concepts/workloads/pods/pod-qos.md index d4378c621c4..0328df65ae0 100644 --- a/content/en/docs/concepts/workloads/pods/pod-qos.md +++ b/content/en/docs/concepts/workloads/pods/pod-qos.md @@ -85,7 +85,7 @@ CPU limit or a CPU request. Containers in a Pod can request other resources (not CPU or memory) and still be classified as `BestEffort`. -### Some behavior is independent of QoS class +## Some behavior is independent of QoS class {#class-independent-behavior} Certain behavior is independent of the QoS class assigned by Kubernetes. For example: From fea5aa7ca0e0df2fa7989be8688edee2e00c5382 Mon Sep 17 00:00:00 2001 From: k0rventen Date: Sun, 5 Feb 2023 21:49:07 +0100 Subject: [PATCH 095/279] french translation for pod pv task --- .../configure-persistent-volume-storage.md | 284 ++++++++++++++++++ 1 file changed, 284 insertions(+) create mode 100644 content/fr/docs/tasks/configure-pod-container/configure-persistent-volume-storage.md diff --git a/content/fr/docs/tasks/configure-pod-container/configure-persistent-volume-storage.md b/content/fr/docs/tasks/configure-pod-container/configure-persistent-volume-storage.md new file mode 100644 index 00000000000..ae96f6aaac7 --- /dev/null +++ b/content/fr/docs/tasks/configure-pod-container/configure-persistent-volume-storage.md @@ -0,0 +1,284 @@ +--- +title: Configurer un Pod pour utiliser un stockage de type PersistentVolume +content_type: task +weight: 60 +--- + + + +Cette page montre comment configurer un Pod afin qu'il utilise un {{< glossary_tooltip text="PersistentVolumeClaim" term_id="persistent-volume-claim" >}} comme stockage. + +Voici un resume des etapes: + +1. En tant qu'administrateur d'un cluster, vous creez un PersistentVolume qui pointe vers un systeme de stockage physique. Vous n'associez le volume avec aucun pod pour le moment. + +1. En tant que developer / utilisateur du cluster, vous creez un PersistentVolumeClaim qui sera automatiquement lie a un PersistentVolume adapte. + +1. Vous creez un Pod qui utilise le PersistentVolumeClaim cree precedemment comme stockage. + + +## {{% heading "prerequisites" %}} + + +* Vous devez avoir a disposition un cluster qui n'a qu'un seul noeud, et l'utilitaire en ligne de commande +{{< glossary_tooltip text="kubectl" term_id="kubectl" >}} doit etre configure pour communiquer avec votre cluster. Si vous n'avez pas deja de cluster a disposition, vous pouvez en creer un en utilisant [Minikube](https://minikube.sigs.k8s.io/docs/). + +* Vous pouvez vous familiariser avec la documentation des +[Persistent Volumes](/docs/concepts/storage/persistent-volumes/). + + + +## Creer un fichier index.html sur votre noeud + +Open a shell to the single Node in your cluster. How you open a shell depends +on how you set up your cluster. For example, if you are using Minikube, you +can open a shell to your Node by entering `minikube ssh`. + +In your shell on that Node, create a `/mnt/data` directory: + +```shell +# This assumes that your Node uses "sudo" to run commands +# as the superuser +sudo mkdir /mnt/data +``` + +Dans le dossier `/mnt/data`, creez un fichier `index.html`: +```shell +# This again assumes that your Node uses "sudo" to run commands +# as the superuser +sudo sh -c "echo 'Hello from Kubernetes storage' > /mnt/data/index.html" +``` + +{{< note >}} +Si votre noeud utilise un utilitaire d'acces privilegie autre que `sudo`, les commandes notees ici fonctionneront en remplacant `sudo` par le nom de l'utilitaire. +{{< /note >}} + +Testez que le fichier `index.html` existe: +```shell +cat /mnt/data/index.html +``` + +Le resultat de la commande doit etre: +``` +Hello from Kubernetes storage +``` + +Vous pouvez maintenant fermer l'acces shell a votre Noeud. + +## Creer un PersistentVolume + +In this exercise, you create a *hostPath* PersistentVolume. Kubernetes supports +hostPath for development and testing on a single-node cluster. A hostPath +PersistentVolume uses a file or directory on the Node to emulate network-attached storage. + +In a production cluster, you would not use hostPath. Instead a cluster administrator +would provision a network resource like a Google Compute Engine persistent disk, +an NFS share, or an Amazon Elastic Block Store volume. Cluster administrators can also +use [StorageClasses](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#storageclass-v1-storage-k8s-io) +to set up +[dynamic provisioning](/docs/concepts/storage/dynamic-provisioning/). + +Here is the configuration file for the hostPath PersistentVolume: + +{{< codenew file="pods/storage/pv-volume.yaml" >}} + +The configuration file specifies that the volume is at `/mnt/data` on the +cluster's Node. The configuration also specifies a size of 10 gibibytes and +an access mode of `ReadWriteOnce`, which means the volume can be mounted as +read-write by a single Node. It defines the [StorageClass name](/docs/concepts/storage/persistent-volumes/#class) +`manual` for the PersistentVolume, which will be used to bind +PersistentVolumeClaim requests to this PersistentVolume. + +Create the PersistentVolume: + +```shell +kubectl apply -f https://k8s.io/examples/pods/storage/pv-volume.yaml +``` + +View information about the PersistentVolume: + +```shell +kubectl get pv task-pv-volume +``` + +The output shows that the PersistentVolume has a `STATUS` of `Available`. This +means it has not yet been bound to a PersistentVolumeClaim. + + NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE + task-pv-volume 10Gi RWO Retain Available manual 4s + +## Create a PersistentVolumeClaim + +The next step is to create a PersistentVolumeClaim. Pods use PersistentVolumeClaims +to request physical storage. In this exercise, you create a PersistentVolumeClaim +that requests a volume of at least three gibibytes that can provide read-write +access for at least one Node. + +Here is the configuration file for the PersistentVolumeClaim: + +{{< codenew file="pods/storage/pv-claim.yaml" >}} + +Create the PersistentVolumeClaim: + + kubectl apply -f https://k8s.io/examples/pods/storage/pv-claim.yaml + +After you create the PersistentVolumeClaim, the Kubernetes control plane looks +for a PersistentVolume that satisfies the claim's requirements. If the control +plane finds a suitable PersistentVolume with the same StorageClass, it binds the +claim to the volume. + +Look again at the PersistentVolume: + +```shell +kubectl get pv task-pv-volume +``` + +Now the output shows a `STATUS` of `Bound`. + + NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE + task-pv-volume 10Gi RWO Retain Bound default/task-pv-claim manual 2m + +Look at the PersistentVolumeClaim: + +```shell +kubectl get pvc task-pv-claim +``` + +The output shows that the PersistentVolumeClaim is bound to your PersistentVolume, +`task-pv-volume`. + + NAME STATUS VOLUME CAPACITY ACCESSMODES STORAGECLASS AGE + task-pv-claim Bound task-pv-volume 10Gi RWO manual 30s + +## Create a Pod + +The next step is to create a Pod that uses your PersistentVolumeClaim as a volume. + +Here is the configuration file for the Pod: + +{{< codenew file="pods/storage/pv-pod.yaml" >}} + +Notice that the Pod's configuration file specifies a PersistentVolumeClaim, but +it does not specify a PersistentVolume. From the Pod's point of view, the claim +is a volume. + +Create the Pod: + +```shell +kubectl apply -f https://k8s.io/examples/pods/storage/pv-pod.yaml +``` + +Verify that the container in the Pod is running; + +```shell +kubectl get pod task-pv-pod +``` + +Get a shell to the container running in your Pod: + +```shell +kubectl exec -it task-pv-pod -- /bin/bash +``` + +In your shell, verify that nginx is serving the `index.html` file from the +hostPath volume: + +```shell +# Be sure to run these 3 commands inside the root shell that comes from +# running "kubectl exec" in the previous step +apt update +apt install curl +curl http://localhost/ +``` + +The output shows the text that you wrote to the `index.html` file on the +hostPath volume: + + Hello from Kubernetes storage + + +If you see that message, you have successfully configured a Pod to +use storage from a PersistentVolumeClaim. + +## Clean up + +Delete the Pod, the PersistentVolumeClaim and the PersistentVolume: + +```shell +kubectl delete pod task-pv-pod +kubectl delete pvc task-pv-claim +kubectl delete pv task-pv-volume +``` + +If you don't already have a shell open to the Node in your cluster, +open a new shell the same way that you did earlier. + +In the shell on your Node, remove the file and directory that you created: + +```shell +# This assumes that your Node uses "sudo" to run commands +# as the superuser +sudo rm /mnt/data/index.html +sudo rmdir /mnt/data +``` + +You can now close the shell to your Node. + +## Mounting the same persistentVolume in two places + +{{< codenew file="pods/storage/pv-duplicate.yaml" >}} + +You can perform 2 volume mounts on your nginx container: + +`/usr/share/nginx/html` for the static website +`/etc/nginx/nginx.conf` for the default config + + + +## Access control + +Storage configured with a group ID (GID) allows writing only by Pods using the same +GID. Mismatched or missing GIDs cause permission denied errors. To reduce the +need for coordination with users, an administrator can annotate a PersistentVolume +with a GID. Then the GID is automatically added to any Pod that uses the +PersistentVolume. + +Use the `pv.beta.kubernetes.io/gid` annotation as follows: +```yaml +apiVersion: v1 +kind: PersistentVolume +metadata: + name: pv1 + annotations: + pv.beta.kubernetes.io/gid: "1234" +``` +When a Pod consumes a PersistentVolume that has a GID annotation, the annotated GID +is applied to all containers in the Pod in the same way that GIDs specified in the +Pod's security context are. Every GID, whether it originates from a PersistentVolume +annotation or the Pod's specification, is applied to the first process run in +each container. + +{{< note >}} +When a Pod consumes a PersistentVolume, the GIDs associated with the +PersistentVolume are not present on the Pod resource itself. +{{< /note >}} + + + + +## {{% heading "whatsnext" %}} + + +* Pour en savoir plus sur les [PersistentVolumes](/docs/concepts/storage/persistent-volumes/). +* Lire la [documentation de conception sur le stockage persistant](https://git.k8s.io/design-proposals-archive/storage/persistent-storage.md). + +### Reference + +* [PersistentVolume](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#persistentvolume-v1-core) +* [PersistentVolumeSpec](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#persistentvolumespec-v1-core) +* [PersistentVolumeClaim](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#persistentvolumeclaim-v1-core) +* [PersistentVolumeClaimSpec](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#persistentvolumeclaimspec-v1-core) + + + + From 3667dd69f4f15b30576f2b7be28cd8cbe2ab3074 Mon Sep 17 00:00:00 2001 From: k0rventen Date: Sun, 5 Feb 2023 22:01:57 +0100 Subject: [PATCH 096/279] second iter on french i18n for pod pv --- .../configure-persistent-volume-storage.md | 83 +++++++++---------- 1 file changed, 41 insertions(+), 42 deletions(-) diff --git a/content/fr/docs/tasks/configure-pod-container/configure-persistent-volume-storage.md b/content/fr/docs/tasks/configure-pod-container/configure-persistent-volume-storage.md index ae96f6aaac7..89e59cd921c 100644 --- a/content/fr/docs/tasks/configure-pod-container/configure-persistent-volume-storage.md +++ b/content/fr/docs/tasks/configure-pod-container/configure-persistent-volume-storage.md @@ -36,16 +36,18 @@ can open a shell to your Node by entering `minikube ssh`. In your shell on that Node, create a `/mnt/data` directory: +Ouvrez une session shell sur le noeud de votre cluster. La facon d'ouvrir +la session va dependre de la configuration de votre cluster. Si vous utilisez Minikube, +vous pouvez ouvrir une session via la commande `minikube ssh`. + ```shell -# This assumes that your Node uses "sudo" to run commands -# as the superuser +# En supposant que votre noeud utilise `sudo` pour les acces privilegies sudo mkdir /mnt/data ``` Dans le dossier `/mnt/data`, creez un fichier `index.html`: ```shell -# This again assumes that your Node uses "sudo" to run commands -# as the superuser +# En supposant toujours que votre noeud utilise `sudo` pour les acces privilegies sudo sh -c "echo 'Hello from Kubernetes storage' > /mnt/data/index.html" ``` @@ -67,19 +69,18 @@ Vous pouvez maintenant fermer l'acces shell a votre Noeud. ## Creer un PersistentVolume -In this exercise, you create a *hostPath* PersistentVolume. Kubernetes supports -hostPath for development and testing on a single-node cluster. A hostPath -PersistentVolume uses a file or directory on the Node to emulate network-attached storage. +Dans cet exercice, vous allez créer un PersistentVolume de type *hostpath*. Prise en charge de Kubernetes +hostPath pour le développement et les tests sur un cluster à nœud unique. Un hostPath +PersistentVolume utilise un fichier ou un répertoire sur le nœud pour émuler le stockage en réseau. -In a production cluster, you would not use hostPath. Instead a cluster administrator -would provision a network resource like a Google Compute Engine persistent disk, -an NFS share, or an Amazon Elastic Block Store volume. Cluster administrators can also -use [StorageClasses](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#storageclass-v1-storage-k8s-io) -to set up -[dynamic provisioning](/docs/concepts/storage/dynamic-provisioning/). - -Here is the configuration file for the hostPath PersistentVolume: +Dans un cluster de production, vous n'utiliseriez pas le type *hostPath*. Communement, un administrateur de cluster +provisionnerait une ressource réseau comme un disque persistant Google Compute Engine, +un partage NFS ou un volume Amazon Elastic Block Store. Les administrateurs de cluster peuvent également +utiliser les [StorageClasses](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#storageclass-v1-storage-k8s-io) +pour parametrer du +[provisioning dynamique](/docs/concepts/storage/dynamic-provisioning/). +Voici le fichier de configuration pour le PersitentVolume de type hostPath: {{< codenew file="pods/storage/pv-volume.yaml" >}} The configuration file specifies that the volume is at `/mnt/data` on the @@ -89,25 +90,25 @@ read-write by a single Node. It defines the [StorageClass name](/docs/concepts/s `manual` for the PersistentVolume, which will be used to bind PersistentVolumeClaim requests to this PersistentVolume. -Create the PersistentVolume: +Creez le PersistentVolume: ```shell kubectl apply -f https://k8s.io/examples/pods/storage/pv-volume.yaml ``` -View information about the PersistentVolume: +Afficher les informations du PersistentVolume: ```shell kubectl get pv task-pv-volume ``` -The output shows that the PersistentVolume has a `STATUS` of `Available`. This -means it has not yet been bound to a PersistentVolumeClaim. +Le resultat affiche que le PersitentVolume a un `STATUS` de `Available`. +Cela signifie qu'il n'a pas encore ete attache a un PersistentVolumeClaim. NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE task-pv-volume 10Gi RWO Retain Available manual 4s -## Create a PersistentVolumeClaim +## Creer un PersistentVolumeClaim The next step is to create a PersistentVolumeClaim. Pods use PersistentVolumeClaims to request physical storage. In this exercise, you create a PersistentVolumeClaim @@ -133,7 +134,7 @@ Look again at the PersistentVolume: kubectl get pv task-pv-volume ``` -Now the output shows a `STATUS` of `Bound`. +Maintenant, le resultat affiche un `STATUS` a `Bound`. NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE task-pv-volume 10Gi RWO Retain Bound default/task-pv-claim manual 2m @@ -144,17 +145,17 @@ Look at the PersistentVolumeClaim: kubectl get pvc task-pv-claim ``` -The output shows that the PersistentVolumeClaim is bound to your PersistentVolume, +Le resultat montre que le PersistentVolumeClaim est attache au PersistentVolume `task-pv-volume`. NAME STATUS VOLUME CAPACITY ACCESSMODES STORAGECLASS AGE task-pv-claim Bound task-pv-volume 10Gi RWO manual 30s -## Create a Pod +## Creer un Pod -The next step is to create a Pod that uses your PersistentVolumeClaim as a volume. +La prochaine etape est de creer un Pod qui utilise le PersistentVolumeClaim comme volume de stockage. -Here is the configuration file for the Pod: +Voici le fichier de configuration du Pod: {{< codenew file="pods/storage/pv-pod.yaml" >}} @@ -162,30 +163,26 @@ Notice that the Pod's configuration file specifies a PersistentVolumeClaim, but it does not specify a PersistentVolume. From the Pod's point of view, the claim is a volume. -Create the Pod: +Creez le Pod: ```shell kubectl apply -f https://k8s.io/examples/pods/storage/pv-pod.yaml ``` -Verify that the container in the Pod is running; - +Verifiez que le container dans le Pod est operationnel: ```shell kubectl get pod task-pv-pod ``` -Get a shell to the container running in your Pod: - +Lancez un shell dans le container du Pod: ```shell kubectl exec -it task-pv-pod -- /bin/bash ``` -In your shell, verify that nginx is serving the `index.html` file from the -hostPath volume: - +Depuis le shell, verifiez que nginx utilise le fichier `index.html` du volume hosPath: ```shell -# Be sure to run these 3 commands inside the root shell that comes from -# running "kubectl exec" in the previous step +# Assurez vouys de lancer ces 3 commandes dans le shell qui provient de +# la commande "kubectl exec" executee precedemment apt update apt install curl curl http://localhost/ @@ -200,10 +197,9 @@ hostPath volume: If you see that message, you have successfully configured a Pod to use storage from a PersistentVolumeClaim. -## Clean up - -Delete the Pod, the PersistentVolumeClaim and the PersistentVolume: +## Nettoyage +Supprimez le Pod, the PersistentVolumeClaim et le PersistentVolume: ```shell kubectl delete pod task-pv-pod kubectl delete pvc task-pv-claim @@ -222,7 +218,7 @@ sudo rm /mnt/data/index.html sudo rmdir /mnt/data ``` -You can now close the shell to your Node. +Vous pouvez maintenant clore la session shell vers votre noeud. ## Mounting the same persistentVolume in two places @@ -237,8 +233,10 @@ You can perform 2 volume mounts on your nginx container: ## Access control -Storage configured with a group ID (GID) allows writing only by Pods using the same -GID. Mismatched or missing GIDs cause permission denied errors. To reduce the +Le stockage configure avec un ID de groupe (GID) ne permettra l'ecriture que par les Pods +qui utilisent le meme GID. + +Mismatched or missing GIDs cause permission denied errors. To reduce the need for coordination with users, an administrator can annotate a PersistentVolume with a GID. Then the GID is automatically added to any Pod that uses the PersistentVolume. @@ -252,6 +250,7 @@ metadata: annotations: pv.beta.kubernetes.io/gid: "1234" ``` + When a Pod consumes a PersistentVolume that has a GID annotation, the annotated GID is applied to all containers in the Pod in the same way that GIDs specified in the Pod's security context are. Every GID, whether it originates from a PersistentVolume @@ -272,7 +271,7 @@ PersistentVolume are not present on the Pod resource itself. * Pour en savoir plus sur les [PersistentVolumes](/docs/concepts/storage/persistent-volumes/). * Lire la [documentation de conception sur le stockage persistant](https://git.k8s.io/design-proposals-archive/storage/persistent-storage.md). -### Reference +### References * [PersistentVolume](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#persistentvolume-v1-core) * [PersistentVolumeSpec](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#persistentvolumespec-v1-core) From b95a76b7f7b506e9343a9e6fb5c6f98a8419a702 Mon Sep 17 00:00:00 2001 From: k0rventen Date: Sun, 5 Feb 2023 22:17:54 +0100 Subject: [PATCH 097/279] copy missing example files from en --- .../fr/examples/pods/storage/pv-claim.yaml | 11 ++++++++++ .../examples/pods/storage/pv-duplicate.yaml | 22 +++++++++++++++++++ content/fr/examples/pods/storage/pv-pod.yaml | 20 +++++++++++++++++ .../fr/examples/pods/storage/pv-volume.yaml | 14 ++++++++++++ 4 files changed, 67 insertions(+) create mode 100644 content/fr/examples/pods/storage/pv-claim.yaml create mode 100644 content/fr/examples/pods/storage/pv-duplicate.yaml create mode 100644 content/fr/examples/pods/storage/pv-pod.yaml create mode 100644 content/fr/examples/pods/storage/pv-volume.yaml diff --git a/content/fr/examples/pods/storage/pv-claim.yaml b/content/fr/examples/pods/storage/pv-claim.yaml new file mode 100644 index 00000000000..b33f6faa4cb --- /dev/null +++ b/content/fr/examples/pods/storage/pv-claim.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: task-pv-claim +spec: + storageClassName: manual + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 3Gi diff --git a/content/fr/examples/pods/storage/pv-duplicate.yaml b/content/fr/examples/pods/storage/pv-duplicate.yaml new file mode 100644 index 00000000000..e5a0e6ff69e --- /dev/null +++ b/content/fr/examples/pods/storage/pv-duplicate.yaml @@ -0,0 +1,22 @@ + +apiVersion: v1 +kind: Pod +metadata: + name: test +spec: + containers: + - name: test + image: nginx + volumeMounts: + # a mount for site-data + - name: config + mountPath: /usr/share/nginx/html + subPath: html + # another mount for nginx config + - name: config + mountPath: /etc/nginx/nginx.conf + subPath: nginx.conf + volumes: + - name: config + persistentVolumeClaim: + claimName: test-nfs-claim diff --git a/content/fr/examples/pods/storage/pv-pod.yaml b/content/fr/examples/pods/storage/pv-pod.yaml new file mode 100644 index 00000000000..a2eddcf0886 --- /dev/null +++ b/content/fr/examples/pods/storage/pv-pod.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Pod +metadata: + name: task-pv-pod +spec: + volumes: + - name: task-pv-storage + persistentVolumeClaim: + claimName: task-pv-claim + containers: + - name: task-pv-container + image: nginx + ports: + - containerPort: 80 + name: "http-server" + volumeMounts: + - mountPath: "/usr/share/nginx/html" + name: task-pv-storage + + diff --git a/content/fr/examples/pods/storage/pv-volume.yaml b/content/fr/examples/pods/storage/pv-volume.yaml new file mode 100644 index 00000000000..36fe3c54247 --- /dev/null +++ b/content/fr/examples/pods/storage/pv-volume.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: task-pv-volume + labels: + type: local +spec: + storageClassName: manual + capacity: + storage: 10Gi + accessModes: + - ReadWriteOnce + hostPath: + path: "/mnt/data" From 44f7a56a4799d1c9a565528d86e45598e2817c1b Mon Sep 17 00:00:00 2001 From: k0rventen Date: Mon, 6 Feb 2023 09:07:03 +0100 Subject: [PATCH 098/279] finalized translation --- .../configure-persistent-volume-storage.md | 160 ++++++++---------- 1 file changed, 67 insertions(+), 93 deletions(-) diff --git a/content/fr/docs/tasks/configure-pod-container/configure-persistent-volume-storage.md b/content/fr/docs/tasks/configure-pod-container/configure-persistent-volume-storage.md index 89e59cd921c..48e9cd694b7 100644 --- a/content/fr/docs/tasks/configure-pod-container/configure-persistent-volume-storage.md +++ b/content/fr/docs/tasks/configure-pod-container/configure-persistent-volume-storage.md @@ -6,53 +6,49 @@ weight: 60 -Cette page montre comment configurer un Pod afin qu'il utilise un {{< glossary_tooltip text="PersistentVolumeClaim" term_id="persistent-volume-claim" >}} comme stockage. +Cette page montre comment configurer un Pod afin qu'il utilise un {{< glossary_tooltip text="PersistentVolumeClaim" term_id="persistent-volume-claim" >}} comme système de stockage. -Voici un resume des etapes: +Voici un résumé des étapes: -1. En tant qu'administrateur d'un cluster, vous creez un PersistentVolume qui pointe vers un systeme de stockage physique. Vous n'associez le volume avec aucun pod pour le moment. +1. En tant qu'administrateur d'un cluster, vous créez un PersistentVolume qui pointe vers un système de stockage physique. Vous n'associez le volume avec aucun Pod pour le moment. -1. En tant que developer / utilisateur du cluster, vous creez un PersistentVolumeClaim qui sera automatiquement lie a un PersistentVolume adapte. +1. En tant que développeur ou utilisateur du cluster, vous créez un PersistentVolumeClaim qui sera automatiquement lié à un PersistentVolume adapté. -1. Vous creez un Pod qui utilise le PersistentVolumeClaim cree precedemment comme stockage. +1. Vous créez un Pod qui utilise le PersistentVolumeClaim créé précédemment comme stockage. ## {{% heading "prerequisites" %}} -* Vous devez avoir a disposition un cluster qui n'a qu'un seul noeud, et l'utilitaire en ligne de commande -{{< glossary_tooltip text="kubectl" term_id="kubectl" >}} doit etre configure pour communiquer avec votre cluster. Si vous n'avez pas deja de cluster a disposition, vous pouvez en creer un en utilisant [Minikube](https://minikube.sigs.k8s.io/docs/). +* Vous devez avoir à disposition un cluster qui n'a qu'un seul noeud, et l'utilitaire en ligne de commande +{{< glossary_tooltip text="kubectl" term_id="kubectl" >}} doit être configuré pour communiquer avec votre cluster. Si vous n'avez pas déja de cluster à disposition, vous pouvez en créer un en utilisant [Minikube](https://minikube.sigs.k8s.io/docs/). * Vous pouvez vous familiariser avec la documentation des [Persistent Volumes](/docs/concepts/storage/persistent-volumes/). -## Creer un fichier index.html sur votre noeud - -Open a shell to the single Node in your cluster. How you open a shell depends -on how you set up your cluster. For example, if you are using Minikube, you -can open a shell to your Node by entering `minikube ssh`. - -In your shell on that Node, create a `/mnt/data` directory: +## Créer un fichier index.html sur votre noeud Ouvrez une session shell sur le noeud de votre cluster. La facon d'ouvrir la session va dependre de la configuration de votre cluster. Si vous utilisez Minikube, vous pouvez ouvrir une session via la commande `minikube ssh`. +Via la session sur ce noeud, créez un dossier `/mnt/data`: + ```shell -# En supposant que votre noeud utilise `sudo` pour les acces privilegies +# En supposant que votre noeud utilise `sudo` pour les accès privilégiés sudo mkdir /mnt/data ``` -Dans le dossier `/mnt/data`, creez un fichier `index.html`: +Dans le dossier `/mnt/data`, créez un fichier `index.html`: ```shell -# En supposant toujours que votre noeud utilise `sudo` pour les acces privilegies +# En supposant toujours que votre noeud utilise `sudo` pour les accès privilégiés sudo sh -c "echo 'Hello from Kubernetes storage' > /mnt/data/index.html" ``` {{< note >}} -Si votre noeud utilise un utilitaire d'acces privilegie autre que `sudo`, les commandes notees ici fonctionneront en remplacant `sudo` par le nom de l'utilitaire. +Si votre noeud utilise un utilitaire d'accès privilégié autre que `sudo`, les commandes notées ici devraient fonctionner en remplacant `sudo` par le nom de l'utilitaire. {{< /note >}} Testez que le fichier `index.html` existe: @@ -60,116 +56,98 @@ Testez que le fichier `index.html` existe: cat /mnt/data/index.html ``` -Le resultat de la commande doit etre: +Le résultat de la commande doit être: ``` Hello from Kubernetes storage ``` -Vous pouvez maintenant fermer l'acces shell a votre Noeud. +Vous pouvez maintenant fermer l'accès shell à votre Noeud. -## Creer un PersistentVolume +## Créer un PersistentVolume -Dans cet exercice, vous allez créer un PersistentVolume de type *hostpath*. Prise en charge de Kubernetes -hostPath pour le développement et les tests sur un cluster à nœud unique. Un hostPath -PersistentVolume utilise un fichier ou un répertoire sur le nœud pour émuler le stockage en réseau. +Dans cet exercice, vous allez créer un PersistentVolume de type *hostpath*. Kubernetes prend en charge le type hostPath pour le développement et les tests sur un cluster à noeud unique. Un PersistentVolume de type hostPath utilise un fichier ou un répertoire sur le noeud pour simuler un stockage réseau. -Dans un cluster de production, vous n'utiliseriez pas le type *hostPath*. Communement, un administrateur de cluster +Dans un cluster de production, vous n'utiliseriez pas le type *hostPath*. Plus communément, un administrateur de cluster provisionnerait une ressource réseau comme un disque persistant Google Compute Engine, un partage NFS ou un volume Amazon Elastic Block Store. Les administrateurs de cluster peuvent également utiliser les [StorageClasses](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#storageclass-v1-storage-k8s-io) -pour parametrer du +pour paramétrer du [provisioning dynamique](/docs/concepts/storage/dynamic-provisioning/). Voici le fichier de configuration pour le PersitentVolume de type hostPath: {{< codenew file="pods/storage/pv-volume.yaml" >}} -The configuration file specifies that the volume is at `/mnt/data` on the -cluster's Node. The configuration also specifies a size of 10 gibibytes and -an access mode of `ReadWriteOnce`, which means the volume can be mounted as -read-write by a single Node. It defines the [StorageClass name](/docs/concepts/storage/persistent-volumes/#class) -`manual` for the PersistentVolume, which will be used to bind -PersistentVolumeClaim requests to this PersistentVolume. +Le fichier de configuration spécifie que le chemin du volume sur le noeud est `/mnt/data`. Il spécifie aussi une taille de 10 gibibytes, ainsi qu'un mode d'accès de type `ReadWriteOnce`, impliquant que le volume ne peut être monté en lecture et écriture que par un seul noeud. Le fichier définit un [nom de StorageClass](/docs/concepts/storage/persistent-volumes/#class) à `manual`, ce qui sera utilisé pour attacher un PersistentVolumeClaim à ce PersistentVolume -Creez le PersistentVolume: +Créez le PersistentVolume: ```shell kubectl apply -f https://k8s.io/examples/pods/storage/pv-volume.yaml ``` -Afficher les informations du PersistentVolume: +Affichez les informations du PersistentVolume: ```shell kubectl get pv task-pv-volume ``` -Le resultat affiche que le PersitentVolume a un `STATUS` de `Available`. -Cela signifie qu'il n'a pas encore ete attache a un PersistentVolumeClaim. +Le résultat affiche que le PersitentVolume a un `STATUS` de `Available`. +Cela signifie qu'il n'a pas encore été attaché à un PersistentVolumeClaim. NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE task-pv-volume 10Gi RWO Retain Available manual 4s -## Creer un PersistentVolumeClaim +## Créer un PersistentVolumeClaim -The next step is to create a PersistentVolumeClaim. Pods use PersistentVolumeClaims -to request physical storage. In this exercise, you create a PersistentVolumeClaim -that requests a volume of at least three gibibytes that can provide read-write -access for at least one Node. - -Here is the configuration file for the PersistentVolumeClaim: +La prochaine étape est de créer un PersistentVolumeClaim (demande de stockage). Les Pods utilisent les PersistentVolumeClaims pour demander un accès à du stockage physique. +Dans cet exercice, vous créez un PersistentVolumeClaim qui demande un volume d'au moins 3 gibibytes, et qui peut être monté en lecture et écriture sur au moins un noeud. +Voici le fichier de configuration du PersistentVolumeClaim: {{< codenew file="pods/storage/pv-claim.yaml" >}} -Create the PersistentVolumeClaim: +Créez le PersistentVolumeClaim: kubectl apply -f https://k8s.io/examples/pods/storage/pv-claim.yaml -After you create the PersistentVolumeClaim, the Kubernetes control plane looks -for a PersistentVolume that satisfies the claim's requirements. If the control -plane finds a suitable PersistentVolume with the same StorageClass, it binds the -claim to the volume. - -Look again at the PersistentVolume: +Après avoir créé le PersistentVolumeClaim, le control plane de Kubernetes va chercher un PersistentVolume qui respecte les exigences du PersistentVolumeClaim. Si le control plane trouve un PersistentVolume approprié avec la même StorageClass, il attache la demande au volume. +Affichez à nouveau les informations du PersistentVolume: ```shell kubectl get pv task-pv-volume ``` -Maintenant, le resultat affiche un `STATUS` a `Bound`. +Maintenant, le résultat affiche un `STATUS` à `Bound`. NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE task-pv-volume 10Gi RWO Retain Bound default/task-pv-claim manual 2m -Look at the PersistentVolumeClaim: - +Affichez les informations du PersistentVolumeClaim: ```shell kubectl get pvc task-pv-claim ``` -Le resultat montre que le PersistentVolumeClaim est attache au PersistentVolume -`task-pv-volume`. +Le résultat montre que le PersistentVolumeClaim est attaché au PersistentVolume `task-pv-volume`. NAME STATUS VOLUME CAPACITY ACCESSMODES STORAGECLASS AGE task-pv-claim Bound task-pv-volume 10Gi RWO manual 30s -## Creer un Pod +## Créer un Pod -La prochaine etape est de creer un Pod qui utilise le PersistentVolumeClaim comme volume de stockage. +La prochaine étape est de créer un Pod qui utilise le PersistentVolumeClaim comme volume de stockage. Voici le fichier de configuration du Pod: {{< codenew file="pods/storage/pv-pod.yaml" >}} -Notice that the Pod's configuration file specifies a PersistentVolumeClaim, but -it does not specify a PersistentVolume. From the Pod's point of view, the claim -is a volume. +Notez que le fichier de configuration du Pod spécifie un PersistentVolumeClaim et non un PersistentVolume. Du point de vue du Pod, la demande est un volume de stockage. -Creez le Pod: +Créez le Pod: ```shell kubectl apply -f https://k8s.io/examples/pods/storage/pv-pod.yaml ``` -Verifiez que le container dans le Pod est operationnel: +Vérifiez que le container dans le Pod est opérationnel: ```shell kubectl get pod task-pv-pod ``` @@ -179,69 +157,69 @@ Lancez un shell dans le container du Pod: kubectl exec -it task-pv-pod -- /bin/bash ``` -Depuis le shell, verifiez que nginx utilise le fichier `index.html` du volume hosPath: +Depuis le shell, vérifiez que nginx utilise le fichier `index.html` du volume hostPath: ```shell -# Assurez vouys de lancer ces 3 commandes dans le shell qui provient de -# la commande "kubectl exec" executee precedemment +# Assurez vous de lancer ces 3 commandes dans le shell qui provient de +# la commande "kubectl exec" exécutée précedemment apt update apt install curl curl http://localhost/ ``` -The output shows the text that you wrote to the `index.html` file on the -hostPath volume: +Le résultat doit afficher le texte qui a été écrit auparavant dans le fichier `index.html` dans le volume hostPath: Hello from Kubernetes storage -If you see that message, you have successfully configured a Pod to -use storage from a PersistentVolumeClaim. +Si vous voyez ce message, vous avez configuré un Pod qui utilise un PersistentVolumeClaim comme stockage avec succès. + ## Nettoyage -Supprimez le Pod, the PersistentVolumeClaim et le PersistentVolume: +Supprimez le Pod, le PersistentVolumeClaim et le PersistentVolume: ```shell kubectl delete pod task-pv-pod kubectl delete pvc task-pv-claim kubectl delete pv task-pv-volume ``` -If you don't already have a shell open to the Node in your cluster, -open a new shell the same way that you did earlier. +Si vous n'avez pas déja de session ouverte sur le noeud de votre cluster, ouvrez en un de la même manière que précédemment. -In the shell on your Node, remove the file and directory that you created: +Dans la session shell, supprimez les fichiers et dossiers que vous avez créé: ```shell -# This assumes that your Node uses "sudo" to run commands -# as the superuser +# En assumant que le noeud utilise "sudo" pour les accès privilégiés sudo rm /mnt/data/index.html sudo rmdir /mnt/data ``` -Vous pouvez maintenant clore la session shell vers votre noeud. +Vous pouvez maintenant arrêter la session shell vers votre noeud. -## Mounting the same persistentVolume in two places +## Monter le même PersistentVolume à deux endroits + +Vous pouvez monter plusieurs fois un même PersistentVolume +à plusieurs endroits différents dans votre container nginx: {{< codenew file="pods/storage/pv-duplicate.yaml" >}} -You can perform 2 volume mounts on your nginx container: - -`/usr/share/nginx/html` for the static website -`/etc/nginx/nginx.conf` for the default config +`/usr/share/nginx/html` pour le site statique +`/etc/nginx/nginx.conf` pour la configuration par défaut -## Access control +## Contrôle d'accès -Le stockage configure avec un ID de groupe (GID) ne permettra l'ecriture que par les Pods -qui utilisent le meme GID. +Le stockage configuré avec un ID de groupe (GID) ne permettra l'écriture que par les Pods qui utilisent le même GID. Mismatched or missing GIDs cause permission denied errors. To reduce the need for coordination with users, an administrator can annotate a PersistentVolume with a GID. Then the GID is automatically added to any Pod that uses the PersistentVolume. -Use the `pv.beta.kubernetes.io/gid` annotation as follows: +Les GID manquants ou qui ne correspondent pas entraîneront des erreurs d'autorisation refusée. Pour alléger la coordination avec les utilisateurs, un administrateur peut annoter un PersistentVolume +avec un GID. Ensuite, le GID sera automatiquement ajouté à tout pod qui utilise le PersistentVolume. + +Utilisez l'annotation `pv.beta.kubernetes.io/gid` comme ceci: ```yaml apiVersion: v1 kind: PersistentVolume @@ -251,15 +229,11 @@ metadata: pv.beta.kubernetes.io/gid: "1234" ``` -When a Pod consumes a PersistentVolume that has a GID annotation, the annotated GID -is applied to all containers in the Pod in the same way that GIDs specified in the -Pod's security context are. Every GID, whether it originates from a PersistentVolume -annotation or the Pod's specification, is applied to the first process run in -each container. +Lorsqu'un Pod attache un PersistentVolume qui a une annotation pour le GID, ce dernier est appliqué à tous les containers du Pod de la même façon que les GID spécifiés dans le contexte de sécurité du Pod. Peu importe s'il provient d'une annotation du PersistentVolume ou de la spécification du Pod, chaque GID sera appliqué au premier process exécuté dans chaque container. + {{< note >}} -When a Pod consumes a PersistentVolume, the GIDs associated with the -PersistentVolume are not present on the Pod resource itself. +Quand un Pod attache un PersistentVolume, les GID associés avec le PersistentVolume ne sont pas répércutés sur la spécification de la ressource du Pod. {{< /note >}} @@ -271,7 +245,7 @@ PersistentVolume are not present on the Pod resource itself. * Pour en savoir plus sur les [PersistentVolumes](/docs/concepts/storage/persistent-volumes/). * Lire la [documentation de conception sur le stockage persistant](https://git.k8s.io/design-proposals-archive/storage/persistent-storage.md). -### References +### Références * [PersistentVolume](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#persistentvolume-v1-core) * [PersistentVolumeSpec](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#persistentvolumespec-v1-core) From 6c67d139c577788879b73fadab7ccbcd64d4c5ed Mon Sep 17 00:00:00 2001 From: k0rventen Date: Mon, 6 Feb 2023 09:14:42 +0100 Subject: [PATCH 099/279] final pass --- .../configure-persistent-volume-storage.md | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/content/fr/docs/tasks/configure-pod-container/configure-persistent-volume-storage.md b/content/fr/docs/tasks/configure-pod-container/configure-persistent-volume-storage.md index 48e9cd694b7..8af571c8e34 100644 --- a/content/fr/docs/tasks/configure-pod-container/configure-persistent-volume-storage.md +++ b/content/fr/docs/tasks/configure-pod-container/configure-persistent-volume-storage.md @@ -65,7 +65,7 @@ Vous pouvez maintenant fermer l'accès shell à votre Noeud. ## Créer un PersistentVolume -Dans cet exercice, vous allez créer un PersistentVolume de type *hostpath*. Kubernetes prend en charge le type hostPath pour le développement et les tests sur un cluster à noeud unique. Un PersistentVolume de type hostPath utilise un fichier ou un répertoire sur le noeud pour simuler un stockage réseau. +Dans cet exercice, vous allez créer un PersistentVolume de type *hostpath*. Kubernetes prend en charge le type hostPath pour le développement et les tests sur un cluster à noeud unique. Un PersistentVolume de type hostPath utilise un fichier ou un dossier sur le noeud pour simuler un stockage réseau. Dans un cluster de production, vous n'utiliseriez pas le type *hostPath*. Plus communément, un administrateur de cluster provisionnerait une ressource réseau comme un disque persistant Google Compute Engine, @@ -74,7 +74,7 @@ utiliser les [StorageClasses](/docs/reference/generated/kubernetes-api/{{< param pour paramétrer du [provisioning dynamique](/docs/concepts/storage/dynamic-provisioning/). -Voici le fichier de configuration pour le PersitentVolume de type hostPath: +Voici le fichier de configuration pour le PersistentVolume de type hostPath: {{< codenew file="pods/storage/pv-volume.yaml" >}} Le fichier de configuration spécifie que le chemin du volume sur le noeud est `/mnt/data`. Il spécifie aussi une taille de 10 gibibytes, ainsi qu'un mode d'accès de type `ReadWriteOnce`, impliquant que le volume ne peut être monté en lecture et écriture que par un seul noeud. Le fichier définit un [nom de StorageClass](/docs/concepts/storage/persistent-volumes/#class) à `manual`, ce qui sera utilisé pour attacher un PersistentVolumeClaim à ce PersistentVolume @@ -202,19 +202,14 @@ Vous pouvez monter plusieurs fois un même PersistentVolume {{< codenew file="pods/storage/pv-duplicate.yaml" >}} -`/usr/share/nginx/html` pour le site statique -`/etc/nginx/nginx.conf` pour la configuration par défaut +- `/usr/share/nginx/html` pour le site statique +- `/etc/nginx/nginx.conf` pour la configuration par défaut ## Contrôle d'accès -Le stockage configuré avec un ID de groupe (GID) ne permettra l'écriture que par les Pods qui utilisent le même GID. - -Mismatched or missing GIDs cause permission denied errors. To reduce the -need for coordination with users, an administrator can annotate a PersistentVolume -with a GID. Then the GID is automatically added to any Pod that uses the -PersistentVolume. +Le stockage configuré avec un ID de groupe (GID) ne permettra l'écriture que par les Pods qui utilisent le même GID. Les GID manquants ou qui ne correspondent pas entraîneront des erreurs d'autorisation refusée. Pour alléger la coordination avec les utilisateurs, un administrateur peut annoter un PersistentVolume avec un GID. Ensuite, le GID sera automatiquement ajouté à tout pod qui utilise le PersistentVolume. From 5040976f98ea43c708837b5705c9ed8787e1c606 Mon Sep 17 00:00:00 2001 From: "paul.zhang" Date: Mon, 6 Feb 2023 16:27:07 +0800 Subject: [PATCH 100/279] =?UTF-8?q?[zh-cn]Fix=20delete=20extra=20words?= =?UTF-8?q?=E2=80=9C=E5=88=B6=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 删除冗余的“制” --- content/zh-cn/docs/concepts/policy/resource-quotas.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/zh-cn/docs/concepts/policy/resource-quotas.md b/content/zh-cn/docs/concepts/policy/resource-quotas.md index 6af4ee8f7a1..bf431338ef0 100644 --- a/content/zh-cn/docs/concepts/policy/resource-quotas.md +++ b/content/zh-cn/docs/concepts/policy/resource-quotas.md @@ -79,7 +79,7 @@ You can use a [LimitRange](/docs/concepts/policy/limit-range/) to automatically a default request for these resources. --> - 对于 `cpu` 和 `memory` 资源:ResourceQuota 强制该命名空间中的每个(新)Pod 为该资源设置限制。 - 如果你在命名空间中为 `cpu` 和 `memory` 制实施资源配额, + 如果你在命名空间中为 `cpu` 和 `memory` 实施资源配额, 你或其他客户端**必须**为你提交的每个新 Pod 指定该资源的 `requests` 或 `limits`。 否则,控制平面可能会拒绝接纳该 Pod。 - 对于其他资源:ResourceQuota 可以工作,并且会忽略命名空间中的 Pod,而无需为该资源设置限制或请求。 From d1887cb11bedddcd260051fb45d0041cba1371b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20L=C3=A9one?= Date: Mon, 6 Feb 2023 09:51:13 +0100 Subject: [PATCH 101/279] Update content/fr/docs/tasks/configure-pod-container/configure-persistent-volume-storage.md --- .../configure-persistent-volume-storage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/fr/docs/tasks/configure-pod-container/configure-persistent-volume-storage.md b/content/fr/docs/tasks/configure-pod-container/configure-persistent-volume-storage.md index 8af571c8e34..75ae3c68462 100644 --- a/content/fr/docs/tasks/configure-pod-container/configure-persistent-volume-storage.md +++ b/content/fr/docs/tasks/configure-pod-container/configure-persistent-volume-storage.md @@ -100,7 +100,7 @@ Cela signifie qu'il n'a pas encore été attaché à un PersistentVolumeClaim. ## Créer un PersistentVolumeClaim La prochaine étape est de créer un PersistentVolumeClaim (demande de stockage). Les Pods utilisent les PersistentVolumeClaims pour demander un accès à du stockage physique. -Dans cet exercice, vous créez un PersistentVolumeClaim qui demande un volume d'au moins 3 gibibytes, et qui peut être monté en lecture et écriture sur au moins un noeud. +Dans cet exercice, vous créez un PersistentVolumeClaim qui demande un volume d'au moins 3 GB, et qui peut être monté en lecture et écriture sur au moins un noeud. Voici le fichier de configuration du PersistentVolumeClaim: {{< codenew file="pods/storage/pv-claim.yaml" >}} From 4cdd540597ac851ed38888ab7838f042fac99558 Mon Sep 17 00:00:00 2001 From: windsonsea Date: Mon, 6 Feb 2023 18:10:10 +0800 Subject: [PATCH 102/279] Tweak line wrappings in blog sig-instrumentation-spotlight --- ...023-02-03-sig-instrumentation-spotlight.md | 122 +++++++++++++++--- 1 file changed, 101 insertions(+), 21 deletions(-) diff --git a/content/en/blog/_posts/2023-02-03-sig-instrumentation-spotlight.md b/content/en/blog/_posts/2023-02-03-sig-instrumentation-spotlight.md index e5da21b7309..b4ff5b7a42b 100644 --- a/content/en/blog/_posts/2023-02-03-sig-instrumentation-spotlight.md +++ b/content/en/blog/_posts/2023-02-03-sig-instrumentation-spotlight.md @@ -8,54 +8,134 @@ canonicalUrl: https://www.kubernetes.dev/blog/2023/02/03/sig-instrumentation-spo **Author:** Imran Noor Mohamed (Delivery Hero) -Observability requires the right data at the right time for the right consumer (human or piece of software) to make the right decision. In the context of Kubernetes, having best practices for cluster observability across all Kubernetes components is crucial. +Observability requires the right data at the right time for the right consumer +(human or piece of software) to make the right decision. In the context of Kubernetes, +having best practices for cluster observability across all Kubernetes components is crucial. -SIG Instrumentation helps to address this issue by providing best practices and tools that all other SIGs use to instrument Kubernetes components-like the *API server*, *scheduler*, *kubelet* and *kube-controller-manager*. +SIG Instrumentation helps to address this issue by providing best practices and tools +that all other SIGs use to instrument Kubernetes components-like the *API server*, +*scheduler*, *kubelet* and *kube-controller-manager*. -In this SIG Instrumentation spotlight, [Imran Noor Mohamed](https://www.linkedin.com/in/imrannoormohamed/), SIG ContribEx-Comms tech lead talked with [Elana Hashman](https://twitter.com/ehashdn), and [Han Kang](https://www.linkedin.com/in/hankang), chairs of SIG Instrumentation, on how the SIG is organized, what are the current challenges and how anyone can get involved and contribute. +In this SIG Instrumentation spotlight, [Imran Noor Mohamed](https://www.linkedin.com/in/imrannoormohamed/), +SIG ContribEx-Comms tech lead talked with [Elana Hashman](https://twitter.com/ehashdn), +and [Han Kang](https://www.linkedin.com/in/hankang), chairs of SIG Instrumentation, +on how the SIG is organized, what are the current challenges and how anyone can get involved and contribute. ## About SIG Instrumentation -**Imran (INM)**: Hello, thank you for the opportunity of learning more about SIG Instrumentation. Could you tell us a bit about yourself, your role, and how you got involved in SIG Instrumentation? +**Imran (INM)**: Hello, thank you for the opportunity of learning more about SIG Instrumentation. +Could you tell us a bit about yourself, your role, and how you got involved in SIG Instrumentation? -**Han (HK)**: I started in SIG Instrumentation in 2018, and became a chair in 2020. I primarily got involved with SIG instrumentation due to a number of upstream issues with metrics which ended up affecting GKE in bad ways. As a result, we ended up launching an initiative to stabilize our metrics and make metrics a proper API. +**Han (HK)**: I started in SIG Instrumentation in 2018, and became a chair in 2020. +I primarily got involved with SIG instrumentation due to a number of upstream issues +with metrics which ended up affecting GKE in bad ways. As a result, we ended up +launching an initiative to stabilize our metrics and make metrics a proper API. -**Elana (EH)**: I also joined SIG Instrumentation in 2018 and became a chair at the same time as Han. I was working as a site reliability engineer (SRE) on bare metal Kubernetes clusters and was working to build out our observability stack. I encountered some issues with label joins where Kubernetes metrics didn’t match kube-state-metrics ([KSM](https://github.com/kubernetes/kube-state-metrics)) and started participating in SIG meetings to improve things. I helped test performance improvements to kube-state-metrics and ultimately coauthored a KEP for overhauling metrics in the 1.14 release to improve usability. +**Elana (EH)**: I also joined SIG Instrumentation in 2018 and became a chair at the +same time as Han. I was working as a site reliability engineer (SRE) on bare metal +Kubernetes clusters and was working to build out our observability stack. +I encountered some issues with label joins where Kubernetes metrics didn’t match +kube-state-metrics ([KSM](https://github.com/kubernetes/kube-state-metrics)) and +started participating in SIG meetings to improve things. I helped test performance +improvements to kube-state-metrics and ultimately coauthored a KEP for overhauling +metrics in the 1.14 release to improve usability. **Imran (INM)**: Interesting! Does that mean SIG Instrumentation involves a lot of plumbing? -**Han (HK)**: I wouldn’t say it involves a ton of plumbing, though it does touch basically every code base. We have our own dedicated directories for our metrics, logs, and tracing frameworks which we tend to work out of primarily. We do have to interact with other SIGs in order to propagate our changes which makes us more of a horizontal SIG. +**Han (HK)**: I wouldn’t say it involves a ton of plumbing, though it does touch +basically every code base. We have our own dedicated directories for our metrics, +logs, and tracing frameworks which we tend to work out of primarily. We do have to +interact with other SIGs in order to propagate our changes which makes us more of +a horizontal SIG. -**Imran (INM)**: Speaking about interaction and coordination with other SIG could you describe how the SIGs is organized? +**Imran (INM)**: Speaking about interaction and coordination with other SIG could +you describe how the SIGs is organized? -**Elana (EH)**: In SIG Instrumentation, we have two chairs, Han and myself, as well as two tech leads, David Ashpole and Damien Grisonnet. We all work together as the SIG’s leads in order to run meetings, triage issues and PRs, review and approve KEPs, plan for each release, present at KubeCon and community meetings, and write our annual report. Within the SIG we also have a number of important subprojects, each of which is stewarded by its subproject owners. For example, Marek Siarkowicz is a subproject owner of [metrics-server](https://github.com/kubernetes-sigs/metrics-server). +**Elana (EH)**: In SIG Instrumentation, we have two chairs, Han and myself, as well +as two tech leads, David Ashpole and Damien Grisonnet. We all work together as the +SIG’s leads in order to run meetings, triage issues and PRs, review and approve KEPs, +plan for each release, present at KubeCon and community meetings, and write our annual +report. Within the SIG we also have a number of important subprojects, each of which is +stewarded by its subproject owners. For example, Marek Siarkowicz is a subproject owner +of [metrics-server](https://github.com/kubernetes-sigs/metrics-server). -Because we’re a horizontal SIG, some of our projects have a wide scope and require coordination from a dedicated group of contributors. For example, in order to guide the Kubernetes migration to structured logging, we chartered the [Structured Logging](https://github.com/kubernetes/community/blob/master/wg-structured-logging/README.md) Working Group (WG), organized by Marek and Patrick Ohly. The WG doesn’t own any code, but helps with various components such as the *kubelet*, *scheduler*, etc. in migrating their code to use structured logs. +Because we’re a horizontal SIG, some of our projects have a wide scope and require +coordination from a dedicated group of contributors. For example, in order to guide +the Kubernetes migration to structured logging, we chartered the +[Structured Logging](https://github.com/kubernetes/community/blob/master/wg-structured-logging/README.md) +Working Group (WG), organized by Marek and Patrick Ohly. The WG doesn’t own any code, +but helps with various components such as the *kubelet*, *scheduler*, etc. in migrating +their code to use structured logs. -**Imran (INM)**: Walking through the [charter](https://github.com/kubernetes/community/blob/master/sig-instrumentation/charter.md) alone it’s clear that SIG Instrumentation has a lot of sub-projects. Could you highlight some important ones? +**Imran (INM)**: Walking through the +[charter](https://github.com/kubernetes/community/blob/master/sig-instrumentation/charter.md) +alone it’s clear that SIG Instrumentation has a lot of sub-projects. +Could you highlight some important ones? -**Han (HK)**: We have many different sub-projects and we are in dire need of people who can come and help shepherd them. Our most important projects in-tree (that is, within the kubernetes/kubernetes repo) are metrics, tracing, and, structured logging. Our most important projects out-of-tree are (a) KSM (kube-state-metrics) and (b) metrics-server. +**Han (HK)**: We have many different sub-projects and we are in dire need of +people who can come and help shepherd them. Our most important projects in-tree +(that is, within the kubernetes/kubernetes repo) are metrics, tracing, and, +structured logging. Our most important projects out-of-tree are +(a) KSM (kube-state-metrics) and (b) metrics-server. -**Elana (EH)**: Echoing this, we would love to bring on more maintainers for kube-state-metrics and metrics-server. Our friends at WG Structured Logging are also looking for contributors. Other subprojects include klog, prometheus-adapter, and a new subproject that we just launched for collecting high-fidelity, scalable utilization metrics called [usage-metrics-collector](https://github.com/kubernetes-sigs/usage-metrics-collector). All are seeking new contributors! +**Elana (EH)**: Echoing this, we would love to bring on more maintainers for +kube-state-metrics and metrics-server. Our friends at WG Structured Logging are +also looking for contributors. Other subprojects include klog, prometheus-adapter, +and a new subproject that we just launched for collecting high-fidelity, scalable +utilization metrics called [usage-metrics-collector](https://github.com/kubernetes-sigs/usage-metrics-collector). +All are seeking new contributors! ## Current status and ongoing challenges -**Imran (INM)**: For release [1.26](https://github.com/kubernetes/sig-release/tree/master/releases/release-1.26) we can see that there are a relevant number of metrics, logs, and tracing [KEPs](https://www.k8s.dev/resources/keps/) in the pipeline. Would you like to point out important things for last release (maybe alpha & stable milestone candidates?) +**Imran (INM)**: For release [1.26](https://github.com/kubernetes/sig-release/tree/master/releases/release-1.26) +we can see that there are a relevant number of metrics, logs, and tracing +[KEPs](https://www.k8s.dev/resources/keps/) in the pipeline. Would you like to +point out important things for last release (maybe alpha & stable milestone candidates?) -**Han (HK)**: We can now generate [documentation](https://kubernetes.io/docs/reference/instrumentation/metrics/) for every single metric in the main Kubernetes code base! We have a pretty fancy static analysis pipeline that enables this functionality. We’ve also added feature metrics so that you can look at your metrics to determine which features are enabled in your cluster at a given time. Lastly, we added a component-sli endpoint, which should make it easy for people to create availability SLOs for *control-plane* components. +**Han (HK)**: We can now generate [documentation](https://kubernetes.io/docs/reference/instrumentation/metrics/) +for every single metric in the main Kubernetes code base! We have a pretty fancy +static analysis pipeline that enables this functionality. We’ve also added feature +metrics so that you can look at your metrics to determine which features are enabled +in your cluster at a given time. Lastly, we added a component-sli endpoint, which +should make it easy for people to create availability SLOs for *control-plane* components. -**Elana (EH)**: We’ve also been working on tracing KEPs for both the *API server* and *kubelet*, though neither graduated in 1.26. I’m also really excited about the work Han is doing with WG Reliability to extend and improve our metrics stability framework. +**Elana (EH)**: We’ve also been working on tracing KEPs for both the *API server* +and *kubelet*, though neither graduated in 1.26. I’m also really excited about the +work Han is doing with WG Reliability to extend and improve our metrics stability framework. -**Imran (INM)**: What do you think are the Kubernetes-specific challenges tackled by the SIG Instrumentation? What are the future efforts to solve them? +**Imran (INM)**: What do you think are the Kubernetes-specific challenges tackled by +the SIG Instrumentation? What are the future efforts to solve them? -**Han (HK)**: SIG instrumentation suffered a bit in the past from being a horizontal SIG. We did not have an obvious location to put our code and did not have a good mechanism to audit metrics that people would randomly add. We’ve fixed this over the years and now we have dedicated spots for our code and a reliable mechanism for auditing new metrics. We also now offer stability guarantees for metrics. We hope to have full-blown tracing up and down the kubernetes stack, and metric support via exemplars. +**Han (HK)**: SIG instrumentation suffered a bit in the past from being a horizontal SIG. +We did not have an obvious location to put our code and did not have a good mechanism to +audit metrics that people would randomly add. We’ve fixed this over the years and now we +have dedicated spots for our code and a reliable mechanism for auditing new metrics. +We also now offer stability guarantees for metrics. We hope to have full-blown tracing +up and down the kubernetes stack, and metric support via exemplars. -**Elana (EH)**: I think SIG Instrumentation is a really interesting SIG because it poses different kinds of opportunities to get involved than in other SIGs. You don’t have to be a software developer to contribute to our SIG! All of our components and subprojects are focused on better understanding Kubernetes and its performance in production, which allowed me to get involved as one of the few SIG Chairs working as an SRE at that time. I like that we provide opportunities for newcomers to contribute through using, testing, and providing feedback on our subprojects, which is a lower barrier to entry. Because many of these projects are out-of-tree, I think one of our challenges is to figure out what’s in scope for core Kubernetes SIGs instrumentation subprojects, what’s missing, and then fill in the gaps. +**Elana (EH)**: I think SIG Instrumentation is a really interesting SIG because it +poses different kinds of opportunities to get involved than in other SIGs. You don’t +have to be a software developer to contribute to our SIG! All of our components and +subprojects are focused on better understanding Kubernetes and its performance in +production, which allowed me to get involved as one of the few SIG Chairs working as +an SRE at that time. I like that we provide opportunities for newcomers to contribute +through using, testing, and providing feedback on our subprojects, which is a lower +barrier to entry. Because many of these projects are out-of-tree, I think one of our +challenges is to figure out what’s in scope for core Kubernetes SIGs instrumentation +subprojects, what’s missing, and then fill in the gaps. ## Community and contribution -**Imran (INM)**: Kubernetes values community over products. Any recommendation for anyone looking into getting involved in SIG Instrumentation work? Where should they start (new contributor-friendly areas within SIG?) +**Imran (INM)**: Kubernetes values community over products. Any recommendation +for anyone looking into getting involved in SIG Instrumentation work? Where +should they start (new contributor-friendly areas within SIG?) -**Han(HK) and Elana (EH)**: Come to our bi-weekly triage [meetings](https://github.com/kubernetes/community/tree/master/sig-instrumentation#meetings)! They aren’t recorded and are a great place to ask questions and learn about our ongoing work. We strive to be a friendly community and one of the easiest SIGs to get started with. You can check out our latest KubeCon NA 2022 [SIG Instrumentation Deep Dive](https://youtu.be/JIzrlWtAA8Y) to get more insight into our work. We also invite you to join our Slack channel #sig-instrumentation and feel free to reach out to any of our SIG leads or subproject owners directly. +**Han(HK) and Elana (EH)**: Come to our bi-weekly triage +[meetings](https://github.com/kubernetes/community/tree/master/sig-instrumentation#meetings)! +They aren’t recorded and are a great place to ask questions and learn about our ongoing work. +We strive to be a friendly community and one of the easiest SIGs to get started with. +You can check out our latest KubeCon NA 2022 [SIG Instrumentation Deep Dive](https://youtu.be/JIzrlWtAA8Y) +to get more insight into our work. We also invite you to join our Slack channel #sig-instrumentation +and feel free to reach out to any of our SIG leads or subproject owners directly. Thank you so much for your time and insights into the workings of SIG Instrumentation! From ca3daacc172c45c6c5e4cbeab20ae1f2929ba337 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 6 Feb 2023 20:37:55 +0900 Subject: [PATCH 103/279] remove obsolete caution about cordon --- content/ja/docs/concepts/architecture/nodes.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/content/ja/docs/concepts/architecture/nodes.md b/content/ja/docs/concepts/architecture/nodes.md index c61b63b63d1..582f3172e2b 100644 --- a/content/ja/docs/concepts/architecture/nodes.md +++ b/content/ja/docs/concepts/architecture/nodes.md @@ -223,11 +223,6 @@ kubeletが`NodeStatus`とLeaseオブジェクトの作成および更新を担 ノードコントローラーは、Podがtaintを許容しない場合、 `NoExecute`のtaintを持つノード上で実行されているPodを排除する責務もあります。 さらに、ノードコントローラーはノードに到達できない、または準備ができていないなどのノードの問題に対応する{{< glossary_tooltip text="taint" term_id="taint" >}}を追加する責務があります。これはスケジューラーが、問題のあるノードにPodを配置しない事を意味しています。 -{{< caution >}} -`kubectl cordon`はノードに'unschedulable'としてマークします。それはロードバランサーのターゲットリストからノードを削除するという -サービスコントローラーの副次的な効果をもたらします。これにより、ロードバランサトラフィックの流入をcordonされたノードから効率的に除去する事ができます。 -{{< /caution >}} - ### ノードのキャパシティ {#node-capacity} Nodeオブジェクトはノードのリソースキャパシティ(CPUの数とメモリの量)を監視します。 From 6fc72c068078685d3a92c668f36081cb5f59870b Mon Sep 17 00:00:00 2001 From: Qiming Teng Date: Tue, 31 Jan 2023 16:16:33 +0800 Subject: [PATCH 104/279] Fix examples test for newly changed example manifest The newly changed `my-scheduler.yaml` breaks the test case. This PR fixes it. --- content/en/examples/examples_test.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/content/en/examples/examples_test.go b/content/en/examples/examples_test.go index 670131237da..82c2fdc14aa 100644 --- a/content/en/examples/examples_test.go +++ b/content/en/examples/examples_test.go @@ -320,6 +320,8 @@ func validateObject(obj runtime.Object) (errors field.ErrorList) { case *rbac.ClusterRoleBinding: // clusterolebinding does not accept namespace errors = rbac_validation.ValidateClusterRoleBinding(t) + case *rbac.RoleBinding: + errors = rbac_validation.ValidateRoleBinding(t) case *storage.StorageClass: // storageclass does not accept namespace errors = storage_validation.ValidateStorageClass(t) @@ -454,7 +456,7 @@ func TestExampleObjectSchemas(t *testing.T) { }, "admin/sched": { "clusterrole": {&rbac.ClusterRole{}}, - "my-scheduler": {&api.ServiceAccount{}, &rbac.ClusterRoleBinding{}, &rbac.ClusterRoleBinding{}, &api.ConfigMap{}, &apps.Deployment{}}, + "my-scheduler": {&api.ServiceAccount{}, &rbac.ClusterRoleBinding{}, &rbac.ClusterRoleBinding{}, &rbac.RoleBinding{}, &api.ConfigMap{}, &apps.Deployment{}}, "pod1": {&api.Pod{}}, "pod2": {&api.Pod{}}, "pod3": {&api.Pod{}}, From 42585e32966739b74e9e2925bc84b6252f803172 Mon Sep 17 00:00:00 2001 From: Asare Nkansah Date: Mon, 6 Feb 2023 08:30:50 -0700 Subject: [PATCH 105/279] Add cleanup commands to kubectl Windows install --- .../en/docs/tasks/tools/install-kubectl-windows.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/content/en/docs/tasks/tools/install-kubectl-windows.md b/content/en/docs/tasks/tools/install-kubectl-windows.md index 0e7bc7c53e0..84dd47c6b9a 100644 --- a/content/en/docs/tasks/tools/install-kubectl-windows.md +++ b/content/en/docs/tasks/tools/install-kubectl-windows.md @@ -72,6 +72,12 @@ The following methods exist for installing kubectl on Windows: kubectl version --client --output=yaml ``` +1. After installing the plugin, clean up the installation files: + + ```bash + del kubectl.exe kubectl.exe.sha256 + ``` + {{< note >}} [Docker Desktop for Windows](https://docs.docker.com/docker-for-windows/#kubernetes) adds its own version of `kubectl` to `PATH`. If you have installed Docker Desktop before, you may need to place your `PATH` entry before the one added by the Docker Desktop installer or remove the Docker Desktop's `kubectl`. @@ -191,6 +197,12 @@ Below are the procedures to set up autocompletion for PowerShell. If you do not see an error, it means the plugin is successfully installed. +1. After installing the plugin, clean up the installation files: + + ```bash + del kubectl-convert.exe kubectl-convert.exe.sha256 + ``` + ## {{% heading "whatsnext" %}} {{< include "included/kubectl-whats-next.md" >}} From 417c97f79fd0451aab241741140c9fcffd7a5acc Mon Sep 17 00:00:00 2001 From: Kinzhi Date: Mon, 6 Feb 2023 01:30:53 +0800 Subject: [PATCH 106/279] [zh-cn]SYNC node-v1.md [zh-cn]SYNC node-v1.md --- .../kubernetes-api/cluster-resources/node-v1.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/content/zh-cn/docs/reference/kubernetes-api/cluster-resources/node-v1.md b/content/zh-cn/docs/reference/kubernetes-api/cluster-resources/node-v1.md index e2d351be1d9..21b7a6c99bc 100644 --- a/content/zh-cn/docs/reference/kubernetes-api/cluster-resources/node-v1.md +++ b/content/zh-cn/docs/reference/kubernetes-api/cluster-resources/node-v1.md @@ -85,11 +85,10 @@ NodeSpec 描述了创建节点时使用的属性。 - **configSource** (NodeConfigSource) - 已弃用:以前用于为 DynamicKubeletConfig 功能指定节点配置的来源。 - 自 1.24 的版本起,此功能已从 Kubelets 中移除,并将在 1.26 的版本中完全移除。 + 已弃用:以前用于为 DynamicKubeletConfig 功能指定节点配置的来源。此功能已删除。 **补丁策略:根据 `type` 键执行合并操作** @@ -293,7 +292,7 @@ NodeStatus 是有关节点当前状态的信息。 注意:该字段声明为可合并,但合并键不够唯一,合并时可能导致数据损坏。 调用者应改为使用完全替换性质的补丁操作。 - 有关示例,请参见 http://pr.k8s.io/79391。 + 有关示例,请参见 https://pr.k8s.io/79391。 @@ -351,7 +352,8 @@ JobSpec 描述了任务执行的情况。 - 此字段为 Beta 级别。任务控制器仅在启用特性门控 JobTrackingWithFinalizers 时使用此字段(默认启用)。 使用此字段可能无法跟踪旧任务,在这种情况下,该字段保持为空。 From 4fa2ae1f7685d4216cf936fa7d4467606810c7ba Mon Sep 17 00:00:00 2001 From: Kinzhi Date: Tue, 7 Feb 2023 00:38:09 +0800 Subject: [PATCH 108/279] [zh-cn]SYNC kubeadm_init.md --- .../reference/setup-tools/kubeadm/generated/kubeadm_init.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/zh-cn/docs/reference/setup-tools/kubeadm/generated/kubeadm_init.md b/content/zh-cn/docs/reference/setup-tools/kubeadm/generated/kubeadm_init.md index 91d7d476b23..395e6ff9e3a 100644 --- a/content/zh-cn/docs/reference/setup-tools/kubeadm/generated/kubeadm_init.md +++ b/content/zh-cn/docs/reference/setup-tools/kubeadm/generated/kubeadm_init.md @@ -27,7 +27,7 @@ Run this command in order to set up the Kubernetes control plane 运行此命令来搭建 Kubernetes 控制平面节点。 "init" 命令执行以下阶段: @@ -69,6 +69,7 @@ kubelet-finalize Updates settings relevant to the kubelet after TLS addon Install required addons for passing Conformance tests /coredns Install the CoreDNS addon to a Kubernetes cluster /kube-proxy Install the kube-proxy addon to a Kubernetes cluster +show-join-command Show the join command for control-plane and worker node ``` ``` @@ -230,12 +231,11 @@ Don't apply any changes; just output what would be done. 一组用来描述各种功能特性的键值(key=value)对。选项是:
    PublicKeysECDSA=true|false (ALPHA - 默认值=false)
    RootlessControlPlane=true|false (ALPHA - 默认值=false) -
    UnversionedKubeletConfigMap=true|false (默认值=true) From a9d7e2bca7d82cffc744731e3bc15c8597662813 Mon Sep 17 00:00:00 2001 From: Mahamed Date: Mon, 6 Feb 2023 16:55:01 +0000 Subject: [PATCH 109/279] Freeze `k8s.gcr.io` image registry (#39214) * freeze the old registry * apply tim's suggestions * apply sergey's suggestions * fix some typos --- ...23-02-06-k8s-gcr-io-freeze-announcement.md | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 content/en/blog/_posts/2023-02-06-k8s-gcr-io-freeze-announcement.md diff --git a/content/en/blog/_posts/2023-02-06-k8s-gcr-io-freeze-announcement.md b/content/en/blog/_posts/2023-02-06-k8s-gcr-io-freeze-announcement.md new file mode 100644 index 00000000000..3a1fbbf7d63 --- /dev/null +++ b/content/en/blog/_posts/2023-02-06-k8s-gcr-io-freeze-announcement.md @@ -0,0 +1,50 @@ +--- +layout: blog +title: "k8s.gcr.io image registry will be frozen from the 3rd of April 2023" +date: 2023-02-06 +slug: k8s-gcr-io-freeze-announcement +--- + +**Authors**: Mahamed Ali (Rackspace Technology) + +The Kubernetes project runs a community-owned image registry called `registry.k8s.io` to host its container images. On the 3rd of April 2023, the old registry `k8s.gcr.io` will be frozen and no further images for Kubernetes and related subprojects will be pushed to the old registry. + +This registry `registry.k8s.io` replaced the old one and has been generally available for several months. We have published a [blog post](/blog/2022/11/28/registry-k8s-io-faster-cheaper-ga/) about its benefits to the community and the Kubernetes project. This post also announced that future versions of Kubernetes will not be available in the old registry. Now that time has come. + +What does this change mean for contributors: +- If you are a maintainer of a subproject, you will need to update your manifests and Helm charts to use the new registry. + +What does this change mean for end users: +- 1.27 Kubernetes release will not be published to the old registry. +- Patch releases for 1.24, 1.25, and 1.26 will no longer be published to the old registry from April. Please read the timelines below for details of the final patch releases in the old registry. +- Starting in 1.25, the default image registry has been set to `registry.k8s.io`. This value is overridable in `kubeadm` and `kubelet` but setting it to `k8s.gcr.io` will fail for new releases after April as they won’t be present in the old registry. +- If you want to increase the reliability of your cluster and remove dependency on the community-owned registry or you are running Kubernetes in networks where external traffic is restricted, you should consider hosting local image registry mirrors. Some cloud vendors may offer hosted solutions for this. + +## Timeline of the Changes: + +- `k8s.gcr.io` will be frozen on the 3rd of April 2023 +- 1.27 is expected to be released on the 12th of April 2023 +- The last 1.23 release on `k8s.gcr.io` will be 1.23.18 (1.23 goes EoL before the freeze) +- The last 1.24 release on `k8s.gcr.io` will be 1.24.12 +- The last 1.25 release on `k8s.gcr.io` will be 1.25.8 +- The last 1.26 release on `k8s.gcr.io` will be 1.26.3 + +## What's next + +Please make sure your cluster does not have dependencies on old image registry. For example, you can run this command to list the images used by pods: + + +```shell +kubectl get pods --all-namespaces -o jsonpath="{.items[*].spec.containers[*].image}" |\ +tr -s '[[:space:]]' '\n' |\ +sort |\ +uniq -c +``` + +There may be other dependencies on the old image registry. Make sure you review any potential dependencies to keep your cluster healthy and up to date. + +## Acknowledgments + +__Change is hard__, and evolving our image-serving platform is needed to ensure a sustainable future for the project. We strive to make things better for everyone using Kubernetes. Many contributors from all corners of our community have been working long and hard to ensure we are making the best decisions possible, executing plans, and doing our best to communicate those plans. + +Thanks to Aaron Crickenberger, Arnaud Meukam, Benjamin Elder, Caleb Woodbine, Davanum Srinivas, Mahamed Ali, and Tim Hockin from SIG K8s Infra, Brian McQueen, and Sergey Kanzhelev from SIG Node, Lubomir Ivanov from SIG Cluster Lifecycle, Adolfo García Veytia, Jeremy Rickard, Sascha Grunert, and Stephen Augustus from SIG Release, Bob Killen and Kaslin Fields from SIG Contribex, Tim Allclair from the Security Response Committee. Also a big thank you to our friends acting as liaisons with our cloud provider partners: Jay Pipes from Amazon and Jon Johnson Jr. from Google. From 679d205d3d52c99192558a60dd67b52471d39aaa Mon Sep 17 00:00:00 2001 From: Shannon Kularathna Date: Tue, 15 Nov 2022 23:15:52 +0000 Subject: [PATCH 110/279] Clean up wording and remove duplicate content Trim environment variable content in concept - Remove steps and link to the relevant task - Add a brief intro to task heading Clean up wording about Secrets as env vars - Improve clarity of the list items - Improve clarity of the intro paragraph for invalid vars Delete environment variable use case --- .../en/docs/concepts/configuration/secret.md | 163 +++++------------- .../distribute-credentials-secure.md | 20 ++- 2 files changed, 57 insertions(+), 126 deletions(-) diff --git a/content/en/docs/concepts/configuration/secret.md b/content/en/docs/concepts/configuration/secret.md index 05680c9cbde..b88ccd0e0d9 100644 --- a/content/en/docs/concepts/configuration/secret.md +++ b/content/en/docs/concepts/configuration/secret.md @@ -165,15 +165,35 @@ for that Pod, including details of the problem fetching the Secret. #### Optional Secrets {#restriction-secret-must-exist} -When you define a container environment variable based on a Secret, -you can mark it as _optional_. The default is for the Secret to be -required. +When you reference a Secret in a Pod, you can mark the Secret as _optional_, +such as in the following example. If an optional Secret doesn't exist, +Kubernetes ignores it. -None of a Pod's containers will start until all non-optional Secrets are -available. +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: mypod +spec: + containers: + - name: mypod + image: redis + volumeMounts: + - name: foo + mountPath: "/etc/foo" + readOnly: true + volumes: + - name: foo + secret: + secretName: mysecret + optional: true +``` -If a Pod references a specific key in a Secret and that Secret does exist, but -is missing the named key, the Pod fails during startup. +By default, Secrets are required. None of a Pod's containers will start until +all non-optional Secrets are available. + +If a Pod references a specific key in a non-optional Secret and that Secret +does exist, but is missing the named key, the Pod fails during startup. ### Using Secrets as files from a Pod {#using-secrets-as-files-from-a-pod} @@ -232,53 +252,23 @@ watch propagation delay, the configured cache TTL, or zero for direct polling). To use a Secret in an {{< glossary_tooltip text="environment variable" term_id="container-env-variables" >}} in a Pod: -1. Create a Secret (or use an existing one). Multiple Pods can reference the same Secret. -1. Modify your Pod definition in each container that you wish to consume the value of a secret - key to add an environment variable for each secret key you wish to consume. The environment - variable that consumes the secret key should populate the secret's name and key in `env[].valueFrom.secretKeyRef`. -1. Modify your image and/or command line so that the program looks for values in the specified - environment variables. - -This is an example of a Pod that uses a Secret via environment variables: - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: secret-env-pod -spec: - containers: - - name: mycontainer - image: redis - env: - - name: SECRET_USERNAME - valueFrom: - secretKeyRef: - name: mysecret - key: username - optional: false # same as default; "mysecret" must exist - # and include a key named "username" - - name: SECRET_PASSWORD - valueFrom: - secretKeyRef: - name: mysecret - key: password - optional: false # same as default; "mysecret" must exist - # and include a key named "password" - restartPolicy: Never -``` +1. For each container in your Pod specification, add an environment variable + for each Secret key that you want to use to the + `env[].valueFrom.secretKeyRef` field. +1. Modify your image and/or command line so that the program looks for values + in the specified environment variables. +For instructions, refer to +[Define container environment variables using Secret data](/docs/tasks/inject-data-application/distribute-credentials-secure/#define-container-environment-variables-using-secret-data). #### Invalid environment variables {#restriction-env-from-invalid} -Secrets used to populate environment variables by the `envFrom` field that have keys -that are considered invalid environment variable names will have those keys -skipped. The Pod is allowed to start. +If your environment variable definitions in your Pod specification are +considered to be invalid environment variable names, those keys aren't made +available to your container. The Pod is allowed to start. -If you define a Pod with an invalid variable name, the failed Pod startup includes -an event with the reason set to `InvalidVariableNames` and a message that lists the -skipped invalid keys. The following example shows a Pod that refers to a Secret -named `mysecret`, where `mysecret` contains 2 invalid keys: `1badkey` and `2alsobad`. +Kubernetes adds an Event with the reason set to `InvalidVariableNames` and a +message that lists the skipped invalid keys. The following example shows a Pod that refers to a Secret named `mysecret`, where `mysecret` contains 2 invalid keys: `1badkey` and `2alsobad`. ```shell kubectl get events @@ -291,42 +281,6 @@ LASTSEEN FIRSTSEEN COUNT NAME KIND SUBOBJECT 0s 0s 1 dapi-test-pod Pod Warning InvalidEnvironmentVariableNames kubelet, 127.0.0.1 Keys [1badkey, 2alsobad] from the EnvFrom secret default/mysecret were skipped since they are considered invalid environment variable names. ``` - -#### Consuming Secret values from environment variables - -Inside a container that consumes a Secret using environment variables, the secret keys appear -as normal environment variables. The values of those variables are the base64 decoded values -of the secret data. - -This is the result of commands executed inside the container from the example above: - -```shell -echo "$SECRET_USERNAME" -``` - -The output is similar to: - -``` -admin -``` - -```shell -echo "$SECRET_PASSWORD" -``` - -The output is similar to: - -``` -1f2d1e2e67df -``` - -{{< note >}} -If a container already consumes a Secret in an environment variable, -a Secret update will not be seen by the container unless it is -restarted. There are third party solutions for triggering restarts when -secrets change. -{{< /note >}} - ### Container image pull secrets {#using-imagepullsecrets} If you want to fetch container images from a private repository, you need a way for @@ -369,43 +323,10 @@ You cannot use ConfigMaps or Secrets with {{< glossary_tooltip text="static Pods ## Use cases -### Use case: As container environment variables +### Use case: As container environment variables {#use-case-as-container-environment-variables} -Create a secret -```yaml -apiVersion: v1 -kind: Secret -metadata: - name: mysecret -type: Opaque -data: - USER_NAME: YWRtaW4= - PASSWORD: MWYyZDFlMmU2N2Rm -``` - -Create the Secret: -```shell -kubectl apply -f mysecret.yaml -``` - -Use `envFrom` to define all of the Secret's data as container environment variables. The key from -the Secret becomes the environment variable name in the Pod. - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: secret-test-pod -spec: - containers: - - name: test-container - image: registry.k8s.io/busybox - command: [ "/bin/sh", "-c", "env" ] - envFrom: - - secretRef: - name: mysecret - restartPolicy: Never -``` +You can create a Secret and use it to +[set environment variables for a container](/docs/tasks/inject-data-application/distribute-credentials-secure/#define-container-environment-variables-using-secret-data). ### Use case: Pod with SSH keys diff --git a/content/en/docs/tasks/inject-data-application/distribute-credentials-secure.md b/content/en/docs/tasks/inject-data-application/distribute-credentials-secure.md index c6dc32043a1..c037dea7cdc 100644 --- a/content/en/docs/tasks/inject-data-application/distribute-credentials-secure.md +++ b/content/en/docs/tasks/inject-data-application/distribute-credentials-secure.md @@ -199,7 +199,8 @@ following: You can set the POSIX file access permission bits for a single Secret key. If you don't specify any permissions, `0644` is used by default. -You can also set a default mode for the entire Secret volume and override per key if needed. +You can also set a default POSIX file mode for the entire Secret volume, and +you can override per key if needed. For example, you can specify a default mode like this: @@ -222,18 +223,27 @@ spec: defaultMode: 0400 ``` -The secret is mounted on `/etc/foo`; all the files created by the +The Secret is mounted on `/etc/foo`; all the files created by the secret volume mount have permission `0400`. {{< note >}} If you're defining a Pod or a Pod template using JSON, beware that the JSON -specification doesn't support octal notation. You can use the decimal value -for the `defaultMode` (for example, 0400 in octal is 256 in decimal) instead. -If you're writing YAML, you can write the `defaultMode` in octal. +specification doesn't support octal literals for numbers because JSON considers +`0400` to be the _decimal_ value `400`. In JSON, use decimal values for the +`defaultMode` instead. If you're writing YAML, you can write the `defaultMode` +in octal. {{< /note >}} ## Define container environment variables using Secret data +You can consume the data in Secrets as environment variables in your +containers. + +If a container already consumes a Secret in an environment variable, +a Secret update will not be seen by the container unless it is +restarted. There are third party solutions for triggering restarts when +secrets change. + ### Define a container environment variable with data from a single Secret * Define an environment variable as a key-value pair in a Secret: From 68b19b6f000609c0de904d0d6b4af0f7ff9e8b8d Mon Sep 17 00:00:00 2001 From: Richard Tweed Date: Mon, 6 Feb 2023 22:33:00 +0000 Subject: [PATCH 111/279] Specify that subresources excluded from mutating webhook example --- .../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 05f9b8369c0..da59b907c48 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 @@ -591,7 +591,7 @@ is not considered to match. Use the object selector only if the webhook is opt-in, because end users may skip the admission webhook by setting the labels. -This example shows a mutating webhook that would match a `CREATE` of any resource with the label `foo: bar`: +This example shows a mutating webhook that would match a `CREATE` of any resource (but not subresources) with the label `foo: bar`: ```yaml apiVersion: admissionregistration.k8s.io/v1 From 971265856d7330af1396f81bcfcb05de84455ed6 Mon Sep 17 00:00:00 2001 From: Arhell Date: Tue, 7 Feb 2023 00:48:07 +0200 Subject: [PATCH 112/279] [zh] updated nginx version to follow examples correctly --- content/zh-cn/examples/application/deployment-scale.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/zh-cn/examples/application/deployment-scale.yaml b/content/zh-cn/examples/application/deployment-scale.yaml index f6c43ab7f41..c1043f71629 100644 --- a/content/zh-cn/examples/application/deployment-scale.yaml +++ b/content/zh-cn/examples/application/deployment-scale.yaml @@ -14,6 +14,6 @@ spec: spec: containers: - name: nginx - image: nginx:1.14.2 + image: nginx:1.16.1 ports: - containerPort: 80 From 04add1a96ba923211a414ce9ba6356cc8a6389ef Mon Sep 17 00:00:00 2001 From: Tim Bannister Date: Mon, 6 Feb 2023 23:42:13 +0000 Subject: [PATCH 113/279] Fix weight for Pod QoS Class concept --- content/en/docs/concepts/workloads/pods/pod-qos.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/docs/concepts/workloads/pods/pod-qos.md b/content/en/docs/concepts/workloads/pods/pod-qos.md index 0328df65ae0..b2035c520f4 100644 --- a/content/en/docs/concepts/workloads/pods/pod-qos.md +++ b/content/en/docs/concepts/workloads/pods/pod-qos.md @@ -1,7 +1,7 @@ --- title: Pod Quality of Service Classes content_type: concept -weight: 30 +weight: 85 --- From e3fb1a803ed5da5af559d98fb760acc3fa392936 Mon Sep 17 00:00:00 2001 From: vaibhav2107 Date: Tue, 7 Feb 2023 05:13:34 +0530 Subject: [PATCH 114/279] Added the glossary tooltips to Virtual IPs and Service Proxies --- .../docs/reference/networking/virtual-ips.md | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/content/en/docs/reference/networking/virtual-ips.md b/content/en/docs/reference/networking/virtual-ips.md index af3899a703d..1b689309ada 100644 --- a/content/en/docs/reference/networking/virtual-ips.md +++ b/content/en/docs/reference/networking/virtual-ips.md @@ -6,7 +6,8 @@ weight: 50 Every {{< glossary_tooltip term_id="node" text="node" >}} in a Kubernetes -cluster runs a [kube-proxy](/docs/reference/command-line-tools-reference/kube-proxy/) +{{< glossary_tooltip term_id="cluster" text="cluster" >}} runs a +[kube-proxy](/docs/reference/command-line-tools-reference/kube-proxy/) (unless you have deployed your own alternative component in place of `kube-proxy`). The `kube-proxy` component is responsible for implementing a _virtual IP_ @@ -39,8 +40,10 @@ network proxying service on a computer. Although the `kube-proxy` executable su to use as-is. -Some of the details in this reference refer to an example: the backend Pods for a stateless -image-processing workload, running with three replicas. Those replicas are +Some of the details in this reference refer to an example: the backend +{{< glossary_tooltip term_id="pod" text="Pods" >}} for a stateless +image-processing {{< glossary_tooltip term_id="workloads" text="workload," >}} running with +three replicas. Those replicas are fungible—frontends do not care which backend they use. While the actual Pods that compose the backend set may change, the frontend clients should not need to be aware of that, nor should they need to keep track of the set of backends themselves. @@ -61,8 +64,10 @@ Note that the kube-proxy starts up in different modes, which are determined by i ### `iptables` proxy mode {#proxy-mode-iptables} -In this mode, kube-proxy watches the Kubernetes control plane for the addition and -removal of Service and EndpointSlice objects. For each Service, it installs +In this mode, kube-proxy watches the Kubernetes +{{< glossary_tooltip term_id="control-plane" text="control plane" >}} for the addition and +removal of Service and EndpointSlice {{< glossary_tooltip term_id="object" text="objects." >}} +For each Service, it installs iptables rules, which capture traffic to the Service's `clusterIP` and `port`, and redirect that traffic to one of the Service's backend sets. For each endpoint, it installs iptables rules which @@ -134,11 +139,13 @@ attempts to resynchronize iptables rules with the kernel. If it is every time any Service or Endpoint changes. This works fine in very small clusters, but it results in a lot of redundant work when lots of things change in a small time period. For example, if you have a -Service backed by a Deployment with 100 pods, and you delete the +Service backed by a {{< glossary_tooltip term_id="deployment" text="Deployment" >}} +with 100 pods, and you delete the Deployment, then with `minSyncPeriod: 0s`, kube-proxy would end up removing the Service's Endpoints from the iptables rules one by one, for a total of 100 updates. With a larger `minSyncPeriod`, multiple -Pod deletion events would get aggregated together, so kube-proxy might +Pod deletion {{< glossary_tooltip term_id="event" text="events" >}} would get aggregated +together, so kube-proxy might instead end up making, say, 5 updates, each removing 20 endpoints, which will be much more efficient in terms of CPU, and result in the full set of changes being synchronized faster. @@ -182,7 +189,8 @@ enable the `MinimizeIPTablesRestore` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/) for kube-proxy with `--feature-gates=MinimizeIPTablesRestore=true,…`. -If you enable that feature gate and you were previously overriding +If you enable that {{< glossary_tooltip term_id="feature-gate" text="feature gate" >}} and +you were previously overriding `minSyncPeriod`, you should try removing that override and letting kube-proxy use the default value (`1s`) or at least a smaller value than you were using before. @@ -274,7 +282,7 @@ someone else's choice. That is an isolation failure. In order to allow you to choose a port number for your Services, we must ensure that no two Services can collide. Kubernetes does that by allocating each Service its own IP address from within the `service-cluster-ip-range` -CIDR range that is configured for the API server. +CIDR range that is configured for the {{< glossary_tooltip term_id="kube-apiserver" text="API Server." >}} To ensure each Service receives a unique IP, an internal allocator atomically updates a global allocation map in {{< glossary_tooltip term_id="etcd" >}} @@ -353,7 +361,8 @@ N to 0 replicas of that deployment. In some cases, external load balancers can s a node with 0 replicas in between health check probes. Routing traffic to terminating endpoints ensures that Node's that are scaling down Pods can gracefully receive and drain traffic to those terminating Pods. By the time the Pod completes termination, the external load balancer -should have seen the node's health check failing and fully removed the node from the backend pool. +should have seen the node's health check failing and fully removed the node from the backend +pool. ## {{% heading "whatsnext" %}} From d7fdb03e707d5b3f1d60f77a8f36e67ee36a06c0 Mon Sep 17 00:00:00 2001 From: Tim Bannister Date: Mon, 6 Feb 2023 23:42:56 +0000 Subject: [PATCH 115/279] Fix broken link in glossary --- content/en/docs/reference/glossary/qos-class.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/docs/reference/glossary/qos-class.md b/content/en/docs/reference/glossary/qos-class.md index a8a66bbf024..475c9f2d01b 100644 --- a/content/en/docs/reference/glossary/qos-class.md +++ b/content/en/docs/reference/glossary/qos-class.md @@ -2,7 +2,7 @@ title: QoS Class id: qos-class date: 2019-04-15 -full_link: /docs/concepts/workloads/pods/pod-quality/ +full_link: /docs/concepts/workloads/pods/pod-qos/ short_description: > QoS Class (Quality of Service Class) provides a way for Kubernetes to classify pods within the cluster into several classes and make decisions about scheduling and eviction. From d5039e8c671e742357b76f468943e9493c77e81a Mon Sep 17 00:00:00 2001 From: Tim Bannister Date: Mon, 6 Feb 2023 23:43:49 +0000 Subject: [PATCH 116/279] Tidy Pod QoS config task --- .../quality-service-pod.md | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/content/en/docs/tasks/configure-pod-container/quality-service-pod.md b/content/en/docs/tasks/configure-pod-container/quality-service-pod.md index 40227171551..562741c7e87 100644 --- a/content/en/docs/tasks/configure-pod-container/quality-service-pod.md +++ b/content/en/docs/tasks/configure-pod-container/quality-service-pod.md @@ -8,28 +8,28 @@ weight: 30 This page shows how to configure Pods so that they will be assigned particular -Quality of Service (QoS) classes. Kubernetes uses QoS classes to make decisions about evicting Pods when Node resources are exceeded. +{{< glossary_tooltip text="Quality of Service (QoS) classes" term_id="qos-class" >}}. +Kubernetes uses QoS classes to make decisions about evicting Pods when Node resources are exceeded. +When Kubernetes creates a Pod it assigns one of these QoS classes to the Pod: + +* [Guaranteed](/docs/concepts/workloads/pods/pod-qos/#guaranteed) +* [Burstable](/docs/concepts/workloads/pods/pod-qos/#burstable) +* [BestEffort](/docs/concepts/workloads/pods/pod-qos/#besteffort) ## {{% heading "prerequisites" %}} -{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} +{{< include "task-tutorial-prereqs.md" >}} +You also need to be able to create and delete namespaces. -## QoS classes - -When Kubernetes creates a Pod it assigns one of these QoS classes to the Pod: - -* Guaranteed -* Burstable -* BestEffort ## Create a namespace @@ -42,7 +42,7 @@ kubectl create namespace qos-example ## Create a Pod that gets assigned a QoS class of Guaranteed -For a Pod to be given a QoS class of Guaranteed: +For a Pod to be given a QoS class of `Guaranteed`: * 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. @@ -53,7 +53,7 @@ These restrictions apply to init containers and app containers equally. [Ephemeral containers](/docs/concepts/workloads/pods/ephemeral-containers/) cannot define resources so these restrictions do not apply. -Here is the configuration file for a Pod that has one Container. The Container has a memory limit and a +Here is a manifest 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: {{< codenew file="pods/qos/qos-pod.yaml" >}} @@ -70,7 +70,7 @@ View detailed information about the Pod: kubectl get pod qos-demo --namespace=qos-example --output=yaml ``` -The output shows that Kubernetes gave the Pod a QoS class of Guaranteed. The output also +The output shows that Kubernetes gave the Pod a QoS class of `Guaranteed`. The output also verifies that the Pod Container has a memory request that matches its memory limit, and it has a CPU request that matches its CPU limit. @@ -105,12 +105,12 @@ kubectl delete pod qos-demo --namespace=qos-example ## Create a Pod that gets assigned a QoS class of Burstable -A Pod is given a QoS class of Burstable if: +A Pod is given a QoS class of `Burstable` if: -* The Pod does not meet the criteria for QoS class Guaranteed. +* The Pod does not meet the criteria for QoS class `Guaranteed`. * At least one Container in the Pod has a memory or CPU request or limit. -Here is the configuration file for a Pod that has one Container. The Container has a memory limit of 200 MiB +Here is a manifest for a Pod that has one Container. The Container has a memory limit of 200 MiB and a memory request of 100 MiB. {{< codenew file="pods/qos/qos-pod-2.yaml" >}} @@ -127,7 +127,7 @@ View detailed information about the Pod: kubectl get pod qos-demo-2 --namespace=qos-example --output=yaml ``` -The output shows that Kubernetes gave the Pod a QoS class of Burstable. +The output shows that Kubernetes gave the Pod a QoS class of `Burstable`: ```yaml spec: @@ -153,10 +153,10 @@ kubectl delete pod qos-demo-2 --namespace=qos-example ## Create a Pod that gets assigned a QoS class of BestEffort -For a Pod to be given a QoS class of BestEffort, the Containers in the Pod must not +For a Pod to be given a QoS class of `BestEffort`, the Containers in the Pod must not have any memory or CPU limits or requests. -Here is the configuration file for a Pod that has one Container. The Container has no memory or CPU +Here is a manifest for a Pod that has one Container. The Container has no memory or CPU limits or requests: {{< codenew file="pods/qos/qos-pod-3.yaml" >}} @@ -173,7 +173,7 @@ View detailed information about the Pod: kubectl get pod qos-demo-3 --namespace=qos-example --output=yaml ``` -The output shows that Kubernetes gave the Pod a QoS class of BestEffort. +The output shows that Kubernetes gave the Pod a QoS class of `BestEffort`: ```yaml spec: @@ -193,13 +193,13 @@ kubectl delete pod qos-demo-3 --namespace=qos-example ## Create a Pod that has two Containers -Here is the configuration file for a Pod that has two Containers. One container specifies a memory +Here is a manifest for a Pod that has two Containers. One container specifies a memory request of 200 MiB. The other Container does not specify any requests or limits. {{< codenew file="pods/qos/qos-pod-4.yaml" >}} -Notice that this Pod meets the criteria for QoS class Burstable. That is, it does not meet the -criteria for QoS class Guaranteed, and one of its Containers has a memory request. +Notice that this Pod meets the criteria for QoS class `Burstable`. That is, it does not meet the +criteria for QoS class `Guaranteed`, and one of its Containers has a memory request. Create the Pod: @@ -213,7 +213,7 @@ View detailed information about the Pod: kubectl get pod qos-demo-4 --namespace=qos-example --output=yaml ``` -The output shows that Kubernetes gave the Pod a QoS class of Burstable: +The output shows that Kubernetes gave the Pod a QoS class of `Burstable`: ```yaml spec: From 7d0542fd5312aa054d6bad89246e1d519bd65d47 Mon Sep 17 00:00:00 2001 From: Tim Bannister Date: Mon, 6 Feb 2023 23:46:56 +0000 Subject: [PATCH 117/279] Explain how to see QoS class for a Pod --- .../configure-pod-container/quality-service-pod.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/content/en/docs/tasks/configure-pod-container/quality-service-pod.md b/content/en/docs/tasks/configure-pod-container/quality-service-pod.md index 562741c7e87..2cf79e97fd4 100644 --- a/content/en/docs/tasks/configure-pod-container/quality-service-pod.md +++ b/content/en/docs/tasks/configure-pod-container/quality-service-pod.md @@ -231,12 +231,19 @@ status: qosClass: Burstable ``` -Delete your Pod: +## Retrieve the QoS class for a Pod -```shell -kubectl delete pod qos-demo-4 --namespace=qos-example +Rather than see all the fields, you can view just the field you need: + +```bash +kubectl --namespace=qos-example get pod qos-demo-4 -o jsonpath='{ .status.qosClass}{"\n"}' ``` +```none +Burstable +``` + + ## Clean up Delete your namespace: From fe1360fb11f5022331d3209d0b039ea88f69de28 Mon Sep 17 00:00:00 2001 From: Tim Bannister Date: Mon, 6 Feb 2023 23:47:15 +0000 Subject: [PATCH 118/279] Add headings for per-step cleanup --- .../tasks/configure-pod-container/quality-service-pod.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/content/en/docs/tasks/configure-pod-container/quality-service-pod.md b/content/en/docs/tasks/configure-pod-container/quality-service-pod.md index 2cf79e97fd4..15d324b9550 100644 --- a/content/en/docs/tasks/configure-pod-container/quality-service-pod.md +++ b/content/en/docs/tasks/configure-pod-container/quality-service-pod.md @@ -97,6 +97,9 @@ CPU limit, but does not specify a CPU request, Kubernetes automatically assigns the limit. {{< /note >}} + +#### Clean up {#clean-up-guaranteed} + Delete your Pod: ```shell @@ -145,6 +148,9 @@ status: qosClass: Burstable ``` + +#### Clean up {#clean-up-burstable} + Delete your Pod: ```shell @@ -185,6 +191,9 @@ status: qosClass: BestEffort ``` + +#### Clean up {#clean-up-besteffort} + Delete your Pod: ```shell From 058dadb2a076b1acc6e16c1f4bdbe428a4cbde6d Mon Sep 17 00:00:00 2001 From: vaibhav2107 Date: Tue, 7 Feb 2023 05:24:55 +0530 Subject: [PATCH 119/279] Corrected the glossary tooltips --- content/en/docs/reference/networking/virtual-ips.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/en/docs/reference/networking/virtual-ips.md b/content/en/docs/reference/networking/virtual-ips.md index 1b689309ada..fcf0693ef75 100644 --- a/content/en/docs/reference/networking/virtual-ips.md +++ b/content/en/docs/reference/networking/virtual-ips.md @@ -42,7 +42,7 @@ to use as-is. Some of the details in this reference refer to an example: the backend {{< glossary_tooltip term_id="pod" text="Pods" >}} for a stateless -image-processing {{< glossary_tooltip term_id="workloads" text="workload," >}} running with +image-processing workloads, running with three replicas. Those replicas are fungible—frontends do not care which backend they use. While the actual Pods that compose the backend set may change, the frontend clients should not need to be aware of that, @@ -189,7 +189,7 @@ enable the `MinimizeIPTablesRestore` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/) for kube-proxy with `--feature-gates=MinimizeIPTablesRestore=true,…`. -If you enable that {{< glossary_tooltip term_id="feature-gate" text="feature gate" >}} and +If you enable that feature gate and you were previously overriding `minSyncPeriod`, you should try removing that override and letting kube-proxy use the default value (`1s`) or at least a smaller value From 4d3c9a6fbd3e2ecb0a554e2c8df5f5617bcd9bc6 Mon Sep 17 00:00:00 2001 From: vaibhav2107 Date: Tue, 7 Feb 2023 05:40:14 +0530 Subject: [PATCH 120/279] Updated the changes for glossary tooltips in Virtual IPs and Service Proxies --- content/en/docs/reference/networking/virtual-ips.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/en/docs/reference/networking/virtual-ips.md b/content/en/docs/reference/networking/virtual-ips.md index fcf0693ef75..670960f1710 100644 --- a/content/en/docs/reference/networking/virtual-ips.md +++ b/content/en/docs/reference/networking/virtual-ips.md @@ -144,7 +144,7 @@ with 100 pods, and you delete the Deployment, then with `minSyncPeriod: 0s`, kube-proxy would end up removing the Service's Endpoints from the iptables rules one by one, for a total of 100 updates. With a larger `minSyncPeriod`, multiple -Pod deletion {{< glossary_tooltip term_id="event" text="events" >}} would get aggregated +Pod deletion events would get aggregated together, so kube-proxy might instead end up making, say, 5 updates, each removing 20 endpoints, which will be much more efficient in terms of CPU, and result in the @@ -282,7 +282,7 @@ someone else's choice. That is an isolation failure. In order to allow you to choose a port number for your Services, we must ensure that no two Services can collide. Kubernetes does that by allocating each Service its own IP address from within the `service-cluster-ip-range` -CIDR range that is configured for the {{< glossary_tooltip term_id="kube-apiserver" text="API Server." >}} +CIDR range that is configured for the {{< glossary_tooltip term_id="kube-apiserver" text="API Server" >}}. To ensure each Service receives a unique IP, an internal allocator atomically updates a global allocation map in {{< glossary_tooltip term_id="etcd" >}} From 9225137a5d129ca5b286ff1cb389131e4be2657e Mon Sep 17 00:00:00 2001 From: windsonsea Date: Tue, 7 Feb 2023 09:23:05 +0800 Subject: [PATCH 121/279] [zh] sync hello-minikube.md --- .../zh-cn/docs/tutorials/hello-minikube.md | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/content/zh-cn/docs/tutorials/hello-minikube.md b/content/zh-cn/docs/tutorials/hello-minikube.md index 6617a6ad985..1462ecd49ec 100644 --- a/content/zh-cn/docs/tutorials/hello-minikube.md +++ b/content/zh-cn/docs/tutorials/hello-minikube.md @@ -43,7 +43,7 @@ You can also follow this tutorial if you've installed minikube locally. See [minikube start](https://minikube.sigs.k8s.io/docs/start/) for installation instructions. --> 如果你已在本地安装 Minikube,也可以按照本教程操作。 -安装指南参阅 [minikube start](https://minikube.sigs.k8s.io/docs/start/) 。 +安装指南参阅 [minikube start](https://minikube.sigs.k8s.io/docs/start/)。 {{< /note >}} ## {{% heading "objectives" %}} @@ -165,11 +165,16 @@ Kubernetes [**Deployment**](/zh-cn/docs/concepts/workloads/controllers/deploymen 检查 Pod 的健康状况,并在 Pod 中的容器终止的情况下重新启动新的容器。 Deployment 是管理 Pod 创建和扩展的推荐方法。 + +1. 仅 Katacoda 环境:在终端窗格的顶部,点击加号,然后点击 **Open a new terminal**。 + -1. 使用 `kubectl create` 命令创建管理 Pod 的 Deployment。该 Pod 根据提供的 Docker +2. 使用 `kubectl create` 命令创建管理 Pod 的 Deployment。该 Pod 根据提供的 Docker 镜像运行容器。 ```shell @@ -177,9 +182,9 @@ Pod runs a Container based on the provided Docker image. ``` -2. 查看 Deployment: +3. 查看 Deployment: ```shell kubectl get deployments @@ -197,9 +202,9 @@ Pod runs a Container based on the provided Docker image. ``` -3. 查看 Pod: +4. 查看 Pod: ```shell kubectl get pods @@ -217,18 +222,18 @@ Pod runs a Container based on the provided Docker image. ``` -4. 查看集群事件: +5. 查看集群事件: ```shell kubectl get events ``` -5. 查看 `kubectl` 配置: +6. 查看 `kubectl` 配置: ```shell kubectl config view From 6e87bdd416b0677628b99a6fbfd0e59f6f83a4c7 Mon Sep 17 00:00:00 2001 From: shubham82 Date: Tue, 7 Feb 2023 14:08:27 +0900 Subject: [PATCH 122/279] Fixed the Broken Link for Quality of Service classes for Pods. --- .../docs/concepts/configuration/manage-resources-containers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/docs/concepts/configuration/manage-resources-containers.md b/content/en/docs/concepts/configuration/manage-resources-containers.md index e7bd7a485aa..25b953e1f6a 100644 --- a/content/en/docs/concepts/configuration/manage-resources-containers.md +++ b/content/en/docs/concepts/configuration/manage-resources-containers.md @@ -807,5 +807,5 @@ memory limit (and possibly request) for that container. and its [resource requirements](/docs/reference/kubernetes-api/workload-resources/pod-v1/#resources) * Read about [project quotas](https://xfs.org/index.php/XFS_FAQ#Q:_Quota:_Do_quotas_work_on_XFS.3F) in XFS * Read more about the [kube-scheduler configuration reference (v1beta3)](/docs/reference/config-api/kube-scheduler-config.v1beta3/) -* Read more about [Quality of Service classes for Pods](/docs/concepts/workloads/pods/pod-quality/) +* Read more about [Quality of Service classes for Pods](/docs/concepts/workloads/pods/pod-qos/) From 100b348192c95e047a3f4085b47dac0effc28888 Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Tue, 7 Feb 2023 13:08:32 +0800 Subject: [PATCH 123/279] [zh] Resync multi-tenancy.md --- .../docs/concepts/security/multi-tenancy.md | 637 +++++++++--------- 1 file changed, 315 insertions(+), 322 deletions(-) diff --git a/content/zh-cn/docs/concepts/security/multi-tenancy.md b/content/zh-cn/docs/concepts/security/multi-tenancy.md index 7304921fc52..ea90ab938e0 100644 --- a/content/zh-cn/docs/concepts/security/multi-tenancy.md +++ b/content/zh-cn/docs/concepts/security/multi-tenancy.md @@ -11,29 +11,31 @@ weight: 80 --> 此页面概述了集群多租户的可用配置选项和最佳实践。 共享集群可以节省成本并简化管理。 然而,共享集群也带来了诸如安全性、公平性和管理**嘈杂邻居**等挑战。 集群可以通过多种方式共享。在某些情况下,不同的应用可能会在同一个集群中运行。 在其他情况下,同一应用的多个实例可能在同一个集群中运行,每个实例对应一个最终用户。 所有这些类型的共享经常使用一个总括术语 **多租户(Multi-Tenancy)** 来表述。 虽然 Kubernetes 没有最终用户或租户的一阶概念, 它还是提供了几个特性来帮助管理不同的租户需求。下面将对此进行讨论。 @@ -44,10 +46,9 @@ it provides several features to help manage different tenancy requirements. Thes ## 用例 {#use-cases} 确定如何共享集群的第一步是理解用例,以便你可以评估可用的模式和工具。 一般来说,Kubernetes 集群中的多租户分为两大类,但也可以有许多变体和混合。 @@ -58,19 +59,19 @@ though many variations and hybrids are also possible. ### 多团队 {#multiple-teams} 多租户的一种常见形式是在组织内的多个团队之间共享一个集群,每个团队可以操作一个或多个工作负载。 这些工作负载经常需要相互通信,并与位于相同或不同集群上的其他工作负载进行通信。 在这一场景中,团队成员通常可以通过类似 `kubectl` 等工具直接访问 Kubernetes 资源, 或者通过 GitOps 控制器或其他类型的自动化发布工具间接访问 Kubernetes 资源。 @@ -83,9 +84,10 @@ but Kubernetes policies such as RBAC, quotas, and network policies are essential ### 多客户 {#multiple-customers} 多租户的另一种主要形式通常涉及为客户运行多个工作负载实例的软件即服务 (SaaS) 供应商。 @@ -94,10 +96,10 @@ and this deployment model can also be used outside of SaaS. 并且这种部署模型也可以在 SaaS 之外使用。 在这种情况下,客户无权访问集群; 从他们的角度来看,Kubernetes 是不可见的,仅由供应商用于管理工作负载。 @@ -114,17 +116,18 @@ and Kubernetes policies are used to ensure that the workloads are strongly isola ### 租户 {#tenants} 在讨论 Kubernetes 中的多租户时,“租户”没有单一的定义。 相反,租户的定义将根据讨论的是多团队还是多客户租户而有所不同。 在多团队使用中,租户通常是一个团队, 每个团队通常部署少量工作负载,这些工作负载会随着服务的复杂性而发生规模伸缩。 @@ -132,21 +135,22 @@ as teams may be organized into higher-level divisions or subdivided into smaller 因为团队可能被组织成更高级别的部门或细分为更小的团队。 相反,如果每个团队为每个新客户部署专用的工作负载,那么他们使用的是多客户租户模型。 在这种情况下,“租户”只是共享单个工作负载的一组用户。 这种租户可能大到整个公司,也可能小到该公司的一个团队。 在许多情况下,同一组织可能在不同的上下文中使用“租户”的两种定义。 例如,一个平台团队可能向多个内部“客户”提供安全工具和数据库等共享服务, @@ -165,30 +169,30 @@ combined with multi-tenant shared services. ### 隔离 {#isolation} 使用 Kubernetes 设计和构建多租户解决方案有多种方法。 每种方法都有自己的一组权衡,这些权衡会影响隔离级别、实现工作量、操作复杂性和服务成本。 Kubernetes 集群由运行 Kubernetes 软件的控制平面和由工作节点组成的数据平面组成, 租户工作负载作为 Pod 在工作节点上执行。 租户隔离可以根据组织要求应用于控制平面和数据平面。 所提供的隔离级别有时会使用一些术语来描述,例如 “硬性(Hard)” 多租户意味着强隔离, 而 “柔性(Soft)” 多租户意味着较弱的隔离。 @@ -198,22 +202,23 @@ though control plane isolation also remains critical. 尽管控制平面隔离也很关键。 但是,“硬性”和“柔性”这两个术语常常令人困惑,因为没有一种定义能够适用于所有用户。 相反,依据“硬度(Hardness)”或“柔度(Softness)”所定义的广泛谱系则更容易理解, 根据你的需求,可以使用许多不同的技术在集群中维护不同类型的隔离。 在更极端的情况下,彻底放弃所有集群级别的共享并为每个租户分配其专用集群可能更容易或有必要, 如果认为虚拟机所提供的安全边界还不够,甚至可以在专用硬件上运行。 @@ -223,9 +228,10 @@ The [Multi-cluster SIG](https://git.k8s.io/community/sig-multicluster/README.md) [Multi-Cluster SIG](https://git.k8s.io/community/sig-multicluster/README.md) 负责解决这些类型的用例。 本页的其余部分重点介绍用于共享 Kubernetes 集群的隔离技术。 但是,即使你正在考虑使用专用集群,查看这些建议也可能很有价值, @@ -237,7 +243,8 @@ as it will give you the flexibility to shift to shared clusters in the future if ## 控制面隔离 {#control-plane-isolation} 控制平面隔离确保不同租户无法访问或影响彼此的 Kubernetes API 资源。 @@ -247,35 +254,36 @@ Control plane isolation ensures that different tenants cannot access or affect e ### 命名空间 {#namespaces} 在 Kubernetes 中, {{}}提供了一种在单个集群中隔离 API 资源组的机制。 这种隔离有两个关键维度: 1. 一个命名空间中的对象名称可以与其他命名空间中的名称重叠,类似于文件夹中的文件。 这允许租户命名他们的资源,而无需考虑其他租户在做什么。 2. 许多 Kubernetes 安全策略的作用域是命名空间。 例如,RBAC Role 和 NetworkPolicy 是命名空间作用域的资源。 使用 RBAC,可以将用户和服务帐户限制在一个命名空间中。 在多租户环境中,命名空间有助于将租户的工作负载划分到各不相同的逻辑管理单元中。 事实上,一种常见的做法是将每个工作负载隔离在自己的命名空间中, @@ -283,8 +291,8 @@ This ensures that each workload has its own identity and can be configured with 这可确保每个工作负载都有自己的身份,并且可以使用适当的安全策略进行配置。 命名空间隔离模型需要配置其他几个 Kubernetes 资源、网络插件, @@ -297,10 +305,10 @@ These considerations are discussed below. ### 访问控制 {#access-controls} 控制平面最重要的隔离类型是授权。如果各个团队或其工作负载可以访问或修改彼此的 API 资源, @@ -309,13 +317,14 @@ and no more. This is known as the "Principle of Least Privilege." 而不是更多,这一点至关重要。这被称为“最小特权原则(Principle of Least Privileges)”。 基于角色的访问控制 (RBAC) 通常用于在 Kubernetes 控制平面中对用户和工作负载(服务帐户)强制执行鉴权。 [角色](/zh-cn/docs/reference/access-authn-authz/rbac/#role-and-clusterrole) @@ -324,17 +333,19 @@ Kubernetes 对象,用来在命名空间级别对应用实施访问控制; 对集群级别的对象访问鉴权也有类似的对象,不过这些对象对于多租户集群不太有用。 在多团队环境中,必须使用 RBAC 来限制租户只能访问合适的命名空间, 并确保集群范围的资源只能由集群管理员等特权用户访问或修改。 如果一个策略最终授予用户的权限比他们所需要的还多, 这可能是一个信号,表明包含受影响资源的命名空间应该被重构为更细粒度的命名空间。 @@ -347,12 +358,13 @@ while still allowing fine-grained policies where necessary. ### 配额 {#quotas} Kubernetes 工作负载消耗节点资源,例如 CPU 和内存。在多租户环境中, 你可以使用[资源配额](/zh-cn/docs/concepts/policy/resource-quotas/)来管理租户工作负载的资源使用情况。 @@ -361,13 +373,12 @@ Kubernetes 工作负载消耗节点资源,例如 CPU 和内存。在多租户 对对象计数的限制确保了公平性,并有助于避免**嘈杂邻居**问题影响共享控制平面的其他租户。 资源配额是命名空间作用域的对象。 通过将租户映射到命名空间, @@ -378,20 +389,20 @@ giving administrators far more flexibility with less effort than built-in quotas 与内置配额相比,降低了管理员的工作量,同时为其提供了更大的灵活性。 配额可防止单个租户所消耗的资源超过其被分配的份额,从而最大限度地减少**嘈杂邻居**问题, 即一个租户对其他租户工作负载的性能产生负面影响。 当你对命名空间应用配额时, Kubernetes 要求你还为每个容器指定资源请求和限制。 @@ -401,7 +412,7 @@ Kubernetes 要求你还为每个容器指定资源请求和限制。 每个容器所请求的数量都可以得到保证,但可能仍然存在跨工作负载的一些潜在影响。 配额不能针对所共享的所有资源(例如网络流量)提供保护。 @@ -413,7 +424,8 @@ Node isolation (described below) may be a better solution for this problem. ## 数据平面隔离 {#data-plane-isolation} 数据平面隔离确保不同租户的 Pod 和工作负载之间被充分隔离。 @@ -423,9 +435,10 @@ Data plane isolation ensures that pods and workloads for different tenants are s ### 网络隔离 {#network-isolation} 默认情况下,Kubernetes 集群中的所有 Pod 都可以相互通信,并且所有网络流量都是未加密的。 这可能导致安全漏洞,导致流量被意外或恶意发送到非预期目的地, @@ -457,9 +470,9 @@ Pod 之间的通信可以使用[网络策略](/zh-cn/docs/concepts/services-netw 属于不同虚拟控制平面的 Pod 不能通过 Kubernetes 网络相互通信。 命名空间管理工具可以简化默认或通用网络策略的创建。 此外,其中一些工具允许你在整个集群中强制实施一组一致的命名空间标签, @@ -467,10 +480,8 @@ ensuring that they are a trusted basis for your policies. {{< warning >}} 网络策略需要一个支持网络策略实现的 [CNI 插件](/zh-cn/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/#cni)。 @@ -478,13 +489,11 @@ Otherwise, NetworkPolicy resources will be ignored. {{< /warning >}} 服务网格可以提供更高级的网络隔离, @@ -502,8 +511,8 @@ However, they can be significantly more complex to manage and may not be appropr ### 存储隔离 {#storage-isolation} Kubernetes 提供了若干类型的卷,可以用作工作负载的持久存储。 @@ -511,20 +520,19 @@ Kubernetes 提供了若干类型的卷,可以用作工作负载的持久存储 并且应避免使用节点资源的卷类型。 [存储类(StorageClass)](/zh-cn/docs/concepts/storage/storage-classes/)允许你根据服务质量级别、 备份策略或由集群管理员确定的自定义策略描述集群提供的自定义存储“类”。 Pod 可以使用[持久卷申领(PersistentVolumeClaim)](/zh-cn/docs/concepts/storage/persistent-volumes/)请求存储。 PersistentVolumeClaim 是一种命名空间作用域的资源, @@ -534,8 +542,7 @@ PersistentVolumeClaim 是一种命名空间作用域的资源, 例如,你可以为每个租户配置一个单独的 StorageClass,并使用它来加强隔离。 @@ -550,21 +557,20 @@ to ensure that a PersistentVolume cannot be reused across different namespaces. {{% thirdparty-content %}} Kubernetes Pod 由在工作节点上执行的一个或多个容器组成。 容器利用操作系统级别的虚拟化, 因此提供的隔离边界比使用基于硬件虚拟化的虚拟机弱一些。 在共享环境中,攻击者可以利用应用和系统层中未修补的漏洞实现容器逃逸和远程代码执行, 从而允许访问主机资源。 @@ -573,19 +579,17 @@ In either case, mechanisms to further isolate and protect workloads using strong 无论哪种情况,都需要使用强隔离进一步隔离和保护工作负载的机制。 沙箱提供了一种在共享集群中隔离运行中的工作负载的方法。 它通常涉及在单独的执行环境(例如虚拟机或用户空间内核)中运行每个 Pod。 @@ -622,12 +626,12 @@ sandboxing implementations are available: ### 节点隔离 {#node-isolation} 节点隔离是另一种可用于将租户工作负载相互隔离的技术。 通过节点隔离,一组节点专用于运行来自特定租户的 Pod,并且禁止混合不同租户 Pod 集合。 @@ -636,15 +640,13 @@ that manages to escape from a container will only have access to the containers 因为成功实现容器逃逸的攻击者也只能访问挂载在该节点上的容器和卷。 尽管来自不同租户的工作负载在不同的节点上运行, 仍然很重要的是要注意 kubelet 和 @@ -655,15 +657,13 @@ or creating separate clusters for each tenant. 例如使用 seccomp、AppArmor 或 SELinux,或者探索使用沙箱容器,或者为每个租户创建单独的集群。 从计费的角度来看,节点隔离比沙箱容器更容易理解, 因为你可以按节点而不是按 Pod 收费。 @@ -674,8 +674,7 @@ so that they run on a specific set of nodes designated for that tenant. 以便它们在为该租户指定的一组特定节点上运行。 节点隔离可以使用[将 Pod 指派给节点](/zh-cn/docs/concepts/scheduling-eviction/assign-pod-node/)或 @@ -697,11 +696,12 @@ This section discusses other Kubernetes constructs and patterns that are relevan ### API 优先级和公平性 {#api-priority-and-fairness} [API 优先级和公平性](/zh-cn/docs/concepts/cluster-administration/flow-control/)是 Kubernetes 的一个特性, 允许你为集群中运行的某些 Pod 赋予优先级。 @@ -710,8 +710,9 @@ When contention is high, lower priority calls can be queued until the server is 当争用很激烈时,较低优先级的调用可以排队,直到服务器不那么忙,或者你可以拒绝请求。 使用 API 优先级和公平性在 SaaS 环境中并不常见, 除非你允许客户运行与 Kubernetes API 接口的应用,例如控制器。 @@ -722,14 +723,13 @@ unless you are allowing customers to run applications that interface with the Ku ### 服务质量 (QoS) {#qos} 当你运行 SaaS 应用时, 你可能希望能够为不同的租户提供不同的服务质量 (QoS) 层级。 @@ -741,15 +741,15 @@ that they paid for. Let’s start by looking at networking QoS. 让我们从网络 QoS 开始。 通常,节点上的所有 Pod 共享一个网络接口。 如果没有网络 QoS,一些 Pod 可能会以牺牲其他 Pod 为代价不公平地消耗可用带宽。 @@ -761,23 +761,23 @@ Kubernetes [带宽插件](https://www.cni.dev/plugins/current/meta/bandwidth/) 该插件被认为是实验性的,在生产环境中使用之前应该进行彻底的测试。 对于存储 QoS,你可能希望创建具有不同性能特征的不同存储类或配置文件。 每个存储配置文件可以与不同的服务层相关联,该服务层针对 IO、冗余或吞吐量等不同的工作负载进行优化。 可能需要额外的逻辑来允许租户将适当的存储配置文件与其工作负载相关联。 最后,还有 [Pod 优先级和抢占](/zh-cn/docs/concepts/scheduling-eviction/pod-priority-preemption/), 你可以在其中为 Pod 分配优先级值。 @@ -792,24 +792,23 @@ you may want to give higher priority to certain tiers using this feature. ### DNS {#dns} Kubernetes 集群包括一个域名系统(DNS)服务, 可为所有服务和 Pod 提供从名称到 IP 地址的转换。 默认情况下,Kubernetes DNS 服务允许在集群中的所有命名空间中进行查找。 在多租户环境中,租户可以访问 Pod 和其他 Kubernetes 资源, 或者在需要更强隔离的情况下,可能需要阻止 Pod 在其他名称空间中查找服务。 @@ -820,10 +819,9 @@ this within the CoreDNS documentation. [示例](https://github.com/coredns/policy#kubernetes-metadata-multi-tenancy-policy)。 当使用[各租户独立虚拟控制面](#virtual-control-plane-per-tenant)模型时, @@ -836,9 +834,10 @@ that supports multiple tenants. ### Operators {#operators} [Operator 模式](/zh-cn/docs/concepts/extend-kubernetes/operator/)是管理应用的 Kubernetes 控制器。 Operator 可以简化应用的多个实例的管理,例如数据库服务, @@ -868,39 +867,37 @@ Specifically, the Operator should: {{% thirdparty-content %}} 为多租户共享 Kubernetes 集群有两种主要方法: 使用命名空间(即每个租户独立的命名空间) 或虚拟化控制平面(即每个租户独立的虚拟控制平面)。 在这两种情况下,还建议对数据平面隔离和其他考虑事项,如 API 优先级和公平性,进行管理。 Kubernetes 很好地支持命名空间隔离,其资源开销可以忽略不计,并提供了允许租户适当交互的机制, 例如允许服务之间的通信。 但是,它可能很难配置,而且不适用于非命名空间作用域的 Kubernetes 资源,例如自定义资源定义、存储类和 Webhook 等。 控制平面虚拟化允许以更高的资源使用率和更困难的跨租户共享为代价隔离非命名空间作用域的资源。 当命名空间隔离不足但不希望使用专用集群时,这是一个不错的选择, @@ -909,7 +906,7 @@ you will likely see benefits by using namespaces as well. 但是,即使在虚拟化控制平面中,你也可能会看到使用命名空间的好处。 以下各节将更详细地讨论这两个选项: @@ -919,14 +916,13 @@ The two options are discussed in more detail in the following sections: ### 每个租户独立的命名空间 {#namespace-per-tenant} 如前所述,你应该考虑将每个工作负载隔离在其自己的命名空间中, 即使你使用的是专用集群或虚拟化控制平面。 @@ -937,13 +933,12 @@ or to use multi-cluster tooling such as service meshes. 或者使用多集群工具,例如服务网格。 相反,在租户级别分配命名空间也有优势, 而不仅仅是工作负载级别, @@ -954,13 +949,11 @@ For example, an organization may have divisions, teams, and subteams - which sho 例如,一个组织可能有部门、团队和子团队 - 哪些应该分配一个命名空间? 为了解决这个问题,Kubernetes 提供了 [Hierarchical Namespace Controller (HNC)](https://github.com/kubernetes-sigs/hierarchical-namespaces), @@ -970,7 +963,8 @@ These capabilities can be useful in both multi-team and multi-customer scenarios 这些功能在多团队和多客户场景中都很有用。 下面列出了提供类似功能并有助于管理命名空间资源的其他项目: @@ -1019,10 +1013,10 @@ Policy engines provide features to validate and generate tenant configurations: ### 每个租户独立的虚拟控制面 {#virtual-control-plane-per-tenant} 控制面隔离的另一种形式是使用 Kubernetes 扩展为每个租户提供一个虚拟控制面, 以实现集群范围内 API 资源的分段。 @@ -1030,14 +1024,13 @@ with this model to securely manage worker nodes across tenants. 以安全地跨多个租户管理工作节点。 基于虚拟控制面的多租户模型通过为每个租户提供专用控制面组件来扩展基于命名空间的多租户, 从而完全控制集群范围的资源和附加服务。 @@ -1046,9 +1039,9 @@ with underlying compute resources it is referred to as a _virtual control plane_ 由于租户的控制面不直接与底层计算资源相关联,因此它被称为**虚拟控制平面**。 虚拟控制面通常由 Kubernetes API 服务器、控制器管理器和 etcd 数据存储组成。 @@ -1056,12 +1049,12 @@ which coordinates changes across tenant control planes and the control plane of 该控制器跨租户控制面和超集群控制面对变化进行协调。 通过使用每个租户单独的专用控制面,可以解决由于所有租户共享一个 API 服务器而导致的大部分隔离问题。 @@ -1071,10 +1064,10 @@ Webhook 和 CRD 等集群范围对象之间的冲突。 Kubernetes API 服务器并期望具有完整集群可管理性的情况。 改进的隔离是以每个租户运行和维护一个单独的虚拟控制平面为代价的。 @@ -1082,8 +1075,8 @@ These must still be addressed separately. 例如节点级的嘈杂邻居或安全威胁。这些仍然必须单独解决。 Kubernetes [Cluster API - Nested (CAPN)](https://github.com/kubernetes-sigs/cluster-api-provider-nested/tree/main/virtualcluster) From 2414b285c5f9ffcf0586e381c356b38115d46929 Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Tue, 7 Feb 2023 13:16:58 +0800 Subject: [PATCH 124/279] [zh] Resync ingress-controllers.md --- .../docs/concepts/services-networking/ingress-controllers.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/zh-cn/docs/concepts/services-networking/ingress-controllers.md b/content/zh-cn/docs/concepts/services-networking/ingress-controllers.md index 36ea9abd118..c3d723f23ae 100644 --- a/content/zh-cn/docs/concepts/services-networking/ingress-controllers.md +++ b/content/zh-cn/docs/concepts/services-networking/ingress-controllers.md @@ -52,13 +52,13 @@ Kubernetes 作为一个项目,目前支持和维护 {{% thirdparty-content %}} -* [AKS 应用程序网关 Ingress 控制器](https://docs.microsoft.com/zh-cn/azure/application-gateway/tutorial-ingress-controller-add-on-existing) +* [AKS 应用程序网关 Ingress 控制器](https://docs.microsoft.com/zh-cn/azure/application-gateway/tutorial-ingress-controller-add-on-existing?toc=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Faks%2Ftoc.json&bc=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fbread%2Ftoc.json) 是一个配置 [Azure 应用程序网关](https://docs.microsoft.com/zh-cn/azure/application-gateway/overview) 的 Ingress 控制器。 * [Ambassador](https://www.getambassador.io/) API 网关是一个基于 From f910c027bf0621f6f47399780ba3d164659b8de2 Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Tue, 7 Feb 2023 13:52:48 +0800 Subject: [PATCH 125/279] Reformat storage-classes page --- .../docs/concepts/storage/storage-classes.md | 315 +++++++++--------- 1 file changed, 157 insertions(+), 158 deletions(-) diff --git a/content/en/docs/concepts/storage/storage-classes.md b/content/en/docs/concepts/storage/storage-classes.md index cffed404563..7ef18aa0319 100644 --- a/content/en/docs/concepts/storage/storage-classes.md +++ b/content/en/docs/concepts/storage/storage-classes.md @@ -62,22 +62,22 @@ volumeBindingMode: Immediate Each StorageClass has a provisioner that determines what volume plugin is used for provisioning PVs. This field must be specified. -| Volume Plugin | Internal Provisioner| Config Example | -| :--- | :---: | :---: | -| AWSElasticBlockStore | ✓ | [AWS EBS](#aws-ebs) | -| AzureFile | ✓ | [Azure File](#azure-file) | -| AzureDisk | ✓ | [Azure Disk](#azure-disk) | -| CephFS | - | - | -| Cinder | ✓ | [OpenStack Cinder](#openstack-cinder)| -| FC | - | - | -| FlexVolume | - | - | -| GCEPersistentDisk | ✓ | [GCE PD](#gce-pd) | -| iSCSI | - | - | -| NFS | - | [NFS](#nfs) | -| RBD | ✓ | [Ceph RBD](#ceph-rbd) | -| VsphereVolume | ✓ | [vSphere](#vsphere) | -| PortworxVolume | ✓ | [Portworx Volume](#portworx-volume) | -| Local | - | [Local](#local) | +| Volume Plugin | Internal Provisioner | Config Example | +| :------------------- | :------------------: | :-----------------------------------: | +| AWSElasticBlockStore | ✓ | [AWS EBS](#aws-ebs) | +| AzureFile | ✓ | [Azure File](#azure-file) | +| AzureDisk | ✓ | [Azure Disk](#azure-disk) | +| CephFS | - | - | +| Cinder | ✓ | [OpenStack Cinder](#openstack-cinder) | +| FC | - | - | +| FlexVolume | - | - | +| GCEPersistentDisk | ✓ | [GCE PD](#gce-pd) | +| iSCSI | - | - | +| NFS | - | [NFS](#nfs) | +| RBD | ✓ | [Ceph RBD](#ceph-rbd) | +| VsphereVolume | ✓ | [vSphere](#vsphere) | +| PortworxVolume | ✓ | [Portworx Volume](#portworx-volume) | +| Local | - | [Local](#local) | You are not restricted to specifying the "internal" provisioners listed here (whose names are prefixed with "kubernetes.io" and shipped @@ -109,29 +109,28 @@ whatever reclaim policy they were assigned at creation. {{< feature-state for_k8s_version="v1.11" state="beta" >}} -PersistentVolumes can be configured to be expandable. This feature when set to `true`, -allows the users to resize the volume by editing the corresponding PVC object. +PersistentVolumes can be configured to be expandable. This feature when set to `true`, +allows the users to resize the volume by editing the corresponding PVC object. The following types of volumes support volume expansion, when the underlying StorageClass has the field `allowVolumeExpansion` set to true. {{< table caption = "Table of Volume types and the version of Kubernetes they require" >}} -Volume type | Required Kubernetes version -:---------- | :-------------------------- -gcePersistentDisk | 1.11 -awsElasticBlockStore | 1.11 -Cinder | 1.11 -rbd | 1.11 -Azure File | 1.11 -Azure Disk | 1.11 -Portworx | 1.11 -FlexVolume | 1.13 -CSI | 1.14 (alpha), 1.16 (beta) +| Volume type | Required Kubernetes version | +| :------------------- | :-------------------------- | +| gcePersistentDisk | 1.11 | +| awsElasticBlockStore | 1.11 | +| Cinder | 1.11 | +| rbd | 1.11 | +| Azure File | 1.11 | +| Azure Disk | 1.11 | +| Portworx | 1.11 | +| FlexVolume | 1.13 | +| CSI | 1.14 (alpha), 1.16 (beta) | {{< /table >}} - {{< note >}} You can only use the volume expansion feature to grow a Volume, not to shrink it. {{< /note >}} @@ -168,14 +167,14 @@ and [taints and tolerations](/docs/concepts/scheduling-eviction/taint-and-tolera The following plugins support `WaitForFirstConsumer` with dynamic provisioning: -* [AWSElasticBlockStore](#aws-ebs) -* [GCEPersistentDisk](#gce-pd) -* [AzureDisk](#azure-disk) +- [AWSElasticBlockStore](#aws-ebs) +- [GCEPersistentDisk](#gce-pd) +- [AzureDisk](#azure-disk) The following plugins support `WaitForFirstConsumer` with pre-created PersistentVolume binding: -* All of the above -* [Local](#local) +- All of the above +- [Local](#local) {{< feature-state state="stable" for_k8s_version="v1.17" >}} [CSI volumes](/docs/concepts/storage/volumes/#csi) are also supported with dynamic provisioning @@ -183,10 +182,10 @@ and pre-created PVs, but you'll need to look at the documentation for a specific to see its supported topology keys and examples. {{< note >}} - If you choose to use `WaitForFirstConsumer`, do not use `nodeName` in the Pod spec - to specify node affinity. If `nodeName` is used in this case, the scheduler will be bypassed and PVC will remain in `pending` state. +If you choose to use `WaitForFirstConsumer`, do not use `nodeName` in the Pod spec +to specify node affinity. If `nodeName` is used in this case, the scheduler will be bypassed and PVC will remain in `pending` state. - Instead, you can use node selector for hostname in this case as shown below. +Instead, you can use node selector for hostname in this case as shown below. {{< /note >}} ```yaml @@ -243,7 +242,7 @@ allowedTopologies: Storage Classes have parameters that describe volumes belonging to the storage class. Different parameters may be accepted depending on the `provisioner`. For - example, the value `io1`, for the parameter `type`, and the parameter +example, the value `io1`, for the parameter `type`, and the parameter `iopsPerGB` are specific to EBS. When a parameter is omitted, some default is used. @@ -265,26 +264,26 @@ parameters: fsType: ext4 ``` -* `type`: `io1`, `gp2`, `sc1`, `st1`. See +- `type`: `io1`, `gp2`, `sc1`, `st1`. See [AWS docs](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html) for details. Default: `gp2`. -* `zone` (Deprecated): AWS zone. If neither `zone` nor `zones` is specified, volumes are +- `zone` (Deprecated): AWS zone. If neither `zone` nor `zones` is specified, volumes are generally round-robin-ed across all active zones where Kubernetes cluster has a node. `zone` and `zones` parameters must not be used at the same time. -* `zones` (Deprecated): A comma separated list of AWS zone(s). If neither `zone` nor `zones` +- `zones` (Deprecated): A comma separated list of AWS zone(s). If neither `zone` nor `zones` is specified, volumes are generally round-robin-ed across all active zones where Kubernetes cluster has a node. `zone` and `zones` parameters must not be used at the same time. -* `iopsPerGB`: only for `io1` volumes. I/O operations per second per GiB. AWS +- `iopsPerGB`: only for `io1` volumes. I/O operations per second per GiB. AWS volume plugin multiplies this with size of requested volume to compute IOPS of the volume and caps it at 20 000 IOPS (maximum supported by AWS, see [AWS docs](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html)). A string is expected here, i.e. `"10"`, not `10`. -* `fsType`: fsType that is supported by kubernetes. Default: `"ext4"`. -* `encrypted`: denotes whether the EBS volume should be encrypted or not. +- `fsType`: fsType that is supported by kubernetes. Default: `"ext4"`. +- `encrypted`: denotes whether the EBS volume should be encrypted or not. Valid values are `"true"` or `"false"`. A string is expected here, i.e. `"true"`, not `true`. -* `kmsKeyId`: optional. The full Amazon Resource Name of the key to use when +- `kmsKeyId`: optional. The full Amazon Resource Name of the key to use when encrypting the volume. If none is supplied but `encrypted` is true, a key is generated by AWS. See AWS docs for valid ARN value. @@ -307,17 +306,17 @@ parameters: replication-type: none ``` -* `type`: `pd-standard` or `pd-ssd`. Default: `pd-standard` -* `zone` (Deprecated): GCE zone. If neither `zone` nor `zones` is specified, volumes are +- `type`: `pd-standard` or `pd-ssd`. Default: `pd-standard` +- `zone` (Deprecated): GCE zone. If neither `zone` nor `zones` is specified, volumes are generally round-robin-ed across all active zones where Kubernetes cluster has a node. `zone` and `zones` parameters must not be used at the same time. -* `zones` (Deprecated): A comma separated list of GCE zone(s). If neither `zone` nor `zones` +- `zones` (Deprecated): A comma separated list of GCE zone(s). If neither `zone` nor `zones` is specified, volumes are generally round-robin-ed across all active zones where Kubernetes cluster has a node. `zone` and `zones` parameters must not be used at the same time. -* `fstype`: `ext4` or `xfs`. Default: `ext4`. The defined filesystem type must be supported by the host operating system. +- `fstype`: `ext4` or `xfs`. Default: `ext4`. The defined filesystem type must be supported by the host operating system. -* `replication-type`: `none` or `regional-pd`. Default: `none`. +- `replication-type`: `none` or `regional-pd`. Default: `none`. If `replication-type` is set to `none`, a regular (zonal) PD will be provisioned. @@ -350,14 +349,15 @@ parameters: readOnly: "false" ``` -* `server`: Server is the hostname or IP address of the NFS server. -* `path`: Path that is exported by the NFS server. -* `readOnly`: A flag indicating whether the storage will be mounted as read only (default false). +- `server`: Server is the hostname or IP address of the NFS server. +- `path`: Path that is exported by the NFS server. +- `readOnly`: A flag indicating whether the storage will be mounted as read only (default false). Kubernetes doesn't include an internal NFS provisioner. You need to use an external provisioner to create a StorageClass for NFS. Here are some examples: -* [NFS Ganesha server and external provisioner](https://github.com/kubernetes-sigs/nfs-ganesha-server-and-external-provisioner) -* [NFS subdir external provisioner](https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner) + +- [NFS Ganesha server and external provisioner](https://github.com/kubernetes-sigs/nfs-ganesha-server-and-external-provisioner) +- [NFS subdir external provisioner](https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner) ### OpenStack Cinder @@ -371,7 +371,7 @@ parameters: availability: nova ``` -* `availability`: Availability Zone. If not specified, volumes are generally +- `availability`: Availability Zone. If not specified, volumes are generally round-robin-ed across all active zones where Kubernetes cluster has a node. {{< note >}} @@ -381,7 +381,7 @@ This internal provisioner of OpenStack is deprecated. Please use [the external c ### vSphere -There are two types of provisioners for vSphere storage classes: +There are two types of provisioners for vSphere storage classes: - [CSI provisioner](#vsphere-provisioner-csi): `csi.vsphere.vmware.com` - [vCP provisioner](#vcp-provisioner): `kubernetes.io/vsphere-volume` @@ -392,73 +392,73 @@ In-tree provisioners are [deprecated](/blog/2019/12/09/kubernetes-1-17-feature-c The vSphere CSI StorageClass provisioner works with Tanzu Kubernetes clusters. For an example, refer to the [vSphere CSI repository](https://github.com/kubernetes-sigs/vsphere-csi-driver/blob/master/example/vanilla-k8s-RWM-filesystem-volumes/example-sc.yaml). -#### vCP Provisioner +#### vCP Provisioner -The following examples use the VMware Cloud Provider (vCP) StorageClass provisioner. +The following examples use the VMware Cloud Provider (vCP) StorageClass provisioner. 1. Create a StorageClass with a user specified disk format. - ```yaml - apiVersion: storage.k8s.io/v1 - kind: StorageClass - metadata: - name: fast - provisioner: kubernetes.io/vsphere-volume - parameters: - diskformat: zeroedthick - ``` + ```yaml + apiVersion: storage.k8s.io/v1 + kind: StorageClass + metadata: + name: fast + provisioner: kubernetes.io/vsphere-volume + parameters: + diskformat: zeroedthick + ``` - `diskformat`: `thin`, `zeroedthick` and `eagerzeroedthick`. Default: `"thin"`. + `diskformat`: `thin`, `zeroedthick` and `eagerzeroedthick`. Default: `"thin"`. 2. Create a StorageClass with a disk format on a user specified datastore. - ```yaml - apiVersion: storage.k8s.io/v1 - kind: StorageClass - metadata: - name: fast - provisioner: kubernetes.io/vsphere-volume - parameters: - diskformat: zeroedthick - datastore: VSANDatastore - ``` + ```yaml + apiVersion: storage.k8s.io/v1 + kind: StorageClass + metadata: + name: fast + provisioner: kubernetes.io/vsphere-volume + parameters: + diskformat: zeroedthick + datastore: VSANDatastore + ``` - `datastore`: The user can also specify the datastore in the StorageClass. - The volume will be created on the datastore specified in the StorageClass, - which in this case is `VSANDatastore`. This field is optional. If the - datastore is not specified, then the volume will be created on the datastore - specified in the vSphere config file used to initialize the vSphere Cloud - Provider. + `datastore`: The user can also specify the datastore in the StorageClass. + The volume will be created on the datastore specified in the StorageClass, + which in this case is `VSANDatastore`. This field is optional. If the + datastore is not specified, then the volume will be created on the datastore + specified in the vSphere config file used to initialize the vSphere Cloud + Provider. 3. Storage Policy Management inside kubernetes - * Using existing vCenter SPBM policy + - Using existing vCenter SPBM policy - One of the most important features of vSphere for Storage Management is - policy based Management. Storage Policy Based Management (SPBM) is a - storage policy framework that provides a single unified control plane - across a broad range of data services and storage solutions. SPBM enables - vSphere administrators to overcome upfront storage provisioning challenges, - such as capacity planning, differentiated service levels and managing - capacity headroom. + One of the most important features of vSphere for Storage Management is + policy based Management. Storage Policy Based Management (SPBM) is a + storage policy framework that provides a single unified control plane + across a broad range of data services and storage solutions. SPBM enables + vSphere administrators to overcome upfront storage provisioning challenges, + such as capacity planning, differentiated service levels and managing + capacity headroom. - The SPBM policies can be specified in the StorageClass using the - `storagePolicyName` parameter. + The SPBM policies can be specified in the StorageClass using the + `storagePolicyName` parameter. - * Virtual SAN policy support inside Kubernetes + - Virtual SAN policy support inside Kubernetes - Vsphere Infrastructure (VI) Admins will have the ability to specify custom - Virtual SAN Storage Capabilities during dynamic volume provisioning. You - can now define storage requirements, such as performance and availability, - in the form of storage capabilities during dynamic volume provisioning. - The storage capability requirements are converted into a Virtual SAN - policy which are then pushed down to the Virtual SAN layer when a - persistent volume (virtual disk) is being created. The virtual disk is - distributed across the Virtual SAN datastore to meet the requirements. + Vsphere Infrastructure (VI) Admins will have the ability to specify custom + Virtual SAN Storage Capabilities during dynamic volume provisioning. You + can now define storage requirements, such as performance and availability, + in the form of storage capabilities during dynamic volume provisioning. + The storage capability requirements are converted into a Virtual SAN + policy which are then pushed down to the Virtual SAN layer when a + persistent volume (virtual disk) is being created. The virtual disk is + distributed across the Virtual SAN datastore to meet the requirements. - You can see [Storage Policy Based Management for dynamic provisioning of volumes](https://github.com/vmware-archive/vsphere-storage-for-kubernetes/blob/fa4c8b8ad46a85b6555d715dd9d27ff69839df53/documentation/policy-based-mgmt.md) - for more details on how to use storage policies for persistent volumes - management. + You can see [Storage Policy Based Management for dynamic provisioning of volumes](https://github.com/vmware-archive/vsphere-storage-for-kubernetes/blob/fa4c8b8ad46a85b6555d715dd9d27ff69839df53/documentation/policy-based-mgmt.md) + for more details on how to use storage policies for persistent volumes + management. There are few [vSphere examples](https://github.com/kubernetes/examples/tree/master/staging/volumes/vsphere) @@ -486,29 +486,30 @@ parameters: imageFeatures: "layering" ``` -* `monitors`: Ceph monitors, comma delimited. This parameter is required. -* `adminId`: Ceph client ID that is capable of creating images in the pool. +- `monitors`: Ceph monitors, comma delimited. This parameter is required. +- `adminId`: Ceph client ID that is capable of creating images in the pool. Default is "admin". -* `adminSecretName`: Secret Name for `adminId`. This parameter is required. +- `adminSecretName`: Secret Name for `adminId`. This parameter is required. The provided secret must have type "kubernetes.io/rbd". -* `adminSecretNamespace`: The namespace for `adminSecretName`. Default is "default". -* `pool`: Ceph RBD pool. Default is "rbd". -* `userId`: Ceph client ID that is used to map the RBD image. Default is the +- `adminSecretNamespace`: The namespace for `adminSecretName`. Default is "default". +- `pool`: Ceph RBD pool. Default is "rbd". +- `userId`: Ceph client ID that is used to map the RBD image. Default is the same as `adminId`. -* `userSecretName`: The name of Ceph Secret for `userId` to map RBD image. It +- `userSecretName`: The name of Ceph Secret for `userId` to map RBD image. It must exist in the same namespace as PVCs. This parameter is required. The provided secret must have type "kubernetes.io/rbd", for example created in this way: - ```shell - kubectl create secret generic ceph-secret --type="kubernetes.io/rbd" \ - --from-literal=key='QVFEQ1pMdFhPUnQrSmhBQUFYaERWNHJsZ3BsMmNjcDR6RFZST0E9PQ==' \ - --namespace=kube-system - ``` -* `userSecretNamespace`: The namespace for `userSecretName`. -* `fsType`: fsType that is supported by kubernetes. Default: `"ext4"`. -* `imageFormat`: Ceph RBD image format, "1" or "2". Default is "2". -* `imageFeatures`: This parameter is optional and should only be used if you + ```shell + kubectl create secret generic ceph-secret --type="kubernetes.io/rbd" \ + --from-literal=key='QVFEQ1pMdFhPUnQrSmhBQUFYaERWNHJsZ3BsMmNjcDR6RFZST0E9PQ==' \ + --namespace=kube-system + ``` + +- `userSecretNamespace`: The namespace for `userSecretName`. +- `fsType`: fsType that is supported by kubernetes. Default: `"ext4"`. +- `imageFormat`: Ceph RBD image format, "1" or "2". Default is "2". +- `imageFeatures`: This parameter is optional and should only be used if you set `imageFormat` to "2". Currently supported features are `layering` only. Default is "", and no features are turned on. @@ -528,9 +529,9 @@ parameters: storageAccount: azure_storage_account_name ``` -* `skuName`: Azure storage account Sku tier. Default is empty. -* `location`: Azure storage account location. Default is empty. -* `storageAccount`: Azure storage account name. If a storage account is provided, +- `skuName`: Azure storage account Sku tier. Default is empty. +- `location`: Azure storage account location. Default is empty. +- `storageAccount`: Azure storage account name. If a storage account is provided, it must reside in the same resource group as the cluster, and `location` is ignored. If a storage account is not provided, a new storage account will be created in the same resource group as the cluster. @@ -548,21 +549,21 @@ parameters: kind: managed ``` -* `storageaccounttype`: Azure storage account Sku tier. Default is empty. -* `kind`: Possible values are `shared`, `dedicated`, and `managed` (default). +- `storageaccounttype`: Azure storage account Sku tier. Default is empty. +- `kind`: Possible values are `shared`, `dedicated`, and `managed` (default). When `kind` is `shared`, all unmanaged disks are created in a few shared storage accounts in the same resource group as the cluster. When `kind` is `dedicated`, a new dedicated storage account will be created for the new - unmanaged disk in the same resource group as the cluster. When `kind` is - `managed`, all managed disks are created in the same resource group as + unmanaged disk in the same resource group as the cluster. When `kind` is + `managed`, all managed disks are created in the same resource group as the cluster. -* `resourceGroup`: Specify the resource group in which the Azure disk will be created. - It must be an existing resource group name. If it is unspecified, the disk will be - placed in the same resource group as the current Kubernetes cluster. +- `resourceGroup`: Specify the resource group in which the Azure disk will be created. + It must be an existing resource group name. If it is unspecified, the disk will be + placed in the same resource group as the current Kubernetes cluster. -- Premium VM can attach both Standard_LRS and Premium_LRS disks, while Standard +* Premium VM can attach both Standard_LRS and Premium_LRS disks, while Standard VM can only attach Standard_LRS disks. -- Managed VM can only attach managed disks and unmanaged VM can only attach +* Managed VM can only attach managed disks and unmanaged VM can only attach unmanaged disks. ### Azure File @@ -579,29 +580,29 @@ parameters: storageAccount: azure_storage_account_name ``` -* `skuName`: Azure storage account Sku tier. Default is empty. -* `location`: Azure storage account location. Default is empty. -* `storageAccount`: Azure storage account name. Default is empty. If a storage +- `skuName`: Azure storage account Sku tier. Default is empty. +- `location`: Azure storage account location. Default is empty. +- `storageAccount`: Azure storage account name. Default is empty. If a storage account is not provided, all storage accounts associated with the resource group are searched to find one that matches `skuName` and `location`. If a storage account is provided, it must reside in the same resource group as the cluster, and `skuName` and `location` are ignored. -* `secretNamespace`: the namespace of the secret that contains the Azure Storage +- `secretNamespace`: the namespace of the secret that contains the Azure Storage Account Name and Key. Default is the same as the Pod. -* `secretName`: the name of the secret that contains the Azure Storage Account Name and +- `secretName`: the name of the secret that contains the Azure Storage Account Name and Key. Default is `azure-storage-account--secret` -* `readOnly`: a flag indicating whether the storage will be mounted as read only. - Defaults to false which means a read/write mount. This setting will impact the +- `readOnly`: a flag indicating whether the storage will be mounted as read only. + Defaults to false which means a read/write mount. This setting will impact the `ReadOnly` setting in VolumeMounts as well. -During storage provisioning, a secret named by `secretName` is created for the -mounting credentials. If the cluster has enabled both -[RBAC](/docs/reference/access-authn-authz/rbac/) and +During storage provisioning, a secret named by `secretName` is created for the +mounting credentials. If the cluster has enabled both +[RBAC](/docs/reference/access-authn-authz/rbac/) and [Controller Roles](/docs/reference/access-authn-authz/rbac/#controller-roles), add the `create` permission of resource `secret` for clusterrole `system:controller:persistent-volume-binder`. -In a multi-tenancy context, it is strongly recommended to set the value for +In a multi-tenancy context, it is strongly recommended to set the value for `secretNamespace` explicitly, otherwise the storage account credentials may be read by other users. @@ -615,26 +616,25 @@ metadata: provisioner: kubernetes.io/portworx-volume parameters: repl: "1" - snap_interval: "70" - priority_io: "high" - + snap_interval: "70" + priority_io: "high" ``` -* `fs`: filesystem to be laid out: `none/xfs/ext4` (default: `ext4`). -* `block_size`: block size in Kbytes (default: `32`). -* `repl`: number of synchronous replicas to be provided in the form of +- `fs`: filesystem to be laid out: `none/xfs/ext4` (default: `ext4`). +- `block_size`: block size in Kbytes (default: `32`). +- `repl`: number of synchronous replicas to be provided in the form of replication factor `1..3` (default: `1`) A string is expected here i.e. `"1"` and not `1`. -* `priority_io`: determines whether the volume will be created from higher +- `priority_io`: determines whether the volume will be created from higher performance or a lower priority storage `high/medium/low` (default: `low`). -* `snap_interval`: clock/time interval in minutes for when to trigger snapshots. +- `snap_interval`: clock/time interval in minutes for when to trigger snapshots. Snapshots are incremental based on difference with the prior snapshot, 0 disables snaps (default: `0`). A string is expected here i.e. `"70"` and not `70`. -* `aggregation_level`: specifies the number of chunks the volume would be +- `aggregation_level`: specifies the number of chunks the volume would be distributed into, 0 indicates a non-aggregated volume (default: `0`). A string is expected here i.e. `"0"` and not `0` -* `ephemeral`: specifies whether the volume should be cleaned-up after unmount +- `ephemeral`: specifies whether the volume should be cleaned-up after unmount or should be persistent. `emptyDir` use case can set this value to true and `persistent volumes` use case such as for databases like Cassandra should set to false, `true/false` (default `false`). A string is expected here i.e. @@ -660,4 +660,3 @@ specified by the `WaitForFirstConsumer` volume binding mode. Delaying volume binding allows the scheduler to consider all of a Pod's scheduling constraints when choosing an appropriate PersistentVolume for a PersistentVolumeClaim. - From 05e275ad5bae7f23d8dd24bbb36aa7cff2025798 Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Tue, 7 Feb 2023 14:08:51 +0800 Subject: [PATCH 126/279] [zh] Resync storage-classes.md --- .../docs/concepts/storage/storage-classes.md | 365 +++++++++--------- 1 file changed, 183 insertions(+), 182 deletions(-) diff --git a/content/zh-cn/docs/concepts/storage/storage-classes.md b/content/zh-cn/docs/concepts/storage/storage-classes.md index 46acbace821..c67f589dfbe 100644 --- a/content/zh-cn/docs/concepts/storage/storage-classes.md +++ b/content/zh-cn/docs/concepts/storage/storage-classes.md @@ -104,7 +104,7 @@ for provisioning PVs. This field must be specified. --> | 卷插件 | 内置制备器 | 配置例子 | -|:---------------------|:----------:|:-------------------------------------:| +| :------------------- | :--------: | :-----------------------------------: | | AWSElasticBlockStore | ✓ | [AWS EBS](#aws-ebs) | | AzureFile | ✓ | [Azure File](#azure-文件) | | AzureDisk | ✓ | [Azure Disk](#azure-磁盘) | @@ -117,8 +117,8 @@ for provisioning PVs. This field must be specified. | NFS | - | [NFS](#nfs) | | RBD | ✓ | [Ceph RBD](#ceph-rbd) | | VsphereVolume | ✓ | [vSphere](#vsphere) | -| PortworxVolume | ✓ | [Portworx Volume](#portworx-卷) | -| Local | - | [Local](#本地) | +| PortworxVolume | ✓ | [Portworx Volume](#portworx-卷) | +| Local | - | [Local](#本地) | -| 卷类型 | Kubernetes 版本要求 | -|:---------------------|:--------------------------| +| 卷类型 | Kubernetes 版本要求 | +| :------------------- | :------------------------ | | gcePersistentDisk | 1.11 | | awsElasticBlockStore | 1.11 | | Cinder | 1.11 | @@ -221,14 +221,14 @@ mount options specified in the `mountOptions` field of the class. If the volume plugin does not support mount options but mount options are specified, provisioning will fail. Mount options are not validated on either -the class or PV, If a mount option is invalid, the PV mount fails. +the class or PV. If a mount option is invalid, the PV mount fails. --> ### 挂载选项 {#mount-options} 由 StorageClass 动态创建的 PersistentVolume 将使用类中 `mountOptions` 字段指定的挂载选项。 如果卷插件不支持挂载选项,却指定了挂载选项,则制备操作会失败。 -挂载选项在 StorageClass 和 PV 上都不会做验证,如果其中一个挂载选项无效,那么这个 PV 挂载操作就会失败。 +挂载选项在 StorageClass 和 PV 上都不会做验证。如果其中一个挂载选项无效,那么这个 PV 挂载操作就会失败。 `volumeBindingMode` 字段控制了[卷绑定和动态制备](/zh-cn/docs/concepts/storage/persistent-volumes/#provisioning)应该发生在什么时候。 +当未设置时,默认使用 `Immediate` 模式。 -默认情况下,`Immediate` 模式表示一旦创建了 PersistentVolumeClaim 也就完成了卷绑定和动态制备。 +`Immediate` 模式表示一旦创建了 PersistentVolumeClaim 也就完成了卷绑定和动态制备。 对于由于拓扑限制而非集群所有节点可达的存储后端,PersistentVolume 会在不知道 Pod 调度要求的情况下绑定或者制备。 @@ -275,26 +276,26 @@ PersistentVolume 会根据 Pod 调度约束指定的拓扑来选择或制备。 以下插件支持动态制备的 `WaitForFirstConsumer` 模式: -* [AWSElasticBlockStore](#aws-ebs) -* [GCEPersistentDisk](#gce-pd) -* [AzureDisk](#azure-disk) +- [AWSElasticBlockStore](#aws-ebs) +- [GCEPersistentDisk](#gce-pd) +- [AzureDisk](#azure-disk) 以下插件支持预创建绑定 PersistentVolume 的 `WaitForFirstConsumer` 模式: -* 上述全部 -* [Local](#local) +- 上述全部 +- [Local](#local) {{< feature-state state="stable" for_k8s_version="v1.17" >}} @@ -307,16 +308,16 @@ to see its supported topology keys and examples. 但是你需要查看特定 CSI 驱动的文档以查看其支持的拓扑键名和例子。 {{< note >}} - - 如果你选择使用 `WaitForFirstConsumer`,请不要在 Pod 规约中使用 `nodeName` 来指定节点亲和性。 - 如果在这种情况下使用 `nodeName`,Pod 将会绕过调度程序,PVC 将停留在 `pending` 状态。 +如果你选择使用 `WaitForFirstConsumer`,请不要在 Pod 规约中使用 `nodeName` 来指定节点亲和性。 +如果在这种情况下使用 `nodeName`,Pod 将会绕过调度程序,PVC 将停留在 `pending` 状态。 - 相反,在这种情况下,你可以使用节点选择器作为主机名,如下所示。 +相反,在这种情况下,你可以使用节点选择器作为主机名,如下所示。 {{< /note >}} @@ -387,7 +388,7 @@ allowedTopologies: Storage Classes have parameters that describe volumes belonging to the storage class. Different parameters may be accepted depending on the `provisioner`. For - example, the value `io1`, for the parameter `type`, and the parameter +example, the value `io1`, for the parameter `type`, and the parameter `iopsPerGB` are specific to EBS. When a parameter is omitted, some default is used. @@ -418,46 +419,46 @@ parameters: ``` -* `type`:`io1`,`gp2`,`sc1`,`st1`。详细信息参见 +- `type`:`io1`,`gp2`,`sc1`,`st1`。详细信息参见 [AWS 文档](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html)。默认值:`gp2`。 -* `zone`(弃用):AWS 区域。如果没有指定 `zone` 和 `zones`, +- `zone`(弃用):AWS 区域。如果没有指定 `zone` 和 `zones`, 通常卷会在 Kubernetes 集群节点所在的活动区域中轮询调度分配。 `zone` 和 `zones` 参数不能同时使用。 -* `zones`(弃用):以逗号分隔的 AWS 区域列表。 +- `zones`(弃用):以逗号分隔的 AWS 区域列表。 如果没有指定 `zone` 和 `zones`,通常卷会在 Kubernetes 集群节点所在的活动区域中轮询调度分配。 `zone`和`zones`参数不能同时使用。 -* `iopsPerGB`:只适用于 `io1` 卷。每 GiB 每秒 I/O 操作。 +- `iopsPerGB`:只适用于 `io1` 卷。每 GiB 每秒 I/O 操作。 AWS 卷插件将其与请求卷的大小相乘以计算 IOPS 的容量, 并将其限制在 20000 IOPS(AWS 支持的最高值,请参阅 [AWS 文档](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html))。 这里需要输入一个字符串,即 `"10"`,而不是 `10`。 -* `fsType`:受 Kubernetes 支持的文件类型。默认值:`"ext4"`。 -* `encrypted`:指定 EBS 卷是否应该被加密。合法值为 `"true"` 或者 `"false"`。 +- `fsType`:受 Kubernetes 支持的文件类型。默认值:`"ext4"`。 +- `encrypted`:指定 EBS 卷是否应该被加密。合法值为 `"true"` 或者 `"false"`。 这里需要输入字符串,即 `"true"`, 而非 `true`。 -* `kmsKeyId`:可选。加密卷时使用密钥的完整 Amazon 资源名称。 +- `kmsKeyId`:可选。加密卷时使用密钥的完整 Amazon 资源名称。 如果没有提供,但 `encrypted` 值为 true,AWS 生成一个密钥。关于有效的 ARN 值,请参阅 AWS 文档。 {{< note >}} @@ -478,31 +479,31 @@ metadata: provisioner: kubernetes.io/gce-pd parameters: type: pd-standard - fstype: ext4 + fstype: ext4 replication-type: none ``` -* `type`:`pd-standard` 或者 `pd-ssd`。默认:`pd-standard` -* `zone`(弃用):GCE 区域。如果没有指定 `zone` 和 `zones`, +- `type`:`pd-standard` 或者 `pd-ssd`。默认:`pd-standard` +- `zone`(弃用):GCE 区域。如果没有指定 `zone` 和 `zones`, 通常卷会在 Kubernetes 集群节点所在的活动区域中轮询调度分配。 `zone` 和 `zones` 参数不能同时使用。 -* `zones`(弃用):逗号分隔的 GCE 区域列表。如果没有指定 `zone` 和 `zones`, +- `zones`(弃用):逗号分隔的 GCE 区域列表。如果没有指定 `zone` 和 `zones`, 通常卷会在 Kubernetes 集群节点所在的活动区域中轮询调度(round-robin)分配。 `zone` 和 `zones` 参数不能同时使用。 -* `fstype`:`ext4` 或 `xfs`。 默认:`ext4`。宿主机操作系统必须支持所定义的文件系统类型。 -* `replication-type`:`none` 或者 `regional-pd`。默认值:`none`。 +- `fstype`:`ext4` 或 `xfs`。 默认:`ext4`。宿主机操作系统必须支持所定义的文件系统类型。 +- `replication-type`:`none` 或者 `regional-pd`。默认值:`none`。 -* `server`:NFS 服务器的主机名或 IP 地址。 -* `path`:NFS 服务器导出的路径。 -* `readOnly`:是否将存储挂载为只读的标志(默认为 false)。 +- `server`:NFS 服务器的主机名或 IP 地址。 +- `path`:NFS 服务器导出的路径。 +- `readOnly`:是否将存储挂载为只读的标志(默认为 false)。 - Kubernetes 不包含内部 NFS 驱动。你需要使用外部驱动为 NFS 创建 StorageClass。 这里有些例子: -* [NFS Ganesha 服务器和外部驱动](https://github.com/kubernetes-sigs/nfs-ganesha-server-and-external-provisioner) -* [NFS subdir 外部驱动](https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner) +- [NFS Ganesha 服务器和外部驱动](https://github.com/kubernetes-sigs/nfs-ganesha-server-and-external-provisioner) +- [NFS subdir 外部驱动](https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner) ### OpenStack Cinder @@ -583,16 +584,16 @@ parameters: ``` -* `availability`:可用区域。如果没有指定,通常卷会在 Kubernetes 集群节点所在的活动区域中轮转调度。 +- `availability`:可用区域。如果没有指定,通常卷会在 Kubernetes 集群节点所在的活动区域中轮转调度。 {{< note >}} -{{< feature-state state="deprecated" for_k8s_version="1.11" >}} +{{< feature-state state="deprecated" for_k8s_version="v1.11" >}} OpenStack 的内部驱动已经被弃用。请使用 [OpenStack 的外部云驱动](https://github.com/kubernetes/cloud-provider-openstack)。 {{< /note >}} @@ -600,7 +601,7 @@ OpenStack 的内部驱动已经被弃用。请使用 ### vSphere {#vsphere} #### vCP 制备器 {#vcp-provisioner} @@ -669,13 +670,13 @@ The following examples use the VMware Cloud Provider (vCP) StorageClass provisio name: fast provisioner: kubernetes.io/vsphere-volume parameters: - diskformat: zeroedthick - datastore: VSANDatastore + diskformat: zeroedthick + datastore: VSANDatastore ``` `datastore`:用户也可以在 StorageClass 中指定数据存储。 - 卷将在 storage class 中指定的数据存储上创建,在这种情况下是 `VSANDatastore`。 + 卷将在 StorageClass 中指定的数据存储上创建,在这种情况下是 `VSANDatastore`。 该字段是可选的。 如果未指定数据存储,则将在用于初始化 vSphere Cloud Provider 的 vSphere 配置文件中指定的数据存储上创建该卷。 @@ -694,7 +695,7 @@ The following examples use the VMware Cloud Provider (vCP) StorageClass provisio 3. Kubernetes 中的存储策略管理 - * 使用现有的 vCenter SPBM 策略 + - 使用现有的 vCenter SPBM 策略 - vSphere 用于存储管理的最重要特性之一是基于策略的管理。 - 基于存储策略的管理(SPBM)是一个存储策略框架,提供单一的统一控制平面的跨越广泛的数据服务和存储解决方案。 - SPBM 使得 vSphere 管理员能够克服先期的存储配置挑战,如容量规划、差异化服务等级和管理容量空间。 + vSphere 用于存储管理的最重要特性之一是基于策略的管理。 + 基于存储策略的管理(SPBM)是一个存储策略框架,提供单一的统一控制平面的跨越广泛的数据服务和存储解决方案。 + SPBM 使得 vSphere 管理员能够克服先期的存储配置挑战,如容量规划、差异化服务等级和管理容量空间。 - SPBM 策略可以在 StorageClass 中使用 `storagePolicyName` 参数声明。 + SPBM 策略可以在 StorageClass 中使用 `storagePolicyName` 参数声明。 - * Kubernetes 内的 Virtual SAN 策略支持 + - Kubernetes 内的 Virtual SAN 策略支持 - Vsphere Infrastructure(VI)管理员将能够在动态卷配置期间指定自定义 Virtual SAN - 存储功能。你现在可以在动态制备卷期间以存储能力的形式定义存储需求,例如性能和可用性。 - 存储能力需求会转换为 Virtual SAN 策略,之后当持久卷(虚拟磁盘)被创建时, - 会将其推送到 Virtual SAN 层。虚拟磁盘分布在 Virtual SAN 数据存储中以满足要求。 + Vsphere Infrastructure(VI)管理员将能够在动态卷配置期间指定自定义 Virtual SAN + 存储功能。你现在可以在动态制备卷期间以存储能力的形式定义存储需求,例如性能和可用性。 + 存储能力需求会转换为 Virtual SAN 策略,之后当持久卷(虚拟磁盘)被创建时, + 会将其推送到 Virtual SAN 层。虚拟磁盘分布在 Virtual SAN 数据存储中以满足要求。 - 你可以参考[基于存储策略的动态制备卷管理](https://github.com/vmware-archive/vsphere-storage-for-kubernetes/blob/fa4c8b8ad46a85b6555d715dd9d27ff69839df53/documentation/policy-based-mgmt.md), - 进一步了解有关持久卷管理的存储策略的详细信息。 + 你可以参考[基于存储策略的动态制备卷管理](https://github.com/vmware-archive/vsphere-storage-for-kubernetes/blob/fa4c8b8ad46a85b6555d715dd9d27ff69839df53/documentation/policy-based-mgmt.md), + 进一步了解有关持久卷管理的存储策略的详细信息。 -* `monitors`:Ceph monitor,逗号分隔。该参数是必需的。 -* `adminId`:Ceph 客户端 ID,用于在池 ceph 池中创建映像。默认是 "admin"。 -* `adminSecret`:`adminId` 的 Secret 名称。该参数是必需的。 +- `monitors`:Ceph monitor,逗号分隔。该参数是必需的。 +- `adminId`:Ceph 客户端 ID,用于在池 ceph 池中创建映像。默认是 "admin"。 +- `adminSecret`:`adminId` 的 Secret 名称。该参数是必需的。 提供的 secret 必须有值为 "kubernetes.io/rbd" 的 type 参数。 -* `adminSecretNamespace`:`adminSecret` 的命名空间。默认是 "default"。 -* `pool`:Ceph RBD 池。默认是 "rbd"。 -* `userId`:Ceph 客户端 ID,用于映射 RBD 镜像。默认与 `adminId` 相同。 +- `adminSecretNamespace`:`adminSecret` 的命名空间。默认是 "default"。 +- `pool`:Ceph RBD 池。默认是 "rbd"。 +- `userId`:Ceph 客户端 ID,用于映射 RBD 镜像。默认与 `adminId` 相同。 -* `userSecretName`:用于映射 RBD 镜像的 `userId` 的 Ceph Secret 的名字。 +- `userSecretName`:用于映射 RBD 镜像的 `userId` 的 Ceph Secret 的名字。 它必须与 PVC 存在于相同的 namespace 中。该参数是必需的。 提供的 secret 必须具有值为 "kubernetes.io/rbd" 的 type 参数,例如以这样的方式创建: - ```shell - kubectl create secret generic ceph-secret --type="kubernetes.io/rbd" \ - --from-literal=key='QVFEQ1pMdFhPUnQrSmhBQUFYaERWNHJsZ3BsMmNjcDR6RFZST0E9PQ==' \ - --namespace=kube-system - ``` + ```shell + kubectl create secret generic ceph-secret --type="kubernetes.io/rbd" \ + --from-literal=key='QVFEQ1pMdFhPUnQrSmhBQUFYaERWNHJsZ3BsMmNjcDR6RFZST0E9PQ==' \ + --namespace=kube-system + ``` -* `userSecretNamespace`:`userSecretName` 的命名空间。 -* `fsType`:Kubernetes 支持的 fsType。默认:`"ext4"`。 -* `imageFormat`:Ceph RBD 镜像格式,"1" 或者 "2"。默认值是 "1"。 -* `imageFeatures`:这个参数是可选的,只能在你将 `imageFormat` 设置为 "2" 才使用。 +- `userSecretNamespace`:`userSecretName` 的命名空间。 +- `fsType`:Kubernetes 支持的 fsType。默认:`"ext4"`。 +- `imageFormat`:Ceph RBD 镜像格式,"1" 或者 "2"。默认值是 "1"。 +- `imageFeatures`:这个参数是可选的,只能在你将 `imageFormat` 设置为 "2" 才使用。 目前支持的功能只是 `layering`。默认是 "",没有功能打开。 #### Azure Unmanaged Disk Storage Class(非托管磁盘存储类){#azure-unmanaged-disk-storage-class} ```yaml -kind: StorageClass apiVersion: storage.k8s.io/v1 +kind: StorageClass metadata: name: slow provisioner: kubernetes.io/azure-disk @@ -845,27 +846,27 @@ parameters: ``` -* `skuName`:Azure 存储帐户 Sku 层。默认为空。 -* `location`:Azure 存储帐户位置。默认为空。 -* `storageAccount`:Azure 存储帐户名称。 +- `skuName`:Azure 存储帐户 Sku 层。默认为空。 +- `location`:Azure 存储帐户位置。默认为空。 +- `storageAccount`:Azure 存储帐户名称。 如果提供存储帐户,它必须位于与集群相同的资源组中,并且 `location` 是被忽略的。如果未提供存储帐户,则会在与集群相同的资源组中创建新的存储帐户。 #### Azure 磁盘 Storage Class(从 v1.7.2 开始){#azure-disk-storage-class} ```yaml -kind: StorageClass apiVersion: storage.k8s.io/v1 +kind: StorageClass metadata: name: slow provisioner: kubernetes.io/azure-disk @@ -875,33 +876,34 @@ parameters: ``` -* `storageaccounttype`:Azure 存储帐户 Sku 层。默认为空。 -* `kind`:可能的值是 `shared`、`dedicated` 和 `managed`(默认)。 + +- `storageaccounttype`:Azure 存储帐户 Sku 层。默认为空。 +- `kind`:可能的值是 `shared`、`dedicated` 和 `managed`(默认)。 当 `kind` 的值是 `shared` 时,所有非托管磁盘都在集群的同一个资源组中的几个共享存储帐户中创建。 当 `kind` 的值是 `dedicated` 时,将为在集群的同一个资源组中新的非托管磁盘创建新的专用存储帐户。 -* `resourceGroup`:指定要创建 Azure 磁盘所属的资源组。必须是已存在的资源组名称。 - 若未指定资源组,磁盘会默认放入与当前 Kubernetes 集群相同的资源组中。 +- `resourceGroup`:指定要创建 Azure 磁盘所属的资源组。必须是已存在的资源组名称。 +若未指定资源组,磁盘会默认放入与当前 Kubernetes 集群相同的资源组中。 -- Premium VM 可以同时添加 Standard_LRS 和 Premium_LRS 磁盘,而 Standard + --> +* Premium VM 可以同时添加 Standard_LRS 和 Premium_LRS 磁盘,而 Standard 虚拟机只能添加 Standard_LRS 磁盘。 -- 托管虚拟机只能连接托管磁盘,非托管虚拟机只能连接非托管磁盘。 +* 托管虚拟机只能连接托管磁盘,非托管虚拟机只能连接非托管磁盘。 -* `skuName`:Azure 存储帐户 Sku 层。默认为空。 -* `location`:Azure 存储帐户位置。默认为空。 -* `storageAccount`:Azure 存储帐户名称。默认为空。 +- `skuName`:Azure 存储帐户 Sku 层。默认为空。 +- `location`:Azure 存储帐户位置。默认为空。 +- `storageAccount`:Azure 存储帐户名称。默认为空。 如果不提供存储帐户,会搜索所有与资源相关的存储帐户,以找到一个匹配 `skuName` 和 `location` 的账号。 如果提供存储帐户,它必须存在于与集群相同的资源组中,`skuName` 和 `location` 会被忽略。 -* `secretNamespace`:包含 Azure 存储帐户名称和密钥的密钥的名字空间。 +- `secretNamespace`:包含 Azure 存储帐户名称和密钥的密钥的名字空间。 默认值与 Pod 相同。 -* `secretName`:包含 Azure 存储帐户名称和密钥的密钥的名称。 +- `secretName`:包含 Azure 存储帐户名称和密钥的密钥的名称。 默认值为 `azure-storage-account--secret` -* `readOnly`:指示是否将存储安装为只读的标志。默认为 false,表示"读/写"挂载。 - 该设置也会影响VolumeMounts中的 `ReadOnly` 设置。 +- `readOnly`:指示是否将存储安装为只读的标志。默认为 false,表示"读/写"挂载。 + 该设置也会影响 VolumeMounts 中的 `ReadOnly` 设置。 -* `fs`:选择的文件系统:`none/xfs/ext4`(默认:`ext4`)。 -* `block_size`:以 Kbytes 为单位的块大小(默认值:`32`)。 -* `repl`:同步副本数量,以复制因子 `1..3`(默认值:`1`)的形式提供。 +- `fs`:选择的文件系统:`none/xfs/ext4`(默认:`ext4`)。 +- `block_size`:以 Kbytes 为单位的块大小(默认值:`32`)。 +- `repl`:同步副本数量,以复制因子 `1..3`(默认值:`1`)的形式提供。 这里需要填写字符串,即,`"1"` 而不是 `1`。 -* `io_priority`:决定是否从更高性能或者较低优先级存储创建卷 +- `io_priority`:决定是否从更高性能或者较低优先级存储创建卷 `high/medium/low`(默认值:`low`)。 -* `snap_interval`:触发快照的时钟/时间间隔(分钟)。 +- `snap_interval`:触发快照的时钟/时间间隔(分钟)。 快照是基于与先前快照的增量变化,0 是禁用快照(默认:`0`)。 这里需要填写字符串,即,是 `"70"` 而不是 `70`。 -* `aggregation_level`:指定卷分配到的块数量,0 表示一个非聚合卷(默认:`0`)。 +- `aggregation_level`:指定卷分配到的块数量,0 表示一个非聚合卷(默认:`0`)。 这里需要填写字符串,即,是 `"0"` 而不是 `0`。 -* `ephemeral`:指定卷在卸载后进行清理还是持久化。 +- `ephemeral`:指定卷在卸载后进行清理还是持久化。 `emptyDir` 的使用场景可以将这个值设置为 true, `persistent volumes` 的使用场景可以将这个值设置为 false (例如 Cassandra 这样的数据库) From 3be6ec244be48b3d432998a852caae06873421c4 Mon Sep 17 00:00:00 2001 From: NitishKumar06 Date: Wed, 4 Jan 2023 23:02:12 +0530 Subject: [PATCH 127/279] Hyperlinked kubernetes.io to kubernetes,io/release/download --- content/en/_index.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/content/en/_index.html b/content/en/_index.html index b30fc0edbec..c685c6a4c4f 100644 --- a/content/en/_index.html +++ b/content/en/_index.html @@ -30,7 +30,9 @@ Whether testing locally or running a global enterprise, Kubernetes flexibility g {{% blocks/feature image="suitcase" %}} #### Run K8s Anywhere -Kubernetes is open source giving you the freedom to take advantage of on-premises, hybrid, or public cloud infrastructure, letting you effortlessly move workloads to where it matters to you. +Kubernetes is open source giving you the freedom to take advantage of on-premises, hybrid, or public cloud infrastructure, letting you effortlessly move workloads to where it matters to you. + +To download Kubernetes, visit the [download](/releases/download/) section. {{% /blocks/feature %}} From 397a0bbc32f8788a09390ba948b1977cd36c0b48 Mon Sep 17 00:00:00 2001 From: suning0 Date: Tue, 7 Feb 2023 00:23:00 +0800 Subject: [PATCH 128/279] [zh-cn]Update cluster-cidr-v1alpha1.md [zh-cn]Update cluster-cidr-v1alpha1.md --- .../kubernetes-api/cluster-resources/cluster-cidr-v1alpha1.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/zh-cn/docs/reference/kubernetes-api/cluster-resources/cluster-cidr-v1alpha1.md b/content/zh-cn/docs/reference/kubernetes-api/cluster-resources/cluster-cidr-v1alpha1.md index 97539890a23..a4fd99af85b 100644 --- a/content/zh-cn/docs/reference/kubernetes-api/cluster-resources/cluster-cidr-v1alpha1.md +++ b/content/zh-cn/docs/reference/kubernetes-api/cluster-resources/cluster-cidr-v1alpha1.md @@ -92,10 +92,10 @@ ClusterCIDRSpec 定义 ClusterCIDR 的预期状态。 - **ipv6** (string) - ipv6 以 CIDR 表示法定义 IPv6 IP 块(例如 “fd12:3456:789a:1::/64”)。 + ipv6 以 CIDR 表示法定义 IPv6 IP 块(例如 “2001:db8::/64”)。 必须至少指定 ipv4 和 ipv6 之一。 该字段是不可变的。 - **nodeSelector** (NodeSelector) From 3237e6a8dfd8fa25868444b10deadb8618d2bbe1 Mon Sep 17 00:00:00 2001 From: suning0 Date: Tue, 7 Feb 2023 23:23:24 +0800 Subject: [PATCH 129/279] [zh-cn]Update secret-pod.yaml --- content/zh-cn/examples/pods/inject/secret-pod.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/content/zh-cn/examples/pods/inject/secret-pod.yaml b/content/zh-cn/examples/pods/inject/secret-pod.yaml index b1abd9b0372..61e7a130505 100644 --- a/content/zh-cn/examples/pods/inject/secret-pod.yaml +++ b/content/zh-cn/examples/pods/inject/secret-pod.yaml @@ -10,6 +10,7 @@ spec: # name 必须与下面的卷名匹配 - name: secret-volume mountPath: /etc/secret-volume + readOnly: true # Secret 数据通过一个卷暴露给该 Pod 中的容器 volumes: - name: secret-volume From 5f9a7ab6d454be74f97a49a46c219c6c8884a094 Mon Sep 17 00:00:00 2001 From: Kinzhi Date: Tue, 7 Feb 2023 23:24:37 +0800 Subject: [PATCH 130/279] [zh-cn]SYNC debug-running-pod.md --- .../docs/tasks/debug/debug-application/debug-running-pod.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/content/zh-cn/docs/tasks/debug/debug-application/debug-running-pod.md b/content/zh-cn/docs/tasks/debug/debug-application/debug-running-pod.md index 73c3d6be823..b01f272be32 100644 --- a/content/zh-cn/docs/tasks/debug/debug-application/debug-running-pod.md +++ b/content/zh-cn/docs/tasks/debug/debug-application/debug-running-pod.md @@ -176,12 +176,10 @@ Currently the only Condition associated with a Pod is the binary Ready condition 并且应该添加到相应服务的负载均衡池中。 最后,你还可以看到与 Pod 相关的近期事件。 -系统通过指示第一次和最后一次看到事件以及看到该事件的次数来压缩多个相同的事件。 “From” 标明记录事件的组件, -“SubobjectPath” 告诉你引用了哪个对象(例如 Pod 中的容器), “Reason” 和 “Message” 告诉你发生了什么。 -Distributed systems often have a need for "leases", which provides a mechanism to lock shared resources and coordinate activity between nodes. -In Kubernetes, the "lease" concept is represented by `Lease` objects in the `coordination.k8s.io` API group, which are used for system-critical -capabilities like node heart beats and component-level leader election. +Distributed systems often have a need for _leases_, which provide a mechanism to lock shared resources +and coordinate activity between members of a set. +In Kubernetes, the lease concept is represented by [Lease](/docs/reference/kubernetes-api/cluster-resources/lease-v1/) +objects in the `coordination.k8s.io` {{< glossary_tooltip text="API Group" term_id="api-group" >}}, +which are used for system-critical capabilities such as node heartbeats and component-level leader election. -## Node Heart Beats +## Node heartbeats {#node-heart-beats} -Kubernetes uses the Lease API to communicate kubelet node heart beats to the Kubernetes API server. +Kubernetes uses the Lease API to communicate kubelet node heartbeats to the Kubernetes API server. For every `Node` , there is a `Lease` object with a matching name in the `kube-node-lease` -namespace. Under the hood, every kubelet heart beat is an UPDATE request to this `Lease` object, updating +namespace. Under the hood, every kubelet heartbeat is an **update** request to this `Lease` object, updating the `spec.renewTime` field for the Lease. The Kubernetes control plane uses the time stamp of this field to determine the availability of this `Node`. See [Node Lease objects](/docs/concepts/architecture/nodes/#heartbeats) for more details. -## Leader Election +## Leader election -Leases are also used in Kubernetes to ensure only one instance of a component is running at any given time. +Kubernetes also uses Leases to ensure only one instance of a component is running at any given time. This is used by control plane components like `kube-controller-manager` and `kube-scheduler` in HA configurations, where only one instance of the component should be actively running while the other instances are on stand-by. -## API Server Identity +## API server identity {{< feature-state for_k8s_version="v1.26" state="beta" >}} @@ -43,22 +45,23 @@ You can inspect Leases owned by each kube-apiserver by checking for lease object with the name `kube-apiserver-`. Alternatively you can use the label selector `k8s.io/component=kube-apiserver`: ```shell -$ kubectl -n kube-system get lease -l k8s.io/component=kube-apiserver +kubectl -n kube-system get lease -l k8s.io/component=kube-apiserver +``` +``` NAME HOLDER AGE kube-apiserver-c4vwjftbvpc5os2vvzle4qg27a kube-apiserver-c4vwjftbvpc5os2vvzle4qg27a_9cbf54e5-1136-44bd-8f9a-1dcd15c346b4 5m33s kube-apiserver-dz2dqprdpsgnm756t5rnov7yka kube-apiserver-dz2dqprdpsgnm756t5rnov7yka_84f2a85d-37c1-4b14-b6b9-603e62e4896f 4m23s kube-apiserver-fyloo45sdenffw2ugwaz3likua kube-apiserver-fyloo45sdenffw2ugwaz3likua_c5ffa286-8a9a-45d4-91e7-61118ed58d2e 4m43s ``` -The SHA256 hash used in the lease name is based on the OS hostname as seen by kube-apiserver. Each kube-apiserver should be +The SHA256 hash used in the lease name is based on the OS hostname as seen by that API server. Each kube-apiserver should be configured to use a hostname that is unique within the cluster. New instances of kube-apiserver that use the same hostname -will take over existing Leases using a new holder identity, as opposed to instantiating new lease objects. You can check the +will take over existing Leases using a new holder identity, as opposed to instantiating new Lease objects. You can check the hostname used by kube-apisever by checking the value of the `kubernetes.io/hostname` label: ```shell -$ kubectl -n kube-system get lease kube-apiserver-c4vwjftbvpc5os2vvzle4qg27a -o yaml +kubectl -n kube-system get lease kube-apiserver-c4vwjftbvpc5os2vvzle4qg27a -o yaml ``` - ```yaml apiVersion: coordination.k8s.io/v1 kind: Lease @@ -78,3 +81,23 @@ spec: ``` Expired leases from kube-apiservers that no longer exist are garbage collected by new kube-apiservers after 1 hour. + +You can disable API server identity leases by disabling the `APIServerIdentity` +[feature gate](/docs/reference/command-line-tools-reference/feature-gates/). + +## Workloads {#custom-workload} + +Your own workload can define its own use of Leases. For example, you might run a custom +{{< glossary_tooltip term_id="controller" text="controller" >}} where a primary or leader member +performs operations that its peers do not. You define a Lease so that the controller replicas can select +or elect a leader, using the Kubernetes API for coordination. +If you do use a Lease, it's a good practice to define a name for the Lease that is obviously linked to +the product or component. For example, if you have a component named Example Foo, use a Lease named +`example-foo`. + +If a cluster operator or another end user could deploy multiple instances of a component, select a name +prefix and pick a mechanism (such as hash of the name of the Deployment) to avoid name collisions +for the Leases. + +You can use another approach so long as it achieves the same outcome: different software products do +not conflict with one another. diff --git a/content/en/docs/concepts/architecture/nodes.md b/content/en/docs/concepts/architecture/nodes.md index 9cf68b6b841..944083bc4d0 100644 --- a/content/en/docs/concepts/architecture/nodes.md +++ b/content/en/docs/concepts/architecture/nodes.md @@ -274,7 +274,7 @@ availability of each node, and to take action when failures are detected. For nodes there are two forms of heartbeats: * updates to the `.status` of a Node -* [Lease](/docs/reference/kubernetes-api/cluster-resources/lease-v1/) objects +* [Lease](/docs/concepts/architecture/leases/) objects within the `kube-node-lease` {{< glossary_tooltip term_id="namespace" text="namespace">}}. Each Node has an associated Lease object. diff --git a/content/en/docs/concepts/overview/working-with-objects/namespaces.md b/content/en/docs/concepts/overview/working-with-objects/namespaces.md index 9ec8edaffda..6e838bac89a 100644 --- a/content/en/docs/concepts/overview/working-with-objects/namespaces.md +++ b/content/en/docs/concepts/overview/working-with-objects/namespaces.md @@ -44,7 +44,7 @@ Kubernetes starts with four initial namespaces: : Kubernetes includes this namespace so that you can start using your new cluster without first creating a namespace. `kube-node-lease` -: This namespace holds [Lease](/docs/reference/kubernetes-api/cluster-resources/lease-v1/) objects associated with each node. Node leases allow the kubelet to send [heartbeats](/docs/concepts/architecture/nodes/#heartbeats) so that the control plane can detect node failure. +: This namespace holds [Lease](/docs/concepts/architecture/leases/) objects associated with each node. Node leases allow the kubelet to send [heartbeats](/docs/concepts/architecture/nodes/#heartbeats) so that the control plane can detect node failure. `kube-public` : This namespace is readable by *all* clients (including those not authenticated). This namespace is mostly reserved for cluster usage, in case that some resources should be visible and readable publicly throughout the whole cluster. The public aspect of this namespace is only a convention, not a requirement. diff --git a/content/en/docs/reference/command-line-tools-reference/feature-gates.md b/content/en/docs/reference/command-line-tools-reference/feature-gates.md index a7b1058b10b..1ea5df83424 100644 --- a/content/en/docs/reference/command-line-tools-reference/feature-gates.md +++ b/content/en/docs/reference/command-line-tools-reference/feature-gates.md @@ -383,7 +383,7 @@ Each feature gate is designed for enabling/disabling a specific feature: to see the requesting subject's authentication information. See [API access to authentication information for a client](/docs/reference/access-authn-authz/authentication/#self-subject-review) for more details. -- `APIServerIdentity`: Assign each API server an ID in a cluster. +- `APIServerIdentity`: Assign each API server an ID in a cluster, using a [Lease](/docs/concepts/architecture/leases). - `APIServerTracing`: Add support for distributed tracing in the API server. See [Traces for Kubernetes System Components](/docs/concepts/cluster-administration/system-traces) for more details. - `AdvancedAuditing`: Enable [advanced auditing](/docs/tasks/debug/debug-cluster/audit/#advanced-audit) From 28b50215b81f6deb6dc53f5d95b8932f5d81e341 Mon Sep 17 00:00:00 2001 From: seancrasto <103709488+seancrasto@users.noreply.github.com> Date: Tue, 7 Feb 2023 18:05:50 -0500 Subject: [PATCH 133/279] Update job.md Corrected spelling of specifying. --- content/en/docs/concepts/workloads/controllers/job.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/docs/concepts/workloads/controllers/job.md b/content/en/docs/concepts/workloads/controllers/job.md index a05ad752c3d..ecdcb62027b 100644 --- a/content/en/docs/concepts/workloads/controllers/job.md +++ b/content/en/docs/concepts/workloads/controllers/job.md @@ -794,7 +794,7 @@ These are some requirements and semantics of the API: are evaluated in order. Once a rule matches a Pod failure, the remaining rules are ignored. When no rule matches the Pod failure, the default handling applies. -- you may want to restrict a rule to a specific container by specifing its name +- you may want to restrict a rule to a specific container by specifying its name in`spec.podFailurePolicy.rules[*].containerName`. When not specified the rule applies to all containers. When specified, it should match one the container or `initContainer` names in the Pod template. From e341ae9d7a25c5d1ba9ab0015c2b42d088a34fd6 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 8 Feb 2023 08:05:48 +0800 Subject: [PATCH 134/279] [zh] sync /overview/working-with-objects/namespaces.md --- .../working-with-objects/namespaces.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/content/zh-cn/docs/concepts/overview/working-with-objects/namespaces.md b/content/zh-cn/docs/concepts/overview/working-with-objects/namespaces.md index a872a08ea91..5ff45d85f90 100644 --- a/content/zh-cn/docs/concepts/overview/working-with-objects/namespaces.md +++ b/content/zh-cn/docs/concepts/overview/working-with-objects/namespaces.md @@ -58,8 +58,7 @@ resources, such as different versions of the same software: use resources within the same namespace. --> 不必使用多个名字空间来分隔仅仅轻微不同的资源,例如同一软件的不同版本: -应该使用{{< glossary_tooltip text="标签" term_id="label" >}} -来区分同一名字空间中的不同资源。 +应该使用{{< glossary_tooltip text="标签" term_id="label" >}}来区分同一名字空间中的不同资源。 {{< note >}} -{{< note >}} 避免使用前缀 `kube-` 创建名字空间,因为它是为 Kubernetes 系统名字空间保留的。 {{< /note >}} @@ -213,8 +213,8 @@ namespaces can have short DNS names that overlap with public DNS records. Workloads from any namespace performing a DNS lookup without a [trailing dot](https://datatracker.ietf.org/doc/html/rfc1034#page-8) will be redirected to those services, taking precedence over public DNS. --> -通过创建与[公共顶级域名](https://data.iana.org/TLD/tlds-alpha-by-domain.txt) -同名的名字空间,这些名字空间中的服务可以拥有与公共 DNS 记录重叠的、较短的 DNS 名称。 +通过创建与[公共顶级域名](https://data.iana.org/TLD/tlds-alpha-by-domain.txt)同名的名字空间, +这些名字空间中的服务可以拥有与公共 DNS 记录重叠的、较短的 DNS 名称。 所有名字空间中的负载在执行 DNS 查找时, 如果查找的名称没有[尾部句点](https://datatracker.ietf.org/doc/html/rfc1034#page-8), 就会被重定向到这些服务上,因此呈现出比公共 DNS 更高的优先序。 @@ -276,8 +276,7 @@ The Kubernetes control plane sets an immutable {{< glossary_tooltip text="label" [feature gate](/docs/reference/command-line-tools-reference/feature-gates/) is enabled. The value of the label is the namespace name. --> -Kubernetes 控制面会为所有名字空间设置一个不可变更的 -{{< glossary_tooltip text="标签" term_id="label" >}} +Kubernetes 控制面会为所有名字空间设置一个不可变更的{{< glossary_tooltip text="标签" term_id="label" >}} `kubernetes.io/metadata.name`,只要 `NamespaceDefaultLabelName` 这一[特性门控](/zh-cn/docs/reference/command-line-tools-reference/feature-gates/)被启用。 标签的值是名字空间的名称。 From 232c952911c3789713cc00597d737bffdb7c8d73 Mon Sep 17 00:00:00 2001 From: Arhell Date: Wed, 8 Feb 2023 03:38:36 +0200 Subject: [PATCH 135/279] [ja] Create Secret / Fixed the raw data example --- .../tasks/configmap-secret/managing-secret-using-kubectl.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ja/docs/tasks/configmap-secret/managing-secret-using-kubectl.md b/content/ja/docs/tasks/configmap-secret/managing-secret-using-kubectl.md index 7be8c0b8907..b52bcc22e40 100644 --- a/content/ja/docs/tasks/configmap-secret/managing-secret-using-kubectl.md +++ b/content/ja/docs/tasks/configmap-secret/managing-secret-using-kubectl.md @@ -59,7 +59,7 @@ kubectl create secret generic db-user-pass \ ```shell kubectl create secret generic db-user-pass \ - --from-literal=username=devuser \ + --from-literal=username=admin \ --from-literal=password='S!B\*d$zDsb=' ``` From ad50091bb983e3617f5667381e39c9927a91a483 Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Wed, 8 Feb 2023 10:34:12 +0800 Subject: [PATCH 136/279] [zh] Cleanup page disruption --- .../concepts/workloads/pods/disruptions.md | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/content/zh-cn/docs/concepts/workloads/pods/disruptions.md b/content/zh-cn/docs/concepts/workloads/pods/disruptions.md index 54802889614..9290801a520 100644 --- a/content/zh-cn/docs/concepts/workloads/pods/disruptions.md +++ b/content/zh-cn/docs/concepts/workloads/pods/disruptions.md @@ -212,7 +212,8 @@ For example, the `kubectl drain` subcommand lets you mark a node as going out of service. When you run `kubectl drain`, the tool tries to evict all of the Pods on the Node you're taking out of service. The eviction request that `kubectl` submits on your behalf may be temporarily rejected, so the tool periodically retries all failed -requests until all Pods on the target node are terminated, or until a configurable timeout is reached. +requests until all Pods on the target node are terminated, or until a configurable timeout +is reached. --> 例如,`kubectl drain` 命令可以用来标记某个节点即将停止服务。 运行 `kubectl drain` 命令时,工具会尝试驱逐你所停服的节点上的所有 Pod。 @@ -426,7 +427,7 @@ can happen, according to: - 控制器的类型 - 集群的资源能力 - ## Pod 干扰状况 {#pod-disruption-conditions} @@ -451,7 +452,7 @@ enabled in your cluster. [特性门控](/zh-cn/docs/reference/command-line-tools-reference/feature-gates/)。 {{< /note >}} - `PreemptionByKubeScheduler` : Pod 将被调度器{{}}, 目的是接受优先级更高的新 Pod。 要了解更多的相关信息,请参阅 [Pod 优先级和抢占](/zh-cn/docs/concepts/scheduling-eviction/pod-priority-preemption/)。 - `DeletionByTaintManager` : 由于 Pod 不能容忍 `NoExecute` 污点,Pod 将被 @@ -482,14 +483,14 @@ Taint Manager(`kube-controller-manager` 中节点生命周期控制器的一 `EvictionByEvictionAPI` : Pod 已被标记为{{}}。 - `DeletionByPodGC` : 绑定到一个不再存在的 Node 上的 Pod 将被 @@ -501,8 +502,8 @@ Taint Manager(`kube-controller-manager` 中节点生命周期控制器的一 --> `TerminationByKubelet` : Pod - 由于{{}}或[节点体面关闭](/zh-cn/docs/concepts/architecture/nodes/#graceful-node-shutdown)而被 - kubelet 终止。 +由于{{}}或[节点体面关闭](/zh-cn/docs/concepts/architecture/nodes/#graceful-node-shutdown)而被 +kubelet 终止。 {{< note >}} Pod 的干扰可能会被中断。控制平面可能会重新尝试继续干扰同一个 Pod,但这没办法保证。 因此,`DisruptionTarget` 条件可能会添被加到 Pod 上, @@ -527,9 +528,9 @@ phase (see also [Pod garbage collection](/docs/concepts/workloads/pods/pod-lifec 则 Pod 垃圾回收器 (PodGC) 也会将这些 Pod 标记为失效 (另见 [Pod 垃圾回收](/zh-cn/docs/concepts/workloads/pods/pod-lifecycle/#pod-garbage-collection))。 - 使用 Job(或 CronJob)时,你可能希望将这些 Pod 干扰状况作为 Job [Pod 失效策略](/zh-cn/docs/concepts/workloads/controllers/job#pod-failure-policy)的一部分。 From a70698ed634453956f407faefc83f2407ec82d0f Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Wed, 8 Feb 2023 13:26:19 +0800 Subject: [PATCH 137/279] Cleanup page replicaset --- .../workloads/controllers/replicaset.md | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/content/en/docs/concepts/workloads/controllers/replicaset.md b/content/en/docs/concepts/workloads/controllers/replicaset.md index 35162c8dbc1..912e0346703 100644 --- a/content/en/docs/concepts/workloads/controllers/replicaset.md +++ b/content/en/docs/concepts/workloads/controllers/replicaset.md @@ -69,7 +69,7 @@ kubectl get rs And see the frontend one you created: -```shell +``` NAME DESIRED CURRENT READY AGE frontend 3 3 3 6s ``` @@ -118,7 +118,7 @@ kubectl get pods You should see Pod information similar to: -```shell +``` NAME READY STATUS RESTARTS AGE frontend-b2zdv 1/1 Running 0 6m36s frontend-vcmts 1/1 Running 0 6m36s @@ -160,7 +160,7 @@ While you can create bare Pods with no problems, it is strongly recommended to m labels which match the selector of one of your ReplicaSets. The reason for this is because a ReplicaSet is not limited to owning Pods specified by its template-- it can acquire other Pods in the manner specified in the previous sections. -Take the previous frontend ReplicaSet example, and the Pods specified in the following manifest: +Take the previous frontend ReplicaSet example, and the Pods specified in the following manifest: {{< codenew file="pods/pod-rs.yaml" >}} @@ -229,9 +229,9 @@ As with all other Kubernetes API objects, a ReplicaSet needs the `apiVersion`, ` For ReplicaSets, the `kind` is always a ReplicaSet. When the control plane creates new Pods for a ReplicaSet, the `.metadata.name` of the -ReplicaSet is part of the basis for naming those Pods. The name of a ReplicaSet must be a valid +ReplicaSet is part of the basis for naming those Pods. The name of a ReplicaSet must be a valid [DNS subdomain](/docs/concepts/overview/working-with-objects/names#dns-subdomain-names) -value, but this can produce unexpected results for the Pod hostnames. For best compatibility, +value, but this can produce unexpected results for the Pod hostnames. For best compatibility, the name should follow the more restrictive rules for a [DNS label](/docs/concepts/overview/working-with-objects/names#dns-label-names). @@ -288,8 +288,8 @@ When using the REST API or the `client-go` library, you must set `propagationPol ```shell kubectl proxy --port=8080 curl -X DELETE 'localhost:8080/apis/apps/v1/namespaces/default/replicasets/frontend' \ -> -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Foreground"}' \ -> -H "Content-Type: application/json" + -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Foreground"}' \ + -H "Content-Type: application/json" ``` ### Deleting just a ReplicaSet @@ -303,11 +303,11 @@ For example: ```shell kubectl proxy --port=8080 curl -X DELETE 'localhost:8080/apis/apps/v1/namespaces/default/replicasets/frontend' \ -> -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Orphan"}' \ -> -H "Content-Type: application/json" + -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Orphan"}' \ + -H "Content-Type: application/json" ``` -Once the original is deleted, you can create a new ReplicaSet to replace it. As long +Once the original is deleted, you can create a new ReplicaSet to replace it. As long as the old and new `.spec.selector` are the same, then the new one will adopt the old Pods. However, it will not make any effort to make existing Pods match a new, different pod template. To update Pods to a new spec in a controlled way, use a @@ -335,19 +335,19 @@ prioritize scaling down pods based on the following general algorithm: 1. If the pods' creation times differ, the pod that was created more recently comes before the older pod (the creation times are bucketed on an integer log scale when the `LogarithmicScaleDown` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/) is enabled) - + If all of the above match, then selection is random. -### Pod deletion cost +### Pod deletion cost {{< feature-state for_k8s_version="v1.22" state="beta" >}} -Using the [`controller.kubernetes.io/pod-deletion-cost`](/docs/reference/labels-annotations-taints/#pod-deletion-cost) +Using the [`controller.kubernetes.io/pod-deletion-cost`](/docs/reference/labels-annotations-taints/#pod-deletion-cost) annotation, users can set a preference regarding which pods to remove first when downscaling a ReplicaSet. The annotation should be set on the pod, the range is [-2147483647, 2147483647]. It represents the cost of deleting a pod compared to other pods belonging to the same ReplicaSet. Pods with lower deletion -cost are preferred to be deleted before pods with higher deletion cost. +cost are preferred to be deleted before pods with higher deletion cost. The implicit value for this annotation for pods that don't set it is 0; negative values are permitted. Invalid values will be rejected by the API server. @@ -360,13 +360,13 @@ This feature is beta and enabled by default. You can disable it using the - This is honored on a best-effort basis, so it does not offer any guarantees on pod deletion order. - Users should avoid updating the annotation frequently, such as updating it based on a metric value, because doing so will generate a significant number of pod updates on the apiserver. -{{< /note >}} + {{< /note >}} #### Example Use Case -The different pods of an application could have different utilization levels. On scale down, the application +The different pods of an application could have different utilization levels. On scale down, the application may prefer to remove the pods with lower utilization. To avoid frequently updating the pods, the application -should update `controller.kubernetes.io/pod-deletion-cost` once before issuing a scale down (setting the +should update `controller.kubernetes.io/pod-deletion-cost` once before issuing a scale down (setting the annotation to a value proportional to pod utilization level). This works if the application itself controls the down scaling; for example, the driver pod of a Spark deployment. @@ -400,7 +400,7 @@ kubectl autoscale rs frontend --max=10 --min=3 --cpu-percent=50 [`Deployment`](/docs/concepts/workloads/controllers/deployment/) is an object which can own ReplicaSets and update them and their Pods via declarative, server-side rolling updates. -While ReplicaSets can be used independently, today they're mainly used by Deployments as a mechanism to orchestrate Pod +While ReplicaSets can be used independently, today they're mainly used by Deployments as a mechanism to orchestrate Pod creation, deletion and updates. When you use Deployments you don't have to worry about managing the ReplicaSets that they create. Deployments own and manage their ReplicaSets. As such, it is recommended to use Deployments when you want ReplicaSets. @@ -422,7 +422,7 @@ expected to terminate on their own (that is, batch jobs). ### DaemonSet Use a [`DaemonSet`](/docs/concepts/workloads/controllers/daemonset/) instead of a ReplicaSet for Pods that provide a -machine-level function, such as machine monitoring or machine logging. These Pods have a lifetime that is tied +machine-level function, such as machine monitoring or machine logging. These Pods have a lifetime that is tied 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. @@ -444,4 +444,3 @@ As such, ReplicaSets are preferred over ReplicationControllers 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. - From 3f1a214261dcd4e415ad44524d664fd121a02114 Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Wed, 8 Feb 2023 10:07:44 +0800 Subject: [PATCH 138/279] [zh]Cleanup pod-lifecycle.md --- .../concepts/workloads/pods/pod-lifecycle.md | 43 ++++++++++--------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/content/zh-cn/docs/concepts/workloads/pods/pod-lifecycle.md b/content/zh-cn/docs/concepts/workloads/pods/pod-lifecycle.md index 0fb350715b0..71f8bc5050e 100644 --- a/content/zh-cn/docs/concepts/workloads/pods/pod-lifecycle.md +++ b/content/zh-cn/docs/concepts/workloads/pods/pod-lifecycle.md @@ -109,6 +109,10 @@ created anew. {{< figure src="/images/docs/pod.svg" title="Pod 结构图例" class="diagram-medium" >}} + *一个包含多个容器的 Pod 中包含一个用来拉取文件的程序和一个 Web 服务器, 均使用持久卷作为容器间共享的存储。* @@ -281,8 +285,7 @@ The `restartPolicy` applies to all containers in the Pod. `restartPolicy` only refers to restarts of the containers by the kubelet on the same node. After containers in a Pod exit, the kubelet restarts them with an exponential back-off delay (10s, 20s, 40s, …), that is capped at five minutes. Once a container has executed for 10 minutes -without any problems, the kubelet resets the restart backoff timer for -that container. +without any problems, the kubelet resets the restart backoff timer for that container. --> ## 容器重启策略 {#restart-policy} @@ -438,21 +441,21 @@ When a Pod's containers are Ready but at least one custom condition is missing o 当 Pod 的容器都已就绪,但至少一个定制状况没有取值或者取值为 `False`, `kubelet` 将 Pod 的[状况](#pod-conditions)设置为 `ContainersReady`。 - ### Pod 网络就绪 {#pod-has-network} {{< feature-state for_k8s_version="v1.25" state="alpha" >}} - 在 Pod 被调度到某节点后,它需要被 Kubelet 接受并且挂载所需的卷。 一旦这些阶段完成,Kubelet 将与容器运行时(使用{{< glossary_tooltip term_id="cri" >}}) @@ -461,43 +464,43 @@ the `PodHasNetwork` condition in the `status.conditions` field of a Pod. kubelet 会通过 Pod 的 `status.conditions` 字段中的 `PodHasNetwork` 状况来报告 Pod 是否达到了初始化里程碑。 - 当 kubelet 检测到 Pod 不具备配置了网络的运行时沙箱时,`PodHasNetwork` 状况将被设置为 `False`。 以下场景中将会发生这种状况: - * 在 Pod 生命周期的早期阶段,kubelet 还没有开始使用容器运行时为 Pod 设置沙箱时。 * 在 Pod 生命周期的末期阶段,Pod 的沙箱由于以下原因被销毁时: * 节点重启时 Pod 没有被驱逐 * 对于使用虚拟机进行隔离的容器运行时,Pod 沙箱虚拟机重启时,需要创建一个新的沙箱和全新的容器网络配置。 - 在运行时插件成功完成 Pod 的沙箱创建和网络配置后, kubelet 会将 `PodHasNetwork` 状况设置为 `True`。 当 `PodHasNetwork` 状况设置为 `True` 后, Kubelet 可以开始拉取容器镜像和创建容器。 - 对于带有 Init 容器的 Pod,kubelet 会在 Init 容器成功完成后将 `Initialized` 状况设置为 `True` (这发生在运行时成功创建沙箱和配置网络之后), @@ -563,7 +566,7 @@ Each probe must define exactly one of these four mechanisms: `grpc` : 使用 [gRPC](https://grpc.io/) 执行一个远程过程调用。 目标应该实现 - [gRPC健康检查](https://grpc.io/grpc/core/md_doc_health-checking.html)。 + [gRPC 健康检查](https://grpc.io/grpc/core/md_doc_health-checking.html)。 如果响应的状态是 "SERVING",则认为诊断成功。 gRPC 探针是一个 Alpha 特性,只有在你启用了 "GRPCContainerProbe" [特性门控](/zh-cn/docs/reference/command-line-tools-reference/feature-gates/)时才能使用。 @@ -766,7 +769,7 @@ startup probe that checks the same endpoint as the liveness probe. The default f allow the container to start, without changing the default values of the liveness probe. This helps to protect against deadlocks. --> -如果你的容器启动时间通常超出 `initialDelaySeconds + failureThreshold × periodSeconds` +如果你的容器启动时间通常超出 `initialDelaySeconds + failureThreshold × periodSeconds` 总值,你应该设置一个启动探测,对存活态探针所使用的同一端点执行检查。 `periodSeconds` 的默认值是 10 秒。你应该将其 `failureThreshold` 设置得足够高, 以便容器有充足的时间完成启动,并且避免更改存活态探针所使用的默认值。 @@ -860,7 +863,7 @@ An example flow: 如果 `preStop` 回调所需要的时间长于默认的体面终止限期,你必须修改 `terminationGracePeriodSeconds` 属性值来使其正常工作。 {{< /note >}} - + -此准入控制器将拒绝任何试图设置特定提升 -[SecurityContext](/zh-cn/docs/tasks/configure-pod-container/security-context/) -中某些字段的 Pod,正如任务[为 Pod 或 Container 配置安全上下文](/zh-cn/docs/tasks/configure-pod-container/security-context/) -中所展示的那样。如果集群没有使用 -[Pod 安全性准入](/zh-cn/docs/concepts/security/pod-security-admission/)、 -[PodSecurityPolicy](/zh-cn/docs/concepts/security/pod-security-policy/), -也没有任何外部强制机制,那么你可以使用此准入控制器来限制安全上下文所能获取的值集。 +这个准入控制器插件是**过时的**且**不完整的**,它可能无法使用或无法达到你的预期。 +它最初旨在防止使用某些(但不是全部)安全敏感字段。 +事实上,像 `privileged` 这样的字段在创建时并没有被过滤, +而且该插件没有根据最新的字段和新的 API(例如 Pod 的 `ephemeralContainers` 字段)来更新。 -有关限制 Pod 权限的更多内容,请参阅 -[Pod 安全标准](/zh-cn/docs/concepts/security/pod-security-standards/)。 +采用 [Pod 安全性标准](/zh-cn/docs/concepts/security/pod-security-standards/)中的 `Restricted` +方案的 [Pod 安全性准入](/zh-cn/docs/concepts/security/pod-security-admission/)插件, +能以更好和最新的方式来表述此插件所要实现的目标。 +{{< /caution >}} + + +此准入控制器将拒绝任何尝试设置以下 +[SecurityContext](/zh-cn/docs/tasks/configure-pod-container/security-context/) +字段的 Pod: + +- `.spec.securityContext.supplementalGroups` +- `.spec.securityContext.seLinuxOptions` +- `.spec.securityContext.runAsUser` +- `.spec.securityContext.fsGroup` +- `.spec.(init)Containers[*].securityContext.seLinuxOptions` +- `.spec.(init)Containers[*].securityContext.runAsUser` + + +有关此插件的更多历史背景,请参阅 Kubernetes 博客中这篇有关 PodSecurityPolicy 及其移除的文章: +[The birth of PodSecurityPolicy](/blog/2022/08/23/podsecuritypolicy-the-historical-context/#the-birth-of-podsecuritypolicy)。 +这篇文章详细地介绍了 PodSecurityPolicy 的历史背景以及 Pod 的 `securityContext` 字段的诞生。 ### ServiceAccount {#serviceaccount} From 3b94924ca78a74f35ef0792bf4e2255265d348a3 Mon Sep 17 00:00:00 2001 From: Mengjiao Liu Date: Wed, 8 Feb 2023 20:44:07 +0800 Subject: [PATCH 145/279] Add mengjiao-liu to sig-docs-en-reviews --- OWNERS_ALIASES | 1 + 1 file changed, 1 insertion(+) diff --git a/OWNERS_ALIASES b/OWNERS_ALIASES index 79422a21832..59bb79c5a71 100644 --- a/OWNERS_ALIASES +++ b/OWNERS_ALIASES @@ -44,6 +44,7 @@ aliases: - divya-mohan0209 - kbhawkey - mehabhalodiya + - mengjiao-liu - natalisucks - nate-double-u - onlydole From a62f2b00283a51e03f443cd7b89ae5722092c3f6 Mon Sep 17 00:00:00 2001 From: windsonsea Date: Wed, 8 Feb 2023 20:49:25 +0800 Subject: [PATCH 146/279] [zh] sync setup-ha-etcd-with-kubeadm.md --- .../kubeadm/setup-ha-etcd-with-kubeadm.md | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/content/zh-cn/docs/setup/production-environment/tools/kubeadm/setup-ha-etcd-with-kubeadm.md b/content/zh-cn/docs/setup/production-environment/tools/kubeadm/setup-ha-etcd-with-kubeadm.md index ff56f95fc1f..2ad943284d0 100644 --- a/content/zh-cn/docs/setup/production-environment/tools/kubeadm/setup-ha-etcd-with-kubeadm.md +++ b/content/zh-cn/docs/setup/production-environment/tools/kubeadm/setup-ha-etcd-with-kubeadm.md @@ -377,27 +377,29 @@ on Kubernetes dual-stack support see [Dual-stack support with kubeadm](/docs/set --> 8. 可选:检查集群运行状况 - ```shell - docker run --rm -it \ - --net host \ - -v /etc/kubernetes:/etc/kubernetes registry.k8s.io/etcd:${ETCD_TAG} etcdctl \ + + 如果 `etcdctl` 不可用,你可以在容器镜像内运行此工具。 + 你可以使用 `crictl run` 这类工具直接在容器运行时执行此操作,而不是通过 Kubernetes。 + + ```sh + ETCDCTL_API=3 etcdctl \ --cert /etc/kubernetes/pki/etcd/peer.crt \ --key /etc/kubernetes/pki/etcd/peer.key \ --cacert /etc/kubernetes/pki/etcd/ca.crt \ - --endpoints https://${HOST0}:2379 endpoint health --cluster + --endpoints https://${HOST0}:2379 endpoint health ... https://[HOST0 IP]:2379 is healthy: successfully committed proposal: took = 16.283339ms https://[HOST1 IP]:2379 is healthy: successfully committed proposal: took = 19.44402ms https://[HOST2 IP]:2379 is healthy: successfully committed proposal: took = 35.926451ms ``` + - - 将 `${ETCD_TAG}` 设置为你的 etcd 镜像的版本标签,例如 `3.4.3-0`。 - 要查看 kubeadm 使用的 etcd 镜像和标签,请执行 - `kubeadm config images list --kubernetes-version ${K8S_VERSION}`, - 例如,其中的 `${K8S_VERSION}` 可以是 `v1.17.0`。 - 将 `${HOST0}` 设置为要测试的主机的 IP 地址。 ## {{% heading "whatsnext" %}} @@ -407,6 +409,6 @@ Once you have an etcd cluster with 3 working members, you can continue setting u highly available control plane using the [external etcd method with kubeadm](/docs/setup/production-environment/tools/kubeadm/high-availability/). --> -一旦拥有了一个正常工作的 3 成员的 etcd 集群,你就可以基于 -[使用 kubeadm 外部 etcd 的方法](/zh-cn/docs/setup/production-environment/tools/kubeadm/high-availability/), +一旦拥有了一个正常工作的 3 成员的 etcd 集群, +你就可以基于[使用 kubeadm 外部 etcd 的方法](/zh-cn/docs/setup/production-environment/tools/kubeadm/high-availability/), 继续部署一个高可用的控制平面。 From a63a43adae8d48a34480de465c89867a875cc3e5 Mon Sep 17 00:00:00 2001 From: windsonsea Date: Tue, 7 Feb 2023 09:29:23 +0800 Subject: [PATCH 147/279] Modify a UI menu in hello-minikube --- content/en/docs/tutorials/hello-minikube.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/content/en/docs/tutorials/hello-minikube.md b/content/en/docs/tutorials/hello-minikube.md index 08e5b3a7d08..0f92b0fd4c3 100644 --- a/content/en/docs/tutorials/hello-minikube.md +++ b/content/en/docs/tutorials/hello-minikube.md @@ -41,7 +41,7 @@ This tutorial provides a container image that uses NGINX to echo back all the re ## Create a minikube cluster -1. Click **Launch Terminal** +1. Click **Launch Terminal**. {{< kat-button >}} @@ -90,11 +90,10 @@ tutorial has only one Container. A Kubernetes Pod and restarts the Pod's Container if it terminates. Deployments are the recommended way to manage the creation and scaling of Pods. -1. Katacoda environment only: At the top of the terminal pane, click the plus sign, and then click open a new terminal. +1. Katacoda environment only: At the top of the terminal pane, click the plus sign, and then click **Open New Terminal**. 1. Use the `kubectl create` command to create a Deployment that manages a Pod. The Pod runs a Container based on the provided Docker image. - ```shell kubectl create deployment hello-node --image=registry.k8s.io/e2e-test-images/agnhost:2.39 -- /agnhost netexec --http-port=8080 From 2c6506d7cfb38cab99c08398c6ff088b47792afc Mon Sep 17 00:00:00 2001 From: windsonsea Date: Wed, 8 Feb 2023 21:02:01 +0800 Subject: [PATCH 148/279] [zh] sync dns-pod-service.md --- .../zh-cn/docs/concepts/services-networking/dns-pod-service.md | 2 +- content/zh-cn/examples/service/networking/custom-dns.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/content/zh-cn/docs/concepts/services-networking/dns-pod-service.md b/content/zh-cn/docs/concepts/services-networking/dns-pod-service.md index c50637c2135..d8183b70ced 100644 --- a/content/zh-cn/docs/concepts/services-networking/dns-pod-service.md +++ b/content/zh-cn/docs/concepts/services-networking/dns-pod-service.md @@ -532,7 +532,7 @@ in its `/etc/resolv.conf` file: 创建上面的 Pod 后,容器 `test` 会在其 `/etc/resolv.conf` 文件中获取以下内容: ``` -nameserver 1.2.3.4 +nameserver 192.0.2.1 search ns1.svc.cluster-domain.example my.dns.search.suffix options ndots:2 edns0 ``` diff --git a/content/zh-cn/examples/service/networking/custom-dns.yaml b/content/zh-cn/examples/service/networking/custom-dns.yaml index 02f77a9efe0..647bba63759 100644 --- a/content/zh-cn/examples/service/networking/custom-dns.yaml +++ b/content/zh-cn/examples/service/networking/custom-dns.yaml @@ -10,7 +10,7 @@ spec: dnsPolicy: "None" dnsConfig: nameservers: - - 1.2.3.4 + - 192.0.2.1 # 这是一个示例 searches: - ns1.svc.cluster-domain.example - my.dns.search.suffix From 0f40f8f4c0d159cdc0e255fb5aa361d6de7dba6f Mon Sep 17 00:00:00 2001 From: windsonsea Date: Tue, 7 Feb 2023 17:07:48 +0800 Subject: [PATCH 149/279] [zh] sync /workloads/pods/_index.md --- .../docs/concepts/workloads/pods/_index.md | 58 ++++++++++++++----- 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/content/zh-cn/docs/concepts/workloads/pods/_index.md b/content/zh-cn/docs/concepts/workloads/pods/_index.md index 59908afe7f8..139aa8eb9ea 100644 --- a/content/zh-cn/docs/concepts/workloads/pods/_index.md +++ b/content/zh-cn/docs/concepts/workloads/pods/_index.md @@ -537,24 +537,9 @@ Pod 中的容器所看到的系统主机名与为 Pod 配置的 `name` 属性值 ## 容器的特权模式 {#privileged-mode-for-containers} -在 Linux 中,Pod 中的任何容器都可以使用容器规约中的 -[安全性上下文](/zh-cn/docs/tasks/configure-pod-container/security-context/)中的 -`privileged`(Linux)参数启用特权模式。 -这对于想要使用操作系统管理权能(Capabilities,如操纵网络堆栈和访问设备)的容器很有用。 - -如果你的集群启用了 `WindowsHostProcessContainers` 特性,你可以使用 Pod 规约中安全上下文的 -`windowsOptions.hostProcess` 参数来创建 -[Windows HostProcess Pod](/zh-cn/docs/tasks/configure-pod-container/create-hostprocess-pod/)。 -这些 Pod 中的所有容器都必须以 Windows HostProcess 容器方式运行。 -HostProcess Pod 可以直接运行在主机上,它也能像 Linux 特权容器一样,用于执行管理任务。 - {{< note >}} +Pod 中的所有容器都可以在特权模式下运行,以使用原本无法访问的操作系统管理权能。 +此模式同时适用于 Windows 和 Linux。 + + +### Linux 特权容器 {#linux-priviledged-containers} + +在 Linux 中,Pod 中的所有容器都可以使用容器规约中的 +[安全性上下文](/zh-cn/docs/tasks/configure-pod-container/security-context/)中的 +`privileged`(Linux)参数启用特权模式。 +这对于想要使用操作系统管理权能(Capabilities,如操纵网络堆栈和访问硬件设备)的容器很有用。 + + +### Windows 特权容器 {#windows-priviledged-containers} + +{{< feature-state for_k8s_version="v1.26" state="stable" >}} + + +在 Windows 中,你可以使用 Pod 规约中安全上下文的 `windowsOptions.hostProcess` 参数来创建 +[Windows HostProcess Pod](/zh-cn/docs/tasks/configure-pod-container/create-hostprocess-pod/)。 +这些 Pod 中的所有容器都必须以 Windows HostProcess 容器方式运行。 +HostProcess Pod 可以直接运行在主机上,它也能像 Linux 特权容器一样,用于执行管理任务。 +想要使用此特性,`WindowsHostProcessContainers` +[特性门控](/zh-cn/docs/reference/command-line-tools-reference/feature-gates/)必须被启用。 + 字段描述 - + + +preEnqueue [Required]
    +PluginSet + + + +

    PreEnqueue 是在将 Pod 添加到调度队列之前应该调用的插件列表。

    + + queueSort [必需]
    PluginSet @@ -1677,4 +1686,4 @@ during leader election cycles.

    - \ No newline at end of file + From a25ac86767cfae0739138fafd3c666362a2efd7a Mon Sep 17 00:00:00 2001 From: Kinzhi Date: Thu, 9 Feb 2023 01:54:48 +0800 Subject: [PATCH 153/279] [zh-cn]SYNC nodes.md --- content/zh-cn/docs/concepts/architecture/nodes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/zh-cn/docs/concepts/architecture/nodes.md b/content/zh-cn/docs/concepts/architecture/nodes.md index 3c85499a27d..655b017d9d3 100644 --- a/content/zh-cn/docs/concepts/architecture/nodes.md +++ b/content/zh-cn/docs/concepts/architecture/nodes.md @@ -507,14 +507,14 @@ Kubernetes 节点发送的心跳帮助你的集群确定每个节点的可用性 * 更新节点的 `.status` * `kube-node-lease` {{}}中的 - [Lease(租约)](/zh-cn/docs/reference/kubernetes-api/cluster-resources/lease-v1/)对象。 + [Lease(租约)](/zh-cn/docs/concepts/architecture/leases/)对象。 每个节点都有一个关联的 Lease 对象。 @@ -131,7 +137,7 @@ A Pod Template in a DaemonSet must have a [`RestartPolicy`](/docs/concepts/workl ### Pod Selector The `.spec.selector` field is a pod selector. It works the same as the `.spec.selector` of -a [Job](/docs/concepts/jobs/run-to-completion-finite-workloads/). +a [Job](/docs/concepts/workloads/controllers/job/). You must specify a pod selector that matches the labels of the `.spec.template`. @@ -177,7 +183,7 @@ Config with these two not matching will be rejected by the API. 如果配置中这两个字段不匹配,则会被 API 拒绝。 -### 仅在某些节点上运行 Pod {#running-pods-on-only-some-nodes} +### 在选定的节点上运行 Pod {#running-pods-on-select-nodes} 如果指定了 `.spec.template.spec.nodeSelector`,DaemonSet 控制器将在能够与 [Node 选择算符](/zh-cn/docs/concepts/scheduling-eviction/assign-pod-node/)匹配的节点上创建 Pod。 @@ -195,7 +201,7 @@ If you do not specify either, then the DaemonSet controller will create Pods on 如果根本就没有指定,则 DaemonSet Controller 将在所有节点上创建 Pod。 @@ -268,13 +274,13 @@ DaemonSet Pod。在调度 DaemonSet Pod 时,默认调度器会忽略 `unschedu ### Taints and Tolerations Although Daemon Pods respect -[taints and tolerations](/docs/concepts/configuration/taint-and-toleration), +[taints and tolerations](/docs/concepts/scheduling-eviction/taint-and-toleration/), the following tolerations are added to DaemonSet Pods automatically according to the related features. --> ### 污点和容忍度 {#taint-and-toleration} -尽管 Daemon Pod 遵循[污点和容忍度](/zh-cn/docs/concepts/scheduling-eviction/taint-and-toleration)规则, +尽管 Daemon Pod 遵循[污点和容忍度](/zh-cn/docs/concepts/scheduling-eviction/taint-and-toleration/)规则, 根据相关特性,控制器会自动将以下容忍度添加到 DaemonSet Pod: | 容忍度键名 | 效果 | 版本 | 描述 | @@ -354,7 +360,7 @@ You can [perform a rolling update](/docs/tasks/manage-daemon/update-daemon-set/) ## DaemonSet 的替代方案 {#alternatives-to-daemon-set} @@ -465,4 +471,3 @@ DaemonSet 与 [Deployment](/zh-cn/docs/concepts/workloads/controllers/deployment [扩展(Addons)](/zh-cn/docs/concepts/cluster-administration/addons/),它们常以 DaemonSet 运行。 * `DaemonSet` 是 Kubernetes REST API 中的顶级资源。阅读 {{< api-reference page="workload-resources/daemon-set-v1" >}} 对象定义理解关于该资源的 API。 - From 57eb0ddc4848c4568e21d72e59fd3118cbfd6128 Mon Sep 17 00:00:00 2001 From: suning0 Date: Wed, 8 Feb 2023 23:30:35 +0800 Subject: [PATCH 159/279] [zh-cn]Update content/zh-cn/_index.html [zh-cn]Update content/zh-cn/_index.html --- content/zh-cn/_index.html | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/content/zh-cn/_index.html b/content/zh-cn/_index.html index 8958fae537c..8a175867799 100644 --- a/content/zh-cn/_index.html +++ b/content/zh-cn/_index.html @@ -47,11 +47,14 @@ consistently and easily no matter how complex your need is. --> #### 永不过时 - + Kubernetes 是开源系统,可以自由地部署在企业内部,私有云、混合云或公有云,让您轻松地做出合适的选择。 +请访问[下载](/releases/download/)部分下载 Kubernetes。 + {{% /blocks/feature %}} {{< /blocks/section >}} From c62ead0b178c9804ea4f0734626cbcac50ee310a Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Thu, 9 Feb 2023 10:53:53 +0800 Subject: [PATCH 160/279] [zh] Resync page statefulset --- .../workloads/controllers/statefulset.md | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/content/zh-cn/docs/concepts/workloads/controllers/statefulset.md b/content/zh-cn/docs/concepts/workloads/controllers/statefulset.md index 410ea3a5572..136837d9504 100644 --- a/content/zh-cn/docs/concepts/workloads/controllers/statefulset.md +++ b/content/zh-cn/docs/concepts/workloads/controllers/statefulset.md @@ -208,7 +208,9 @@ Provisioner. 它可以使用 PersistentVolume 制备程序所准备的 [PersistentVolumes](/zh-cn/docs/concepts/storage/persistent-volumes/) 来提供稳定的存储。 - + ### 最短就绪秒数 {#minimum-ready-seconds} {{< feature-state for_k8s_version="v1.25" state="stable" >}} @@ -356,7 +358,7 @@ Cluster Domain | Service (ns/name) | StatefulSet (ns/name) | StatefulSet Domain {{< note >}} 集群域会被设置为 `cluster.local`,除非有[其他配置](/zh-cn/docs/concepts/services-networking/dns-pod-service/)。 {{< /note >}} @@ -477,8 +479,8 @@ described [above](#deployment-and-scaling-guarantees). `Parallel` pod management tells the StatefulSet controller to launch or terminate all Pods in parallel, and to not wait for Pods to become Running and Ready or completely terminated prior to launching or terminating another -Pod. This option only affects the behavior for scaling operations. Updates are not affected. - +Pod. This option only affects the behavior for scaling operations. Updates are not +affected. --> #### 并行 Pod 管理 {#parallel-pod-management} @@ -487,7 +489,7 @@ Pod. This option only affects the behavior for scaling operations. Updates are n 这个选项只会影响扩缩操作的行为,更新则不会被影响。 + ## PersistentVolumeClaim 保留 {#persistentvolumeclaim-retention} {{< feature-state for_k8s_version="v1.23" state="alpha" >}} @@ -666,7 +670,7 @@ Once enabled, there are two policies you can configure for each StatefulSet: `whenScaled` : configures the volume retention behavior that applies when the replica count of the StatefulSet is reduced; for example, when scaling down the set. - + For each policy that you can configure, you can set the value to either `Delete` or `Retain`. --> `whenDeleted` @@ -704,7 +708,7 @@ StatefulSet being deleted or scaled down. For example, if a Pod associated with fails due to node failure, and the control plane creates a replacement Pod, the StatefulSet retains the existing PVC. The existing volume is unaffected, and the cluster will attach it to the node where the new Pod is about to launch. - + The default for policies is `Retain`, matching the StatefulSet behavior before this new feature. Here is an example policy. From a0c0a7778e95dffd269702867f9f585325d418fa Mon Sep 17 00:00:00 2001 From: windsonsea Date: Thu, 9 Feb 2023 10:20:05 +0800 Subject: [PATCH 161/279] [zh] sync /services-networking/service.md --- .../concepts/services-networking/service.md | 47 +++++++++++-------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/content/zh-cn/docs/concepts/services-networking/service.md b/content/zh-cn/docs/concepts/services-networking/service.md index 8138ca3a908..a33e91aa82e 100644 --- a/content/zh-cn/docs/concepts/services-networking/service.md +++ b/content/zh-cn/docs/concepts/services-networking/service.md @@ -70,7 +70,7 @@ Pod 是非永久性资源。 这导致了一个问题: 如果一组 Pod(称为“后端”)为集群内的其他 Pod(称为“前端”)提供功能, 那么前端如何找出并跟踪要连接的 IP 地址,以便前端可以使用提供工作负载的后端部分? -进入 **Services**。 +进入 **Service**。 Kubernetes 还支持命名端口的 DNS SRV(服务)记录。 如果 `my-service.my-ns` 服务具有名为 `http` 的端口,且协议设置为 TCP, 则可以对 `_http._tcp.my-service.my-ns` 执行 DNS SRV 查询以发现该端口号、`"http"` 以及 IP 地址。 Kubernetes DNS 服务器是唯一的一种能够访问 `ExternalName` 类型的 Service 的方式。 -更多关于 `ExternalName` 信息可以查看 -[DNS Pod 和 Service](/zh-cn/docs/concepts/services-networking/dns-pod-service/)。 +更多关于 `ExternalName` 解析的信息可以查看 +[Service 与 Pod 的 DNS](/zh-cn/docs/concepts/services-networking/dns-pod-service/)。 -* 遵循[使用 Service 连接到应用](/zh-cn/docs/tutorials/services/connect-applications-service/)教程 -* 阅读了解 [Ingress](/zh-cn/docs/concepts/services-networking/ingress/) -* 阅读了解[端点切片(Endpoint Slices)](/zh-cn/docs/concepts/services-networking/endpoint-slices/) +进一步学习以下章节: +* 遵循[使用 Service 连接到应用](/zh-cn/docs/tutorials/services/connect-applications-service/)教程 +* [Ingress](/zh-cn/docs/concepts/services-networking/ingress/) 将来自集群外部的 HTTP 和 HTTPS + 请求路由暴露给集群内的服务。 +* [EndpointSlice](/zh-cn/docs/concepts/services-networking/endpoint-slices/) + + 更多上下文: -* 阅读[虚拟 IP 和 Service 代理](/zh-cn/docs/reference/networking/virtual-ips/) -* 阅读 Service API 的 [API 参考](/zh-cn/docs/reference/kubernetes-api/service-resources/service-v1/) -* 阅读 EndpointSlice API 的 [API 参考](/zh-cn/docs/reference/kubernetes-api/service-resources/endpoint-slice-v1/) + +* [虚拟 IP 和 Service 代理](/zh-cn/docs/reference/networking/virtual-ips/) +* Service API 的 [API 参考](/zh-cn/docs/reference/kubernetes-api/service-resources/service-v1/) +* Endpoints API 的 [API 参考](/zh-cn/docs/reference/kubernetes-api/service-resources/endpoints-v1/) +* EndpointSlice API 的 [API 参考](/zh-cn/docs/reference/kubernetes-api/service-resources/endpoint-slice-v1/) From 6900728caf36cc2633523e9c569033711a6fa030 Mon Sep 17 00:00:00 2001 From: Kevin Arroyo <54748237+kevarr@users.noreply.github.com> Date: Wed, 8 Feb 2023 23:11:46 -0500 Subject: [PATCH 162/279] Fix Link [/docs/.../service#proxy-mode-iptables](https://kubernetes.io/docs/concepts/services-networking/service/#proxy-mode-iptables) no longer links to an anchored section of the `service` documentation page. Corrected the link. --- content/en/docs/tutorials/services/source-ip.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/docs/tutorials/services/source-ip.md b/content/en/docs/tutorials/services/source-ip.md index ddcdd861c60..c6aeea4ac42 100644 --- a/content/en/docs/tutorials/services/source-ip.md +++ b/content/en/docs/tutorials/services/source-ip.md @@ -74,7 +74,7 @@ deployment.apps/source-ip-app created Packets sent to ClusterIP from within the cluster are never source NAT'd if you're running kube-proxy in -[iptables mode](/docs/concepts/services-networking/service/#proxy-mode-iptables), +[iptables mode](/docs/reference/networking/virtual-ips/#proxy-mode-iptables), (the default). You can query the kube-proxy mode by fetching `http://localhost:10249/proxyMode` on the node where kube-proxy is running. From 3f5c63527466fa4a8cda3b8b06ea7b5710d3e1b9 Mon Sep 17 00:00:00 2001 From: suning0 Date: Tue, 7 Feb 2023 23:14:08 +0800 Subject: [PATCH 163/279] [zh-cn]Update git extensible-admission-controllers.md [zh-cn]Update extensible-admission-controllers.md --- .../access-authn-authz/extensible-admission-controllers.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/zh-cn/docs/reference/access-authn-authz/extensible-admission-controllers.md b/content/zh-cn/docs/reference/access-authn-authz/extensible-admission-controllers.md index bd7fad888df..af84e467523 100644 --- a/content/zh-cn/docs/reference/access-authn-authz/extensible-admission-controllers.md +++ b/content/zh-cn/docs/reference/access-authn-authz/extensible-admission-controllers.md @@ -861,10 +861,10 @@ Use the object selector only if the webhook is opt-in, because end users may ski 跳过准入 Webhook。 -这个例子展示了一个 mutating webhook,它将匹配带有标签 `foo:bar` 的任何资源的 -`CREATE` 的操作: +这个例子展示了一个变更性质的 Webhook,它将匹配带有标签 `foo:bar` 的所有资源(但不包括子资源)的 +`CREATE` 操作: ```yaml apiVersion: admissionregistration.k8s.io/v1 From 1c3387ecd7da1010c1ad3b2114f59fdbbc8a3c1a Mon Sep 17 00:00:00 2001 From: suning0 Date: Tue, 7 Feb 2023 22:32:12 +0800 Subject: [PATCH 164/279] [zh-cn]Update manage-resources-containers.md [zh-cn]Update manage-resources-containers.md [zh-cn]Update manage-resources-containers.md --- .../docs/concepts/configuration/manage-resources-containers.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/content/zh-cn/docs/concepts/configuration/manage-resources-containers.md b/content/zh-cn/docs/concepts/configuration/manage-resources-containers.md index 8feb4342971..ecf9121e9cf 100644 --- a/content/zh-cn/docs/concepts/configuration/manage-resources-containers.md +++ b/content/zh-cn/docs/concepts/configuration/manage-resources-containers.md @@ -1375,6 +1375,7 @@ memory limit (and possibly request) for that container. and its [resource requirements](/docs/reference/kubernetes-api/workload-resources/pod-v1/#resources) * Read about [project quotas](https://xfs.org/index.php/XFS_FAQ#Q:_Quota:_Do_quotas_work_on_XFS.3F) in XFS * Read more about the [kube-scheduler configuration reference (v1beta3)](/docs/reference/config-api/kube-scheduler-config.v1beta3/) +* Read more about [Quality of Service classes for Pods](/docs/concepts/workloads/pods/pod-qos/) --> * 获取[分配内存资源给容器和 Pod](/zh-cn/docs/tasks/configure-pod-container/assign-memory-resource/) 的实践经验 * 获取[分配 CPU 资源给容器和 Pod](/zh-cn/docs/tasks/configure-pod-container/assign-cpu-resource/) 的实践经验 @@ -1382,4 +1383,5 @@ memory limit (and possibly request) for that container. 及其[资源请求](/zh-cn/docs/reference/kubernetes-api/workload-resources/pod-v1/#resources)。 * 阅读 XFS 中[配额](https://xfs.org/index.php/XFS_FAQ#Q:_Quota:_Do_quotas_work_on_XFS.3F)的文档 * 进一步阅读 [kube-scheduler 配置参考 (v1beta3)](/zh-cn/docs/reference/config-api/kube-scheduler-config.v1beta3/) +* 进一步阅读 [Pod 的服务质量等级](/zh-cn/docs/concepts/workloads/pods/pod-qos/) From 9ab8cd6c0b745066611a029c3cedade867c7c78e Mon Sep 17 00:00:00 2001 From: Raunak Pradip Shah Date: Thu, 9 Feb 2023 11:25:13 +0530 Subject: [PATCH 165/279] Update volume mode change annotation in documentation --- content/en/docs/concepts/storage/volume-snapshots.md | 4 ++-- content/en/docs/reference/labels-annotations-taints/_index.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/content/en/docs/concepts/storage/volume-snapshots.md b/content/en/docs/concepts/storage/volume-snapshots.md index ef7bb83f9ef..3f1744e1087 100644 --- a/content/en/docs/concepts/storage/volume-snapshots.md +++ b/content/en/docs/concepts/storage/volume-snapshots.md @@ -227,7 +227,7 @@ $ kubectl get crd volumesnapshotcontent -o yaml If you want to allow users to create a `PersistentVolumeClaim` from an existing `VolumeSnapshot`, but with a different volume mode than the source, the annotation -`snapshot.storage.kubernetes.io/allowVolumeModeChange: "true"`needs to be added to +`snapshot.storage.kubernetes.io/allow-volume-mode-change: "true"`needs to be added to the `VolumeSnapshotContent` that corresponds to the `VolumeSnapshot`. For pre-provisioned snapshots, `spec.sourceVolumeMode` needs to be populated @@ -241,7 +241,7 @@ kind: VolumeSnapshotContent metadata: name: new-snapshot-content-test annotations: - - snapshot.storage.kubernetes.io/allowVolumeModeChange: "true" + - snapshot.storage.kubernetes.io/allow-volume-mode-change: "true" spec: deletionPolicy: Delete driver: hostpath.csi.k8s.io diff --git a/content/en/docs/reference/labels-annotations-taints/_index.md b/content/en/docs/reference/labels-annotations-taints/_index.md index 46cf104bf97..8914416f634 100644 --- a/content/en/docs/reference/labels-annotations-taints/_index.md +++ b/content/en/docs/reference/labels-annotations-taints/_index.md @@ -844,9 +844,9 @@ you through the steps you follow to apply a seccomp profile to a Pod or to one o its containers. That tutorial covers the supported mechanism for configuring seccomp in Kubernetes, based on setting `securityContext` within the Pod's `.spec`. -### snapshot.storage.kubernetes.io/allowVolumeModeChange +### snapshot.storage.kubernetes.io/allow-volume-mode-change -Example: `snapshot.storage.kubernetes.io/allowVolumeModeChange: "true"` +Example: `snapshot.storage.kubernetes.io/allow-volume-mode-change: "true"` Used on: VolumeSnapshotContent From ac0d48784ad3744a9b592f7b92db1a766d9e1247 Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Thu, 9 Feb 2023 17:00:01 +0800 Subject: [PATCH 166/279] [zh] Sync small changes in page storage-capacity,storage-limits,volume-snapshots --- content/zh-cn/docs/concepts/storage/storage-capacity.md | 4 ++-- content/zh-cn/docs/concepts/storage/storage-limits.md | 8 ++++---- content/zh-cn/docs/concepts/storage/volume-snapshots.md | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/content/zh-cn/docs/concepts/storage/storage-capacity.md b/content/zh-cn/docs/concepts/storage/storage-capacity.md index 461e80b3695..91b9723fe43 100644 --- a/content/zh-cn/docs/concepts/storage/storage-capacity.md +++ b/content/zh-cn/docs/concepts/storage/storage-capacity.md @@ -1,7 +1,7 @@ --- title: 存储容量 content_type: concept -weight: 70 +weight: 80 --- diff --git a/content/zh-cn/docs/concepts/storage/storage-limits.md b/content/zh-cn/docs/concepts/storage/storage-limits.md index f9eb0410722..4572560c632 100644 --- a/content/zh-cn/docs/concepts/storage/storage-limits.md +++ b/content/zh-cn/docs/concepts/storage/storage-limits.md @@ -18,17 +18,17 @@ weight: 90 - 此页面描述了各个云供应商可关联至一个节点的最大卷数。 - 谷歌、亚马逊和微软等云供应商通常对可以关联到节点的卷数量进行限制。 Kubernetes 需要尊重这些限制。 否则,在节点上调度的 Pod 可能会卡住去等待卷的关联。 diff --git a/content/zh-cn/docs/concepts/storage/volume-snapshots.md b/content/zh-cn/docs/concepts/storage/volume-snapshots.md index 27bdef16d3b..b908ffb9133 100644 --- a/content/zh-cn/docs/concepts/storage/volume-snapshots.md +++ b/content/zh-cn/docs/concepts/storage/volume-snapshots.md @@ -390,12 +390,12 @@ the `VolumeSnapshotContent` that corresponds to the `VolumeSnapshot`. 到对应 `VolumeSnapshot` 的 `VolumeSnapshotContent` 中。 -对于预制备的快照,`spec.SourceVolumeMode` 需要由集群管理员填充。 +对于预制备的快照,`spec.sourceVolumeMode` 需要由集群管理员填充。 启用此特性的 `VolumeSnapshotContent` 资源示例如下所示: From 90baea988d6be3e12c5605b036136fa9c8797dc9 Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Thu, 9 Feb 2023 17:37:51 +0800 Subject: [PATCH 167/279] [zh] Resync page services-networking/service --- .../concepts/services-networking/service.md | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/content/zh-cn/docs/concepts/services-networking/service.md b/content/zh-cn/docs/concepts/services-networking/service.md index a33e91aa82e..c027fb3ada3 100644 --- a/content/zh-cn/docs/concepts/services-networking/service.md +++ b/content/zh-cn/docs/concepts/services-networking/service.md @@ -240,7 +240,7 @@ in the next version of your backend software, without breaking clients. 例如,你可以在新版本中更改 Pod 中后端软件公开的端口号,而不会破坏客户端。 Kubernetes API 服务器不允许代理到未被映射至 Pod 上的端点。由于此约束,当 Service -没有选择算符时,诸如 `kubectl proxy ` 之类的操作将会失败。这可以防止 +没有选择算符时,诸如 `kubectl proxy ` 之类的操作将会失败。这可以防止 Kubernetes API 服务器被用作调用者可能无权访问的端点的代理。 {{< /note >}} @@ -515,7 +515,7 @@ The same API limit means that you cannot manually update an Endpoints to have mo {{< feature-state for_k8s_version="v1.20" state="stable" >}} - +* [Pod](/zh-cn/docs/concepts/workloads/pods/) + Pod 是 Kubernetes 的基本构建块,是可以创建或部署的最小和最简单的单元。 + 你不可以在同一个 Pod 中部署 Windows 和 Linux 容器。 + Pod 中的所有容器都调度到同一 Node 上,每个 Node 代表一个特定的平台和体系结构。 + Windows 容器支持以下 Pod 能力、属性和事件: + -* [Pod](/zh-cn/docs/concepts/workloads/pods/) - - Pod 是 Kubernetes 的基本构建块,是可以创建或部署的最小和最简单的单元。 - 你不可以在同一个 Pod 中部署 Windows 和 Linux 容器。 - Pod 中的所有容器都调度到同一 Node 上,每个 Node 代表一个特定的平台和体系结构。 - Windows 容器支持以下 Pod 能力、属性和事件: - + --> * 每个 Pod 有一个或多个容器,具有进程隔离和卷共享能力 * Pod `status` 字段 * 就绪、存活和启动探针 @@ -172,14 +158,26 @@ Kubernetes 关键组件在 Windows 上的工作方式与在 Linux 上相同。 * `emptyDir` 卷 * 命名管道形式的主机挂载 * 资源限制 + * 操作系统字段: `.spec.os.name` 字段应设置为 `windows` 以表明当前 Pod 使用 Windows 容器。 {{< note >}} + 从 1.25 开始,`IdentifyPodOS` 特性门控进入 GA 阶段,默认启用。 {{< /note >}} + 如果你将 `.spec.os.name` 字段设置为 `windows`, 则你必须不能在对应 Pod 的 `.spec` 中设置以下字段: @@ -203,7 +201,13 @@ Kubernetes 关键组件在 Windows 上的工作方式与在 Linux 上相同。 * `spec.containers[*].securityContext.procMount` * `spec.containers[*].securityContext.runAsUser` * `spec.containers[*].securityContext.runAsGroup` - + + 在上述列表中,通配符(`*`)表示列表中的所有项。 例如,`spec.containers[*].securityContext` 指代所有容器的 SecurityContext 对象。 如果指定了这些字段中的任意一个,则 API 服务器不会接受此 Pod。 @@ -238,7 +242,7 @@ Kubernetes 关键组件在 Windows 上的工作方式与在 Linux 上相同。 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. Kubernetes also supports: +environment. * `kubectl exec` * Pod and container metrics @@ -248,7 +252,6 @@ environment. Kubernetes also supports: --> Pod、工作负载资源和 Service 是在 Kubernetes 上管理 Windows 工作负载的关键元素。 然而,它们本身还不足以在动态的云原生环境中对 Windows 工作负载进行恰当的生命周期管理。 -Kubernetes 还支持: * `kubectl exec` * Pod 和容器度量指标 @@ -356,7 +359,7 @@ passed from the Kubernetes components (kubelet, kube-proxy) are unchanged. 但是,从 Kubernetes 组件(kubelet、kube-proxy)传递的退出码保持不变。 -##### 容器规范的字段兼容性 {#compatibility-v1-pod-spec-containers} +#### 容器规约的字段兼容性 {#compatibility-v1-pod-spec-containers} -以下列表记录了 Pod 容器规范在 Windows 和 Linux 之间的工作方式差异: +以下列表记录了 Pod 容器规约在 Windows 和 Linux 之间的工作方式差异: * 巨页(Huge page)在 Windows 容器运行时中未实现,且不可用。 巨页需要不可为容器配置的[用户特权生效](https://docs.microsoft.com/zh-cn/windows/win32/memory/large-page-support)。 @@ -419,7 +422,7 @@ work between Windows and Linux: default value is `/dev/termination-log`, which does work because it does not exist on Windows by default. --> -* `securityContext.runAsNonRoot` - +* `securityContext.runAsNonRoot` - 此设置将阻止以 `ContainerAdministrator` 身份运行容器,这是 Windows 上与 root 用户最接近的身份。 * `securityContext.runAsUser` - 改用 [`runAsUserName`](/zh-cn/docs/tasks/configure-pod-container/configure-runasusername)。 * `securityContext.seLinuxOptions` - 不能在 Windows 上使用,因为 SELinux 特定于 Linux。 @@ -427,7 +430,7 @@ work between Windows and Linux: 默认值为 `/dev/termination-log`,因为默认情况下它在 Windows 上不存在,所以能生效。 -##### Pod 规范的字段兼容性 {#compatibility-v1-pod} +#### Pod 规约的字段兼容性 {#compatibility-v1-pod} -以下列表记录了 Pod 规范在 Windows 和 Linux 之间的工作方式差异: +以下列表记录了 Pod 规约在 Windows 和 Linux 之间的工作方式差异: * `hostIPC` 和 `hostpid` - 不能在 Windows 上共享主机命名空间。 * `hostNetwork` - [参见下文](#compatibility-v1-pod-spec-containers-hostnetwork) @@ -498,7 +501,7 @@ of creating a new pod network namespace. To enable this functionality pass `--fe {{< note >}} 此功能需要支持该功能的容器运行时。 {{< /note >}} @@ -506,12 +509,13 @@ This functionality requires a container runtime that supports this functionality #### Pod 安全上下文的字段兼容性 {#compatibility-v1-pod-spec-containers-securitycontext} -Pod 的所有 [`securityContext`](/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context) -字段都无法在 Windows 上生效。 +Pod 的 [`securityContext`](/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context) +中只有 `securityContext.runAsNonRoot` 和 `securityContext.windowsOptions` 字段在 Windows 上生效。 -### Pause 容器 {#pause-container} +## Pause 容器 {#pause-container} 在 Kubernetes Pod 中,首先创建一个基础容器或 “pause” 容器来承载容器。 在 Linux 中,构成 Pod 的 cgroup 和命名空间维持持续存在需要一个进程; @@ -572,7 +576,7 @@ Microsoft 进行了[验证码签名](https://docs.microsoft.com/zh-cn/windows-ha Kubernetes 项目建议使用 Microsoft 维护的镜像。 -### 容器运行时 {#container-runtime} +## 容器运行时 {#container-runtime} 你需要将{{< glossary_tooltip text="容器运行时" term_id="container-runtime" >}}安装到集群中的每个节点, 这样 Pod 才能在这些节点上运行。 @@ -590,7 +594,7 @@ The following container runtimes work with Windows: {{% thirdparty-content %}} -#### ContainerD {#containerd} +### ContainerD {#containerd} {{< feature-state for_k8s_version="v1.20" state="stable" >}} @@ -608,26 +612,26 @@ Learn how to [install ContainerD on a Windows node](/docs/setup/production-envir 学习如何[在 Windows 上安装 ContainerD](/zh-cn/docs/setup/production-environment/container-runtimes/#install-containerd)。 +{{< note >}} -{{< note >}} 将 GMSA 和 containerd 一起用于访问 Windows 网络共享时存在[已知限制](/zh-cn/docs/tasks/configure-pod-container/configure-gmsa/#gmsa-limitations), 这需要一个内核补丁。 {{< /note >}} -#### Mirantis 容器运行时 {#mcr} +### Mirantis 容器运行时 {#mcr} [Mirantis 容器运行时](https://docs.mirantis.com/mcr/20.10/overview.html)(MCR) 可作为所有 Windows Server 2019 和更高版本的容器运行时。 @@ -711,21 +715,21 @@ Kubernetes Slack 上的 SIG Windows 频道也是一个很好的途径, ## {{% heading "whatsnext" %}} -### 部署工具 {#deployment-tools} +## 部署工具 {#deployment-tools} kubeadm 工具帮助你部署 Kubernetes 集群,提供管理集群的控制平面以及运行工作负载的节点。 Kubernetes [集群 API](https://cluster-api.sigs.k8s.io/) 项目也提供了自动部署 Windows 节点的方式。 -### Windows 分发渠道 {#windows-distribution-channels} +## Windows 分发渠道 {#windows-distribution-channels} 有关 Windows 分发渠道的详细阐述,请参考 [Microsoft 文档](https://docs.microsoft.com/zh-cn/windows-server/get-started-19/servicing-channels-19)。 From 97f7d2f52a23becc0ee6439df198b8a4e9cbc392 Mon Sep 17 00:00:00 2001 From: kadtendulkar Date: Thu, 9 Feb 2023 21:59:16 +0530 Subject: [PATCH 169/279] Update content/en/blog/_posts/2022-07-13-gateway-api-in-beta.md --- content/en/blog/_posts/2022-07-13-gateway-api-in-beta.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/blog/_posts/2022-07-13-gateway-api-in-beta.md b/content/en/blog/_posts/2022-07-13-gateway-api-in-beta.md index 54457cd3366..cbc26040ef9 100644 --- a/content/en/blog/_posts/2022-07-13-gateway-api-in-beta.md +++ b/content/en/blog/_posts/2022-07-13-gateway-api-in-beta.md @@ -145,7 +145,7 @@ workstream within the Gateway API subproject focused on Gateway API for Mesh Management and Administration. This group will deliver [enhancement -proposals](https://gateway-api.sigs.k8s.io/v1beta1/contributing/gep/) consisting +proposals](https://gateway-api.sigs.k8s.io/geps/overview/) consisting of resources, additions, and modifications to the Gateway API specification for mesh and mesh-adjacent use-cases. From 07e120bd5de9c9f0584f1f36aee466311e785175 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulo=20Gon=C3=A7alves=20Lima?= <18203100+PauloGoncalvesLima@users.noreply.github.com> Date: Thu, 9 Feb 2023 14:32:27 -0300 Subject: [PATCH 170/279] Fix: Translation erros. --- .../dns-custom-nameservers.md | 37 ++++++++----------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/content/pt-br/docs/tasks/administer-cluster/dns-custom-nameservers.md b/content/pt-br/docs/tasks/administer-cluster/dns-custom-nameservers.md index f2c72efedf4..3e6b3441b02 100644 --- a/content/pt-br/docs/tasks/administer-cluster/dns-custom-nameservers.md +++ b/content/pt-br/docs/tasks/administer-cluster/dns-custom-nameservers.md @@ -1,15 +1,12 @@ --- -reviewers: -- bowei -- zihongz title: Personalizando o Serviço DNS content_type: task min-kubernetes-server-version: v1.12 --- -Essa pagina explica como configurar o seu DNS -{{< glossary_tooltip text="Pod(s)" term_id="pod" >}} e personalizar o processo de resolução de DNS no seu cluster. +Essa página explica como configurar os seus {{< glossary_tooltip text="Pod(s)" term_id="pod" >}} de DNS +e personalizar o processo de resolução de DNS no seu cluster. ## {{% heading "prerequisites" %}} @@ -23,15 +20,15 @@ Seu cluster deve estar executando o complemento CoreDNS. ## Introdução -DNS é um serviço integrado do Kubernetes que é integrado automaticamente usando o _gerenciador de complementos_ [cluster add-on](http://releases.k8s.io/master/cluster/addons/README.md). +DNS é um serviço integrado do Kubernetes que é iniciado automaticamente usando o _gerenciador de complementos_ [cluster add-on](http://releases.k8s.io/master/cluster/addons/README.md). {{< note >}} -O Serviço CoreDNS é chamado de `kube-dns` no campo `metadata.name`. +O service CoreDNS é chamado de `kube-dns` no campo `metadata.name`. O objetivo é garantir maior interoperabilidade com cargas de trabalho que dependiam do nome de serviço legado `kube-dns` para resolver endereços internos ao cluster. -Usando o serviço chamado `kube-dns` abstrai o detalhe de implementação de qual provedor de DNS está sendo executado por trás desse nome comum. +Usando o service chamado `kube-dns` abstrai o detalhe de implementação de qual provedor de DNS está sendo executado por trás desse nome comum. {{< /note >}} -Se você estiver executando o CoreDNS como um Deployment, ele geralmente será exposto como um Serviço do Kubernetes com o endereço de IP estático. +Se você estiver executando o CoreDNS como um Deployment, ele geralmente será exposto como um service do Kubernetes com o endereço de IP estático. O kubelet passa informações de resolução de DNS para cada contêiner com a flag `--cluster-dns=`. Os nomes DNS também precisam de domínios. Você configura o domínio local no kubelet com a flag `--cluster-domain=`. @@ -39,7 +36,7 @@ Os nomes DNS também precisam de domínios. Você configura o domínio local no O servidor DNS suporta pesquisas de encaminhamento (registros A e AAAA), pesquisas de porta (registros SRV), pesquisas de endereço de IP reverso (registros PTR) e muito mais. Para mais informações, veja [DNS para Serviços e Pods](/docs/concepts/services-networking/dns-pod-service/). Se a `dnsPolicy` de um Pod estiver definida como `default`, ele herda a configuração de resolução de nome do nó em que o Pod é executado. A resolução de DNS do Pod deve se comportar da mesma forma que o nó. -Veja [Problemas conhecidos](/docs/tasks/administer-cluster/dns-debugging-resolution/#known-issues).. +Veja [Problemas conhecidos](/docs/tasks/administer-cluster/dns-debugging-resolution/#known-issues). Se você não quiser isso, ou se quiser uma configuração de DNS diferente para os pods, pode usar a flag `--resolv-conf` do kubelet. Defina essa flag como "" para impedir que os Pods herdem a configuração do DNS. Defina-a como um caminho de arquivo válido para especificar um arquivo diferente de `/etc/resolv.conf` para a herança de DNS. @@ -48,7 +45,7 @@ Se você não quiser isso, ou se quiser uma configuração de DNS diferente para CoreDNS é um servidor oficial de DNS de propósito geral que pode atuar como DNS do cluster, cumprindo com as [especificações DNS](https://github.com/kubernetes/dns/blob/master/docs/specification.md). -### CoreDNS ConfigMap options +### Opções CoreDNS ConfigMap options CoreDNS é um servidor DNS que é modular e plugável, com plugins que adicionam novas funcionalidades. O servidor CoreDNS pode ser configurado por um [Corefile](https://coredns.io/2017/07/23/corefile-explained/), @@ -56,7 +53,7 @@ que é o arquivo de configuração do CoreDNS. Como administrador de cluster, vo {{< glossary_tooltip text="ConfigMap" term_id="configmap" >}} para o arquivo Corefile do CoreDNS para mudar como o descobrimento de serviços DNS se comporta para esse cluster. -Em Kubernetes, o CoreDNS é instalado com a seguinte configuração padrão do Corefile: +No Kubernetes, o CoreDNS é instalado com a seguinte configuração padrão do Corefile: ```yaml apiVersion: v1 @@ -88,20 +85,18 @@ data: A configuração do Corefile inclui os seguintes [plugins](https://coredns.io/plugins/) do CoreDNS: -* [errors](https://coredns.io/plugins/errors/): Erros são registrados para stdout. -* [health](https://coredns.io/plugins/health/): A saúde do CoreDNS é reportada para -`http://localhost:8080/health`. Nesta sintaxe estendida, `lameduck` fará o processo -insalubre, esperando por 5 segundos antes que o processo seja encerrado. +* [errors](https://coredns.io/plugins/errors/): Erros são enviados para stdout. +* [health](https://coredns.io/plugins/health/): A integridade do CoreDNS é reportada para +`http://localhost:8080/health`. Nesta sintaxe estendida, `lameduck` marcará o processo como não-íntegro, esperando por 5 segundos antes que o processo seja encerrado. * [ready](https://coredns.io/plugins/ready/): Um endpoint HTTP na porta 8181 retornará 200 OK, quando todos os plugins que são capazes de sinalizar prontidão tiverem feito isso. * [kubernetes](https://coredns.io/plugins/kubernetes/): O CoreDNS responderá a consultas DNS baseado no IP dos Serviços e Pods. Você pode encontrar [mais detalhes em](https://coredns.io/plugins/kubernetes/). sobre este plugin no site do CoreDNS. * `ttl` permite que você defina um TTL personalizado para as respostas. O padrão é 5 segundos. O TTL mínimo permitido é de 0 segundos e o máximo é de 3600 segundos. Definir o TTL como 0 impedirá que os registros sejam armazenados em cache. * A opção `pods insecure` é fornecida para retrocompatibilidade com o `kube-dns`. - * Você pode usar a opção `pods verified`, que retorna um registro A somente se houver um pod no mesmo namespace com um IP correspondente. - * A opção `pods disabled` pode ser usada se você não usar registros de pod. -* [prometheus](https://coredns.io/plugins/metrics/): As métricas do CoreDNS estão disponíveis em `http://localhost:9153/metrics` no formato [Prometheus](https://prometheus.io/) - (também conhecido como OpenMetrics). + * Você pode usar a opção `pods verified`, que retorna um registro A somente se houver um Pod no mesmo namespace com um IP correspondente. + * A opção `pods disabled` pode ser usada se você não usar registros de Pod. +* [prometheus](https://coredns.io/plugins/metrics/): As métricas do CoreDNS ficam disponíveis em `http://localhost:9153/metrics` seguindo o formato [Prometheus](https://prometheus.io/), também conhecido como OpenMetrics. * [forward](https://coredns.io/plugins/forward/): Qualquer consulta que não esteja no domínio do cluster do Kubernetes é encaminhada para resolutores predefinidos (/etc/resolv.conf). * [cache](https://coredns.io/plugins/cache/): Habilita um cache de frontend. * [loop](https://coredns.io/plugins/loop/): Detecta loops de encaminhamento simples e interrompe o processo do CoreDNS se um loop for encontrado. @@ -119,7 +114,7 @@ O CoreDNS tem a capacidade de configurar domínios Stub e upstream nameservers u Se um operador de cluster possui um servidor de domínio [Consul](https://www.consul.io/) localizado em "10.150.0.1" e todos os nomes Consul possuem o sufixo ".consul.local". Para configurá-lo no CoreDNS, -o administrador do cluster cria a seguinte stanza no ConfigMap do CoreDNS. +o administrador do cluster cria a seguinte entrada no ConfigMap do CoreDNS. ```config consul.local:53 { From 11f0311f08752037039802806ca1788ed6d9b8a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulo=20Gon=C3=A7alves=20Lima?= <18203100+PauloGoncalvesLima@users.noreply.github.com> Date: Thu, 9 Feb 2023 14:40:21 -0300 Subject: [PATCH 171/279] Fix: Translation erros --- .../tasks/administer-cluster/dns-custom-nameservers.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/content/pt-br/docs/tasks/administer-cluster/dns-custom-nameservers.md b/content/pt-br/docs/tasks/administer-cluster/dns-custom-nameservers.md index 3e6b3441b02..ce9822509b9 100644 --- a/content/pt-br/docs/tasks/administer-cluster/dns-custom-nameservers.md +++ b/content/pt-br/docs/tasks/administer-cluster/dns-custom-nameservers.md @@ -50,8 +50,8 @@ cumprindo com as [especificações DNS](https://github.com/kubernetes/dns/blob/m CoreDNS é um servidor DNS que é modular e plugável, com plugins que adicionam novas funcionalidades. O servidor CoreDNS pode ser configurado por um [Corefile](https://coredns.io/2017/07/23/corefile-explained/), que é o arquivo de configuração do CoreDNS. Como administrador de cluster, você pode modificar o -{{< glossary_tooltip text="ConfigMap" term_id="configmap" >}} para o arquivo Corefile do CoreDNS para -mudar como o descobrimento de serviços DNS se comporta para esse cluster. +{{< glossary_tooltip text="ConfigMap" term_id="configmap" >}} que contém o arquivo Corefile do CoreDNS para +mudar como o descoberta de serviços DNS se comporta para esse cluster. No Kubernetes, o CoreDNS é instalado com a seguinte configuração padrão do Corefile: @@ -90,8 +90,7 @@ A configuração do Corefile inclui os seguintes [plugins](https://coredns.io/pl `http://localhost:8080/health`. Nesta sintaxe estendida, `lameduck` marcará o processo como não-íntegro, esperando por 5 segundos antes que o processo seja encerrado. * [ready](https://coredns.io/plugins/ready/): Um endpoint HTTP na porta 8181 retornará 200 OK, quando todos os plugins que são capazes de sinalizar prontidão tiverem feito isso. * [kubernetes](https://coredns.io/plugins/kubernetes/): O CoreDNS responderá a consultas DNS - baseado no IP dos Serviços e Pods. Você pode encontrar [mais detalhes em](https://coredns.io/plugins/kubernetes/). - sobre este plugin no site do CoreDNS. + baseado no IP dos Serviços e Pods. Você pode encontrar mais detalhes sobre este plugin no [site do CoreDNS](https://coredns.io/plugins/kubernetes/). * `ttl` permite que você defina um TTL personalizado para as respostas. O padrão é 5 segundos. O TTL mínimo permitido é de 0 segundos e o máximo é de 3600 segundos. Definir o TTL como 0 impedirá que os registros sejam armazenados em cache. * A opção `pods insecure` é fornecida para retrocompatibilidade com o `kube-dns`. * Você pode usar a opção `pods verified`, que retorna um registro A somente se houver um Pod no mesmo namespace com um IP correspondente. From 82ca1266720b22f404f886a83590293999fe45ee Mon Sep 17 00:00:00 2001 From: Arhell Date: Fri, 10 Feb 2023 00:20:00 +0200 Subject: [PATCH 172/279] [en] fix typo memory-manager.md --- content/en/docs/tasks/administer-cluster/memory-manager.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/en/docs/tasks/administer-cluster/memory-manager.md b/content/en/docs/tasks/administer-cluster/memory-manager.md index 33d7b643fa4..b64adede0e6 100644 --- a/content/en/docs/tasks/administer-cluster/memory-manager.md +++ b/content/en/docs/tasks/administer-cluster/memory-manager.md @@ -111,11 +111,11 @@ This is the default policy and does not affect the memory allocation in any way. It acts the same as if the Memory Manager is not present at all. The `None` policy returns default topology hint. This special hint denotes that Hint Provider -(Memory Manger in this case) has no preference for NUMA affinity with any resource. +(Memory Manager in this case) has no preference for NUMA affinity with any resource. #### Static policy {#policy-static} -In the case of the `Guaranteed` pod, the `Static` Memory Manger policy returns topology hints +In the case of the `Guaranteed` pod, the `Static` Memory Manager policy returns topology hints relating to the set of NUMA nodes where the memory can be guaranteed, and reserves the memory through updating the internal [NodeMap][2] object. From 4f1cf5a37544f318fe16dba12f55da87dac39402 Mon Sep 17 00:00:00 2001 From: windsonsea Date: Fri, 10 Feb 2023 09:10:29 +0800 Subject: [PATCH 173/279] [zh] sync 2022-07-13-gateway-api-in-beta.md --- .../blog/_posts/2022-07-13-gateway-api-in-beta.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/content/zh-cn/blog/_posts/2022-07-13-gateway-api-in-beta.md b/content/zh-cn/blog/_posts/2022-07-13-gateway-api-in-beta.md index 570b55f3015..f57e9b816f5 100644 --- a/content/zh-cn/blog/_posts/2022-07-13-gateway-api-in-beta.md +++ b/content/zh-cn/blog/_posts/2022-07-13-gateway-api-in-beta.md @@ -17,6 +17,8 @@ canonicalUrl: https://gateway-api.sigs.k8s.io/blog/2022/graduating-to-beta/ --> **作者:** Shane Utt (Kong)、Rob Scott (Google)、Nick Young (VMware)、Jeff Apple (HashiCorp) +**译者:** Michael Yao (DaoCloud) + -这个小组将交付[增强提案](https://gateway-api.sigs.k8s.io/v1beta1/contributing/gep/), +这个小组将交付[增强提案](https://gateway-api.sigs.k8s.io/geps/overview/), 包括对网格和网格相关用例适用的 Gateway API 规约的资源、添加和修改。 -这项工作已从 -[探索针对服务间流量使用 Gateway API](https://docs.google.com/document/d/1T_DtMQoq2tccLAtJTpo3c0ohjm25vRS35MsestSL9QU/edit#heading=h.jt37re3yi6k5) +这项工作已从[探索针对服务间流量使用 Gateway API](https://docs.google.com/document/d/1T_DtMQoq2tccLAtJTpo3c0ohjm25vRS35MsestSL9QU/edit#heading=h.jt37re3yi6k5) 开始,并将继续增强身份验证和鉴权策略等领域。 +5. 安装插件后,清理安装文件: + + ```powershell + del kubectl.exe kubectl.exe.sha256 + ``` + {{< note >}} 如果你没有看到任何错误就代表插件安装成功了。 + +5. 安装插件后,清理安装文件: + + ```powershell + del kubectl-convert.exe kubectl-convert.exe.sha256 + ``` + ## {{% heading "whatsnext" %}} {{< include "included/kubectl-whats-next.md" >}} From 615431ccdc7523cdecfdedc585919e5b834b8ef3 Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Fri, 10 Feb 2023 11:38:47 +0800 Subject: [PATCH 175/279] [zh] Resync memory-manager.md --- .../administer-cluster/memory-manager.md | 70 +++++++++---------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/content/zh-cn/docs/tasks/administer-cluster/memory-manager.md b/content/zh-cn/docs/tasks/administer-cluster/memory-manager.md index 25bf6185047..0857161da74 100644 --- a/content/zh-cn/docs/tasks/administer-cluster/memory-manager.md +++ b/content/zh-cn/docs/tasks/administer-cluster/memory-manager.md @@ -2,6 +2,7 @@ title: 使用 NUMA 感知的内存管理器 content_type: task min-kubernetes-server-version: v1.21 +weight: 410 --- @@ -37,9 +39,8 @@ Kubernetes 内存管理器(Memory Manager)为 `Guaranteed` 或者会被某节点接受,或者被该节点拒绝。 @@ -52,7 +53,7 @@ The Memory Manager is only pertinent to Linux based hosts. {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} @@ -158,8 +159,8 @@ The administrator must provide `--reserved-memory` flag when `Static` policy is ### 运行时 {#runtime} 参考文献 [Memory Manager KEP: Memory Maps at runtime (with examples)][6] @@ -173,7 +174,7 @@ attempts to create a group that comprises several NUMA nodes and features extend The problem has been solved as elaborated in [Memory Manager KEP: How to enable the guaranteed memory allocation over many NUMA nodes?][3]. Also, reference [Memory Manager KEP: Simulation - how the Memory Manager works? (by examples)][1] -illustrates how the management of groups occurs. +illustrates how the management of groups occurs. --> 在内存管理器运作的语境中,一个重要的话题是对 NUMA 分组的管理。 每当 Pod 的内存请求超出单个 NUMA 节点容量时,内存管理器会尝试创建一个包含多个 @@ -199,7 +200,7 @@ node stability (section [Reserved memory flag](#reserved-memory-flag)). ([预留内存标志](#reserved-memory-flag))。 ### 策略 {#policies} @@ -222,7 +223,7 @@ This is the default policy and does not affect the memory allocation in any way. It acts the same as if the Memory Manager is not present at all. The `None` policy returns default topology hint. This special hint denotes that Hint Provider -(Memory Manger in this case) has no preference for NUMA affinity with any resource. +(Memory Manager in this case) has no preference for NUMA affinity with any resource. --> #### None 策略 {#policy-none} @@ -234,7 +235,7 @@ The `None` policy returns default topology hint. This special hint denotes that Kubernetes 调度器在优化 Pod 调度过程时,会考虑“可分配的”内存。 前面提到的标志包括 `--kube-reserved`、`--system-reserved` 和 `--eviction-threshold`。 @@ -287,7 +288,7 @@ Kubernetes 调度器在优化 Pod 调度过程时,会考虑“可分配的” 语法: @@ -346,7 +347,7 @@ Syntax: * `N` (integer) - NUMA node index, e.g. `0` * `memory-type` (string) - represents memory type: * `memory` - conventional memory - * `hugepages-2Mi` or `hugepages-1Gi` - hugepages + * `hugepages-2Mi` or `hugepages-1Gi` - hugepages * `value` (string) - the quantity of reserved memory, e.g. `1Gi` --> * `N`(整数)- NUMA 节点索引,例如,`0` @@ -378,11 +379,11 @@ or 当你为 `--reserved-memory` 标志指定取值时,必须要遵从之前通过节点可分配特性标志所设置的值。 换言之,对每种内存类型而言都要遵从下面的规则: @@ -395,7 +396,7 @@ where `i` is an index of a NUMA node. If you do not follow the formula above, the Memory Manager will show an error on startup. In other words, the example above illustrates that for the conventional memory (`type=memory`), -we reserve `3Gi` in total, i.e.: +we reserve `3Gi` in total, i.e.: --> 如果你不遵守上面的公式,内存管理器会在启动时输出错误信息。 @@ -412,12 +413,12 @@ An example of kubelet command-line arguments relevant to the node Allocatable co * `--system-reserved=cpu=123m,memory=333Mi` * `--eviction-hard=memory.available<500Mi` -{{< note >}} +{{< note >}} 默认的硬性驱逐阈值是 100MiB,**不是**零。 请记得在使用 `--reserved-memory` 设置要预留的内存量时,加上这个硬性驱逐阈值。 @@ -430,10 +431,10 @@ Here is an example of a correct configuration: 下面是一个正确配置的示例: ```shell ---feature-gates=MemoryManager=true ---kube-reserved=cpu=4,memory=4Gi ---system-reserved=cpu=1,memory=1Gi ---memory-manager-policy=Static +--feature-gates=MemoryManager=true +--kube-reserved=cpu=4,memory=4Gi +--system-reserved=cpu=1,memory=1Gi +--memory-manager-policy=Static --reserved-memory '0:memory=3Gi;1:memory=2148Mi' ``` @@ -527,7 +528,7 @@ became rejected at a node: - pod status - indicates topology affinity errors - system logs - include valuable information for debugging, e.g., about generated hints - state file - the dump of internal state of the Memory Manager - (includes [Node Map and Memory Maps][2]) + (includes [Node Map and Memory Maps][2]) - starting from v1.22, the [device plugin resource API](#device-plugin-resource-api) can be used to retrieve information about the memory reserved for containers --> @@ -543,7 +544,7 @@ became rejected at a node: This error typically occurs in the following situations: * a node has not enough resources available to satisfy the pod's request -* the pod's request is rejected due to particular Topology Manager policy constraints +* the pod's request is rejected due to particular Topology Manager policy constraints The error appears in the status of a pod: --> @@ -579,7 +580,7 @@ Warning TopologyAffinityError 10m kubelet, dell8 Resources cannot be alloca Search system logs with respect to a particular pod. -The set of hints that Memory Manager generated for the pod can be found in the logs. +The set of hints that Memory Manager generated for the pod can be found in the logs. Also, the set of hints generated by CPU Manager should be present in the logs. --> ### 系统日志 {#system-logs} @@ -595,7 +596,7 @@ The best hint should be also present in the logs. The best hint indicates where to allocate all the resources. Topology Manager tests this hint against its current policy, and based on the verdict, -it either admits the pod to the node or rejects it. +it either admits the pod to the node or rejects it. Also, search the logs for occurrences associated with the Memory Manager, e.g. to find out information about `cgroups` and `cpuset.mems` updates. @@ -636,7 +637,7 @@ spec: cpu: "2" memory: 150Gi command: ["sleep","infinity"] -``` +``` 术语绑定(pinned)意味着 Pod 的内存使用被(通过 `cgroups` 配置)限制到这些 NUMA 节点。 @@ -743,7 +744,7 @@ Notice that the management of groups is handled in a relatively complex manner, further elaboration is provided in Memory Manager KEP in [this][1] and [this][3] sections. In order to analyse memory resources available in a group,the corresponding entries from -NUMA nodes belonging to the group must be added up. +NUMA nodes belonging to the group must be added up. --> 注意 NUMA 分组的管理是有一个相对复杂的管理器处理的, 相关逻辑的进一步细节可在内存管理器的 KEP 中[示例1][1]和[跨 NUMA 节点][3]节找到。 @@ -791,7 +792,7 @@ kubelet 提供了一个 `PodResourceLister` gRPC 服务来启用对资源和相 -- [Memory Manager KEP: Design Overview][4] +- [Memory Manager KEP: Design Overview][4] - [Memory Manager KEP: Memory Maps at start-up (with examples)][5] - [Memory Manager KEP: Memory Maps at runtime (with examples)][6] - [Memory Manager KEP: Simulation - how the Memory Manager works? (by examples)][1] @@ -804,4 +805,3 @@ kubelet 提供了一个 `PodResourceLister` gRPC 服务来启用对资源和相 [4]: https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/1769-memory-manager#design-overview [5]: https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/1769-memory-manager#memory-maps-at-start-up-with-examples [6]: https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/1769-memory-manager#memory-maps-at-runtime-with-examples - From a362de20d608f83407f8762a25ff8b51ee9d4a2f Mon Sep 17 00:00:00 2001 From: windsonsea Date: Fri, 10 Feb 2023 10:11:01 +0800 Subject: [PATCH 176/279] [zh] sync 2023-02-06-k8s-gcr-io-freeze-announcement.md --- ...23-02-06-k8s-gcr-io-freeze-announcement.md | 122 ++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 content/zh-cn/blog/_posts/2023-02-06-k8s-gcr-io-freeze-announcement.md diff --git a/content/zh-cn/blog/_posts/2023-02-06-k8s-gcr-io-freeze-announcement.md b/content/zh-cn/blog/_posts/2023-02-06-k8s-gcr-io-freeze-announcement.md new file mode 100644 index 00000000000..fadf16af045 --- /dev/null +++ b/content/zh-cn/blog/_posts/2023-02-06-k8s-gcr-io-freeze-announcement.md @@ -0,0 +1,122 @@ +--- +layout: blog +title: "k8s.gcr.io 镜像仓库将从 2023 年 4 月 3 日起被冻结" +date: 2023-02-06 +slug: k8s-gcr-io-freeze-announcement +--- + + + +**作者**:Mahamed Ali (Rackspace Technology) + +**译者**:Michael Yao (Daocloud) + + +Kubernetes 项目运行一个名为 `registry.k8s.io`、由社区管理的镜像仓库来托管其容器镜像。 +2023 年 4 月 3 日,旧仓库 `k8s.gcr.io` 将被冻结,Kubernetes 及其相关子项目的镜像将不再推送到这个旧仓库。 + +`registry.k8s.io` 这个仓库代替了旧仓库,这个新仓库已正式发布七个月。 +我们也发布了一篇[博文](/blog/2022/11/28/registry-k8s-io-faster-cheaper-ga/)阐述新仓库给社区和 +Kubernetes 项目带来的好处。这篇博客再次宣布后续版本的 Kubernetes 将不可用于旧仓库。这个时刻已经到来。 + + +这次变更对贡献者意味着: + +- 如果你是某子项目的 Maintainer,你将需要更新清单 (manifest) 和 Helm Chart 才能使用新仓库。 + + +这次变更对终端用户意味着: + +- Kubernetes 1.27 版本将不会发布到旧仓库。 +- 1.24、1.25 和 1.26 版本的补丁从 4 月份起将不再发布到旧仓库。请阅读以下时间线,了解旧仓库最终补丁版本的详情。 +- 从 1.25 开始,默认的镜像仓库已设置为 `registry.k8s.io`。`kubeadm` 和 `kubelet` + 中的这个镜像仓库地址是可覆盖的,但设置为 `k8s.gcr.io` 将在 4 月份之后的新版本中失败, + 因为旧仓库将没有这些版本了。 +- 如果你想提高集群的可靠性,不想再依赖社区管理的镜像仓库,或你正在外部流量受限的网络中运行 Kubernetes, + 你应该考虑托管本地镜像仓库的镜像。一些云供应商可能会为此提供托管解决方案。 + + +## 变更时间线 {#timeline-of-changes} + +- `k8s.gcr.io` 将于 2023 年 4 月 3 日被冻结 +- 1.27 预计于 2023 年 4 月 12 日发布 +- `k8s.gcr.io` 上的最后一个 1.23 版本将是 1.23.18(1.23 在仓库冻结前进入不再支持阶段) +- `k8s.gcr.io` 上的最后一个 1.24 版本将是 1.24.12 +- `k8s.gcr.io` 上的最后一个 1.25 版本将是 1.25.8 +- `k8s.gcr.io` 上的最后一个 1.26 版本将是 1.26.3 + + +## 下一步 {#whats-next} + +请确保你的集群未依赖旧的镜像仓库。例如,你可以运行以下命令列出 Pod 使用的镜像: + +```shell +kubectl get pods --all-namespaces -o jsonpath="{.items[*].spec.containers[*].image}" |\ +tr -s '[[:space:]]' '\n' |\ +sort |\ +uniq -c +``` + + +旧的镜像仓库可能存在其他依赖项。请确保你检查了所有潜在的依赖项,以保持集群健康和最新。 + + +## 致谢 {#acknowledgments} + +__改变是艰难的__,但只有镜像服务平台演进才能确保 Kubernetes 项目可持续的未来。 +我们努力为 Kubernetes 的每个使用者提供更好的服务。从社区各个角落汇聚而来的众多贡献者长期努力工作, +确保我们能够做出尽可能最好的决策、履行计划并尽最大努力传达这些计划。 + + +衷心感谢: + +- 来自 SIG K8s Infra 的 Aaron Crickenberger、Arnaud Meukam、Benjamin Elder、Caleb + Woodbine、Davanum Srinivas、Mahamed Ali 和 Tim Hockin +- 来自 SIG Node 的 Brian McQueen 和 Sergey Kanzhelev +- 来自 SIG Cluster Lifecycle 的 Lubomir Ivanov +- 来自 SIG Release 的 Adolfo García Veytia、Jeremy Rickard、Sascha Grunert 和 Stephen Augustus +- 来自 SIG Contribex 的 Bob Killen 和 Kaslin Fields +- 来自 Security Response Committee(安全响应委员会)的 Tim Allclair + +此外非常感谢负责联络各个云提供商合作伙伴的朋友们:来自 Amazon 的 Jay Pipes 和来自 Google 的 Jon Johnson Jr. From 7f9743f2552fa368204f747751fdd61e13d49007 Mon Sep 17 00:00:00 2001 From: Liz Rice Date: Fri, 10 Feb 2023 11:58:22 +0000 Subject: [PATCH 177/279] Docs: identify CNCF project network add-ons Indicating CNCF project status, to help end users understand which network add-ons are part of the CNCF family --- content/en/docs/concepts/cluster-administration/addons.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/en/docs/concepts/cluster-administration/addons.md b/content/en/docs/concepts/cluster-administration/addons.md index e767ea4bc15..0e691a24865 100644 --- a/content/en/docs/concepts/cluster-administration/addons.md +++ b/content/en/docs/concepts/cluster-administration/addons.md @@ -17,11 +17,11 @@ This page lists some of the available add-ons and links to their respective inst ## Networking and Network Policy * [ACI](https://www.github.com/noironetworks/aci-containers) provides integrated container networking and network security with Cisco ACI. -* [Antrea](https://antrea.io/) operates at Layer 3/4 to provide networking and security services for Kubernetes, leveraging Open vSwitch as the networking data plane. +* [Antrea](https://antrea.io/) operates at Layer 3/4 to provide networking and security services for Kubernetes, leveraging Open vSwitch as the networking data plane. Antrea is a [CNCF project at the Sandbox level](https://www.cncf.io/projects/antrea/). * [Calico](https://docs.projectcalico.org/latest/introduction/) is a networking and network policy provider. Calico supports a flexible set of networking options so you can choose the most efficient option for your situation, including non-overlay and overlay networks, with or without BGP. Calico uses the same engine to enforce network policy for hosts, pods, and (if using Istio & Envoy) applications at the service mesh layer. * [Canal](https://projectcalico.docs.tigera.io/getting-started/kubernetes/flannel/flannel) unites Flannel and Calico, providing networking and network policy. -* [Cilium](https://github.com/cilium/cilium) is a networking, observability, and security solution with an eBPF-based data plane. Cilium provides a simple flat Layer 3 network with the ability to span multiple clusters in either a native routing or overlay/encapsulation mode, and can enforce network policies on L3-L7 using an identity-based security model that is decoupled from network addressing. Cilium can act as a replacement for kube-proxy; it also offers additional, opt-in observability and security features. -* [CNI-Genie](https://github.com/cni-genie/CNI-Genie) enables Kubernetes to seamlessly connect to a choice of CNI plugins, such as Calico, Canal, Flannel, or Weave. +* [Cilium](https://github.com/cilium/cilium) is a networking, observability, and security solution with an eBPF-based data plane. Cilium provides a simple flat Layer 3 network with the ability to span multiple clusters in either a native routing or overlay/encapsulation mode, and can enforce network policies on L3-L7 using an identity-based security model that is decoupled from network addressing. Cilium can act as a replacement for kube-proxy; it also offers additional, opt-in observability and security features. Cilium is a [CNCF project at the Incubation level](https://www.cncf.io/projects/cilium/). +* [CNI-Genie](https://github.com/cni-genie/CNI-Genie) enables Kubernetes to seamlessly connect to a choice of CNI plugins, such as Calico, Canal, Flannel, or Weave. CNI-Genie is a [CNCF project at the Sandbox level](https://www.cncf.io/projects/cni-genie/). * [Contiv](https://contivpp.io/) provides configurable networking (native L3 using BGP, overlay using vxlan, classic L2, and Cisco-SDN/ACI) for various use cases and a rich policy framework. Contiv project is fully [open sourced](https://github.com/contiv). The [installer](https://github.com/contiv/install) provides both kubeadm and non-kubeadm based installation options. * [Contrail](https://www.juniper.net/us/en/products-services/sdn/contrail/contrail-networking/), based on [Tungsten Fabric](https://tungsten.io), is an open source, multi-cloud network virtualization and policy management platform. Contrail and Tungsten Fabric are integrated with orchestration systems such as Kubernetes, OpenShift, OpenStack and Mesos, and provide isolation modes for virtual machines, containers/pods and bare metal workloads. * [Flannel](https://github.com/flannel-io/flannel#deploying-flannel-manually) is an overlay network provider that can be used with Kubernetes. From 1c72280493c727a11fc754818867ea83e63e3c9f Mon Sep 17 00:00:00 2001 From: Guangwen Feng Date: Fri, 10 Feb 2023 22:33:27 +0800 Subject: [PATCH 178/279] Fix some typos Signed-off-by: Guangwen Feng --- ...2016-10-00-Dynamic-Provisioning-And-Storage-In-Kubernetes.md | 2 +- .../en/blog/_posts/2018-06-28-Airflow-Kubernetes-Operator.md | 2 +- .../blog/_posts/2018-10-02-network-bootable-farm-with-ltsp.md | 2 +- .../blog/_posts/2020-05-06-third-party-dual-sourced-content.md | 2 +- content/en/blog/_posts/2020-05-21-wsl2-dockerdesktop-k8s.md | 2 +- .../blog/_posts/2020-07-27-kubernetes-1-17-release-interview.md | 2 +- content/en/blog/_posts/2021-12-07-kubernetes-release-1.23.md | 2 +- .../2022-03-15-meet-our-contributors-APAC-AU-NZ-region-02.md | 2 +- .../en/blog/_posts/2022-05-27-maxunavailable-for-statefulset.md | 2 +- content/en/blog/_posts/2022-08-31-cgroupv2-ga.md | 2 +- content/en/blog/_posts/2022-09-29-immutability-with-cel.md | 2 +- content/en/blog/_posts/2022-12-09-kubernetes-1.26-blog.md | 2 +- .../en/blog/_posts/2022-12-29-scalable-job-tracking-ga/index.md | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/content/en/blog/_posts/2016-10-00-Dynamic-Provisioning-And-Storage-In-Kubernetes.md b/content/en/blog/_posts/2016-10-00-Dynamic-Provisioning-And-Storage-In-Kubernetes.md index 64039e68a7a..31025542580 100644 --- a/content/en/blog/_posts/2016-10-00-Dynamic-Provisioning-And-Storage-In-Kubernetes.md +++ b/content/en/blog/_posts/2016-10-00-Dynamic-Provisioning-And-Storage-In-Kubernetes.md @@ -143,7 +143,7 @@ When a default StorageClass exists and a user creates a PersistentVolumeClaim wi -Kubernetes 1.4 maintains backwards compatibility with the alpha version of the dynamic provisioning feature to allow for a smoother transition to the beta version. The alpha behavior is triggered by the existance of the alpha dynamic provisioning annotation (volume. **alpha**.kubernetes.io/storage-class). Keep in mind that if the beta annotation (volume. **beta**.kubernetes.io/storage-class) is present, it takes precedence, and triggers the beta behavior. +Kubernetes 1.4 maintains backwards compatibility with the alpha version of the dynamic provisioning feature to allow for a smoother transition to the beta version. The alpha behavior is triggered by the existence of the alpha dynamic provisioning annotation (volume. **alpha**.kubernetes.io/storage-class). Keep in mind that if the beta annotation (volume. **beta**.kubernetes.io/storage-class) is present, it takes precedence, and triggers the beta behavior. diff --git a/content/en/blog/_posts/2018-06-28-Airflow-Kubernetes-Operator.md b/content/en/blog/_posts/2018-06-28-Airflow-Kubernetes-Operator.md index bb77bd1e5ad..5a18fa4c9a1 100644 --- a/content/en/blog/_posts/2018-06-28-Airflow-Kubernetes-Operator.md +++ b/content/en/blog/_posts/2018-06-28-Airflow-Kubernetes-Operator.md @@ -192,7 +192,7 @@ To modify/add your own DAGs, you can use `kubectl cp` to upload local files into # Get Involved -This feature is just the beginning of multiple major efforts to improves Apache Airflow integration into Kubernetes. The Kubernetes Operator has been merged into the [1.10 release branch of Airflow](https://github.com/apache/incubator-airflow/tree/v1-10-test) (the executor in experimental mode), along with a fully k8s native scheduler called the Kubernetes Executor (article to come). These features are still in a stage where early adopters/contributers can have a huge influence on the future of these features. +This feature is just the beginning of multiple major efforts to improves Apache Airflow integration into Kubernetes. The Kubernetes Operator has been merged into the [1.10 release branch of Airflow](https://github.com/apache/incubator-airflow/tree/v1-10-test) (the executor in experimental mode), along with a fully k8s native scheduler called the Kubernetes Executor (article to come). These features are still in a stage where early adopters/contributors can have a huge influence on the future of these features. For those interested in joining these efforts, I'd recommend checkint out these steps: diff --git a/content/en/blog/_posts/2018-10-02-network-bootable-farm-with-ltsp.md b/content/en/blog/_posts/2018-10-02-network-bootable-farm-with-ltsp.md index 2039a4d5b68..6026e068551 100644 --- a/content/en/blog/_posts/2018-10-02-network-bootable-farm-with-ltsp.md +++ b/content/en/blog/_posts/2018-10-02-network-bootable-farm-with-ltsp.md @@ -460,7 +460,7 @@ Now you can configure your DHCP. Basically you should set the `next-server` and I use ISC-DHCP server, and here is an example `dhcpd.conf`: ``` -shared-network ltsp-netowrk { +shared-network ltsp-network { subnet 10.9.0.0 netmask 255.255.0.0 { authoritative; default-lease-time -1; diff --git a/content/en/blog/_posts/2020-05-06-third-party-dual-sourced-content.md b/content/en/blog/_posts/2020-05-06-third-party-dual-sourced-content.md index 54b2910cf7f..f41aeddb7b9 100644 --- a/content/en/blog/_posts/2020-05-06-third-party-dual-sourced-content.md +++ b/content/en/blog/_posts/2020-05-06-third-party-dual-sourced-content.md @@ -27,7 +27,7 @@ Our goal is for Kubernetes docs to be a trustworthy guide to Kubernetes features ### Re-homing content -Some content will be removed that readers may find helpful. To make sure readers have continous access to information, we're giving stakeholders until the [1.19 release deadline for docs](https://github.com/kubernetes/sig-release/tree/master/releases/release-1.19), **July 9th, 2020** to re-home any content slated for removal. +Some content will be removed that readers may find helpful. To make sure readers have continuous access to information, we're giving stakeholders until the [1.19 release deadline for docs](https://github.com/kubernetes/sig-release/tree/master/releases/release-1.19), **July 9th, 2020** to re-home any content slated for removal. Over the next few months you'll see less third party content in the docs as contributors open PRs to remove content. diff --git a/content/en/blog/_posts/2020-05-21-wsl2-dockerdesktop-k8s.md b/content/en/blog/_posts/2020-05-21-wsl2-dockerdesktop-k8s.md index 9a1d4760306..bb9931bf900 100644 --- a/content/en/blog/_posts/2020-05-21-wsl2-dockerdesktop-k8s.md +++ b/content/en/blog/_posts/2020-05-21-wsl2-dockerdesktop-k8s.md @@ -520,7 +520,7 @@ And the real strength of WSL2 integration, the port `8443` once open on WSL2 dis Working on the command line is always good and very insightful. However, when dealing with Kubernetes we might want, at some point, to have a visual overview. -For that, Minikube embeded the [Kubernetes Dashboard](https://github.com/kubernetes/dashboard). Thanks to it, running and accessing the Dashboard is very simple: +For that, Minikube embedded the [Kubernetes Dashboard](https://github.com/kubernetes/dashboard). Thanks to it, running and accessing the Dashboard is very simple: ```bash # Enable the Dashboard service diff --git a/content/en/blog/_posts/2020-07-27-kubernetes-1-17-release-interview.md b/content/en/blog/_posts/2020-07-27-kubernetes-1-17-release-interview.md index c61def44be5..44154c62b3c 100644 --- a/content/en/blog/_posts/2020-07-27-kubernetes-1-17-release-interview.md +++ b/content/en/blog/_posts/2020-07-27-kubernetes-1-17-release-interview.md @@ -198,7 +198,7 @@ GUINEVERE SAENGER: I would want Jorge to be really on top of making sure that ev Greater communication of timelines and just giving people more time and space to be able to get in their changes, or at least, seemingly give them more time and space by sending early warnings, is going to be helpful. Of course, he's going to have a slightly longer release, too, than I did. This might be related to a unique Q4 challenge. Overall, I would encourage him to take more breaks, to rely more on his release shadows, and split out the work in a fashion that allows everyone to have a turn and everyone to have a break as well. -**ADAM GLICK: What would your advice be to someone who is hearing your experience and is inspired to get involved with the Kubernetes release or contributer process?** +**ADAM GLICK: What would your advice be to someone who is hearing your experience and is inspired to get involved with the Kubernetes release or contributor process?** GUINEVERE SAENGER: Those are two separate questions. So let me tackle the Kubernetes release question first. Kubernetes [SIG Release](https://github.com/kubernetes/sig-release/#readme) has, in my opinion, a really excellent onboarding program for new members. We have what is called the [Release Team Shadow Program](https://github.com/kubernetes/sig-release/blob/master/release-team/shadows.md). We also have the Release Engineering Shadow Program, or the Release Management Shadow Program. Those are two separate subprojects within SIG Release. And each subproject has a team of roles, and each role can have two to four shadows that are basically people who are part of that role team, and they are learning that role as they are doing it. diff --git a/content/en/blog/_posts/2021-12-07-kubernetes-release-1.23.md b/content/en/blog/_posts/2021-12-07-kubernetes-release-1.23.md index 98a15210626..ae3bd6cf02f 100644 --- a/content/en/blog/_posts/2021-12-07-kubernetes-release-1.23.md +++ b/content/en/blog/_posts/2021-12-07-kubernetes-release-1.23.md @@ -81,7 +81,7 @@ If the `ServerSideFieldValidation` feature gate is enabled starting 1.23, users With the feature gate enabled, we also introduce the `fieldValidation` query parameter so that users can specify the desired behavior of the server on a per request basis. Valid values for the `fieldValidation` query parameter are: -- Ignore (default when feature gate is disabled, same as pre-1.23 behavior of dropping/ignoring unkonwn fields) +- Ignore (default when feature gate is disabled, same as pre-1.23 behavior of dropping/ignoring unknown fields) - Warn (default when feature gate is enabled). - Strict (this will fail the request with an Invalid Request error) diff --git a/content/en/blog/_posts/2022-03-15-meet-our-contributors-APAC-AU-NZ-region-02.md b/content/en/blog/_posts/2022-03-15-meet-our-contributors-APAC-AU-NZ-region-02.md index e8d9cfdf89d..1d0ac8a8d87 100644 --- a/content/en/blog/_posts/2022-03-15-meet-our-contributors-APAC-AU-NZ-region-02.md +++ b/content/en/blog/_posts/2022-03-15-meet-our-contributors-APAC-AU-NZ-region-02.md @@ -32,7 +32,7 @@ Caleb is also a co-organizer of the [CloudNative NZ](https://www.meetup.com/clou ## [Dylan Graham](https://github.com/DylanGraham) -Dylan Graham is a cloud engineer from Adeliade, Australia. He has been contributing to the upstream Kubernetes project since 2018. +Dylan Graham is a cloud engineer from Adelaide, Australia. He has been contributing to the upstream Kubernetes project since 2018. He stated that being a part of such a large-scale project was initially overwhelming, but that the community's friendliness and openness assisted him in getting through it. diff --git a/content/en/blog/_posts/2022-05-27-maxunavailable-for-statefulset.md b/content/en/blog/_posts/2022-05-27-maxunavailable-for-statefulset.md index 5d34a7196cd..4093758e1fc 100644 --- a/content/en/blog/_posts/2022-05-27-maxunavailable-for-statefulset.md +++ b/content/en/blog/_posts/2022-05-27-maxunavailable-for-statefulset.md @@ -18,7 +18,7 @@ case where you're using the `OrderedReady` Pod management policy for a StatefulS Here are some examples: - I am using a StatefulSet to orchestrate a multi-instance, cache based application where the size of the cache is large. The cache - starts cold and requires some siginificant amount of time before the container can start. There could be more initial startup tasks + starts cold and requires some significant amount of time before the container can start. There could be more initial startup tasks that are required. A RollingUpdate on this StatefulSet would take a lot of time before the application is fully updated. If the StatefulSet supported updating more than one pod at a time, it would result in a much faster update. diff --git a/content/en/blog/_posts/2022-08-31-cgroupv2-ga.md b/content/en/blog/_posts/2022-08-31-cgroupv2-ga.md index 456d15a6b8a..76963a4748b 100644 --- a/content/en/blog/_posts/2022-08-31-cgroupv2-ga.md +++ b/content/en/blog/_posts/2022-08-31-cgroupv2-ga.md @@ -89,7 +89,7 @@ To use cgroup v2 with Kubernetes, you must meet the following requirements: * The kubelet and the container runtime are configured to use the [systemd cgroup driver](/docs/setup/production-environment/container-runtimes#systemd-cgroup-driver) The kubelet and container runtime use a [cgroup driver](/docs/setup/production-environment/container-runtimes#cgroup-drivers) -to set cgroup paramaters. When using cgroup v2, it's strongly recommended that both +to set cgroup parameters. When using cgroup v2, it's strongly recommended that both the kubelet and your container runtime use the [systemd cgroup driver](/docs/setup/production-environment/container-runtimes#systemd-cgroup-driver), so that there's a single cgroup manager on the system. To configure the kubelet diff --git a/content/en/blog/_posts/2022-09-29-immutability-with-cel.md b/content/en/blog/_posts/2022-09-29-immutability-with-cel.md index c857b06a1fb..b16e300c32f 100644 --- a/content/en/blog/_posts/2022-09-29-immutability-with-cel.md +++ b/content/en/blog/_posts/2022-09-29-immutability-with-cel.md @@ -438,7 +438,7 @@ kubectl apply -f crds/stable.example.com_appendonlylists.yaml customresourcedefinition.apiextensions.k8s.io/appendonlylists.stable.example.com created ``` -Creating an inital list with one element inside should succeed without problem: +Creating an initial list with one element inside should succeed without problem: ```shell kubectl apply -f - < Date: Fri, 10 Feb 2023 13:23:31 -0500 Subject: [PATCH 179/279] Making dockershim FAQ evergreen (#39106) --- content/en/blog/_posts/2022-02-17-updated-dockershim-faq.md | 1 + 1 file changed, 1 insertion(+) diff --git a/content/en/blog/_posts/2022-02-17-updated-dockershim-faq.md b/content/en/blog/_posts/2022-02-17-updated-dockershim-faq.md index 4950f880973..26fa20133cd 100644 --- a/content/en/blog/_posts/2022-02-17-updated-dockershim-faq.md +++ b/content/en/blog/_posts/2022-02-17-updated-dockershim-faq.md @@ -5,6 +5,7 @@ linkTitle: "Dockershim Removal FAQ" date: 2022-02-17 slug: dockershim-faq aliases: [ '/dockershim' ] +evergreen: true --- **This supersedes the original From 8355f38ae431e3bd04c01ac66a3e0b8f37fc0382 Mon Sep 17 00:00:00 2001 From: Akihiro Suda Date: Fri, 10 Feb 2023 13:33:02 +0900 Subject: [PATCH 180/279] `mountPropagation: None` equates to `rprivate`, not `private` Evidences: - https://github.com/containerd/containerd/blob/v1.6.16/pkg/cri/opts/spec_linux.go#L181 - https://github.com/cri-o/cri-o/blob/v1.26.1/server/container_create_linux.go#L982 This commit also replaces the link to https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt with https://man7.org/linux/man-pages/man8/mount.8.html , as the former one does not mention `rprivate` . Signed-off-by: Akihiro Suda --- content/en/docs/concepts/storage/volumes.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/content/en/docs/concepts/storage/volumes.md b/content/en/docs/concepts/storage/volumes.md index 9ae9febe3bb..80f259aab31 100644 --- a/content/en/docs/concepts/storage/volumes.md +++ b/content/en/docs/concepts/storage/volumes.md @@ -1282,8 +1282,13 @@ in `Container.volumeMounts`. Its values are: In similar fashion, no mounts created by the container will be visible on the host. This is the default mode. - This mode is equal to `private` mount propagation as described in the - [Linux kernel documentation](https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt) + This mode is equal to `rprivate` mount propagation as described in + [`mount(8)`](https://man7.org/linux/man-pages/man8/mount.8.html) + + However, the CRI runtime may choose `rslave` mount propagation (i.e., + `HostToContainer`) instead, when `rprivate` propagation is not applicable. + cri-dockerd (Docker) is known to choose `rslave` mount propagation when the + mount source contains the Docker daemon's root directory (`/var/lib/docker`). * `HostToContainer` - This volume mount will receive all subsequent mounts that are mounted to this volume or any of its subdirectories. @@ -1296,7 +1301,7 @@ in `Container.volumeMounts`. Its values are: propagation will see it. This mode is equal to `rslave` mount propagation as described in the - [Linux kernel documentation](https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt) + [`mount(8)`](https://man7.org/linux/man-pages/man8/mount.8.html) * `Bidirectional` - This volume mount behaves the same the `HostToContainer` mount. In addition, all volume mounts created by the container will be propagated @@ -1306,7 +1311,7 @@ in `Container.volumeMounts`. Its values are: a Pod that needs to mount something on the host using a `hostPath` volume. This mode is equal to `rshared` mount propagation as described in the - [Linux kernel documentation](https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt) + [`mount(8)`](https://man7.org/linux/man-pages/man8/mount.8.html) {{< warning >}} `Bidirectional` mount propagation can be dangerous. It can damage From 09c9776dc34036dd4ac7ee4602cdc861eb48a2cc Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Sat, 11 Feb 2023 20:20:20 +0800 Subject: [PATCH 181/279] [zh] Resync page volume-snapshots --- content/zh-cn/docs/concepts/storage/volume-snapshots.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/zh-cn/docs/concepts/storage/volume-snapshots.md b/content/zh-cn/docs/concepts/storage/volume-snapshots.md index b908ffb9133..19494f81607 100644 --- a/content/zh-cn/docs/concepts/storage/volume-snapshots.md +++ b/content/zh-cn/docs/concepts/storage/volume-snapshots.md @@ -381,12 +381,12 @@ kubectl get crd volumesnapshotcontent -o yaml 如果你希望允许用户从现有的 `VolumeSnapshot` 创建 `PersistentVolumeClaim`, 但是使用与源卷不同的卷模式,则需要添加注解 -`snapshot.storage.kubernetes.io/allowVolumeModeChange: "true"` +`snapshot.storage.kubernetes.io/allow-volume-mode-change: "true"` 到对应 `VolumeSnapshot` 的 `VolumeSnapshotContent` 中。 ## 联网和网络策略 * [ACI](https://www.github.com/noironetworks/aci-containers) 通过 Cisco ACI 提供集成的容器网络和安全网络。 * [Antrea](https://antrea.io/) 在第 3/4 层执行操作,为 Kubernetes 提供网络连接和安全服务。Antrea 利用 Open vSwitch 作为网络的数据面。 + Antrea 是一个[沙箱级的 CNCF 项目](https://www.cncf.io/projects/antrea/)。 * [Calico](https://docs.projectcalico.org/latest/introduction/) 是一个联网和网络策略供应商。 Calico 支持一套灵活的网络选项,因此你可以根据自己的情况选择最有效的选项,包括非覆盖和覆盖网络,带或不带 BGP。 Calico 使用相同的引擎为主机、Pod 和(如果使用 Istio 和 Envoy)应用程序在服务网格层执行网络策略。 @@ -42,13 +43,15 @@ Add-ons 扩展了 Kubernetes 的功能。 能够以原生路由(routing)和覆盖/封装(overlay/encapsulation)模式跨越多个集群, 并且可以使用与网络寻址分离的基于身份的安全模型在 L3 至 L7 上实施网络策略。 Cilium 可以作为 kube-proxy 的替代品;它还提供额外的、可选的可观察性和安全功能。 + Cilium 是一个[孵化级别的 CNCF 项目](https://www.cncf.io/projects/cilium/)。 * [CNI-Genie](https://github.com/cni-genie/CNI-Genie) 使 Kubernetes 无缝连接到 Calico、Canal、Flannel 或 Weave 等其中一种 CNI 插件。 + CNI-Genie 是一个[沙箱级的 CNCF 项目](https://www.cncf.io/projects/cni-genie/)。 * [Contiv](https://contivpp.io/) 为各种用例和丰富的策略框架提供可配置的网络 (带 BGP 的原生 L3、带 vxlan 的覆盖、标准 L2 和 Cisco-SDN/ACI)。 Contiv 项目完全[开源](https://github.com/contiv)。 From 2f80461f52f22f73df30b66f064e035e444e0d6b Mon Sep 17 00:00:00 2001 From: Kinzhi Date: Sun, 12 Feb 2023 02:45:37 +0800 Subject: [PATCH 183/279] [zh-cn]SYNC source-ip.md --- content/zh-cn/docs/tutorials/services/source-ip.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/zh-cn/docs/tutorials/services/source-ip.md b/content/zh-cn/docs/tutorials/services/source-ip.md index ddd734daab2..9b8ab74dbd1 100644 --- a/content/zh-cn/docs/tutorials/services/source-ip.md +++ b/content/zh-cn/docs/tutorials/services/source-ip.md @@ -118,11 +118,11 @@ deployment.apps/source-ip-app created -如果你在 [iptables 模式](/zh-cn/docs/concepts/services-networking/service/#proxy-mode-iptables)(默认)下运行 +如果你在 [iptables 模式](/zh-cn/docs/reference/networking/virtual-ips/#proxy-mode-iptables)(默认)下运行 kube-proxy,则从集群内发送到 ClusterIP 的数据包永远不会进行源 NAT。 你可以通过在运行 kube-proxy 的节点上获取 `http://localhost:10249/proxyMode` 来查询 kube-proxy 模式。 From 75be9fdf02461f8268992b23e71439d7618c1c1c Mon Sep 17 00:00:00 2001 From: Arhell Date: Sun, 12 Feb 2023 01:00:08 +0200 Subject: [PATCH 184/279] [zh] Update ConfigMap data extraction to use jsonpath instead of grep/sed --- .../zh-cn/docs/reference/setup-tools/kubeadm/kubeadm-join.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/zh-cn/docs/reference/setup-tools/kubeadm/kubeadm-join.md b/content/zh-cn/docs/reference/setup-tools/kubeadm/kubeadm-join.md index 167a3903872..6ceea2a63e6 100644 --- a/content/zh-cn/docs/reference/setup-tools/kubeadm/kubeadm-join.md +++ b/content/zh-cn/docs/reference/setup-tools/kubeadm/kubeadm-join.md @@ -475,7 +475,7 @@ it off regardless. Doing so will disable the ability to use the `--discovery-tok * 从 API 服务器获取 `cluster-info` 文件: ```shell -kubectl -n kube-public get cm cluster-info -o yaml | grep "kubeconfig:" -A11 | grep "apiVersion" -A10 | sed "s/ //" | tee cluster-info.yaml +kubectl -n kube-public get cm cluster-info -o jsonpath='{.data.kubeconfig}' | tee cluster-info.yaml ``` * `None` - 此卷挂载将不会感知到主机后续在此卷或其任何子目录上执行的挂载变化。 类似的,容器所创建的卷挂载在主机上是不可见的。这是默认模式。 - 该模式等同于 [Linux 内核文档](https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt)中描述的 - `private` 挂载传播选项。 + 该模式等同于 [`mount(8)`](https://man7.org/linux/man-pages/man8/mount.8.html)中描述的 + `rprivate` 挂载传播选项。 + + 然而,当 `rprivate` 传播选项不适用时,CRI 运行时可以转为选择 `rslave` 挂载传播选项 + (即 `HostToContainer`)。当挂载源包含 Docker 守护进程的根目录(`/var/lib/docker`)时, + cri-dockerd (Docker) 已知可以选择 `rslave` 挂载传播选项。 + 。 * `HostToContainer` - 此卷挂载将会感知到主机后续针对此卷或其任何子目录的挂载操作。 @@ -2193,7 +2203,7 @@ in `Container.volumeMounts`. Its values are: 类似的,配置了 `Bidirectional` 挂载传播选项的 Pod 如果在同一卷上挂载了内容,挂载传播设置为 `HostToContainer` 的容器都将能看到这一变化。 - 该模式等同于 [Linux 内核文档](https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt)中描述的 + 该模式等同于 [`mount(8)`](https://man7.org/linux/man-pages/man8/mount.8.html)中描述的 `rslave` 挂载传播选项。 * `Bidirectional` - 这种卷挂载和 `HostToContainer` 挂载表现相同。 另外,容器创建的卷挂载将被传播回至主机和使用同一卷的所有 Pod 的所有容器。 - 该模式等同于 [Linux 内核文档](https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt)中描述的 + 该模式等同于 [`mount(8)`](https://man7.org/linux/man-pages/man8/mount.8.html)中描述的 `rshared` 挂载传播选项。 {{< warning >}} From 75749ddc0b5e7f210fa1bc103ee7057302c8c1d4 Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Sun, 12 Feb 2023 13:26:51 +0800 Subject: [PATCH 187/279] [zh]Add markup to fix skew output in documentation --- .../docs/tasks/configure-pod-container/migrate-from-psp.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/zh-cn/docs/tasks/configure-pod-container/migrate-from-psp.md b/content/zh-cn/docs/tasks/configure-pod-container/migrate-from-psp.md index ac62e72e32e..3a48f1e0378 100644 --- a/content/zh-cn/docs/tasks/configure-pod-container/migrate-from-psp.md +++ b/content/zh-cn/docs/tasks/configure-pod-container/migrate-from-psp.md @@ -30,11 +30,11 @@ admission controller. This can be done effectively using a combination of dry-ru -如果你目前运行的 Kubernetes 版本不是 {{ skew currentVersion }}, +如果你目前运行的 Kubernetes 版本不是 {{< skew currentVersion >}}, 你可能要切换本页面以查阅你实际所运行的 Kubernetes 版本文档。 -集群中的每个节点必须至少有 1 个 CPU 可用才能运行本任务中的示例。 +你的集群必须至少有 1 个 CPU 可用才能运行本任务中的示例。 本页的一些步骤要求你在集群中运行 [metrics-server](https://github.com/kubernetes-sigs/metrics-server) @@ -61,7 +61,7 @@ kubectl get apiservices ``` 如果资源指标 API 可用,则会输出将包含一个对 `metrics.k8s.io` 的引用。 @@ -124,7 +124,7 @@ kubectl apply -f https://k8s.io/examples/pods/resource/cpu-request-limit.yaml -- ``` 验证所创建的 Pod 处于 Running 状态 @@ -182,15 +182,13 @@ Recall that by setting `-cpu "2"`, you configured the Container to attempt to us 但是容器只被允许使用大约 1 个 CPU。 容器的 CPU 用量受到限制,因为该容器正尝试使用超出其限制的 CPU 资源。 +{{< note >}} -{{< note >}} CPU 使用率低于 1.0 的另一种可能的解释是,节点可能没有足够的 CPU 资源可用。 -回想一下,此练习的先决条件需要你的节点至少具有 1 个 CPU 可用。 +回想一下,此练习的先决条件需要你的集群至少具有 1 个 CPU 可用。 如果你的容器在只有 1 个 CPU 的节点上运行,则容器无论为容器指定的 CPU 限制如何, 都不能使用超过 1 个 CPU。 {{< /note >}} @@ -276,7 +274,7 @@ Pod 调度是基于资源请求值来进行的。 kubectl apply -f https://k8s.io/examples/pods/resource/cpu-request-limit-2.yaml --namespace=cpu-example ``` 查看该 Pod 的状态: @@ -420,20 +418,19 @@ kubectl delete namespace cpu-example ### 针对集群管理员 {for-cluster-administrators} * [配置名字空间的默认内存请求和限制](/zh-cn/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/) * [为名字空间配置默认 CPU 请求和限制](/zh-cn/docs/tasks/administer-cluster/manage-resources/cpu-default-namespace/) -* [为名字空间配置最小和最大内存限制](/zh-cn/docs/tasks/administer-cluster//manage-resources/memory-constraint-namespace/) +* [为名字空间配置最小和最大内存限制](/zh-cn/docs/tasks/administer-cluster/manage-resources/memory-constraint-namespace/) * [为名字空间配置最小和最大 CPU 约束](/zh-cn/docs/tasks/administer-cluster/manage-resources/cpu-constraint-namespace/) * [为名字空间配置内存和 CPU 配额](/zh-cn/docs/tasks/administer-cluster/manage-resources/quota-memory-cpu-namespace/) * [为名字空间配置 Pod 配额](/zh-cn/docs/tasks/administer-cluster/manage-resources/quota-pod-namespace/) From c3f2b924c502f0dccff580864f483b19dc7654e0 Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Sun, 12 Feb 2023 15:20:22 +0800 Subject: [PATCH 189/279] [zh] Resync tasks/tls pages --- .../tasks/tls/managing-tls-in-a-cluster.md | 20 ++++++---- .../tls/manual-rotation-of-ca-certificates.md | 40 +++++++++---------- 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/content/zh-cn/docs/tasks/tls/managing-tls-in-a-cluster.md b/content/zh-cn/docs/tasks/tls/managing-tls-in-a-cluster.md index 2389fe9f96f..7a4940a2dee 100644 --- a/content/zh-cn/docs/tasks/tls/managing-tls-in-a-cluster.md +++ b/content/zh-cn/docs/tasks/tls/managing-tls-in-a-cluster.md @@ -177,12 +177,12 @@ is still to be created. ## 创建证书签名请求(CSR)对象发送到 Kubernetes API -使用以下命令创建 CSR YAML 文件,并发送到 API 服务器: +你可以使用以下命令创建 CSR 清单(YAML 格式),并发送到 API 服务器: ```shell cat < 这会产生一个证书颁发机构密钥文件(`ca-key.pem`)和证书(`ca.pem`)。 @@ -361,14 +361,18 @@ kubectl get csr my-svc.my-namespace -o jsonpath='{.spec.request}' | \ cfssljson -bare ca-signed-server ``` - + 你应该看到类似于以下的输出: ``` 2022/02/01 11:52:26 [INFO] signed certificate with serial number 576048928624926584381415936700914530534472870337 ``` - + 这会生成一个签名的服务证书文件,`ca-signed-server.pem`。 现在你可以将 `server.crt` 和 `server-key.pem` 填充到 {{}} 中, @@ -535,7 +539,7 @@ reference page. 1. 将新的 CA 证书和私钥(例如:`ca.crt`、`ca.key`、`front-proxy-ca.crt` 和 `front-proxy-client.key`)分发到所有控制面节点,放在其 Kubernetes 证书目录下。 2. 更新 {{< glossary_tooltip text="kube-controller-manager" term_id="kube-controller-manager" >}} - 的 `--root-ca-file` 标志,使之同时包含老的和新的 CA,之后重启组件。 + 的 `--root-ca-file` 标志,使之同时包含老的和新的 CA,之后重启 + kube-controller-manager。 自此刻起,所创建的所有{{< glossary_tooltip text="ServiceAccount" term_id="service-account" >}} 都会获得同时包含老的 CA 和新的 CA 的 Secret。 @@ -79,9 +79,9 @@ Configurations with a single API server will experience unavailability while the kube-controller-manager 标志 `--client-ca-file` 和 `--cluster-signing-cert-file` 所引用的文件不能是 CA 证书包。如果这些标志和 `--root-ca-file` 指向同一个 `ca.crt` 包文件 @@ -99,7 +99,7 @@ Configurations with a single API server will experience unavailability while the {{< /note >}} @@ -114,10 +114,10 @@ If any Pods are started before new CA is used by API servers, the new Pods get t * Make sure CoreDNS, kube-proxy and other Pods using in-cluster configurations are working as expected. -1. Append the both old and new CA to the file against `-client-ca-file` and `-kubelet-certificate-authority` +1. Append the both old and new CA to the file against `--client-ca-file` and `--kubelet-certificate-authority` flag in the `kube-apiserver` configuration. -1. Append the both old and new CA to the file against `-client-ca-file` flag in the `kube-scheduler` configuration. +1. Append the both old and new CA to the file against `--client-ca-file` flag in the `kube-scheduler` configuration. --> 4. 重启所有使用集群内配置的 Pod(例如:kube-proxy、CoreDNS 等),以便这些 Pod 能够使用与 ServiceAccount 相关联的 Secret 中的、已更新的证书机构数据。 @@ -161,17 +161,17 @@ If any Pods are started before new CA is used by API servers, the new Pods get t {{< /note >}} 9. 遵循下列步骤执行滚动更新 @@ -179,10 +179,10 @@ If any Pods are started before new CA is used by API servers, the new Pods get t 1. 重新启动所有其他[被聚合的 API 服务器](/zh-cn/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/) 或者 Webhook 处理程序,使之信任新的 CA 证书。 - 1. 在所有节点上更新 kubelet 配置中的 `clientCAFile` 所指文件以及 kubelet.conf 中的 + 2. 在所有节点上更新 kubelet 配置中的 `clientCAFile` 所指文件以及 `kubelet.conf` 中的 `certificate-authority-data` 并重启 kubelet 以同时使用老的和新的 CA 证书。 - 如果你的 kubelet 并未使用客户端证书轮换,则在所有节点上更新 kubelet.conf 中 + 如果你的 kubelet 并未使用客户端证书轮换,则在所有节点上更新 `kubelet.conf` 中 `client-certificate-data` 和 `client-key-data` 以及 kubelet 客户端证书文件(通常位于 `/var/lib/kubelet/pki` 目录下) @@ -274,7 +274,7 @@ If any Pods are started before new CA is used by API servers, the new Pods get t 1. Verify the cluster functionality. 1. Check the logs from control plane components, along with the kubelet and the kube-proxy. - Ensure those components are not reporting any TLS errors, see + Ensure those components are not reporting any TLS errors; see [looking at the logs](/docs/tasks/debug/debug-cluster/#looking-at-logs) for more details. 1. Validate logs from any aggregated api servers and pods using in-cluster config. @@ -291,7 +291,7 @@ If any Pods are started before new CA is used by API servers, the new Pods get t 1. Update all service account tokens to include new CA certificate only. - * All pods using an in-cluster kubeconfig will eventually need to be restarted to pick up the new secret, + * All pods using an in-cluster kubeconfig will eventually need to be restarted to pick up the new Secret, so that no Pods are relying on the old cluster CA. 1. Restart the control plane components by removing the old CA from the kubeconfig files and the files against `--client-ca-file`, `--root-ca-file` flags resp. From 0962546bc451fc4e998e18f097332ad30ad5a05e Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 12 Feb 2023 19:45:03 +0800 Subject: [PATCH 190/279] [zh] sync migrate-from-psp.md --- .../configure-pod-container/migrate-from-psp.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/content/zh-cn/docs/tasks/configure-pod-container/migrate-from-psp.md b/content/zh-cn/docs/tasks/configure-pod-container/migrate-from-psp.md index ac62e72e32e..0061e4cd0c7 100644 --- a/content/zh-cn/docs/tasks/configure-pod-container/migrate-from-psp.md +++ b/content/zh-cn/docs/tasks/configure-pod-container/migrate-from-psp.md @@ -30,11 +30,11 @@ admission controller. This can be done effectively using a combination of dry-ru -如果你目前运行的 Kubernetes 版本不是 {{ skew currentVersion }}, +如果你目前运行的 Kubernetes 版本不是 {{< skew currentVersion >}}, 你可能要切换本页面以查阅你实际所运行的 Kubernetes 版本文档。 PodSecurityPolicy 中有一些字段未被 Pod 安全性准入机制覆盖。如果你必须使用这些选项, -你需要在 Pod 安全性准入之外部署 -[准入 Webhook](/zh-cn/docs/reference/access-authn-authz/extensible-admission-controllers/) +你需要在 Pod 安全性准入之外部署[准入 Webhook](/zh-cn/docs/reference/access-authn-authz/extensible-admission-controllers/) 以补充这一能力,而这类操作不在本指南范围。 -首先,你可以去掉 Pod 安全性标准所未覆盖的那些验证性字段。这些字段(也列举于 -[将 PodSecurityPolicy 映射到 Pod 安全性标准](/zh-cn/docs/reference/access-authn-authz/psp-to-pod-security-standards/)参考中,标记为“无意见”)有: +首先,你可以去掉 Pod 安全性标准所未覆盖的那些验证性字段。这些字段 +(也列举于[将 PodSecurityPolicy 映射到 Pod 安全性标准](/zh-cn/docs/reference/access-authn-authz/psp-to-pod-security-standards/)参考中, +标记为“无意见”)有: - `.spec.allowedHostPaths` - `.spec.allowedFlexVolumes` @@ -449,8 +449,8 @@ There are several ways to choose a Pod Security level for your namespace: level that is at least as restrictive. You can see which PSPs are in use for pods in a given namespace with this command: --> -2. **根据现有的 PodSecurityPolicy 来确定** - 基于 - [将 PodSecurityPolicy 映射到 Pod 安全性标准](/zh-cn/docs/reference/access-authn-authz/psp-to-pod-security-standards/) +2. **根据现有的 PodSecurityPolicy 来确定** - + 基于[将 PodSecurityPolicy 映射到 Pod 安全性标准](/zh-cn/docs/reference/access-authn-authz/psp-to-pod-security-standards/) 参考资料,你可以将各个 PSP 映射到某个 Pod 安全性标准级别。如果你的 PSP 不是基于 Pod 安全性标准的,你可能或者需要选择一个至少与该 PSP 一样宽松的级别, 或者选择一个至少与其一样严格的级别。使用下面的命令你可以查看被 Pod 使用的 PSP 有哪些: From 3babf09e1adc484de88961bb20a04db4fcf5f963 Mon Sep 17 00:00:00 2001 From: Qiming Teng Date: Sun, 12 Feb 2023 13:45:31 +0800 Subject: [PATCH 191/279] [zh] Resync tasks/tools pages --- content/zh-cn/docs/home/_index.md | 77 ++++++++++--------- content/zh-cn/docs/tasks/tools/_index.md | 11 +-- .../zh-cn/docs/tasks/tools/included/_index.md | 10 ++- .../included/kubectl-convert-overview.md | 8 +- .../tools/included/kubectl-whats-next.md | 19 +++-- .../optional-kubectl-configs-bash-linux.md | 11 ++- .../included/optional-kubectl-configs-pwsh.md | 14 ++-- .../included/optional-kubectl-configs-zsh.md | 17 ++-- .../docs/tasks/tools/install-kubectl-macos.md | 2 + 9 files changed, 98 insertions(+), 71 deletions(-) diff --git a/content/zh-cn/docs/home/_index.md b/content/zh-cn/docs/home/_index.md index 738ee19bb4e..0a8d131abfa 100644 --- a/content/zh-cn/docs/home/_index.md +++ b/content/zh-cn/docs/home/_index.md @@ -18,11 +18,13 @@ menu: # Kubernetes is an open source container orchestration engine for automating deployment, scaling, and management of containerized applications. The open source project is hosted by the Cloud Native Computing Foundation. description: > Kubernetes 是一个开源的容器编排引擎,用来对容器化应用进行自动部署、 扩缩和管理。此开源项目由云原生计算基金会(CNCF)托管。 + # overview: # Kubernetes is an open source container orchestration engine for automating deployment, scaling, and management of containerized applications. The open source project is hosted by the Cloud Native Computing Foundation (CNCF). overview: Kubernetes 是一个开源的容器编排引擎,用来对容器化应用进行自动化部署、 扩缩和管理。该项目托管在 CNCF。 -# cards: + +cards: # - name: concepts # title: "Understand Kubernetes" # description: "Learn about Kubernetes and its fundamental concepts." @@ -33,6 +35,16 @@ overview: # description: "Follow tutorials to learn how to deploy applications in Kubernetes." # button: "View Tutorials" # button_path: "/docs/tutorials" +- name: concepts + title: "了解 Kubernetes" + description: "了解 Kubernetes 及其基础概念。" + button: "查看概念" + button_path: "/zh-cn/docs/concepts" +- name: tutorials + title: "尝试 Kubernetes" + description: "按照教程学习如何在 Kubernetes 上部署应用。" + button: "查看教程" + button_path: "/zh-cn/docs/tutorials" # - name: setup # title: "Set up a K8s cluster" # description: "Get Kubernetes running based on your resources and needs." @@ -43,6 +55,16 @@ overview: # description: "Look up common tasks and how to perform them using a short sequence of steps." # button: "View Tasks" # button_path: "/docs/tasks" +- name: setup + title: "安裝 K8s 集群" + description: "基于你的资源情况和需要运行 Kubernetes。" + button: "安装 Kubernetes" + button_path: "/zh-cn/docs/setup" +- name: tasks + title: "了解如何使用 Kubernetes" + description: "查看常见任务以及如何使用简单步骤执行它们。" + button: "查看任务" + button_path: "/zh-cn/docs/tasks" # - name: training # title: "Training" # description: "Get certified in Kubernetes and make your cloud native projects successful!" @@ -53,40 +75,6 @@ overview: # description: Browse terminology, command line syntax, API resource types, and setup tool documentation. # button: View Reference # button_path: /docs/reference -# - name: contribute -# title: Contribute to the docs -# description: Anyone can contribute, whether you’re new to the project or you’ve been around a long time. -# button: Contribute to the docs -# button_path: /docs/contribute -# - name: release-notes -# title: K8s Release Notes -# description: If you are installing Kubernetes or upgrading to the newest version, refer to the current release notes. -# button: "Download Kubernetes" -# button_path: "/zh-cn/docs/setup/release/notes" -# - name: about -# title: About the documentation -# description: This website contains documentation for the current and previous 4 versions of Kubernetes. -cards: -- name: concepts - title: "了解 Kubernetes" - description: "了解 Kubernetes 和其基础概念。" - button: "查看概念" - button_path: "/zh-cn/docs/concepts" -- name: tutorials - title: "尝试 Kubernetes" - description: "按照教程学习如何在 Kubernetes 上部署应用。" - button: "查看教程" - button_path: "/zh-cn/docs/tutorials" -- name: setup - title: "设置 K8s 集群" - description: "按照你的资源情况和需求运行 Kubernetes。" - button: "设置 Kubernetes" - button_path: "/zh-cn/docs/setup" -- name: tasks - title: "了解如何使用 Kubernetes" - description: "查看常见任务以及如何使用简单步骤执行它们。" - button: "查看任务" - button_path: "/zh-cn/docs/tasks" - name: training title: "培训" description: "通过 Kubernetes 认证,助你的云原生项目成功!" @@ -97,16 +85,29 @@ cards: description: 浏览术语、命令行语法、API 资源类型和安装工具文档。 button: 查看参考 button_path: /zh-cn/docs/reference +# - name: contribute +# title: Contribute to the docs +# description: Anyone can contribute, whether you’re new to the project or you’ve been around a long time. +# button: Contribute to the docs +# button_path: /docs/contribute +# - name: release-notes +# title: K8s Release Notes +# description: If you are installing Kubernetes or upgrading to the newest version, refer to the current release notes. +# button: "Download Kubernetes" +# button_path: "/zh-cn/docs/setup/release/notes" - name: contribute title: 为文档作贡献 description: 任何人,无论对该项目熟悉与否,都能贡献自己的力量。 button: 为文档作贡献 button_path: /zh-cn/docs/contribute -- name: release-notes - title: K8s 发布说明 - description: 如果你正在安装或升级 Kubernetes,最好参考最新的发布说明。 +- name: Download + title: 下载 Kubernetes + description: 安装 Kubernetes 或将其升级到最新版本。 button: "下载 Kubernetes" button_path: "/releases/download" +# - name: about +# title: About the documentation +# description: This website contains documentation for the current and previous 4 versions of Kubernetes. - name: about title: 关于文档 description: 本网站包含了当前及前 4 个版本的 Kubernetes 文档。 diff --git a/content/zh-cn/docs/tasks/tools/_index.md b/content/zh-cn/docs/tasks/tools/_index.md index b112852e592..5497937cdbf 100644 --- a/content/zh-cn/docs/tasks/tools/_index.md +++ b/content/zh-cn/docs/tasks/tools/_index.md @@ -47,7 +47,7 @@ kubectl 可安装在各种 Linux 平台、 macOS 和 Windows 上。 ## kind -[`kind`](https://kind.sigs.k8s.io/docs/) 让你能够在本地计算机上运行 Kubernetes。 +[`kind`](https://kind.sigs.k8s.io/) 让你能够在本地计算机上运行 Kubernetes。 `kind` 要求你安装并配置好 [Docker](https://docs.docker.com/get-docker/)。 -kind [快速入门](https://kind.sigs.k8s.io/docs/user/quick-start/)页面展示了开始使用 +kind 的 [Quick Start](https://kind.sigs.k8s.io/docs/user/quick-start/) 页面展示开始使用 `kind` 所需要完成的操作。 与 `kind` 类似,[`minikube`](https://minikube.sigs.k8s.io/) 是一个工具, 能让你在本地运行 Kubernetes。 -`minikube` 在你的个人计算机(包括 Windows、macOS 和 Linux PC)上运行一个一体化(all-in-one)或多节点的本地 -Kubernetes 集群,以便你来尝试 Kubernetes 或者开展每天的开发工作。 +`minikube` 在你的个人计算机(包括 Windows、macOS 和 Linux PC)上运行一个一体化(all-in-one) +或多节点的本地 Kubernetes 集群,以便你来尝试 Kubernetes 或者开展每天的开发工作。 如果你关注如何安装此工具,可以按官方的 [Get Started!](https://minikube.sigs.k8s.io/docs/start/)指南操作。 @@ -125,3 +125,4 @@ Once installed, you can use it to [create a cluster](/docs/setup/production-envi 查看 kubeadm 安装指南 + diff --git a/content/zh-cn/docs/tasks/tools/included/_index.md b/content/zh-cn/docs/tasks/tools/included/_index.md index 0b1291134b3..aa3c87ea954 100644 --- a/content/zh-cn/docs/tasks/tools/included/_index.md +++ b/content/zh-cn/docs/tasks/tools/included/_index.md @@ -3,12 +3,18 @@ title: "内含的工具" description: "在页面 kubectl-installs-*.md 中包含的代码片段" headless: true toc_hide: true +_build: + list: never + render: never + publishResources: false --- diff --git a/content/zh-cn/docs/tasks/tools/included/kubectl-convert-overview.md b/content/zh-cn/docs/tasks/tools/included/kubectl-convert-overview.md index 21d65563316..994a33d0e48 100644 --- a/content/zh-cn/docs/tasks/tools/included/kubectl-convert-overview.md +++ b/content/zh-cn/docs/tasks/tools/included/kubectl-convert-overview.md @@ -3,15 +3,17 @@ title: "kubectl-convert 概述" description: >- 一个 kubectl 插件,允许你将清单从一个 Kubernetes API 版本转换到不同的版本。 headless: true +_build: + list: never + render: never + publishResources: false --- 一个 Kubernetes 命令行工具 `kubectl` 的插件,允许你将清单在不同 API 版本间转换。 这对于将清单迁移到新的 Kubernetes 发行版上未被废弃的 API 版本时尤其有帮助。 -更多信息请访问 [迁移到非弃用 API](/zh-cn/docs/reference/using-api/deprecation-guide/#migrate-to-non-deprecated-apis) +更多信息请访问[迁移到非弃用 API](/zh-cn/docs/reference/using-api/deprecation-guide/#migrate-to-non-deprecated-apis) diff --git a/content/zh-cn/docs/tasks/tools/included/kubectl-whats-next.md b/content/zh-cn/docs/tasks/tools/included/kubectl-whats-next.md index 6d8a9a136da..4c5fe195159 100644 --- a/content/zh-cn/docs/tasks/tools/included/kubectl-whats-next.md +++ b/content/zh-cn/docs/tasks/tools/included/kubectl-whats-next.md @@ -2,13 +2,15 @@ title: "后续内容" description: "安装 kubectl 之后,还可以做些什么?" headless: true +_build: + list: never + render: never + publishResources: false --- -* [安装 Minikube](https://minikube.sigs.k8s.io/docs/start/) -* 有关创建集群的更多信息,请参阅[入门指南](/zh-cn/docs/setup/). -* [学习如何启动并对外公开你的应用程序。](/zh-cn/docs/tasks/access-application-cluster/service-access-application-cluster/) -* 如果你需要访问其他人创建的集群,请参阅 - [共享集群接入文档](/zh-cn/docs/tasks/access-application-cluster/configure-access-multiple-clusters/). -* 阅读 [kubectl 参考文档](/zh-cn/docs/reference/kubectl/kubectl/) +* [安装 Minikube](https://minikube.sigs.k8s.io/docs/start/)。 +* 有关创建集群的更多信息,请参阅[入门指南](/zh-cn/docs/setup/)。 +* [学习如何启动并对外公开你的应用程序](/zh-cn/docs/tasks/access-application-cluster/service-access-application-cluster/)。 +* 如果你需要访问其他人创建的集群, + 请参阅[共享集群接入文档](/zh-cn/docs/tasks/access-application-cluster/configure-access-multiple-clusters/)。 +* 阅读 [kubectl 参考文档](/zh-cn/docs/reference/kubectl/kubectl/)。 + diff --git a/content/zh-cn/docs/tasks/tools/included/optional-kubectl-configs-bash-linux.md b/content/zh-cn/docs/tasks/tools/included/optional-kubectl-configs-bash-linux.md index d16a6220bc4..f4d2a55c0d3 100644 --- a/content/zh-cn/docs/tasks/tools/included/optional-kubectl-configs-bash-linux.md +++ b/content/zh-cn/docs/tasks/tools/included/optional-kubectl-configs-bash-linux.md @@ -2,6 +2,11 @@ title: "Linux 系统中的 Bash 自动补全功能" description: "Linux 系统中 Bash 自动补全功能的一些可选配置。" headless: true +_build: + list: never + render: never + publishResources: false + --- 两种方式的效果相同。重新加载 Shell 后,kubectl 自动补全功能即可生效。 -若要在当前 Shell 会话中启用 Bash 补全功能,需要运行 `exec bash` 命令: +若要在当前 Shell 会话中启用 Bash 补全功能,源引 `~/.bashrc` 文件: ```bash -exec bash +source ~/.bashrc ``` diff --git a/content/zh-cn/docs/tasks/tools/included/optional-kubectl-configs-pwsh.md b/content/zh-cn/docs/tasks/tools/included/optional-kubectl-configs-pwsh.md index 9cbf851b4f5..02eaea3db43 100644 --- a/content/zh-cn/docs/tasks/tools/included/optional-kubectl-configs-pwsh.md +++ b/content/zh-cn/docs/tasks/tools/included/optional-kubectl-configs-pwsh.md @@ -2,13 +2,15 @@ title: "PowerShell 自动补全" description: "powershell 自动补全的一些可选配置。" headless: true +_build: + list: never + render: never + publishResources: false --- -使用命令 `kubectl completion powershell` 生成 PowerShell 的 kubectl 自动补全脚本。 +你可以使用命令 `kubectl completion powershell` 生成 PowerShell 的 kubectl 自动补全脚本。 -如果需要自动补全在所有 shell 会话中生效,请将以下命令添加到 `$PROFILE` 文件中: +如果需要自动补全在所有 Shell 会话中生效,请将以下命令添加到 `$PROFILE` 文件中: ```powershell kubectl completion powershell | Out-String | Invoke-Expression @@ -32,7 +34,7 @@ This command will regenerate the auto-completion script on every PowerShell star -如果需要将自动补全脚本直接添加到 `$PROFILE` 文件中,请在 PowerShell 终端运行以下命令: +如果需要将自动补全脚本直接添加到 `$PROFILE` 文件中,请在 PowerShell 命令行运行以下命令: ```powershell kubectl completion powershell >> $PROFILE @@ -41,4 +43,4 @@ kubectl completion powershell >> $PROFILE -完成上述操作后重启 shell,kubectl的自动补全就可以工作了。 +完成上述操作后重启 Shell,kubectl 的自动补全就可以工作了。 diff --git a/content/zh-cn/docs/tasks/tools/included/optional-kubectl-configs-zsh.md b/content/zh-cn/docs/tasks/tools/included/optional-kubectl-configs-zsh.md index 9a40a829aa3..a5e8c00faad 100644 --- a/content/zh-cn/docs/tasks/tools/included/optional-kubectl-configs-zsh.md +++ b/content/zh-cn/docs/tasks/tools/included/optional-kubectl-configs-zsh.md @@ -2,13 +2,15 @@ title: "zsh 自动补全" description: "zsh 自动补全的一些可选配置" headless: true +_build: + list: never + render: never + publishResources: false --- kubectl 通过命令 `kubectl completion zsh` 生成 Zsh 自动补全脚本。 -在 shell 中导入(Sourcing)该自动补全脚本,将启动 kubectl 自动补全功能。 +在 Shell 中导入(Sourcing)该自动补全脚本,将启动 kubectl 自动补全功能。 -为了在所有的 shell 会话中实现此功能,请将下面内容加入到文件 `~/.zshrc` 中。 +为了在所有的 Shell 会话中实现此功能,请将下面内容加入到文件 `~/.zshrc` 中。 ```zsh source <(kubectl completion zsh) @@ -36,10 +38,13 @@ After reloading your shell, kubectl autocompletion should be working. If you get an error like `complete:13: command not found: compdef`, then add the following to the beginning of your `~/.zshrc` file: If you get an error like `2: command not found: compdef`, then add the following to the beginning of your `~/.zshrc` file: --> -重新加载 shell 后,kubectl 自动补全功能将立即生效。 +重新加载 Shell 后,kubectl 自动补全功能将立即生效。 + +如果你收到 `2: command not found: compdef` 这样的错误提示,那请将下面内容添加到 +`~/.zshrc` 文件的开头: -如果你收到 `2: command not found: compdef` 这样的错误提示,那请将下面内容添加到 `~/.zshrc` 文件的开头: ```zsh autoload -Uz compinit compinit ``` + diff --git a/content/zh-cn/docs/tasks/tools/install-kubectl-macos.md b/content/zh-cn/docs/tasks/tools/install-kubectl-macos.md index b02aa806a67..c6be2f34809 100644 --- a/content/zh-cn/docs/tasks/tools/install-kubectl-macos.md +++ b/content/zh-cn/docs/tasks/tools/install-kubectl-macos.md @@ -58,6 +58,7 @@ The following methods exist for installing kubectl on macOS: - [可选的 kubectl 配置和插件](#optional-kubectl-configurations-and-plugins) - [启用 shell 自动补全功能](#enable-shell-autocompletion) - [安装 `kubectl convert` 插件](#install-kubectl-convert-plugin) + @@ -426,3 +427,4 @@ kubectl 为 Bash、Zsh、Fish 和 PowerShell 提供自动补全功能,可以 ## {{% heading "whatsnext" %}} {{< include "included/kubectl-whats-next.md" >}} + From e0810bcaadf752a6c424d1133db81f35c3e31963 Mon Sep 17 00:00:00 2001 From: seancrasto <103709488+seancrasto@users.noreply.github.com> Date: Sun, 12 Feb 2023 19:24:16 -0500 Subject: [PATCH 192/279] Update endpoint-slices.md Changed break to breaking. --- content/en/docs/concepts/services-networking/endpoint-slices.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/docs/concepts/services-networking/endpoint-slices.md b/content/en/docs/concepts/services-networking/endpoint-slices.md index 5e84c43bdd7..5d833000327 100644 --- a/content/en/docs/concepts/services-networking/endpoint-slices.md +++ b/content/en/docs/concepts/services-networking/endpoint-slices.md @@ -104,7 +104,7 @@ the pod is also terminating. {{< note >}} -Although `serving` is almost identical to `ready`, it was added to prevent break the existing meaning +Although `serving` is almost identical to `ready`, it was added to prevent breaking the existing meaning of `ready`. It may be unexpected for existing clients if `ready` could be `true` for terminating endpoints, since historically terminating endpoints were never included in the Endpoints or EndpointSlice API to begin with. For this reason, `ready` is _always_ `false` for terminating From ba227d1a69d48e5905fb345eec6f04969109f0d2 Mon Sep 17 00:00:00 2001 From: my-git9 Date: Mon, 13 Feb 2023 08:35:58 +0800 Subject: [PATCH 193/279] [zh-cn]sync some little change for some docs (#39399) Signed-off-by: xin.li --- .../docs/tasks/access-application-cluster/access-cluster.md | 4 ++-- content/zh-cn/docs/tasks/administer-cluster/certificates.md | 4 ++-- .../tasks/administer-cluster/change-default-storage-class.md | 1 + .../docs/tasks/administer-cluster/change-pv-reclaim-policy.md | 1 + .../docs/tasks/administer-cluster/configure-upgrade-etcd.md | 2 ++ .../docs/tasks/administer-cluster/kubelet-config-file.md | 2 ++ .../tasks/administer-cluster/limit-storage-consumption.md | 2 ++ .../docs/tasks/administer-cluster/namespaces-walkthrough.md | 2 ++ content/zh-cn/docs/tasks/administer-cluster/namespaces.md | 2 ++ .../zh-cn/docs/tasks/administer-cluster/quota-api-object.md | 2 ++ 10 files changed, 18 insertions(+), 4 deletions(-) diff --git a/content/zh-cn/docs/tasks/access-application-cluster/access-cluster.md b/content/zh-cn/docs/tasks/access-application-cluster/access-cluster.md index 1f910735d3a..5c1ff12f73f 100644 --- a/content/zh-cn/docs/tasks/access-application-cluster/access-cluster.md +++ b/content/zh-cn/docs/tasks/access-application-cluster/access-cluster.md @@ -30,7 +30,7 @@ Kubernetes CLI, `kubectl`. To access a cluster, you need to know the location of the cluster and have credentials to access it. Typically, this is automatically set-up when you work through a [Getting started guide](/docs/setup/), -or someone else setup the cluster and provided you with credentials and a location. +or someone else set up the cluster and provided you with credentials and a location. Check the location and credentials that kubectl knows about with this command: --> @@ -463,7 +463,7 @@ There are several different proxies you may encounter when using Kubernetes: - implementation varies by cloud provider. Kubernetes users will typically not need to worry about anything other than the first two types. The cluster admin -will typically ensure that the latter types are setup correctly. +will typically ensure that the latter types are set up correctly. --> 5. 外部服务上的云负载均衡器: diff --git a/content/zh-cn/docs/tasks/administer-cluster/certificates.md b/content/zh-cn/docs/tasks/administer-cluster/certificates.md index db7653e95d1..85350b574d7 100644 --- a/content/zh-cn/docs/tasks/administer-cluster/certificates.md +++ b/content/zh-cn/docs/tasks/administer-cluster/certificates.md @@ -1,12 +1,12 @@ --- title: 手动生成证书 content_type: task -weight: 20 +weight: 30 --- diff --git a/content/zh-cn/docs/tasks/administer-cluster/change-default-storage-class.md b/content/zh-cn/docs/tasks/administer-cluster/change-default-storage-class.md index fea5db84f5f..d9bbe0422d5 100644 --- a/content/zh-cn/docs/tasks/administer-cluster/change-default-storage-class.md +++ b/content/zh-cn/docs/tasks/administer-cluster/change-default-storage-class.md @@ -1,6 +1,7 @@ --- title: 改变默认 StorageClass content_type: task +weight: 90 --- diff --git a/content/zh-cn/docs/tasks/administer-cluster/change-pv-reclaim-policy.md b/content/zh-cn/docs/tasks/administer-cluster/change-pv-reclaim-policy.md index 086cf6bd267..3de2953b67f 100644 --- a/content/zh-cn/docs/tasks/administer-cluster/change-pv-reclaim-policy.md +++ b/content/zh-cn/docs/tasks/administer-cluster/change-pv-reclaim-policy.md @@ -1,6 +1,7 @@ --- title: 更改 PersistentVolume 的回收策略 content_type: task +weight: 100 --- diff --git a/content/zh-cn/docs/tasks/administer-cluster/configure-upgrade-etcd.md b/content/zh-cn/docs/tasks/administer-cluster/configure-upgrade-etcd.md index 2085aa5c9f6..22fd6199bb7 100644 --- a/content/zh-cn/docs/tasks/administer-cluster/configure-upgrade-etcd.md +++ b/content/zh-cn/docs/tasks/administer-cluster/configure-upgrade-etcd.md @@ -1,6 +1,7 @@ --- title: 为 Kubernetes 运行 etcd 集群 content_type: task +weight: 270 --- diff --git a/content/zh-cn/docs/tasks/administer-cluster/kubelet-config-file.md b/content/zh-cn/docs/tasks/administer-cluster/kubelet-config-file.md index a1ea20805c5..2dee80478ce 100644 --- a/content/zh-cn/docs/tasks/administer-cluster/kubelet-config-file.md +++ b/content/zh-cn/docs/tasks/administer-cluster/kubelet-config-file.md @@ -1,6 +1,7 @@ --- title: 通过配置文件设置 Kubelet 参数 content_type: task +weight: 330 --- diff --git a/content/zh-cn/docs/tasks/administer-cluster/limit-storage-consumption.md b/content/zh-cn/docs/tasks/administer-cluster/limit-storage-consumption.md index 1ac684de586..bd629d13ed0 100644 --- a/content/zh-cn/docs/tasks/administer-cluster/limit-storage-consumption.md +++ b/content/zh-cn/docs/tasks/administer-cluster/limit-storage-consumption.md @@ -1,10 +1,12 @@ --- title: 限制存储使用量 content_type: task +weight: 240 --- diff --git a/content/zh-cn/docs/tasks/administer-cluster/namespaces-walkthrough.md b/content/zh-cn/docs/tasks/administer-cluster/namespaces-walkthrough.md index 1e3ee64aedc..df1fdcb85ce 100644 --- a/content/zh-cn/docs/tasks/administer-cluster/namespaces-walkthrough.md +++ b/content/zh-cn/docs/tasks/administer-cluster/namespaces-walkthrough.md @@ -1,6 +1,7 @@ --- title: 名字空间演练 content_type: task +weight: 260 --- diff --git a/content/zh-cn/docs/tasks/administer-cluster/namespaces.md b/content/zh-cn/docs/tasks/administer-cluster/namespaces.md index 92903e5a5dc..4f14fdb1a8e 100644 --- a/content/zh-cn/docs/tasks/administer-cluster/namespaces.md +++ b/content/zh-cn/docs/tasks/administer-cluster/namespaces.md @@ -1,6 +1,7 @@ --- title: 通过名字空间共享集群 content_type: task +weight: 340 --- diff --git a/content/zh-cn/docs/tasks/administer-cluster/quota-api-object.md b/content/zh-cn/docs/tasks/administer-cluster/quota-api-object.md index ac8cabc067d..8ad94a2505f 100644 --- a/content/zh-cn/docs/tasks/administer-cluster/quota-api-object.md +++ b/content/zh-cn/docs/tasks/administer-cluster/quota-api-object.md @@ -1,11 +1,13 @@ --- title: 配置 API 对象配额 content_type: task +weight: 130 --- From 583cf7242fcff060f51ad087970067d27fe429df Mon Sep 17 00:00:00 2001 From: "xin.li" Date: Sun, 12 Feb 2023 11:25:15 +0800 Subject: [PATCH 194/279] [zh-cn]sync some little for tasks Signed-off-by: xin.li --- .../docs/tasks/administer-cluster/reconfigure-kubelet.md | 2 ++ .../tasks/administer-cluster/reserve-compute-resources.md | 6 +++++- .../tasks/administer-cluster/running-cloud-controller.md | 2 ++ .../docs/tasks/administer-cluster/securing-a-cluster.md | 2 ++ .../zh-cn/docs/tasks/administer-cluster/sysctl-cluster.md | 2 ++ .../docs/tasks/administer-cluster/topology-manager.md | 2 ++ .../tasks/administer-cluster/use-cascading-deletion.md | 2 ++ .../tasks/administer-cluster/verify-signed-artifacts.md | 7 +++++++ 8 files changed, 24 insertions(+), 1 deletion(-) diff --git a/content/zh-cn/docs/tasks/administer-cluster/reconfigure-kubelet.md b/content/zh-cn/docs/tasks/administer-cluster/reconfigure-kubelet.md index 63dcd3ebf0b..537cbb7599c 100644 --- a/content/zh-cn/docs/tasks/administer-cluster/reconfigure-kubelet.md +++ b/content/zh-cn/docs/tasks/administer-cluster/reconfigure-kubelet.md @@ -2,6 +2,7 @@ title: 在运行中的集群上重新配置节点的 kubelet content_type: task min-kubernetes-server-version: v1.11 +weight: 280 --- diff --git a/content/zh-cn/docs/tasks/administer-cluster/reserve-compute-resources.md b/content/zh-cn/docs/tasks/administer-cluster/reserve-compute-resources.md index 56b8521c5c3..96d000d644b 100644 --- a/content/zh-cn/docs/tasks/administer-cluster/reserve-compute-resources.md +++ b/content/zh-cn/docs/tasks/administer-cluster/reserve-compute-resources.md @@ -2,6 +2,7 @@ title: 为系统守护进程预留计算资源 content_type: task min-kubernetes-server-version: 1.8 +weight: 290 --- @@ -249,8 +251,10 @@ with `.slice` appended. -**Kubelet 标志**:`--reserved-cpus=0-3` +**Kubelet 标志**: `--reserved-cpus=0-3` +**KubeletConfiguration 标志**:`reservedSystemCpus: 0-3` diff --git a/content/zh-cn/docs/tasks/administer-cluster/securing-a-cluster.md b/content/zh-cn/docs/tasks/administer-cluster/securing-a-cluster.md index 33ff11787b9..93096e06d94 100644 --- a/content/zh-cn/docs/tasks/administer-cluster/securing-a-cluster.md +++ b/content/zh-cn/docs/tasks/administer-cluster/securing-a-cluster.md @@ -1,6 +1,7 @@ --- title: 保护集群 content_type: task +weight: 320 --- diff --git a/content/zh-cn/docs/tasks/administer-cluster/sysctl-cluster.md b/content/zh-cn/docs/tasks/administer-cluster/sysctl-cluster.md index aaf8740dfb4..eb4a609affb 100644 --- a/content/zh-cn/docs/tasks/administer-cluster/sysctl-cluster.md +++ b/content/zh-cn/docs/tasks/administer-cluster/sysctl-cluster.md @@ -1,6 +1,7 @@ --- title: 在 Kubernetes 集群中使用 sysctl content_type: task +weight: 400 --- diff --git a/content/zh-cn/docs/tasks/administer-cluster/topology-manager.md b/content/zh-cn/docs/tasks/administer-cluster/topology-manager.md index d071207d0c7..5172c638a84 100644 --- a/content/zh-cn/docs/tasks/administer-cluster/topology-manager.md +++ b/content/zh-cn/docs/tasks/administer-cluster/topology-manager.md @@ -2,6 +2,7 @@ title: 控制节点上的拓扑管理策略 content_type: task min-kubernetes-server-version: v1.18 +weight: 150 --- diff --git a/content/zh-cn/docs/tasks/administer-cluster/use-cascading-deletion.md b/content/zh-cn/docs/tasks/administer-cluster/use-cascading-deletion.md index 5eb09bd2044..5f1991f1f37 100644 --- a/content/zh-cn/docs/tasks/administer-cluster/use-cascading-deletion.md +++ b/content/zh-cn/docs/tasks/administer-cluster/use-cascading-deletion.md @@ -1,11 +1,13 @@ --- title: 在集群中使用级联删除 content_type: task +weight: 360 --- diff --git a/content/zh-cn/docs/tasks/administer-cluster/verify-signed-artifacts.md b/content/zh-cn/docs/tasks/administer-cluster/verify-signed-artifacts.md index 60cb836ef2c..986e3e964d2 100644 --- a/content/zh-cn/docs/tasks/administer-cluster/verify-signed-artifacts.md +++ b/content/zh-cn/docs/tasks/administer-cluster/verify-signed-artifacts.md @@ -2,11 +2,13 @@ title: 验证已签名容器镜像 content_type: task min-kubernetes-server-version: v1.24 +weight: 420 --- @@ -63,6 +65,9 @@ done 然后使用 `cosign` 验证二进制文件: @@ -70,6 +75,8 @@ Then verify the blob by using `cosign`: cosign verify-blob "$BINARY" --signature "$BINARY".sig --certificate "$BINARY".cert ``` +cosign 自 v1.9.0 版本开始才能使用 `--certificate` 标志,旧版本的 cosign 请使用 `--cert`。 + {{< note >}} ## 使用临时容器来调试的例子 {#ephemeral-container-example} @@ -548,12 +540,15 @@ images. 首先,像示例一样创建一个 pod: ```shell -kubectl run ephemeral-demo --image=k8s.gcr.io/pause:3.1 --restart=Never +kubectl run ephemeral-demo --image=registry.k8s.io/pause:3.1 --restart=Never ``` -{{< note >}} + 本节示例中使用 `pause` 容器镜像,因为它不包含调试程序,但是这个方法适用于所有容器镜像。 -{{< /note >}} **作者:** Mayank Kumar (Salesforce) +**译者:** Xiaoyang Zhang(Huawei) + @@ -82,7 +84,8 @@ spec: app: nginx spec: containers: - - image: k8s.gcr.io/nginx-slim:0.8 + # 镜像自发布以来已更改(以前使用的仓库为 "k8s.gcr.io") + - image: registry.k8s.io/nginx-slim:0.8 imagePullPolicy: IfNotPresent name: nginx updateStrategy: @@ -107,15 +110,15 @@ has 5 replicas, with `maxUnavailable` set to 2 and `partition` set to 0. `maxUnavailable` 设置为 2 并将 `partition` 设置为 0。 -我可以通过将镜像更改为 `k8s.gcr.io/nginx-slim:0.9` 来触发滚动更新。一旦开始滚动更新, +我可以通过将镜像更改为 `registry.k8s.io/nginx-slim:0.9` 来触发滚动更新。一旦开始滚动更新, 就可以看到一次更新 2 个 Pod,因为 `maxUnavailable` 的当前值是 2。 下面的输出显示了一个时间段内的结果,但并不是完整过程。`maxUnavailable` 可以是绝对数值(例如 2)或所需 Pod -的百分比(例如 10%),绝对数是通过百分比计算结果进行四舍五入得出的。 +的百分比(例如 10%),绝对数是通过百分比计算结果进行四舍五入到最接近的整数得出的。 ``` kubectl get pods --watch From 906f70bd3239e932c4791e86932748b46eca0458 Mon Sep 17 00:00:00 2001 From: Mengjiao Liu Date: Mon, 13 Feb 2023 15:53:32 +0800 Subject: [PATCH 198/279] [zh-cn] Resync 2022-05-13-grpc-probes-in-beta.md --- .../_posts/2022-05-13-grpc-probes-in-beta.md | 33 ++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/content/zh-cn/blog/_posts/2022-05-13-grpc-probes-in-beta.md b/content/zh-cn/blog/_posts/2022-05-13-grpc-probes-in-beta.md index 657f768e312..505e028d394 100644 --- a/content/zh-cn/blog/_posts/2022-05-13-grpc-probes-in-beta.md +++ b/content/zh-cn/blog/_posts/2022-05-13-grpc-probes-in-beta.md @@ -16,10 +16,12 @@ slug: grpc-probes-now-in-beta --> **作者**:Sergey Kanzhelev (Google) +**译者**:Xiaoyang Zhang(Huawei) + 在 Kubernetes 1.24 中,gRPC 探针(probe)功能进入了 beta 阶段,默认情况下可用。 现在,你可以为 gRPC 应用程序配置启动、活跃和就绪探测,而无需公开任何 HTTP 端点, @@ -63,7 +65,7 @@ the first release at [Sep 19, 2018](https://github.com/grpc-ecosystem/grpc-healt 这种 gRPC 应用健康检查的方法非常受欢迎。使用 GitHub 上的基本搜索,发现了带有 `grpc_health_probe` @@ -203,7 +205,7 @@ exposes ports `5000` and `8080`, and configures gRPC readiness probe: --> 下面是一个 Pod 定义示例。它启用 `grpc-health-checking` 模块,暴露 5000 和 8080 端口,并配置 gRPC 就绪探针: -``` yaml +```yaml --- apiVersion: v1 kind: Pod @@ -211,22 +213,23 @@ metadata: name: test-grpc spec: containers: - - name: agnhost - image: k8s.gcr.io/e2e-test-images/agnhost:2.35 - command: ["/agnhost", "grpc-health-checking"] - ports: - - containerPort: 5000 - - containerPort: 8080 - readinessProbe: - grpc: - port: 5000 + - name: agnhost + # 镜像自发布以来已更改(以前使用的仓库为 "k8s.gcr.io") + image: registry.k8s.io/e2e-test-images/agnhost:2.35 + command: ["/agnhost", "grpc-health-checking"] + ports: + - containerPort: 5000 + - containerPort: 8080 + readinessProbe: + grpc: + port: 5000 ``` -如果文件名为 `test.yaml`,你可以用以下命令创建 Pod,并检查它的状态。如输出片段所示,Pod 将处于就绪状态。 +如果清单文件名为 `test.yaml`,你可以用以下命令创建 Pod,并检查它的状态。如输出片段所示,Pod 将处于就绪状态。 ```shell kubectl apply -f test.yaml @@ -298,7 +301,7 @@ Once it is switched back, in about one second the Pod will get back to ready sta --> 一旦切换回来,Pod 将在大约一秒钟后恢复到就绪状态: -``` bsh +```bash curl http://localhost:8080/make-serving kubectl describe test-grpc ``` From e4fea38b16c874e21d3c4f32a98df089911e5b9a Mon Sep 17 00:00:00 2001 From: Kundan Kumar Date: Mon, 13 Feb 2023 20:02:04 +0530 Subject: [PATCH 199/279] Updated link for kubernetes cluster federation --- .../blog/_posts/2018-12-11-Kubernetes-Federation-Evolution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/blog/_posts/2018-12-11-Kubernetes-Federation-Evolution.md b/content/en/blog/_posts/2018-12-11-Kubernetes-Federation-Evolution.md index 81c1326dade..235b3577d98 100644 --- a/content/en/blog/_posts/2018-12-11-Kubernetes-Federation-Evolution.md +++ b/content/en/blog/_posts/2018-12-11-Kubernetes-Federation-Evolution.md @@ -8,7 +8,7 @@ date: 2018-12-12 Kubernetes provides great primitives for deploying applications to a cluster: it can be as simple as `kubectl create -f app.yaml`. Deploy apps across multiple clusters has never been that simple. How should app workloads be distributed? Should the app resources be replicated into all clusters, replicated into selected clusters, or partitioned into clusters? How is access to the clusters managed? What happens if some of the resources that a user wants to distribute pre-exist, in some or all of the clusters, in some form? -In SIG Multicluster, our journey has revealed that there are multiple possible models to solve these problems and there probably is no single best-fit, all-scenario solution. [Federation](/docs/concepts/cluster-administration/federation/), however, is the single biggest Kubernetes open source sub-project, and has seen the maximum interest and contribution from the community in this problem space. The project initially reused the Kubernetes API to do away with any added usage complexity for an existing Kubernetes user. This approach was not viable, because of the problems summarised below: +In SIG Multicluster, our journey has revealed that there are multiple possible models to solve these problems and there probably is no single best-fit, all-scenario solution. [Kubernetes Cluster Federation (KubeFed for short)](https://github.com/kubernetes-sigs/kubefed), however, is the single biggest Kubernetes open source sub-project, and has seen the maximum interest and contribution from the community in this problem space. The project initially reused the Kubernetes API to do away with any added usage complexity for an existing Kubernetes user. This approach was not viable, because of the problems summarised below: * Difficulties in re-implementing the Kubernetes API at the cluster level, as federation-specific extensions were stored in annotations. * Limited flexibility in federated types, placement and reconciliation, due to 1:1 emulation of the Kubernetes API. From 7cb6d1eb35e56bd96eb7113c22fcc7c5f20dccf0 Mon Sep 17 00:00:00 2001 From: Shannon Kularathna Date: Mon, 5 Dec 2022 21:13:30 +0000 Subject: [PATCH 200/279] Add a new concept page for service accounts Also add a glossary definition for JWTs Co-authored-by: Tim Bannister Co-authored-by: Jordan Liggitt Co-authored-by: stlaz --- .../concepts/security/service-accounts.md | 256 ++++++++++++++++++ content/en/docs/reference/glossary/jwt.md | 20 ++ 2 files changed, 276 insertions(+) create mode 100644 content/en/docs/concepts/security/service-accounts.md create mode 100644 content/en/docs/reference/glossary/jwt.md diff --git a/content/en/docs/concepts/security/service-accounts.md b/content/en/docs/concepts/security/service-accounts.md new file mode 100644 index 00000000000..5a5d973bac7 --- /dev/null +++ b/content/en/docs/concepts/security/service-accounts.md @@ -0,0 +1,256 @@ +--- +title: Service Accounts +description: > + Learn about the Kubernetes ServiceAccount object. +content_type: concept +weight: 10 +--- + + + +This page introduces the ServiceAccount object in Kubernetes, providing +information about how service accounts work, use cases, limitations, +alternatives, and links to resources for additional guidance. + + + +## What are service accounts? {#what-are-service-accounts} + +A service account is a type of non-human account that, in Kubernetes, provides +a distinct identity in a Kubernetes cluster. Application Pods, system +components, and entities inside and outside the cluster can use a specific +ServiceAccount's credentials to identify as that ServiceAccount. This identity +is useful in various situations, including authenticating to the API server or +implementing identity-based security policies. + +Service accounts exist as ServiceAccount objects in the API server. Service +accounts have the following properties: + +* **Namespaced:** Each service account is bound to a Kubernetes + {{}}. Every namespace + gets a [`default` ServiceAccount](#default-service-accounts) upon creation. + +* **Lightweight:** Service accounts exist in the cluster and are + defined in the Kubernetes API. You can quickly create service accounts to + enable specific tasks. + +* **Portable:** A configuration bundle for a complex containerized workload + might include service account definitions for the system's components. The + lightweight nature of service accounts and the namespaced identities make + the configurations portable. + +Service accounts are different from user accounts, which are authenticated +human users in the cluster. By default, user accounts don't exist in the Kubernetes API server; instead, the API server treats user identities as opaque +data. You can authenticate as a user account using multiple methods. Some +Kubernetes distributions might add custom extension APIs to represent user +accounts in the API server. + +{{< table caption="Comparison between service accounts and users" >}} + +| Description | ServiceAccount | User or group | +| --- | --- | --- | +| Location | Kubernetes API (ServiceAccount object) | External | +| Access control | Kubernetes RBAC or other [authorization mechanisms](/docs/reference/access-authn-authz/authorization/#authorization-modules) | Kubernetes RBAC or other identity and access management mechanisms | +| Intended use | Workloads, automation | People | + +{{< /table >}} + +### Default service accounts {#default-service-accounts} + +When you create a cluster, Kubernetes automatically creates a ServiceAccount +object named `default` for every namespace in your cluster. The `default` +service accounts in each namespace get no permissions by default other than the +[default API discovery permissions](/docs/reference/access-authn-authz/rbac/#default-roles-and-role-bindings) +that Kubernetes grants to all authenticated principals if role-based access control (RBAC) is enabled. If you delete the +`default` ServiceAccount object in a namespace, the +{{}} +replaces it with a new one. + +If you deploy a Pod in a namespace, and you don't +[manually assign a ServiceAccount to the Pod](#assign-to-pod), Kubernetes +assigns the `default` ServiceAccount for that namespace to the Pod. + +## Use cases for Kubernetes service accounts {#use-cases} + +As a general guideline, you can use service accounts to provide identities in +the following scenarios: + +* Your Pods need to communicate with the Kubernetes API server, for example in + situations such as the following: + * Providing read-only access to sensitive information stored in Secrets. + * Granting [cross-namespace access](#cross-namespace), such as allowing a + Pod in namespace `example` to read, list, and watch for Lease objects in + the `kube-node-lease` namespace. +* Your Pods need to communicate with an external service. For example, a + workload Pod requires an identity for a commercially available cloud API, + and the commercial provider allows configuring a suitable trust relationship. +* [Authenticating to a private image registry using an `imagePullSecret`](/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account). +* An external service needs to communicate with the Kubernetes API server. For + example, authenticating to the cluster as part of a CI/CD pipeline. +* You use third-party security software in your cluster that relies on the + ServiceAccount identity of different Pods to group those Pods into different + contexts. + + +## How to use service accounts {#how-to-use} + +To use a Kubernetes service account, you do the following: + +1. Create a ServiceAccount object using a Kubernetes + client like `kubectl` or a manifest that defines the object. +1. Grant permissions to the ServiceAccount object using an authorization + mechanism such as + [RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/). +1. Assign the ServiceAccount object to Pods during Pod creation. + + If you're using the identity from an external service, + [retrieve the ServiceAccount token](#get-a-token) and use it from that + service instead. + +For instructions, refer to +[Configure Service Accounts for Pods](/docs/tasks/configure-pod-container/configure-service-account/). + +### Grant permissions to a ServiceAccount {#grant-permissions} + +You can use the built-in Kubernetes +[role-based access control (RBAC)](/docs/reference/access-authn-authz/rbac/) +mechanism to grant the minimum permissions required by each service account. +You create a *role*, which grants access, and then *bind* the role to your +ServiceAccount. RBAC lets you define a minimum set of permissions so that the +service account permissions follow the principle of least privilege. Pods that +use that service account don't get more permissions than are required to +function correctly. + +For instructions, refer to +[ServiceAccount permissions](/docs/reference/access-authn-authz/rbac/#service-account-permissions). + +#### Cross-namespace access using a ServiceAccount {#cross-namespace} + +You can use RBAC to allow service accounts in one namespace to perform actions +on resources in a different namespace in the cluster. For example, consider a +scenario where you have a service account and Pod in the `dev` namespace and +you want your Pod to see Jobs running in the `maintenance` namespace. You could +create a Role object that grants permissions to list Job objects. Then, +you'd create a RoleBinding object in the `maintenance` namespace to bind the +Role to the ServiceAccount object. Now, Pods in the `dev` namespace can list +Job objects in the `maintenance` namespace using that service account. + +### Assign a ServiceAccount to a Pod {#assign-to-pod} + +To assign a ServiceAccount to a Pod, you set the `spec.serviceAccountName` +field in the Pod specification. Kubernetes then automatically provides the +credentials for that ServiceAccount to the Pod. In v1.22 and later, Kubernetes +gets a short-lived, **automatically rotating** token using the `TokenRequest` +API and mounts the token as a +[projected volume](/docs/concepts/storage/projected-volumes/#serviceaccounttoken). + +By default, Kubernetes provides the Pod +with the credentials for an assigned ServiceAccount, whether that is the +`default` ServiceAccount or a custom ServiceAccount that you specify. + +To prevent Kubernetes from automatically injecting +credentials for a specified ServiceAccount or the `default` ServiceAccount, set the +`automountServiceAccountToken` field in your Pod specification to `false`. + + + +In versions earlier than 1.22, Kubernetes provides a long-lived, static token +to the Pod as a Secret. + +#### Manually retrieve ServiceAccount credentials {#get-a-token} + +If you need the credentials for a ServiceAccount to mount in a non-standard +location, or for an audience that isn't the API server, use one of the +following methods: + +* [TokenRequest API](/docs/reference/kubernetes-api/authentication-resources/token-request-v1/) + (recommended): Request a short-lived service account token using your + *application code*. The token expires automatically and can rotate upon + expiration. +* [Token Volume Projection](/docs/tasks/configure-pod-container/configure-service-account/#service-account-token-volume-projection) + (recommended): In Kubernetes v1.20 and later, use the Pod specification to + tell the kubelet to add the service account token to the Pod as a + *projected volume*. Projected tokens expire automatically, and the kubelet + rotates the token before it expires. +* [Service Account Token Secrets](/docs/tasks/configure-pod-container/configure-service-account/#manually-create-a-service-account-api-token) + (not recommended): You can mount service account tokens as Kubernetes + Secrets in Pods. These tokens don't expire and don't rotate. This method + is not recommended, especially at scale, because of the risks associated + with static, long-lived credentials. In Kubernetes v1.24 and later, the + [LegacyServiceAccountTokenNoAutoGeneration feature gate](/docs/reference/command-line-tools-reference/feature-gates/#feature-gates-for-graduated-or-deprecated-features) + prevents Kubernetes from automatically creating these tokens for + ServiceAccounts. + +## Authenticating service account credentials {#authenticating-credentials} + +ServiceAccounts use signed +{{}} (JWTs) +to authenticate to the Kubernetes API server, and to any other system where a +trust relationship exists. Depending on how the token was issued +(either time-limited using a `TokenRequest` or using a legacy mechanism with +a Secret), a ServiceAccount token might also have an expiry time, an audience, +and a time after which the token *starts* being valid. When a process running +in a Pod attempts to communicate with the Kubernetes API server, it adds an +`Authorization: Bearer ` header to the HTTP request. The API server +checks the validity of the bearer token as follows: + +1. Check the token signature. +1. Check whether the token has expired. +1. Checks whether object references in the token claims are currently valid +1. Check whether the token is currently valid. +1. Check the audience claims. + +For tokens issued using the `TokenRequest` API, the API server also checks that +the specific object reference that is using the ServiceAccount still exists, +matching by the {{< glossary_tooltip term_id="uid" text="unique ID" >}} of that +object. For legacy tokens that are mounted as Secrets in Pods, the API server +checks the token against the Secret. + +For more information about the authentication process, refer to +[Authentication](/docs/reference/access-authn-authz/authentication/#service-account-tokens). + +### Authenticating service account credentials in your own code {authenticating-in-code} + +If you have services of your own that need to validate Kubernetes service +account credentials, you can use the following methods: + +* [TokenReview API](/docs/reference/kubernetes-api/authentication-resources/token-review-v1/) + (recommended) +* OIDC discovery + +The Kubernetes project recommends that you use the TokenReview API, because +this method invalidates tokens that are bound to API objects such as Secrets, +ServiceAccounts, and Pods when those objects are deleted. For example, if you +delete the Pod that contains a projected ServiceAccount token, the TokenReview +API invalidates that token immediately. If you use OIDC validation instead, your clients continue to treat the token as valid until the token reaches its +expiration timestamp. + +Your application should always define the audience that it accepts, and should +check that the token's audiences match the audiences that the application +expects. This helps to minimize the scope of the token so that it can only be +used in your appplication and nowhere else. + +## Alternatives + +* Issue your own tokens using another mechanism, and then use + [Webhook Token Authentication](/docs/reference/access-authn-authz/authentication/#webhook-token-authentication) + to validate bearer tokens using your own validation service. +* Provide your own identities to Pods. + * [Use the SPIFFE CSI driver plugin to provide SPIFFE SVIDs as X.509 certificate pairs to Pods](https://cert-manager.io/docs/projects/csi-driver-spiffe/). + {{% thirdparty-content single="true" %}} + * [Use a service mesh such as Istio to provide certificates to Pods](https://istio.io/latest/docs/tasks/security/cert-management/plugin-ca-cert/). +* Authenticate from outside the cluster to the API server without using service account tokens: + * [Configure the API server to accept OpenID Connect (OIDC) tokens from your identity provider](/docs/reference/access-authn-authz/authentication/#openid-connect-tokens). + * Use service accounts or user accounts created using an external Identity + and Access Management (IAM) service, such as from a cloud provider, to + authenticate to your cluster. + * [Use the CertificateSigningRequest API with client certificates](/docs/tasks/tls/managing-tls-in-a-cluster/). +* [Configure the kubelet to retrieve credentials from an image registry](/docs/tasks/administer-cluster/kubelet-credential-provider/). +* Use a Device Plugin to access a virtual Trusted Platform Module (TPM), which + then allows authentication using a private key. + +## {{% heading "whatsnext" %}} + +* Learn how to [manage your ServiceAccounts as a cluster administrator](/docs/reference/access-authn-authz/service-accounts-admin/). +* Learn how to [assign a ServiceAccount to a Pod](/docs/tasks/configure-pod-container/configure-service-account/). +* Read the [ServiceAccount API reference](/docs/reference/kubernetes-api/authentication-resources/service-account-v1/). \ No newline at end of file diff --git a/content/en/docs/reference/glossary/jwt.md b/content/en/docs/reference/glossary/jwt.md new file mode 100644 index 00000000000..906c941dd3c --- /dev/null +++ b/content/en/docs/reference/glossary/jwt.md @@ -0,0 +1,20 @@ +--- +title: JSON Web Token (JWT) +id: jwt +date: 2023-01-17 +full_link: https://www.rfc-editor.org/rfc/rfc7519 +short_description: > + A means of representing claims to be transferred between two parties. + +aka: +tags: +- security +- architecture +--- + A means of representing claims to be transferred between two parties. + + + +JWTs can be digitally signed and encrypted. Kubernetes uses JWTs as +authentication tokens to verify the identity of entities that want to perform +actions in a cluster. From 9eb2767333c36cf3e9d66e7f25797b319c300135 Mon Sep 17 00:00:00 2001 From: Shannon Kularathna Date: Mon, 13 Feb 2023 12:49:20 -0500 Subject: [PATCH 201/279] Add a missing anchor pound sign --- content/en/docs/concepts/security/service-accounts.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/en/docs/concepts/security/service-accounts.md b/content/en/docs/concepts/security/service-accounts.md index 5a5d973bac7..5eb70ed654e 100644 --- a/content/en/docs/concepts/security/service-accounts.md +++ b/content/en/docs/concepts/security/service-accounts.md @@ -209,7 +209,7 @@ checks the token against the Secret. For more information about the authentication process, refer to [Authentication](/docs/reference/access-authn-authz/authentication/#service-account-tokens). -### Authenticating service account credentials in your own code {authenticating-in-code} +### Authenticating service account credentials in your own code {#authenticating-in-code} If you have services of your own that need to validate Kubernetes service account credentials, you can use the following methods: @@ -253,4 +253,4 @@ used in your appplication and nowhere else. * Learn how to [manage your ServiceAccounts as a cluster administrator](/docs/reference/access-authn-authz/service-accounts-admin/). * Learn how to [assign a ServiceAccount to a Pod](/docs/tasks/configure-pod-container/configure-service-account/). -* Read the [ServiceAccount API reference](/docs/reference/kubernetes-api/authentication-resources/service-account-v1/). \ No newline at end of file +* Read the [ServiceAccount API reference](/docs/reference/kubernetes-api/authentication-resources/service-account-v1/). From 778cfdc75aec0f98a3b1904bd279b0260e21f5c3 Mon Sep 17 00:00:00 2001 From: Arhell Date: Tue, 14 Feb 2023 00:15:11 +0200 Subject: [PATCH 202/279] [pt] Update ConfigMap data extraction to use jsonpath instead of grep/sed --- .../pt-br/docs/reference/setup-tools/kubeadm/kubeadm-join.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/pt-br/docs/reference/setup-tools/kubeadm/kubeadm-join.md b/content/pt-br/docs/reference/setup-tools/kubeadm/kubeadm-join.md index 7ecbda061d5..b1cf6935388 100644 --- a/content/pt-br/docs/reference/setup-tools/kubeadm/kubeadm-join.md +++ b/content/pt-br/docs/reference/setup-tools/kubeadm/kubeadm-join.md @@ -283,7 +283,7 @@ acesso: * Obtenha o arquivo `cluster-info` do servidor da API: ```shell -kubectl -n kube-public get cm cluster-info -o yaml | grep "kubeconfig:" -A11 | grep "apiVersion" -A10 | sed "s/ //" | tee cluster-info.yaml +kubectl -n kube-public get cm cluster-info -o jsonpath='{.data.kubeconfig}' | tee cluster-info.yaml ``` A saída é semelhante a: From 714ac3a67b8cf24ba190898041182a660ea51fd1 Mon Sep 17 00:00:00 2001 From: grainrigi Date: Sun, 5 Feb 2023 20:11:01 +0900 Subject: [PATCH 203/279] [ja] Update container-runtimes.md and related links --- .../ja/docs/concepts/architecture/cgroups.md | 4 +- .../docs/concepts/containers/runtime-class.md | 2 +- .../container-runtimes.md | 640 +++++++----------- .../kubeadm/configure-cgroup-driver.md | 6 +- .../find-out-runtime-you-use.md | 4 +- 5 files changed, 253 insertions(+), 403 deletions(-) diff --git a/content/ja/docs/concepts/architecture/cgroups.md b/content/ja/docs/concepts/architecture/cgroups.md index 8a9f14d7c33..0243916d96c 100644 --- a/content/ja/docs/concepts/architecture/cgroups.md +++ b/content/ja/docs/concepts/architecture/cgroups.md @@ -49,7 +49,7 @@ cgroup v2を使うには以下のような必要要件があります。 * コンテナランタイムがcgroup v2をサポートしていること。例えば、 * [containerd](https://containerd.io/) v1.4以降 * [cri-o](https://cri-o.io/) v1.20以降 -* kubeletとコンテナランタイムが[systemd cgroupドライバー](/docs/setup/production-environment/container-runtimes#systemd-cgroup-driver)を使うように設定されていること +* kubeletとコンテナランタイムが[systemd cgroupドライバー](/ja/docs/setup/production-environment/container-runtimes#systemd-cgroup-driver)を使うように設定されていること ### Linuxディストリビューションのcgroup v2サポート @@ -103,4 +103,4 @@ cgroup v1では、`tmpfs`と出力されます。 - [cgroups](https://man7.org/linux/man-pages/man7/cgroups.7.html)についてもっと学習しましょう。 - [コンテナランタイム](/ja/docs/concepts/architecture/cri)についてもっと学習しましょう。 -- [cgroupドライバー](/docs/setup/production-environment/container-runtimes#cgroup-drivers)についてもっと学習しましょう。 +- [cgroupドライバー](/ja/docs/setup/production-environment/container-runtimes#cgroup-drivers)についてもっと学習しましょう。 diff --git a/content/ja/docs/concepts/containers/runtime-class.md b/content/ja/docs/concepts/containers/runtime-class.md index ce2f40390df..2c663bf7c13 100644 --- a/content/ja/docs/concepts/containers/runtime-class.md +++ b/content/ja/docs/concepts/containers/runtime-class.md @@ -88,7 +88,7 @@ spec: ### CRIの設定 {#cri-configuration} -CRIランタイムのセットアップに関するさらなる詳細は、[CRIのインストール](/docs/setup/cri/)を参照してください。 +CRIランタイムのセットアップに関するさらなる詳細は、[コンテナランタイム](/ja/docs/setup/production-environment/container-runtimes/)を参照してください。 #### {{< glossary_tooltip term_id="containerd" >}} diff --git a/content/ja/docs/setup/production-environment/container-runtimes.md b/content/ja/docs/setup/production-environment/container-runtimes.md index 0f48e26f64b..171b2994bbc 100644 --- a/content/ja/docs/setup/production-environment/container-runtimes.md +++ b/content/ja/docs/setup/production-environment/container-runtimes.md @@ -1,439 +1,289 @@ --- -title: CRIのインストール +title: コンテナランタイム content_type: concept -weight: 10 +weight: 20 --- -{{< feature-state for_k8s_version="v1.6" state="stable" >}} -Podのコンテナを実行するために、Kubernetesはコンテナランタイムを使用します。 -様々なランタイムのインストール手順は次のとおりです。 +{{% dockershim-removal %}} +クラスター内の各ノードがPodを実行できるようにするため、{{< glossary_tooltip text="コンテナランタイム" term_id="container-runtime" >}}をインストールする必要があります。 +このページでは、ノードをセットアップするための概要と関連する作業について説明します。 + +Kubernetes {{< skew currentVersion >}}においては、{{< glossary_tooltip term_id="cri" text="Container Runtime Interface">}} (CRI)に準拠したランタイムを使用する必要があります。 + +詳しくは[サポートするCRIのバージョン](#cri-versions)をご覧ください。 + +このページではいくつかの一般的なコンテナランタイムをKubernetesで使用する方法の概要を説明します。 + +- [containerd](#containerd) +- [CRI-O](#cri-o) +- [Docker Engine](#docker) +- [Mirantis Container Runtime](#mcr) + +{{< note >}} +v1.24以前のKubernetesリリースでは、 _dockershim_ という名前のコンポーネントを使用したDocker Engineとの直接の統合が含まれていました。 +この特別な直接統合は、もはやKubernetesの一部ではありません(この削除はv1.20リリースの一部として[発表](/blog/2020/12/08/kubernetes-1-20-release-announcement/#dockershim-deprecation)されています)。 +dockershimの廃止がどのような影響を与えるかについては、[dockershim削除の影響範囲を確認する](/ja/docs/tasks/administer-cluster/migrating-from-dockershim/check-if-dockershim-removal-affects-you/) をご覧ください。 +dockershimからの移行について知りたい場合、[dockershimからの移行](/ja/docs/tasks/administer-cluster/migrating-from-dockershim/)を参照してください。 + +v{{< skew currentVersion >}}以外のバージョンのKubernetesを実行している場合、そのバージョンのドキュメントを確認してください。 +{{< /note >}} +## インストールと設定の必須要件 -{{< caution >}} -コンテナ実行時にruncがシステムファイルディスクリプターを扱える脆弱性が見つかりました。 -悪意のあるコンテナがこの脆弱性を利用してruncのバイナリを上書きし、 -コンテナホストシステム上で任意のコマンドを実行する可能性があります。 +以下の手順では、全コンテナランタイムに共通の設定をLinux上のKubernetesノードに適用します。 -この問題の更なる情報は[CVE-2019-5736](https://access.redhat.com/security/cve/cve-2019-5736)を参照してください。 -{{< /caution >}} +特定の設定が不要であることが分かっている場合、手順をスキップして頂いて構いません。 -### 適用性 +詳細については、[Network Plugin Requirements](/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/#network-plugin-requirements)または、特定のコンテナランタイムのドキュメントを参照してください。 -{{< note >}} -このドキュメントはLinuxにCRIをインストールするユーザーのために書かれています。 -他のオペレーティングシステムの場合、プラットフォーム固有のドキュメントを見つけてください。 -{{< /note >}} +### IPv4フォワーディングを有効化し、iptablesからブリッジされたトラフィックを見えるようにする -このガイドでは全てのコマンドを `root` で実行します。 -例として、コマンドに `sudo` を付けたり、 `root` になってそのユーザーでコマンドを実行します。 +以下のコマンドを実行します。 -### Cgroupドライバー - -systemdがLinuxのディストリビューションのinitシステムとして選択されている場合、 -initプロセスが作成され、rootコントロールグループ(`cgroup`)を使い、cgroupマネージャーとして行動します。 -systemdはcgroupと密接に統合されており、プロセスごとにcgroupを割り当てます。 -`cgroupfs` を使うように、あなたのコンテナランライムとkubeletを設定することができます。 -systemdと一緒に `cgroupfs` を使用するということは、2つの異なるcgroupマネージャーがあることを意味します。 - -コントロールグループはプロセスに割り当てられるリソースを制御するために使用されます。 -単一のcgroupマネージャーは、割り当てられているリソースのビューを単純化し、 -デフォルトでは使用可能なリソースと使用中のリソースについてより一貫性のあるビューになります。 -2つのマネージャーがある場合、それらのリソースについて2つのビューが得られます。 -kubeletとDockerに `cgroupfs` を使用し、ノード上で実行されている残りのプロセスに `systemd` を使用するように設定されたノードが、 -リソース圧迫下で不安定になる場合があります。 - -コンテナランタイムとkubeletがcgroupドライバーとしてsystemdを使用するように設定を変更することでシステムは安定します。 -以下のDocker設定の `native.cgroupdriver=systemd` オプションに注意してください。 - -{{< caution >}} -すでにクラスターに組み込まれているノードのcgroupドライバーを変更することは非常におすすめしません。 -kubeletが一方のcgroupドライバーを使用してPodを作成した場合、コンテナランタイムを別のもう一方のcgroupドライバーに変更すると、そのような既存のPodのPodサンドボックスを再作成しようとするとエラーが発生する可能性があります。 -kubeletを再起動しても問題は解決しないでしょう。 -ワークロードからノードを縮退させ、クラスターから削除して再び組み込むことを推奨します。 -{{< /caution >}} - -## Docker - -それぞれのマシンに対してDockerをインストールします。 -バージョン19.03.11が推奨されていますが、1.13.1、17.03、17.06、17.09、18.06、18.09についても動作が確認されています。 -Kubernetesのリリースノートにある、Dockerの動作確認済み最新バージョンについてもご確認ください。 - -システムへDockerをインストールするには、次のコマンドを実行します。 - -{{< tabs name="tab-cri-docker-installation" >}} -{{% tab name="Ubuntu 16.04+" %}} - -```shell -# (Install Docker CE) -## リポジトリをセットアップ -### HTTPS越しのリポジトリの使用をaptに許可するために、パッケージをインストール -apt-get update && apt-get install -y \ - apt-transport-https ca-certificates curl software-properties-common gnupg2 -``` - -```shell -# Docker公式のGPG鍵を追加: -curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - -``` - -```shell -# Dockerのaptレポジトリを追加: -add-apt-repository \ - "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ - $(lsb_release -cs) \ - stable" -``` - -```shell -# Docker CEのインストール -apt-get update && apt-get install -y \ -containerd.io=1.2.13-2 \ -docker-ce=5:19.03.11~3-0~ubuntu-$(lsb_release -cs) \ -docker-ce-cli=5:19.03.11~3-0~ubuntu-$(lsb_release -cs) -``` - -```shell -# デーモンをセットアップ -cat > /etc/docker/daemon.json < /etc/docker/daemon.json <}} - -ブート時にDockerサービスを開始させたい場合は、以下のコマンドを入力してください: - -```shell -sudo systemctl enable docker -``` - -詳細については、[Dockerの公式インストールガイド](https://docs.docker.com/engine/installation/)を参照してください。 - -## CRI-O - -このセクションでは、CRIランタイムとして`CRI-O`を利用するために必要な手順について説明します。 - -システムへCRI-Oをインストールするためには以下のコマンドを利用します: - -{{< note >}} -CRI-OのメジャーとマイナーバージョンはKubernetesのメジャーとマイナーバージョンと一致しなければなりません。 -詳細は[CRI-O互換性表](https://github.com/cri-o/cri-o)を参照してください。 -{{< /note >}} - -### 事前準備 - -```shell -modprobe overlay -modprobe br_netfilter - -# 必要なカーネルパラメータの設定をします。これらの設定値は再起動後も永続化されます。 -cat > /etc/sysctl.d/99-kubernetes-cri.conf <}} -{{% tab name="Debian" %}} - - CRI-Oを以下のOSにインストールするには、環境変数$OSを以下の表の適切なフィールドに設定します。 - -| Operating system | $OS | -| ---------------- | ----------------- | -| Debian Unstable | `Debian_Unstable` | -| Debian Testing | `Debian_Testing` | - -
    -そして、`$VERSION`にKubernetesのバージョンに合わせたCRI-Oのバージョンを設定します。例えば、CRI-O 1.18をインストールしたい場合は、`VERSION=1.18` を設定します。インストールを特定のリリースに固定することができます。バージョン 1.18.3をインストールするには、`VERSION=1.18:1.18.3` を設定します。 -
    - -以下を実行します。 -```shell -echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list -echo "deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VERSION/$OS/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable:cri-o:$VERSION.list - -curl -L https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable:cri-o:$VERSION/$OS/Release.key | apt-key add - -curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/Release.key | apt-key add - - -apt-get update -apt-get install cri-o cri-o-runc -``` - -{{% /tab %}} - -{{% tab name="Ubuntu" %}} - - CRI-Oを以下のOSにインストールするには、環境変数$OSを以下の表の適切なフィールドに設定します。 - -| Operating system | $OS | -| ---------------- | ----------------- | -| Ubuntu 20.04 | `xUbuntu_20.04` | -| Ubuntu 19.10 | `xUbuntu_19.10` | -| Ubuntu 19.04 | `xUbuntu_19.04` | -| Ubuntu 18.04 | `xUbuntu_18.04` | - -
    -次に、`$VERSION`をKubernetesのバージョンと一致するCRI-Oのバージョンに設定します。例えば、CRI-O 1.18をインストールしたい場合は、`VERSION=1.18` を設定します。インストールを特定のリリースに固定することができます。バージョン 1.18.3 をインストールするには、`VERSION=1.18:1.18.3` を設定します。 -
    - -以下を実行します。 -```shell -echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list -echo "deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VERSION/$OS/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable:cri-o:$VERSION.list - -curl -L https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable:cri-o:$VERSION/$OS/Release.key | apt-key add - -curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/Release.key | apt-key add - - -apt-get update -apt-get install cri-o cri-o-runc -``` -{{% /tab %}} - -{{% tab name="CentOS" %}} - - CRI-Oを以下のOSにインストールするには、環境変数$OSを以下の表の適切なフィールドに設定します。 - -| Operating system | $OS | -| ---------------- | ----------------- | -| Centos 8 | `CentOS_8` | -| Centos 8 Stream | `CentOS_8_Stream` | -| Centos 7 | `CentOS_7` | - -
    -次に、`$VERSION`をKubernetesのバージョンと一致するCRI-Oのバージョンに設定します。例えば、CRI-O 1.18 をインストールしたい場合は、`VERSION=1.18` を設定します。インストールを特定のリリースに固定することができます。バージョン 1.18.3 をインストールするには、`VERSION=1.18:1.18.3` を設定します。 -
    - -以下を実行します。 -```shell -curl -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable.repo https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/devel:kubic:libcontainers:stable.repo -curl -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable:cri-o:$VERSION.repo https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable:cri-o:$VERSION/$OS/devel:kubic:libcontainers:stable:cri-o:$VERSION.repo -yum install cri-o -``` - -{{% /tab %}} - -{{% tab name="openSUSE Tumbleweed" %}} - -```shell - sudo zypper install cri-o -``` -{{% /tab %}} -{{% tab name="Fedora" %}} - -$VERSIONには、Kubernetesのバージョンと一致するCRI-Oのバージョンを設定します。例えば、CRI-O 1.18をインストールしたい場合は、$VERSION=1.18を設定します。 -以下のコマンドで、利用可能なバージョンを見つけることができます。 -```shell -dnf module list cri-o -``` -CRI-OはFedoraの特定のリリースにピン留めすることをサポートしていません。 - -以下を実行します。 -```shell -dnf module enable cri-o:$VERSION -dnf install cri-o -``` - -{{% /tab %}} -{{< /tabs >}} - - -### CRI-Oの起動 - -```shell -systemctl daemon-reload -systemctl start crio -``` - -詳細については、[CRI-Oインストールガイド](https://github.com/kubernetes-sigs/cri-o#getting-started)を参照してください。 - -## Containerd - -このセクションでは、CRIランタイムとして`containerd`を利用するために必要な手順について説明します。 - -システムへContainerdをインストールするためには次のコマンドを実行します。 - -### 必要な設定の追加 - -```shell -cat > /etc/modules-load.d/containerd.conf < /etc/sysctl.d/99-kubernetes-cri.conf <}} -{{% tab name="Ubuntu 16.04" %}} - -```shell -# (containerdのインストール) -## リポジトリの設定 -### HTTPS越しのリポジトリの使用をaptに許可するために、パッケージをインストール -apt-get update && apt-get install -y apt-transport-https ca-certificates curl software-properties-common +```bash +lsmod | grep br_netfilter +lsmod | grep overlay ``` -```shell -## Docker公式のGPG鍵を追加 -curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - +以下のコマンドを実行して、`net.bridge.bridge-nf-call-iptables`、`net.bridge.bridge-nf-call-ip6tables`、`net.ipv4.ip_forward`カーネルパラメーターが1に設定されていることを確認します。 + +```bash +sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward ``` -```shell -## Dockerのaptリポジトリの追加 -add-apt-repository \ - "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ - $(lsb_release -cs) \ - stable" +## cgroupドライバー {#cgroup-drivers} + +Linuxでは、プロセスに割り当てられるリソースを制約するために{{< glossary_tooltip text="cgroup" term_id="cgroup" >}}が使用されます。 + +{{< glossary_tooltip text="kubelet" term_id="kubelet" >}}と基盤となるコンテナランタイムは、[コンテナのリソース管理](/ja/docs/concepts/configuration/manage-resources-containers/)を実施し、CPU/メモリーの要求や制限などのリソースを設定するため、cgroupとインターフェースする必要があります。 +cgroupとインターフェースするために、kubeletおよびコンテナランタイムは*cgroupドライバー*を使用する必要があります。 +この際、kubeletとコンテナランタイムが同一のcgroupドライバーを使用し、同一の設定を適用することが不可欠となります。 + +利用可能なcgroupドライバーは以下の2つです。 + +* [`cgroupfs`](#cgroupfs-cgroup-driver) +* [`systemd`](#systemd-cgroup-driver) + +### cgroupfsドライバー {#cgroupfs-cgroup-driver} + +`cgroupfs`ドライバーは、kubeletのデフォルトのcgroupドライバーです。 +`cgroupfs`ドライバーを使用すると、kubeletとコンテナランタイムはcgroupファイルシステムと直接インターフェイスし、cgroupを設定します。 + +[systemd](https://www.freedesktop.org/wiki/Software/systemd/)がinitシステムである場合、`cgroupfs`ドライバーは推奨**されません**。 +なぜなら、systemdはシステム上のcgroupマネージャーが単一であると想定しているからです。 +また、[cgroup v2](/ja/docs/concepts/architecture/cgroups)を使用している場合は、`cgroupfs`の代わりに`systemd` cgroupドライバーを使用してください。 + +### systemd cgroupドライバー {#systemd-cgroup-driver} + +Linuxディストリビューションのinitシステムに[systemd](https://www.freedesktop.org/wiki/Software/systemd/)が選択されている場合、 +initプロセスはルートcgroupを生成・消費し、cgroupマネージャーとして動作します。 + +systemdはcgroupと密接に連携しており、systemdユニットごとにcgroupを割り当てます。 +その結果、initシステムに`systemd`を使用した状態で`cgroupfs`ドライバーを使用すると、 +システムには2つの異なるcgroupマネージャーが存在することになります。 + +2つのcgroupマネージャーが存在することで、システムで利用可能なリソースおよび使用中のリソースに、2つの異なる見え方が与えられることになります。 +特定の場合において、kubeletとコンテナランタイムに`cgroupfs`を、残りのプロセスに`systemd`を使用するように設定されたノードが高負荷時に不安定になることがあります。 + +このような不安定性を緩和するためのアプローチは、systemdがinitシステムに採用されている場合にkubeletとコンテナランタイムのcgroupドライバーとして`systemd`を使用することです。 + +cgroupドライバーに`systemd`を設定するには、以下のように[`KubeletConfiguration`](/docs/tasks/administer-cluster/kubelet-config-file/)の`cgroupDriver`オプションを編集して`systemd`を設定します。 + +```yaml +apiVersion: kubelet.config.k8s.io/v1beta1 +kind: KubeletConfiguration +... +cgroupDriver: systemd ``` -```shell -## containerdのインストール -apt-get update && apt-get install -y containerd.io -``` +kubelet用のcgroupドライバーとして`systemd`を設定する場合、コンテナランタイムのcgroupドライバーにも`systemd`を設定する必要があります。 +具体的な手順については、以下のリンクなどの、お使いのコンテナランタイムのドキュメントを参照してください。 -```shell -# containerdの設定 -mkdir -p /etc/containerd -containerd config default | sudo tee /etc/containerd/config.toml -``` +* [containerd](#containerd-systemd) +* [CRI-O](#cri-o) -```shell -# containerdの再起動 -systemctl restart containerd -``` +{{< caution >}} +クラスターに参加したノードのcgroupドライバーを変更するのはデリケートな操作です。 +kubeletが特定のcgroupドライバーのセマンティクスを使用してPodを作成していた場合、 +コンテナランタイムを別のcgroupドライバーに変更すると、そのような既存のPodに対してPodサンドボックスを再作成しようとしたときにエラーが発生することがあります。 +kubeletを再起動してもこのようなエラーは解決しない可能性があります。 + +もしあなたが適切な自動化の手段を持っているのであれば、更新された設定を使用してノードを別のノードに置き換えるか、自動化を使用して再インストールを行ってください。 +{{< /caution >}} + +### kubeadmで管理されたクラスターでの`systemd`ドライバーへの移行 + +既存のkubeadm管理クラスターで`systemd` cgroupドライバーに移行したい場合は、[cgroupドライバーの設定](/ja/docs/tasks/administer-cluster/kubeadm/configure-cgroup-driver/)に従ってください。 + +## サポートするCRIのバージョン {#cri-versions} + +コンテナランタイムは、Container Runtime Interfaceのv1alpha2以上をサポートする必要があります。 + +Kubernetes {{< skew currentVersion >}}は、デフォルトでCRI APIのv1を使用します。 +コンテナランタイムがv1 APIをサポートしていない場合、kubeletは代わりに(非推奨の)v1alpha2 APIにフォールバックします。 + +## コンテナランタイム {#container-runtimes} + +{{% thirdparty-content %}} + +### containerd + +このセクションでは、CRIランタイムとしてcontainerdを使用するために必要な手順の概要を説明します。 + +以下のコマンドを使用して、システムにcontainerdをインストールします: + +まずは[containerdの使用を開始する](https://github.com/containerd/containerd/blob/main/docs/getting-started.md)の指示に従ってください。有効な`config.toml`設定ファイルを作成したら、このステップに戻ります。 + +{{< tabs name="Finding your config.toml file" >}} +{{% tab name="Linux" %}} +このファイルはパス`/etc/containerd/config.toml`にあります。 {{% /tab %}} -{{% tab name="CentOS/RHEL 7.4+" %}} - -```shell -# (containerdのインストール) -## リポジトリの設定 -### 必要なパッケージのインストール -yum install -y yum-utils device-mapper-persistent-data lvm2 -``` - -```shell -## Dockerのリポジトリの追加 -yum-config-manager \ - --add-repo \ - https://download.docker.com/linux/centos/docker-ce.repo -``` - -```shell -## containerdのインストール -yum update -y && yum install -y containerd.io -``` - -```shell -## containerdの設定 -mkdir -p /etc/containerd -containerd config default | sudo tee /etc/containerd/config.toml -``` - -```shell -# containerdの再起動 -systemctl restart containerd -``` +{{% tab name="Windows" %}} +このファイルは`C:\Program Files\containerd\config.toml`にあります。 {{% /tab %}} {{< /tabs >}} -### systemd +Linuxでは、containerd用のデフォルトのCRIソケットは`/run/containerd/containerd.sock`です。 +Windowsでは、デフォルトのCRIエンドポイントは`npipe://./pipe/containerd-containerd`です。 -`systemd`のcgroupドライバーを使うには、`/etc/containerd/config.toml`内で`plugins.cri.systemd_cgroup = true`を設定してください。 -kubeadmを使う場合は[kubeletのためのcgroupドライバー](/ja/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#マスターノードのkubeletによって使用されるcgroupドライバーの設定)を手動で設定してください。 +#### `systemd` cgroupドライバーを構成する -## その他のCRIランタイム: frakti +`/etc/containerd/config.toml`内で`runc`が`systemd` cgroupドライバーを使うようにするには、次のように設定します。 -詳細については[Fraktiのクイックスタートガイド](https://github.com/kubernetes/frakti#quickstart)を参照してください。 +``` +[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] + ... + [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] + SystemdCgroup = true +``` +[cgroup v2](/ja/docs/concepts/architecture/cgroups)を使用する場合は`systemd` cgroupドライバーの利用を推奨します。 +{{< note >}} +パッケージ(RPMや`.deb`など)からcontainerdをインストールした場合、 +CRI統合プラグインがデフォルトで無効になっていることがあります。 + +Kubernetesでcontainerdを使用するには、CRIサポートを有効にする必要があります。 +`/etc/containerd/config.toml`内の`disabled_plugins`リストに`cri`が含まれていないことを確認してください。 +このファイルを変更した場合、`containerd`も再起動してください。 + +クラスターの初回構築後、またはCNIをインストールした後にコンテナのクラッシュループが発生した場合、 +パッケージと共に提供されるcontainerdの設定に互換性のないパラメーターが含まれている可能性があります。 +[get-started.md](https://github.com/containerd/containerd/blob/main/docs/getting-started.md#advanced-topics)にあるように、 +`containerd config default > /etc/containerd/config.toml`でcontainerdの設定をリセットした上で、 +上記の設定パラメーターを使用することを検討してください。 +{{< /note >}} + +この変更を適用した場合、必ずcontainerdを再起動してください。 + +```shell +sudo systemctl restart containerd +``` + +kubeadmを使用している場合、手動で[kubelet cgroupドライバーの設定](/ja/docs/tasks/administer-cluster/kubeadm/configure-cgroup-driver/#configuring-the-kubelet-cgroup-driver)を行ってください。 + +#### サンドボックス(pause)イメージの上書き {#override-pause-image-containerd} + +[containerdの設定](https://github.com/containerd/containerd/blob/main/docs/cri/config.md)で以下の設定をすることで、サンドボックスのイメージを上書きすることができます。 + +```toml +[plugins."io.containerd.grpc.v1.cri"] + sandbox_image = "registry.k8s.io/pause:3.2" +``` + +この場合も、設定ファイルの更新後に`systemctl restart containerd`を実行して`containerd`も再起動する必要があるでしょう。 + +### CRI-O + +本セクションでは、コンテナランタイムとしてCRI-Oをインストールするために必要な手順を説明します。 + +CRI-Oをインストールするには、[CRI-Oのインストール手順](https://github.com/cri-o/cri-o/blob/main/install.md#readme)に従ってください。 + +#### cgroupドライバー + +CRI-Oはデフォルトでsystemd cgroupドライバーを使用し、おそらく問題なく動作します。 +`cgroupfs` cgroupドライバーに切り替えるには、`/etc/crio/crio.conf` を編集するか、 +`/etc/crio/crio.conf.d/02-cgroup-manager.conf`にドロップイン設定ファイルを置いて、以下のような設定を記述してください。 + +```toml +[crio.runtime] +conmon_cgroup = "pod" +cgroup_manager = "cgroupfs" +``` + +上記で`conmon_cgroup`も変更されていることに注意してください。 +CRI-Oで`cgroupfs`を使用する場合、ここには`pod`という値を設定する必要があります。 +一般に、kubeletのcgroupドライバーの設定(通常はkubeadmによって行われます)とCRI-Oの設定は一致させる必要があります。 + +CRI-Oの場合、CRIソケットはデフォルトで`/var/run/crio/crio.sock`となります。 + +#### サンドボックス(pause)イメージの上書き {#override-pause-image-cri-o} + +[CRI-Oの設定](https://github.com/cri-o/cri-o/blob/main/docs/crio.conf.5.md)において、以下の値を設定することができます。 + +```toml +[crio.image] +pause_image="registry.k8s.io/pause:3.6" +``` + +このオプションはライブ設定リロードによる変更の適用に対応しています。 +`systemctl reload crio`または`crio`プロセスに`SIGHUP`を送信することで変更を適用できます。 + +### Docker Engine {#docker} + +{{< note >}} +この手順では、Docker EngineとKubernetesを統合するために[`cri-dockerd`](https://github.com/Mirantis/cri-dockerd)アダプターを使用することを想定しています。 +{{< /note >}} + +1. 各ノードに、使用しているLinuxディストリビューション用のDockerを[Docker Engineのインストール](https://docs.docker.com/engine/install/#server)に従ってインストールします。 + +2. [`cri-dockerd`](https://github.com/Mirantis/cri-dockerd)をリポジトリ内の指示に従ってインストールします。 + +`cri-dockerd`の場合、CRIソケットはデフォルトで`/run/cri-dockerd.sock`になります。 + +### Mirantis Container Runtime {#mcr} + +[Mirantis Container Runtime](https://docs.mirantis.com/mcr/20.10/overview.html)(MCR)は、 +以前はDocker Enterprise Editionとして知られていた、商業的に利用可能なコンテナランタイムです。 + +MCRに含まれるオープンソースの[`cri-dockerd`](https://github.com/Mirantis/cri-dockerd)コンポーネントを使用することで、 +Mirantis Container RuntimeをKubernetesで使用することができます。 + +Mirantis Container Runtimeのインストール方法について知るには、[MCRデプロイガイド](https://docs.mirantis.com/mcr/20.10/install.html)を参照してください。 + +CRIソケットのパスを見つけるには、systemdの`cri-docker.socket`という名前のユニットを確認してください。 + +#### サンドボックス(pause)イメージを上書きする {#override-pause-image-cri-dockerd-mcr} + +`cri-dockerd`アダプターは、Podインフラコンテナ("pause image")として使用するコンテナイメージを指定するためのコマンドライン引数を受け付けます。 +使用するコマンドライン引数は `--pod-infra-container-image`です。 + +## {{% heading "whatsnext" %}} + +コンテナランタイムに加えて、クラスターには動作する[ネットワークプラグイン](/ja/docs/concepts/cluster-administration/networking/#how-to-implement-the-kubernetes-network-model)が必要です。 diff --git a/content/ja/docs/tasks/administer-cluster/kubeadm/configure-cgroup-driver.md b/content/ja/docs/tasks/administer-cluster/kubeadm/configure-cgroup-driver.md index 90205b61067..c4381bb8c95 100644 --- a/content/ja/docs/tasks/administer-cluster/kubeadm/configure-cgroup-driver.md +++ b/content/ja/docs/tasks/administer-cluster/kubeadm/configure-cgroup-driver.md @@ -10,17 +10,17 @@ weight: 10 ## {{% heading "prerequisites" %}} -Kubernetesの[コンテナランタイムの要件](/docs/setup/production-environment/container-runtimes)を熟知している必要があります。 +Kubernetesの[コンテナランタイムの要件](/ja/docs/setup/production-environment/container-runtimes)を熟知している必要があります。 ## コンテナランタイムのcgroupドライバーの設定 -[Container runtimes](/docs/setup/production-environment/container-runtimes)ページでは、kubeadmベースのセットアップでは`cgroupfs`ドライバーではなく、`systemd`ドライバーが推奨されると説明されています。 +[コンテナランタイム](/ja/docs/setup/production-environment/container-runtimes)ページでは、kubeadmベースのセットアップでは`cgroupfs`ドライバーではなく、`systemd`ドライバーが推奨されると説明されています。 このページでは、デフォルトの`systemd`ドライバーを使用して多くの異なるコンテナランタイムをセットアップする方法についての詳細も説明されています。 -## kubelet cgroupドライバーの設定 +## kubelet cgroupドライバーの設定 {#configuring-the-kubelet-cgroup-driver} kubeadmでは、`kubeadm init`の際に`KubeletConfiguration`構造体を渡すことができます。 diff --git a/content/ja/docs/tasks/administer-cluster/migrating-from-dockershim/find-out-runtime-you-use.md b/content/ja/docs/tasks/administer-cluster/migrating-from-dockershim/find-out-runtime-you-use.md index a6d297bdd8a..e9ae0e3fc1d 100644 --- a/content/ja/docs/tasks/administer-cluster/migrating-from-dockershim/find-out-runtime-you-use.md +++ b/content/ja/docs/tasks/administer-cluster/migrating-from-dockershim/find-out-runtime-you-use.md @@ -6,7 +6,7 @@ weight: 10 -このページでは、クラスター内のノードが使用している[コンテナランタイム](/docs/setup/production-environment/container-runtimes/)を確認する手順を概説しています。 +このページでは、クラスター内のノードが使用している[コンテナランタイム](/ja/docs/setup/production-environment/container-runtimes/)を確認する手順を概説しています。 クラスターの実行方法によっては、ノード用のコンテナランタイムが事前に設定されている場合と、設定する必要がある場合があります。 マネージドKubernetesサービスを使用している場合、ノードに設定されているコンテナランタイムを確認するためのベンダー固有の方法があるかもしれません。 @@ -42,4 +42,4 @@ node-2 Ready v1.19.6 containerd://1.4.1 node-3 Ready v1.19.6 containerd://1.4.1 ``` -コンテナランタイムについては、[コンテナランタイム](/docs/setup/production-environment/container-runtimes/)のページで詳細を確認することができます。 +コンテナランタイムについては、[コンテナランタイム](/ja/docs/setup/production-environment/container-runtimes/)のページで詳細を確認することができます。 From 19675b1acdb3cfdca60773fdf342e08a96a866cd Mon Sep 17 00:00:00 2001 From: Qiming Teng Date: Sun, 12 Feb 2023 21:15:44 +0800 Subject: [PATCH 204/279] [zh] Resync configure service account page --- .../configure-service-account.md | 641 +++++++++++------- 1 file changed, 408 insertions(+), 233 deletions(-) diff --git a/content/zh-cn/docs/tasks/configure-pod-container/configure-service-account.md b/content/zh-cn/docs/tasks/configure-pod-container/configure-service-account.md index 3b4c0f300e2..8f2ab826654 100644 --- a/content/zh-cn/docs/tasks/configure-pod-container/configure-service-account.md +++ b/content/zh-cn/docs/tasks/configure-pod-container/configure-service-account.md @@ -16,68 +16,114 @@ weight: 90 -服务账号为 Pod 中运行的进程提供了一个标识。 - -{{< note >}} -本文是服务账号的用户使用介绍,描述服务账号在集群中如何起作用。 -你的集群管理员可能已经对你的集群做了定制,因此导致本文中所讲述的内容并不适用。 -{{< /note >}} +Kubernetes 提供两种完全不同的方式来为客户端提供支持,这些客户端可能运行在你的集群中, +也可能与你的集群的{{< glossary_tooltip text="控制面" term_id="control-plane" >}}相关, +需要向 {{< glossary_tooltip text="API 服务器" term_id="kube-apiserver" >}}完成身份认证。 -当你(自然人)访问集群时(例如,使用 `kubectl`),API 服务器将你的身份验证为 -特定的用户账号(当前这通常是 `admin`,除非你的集群管理员已经定制了你的集群配置)。 -Pod 内的容器中的进程也可以与 API 服务器接触。 -当它们进行身份验证时,它们被验证为特定的服务账号(例如,`default`)。 +**服务账号(Service Account)**为 Pod 中运行的进程提供身份标识, +并映射到 ServiceAccount 对象。当你向 API 服务器执行身份认证时, +你会将自己标识为某个**用户(User)**。Kubernetes 能够识别用户的概念, +但是 Kubernetes 自身**并不**提供 User API。 + + +本服务是关于 ServiceAccount 的,而 ServiceAccount 则确实存在于 Kubernetes 的 API 中。 +本指南为你展示为 Pod 配置 ServiceAccount 的一些方法。 ## {{% heading "prerequisites" %}} -{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} +{{< include "task-tutorial-prereqs.md" >}} -## 使用默认的服务账号访问 API 服务器 +## 使用默认的服务账号访问 API 服务器 {#use-the-default-service-account-to-access-the-api-server} -当你创建 Pod 时,如果没有指定服务账号,Pod 会被指定给命名空间中的 `default` 服务账号。 -如果你查看 Pod 的原始 JSON 或 YAML(例如:`kubectl get pods/ -o yaml`), -你可以看到 `spec.serviceAccountName` 字段已经被[自动设置](/zh-cn/docs/concepts/overview/working-with-objects/object-management/)了。 +当 Pod 与 API 服务器联系时,Pod 会被认证为某个特定的 ServiceAccount(例如:`default`)。 +在每个{{< glossary_tooltip text="名字空间" term_id="namespace" >}}中,至少存在一个 +ServiceAccount。 + +每个 Kubernetes 名字空间至少包含一个 ServiceAccount:也就是该名字空间的默认服务账号, +名为 `default`。如果你在创建 Pod 时没有指定 ServiceAccount,Kubernetes 会自动将该名字空间中 +名为 `default` 的 ServiceAccount 分配给该 Pod。 + +你可以检视你刚刚创建的 Pod 的细节。例如: + +```shell +kubectl get pods/ -o yaml +``` -你可以使用自动挂载给 Pod 的服务账号凭据访问 API, -[访问集群](/zh-cn/docs/tasks/access-application-cluster/access-cluster)页面中有相关描述。 -服务账号的 API -许可取决于你所使用的[鉴权插件和策略](/zh-cn/docs/reference/access-authn-authz/authorization/#authorization-modules)。 +在输出中,你可以看到字段 `spec.serviceAccountName`。当你在创建 Pod 时未设置该字段时, +Kubernetes [自动](/zh-cn/docs/concepts/overview/working-with-objects/object-management/)为 +Pod 设置这一属性的取值。 -你可以通过在 ServiceAccount 上设置 `automountServiceAccountToken: false` -来实现不给服务账号自动挂载 API 凭据到 `/var/run/secrets/kubernetes.io/serviceaccount/token` -的目的: +Pod 中运行的应用可以使用这一自动挂载的服务账号凭据来访问 Kubernetes API。 +参阅[访问集群](/zh-cn/docs/tasks/access-application-cluster/access-cluster/)以进一步了解。 + + +当 Pod 被身份认证为某个 ServiceAccount 时, +其访问能力取决于所使用的[鉴权插件和策略](/zh-cn/docs/reference/access-authn-authz/authorization/#authorization-modules)。 + + +### 放弃 API 凭据的自动挂载 {#opt-out-of-api-credential-automounting} + +如果你不希望 {{< glossary_tooltip text="kubelet" term_id="kubelet" >}} 自动挂载某 +ServiceAccount 的 API 访问凭据,你可以选择不采用这一默认行为。 +通过在 ServiceAccount 对象上设置 `automountServiceAccountToken: false`,可以放弃在 +`/var/run/secrets/kubernetes.io/serviceaccount/token` 处自动挂载该服务账号的 API 凭据。 + +例如: ```yaml apiVersion: v1 @@ -87,11 +133,10 @@ metadata: automountServiceAccountToken: false ... ``` - -在 1.6 以上版本中,你也可以选择不给特定 Pod 自动挂载 API 凭据: +你也可以选择不给特定 Pod 自动挂载 API 凭据: ```yaml apiVersion: v1 @@ -105,20 +150,25 @@ spec: ``` -如果 Pod 和服务账号都指定了 `automountServiceAccountToken` 值,则 Pod 的 spec 优先于服务账号。 +如果 ServiceAccount 和 Pod 的 `.spec` 都设置了 `automountServiceAccountToken` 值, +则 Pod 上 spec 的设置优先于服务账号的设置。 ## 使用多个服务账号 {#use-multiple-service-accounts} -每个命名空间都有一个名为 `default` 的服务账号资源。 -你可以用下面的命令查询这个服务账号以及命名空间中的其他 ServiceAccount 资源: +每个名字空间都至少有一个 ServiceAccount:名为 `default` 的默认 ServiceAccount 资源。 +你可以用下面的命令列举你[当前名字空间](/zh-cn/docs/concepts/overview/working-with-objects/namespaces/#setting-the-namespace-preference) +中的所有 ServiceAccount 资源: ```shell kubectl get serviceaccounts @@ -181,23 +231,23 @@ metadata: ``` -你可以使用授权插件来[设置服务账号的访问许可](/zh-cn/docs/reference/access-authn-authz/rbac/#service-account-permissions)。 +你可以使用鉴权插件来[设置服务账号的访问许可](/zh-cn/docs/reference/access-authn-authz/rbac/#service-account-permissions)。 要使用非默认的服务账号,将 Pod 的 `spec.serviceAccountName` 字段设置为你想用的服务账号名称。 -Pod 被创建时服务账号必须存在,否则会被拒绝。 - -你不能更新已经创建好的 Pod 的服务账号。 +只能在创建 Pod 时或者为新 Pod 指定模板时,你才可以设置 `serviceAccountName`。 +你不能更新已经存在的 Pod 的 `.spec.serviceAccountName` 字段。 {{< note >}} -你可以清除服务账号,如下所示: +### 清理 {#cleanup-use-multiple-service-accounts} + +如果你尝试了创建前文示例中所给的 `build-robot` ServiceAccount, +你可以通过运行下面的命令来完成清理操作: ```shell kubectl delete serviceaccount/build-robot ``` -## 手动创建服务账号 API 令牌 +## 手动为 ServiceAccount 创建 API 令牌 {#manually-create-an-api-token-for-a-serviceaccount} -假设我们有一个上面提到的名为 "build-robot" 的服务账号,现在我们手动创建一个新的 Secret。 +假设你已经有了一个前文所提到的名为 "build-robot" 的服务账号。 +你可以使用 `kubectl` 为该 ServiceAccount 获得一个时间上受限的 API 令牌: + +```shell +kubectl create token build-robot +``` + + +这一命令的输出是一个令牌,你可以使用该令牌来将身份认证为对应的 ServiceAccount。 +你可以使用 `kubectl create token` 命令的 `--duration` 参数来请求特定的令牌有效期 +(实际签发的令牌的有效期可能会稍短一些,也可能会稍长一些)。 + +{{< note >}} + +Kubernetes 在 v1.22 版本之前自动创建用来访问 Kubernetes API 的长期凭据。 +这一较老的机制是基于创建令牌 Secret 对象来实现的,Secret 对象可被挂载到运行中的 Pod 内。 +在最近的版本中,包括 Kubernetes v{{< skew currentVersion >}},API 凭据可以直接使用 +[TokenRequest](/zh-cn/docs/reference/kubernetes-api/authentication-resources/token-request-v1/) API +来获得,并使用一个[投射卷](/zh-cn/docs/reference/access-authn-authz/service-accounts-admin/#bound-service-account-token-volume)挂载到 +Pod 中。使用此方法获得的令牌具有受限的生命期长度,并且能够在挂载它们的 Pod +被删除时自动被废弃。 + + +你仍然可以通过手动方式来创建服务账号令牌 Secret 对象,例如你需要一个永远不过期的令牌时。 +不过,使用 [TokenRequest](/zh-cn/docs/reference/kubernetes-api/authentication-resources/token-request-v1/) +子资源来获得访问 API 的令牌的做法仍然是推荐的方式。 +{{< /note >}} + + +### 手动为 ServiceAccount 创建长期有效的 API 令牌 {#manually-create-a-long-lived-api-token-for-a-serviceaccount}」 + +如果你需要为 ServiceAccount 获得一个 API 令牌,你可以创建一个新的、带有特殊注解 +`kubernetes.io/service-account.name` 的 Secret 对象。 ```shell kubectl apply -f - < -现在,你可以确认新构建的 Secret 中填充了 "build-robot" 服务账号的 API 令牌。 -令牌控制器将清理不存在的服务账号的所有令牌。 +如果你通过下面的命令来查看 Secret: + +```shell +kubectl get secret/build-robot-secret -o yaml +``` + + +你可以看到 Secret 中现在包含针对 "build-robot" ServiceAccount 的 API 令牌。 + +鉴于你所设置的注解,控制面会自动为该 ServiceAccount 生成一个令牌,并将其保存到相关的 Secret +中。控制面也会为已删除的 ServiceAccount 执行令牌清理操作。 ```shell kubectl describe secrets/build-robot-secret @@ -256,7 +383,7 @@ kubectl describe secrets/build-robot-secret -输出类似于: +输出类似于这样: ``` Name: build-robot-secret @@ -277,42 +404,60 @@ token: ... {{< note >}} -这里省略了 `token` 的内容。 +这里将 `token` 的内容抹去了。 + +注意在你的终端或者计算机屏幕可能被旁观者看到的场合,不要显示 +`kubernetes.io/service-account-token` 的内容。 {{< /note >}} + +当你删除一个与某 Secret 相关联的 ServiceAccount 时,Kubernetes 的控制面会自动清理该 +Secret 中长期有效的令牌。 + -## 为服务账号添加 ImagePullSecrets {#add-imagepullsecrets-to-a-service-account} +## 为服务账号添加 ImagePullSecrets {#add-imagepullsecrets-to-a-service-account} -### 创建 ImagePullSecret +首先,[生成一个 imagePullSecret](/zh-cn/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod); +接下来,验证该 Secret 已被创建。例如: -- 创建一个 ImagePullSecret,如[为 Pod 设置 ImagePullSecret](/zh-cn/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod) 所述。 + +- 按[为 Pod 设置 imagePullSecret](/zh-cn/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod) + 所描述的,生成一个镜像拉取 Secret: ```shell kubectl create secret docker-registry myregistrykey --docker-server=DUMMY_SERVER \ - --docker-username=DUMMY_USERNAME --docker-password=DUMMY_DOCKER_PASSWORD \ - --docker-email=DUMMY_DOCKER_EMAIL + --docker-username=DUMMY_USERNAME --docker-password=DUMMY_DOCKER_PASSWORD \ + --docker-email=DUMMY_DOCKER_EMAIL ``` -- 确认创建成功: +- 检查该 Secret 已经被创建。 ```shell kubectl get secrets myregistrykey ``` - + - 输出类似于: + 输出类似于这样: ``` NAME TYPE DATA AGE @@ -322,36 +467,35 @@ The content of `token` is elided here. -### 将镜像拉取 Secret 添加到服务账号 +### 将镜像拉取 Secret 添加到服务账号 {#add-image-pull-secret-to-service-account} -接着修改命名空间的 `default` 服务账号,令其使用该 Secret 用作 `imagePullSecret`。 +接下来更改名字空间的默认服务账号,将该 Secret 用作 imagePullSecret。 ```shell kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "myregistrykey"}]}' ``` -你也可以使用 `kubectl edit`,或者如下所示手动编辑 YAML 清单: +你也可以通过手动编辑该对象来实现同样的效果: ```shell -kubectl get serviceaccounts default -o yaml > ./sa.yaml +kubectl edit serviceaccount/default ``` - -`sa.yaml` 文件的输出类似这样: +你所选择的文本编辑器会被打开,展示如下所示的配置: ```yaml apiVersion: v1 kind: ServiceAccount metadata: - creationTimestamp: 2015-08-07T22:02:39Z + creationTimestamp: 2021-07-07T22:02:39Z name: default namespace: default resourceVersion: "243024" @@ -359,45 +503,38 @@ metadata: ``` -使用你常用的编辑器(例如 `vi`),打开 `sa.yaml` 文件,删除带有键名 -`resourceVersion` 的行,添加带有 `imagePullSecrets:` 的行,最后保存文件。 +使用你的编辑器,删掉包含 `resourceVersion` 主键的行,添加包含 `imagePullSecrets:` +的行并保存文件。对于 `uid` 而言,保持其取值与你读到的值一样。 -所得到的 `sa.yaml` 文件类似于: +当你完成这些变更之后,所编辑的 ServiceAccount 看起来像是这样: ```yaml apiVersion: v1 kind: ServiceAccount metadata: - creationTimestamp: 2015-08-07T22:02:39Z + creationTimestamp: 2021-07-07T22:02:39Z name: default namespace: default uid: 052fb0f4-3d50-11e5-b066-42010af0d7b6 imagePullSecrets: -- name: myregistrykey + - name: myregistrykey ``` -最后,使用新更新的 `sa.yaml` 文件替换服务账号。 +### 检查 imagePullSecrets 已经被设置到新 Pod 上 {#verify-that-imagepullsecrets-are-set-for-new-pods} -```shell -kubectl replace serviceaccount default -f ./sa.yaml -``` - - -### 验证镜像拉取 Secret 已经被添加到 Pod 规约 - -现在,在当前命名空间中创建使用默认服务账号的新 Pod 时,新 Pod -会自动设置其 `.spec.imagePullSecrets` 字段: +现在,在当前名字空间中创建新 Pod 并使用默认 ServiceAccount 时, +新 Pod 的 `spec.imagePullSecrets` 会被自动设置。 ```shell kubectl run nginx --image=nginx --restart=Never @@ -420,6 +557,7 @@ myregistrykey {{< feature-state for_k8s_version="v1.20" state="stable" >}} +{{< note >}} -* `--service-account-issuer` - - 此参数可作为服务账号令牌发放者的身份标识(Identifier)。你可以多次指定 - `--service-account-issuer` 参数,对于要变更发放者而又不想带来业务中断的场景, - 这样做是有用的。如果这个参数被多次指定,则第一个参数值会被用来生成令牌, +`--service-account-issuer` +: 定义服务账号令牌发放者的身份标识(Identifier)。你可以多次指定 + `--service-account-issuer` 参数,对于需要变更发放者而又不想带来业务中断的场景, + 这样做是有用的。如果这个参数被多次指定,其第一个参数值会被用来生成令牌, 而所有参数值都会被用来确定哪些发放者是可接受的。你所运行的 Kubernetes - 集群必须是 v1.22 或更高版本,才能多次指定 `--service-account-issuer`。 + 集群必须是 v1.22 或更高版本才能多次指定 `--service-account-issuer`。 + -* `--service-account-key-file` +`--service-account-key-file` +: 给出某文件的路径,其中包含 PEM 编码的 x509 RSA 或 ECDSA 私钥或公钥,用来检查 ServiceAccount + 的令牌。所指定的文件中可以包含多个秘钥,并且你可以多次使用此参数,每个参数值为不同的文件。 + 多次使用此参数时,由所给的秘钥之一签名的令牌会被 Kubernetes API 服务器认为是合法令牌。 - 包含 PEM 编码的 x509 RSA 或 ECDSA 私钥或公钥,用来检查 ServiceAccount - 的令牌。所指定的文件中可以包含多个秘钥,并且你可以多次使用此参数, - 每次参数值为不同的文件。多次使用此参数时,由所给的秘钥之一签名的令牌会被 - Kubernetes API 服务器认为是合法令牌。 -* `--service-account-signing-key-file` - - 指向包含当前服务账号令牌发放者的私钥的文件路径。 +`--service-account-signing-key-file` +: 指向某文件的路径,其中包含当前服务账号令牌发放者的私钥。 此发放者使用此私钥来签署所发放的 ID 令牌。 + -* `--api-audiences` (可以省略) - +`--api-audiences` (可以省略) +: 为 ServiceAccount 令牌定义其受众(Audiences)。 服务账号令牌身份检查组件会检查针对 API 访问所使用的令牌, - 确认令牌至少是被绑定到这里所给的受众(audiences)之一。 - 如果此参数被多次指定,则针对所给的多个受众中任何目标的令牌都会被 - Kubernetes API 服务器当做合法的令牌。如果 `--service-account-issuer` - 参数被设置,而这个参数未指定,则这个参数的默认值为一个只有一个元素的列表, + 确认令牌至少是被绑定到这里所给的受众之一。 + 如果 `api-audiences` 被多次指定,则针对所给的多个受众中任何目标的令牌都会被 + Kubernetes API 服务器当做合法的令牌。如果你指定了 `--service-account-issuer` + 参数,但沒有設置 `--api-audiences`,则控制面认为此参数的默认值为一个只有一个元素的列表, 且该元素为令牌发放者的 URL。 +{{< /note >}} -kubelet 还可以将服务账号令牌投射到 Pod 中。 -你可以指定令牌的期望属性,例如受众和有效期限。 -这些属性在 default 服务账号令牌上无法配置。 -当删除 Pod 或 ServiceAccount 时,服务账号令牌也将对 API 无效。 +kubelet 还可以将 ServiceAccount 令牌投射到 Pod 中。你可以指定令牌的期望属性, +例如受众和有效期限。这些属性在 default ServiceAccount 令牌上**无法**配置。 +当 Pod 或 ServiceAccount 被删除时,该令牌也将对 API 无效。 -使用名为 [ServiceAccountToken](/zh-cn/docs/concepts/storage/volumes/#projected) 的 -ProjectedVolume 类型在 PodSpec 上配置此功能。 -要向 Pod 提供具有 "vault" 用户以及两个小时有效期的令牌,可以在 PodSpec 中配置以下内容: +你可以使用类型为 `ServiceAccountToken` 的[投射卷](/zh-cn/docs/concepts/storage/volumes/#projected) +来为 Pod 的 `spec` 配置此行为。 + + +### 启动使用服务账号令牌投射的 Pod {#launch-a-pod-using-service-account-token-projection} + +要为某 Pod 提供一个受众为 `vault` 并且有效期限为 2 小时的令牌,你可以定义一个与下面类似的 +Pod 清单: {{< codenew file="pods/pod-projected-svc-token.yaml" >}} -创建 Pod: +创建此 Pod: ```shell kubectl create -f https://k8s.io/examples/pods/pod-projected-svc-token.yaml ``` -`kubelet` 组件会替 Pod 请求令牌并将其保存起来, -通过将令牌存储到一个可配置的路径使之在 Pod 内可用, -并在令牌快要到期的时候刷新它。 -`kubelet` 会在令牌存在期达到其 TTL 的 80% 的时候或者令牌生命期超过 -24 小时的时候主动轮换它。 +kubelet 组件会替 Pod 请求令牌并将其保存起来;通过将令牌存储到一个可配置的路径以使之在 +Pod 内可用;在令牌快要到期的时候刷新它。kubelet 会在令牌存在期达到其 TTL 的 80% +的时候或者令牌生命期超过 24 小时的时候主动请求将其轮换掉。 -应用程序负责在令牌被轮换时重新加载其内容。对于大多数使用场景而言, -周期性地(例如,每隔 5 分钟)重新加载就足够了。 + +应用负责在令牌被轮换时重新加载其内容。通常而言,周期性地(例如,每隔 5 分钟) +重新加载就足够了,不必跟踪令牌的实际过期时间。 -当启用服务账号令牌投射时启用发现服务账号分发者(Service Account Issuer Discovery) -这一功能特性,如[上文所述](#service-account-token-volume-projection)。 +如果你在你的集群中已经为 ServiceAccount 启用了[令牌投射](#serviceaccount-token-volume-projection), +那么你也可以利用其发现能力。Kubernetes 提供一种方式来让客户端将一个或多个外部系统进行联邦, +作为**标识提供者(Identity Provider)**,而这些外部系统的角色是**依赖方(Relying Party)**。 +{{< note >}} -{{< note >}} 分发者的 URL 必须遵从 [OIDC 发现规范](https://openid.net/specs/openid-connect-discovery-1_0.html)。 -这意味着 URL 必须使用 `https` 模式,并且必须在 +实现上,这意味着 URL 必须使用 `https` 模式,并且必须在路径 `{service-account-issuer}/.well-known/openid-configuration` -路径给出 OpenID 提供者(Provider)配置。 +处给出 OpenID 提供者(Provider)的配置信息。 -如果 URL 没有遵从这一规范,`ServiceAccountIssuerDiscovery` 末端就不会被注册, -即使该特性已经被启用。 +如果 URL 没有遵从这一规范,ServiceAccount 分发者发现末端末端就不会被注册也无法访问。 {{< /note >}} -发现服务账号分发者这一功能使得用户能够用联邦的方式结合使用 Kubernetes -集群(“Identity Provider”,标识提供者)与外部系统(“Relying Parties”, -依赖方)所分发的服务账号令牌。 - -当此功能被启用时,Kubernetes API 服务器会在 `/.well-known/openid-configuration` -提供一个 OpenID 提供者配置文档,并在 `/openid/v1/jwks` 处提供与之关联的 +当此特性被启用时,Kubernetes API 服务器会通过 HTTP 提供一个 OpenID 提供者配置文档。 +该配置文档发布在 `/.well-known/openid-configuration` 路径。 +这里的 OpenID 提供者配置(OpenID Provider Configuration)有时候也被称作 +“发现文档(Discovery Document)”。 +Kubernetes API 服务器也通过 HTTP 在 `/openid/v1/jwks` 处发布相关的 JSON Web Key Set(JWKS)。 -这里的 OpenID 提供者配置有时候也被称作“发现文档(Discovery Document)”。 - - -集群包括一个的默认 RBAC ClusterRole, 名为 `system:service-account-issuer-discovery`。 -默认的 RBAC ClusterRoleBinding 将此角色分配给 `system:serviceaccounts` 组, -所有服务账号隐式属于该组。这使得集群上运行的 Pod -能够通过它们所挂载的服务账号令牌访问服务账号发现文档。 -此外,管理员可以根据其安全性需要以及期望集成的外部系统选择是否将该角色绑定到 -`system:authenticated` 或 `system:unauthenticated`。 +{{< note >}} -{{< note >}} -对 `/.well-known/openid-configuration` 和 `/openid/v1/jwks` 路径请求的响应被设计为与 -OIDC 兼容,但不是与其完全一致。 -返回的文档仅包含对 Kubernetes 服务账号令牌进行验证所必须的参数。 +对于在 `/.well-known/openid-configuration` 和 `/openid/v1/jwks` 上给出的响应而言, +其设计上是保证与 OIDC 兼容的,但并不严格遵从 OIDC 的规范。 +响应中所包含的文档进包含对 Kubernetes 服务账号令牌进行校验所必需的参数。 {{< /note >}} + +使用 {{< glossary_tooltip text="RBAC" term_id="rbac">}} 的集群都包含一个的默认 +RBAC ClusterRole, 名为 `system:service-account-issuer-discovery`。 +默认的 RBAC ClusterRoleBinding 将此角色分配给 `system:serviceaccounts` 组, +所有 ServiceAccount 隐式属于该组。这使得集群上运行的 Pod +能够通过它们所挂载的服务账号令牌访问服务账号发现文档。 +此外,管理员可以根据其安全性需要以及期望集成的外部系统,选择是否将该角色绑定到 +`system:authenticated` 或 `system:unauthenticated`。 + 另请参见: -- [服务账号的集群管理员指南](/zh-cn/docs/reference/access-authn-authz/service-accounts-admin/) -- [服务账号签署密钥检索 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) +- 阅读[为集群管理员提供的服务账号指南](/zh-cn/docs/reference/access-authn-authz/service-accounts-admin/) +- 阅读 [Kubernetes中的鉴权](/zh-cn/docs/reference/access-authn-authz/authorization/) +- 阅读 [Secret](/zh-cn/docs/concepts/configuration/secret/) 的概念 + - 或者学习[使用 Secret 来安全地分发凭据](/zh-cn/docs/tasks/inject-data-application/distribute-credentials-secure/) + - 不过也要注意,使用 Secret 来完成 ServiceAccount 身份验证的做法已经过时。 + 建议的替代做法是执行 [ServiceAccount 令牌卷投射](#service-account-token-volume-projection). + +- 阅读理解[投射卷](/zh-cn/docs/tasks/configure-pod-container/configure-projected-volume-storage/) +- 关于 OIDC 发现的相关背景信息,阅读[服务账号签署密钥检索 KEP](https://github.com/kubernetes/enhancements/tree/master/keps/sig-auth/1393-oidc-discovery) + 这一 Kubernetes 增强提案 +- 阅读 [OIDC 发现规范](https://openid.net/specs/openid-connect-discovery-1_0.html) From 821e480feac59c06000069cade9d3b90bd9f1143 Mon Sep 17 00:00:00 2001 From: windsonsea Date: Tue, 14 Feb 2023 09:42:33 +0800 Subject: [PATCH 205/279] [zh] sync /glossary/jwt.md --- content/zh-cn/docs/reference/glossary/jwt.md | 41 ++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 content/zh-cn/docs/reference/glossary/jwt.md diff --git a/content/zh-cn/docs/reference/glossary/jwt.md b/content/zh-cn/docs/reference/glossary/jwt.md new file mode 100644 index 00000000000..5d0dbbdc722 --- /dev/null +++ b/content/zh-cn/docs/reference/glossary/jwt.md @@ -0,0 +1,41 @@ +--- +title: JSON Web 令牌 (JWT) +id: jwt +date: 2023-01-17 +full_link: https://www.rfc-editor.org/rfc/rfc7519 +short_description: > + JWT 是用来表示在两方之间所转移的权限声明的一种方式。 + +aka: +tags: +- security +- architecture +--- + + + +JWT 是用来表示在两方之间所转移的权限声明的一种方式。 + + + + +JWT 可以用数字方式签名和加密。 +Kubernetes 将 JWT 用作身份验证令牌,以验证想要在集群中执行一些操作的实体的身份。 From 5a5504610aa25a50830aee2e8a4baef8eb9434cc Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 13 Feb 2023 21:03:24 +0800 Subject: [PATCH 206/279] [zh] sync /concepts/architecture/leases.md --- .../docs/concepts/architecture/leases.md | 84 ++++++++++++++----- 1 file changed, 65 insertions(+), 19 deletions(-) diff --git a/content/zh-cn/docs/concepts/architecture/leases.md b/content/zh-cn/docs/concepts/architecture/leases.md index 69e1a3f3fab..99d97870d0b 100644 --- a/content/zh-cn/docs/concepts/architecture/leases.md +++ b/content/zh-cn/docs/concepts/architecture/leases.md @@ -12,22 +12,26 @@ weight: 30 -分布式系统通常需要“租约”,它提供了一种机制来锁定共享资源并协调节点之间的活动。 -在 Kubernetes 中,“租约”概念表示为 `coordination.k8s.io` API 组中的 `Lease` 对象, +分布式系统通常需要**租约(Lease)**;租约提供了一种机制来锁定共享资源并协调集合成员之间的活动。 +在 Kubernetes 中,租约概念表示为 `coordination.k8s.io` +{{< glossary_tooltip text="API 组" term_id="api-group" >}}中的 +[Lease](/zh-cn/docs/reference/kubernetes-api/cluster-resources/lease-v1/) 对象, 常用于类似节点心跳和组件级领导者选举等系统核心能力。 ## 领导者选举 {#leader-election} -租约在 Kubernetes 中还用于确保在任何给定时间某个组件只有一个实例在运行。 +Kubernetes 也使用 Lease 确保在任何给定时间某个组件只有一个实例在运行。 这在高可用配置中由 `kube-controller-manager` 和 `kube-scheduler` 等控制平面组件进行使用, 这些组件只应有一个实例激活运行,而其他实例待机。 ## API 服务器身份 {#api-server-identity} @@ -81,7 +85,10 @@ Kubernetes 控制平面。kube-apiserver 租约的存在使得未来可以在各 kube-apiserver 拥有的租约。你还可以使用标签选择算符 `k8s.io/component=kube-apiserver`: ```shell -$ kubectl -n kube-system get lease -l k8s.io/component=kube-apiserver +kubectl -n kube-system get lease -l k8s.io/component=kube-apiserver +``` + +``` NAME HOLDER AGE kube-apiserver-c4vwjftbvpc5os2vvzle4qg27a kube-apiserver-c4vwjftbvpc5os2vvzle4qg27a_9cbf54e5-1136-44bd-8f9a-1dcd15c346b4 5m33s kube-apiserver-dz2dqprdpsgnm756t5rnov7yka kube-apiserver-dz2dqprdpsgnm756t5rnov7yka_84f2a85d-37c1-4b14-b6b9-603e62e4896f 4m23s @@ -89,14 +96,14 @@ kube-apiserver-fyloo45sdenffw2ugwaz3likua kube-apiserver-fyloo45sdenffw2ugwaz3 ``` -租约名称中使用的 SHA256 哈希基于 kube-apiserver 所看到的操作系统主机名生成。 +租约名称中使用的 SHA256 哈希基于 API 服务器所看到的操作系统主机名生成。 每个 kube-apiserver 都应该被配置为使用集群中唯一的主机名。 -使用相同主机名的 kube-apiserver 新实例将使用新的持有者身份接管现有租约,而不是实例化新的 Lease 对象。 +使用相同主机名的 kube-apiserver 新实例将使用新的持有者身份接管现有 Lease,而不是实例化新的 Lease 对象。 你可以通过检查 `kubernetes.io/hostname` 标签的值来查看 kube-apisever 所使用的主机名: ```shell @@ -123,5 +130,44 @@ spec: -kube-apiserver 中不再存续的已到期租约将在到期 1 小时后被新的 kube-apiservers 作为垃圾收集。 +kube-apiserver 中不再存续的已到期租约将在到期 1 小时后被新的 kube-apiserver 作为垃圾收集。 + +你可以通过禁用 `APIServerIdentity` +[特性门控](/zh-cn/docs/reference/command-line-tools-reference/feature-gates/)来禁用 API 服务器身份租约。 + + +## 工作负载 {#custom-workload} + +你自己的工作负载可以定义自己使用的 Lease。例如, +你可以运行自定义的{{< glossary_tooltip term_id="controller" text="控制器" >}}, +让主要成员或领导者成员在其中执行其对等方未执行的操作。 +你定义一个 Lease,以便控制器副本可以使用 Kubernetes API 进行协调以选择或选举一个领导者。 +如果你使用 Lease,良好的做法是为明显关联到产品或组件的 Lease 定义一个名称。 +例如,如果你有一个名为 Example Foo 的组件,可以使用名为 `example-foo` 的 Lease。 + + +如果集群操作员或其他终端用户可以部署一个组件的多个实例, +则选择名称前缀并挑选一种机制(例如 Deployment 名称的哈希)以避免 Lease 的名称冲突。 + +你可以使用另一种方式来达到相同的效果:不同的软件产品不相互冲突。 From cb5a8930dc10b1a22e7c44fbabb3dee6dc21936b Mon Sep 17 00:00:00 2001 From: Tim Bannister Date: Mon, 13 Feb 2023 18:04:50 +0000 Subject: [PATCH 207/279] Fix broken anchor --- content/en/docs/concepts/security/service-accounts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/docs/concepts/security/service-accounts.md b/content/en/docs/concepts/security/service-accounts.md index 5a5d973bac7..68c3299c91b 100644 --- a/content/en/docs/concepts/security/service-accounts.md +++ b/content/en/docs/concepts/security/service-accounts.md @@ -209,7 +209,7 @@ checks the token against the Secret. For more information about the authentication process, refer to [Authentication](/docs/reference/access-authn-authz/authentication/#service-account-tokens). -### Authenticating service account credentials in your own code {authenticating-in-code} +### Authenticating service account credentials in your own code {#authenticating-in-code} If you have services of your own that need to validate Kubernetes service account credentials, you can use the following methods: From 96d49317a2f3089c5f33dba58076f2d1689148e7 Mon Sep 17 00:00:00 2001 From: Tim Bannister Date: Mon, 13 Feb 2023 18:04:31 +0000 Subject: [PATCH 208/279] Fix wording for ServiceAccount concept Co-authored-by: Qiming Teng Co-authored-by: Shannon Kularathna --- .../concepts/security/service-accounts.md | 48 +++++++++++-------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/content/en/docs/concepts/security/service-accounts.md b/content/en/docs/concepts/security/service-accounts.md index 68c3299c91b..bd0a270964a 100644 --- a/content/en/docs/concepts/security/service-accounts.md +++ b/content/en/docs/concepts/security/service-accounts.md @@ -1,7 +1,7 @@ --- title: Service Accounts description: > - Learn about the Kubernetes ServiceAccount object. + Learn about ServiceAccount objects in Kubernetes. content_type: concept weight: 10 --- @@ -40,7 +40,8 @@ accounts have the following properties: the configurations portable. Service accounts are different from user accounts, which are authenticated -human users in the cluster. By default, user accounts don't exist in the Kubernetes API server; instead, the API server treats user identities as opaque +human users in the cluster. By default, user accounts don't exist in the Kubernetes +API server; instead, the API server treats user identities as opaque data. You can authenticate as a user account using multiple methods. Some Kubernetes distributions might add custom extension APIs to represent user accounts in the API server. @@ -61,9 +62,9 @@ When you create a cluster, Kubernetes automatically creates a ServiceAccount object named `default` for every namespace in your cluster. The `default` service accounts in each namespace get no permissions by default other than the [default API discovery permissions](/docs/reference/access-authn-authz/rbac/#default-roles-and-role-bindings) -that Kubernetes grants to all authenticated principals if role-based access control (RBAC) is enabled. If you delete the -`default` ServiceAccount object in a namespace, the -{{}} +that Kubernetes grants to all authenticated principals if role-based access control (RBAC) is enabled. +If you delete the `default` ServiceAccount object in a namespace, the +{{< glossary_tooltip text="control plane" term_id="control-plane" >}} replaces it with a new one. If you deploy a Pod in a namespace, and you don't @@ -164,11 +165,14 @@ location, or for an audience that isn't the API server, use one of the following methods: * [TokenRequest API](/docs/reference/kubernetes-api/authentication-resources/token-request-v1/) - (recommended): Request a short-lived service account token using your - *application code*. The token expires automatically and can rotate upon - expiration. + (recommended): Request a short-lived service account token from within + your own *application code*. The token expires automatically and can rotate + upon expiration. + If you have a legacy application that is not aware of Kubernetes, you + could use a sidecar container within the same pod to fetch these tokens + and make them available to the application workload. * [Token Volume Projection](/docs/tasks/configure-pod-container/configure-service-account/#service-account-token-volume-projection) - (recommended): In Kubernetes v1.20 and later, use the Pod specification to + (also recommended): In Kubernetes v1.20 and later, use the Pod specification to tell the kubelet to add the service account token to the Pod as a *projected volume*. Projected tokens expire automatically, and the kubelet rotates the token before it expires. @@ -179,7 +183,8 @@ following methods: with static, long-lived credentials. In Kubernetes v1.24 and later, the [LegacyServiceAccountTokenNoAutoGeneration feature gate](/docs/reference/command-line-tools-reference/feature-gates/#feature-gates-for-graduated-or-deprecated-features) prevents Kubernetes from automatically creating these tokens for - ServiceAccounts. + ServiceAccounts. `LegacyServiceAccountTokenNoAutoGeneration` is enabled + by default; in other words, Kubernetes does not create these tokens. ## Authenticating service account credentials {#authenticating-credentials} @@ -189,17 +194,21 @@ to authenticate to the Kubernetes API server, and to any other system where a trust relationship exists. Depending on how the token was issued (either time-limited using a `TokenRequest` or using a legacy mechanism with a Secret), a ServiceAccount token might also have an expiry time, an audience, -and a time after which the token *starts* being valid. When a process running -in a Pod attempts to communicate with the Kubernetes API server, it adds an -`Authorization: Bearer ` header to the HTTP request. The API server -checks the validity of the bearer token as follows: +and a time after which the token *starts* being valid. When a client that is +acting as a ServiceAccount tries to communicate with the Kubernetes API server, +the client includes an `Authorization: Bearer ` header with the HTTP +request. The API server checks the validity of that bearer token as follows: 1. Check the token signature. 1. Check whether the token has expired. -1. Checks whether object references in the token claims are currently valid +1. Check whether object references in the token claims are currently valid. 1. Check whether the token is currently valid. 1. Check the audience claims. +The TokenRequest API produces _bound tokens_ for a ServiceAccount. This +binding is linked to the lifetime of the client, such as a Pod, that is acting +as that ServiceAccount. + For tokens issued using the `TokenRequest` API, the API server also checks that the specific object reference that is using the ServiceAccount still exists, matching by the {{< glossary_tooltip term_id="uid" text="unique ID" >}} of that @@ -221,14 +230,15 @@ account credentials, you can use the following methods: The Kubernetes project recommends that you use the TokenReview API, because this method invalidates tokens that are bound to API objects such as Secrets, ServiceAccounts, and Pods when those objects are deleted. For example, if you -delete the Pod that contains a projected ServiceAccount token, the TokenReview -API invalidates that token immediately. If you use OIDC validation instead, your clients continue to treat the token as valid until the token reaches its -expiration timestamp. +delete the Pod that contains a projected ServiceAccount token, the cluster +invalidates that token immediately and a TokenReview immediately fails. +If you use OIDC validation instead, your clients continue to treat the token +as valid until the token reaches its expiration timestamp. Your application should always define the audience that it accepts, and should check that the token's audiences match the audiences that the application expects. This helps to minimize the scope of the token so that it can only be -used in your appplication and nowhere else. +used in your application and nowhere else. ## Alternatives From 14b83a1f8755c3cd56451065df8bded037ce45e1 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 14 Feb 2023 23:57:48 +0900 Subject: [PATCH 209/279] add weight to developing-cloud-controller-manager.md --- .../administer-cluster/developing-cloud-controller-manager.md | 1 + 1 file changed, 1 insertion(+) diff --git a/content/ja/docs/tasks/administer-cluster/developing-cloud-controller-manager.md b/content/ja/docs/tasks/administer-cluster/developing-cloud-controller-manager.md index d4f5a4e9fb8..2219eeea05e 100644 --- a/content/ja/docs/tasks/administer-cluster/developing-cloud-controller-manager.md +++ b/content/ja/docs/tasks/administer-cluster/developing-cloud-controller-manager.md @@ -1,6 +1,7 @@ --- title: クラウドコントローラーマネージャーの開発 content_type: concept +weight: 190 --- From f4082eefe9af4355a31141b04a1aa91bf1091278 Mon Sep 17 00:00:00 2001 From: Qiming Teng Date: Sun, 12 Feb 2023 14:37:32 +0800 Subject: [PATCH 210/279] [zh] Resync QoS Pod page --- .../quality-service-pod.md | 184 +++++++++++------- 1 file changed, 110 insertions(+), 74 deletions(-) diff --git a/content/zh-cn/docs/tasks/configure-pod-container/quality-service-pod.md b/content/zh-cn/docs/tasks/configure-pod-container/quality-service-pod.md index 58340ff47a9..d93b183fd19 100644 --- a/content/zh-cn/docs/tasks/configure-pod-container/quality-service-pod.md +++ b/content/zh-cn/docs/tasks/configure-pod-container/quality-service-pod.md @@ -14,29 +14,36 @@ weight: 30 -本页介绍怎样配置 Pod 让其获得特定的服务质量(QoS)类。Kubernetes 使用 QoS 类来决定 Pod 的调度和驱逐策略。 +本页介绍怎样配置 Pod 以让其归属于特定的 +{{< glossary_tooltip text="服务质量类(Quality of Service class,QoS class)" term_id="qos-class" >}}. +Kubernetes 在 Node 资源不足时使用 QoS 类来就驱逐 Pod 作出决定。 + + +Kubernetes 创建 Pod 时,会将如下 QoS 类之一设置到 Pod 上: + +* [Guaranteed](/zh-cn/docs/concepts/workloads/pods/pod-qos/#guaranteed) +* [Burstable](/zh-cn/docs/concepts/workloads/pods/pod-qos/#burstable) +* [BestEffort](/zh-cn/docs/concepts/workloads/pods/pod-qos/#besteffort) ## {{% heading "prerequisites" %}} -{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} - - +{{< include "task-tutorial-prereqs.md" >}} -## QoS 类 {#qos-classes} +你还需要能够创建和删除名字空间。 -Kubernetes 创建 Pod 时就给它指定了下列一种 QoS 类: - -* Guaranteed -* Burstable -* BestEffort + -## 创建命名空间 {#create-a-namespace} +## 创建名字空间 {#create-a-namespace} -创建一个命名空间,以便将本练习所创建的资源与集群的其余资源相隔离。 +创建一个名字空间,以便将本练习所创建的资源与集群的其余资源相隔离。 ```shell kubectl create namespace qos-example @@ -62,10 +69,6 @@ For a Pod to be given a QoS class of Guaranteed: * 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: --> ## 创建一个 QoS 类为 Guaranteed 的 Pod {#create-a-pod-that-gets-assigned-a-qos-class-of-guaranteed} @@ -76,11 +79,21 @@ memory request, both equal to 200 MiB. The Container has a CPU limit and a CPU r * Pod 中的每个容器都必须指定 CPU 限制和 CPU 请求。 * 对于 Pod 中的每个容器,CPU 限制必须等于 CPU 请求。 -这些限制同样适用于初始化容器和应用程序容器。 + + +这些限制同样适用于初始化容器和应用程序容器。 +[临时容器(Ephemeral Container)](/zh-cn/docs/concepts/workloads/pods/ephemeral-containers/) +无法定义资源,因此不受这些约束限制。 + +下面是包含一个 Container 的 Pod 清单。该 Container 设置了内存请求和内存限制,值都是 200 MiB。 +该 Container 设置了 CPU 请求和 CPU 限制,值都是 700 milliCPU: {{< codenew file="pods/qos/qos-pod.yaml" >}} @@ -133,10 +146,16 @@ automatically assigns a memory request that matches the limit. Similarly, if a C CPU limit, but does not specify a CPU request, Kubernetes automatically assigns a CPU request that matches the limit. --> -如果容器指定了自己的内存限制,但没有指定内存请求,Kubernetes 会自动为它指定与内存限制匹配的内存请求。 -同样,如果容器指定了自己的 CPU 限制,但没有指定 CPU 请求,Kubernetes 会自动为它指定与 CPU 限制匹配的 CPU 请求。 +如果某 Container 指定了自己的内存限制,但没有指定内存请求,Kubernetes +会自动为它指定与内存限制相等的内存请求。同样,如果容器指定了自己的 CPU 限制, +但没有指定 CPU 请求,Kubernetes 会自动为它指定与 CPU 限制相等的 CPU 请求。 {{< /note >}} + +#### 清理 {#clean-up-guaranteed} + @@ -149,23 +168,23 @@ kubectl delete pod qos-demo --namespace=qos-example ## 创建一个 QoS 类为 Burstable 的 Pod {#create-a-pod-that-gets-assigned-a-qos-class-of-burstable} -如果满足下面条件,将会指定 Pod 的 QoS 类为 Burstable: +如果满足下面条件,Kubernetes 将会指定 Pod 的 QoS 类为 `Burstable`: -* Pod 不符合 Guaranteed QoS 类的标准。 -* Pod 中至少一个容器具有内存或 CPU 的请求或限制。 +* Pod 不符合 `Guaranteed` QoS 类的标准。 +* Pod 中至少一个 Container 具有内存或 CPU 的请求或限制。 -下面是包含一个容器的 Pod 配置文件。 -该容器设置了内存限制 200 MiB 和内存请求 100 MiB。 +下面是包含一个 Container 的 Pod 清单。该 Container 设置的内存限制为 200 MiB, +内存请求为 100 MiB。 {{< codenew file="pods/qos/qos-pod-2.yaml" >}} @@ -188,9 +207,9 @@ kubectl get pod qos-demo-2 --namespace=qos-example --output=yaml ``` -结果表明 Kubernetes 为 Pod 配置的 QoS 类为 Burstable。 +结果表明 Kubernetes 为 Pod 配置的 QoS 类为 `Burstable`。 ```yaml spec: @@ -208,6 +227,11 @@ status: qosClass: Burstable ``` + +#### 清理 {#clean-up-burstable} + @@ -220,7 +244,7 @@ kubectl delete pod qos-demo-2 --namespace=qos-example ## 创建一个 QoS 类为 BestEffort 的 Pod {#create-a-pod-that-gets-assigned-a-qos-class-of-besteffort} -对于 QoS 类为 BestEffort 的 Pod,Pod 中的容器必须没有设置内存和 CPU 限制或请求。 +对于 QoS 类为 `BestEffort` 的 Pod,Pod 中的 Container 必须没有设置内存和 CPU 限制或请求。 -下面是包含一个容器的 Pod 配置文件。 -该容器没有设置内存和 CPU 限制或请求。 +下面是包含一个 Container 的 Pod 清单。该 Container 没有设置内存和 CPU 限制或请求。 {{< codenew file="pods/qos/qos-pod-3.yaml" >}} @@ -254,9 +277,9 @@ kubectl get pod qos-demo-3 --namespace=qos-example --output=yaml ``` -结果表明 Kubernetes 为 Pod 配置的 QoS 类为 BestEffort。 +结果表明 Kubernetes 为 Pod 配置的 QoS 类为 `BestEffort`。 ```yaml spec: @@ -268,6 +291,11 @@ status: qosClass: BestEffort ``` + +#### 清理 {#clean-up-besteffort} + @@ -285,20 +313,19 @@ request of 200 MiB. The other Container does not specify any requests or limits. --> ## 创建包含两个容器的 Pod {#create-a-pod-that-has-two-containers} -下面是包含两个容器的 Pod 配置文件。 -一个容器指定了内存请求 200 MiB。 -另外一个容器没有指定任何请求和限制。 +下面是包含两个 Container 的 Pod 配置文件。一个 Container 指定内存请求为 200 MiB。 +另外一个 Container 没有指定任何请求或限制。 {{< codenew file="pods/qos/qos-pod-4.yaml" >}} -注意此 Pod 满足 Burstable QoS 类的标准。 -也就是说它不满足 Guaranteed QoS 类标准,因为它的一个容器设有内存请求。 +注意此 Pod 满足 `Burstable` QoS 类的标准。也就是说它不满足 Guaranteed QoS 类标准, +因为它的 Container 之一设有内存请求。 创建 Pod: @@ -316,9 +343,9 @@ kubectl get pod qos-demo-4 --namespace=qos-example --output=yaml ``` -结果表明 Kubernetes 为 Pod 配置的 QoS 类为 Burstable: +结果表明 Kubernetes 为 Pod 配置的 QoS 类为 `Burstable`: ```yaml spec: @@ -336,6 +363,31 @@ status: qosClass: Burstable ``` + +## 检视 Pod 的 QoS 类 {#retrieve-the-qos-class-for-a-pod} + + +你也可以只查看你所需要的字段,而不是查看所有字段: + +```bash +kubectl --namespace=qos-example get pod qos-demo-4 -o jsonpath='{ .status.qosClass}{"\n"}' +``` + +```none +Burstable +``` + + +## 清理 {#clean-up} + @@ -352,7 +404,7 @@ Delete your namespace: --> ## 环境清理 {#clean-up} -删除命名空间: +删除名字空间: ```shell kubectl delete namespace qos-example @@ -370,44 +422,28 @@ kubectl delete namespace qos-example ### 应用开发者参考 * [为 Pod 和容器分配内存资源](/zh-cn/docs/tasks/configure-pod-container/assign-memory-resource/) - * [为 Pod 和容器分配 CPU 资源](/zh-cn/docs/tasks/configure-pod-container/assign-cpu-resource/) - ### 集群管理员参考 -* [为命名空间配置默认的内存请求和限制](/zh-cn/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/) - -* [为命名空间配置默认的 CPU 请求和限制](/zh-cn/docs/tasks/administer-cluster/manage-resources/cpu-default-namespace/) - -* [为命名空间配置最小和最大内存限制](/zh-cn/docs/tasks/administer-cluster/manage-resources/memory-constraint-namespace/) - -* [为命名空间配置最小和最大 CPU 限制](/zh-cn/docs/tasks/administer-cluster/manage-resources/cpu-constraint-namespace/) - -* [为命名空间配置内存和 CPU 配额](/zh-cn/docs/tasks/administer-cluster/manage-resources/quota-memory-cpu-namespace/) - -* [为命名空间配置 Pod 配额](/zh-cn/docs/tasks/administer-cluster/manage-resources/quota-pod-namespace/) - +* [为名字空间配置默认的内存请求和限制](/zh-cn/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/) +* [为名字空间配置默认的 CPU 请求和限制](/zh-cn/docs/tasks/administer-cluster/manage-resources/cpu-default-namespace/) +* [为名字空间配置最小和最大内存限制](/zh-cn/docs/tasks/administer-cluster/manage-resources/memory-constraint-namespace/) +* [为名字空间配置最小和最大 CPU 限制](/zh-cn/docs/tasks/administer-cluster/manage-resources/cpu-constraint-namespace/) +* [为名字空间配置内存和 CPU 配额](/zh-cn/docs/tasks/administer-cluster/manage-resources/quota-memory-cpu-namespace/) +* [为名字空间配置 Pod 配额](/zh-cn/docs/tasks/administer-cluster/manage-resources/quota-pod-namespace/) * [为 API 对象配置配额](/zh-cn/docs/tasks/administer-cluster/quota-api-object/) - * [控制节点上的拓扑管理策略](/zh-cn/docs/tasks/administer-cluster/topology-manager/) From 47e6adfcc9721b34e4459019f2bfa21e69cc923b Mon Sep 17 00:00:00 2001 From: Todd Neal Date: Tue, 14 Feb 2023 09:27:50 -0600 Subject: [PATCH 211/279] add a node indicating when nodeName should be used --- .../en/docs/concepts/scheduling-eviction/assign-pod-node.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/content/en/docs/concepts/scheduling-eviction/assign-pod-node.md b/content/en/docs/concepts/scheduling-eviction/assign-pod-node.md index c88274eb0b5..df3d3d3d640 100644 --- a/content/en/docs/concepts/scheduling-eviction/assign-pod-node.md +++ b/content/en/docs/concepts/scheduling-eviction/assign-pod-node.md @@ -461,6 +461,12 @@ Some of the limitations of using `nodeName` to select nodes are: - Node names in cloud environments are not always predictable or stable. +{{< note >}} +`nodeName` is intended for use by custom schedulers or advanced use cases where +you need to bypass any configured schedulers. Using affinity or a `nodeSelector` is +the recommended way to assign a pod to a node. +{{}} + Here is an example of a Pod spec using the `nodeName` field: ```yaml From f9a19295eecdadae988d73ca83a1a13e8a0db52d Mon Sep 17 00:00:00 2001 From: Todd Neal Date: Tue, 14 Feb 2023 09:51:42 -0600 Subject: [PATCH 212/279] Update content/en/docs/concepts/scheduling-eviction/assign-pod-node.md Co-authored-by: Aldo Culquicondor <1299064+alculquicondor@users.noreply.github.com> --- .../en/docs/concepts/scheduling-eviction/assign-pod-node.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/en/docs/concepts/scheduling-eviction/assign-pod-node.md b/content/en/docs/concepts/scheduling-eviction/assign-pod-node.md index df3d3d3d640..e6c793bf074 100644 --- a/content/en/docs/concepts/scheduling-eviction/assign-pod-node.md +++ b/content/en/docs/concepts/scheduling-eviction/assign-pod-node.md @@ -463,8 +463,8 @@ Some of the limitations of using `nodeName` to select nodes are: {{< note >}} `nodeName` is intended for use by custom schedulers or advanced use cases where -you need to bypass any configured schedulers. Using affinity or a `nodeSelector` is -the recommended way to assign a pod to a node. +you need to bypass any configured schedulers. Bypassing the schedulers might lead to +failed Pods if the assigned Nodes get oversubscribed. You can use [node affinity](#node-affinity) or a the [`nodeselector` field](#nodeselector) to assign a Pod to a specific Node without bypassing the schedulers. {{}} Here is an example of a Pod spec using the `nodeName` field: From f15f257ff3cc4587284e4ad678e1f5272408122b Mon Sep 17 00:00:00 2001 From: Natali Vlatko Date: Tue, 14 Feb 2023 17:03:32 +0100 Subject: [PATCH 213/279] Katacoda shutdown notice for the Kubernetes blog (#39434) * Katacoda shutdown notice for the Kubernetes blog SIG Docs has confirmed with O'Reilly that Katacoda tutorials for the Kubernetes community will be shutting down on 31 March, 2023. This blog post serves as an announcement to the community, 6 weeks before the intended shutdown date. * Updating filename to correct format * Apply Rey's feedback adding link to GitHub discussion Co-authored-by: Rey Lejano * Fix issue with link in Markdown from review --------- Co-authored-by: Rey Lejano --- ...-kubernetes-tutorials-are-shutting-down.md | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 content/en/blog/_posts/free-katacoda-kubernetes-tutorials-are-shutting-down.md diff --git a/content/en/blog/_posts/free-katacoda-kubernetes-tutorials-are-shutting-down.md b/content/en/blog/_posts/free-katacoda-kubernetes-tutorials-are-shutting-down.md new file mode 100644 index 00000000000..f5319025303 --- /dev/null +++ b/content/en/blog/_posts/free-katacoda-kubernetes-tutorials-are-shutting-down.md @@ -0,0 +1,36 @@ +--- +layout: blog +title: "Free Katacoda Kubernetes Tutorials Are Shutting Down" +date: 2023-02-14 +slug: kubernetes-katacoda-tutorials-stop-from-2023-03-31 +evergreen: true +--- + +**Author**: Natali Vlatko, SIG Docs Co-Chair for Kubernetes + +[Katacoda](https://katacoda.com/kubernetes), the popular learning platform from O’Reilly that has been helping people learn all about +Java, Docker, Kubernetes, Python, Go, C++, and more, [shut down for public use in June 2022](https://www.oreilly.com/online-learning/leveraging-katacoda-technology.html). +However, tutorials specifically for Kubernetes, linked from the Kubernetes website for our project’s +users and contributors, remained available and active after this change. Unfortunately, this will no +longer be the case, and Katacoda tutorials for learning Kubernetes will cease working after March 31st, 2023. + +The Kubernetes Project wishes to thank O'Reilly Media for the many years it has supported the community +via the Katacoda learning platform. You can read more about [the decision to shutter katacoda.com](https://www.oreilly.com/online-learning/leveraging-katacoda-technology.html) +on O'Reilly's own site. With this change, we’ll be focusing on the work needed to remove links to +their various tutorials. We have a general issue tracking this topic at [#33936](https://github.com/kubernetes/website/issues/33936) and [GitHub discussion](https://github.com/kubernetes/website/discussions/38878). We’re also +interested in researching what other learning platforms could be beneficial for the Kubernetes community, +replacing Katacoda with a link to a platform or service that has a similar user experience. However, +this research will take time, so we’re actively looking for volunteers to help with this work. +If a replacement is found, it will need to be supported by Kubernetes leadership, specifically, +SIG Contributor Experience, SIG Docs, and the Kubernetes Steering Committee. + +The Katacoda shutdown affects 25 tutorial pages, their localizations, as well as the Katacoda +Scenario repository: [github.com/katacoda-scenarios/kubernetes-bootcamp-scenarios](https://github.com/katacoda-scenarios/kubernetes-bootcamp-scenarios). We recommend +that any links, guides, or documentation you have that points to the Katacoda learning platform be +updated immediately to reflect this change. While we have yet to find a replacement learning solution, +the Kubernetes website contains a lot of helpful documentation to support your continued learning and growth. +You can find all of our available documentation tutorials for Kubernetes at https://k8s.io/docs/tutorials/. + +If you have any questions regarding the Katacoda shutdown, or subsequent link removal from Kubernetes +tutorial pages, please feel free to comment on the [general issue tracking the shutdown](https://github.com/kubernetes/website/issues/33936), +or visit the #sig-docs channel on the Kubernetes Slack. From cf252ccf3e7232c6c1ac68b5f68a447c623e9bb0 Mon Sep 17 00:00:00 2001 From: carolina valencia Date: Tue, 14 Feb 2023 13:57:43 -0300 Subject: [PATCH 214/279] chore: after review --- content/es/docs/concepts/security/pod-security-policy.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/es/docs/concepts/security/pod-security-policy.md b/content/es/docs/concepts/security/pod-security-policy.md index c92008db060..b060f57bb5d 100644 --- a/content/es/docs/concepts/security/pod-security-policy.md +++ b/content/es/docs/concepts/security/pod-security-policy.md @@ -6,8 +6,8 @@ weight: 30 -{{% alert title="Función eliminada" color="warning" %}} -PodSecurityPolicy está en [deprecación](/blog/2021/04/08/kubernetes-1-21-release-announcement/#podsecuritypolicy-deprecation) +{{% alert title="Funcionalidad eliminada" color="warning" %}} +PodSecurityPolicy está en [obsoleto](/blog/2021/04/08/kubernetes-1-21-release-announcement/#podsecuritypolicy-deprecation) en Kubernetes v1.21, y removida desde Kubernetes v1.25. {{% /alert %}} @@ -20,7 +20,7 @@ cualquiera o los dos: Para obtener una guía de migración, consulte [Migrar de PodSecurityPolicy al Controlador de Admisión de Seguridad de Pod Integrado](/docs/tasks/configure-pod-container/migrate-from-psp/). Para obtener más información sobre la eliminación de esta API, consulte -[Deprecación de PodSecurityPolicy: Pasado, Presente y Futuro](/blog/2021/04/06/podsecuritypolicy-deprecation-past-present-and-future/). +[Obsoleto de PodSecurityPolicy: Pasado, Presente y Futuro](/blog/2021/04/06/podsecuritypolicy-deprecation-past-present-and-future/). Si no está ejecutando Kubernetes v{{< skew currentVersion >}}, consulte la documentación para su versión de Kubernetes. From 84353cfa128ec9622c5ce1e97321d5cc6a96755c Mon Sep 17 00:00:00 2001 From: windsonsea Date: Wed, 15 Feb 2023 09:43:26 +0800 Subject: [PATCH 215/279] [zh] sync /security/pod-security-admission.md --- .../concepts/security/pod-security-admission.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/content/zh-cn/docs/concepts/security/pod-security-admission.md b/content/zh-cn/docs/concepts/security/pod-security-admission.md index 8c02233f3c7..df5a019f77f 100644 --- a/content/zh-cn/docs/concepts/security/pod-security-admission.md +++ b/content/zh-cn/docs/concepts/security/pod-security-admission.md @@ -27,7 +27,7 @@ The Kubernetes [Pod Security Standards](/docs/concepts/security/pod-security-sta different isolation levels for Pods. These standards let you define how you want to restrict the behavior of pods in a clear, consistent fashion. --> -Kubernetes [Pod 安全性标准(Security Standards)](/zh-cn/docs/concepts/security/pod-security-standards/) +Kubernetes [Pod 安全性标准(Security Standard)](/zh-cn/docs/concepts/security/pod-security-standards/) 为 Pod 定义不同的隔离级别。这些标准能够让你以一种清晰、一致的方式定义如何限制 Pod 行为。 - [Pod 安全性标准](/zh-cn/docs/concepts/security/pod-security-standards/) - [强制实施 Pod 安全性标准](/zh-cn/docs/setup/best-practices/enforcing-pod-security-standards/) - [通过配置内置的准入控制器强制实施 Pod 安全性标准](/zh-cn/docs/tasks/configure-pod-container/enforce-standards-admission-controller/) - [使用名字空间标签来实施 Pod 安全性标准](/zh-cn/docs/tasks/configure-pod-container/enforce-standards-namespace-labels/) -- [从 PodSecurityPolicy 迁移到内置的 PodSecurity 准入控制器](/zh-cn/docs/tasks/configure-pod-container/migrate-from-psp/) + +如果你正运行较老版本的 Kubernetes,想要升级到不包含 PodSecurityPolicy 的 Kubernetes 版本, +可以参阅[从 PodSecurityPolicy 迁移到内置的 PodSecurity 准入控制器](/zh-cn/docs/tasks/configure-pod-container/migrate-from-psp)。 From 0aa084fa3b5e53d53c6950bb2901608001bfd862 Mon Sep 17 00:00:00 2001 From: windsonsea Date: Wed, 15 Feb 2023 09:31:22 +0800 Subject: [PATCH 216/279] [zh] sync /scheduling-eviction/assign-pod-node.md --- .../concepts/scheduling-eviction/assign-pod-node.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/content/zh-cn/docs/concepts/scheduling-eviction/assign-pod-node.md b/content/zh-cn/docs/concepts/scheduling-eviction/assign-pod-node.md index 4f58e3541eb..32c00c54635 100644 --- a/content/zh-cn/docs/concepts/scheduling-eviction/assign-pod-node.md +++ b/content/zh-cn/docs/concepts/scheduling-eviction/assign-pod-node.md @@ -815,6 +815,18 @@ Some of the limitations of using `nodeName` to select nodes are: 而其失败原因中会给出是否因为内存或 CPU 不足而造成无法运行。 - 在云环境中的节点名称并不总是可预测的,也不总是稳定的。 +{{< note >}} + +`nodeName` 旨在供自定义调度程序或需要绕过任何已配置调度程序的高级场景使用。 +如果已分配的 Node 负载过重,绕过调度程序可能会导致 Pod 失败。 +你可以使用[节点亲和性](#node-affinity)或 [`nodeselector` 字段](#nodeselector)将 +Pod 分配给特定 Node,而无需绕过调度程序。 +{{}} + From e36fc155505cd36b84f941af56c717f1f1c7a4cc Mon Sep 17 00:00:00 2001 From: windsonsea Date: Wed, 15 Feb 2023 14:51:04 +0800 Subject: [PATCH 217/279] [zh] Sync blog: free-katacoda-kubernetes-tutorials-are-shutting-down --- ...-kubernetes-tutorials-are-shutting-down.md | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 content/zh-cn/blog/_posts/free-katacoda-kubernetes-tutorials-are-shutting-down.md diff --git a/content/zh-cn/blog/_posts/free-katacoda-kubernetes-tutorials-are-shutting-down.md b/content/zh-cn/blog/_posts/free-katacoda-kubernetes-tutorials-are-shutting-down.md new file mode 100644 index 00000000000..0b324e787e1 --- /dev/null +++ b/content/zh-cn/blog/_posts/free-katacoda-kubernetes-tutorials-are-shutting-down.md @@ -0,0 +1,79 @@ +--- +layout: blog +title: "免费的 Katacoda Kubernetes 教程即将关闭" +date: 2023-02-14 +slug: kubernetes-katacoda-tutorials-stop-from-2023-03-31 +evergreen: true +--- + + + +**作者**:Natali Vlatko,Kubernetes SIG Docs 联合主席 + +**译者**:Michael Yao (DaoCloud) + + +[Katacoda](https://katacoda.com/kubernetes) 是 O’Reilly 开设的热门学习平台, +帮助人们学习 Java、Docker、Kubernetes、Python、Go、C++ 和其他更多内容, +这个学习平台于 [2022 年 6 月停止对公众开放](https://www.oreilly.com/online-learning/leveraging-katacoda-technology.html)。 +但是,从 Kubernetes 网站为相关项目用户和贡献者关联的 Kubernetes 专门教程在那次变更后仍然可用并处于活跃状态。 +遗憾的是,接下来情况将发生变化,Katacoda 上有关学习 Kubernetes 的教程将在 2023 年 3 月 31 日之后彻底关闭。 + + +Kubernetes 项目感谢 O'Reilly Media 多年来通过 Katacoda 学习平台对 Kubernetes 社区的支持。 +你可以在 O'Reilly 自有的网站上阅读 +[the decision to shutter katacoda.com](https://www.oreilly.com/online-learning/leveraging-katacoda-technology.html) +有关的更多信息。此次变更之后,我们将专注于移除指向 Katacoda 各种教程的链接。 +我们通过 [Issue #33936](https://github.com/kubernetes/website/issues/33936) +和 [GitHub 讨论](https://github.com/kubernetes/website/discussions/38878)跟踪此主题相关的常规问题。 +我们也有兴趣调研其他哪些学习平台可能对 Kubernetes 社区有益,尝试将 Katacoda 链接替换为具有类似用户体验的平台或服务。 +然而,这项调研需要时间,因此我们正在积极寻觅志愿者来协助完成这项工作。 +如果找到替代的平台,需要得到 Kubernetes 领导层的支持,特别是 +SIG Contributor Experience、SIG Docs 和 Kubernetes Steering Committee。 + + +Katacoda 的关闭会影响 25 个英文教程页面、对应的多语言页面以及 Katacoda Scenario仓库: +[github.com/katacoda-scenarios/kubernetes-bootcamp-scenarios](https://github.com/katacoda-scenarios/kubernetes-bootcamp-scenarios)。 +我们建议你立即更新指向 Katacoda 学习平台的所有链接、指南或文档,以反映这一变化。 +虽然我们还没有找到替代这个学习平台的解决方案,但 Kubernetes 网站本身就包含了大量有用的文档可助你继续学习和成长。 +你可以在 https://k8s.io/docs/tutorials/ 找到所有可用的 Kubernetes 文档教程。 + + +如果你对 Katacoda 关闭或后续从 Kubernetes 教程页面移除相关链接有任何疑问, +请在 [general issue tracking the shutdown](https://github.com/kubernetes/website/issues/33936) +上发表评论,或加入 Kubernetes Slack 的 #sig-docs 频道。 From 84af547628f31f785f321380d40c6ec9497f9887 Mon Sep 17 00:00:00 2001 From: David Hadas Date: Wed, 15 Feb 2023 12:24:48 +0200 Subject: [PATCH 218/279] Update index.md The post uses wrongly the term `Analysis` instead of using the term "Analytics" --- .../blog/_posts/2023-01-20-Security-Bahavior-Analysis/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/index.md b/content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/index.md index d10abcd5f3a..433fac80e40 100644 --- a/content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/index.md +++ b/content/en/blog/_posts/2023-01-20-Security-Bahavior-Analysis/index.md @@ -8,7 +8,7 @@ slug: security-behavior-analysis **Author:** David Hadas (IBM Research Labs) -_This post warns Devops from a false sense of security. Following security best practices when developing and configuring microservices do not result in non-vulnerable microservices. The post shows that although all deployed microservices are vulnerable, there is much that can be done to ensure microservices are not exploited. It explains how analyzing the behavior of clients and services from a security standpoint, named here **"Security-Behavior Analysis"**, can protect the deployed vulnerable microservices. It points to [Guard](http://knative.dev/security-guard), an open source project offering security-behavior monitoring and control of Kubernetes microservices presumed vulnerable._ +_This post warns Devops from a false sense of security. Following security best practices when developing and configuring microservices do not result in non-vulnerable microservices. The post shows that although all deployed microservices are vulnerable, there is much that can be done to ensure microservices are not exploited. It explains how analyzing the behavior of clients and services from a security standpoint, named here **"Security-Behavior Analytics"**, can protect the deployed vulnerable microservices. It points to [Guard](http://knative.dev/security-guard), an open source project offering security-behavior monitoring and control of Kubernetes microservices presumed vulnerable._ As cyber attacks continue to intensify in sophistication, organizations deploying cloud services continue to grow their cyber investments aiming to produce safe and non-vulnerable services. However, the year-by-year growth in cyber investments does not result in a parallel reduction in cyber incidents. Instead, the number of cyber incidents continues to grow annually. Evidently, organizations are doomed to fail in this struggle - no matter how much effort is made to detect and remove cyber weaknesses from deployed services, it seems offenders always have the upper hand. From bbd7aa8d29dda43c310e8a42b0a91a12680ceec0 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 15 Feb 2023 19:47:01 +0800 Subject: [PATCH 219/279] [zh] sync enforce-standards-namespace-labels.md --- .../enforce-standards-namespace-labels.md | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/content/zh-cn/docs/tasks/configure-pod-container/enforce-standards-namespace-labels.md b/content/zh-cn/docs/tasks/configure-pod-container/enforce-standards-namespace-labels.md index 6a0912f8e66..124bbf16bd2 100644 --- a/content/zh-cn/docs/tasks/configure-pod-container/enforce-standards-namespace-labels.md +++ b/content/zh-cn/docs/tasks/configure-pod-container/enforce-standards-namespace-labels.md @@ -1,7 +1,6 @@ --- title: 使用名字空间标签来实施 Pod 安全性标准 content_type: task -min-kubernetes-server-version: v1.22 --- +名字空间可以打上标签以强制执行 [Pod 安全性标准](/zh-cn/docs/concepts/security/pod-security-standards)。 [特权(privileged)](/zh-cn/docs/concepts/security/pod-security-standards/#privileged)、 [基线(baseline)](/zh-cn/docs/concepts/security/pod-security-standards/#baseline)和 -[受限(restricted)](/zh-cn/docs/concepts/security/pod-security-standards/#restricted) -这三种策略涵盖了广泛安全范围,并由 [Pod 安全](/zh-cn/docs/concepts/security/pod-security-admission/) - {{< glossary_tooltip text="准入控制器" term_id="admission-controller" >}}实现。 +[受限(restricted)](/zh-cn/docs/concepts/security/pod-security-standards/#restricted) +这三种策略涵盖了广泛安全范围,并由 +[Pod 安全](/zh-cn/docs/concepts/security/pod-security-admission/){{< glossary_tooltip text="准入控制器" term_id="admission-controller" >}}实现。 ## {{% heading "prerequisites" %}} -{{% version-check %}} - -- 确保 `PodSecurity` [特性门控](/zh-cn/docs/reference/command-line-tools-reference/feature-gates/#feature-gates-for-alpha-or-beta-features)已被启用。 +Pod 安全性准入(Pod Security Admission)在 Kubernetes v1.23 中作为 Beta 特性默认可用。 +从 1.25 版本起,此特性进阶至正式发布(Generally Available)。 + +{{% version-check %}} 下面的清单定义了一个 `my-baseline-namespace` 名字空间,其中 -- *阻止*任何不满足 `baseline` 策略要求的 Pods; +- **阻止**任何不满足 `baseline` 策略要求的 Pod; - 针对任何无法满足 `restricted` 策略要求的、已创建的 Pod 为用户生成警告信息, 并添加审计注解; - 将 `baseline` 和 `restricted` 策略的版本锁定到 v{{< skew currentVersion >}}。 @@ -89,7 +92,7 @@ namespaces. The Pod Security Standard checks will still be run in _dry run_ mode information about how the new policy would treat existing pods, without actually updating a policy. --> 在刚开始为名字空间评估安全性策略变更时,使用 `--dry-run` 标志是很有用的。 -Pod 安全性标准会在 _dry run(试运行)_ +Pod 安全性标准会在 **dry run(试运行)** 模式下运行,在这种模式下会生成新策略如何处理现有 Pod 的信息, 但不会真正更新策略。 From 681e433bb1e419f94a7a8eb2bd5940b64303a1e7 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 15 Feb 2023 20:18:56 +0800 Subject: [PATCH 220/279] Fix typo and add blank lines in enforce-standards-admission-controller --- .../enforce-standards-admission-controller.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/content/en/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md b/content/en/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md index 311a4d54759..614d5c3b56a 100644 --- a/content/en/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md +++ b/content/en/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md @@ -13,9 +13,11 @@ You can configure this admission controller to set cluster-wide defaults and [ex ## {{% heading "prerequisites" %}} Following an alpha release in Kubernetes v1.22, -Pod Security Admission becaome available by default in Kubernetes v1.23, as +Pod Security Admission became available by default in Kubernetes v1.23, as a beta. From version 1.25 onwards, Pod Security Admission is generally -available. {{% version-check %}} +available. + +{{% version-check %}} If you are not running Kubernetes {{< skew currentVersion >}}, you can switch to viewing this page in the documentation for the Kubernetes version that you @@ -29,7 +31,6 @@ For v1.23 and v1.24, use [v1beta1](https://v1-24.docs.kubernetes.io/docs/tasks/c For v1.22, use [v1alpha1](https://v1-22.docs.kubernetes.io/docs/tasks/configure-pod-container/enforce-standards-admission-controller/). {{< /note >}} - ```yaml apiVersion: apiserver.config.k8s.io/v1 # see compatibility note kind: AdmissionConfiguration @@ -63,6 +64,7 @@ plugins: # Array of namespaces to exempt. namespaces: [] ``` + {{< note >}} The above manifest needs to be specified via the `--admission-control-config-file` to kube-apiserver. {{< /note >}} From 5e86649304fe4ad206f1039c5f2613dc81a9bcea Mon Sep 17 00:00:00 2001 From: k0rventen Date: Wed, 15 Feb 2023 13:22:33 +0100 Subject: [PATCH 221/279] add french translation for task 'Define a Command and Arguments for a Container' --- .../tasks/inject-data-application/_index.md | 3 +- .../define-command-argument-container.md | 102 ++++++++++++++++++ content/fr/examples/pods/commands.yaml | 13 +++ 3 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 content/fr/docs/tasks/inject-data-application/define-command-argument-container.md create mode 100644 content/fr/examples/pods/commands.yaml diff --git a/content/fr/docs/tasks/inject-data-application/_index.md b/content/fr/docs/tasks/inject-data-application/_index.md index e6d3f386a4e..dbe02187c6c 100644 --- a/content/fr/docs/tasks/inject-data-application/_index.md +++ b/content/fr/docs/tasks/inject-data-application/_index.md @@ -1,4 +1,5 @@ --- -title: Injection des données dans les applications +title: "Injecter des données dans les applications" +description: Spécifier la configuration et paramètres pour les Pods qui exécutent vos charge de travail. weight: 30 --- diff --git a/content/fr/docs/tasks/inject-data-application/define-command-argument-container.md b/content/fr/docs/tasks/inject-data-application/define-command-argument-container.md new file mode 100644 index 00000000000..bd151e20f15 --- /dev/null +++ b/content/fr/docs/tasks/inject-data-application/define-command-argument-container.md @@ -0,0 +1,102 @@ +--- +title: Définir une commande et ses arguments pour un Container +content_type: task +weight: 10 +--- + + + +Cette page montre comment définir les commandes et arguments d'un container au sein d'un {{< glossary_tooltip term_id="pod" >}}. + + + + +## {{% heading "prerequisites" %}} + + +{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} + + + + + + +## Définir une commande et ses arguments à la création d'un Pod + +Lorsque vous créez un Pod, il est possible de définir une commande et des arguements pour les containers qui seront exécutes dans votre Pod. Pour définir une commande, ajoutez un champ `command` dans le fichier de configuration. Pour définir des arguments, ajoutez le champ `args` dans le fichier de configuration. La commande et les arguments qui sont définis ne peuvent être changés après la création du Pod. + +La commande et les arguments que vous définissez dans le fichier de configuration écrase la commande et les arguments définis par l'image utilisée par le container. Si vous définissez uniquement des arguments, la commande par défaut sera exécutée avec les arguments que vous avez configurés. +{{< note >}} +Le champ `command` correspond à `entrypoint` dans certains runtimes de containers. +{{< /note >}} + +Dans cet exercice, vous allez créer un Pod qui exécute un container. Le fichier de configuration pour le Pod défini une commande ainsi que deux arguments: +{{< codenew file="pods/commands.yaml" >}} + +1. Créer un Pod en utilisant le fichier YAML de configuration suivant: + + ```shell + kubectl apply -f https://k8s.io/examples/pods/commands.yaml + ``` + +1. Lister les Pods + + ```shell + kubectl get pods + ``` + + Le résultat montre que le container exécuté dans le Pod nommé container-demo a complété son exécution. + +1. Pour voir le résultat de la commade exécutée dans le container, on peut afficher les logs pour le Pod: + + ```shell + kubectl logs command-demo + ``` + + Le résultat montre les valeurs des variables d'environnement HOSTNAME et KUBERNETES_PORT: + + ``` + command-demo + tcp://10.3.240.1:443 + ``` + +## Utiliser des variables d'environnements dans les arguments + +Dans l'exemple précédent, vous avez défini des arguments en donnant +directement les valeurs en format string. +Il est aussi possible de définir des arguments en utilisant des variables d'environnement: + +```yaml +env: +- name: MESSAGE + value: "hello world" +command: ["/bin/echo"] +args: ["$(MESSAGE)"] +``` + +Il est donc possible de définir un argument pour un Pod en utilisant n'importe quelle méthode disponible pour définir des variables d'environnements, ce qui inclut les +[ConfigMaps](/docs/tasks/configure-pod-container/configure-pod-configmap/) +et les +[Secrets](/docs/concepts/configuration/secret/). + +{{< note >}} +Les variables d'environnements apparaissent ente parenthèses `"$(VAR)"`. +Cette écriture est requise pour que la variable soit correctement +interpolée dans les champs `command` ou `args`. +{{< /note >}} + +## Exécuter une commande à l'intérieur d'un shell + +Dans certains cas, certaines commandes nécéssitent d'être exécutées dans un shell. Par exemple, certaines commandes consistent en une chaine de commandes, ou un script shell. Pour exécuter une commande dans un shell, il est possible de wrapper la commande comme ceci: + +```shell +command: ["/bin/sh"] +args: ["-c", "while true; do echo hello; sleep 10;done"] +``` + +## {{% heading "whatsnext" %}} + + +* Aller plus loin dans la [configuration des pods et des containers](/docs/tasks/). +* Apprendre à [exécuter des commandes dans un container](/docs/tasks/debug/debug-application/get-shell-running-container/). +* Voir la [documentation de référence sur les containers](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#container-v1-core). diff --git a/content/fr/examples/pods/commands.yaml b/content/fr/examples/pods/commands.yaml new file mode 100644 index 00000000000..2327d258274 --- /dev/null +++ b/content/fr/examples/pods/commands.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Pod +metadata: + name: command-demo + labels: + purpose: demonstrate-command +spec: + containers: + - name: command-demo-container + image: debian + command: ["printenv"] + args: ["HOSTNAME", "KUBERNETES_PORT"] + restartPolicy: OnFailure From d0b3ba5ccea5138c06ece1ad9f4e4c2b0c5ef897 Mon Sep 17 00:00:00 2001 From: Grigoris Thanasoulas Date: Sat, 11 Feb 2023 12:19:41 +0200 Subject: [PATCH 222/279] Update DaemonSet guide Rewrite "How Daemon Pods are scheduled" section of the DaemonSet guide to align with the current state and be more clear. Signed-off-by: Grigoris Thanasoulas --- .../workloads/controllers/daemonset.md | 85 ++++++++++--------- 1 file changed, 47 insertions(+), 38 deletions(-) diff --git a/content/en/docs/concepts/workloads/controllers/daemonset.md b/content/en/docs/concepts/workloads/controllers/daemonset.md index 98147a6e647..19ad8e27c9e 100644 --- a/content/en/docs/concepts/workloads/controllers/daemonset.md +++ b/content/en/docs/concepts/workloads/controllers/daemonset.md @@ -105,30 +105,24 @@ If you do not specify either, then the DaemonSet controller will create Pods on ## How Daemon Pods are scheduled -### Scheduled by default scheduler +A DaemonSet ensures that all eligible nodes run a copy of a Pod. The DaemonSet +controller creates a Pod for each eligible node and adds the +`spec.affinity.nodeAffinity` field of the Pod to match the target host. After +the Pod is created, the default scheduler typically takes over and then binds +the Pod to the target host by setting the `.spec.nodeName` field. If the new +Pod cannot fit on the node, the default scheduler may preempt (evict) some of +the existing Pods based on the +[priority](/docs/concepts/scheduling-eviction/pod-priority-preemption/#pod-priority) +of the new Pod. -{{< feature-state for_k8s_version="1.17" state="stable" >}} +The user can specify a different scheduler for the Pods of the DamonSet, by +setting the `.spec.template.spec.schedulerName` field of the DaemonSet. -A DaemonSet ensures that all eligible nodes run a copy of a Pod. Normally, the -node that a Pod runs on is selected by the Kubernetes scheduler. However, -DaemonSet pods are created and scheduled by the DaemonSet controller instead. -That introduces the following issues: - -* Inconsistent Pod behavior: Normal Pods waiting to be scheduled are created - and in `Pending` state, but DaemonSet pods are not created in `Pending` - state. This is confusing to the user. -* [Pod preemption](/docs/concepts/scheduling-eviction/pod-priority-preemption/) - is handled by default scheduler. When preemption is enabled, the DaemonSet controller - will make scheduling decisions without considering pod priority and preemption. - -`ScheduleDaemonSetPods` allows you to schedule DaemonSets using the default -scheduler instead of the DaemonSet controller, by adding the `NodeAffinity` term -to the DaemonSet pods, instead of the `.spec.nodeName` term. The default -scheduler is then used to bind the pod to the target host. If node affinity of -the DaemonSet pod already exists, it is replaced (the original node affinity was -taken into account before selecting the target host). The DaemonSet controller only -performs these operations when creating or modifying DaemonSet pods, and no -changes are made to the `spec.template` of the DaemonSet. +The original node affinity specified at the +`.spec.template.spec.affinity.nodeAffinity` field (if specified) is taken into +consideration by the DaemonSet controller when evaluating the eligible nodes, +but is replaced on the created Pod with the node affinity that matches the name +of the eligible node. ```yaml nodeAffinity: @@ -141,25 +135,40 @@ nodeAffinity: - target-host-name ``` -In addition, `node.kubernetes.io/unschedulable:NoSchedule` toleration is added -automatically to DaemonSet Pods. The default scheduler ignores -`unschedulable` Nodes when scheduling DaemonSet Pods. -### Taints and Tolerations +### Taints and tolerations -Although Daemon Pods respect -[taints and tolerations](/docs/concepts/scheduling-eviction/taint-and-toleration/), -the following tolerations are added to DaemonSet Pods automatically according to -the related features. +The DaemonSet controller automatically adds a set of {{< glossary_tooltip +text="tolerations" term_id="toleration" >}} to DaemonSet Pods: -| Toleration Key | Effect | Version | Description | -| ---------------------------------------- | ---------- | ------- | ----------- | -| `node.kubernetes.io/not-ready` | NoExecute | 1.13+ | DaemonSet pods will not be evicted when there are node problems such as a network partition. | -| `node.kubernetes.io/unreachable` | NoExecute | 1.13+ | DaemonSet pods will not be evicted when there are node problems such as a network partition. | -| `node.kubernetes.io/disk-pressure` | NoSchedule | 1.8+ | DaemonSet pods tolerate disk-pressure attributes by default scheduler. | -| `node.kubernetes.io/memory-pressure` | NoSchedule | 1.8+ | DaemonSet pods tolerate memory-pressure attributes by default scheduler. | -| `node.kubernetes.io/unschedulable` | NoSchedule | 1.12+ | DaemonSet pods tolerate unschedulable attributes by default scheduler. | -| `node.kubernetes.io/network-unavailable` | NoSchedule | 1.12+ | DaemonSet pods, who uses host network, tolerate network-unavailable attributes by default scheduler. | +{{< table caption="Tolerations for DaemonSet pods" >}} + +| Toleration key | Effect | Details | +| --------------------------------------------------------------------------------------------------------------------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------- | +| [`node.kubernetes.io/not-ready`](/docs/reference/labels-annotations-taints/#node-kubernetes-io-not-ready) | `NoExecute` | DaemonSet Pods can be scheduled onto nodes that are not healthy or ready to accept Pods. Any DaemonSet Pods running on such nodes will not be evicted. | +| [`node.kubernetes.io/unreachable`](/docs/reference/labels-annotations-taints/#node-kubernetes-io-unreachable) | `NoExecute` | DaemonSet Pods can be scheduled onto nodes that are unreachable from the node controller. Any DaemonSet Pods running on such nodes will not be evicted. | +| [`node.kubernetes.io/disk-pressure`](/docs/reference/labels-annotations-taints/#node-kubernetes-io-disk-pressure) | `NoSchedule` | DaemonSet Pods can be scheduled onto nodes with disk pressure issues. | +| [`node.kubernetes.io/memory-pressure`](/docs/reference/labels-annotations-taints/#node-kubernetes-io-memory-pressure) | `NoSchedule` | DaemonSet Pods can be scheduled onto nodes with memory pressure issues. | +| [`node.kubernetes.io/pid-pressure`](/docs/reference/labels-annotations-taints/#node-kubernetes-io-pid-pressure) | `NoSchedule` | DaemonSet Pods can be scheduled onto nodes with process pressure issues. | +| [`node.kubernetes.io/unschedulable`](/docs/reference/labels-annotations-taints/#node-kubernetes-io-unschedulable) | `NoSchedule` | DaemonSet Pods can be scheduled onto nodes that are unschedulable. | +| [`node.kubernetes.io/network-unavailable`](/docs/reference/labels-annotations-taints/#node-kubernetes-io-network-unavailable) | `NoSchedule` | **Only added for DaemonSet Pods that request host networking**, i.e., Pods having `spec.hostNetwork: true`. Such DaemonSet Pods can be scheduled onto nodes with unavailable network.| + +{{< /table >}} + +You can add your own tolerations to the Pods of a Daemonset as well, by +defining these in the Pod template of the DaemonSet. + +Because the DaemonSet controller sets the +`node.kubernetes.io/unschedulable:NoSchedule` toleration automatically, +Kubernetes can run DaemonSet Pods on nodes that are marked as _unschedulable_. + +If you use a DaemonSet to provide an important node-level function, such as +[cluster networking](/docs/concepts/cluster-administration/networking/), it is +helpful that Kubernetes places DaemonSet Pods on nodes before they are ready. +For example, without that special toleration, you could end up in a deadlock +situation where the node is not marked as ready because the network plugin is +not running there, and at the same time the network plugin is not running on +that node because the node is not yet ready. ## Communicating with Daemon Pods From eb3cb4d410da5d3c524b4441a5bcd16f12b6007e Mon Sep 17 00:00:00 2001 From: k0rventen Date: Wed, 15 Feb 2023 23:27:44 +0100 Subject: [PATCH 223/279] final pass on typos & missing translations --- .../tasks/inject-data-application/_index.md | 2 +- .../define-command-argument-container.md | 28 ++++++++++++------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/content/fr/docs/tasks/inject-data-application/_index.md b/content/fr/docs/tasks/inject-data-application/_index.md index dbe02187c6c..6ec828ecba7 100644 --- a/content/fr/docs/tasks/inject-data-application/_index.md +++ b/content/fr/docs/tasks/inject-data-application/_index.md @@ -1,5 +1,5 @@ --- title: "Injecter des données dans les applications" -description: Spécifier la configuration et paramètres pour les Pods qui exécutent vos charge de travail. +description: Spécifier la configuration et paramètres pour les Pods qui exécutent vos charges de travail. weight: 30 --- diff --git a/content/fr/docs/tasks/inject-data-application/define-command-argument-container.md b/content/fr/docs/tasks/inject-data-application/define-command-argument-container.md index bd151e20f15..bf55910e445 100644 --- a/content/fr/docs/tasks/inject-data-application/define-command-argument-container.md +++ b/content/fr/docs/tasks/inject-data-application/define-command-argument-container.md @@ -23,23 +23,30 @@ Cette page montre comment définir les commandes et arguments d'un container au ## Définir une commande et ses arguments à la création d'un Pod -Lorsque vous créez un Pod, il est possible de définir une commande et des arguements pour les containers qui seront exécutes dans votre Pod. Pour définir une commande, ajoutez un champ `command` dans le fichier de configuration. Pour définir des arguments, ajoutez le champ `args` dans le fichier de configuration. La commande et les arguments qui sont définis ne peuvent être changés après la création du Pod. +Lorsque vous créez un Pod, il est possible de définir une commande et des arguments +pour les containers qui seront exécutés dans votre Pod. +Pour définir une commande, ajoutez un champ `command` dans le fichier de configuration. +Pour définir des arguments, ajoutez le champ `args` dans le fichier de configuration. +La commande et les arguments qui sont définis ne peuvent être changés après la création du Pod. -La commande et les arguments que vous définissez dans le fichier de configuration écrase la commande et les arguments définis par l'image utilisée par le container. Si vous définissez uniquement des arguments, la commande par défaut sera exécutée avec les arguments que vous avez configurés. +La commande et les arguments que vous définissez dans le fichier de configuration +écraseront la commande et les arguments définis par l'image utilisée par le container. +Si vous définissez uniquement des arguments, la commande par défaut sera exécutée avec les arguments que vous avez configurés. {{< note >}} Le champ `command` correspond à `entrypoint` dans certains runtimes de containers. {{< /note >}} -Dans cet exercice, vous allez créer un Pod qui exécute un container. Le fichier de configuration pour le Pod défini une commande ainsi que deux arguments: +Dans cet exercice, vous allez créer un Pod qui exécute un container. +Le fichier de configuration pour le Pod défini une commande ainsi que deux arguments: {{< codenew file="pods/commands.yaml" >}} -1. Créer un Pod en utilisant le fichier YAML de configuration suivant: +1. Créez un Pod en utilisant le fichier YAML de configuration suivant: ```shell kubectl apply -f https://k8s.io/examples/pods/commands.yaml ``` -1. Lister les Pods +1. Listez les Pods ```shell kubectl get pods @@ -60,10 +67,10 @@ Dans cet exercice, vous allez créer un Pod qui exécute un container. Le fichie tcp://10.3.240.1:443 ``` -## Utiliser des variables d'environnements dans les arguments +## Utiliser des variables d'environnement dans les arguments Dans l'exemple précédent, vous avez défini des arguments en donnant -directement les valeurs en format string. +directement les valeurs en format chaîne de caractères. Il est aussi possible de définir des arguments en utilisant des variables d'environnement: ```yaml @@ -74,7 +81,8 @@ command: ["/bin/echo"] args: ["$(MESSAGE)"] ``` -Il est donc possible de définir un argument pour un Pod en utilisant n'importe quelle méthode disponible pour définir des variables d'environnements, ce qui inclut les +Il est donc possible de définir un argument pour un Pod en utilisant n'importe +quelle méthode disponible pour définir des variables d'environnements, ce qui inclut les [ConfigMaps](/docs/tasks/configure-pod-container/configure-pod-configmap/) et les [Secrets](/docs/concepts/configuration/secret/). @@ -82,12 +90,12 @@ et les {{< note >}} Les variables d'environnements apparaissent ente parenthèses `"$(VAR)"`. Cette écriture est requise pour que la variable soit correctement -interpolée dans les champs `command` ou `args`. +développée dans les champs `command` ou `args`. {{< /note >}} ## Exécuter une commande à l'intérieur d'un shell -Dans certains cas, certaines commandes nécéssitent d'être exécutées dans un shell. Par exemple, certaines commandes consistent en une chaine de commandes, ou un script shell. Pour exécuter une commande dans un shell, il est possible de wrapper la commande comme ceci: +Dans certains cas, certaines commandes nécéssitent d'être exécutées dans un shell. Par exemple, certaines commandes consistent en une chaîne de commandes, ou un script shell. Pour exécuter une commande dans un shell, il est possible d'envelopper la commande comme ceci: ```shell command: ["/bin/sh"] From 296e40e619d13e5f466ffc242bb3fde041b344f0 Mon Sep 17 00:00:00 2001 From: seancrasto <103709488+seancrasto@users.noreply.github.com> Date: Wed, 15 Feb 2023 19:37:42 -0500 Subject: [PATCH 224/279] Update topology-aware-hints.md Added back to correct sentence --- .../docs/concepts/services-networking/topology-aware-hints.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/docs/concepts/services-networking/topology-aware-hints.md b/content/en/docs/concepts/services-networking/topology-aware-hints.md index 8d298d2627a..7a6d212476e 100644 --- a/content/en/docs/concepts/services-networking/topology-aware-hints.md +++ b/content/en/docs/concepts/services-networking/topology-aware-hints.md @@ -126,7 +126,7 @@ zone. 5. **A zone is not represented in hints:** If the kube-proxy is unable to find at least one endpoint with a hint targeting the zone it is running in, it falls - to using endpoints from all zones. This is most likely to happen as you add + back to using endpoints from all zones. This is most likely to happen as you add a new zone into your existing cluster. ## Constraints From b606edb0794c21b51b1b20310dcaaf7ce27cc45e Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 15 Feb 2023 20:02:06 +0800 Subject: [PATCH 225/279] [zh] sync enforce-standards-admission-controller.md --- .../enforce-standards-admission-controller.md | 51 ++++++++++++------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/content/zh-cn/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md b/content/zh-cn/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md index a83dcbb22f1..f526c26b253 100644 --- a/content/zh-cn/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md +++ b/content/zh-cn/docs/tasks/configure-pod-container/enforce-standards-admission-controller.md @@ -1,43 +1,66 @@ --- title: 通过配置内置准入控制器实施 Pod 安全标准 content_type: task -min-kubernetes-server-version: v1.22 --- - -在 v1.22 版本中,Kubernetes 提供一种内置的[准入控制器](/zh-cn/docs/reference/access-authn-authz/admission-controllers/#podsecurity) -用来强制实施 [Pod 安全标准](/zh-cn/docs/concepts/security/pod-security-standards)。 +Kubernetes 提供一种内置的[准入控制器](/zh-cn/docs/reference/access-authn-authz/admission-controllers/#podsecurity) +用来强制实施 [Pod 安全性标准](/zh-cn/docs/concepts/security/pod-security-standards)。 你可以配置此准入控制器来设置集群范围的默认值和[豁免选项](/zh-cn/docs/concepts/security/pod-security-admission/#exemptions)。 ## {{% heading "prerequisites" %}} + +Pod 安全性准入(Pod Security Admission)在 Kubernetes v1.22 作为 Alpha 特性发布, +在 Kubernetes v1.23 中作为 Beta 特性默认可用。从 1.25 版本起, +此特性进阶至正式发布(Generally Available)。 + {{% version-check %}} -- 确保 `PodSecurity` [特性门控](/zh-cn/docs/reference/command-line-tools-reference/feature-gates/#feature-gates-for-alpha-or-beta-features)已被启用。 +如果未运行 Kubernetes {{< skew currentVersion >}}, +你可以切换到与当前运行的 Kubernetes 版本所对应的文档。 ## 配置准入控制器 {#configure-the-admission-controller} +{{< note >}} + +`pod-security.admission.config.k8s.io/v1` 配置需要 v1.25+。 +对于 v1.23 和 v1.24,使用 +[v1beta1](https://v1-24.docs.kubernetes.io/zh-cn/docs/tasks/configure-pod-container/enforce-standards-admission-controller/)。 +对于 v1.22,使用 +[v1alpha1](https://v1-22.docs.kubernetes.io/docs/tasks/configure-pod-container/enforce-standards-admission-controller/)。 +{{< /note >}} + ```yaml -apiVersion: apiserver.config.k8s.io/v1 +apiVersion: apiserver.config.k8s.io/v1 # 查阅兼容性说明 kind: AdmissionConfiguration plugins: - name: PodSecurity @@ -77,13 +100,3 @@ The above manifest needs to be specified via the `--admission-control-config-fil 上面的清单需要通过 `--admission-control-config-file` 指定给 kube-apiserver。 {{< /note >}} -{{< note >}} - -`pod-security.admission.config.k8s.io/v1` 配置需要 v1.25+。 -对于 v1.23 和 v1.24,使用 [v1beta1](https://v1-24.docs.kubernetes.io/zh-cn/docs/tasks/configure-pod-container/enforce-standards-admission-controller/)。 -对于 v1.22,使用 [v1alpha1](https://v1-22.docs.kubernetes.io/docs/tasks/configure-pod-container/enforce-standards-admission-controller/)。 -{{< /note >}} From 4ae516aee8cd16b771e7cd1857daa08e0ff90256 Mon Sep 17 00:00:00 2001 From: windsonsea Date: Thu, 16 Feb 2023 09:51:12 +0800 Subject: [PATCH 226/279] Tweak line wrappings in PV storage concepts --- .../concepts/storage/persistent-volumes.md | 361 +++++++++++++----- 1 file changed, 267 insertions(+), 94 deletions(-) diff --git a/content/en/docs/concepts/storage/persistent-volumes.md b/content/en/docs/concepts/storage/persistent-volumes.md index 2ae3d42964d..13ede898e59 100644 --- a/content/en/docs/concepts/storage/persistent-volumes.md +++ b/content/en/docs/concepts/storage/persistent-volumes.md @@ -16,25 +16,45 @@ weight: 20 -This document describes _persistent volumes_ in Kubernetes. Familiarity with [volumes](/docs/concepts/storage/volumes/) is suggested. +This document describes _persistent volumes_ in Kubernetes. Familiarity with +[volumes](/docs/concepts/storage/volumes/) is suggested. ## Introduction -Managing storage is a distinct problem from managing compute instances. The PersistentVolume subsystem provides an API for users and administrators that abstracts details of how storage is provided from how it is consumed. To do this, we introduce two new API resources: PersistentVolume and PersistentVolumeClaim. +Managing storage is a distinct problem from managing compute instances. +The PersistentVolume subsystem provides an API for users and administrators +that abstracts details of how storage is provided from how it is consumed. +To do this, we introduce two new API resources: PersistentVolume and PersistentVolumeClaim. -A _PersistentVolume_ (PV) is a piece of storage in the cluster that has been provisioned by an administrator or dynamically provisioned using [Storage Classes](/docs/concepts/storage/storage-classes/). It is a resource in the cluster just like a node is a cluster resource. PVs are volume plugins like Volumes, but have a lifecycle independent of any individual Pod that uses the PV. This API object captures the details of the implementation of the storage, be that NFS, iSCSI, or a cloud-provider-specific storage system. +A _PersistentVolume_ (PV) is a piece of storage in the cluster that has been +provisioned by an administrator or dynamically provisioned using +[Storage Classes](/docs/concepts/storage/storage-classes/). It is a resource in +the cluster just like a node is a cluster resource. PVs are volume plugins like +Volumes, but have a lifecycle independent of any individual Pod that uses the PV. +This API object captures the details of the implementation of the storage, be that +NFS, iSCSI, or a cloud-provider-specific storage system. -A _PersistentVolumeClaim_ (PVC) is a request for storage by a user. It is similar to a Pod. Pods consume node resources and PVCs consume PV resources. Pods can request specific levels of resources (CPU and Memory). Claims can request specific size and access modes (e.g., they can be mounted ReadWriteOnce, ReadOnlyMany or ReadWriteMany, see [AccessModes](#access-modes)). +A _PersistentVolumeClaim_ (PVC) is a request for storage by a user. It is similar +to a Pod. Pods consume node resources and PVCs consume PV resources. Pods can +request specific levels of resources (CPU and Memory). Claims can request specific +size and access modes (e.g., they can be mounted ReadWriteOnce, ReadOnlyMany or +ReadWriteMany, see [AccessModes](#access-modes)). -While PersistentVolumeClaims allow a user to consume abstract storage resources, it is common that users need PersistentVolumes with varying properties, such as performance, for different problems. Cluster administrators need to be able to offer a variety of PersistentVolumes that differ in more ways than size and access modes, without exposing users to the details of how those volumes are implemented. For these needs, there is the _StorageClass_ resource. +While PersistentVolumeClaims allow a user to consume abstract storage resources, +it is common that users need PersistentVolumes with varying properties, such as +performance, for different problems. Cluster administrators need to be able to +offer a variety of PersistentVolumes that differ in more ways than size and access +modes, without exposing users to the details of how those volumes are implemented. +For these needs, there is the _StorageClass_ resource. See the [detailed walkthrough with working examples](/docs/tasks/configure-pod-container/configure-persistent-volume-storage/). ## Lifecycle of a volume and claim -PVs are resources in the cluster. PVCs are requests for those resources and also act as claim checks to the resource. The interaction between PVs and PVCs follows this lifecycle: +PVs are resources in the cluster. PVCs are requests for those resources and also act +as claim checks to the resource. The interaction between PVs and PVCs follows this lifecycle: ### Provisioning @@ -42,7 +62,9 @@ There are two ways PVs may be provisioned: statically or dynamically. #### Static -A cluster administrator creates a number of PVs. They carry the details of the real storage, which is available for use by cluster users. They exist in the Kubernetes API and are available for consumption. +A cluster administrator creates a number of PVs. They carry the details of the +real storage, which is available for use by cluster users. They exist in the +Kubernetes API and are available for consumption. #### Dynamic @@ -55,7 +77,8 @@ provisioning to occur. Claims that request the class `""` effectively disable dynamic provisioning for themselves. To enable dynamic storage provisioning based on storage class, the cluster administrator -needs to enable the `DefaultStorageClass` [admission controller](/docs/reference/access-authn-authz/admission-controllers/#defaultstorageclass) +needs to enable the `DefaultStorageClass` +[admission controller](/docs/reference/access-authn-authz/admission-controllers/#defaultstorageclass) on the API server. This can be done, for example, by ensuring that `DefaultStorageClass` is among the comma-delimited, ordered list of values for the `--enable-admission-plugins` flag of the API server component. For more information on API server command-line flags, @@ -63,26 +86,51 @@ check [kube-apiserver](/docs/admin/kube-apiserver/) documentation. ### Binding -A user creates, or in the case of dynamic provisioning, has already created, a PersistentVolumeClaim with a specific amount of storage requested and with certain access modes. A control loop in the master watches for new PVCs, finds a matching PV (if possible), and binds them together. If a PV was dynamically provisioned for a new PVC, the loop will always bind that PV to the PVC. Otherwise, the user will always get at least what they asked for, but the volume may be in excess of what was requested. Once bound, PersistentVolumeClaim binds are exclusive, regardless of how they were bound. A PVC to PV binding is a one-to-one mapping, using a ClaimRef which is a bi-directional binding between the PersistentVolume and the PersistentVolumeClaim. +A user creates, or in the case of dynamic provisioning, has already created, +a PersistentVolumeClaim with a specific amount of storage requested and with +certain access modes. A control loop in the master watches for new PVCs, finds +a matching PV (if possible), and binds them together. If a PV was dynamically +provisioned for a new PVC, the loop will always bind that PV to the PVC. Otherwise, +the user will always get at least what they asked for, but the volume may be in +excess of what was requested. Once bound, PersistentVolumeClaim binds are exclusive, +regardless of how they were bound. A PVC to PV binding is a one-to-one mapping, +using a ClaimRef which is a bi-directional binding between the PersistentVolume +and the PersistentVolumeClaim. -Claims will remain unbound indefinitely if a matching volume does not exist. Claims will be bound as matching volumes become available. For example, a cluster provisioned with many 50Gi PVs would not match a PVC requesting 100Gi. The PVC can be bound when a 100Gi PV is added to the cluster. +Claims will remain unbound indefinitely if a matching volume does not exist. +Claims will be bound as matching volumes become available. For example, a +cluster provisioned with many 50Gi PVs would not match a PVC requesting 100Gi. +The PVC can be bound when a 100Gi PV is added to the cluster. ### Using -Pods use claims as volumes. The cluster inspects the claim to find the bound volume and mounts that volume for a Pod. For volumes that support multiple access modes, the user specifies which mode is desired when using their claim as a volume in a Pod. +Pods use claims as volumes. The cluster inspects the claim to find the bound +volume and mounts that volume for a Pod. For volumes that support multiple +access modes, the user specifies which mode is desired when using their claim +as a volume in a Pod. -Once a user has a claim and that claim is bound, the bound PV belongs to the user for as long as they need it. Users schedule Pods and access their claimed PVs by including a `persistentVolumeClaim` section in a Pod's `volumes` block. See [Claims As Volumes](#claims-as-volumes) for more details on this. +Once a user has a claim and that claim is bound, the bound PV belongs to the +user for as long as they need it. Users schedule Pods and access their claimed +PVs by including a `persistentVolumeClaim` section in a Pod's `volumes` block. +See [Claims As Volumes](#claims-as-volumes) for more details on this. ### Storage Object in Use Protection -The purpose of the Storage Object in Use Protection feature is to ensure that PersistentVolumeClaims (PVCs) in active use by a Pod and PersistentVolume (PVs) that are bound to PVCs are not removed from the system, as this may result in data loss. + +The purpose of the Storage Object in Use Protection feature is to ensure that +PersistentVolumeClaims (PVCs) in active use by a Pod and PersistentVolume (PVs) +that are bound to PVCs are not removed from the system, as this may result in data loss. {{< note >}} PVC is in active use by a Pod when a Pod object exists that is using the PVC. {{< /note >}} -If a user deletes a PVC in active use by a Pod, the PVC is not removed immediately. PVC removal is postponed until the PVC is no longer actively used by any Pods. Also, if an admin deletes a PV that is bound to a PVC, the PV is not removed immediately. PV removal is postponed until the PV is no longer bound to a PVC. +If a user deletes a PVC in active use by a Pod, the PVC is not removed immediately. +PVC removal is postponed until the PVC is no longer actively used by any Pods. Also, +if an admin deletes a PV that is bound to a PVC, the PV is not removed immediately. +PV removal is postponed until the PV is no longer bound to a PVC. -You can see that a PVC is protected when the PVC's status is `Terminating` and the `Finalizers` list includes `kubernetes.io/pvc-protection`: +You can see that a PVC is protected when the PVC's status is `Terminating` and the +`Finalizers` list includes `kubernetes.io/pvc-protection`: ```shell kubectl describe pvc hostpath @@ -98,7 +146,8 @@ Finalizers: [kubernetes.io/pvc-protection] ... ``` -You can see that a PV is protected when the PV's status is `Terminating` and the `Finalizers` list includes `kubernetes.io/pv-protection` too: +You can see that a PV is protected when the PV's status is `Terminating` and +the `Finalizers` list includes `kubernetes.io/pv-protection` too: ```shell kubectl describe pv task-pv-volume @@ -122,29 +171,48 @@ Events: ### Reclaiming -When a user is done with their volume, they can delete the PVC objects from the API that allows reclamation of the resource. The reclaim policy for a PersistentVolume tells the cluster what to do with the volume after it has been released of its claim. Currently, volumes can either be Retained, Recycled, or Deleted. +When a user is done with their volume, they can delete the PVC objects from the +API that allows reclamation of the resource. The reclaim policy for a PersistentVolume +tells the cluster what to do with the volume after it has been released of its claim. +Currently, volumes can either be Retained, Recycled, or Deleted. #### Retain -The `Retain` reclaim policy allows for manual reclamation of the resource. When the PersistentVolumeClaim is deleted, the PersistentVolume still exists and the volume is considered "released". But it is not yet available for another claim because the previous claimant's data remains on the volume. An administrator can manually reclaim the volume with the following steps. +The `Retain` reclaim policy allows for manual reclamation of the resource. +When the PersistentVolumeClaim is deleted, the PersistentVolume still exists +and the volume is considered "released". But it is not yet available for +another claim because the previous claimant's data remains on the volume. +An administrator can manually reclaim the volume with the following steps. -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. 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. -If you want to reuse the same storage asset, create a new PersistentVolume with the same storage asset definition. +If you want to reuse the same storage asset, create a new PersistentVolume with +the same storage asset definition. #### Delete -For volume plugins that support the `Delete` reclaim policy, deletion removes both the PersistentVolume object from Kubernetes, as well as the associated storage asset in the external infrastructure, such as an AWS EBS, GCE PD, Azure Disk, or Cinder volume. Volumes that were dynamically provisioned inherit the [reclaim policy of their StorageClass](#reclaim-policy), which defaults to `Delete`. The administrator should configure the StorageClass according to users' expectations; otherwise, the PV must be edited or patched after it is created. See [Change the Reclaim Policy of a PersistentVolume](/docs/tasks/administer-cluster/change-pv-reclaim-policy/). +For volume plugins that support the `Delete` reclaim policy, deletion removes +both the PersistentVolume object from Kubernetes, as well as the associated +storage asset in the external infrastructure, such as an AWS EBS, GCE PD, +Azure Disk, or Cinder volume. Volumes that were dynamically provisioned +inherit the [reclaim policy of their StorageClass](#reclaim-policy), which +defaults to `Delete`. The administrator should configure the StorageClass +according to users' expectations; otherwise, the PV must be edited or +patched after it is created. See +[Change the Reclaim Policy of a PersistentVolume](/docs/tasks/administer-cluster/change-pv-reclaim-policy/). #### Recycle {{< warning >}} -The `Recycle` reclaim policy is deprecated. Instead, the recommended approach is to use dynamic provisioning. +The `Recycle` reclaim policy is deprecated. Instead, the recommended approach +is to use dynamic provisioning. {{< /warning >}} -If supported by the underlying volume plugin, the `Recycle` reclaim policy performs a basic scrub (`rm -rf /thevolume/*`) on the volume and makes it available again for a new claim. +If supported by the underlying volume plugin, the `Recycle` reclaim policy performs +a basic scrub (`rm -rf /thevolume/*`) on the volume and makes it available again for a new claim. However, an administrator can configure a custom recycler Pod template using the Kubernetes controller manager command line arguments as described in the @@ -173,7 +241,8 @@ spec: mountPath: /scrub ``` -However, the particular path specified in the custom recycler Pod template in the `volumes` part is replaced with the particular path of the volume that is being recycled. +However, the particular path specified in the custom recycler Pod template in the +`volumes` part is replaced with the particular path of the volume that is being recycled. ### PersistentVolume deletion protection finalizer {{< feature-state for_k8s_version="v1.23" state="alpha" >}} @@ -181,10 +250,12 @@ However, the particular path specified in the custom recycler Pod template in th Finalizers can be added on a PersistentVolume to ensure that PersistentVolumes having `Delete` reclaim policy are deleted only after the backing storage are deleted. -The newly introduced finalizers `kubernetes.io/pv-controller` and `external-provisioner.volume.kubernetes.io/finalizer` +The newly introduced finalizers `kubernetes.io/pv-controller` and +`external-provisioner.volume.kubernetes.io/finalizer` are only added to dynamically provisioned volumes. -The finalizer `kubernetes.io/pv-controller` is added to in-tree plugin volumes. The following is an example +The finalizer `kubernetes.io/pv-controller` is added to in-tree plugin volumes. +The following is an example ```shell kubectl describe pv pvc-74a498d6-3929-47e8-8c02-078c1ece4d78 @@ -213,6 +284,7 @@ Events: The finalizer `external-provisioner.volume.kubernetes.io/finalizer` is added for CSI volumes. The following is an example: + ```shell Name: pvc-2f0bab97-85a8-4552-8044-eb8be45cf48d Labels: @@ -244,14 +316,17 @@ the `kubernetes.io/pv-controller` finalizer is replaced by the ### Reserving a PersistentVolume -The control plane can [bind PersistentVolumeClaims to matching PersistentVolumes](#binding) in the -cluster. However, if you want a PVC to bind to a specific PV, you need to pre-bind them. +The control plane can [bind PersistentVolumeClaims to matching PersistentVolumes](#binding) +in the cluster. However, if you want a PVC to bind to a specific PV, you need to pre-bind them. -By specifying a PersistentVolume in a PersistentVolumeClaim, you declare a binding between that specific PV and PVC. -If the PersistentVolume exists and has not reserved PersistentVolumeClaims through its `claimRef` field, then the PersistentVolume and PersistentVolumeClaim will be bound. +By specifying a PersistentVolume in a PersistentVolumeClaim, you declare a binding +between that specific PV and PVC. If the PersistentVolume exists and has not reserved +PersistentVolumeClaims through its `claimRef` field, then the PersistentVolume and +PersistentVolumeClaim will be bound. The binding happens regardless of some volume matching criteria, including node affinity. -The control plane still checks that [storage class](/docs/concepts/storage/storage-classes/), access modes, and requested storage size are valid. +The control plane still checks that [storage class](/docs/concepts/storage/storage-classes/), +access modes, and requested storage size are valid. ```yaml apiVersion: v1 @@ -265,7 +340,10 @@ spec: ... ``` -This method does not guarantee any binding privileges to the PersistentVolume. If other PersistentVolumeClaims could use the PV that you specify, you first need to reserve that storage volume. Specify the relevant PersistentVolumeClaim in the `claimRef` field of the PV so that other PVCs can not bind to it. +This method does not guarantee any binding privileges to the PersistentVolume. +If other PersistentVolumeClaims could use the PV that you specify, you first +need to reserve that storage volume. Specify the relevant PersistentVolumeClaim +in the `claimRef` field of the PV so that other PVCs can not bind to it. ```yaml apiVersion: v1 @@ -334,8 +412,9 @@ increased and that no resize is necessary. {{< feature-state for_k8s_version="v1.24" state="stable" >}} -Support for expanding CSI volumes is enabled by default but it also requires a specific CSI driver to support volume expansion. Refer to documentation of the specific CSI driver for more information. - +Support for expanding CSI volumes is enabled by default but it also requires a +specific CSI driver to support volume expansion. Refer to documentation of the +specific CSI driver for more information. #### Resizing a volume containing a file system @@ -364,22 +443,33 @@ FlexVolume resize is possible only when the underlying driver supports resize. {{< /note >}} {{< note >}} -Expanding EBS volumes is a time-consuming operation. Also, there is a per-volume quota of one modification every 6 hours. +Expanding EBS volumes is a time-consuming operation. +Also, there is a per-volume quota of one modification every 6 hours. {{< /note >}} #### Recovering from Failure when Expanding Volumes -If a user specifies a new size that is too big to be satisfied by underlying storage system, expansion of PVC will be continuously retried until user or cluster administrator takes some action. This can be undesirable and hence Kubernetes provides following methods of recovering from such failures. +If a user specifies a new size that is too big to be satisfied by underlying +storage system, expansion of PVC will be continuously retried until user or +cluster administrator takes some action. This can be undesirable and hence +Kubernetes provides following methods of recovering from such failures. {{< tabs name="recovery_methods" >}} {{% tab name="Manually with Cluster Administrator access" %}} -If expanding underlying storage fails, the cluster administrator can manually recover the Persistent Volume Claim (PVC) state and cancel the resize requests. Otherwise, the resize requests are continuously retried by the controller without administrator intervention. +If expanding underlying storage fails, the cluster administrator can manually +recover the Persistent Volume Claim (PVC) state and cancel the resize requests. +Otherwise, the resize requests are continuously retried by the controller without +administrator intervention. -1. Mark the PersistentVolume(PV) that is bound to the PersistentVolumeClaim(PVC) with `Retain` reclaim policy. -2. Delete the PVC. Since PV has `Retain` reclaim policy - we will not lose any data when we recreate the PVC. -3. Delete the `claimRef` entry from PV specs, so as new PVC can bind to it. This should make the PV `Available`. -4. Re-create the PVC with smaller size than PV and set `volumeName` field of the PVC to the name of the PV. This should bind new PVC to existing PV. +1. Mark the PersistentVolume(PV) that is bound to the PersistentVolumeClaim(PVC) + with `Retain` reclaim policy. +2. Delete the PVC. Since PV has `Retain` reclaim policy - we will not lose any data + when we recreate the PVC. +3. Delete the `claimRef` entry from PV specs, so as new PVC can bind to it. + This should make the PV `Available`. +4. Re-create the PVC with smaller size than PV and set `volumeName` field of the + PVC to the name of the PV. This should bind new PVC to existing PV. 5. Don't forget to restore the reclaim policy of the PV. {{% /tab %}} @@ -387,7 +477,11 @@ If expanding underlying storage fails, the cluster administrator can manually re {{% feature-state for_k8s_version="v1.23" state="alpha" %}} {{< note >}} -Recovery from failing PVC expansion by users is available as an alpha feature since Kubernetes 1.23. The `RecoverVolumeExpansionFailure` feature must be enabled for this feature to work. Refer to the [feature gate](/docs/reference/command-line-tools-reference/feature-gates/) documentation for more information. +Recovery from failing PVC expansion by users is available as an alpha feature +since Kubernetes 1.23. The `RecoverVolumeExpansionFailure` feature must be +enabled for this feature to work. Refer to the +[feature gate](/docs/reference/command-line-tools-reference/feature-gates/) +documentation for more information. {{< /note >}} If the feature gates `RecoverVolumeExpansionFailure` is @@ -397,7 +491,8 @@ smaller proposed size, edit `.spec.resources` for that PVC and choose a value th value you previously tried. This is useful if expansion to a higher value did not succeed because of capacity constraint. If that has happened, or you suspect that it might have, you can retry expansion by specifying a -size that is within the capacity limits of underlying storage provider. You can monitor status of resize operation by watching `.status.resizeStatus` and events on the PVC. +size that is within the capacity limits of underlying storage provider. You can monitor status of +resize operation by watching `.status.resizeStatus` and events on the PVC. Note that, although you can specify a lower amount of storage than what was requested previously, @@ -406,7 +501,6 @@ Kubernetes does not support shrinking a PVC to less than its current size. {{% /tab %}} {{% /tabs %}} - ## Types of Persistent Volumes PersistentVolume types are implemented as plugins. Kubernetes currently supports the following plugins: @@ -423,7 +517,8 @@ PersistentVolume types are implemented as plugins. Kubernetes currently supports * [`nfs`](/docs/concepts/storage/volumes/#nfs) - Network File System (NFS) storage * [`rbd`](/docs/concepts/storage/volumes/#rbd) - Rados Block Device (RBD) volume -The following types of PersistentVolume are deprecated. This means that support is still available but will be removed in a future Kubernetes release. +The following types of PersistentVolume are deprecated. +This means that support is still available but will be removed in a future Kubernetes release. * [`awsElasticBlockStore`](/docs/concepts/storage/volumes/#awselasticblockstore) - AWS Elastic Block Store (EBS) (**deprecated** in v1.17) @@ -483,14 +578,21 @@ spec: ``` {{< note >}} -Helper programs relating to the volume type may be required for consumption of a PersistentVolume within a cluster. In this example, the PersistentVolume is of type NFS and the helper program /sbin/mount.nfs is required to support the mounting of NFS filesystems. +Helper programs relating to the volume type may be required for consumption of +a PersistentVolume within a cluster. In this example, the PersistentVolume is +of type NFS and the helper program /sbin/mount.nfs is required to support the +mounting of NFS filesystems. {{< /note >}} ### Capacity -Generally, a PV will have a specific storage capacity. This is set using the PV's `capacity` attribute. Read the glossary term [Quantity](/docs/reference/glossary/?all=true#term-quantity) to understand the units expected by `capacity`. +Generally, a PV will have a specific storage capacity. This is set using the PV's +`capacity` attribute. Read the glossary term +[Quantity](/docs/reference/glossary/?all=true#term-quantity) to understand the units +expected by `capacity`. -Currently, storage size is the only resource that can be set or requested. Future attributes may include IOPS, throughput, etc. +Currently, storage size is the only resource that can be set or requested. +Future attributes may include IOPS, throughput, etc. ### Volume Mode @@ -515,12 +617,18 @@ for an example on how to use a volume with `volumeMode: Block` in a Pod. ### Access Modes -A PersistentVolume can be mounted on a host in any way supported by the resource provider. As shown in the table below, providers will have different capabilities and each PV's access modes are set to the specific modes supported by that particular volume. For example, NFS can support multiple read/write clients, but a specific NFS PV might be exported on the server as read-only. Each PV gets its own set of access modes describing that specific PV's capabilities. +A PersistentVolume can be mounted on a host in any way supported by the resource +provider. As shown in the table below, providers will have different capabilities +and each PV's access modes are set to the specific modes supported by that particular +volume. For example, NFS can support multiple read/write clients, but a specific +NFS PV might be exported on the server as read-only. Each PV gets its own set of +access modes describing that specific PV's capabilities. The access modes are: -`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. +`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. @@ -529,12 +637,14 @@ The access modes are: : 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 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. - +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: @@ -547,13 +657,15 @@ In the CLI, the access modes are abbreviated to: Kubernetes uses volume access modes to match PersistentVolumeClaims and PersistentVolumes. In some cases, the volume access modes also constrain where the PersistentVolume can be mounted. Volume access modes do **not** enforce write protection once the storage has been mounted. -Even if the access modes are specified as ReadWriteOnce, ReadOnlyMany, or ReadWriteMany, they don't set any constraints on the volume. -For example, even if a PersistentVolume is created as ReadOnlyMany, it is no guarantee that it will be read-only. -If the access modes are specified as ReadWriteOncePod, the volume is constrained and can be mounted on only a single Pod. +Even if the access modes are specified as ReadWriteOnce, ReadOnlyMany, or ReadWriteMany, +they don't set any constraints on the volume. For example, even if a PersistentVolume is +created as ReadOnlyMany, it is no guarantee that it will be read-only. If the access modes +are specified as ReadWriteOncePod, the volume is constrained and can be mounted on only a single Pod. {{< /note >}} -> __Important!__ A volume can only be mounted using one access mode at a time, even if it supports many. For example, a GCEPersistentDisk can be mounted as ReadWriteOnce by a single node or ReadOnlyMany by many nodes, but not at the same time. - +> __Important!__ A volume can only be mounted using one access mode at a time, +> even if it supports many. For example, a GCEPersistentDisk can be mounted as +> ReadWriteOnce by a single node or ReadOnlyMany by many nodes, but not at the same time. | Volume Plugin | ReadWriteOnce | ReadOnlyMany | ReadWriteMany | ReadWriteOncePod | | :--- | :---: | :---: | :---: | - | @@ -593,13 +705,16 @@ Current reclaim policies are: * Retain -- manual reclamation * Recycle -- basic scrub (`rm -rf /thevolume/*`) -* Delete -- associated storage asset such as AWS EBS, GCE PD, Azure Disk, or OpenStack Cinder volume is deleted +* Delete -- associated storage asset such as AWS EBS, GCE PD, Azure Disk, + or OpenStack Cinder volume is deleted -Currently, only NFS and HostPath support recycling. AWS EBS, GCE PD, Azure Disk, and Cinder volumes support deletion. +Currently, only NFS and HostPath support recycling. AWS EBS, GCE PD, Azure Disk, +and Cinder volumes support deletion. ### Mount Options -A Kubernetes administrator can specify additional mount options for when a Persistent Volume is mounted on a node. +A Kubernetes administrator can specify additional mount options for when a +Persistent Volume is mounted on a node. {{< note >}} Not all Persistent Volume types support mount options. @@ -627,10 +742,19 @@ it will become fully deprecated in a future Kubernetes release. ### Node Affinity {{< note >}} -For most volume types, you do not need to set this field. It is automatically populated for [AWS EBS](/docs/concepts/storage/volumes/#awselasticblockstore), [GCE PD](/docs/concepts/storage/volumes/#gcepersistentdisk) and [Azure Disk](/docs/concepts/storage/volumes/#azuredisk) volume block types. You need to explicitly set this for [local](/docs/concepts/storage/volumes/#local) volumes. +For most volume types, you do not need to set this field. It is automatically +populated for [AWS EBS](/docs/concepts/storage/volumes/#awselasticblockstore), +[GCE PD](/docs/concepts/storage/volumes/#gcepersistentdisk) and +[Azure Disk](/docs/concepts/storage/volumes/#azuredisk) volume block types. You +need to explicitly set this for [local](/docs/concepts/storage/volumes/#local) volumes. {{< /note >}} -A PV can specify node affinity to define constraints that limit what nodes this volume can be accessed from. Pods that use a PV will only be scheduled to nodes that are selected by the node affinity. To specify node affinity, set `nodeAffinity` in the `.spec` of a PV. The [PersistentVolume](/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-v1/#PersistentVolumeSpec) API reference has more details on this field. +A PV can specify node affinity to define constraints that limit what nodes this +volume can be accessed from. Pods that use a PV will only be scheduled to nodes +that are selected by the node affinity. To specify node affinity, set +`nodeAffinity` in the `.spec` of a PV. The +[PersistentVolume](/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-v1/#PersistentVolumeSpec) +API reference has more details on this field. ### Phase @@ -671,24 +795,35 @@ spec: ### Access Modes -Claims use [the same conventions as volumes](#access-modes) when requesting storage with specific access modes. +Claims use [the same conventions as volumes](#access-modes) when requesting +storage with specific access modes. ### Volume Modes -Claims use [the same convention as volumes](#volume-mode) to indicate the consumption of the volume as either a filesystem or block device. +Claims use [the same convention as volumes](#volume-mode) to indicate the +consumption of the volume as either a filesystem or block device. ### Resources -Claims, like Pods, can request specific quantities of a resource. In this case, the request is for storage. The same [resource model](https://git.k8s.io/design-proposals-archive/scheduling/resources.md) applies to both volumes and claims. +Claims, like Pods, can request specific quantities of a resource. In this case, +the request is for storage. The same +[resource model](https://git.k8s.io/design-proposals-archive/scheduling/resources.md) +applies to both volumes and claims. ### Selector -Claims can specify a [label selector](/docs/concepts/overview/working-with-objects/labels/#label-selectors) to further filter the set of volumes. Only the volumes whose labels match the selector can be bound to the claim. The selector can consist of two fields: +Claims can specify a +[label selector](/docs/concepts/overview/working-with-objects/labels/#label-selectors) +to further filter the set of volumes. Only the volumes whose labels match the selector +can be bound to the claim. The selector can consist of two fields: * `matchLabels` - the volume must have a label with this value -* `matchExpressions` - a list of requirements made by specifying key, list of values, and operator that relates the key and values. Valid operators include In, NotIn, Exists, and DoesNotExist. +* `matchExpressions` - a list of requirements made by specifying key, list of values, + and operator that relates the key and values. Valid operators include In, NotIn, + Exists, and DoesNotExist. -All of the requirements, from both `matchLabels` and `matchExpressions`, are ANDed together – they must all be satisfied in order to match. +All of the requirements, from both `matchLabels` and `matchExpressions`, are +ANDed together – they must all be satisfied in order to match. ### Class @@ -738,22 +873,38 @@ In the past, the annotation `volume.beta.kubernetes.io/storage-class` was used i of `storageClassName` attribute. This annotation is still working; however, it won't be supported in a future Kubernetes release. - #### Retroactive default StorageClass assignment {{< feature-state for_k8s_version="v1.26" state="beta" >}} -You can create a PersistentVolumeClaim without specifying a `storageClassName` for the new PVC, and you can do so even when no default StorageClass exists in your cluster. In this case, the new PVC creates as you defined it, and the `storageClassName` of that PVC remains unset until default becomes available. +You can create a PersistentVolumeClaim without specifying a `storageClassName` +for the new PVC, and you can do so even when no default StorageClass exists +in your cluster. In this case, the new PVC creates as you defined it, and the +`storageClassName` of that PVC remains unset until default becomes available. -When a default StorageClass becomes available, the control plane identifies any existing PVCs without `storageClassName`. For the PVCs that either have an empty value for `storageClassName` or do not have this key, the control plane then updates those PVCs to set `storageClassName` to match the new default StorageClass. If you have an existing PVC where the `storageClassName` is `""`, and you configure a default StorageClass, then this PVC will not get updated. +When a default StorageClass becomes available, the control plane identifies any +existing PVCs without `storageClassName`. For the PVCs that either have an empty +value for `storageClassName` or do not have this key, the control plane then +updates those PVCs to set `storageClassName` to match the new default StorageClass. +If you have an existing PVC where the `storageClassName` is `""`, and you configure +a default StorageClass, then this PVC will not get updated. -In order to keep binding to PVs with `storageClassName` set to `""` (while a default StorageClass is present), you need to set the `storageClassName` of the associated PVC to `""`. +In order to keep binding to PVs with `storageClassName` set to `""` +(while a default StorageClass is present), you need to set the `storageClassName` +of the associated PVC to `""`. -This behavior helps administrators change default StorageClass by removing the old one first and then creating or setting another one. This brief window while there is no default causes PVCs without `storageClassName` created at that time to not have any default, but due to the retroactive default StorageClass assignment this way of changing defaults is safe. +This behavior helps administrators change default StorageClass by removing the +old one first and then creating or setting another one. This brief window while +there is no default causes PVCs without `storageClassName` created at that time +to not have any default, but due to the retroactive default StorageClass +assignment this way of changing defaults is safe. ## Claims As Volumes -Pods access storage by using the claim as a volume. Claims must exist in the same namespace as the Pod using the claim. The cluster finds the claim in the Pod's namespace and uses it to get the PersistentVolume backing the claim. The volume is then mounted to the host and into the Pod. +Pods access storage by using the claim as a volume. Claims must exist in the +same namespace as the Pod using the claim. The cluster finds the claim in the +Pod's namespace and uses it to get the PersistentVolume backing the claim. +The volume is then mounted to the host and into the Pod. ```yaml apiVersion: v1 @@ -775,12 +926,15 @@ spec: ### A Note on Namespaces -PersistentVolumes binds are exclusive, and since PersistentVolumeClaims are namespaced objects, mounting claims with "Many" modes (`ROX`, `RWX`) is only possible within one namespace. +PersistentVolumes binds are exclusive, and since PersistentVolumeClaims are +namespaced objects, mounting claims with "Many" modes (`ROX`, `RWX`) is only +possible within one namespace. ### PersistentVolumes typed `hostPath` -A `hostPath` PersistentVolume uses a file or directory on the Node to emulate network-attached storage. -See [an example of `hostPath` typed volume](/docs/tasks/configure-pod-container/configure-persistent-volume-storage/#create-a-persistentvolume). +A `hostPath` PersistentVolume uses a file or directory on the Node to emulate +network-attached storage. See +[an example of `hostPath` typed volume](/docs/tasks/configure-pod-container/configure-persistent-volume-storage/#create-a-persistentvolume). ## Raw Block Volume Support @@ -819,6 +973,7 @@ spec: lun: 0 readOnly: false ``` + ### PersistentVolumeClaim requesting a Raw Block Volume {#persistent-volume-claim-requesting-a-raw-block-volume} ```yaml @@ -858,14 +1013,18 @@ spec: ``` {{< note >}} -When adding a raw block device for a Pod, you specify the device path in the container instead of a mount path. +When adding a raw block device for a Pod, you specify the device path in the +container instead of a mount path. {{< /note >}} ### Binding Block Volumes -If a user requests a raw block volume by indicating this using the `volumeMode` field in the PersistentVolumeClaim spec, the binding rules differ slightly from previous releases that didn't consider this mode as part of the spec. -Listed is a table of possible combinations the user and admin might specify for requesting a raw block device. The table indicates if the volume will be bound or not given the combinations: -Volume binding matrix for statically provisioned volumes: +If a user requests a raw block volume by indicating this using the `volumeMode` +field in the PersistentVolumeClaim spec, the binding rules differ slightly from +previous releases that didn't consider this mode as part of the spec. +Listed is a table of possible combinations the user and admin might specify for +requesting a raw block device. The table indicates if the volume will be bound or +not given the combinations: Volume binding matrix for statically provisioned volumes: | PV volumeMode | PVC volumeMode | Result | | --------------|:---------------:| ----------------:| @@ -880,15 +1039,19 @@ Volume binding matrix for statically provisioned volumes: | Filesystem | unspecified | BIND | {{< note >}} -Only statically provisioned volumes are supported for alpha release. Administrators should take care to consider these values when working with raw block devices. +Only statically provisioned volumes are supported for alpha release. Administrators +should take care to consider these values when working with raw block devices. {{< /note >}} ## Volume Snapshot and Restore Volume from Snapshot Support {{< feature-state for_k8s_version="v1.20" state="stable" >}} -Volume snapshots only support the out-of-tree CSI volume plugins. For details, see [Volume Snapshots](/docs/concepts/storage/volume-snapshots/). -In-tree volume plugins are deprecated. You can read about the deprecated volume plugins in the [Volume Plugin FAQ](https://github.com/kubernetes/community/blob/master/sig-storage/volume-plugin-faq.md). +Volume snapshots only support the out-of-tree CSI volume plugins. +For details, see [Volume Snapshots](/docs/concepts/storage/volume-snapshots/). +In-tree volume plugins are deprecated. You can read about the deprecated volume +plugins in the +[Volume Plugin FAQ](https://github.com/kubernetes/community/blob/master/sig-storage/volume-plugin-faq.md). ### Create a PersistentVolumeClaim from a Volume Snapshot {#create-persistent-volume-claim-from-volume-snapshot} @@ -912,7 +1075,8 @@ spec: ## Volume Cloning -[Volume Cloning](/docs/concepts/storage/volume-pvc-datasource/) only available for CSI volume plugins. +[Volume Cloning](/docs/concepts/storage/volume-pvc-datasource/) +only available for CSI volume plugins. ### Create PersistentVolumeClaim from an existing PVC {#create-persistent-volume-claim-from-an-existing-pvc} @@ -949,20 +1113,25 @@ same namespace, except for core objects other than PVCs. For clusters that have gate enabled, use of the `dataSourceRef` is preferred over `dataSource`. ## Cross namespace data sources + {{< feature-state for_k8s_version="v1.26" state="alpha" >}} Kubernetes supports cross namespace volume data sources. -To use cross namespace volume data sources, you must enable the `AnyVolumeDataSource` and `CrossNamespaceVolumeDataSource` +To use cross namespace volume data sources, you must enable the `AnyVolumeDataSource` +and `CrossNamespaceVolumeDataSource` [feature gates](/docs/reference/command-line-tools-reference/feature-gates/) for the kube-apiserver, kube-controller-manager. Also, you must enable the `CrossNamespaceVolumeDataSource` feature gate for the csi-provisioner. -Enabling the `CrossNamespaceVolumeDataSource` feature gate allow you to specify a namespace in the dataSourceRef field. +Enabling the `CrossNamespaceVolumeDataSource` feature gate allow you to specify +a namespace in the dataSourceRef field. + {{< note >}} When you specify a namespace for a volume data source, Kubernetes checks for a ReferenceGrant in the other namespace before accepting the reference. ReferenceGrant is part of the `gateway.networking.k8s.io` extension APIs. -See [ReferenceGrant](https://gateway-api.sigs.k8s.io/api-types/referencegrant/) in the Gateway API documentation for details. +See [ReferenceGrant](https://gateway-api.sigs.k8s.io/api-types/referencegrant/) +in the Gateway API documentation for details. This means that you must extend your Kubernetes cluster with at least ReferenceGrant from the Gateway API before you can use this mechanism. {{< /note >}} @@ -986,7 +1155,8 @@ users should be aware of: When the `CrossNamespaceVolumeDataSource` feature is enabled, there are additional differences: -* The `dataSource` field only allows local objects, while the `dataSourceRef` field allows objects in any namespaces. +* The `dataSource` field only allows local objects, while the `dataSourceRef` field allows + objects in any namespaces. * When namespace is specified, `dataSource` and `dataSourceRef` are not synced. Users should always use `dataSourceRef` on clusters that have the feature gate enabled, and @@ -1030,10 +1200,13 @@ responsibility of that populator controller to report Events that relate to volu the process. ### Using a cross-namespace volume data source + {{< feature-state for_k8s_version="v1.26" state="alpha" >}} Create a ReferenceGrant to allow the namespace owner to accept the reference. -You define a populated volume by specifying a cross namespace volume data source using the `dataSourceRef` field. You must already have a valid ReferenceGrant in the source namespace: +You define a populated volume by specifying a cross namespace volume data source +using the `dataSourceRef` field. You must already have a valid ReferenceGrant +in the source namespace: ```yaml apiVersion: gateway.networking.k8s.io/v1beta1 From e2a33136c2b31546205dd3a992936276e7ebbb96 Mon Sep 17 00:00:00 2001 From: Sajiyah Salat <109643863+Sajiyah-Salat@users.noreply.github.com> Date: Thu, 16 Feb 2023 08:10:47 +0530 Subject: [PATCH 227/279] Update names.md --- content/en/docs/concepts/overview/working-with-objects/names.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/content/en/docs/concepts/overview/working-with-objects/names.md b/content/en/docs/concepts/overview/working-with-objects/names.md index 22b0403dad1..b9294a14dc4 100644 --- a/content/en/docs/concepts/overview/working-with-objects/names.md +++ b/content/en/docs/concepts/overview/working-with-objects/names.md @@ -24,6 +24,8 @@ For non-unique user-provided attributes, Kubernetes provides [labels](/docs/conc {{< glossary_definition term_id="name" length="all" >}} +**Names are unique across [API versions](https://kubernetes.io/docs/concepts/overview/kubernetes-api/#api-groups-and-versioning) of the resource. API resources are distinguished by their API group, resource type, namespace (for namespaced resources), and name. In other words, API version is irrelevant in this context.** + {{< note >}} In cases when objects represent a physical entity, like a Node representing a physical host, when the host is re-created under the same name without deleting and re-creating the Node, Kubernetes treats the new host as the old one, which may lead to inconsistencies. {{< /note >}} From 721b220745cc1b20b73e4106bc29c684b17ed659 Mon Sep 17 00:00:00 2001 From: Jian Wen Date: Thu, 16 Feb 2023 10:51:44 +0800 Subject: [PATCH 228/279] Update cgroups.md Add an example of uber-go/automaxprocs which is used by lots of applications to avoid CPU throttling. Related to https://github.com/uber-go/automaxprocs/issues/49 --- content/en/docs/concepts/architecture/cgroups.md | 1 + 1 file changed, 1 insertion(+) diff --git a/content/en/docs/concepts/architecture/cgroups.md b/content/en/docs/concepts/architecture/cgroups.md index 377c073b42b..86627a65d18 100644 --- a/content/en/docs/concepts/architecture/cgroups.md +++ b/content/en/docs/concepts/architecture/cgroups.md @@ -103,6 +103,7 @@ updated to newer versions that support cgroup v2. For example: * If you run [cAdvisor](https://github.com/google/cadvisor) as a stand-alone DaemonSet for monitoring pods and containers, update it to v0.43.0 or later. * If you use JDK, prefer to use JDK 11.0.16 and later or JDK 15 and later, which [fully support cgroup v2](https://bugs.openjdk.org/browse/JDK-8230305). +* If you use uber-go/automaxprocs, update it to v1.5.1 or later. ## Identify the cgroup version on Linux Nodes {#check-cgroup-version} From aa686a8d3a36fe6fe01c8f58dc9708db0f45fb99 Mon Sep 17 00:00:00 2001 From: Sajiyah Salat <109643863+Sajiyah-Salat@users.noreply.github.com> Date: Thu, 16 Feb 2023 13:01:19 +0530 Subject: [PATCH 229/279] Update content/en/docs/concepts/overview/working-with-objects/names.md Co-authored-by: Qiming Teng --- .../en/docs/concepts/overview/working-with-objects/names.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/content/en/docs/concepts/overview/working-with-objects/names.md b/content/en/docs/concepts/overview/working-with-objects/names.md index b9294a14dc4..0b499386374 100644 --- a/content/en/docs/concepts/overview/working-with-objects/names.md +++ b/content/en/docs/concepts/overview/working-with-objects/names.md @@ -24,7 +24,9 @@ For non-unique user-provided attributes, Kubernetes provides [labels](/docs/conc {{< glossary_definition term_id="name" length="all" >}} -**Names are unique across [API versions](https://kubernetes.io/docs/concepts/overview/kubernetes-api/#api-groups-and-versioning) of the resource. API resources are distinguished by their API group, resource type, namespace (for namespaced resources), and name. In other words, API version is irrelevant in this context.** +**Names must be unique across all [API versions](/docs/concepts/overview/kubernetes-api/#api-groups-and-versioning) +of the same resource. API resources are distinguished by their API group, resource type, namespace +(for namespaced resources), and name. In other words, API version is irrelevant in this context.** {{< note >}} In cases when objects represent a physical entity, like a Node representing a physical host, when the host is re-created under the same name without deleting and re-creating the Node, Kubernetes treats the new host as the old one, which may lead to inconsistencies. From b9b8af1bdebd50f2cae8080298de7468fd74f264 Mon Sep 17 00:00:00 2001 From: Kirill Kononovich <41591254+kirkonru@users.noreply.github.com> Date: Wed, 6 Jul 2022 20:21:10 +0300 Subject: [PATCH 230/279] [ru] Add and translate logging.md Update content/ru/docs/concepts/cluster-administration/logging.md Co-authored-by: Dmitry Shurupov Update content/ru/docs/concepts/cluster-administration/logging.md Co-authored-by: Dmitry Shurupov Update content/ru/docs/concepts/cluster-administration/logging.md Co-authored-by: Dmitry Shurupov Update content/ru/docs/concepts/cluster-administration/logging.md Co-authored-by: Dmitry Shurupov Update content/ru/docs/concepts/cluster-administration/logging.md Co-authored-by: Dmitry Shurupov Update content/ru/docs/concepts/cluster-administration/logging.md Co-authored-by: Dmitry Shurupov Update content/ru/docs/concepts/cluster-administration/logging.md Co-authored-by: Dmitry Shurupov Update content/ru/docs/concepts/cluster-administration/logging.md Update content/ru/docs/concepts/cluster-administration/logging.md Add counter-pod.yaml Add two-files-counter-pod.yaml Add two-files-counter-pod.yaml Create two-files-counter-pod-streaming-sidecar.yaml Create fluentd-sidecar-config.yaml Create two-files-counter-pod-agent-sidecar.yaml --- .../cluster-administration/logging.md | 205 ++++++++++++++++++ .../admin/logging/fluentd-sidecar-config.yaml | 25 +++ .../two-files-counter-pod-agent-sidecar.yaml | 39 ++++ ...o-files-counter-pod-streaming-sidecar.yaml | 38 ++++ .../admin/logging/two-files-counter-pod.yaml | 26 +++ content/ru/examples/debug/counter-pod.yaml | 10 + 6 files changed, 343 insertions(+) create mode 100644 content/ru/docs/concepts/cluster-administration/logging.md create mode 100644 content/ru/examples/admin/logging/fluentd-sidecar-config.yaml create mode 100644 content/ru/examples/admin/logging/two-files-counter-pod-agent-sidecar.yaml create mode 100644 content/ru/examples/admin/logging/two-files-counter-pod-streaming-sidecar.yaml create mode 100644 content/ru/examples/admin/logging/two-files-counter-pod.yaml create mode 100644 content/ru/examples/debug/counter-pod.yaml diff --git a/content/ru/docs/concepts/cluster-administration/logging.md b/content/ru/docs/concepts/cluster-administration/logging.md new file mode 100644 index 00000000000..66bf34fca91 --- /dev/null +++ b/content/ru/docs/concepts/cluster-administration/logging.md @@ -0,0 +1,205 @@ +--- +reviewers: +title: Архитектура для сбора логов +content_type: concept +weight: 60 +--- + + + +Логи помогают понять, что происходит внутри приложения. Они особенно полезны для отладки проблем и мониторинга деятельности кластера. У большинства современных приложений имеется тот или иной механизм сбора логов. Контейнерные движки в этом смысле не исключение. Самый простой и наиболее распространенный метод сбора логов для контейнерных приложений задействует потоки `stdout` и `stderr`. + +Однако встроенной функциональности контейнерного движка или среды исполнения обычно недостаточно для организации полноценного решения по сбору логов. + +Например, может возникнуть необходимость просмотреть логи приложения при аварийном завершении работы Pod'а, его вытеснении (eviction) или "падении" узла. + +В кластере у логов должно быть отдельное хранилище и жизненный цикл, не зависящий от узлов, Pod'ов или контейнеров. Эта концепция называется _сбор логов на уровне кластера_. + + + +Архитектуры для сбора логов на уровне кластера требуют отдельного бэкенда для их хранения, анализа и выполнения запросов. Kubernetes не имеет собственного решения для хранения такого типа данных. Вместо этого существует множество продуктов для сбора логов, которые прекрасно с ним интегрируются. В последующих разделах описано, как обрабатывать логи и хранить их на узлах. + +## Основы сбора логов в Kubernetes + +В примере ниже используется спецификация `Pod` с контейнером для отправки текста в стандартный поток вывода раз в секунду. + +{{< codenew file="debug/counter-pod.yaml" >}} + +Запустить его можно с помощью следующей команды: + +```shell +kubectl apply -f https://k8s.io/examples/debug/counter-pod.yaml +``` + +Результат будет таким: + +```console +pod/counter created +``` + +Получить логи можно с помощью команды `kubectl logs`, как показано ниже: + +```shell +kubectl logs counter +``` + +Результат будет таким: + +```console +0: Mon Jan 1 00:00:00 UTC 2001 +1: Mon Jan 1 00:00:01 UTC 2001 +2: Mon Jan 1 00:00:02 UTC 2001 +... +``` + +Команда `kubectl logs --previous` позволяет извлечь логи из предыдущего воплощения контейнера. Если в Pod'е несколько контейнеров, выбрать нужный для извлечения логов можно с помощью флага `-c`: + +```console +kubectl logs counter -c count +``` + +Для получения дополнительной информации см. [документацию по `kubectl logs`](/docs/reference/generated/kubectl/kubectl-commands#logs). + +## Сбор логов на уровне узла + +![Сбор логов на уровне узла](/images/docs/user-guide/logging/logging-node-level.png) + +Среда исполнения для контейнера обрабатывает и перенаправляет любой вывод в потоки `stdout` и `stderr` приложения. Docker Engine, например, перенаправляет эти потоки [драйверу журналирования](https://docs.docker.com/engine/admin/logging/overview), который в Kubernetes настроен на запись в файл в формате JSON. + +{{< note >}} +JSON-драйвер Docker для сбора логов рассматривает каждую строку как отдельное сообщение. В данном случае поддержка многострочных сообщений отсутствует. Обработка многострочных сообщений должна выполняться на уровне лог-агента или выше. +{{< /note >}} + +По умолчанию, если контейнер перезапускается, kubelet сохраняет один завершенный контейнер с его логами. Если Pod вытесняется с узла, все соответствующие контейнеры также вытесняются вместе с их логами. + +Важным моментом при сборе логов на уровне узла является их ротация, чтобы логи не занимали все доступное место на узле. Kubernetes не отвечает за ротацию логов, но способен развернуть инструмент для решения этой проблемы. Например, в кластерах Kubernetes, развертываемых с помощью скрипта `kube-up.sh`, имеется инструмент [`logrotate`](https://linux.die.net/man/8/logrotate), настроенный на ежечасный запуск. Также можно настроить среду исполнения контейнера на автоматическую ротацию логов приложения. + +Подробную информацию о том, как `kube-up.sh` настраивает логирование для образа COS на GCP, можно найти в соответствующем скрипте [`configure-helper`](https://github.com/kubernetes/kubernetes/blob/master/cluster/gce/gci/configure-helper.sh). + +При использовании **среды исполнения контейнера CRI** kubelet отвечает за ротацию логов и управление структурой их директории. kubelet передает данные среде исполнения контейнера CRI, а та сохраняет логи контейнера в указанное место. С помощью параметров [`containerLogMaxSize` и `containerLogMaxFiles`](/docs/reference/config-api/kubelet-config.v1beta1/#kubelet-config-k8s-io-v1beta1-KubeletConfiguration) в [конфигурационном файле kubelet'а](/docs/tasks/administer-cluster/kubelet-config-file/) можно настроить максимальный размер каждого лог-файла и максимальное число таких файлов для каждого контейнера соответственно. + +При выполнении команды [`kubectl logs`](/docs/reference/generated/kubectl/kubectl-commands#logs) (как в примере из раздела про основы сбора логов) kubelet на узле обрабатывает запрос и считывает данные непосредственно из файла журнала. Затем он возвращает его содержимое. + +{{< note >}} +Если ротацию выполнила внешняя система или используется среда исполнения контейнера CRI, команде `kubectl logs` будет доступно содержимое только последнего лог-файла. Например, имеется файл размером 10 МБ, `logrotate` выполняет ротацию, и получается два файла: первый размером 10 МБ, второй - пустой. В этом случае `kubectl logs` вернет второй лог-файл (пустой). +{{< /note >}} + +### Логи системных компонентов + +Существует два типа системных компонентов: те, которые работают в контейнере, и те, которые работают за пределами контейнера. Например: + +* планировщик Kubernetes и kube-proxy выполняются в контейнере; +* kubelet и среда исполнения контейнера работают за пределами контейнера. + +На машинах с systemd среда исполнения и kubelet пишут в journald. Если systemd отсутствует, среда исполнения и kubelet пишут в файлы `.log` в директории `/var/log`. Системные компоненты внутри контейнеров всегда пишут в директорию `/var/log`, обходя механизм ведения логов по умолчанию. Они используют библиотеку для сбора логов [`klog`](https://github.com/kubernetes/klog). Правила сбора логов и рекомендации можно найти в соответствующей [документации](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/logging.md). + +Как и логи контейнеров, логи системных компонентов в директории `/var/log` необходимо ротировать. В кластерах Kubernetes, созданных с помощью скрипта `kube-up.sh`, эти файлы настроены на ежедневную ротацию с помощью инструмента `logrotate` или при достижении 100 МБ. + +## Архитектуры для сбора логов на уровне кластера + +Kubernetes не имеет собственного решения для сбора логов на уровне кластера, но есть общие подходы, которые можно рассмотреть. Вот некоторые из них: + +* использовать агент на уровне узлов (запускается на каждом узле); +* внедрить в Pod с приложением специальный sidecar-контейнер для сбора логов; +* отправлять логи из приложения непосредственно в бэкенд. + +### Использование агента на уровне узлов + +![Использование агента на уровне узлов](/images/docs/user-guide/logging/logging-with-node-agent.png) + +Сбор логов на уровне кластера можно реализовать, запустив _node-level-агент_ на каждом узле. Лог-агент — это специальный инструмент, который предоставляет доступ к логам или передает их бэкенду. Как правило, лог-агент представляет собой контейнер с доступом к директории с файлами логов всех контейнеров приложений на этом узле. + +Поскольку лог-агент должен работать на каждом узле, рекомендуется запускать его как `DaemonSet`. + +Сбор логов на уровне узла предусматривает запуск одного агента на узел и не требует изменений в приложениях, работающих на узле. + +Контейнеры пишут в `stdout` и `stderr`, но без согласованного формата. Агент на уровне узла собирает эти логи и направляет их на агрегацию. + +### Сбор логов с помощью sidecar-контейнера с лог-агентом {#sidecar-container-with-logging-agent} + +Sidecar-контейнер можно использовать одним из следующих способов: + +* sidecar-контейнер транслирует логи приложений на свой собственный `stdout`; +* в sidecar-контейнере работает агент, настроенный на сбор логов из контейнера приложения. + +#### Транслирующий sidecar-контейнер + +![Sidecar-контейнер с транслирующим контейнером](/images/docs/user-guide/logging/logging-with-streaming-sidecar.png) + +Настроив sidecar-контейнеры на вывод в их собственные потоки `stdout` и `stderr`, можно воспользоваться преимуществами kubelet и лог-агента, которые уже работают на каждом узле. Sidecar-контейнеры считывают логи из файла, сокета или journald. Затем каждый из них пишет логи в собственный поток `stdout` или `stderr`. + +Такой подход позволяет разграничить потоки логов от разных частей приложения, некоторые из которых могут не поддерживать запись в `stdout` или `stderr`. Логика, управляющая перенаправлением логов, проста и не требует значительных ресурсов. Кроме того, поскольку `stdout` и `stderr` обрабатываются kubelet'ом, можно использовать встроенные инструменты вроде `kubectl logs`. + +Предположим, к примеру, что в Pod'е работает один контейнер, который пишет логи в два разных файла в двух разных форматах. Вот пример конфигурации такого Pod'а: + +{{< codenew file="admin/logging/two-files-counter-pod.yaml" >}} + +Не рекомендуется писать логи разных форматов в один и тот же поток, даже если удалось перенаправить оба компонента в `stdout` контейнера. Вместо этого можно создать два sidecar-контейнера. Каждый из них будет забирать определенный лог-файл с общего тома и перенаправлять логи в свой `stdout`. + +Вот пример конфигурации Pod'а с двумя sidecar-контейнерами: + +{{< codenew file="admin/logging/two-files-counter-pod-streaming-sidecar.yaml" >}} + +Доступ к каждому потоку логов такого Pod'а можно получить отдельно, выполнив следующие команды: + +```shell +kubectl logs counter count-log-1 +``` + +Результат будет таким: + +```console +0: Mon Jan 1 00:00:00 UTC 2001 +1: Mon Jan 1 00:00:01 UTC 2001 +2: Mon Jan 1 00:00:02 UTC 2001 +... +``` + +```shell +kubectl logs counter count-log-2 +``` + +Результат будет таким: + +```console +Mon Jan 1 00:00:00 UTC 2001 INFO 0 +Mon Jan 1 00:00:01 UTC 2001 INFO 1 +Mon Jan 1 00:00:02 UTC 2001 INFO 2 +... +``` + +Агент на уровне узла, установленный в кластере, подхватывает эти потоки логов автоматически без дополнительной настройки. При желании можно настроить агент на парсинг логов в зависимости от контейнера-источника. + +Обратите внимание: несмотря на низкое использование процессора и памяти (порядка нескольких milliCPU для процессора и пары мегабайт памяти), запись логов в файл и их последующая потоковая передача в `stdout` может вдвое увеличить нагрузку на диск. Если приложение пишет в один файл, рекомендуется установить `/dev/stdout` в качестве адресата, нежели использовать подход с транслирующим контейнером. + +Sidecar-контейнеры также можно использовать для ротации файлов логов, которые не могут быть ротированы самим приложением. В качестве примера можно привести небольшой контейнер, периодически запускающий `logrotate`. Однако рекомендуется использовать `stdout` и `stderr` напрямую, а управление политиками ротации и хранения оставить kubelet'у. + +#### Sidecar-контейнер с лог-агентом + +![Sidecar-контейнер с лог-агентом](/images/docs/user-guide/logging/logging-with-sidecar-agent.png) + +Если лог-агент на уровне узла недостаточно гибок для ваших потребностей, можно создать sidecar-контейнер с отдельным лог-агентом, специально настроенным на работу с приложением. + +{{< note >}} +Работа лог-агента в sidecar-контейнере может привести к значительному потреблению ресурсов. Более того, доступ к этим журналам с помощью `kubectl logs` будет невозможен, поскольку они не контролируются kubelet'ом. +{{< /note >}} + +Ниже приведены два файла конфигурации sidecar-контейнера с лог-агентом. Первый содержит [`ConfigMap`](/docs/tasks/configure-pod-container/configure-pod-configmap/) для настройки fluentd. + +{{< codenew file="admin/logging/fluentd-sidecar-config.yaml" >}} + +{{< note >}} +За информацией о настройке fluentd обратитесь к его [документации](https://docs.fluentd.org/). +{{< /note >}} + +Второй файл описывает Pod с sidecar-контейнером, в котором работает fluentd. Pod монтирует том с конфигурацией fluentd. + +{{< codenew file="admin/logging/two-files-counter-pod-agent-sidecar.yaml" >}} + +В приведенных выше примерах fluentd можно заменить на другой лог-агент, считывающий данные из любого источника в контейнере приложения. + +### Прямой доступ к логам из приложения + +![Прямой доступ к логам из приложения](/images/docs/user-guide/logging/logging-from-application.png) + +Сбор логов приложения на уровне кластера, при котором доступ к ним осуществляется напрямую, выходит за рамки Kubernetes. diff --git a/content/ru/examples/admin/logging/fluentd-sidecar-config.yaml b/content/ru/examples/admin/logging/fluentd-sidecar-config.yaml new file mode 100644 index 00000000000..eea1849b033 --- /dev/null +++ b/content/ru/examples/admin/logging/fluentd-sidecar-config.yaml @@ -0,0 +1,25 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: fluentd-config +data: + fluentd.conf: | + + type tail + format none + path /var/log/1.log + pos_file /var/log/1.log.pos + tag count.format1 + + + + type tail + format none + path /var/log/2.log + pos_file /var/log/2.log.pos + tag count.format2 + + + + type google_cloud + diff --git a/content/ru/examples/admin/logging/two-files-counter-pod-agent-sidecar.yaml b/content/ru/examples/admin/logging/two-files-counter-pod-agent-sidecar.yaml new file mode 100644 index 00000000000..ddfb8104cb9 --- /dev/null +++ b/content/ru/examples/admin/logging/two-files-counter-pod-agent-sidecar.yaml @@ -0,0 +1,39 @@ +apiVersion: v1 +kind: Pod +metadata: + name: counter +spec: + containers: + - name: count + image: busybox:1.28 + args: + - /bin/sh + - -c + - > + i=0; + while true; + do + echo "$i: $(date)" >> /var/log/1.log; + echo "$(date) INFO $i" >> /var/log/2.log; + i=$((i+1)); + sleep 1; + done + volumeMounts: + - name: varlog + mountPath: /var/log + - name: count-agent + image: k8s.gcr.io/fluentd-gcp:1.30 + env: + - name: FLUENTD_ARGS + value: -c /etc/fluentd-config/fluentd.conf + volumeMounts: + - name: varlog + mountPath: /var/log + - name: config-volume + mountPath: /etc/fluentd-config + volumes: + - name: varlog + emptyDir: {} + - name: config-volume + configMap: + name: fluentd-config diff --git a/content/ru/examples/admin/logging/two-files-counter-pod-streaming-sidecar.yaml b/content/ru/examples/admin/logging/two-files-counter-pod-streaming-sidecar.yaml new file mode 100644 index 00000000000..ac19efe4a23 --- /dev/null +++ b/content/ru/examples/admin/logging/two-files-counter-pod-streaming-sidecar.yaml @@ -0,0 +1,38 @@ +apiVersion: v1 +kind: Pod +metadata: + name: counter +spec: + containers: + - name: count + image: busybox:1.28 + args: + - /bin/sh + - -c + - > + i=0; + while true; + do + echo "$i: $(date)" >> /var/log/1.log; + echo "$(date) INFO $i" >> /var/log/2.log; + i=$((i+1)); + sleep 1; + done + volumeMounts: + - name: varlog + mountPath: /var/log + - name: count-log-1 + image: busybox:1.28 + args: [/bin/sh, -c, 'tail -n+1 -F /var/log/1.log'] + volumeMounts: + - name: varlog + mountPath: /var/log + - name: count-log-2 + image: busybox:1.28 + args: [/bin/sh, -c, 'tail -n+1 -F /var/log/2.log'] + volumeMounts: + - name: varlog + mountPath: /var/log + volumes: + - name: varlog + emptyDir: {} diff --git a/content/ru/examples/admin/logging/two-files-counter-pod.yaml b/content/ru/examples/admin/logging/two-files-counter-pod.yaml new file mode 100644 index 00000000000..31bbed3cf86 --- /dev/null +++ b/content/ru/examples/admin/logging/two-files-counter-pod.yaml @@ -0,0 +1,26 @@ +apiVersion: v1 +kind: Pod +metadata: + name: counter +spec: + containers: + - name: count + image: busybox:1.28 + args: + - /bin/sh + - -c + - > + i=0; + while true; + do + echo "$i: $(date)" >> /var/log/1.log; + echo "$(date) INFO $i" >> /var/log/2.log; + i=$((i+1)); + sleep 1; + done + volumeMounts: + - name: varlog + mountPath: /var/log + volumes: + - name: varlog + emptyDir: {} diff --git a/content/ru/examples/debug/counter-pod.yaml b/content/ru/examples/debug/counter-pod.yaml new file mode 100644 index 00000000000..a91b2f89158 --- /dev/null +++ b/content/ru/examples/debug/counter-pod.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Pod +metadata: + name: counter +spec: + containers: + - name: count + image: busybox:1.28 + args: [/bin/sh, -c, + 'i=0; while true; do echo "$i: $(date)"; i=$((i+1)); sleep 1; done'] From eed0bc8417757819dae46960fee44368dd9e1daf Mon Sep 17 00:00:00 2001 From: Kirill Kononovich <41591254+kirkonru@users.noreply.github.com> Date: Mon, 4 Jul 2022 20:20:20 +0300 Subject: [PATCH 231/279] Add flow-control.md and translate it Co-authored-by: Dmitry Shurupov Add health-for-strangers.yaml --- .../cluster-administration/flow-control.md | 328 ++++++++++++++++++ .../health-for-strangers.yaml | 20 ++ 2 files changed, 348 insertions(+) create mode 100644 content/ru/docs/concepts/cluster-administration/flow-control.md create mode 100644 content/ru/examples/priority-and-fairness/health-for-strangers.yaml diff --git a/content/ru/docs/concepts/cluster-administration/flow-control.md b/content/ru/docs/concepts/cluster-administration/flow-control.md new file mode 100644 index 00000000000..0424b87d296 --- /dev/null +++ b/content/ru/docs/concepts/cluster-administration/flow-control.md @@ -0,0 +1,328 @@ +--- +title: Равноправный доступ к API +content_type: concept +min-kubernetes-server-version: v1.18 +--- + + + +{{< feature-state state="beta" for_k8s_version="v1.20" >}} + +Контроль за поведением API-сервера Kubernetes в условиях высокой нагрузки — ключевая задача для администраторов кластера. В {{< glossary_tooltip term_id="kube-apiserver" text="kube-apiserver">}} имеются некоторые механизмы управления (например, флаги командной строки `--max-requests-inflight` и `--max-mutating-requests-inflight`) для ограничения нагрузки на сервер. Они предотвращают наплыв входящих запросов и потенциальный отказ сервера API, но не позволяют гарантировать прохождение наиболее важных запросов в периоды высокой нагрузки. + +Функция регулирования приоритета и обеспечения равноправного доступа к API (API Priority and Fairness), или РДА, — отличная альтернатива флагам. Она оптимизирует вышеупомянутые ограничения на максимальное количество запросов. РДА тщательнее классифицирует запросы и изолирует их. Также она поддерживает механизм очередей, который помогает обрабатывать запросы при краткосрочных всплесках нагрузки. Отправка запросов из очередей осуществляется на основе метода организации равноправных очередей, поэтому плохо работающий {{< glossary_tooltip text="контроллер" term_id="controller" >}} не будет мешать работе других (даже с аналогичным уровнем приоритета). + +Эта функция предназначена для корректной работы со стандартными контроллерами, которые используют информеры и реагируют на неудачные API-запросы, экспоненциально увеличивая выдержку (back-off) между ними, а также клиентами, устроенными аналогичным образом. + +{{< caution >}} +Запросы, отнесенные к категории "long-running" — в первую очередь следящие, — не подпадают под действие фильтра функции равноправного доступа к API. Это также верно для флага `--max-requests-inflight` без включенной функции РДА. +{{< /caution >}} + + + +## Включение/отключение равноправного доступа к API + +Управление РДА осуществляется с помощью переключателя функционала (feature gate); по умолчанию функция включена. В разделе [Переключатели функционала](/docs/reference/command-line-tools-reference/feature-gates/) приведено их общее описание и способы включения/отключения. В случае РДА соответствующий переключатель называется "APIPriorityAndFairness". Данная функция также включает {{< glossary_tooltip term_id="api-group" text="группу API" >}}, при этом: (a) версия `v1alpha1` по умолчанию отключена, (b) версии `v1beta1` и `v1beta2` по умолчанию включены. Чтобы отключить РДА и бета-версии групп API, добавьте следующие флаги командной строки в вызов `kube-apiserver`: + +```shell +kube-apiserver \ +--feature-gates=APIPriorityAndFairness=false \ +--runtime-config=flowcontrol.apiserver.k8s.io/v1beta1=false,flowcontrol.apiserver.k8s.io/v1beta2=false \ + # …и остальные флаги, как обычно +``` + +Кроме того, версию v1alpha1 группы API можно включить с помощью `--runtime-config=flowcontrol.apiserver.k8s.io/v1alpha1=true`. + +Флаг командной строки `--enable-priority-and-fairness=false` отключит функцию равноправного доступа к API, даже если другие флаги ее активировали. + +## Основные понятия + +Функция равноправного доступа к API в своей работе использует несколько базовых понятий/механизмов. Входящие запросы классифицируются по атрибутам с помощью т.н. _FlowSchemas_, после чего им присваиваются уровни приоритета. Уровни приоритета обеспечивают некоторую степень изоляции, обеспечивая различные пределы параллелизма, предотвращая влияние запросов с разными уровнями приоритета друг на друга. В пределах одного приоритета алгоритм равнодоступного формирования очереди предотвращает взаимное влияние запросов из разных _потоков_ и формирует очередь запросов, снижая число неудачных запросов во время всплесков трафика при приемлемо низкой средней нагрузке. + +### Уровни приоритета + +Без включенного равноправного доступа к API управление общим параллелизмом в API-сервере осуществляется флагами `--max-requests-inflight` и `--max-mutating-requests-inflight` для `kube-apiserver`. При включенном равноправном доступе к API пределы параллелизма, заданные этими флагами, суммируются, а затем сумма распределяется по настраиваемому набору _уровней приоритета_. Каждому входящему запросу присваивается определенный уровень приоритета, причем каждый уровень приоритета может отправлять только такое количество параллельных запросов, которое прописано в его конфигурации. + +Конфигурация по умолчанию, например, предусматривает отдельные уровни приоритета для запросов на выборы лидера, запросов от встроенных контроллеров и запросов от Pod'ов. Это означает, что Pod, ведущий себя некорректно и переполняющий API-сервер запросами, не сможет помешать выборам лидера или оказать влияние на действия встроенных контроллеров. + +### Очереди + +Каждый уровень приоритета может включать большое количество различных источников трафика. Во время перегрузки важно предотвратить негативное влияние одного потока запросов на остальные (например, в идеале один сбойный клиент, переполняющий kube-apiserver своими запросами, не должен оказывать заметного влияния на других клиентов). Для этого при обработке запросов с одинаковым уровнем приоритета используется алгоритм равнодоступной очереди. Каждый запрос приписывается к _потоку_, который идентифицируется по имени соответствующей FlowSchema и _дифференциатору потока_: пользователю-источнику запроса, пространству имен целевого ресурса или пустым значением. Система старается придать примерно равный вес запросам в разных потоках с одинаковым уровнем приоритета. +Для раздельной обработки различных инстансов контроллеры с большим их числом должны аутентифицироваться под разными именами пользователей. + +Распределив запрос в некоторый поток, РДА приписывает его к очереди. Этот процесс базируется на методе, известном как {{< glossary_tooltip term_id="shuffle-sharding" text="shuffle sharding" >}} (тасование между шардами), который относительно эффективно изолирует потоки низкой интенсивности от потоков высокой интенсивности с помощью очередей. + +Параметры алгоритма постановки в очередь можно настраивать для каждого уровня приоритетов. В результате администратор может выбирать между использованием памяти, равнодоступностью (свойством, которое обеспечивает продвижение независимых потоков, когда совокупный трафик превышает пропускную способность), толерантностью к всплескам трафика и дополнительной задержкой, вызванной постановкой в очередь. + +### Запросы-исключения + +Некоторые запросы считаются настолько важными, что на них не распространяется ни одно из ограничений, налагаемых этой функцией. Механизм исключений не позволяет ошибочно настроенной конфигурации управления потоком полностью вывести сервер API из строя. + +## Ресурсы + +API управления потоками включает в себя два вида ресурсов. [PriorityLevelConfigurations](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#prioritylevelconfiguration-v1beta2-flowcontrol-apiserver-k8s-io) определяет доступные классы изоляции, долю доступного бюджета параллелизма, которая выделяется для каждого класса, и позволяет выполнять тонкую настройку работы с очередями. [FlowSchema](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#flowschema-v1beta2-flowcontrol-apiserver-k8s-io) используется для классификации отдельных входящих запросов, сопоставляя каждый из них с одной из конфигураций PriorityLevelConfiguration. Кроме того, существует версия `v1alpha1` данной группы API, с аналогичными Kinds с теми же синтаксисом и семантикой. + +### PriorityLevelConfiguration + +PriorityLevelConfiguration представляет отдельный класс изоляции. У каждой конфигурации PriorityLevelConfiguration имеется независимый предел на количество активных запросов и ограничения на число запросов в очереди. + +Пределы параллелизма для PriorityLevelConfigurations указываются не в виде абсолютного количества запросов, а в виде "долей параллелизма" (concurrency shares). Совокупный объем ресурсов API-сервера, доступных для параллелизма, распределяется между существующими PriorityLevelConfigurations пропорционально этим долям. Администратор кластера может увеличить или уменьшить совокупный объем трафика на сервер, просто перезапустив kube-apiserver с другим значением `--max-requests-inflight` (или `--max-mutating-requests-inflight`). В результате пропускная способность каждой PriorityLevelConfigurations возрастет (или снизится) соразмерно ее доле. + +{{< caution >}} +При включенной функции Priority and Fairness суммарный предел параллелизма для сервера равен сумме `--max-requests-inflight` и `--max-mutating-requests-inflight`. При этом мутирующие и не мутирующие запросы рассматриваются вместе; чтобы обрабатывать их независимо для некоторого ресурса, создайте отдельные FlowSchemas для мутирующих и не мутирующих действий (verbs). +{{< /caution >}} + +Поле `type` спецификации PriorityLevelConfiguration определяет судьбу избыточных запросов, когда их объем, отнесенный к одной PriorityLevelConfiguration, превышает ее допустимый уровень параллелизма. Тип `Reject` означает, что избыточный трафик будет немедленно отклонен с ошибкой HTTP 429 (Too Many Requests). Тип `Queue` означает, что запросы, превышающие пороговое значение, будут поставлены в очередь, при этом для балансировки прогресса между потоками запросов будут использоваться методы тасования между шардами и равноправных очередей. + +Конфигурация очередей позволяет настроить алгоритм равноправных очередей для каждого уровня приоритета. Подробности об алгоритме можно узнать из [предложения по улучшению](https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/1040-priority-and-fairness); если вкратце: + +* Увеличение `queues` снижает количество конфликтов между различными потоками за счет повышенного использования памяти. При единице логика равнодоступной очереди отключается, но запросы все равно могут быть поставлены в очередь. + +* Увеличение длины очереди (`queueLengthLimit`) позволяет выдерживать большие всплески трафика без потери запросов за счет увеличения задержек и повышенного потребления памяти. + +* Изменение `handSize` позволяет регулировать вероятность конфликтов между различными потоками и общий параллелизм, доступный для одного потока в условиях чрезмерной нагрузки. + + {{< note >}} + Больший `handSize` снижает вероятность конфликта двух отдельных потоков (и, следовательно, вероятность того, что один из них подавит другой), но повышает вероятность того, что малое число потоков загрузят API-сервер. Больший `handSize` также потенциально увеличивает задержку, которую может вызвать один поток с высоким трафиком. Максимальное возможное количество запросов в очереди от одного потока равно `handSize * queueLengthLimit`. + {{< /note >}} + +Ниже приведена таблица с различными конфигурациями, показывающая вероятность того, что "мышь" (поток низкой интенсивности) будет раздавлена "слонами" (потоками высокой интенсивности) в зависимости от числа "слонов" при тасовании потоков между шардами. Скрипт для расчета таблицы доступен по [ссылке](https://play.golang.org/p/Gi0PLgVHiUg). + +{{< table caption = "Конфигурации shuffle sharding" >}} +`handSize` | Число очередей | 1 слон | 4 слона | 16 слонов +|----------|-----------|------------|----------------|--------------------| +| 12 | 32 | 4.428838398950118e-09 | 0.11431348830099144 | 0.9935089607656024 | +| 10 | 32 | 1.550093439632541e-08 | 0.0626479840223545 | 0.9753101519027554 | +| 10 | 64 | 6.601827268370426e-12 | 0.00045571320990370776 | 0.49999929150089345 | +| 9 | 64 | 3.6310049976037345e-11 | 0.00045501212304112273 | 0.4282314876454858 | +| 8 | 64 | 2.25929199850899e-10 | 0.0004886697053040446 | 0.35935114681123076 | +| 8 | 128 | 6.994461389026097e-13 | 3.4055790161620863e-06 | 0.02746173137155063 | +| 7 | 128 | 1.0579122850901972e-11 | 6.960839379258192e-06 | 0.02406157386340147 | +| 7 | 256 | 7.597695465552631e-14 | 6.728547142019406e-08 | 0.0006709661542533682 | +| 6 | 256 | 2.7134626662687968e-12 | 2.9516464018476436e-07 | 0.0008895654642000348 | +| 6 | 512 | 4.116062922897309e-14 | 4.982983350480894e-09 | 2.26025764343413e-05 | +| 6 | 1024 | 6.337324016514285e-16 | 8.09060164312957e-11 | 4.517408062903668e-07 | +{{< /table >}} + +### FlowSchema + +FlowSchema сопоставляется со входящими запросами; по результатам данного действия тем приписывается определенный уровень приоритета. Каждый входящий запрос по очереди проверяется на соответствие каждой FlowSchema, начиная с тех, у которых наименьшее численное значение `matchingPrecedence` (т.е., логически наивысший приоритет). Проверка ведется до первого совпадения. + +{{< caution >}} +Учитывается только первая подходящая FlowSchema для данного запроса. Если одному входящему запросу соответствует несколько FlowSchemas, он попадет в ту, у которой наивысший `matchingPrecedence`. Если несколько FlowSchema с одинаковым `matchingPrecedence` соответствуют одному запросу, предпочтение будет отдано той, у которой лексикографически меньшее имя (`name`). Впрочем, лучше не полагаться на это, а убедиться, что `matchingPrecedence` уникален для всех FlowSchema. +{{< /caution >}} + +Схема FlowSchema подходит определенному запросу, если хотя бы одно из ее правил (`rules`) подходит ему. В свою очередь, правило соответствует запросу, если ему соответствует хотя бы один из его субъектов (`subjects`) *и* хотя бы одно из его правил `resourceRules` или `nonResourceRules` (в зависимости от того, является ли входящий запрос ресурсным или нересурсным URL). + +Для поля `name` в субъектах (subjects) и полей `verbs`, `apiGroups`, `resources`, `namespaces` и `nonResourceURLs` в ресурсных и нересурсных правилах может быть указан универсальный символ `*`, который будет соответствовать всем значениям для данного поля, фактически исключая его из рассмотрения. + +Параметр `distinguisherMethod.type` схемы FlowSchema определяет, как запросы, соответствующие этой схеме, будут разделяться на потоки. Он может быть либо `ByUser` (в этом случае один запрашивающий пользователь не сможет лишить других пользователей ресурсов), либо `ByNamespace` (в этом случае запросы на ресурсы в одном пространстве имен не смогут помешать запросам на ресурсы в других пространствах имен), либо он может быть пустым (или `distinguisherMethod` может быть опущен) (в этом случае все запросы, соответствующие данной FlowSchema, будут считаться частью одного потока). Правильный выбор для определенной FlowSchema зависит от ресурса и конкретной среды. + +## Значения по умолчанию + +kube-apiserver поддерживает два вида объектов конфигурации РДА: обязательные и рекомендуемые. + +### Обязательные объекты конфигурации + +Четыре обязательных объекта конфигурации отражают защитное поведение, встроенное в серверы. Оно реализуется независимо от этих объектов; параметры последних просто его отражают. + +* Обязательный уровень приоритета `exempt` используется для запросов, которые вообще не подчиняются контролю потока: они всегда будут доставляться немедленно. Обязательная FlowSchema `exempt` относит к этому уровню приоритета все запросы из группы `system:masters`. При необходимости можно задать другие FlowSchemas, которые будут наделять другие запросы данным уровнем приоритета. + +* Обязательный уровень приоритета `catch-all` используется в сочетании с обязательной FlowSchema `catch-all`, гарантируя, что каждый запрос получит какую-либо классификацию. Как правило, полагаться на эту универсальную конфигурацию не следует. Рекомендуется создать свои собственные универсальные FlowSchema и PriorityLevelConfiguration (или использовать опциональный уровень приоритета `global-default`, доступный по умолчанию). Поскольку предполагается, что обязательный уровень приоритета `catch-all` будет использоваться редко, его доля параллелизма невысока, кроме того, он не ставит запросы в очередь. + +### Опциональные объекты конфигурации + +Опциональные объекты FlowSchemas и PriorityLevelConfigurations образуют оптимальную конфигурацию по умолчанию. При желании их можно изменить и/или создать дополнительные объекты конфигурации. Если велика вероятность высокой нагрузки на кластер, следует решить, какая конфигурация будет работать лучше всего. + +Опциональная конфигурация группирует запросы по шести уровням приоритета: + +* Уровень приоритета `node-high` предназначен для проверки здоровья узлов. + +* Уровень приоритета `system` предназначен для запросов от группы `system:nodes`, не связанных с состоянием узлов, а именно: от kubelet'ов, которые должны иметь возможность связываться с сервером API для планирования рабочих нагрузок. + +* Уровень приоритета `leader-election` предназначен для запросов на выборы лидера от встроенных контроллеров (в частности, запросы на объекты типа `Endpoint`, `ConfigMap` или `Lease`, поступающие от пользователей `system:kube-controller-manager` или `system:kube-scheduler` и служебных учетных записей в пространстве имен `kube-system`). Их важно изолировать от другого трафика, поскольку сбои при выборе лидеров приводят к перезагрузкам контроллеров. Соответственно, новые контроллеры потребляют трафик, синхронизируя свои информеры. + +* Уровень приоритета `workload-high` предназначен для прочих запросов от встроенных контроллеров. + +* Уровень приоритета `workload-low` предназначен для запросов от остальных учетных записей служб, которые обычно включают все запросы от контроллеров, работающих в Pod'ах. + +* Уровень приоритета `global-default` обрабатывает весь остальной трафик, например, интерактивные команды `kubectl`, выполняемые непривилегированными пользователями. + +Опциональные FlowSchemas служат для направления запросов на вышеуказанные уровни приоритета и здесь не перечисляются. + +### Обслуживание обязательных и опциональных объектов конфигурации + +Каждый `kube-apiserver` самостоятельно обслуживает обязательные и опциональные объекты конфигурации, используя стратегию начальных/периодических проходов. Таким образом, в ситуации с серверами разных версий может возникнуть пробуксовка (thrashing) из-за разного представления серверов о правильном содержании этих объектов. + +Каждый `kube-apiserver` выполняет начальный проход по обязательным и опциональным объектам конфигурации, а затем периодически (раз в минуту) обходит их. + +Для обязательных объектов обслуживание заключается в проверке того, что объект существует и имеет надлежащую спецификацию (spec). Сервер не разрешает создавать или обновлять объекты со spec, которая не соответствует его защитному поведению. + +Обслуживание опциональных объектов конфигурации предусматривает возможность переопределения их спецификации (spec). Кроме того, удаление носит непостоянный характер: объект будет восстановлен в процессе обслуживания. Если опциональный объект конфигурации не нужен, его не нужно удалять, но достаточно настроить spec'и так, чтобы последствия были минимальными. Обслуживание опциональных объектов также рассчитано на поддержку автоматической миграции при выходе новой версии `kube-apiserver`, при этом вероятны конфликты (thrashing), пока группировка серверов остается смешанной. + +Обслуживание опционального объекта конфигурации предусматривает его создание — с рекомендуемой спецификацией сервера — если тот не существует. В то же время, если объект уже существует, поведение при обслуживании зависит от того, кто им управляет — `kube-apiserver`'ы или пользователи. В первом случае сервер гарантирует, что спецификация объекта соответствует рекомендуемой; во втором случае спецификация не анализируется. + +Чтобы узнать, кто управляет объектом, необходимо найти аннотацию с ключом `apf.kubernetes.io/autoupdate-spec`. Если такая аннотация существует и ее значение равно `true`, то объект контролируется kube-apiserver'ами. Если аннотация существует и ее значение равно `false`, объект контролируется пользователями. Если ни одно из этих условий не выполняется, выполняется обращение к `metadata.generation` объекта. Если этот параметр равен 1, объект контролируется kube-apiserver'ами. В противном случае объект контролируют пользователи. Эти правила были введены в версии 1.22, и использование `metadata.generation` обусловлено переходом от более простого предыдущего поведения. Пользователи, желающие контролировать опциональный объект конфигурации, должны убедиться, что его аннотация `apf.kubernetes.io/autoupdate-spec` имеет значение `false`. + +Обслуживание обязательного или опционального объекта конфигурации также предусматривает проверку наличия у него аннотации `apf.kubernetes.io/autoupdate-spec`, которая позволяет понять, контролируют ли его kube-apiserver'ы. + +Обслуживание также предусматривает удаление объектов, которые не являются ни обязательными, ни опциональными, но имеют аннотацию `apf.kubernetes.io/autoupdate-spec=true`. + +## Освобождение проверок работоспособности от параллелизма + +Опциональная конфигурация не предусматривает особого отношения к health check-запросам на kube-apiserver'ы от их локальных kubelet'ов. В данном случае обычно используется защищенный порт, но учетные данные не передаются. В опциональной конфигурации такие запросы относятся к FlowSchema `global-default` и соответствующему уровню приоритета `global-default`, где другой трафик может мешать их прохождению. + +Чтобы освободить такие запросы от частотных ограничений, можно добавить FlowSchema, приведенную ниже. + +{{< caution >}} +Добавление данной FlowSchema позволит злоумышленникам отправлять удовлетворяющие ей health-check-запросы в любом количестве. При наличии фильтра веб-трафика или аналогичного внешнего механизма безопасности для защиты API-сервера кластера от интернет-трафика можно настроить правила для блокировки любых health-check-запросов, поступающих из-за пределов кластера. +{{< /caution >}} + +{{< codenew file="priority-and-fairness/health-for-strangers.yaml" >}} + +## Диагностика + +Каждый HTTP-ответ от сервера API с включенной функцией РДА содержит два дополнительных заголовка: `X-Kubernetes-PF-FlowSchema-UID` и `X-Kubernetes-PF-PriorityLevel-UID`. В них указываются схема потока и уровень приоритета соответственно. Имена объектов API не включаются в эти заголовки на случай, если запрашивающий пользователь не обладает правами на их просмотр, поэтому при отладке можно использовать команду типа: + +```shell +kubectl get flowschemas -o custom-columns="uid:{metadata.uid},name:{metadata.name}" +kubectl get prioritylevelconfigurations -o custom-columns="uid:{metadata.uid},name:{metadata.name}" +``` + +чтобы привязать UID к именам для FlowSchemas и PriorityLevelConfigurations. + +## Наблюдаемость + +### Метрики + +{{< note >}} +В Kubernetes до версии v1.20 лейблы `flow_schema` и `priority_level` также могли называться `flowSchema` и `priorityLevel`, соответственно. При использовании Kubernetes v1.19 и более ранних версий обратитесь к документации для соответствующей версии. +{{< /note >}} + +При включении функции равноправного доступа к API kube-apiserver начинает экспортировать дополнительные метрики. Их мониторинг помогает выявить негативное влияние (throttling) текущей конфигурации на важный трафик или найти неэффективные рабочие нагрузки, которые вредят здоровью системы. + +* `apiserver_flowcontrol_rejected_requests_total` — вектор-счетчик (кумулятивный с момента запуска сервера) запросов, которые были отклонены, с разбивкой по лейблам `flow_schema` (указывает на FlowSchema у запросов, попавших под соответствие), `priority_level` (уровень приоритета, который был присвоен этим запросам) и `reason`. Лейбл `reason` будет иметь одно из следующих значений: + + * `queue-full` — в очереди уже слишком много запросов; + * `concurrency-limit` — PriorityLevelConfiguration настроена на отклонение, а не на постановку в очередь избыточных запросов; + * `time-out` — запрос все еще находился в очереди, когда истек его лимит ожидания. + +* `apiserver_flowcontrol_dispatched_requests_total` — вектор-счетчик (кумулятивный с момента запуска сервера) запросов, которые начали выполняться, сгруппированный по лейблам `flow_schema` (указывает на FlowSchema у запросов, попавших под соответствие) и `priority_level` (уровень приоритета, который был присвоен этим запросам). + +* `apiserver_current_inqueue_requests` — вектор предыдущего максимума числа запросов в очереди, сгруппированных по лейблу `request_kind`, значение которого `mutating` или `readOnly`. Эти максимумы описывают наибольшее число, наблюдавшееся в последнем завершенном односекундном окне. Они дополняют более старый вектор `apiserver_current_inflight_requests`, который показывает максимум активно обслуживаемых запросов в последнем окне. + +* `apiserver_flowcontrol_read_vs_write_request_count_samples` — вектор-гистограмма наблюдений за тогда-текущим количеством запросов с разбивкой по лейблам `phase` (принимает значения `waiting` и `executing`) и `request_kind` (принимает значения `mutating` и `readOnly`). Наблюдения проводятся периодически с высокой частотой. Каждое наблюдаемое значение представляет собой число в диапазоне от 0 до 1, равное отношению числа запросов к соответствующему ограничению на их количество (ограничение длины очереди в случае ожидания и лимит параллелизма в случае выполнения). + +* `apiserver_flowcontrol_read_vs_write_request_count_watermarks` — вектор-гистограмма максимумов или минимумов количества запросов (число запросов, деленное на соответствующее ограничение) с разбивкой по лейблам `phase` (принимает значения `waiting` и `executing`) и `request_kind` (принимает значения `mutating` и `readOnly`); лейбл `mark` принимает значения `high` и `low`. Минимумы и максимумы собираются в окнах, ограниченных временем, когда наблюдение было добавлено в `apiserver_flowcontrol_read_vs_write_request_count_samples`. Эти экстремумы помогают определить разброс диапазона значений, наблюдавшийся в разных сэмплах. + +* `apiserver_flowcontrol_current_inqueue_requests` — gauge-вектор, содержащий количество стоящих в очереди (не выполняющихся) запросов в каждый момент с разбивкой по лейблам `priority_level` и `flow_schema`. + +* `apiserver_flowcontrol_current_executing_requests` — gauge-вектор, содержащий количество исполняемых (не ожидающих в очереди) запросов в каждый момент с разбивкой по лейблам `priority_level` и `flow_schema`. + +* `apiserver_flowcontrol_request_concurrency_in_use` — gauge-вектор, содержащий количество занятых мест в каждый момент с разбивкой по лейблам `priority_level` и `flow_schema`. + +* `apiserver_flowcontrol_priority_level_request_count_samples` — вектор-гистограмма наблюдений за текущим-на-тот-момент количеством запросов с разбивкой по лейблам `phase` (принимает значения `waiting` и `executing`) и `priority_level`. Каждая гистограмма получает наблюдения, сделанные периодически, вплоть до последней активности соответствующего рода. Наблюдения проводятся с высокой частотой. Каждое наблюдаемое значение представляет собой число в диапазоне от 0 до 1, равное отношению числа запросов к соответствующему ограничению на их количество (ограничение длины очереди в случае ожидания и лимит параллелизма в случае выполнения). + +* `apiserver_flowcontrol_priority_level_request_count_watermarks` — вектор-гистограмма максимумов или минимумов количества запросов с разбивкой по лейблам `phase` (принимает значения `waiting` и `executing`) и `priority_level`; лейбл `mark` принимает значения `high` и `low`. Минимумы и максимумы собираются в окнах, ограниченных временем, когда наблюдение было добавлено в `apiserver_flowcontrol_priority_level_request_count_samples`. Эти экстремумы показывают диапазон значений, наблюдавшийся в разных сэмплах. + +* `apiserver_flowcontrol_priority_level_seat_count_samples` — вектор-гистограмма наблюдений за использованием лимита параллелизма для уровня приоритета с разбивкой по `priority_level`. Использование — отношение (количество занятых мест) / (предел параллелизма). Метрика учитывает все стадии выполнения (как обычную, так и дополнительную задержку в конце записи для покрытия соответствующей работы по уведомлению) всех запросов, кроме WATCHes; для этих запросов учитывается только начальная стадия по доставке уведомлений о ранее существующих объектах. Каждая гистограмма в векторе также помечена лейблом `phase: executing` (количество мест для фазы ожидания не ограничено). Каждая гистограмма получает наблюдения, сделанные периодически, вплоть до последней активности соответствующего рода. Наблюдения производятся с высокой частотой. + +* `apiserver_flowcontrol_priority_level_seat_count_watermarks` — вектор-гистограмма минимумов и максимумов использования предела параллелизма для уровня приоритета с разбивкой по `priority_leve` и `mark` (принимает значения `high` и `low`). Каждая гистограмма в векторе также помечена лейблом `phase: executing` (для фазы ожидания предел на места отсутствует). Максимумы и минимумы собираются в окнах, ограниченных временем, когда наблюдение было добавлено в `apiserver_flowcontrol_priority_level_seat_count_samples`. Эти экстремумы помогают определить разброс диапазона значений, наблюдавшийся в разных сэмплах. + +* `apiserver_flowcontrol_request_queue_length_after_enqueue` — вектор-гистограмма длины очереди для очередей с разбивкой по лейблам `priority_level` и `flow_schema` как выборки по поставленным в очередь запросам. Каждый запрос при постановке в очередь вносит один сэмпл в гистограмму, сообщая о длине очереди сразу после добавления запроса. Обратите внимание, что это дает иную статистику, чем при объективном исследовании. + + {{< note >}} + В данном случае выброс в гистограмме означает, что, скорее всего, один поток (т.е. запросы от одного пользователя или для одного пространства имен, в зависимости от конфигурации) переполняет сервер API и "срезается" (throttled). И наоборот, если гистограмма одного уровня приоритета показывает, что все очереди для этого уровня приоритета длиннее, чем для других уровней приоритета, возможно, следует увеличить долю параллелизма для этого уровня приоритета в PriorityLevelConfiguration. + {{< /note >}} + +* `apiserver_flowcontrol_request_concurrency_limit` — gauge-вектор, содержащий вычисленный лимит параллелизма (основанный на общем лимите параллелизма сервера API и долях параллелизма PriorityLevelConfigurations), с разбивкой по лейблу `priority_level`. + +* `apiserver_flowcontrol_request_wait_duration_seconds` — вектор-гистограмма времени ожидания запросов в очереди с разбивкой по лейблам `flow_schema` (указывает, какая схема соответствует запросу), `priority_level` (указывает, к какому уровню был отнесен запрос) и `execute` (указывает, начал ли запрос выполняться). + + {{< note >}} + Поскольку каждая FlowSchema всегда относит запросы к одному PriorityLevelConfiguration, можно сложить гистограммы для всех FlowSchema для одного уровня приоритета, чтобы получить эффективную гистограмму для запросов, отнесенных к этому уровню приоритета. + {{< /note >}} + +* `apiserver_flowcontrol_request_execution_seconds` — вектор-гистограмма времени, затраченного на выполнение запросов, с разбивкой по по лейблам `flow_schema` (указывает, какая схема соответствует запросу) и `priority_level` (указывает, к какому уровню был отнесен запрос). + +* `apiserver_flowcontrol_watch_count_samples` — вектор-гистограмма количества активных запросов WATCH, относящихся к данной записи, с разбивкой по `flow_schema` и `priority_level`. + +* `apiserver_flowcontrol_work_estimated_seats` — вектор-гистограмма количества предполагаемых мест (максимум начального и конечного этапа выполнения), связанных с запросами, с разбивкой по `flow_schema` и `priority_level`. + +* `apiserver_flowcontrol_request_dispatch_no_accommodation_total` — вектор-счетчик количества событий, которые в принципе могли бы привести к отправке запроса, но не привели из-за отсутствия доступного параллелизма, с разбивкой по `flow_schema` и `priority_level`. Соответствующими событиями являются поступление запроса и завершение запроса. + +### Отладочные endpoint'ы + +При включении функции равноправного доступа к API `kube-apiserver` предоставляет следующие дополнительные пути на своих HTTP[S]-портах. + +- `/debug/api_priority_and_fairness/dump_priority_levels` — список всех уровней приоритета и текущее состояние каждого из них. Получить его можно следующим образом: + + ```shell + kubectl get --raw /debug/api_priority_and_fairness/dump_priority_levels + ``` + + Вывод выглядит примерно так: + + ```none + PriorityLevelName, ActiveQueues, IsIdle, IsQuiescing, WaitingRequests, ExecutingRequests, + workload-low, 0, true, false, 0, 0, + global-default, 0, true, false, 0, 0, + exempt, , , , , , + catch-all, 0, true, false, 0, 0, + system, 0, true, false, 0, 0, + leader-election, 0, true, false, 0, 0, + workload-high, 0, true, false, 0, 0, + ``` + +- `/debug/api_priority_and_fairness/dump_queues` — список всех очередей и их текущее состояние. Получить его можно следующим образом: + + ```shell + kubectl get --raw /debug/api_priority_and_fairness/dump_queues + ``` + + Вывод выглядит примерно так: + + ```none + PriorityLevelName, Index, PendingRequests, ExecutingRequests, VirtualStart, + workload-high, 0, 0, 0, 0.0000, + workload-high, 1, 0, 0, 0.0000, + workload-high, 2, 0, 0, 0.0000, + ... + leader-election, 14, 0, 0, 0.0000, + leader-election, 15, 0, 0, 0.0000, + ``` + +- `/debug/api_priority_and_fairness/dump_requests` — список всех запросов, которые в настоящее время ожидают в очереди. Получить его можно следующим образом: + + ```shell + kubectl get --raw /debug/api_priority_and_fairness/dump_requests + ``` + + Вывод выглядит примерно так: + + ```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, + ``` + + В дополнение к запросам, стоящим в очереди, вывод включает одну фантомную строку для каждого уровня приоритета, на которую не распространяется ограничение. + + Более подробный список можно получить с помощью следующей команды: + + ```shell + kubectl get --raw '/debug/api_priority_and_fairness/dump_requests?includeRequestDetails=1' + ``` + + Вывод выглядит примерно так: + + ```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, + ``` + +## {{% heading "whatsnext" %}} + + +Для получения подробной информации о функции равноправного доступа к API см. [предложение по улучшению (KEP)](https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/1040-priority-and-fairness). Предложения и запросы функционала принимаются через [SIG API Machinery](https://github.com/kubernetes/community/tree/master/sig-api-machinery) или в специализированном [канале Slack](https://kubernetes.slack.com/messages/api-priority-and-fairness). diff --git a/content/ru/examples/priority-and-fairness/health-for-strangers.yaml b/content/ru/examples/priority-and-fairness/health-for-strangers.yaml new file mode 100644 index 00000000000..c57e2cae372 --- /dev/null +++ b/content/ru/examples/priority-and-fairness/health-for-strangers.yaml @@ -0,0 +1,20 @@ +apiVersion: flowcontrol.apiserver.k8s.io/v1beta2 +kind: FlowSchema +metadata: + name: health-for-strangers +spec: + matchingPrecedence: 1000 + priorityLevelConfiguration: + name: exempt + rules: + - nonResourceRules: + - nonResourceURLs: + - "/healthz" + - "/livez" + - "/readyz" + verbs: + - "*" + subjects: + - kind: Group + group: + name: system:unauthenticated From 87ece51122aabf579e3d07f9370fdc3c48fd1916 Mon Sep 17 00:00:00 2001 From: Kirill Kononovich <41591254+kirkonru@users.noreply.github.com> Date: Fri, 25 Nov 2022 19:08:34 +0300 Subject: [PATCH 232/279] Create & localize _index.md Create api-eviction.md Apply suggestions from code review Co-authored-by: Dmitry Shurupov [ru] create api-eviction.md [ru] create pod-disruption.md --- .../concepts/scheduling-eviction/_index.md | 35 +++++ .../scheduling-eviction/api-eviction.md | 121 ++++++++++++++++++ .../docs/reference/glossary/api-eviction.md | 24 ++++ .../docs/reference/glossary/pod-disruption.md | 24 ++++ 4 files changed, 204 insertions(+) create mode 100644 content/ru/docs/concepts/scheduling-eviction/_index.md create mode 100644 content/ru/docs/concepts/scheduling-eviction/api-eviction.md create mode 100644 content/ru/docs/reference/glossary/api-eviction.md create mode 100644 content/ru/docs/reference/glossary/pod-disruption.md diff --git a/content/ru/docs/concepts/scheduling-eviction/_index.md b/content/ru/docs/concepts/scheduling-eviction/_index.md new file mode 100644 index 00000000000..f2e598a2a5a --- /dev/null +++ b/content/ru/docs/concepts/scheduling-eviction/_index.md @@ -0,0 +1,35 @@ +--- +title: "Планирование, приоритизация и вытеснение" +weight: 95 +content_type: concept +description: > + В Kubernetes под планированием понимается поиск подходящих узлов, на которых kubelet сможет запустить Pod'ы. + Приоритизация — процесс завершения работы Pod'ов с более низким приоритетом и высвобождения места для Pod'ов + с более высоким приоритетом. Вытеснение — это проактивное завершение работы одного или нескольких Pod'ов на + узлах с дефицитом ресурсов. + +no_list: true +--- + +В Kubernetes под планированием понимается поиск {{}}, подходящих для размещения {{}} так, чтобы {{}} +мог их запустить. Приоритизация (упреждение; preemption) — процесс завершения работы Pod'ов +с более низким {{}} с освобождением места для Pod'ов с более высоким приоритетом. Вытеснение (eviction) — завершение работы одного или нескольких Pod'ов на узлах. + +## Планирование + +* [Планировщик Kubernetes](/docs/concepts/scheduling-eviction/kube-scheduler/); +* [Распределение Pod'ов по узлам](/docs/concepts/scheduling-eviction/assign-pod-node/); +* [Overhead Pod'а](/docs/concepts/scheduling-eviction/pod-overhead/); +* [Ограничения на топологию распределения Pod'ов](/docs/concepts/scheduling-eviction/topology-spread-constraints/); +* [Ограничения (taints) и допуски (tolerations)](/docs/concepts/scheduling-eviction/taint-and-toleration/); +* [Фреймворк для планирования](/docs/concepts/scheduling-eviction/scheduling-framework); +* [Настройка производительности планировщика](/docs/concepts/scheduling-eviction/scheduler-perf-tuning/); +* [Упаковка расширенных ресурсов](/docs/concepts/scheduling-eviction/resource-bin-packing/). + +## Завершение работы Pod'ов + +{{}} + +* [Приоритет и приоритизация Pod'ов](/docs/concepts/scheduling-eviction/pod-priority-preemption/); +* [Вытеснение из-за недостатка ресурсов на узле](/docs/concepts/scheduling-eviction/node-pressure-eviction/); +* [Вытеснение, инициированное API](/docs/concepts/scheduling-eviction/api-eviction/). diff --git a/content/ru/docs/concepts/scheduling-eviction/api-eviction.md b/content/ru/docs/concepts/scheduling-eviction/api-eviction.md new file mode 100644 index 00000000000..c545b597a06 --- /dev/null +++ b/content/ru/docs/concepts/scheduling-eviction/api-eviction.md @@ -0,0 +1,121 @@ +--- +title: Вытеснение, инициированное через API +content_type: concept +weight: 110 +--- + +{{< glossary_definition term_id="api-eviction" length="short" >}}
    + +Вытеснение можно инициировать напрямую с помощью Eviction API или программно, +используя клиент {{}} +(например, командой `kubectl drain`). В результате будет создан объект `Eviction`, +который запустит процесс контролируемого завершения работы Pod'а. + +Вытеснения, инициированные через API, учитывают настройки [`PodDisruptionBudget`](/docs/tasks/run-application/configure-pdb/) +и [`terminationGracePeriodSeconds`](/docs/concepts/workloads/pods/pod-lifecycle#pod-termination). + +Создание с помощью API объекта Eviction для Pod'а аналогично выполнению +[операции `DELETE`](/docs/reference/kubernetes-api/workload-resources/pod-v1/#delete-delete-a-pod) +для этого Pod'а, которая контролируется политикой. + +## Вызов API Eviction + +Для доступа к API Kubernetes и создания объекта `Eviction` можно воспользоваться [клиентской библиотекой](/docs/tasks/administer-cluster/access-cluster-api/#programmatic-access-to-the-api). Необходимая операция оформляется в виде 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", + "kind": "Eviction", + "metadata": { + "name": "quux", + "namespace": "default" + } +} +``` +{{% /tab %}} +{{< /tabs >}} + +Также можно попытаться выполнить операцию вытеснения, +обратившись к API с помощью `curl` или `wget`, как показано в следующем примере: + +```bash +curl -v -H 'Content-type: application/json' https://your-cluster-api-endpoint.example/api/v1/namespaces/default/pods/quux/eviction -d @eviction.json +``` + +## Как работает вытеснение, инициированное через API + +При вытеснении, инициированном через API, сервер API выполняет admission-проверки +и отвечает одним из следующих способов: + +* `200 OK`: вытеснение разрешено, подресурс `Eviction` создан, + Pod удален (аналогично отправке запроса `DELETE` на URL Pod'а). +* `429 Too Many Requests`: вытеснение в данный момент не разрешено из-за настроек + {{}}. + Попытку вытеснения можно повторить позже. Такой ответ также может быть вызван + работой механизма по ограничению частоты запросов к API. +* `500 Internal Server Error`: вытесение запрещено из-за неправильной конфигурации; + например, несколько PodDisruptionBudget'ов могут ссылаться на один и тот же Pod. + +Если Pod, предназначенный для вытеснения, не является частью рабочей нагрузки +с настроенным PodDisruptionBudget'ом, сервер API всегда возвращает `200 OK` и +разрешает вытеснение. + +В случае, если вытеснение разрешено, процесс удаления Pod'а выглядит следующим образом: + +1. К ресурсу `Pod` на сервере API добавляется метка времени удаления, + после чего сервер API считает ресурс Pod завершенным (terminated). Ресурс `Pod` также помечается + настроенным grace-периодом. +1. {{}} на узле, где запущен + локальный Pod, замечает, что ресурс `Pod` помечен на удаление, и приступает к + корректному завершению работы локального Pod'а. +1. Пока kubelet завершает работу Pod'а, управляющий слой удаляет Pod из объектов + {{}} и + {{}}. + В результате контроллеры больше не рассматривают Pod как валидный объект. +1. После истечения периода корректного завершения работы (grace-периода) kubelet + принудительно завершает работу локального Pod'а. +1. kubelet передает API-серверу информацию о необходимости удалить ресурс `Pod`. +1. Сервер API удаляет ресурс `Pod`. + +## Зависшие вытеснения + +В некоторых ситуациях сбой приводит к тому, что API Eviction начинает возвращать +исключительно ответы `429` или `500`. Такое может случиться, если, например, +за создание Pod'ов для приложения отвечает ReplicaSet, однако новые Pod'ы не +переходят в состояние `Ready`. Подобное поведение также может наблюдаться в случаях, +когда у последнего вытесненного Pod'а слишком долгий период завершения работы (grace-период). + +Одно из следующих решений может помочь решить проблему: + +* Прервите или приостановите автоматическую операцию, вызвавшую сбой. + Перед повторным запуском операции внимательно изучите сбойное приложение. +* Подождите некоторое время, затем напрямую удалите Pod из управляющего слоя + кластера вместо того, чтобы пытаться удалить его с помощью Eviction API. + +## {{% heading "whatsnext" %}} + +* Обеспечение работоспособности приложений с помощью [Pod Disruption Budget](/docs/tasks/run-application/configure-pdb/). +* [Вытеснение из-за дефицита ресурсов на узле](/docs/concepts/scheduling-eviction/node-pressure-eviction/). +* [Приоритет Pod'а и приоритизация](/docs/concepts/scheduling-eviction/pod-priority-preemption/). diff --git a/content/ru/docs/reference/glossary/api-eviction.md b/content/ru/docs/reference/glossary/api-eviction.md new file mode 100644 index 00000000000..0ab35ae3fc1 --- /dev/null +++ b/content/ru/docs/reference/glossary/api-eviction.md @@ -0,0 +1,24 @@ +--- +title: Вытеснение, инициированное через API +id: api-eviction +date: 2021-04-27 +full_link: /docs/concepts/scheduling-eviction/api-eviction/ +short_description: > + Вытеснение, инициированное через API — процесс, при котором с помощью Eviction API создается объект Eviction, + который запускает корректное завершение работы Pod'а. +aka: +tags: +- operation +--- + Вытеснение, инициированное через API — процесс, при котором с помощью [Eviction API](/docs/reference/generated/kubernetes-api/{{}}/#create-eviction-pod-v1-core) +создается объект `Eviction`, который запускает корректное завершение работы Pod'а. + + + +Вытеснение можно запросить через Eviction API, обратившись к нему напрямую, либо программно (через клиент API-сервера — например, с помощью команды `kubectl drain`). При этом будет создан объект `Eviction`, на основании которого API-сервер завершит работу Pod'а. + +Вытеснения, инициированные через API, учитывают заданные параметры [`PodDisruptionBudget`](/docs/tasks/run-application/configure-pdb/) (минимальное количество реплик, которые должны быть доступны для данного развертывания в любой момент времени) и [`terminationGracePeriodSeconds`](/docs/concepts/workloads/pods/pod-lifecycle#pod-termination) (период ожидания корректного завершения работы Pod'а). + +Обратите внимание: вытеснение, инициированное через API — не то же самое, что вытеснение из-за [дефицита ресурсов на узле](/docs/concepts/scheduling-eviction/node-pressure-eviction/). + +* Дополнительная информация доступна в разделе ["Вытеснение, инициированное API"](/docs/concepts/scheduling-eviction/api-eviction/). diff --git a/content/ru/docs/reference/glossary/pod-disruption.md b/content/ru/docs/reference/glossary/pod-disruption.md new file mode 100644 index 00000000000..e2a0a0f3db3 --- /dev/null +++ b/content/ru/docs/reference/glossary/pod-disruption.md @@ -0,0 +1,24 @@ +--- +id: pod-disruption +title: Нарушение работы Pod'ов +full_link: /docs/concepts/workloads/pods/disruptions/ +date: 2021-05-12 +short_description: > + Процесс, в ходе которого происходит плановое или принудительное завершение работы Pod'ов на узлах. + +aka: +related: + - pod + - container +tags: + - operation +--- + +[Нарушение работы Pod'ов (Pod disruption)](/docs/concepts/workloads/pods/disruptions/) — процесс, +в ходе которого происходит плановое или внеплановое (принудительное) завершение работы Pod'ов на узлах. + + + +Плановое завершение работы Pod'ов инициируется владельцами приложений или администраторами +кластера. Внеплановое завершение работы обычно вызвано непредвиденными обстоятельствами различной природы, +например, с недостатком ресурсов на узлах или случайными удалениями. From cc2fe4da21cd954d208172d53e7566fcd34a2ca7 Mon Sep 17 00:00:00 2001 From: Kinzhi Date: Thu, 16 Feb 2023 22:48:22 +0800 Subject: [PATCH 233/279] [zh-cn]SYNC pod-scheduling-readiness.md [zh-cn]SYNC pod-scheduling-readiness.md --- .../pod-scheduling-readiness.md | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/content/zh-cn/docs/concepts/scheduling-eviction/pod-scheduling-readiness.md b/content/zh-cn/docs/concepts/scheduling-eviction/pod-scheduling-readiness.md index 291a71c3004..637f1a299df 100644 --- a/content/zh-cn/docs/concepts/scheduling-eviction/pod-scheduling-readiness.md +++ b/content/zh-cn/docs/concepts/scheduling-eviction/pod-scheduling-readiness.md @@ -47,22 +47,7 @@ each schedulingGate can be removed in arbitrary order, but addition of a new sch 该字段只能在创建 Pod 时初始化(由客户端创建,或在准入期间更改)。 创建后,每个 schedulingGate 可以按任意顺序删除,但不允许添加新的调度门控。 -{{}} -stateDiagram-v2 - s1: 创建 Pod - s2: Pod 调度门控 - s3: Pod 调度就绪 - s4: Pod 运行 - if: 调度门控为空? - [*] --> s1 - s1 --> if - s2 --> if: 移除了调度门控 - if --> s2: 否 - if --> s3: 是 - s3 --> s4 - s4 --> [*] -{{< /mermaid >}} - +{{< figure src="/docs/images/podSchedulingGates.svg" alt="pod-scheduling-gates-diagram" caption="数字。Pod SchedulingGates" class="diagram-large" link="https://mermaid.live/edit#pako:eNplkktTwyAUhf8KgzuHWpukaYszutGlK3caFxQuCVMCGSDVTKf_XfKyPlhxz4HDB9wT5lYAptgHFuBRsdKxenFMClMYFIdfUdRYgbiD6ItJTEbR8wpEq5UpUfnDTf-5cbPoJjcbXdcaE61RVJIiqJvQ_Y30D-OCt-t3tFjcR5wZayiVnIGmkv4NiEfX9jijKTmmRH5jf0sRugOP0HyHUc1m6KGMFP27cM28fwSJDluPpNKaXqVJzmFNfHD2APRKSjnNFx9KhIpmzSfhVls3eHdTRrwG8QnxKfEZUUNeYTDBNbiaKRF_5dSfX-BQQQ0FpnEqQLJWhwIX5hyXsjbYl85wTINrgeC2EZd_xFQy7b_VJ6GCdd-itkxALE84dE3fAqXyIUZya6Qqe711OspVCI2ny2Vv35QqVO3-htt66ZWomAvVcZcv8yTfsiSFfJOydZoKvl_ttjLJVlJsblcJw-czwQ0zr9ZeqGDgeR77b2jD8xdtjtDn" >}} -或者通过**exists**运算符限制不匹配: +或者通过**notin**运算符限制不匹配: ```shell kubectl get pods -l 'environment,environment notin (frontend)' From 7cecd6a4ab2919b43ecd3573d40c6f43e7629d92 Mon Sep 17 00:00:00 2001 From: longalong <35618556+iamlongalong@users.noreply.github.com> Date: Thu, 16 Feb 2023 23:50:19 +0800 Subject: [PATCH 235/279] Update _index.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix markdown syntax mistake of "网络插件" link --- content/zh-cn/docs/concepts/extend-kubernetes/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/zh-cn/docs/concepts/extend-kubernetes/_index.md b/content/zh-cn/docs/concepts/extend-kubernetes/_index.md index e9b747100ce..a69cf493e70 100644 --- a/content/zh-cn/docs/concepts/extend-kubernetes/_index.md +++ b/content/zh-cn/docs/concepts/extend-kubernetes/_index.md @@ -542,7 +542,7 @@ allow Kubernetes to work with different networking topologies and technologies. 你的 Kubernetes 集群需要一个**网络插件**才能拥有一个正常工作的 Pod 网络, 才能支持 Kubernetes 网络模型的其他方面。 -[网络插件](/zh-cn/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/可以让 +[网络插件](/zh-cn/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/)可以让 Kubernetes 使用不同的网络拓扑和技术。 - -## Motivation - -Kubernetes {{< glossary_tooltip term_id="pod" text="Pods" >}} are created and destroyed -to match the desired state of your cluster. Pods are nonpermanent resources. If you use a {{< glossary_tooltip term_id="deployment" >}} to run your app, -it can create and destroy Pods dynamically. +that Deployment can create and destroy Pods dynamically. From one moment to the next, +you don't know how many of those Pods are working and healthy; you might not even know +what those healthy Pods are named. +Kubernetes {{< glossary_tooltip term_id="pod" text="Pods" >}} are created and destroyed +to match the desired state of your cluster. Pods are emphemeral resources (you should not +expect that an individual Pod is reliable and durable). -Each Pod gets its own IP address, however in a Deployment, the set of Pods -running in one moment in time could be different from -the set of Pods running that application a moment later. +Each Pod gets its own IP address (Kubernetes expects network plugins to ensure this). +For a given Deployment in your cluster, the set of Pods running in one moment in +time could be different from the set of Pods running that application a moment later. This leads to a problem: if some set of Pods (call them "backends") provides functionality to other Pods (call them "frontends") inside your cluster, @@ -42,14 +43,13 @@ to, so that the frontend can use the backend part of the workload? Enter _Services_. -## Service resources {#service-resource} + -In Kubernetes, a Service is an abstraction which defines a logical set of Pods -and a policy by which to access them (sometimes this pattern is called -a micro-service). The set of Pods targeted by a Service is usually determined -by a {{< glossary_tooltip text="selector" term_id="selector" >}}. -To learn about other ways to define Service endpoints, -see [Services _without_ selectors](#services-without-selectors). +## Services in Kubernetes + +The Service API, part of Kubernetes, is an abstraction to help you expose groups of +Pods over a network. Each Service object defines a logical set of endpoints (usually +these endpoints are Pods) along with a policy about how to make those pods accessible. For example, consider a stateless image-processing backend which is running with 3 replicas. Those replicas are fungible—frontends do not care which backend @@ -59,6 +59,26 @@ track of the set of backends themselves. The Service abstraction enables this decoupling. +The set of Pods targeted by a Service is usually determined +by a {{< glossary_tooltip text="selector" term_id="selector" >}} that you +define. +To learn about other ways to define Service endpoints, +see [Services _without_ selectors](#services-without-selectors). + +If your workload speaks HTTP, you might choose to use an +[Ingress](/docs/concepts/services-networking/ingress/) to control how web traffic +reaches that workload. +Ingress is not a Service type, but it acts as the entry point for your +cluster. An Ingress lets you consolidate your routing rules into a single resource, so +that you can expose multiple components of your workload, running separately in your +cluster, behind a single listener. + +The [Gateway](https://gateway-api.sigs.k8s.io/#what-is-the-gateway-api) API for Kubernetes +provides extra capabilities beyond Ingress and Service. You can add Gateway to your cluster - +it is a family of extension APIs, implemented using +{{< glossary_tooltip term_id="CustomResourceDefinition" text="CustomResourceDefinitions" >}} - +and then use these to configure access to network services that are running in your cluster. + ### Cloud-native service discovery If you're able to use Kubernetes APIs for service discovery in your application, @@ -69,6 +89,9 @@ whenever the set of Pods in a Service changes. For non-native applications, Kubernetes offers ways to place a network port or load balancer in between your application and the backend Pods. +Either way, your workload can use these [service discovery](#discovering-services) +mechanisms to find the target it wants to connect to. + ## Defining a Service A Service in Kubernetes is a REST object, similar to a Pod. Like all of the From 0dee0cf41e939d0aa3a09ff7d71a39506cc8f321 Mon Sep 17 00:00:00 2001 From: Shannon Kularathna Date: Thu, 16 Feb 2023 21:39:07 +0000 Subject: [PATCH 237/279] Clean up using secrets as files section --- .../en/docs/concepts/configuration/secret.md | 48 +++++++++---------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/content/en/docs/concepts/configuration/secret.md b/content/en/docs/concepts/configuration/secret.md index fc3bdc616d5..2186366fee9 100644 --- a/content/en/docs/concepts/configuration/secret.md +++ b/content/en/docs/concepts/configuration/secret.md @@ -201,25 +201,8 @@ If you want to access data from a Secret in a Pod, one way to do that is to have Kubernetes make the value of that Secret be available as a file inside the filesystem of one or more of the Pod's containers. -{{< note >}} -Versions of Kubernetes before v1.22 automatically created credentials for accessing -the Kubernetes API. This older mechanism was based on creating token Secrets that -could then be mounted into running Pods. -In more recent versions, including Kubernetes v{{< skew currentVersion >}}, API credentials -are obtained directly by using the [TokenRequest](/docs/reference/kubernetes-api/authentication-resources/token-request-v1/) API, -and are mounted into Pods using a [projected volume](/docs/reference/access-authn-authz/service-accounts-admin/#bound-service-account-token-volume). -The tokens obtained using this method have bounded lifetimes, and are automatically -invalidated when the Pod they are mounted into is deleted. - -You can still [manually create](/docs/tasks/configure-pod-container/configure-service-account/#manually-create-a-service-account-api-token) -a service account token Secret; for example, if you need a token that never expires. -However, using the [TokenRequest](/docs/reference/kubernetes-api/authentication-resources/token-request-v1/) -subresource to obtain a token to access the API is recommended instead. -You can use the [`kubectl create token`](/docs/reference/generated/kubectl/kubectl-commands#-em-token-em-) -command to obtain a token from the `TokenRequest` API. -{{< /note >}} - -#### Mounted Secrets are updated automatically +For instructions, refer to +[Distribute credentials securely using Secrets](/docs/tasks/inject-data-application/distribute-credentials-secure/#create-a-pod-that-has-access-to-the-secret-data-through-a-volume). When a volume contains data from a Secret, and that Secret is updated, Kubernetes tracks this and updates the data in the volume, using an eventually-consistent approach. @@ -638,13 +621,28 @@ A `kubernetes.io/service-account-token` type of Secret is used to store a token credential that identifies a {{< glossary_tooltip text="service account" term_id="service-account" >}}. -Since 1.22, this type of Secret is no longer used to mount credentials into Pods, -and obtaining tokens via the [TokenRequest](/docs/reference/kubernetes-api/authentication-resources/token-request-v1/) -API is recommended instead of using service account token Secret objects. -Tokens obtained from the `TokenRequest` API are more secure than ones stored in Secret objects, -because they have a bounded lifetime and are not readable by other API clients. -You can use the [`kubectl create token`](/docs/reference/generated/kubectl/kubectl-commands#-em-token-em-) +{{< note >}} +Versions of Kubernetes before v1.22 automatically created credentials for +accessing the Kubernetes API. This older mechanism was based on creating token +Secrets that could then be mounted into running Pods. +In more recent versions, including Kubernetes v{{< skew currentVersion >}}, API +credentials are obtained directly by using the +[TokenRequest](/docs/reference/kubernetes-api/authentication-resources/token-request-v1/) +API, and are mounted into Pods using a +[projected volume](/docs/reference/access-authn-authz/service-accounts-admin/#bound-service-account-token-volume). +The tokens obtained using this method have bounded lifetimes, and are +automatically invalidated when the Pod they are mounted into is deleted. + +You can still +[manually create](/docs/tasks/configure-pod-container/configure-service-account/#manually-create-a-service-account-api-token) +a service account token Secret; for example, if you need a token that never +expires. However, using the +[TokenRequest](/docs/reference/kubernetes-api/authentication-resources/token-request-v1/) +subresource to obtain a token to access the API is recommended instead. +You can use the +[`kubectl create token`](/docs/reference/generated/kubectl/kubectl-commands#-em-token-em-) command to obtain a token from the `TokenRequest` API. +{{< /note >}} You should only create a service account token Secret object if you can't use the `TokenRequest` API to obtain a token, From 0effee1f4674f68a2f15f00e9f346dc585f8ccc9 Mon Sep 17 00:00:00 2001 From: windsonsea Date: Fri, 17 Feb 2023 09:32:44 +0800 Subject: [PATCH 238/279] [zh] sync /translate-compose-kubernetes.md --- .../translate-compose-kubernetes.md | 80 +++++++++++-------- 1 file changed, 47 insertions(+), 33 deletions(-) diff --git a/content/zh-cn/docs/tasks/configure-pod-container/translate-compose-kubernetes.md b/content/zh-cn/docs/tasks/configure-pod-container/translate-compose-kubernetes.md index 6a70baec9cd..7b10d43e5c1 100644 --- a/content/zh-cn/docs/tasks/configure-pod-container/translate-compose-kubernetes.md +++ b/content/zh-cn/docs/tasks/configure-pod-container/translate-compose-kubernetes.md @@ -188,28 +188,16 @@ you need is an existing `docker-compose.yml` file. 输出类似于: ```none - INFO Kubernetes file "frontend-service.yaml" created - INFO Kubernetes file "frontend-service.yaml" created - INFO Kubernetes file "frontend-service.yaml" created - INFO Kubernetes file "redis-master-service.yaml" created - INFO Kubernetes file "redis-master-service.yaml" created - INFO Kubernetes file "redis-master-service.yaml" created - INFO Kubernetes file "redis-slave-service.yaml" created - INFO Kubernetes file "redis-slave-service.yaml" created - INFO Kubernetes file "redis-slave-service.yaml" created - INFO Kubernetes file "frontend-deployment.yaml" created - INFO Kubernetes file "frontend-deployment.yaml" created - INFO Kubernetes file "frontend-deployment.yaml" created - INFO Kubernetes file "redis-master-deployment.yaml" created - INFO Kubernetes file "redis-master-deployment.yaml" created - INFO Kubernetes file "redis-master-deployment.yaml" created - INFO Kubernetes file "redis-slave-deployment.yaml" created - INFO Kubernetes file "redis-slave-deployment.yaml" created + INFO Kubernetes file "frontend-tcp-service.yaml" created + INFO Kubernetes file "redis-master-service.yaml" created + INFO Kubernetes file "redis-slave-service.yaml" created + INFO Kubernetes file "frontend-deployment.yaml" created + INFO Kubernetes file "redis-master-deployment.yaml" created INFO Kubernetes file "redis-slave-deployment.yaml" created ``` ```bash - kubectl apply -f frontend-service.yaml,redis-master-service.yaml,redis-slave-service.yaml,frontend-deployment.yaml,redis-master-deployment.yaml,redis-slave-deployment.yaml + kubectl apply -f frontend-tcp-service.yaml,redis-master-service.yaml,redis-slave-service.yaml,frontend-deployment.yaml,redis-master-deployment.yaml,redis-slave-deployment.yaml ``` +4. 清理。 + + + 你完成示例应用 Deployment 的测试之后,只需在 Shell 中运行以下命令,就能删除用过的资源。 + + ```sh + kubectl delete -f frontend-tcp-service.yaml,redis-master-service.yaml,redis-slave-service.yaml,frontend-deployment.yaml,redis-master-deployment.yaml,redis-slave-deployment.yaml + ``` + -{{< note >}} 如果使用 ``oc create -f`` 手动推送 OpenShift 工件,则需要确保在构建配置工件之前推送 imagestream 工件,以解决 OpenShift 的这个问题: https://github.com/openshift/origin/issues/4518。 {{< /note >}} @@ -659,10 +673,10 @@ If you want to create normal pods without controllers you can use `restart` cons | `on-failure` | Pod | `OnFailure` | | `no` | Pod | `Never` | +{{< note >}} -{{< note >}} 控制器对象可以是 `deployment` 或 `replicationcontroller`。 {{< /note >}} From 6a60f037d282e7225b528a03bee07985ab56d0a6 Mon Sep 17 00:00:00 2001 From: Jian Wen Date: Fri, 17 Feb 2023 11:45:17 +0800 Subject: [PATCH 239/279] Update content/en/docs/concepts/architecture/cgroups.md Co-authored-by: Qiming Teng --- content/en/docs/concepts/architecture/cgroups.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/content/en/docs/concepts/architecture/cgroups.md b/content/en/docs/concepts/architecture/cgroups.md index 86627a65d18..f2090dfe1c9 100644 --- a/content/en/docs/concepts/architecture/cgroups.md +++ b/content/en/docs/concepts/architecture/cgroups.md @@ -103,7 +103,8 @@ updated to newer versions that support cgroup v2. For example: * If you run [cAdvisor](https://github.com/google/cadvisor) as a stand-alone DaemonSet for monitoring pods and containers, update it to v0.43.0 or later. * If you use JDK, prefer to use JDK 11.0.16 and later or JDK 15 and later, which [fully support cgroup v2](https://bugs.openjdk.org/browse/JDK-8230305). -* If you use uber-go/automaxprocs, update it to v1.5.1 or later. +* If you are using the [uber-go/automaxprocs](https://github.com/uber-go/automaxprocs) package, make sure + the version you use is v1.5.1 or higher. ## Identify the cgroup version on Linux Nodes {#check-cgroup-version} From f16f67eb56547ef7eb6700d38d84d01e31737536 Mon Sep 17 00:00:00 2001 From: lianghao208 Date: Fri, 17 Feb 2023 15:22:08 +0800 Subject: [PATCH 240/279] update pod scheduling readiness gate in pod lifecycle --- content/en/docs/concepts/workloads/pods/pod-lifecycle.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/content/en/docs/concepts/workloads/pods/pod-lifecycle.md b/content/en/docs/concepts/workloads/pods/pod-lifecycle.md index 852f965530c..43f9c70ccf3 100644 --- a/content/en/docs/concepts/workloads/pods/pod-lifecycle.md +++ b/content/en/docs/concepts/workloads/pods/pod-lifecycle.md @@ -267,6 +267,11 @@ after successful sandbox creation and network configuration by the runtime plugin). For a Pod without init containers, the kubelet sets the `Initialized` condition to `True` before sandbox creation and network configuration starts. +### Pod scheduling readiness {#pod-scheduling-readiness-gate} + +{{< feature-state for_k8s_version="v1.26" state="alpha" >}} + +See [Pod Scheduling Readiness](/docs/concepts/scheduling-eviction/pod-scheduling-readiness/) for more information. ## Container probes From 7e343b331366b8f242262b154945491b243cf384 Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 16 Feb 2023 21:15:25 +0800 Subject: [PATCH 241/279] [zh] sync /controllers/daemonset.md --- .../workloads/controllers/daemonset.md | 136 ++++++++++++------ 1 file changed, 89 insertions(+), 47 deletions(-) diff --git a/content/zh-cn/docs/concepts/workloads/controllers/daemonset.md b/content/zh-cn/docs/concepts/workloads/controllers/daemonset.md index c90130bcb57..2902f32d187 100644 --- a/content/zh-cn/docs/concepts/workloads/controllers/daemonset.md +++ b/content/zh-cn/docs/concepts/workloads/controllers/daemonset.md @@ -202,36 +202,42 @@ If you do not specify either, then the DaemonSet controller will create Pods on ## Daemon Pods 是如何被调度的 {#how-daemon-pods-are-scheduled} -### 通过默认调度器调度 {#scheduled-by-default-scheduler} - -{{< feature-state for_k8s_version="1.17" state="stable" >}} - DaemonSet 确保所有符合条件的节点都运行该 Pod 的一个副本。 -通常,运行 Pod 的节点由 Kubernetes 调度器选择。 -不过,DaemonSet Pods 由 DaemonSet 控制器创建和调度。这就带来了以下问题: +DaemonSet 控制器为每个符合条件的节点创建一个 Pod,并添加 Pod 的 `spec.affinity.nodeAffinity` +字段以匹配目标主机。Pod 被创建之后,默认的调度程序通常通过设置 `.spec.nodeName` 字段来接管 Pod 并将 +Pod 绑定到目标主机。如果新的 Pod 无法放在节点上,则默认的调度程序可能会根据新 Pod +的[优先级](/zh-cn/docs/concepts/scheduling-eviction/pod-priority-preemption/#pod-priority)抢占 +(驱逐)某些现存的 Pod。 -* Pod 行为的不一致性:正常 Pod 在被创建后等待调度时处于 `Pending` 状态, - DaemonSet Pods 创建后不会处于 `Pending` 状态下。这使用户感到困惑。 -* [Pod 抢占](/zh-cn/docs/concepts/scheduling-eviction/pod-priority-preemption/)由默认调度器处理。 - 启用抢占后,DaemonSet 控制器将在不考虑 Pod 优先级和抢占的情况下制定调度决策。 + +用户通过设置 DaemonSet 的 `.spec.template.spec.schedulerName` 字段,可以为 DamonSet +的 Pod 指定不同的调度程序。 + +当评估符合条件的节点时,原本在 `.spec.template.spec.affinity.nodeAffinity` 字段上指定的节点亲和性将由 +DaemonSet 控制器进行考量,但在创建的 Pod 上会被替换为与符合条件的节点名称匹配的节点亲和性。 -此外,系统会自动添加 `node.kubernetes.io/unschedulable:NoSchedule` 容忍度到这些 -DaemonSet Pod。在调度 DaemonSet Pod 时,默认调度器会忽略 `unschedulable` 节点。 +### Taints and tolerations - ### 污点和容忍度 {#taint-and-toleration} -尽管 Daemon Pod 遵循[污点和容忍度](/zh-cn/docs/concepts/scheduling-eviction/taint-and-toleration/)规则, -根据相关特性,控制器会自动将以下容忍度添加到 DaemonSet Pod: +DaemonSet 控制器会自动将一组容忍度添加到 DaemonSet Pod: -| 容忍度键名 | 效果 | 版本 | 描述 | -| ---------------------------------------- | ---------- | ------- | ------------------------------------------------------------ | -| `node.kubernetes.io/not-ready` | NoExecute | 1.13+ | 当出现类似网络断开的情况导致节点问题时,DaemonSet Pod 不会被逐出。 | -| `node.kubernetes.io/unreachable` | NoExecute | 1.13+ | 当出现类似于网络断开的情况导致节点问题时,DaemonSet Pod 不会被逐出。 | -| `node.kubernetes.io/disk-pressure` | NoSchedule | 1.8+ | DaemonSet Pod 被默认调度器调度时能够容忍磁盘压力属性。 | -| `node.kubernetes.io/memory-pressure` | NoSchedule | 1.8+ | DaemonSet Pod 被默认调度器调度时能够容忍内存压力属性。 | -| `node.kubernetes.io/unschedulable` | NoSchedule | 1.12+ | DaemonSet Pod 能够容忍默认调度器所设置的 `unschedulable` 属性. | -| `node.kubernetes.io/network-unavailable` | NoSchedule | 1.12+ | DaemonSet 在使用宿主网络时,能够容忍默认调度器所设置的 `network-unavailable` 属性。 | + +{{< table caption="DaemonSet Pod 适用的容忍度" >}} + + +| 容忍度键名 | 效果 | 描述 | +| -------------------------------------------------------- | ---------- | ----------------------- | +| [`node.kubernetes.io/not-ready`](/zh-cn/docs/reference/labels-annotations-taints/#node-kubernetes-io-not-ready) | `NoExecute` | DaemonSet Pod 可以被调度到不健康或还不准备接受 Pod 的节点上。在这些节点上运行的所有 DaemonSet Pod 将不会被驱逐。 | +| [`node.kubernetes.io/unreachable`](/zh-cn/docs/reference/labels-annotations-taints/#node-kubernetes-io-unreachable) | `NoExecute` | DaemonSet Pod 可以被调度到从节点控制器不可达的节点上。在这些节点上运行的所有 DaemonSet Pod 将不会被驱逐。 | +| [`node.kubernetes.io/disk-pressure`](/zh-cn/docs/reference/labels-annotations-taints/#node-kubernetes-io-disk-pressure) | `NoSchedule` | DaemonSet Pod 可以被调度到具有磁盘压力问题的节点上。 | +| [`node.kubernetes.io/memory-pressure`](/zh-cn/docs/reference/labels-annotations-taints/#node-kubernetes-io-memory-pressure) | `NoSchedule` | DaemonSet Pod 可以被调度到具有内存压力问题的节点上。 | +| [`node.kubernetes.io/pid-pressure`](/zh-cn/docs/reference/labels-annotations-taints/#node-kubernetes-io-pid-pressure) | `NoSchedule` | DaemonSet Pod 可以被调度到具有进程压力问题的节点上。 | +| [`node.kubernetes.io/unschedulable`](/zh-cn/docs/reference/labels-annotations-taints/#node-kubernetes-io-unschedulable) | `NoSchedule` | DaemonSet Pod 可以被调度到不可调度的节点上。 | +| [`node.kubernetes.io/network-unavailable`](/zh-cn/docs/reference/labels-annotations-taints/#node-kubernetes-io-network-unavailable) | `NoSchedule` | **仅针对请求主机联网的 DaemonSet Pod 添加此容忍度**,即 Pod 具有 `spec.hostNetwork: true`。这些 DaemonSet Pod 可以被调度到网络不可用的节点上。| + +{{< /table >}} + + +你也可以在 DaemonSet 的 Pod 模板中定义自己的容忍度并将其添加到 DaemonSet Pod。 + +因为 DaemonSet 控制器自动设置 `node.kubernetes.io/unschedulable:NoSchedule` 容忍度, +所以 Kubernetes 可以在标记为**不可调度**的节点上运行 DaemonSet Pod。 + + +如果你使用 DaemonSet 提供重要的节点级别功能, +例如[集群联网](/zh-cn/docs/concepts/cluster-administration/networking/), +Kubernetes 在节点就绪之前将 DaemonSet Pod 放到节点上会很有帮助。 +例如,如果没有这种特殊的容忍度,因为网络插件未在节点上运行,所以你可能会在未标记为就绪的节点上陷入死锁状态, +同时因为该节点还未就绪,所以网络插件不会在该节点上运行。 -## 与 Daemon Pods 通信 {#communicating-with-daemon-pods} +## 与 Daemon Pod 通信 {#communicating-with-daemon-pods} - 不同的团队可以在不同的命名空间下工作。这可以通过 [RBAC](/zh-cn/docs/reference/access-authn-authz/rbac/) 强制执行。 @@ -337,7 +339,7 @@ Secret 的数量进行配额限制。 Job 而导致集群拒绝服务。 对有限的一组资源上实施一般性的对象数量配额也是可能的。 @@ -542,7 +544,9 @@ works as follows: - 集群中的 Pod 可取三个优先级类之一,即 "low"、"medium"、"high"。 - 为每个优先级创建一个配额对象。 - + 将以下 YAML 保存到文件 `quota.yml` 中。 ```yaml @@ -560,7 +564,7 @@ items: pods: "10" scopeSelector: matchExpressions: - - operator : In + - operator: In scopeName: PriorityClass values: ["high"] - apiVersion: v1 @@ -574,7 +578,7 @@ items: pods: "10" scopeSelector: matchExpressions: - - operator : In + - operator: In scopeName: PriorityClass values: ["medium"] - apiVersion: v1 @@ -588,7 +592,7 @@ items: pods: "10" scopeSelector: matchExpressions: - - operator : In + - operator: In scopeName: PriorityClass values: ["low"] ``` @@ -746,7 +750,7 @@ from getting scheduled in a failure domain. 因为带有反亲和性约束的 Pod 可能会阻止所有其他名字空间的 Pod 被调度到某失效域中。 @@ -769,8 +773,8 @@ spec: ``` @@ -795,7 +799,7 @@ plugins: 基于上面的配置,只有名字空间中包含作用域为 `CrossNamespaceAffinity` From 141050b4289ff34bf018613c87f21247dc99af70 Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Sat, 18 Feb 2023 00:45:45 +0800 Subject: [PATCH 246/279] [zh] Resync pages in concepts/overview --- .../concepts/overview/working-with-objects/annotations.md | 7 +++---- .../overview/working-with-objects/kubernetes-objects.md | 3 ++- .../concepts/overview/working-with-objects/namespaces.md | 2 +- .../overview/working-with-objects/object-management.md | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/content/zh-cn/docs/concepts/overview/working-with-objects/annotations.md b/content/zh-cn/docs/concepts/overview/working-with-objects/annotations.md index 8c8b5c107bb..bb903ff85b2 100644 --- a/content/zh-cn/docs/concepts/overview/working-with-objects/annotations.md +++ b/content/zh-cn/docs/concepts/overview/working-with-objects/annotations.md @@ -153,7 +153,7 @@ metadata: spec: containers: - name: nginx - image: nginx:1.7.9 + image: nginx:1.14.2 ports: - containerPort: 80 ``` @@ -161,7 +161,6 @@ spec: ## {{% heading "whatsnext" %}} -* 进一步了解[标签和选择算符](/zh-cn/docs/concepts/overview/working-with-objects/labels/)。 - +进一步了解[标签和选择算符](/zh-cn/docs/concepts/overview/working-with-objects/labels/)。 diff --git a/content/zh-cn/docs/concepts/overview/working-with-objects/kubernetes-objects.md b/content/zh-cn/docs/concepts/overview/working-with-objects/kubernetes-objects.md index 83a3a094c7d..e74da9595c3 100644 --- a/content/zh-cn/docs/concepts/overview/working-with-objects/kubernetes-objects.md +++ b/content/zh-cn/docs/concepts/overview/working-with-objects/kubernetes-objects.md @@ -18,7 +18,8 @@ card: 本页说明了在 Kubernetes API 中是如何表示 Kubernetes 对象的, 以及使用 `.yaml` 格式的文件表示 Kubernetes 对象。 diff --git a/content/zh-cn/docs/concepts/overview/working-with-objects/namespaces.md b/content/zh-cn/docs/concepts/overview/working-with-objects/namespaces.md index 5ff45d85f90..8e2b194d6d3 100644 --- a/content/zh-cn/docs/concepts/overview/working-with-objects/namespaces.md +++ b/content/zh-cn/docs/concepts/overview/working-with-objects/namespaces.md @@ -268,7 +268,7 @@ kubectl api-resources --namespaced=false --> ## 自动打标签 {#automatic-labelling} -{{< feature-state state="beta" for_k8s_version="stable" >}} +{{< feature-state for_k8s_version="1.22" state="stable" >}} 与对象配置相比的优点: -- 命令简单,易学且易于记忆。 +- 命令用单个动词表示。 - 命令仅需一步即可对集群进行更改。 Kubernetes 是一个可移植、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。 Kubernetes 拥有一个庞大且快速增长的生态,其服务、支持和工具的使用范围相当广泛。 **Kubernetes** 这个名字源于希腊语,意为“舵手”或“飞行员”。k8s 这个缩写是因为 k 和 s 之间有八个字符的关系。 Google 在 2014 年开源了 Kubernetes 项目。 @@ -61,7 +68,13 @@ Let's take a look at why Kubernetes is so useful by going back in time. **传统部署时代:** @@ -74,7 +87,10 @@ Early on, organizations ran applications on physical servers. There was no way t 而且维护许多物理服务器的成本很高。 **虚拟化部署时代:** @@ -83,9 +99,13 @@ Early on, organizations ran applications on physical servers. There was no way t 因为一个应用程序的信息不能被另一应用程序随意访问。 虚拟化技术能够更好地利用物理服务器的资源,并且因为可轻松地添加或更新应用程序, 而因此可以具有更高的可扩缩性,以及降低硬件成本等等的好处。 @@ -94,7 +114,12 @@ Each VM is a full machine running all the components, including its own operatin 每个 VM 是一台完整的计算机,在虚拟化硬件之上运行所有组件,包括其自己的操作系统。 **容器部署时代:** @@ -108,14 +133,25 @@ Containers have become popular because they provide extra benefits, such as: 容器因具有许多优势而变得流行起来,例如: @@ -140,7 +176,10 @@ Containers have become popular because they provide extra benefits, such as: ## 为什么需要 Kubernetes,它能做什么? {#why-you-need-kubernetes-and-what-can-it-do} 容器是打包和运行应用程序的好方式。在生产环境中, 你需要管理运行着应用程序的容器,并确保服务不会下线。 @@ -148,7 +187,10 @@ Containers are a good way to bundle and run your applications. In a production e 如果此行为交由给系统处理,是不是会更容易一些? 这就是 Kubernetes 要来做的事情! Kubernetes 为你提供了一个可弹性运行分布式系统的框架。 @@ -162,7 +204,9 @@ Kubernetes 为你提供: * **服务发现和负载均衡** @@ -172,7 +216,8 @@ Kubernetes can expose a container using the DNS name or using their own IP addre * **存储编排** @@ -180,7 +225,10 @@ Kubernetes allows you to automatically mount a storage system of your choice, su * **自动部署和回滚** @@ -191,7 +239,9 @@ You can describe the desired state for your deployed containers using Kubernetes * **自动完成装箱计算** @@ -201,7 +251,9 @@ You provide Kubernetes with a cluster of nodes that it can use to run containeri * **自我修复** @@ -210,7 +262,9 @@ Kubernetes restarts containers that fail, replaces containers, kills containers * **密钥与配置管理** @@ -223,7 +277,13 @@ Kubernetes lets you store and manage sensitive information, such as passwords, O ## Kubernetes 不是什么 {#what-kubernetes-is-not} Kubernetes 不是传统的、包罗万象的 PaaS(平台即服务)系统。 由于 Kubernetes 是在容器级别运行,而非在硬件级别,它提供了 PaaS 产品共有的一些普遍适用的功能, @@ -237,9 +297,17 @@ Kubernetes: Kubernetes: * 不限制支持的应用程序类型。 Kubernetes 旨在支持极其多种多样的工作负载,包括无状态、有状态和数据处理工作负载。 @@ -251,10 +319,18 @@ Kubernetes: (例如 Ceph)。这样的组件可以在 Kubernetes 上运行,并且/或者可以由运行在 Kubernetes 上的应用程序通过可移植机制(例如[开放服务代理](https://openservicebrokerapi.org/))来访问。 * 不是日志记录、监视或警报的解决方案。 它集成了一些功能作为概念证明,并提供了收集和导出指标的机制。 diff --git a/content/zh-cn/docs/concepts/overview/components.md b/content/zh-cn/docs/concepts/overview/components.md index 97c4bbcc17b..2c59b84aefb 100644 --- a/content/zh-cn/docs/concepts/overview/components.md +++ b/content/zh-cn/docs/concepts/overview/components.md @@ -22,16 +22,16 @@ card: weight: 20 --> + - 当你部署完 Kubernetes,便拥有了一个完整的集群。 {{< glossary_definition term_id="cluster" length="all" >}} @@ -152,7 +152,7 @@ Node components run on every node, maintaining running pods and providing the Ku {{< glossary_definition term_id="kube-proxy" length="all" >}} ### 容器运行时(Container Runtime) {#container-runtime} diff --git a/content/zh-cn/docs/concepts/overview/kubernetes-api.md b/content/zh-cn/docs/concepts/overview/kubernetes-api.md index b4272751b7e..e5c3a22ddf7 100644 --- a/content/zh-cn/docs/concepts/overview/kubernetes-api.md +++ b/content/zh-cn/docs/concepts/overview/kubernetes-api.md @@ -201,7 +201,7 @@ The relative URLs are pointing to immutable OpenAPI descriptions, in order to improve client-side caching. The proper HTTP caching headers are also set by the API server for that purpose (`Expires` to 1 year in the future, and `Cache-Control` to `immutable`). When an obsolete URL is -used, the API server returns a redirect to the newest URL. +used, the API server returns a redirect to the newest URL. --> 为了改进客户端缓存,相对的 URL 会指向不可变的 OpenAPI 描述。 为了此目的,API 服务器也会设置正确的 HTTP 缓存标头 @@ -213,7 +213,7 @@ The Kubernetes API server publishes an OpenAPI v3 spec per Kubernetes group version at the `/openapi/v3/apis//?hash=` endpoint. -Refer to the table below for accepted request headers. +Refer to the table below for accepted request headers. --> Kubernetes API 服务器会在端点 `/openapi/v3/apis//?hash=` 发布一个 Kubernetes 组版本的 OpenAPI v3 规范。 @@ -311,14 +311,14 @@ API 服务器可以通过多个 API 版本提供相同的底层数据。 直到 `v1beta1` 版本被废弃和移除为止。此后,你可以使用 `v1` API 继续访问和修改该对象。 -## API 变更 {#api-changes} +### API 变更 {#api-changes} 任何成功的系统都要随着新的使用案例的出现和现有案例的变化来成长和变化。 为此,Kubernetes 已设计了 Kubernetes API 来持续变更和成长。 From d08ae655fd29f3f4544358c9d40f78054fb8c9ea Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Sat, 18 Feb 2023 01:07:55 +0800 Subject: [PATCH 248/279] Clean up page device-plugins --- .../compute-storage-net/device-plugins.md | 86 +++++++++---------- 1 file changed, 42 insertions(+), 44 deletions(-) diff --git a/content/en/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins.md b/content/en/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins.md index b26a25af04d..a241ccee3d4 100644 --- a/content/en/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins.md +++ b/content/en/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins.md @@ -88,56 +88,56 @@ spec: The general workflow of a device plugin includes the following steps: 1. Initialization. During this phase, the device plugin performs vendor-specific - initialization and setup to make sure the devices are in a ready state. + initialization and setup to make sure the devices are in a ready state. 1. The plugin starts a gRPC service, with a Unix socket under the host path - `/var/lib/kubelet/device-plugins/`, that implements the following interfaces: + `/var/lib/kubelet/device-plugins/`, that implements the following interfaces: - ```gRPC - service DevicePlugin { - // GetDevicePluginOptions returns options to be communicated with Device Manager. - rpc GetDevicePluginOptions(Empty) returns (DevicePluginOptions) {} + ```gRPC + service DevicePlugin { + // GetDevicePluginOptions returns options to be communicated with Device Manager. + rpc GetDevicePluginOptions(Empty) returns (DevicePluginOptions) {} - // ListAndWatch returns a stream of List of Devices - // Whenever a Device state change or a Device disappears, ListAndWatch - // returns the new list - rpc ListAndWatch(Empty) returns (stream ListAndWatchResponse) {} + // ListAndWatch returns a stream of List of Devices + // Whenever a Device state change or a Device disappears, ListAndWatch + // returns the new list + rpc ListAndWatch(Empty) returns (stream ListAndWatchResponse) {} - // Allocate is called during container creation so that the Device - // Plugin can run device specific operations and instruct Kubelet - // of the steps to make the Device available in the container - rpc Allocate(AllocateRequest) returns (AllocateResponse) {} + // Allocate is called during container creation so that the Device + // Plugin can run device specific operations and instruct Kubelet + // of the steps to make the Device available in the container + rpc Allocate(AllocateRequest) returns (AllocateResponse) {} - // GetPreferredAllocation returns a preferred set of devices to allocate - // from a list of available ones. The resulting preferred allocation is not - // guaranteed to be the allocation ultimately performed by the - // devicemanager. It is only designed to help the devicemanager make a more - // informed allocation decision when possible. - rpc GetPreferredAllocation(PreferredAllocationRequest) returns (PreferredAllocationResponse) {} + // GetPreferredAllocation returns a preferred set of devices to allocate + // from a list of available ones. The resulting preferred allocation is not + // guaranteed to be the allocation ultimately performed by the + // devicemanager. It is only designed to help the devicemanager make a more + // informed allocation decision when possible. + rpc GetPreferredAllocation(PreferredAllocationRequest) returns (PreferredAllocationResponse) {} - // PreStartContainer is called, if indicated by Device Plugin during registeration phase, - // before each container start. Device plugin can run device specific operations - // such as resetting the device before making devices available to the container. - rpc PreStartContainer(PreStartContainerRequest) returns (PreStartContainerResponse) {} - } - ``` + // PreStartContainer is called, if indicated by Device Plugin during registeration phase, + // before each container start. Device plugin can run device specific operations + // such as resetting the device before making devices available to the container. + rpc PreStartContainer(PreStartContainerRequest) returns (PreStartContainerResponse) {} + } + ``` - {{< note >}} - Plugins are not required to provide useful implementations for - `GetPreferredAllocation()` or `PreStartContainer()`. Flags indicating - the availability of these calls, if any, should be set in the `DevicePluginOptions` - message sent back by a call to `GetDevicePluginOptions()`. The `kubelet` will - always call `GetDevicePluginOptions()` to see which optional functions are - available, before calling any of them directly. - {{< /note >}} + {{< note >}} + Plugins are not required to provide useful implementations for + `GetPreferredAllocation()` or `PreStartContainer()`. Flags indicating + the availability of these calls, if any, should be set in the `DevicePluginOptions` + message sent back by a call to `GetDevicePluginOptions()`. The `kubelet` will + always call `GetDevicePluginOptions()` to see which optional functions are + available, before calling any of them directly. + {{< /note >}} 1. The plugin registers itself with the kubelet through the Unix socket at host - path `/var/lib/kubelet/device-plugins/kubelet.sock`. + path `/var/lib/kubelet/device-plugins/kubelet.sock`. - {{< note >}} - The ordering of the workflow is important. A plugin MUST start serving gRPC - service before registering itself with kubelet for successful registration. - {{< /note >}} + {{< note >}} + The ordering of the workflow is important. A plugin MUST start serving gRPC + service before registering itself with kubelet for successful registration. + {{< /note >}} 1. After successfully registering itself, the device plugin runs in serving mode, during which it keeps monitoring device health and reports back to the kubelet upon any device state changes. @@ -297,7 +297,6 @@ However, calling `GetAllocatableResources` endpoint is not sufficient in case of update and Kubelet needs to be restarted to reflect the correct resource capacity and allocatable. {{< /note >}} - ```gRPC // AllocatableResourcesResponses contains informations about all the devices known by the kubelet message AllocatableResourcesResponse { @@ -318,14 +317,14 @@ Preceding Kubernetes v1.23, to enable this feature `kubelet` must be started wit ``` `ContainerDevices` do expose the topology information declaring to which NUMA cells the device is -affine. The NUMA cells are identified using a opaque integer ID, which value is consistent to +affine. The NUMA cells are identified using a opaque integer ID, which value is consistent to what device plugins report [when they register themselves to the kubelet](/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/#device-plugin-integration-with-the-topology-manager). The gRPC service is served over a unix socket at `/var/lib/kubelet/pod-resources/kubelet.sock`. Monitoring agents for device plugin resources can be deployed as a daemon, or as a DaemonSet. The canonical directory `/var/lib/kubelet/pod-resources` requires privileged access, so monitoring -agents must run in a privileged security context. If a device monitoring agent is running as a +agents must run in a privileged security context. If a device monitoring agent is running as a DaemonSet, `/var/lib/kubelet/pod-resources` must be mounted as a {{< glossary_tooltip term_id="volume" >}} in the device monitoring agent's [PodSpec](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podspec-v1-core). @@ -360,7 +359,7 @@ resource assignment decisions. `TopologyInfo` supports setting a `nodes` field to either `nil` or a list of NUMA nodes. This allows the Device Plugin to advertise a device that spans multiple NUMA nodes. -Setting `TopologyInfo` to `nil` or providing an empty list of NUMA nodes for a given device +Setting `TopologyInfo` to `nil` or providing an empty list of NUMA nodes for a given device indicates that the Device Plugin does not have a NUMA affinity preference for that device. An example `TopologyInfo` struct populated for a device by a Device Plugin: @@ -396,4 +395,3 @@ Here are some examples of device plugin implementations: * Learn about the [Topology Manager](/docs/tasks/administer-cluster/topology-manager/) * Read about using [hardware acceleration for TLS ingress](/blog/2019/04/24/hardware-accelerated-ssl/tls-termination-in-ingress-controllers-using-kubernetes-device-plugins-and-runtimeclass/) with Kubernetes - From 30b23dd10704bf61ad1bad2b991fcfb694620918 Mon Sep 17 00:00:00 2001 From: grainrigi Date: Sun, 5 Feb 2023 10:42:52 +0900 Subject: [PATCH 249/279] [ja] Add /blog/2022/02/17/dockershim-faq (/ja/dockershim) and dockershim_message --- ...-12-02-dont-panic-kubernetes-and-docker.md | 2 +- .../2022-02-17-updated-dockershim-faq.md | 194 ++++++++++++++++++ .../migrating-from-dockershim/_index.md | 2 +- ...migrating-telemetry-and-security-agents.md | 2 +- data/i18n/ja/ja.toml | 3 + 5 files changed, 200 insertions(+), 3 deletions(-) create mode 100644 content/ja/blog/_posts/2022-02-17-updated-dockershim-faq.md diff --git a/content/ja/blog/_posts/2020-12-02-dont-panic-kubernetes-and-docker.md b/content/ja/blog/_posts/2020-12-02-dont-panic-kubernetes-and-docker.md index 09e2a5592e4..46b9cb28b87 100644 --- a/content/ja/blog/_posts/2020-12-02-dont-panic-kubernetes-and-docker.md +++ b/content/ja/blog/_posts/2020-12-02-dont-panic-kubernetes-and-docker.md @@ -43,4 +43,4 @@ DockerはCRI([Container Runtime Interface](https://kubernetes.io/blog/2016/12/co 経験の多寡や難易度にかかわらず、どんなことでも質問してください。我々の目標は、全ての人が将来の変化について、可能な限りの知識と理解を得られることです。 このブログが多くの質問の答えとなり、不安を和らげることができればと願っています。 -別の情報をお探してあれば、[Dockershim Deprecation FAQ](/blog/2020/12/02/dockershim-faq/)を参照してください。 +別の情報をお探してあれば、[dockershimの削除に関するFAQ](/ja/dockershim)を参照してください。 diff --git a/content/ja/blog/_posts/2022-02-17-updated-dockershim-faq.md b/content/ja/blog/_posts/2022-02-17-updated-dockershim-faq.md new file mode 100644 index 00000000000..329a07016b6 --- /dev/null +++ b/content/ja/blog/_posts/2022-02-17-updated-dockershim-faq.md @@ -0,0 +1,194 @@ +--- +layout: blog +title: "更新: dockershimの削除に関するFAQ" +linkTitle: "dockershimの削除に関するFAQ" +date: 2022-02-17 +slug: dockershim-faq +aliases: [ '/ja/dockershim' ] +--- + +**この記事は2020年の後半に投稿されたオリジナルの記事[Dockershim Deprecation FAQ](/blog/2020/12/02/dockershim-faq/)の更新版です。 +この記事にはv1.24のリリースに関する更新を含みます。** + +--- + +この文書では、Kubernetesからの _dockershim_ の削除に関するよくある質問について説明します。 +この削除はKubernetes v1.20リリースの一部としてはじめて[発表](/blog/2020/12/08/kubernetes-1-20-release-announcement/)されたものです。 +Kubernetes [v1.24のリリース](/releases/#release-v1-24)においてdockershimは実際にKubernetesから削除されました。 + +これが何を意味するかについては、ブログ記事[Don't Panic: Kubernetes and Docker](/ja/blog/2020/12/02/dont-panic-kubernetes-and-docker/)をご覧ください。 + +[Check whether dockershim removal affects you](/docs/tasks/administer-cluster/migrating-from-dockershim/check-if-dockershim-removal-affects-you/)をお読みいただくことで、 +dockershimの削除があなたやあなたの組織に与える影響をご判断いただけます。 + +Kubernetes 1.24リリースに至るまでの間、Kubernetesコントリビューターはこの移行を円滑に行えるようにするために尽力してきました。 + +- 私たちの[コミットメントと次のステップ](/blog/2022/01/07/kubernetes-is-moving-on-from-dockershim/)を詳述したブログ記事。 +- [他のコンテナランタイム](/ja/docs/setup/production-environment/container-runtimes/#container-runtimes)への移行に大きな障害があるかどうかのチェック。 +- [dockershimからの移行](/ja/docs/tasks/administer-cluster/migrating-from-dockershim/)ガイドの追加。 +- [dockershimの削除とCRI互換ランタイムの使用に関する記事一覧](/docs/reference/node/topics-on-dockershim-and-cri-compatible-runtimes/)の作成。 + このリストには、上に示した文書の一部が含まれており、また、厳選された外部の情報(ベンダーによるガイドを含む)もカバーしています。 + +### dockershimはなぜKubernetesから削除されたのですか? + +Kubernetesの初期のバージョンは、特定のコンテナランタイム上でのみ動作しました。 +Docker Engineです。その後、Kubernetesは他のコンテナランタイムと連携するためのサポートを追加しました。 +オーケストレーター(Kubernetesなど)と多くの異なるコンテナランタイムの間の相互運用を可能にするため、 +CRI標準が[作成](/blog/2016/12/container-runtime-interface-cri-in-kubernetes/)されました。 +Docker Engineはそのインターフェイス(CRI)を実装していないため、Kubernetesプロジェクトは移行を支援する特別なコードを作成し、 +その _dockershim_ コードをKubernetes自身の一部としました。 + +dockershimコードは常に一時的な解決策であることを意図されていました(このためshimと名付けられています)。 +コミュニティでの議論や計画については、[dockershimの削除によるKubernetes改良の提案][drkep]にてお読みいただけます。 + +実際、dockershimのメンテナンスはKubernetesメンテナーにとって大きな負担になっていました。 + +さらに、dockershimとほとんど互換性のなかった機能、たとえばcgroups v2やユーザーネームスペースなどが、 +これらの新しいCRIランタイムに実装されています。Kubernetesからdockershimを削除することで、これらの分野でのさらなる開発が可能になります。 + +[drkep]: https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/2221-remove-dockershim + +### Dockerとコンテナは同じものですか? + +DockerはLinuxのコンテナパターンを普及させ、その基盤技術の発展に寄与してきましたが、 +Linuxのコンテナ技術そのものはかなり以前から存在しています。 +また、コンテナエコシステムはDockerを超えてより広範に発展してきました。 +OCIやCRIのような標準は、Dockerの機能の一部を置き換えたり、既存の機能を強化したりすることで、 +私達のエコシステムの多くのツールの成長と繁栄を助けてきました。 + +### 既存のコンテナイメージは引き続き使えるのですか? + +はい、`docker build`から生成されるイメージは、全てのCRI実装で動作します。 +既存のイメージも全く同じように動作します。 + +### プライベートイメージについてはどうでしょうか? + +はい、すべてのCRIランタイムはKubernetesで使われているものと同一のpull secretsをサポートしており、 +PodSpecまたはService Accountを通して利用できます。 + +### Kubernetes 1.23でDocker Engineを引き続き使用できますか? + +はい、1.20で変更されたのは、Docker Engineランタイムを使用している場合に警告ログが[kubelet]起動時に出るようになったことだけです。 +この警告は、1.23までのすべてのバージョンで表示されます。 +dockershimの削除はKubernetes 1.24で行われました。 + +Kubernetes v1.24以降を実行している場合は、[Docker Engineを引き続きコンテナランタイムとして利用できますか?](#can-i-still-use-docker-engine-as-my-container-runtime)をご覧ください。 +(CRIがサポートされているKubernetesリリースを使用している場合、dockershimから切り替えることができることを忘れないでください。 +リリースv1.24からはKubernetesにdockershimが含まれなくなったため、**必ず**切り替えなければなりません)。 + +[kubelet]: /docs/reference/command-line-tools-reference/kubelet/ + +### どのCRIの実装を使うべきでしょうか? + +これは難しい質問で、様々な要素に依存します。 +もしDocker Engineがうまく動いているのであれば、containerdに移行するのは比較的簡単で、 +性能もオーバーヘッドも確実に改善されるでしょう。 +しかし、他の選択のほうがあなたの環境により適合する場合もありますので、 +[CNCF landscape]にあるすべての選択肢を検討されることをおすすめします。 + +[CNCF landscape]: https://landscape.cncf.io/card-mode?category=container-runtime&grouping=category + +#### Docker Engineを引き続きコンテナランタイムとして利用できますか? {#can-i-still-use-docker-engine-as-my-container-runtime} + +第一に、ご自身のPCで開発やテスト用途でDockerを使用している場合、何も変わることはありません。 +Kubernetesでどのコンテナランタイムを使っていても、Dockerをローカルで使い続けることができます。 +コンテナではこのような相互運用性を実現できます。 + +MirantisとDockerは、Kubernetesから内蔵のdockershimが削除された後も、 +Docker Engineの代替アダプターを維持することに[コミット][mirantis]しています。 +代替アダプターの名前は[`cri-dockerd`](https://github.com/Mirantis/cri-dockerd)です。 + +`cri-dockerd`をインストールして、kubeletをDocker Engineに接続するために使用することができます。 +詳細については、[Migrate Docker Engine nodes from dockershim to cri-dockerd](/docs/tasks/administer-cluster/migrating-from-dockershim/migrate-dockershim-dockerd/)を読んでください。 + +[mirantis]: https://www.mirantis.com/blog/mirantis-to-take-over-support-of-kubernetes-dockershim-2/ + +### 今現在でプロダクション環境に他のランタイムを使用している例はあるのでしょうか? + +Kubernetesプロジェクトが生み出したすべての成果物(Kubernetesバイナリ)は、リリースごとに検証されています。 + +また、[kind]プロジェクトは以前からcontainerdを使っており、プロジェクトのユースケースにおいて安定性が向上してきています。 +kindとcontainerdは、Kubernetesコードベースの変更を検証するために毎日何回も利用されています。 +他の関連プロジェクトも同様のパターンを追っており、他のコンテナランタイムの安定性と使いやすさが示されています。 +例として、OpenShift 4.xは2019年6月以降、CRI-Oランタイムをプロダクション環境で使っています。 + +他の事例や参考資料はについては、 +containerdとCRI-O(Cloud Native Computing Foundation ([CNCF])の2つのコンテナランタイム)の採用例をご覧ください。 + +- [containerd](https://github.com/containerd/containerd/blob/master/ADOPTERS.md) +- [CRI-O](https://github.com/cri-o/cri-o/blob/master/ADOPTERS.md) + +[CRI-O]: https://cri-o.io/ +[kind]: https://kind.sigs.k8s.io/ +[CNCF]: https://cncf.io + +### OCIという単語をよく見るのですが、これは何ですか? + +OCIは[Open Container Initiative]の略で、コンテナツールとテクノロジー間の数多くのインターフェースの標準化を行った団体です。 +彼らはコンテナイメージをパッケージするための標準仕様(OCI image-spec)と、 +コンテナを実行するための標準仕様(OCI runtime-spec)をメンテナンスしています。 +また、[runc]という形でruntime-specの実装もメンテナンスしており、 +これは[containerd]と[CRI-O]の両方でデフォルトの下位ランタイムとなっています。 +CRIはこれらの低レベル仕様に基づいて、コンテナを管理するためのエンドツーエンドの標準を提供します。 + +[Open Container Initiative]: https://opencontainers.org/about/overview/ +[runc]: https://github.com/opencontainers/runc +[containerd]: https://containerd.io/ + +### CRI実装を変更する際に注意すべきことは何ですか? + +DockerとほとんどのCRI(containerdを含む)において、下位で使用されるコンテナ化コードは同じものですが、 +いくつかの細かい違いが存在します。移行する際に考慮すべき一般的な事項は次のとおりです。 + +- ログ設定 +- ランタイムリソースの制限 +- ノード構成スクリプトでdockerコマンドやコントロールソケット経由でDocker Engineを使用しているもの +- `kubectl`のプラグインで`docker` CLIまたはDocker Engineコントロールソケットが必要なもの +- KubernetesプロジェクトのツールでDocker Engineへの直接アクセスが必要なもの(例:廃止された`kube-imagepuller`ツール) +- `registry-mirrors`やinsecureレジストリなどの機能の設定 +- その他の支援スクリプトやデーモンでDocker Engineが利用可能であることを想定していてKubernetes外で実行されるもの(モニタリング・セキュリティエージェントなど) +- GPUまたは特別なハードウェア、そしてランタイムおよびKubernetesとそれらハードウェアの統合方法 + +あなたがKubernetesのリソース要求/制限やファイルベースのログ収集DaemonSetを使用しているのであれば、それらは問題なく動作し続けますが、 +`dockerd`の設定をカスタマイズしていた場合は、それを新しいコンテナランタイムに適合させる必要があるでしょう。 + +他に注意することとしては、システムメンテナンスを実行するようなものや、コンテナ内でイメージをビルドするようなものが動作しなくなります。 +前者の場合は、[`crictl`][cr]ツールをdrop-inの置き換えとして使用できます([docker cliからcrictlへのマッピング](https://kubernetes.io/ja/docs/tasks/debug/debug-cluster/crictl/#docker-cli%E3%81%8B%E3%82%89crictl%E3%81%B8%E3%81%AE%E3%83%9E%E3%83%83%E3%83%94%E3%83%B3%E3%82%B0)を参照)。 +後者の場合は、[img]、[buildah]、[kaniko]、[buildkit-cli-for-kubectl]のようなDockerを必要としない新しいコンテナビルドの選択肢を使用できます。 + +[cr]: https://github.com/kubernetes-sigs/cri-tools +[img]: https://github.com/genuinetools/img +[buildah]: https://github.com/containers/buildah +[kaniko]: https://github.com/GoogleContainerTools/kaniko +[buildkit-cli-for-kubectl]: https://github.com/vmware-tanzu/buildkit-cli-for-kubectl + +containerdを使っているのであれば、[ドキュメント]を参照して、移行するのにどのような構成が利用可能かを確認するところから始めるといいでしょう。 + +[ドキュメント]: https://github.com/containerd/cri/blob/master/docs/registry.md + +containerdとCRI-OをKubernetesで使用する方法に関しては、[コンテナランタイム]に関するKubernetesのドキュメントを参照してください。 + +[コンテナランタイム]: /ja/docs/setup/production-environment/container-runtimes/ + +### さらに質問がある場合どうすればいいでしょうか? + +ベンダーサポートのKubernetesディストリビューションを使用している場合、彼らの製品に対するアップグレード計画について尋ねることができます。 +エンドユーザーの質問に関しては、[エンドユーザーコミュニティフォーラム](https://discuss.kubernetes.io/)に投稿してください。 + +dockershimの削除に関する決定については、専用の[GitHub issue](https://github.com/kubernetes/kubernetes/issues/106917)で議論することができます。 + +変更点に関するより詳細な技術的な議論は、[待ってください、DockerはKubernetesで非推奨になったのですか?][dep]という素晴らしいブログ記事も参照してください。 + +[dep]: https://dev.to/inductor/wait-docker-is-deprecated-in-kubernetes-now-what-do-i-do-e4m + +### dockershimを使っているかどうかを検出できるツールはありますか? + +はい![Detector for Docker Socket (DDS)][dds]というkubectlプラグインをインストールすることであなたのクラスターを確認していただけます。 +DDSは、アクティブなKubernetesワークロードがDocker Engineソケット(`docker.sock`)をボリュームとしてマウントしているかを検出できます。 +さらなる詳細と使用パターンについては、DDSプロジェクトの[README][dds]を参照してください。 + +[dds]: https://github.com/aws-containers/kubectl-detector-for-docker-socket + +### ハグしていただけますか? + +はい、私達は引き続きいつでもハグに応じています。🤗🤗🤗 diff --git a/content/ja/docs/tasks/administer-cluster/migrating-from-dockershim/_index.md b/content/ja/docs/tasks/administer-cluster/migrating-from-dockershim/_index.md index b93d71071e2..a37dffaee3a 100644 --- a/content/ja/docs/tasks/administer-cluster/migrating-from-dockershim/_index.md +++ b/content/ja/docs/tasks/administer-cluster/migrating-from-dockershim/_index.md @@ -10,7 +10,7 @@ dockershimから他のコンテナランタイムに移行する際に知って Kubernetes 1.20で[dockershim deprecation](blog/2020/12/08/kubernetes-1-20-release-announcement/#dockershim-deprecation)が発表されてから、様々なワークロードやKubernetesインストールにどう影響するのかという質問が寄せられています。 -この問題をよりよく理解するために、[Dockershim Deprecation FAQ](/blog/2020/12/02/dockershim-faq/)ブログが役に立つでしょう。 +この問題をよりよく理解するために、[dockershimの削除に関するFAQ](/ja/dockershim)ブログが役に立つでしょう。 dockershimから代替のコンテナランタイムに移行することが推奨されます。 [コンテナランタイム](/ja/docs/setup/production-environment/container-runtimes/)のセクションをチェックして、どのような選択肢があるかを確認してください。 diff --git a/content/ja/docs/tasks/administer-cluster/migrating-from-dockershim/migrating-telemetry-and-security-agents.md b/content/ja/docs/tasks/administer-cluster/migrating-from-dockershim/migrating-telemetry-and-security-agents.md index a3b9a03d186..e74dc4fd35e 100644 --- a/content/ja/docs/tasks/administer-cluster/migrating-from-dockershim/migrating-telemetry-and-security-agents.md +++ b/content/ja/docs/tasks/administer-cluster/migrating-from-dockershim/migrating-telemetry-and-security-agents.md @@ -8,7 +8,7 @@ weight: 70 Kubernetes 1.20でdockershimは非推奨になりました。 -[Dockershim Deprecation FAQ](/blog/2020/12/02/dockershim-faq/)から、ほとんどのアプリがコンテナをホストするランタイムに直接依存しないことは既にご存知かもしれません。 +[dockershimの削除に関するFAQ](/ja/dockershim)から、ほとんどのアプリがコンテナをホストするランタイムに直接依存しないことは既にご存知かもしれません。 しかし、コンテナのメタデータやログ、メトリクスを収集するためにDockerに依存しているテレメトリーやセキュリティエージェントはまだ多く存在します。 この文書では、これらの依存関係を検出する方法と、これらのエージェントを汎用ツールまたは代替ランタイムに移行する方法に関するリンクを集約しています。 diff --git a/data/i18n/ja/ja.toml b/data/i18n/ja/ja.toml index 3fdeebe8d2a..3bce106158a 100644 --- a/data/i18n/ja/ja.toml +++ b/data/i18n/ja/ja.toml @@ -37,6 +37,9 @@ other = "現在表示しているのは、次のバージョン向けのドキ [deprecation_warning] other = " のドキュメントは積極的にメンテナンスされていません。現在表示されているバージョンはスナップショットです。最新のドキュメントはこちらです: " +[dockershim_message] +other = """dockershimは1.24のリリースをもってKubernetesプロジェクトから削除されました。詳しくは、dockershimの削除に関するFAQをご覧ください。""" + [docs_label_browse] other = "ドキュメントの参照" From bce9885a764f0c644ac14218d44731914e672ed2 Mon Sep 17 00:00:00 2001 From: grainrigi Date: Sun, 5 Feb 2023 10:57:24 +0900 Subject: [PATCH 250/279] [ja] update dockershim deprecation to removal on tasks page from 9211599 --- content/ja/blog/_posts/2022-02-17-updated-dockershim-faq.md | 2 +- ...ts-you.md => check-if-dockershim-removal-affects-you.md} | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) rename content/ja/docs/tasks/administer-cluster/migrating-from-dockershim/{check-if-dockershim-deprecation-affects-you.md => check-if-dockershim-removal-affects-you.md} (97%) diff --git a/content/ja/blog/_posts/2022-02-17-updated-dockershim-faq.md b/content/ja/blog/_posts/2022-02-17-updated-dockershim-faq.md index 329a07016b6..89696d1bb44 100644 --- a/content/ja/blog/_posts/2022-02-17-updated-dockershim-faq.md +++ b/content/ja/blog/_posts/2022-02-17-updated-dockershim-faq.md @@ -18,7 +18,7 @@ Kubernetes [v1.24のリリース](/releases/#release-v1-24)においてdockershi これが何を意味するかについては、ブログ記事[Don't Panic: Kubernetes and Docker](/ja/blog/2020/12/02/dont-panic-kubernetes-and-docker/)をご覧ください。 -[Check whether dockershim removal affects you](/docs/tasks/administer-cluster/migrating-from-dockershim/check-if-dockershim-removal-affects-you/)をお読みいただくことで、 +[dockershim削除の影響範囲を確認する](/ja/docs/tasks/administer-cluster/migrating-from-dockershim/check-if-dockershim-removal-affects-you/)をお読みいただくことで、 dockershimの削除があなたやあなたの組織に与える影響をご判断いただけます。 Kubernetes 1.24リリースに至るまでの間、Kubernetesコントリビューターはこの移行を円滑に行えるようにするために尽力してきました。 diff --git a/content/ja/docs/tasks/administer-cluster/migrating-from-dockershim/check-if-dockershim-deprecation-affects-you.md b/content/ja/docs/tasks/administer-cluster/migrating-from-dockershim/check-if-dockershim-removal-affects-you.md similarity index 97% rename from content/ja/docs/tasks/administer-cluster/migrating-from-dockershim/check-if-dockershim-deprecation-affects-you.md rename to content/ja/docs/tasks/administer-cluster/migrating-from-dockershim/check-if-dockershim-removal-affects-you.md index f854f051f73..8fa9132ec88 100644 --- a/content/ja/docs/tasks/administer-cluster/migrating-from-dockershim/check-if-dockershim-deprecation-affects-you.md +++ b/content/ja/docs/tasks/administer-cluster/migrating-from-dockershim/check-if-dockershim-removal-affects-you.md @@ -1,5 +1,5 @@ --- -title: Dockershim非推奨の影響範囲を確認する +title: dockershim削除の影響範囲を確認する content_type: task weight: 20 --- @@ -7,9 +7,9 @@ weight: 20 Kubernetesの`dockershim`コンポーネントは、DockerをKubernetesの{{< glossary_tooltip text="コンテナランタイム" term_id="container-runtime" >}}として使用することを可能にします。 -Kubernetesの組み込みコンポーネントである`dockershim`はリリースv1.20で非推奨となりました。 +Kubernetesの組み込みコンポーネントである`dockershim`はリリースv1.24で削除されました。 -このページでは、あなたのクラスターがどのようにDockerをコンテナランタイムとして使用しているか、使用中の`dockershim`が果たす役割について詳しく説明し、`dockershim`の廃止によって影響を受けるワークロードがあるかどうかをチェックするためのステップを示します。 +このページでは、あなたのクラスターがどのようにDockerをコンテナランタイムとして使用しているか、使用中の`dockershim`が果たす役割について詳しく説明し、`dockershim`の削除によって影響を受けるワークロードがあるかどうかをチェックするためのステップを示します。 ## 自分のアプリがDockerに依存しているかどうかの確認 {#find-docker-dependencies} From 773a7d80ce35aa8e318c41bd46a03a294ccd841e Mon Sep 17 00:00:00 2001 From: grainrigi Date: Sat, 18 Feb 2023 09:12:42 +0900 Subject: [PATCH 251/279] [ja] Fix typo in /blog/2020/12/02/dont-panic-kubernetes-and-docker --- .../blog/_posts/2020-12-02-dont-panic-kubernetes-and-docker.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/ja/blog/_posts/2020-12-02-dont-panic-kubernetes-and-docker.md b/content/ja/blog/_posts/2020-12-02-dont-panic-kubernetes-and-docker.md index 46b9cb28b87..3e57783328a 100644 --- a/content/ja/blog/_posts/2020-12-02-dont-panic-kubernetes-and-docker.md +++ b/content/ja/blog/_posts/2020-12-02-dont-panic-kubernetes-and-docker.md @@ -43,4 +43,4 @@ DockerはCRI([Container Runtime Interface](https://kubernetes.io/blog/2016/12/co 経験の多寡や難易度にかかわらず、どんなことでも質問してください。我々の目標は、全ての人が将来の変化について、可能な限りの知識と理解を得られることです。 このブログが多くの質問の答えとなり、不安を和らげることができればと願っています。 -別の情報をお探してあれば、[dockershimの削除に関するFAQ](/ja/dockershim)を参照してください。 +別の情報をお探しであれば、[dockershimの削除に関するFAQ](/ja/dockershim)を参照してください。 From 42c3d5074a21c90a27f4dfa48ddeb57f03be913e Mon Sep 17 00:00:00 2001 From: Bo Li Date: Sat, 18 Feb 2023 10:52:16 +0800 Subject: [PATCH 252/279] update output for APF dump_priority_levels endpoint --- .../cluster-administration/flow-control.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/content/en/docs/concepts/cluster-administration/flow-control.md b/content/en/docs/concepts/cluster-administration/flow-control.md index 15456f2b91c..5cd5ca339e6 100644 --- a/content/en/docs/concepts/cluster-administration/flow-control.md +++ b/content/en/docs/concepts/cluster-administration/flow-control.md @@ -705,14 +705,15 @@ serves the following additional paths at its HTTP[S] ports. The output is similar to this: ```none - PriorityLevelName, ActiveQueues, IsIdle, IsQuiescing, WaitingRequests, ExecutingRequests, - workload-low, 0, true, false, 0, 0, - global-default, 0, true, false, 0, 0, - exempt, , , , , , - catch-all, 0, true, false, 0, 0, - system, 0, true, false, 0, 0, - leader-election, 0, true, false, 0, 0, - workload-high, 0, true, false, 0, 0, + PriorityLevelName, ActiveQueues, IsIdle, IsQuiescing, WaitingRequests, ExecutingRequests, DispatchedRequests, RejectedRequests, TimedoutRequests, CancelledRequests + catch-all, 0, true, false, 0, 0, 1, 0, 0, 0 + exempt, , , , , , , , , + global-default, 0, true, false, 0, 0, 46, 0, 0, 0 + leader-election, 0, true, false, 0, 0, 4, 0, 0, 0 + node-high, 0, true, false, 0, 0, 34, 0, 0, 0 + system, 0, true, false, 0, 0, 48, 0, 0, 0 + workload-high, 0, true, false, 0, 0, 500, 0, 0, 0 + workload-low, 0, true, false, 0, 0, 0, 0, 0, 0 ``` - `/debug/api_priority_and_fairness/dump_queues` - a listing of all the From 6337acdd9d77c47656bcb98423805f5f4d6b4ea6 Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Sat, 18 Feb 2023 16:05:30 +0800 Subject: [PATCH 253/279] [zh] Resync page device-plugins --- .../compute-storage-net/device-plugins.md | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/content/zh-cn/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins.md b/content/zh-cn/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins.md index 751560ef429..2b0a54b4e2d 100644 --- a/content/zh-cn/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins.md +++ b/content/zh-cn/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins.md @@ -141,10 +141,10 @@ spec: The general workflow of a device plugin includes the following steps: 1. Initialization. During this phase, the device plugin performs vendor-specific - initialization and setup to make sure the devices are in a ready state. + initialization and setup to make sure the devices are in a ready state. 1. The plugin starts a gRPC service, with a Unix socket under the host path - `/var/lib/kubelet/device-plugins/`, that implements the following interfaces: + `/var/lib/kubelet/device-plugins/`, that implements the following interfaces: --> ## 设备插件的实现 {#device-plugin-implementation} @@ -348,7 +348,7 @@ of the device allocations during the upgrade. 采用该方法将确保升级期间设备分配的连续运行。 ## 监控设备插件资源 {#monitoring-device-plugin-resources} @@ -375,7 +375,7 @@ for these devices: kubelet 提供了 gRPC 服务来使得正在使用中的设备被发现,并且还为这些设备提供了元数据: ```gRPC -// PodResourcesLister 是一个由 kubelet 提供的服务,用来提供供节点上 +// PodResourcesLister 是一个由 kubelet 提供的服务,用来提供供节点上 // Pod 和容器使用的节点资源的信息 service PodResourcesLister { rpc List(ListPodResourcesRequest) returns (ListPodResourcesResponse) {} @@ -383,6 +383,9 @@ service PodResourcesLister { } ``` + ### `List` gRPC 端点 {#grpc-endpoint-list} @@ -535,7 +538,7 @@ NUMA 单元通过一个整数 ID 来标识,其取值与设备插件所报告 The gRPC service is served over a unix socket at `/var/lib/kubelet/pod-resources/kubelet.sock`. Monitoring agents for device plugin resources can be deployed as a daemon, or as a DaemonSet. The canonical directory `/var/lib/kubelet/pod-resources` requires privileged access, so monitoring -agents must run in a privileged security context. If a device monitoring agent is running as a +agents must run in a privileged security context. If a device monitoring agent is running as a DaemonSet, `/var/lib/kubelet/pod-resources` must be mounted as a {{< glossary_tooltip term_id="volume" >}} in the device monitoring agent's [PodSpec](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podspec-v1-core). @@ -591,7 +594,7 @@ resource assignment decisions. `TopologyInfo` supports setting a `nodes` field to either `nil` or a list of NUMA nodes. This allows the Device Plugin to advertise a device that spans multiple NUMA nodes. -Setting `TopologyInfo` to `nil` or providing an empty list of NUMA nodes for a given device +Setting `TopologyInfo` to `nil` or providing an empty list of NUMA nodes for a given device indicates that the Device Plugin does not have a NUMA affinity preference for that device. An example `TopologyInfo` struct populated for a device by a Device Plugin: From 6a05d3004e7c262189df3d5c683152ae21b53f92 Mon Sep 17 00:00:00 2001 From: coder2835 <83513452+coder2835@users.noreply.github.com> Date: Mon, 13 Feb 2023 19:39:15 +0530 Subject: [PATCH 254/279] Add note about checking kubectl version In "Test to ensure the version you installed is up-to-date:", the command "kubectl version --client" is given but on running it on my system it says "This version information is deprecated and will be replaced with the output from kubectl version --short". But kubectl --short also gives a warning. So I thought it would be best to update the docs to add a note to ignore this warning. Co-Authored-By: Tim Bannister --- content/en/docs/tasks/tools/install-kubectl-linux.md | 10 ++++++++++ content/en/docs/tasks/tools/install-kubectl-macos.md | 11 +++++++++++ .../en/docs/tasks/tools/install-kubectl-windows.md | 10 ++++++++++ 3 files changed, 31 insertions(+) diff --git a/content/en/docs/tasks/tools/install-kubectl-linux.md b/content/en/docs/tasks/tools/install-kubectl-linux.md index a48dcd654e6..6752a7a4a28 100644 --- a/content/en/docs/tasks/tools/install-kubectl-linux.md +++ b/content/en/docs/tasks/tools/install-kubectl-linux.md @@ -95,6 +95,16 @@ For example, to download version {{< param "fullversion" >}} on Linux, type: ```bash kubectl version --client ``` + {{< note >}} + The above command will generate a warning: + ``` + WARNING: This version information is deprecated and will be replaced with the output from kubectl version --short. + ``` + You can ignore this warning. You are only checking the version of `kubectl` that you + have installed. + + {{< /note >}} + Or use this for detailed view of version: ```cmd diff --git a/content/en/docs/tasks/tools/install-kubectl-macos.md b/content/en/docs/tasks/tools/install-kubectl-macos.md index a02b027b280..8b384979ad5 100644 --- a/content/en/docs/tasks/tools/install-kubectl-macos.md +++ b/content/en/docs/tasks/tools/install-kubectl-macos.md @@ -116,6 +116,17 @@ The following methods exist for installing kubectl on macOS: ```bash kubectl version --client ``` + + {{< note >}} + The above command will generate a warning: + ``` + WARNING: This version information is deprecated and will be replaced with the output from kubectl version --short. + ``` + You can ignore this warning. You are only checking the version of `kubectl` that you + have installed. + + {{< /note >}} + Or use this for detailed view of version: ```cmd diff --git a/content/en/docs/tasks/tools/install-kubectl-windows.md b/content/en/docs/tasks/tools/install-kubectl-windows.md index 235e6f54800..4717ef16a8c 100644 --- a/content/en/docs/tasks/tools/install-kubectl-windows.md +++ b/content/en/docs/tasks/tools/install-kubectl-windows.md @@ -66,6 +66,16 @@ The following methods exist for installing kubectl on Windows: ```cmd kubectl version --client ``` + {{< note >}} + The above command will generate a warning: + ``` + WARNING: This version information is deprecated and will be replaced with the output from kubectl version --short. + ``` + You can ignore this warning. You are only checking the version of `kubectl` that you + have installed. + + {{< /note >}} + Or use this for detailed view of version: ```cmd From 99b7d29a3038fd14ff8d94fa49df2fb3425f1ce3 Mon Sep 17 00:00:00 2001 From: "Mr. Erlison" Date: Sat, 18 Feb 2023 10:15:10 -0300 Subject: [PATCH 255/279] Propose mrerlison as a reviewer for the pt-br docs --- OWNERS_ALIASES | 1 + 1 file changed, 1 insertion(+) diff --git a/OWNERS_ALIASES b/OWNERS_ALIASES index 7b89fd11374..22c93329763 100644 --- a/OWNERS_ALIASES +++ b/OWNERS_ALIASES @@ -168,6 +168,7 @@ aliases: - edsoncelio - femrtnz - jcjesus + - mrerlison - rikatz - stormqueen1990 - yagonobre From e5545e0e6cc45e51ea9a1810dabd9b43542192ab Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 18 Jan 2023 11:35:14 +0800 Subject: [PATCH 256/279] [zh] sync /storage/persistent-volumes.md --- .../concepts/storage/persistent-volumes.md | 548 +++++++++++++----- 1 file changed, 407 insertions(+), 141 deletions(-) diff --git a/content/zh-cn/docs/concepts/storage/persistent-volumes.md b/content/zh-cn/docs/concepts/storage/persistent-volumes.md index 487337b263b..4522f0e6fcd 100644 --- a/content/zh-cn/docs/concepts/storage/persistent-volumes.md +++ b/content/zh-cn/docs/concepts/storage/persistent-volumes.md @@ -28,7 +28,8 @@ weight: 20 本文描述 Kubernetes 中的**持久卷(Persistent Volume)** 。 建议先熟悉[卷(Volume)](/zh-cn/docs/concepts/storage/volumes/)的概念。 @@ -38,7 +39,10 @@ This document describes _persistent volumes_ in Kubernetes. Familiarity with [vo ## 介绍 {#introduction} @@ -58,7 +62,11 @@ A _PersistentVolume_ (PV) is a piece of storage in the cluster that has been pro 此 API 对象中记述了存储的实现细节,无论其背后是 NFS、iSCSI 还是特定于云平台的存储系统。 **持久卷申领(PersistentVolumeClaim,PVC)** 表达的是用户对存储的请求。概念上与 Pod 类似。 Pod 会耗用节点资源,而 PVC 申领会耗用 PV 资源。Pod 可以请求特定数量的资源(CPU @@ -67,7 +75,12 @@ Pod 会耗用节点资源,而 PVC 申领会耗用 PV 资源。Pod 可以请求 模式之一来挂载,参见[访问模式](#access-modes))。 @@ -82,7 +95,8 @@ See the [detailed walkthrough with working examples](/docs/tasks/configure-pod-c #### 静态制备 {#static} @@ -129,14 +145,15 @@ dynamic provisioning for themselves. -为了基于存储类完成动态的存储制备,集群管理员需要在 API 服务器上启用 -`DefaultStorageClass` [准入控制器](/zh-cn/docs/reference/access-authn-authz/admission-controllers/#defaultstorageclass)。 +为了基于存储类完成动态的存储制备,集群管理员需要在 API 服务器上启用 `DefaultStorageClass` +[准入控制器](/zh-cn/docs/reference/access-authn-authz/admission-controllers/#defaultstorageclass)。 举例而言,可以通过保证 `DefaultStorageClass` 出现在 API 服务器组件的 `--enable-admission-plugins` 标志值中实现这点;该标志的值可以是逗号分隔的有序列表。 关于 API 服务器标志的更多信息,可以参考 @@ -146,7 +163,16 @@ check [kube-apiserver](/docs/admin/kube-apiserver/) documentation. ### 绑定 {#binding} @@ -162,7 +188,10 @@ PVC 申领与 PV 卷之间的绑定是一种一对一的映射,实现上使用 PV 卷与 PVC 申领间的双向绑定关系。 如果找不到匹配的 PV 卷,PVC 申领会无限期地处于未绑定状态。 当与之匹配的 PV 卷可用时,PVC 申领会被绑定。 @@ -173,7 +202,10 @@ Claims will remain unbound indefinitely if a matching volume does not exist. Cla ### 使用 {#using} @@ -182,7 +214,10 @@ Pod 将 PVC 申领当做存储卷来使用。集群会检视 PVC 申领,找到 用户要在 Pod 中以卷的形式使用申领时指定期望的访问模式。 一旦用户有了申领对象并且该申领已经被绑定, 则所绑定的 PV 卷在用户仍然需要它期间一直属于该用户。 @@ -193,7 +228,9 @@ Once a user has a claim and that claim is bound, the bound PV belongs to the use ### 保护使用中的存储对象 {#storage-object-in-use-protection} @@ -201,17 +238,21 @@ The purpose of the Storage Object in Use Protection feature is to ensure that Pe 这一功能特性的目的是确保仍被 Pod 使用的 PersistentVolumeClaim(PVC) 对象及其所绑定的 PersistentVolume(PV)对象在系统中不会被删除,因为这样做可能会引起数据丢失。 +{{< note >}} -{{< note >}} 当使用某 PVC 的 Pod 对象仍然存在时,认为该 PVC 仍被此 Pod 使用。 {{< /note >}} 如果用户删除被某 Pod 使用的 PVC 对象,该 PVC 申领不会被立即移除。 PVC 对象的移除会被推迟,直至其不再被任何 Pod 使用。 @@ -238,7 +279,8 @@ Finalizers: [kubernetes.io/pvc-protection] ``` 你也可以看到当 PV 对象的状态为 `Terminating` 且其 `Finalizers` 列表中包含 `kubernetes.io/pv-protection` 时,PV 对象是处于被保护状态的。 @@ -268,7 +310,10 @@ Events: ### 回收(Reclaiming) {#reclaiming} @@ -280,7 +325,11 @@ When a user is done with their volume, they can delete the PVC objects from the #### 保留(Retain) {#retain} @@ -290,11 +339,13 @@ The `Retain` reclaim policy allows for manual reclamation of the resource. When 管理员可以通过下面的步骤来手动回收该卷: 1. 删除 PersistentVolume 对象。与之相关的、位于外部基础设施中的存储资产 (例如 AWS EBS、GCE PD、Azure Disk 或 Cinder 卷)在 PV 删除之后仍然存在。 @@ -306,7 +357,15 @@ If you want to reuse the same storage asset, create a new PersistentVolume with #### 删除(Delete) {#delete} @@ -320,17 +379,21 @@ Cinder 卷)中移除所关联的存储资产。 #### 回收(Recycle) {#recycle} {{< warning >}} + 回收策略 `Recycle` 已被废弃。取而代之的建议方案是使用动态制备。 {{< /warning >}} + 如果下层的卷插件支持,回收策略 `Recycle` 会在卷上执行一些基本的擦除 (`rm -rf /thevolume/*`)操作,之后允许该卷用于新的 PVC 申领。 @@ -341,9 +404,8 @@ the Kubernetes controller manager command line arguments as described in the The custom recycler Pod template must contain a `volumes` specification, as shown in the example below: --> -不过,管理员可以按 -[参考资料](/zh-cn/docs/reference/command-line-tools-reference/kube-controller-manager/) -中所述,使用 Kubernetes 控制器管理器命令行参数来配置一个定制的回收器(Recycler) +不过,管理员可以按[参考资料](/zh-cn/docs/reference/command-line-tools-reference/kube-controller-manager/)中所述, +使用 Kubernetes 控制器管理器命令行参数来配置一个定制的回收器(Recycler) Pod 模板。此定制的回收器 Pod 模板必须包含一个 `volumes` 规约,如下例所示: ```yaml @@ -368,27 +430,32 @@ spec: ``` 定制回收器 Pod 模板中在 `volumes` 部分所指定的特定路径要替换为正被回收的卷的路径。 +### PersistentVolume 删除保护 finalizer {#persistentvolume-deletion-protection-finalizer} +{{< feature-state for_k8s_version="v1.23" state="alpha" >}} + + -### PersistentVolume 删除保护 finalizer {#persistentvolume-deletion-protection-finalizer} -{{< feature-state for_k8s_version="v1.23" state="alpha" >}} - 可以在 PersistentVolume 上添加终结器(Finalizer), 以确保只有在删除对应的存储后才删除具有 `Delete` 回收策略的 PersistentVolume。 新引入的 `kubernetes.io/pv-controller` 和 `external-provisioner.volume.kubernetes.io/finalizer` 终结器仅会被添加到动态制备的卷上。 @@ -398,6 +465,8 @@ The finalizer `kubernetes.io/pv-controller` is added to in-tree plugin volumes. ```shell kubectl describe pv pvc-74a498d6-3929-47e8-8c02-078c1ece4d78 +``` +```none Name: pvc-74a498d6-3929-47e8-8c02-078c1ece4d78 Labels: Annotations: kubernetes.io/createdby: vsphere-volume-dynamic-provisioner @@ -427,7 +496,7 @@ The following is an example: --> 终结器 `external-provisioner.volume.kubernetes.io/finalizer` 会被添加到 CSI 卷上。下面是一个例子: -```shell +```none Name: pvc-2f0bab97-85a8-4552-8044-eb8be45cf48d Labels: Annotations: pv.kubernetes.io/provisioned-by: csi.vsphere.vmware.com @@ -463,8 +532,8 @@ the `kubernetes.io/pv-controller` finalizer is replaced by the ### 预留 PersistentVolume {#reserving-a-persistentvolume} @@ -472,8 +541,10 @@ cluster. However, if you want a PVC to bind to a specific PV, you need to pre-bi 但是,如果你希望 PVC 绑定到特定 PV,则需要预先绑定它们。 通过在 PersistentVolumeClaim 中指定 PersistentVolume,你可以声明该特定 PV 与 PVC 之间的绑定关系。如果该 PersistentVolume 存在且未被通过其 @@ -482,7 +553,8 @@ PV 与 PVC 之间的绑定关系。如果该 PersistentVolume 存在且未被通 绑定操作不会考虑某些卷匹配条件是否满足,包括节点亲和性等等。 控制面仍然会检查[存储类](/zh-cn/docs/concepts/storage/storage-classes/)、 @@ -501,7 +573,10 @@ spec: ``` 此方法无法对 PersistentVolume 的绑定特权做出任何形式的保证。 如果有其他 PersistentVolumeClaim 可以使用你所指定的 PV, @@ -548,7 +623,6 @@ the following types of volumes: * {{< glossary_tooltip text="csi" term_id="csi" >}} * flexVolume (已弃用) * gcePersistentDisk -* glusterfs (已弃用) * rbd * portworxVolume @@ -581,6 +655,7 @@ new PersistentVolume is never created to satisfy the claim. Instead, an existing Kubernetes 不会创建新的 PV 卷来满足此申领的请求。 与之相反,现有的卷会被调整大小。 +{{< warning >}} -{{< warning >}} 直接编辑 PersistentVolume 的大小可以阻止该卷自动调整大小。 如果对 PersistentVolume 的容量进行编辑,然后又将其所对应的 PersistentVolumeClaim 的 `.spec` 进行编辑,使该 PersistentVolumeClaim @@ -607,7 +681,9 @@ Kubernetes 控制平面将看到两个资源的所需状态匹配, {{< feature-state for_k8s_version="v1.24" state="stable" >}} 对 CSI 卷的扩充能力默认是被启用的,不过扩充 CSI 卷要求 CSI 驱动支持卷扩充操作。可参阅特定 CSI 驱动的文档了解更多信息。 @@ -659,17 +735,18 @@ Similar to other volume types - FlexVolume volumes can also be expanded when in- --> 与其他卷类型类似,FlexVolume 卷也可以在被 Pod 使用期间执行扩充操作。 +{{< note >}} -{{< note >}} FlexVolume 卷的重设大小只能在下层驱动支持重设大小的时候才可进行。 {{< /note >}} - {{< note >}} + 扩充 EBS 卷的操作非常耗时。同时还存在另一个配额限制: 每 6 小时只能执行一次(尺寸)修改操作。 {{< /note >}} @@ -677,7 +754,10 @@ Expanding EBS volumes is a time-consuming operation. Also, there is a per-volume #### 处理扩充卷过程中的失败 {#recovering-from-failure-when-expanding-volumes} @@ -689,17 +769,24 @@ If a user specifies a new size that is too big to be satisfied by underlying sto {{% tab name="集群管理员手动处理" %}} 如果扩充下层存储的操作失败,集群管理员可以手动地恢复 PVC 申领的状态并取消重设大小的请求。否则,在没有管理员干预的情况下, 控制器会反复重试重设大小的操作。 1. 将绑定到 PVC 申领的 PV 卷标记为 `Retain` 回收策略。 @@ -714,10 +801,14 @@ If expanding underlying storage fails, the cluster administrator can manually re {{% tab name="通过请求扩展为更小尺寸" %}} {{% feature-state for_k8s_version="v1.23" state="alpha" %}} - {{< note >}} + Kubernetes 从 1.23 版本开始将允许用户恢复失败的 PVC 扩展这一能力作为 alpha 特性支持。`RecoverVolumeExpansionFailure` 必须被启用以允许使用此特性。 可参考[特性门控](/zh-cn/docs/reference/command-line-tools-reference/feature-gates/) @@ -732,7 +823,8 @@ smaller proposed size, edit `.spec.resources` for that PVC and choose a value th value you previously tried. This is useful if expansion to a higher value did not succeed because of capacity constraint. If that has happened, or you suspect that it might have, you can retry expansion by specifying a -size that is within the capacity limits of underlying storage provider. You can monitor status of resize operation by watching `.status.resizeStatus` and events on the PVC. +size that is within the capacity limits of underlying storage provider. You can monitor status of +resize operation by watching `.status.resizeStatus` and events on the PVC. --> 如果集群中的特性门控 `RecoverVolumeExpansionFailure` 已启用,在 PVC 的扩展发生失败时,你可以使用比先前请求的值更小的尺寸来重试扩展。 @@ -756,11 +848,10 @@ Kubernetes 不支持将 PVC 缩小到小于其当前的尺寸。 {{% /tab %}} {{% /tabs %}} - ## 持久卷的类型 {#types-of-persistent-volumes} @@ -791,7 +882,8 @@ PV 持久卷是用插件的形式来实现的。Kubernetes 目前支持以下插 * [`rbd`](/zh-cn/docs/concepts/storage/volumes/#rbd) - Rados 块设备 (RBD) 卷 - 以下的持久卷已被弃用。这意味着当前仍是支持的,但是 Kubernetes 将来的发行版会将其移除。 * [`awsElasticBlockStore`](/zh-cn/docs/concepts/storage/volumes/#awselasticblockstore) - AWS 弹性块存储(EBS) @@ -825,8 +914,6 @@ The following types of PersistentVolume are deprecated. This means that support * [`flexVolume`](/zh-cn/docs/concepts/storage/volumes/#flexVolume) - FlexVolume (于 v1.23 **弃用**) * [`gcePersistentDisk`](/zh-cn/docs/concepts/storage/volumes/#gcepersistentdisk) - GCE Persistent Disk (于 v1.17 **弃用**) -* [`glusterfs`](/zh-cn/docs/concepts/storage/volumes/#glusterfs) - Glusterfs 卷 - (于 v1.25 **弃用**) * [`portworxVolume`](/zh-cn/docs/concepts/storage/volumes/#portworxvolume) - Portworx 卷 (于 v1.25 **弃用**) * [`vsphereVolume`](/zh-cn/docs/concepts/storage/volumes/#vspherevolume) - vSphere VMDK 卷 @@ -892,10 +979,13 @@ spec: server: 172.17.0.2 ``` - {{< note >}} + 在集群中使用持久卷存储通常需要一些特定于具体卷类型的辅助程序。 在这个例子中,PersistentVolume 是 NFS 类型的,因此需要辅助程序 `/sbin/mount.nfs` 来支持挂载 NFS 文件系统。 @@ -904,9 +994,13 @@ Helper programs relating to the volume type may be required for consumption of a ### 容量 {#capacity} @@ -962,7 +1056,12 @@ Pod 和卷之间不存在文件系统层。另外,Pod 中运行的应用必须 ### 访问模式 {#access-modes} @@ -974,8 +1073,9 @@ PersistentVolume 卷可以用资源提供者所支持的任何方式挂载到宿 访问模式有: `ReadWriteOnce` : 卷可以被一个节点以读写方式挂载。 -ReadWriteOnce 访问模式也允许运行在同一节点上的多个 Pod 访问卷。 + ReadWriteOnce 访问模式也允许运行在同一节点上的多个 Pod 访问卷。 `ReadOnlyMany` : 卷可以被多个节点以只读方式挂载。 @@ -1002,8 +1107,8 @@ ReadWriteOnce 访问模式也允许运行在同一节点上的多个 Pod 访问 `ReadWriteOncePod` : 卷可以被单个 Pod 以读写方式挂载。 -如果你想确保整个集群中只有一个 Pod 可以读取或写入该 PVC, -请使用 ReadWriteOncePod 访问模式。这只支持 CSI 卷以及需要 Kubernetes 1.22 以上版本。 + 如果你想确保整个集群中只有一个 Pod 可以读取或写入该 PVC, + 请使用 ReadWriteOncePod 访问模式。这只支持 CSI 卷以及需要 Kubernetes 1.22 以上版本。 这篇博客文章 [Introducing Single Pod Access Mode for PersistentVolumes](/blog/2021/09/13/read-write-once-pod-access-mode-alpha/) 描述了更详细的内容。 @@ -1028,9 +1133,10 @@ In the CLI, the access modes are abbreviated to: Kubernetes uses volume access modes to match PersistentVolumeClaims and PersistentVolumes. In some cases, the volume access modes also constrain where the PersistentVolume can be mounted. Volume access modes do **not** enforce write protection once the storage has been mounted. -Even if the access modes are specified as ReadWriteOnce, ReadOnlyMany, or ReadWriteMany, they don't set any constraints on the volume. -For example, even if a PersistentVolume is created as ReadOnlyMany, it is no guarantee that it will be read-only. -If the access modes are specified as ReadWriteOncePod, the volume is constrained and can be mounted on only a single Pod. +Even if the access modes are specified as ReadWriteOnce, ReadOnlyMany, or ReadWriteMany, +they don't set any constraints on the volume. For example, even if a PersistentVolume is +created as ReadOnlyMany, it is no guarantee that it will be read-only. If the access modes +are specified as ReadWriteOncePod, the volume is constrained and can be mounted on only a single Pod. --> Kubernetes 使用卷访问模式来匹配 PersistentVolumeClaim 和 PersistentVolume。 在某些场合下,卷访问模式也会限制 PersistentVolume 可以挂载的位置。 @@ -1041,7 +1147,9 @@ Kubernetes 使用卷访问模式来匹配 PersistentVolumeClaim 和 PersistentVo {{< /note >}} > **重要提醒!** 每个卷同一时刻只能以一种访问模式挂载,即使该卷能够支持多种访问模式。 > 例如,一个 GCEPersistentDisk 卷可以被某节点以 ReadWriteOnce @@ -1103,16 +1211,18 @@ Current reclaim policies are: * Retain -- manual reclamation * Recycle -- basic scrub (`rm -rf /thevolume/*`) -* Delete -- associated storage asset such as AWS EBS, GCE PD, Azure Disk, or OpenStack Cinder volume is deleted +* Delete -- associated storage asset such as AWS EBS, GCE PD, Azure Disk, + or OpenStack Cinder volume is deleted -Currently, only NFS and HostPath support recycling. AWS EBS, GCE PD, Azure Disk, and Cinder volumes support deletion. +Currently, only NFS and HostPath support recycling. AWS EBS, GCE PD, Azure Disk, +and Cinder volumes support deletion. --> ### 回收策略 {#reclaim-policy} 目前的回收策略有: * Retain -- 手动回收 -* Recycle -- 基本擦除 (`rm -rf /thevolume/*`) +* Recycle -- 基本擦除 (`rm -rf /thevolume/*`) * Delete -- 诸如 AWS EBS、GCE PD、Azure Disk 或 OpenStack Cinder 卷这类关联存储资产也被删除 目前,仅 NFS 和 HostPath 支持回收(Recycle)。 @@ -1121,16 +1231,17 @@ AWS EBS、GCE PD、Azure Disk 和 Cinder 卷都支持删除(Delete)。 ### 挂载选项 {#mount-options} Kubernetes 管理员可以指定持久卷被挂载到节点上时使用的附加挂载选项。 +{{< note >}} -{{< note >}} 并非所有持久卷类型都支持挂载选项。 {{< /note >}} @@ -1145,7 +1256,6 @@ The following volume types support mount options: * `cephfs` * `cinder`(于 v1.18 **弃用**) * `gcePersistentDisk` -* `glusterfs`(于 v1.25 **弃用**) * `iscsi` * `nfs` * `rbd` @@ -1170,10 +1280,14 @@ it will become fully deprecated in a future Kubernetes release. --> ### 节点亲和性 {#node-affinity} - {{< note >}} + 对大多数类型的卷而言,你不需要设置节点亲和性字段。 [AWS EBS](/zh-cn/docs/concepts/storage/volumes/#awselasticblockstore)、 [GCE PD](/zh-cn/docs/concepts/storage/volumes/#gcepersistentdisk) 和 @@ -1182,7 +1296,12 @@ For most volume types, you do not need to set this field. It is automatically po {{< /note >}} 每个 PV 卷可以通过设置节点亲和性来定义一些约束,进而限制从哪些节点上可以访问此卷。 使用这些卷的 Pod 只会被调度到节点亲和性规则所选择的节点上执行。 @@ -1247,7 +1366,8 @@ spec: ### 访问模式 {#access-modes} @@ -1256,7 +1376,8 @@ Claims use [the same conventions as volumes](#access-modes) when requesting stor ### 卷模式 {#volume-modes} @@ -1265,7 +1386,10 @@ Claims use [the same convention as volumes](#volume-mode) to indicate the consum ### 资源 {#resources} @@ -1276,7 +1400,10 @@ Claims, like Pods, can request specific quantities of a resource. In this case, ### 选择算符 {#selector} @@ -1286,9 +1413,12 @@ Claims can specify a [label selector](/docs/concepts/overview/working-with-objec * `matchLabels` - 卷必须包含带有此值的标签 * `matchExpressions` - 通过设定键(key)、值列表和操作符(operator) @@ -1376,10 +1506,10 @@ Manager)部署到集群中。 当某 PVC 除了请求 StorageClass 之外还设置了 `selector`,则这两种需求会按逻辑与关系处理: 只有隶属于所请求类且带有所请求标签的 PV 才能绑定到 PVC。 +{{< note >}} -{{< note >}} 目前,设置了非空 `selector` 的 PVC 对象无法让集群为其动态制备 PV 卷。 {{< /note >}} @@ -1397,20 +1527,25 @@ it won't be supported in a future Kubernetes release. --> #### 可追溯的默认 StorageClass 赋值 {#retroactive-default-storageclass-assignment} -{{< feature-state for_k8s_version="v1.25" state="alpha" >}} +{{< feature-state for_k8s_version="v1.26" state="beta" >}} 你可以创建 PersistentVolumeClaim,而无需为新 PVC 指定 `storageClassName`。 即使你的集群中不存在默认 StorageClass,你也可以这样做。 在这种情况下,新的 PVC 会按照你的定义进行创建,并且在默认值可用之前,该 PVC 的 `storageClassName` 保持不设置。 -但是,如果你启用了 [`RetroactiveDefaultStorageClass` 特性门控](/zh-cn/docs/reference/command-line-tools-reference/feature-gates/), -则 Kubernetes 的行为会有所不同:现有 PVC 无需更新 `storageClassName` 就能使用新的默认 StorageClass。 当一个默认的 StorageClass 变得可用时,控制平面会识别所有未设置 `storageClassName` 的现有 PVC。 对于 `storageClassName` 为空值或没有此主键的 PVC, @@ -1419,9 +1554,15 @@ When a default StorageClass becomes available, the control plane identifies any 并且你配置了默认 StorageClass,则此 PVC 将不会得到更新。 为了保持绑定到 `storageClassName` 设为 `""` 的 PV(当存在默认 StorageClass 时), 你需要将关联 PVC 的 `storageClassName` 设置为 `""`。 @@ -1433,7 +1574,10 @@ This behavior helps administrators change default StorageClass by removing the o ## 使用申领作为卷 {#claims-as-volumes} @@ -1463,7 +1607,9 @@ spec: ### 关于名字空间的说明 {#a-note-on-namespaces} @@ -1474,8 +1620,9 @@ PersistentVolume 卷的绑定是排他性的。 ### 类型为 `hostpath` 的 PersistentVolume {#persistentvolumes-typed-hostpath} @@ -1498,12 +1645,12 @@ applicable: * AWSElasticBlockStore * AzureDisk * CSI -* FC (光纤通道) +* FC(光纤通道) * GCEPersistentDisk * iSCSI * Local 卷 * OpenStack Cinder -* RBD (Ceph 块设备) +* RBD(Ceph 块设备) * VsphereVolume {{< note >}} + 向 Pod 中添加原始块设备时,你要在容器内设置设备路径而不是挂载路径。 {{< /note >}} ### 绑定块卷 {#binding-block-volumes} @@ -1620,10 +1771,11 @@ Volume binding matrix for statically provisioned volumes: | Filesystem | Block | 不绑定 | | Filesystem | 未指定 | 绑定 | - {{< note >}} + Alpha 发行版本中仅支持静态制备的卷。 管理员需要在处理原始块设备时小心处理这些值。 {{< /note >}} @@ -1636,8 +1788,11 @@ Alpha 发行版本中仅支持静态制备的卷。 {{< feature-state for_k8s_version="v1.20" state="stable" >}} 卷快照(Volume Snapshot)仅支持树外 CSI 卷插件。 有关细节可参阅[卷快照](/zh-cn/docs/concepts/storage/volume-snapshots/)文档。 @@ -1670,7 +1825,8 @@ spec: ## 卷克隆 {#volume-cloning} @@ -1700,7 +1856,12 @@ spec: +## 卷填充器(Populator)与数据源 {#volume-populators-and-data-sources} +{{< feature-state for_k8s_version="v1.24" state="beta" >}} + + - -## 卷填充器(Populator)与数据源 {#volume-populators-and-data-sources} - -{{< feature-state for_k8s_version="v1.24" state="beta" >}} - Kubernetes 支持自定义的卷填充器。要使用自定义的卷填充器,你必须为 kube-apiserver 和 kube-controller-manager 启用 `AnyVolumeDataSource` [特性门控](/zh-cn/docs/reference/command-line-tools-reference/feature-gates/)。 @@ -1726,6 +1882,48 @@ kube-apiserver 和 kube-controller-manager 启用 `AnyVolumeDataSource` `dataSourceRef` 字段可以包含对同一命名空间中任何对象的引用(不包含除 PVC 以外的核心资源)。 对于启用了特性门控的集群,使用 `dataSourceRef` 比 `dataSource` 更好。 + +## 跨名字空间数据源 {#cross-namespace-data-sources} + +{{< feature-state for_k8s_version="v1.26" state="alpha" >}} + + +Kubernetes 支持跨名字空间卷数据源。 +要使用跨名字空间卷数据源,你必须为 kube-apiserver、kube-controller 管理器启用 +`AnyVolumeDataSource` 和 `CrossNamespaceVolumeDataSource` +[特性门控](/zh-cn/docs/reference/command-line-tools-reference/feature-gates/)。 +此外,你必须为 csi-provisioner 启用 `CrossNamespaceVolumeDataSource` 特性门控。 + +启用 `CrossNamespaceVolumeDataSource` 特性门控允许你在 dataSourceRef 字段中指定名字空间。 + +{{< note >}} + +当你为卷数据源指定名字空间时,Kubernetes 在接受此引用之前在另一个名字空间中检查 ReferenceGrant。 +ReferenceGrant 是 `gateway.networking.k8s.io` 扩展 API 的一部分。更多细节请参见 Gateway API 文档中的 +[ReferenceGrant](https://gateway-api.sigs.k8s.io/api-types/referencegrant/)。 +这意味着你必须在使用此机制之前至少使用 Gateway API 的 ReferenceGrant 来扩展 Kubernetes 集群。 +{{< /note >}} + - ## 数据源引用 {#data-source-references} `dataSourceRef` 字段的行为与 `dataSource` 字段几乎相同。 @@ -1752,12 +1949,6 @@ users should be aware of: used. Invalid values are any core object (objects with no apiGroup) except for PVCs. * The `dataSourceRef` field may contain different types of objects, while the `dataSource` field only allows PVCs and VolumeSnapshots. - -Users should always use `dataSourceRef` on clusters that have the feature gate enabled, and -fall back to `dataSource` on clusters that do not. It is not necessary to look at both fields -under any circumstance. The duplicated values with slightly different semantics exist only for -backwards compatibility. In particular, a mixture of older and newer controllers are able to -interoperate because the fields are the same. --> 在 `dataSourceRef` 字段和 `dataSource` 字段之间有两个用户应该注意的区别: @@ -1766,7 +1957,27 @@ interoperate because the fields are the same. 无效值指的是 PVC 之外的核心对象(没有 apiGroup 的对象)。 * `dataSourceRef` 字段可以包含不同类型的对象,而 `dataSource` 字段只允许 PVC 和卷快照。 -用户应该始终在启用了特性门控的集群上使用 `dataSourceRef`,而在没有启用特性门控的集群上使用 `dataSource`。 + +当 `CrossNamespaceVolumeDataSource` 特性被启用时,存在其他区别: + +* `dataSource` 字段仅允许本地对象,而 `dataSourceRef` 字段允许任何名字空间中的对象。 +* 若指定了 namespace,则 `dataSource` 和 `dataSourceRef` 不会被同步。 + + +用户始终应该在启用了此特性门控的集群上使用 `dataSourceRef`, +在没有启用该特性门控的集群上使用 `dataSource`。 在任何情况下都没有必要查看这两个字段。 这两个字段的值看似相同但是语义稍微不一样,是为了向后兼容。 特别是混用旧版本和新版本的控制器时,它们能够互通。 @@ -1821,6 +2032,61 @@ the process. 如果没有填充器处理该数据源的情况下,该控制器会在 PVC 上产生警告事件。 当一个合适的填充器被安装到 PVC 上时,该控制器的职责是上报与卷创建有关的事件,以及在该过程中发生的问题。 + +### 使用跨名字空间的卷数据源 {#using-a-cross-namespace-volume-data-source} + +{{< feature-state for_k8s_version="v1.26" state="alpha" >}} + + +创建 ReferenceGrant 以允许名字空间属主接受引用。 +你通过使用 `dataSourceRef` 字段指定跨名字空间卷数据源,定义填充的卷。 +你必须在源名字空间中已经有一个有效的 ReferenceGrant: + +```yaml +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: ReferenceGrant +metadata: + name: allow-ns1-pvc + namespace: default +spec: + from: + - group: "" + kind: PersistentVolumeClaim + namespace: ns1 + to: + - group: snapshot.storage.k8s.io + kind: VolumeSnapshot + name: new-snapshot-demo +``` + +```yaml +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: foo-pvc + namespace: ns1 +spec: + storageClassName: example + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + dataSourceRef: + apiGroup: snapshot.storage.k8s.io + kind: VolumeSnapshot + name: new-snapshot-demo + namespace: default + volumeMode: Filesystem +``` + #### 可选的 Secret {#restriction-secret-must-exist} -当你定义一个基于 Secret 的环境变量时,你可以将其标记为可选。 -默认情况下,所引用的 Secret 都是必需的。 + +当你在 Pod 中引用 Secret 时,你可以将该 Secret 标记为**可选**,就像下面例子中所展示的那样。 +如果可选的 Secret 不存在,Kubernetes 将忽略它。 -只有所有非可选的 Secret 都可用时,Pod 中的容器才能启动运行。 +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: mypod +spec: + containers: + - name: mypod + image: redis + volumeMounts: + - name: foo + mountPath: "/etc/foo" + readOnly: true + volumes: + - name: foo + secret: + secretName: mysecret + optional: true +``` -如果 Pod 引用了 Secret 中的特定主键,而虽然 Secret 本身存在,对应的主键不存在, -Pod 启动也会失败。 + +默认情况下,Secret 是必需的。在所有非可选的 Secret 都可用之前,Pod 的所有容器都不会启动。 + + +如果 Pod 引用了非可选 Secret 中的特定键,并且该 Secret 确实存在,但缺少所指定的键, +则 Pod 在启动期间会失败。 -### 在 Pod 中以文件形式使用 Secret {#using-secrets-as-files-from-a-pod} +### 在 Pod 以文件形式使用 Secret {#using-secrets-as-files-from-a-pod} -如果你希望在 Pod 中访问 Secret 内的数据,一种方式是让 Kubernetes 将 Secret -以 Pod 中一个或多个容器的文件系统中的文件的形式呈现出来。 - -要配置这种行为,你需要: +如果你要在 Pod 中访问来自 Secret 的数据,一种方式是让 Kubernetes 将该 Secret 的值以 +文件的形式呈现,该文件存在于 Pod 中一个或多个容器内的文件系统内。 -1. 创建一个 Secret 或者使用已有的 Secret。多个 Pod 可以引用同一个 Secret。 -1. 更改 Pod 定义,在 `.spec.volumes[]` 下添加一个卷。根据需要为卷设置其名称, - 并将 `.spec.volumes[].secret.secretName` 字段设置为 Secret 对象的名称。 -1. 为每个需要该 Secret 的容器添加 `.spec.containers[].volumeMounts[]`。 - 并将 `.spec.containers[].volumeMounts[].readOnly` 设置为 `true`, - 将 `.spec.containers[].volumeMounts[].mountPath` 设置为希望 Secret - 被放置的、目前尚未被使用的路径名。 -1. 更改你的镜像或命令行,以便程序读取所设置的目录下的文件。Secret 的 `data` - 映射中的每个主键都成为 `mountPath` 下面的文件名。 - -下面是一个通过卷来挂载名为 `mysecret` 的 Secret 的 Pod 示例: - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: mypod -spec: - containers: - - name: mypod - image: redis - volumeMounts: - - name: foo - mountPath: "/etc/foo" - readOnly: true - volumes: - - name: foo - secret: - secretName: mysecret - optional: false # 默认设置,意味着 "mysecret" 必须已经存在 -``` +相关的指示说明, +可以参阅[使用 Secret 安全地分发凭据](/zh-cn/docs/tasks/inject-data-application/distribute-credentials-secure/#create-a-pod-that-has-access-to-the-secret-data-through-a-volume)。 -你要访问的每个 Secret 都需要通过 `.spec.volumes` 来引用。 - -如果 Pod 中包含多个容器,则每个容器需要自己的 `volumeMounts` 块, -不过针对每个 Secret 而言,只需要一份 `.spec.volumes` 设置。 - -{{< note >}} - -Kubernetes v1.22 版本之前都会自动创建用来访问 Kubernetes API 的凭证。 -这一老的机制是基于创建可被挂载到 Pod 中的令牌 Secret 来实现的。 -在最近的版本中,包括 Kubernetes v{{< skew currentVersion >}} 中,API 凭据是直接通过 -[TokenRequest](/zh-cn/docs/reference/kubernetes-api/authentication-resources/token-request-v1/) -API 来获得的,这一凭据会使用[投射卷](/zh-cn/docs/reference/access-authn-authz/service-accounts-admin/#bound-service-account-token-volume) -挂载到 Pod 中。使用这种方式获得的令牌有确定的生命期,并且在挂载它们的 Pod -被删除时自动作废。 - - -你仍然可以[手动创建](/zh-cn/docs/tasks/configure-pod-container/configure-service-account/#manually-create-a-service-account-api-token) -服务账号令牌。例如,当你需要一个永远都不过期的令牌时。 -不过,仍然建议使用 [TokenRequest](/zh-cn/docs/reference/kubernetes-api/authentication-resources/token-request-v1/) -子资源来获得访问 API 服务器的令牌。 -你可以使用 [`kubectl create token`](/docs/reference/generated/kubectl/kubectl-commands#-em-token-em-) -命令调用 `TokenRequest` API 获得令牌。 -{{< /note >}} - - -#### 将 Secret 键投射到特定目录 {#projection-of-secret-keys-to-specific-paths} - -你也可以控制 Secret 键所投射到的卷中的路径。 -你可以使用 `.spec.volumes[].secret.items` 字段来更改每个主键的目标路径: - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: mypod -spec: - containers: - - name: mypod - image: redis - volumeMounts: - - name: foo - mountPath: "/etc/foo" - readOnly: true - volumes: - - name: foo - secret: - secretName: mysecret - items: - - key: username - path: my-group/my-username -``` - - -将发生的事情如下: - -- `mysecret` 中的键 `username` 会出现在容器中的路径为 `/etc/foo/my-group/my-username`, - 而不是 `/etc/foo/username`。 -- Secret 对象的 `password` 键不会被投射。 - -如果使用了 `.spec.volumes[].secret.items`,则只有 `items` 中指定了的主键会被投射。 -如果要使用 Secret 中的所有主键,则需要将它们全部枚举到 `items` 字段中。 - -如果你显式地列举了主键,则所列举的主键都必须在对应的 Secret 中存在。 -否则所在的卷不会被创建。 - - -#### Secret 文件的访问权限 {#secret-files-permissions} - -你可以为某个 Secret 主键设置 POSIX 文件访问权限位。 -如果你不指定访问权限,默认会使用 `0644`。 -你也可以为整个 Secret 卷设置默认的访问模式,然后再根据需要在主键层面重载。 - -例如,你可以像下面这样设置默认的模式: - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: mypod -spec: - containers: - - name: mypod - image: redis - volumeMounts: - - name: foo - mountPath: "/etc/foo" - volumes: - - name: foo - secret: - secretName: mysecret - defaultMode: 0400 -``` - - -该 Secret 被挂载在 `/etc/foo` 下,Secret 卷挂载所创建的所有文件的访问模式都是 `0400`。 - -{{< note >}} - -如果你是使用 JSON 来定义 Pod 或 Pod 模板,需要注意 JSON 规范不支持八进制的记数方式。 -你可以在 `defaultMode` 中设置十进制的值(例如,八进制中的 0400 在十进制中为 256)。 -如果你使用 YAML 来编写定义,你可以用八进制值来设置 `defaultMode`。 -{{< /note >}} - - -#### 使用来自卷中的 Secret 值 {#consuming-secret-values-from-volumes} - -在挂载了 Secret 卷的容器内,Secret 的主键都呈现为文件。 -Secret 的取值都是 Base64 编码的,保存在这些文件中。 - -下面是在上例中的容器内执行命令的结果: - -```shell -ls /etc/foo/ -``` - - -输出类似于: - -``` -username -password -``` - -```shell -cat /etc/foo/username -``` - - -输出类似于: - -``` -admin -``` - -```shell -cat /etc/foo/password -``` - - -输出类似于: - -``` -1f2d1e2e67df -``` - - -容器中的程序要负责根据需要读取 Secret 数据。 - - -#### 挂载的 Secret 是被自动更新的 {#mounted-secrets-are-updated-automatically} - 当卷中包含来自 Secret 的数据,而对应的 Secret 被更新,Kubernetes 会跟踪到这一操作并更新卷中的数据。更新的方式是保证最终一致性。 @@ -693,72 +452,40 @@ in a Pod: 中以{{< glossary_tooltip text="环境变量" term_id="container-env-variables" >}}的形式使用 Secret: -1. 创建 Secret(或者使用现有 Secret)。多个 Pod 可以引用同一个 Secret。 -1. 更改 Pod 定义,在要使用 Secret 键值的每个容器中添加与所使用的主键对应的环境变量。 - 读取 Secret 主键的环境变量应该在 `env[].valueFrom.secretKeyRef` 中填写 Secret - 的名称和主键名称。 -1. 更改你的镜像或命令行,以便程序读取环境变量中保存的值。 +1. 对于 Pod 规约中的每个容器,针对你要使用的每个 Secret 键,将对应的环境变量添加到 + `env[].valueFrom.secretKeyRef` 中。 +1. 更改你的镜像或命令行,以便程序能够从指定的环境变量找到所需要的值。 -下面是一个通过环境变量来使用 Secret 的示例 Pod: - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: secret-env-pod -spec: - containers: - - name: mycontainer - image: redis - env: - - name: SECRET_USERNAME - valueFrom: - secretKeyRef: - name: mysecret - key: username - optional: false # 此值为默认值;意味着 "mysecret" - # 必须存在且包含名为 "username" 的主键 - - name: SECRET_PASSWORD - valueFrom: - secretKeyRef: - name: mysecret - key: password - optional: false # 此值为默认值;意味着 "mysecret" - # 必须存在且包含名为 "password" 的主键 - restartPolicy: Never -``` +相关的指示说明, +可以参阅[使用 Secret 数据定义容器变量](/zh-cn/docs/tasks/inject-data-application/distribute-credentials-secure/#define-container-environment-variables-using-secret-data)。 #### 非法环境变量 {#restriction-env-from-invalid} -对于通过 `envFrom` 字段来填充环境变量的 Secret 而言, -如果其中包含的主键不能被当做合法的环境变量名,这些主键会被忽略掉。 +如果 Pod 规约中环境变量定义会被视为非法的环境变量名,这些主键将在你的容器中不可用。 Pod 仍然可以启动。 -如果你定义的 Pod 中包含非法的变量名称,则 Pod 可能启动失败, -会形成 reason 为 `InvalidVariableNames` 的事件,以及列举被略过的非法主键的消息。 +Kubernetes 添加一个 Event,其 reason 设置为 `InvalidVariableNames`,其消息将列举被略过的非法主键。 下面的例子中展示了一个 Pod,引用的是名为 `mysecret` 的 Secret, 其中包含两个非法的主键:`1badkey` 和 `2alsobad`。 @@ -776,59 +503,6 @@ LASTSEEN FIRSTSEEN COUNT NAME KIND SUBOBJECT 0s 0s 1 dapi-test-pod Pod Warning InvalidEnvironmentVariableNames kubelet, 127.0.0.1 Keys [1badkey, 2alsobad] from the EnvFrom secret default/mysecret were skipped since they are considered invalid environment variable names. ``` - -#### 通过环境变量使用 Secret 值 {#consuming-secret-values-from-environment-variables} - -在通过环境变量来使用 Secret 的容器中,Secret 主键展现为普通的环境变量。 -这些变量的取值是 Secret 数据的 Base64 解码值。 - -下面是在前文示例中的容器内执行命令的结果: - -```shell -echo "$SECRET_USERNAME" -``` - - -输出类似于: - -``` -admin -``` - -```shell -echo "$SECRET_PASSWORD" -``` - - -输出类似于: - -``` -1f2d1e2e67df -``` - -{{< note >}} - -如果容器已经在通过环境变量来使用 Secret,Secret 更新在容器内是看不到的, -除非容器被重启。有一些第三方的解决方案,能够在 Secret 发生变化时触发容器重启。 -{{< /note >}} - ## 使用场景 {#use-case} ### 使用场景:作为容器环境变量 {#use-case-as-container-environment-variables} -创建 Secret: - -```yaml -apiVersion: v1 -kind: Secret -metadata: - name: mysecret -type: Opaque -data: - USER_NAME: YWRtaW4= - PASSWORD: MWYyZDFlMmU2N2Rm -``` - - -创建 Secret: - -```shell -kubectl apply -f mysecret.yaml -``` - - -使用 `envFrom` 来将 Secret 的所有数据定义为容器的环境变量。 -来自 Secret 的主键成为 Pod 中的环境变量名称: - -```yaml -apiVersion: v1 -kind: Pod -metadata: - name: secret-test-pod -spec: - containers: - - name: test-container - image: registry.k8s.io/busybox - command: [ "/bin/sh", "-c", "env" ] - envFrom: - - secretRef: - name: mysecret - restartPolicy: Never -``` +你可以创建 Secret +并使用它[为容器设置环境变量](/zh-cn/docs/tasks/inject-data-application/distribute-credentials-secure/#define-container-environment-variables-using-secret-data)。 +Kubernetes 在 v1.22 版本之前都会自动创建用来访问 Kubernetes API 的凭据。 +这一老的机制是基于创建可被挂载到运行中 Pod 内的令牌 Secret 来实现的。 +在最近的版本中,包括 Kubernetes v{{< skew currentVersion >}} 中,API 凭据是直接通过 +[TokenRequest](/zh-cn/docs/reference/kubernetes-api/authentication-resources/token-request-v1/) +API 来获得的,这一凭据会使用[投射卷](/zh-cn/docs/reference/access-authn-authz/service-accounts-admin/#bound-service-account-token-volume)挂载到 +Pod 中。使用这种方式获得的令牌有确定的生命期,并且在挂载它们的 Pod 被删除时自动作废。 + + -从 v1.22 开始,这种类型的 Secret 不再被用来向 Pod 中加载凭据数据, -建议通过 [TokenRequest](/zh-cn/docs/reference/kubernetes-api/authentication-resources/token-request-v1/) -API 来获得令牌,而不是使用服务账号令牌 Secret 对象。 -通过 `TokenRequest` API 获得的令牌比保存在 Secret 对象中的令牌更加安全, -因为这些令牌有着被限定的生命期,并且不会被其他 API 客户端读取。 +你仍然可以[手动创建](/zh-cn/docs/tasks/configure-pod-container/configure-service-account/#manually-create-a-service-account-api-token) +服务账号令牌。例如,当你需要一个永远都不过期的令牌时。 +不过,仍然建议使用 [TokenRequest](/zh-cn/docs/reference/kubernetes-api/authentication-resources/token-request-v1/) +子资源来获得访问 API 服务器的令牌。 你可以使用 [`kubectl create token`](/docs/reference/generated/kubectl/kubectl-commands#-em-token-em-) 命令调用 `TokenRequest` API 获得令牌。 +{{< /note >}} -对于用户提供的非唯一性的属性,Kubernetes 提供了 -[标签(Labels)](/zh-cn/docs/concepts/overview/working-with-objects/labels/)和 +对于用户提供的非唯一性的属性,Kubernetes +提供了[标签(Label)](/zh-cn/docs/concepts/overview/working-with-objects/labels/)和 [注解(Annotation)](/zh-cn/docs/concepts/overview/working-with-objects/annotations/)机制。 @@ -44,6 +44,16 @@ For non-unique user-provided attributes, Kubernetes provides [labels](/docs/conc {{< glossary_definition term_id="name" length="all" >}} + +**名称在同一资源的所有 +[API 版本](/zh-cn/docs/concepts/overview/kubernetes-api/#api-groups-and-versioning)中必须是唯一的。 +这些 API 资源通过各自的 API 组、资源类型、名字空间(对于划分名字空间的资源)和名称来区分。 +换言之,API 版本在此上下文中是不相关的。** + {{< note >}} - ### DNS 子域名 {#dns-subdomain-names} 很多资源类型需要可以用作 DNS 子域名的名称。 From 46ff1a8047061b1b2a369b96fe99a0320ff8156f Mon Sep 17 00:00:00 2001 From: seancrasto <103709488+seancrasto@users.noreply.github.com> Date: Sat, 18 Feb 2023 18:42:54 -0500 Subject: [PATCH 260/279] Update persistent-volumes.md Minor corrections. --- content/en/docs/concepts/storage/persistent-volumes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/en/docs/concepts/storage/persistent-volumes.md b/content/en/docs/concepts/storage/persistent-volumes.md index 13ede898e59..27d5bd2ac71 100644 --- a/content/en/docs/concepts/storage/persistent-volumes.md +++ b/content/en/docs/concepts/storage/persistent-volumes.md @@ -1123,7 +1123,7 @@ and `CrossNamespaceVolumeDataSource` the kube-apiserver, kube-controller-manager. Also, you must enable the `CrossNamespaceVolumeDataSource` feature gate for the csi-provisioner. -Enabling the `CrossNamespaceVolumeDataSource` feature gate allow you to specify +Enabling the `CrossNamespaceVolumeDataSource` feature gate allows you to specify a namespace in the dataSourceRef field. {{< note >}} @@ -1138,7 +1138,7 @@ Gateway API before you can use this mechanism. ## Data source references -The `dataSourceRef` field behaves almost the same as the `dataSource` field. If either one is +The `dataSourceRef` field behaves almost the same as the `dataSource` field. If one is specified while the other is not, the API server will give both fields the same value. Neither field can be changed after creation, and attempting to specify different values for the two fields will result in a validation error. Therefore the two fields will always have the same From 9f3f8b8ad139c7c0fcfcaba3034f0e5bf5c8cf41 Mon Sep 17 00:00:00 2001 From: windsonsea Date: Sun, 19 Feb 2023 14:01:07 +0800 Subject: [PATCH 261/279] [zh] sync /cluster-administration/flow-control.md --- .../cluster-administration/flow-control.md | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/content/zh-cn/docs/concepts/cluster-administration/flow-control.md b/content/zh-cn/docs/concepts/cluster-administration/flow-control.md index aa0c1f0baef..92948200c35 100644 --- a/content/zh-cn/docs/concepts/cluster-administration/flow-control.md +++ b/content/zh-cn/docs/concepts/cluster-administration/flow-control.md @@ -154,7 +154,7 @@ configurable set of _priority levels_. Each incoming request is assigned to a single priority level, and each priority level will only dispatch as many concurrent requests as its particular limit allows. --> -### 优先级 {#Priority-Levels} +### 优先级 {#priority-levels} 如果未启用 APF,API 服务器中的整体并发量将受到 `kube-apiserver` 的参数 `--max-requests-inflight` 和 `--max-mutating-requests-inflight` 的限制。 @@ -262,7 +262,7 @@ flows of the same priority level. To enable distinct handling of distinct instances, controllers that have many instances should authenticate with distinct usernames --> -### 排队 {#Queuing} +### 排队 {#queuing} 即使在同一优先级内,也可能存在大量不同的流量源。 在过载情况下,防止一个请求流饿死其他流是非常有价值的 @@ -304,7 +304,7 @@ any of the limitations imposed by this feature. These exemptions prevent an improperly-configured flow control configuration from totally disabling an API server. --> -### 豁免请求 {#Exempt-requests} +### 豁免请求 {#exempt-requests} 某些特别重要的请求不受制于此特性施加的任何限制。 这些豁免可防止不当的流控配置完全禁用 API 服务器。 @@ -322,7 +322,7 @@ single PriorityLevelConfiguration. There is also a `v1alpha1` version of the same API group, and it has the same Kinds with the same syntax and semantics. --> -## 资源 {#Resources} +## 资源 {#resources} 流控 API 涉及两种资源。 [PriorityLevelConfiguration](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#prioritylevelconfiguration-v1beta2-flowcontrol-apiserver-k8s-io) @@ -338,7 +338,7 @@ A PriorityLevelConfiguration represents a single priority level. Each PriorityLevelConfiguration has an independent limit on the number of outstanding requests, and limitations on the number of queued requests. --> -### PriorityLevelConfiguration {#PriorityLevelConfiguration} +### PriorityLevelConfiguration 一个 PriorityLevelConfiguration 表示单个优先级。每个 PriorityLevelConfiguration 对未完成的请求数有各自的限制,对排队中的请求数也有限制。 @@ -511,7 +511,7 @@ FlowSchema in turn, starting with those with numerically lowest --- which we take to be the logically highest --- `matchingPrecedence` and working onward. The first match wins. --> -### FlowSchema {#flowschema} +### FlowSchema FlowSchema 匹配一些入站请求,并将它们分配给优先级。 每个入站请求都会对所有 FlowSchema 测试是否匹配, @@ -656,7 +656,7 @@ The suggested configuration groups requests into six priority levels: them. --> * `system` 优先级用于 `system:nodes` 组(即 kubelet)的与健康状态更新无关的请求; - kubelets 必须能连上 API 服务器,以便工作负载能够调度到其上。 + kubelet 必须能连上 API 服务器,以便工作负载能够调度到其上。 -## 健康检查并发豁免 {#Health-check-concurrency-exemption} +## 健康检查并发豁免 {#health-check-concurrency-exemption} 推荐配置没有为本地 kubelet 对 kube-apiserver 执行健康检查的请求进行任何特殊处理 ——它们倾向于使用安全端口,但不提供凭据。 @@ -870,9 +870,9 @@ PriorityLevelConfigurations. ### Metrics --> -## 可观察性 {#Observability} +## 可观察性 {#observability} -### 指标 {#Metrics} +### 指标 {#metrics} {{< note >}} -### 调试端点 {#Debug-endpoints} +### 调试端点 {#debug-endpoints} -启用 APF 特性后, kube-apiserver 会在其 HTTP/HTTPS 端口提供以下路径: +启用 APF 特性后,kube-apiserver 会在其 HTTP/HTTPS 端口提供以下路径: -## 一般规定 +## 一般规定 {#general} 本节列举一些译文中常见问题和约定。 -### 英文原文的保留 +### 英文原文的保留 {#commented-en-text} 为便于译文审查和变更追踪,所有中文本地化 Markdown 文件中都应使用 HTML 注释 `` 将英文原文逐段注释起来,后跟对应中文译文。例如: @@ -38,7 +38,7 @@ This is English text ... 无论英文原文或者中文译文中,都不要保留过多的、不必要的空白行。 -#### 段落划分 +#### 段落划分 {#paras} 请避免大段大段地注释和翻译。一般而言,每段翻译可对应两三个自然段。 段落过长会导致译文很难评阅。但也不必每个段落都单独翻译。例如: @@ -77,7 +77,7 @@ First paragraph, not very long. 第一段落,不太长。 ``` -#### 编号列表的处理 +#### 编号列表的处理 {#list} 编号列表需要编号的连续性,处理不好的话可能导致输出结果错误。 由于有些列表可能很长,一次性等将整个列表注释掉再翻译也不现实。 @@ -124,7 +124,7 @@ First paragraph, not very long. 4. 列表终于结束 ``` -#### Frontmatter 的处理 +#### Frontmatter 的处理 {#frontmatter} 页面中的 Frontmatter 指的是文件头的两个 `---` 中间的部分。 对这一部分,解析器有特殊处理,因此不能将英文部分放在前面,中文跟在后面。 @@ -152,8 +152,7 @@ weight: 30 - `title`、`description` 的内容要翻译,其他字段一般不必(甚至不可)翻译。 - `reviewers` 部分要删除,不然中文译文会转给英文作者来审阅。 - -#### 短代码(shortcode)处理 +#### 短代码(shortcode)处理 {#shortcode} 通过 HTML 注释的短代码仍会被运行,因此需要额外小心。建议处理方式: @@ -171,9 +170,9 @@ English text 保持注释掉的英文与译文都在短代码内更便于维护。 {{< /note >}} -### 译与不译 +### 译与不译 {#keep-or-translate} -#### 资源名称或字段不译 +#### 资源名称或字段不译 {#resource-name-or-fields} 根据英文原文写作风格约定【也在持续修订改进】,对 Kubernetes 中的 API 资源均按其规范中所给的大小写形式书写,例如:英文中会使用 Deployment 而不是 @@ -187,13 +186,12 @@ deployment 来表示名为 "Deployment" 的 API 资源类型和对象实例。 这时在本地化版本中一定不能译为“秘密”,以免与原文的语义不符。 {{< /note >}} -#### 代码中的注释 +#### 代码中的注释 {#code-comments} 一般而言,代码中的注释需要翻译,包括存放在 `content/zh-cn/examples/` 目录下的清单文件中的注释。 - -#### 出站链接 +#### 出站链接 {#external-links} 如果超级链接的目标是 Kubernetes 网站之外的纯英文网页,链接中的内容**可以**不翻译。 例如: @@ -209,7 +207,7 @@ Please check [installation caveats](https://acme.com/docs/v1/caveats) ... 注意,这里的 `installation` 与 `参阅` 之间留白,因为解析后属于中英文混排的情况。 {{< /note >}} -### 标点符号 +### 标点符号 {#punctuations} 1. 译文中标点符号要使用全角字符,除非以下两种情况: @@ -218,7 +216,7 @@ Please check [installation caveats](https://acme.com/docs/v1/caveats) ... 1. 英文排比句式中采用的逗号,在译文中要使用顿号代替,以便符合中文书写习惯。 -## 更新译文 +## 更新译文 {#update} 由于整个文档站点会随着 Kubernetes 项目的开发进展而演化,英文版本的网站内容会不断更新。 鉴于中文站点的基本翻译工作在 1.19 版本已完成, @@ -238,9 +236,9 @@ Please check [installation caveats](https://acme.com/docs/v1/caveats) ... ./scripts/lsync.sh content/zh-cn/docs/foo/bar.md ``` -## 关于链接 +## 关于链接 {#about-links} -### 链接锚点 +### 链接锚点 {#anchors} 英文 Markdown 中的各级标题会自动生成锚点,以便从其他页面中链接。 在译为中文后,相应的链接必然会失效。为防止这类问题, @@ -255,8 +253,7 @@ Please check [installation caveats](https://acme.com/docs/v1/caveats) ... 此类问题对于概念部分的页面最为突出,需要格外注意。 - -### 中文链接目标 +### 中文链接目标 {#link-to-zh-pages} 由于大部分页面已经完成中文本地化,这意味着很多链接可以使用中文版本作为目标。 例如: @@ -281,7 +278,7 @@ Website 的仓库中 `scripts/linkchecker.py` 是一个工具,可用来检查 ``` {{< /note >}} -## 排版格式 +## 排版格式 {#layout-format} 以下为译文 Markdown 排版格式要求: @@ -309,12 +306,11 @@ Website 的仓库中 `scripts/linkchecker.py` 是一个工具,可用来检查 甚至将超级链接中的半角井号(`#`)转换为全角,导致链接失效。 {{< /warning >}} - -## 特殊词汇 +## 特殊词汇 {#special-words} 英文中 "you" 翻译成 "你",不必翻译为 "您" 以表现尊敬或谦卑。 -### 术语拼写 +### 术语拼写 {#terms-spelling} 按中文译文习惯,尽量不要在中文译文中使用首字母小写的拼写。例如: @@ -337,7 +333,7 @@ Website 的仓库中 `scripts/linkchecker.py` 是一个工具,可用来检查 镜像策略(Image Policy)用来控制集群可拉取的镜像仓库(Image Registry)源。 ``` -### 术语对照 +### 术语对照 {#glossary} 本节列举常见术语的统一译法。除极个别情况,对于专业术语应使用本节所列举的译法: From 07526a10ce575f81614ad854d5355024f685c789 Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Sun, 19 Feb 2023 14:58:34 +0800 Subject: [PATCH 263/279] Clean up page assign-pod-node --- .../scheduling-eviction/assign-pod-node.md | 103 +++++++++--------- 1 file changed, 50 insertions(+), 53 deletions(-) diff --git a/content/en/docs/concepts/scheduling-eviction/assign-pod-node.md b/content/en/docs/concepts/scheduling-eviction/assign-pod-node.md index e6c793bf074..1ce5ea8e953 100644 --- a/content/en/docs/concepts/scheduling-eviction/assign-pod-node.md +++ b/content/en/docs/concepts/scheduling-eviction/assign-pod-node.md @@ -8,16 +8,15 @@ content_type: concept weight: 20 --- - -You can constrain a {{< glossary_tooltip text="Pod" term_id="pod" >}} so that it is +You can constrain a {{< glossary_tooltip text="Pod" term_id="pod" >}} so that it is _restricted_ to run on particular {{< glossary_tooltip text="node(s)" term_id="node" >}}, or to _prefer_ to run on particular nodes. There are several ways to do this and the recommended approaches all use [label selectors](/docs/concepts/overview/working-with-objects/labels/) to facilitate the selection. Often, you do not need to set any such constraints; the -{{< glossary_tooltip text="scheduler" term_id="kube-scheduler" >}} will automatically do a reasonable placement +{{< glossary_tooltip text="scheduler" term_id="kube-scheduler" >}} will automatically do a reasonable placement (for example, spreading your Pods across nodes so as not place Pods on a node with insufficient free resources). However, there are some circumstances where you may want to control which node the Pod deploys to, for example, to ensure that a Pod ends up on a node with an SSD attached to it, @@ -28,10 +27,10 @@ or to co-locate Pods from two different services that communicate a lot into the You can use any of the following methods to choose where Kubernetes schedules specific Pods: - * [nodeSelector](#nodeselector) field matching against [node labels](#built-in-node-labels) - * [Affinity and anti-affinity](#affinity-and-anti-affinity) - * [nodeName](#nodename) field - * [Pod topology spread constraints](#pod-topology-spread-constraints) +- [nodeSelector](#nodeselector) field matching against [node labels](#built-in-node-labels) +- [Affinity and anti-affinity](#affinity-and-anti-affinity) +- [nodeName](#nodename) field +- [Pod topology spread constraints](#pod-topology-spread-constraints) ## Node labels {#built-in-node-labels} @@ -51,7 +50,7 @@ and a different value in other environments. Adding labels to nodes allows you to target Pods for scheduling on specific nodes or groups of nodes. You can use this functionality to ensure that specific Pods only run on nodes with certain isolation, security, or regulatory -properties. +properties. If you use labels for node isolation, choose label keys that the {{}} cannot modify. This prevents a compromised node from setting those labels on @@ -59,7 +58,7 @@ itself so that the scheduler schedules workloads onto the compromised node. The [`NodeRestriction` admission plugin](/docs/reference/access-authn-authz/admission-controllers/#noderestriction) prevents the kubelet from setting or modifying labels with a -`node-restriction.kubernetes.io/` prefix. +`node-restriction.kubernetes.io/` prefix. To make use of that label prefix for node isolation: @@ -73,7 +72,7 @@ To make use of that label prefix for node isolation: You can add the `nodeSelector` field to your Pod specification and specify the [node labels](#built-in-node-labels) you want the target node to have. Kubernetes only schedules the Pod onto nodes that have each of the labels you -specify. +specify. See [Assign Pods to Nodes](/docs/tasks/configure-pod-container/assign-pods-nodes) for more information. @@ -84,20 +83,20 @@ information. labels. Affinity and anti-affinity expands the types of constraints you can define. Some of the benefits of affinity and anti-affinity include: -* The affinity/anti-affinity language is more expressive. `nodeSelector` only +- The affinity/anti-affinity language is more expressive. `nodeSelector` only selects nodes with all the specified labels. Affinity/anti-affinity gives you more control over the selection logic. -* You can indicate that a rule is *soft* or *preferred*, so that the scheduler +- You can indicate that a rule is *soft* or *preferred*, so that the scheduler still schedules the Pod even if it can't find a matching node. -* You can constrain a Pod using labels on other Pods running on the node (or other topological domain), +- You can constrain a Pod using labels on other Pods running on the node (or other topological domain), instead of just node labels, which allows you to define rules for which Pods can be co-located on a node. The affinity feature consists of two types of affinity: -* *Node affinity* functions like the `nodeSelector` field but is more expressive and +- *Node affinity* functions like the `nodeSelector` field but is more expressive and allows you to specify soft rules. -* *Inter-pod affinity/anti-affinity* allows you to constrain Pods against labels +- *Inter-pod affinity/anti-affinity* allows you to constrain Pods against labels on other Pods. ### Node affinity @@ -106,12 +105,12 @@ Node affinity is conceptually similar to `nodeSelector`, allowing you to constra Pod can be scheduled on based on node labels. There are two types of node affinity: - * `requiredDuringSchedulingIgnoredDuringExecution`: The scheduler can't - schedule the Pod unless the rule is met. This functions like `nodeSelector`, - but with a more expressive syntax. - * `preferredDuringSchedulingIgnoredDuringExecution`: The scheduler tries to - find a node that meets the rule. If a matching node is not available, the - scheduler still schedules the Pod. +- `requiredDuringSchedulingIgnoredDuringExecution`: The scheduler can't + schedule the Pod unless the rule is met. This functions like `nodeSelector`, + but with a more expressive syntax. +- `preferredDuringSchedulingIgnoredDuringExecution`: The scheduler tries to + find a node that meets the rule. If a matching node is not available, the + scheduler still schedules the Pod. {{}} In the preceding types, `IgnoredDuringExecution` means that if the node labels @@ -127,17 +126,17 @@ For example, consider the following Pod spec: In this example, the following rules apply: - * The node *must* have a label with the key `topology.kubernetes.io/zone` and - the value of that label *must* be either `antarctica-east1` or `antarctica-west1`. - * The node *preferably* has a label with the key `another-node-label-key` and - the value `another-node-label-value`. +- The node *must* have a label with the key `topology.kubernetes.io/zone` and + the value of that label *must* be either `antarctica-east1` or `antarctica-west1`. +- The node *preferably* has a label with the key `another-node-label-key` and + the value `another-node-label-value`. You can use the `operator` field to specify a logical operator for Kubernetes to use when interpreting the rules. You can use `In`, `NotIn`, `Exists`, `DoesNotExist`, `Gt` and `Lt`. `NotIn` and `DoesNotExist` allow you to define node anti-affinity behavior. -Alternatively, you can use [node taints](/docs/concepts/scheduling-eviction/taint-and-toleration/) +Alternatively, you can use [node taints](/docs/concepts/scheduling-eviction/taint-and-toleration/) to repel Pods from specific nodes. {{}} @@ -168,7 +167,7 @@ The final sum is added to the score of other priority functions for the node. Nodes with the highest total score are prioritized when the scheduler makes a scheduling decision for the Pod. -For example, consider the following Pod spec: +For example, consider the following Pod spec: {{< codenew file="pods/pod-with-affinity-anti-affinity.yaml" >}} @@ -268,8 +267,8 @@ to unintended behavior. Similar to [node affinity](#node-affinity) are two types of Pod affinity and anti-affinity as follows: - * `requiredDuringSchedulingIgnoredDuringExecution` - * `preferredDuringSchedulingIgnoredDuringExecution` +- `requiredDuringSchedulingIgnoredDuringExecution` +- `preferredDuringSchedulingIgnoredDuringExecution` For example, you could use `requiredDuringSchedulingIgnoredDuringExecution` affinity to tell the scheduler to @@ -297,7 +296,7 @@ The affinity rule says that the scheduler can only schedule a Pod onto a node if the node is in the same zone as one or more existing Pods with the label `security=S1`. More precisely, the scheduler must place the Pod on a node that has the `topology.kubernetes.io/zone=V` label, as long as there is at least one node in -that zone that currently has one or more Pods with the Pod label `security=S1`. +that zone that currently has one or more Pods with the Pod label `security=S1`. The anti-affinity rule says that the scheduler should try to avoid scheduling the Pod onto a node that is in the same zone as one or more Pods with the label @@ -314,9 +313,9 @@ You can use the `In`, `NotIn`, `Exists` and `DoesNotExist` values in the In principle, the `topologyKey` can be any allowed label key with the following exceptions for performance and security reasons: -* For Pod affinity and anti-affinity, an empty `topologyKey` field is not allowed in both `requiredDuringSchedulingIgnoredDuringExecution` +- For Pod affinity and anti-affinity, an empty `topologyKey` field is not allowed in both `requiredDuringSchedulingIgnoredDuringExecution` and `preferredDuringSchedulingIgnoredDuringExecution`. -* For `requiredDuringSchedulingIgnoredDuringExecution` Pod anti-affinity rules, +- For `requiredDuringSchedulingIgnoredDuringExecution` Pod anti-affinity rules, the admission controller `LimitPodHardAntiAffinityTopology` limits `topologyKey` to `kubernetes.io/hostname`. You can modify or disable the admission controller if you want to allow custom topologies. @@ -328,17 +327,18 @@ If omitted or empty, `namespaces` defaults to the namespace of the Pod where the affinity/anti-affinity definition appears. #### Namespace selector + {{< feature-state for_k8s_version="v1.24" state="stable" >}} You can also select matching namespaces using `namespaceSelector`, which is a label query over the set of namespaces. The affinity term is applied to namespaces selected by both `namespaceSelector` and the `namespaces` field. -Note that an empty `namespaceSelector` ({}) matches all namespaces, while a null or empty `namespaces` list and +Note that an empty `namespaceSelector` ({}) matches all namespaces, while a null or empty `namespaces` list and null `namespaceSelector` matches the namespace of the Pod where the rule is defined. #### More practical use-cases Inter-pod affinity and anti-affinity can be even more useful when they are used with higher -level collections such as ReplicaSets, StatefulSets, Deployments, etc. These +level collections such as ReplicaSets, StatefulSets, Deployments, etc. These rules allow you to configure that a set of workloads should be co-located in the same defined topology; for example, preferring to place two related Pods onto the same node. @@ -430,10 +430,10 @@ spec: Creating the two preceding Deployments results in the following cluster layout, where each web server is co-located with a cache, on three separate nodes. -| node-1 | node-2 | node-3 | -|:--------------------:|:-------------------:|:------------------:| -| *webserver-1* | *webserver-2* | *webserver-3* | -| *cache-1* | *cache-2* | *cache-3* | +| node-1 | node-2 | node-3 | +| :-----------: | :-----------: | :-----------: | +| *webserver-1* | *webserver-2* | *webserver-3* | +| *cache-1* | *cache-2* | *cache-3* | The overall effect is that each cache instance is likely to be accessed by a single client, that is running on the same node. This approach aims to minimize both skew (imbalanced load) and latency. @@ -453,13 +453,12 @@ tries to place the Pod on that node. Using `nodeName` overrules using Some of the limitations of using `nodeName` to select nodes are: -- If the named node does not exist, the Pod will not run, and in - some cases may be automatically deleted. -- If the named node does not have the resources to accommodate the - Pod, the Pod will fail and its reason will indicate why, - for example OutOfmemory or OutOfcpu. -- Node names in cloud environments are not always predictable or - stable. +- If the named node does not exist, the Pod will not run, and in + some cases may be automatically deleted. +- If the named node does not have the resources to accommodate the + Pod, the Pod will fail and its reason will indicate why, + for example OutOfmemory or OutOfcpu. +- Node names in cloud environments are not always predictable or stable. {{< note >}} `nodeName` is intended for use by custom schedulers or advanced use cases where @@ -495,12 +494,10 @@ to learn more about how these work. ## {{% heading "whatsnext" %}} -* Read more about [taints and tolerations](/docs/concepts/scheduling-eviction/taint-and-toleration/) . -* Read the design docs for [node affinity](https://git.k8s.io/design-proposals-archive/scheduling/nodeaffinity.md) +- Read more about [taints and tolerations](/docs/concepts/scheduling-eviction/taint-and-toleration/) . +- Read the design docs for [node affinity](https://git.k8s.io/design-proposals-archive/scheduling/nodeaffinity.md) and for [inter-pod affinity/anti-affinity](https://git.k8s.io/design-proposals-archive/scheduling/podaffinity.md). -* Learn about how the [topology manager](/docs/tasks/administer-cluster/topology-manager/) takes part in node-level - resource allocation decisions. -* Learn how to use [nodeSelector](/docs/tasks/configure-pod-container/assign-pods-nodes/). -* Learn how to use [affinity and anti-affinity](/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/). - - +- Learn about how the [topology manager](/docs/tasks/administer-cluster/topology-manager/) takes part in node-level + resource allocation decisions. +- Learn how to use [nodeSelector](/docs/tasks/configure-pod-container/assign-pods-nodes/). +- Learn how to use [affinity and anti-affinity](/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/). From e9784b98be593077f56d2e1b209c42baacb242e5 Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Sun, 19 Feb 2023 15:30:04 +0800 Subject: [PATCH 264/279] Add syntax tag to highlight the shell --- .../run-stateless-application-deployment.md | 148 +++++++++--------- 1 file changed, 76 insertions(+), 72 deletions(-) diff --git a/content/en/docs/tasks/run-application/run-stateless-application-deployment.md b/content/en/docs/tasks/run-application/run-stateless-application-deployment.md index 62bd984ddc7..370892522b9 100644 --- a/content/en/docs/tasks/run-application/run-stateless-application-deployment.md +++ b/content/en/docs/tasks/run-application/run-stateless-application-deployment.md @@ -9,27 +9,16 @@ weight: 10 This page shows how to run an application using a Kubernetes Deployment object. - - - ## {{% heading "objectives" %}} - -* Create an nginx deployment. -* Use kubectl to list information about the deployment. -* Update the deployment. - - - +- Create an nginx deployment. +- Use kubectl to list information about the deployment. +- Update the deployment. ## {{% heading "prerequisites" %}} - {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} - - - ## Creating and exploring an nginx deployment @@ -40,60 +29,71 @@ a Deployment that runs the nginx:1.14.2 Docker image: {{< codenew file="application/deployment.yaml" >}} - 1. Create a Deployment based on the YAML file: - kubectl apply -f https://k8s.io/examples/application/deployment.yaml + ```shell + kubectl apply -f https://k8s.io/examples/application/deployment.yaml + ``` 1. Display information about the Deployment: - kubectl describe deployment nginx-deployment + ```shell + kubectl describe deployment nginx-deployment + ``` - The output is similar to this: + The output is similar to this: - Name: nginx-deployment - Namespace: default - CreationTimestamp: Tue, 30 Aug 2016 18:11:37 -0700 - Labels: app=nginx - Annotations: deployment.kubernetes.io/revision=1 - Selector: app=nginx - Replicas: 2 desired | 2 updated | 2 total | 2 available | 0 unavailable - StrategyType: RollingUpdate - MinReadySeconds: 0 - RollingUpdateStrategy: 1 max unavailable, 1 max surge - Pod Template: - Labels: app=nginx - Containers: - nginx: - Image: nginx:1.14.2 - Port: 80/TCP - Environment: - Mounts: - Volumes: - Conditions: - Type Status Reason - ---- ------ ------ - Available True MinimumReplicasAvailable - Progressing True NewReplicaSetAvailable - OldReplicaSets: - NewReplicaSet: nginx-deployment-1771418926 (2/2 replicas created) - No events. + ``` + Name: nginx-deployment + Namespace: default + CreationTimestamp: Tue, 30 Aug 2016 18:11:37 -0700 + Labels: app=nginx + Annotations: deployment.kubernetes.io/revision=1 + Selector: app=nginx + Replicas: 2 desired | 2 updated | 2 total | 2 available | 0 unavailable + StrategyType: RollingUpdate + MinReadySeconds: 0 + RollingUpdateStrategy: 1 max unavailable, 1 max surge + Pod Template: + Labels: app=nginx + Containers: + nginx: + Image: nginx:1.14.2 + Port: 80/TCP + Environment: + Mounts: + Volumes: + Conditions: + Type Status Reason + ---- ------ ------ + Available True MinimumReplicasAvailable + Progressing True NewReplicaSetAvailable + OldReplicaSets: + NewReplicaSet: nginx-deployment-1771418926 (2/2 replicas created) + No events. + ``` 1. List the Pods created by the deployment: - kubectl get pods -l app=nginx + ```shell + kubectl get pods -l app=nginx + ``` - The output is similar to this: + The output is similar to this: - NAME READY STATUS RESTARTS AGE - nginx-deployment-1771418926-7o5ns 1/1 Running 0 16h - nginx-deployment-1771418926-r18az 1/1 Running 0 16h + ``` + NAME READY STATUS RESTARTS AGE + nginx-deployment-1771418926-7o5ns 1/1 Running 0 16h + nginx-deployment-1771418926-r18az 1/1 Running 0 16h + ``` 1. Display information about a Pod: - kubectl describe pod + ```shell + kubectl describe pod + ``` - where `` is the name of one of your Pods. + where `` is the name of one of your Pods. ## Updating the deployment @@ -104,11 +104,15 @@ specifies that the deployment should be updated to use nginx 1.16.1. 1. Apply the new YAML file: - kubectl apply -f https://k8s.io/examples/application/deployment-update.yaml + ```shell + kubectl apply -f https://k8s.io/examples/application/deployment-update.yaml + ``` 1. Watch the deployment create pods with new names and delete the old pods: - kubectl get pods -l app=nginx + ```shell + kubectl get pods -l app=nginx + ``` ## Scaling the application by increasing the replica count @@ -120,25 +124,33 @@ should have four Pods: 1. Apply the new YAML file: - kubectl apply -f https://k8s.io/examples/application/deployment-scale.yaml + ```shell + kubectl apply -f https://k8s.io/examples/application/deployment-scale.yaml + ``` 1. Verify that the Deployment has four Pods: - kubectl get pods -l app=nginx + ```shell + kubectl get pods -l app=nginx + ``` - The output is similar to this: + The output is similar to this: - NAME READY STATUS RESTARTS AGE - nginx-deployment-148880595-4zdqq 1/1 Running 0 25s - nginx-deployment-148880595-6zgi1 1/1 Running 0 25s - nginx-deployment-148880595-fxcez 1/1 Running 0 2m - nginx-deployment-148880595-rwovn 1/1 Running 0 2m + ``` + NAME READY STATUS RESTARTS AGE + nginx-deployment-148880595-4zdqq 1/1 Running 0 25s + nginx-deployment-148880595-6zgi1 1/1 Running 0 25s + nginx-deployment-148880595-fxcez 1/1 Running 0 2m + nginx-deployment-148880595-rwovn 1/1 Running 0 2m + ``` ## Deleting a deployment Delete the deployment by name: - kubectl delete deployment nginx-deployment +```shell +kubectl delete deployment nginx-deployment +``` ## ReplicationControllers -- the Old Way @@ -147,14 +159,6 @@ which in turn uses a ReplicaSet. Before the Deployment and ReplicaSet were added to Kubernetes, replicated applications were configured using a [ReplicationController](/docs/concepts/workloads/controllers/replicationcontroller/). - - - ## {{% heading "whatsnext" %}} - -* Learn more about [Deployment objects](/docs/concepts/workloads/controllers/deployment/). - - - - +- Learn more about [Deployment objects](/docs/concepts/workloads/controllers/deployment/). From 876ce6c7a7a15d2464f8a42e9d44206bec804a11 Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Sun, 19 Feb 2023 16:13:59 +0800 Subject: [PATCH 265/279] [zh] Resync some tiny changes in page under tasks --- .../update-api-object-kubectl-patch.md | 2 +- .../configure-pod-container/configure-volume-storage.md | 4 ++-- .../docs/tasks/configure-pod-container/migrate-from-psp.md | 1 + .../configure-pod-container/pull-image-private-registry.md | 4 ++-- .../update-api-object-kubectl-patch.md | 2 +- content/zh-cn/docs/tasks/network/validate-dual-stack.md | 6 ++++-- .../zh-cn/docs/tasks/run-application/scale-stateful-set.md | 1 + 7 files changed, 12 insertions(+), 8 deletions(-) diff --git a/content/en/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch.md b/content/en/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch.md index 4bd40719ac2..4a2f7e3ac07 100644 --- a/content/en/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch.md +++ b/content/en/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch.md @@ -261,7 +261,7 @@ kubectl get deployment patch-demo --output yaml The `containers` list that you specified in the patch has only one Container. The output shows that your list of one Container replaced the existing `containers` list. -```shell +```yaml spec: containers: - image: gcr.io/google-samples/node-hello:1.0 diff --git a/content/zh-cn/docs/tasks/configure-pod-container/configure-volume-storage.md b/content/zh-cn/docs/tasks/configure-pod-container/configure-volume-storage.md index a0f6fa6b0ee..2065d4ef378 100644 --- a/content/zh-cn/docs/tasks/configure-pod-container/configure-volume-storage.md +++ b/content/zh-cn/docs/tasks/configure-pod-container/configure-volume-storage.md @@ -49,7 +49,7 @@ restarts. Here is the configuration file for the Pod: {{< codenew file="pods/storage/redis.yaml" >}} 1. 创建 Pod: @@ -88,7 +88,7 @@ restarts. Here is the configuration file for the Pod: ``` 4. 在你的 Shell 中,切换到 `/data/redis` 目录下,然后创建一个文件: diff --git a/content/zh-cn/docs/tasks/configure-pod-container/migrate-from-psp.md b/content/zh-cn/docs/tasks/configure-pod-container/migrate-from-psp.md index 0061e4cd0c7..99d03c80e6b 100644 --- a/content/zh-cn/docs/tasks/configure-pod-container/migrate-from-psp.md +++ b/content/zh-cn/docs/tasks/configure-pod-container/migrate-from-psp.md @@ -356,6 +356,7 @@ For each updated PodSecurityPolicy: you can compare the pod with the PodTemplate in the controller resource. If any changes are identified, the original Pod or PodTemplate should be updated with the desired configuration. The fields to review are: + - `.metadata.annotations['container.apparmor.security.beta.kubernetes.io/*']` (replace * with each container name) --> 2. 比较运行中的 Pod 与原来的 Pod 规约,确定 PodSecurityPolicy 是否更改过这些 Pod。 对于通过[工作负载资源](/zh-cn/docs/concepts/workloads/controllers/)所创建的 Pod, diff --git a/content/zh-cn/docs/tasks/configure-pod-container/pull-image-private-registry.md b/content/zh-cn/docs/tasks/configure-pod-container/pull-image-private-registry.md index ed0f33623b6..21ff6407bdb 100644 --- a/content/zh-cn/docs/tasks/configure-pod-container/pull-image-private-registry.md +++ b/content/zh-cn/docs/tasks/configure-pod-container/pull-image-private-registry.md @@ -44,11 +44,11 @@ as an example registry. -## 登录 Docker 镜像仓库 {#log-in-to-docker} +## 登录 Docker 镜像仓库 {#log-in-to-docker-hub} 在个人电脑上,要想拉取私有镜像必须在镜像仓库上进行身份验证。 diff --git a/content/zh-cn/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch.md b/content/zh-cn/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch.md index 68ca773fce2..81274916b55 100644 --- a/content/zh-cn/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch.md +++ b/content/zh-cn/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch.md @@ -639,7 +639,7 @@ kubectl patch deployment patch-demo --patch '{"spec": {"template": {"spec": {"co The flag `--subresource=[subresource-name]` is used with kubectl commands like get, patch, edit and replace to fetch and update `status` and `scale` subresources of the resources (applicable for kubectl version v1.24 or more). This flag is used with all the API resources -(built-in and CRs) which has `status` or `scale` subresource. Deployment is one of the +(built-in and CRs) that have `status` or `scale` subresource. Deployment is one of the examples which supports these subresources. Here's a manifest for a Deployment that has two replicas: diff --git a/content/zh-cn/docs/tasks/network/validate-dual-stack.md b/content/zh-cn/docs/tasks/network/validate-dual-stack.md index a0b70b97e6c..18d50d70eeb 100644 --- a/content/zh-cn/docs/tasks/network/validate-dual-stack.md +++ b/content/zh-cn/docs/tasks/network/validate-dual-stack.md @@ -7,6 +7,8 @@ content_type: task reviewers: - lachie83 - khenidak +- bridgetkromhout +min-kubernetes-server-version: v1.23 title: Validate IPv4/IPv6 dual-stack content_type: task --> @@ -316,7 +318,7 @@ Events: ### 创建双协议栈负载均衡服务 @@ -336,7 +338,7 @@ kubectl get svc -l app.kubernetes.io/name=MyApp ``` 验证服务是否从 IPv6 地址块中接收到 `CLUSTER-IP` 地址以及 `EXTERNAL-IP`。 然后,你可以通过 IP 和端口验证对服务的访问。 diff --git a/content/zh-cn/docs/tasks/run-application/scale-stateful-set.md b/content/zh-cn/docs/tasks/run-application/scale-stateful-set.md index 02e7f13aa8e..c8ca657e833 100644 --- a/content/zh-cn/docs/tasks/run-application/scale-stateful-set.md +++ b/content/zh-cn/docs/tasks/run-application/scale-stateful-set.md @@ -1,6 +1,7 @@ --- title: 扩缩 StatefulSet content_type: task +weight: 50 --- From 19085a3853a3662f4e3ae253bc6f1e0bb436ae1a Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Sun, 19 Feb 2023 16:15:11 +0800 Subject: [PATCH 266/279] [zh] Resync page quality-service-pod --- .../quality-service-pod.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/content/zh-cn/docs/tasks/configure-pod-container/quality-service-pod.md b/content/zh-cn/docs/tasks/configure-pod-container/quality-service-pod.md index d93b183fd19..4691bd2079d 100644 --- a/content/zh-cn/docs/tasks/configure-pod-container/quality-service-pod.md +++ b/content/zh-cn/docs/tasks/configure-pod-container/quality-service-pod.md @@ -62,7 +62,7 @@ kubectl create namespace qos-example ## 创建一个 QoS 类为 Guaranteed 的 Pod {#create-a-pod-that-gets-assigned-a-qos-class-of-guaranteed} -对于 QoS 类为 Guaranteed 的 Pod: +对于 QoS 类为 `Guaranteed` 的 Pod: * Pod 中的每个容器都必须指定内存限制和内存请求。 * 对于 Pod 中的每个容器,内存限制必须等于内存请求。 @@ -116,11 +116,11 @@ kubectl get pod qos-demo --namespace=qos-example --output=yaml ``` -结果表明 Kubernetes 为 Pod 配置的 QoS 类为 Guaranteed。 +结果表明 Kubernetes 为 Pod 配置的 QoS 类为 `Guaranteed`。 结果也确认了 Pod 容器设置了与内存限制匹配的内存请求,设置了与 CPU 限制匹配的 CPU 请求。 ```yaml @@ -247,7 +247,7 @@ kubectl delete pod qos-demo-2 --namespace=qos-example For a Pod to be given a QoS class of `BestEffort`, the Containers in the Pod must not have any memory or CPU limits or requests. -Here is the configuration file for a Pod that has one Container. The Container has no memory or CPU +Here is a manifest for a Pod that has one Container. The Container has no memory or CPU limits or requests: --> ## 创建一个 QoS 类为 BestEffort 的 Pod {#create-a-pod-that-gets-assigned-a-qos-class-of-besteffort} @@ -308,23 +308,23 @@ kubectl delete pod qos-demo-3 --namespace=qos-example ## 创建包含两个容器的 Pod {#create-a-pod-that-has-two-containers} -下面是包含两个 Container 的 Pod 配置文件。一个 Container 指定内存请求为 200 MiB。 +下面是包含两个 Container 的 Pod 清单。一个 Container 指定内存请求为 200 MiB。 另外一个 Container 没有指定任何请求或限制。 {{< codenew file="pods/qos/qos-pod-4.yaml" >}} -注意此 Pod 满足 `Burstable` QoS 类的标准。也就是说它不满足 Guaranteed QoS 类标准, +注意此 Pod 满足 `Burstable` QoS 类的标准。也就是说它不满足 `Guaranteed` QoS 类标准, 因为它的 Container 之一设有内存请求。 创建 Pod: From 3ca95d6c88fe7af0bf2da0c5f2363ba41c86ef9a Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Sun, 19 Feb 2023 16:30:51 +0800 Subject: [PATCH 267/279] Tidy concepts pages within Label and Annotation --- .../overview/working-with-objects/annotations.md | 10 +--------- .../concepts/overview/working-with-objects/labels.md | 8 ++++---- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/content/en/docs/concepts/overview/working-with-objects/annotations.md b/content/en/docs/concepts/overview/working-with-objects/annotations.md index 02d3982c695..721bb67c7d7 100644 --- a/content/en/docs/concepts/overview/working-with-objects/annotations.md +++ b/content/en/docs/concepts/overview/working-with-objects/annotations.md @@ -8,7 +8,6 @@ weight: 60 You can use Kubernetes annotations to attach arbitrary non-identifying metadata to objects. Clients such as tools and libraries can retrieve this metadata. - ## Attaching metadata to objects @@ -74,10 +73,9 @@ If the prefix is omitted, the annotation Key is presumed to be private to the us The `kubernetes.io/` and `k8s.io/` prefixes are reserved for Kubernetes core components. -For example, here's the configuration file for a Pod that has the annotation `imageregistry: https://hub.docker.com/` : +For example, here's a manifest for a Pod that has the annotation `imageregistry: https://hub.docker.com/` : ```yaml - apiVersion: v1 kind: Pod metadata: @@ -90,14 +88,8 @@ spec: image: nginx:1.14.2 ports: - containerPort: 80 - ``` - - ## {{% heading "whatsnext" %}} Learn more about [Labels and Selectors](/docs/concepts/overview/working-with-objects/labels/). - - - diff --git a/content/en/docs/concepts/overview/working-with-objects/labels.md b/content/en/docs/concepts/overview/working-with-objects/labels.md index d57e47ab4a3..aec2c4cc013 100644 --- a/content/en/docs/concepts/overview/working-with-objects/labels.md +++ b/content/en/docs/concepts/overview/working-with-objects/labels.md @@ -79,7 +79,7 @@ Valid label value: * unless empty, must begin and end with an alphanumeric character (`[a-z0-9A-Z]`), * could contain dashes (`-`), underscores (`_`), dots (`.`), and alphanumerics between. -For example, here's the configuration file for a Pod that has two labels +For example, here's a manifest for a Pod that has two labels `environment: production` and `app: nginx`: ```yaml @@ -259,7 +259,7 @@ or ```yaml selector: - component: redis + component: redis ``` This selector (respectively in `json` or `yaml` format) is equivalent to @@ -278,8 +278,8 @@ selector: matchLabels: component: redis matchExpressions: - - {key: tier, operator: In, values: [cache]} - - {key: environment, operator: NotIn, values: [dev]} + - { key: tier, operator: In, values: [cache] } + - { key: environment, operator: NotIn, values: [dev] } ``` `matchLabels` is a map of `{key,value}` pairs. A single `{key,value}` in the From 7b59d55a64a6f57c3ea88bcabb5c4793a33d7621 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 19 Feb 2023 19:59:24 +0800 Subject: [PATCH 268/279] [zh] sync kubeadm_reset_phase_remove-etcd-member.md --- .../kubeadm_reset_phase_remove-etcd-member.md | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/content/zh-cn/docs/reference/setup-tools/kubeadm/generated/kubeadm_reset_phase_remove-etcd-member.md b/content/zh-cn/docs/reference/setup-tools/kubeadm/generated/kubeadm_reset_phase_remove-etcd-member.md index 8b69953efd8..b95fcb7cf84 100644 --- a/content/zh-cn/docs/reference/setup-tools/kubeadm/generated/kubeadm_reset_phase_remove-etcd-member.md +++ b/content/zh-cn/docs/reference/setup-tools/kubeadm/generated/kubeadm_reset_phase_remove-etcd-member.md @@ -3,7 +3,7 @@ The file is auto-generated from the Go source code of the component using a gene [generator](https://github.com/kubernetes-sigs/reference-docs/). To learn how to generate the reference documentation, please read [Contributing to the reference documentation](/docs/contribute/generate-ref-docs/). -To update the reference conent, please follow the +To update the reference content, please follow the [Contributing upstream](/docs/contribute/generate-ref-docs/contribute-upstream/) guide. You can file document formatting bugs against the [reference-docs](https://github.com/kubernetes-sigs/reference-docs/) project. @@ -12,18 +12,17 @@ guide. You can file document formatting bugs against the -删除本地 etcd 成员 +删除本地 etcd 成员。 - ### 概要 -删除控制平面节点的本地 etcd 成员 +删除控制平面节点的本地 etcd 成员。 ``` kubeadm reset phase remove-etcd-member [flags] @@ -32,7 +31,6 @@ kubeadm reset phase remove-etcd-member [flags] - ### 选项 @@ -42,6 +40,16 @@ kubeadm reset phase remove-etcd-member [flags] + + + + + + + @@ -68,11 +76,9 @@ remove-etcd-member 的帮助信息
    --dry-run

    + +不应用任何更改;仅输出要完成的内容。 +

    -h, --help
    - - ### 从父命令继承的选项 From e2e8192cb69a131dd50a5150d748849d04b5ce84 Mon Sep 17 00:00:00 2001 From: Dipesh Rawat Date: Sun, 19 Feb 2023 19:46:41 +0000 Subject: [PATCH 269/279] Fixed Calico Quickstart link --- .../network-policy-provider/calico-network-policy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/docs/tasks/administer-cluster/network-policy-provider/calico-network-policy.md b/content/en/docs/tasks/administer-cluster/network-policy-provider/calico-network-policy.md index 0cf26dcf8ca..972c90e0fa2 100644 --- a/content/en/docs/tasks/administer-cluster/network-policy-provider/calico-network-policy.md +++ b/content/en/docs/tasks/administer-cluster/network-policy-provider/calico-network-policy.md @@ -43,7 +43,7 @@ Decide whether you want to deploy a [cloud](#creating-a-calico-cluster-with-goog ## Creating a local Calico cluster with kubeadm To get a local single-host Calico cluster in fifteen minutes using kubeadm, refer to the -[Calico Quickstart](https://docs.projectcalico.org/latest/getting-started/kubernetes/). +[Calico Quickstart](https://projectcalico.docs.tigera.io/getting-started/kubernetes/). From 1767db3e748818b8a35e5e0c46a3c52686cb26f3 Mon Sep 17 00:00:00 2001 From: Mengjiao Liu Date: Mon, 20 Feb 2023 11:28:51 +0800 Subject: [PATCH 270/279] [zh-cn] Add blog translators description --- .../zh-cn/docs/contribute/localization_zh.md | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/content/zh-cn/docs/contribute/localization_zh.md b/content/zh-cn/docs/contribute/localization_zh.md index f79ea8f41ef..5f8e0e4a9bb 100644 --- a/content/zh-cn/docs/contribute/localization_zh.md +++ b/content/zh-cn/docs/contribute/localization_zh.md @@ -170,6 +170,27 @@ English text 保持注释掉的英文与译文都在短代码内更便于维护。 {{< /note >}} +### 博客译者署名 {#blog-translators-signature} + +翻译一篇博客需要花费大量的时间和精力,添加署名是对译者工作的认可, +也有利于激励贡献者同步英文博客,提升博客质量。 +如要添加译者署名,可在作者下面一行添加译者相关内容。例如: + +``` + +**作者** :Alice (Google) + +**译者** :李明 (百度) +``` + +{{< note >}} +译者也可以放弃署名,这取决于个人偏好,不是强制性的。 +译者所属公司由译者本人决定是否填写。 +多人翻译同一篇博客默认按照译者的贡献大小进行署名,贡献越大的署名越靠前。 +{{< /note >}} + ### 译与不译 {#keep-or-translate} #### 资源名称或字段不译 {#resource-name-or-fields} From 0dfd829c65bd99f9b142d2f1ae11fb2cefe76b82 Mon Sep 17 00:00:00 2001 From: zhuzhenghao Date: Sun, 19 Feb 2023 21:26:00 +0800 Subject: [PATCH 271/279] Add code block in page run-single-instance-stateful-application --- ...un-single-instance-stateful-application.md | 175 +++++++++--------- 1 file changed, 86 insertions(+), 89 deletions(-) diff --git a/content/en/docs/tasks/run-application/run-single-instance-stateful-application.md b/content/en/docs/tasks/run-application/run-single-instance-stateful-application.md index bdc3b0c524a..de68f49892d 100644 --- a/content/en/docs/tasks/run-application/run-single-instance-stateful-application.md +++ b/content/en/docs/tasks/run-application/run-single-instance-stateful-application.md @@ -10,28 +10,17 @@ This page shows you how to run a single-instance stateful application in Kubernetes using a PersistentVolume and a Deployment. The application is MySQL. - - - ## {{% heading "objectives" %}} - -* Create a PersistentVolume referencing a disk in your environment. -* Create a MySQL Deployment. -* Expose MySQL to other pods in the cluster at a known DNS name. - - - +- Create a PersistentVolume referencing a disk in your environment. +- Create a MySQL Deployment. +- Expose MySQL to other pods in the cluster at a known DNS name. ## {{% heading "prerequisites" %}} +- {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} -* {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} - -* {{< include "default-storage-class-prereqs.md" >}} - - - +- {{< include "default-storage-class-prereqs.md" >}} @@ -39,7 +28,7 @@ application is MySQL. You can run a stateful application by creating a Kubernetes Deployment and connecting it to an existing PersistentVolume using a -PersistentVolumeClaim. For example, this YAML file describes a +PersistentVolumeClaim. For example, this YAML file describes a Deployment that runs MySQL and references the PersistentVolumeClaim. The file defines a volume mount for /var/lib/mysql, and then creates a PersistentVolumeClaim that looks for a 20G volume. This claim is @@ -55,80 +44,96 @@ for a secure solution. 1. Deploy the PV and PVC of the YAML file: - kubectl apply -f https://k8s.io/examples/application/mysql/mysql-pv.yaml + ```shell + kubectl apply -f https://k8s.io/examples/application/mysql/mysql-pv.yaml + ``` 1. Deploy the contents of the YAML file: - kubectl apply -f https://k8s.io/examples/application/mysql/mysql-deployment.yaml + ```shell + kubectl apply -f https://k8s.io/examples/application/mysql/mysql-deployment.yaml + ``` 1. Display information about the Deployment: - kubectl describe deployment mysql + ```shell + kubectl describe deployment mysql + ``` - The output is similar to this: + The output is similar to this: - Name: mysql - Namespace: default - CreationTimestamp: Tue, 01 Nov 2016 11:18:45 -0700 - Labels: app=mysql - Annotations: deployment.kubernetes.io/revision=1 - Selector: app=mysql - Replicas: 1 desired | 1 updated | 1 total | 0 available | 1 unavailable - StrategyType: Recreate - MinReadySeconds: 0 - Pod Template: - Labels: app=mysql - Containers: - mysql: - Image: mysql:5.6 - Port: 3306/TCP - Environment: - MYSQL_ROOT_PASSWORD: password - Mounts: - /var/lib/mysql from mysql-persistent-storage (rw) - Volumes: - mysql-persistent-storage: - Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace) - ClaimName: mysql-pv-claim - ReadOnly: false - Conditions: - Type Status Reason - ---- ------ ------ - Available False MinimumReplicasUnavailable - Progressing True ReplicaSetUpdated - OldReplicaSets: - NewReplicaSet: mysql-63082529 (1/1 replicas created) - Events: - FirstSeen LastSeen Count From SubobjectPath Type Reason Message - --------- -------- ----- ---- ------------- -------- ------ ------- - 33s 33s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set mysql-63082529 to 1 + ``` + Name: mysql + Namespace: default + CreationTimestamp: Tue, 01 Nov 2016 11:18:45 -0700 + Labels: app=mysql + Annotations: deployment.kubernetes.io/revision=1 + Selector: app=mysql + Replicas: 1 desired | 1 updated | 1 total | 0 available | 1 unavailable + StrategyType: Recreate + MinReadySeconds: 0 + Pod Template: + Labels: app=mysql + Containers: + mysql: + Image: mysql:5.6 + Port: 3306/TCP + Environment: + MYSQL_ROOT_PASSWORD: password + Mounts: + /var/lib/mysql from mysql-persistent-storage (rw) + Volumes: + mysql-persistent-storage: + Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace) + ClaimName: mysql-pv-claim + ReadOnly: false + Conditions: + Type Status Reason + ---- ------ ------ + Available False MinimumReplicasUnavailable + Progressing True ReplicaSetUpdated + OldReplicaSets: + NewReplicaSet: mysql-63082529 (1/1 replicas created) + Events: + FirstSeen LastSeen Count From SubobjectPath Type Reason Message + --------- -------- ----- ---- ------------- -------- ------ ------- + 33s 33s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set mysql-63082529 to 1 + ``` 1. List the pods created by the Deployment: - kubectl get pods -l app=mysql + ```shell + kubectl get pods -l app=mysql + ``` - The output is similar to this: + The output is similar to this: - NAME READY STATUS RESTARTS AGE - mysql-63082529-2z3ki 1/1 Running 0 3m + ``` + NAME READY STATUS RESTARTS AGE + mysql-63082529-2z3ki 1/1 Running 0 3m + ``` 1. Inspect the PersistentVolumeClaim: - kubectl describe pvc mysql-pv-claim + ```shell + kubectl describe pvc mysql-pv-claim + ``` - The output is similar to this: + The output is similar to this: - Name: mysql-pv-claim - Namespace: default - StorageClass: - Status: Bound - Volume: mysql-pv-volume - Labels: - Annotations: pv.kubernetes.io/bind-completed=yes - pv.kubernetes.io/bound-by-controller=yes - Capacity: 20Gi - Access Modes: RWO - Events: + ``` + Name: mysql-pv-claim + Namespace: default + StorageClass: + Status: Bound + Volume: mysql-pv-volume + Labels: + Annotations: pv.kubernetes.io/bind-completed=yes + pv.kubernetes.io/bound-by-controller=yes + Capacity: 20Gi + Access Modes: RWO + Events: + ``` ## Accessing the MySQL instance @@ -140,7 +145,7 @@ behind a Service and you don't intend to increase the number of Pods. Run a MySQL client to connect to the server: -``` +```shell kubectl run -it --rm --image=mysql:5.6 --restart=Never mysql-client -- mysql -h mysql -ppassword ``` @@ -161,11 +166,11 @@ The image or any other part of the Deployment can be updated as usual with the `kubectl apply` command. Here are some precautions that are specific to stateful apps: -* Don't scale the app. This setup is for single-instance apps +- Don't scale the app. This setup is for single-instance apps only. The underlying PersistentVolume can only be mounted to one Pod. For clustered stateful apps, see the [StatefulSet documentation](/docs/concepts/workloads/controllers/statefulset/). -* Use `strategy:` `type: Recreate` in the Deployment configuration +- Use `strategy:` `type: Recreate` in the Deployment configuration YAML file. This instructs Kubernetes to _not_ use rolling updates. Rolling updates will not work, as you cannot have more than one Pod running at a time. The `Recreate` strategy will stop the @@ -175,7 +180,7 @@ specific to stateful apps: Delete the deployed objects by name: -``` +```shell kubectl delete deployment,svc mysql kubectl delete pvc mysql-pv-claim kubectl delete pv mysql-pv-volume @@ -188,20 +193,12 @@ PersistentVolume when it sees that you deleted the PersistentVolumeClaim. Some dynamic provisioners (such as those for EBS and PD) also release the underlying resource upon deleting the PersistentVolume. - - - ## {{% heading "whatsnext" %}} +- Learn more about [Deployment objects](/docs/concepts/workloads/controllers/deployment/). -* Learn more about [Deployment objects](/docs/concepts/workloads/controllers/deployment/). - -* Learn more about [Deploying applications](/docs/tasks/run-application/run-stateless-application-deployment/) - -* [kubectl run documentation](/docs/reference/generated/kubectl/kubectl-commands/#run) - -* [Volumes](/docs/concepts/storage/volumes/) and [Persistent Volumes](/docs/concepts/storage/persistent-volumes/) - - +- Learn more about [Deploying applications](/docs/tasks/run-application/run-stateless-application-deployment/) +- [kubectl run documentation](/docs/reference/generated/kubectl/kubectl-commands/#run) +- [Volumes](/docs/concepts/storage/volumes/) and [Persistent Volumes](/docs/concepts/storage/persistent-volumes/) From 7aae1ad20715a6957fa41bd5a0f313ac4874600a Mon Sep 17 00:00:00 2001 From: Mengjiao Liu Date: Mon, 20 Feb 2023 15:26:33 +0800 Subject: [PATCH 272/279] [zh-cn] Resync kubeadm_init_phase_control-plane_scheduler.md --- .../kubeadm_init_phase_control-plane_scheduler.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/content/zh-cn/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_control-plane_scheduler.md b/content/zh-cn/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_control-plane_scheduler.md index 3b10963776f..da937ae7e2c 100644 --- a/content/zh-cn/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_control-plane_scheduler.md +++ b/content/zh-cn/docs/reference/setup-tools/kubeadm/generated/kubeadm_init_phase_control-plane_scheduler.md @@ -3,7 +3,7 @@ The file is auto-generated from the Go source code of the component using a gene [generator](https://github.com/kubernetes-sigs/reference-docs/). To learn how to generate the reference documentation, please read [Contributing to the reference documentation](/docs/contribute/generate-ref-docs/). -To update the reference conent, please follow the +To update the reference content, please follow the [Contributing upstream](/docs/contribute/generate-ref-docs/contribute-upstream/) guide. You can file document formatting bugs against the [reference-docs](https://github.com/kubernetes-sigs/reference-docs/) project. @@ -96,9 +96,9 @@ kubeadm init phase control-plane scheduler [flags] @@ -132,10 +132,11 @@ kubeadm init phase control-plane scheduler [flags]
    ---image-repository string     默认值:"k8s.gcr.io" +--image-repository string     默认值:"registry.k8s.io"
    - + 包含名为 "target[suffix][+patchtype].extension" 的文件的目录。 例如,"kube-apiserver0+merge.yaml" 或者 "etcd.json"。 -"patchtype" 可以是 "strategic"、"merge" 或 "json" 之一,分别与 kubectl +"target" 可以是 "kube-apiserver"、"kube-controller-manager"、"kube-scheduler"、"etcd"、"kubeletconfiguration" 之一。 +"patchtype" 可以是 "strategic"、"merge"、"json" 之一,分别与 kubectl 所支持的 patch 格式相匹配。默认的 "patchtype" 是 "strategic"。 "extension" 必须是 "json" 或 "yaml"。 "suffix" 是一个可选的字符串,用来确定按字母顺序排序时首先应用哪些 patch。 From f416212db369202351ea11c92dfd0c7108456397 Mon Sep 17 00:00:00 2001 From: windsonsea Date: Mon, 20 Feb 2023 10:02:49 +0800 Subject: [PATCH 273/279] [zh] sync self-subject-review-v1alpha1.md --- .../self-subject-review-v1alpha1.md | 169 ++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 content/zh-cn/docs/reference/kubernetes-api/authorization-resources/self-subject-review-v1alpha1.md diff --git a/content/zh-cn/docs/reference/kubernetes-api/authorization-resources/self-subject-review-v1alpha1.md b/content/zh-cn/docs/reference/kubernetes-api/authorization-resources/self-subject-review-v1alpha1.md new file mode 100644 index 00000000000..ecf6c758650 --- /dev/null +++ b/content/zh-cn/docs/reference/kubernetes-api/authorization-resources/self-subject-review-v1alpha1.md @@ -0,0 +1,169 @@ +--- +api_metadata: + apiVersion: "authentication.k8s.io/v1alpha1" + import: "k8s.io/api/authentication/v1alpha1" + kind: "SelfSubjectReview" +content_type: "api_reference" +description: "SelfSubjectReview 包含 kube-apiserver 所拥有的与发出此请求的用户有关的用户信息。" +title: "SelfSubjectReview v1alpha1" +weight: 5 +--- + + +`apiVersion: authentication.k8s.io/v1alpha1` + +`import "k8s.io/api/authentication/v1alpha1"` + +## SelfSubjectReview {#SelfSubjectReview} + + +SelfSubjectReview 包含 kube-apiserver 所拥有的与发出此请求的用户有关的用户信息。 +使用伪装时,用户将收到被伪装用户的用户信息。 + +
    + +- **apiVersion**: authentication.k8s.io/v1alpha1 + +- **kind**: SelfSubjectReview + +- **metadata** (}}">ObjectMeta) + + + 标准的对象元数据。更多信息: + https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + +- **status** (}}">SelfSubjectReviewStatus) + + + status 由服务器以用户属性进行填充。 + +## SelfSubjectReviewStatus {#SelfSubjectReviewStatus} + + +SelfSubjectReviewStatus 由 kube-apiserver 进行填充并发送回用户。 + +
    + +- **userInfo** (UserInfo) + + + 发出此请求的用户的用户属性。 + + + + userInfo 包含实现 user.Info 接口所需的用户相关信息。 + + - **userInfo.extra** (map[string][]string) + + + + 由身份认证组件提供的所有附加信息。 + + - **userInfo.groups** ([]string) + + + + 此用户所属的用户组的名称。 + + - **userInfo.uid** (string) + + + + 跨时间标识此用户的唯一值。如果此用户被删除且另一个同名用户被添加,他们将具有不同的 UID。 + + - **userInfo.username** (string) + + + + 在所有活跃用户中标识此用户的名称。 + + +## 操作 {#Operations} + +
    + + +### `create` 创建 SelfSubjectReview + +#### HTTP 请求 + +POST /apis/authentication.k8s.io/v1alpha1/selfsubjectreviews + + +#### 参数 + +- **body**: }}">SelfSubjectReview,必需 + +- **dryRun** (**查询参数**): string + + }}">dryRun + +- **fieldManager** (**查询参数**): string + + }}">fieldManager + +- **fieldValidation** (**查询参数**): string + + }}">fieldValidation + +- **pretty** (**查询参数**): string + + }}">pretty + + +#### 响应 + +200 (}}">SelfSubjectReview): OK + +201 (}}">SelfSubjectReview): Created + +202 (}}">SelfSubjectReview): Accepted + +401: Unauthorized From 5c775fc202ae29df4b0ae54fe3701afafe288740 Mon Sep 17 00:00:00 2001 From: Tim Bannister Date: Mon, 20 Feb 2023 11:34:05 +0000 Subject: [PATCH 274/279] Reword further reading Co-authored-by: Shannon Kularathna --- 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 62eff0297c6..a74ac395f94 100644 --- a/content/en/docs/concepts/services-networking/service.md +++ b/content/en/docs/concepts/services-networking/service.md @@ -1191,7 +1191,7 @@ Learn more about Services and how they fit into Kubernetes: * Read about [Gateway](https://gateway-api.sigs.k8s.io/), an extension to Kubernetes that provides more flexibility than Ingress. -For more context, read: +For more context, read the following: * [Virtual IPs and Service Proxies](/docs/reference/networking/virtual-ips/) * [EndpointSlices](/docs/concepts/services-networking/endpoint-slices/) * [Service API reference](/docs/reference/kubernetes-api/service-resources/service-v1/) From 2a77eefafdec52ec9a7e2eea0dd48ead418ecc1f Mon Sep 17 00:00:00 2001 From: Valters Jansons Date: Mon, 20 Feb 2023 20:09:13 +0000 Subject: [PATCH 275/279] Rename "Enabling Unsafe Sysctls" section Section called "Enabling Unsafe Sysctls" sounds dangerous, when trying to tell someone that `net.ipv4.ip_unprivileged_port_start` is considered a _safe_ sysctl in current Kubernetes versions. The overall explanation of safe and unsafe sysctls should be renamed more generic, and later subsection about how to actually enable unsafes can retain the pre-existing section name. --- content/en/docs/tasks/administer-cluster/sysctl-cluster.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/content/en/docs/tasks/administer-cluster/sysctl-cluster.md b/content/en/docs/tasks/administer-cluster/sysctl-cluster.md index a66ca9319b0..390a92ae626 100644 --- a/content/en/docs/tasks/administer-cluster/sysctl-cluster.md +++ b/content/en/docs/tasks/administer-cluster/sysctl-cluster.md @@ -53,9 +53,9 @@ To get a list of all parameters, you can run sudo sysctl -a ``` -## Enabling Unsafe Sysctls +## Safe and Unsafe Sysctls -Sysctls are grouped into _safe_ and _unsafe_ sysctls. In addition to proper +Kubernetes classes sysctls as either _safe_ or _unsafe_. In addition to proper namespacing, a _safe_ sysctl must be properly _isolated_ between pods on the same node. This means that setting a _safe_ sysctl for one pod @@ -80,6 +80,8 @@ The example `net.ipv4.tcp_syncookies` is not namespaced on Linux kernel version This list will be extended in future Kubernetes versions when the kubelet supports better isolation mechanisms. +### Enabling Unsafe Sysctls + All _safe_ sysctls are enabled by default. All _unsafe_ sysctls are disabled by default and must be allowed manually by the From a41c3431b1d118f34e947a80ba2b6a6a75d0a93f Mon Sep 17 00:00:00 2001 From: windsonsea Date: Tue, 21 Feb 2023 09:46:03 +0800 Subject: [PATCH 276/279] [zh] sync ingress-minikube.md --- .../ingress-minikube.md | 292 +++++++++++------- 1 file changed, 176 insertions(+), 116 deletions(-) diff --git a/content/zh-cn/docs/tasks/access-application-cluster/ingress-minikube.md b/content/zh-cn/docs/tasks/access-application-cluster/ingress-minikube.md index e220d760f42..f8daab406ae 100644 --- a/content/zh-cn/docs/tasks/access-application-cluster/ingress-minikube.md +++ b/content/zh-cn/docs/tasks/access-application-cluster/ingress-minikube.md @@ -14,39 +14,51 @@ min-kubernetes-server-version: 1.19 -[Ingress](/zh-cn/docs/concepts/services-networking/ingress/)是一种 API 对象,其中定义了一些规则使得集群中的 -服务可以从集群外访问。 -[Ingress 控制器](/zh-cn/docs/concepts/services-networking/ingress-controllers/) -负责满足 Ingress 中所设置的规则。 - -本节为你展示如何配置一个简单的 Ingress,根据 HTTP URI 将服务请求路由到 -服务 `web` 或 `web2`。 +[Ingress](/zh-cn/docs/concepts/services-networking/ingress/)是一种 API 对象, +其中定义了一些规则使得集群中的服务可以从集群外访问。 +[Ingress 控制器](/zh-cn/docs/concepts/services-networking/ingress-controllers/)负责满足 +Ingress 中所设置的规则。 +本节为你展示如何配置一个简单的 Ingress,根据 HTTP URI 将服务请求路由到服务 `web` 或 `web2`。 ## {{% heading "prerequisites" %}} - {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} + 如果你使用的是较早的 Kubernetes 版本,请切换到该版本的文档。 -### 创建一个 Minikube 集群 +### 创建一个 Minikube 集群 {#create-minikube-cluster} 使用 Katacoda : {{< kat-button >}} 本地 -: 如果已经在本地[安装Minikube](/zh-cn/docs/tasks/tools/#minikube), -请运行 `minikube start` 创建一个集群。 +: 如果已经在本地[安装 Minikube](/zh-cn/docs/tasks/tools/#minikube), + 请运行 `minikube start` 创建一个集群。 + + 2. 检查验证 NGINX Ingress 控制器处于运行状态: - {{< tabs name="tab_with_md" >}} {{% tab name="minikube v1.19 或更高版本" %}} -```shell -kubectl get pods -n ingress-nginx -``` - - {{< note >}}最多可能需要等待一分钟才能看到这些 Pod 运行正常。{{< /note >}} - + ```shell + kubectl get pods -n ingress-nginx + ``` + + {{< note >}} + + 最多可能需要等待一分钟才能看到这些 Pod 运行正常。 + {{< /note >}} + + 输出类似于: -``` -NAME READY STATUS RESTARTS AGE -ingress-nginx-admission-create-g9g49 0/1 Completed 0 11m -ingress-nginx-admission-patch-rqp78 0/1 Completed 1 11m -ingress-nginx-controller-59b45fb494-26npt 1/1 Running 0 11m -``` + ```none + NAME READY STATUS RESTARTS AGE + ingress-nginx-admission-create-g9g49 0/1 Completed 0 11m + ingress-nginx-admission-patch-rqp78 0/1 Completed 1 11m + ingress-nginx-controller-59b45fb494-26npt 1/1 Running 0 11m + ``` + {{% /tab %}} {{% tab name="minikube v1.18.1 或更早版本" %}} -```shell -kubectl get pods -n kube-system -``` - - {{< note >}}最多可能需要等待一分钟才能看到这些 Pod 运行正常。{{< /note >}} - + ```shell + kubectl get pods -n kube-system + ``` + + {{< note >}} + + 最多可能需要等待一分钟才能看到这些 Pod 运行正常。 + {{< /note >}} + + 输出类似于: -``` -NAME READY STATUS RESTARTS AGE -default-http-backend-59868b7dd6-xb8tq 1/1 Running 0 1m -kube-addon-manager-minikube 1/1 Running 0 3m -kube-dns-6dcb57bcc8-n4xd4 3/3 Running 0 2m -kubernetes-dashboard-5498ccf677-b8p5h 1/1 Running 0 2m -nginx-ingress-controller-5984b97644-rnkrg 1/1 Running 0 1m -storage-provisioner 1/1 Running 0 2m -``` + ```none + NAME READY STATUS RESTARTS AGE + default-http-backend-59868b7dd6-xb8tq 1/1 Running 0 1m + kube-addon-manager-minikube 1/1 Running 0 3m + kube-dns-6dcb57bcc8-n4xd4 3/3 Running 0 2m + kubernetes-dashboard-5498ccf677-b8p5h 1/1 Running 0 2m + nginx-ingress-controller-5984b97644-rnkrg 1/1 Running 0 1m + storage-provisioner 1/1 Running 0 2m + ``` 请确保可以在输出中看到一个名称以 `nginx-ingress-controller-` 为前缀的 Pod。 + {{% /tab %}} {{< /tabs >}} @@ -118,7 +146,7 @@ storage-provisioner 1/1 Running 0 2m 1. Create a Deployment using the following command: --> -## 部署一个 Hello World 应用 +## 部署一个 Hello World 应用 {#deploy-hello-world} 1. 使用下面的命令创建一个 Deployment: @@ -126,10 +154,12 @@ storage-provisioner 1/1 Running 0 2m kubectl create deployment web --image=gcr.io/google-samples/hello-app:1.0 ``` - + 输出: - ``` + ```none deployment.apps/web created ``` @@ -142,10 +172,12 @@ storage-provisioner 1/1 Running 0 2m kubectl expose deployment web --type=NodePort --port=8080 ``` - - 输出: + + 输出类似于: - ``` + ```none service/web exposed ``` @@ -158,10 +190,12 @@ storage-provisioner 1/1 Running 0 2m kubectl get service web ``` - + 输出类似于: - ```shell + ```none NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE web NodePort 10.104.133.249 8080:31637/TCP 12m ``` @@ -175,34 +209,40 @@ storage-provisioner 1/1 Running 0 2m minikube service web --url ``` - + 输出类似于: - ```shell + ```none http://172.17.0.15:31637 ``` - {{< note >}} + 如果使用的是 Katacoda 环境,在终端面板顶端,请点击加号标志。 然后点击 **Select port to view on Host 1**。 输入节点和端口号(这里是`31637`),之后点击 **Display Port**。 {{< /note >}} - + 输出类似于: - ```shell + ```none Hello, world! Version: 1.0.0 Hostname: web-55b8c6998d-8k564 ``` 你现在应该可以通过 Minikube 的 IP 地址和节点端口来访问示例应用了。 下一步是让自己能够通过 Ingress 资源来访问应用。 @@ -210,14 +250,15 @@ storage-provisioner 1/1 Running 0 2m ## 创建一个 Ingress -下面是一个定义 Ingress 的配置文件,负责通过 `hello-world.info` 将请求 -转发到你的服务。 +下面是一个定义 Ingress 的配置文件,负责通过 `hello-world.info` +将请求转发到你的服务。 1. 根据下面的 YAML 创建文件 `example-ingress.yaml`: @@ -232,10 +273,12 @@ The following manifest defines an Ingress that sends traffic to your Service via kubectl apply -f https://k8s.io/examples/service/networking/example-ingress.yaml ``` - - 输出: + + 输出类似于: - ``` + ```none ingress.networking.k8s.io/example-ingress created ``` @@ -248,15 +291,19 @@ The following manifest defines an Ingress that sends traffic to your Service via kubectl get ingress ``` - {{< note >}} + 此操作可能需要几分钟时间。 {{< /note >}} - - 接下来你将会在ADDRESS列中看到IPv4地址,例如: + + 接下来你将会在 `ADDRESS` 列中看到 IPv4 地址,例如: - ``` + ```none NAME CLASS HOSTS ADDRESS PORTS AGE example-ingress hello-world.info 172.17.0.15 80 38s ``` @@ -267,22 +314,24 @@ The following manifest defines an Ingress that sends traffic to your Service via --> 4. 在 `/etc/hosts` 文件的末尾添加以下内容(需要管理员访问权限): - - {{< note >}} - 如果你在本地运行 Minikube 环境,需要使用 `minikube ip` 获得外部 IP 地址。 - Ingress 列表中显示的 IP 地址会是内部 IP 地址。 - {{< /note >}} - ``` + ```none 172.17.0.15 hello-world.info ``` + {{< note >}} + + 如果你在本地运行 Minikube 环境,需要使用 `minikube ip` 获得外部 IP 地址。 + Ingress 列表中显示的 IP 地址会是内部 IP 地址。 + {{< /note >}} + - 添加完成后,在浏览器中访问URL `hello-world.info`,请求将被发送到 Minikube。 + 添加完成后,在浏览器中访问 URL `hello-world.info`,请求将被发送到 Minikube。 + 你应该看到类似输出: - ``` + ```none Hello, world! Version: 1.0.0 Hostname: web-55b8c6998d-8k564 ``` - {{< note >}} + 如果你在使用本地 Minikube 环境,你可以从浏览器中访问 hello-world.info。 {{< /note >}} @@ -314,7 +365,7 @@ The following manifest defines an Ingress that sends traffic to your Service via 1. Create another Deployment using the following command: --> -## 创建第二个 Deployment +## 创建第二个 Deployment {#create-second-deployment} 1. 使用下面的命令创建第二个 Deployment: @@ -322,10 +373,12 @@ The following manifest defines an Ingress that sends traffic to your Service via kubectl create deployment web2 --image=gcr.io/google-samples/hello-app:2.0 ``` - - 输出: + + 输出类似于: - ``` + ```none deployment.apps/web2 created ``` @@ -338,10 +391,12 @@ The following manifest defines an Ingress that sends traffic to your Service via kubectl expose deployment web2 --port=8080 --type=NodePort ``` - - 输出: + + 输出类似于: - ``` + ```none service/web2 exposed ``` @@ -355,15 +410,14 @@ The following manifest defines an Ingress that sends traffic to your Service via 1. 编辑现有的 `example-ingress.yaml`,在文件最后添加以下行: - ```yaml - - path: /v2 - pathType: Prefix - backend: - service: - name: web2 - port: - number: 8080 + - path: /v2 + pathType: Prefix + backend: + service: + name: web2 + port: + number: 8080 ``` - 输出: + + 输出类似于: - ``` + ```none ingress.networking/example-ingress configured ``` @@ -387,18 +443,20 @@ The following manifest defines an Ingress that sends traffic to your Service via 1. Access the 1st version of the Hello World app. --> -## 测试你的 Ingress +## 测试你的 Ingress {#test-ingress} -1. 访问 HelloWorld 应用的第一个版本: +1. 访问 Hello World 应用的第一个版本: ```shell curl hello-world.info ``` - + 输出类似于: - ``` + ```none Hello, world! Version: 1.0.0 Hostname: web-55b8c6998d-8k564 @@ -407,27 +465,30 @@ The following manifest defines an Ingress that sends traffic to your Service via -2. 访问 HelloWorld 应用的第二个版本: +2. 访问 Hello World 应用的第二个版本: ```shell curl hello-world.info/v2 ``` - + 输出类似于: - ``` + ```none Hello, world! Version: 2.0.0 Hostname: web2-75cd47646f-t8cjk ``` - {{< note >}} + 如果你在本地运行 Minikube 环境,你可以使用浏览器来访问 - hello-world.info 和 hello-world.info/v2。 + `hello-world.info` 和 `hello-world.info/v2`。 {{< /note >}} ## {{% heading "whatsnext" %}} @@ -437,7 +498,6 @@ The following manifest defines an Ingress that sends traffic to your Service via * Read more about [Ingress Controllers](/docs/concepts/services-networking/ingress-controllers/) * Read more about [Services](/docs/concepts/services-networking/service/) --> - -* 进一步了解 [Ingress](/zh-cn/docs/concepts/services-networking/ingress/)。 +* 进一步了解 [Ingress](/zh-cn/docs/concepts/services-networking/ingress/) * 进一步了解 [Ingress 控制器](/zh-cn/docs/concepts/services-networking/ingress-controllers/) * 进一步了解 [服务](/zh-cn/docs/concepts/services-networking/service/) From 981f21e008e663509d776d6a7e45f0d822e6468e Mon Sep 17 00:00:00 2001 From: Joe Bowbeer Date: Mon, 20 Feb 2023 18:34:53 -0800 Subject: [PATCH 277/279] Update coarse-parallel-processing-work-queue.md Update detailed description to match overview. --- .../en/docs/tasks/job/coarse-parallel-processing-work-queue.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/docs/tasks/job/coarse-parallel-processing-work-queue.md b/content/en/docs/tasks/job/coarse-parallel-processing-work-queue.md index 41d64cdba08..fef005c3bf7 100644 --- a/content/en/docs/tasks/job/coarse-parallel-processing-work-queue.md +++ b/content/en/docs/tasks/job/coarse-parallel-processing-work-queue.md @@ -21,7 +21,7 @@ Here is an overview of the steps in this example: 1. **Create a queue, and fill it with messages.** Each message represents one task to be done. In this example, a message is an integer that we will do a lengthy computation on. 1. **Start a Job that works on tasks from the queue**. The Job starts several pods. Each pod takes - one task from the message queue, processes it, and repeats until the end of the queue is reached. + one task from the message queue, processes it, and exits. ## {{% heading "prerequisites" %}} From 90618e984dc0baf5cc90034b5cdf7e1cd95c4657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulo=20Gon=C3=A7alves=20Lima?= <18203100+PauloGoncalvesLima@users.noreply.github.com> Date: Tue, 21 Feb 2023 10:38:11 -0300 Subject: [PATCH 278/279] Fix: Translation. --- .../docs/tasks/administer-cluster/dns-custom-nameservers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/pt-br/docs/tasks/administer-cluster/dns-custom-nameservers.md b/content/pt-br/docs/tasks/administer-cluster/dns-custom-nameservers.md index ce9822509b9..662654beee6 100644 --- a/content/pt-br/docs/tasks/administer-cluster/dns-custom-nameservers.md +++ b/content/pt-br/docs/tasks/administer-cluster/dns-custom-nameservers.md @@ -23,7 +23,7 @@ Seu cluster deve estar executando o complemento CoreDNS. DNS é um serviço integrado do Kubernetes que é iniciado automaticamente usando o _gerenciador de complementos_ [cluster add-on](http://releases.k8s.io/master/cluster/addons/README.md). {{< note >}} -O service CoreDNS é chamado de `kube-dns` no campo `metadata.name`. +O Service CoreDNS é chamado de `kube-dns` no campo `metadata.name`. O objetivo é garantir maior interoperabilidade com cargas de trabalho que dependiam do nome de serviço legado `kube-dns` para resolver endereços internos ao cluster. Usando o service chamado `kube-dns` abstrai o detalhe de implementação de qual provedor de DNS está sendo executado por trás desse nome comum. {{< /note >}} From daddedcb45d6ae695401d3dcd9b8445bf7da9461 Mon Sep 17 00:00:00 2001 From: Dipesh Rawat Date: Tue, 21 Feb 2023 18:08:24 +0000 Subject: [PATCH 279/279] Fix Introduction to Cilium link --- .../network-policy-provider/cilium-network-policy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/docs/tasks/administer-cluster/network-policy-provider/cilium-network-policy.md b/content/en/docs/tasks/administer-cluster/network-policy-provider/cilium-network-policy.md index ebafa8527ab..af266688d5e 100644 --- a/content/en/docs/tasks/administer-cluster/network-policy-provider/cilium-network-policy.md +++ b/content/en/docs/tasks/administer-cluster/network-policy-provider/cilium-network-policy.md @@ -10,7 +10,7 @@ weight: 30 This page shows how to use Cilium for NetworkPolicy. -For background on Cilium, read the [Introduction to Cilium](https://docs.cilium.io/en/stable/intro). +For background on Cilium, read the [Introduction to Cilium](https://docs.cilium.io/en/stable/overview/intro). ## {{% heading "prerequisites" %}}