Essa é a versão completa de impressão dessa seção Clique aqui para imprimir.

Retornar à visualização normal.

Referência

Esta seção da documentação do Kubernetes contém referências.

Referência da API

Biblioteca de clientes da API

Para chamar a API Kubernetes de uma linguagem de programação, você pode usar bibliotecas de clientes. Bibliotecas oficialmente suportadas:

Referência da CLI

  • kubectl - Ferramenta CLI principal para executar comandos e gerenciar clusters do Kubernetes.
  • kubeadm - Ferramenta CLI para provisionar facilmente um cluster Kubernetes seguro.

Referência de configuração

  • kubelet - O principal agente do nó que é executado em cada nó. O kubelet usa um conjunto de PodSpecs e garante que os contêineres descritos estejam funcionando e saudáveis.
  • kube-apiserver - API REST que valida e configura dados para objetos de API, como pods, serviços, controladores de replicação.
  • kube-controller-manager - Daemon que incorpora os principais loops de controle enviados com o Kubernetes.
  • kube-proxy - É possível fazer o encaminhamento de fluxo TCP/UDP de forma simples ou utilizando o algoritimo de Round Robin encaminhando através de um conjunto de back-ends.
  • kube-scheduler - Agendador que gerencia disponibilidade, desempenho e capacidade.

Documentos de design

Um arquivo dos documentos de design para as funcionalidades do Kubernetes. Bons pontos de partida são Arquitetura Kubernetes e Visão geral do design do Kubernetes.

1 - Glossário

2 - Autenticação

Essa página demonstra uma visão geral sobre autenticação

Usuários no Kubernetes

Todos os clusters Kubernetes possuem duas categorias de usuários: contas de serviço gerenciadas pelo Kubernetes e usuários normais.

Assume-se que um serviço independente do cluster gerencia usuários normais das seguintes formas:

  • Um administrador distribuindo chaves privadas
  • Uma base de usuários como Keystone

    Keystone é o serviço de identidade usado pelo OpenStack para autenticação (authN) e autorização de alto nível (authZ). Atualmente, ele oferece suporte a authN com base em token e autorização de serviço do usuário. Recentemente, foi reprojetado para permitir a expansão para oferecer suporte a serviços externos de proxy e mecanismos AuthN / AuthZ, como oAuth, SAML e openID em versões futuras.

    ou Google Accounts
  • Um arquivo com uma lista de nomes de usuários e senhas

Neste quesito, Kubernetes não possui objetos que possam representar as contas de um usuário normal. Usuários normais não podem ser adicionados ao cluster através de uma chamada para a API.

Apesar de um usuário normal não poder ser adicionado através de uma chamada para a API, qualquer usuário que apresente um certificado válido e assinado pela autoridade de certificados (CA) do cluster é considerado autenticado. Nesta configuração, Kubernetes determina o nome do usuário baseado no campo de nome comum no sujeito (subject) do certificado (por exemplo: "/CN=bob"). A partir daí, o subsistema de controle de acesso baseado em função (RBAC) determina se o usuário é autorizado a realizar uma operação específica sobre o recurso. Para mais detalhes, veja a referência sobre o tópico de usuários normais dentro de requisição de certificado.

Em contraste a usuários normais, contas de serviço são considerados usuários gerenciados pela API do Kubernetes. Elas estão vinculadas à namespaces específicas e criadas automaticamente pelo servidor de API ou manualmente através de chamadas da API. Contas de serviço estão ligadas a um conjunto de credenciais armazenados como Secrets, aos quais são montados dentro dos pods assim permitindo que processos internos ao cluster comuniquem-se com a API do Kubernetes.

Requisições para a API estão ligadas a um usuário normal, conta de serviço ou serão tratadas como requisições anônimas. Isto significa que cada processo dentro ou fora do cluster, desde um usuário humano utilizando o kubectl de uma estação de trabalho, a kubelets rodando nos nós, a membros da camada de gerenciamento (s/painel de controle) devem autenticar-se ao realizarem suas requisições para o servidor API ou serão tratados como usuário anônimo.

Estratégias de autenticação

Kubernetes usa certificados de clientes, bearer Token, um proxy realizando autenticação, ou uma autenticação básica HTTP para autenticar requisições para o servidor de API através de plugins. Como requisições HTTP são feitas no servidor de API, plugins tentam associar os seguintes atributos junto a requisição:

  • Username

    Um nome de usuário é um nome que identifica exclusivamente alguém em um sistema de computador. Por exemplo, um computador pode ser configurado com várias contas, com nomes de usuário diferentes para cada conta. Muitos sites permitem que os usuários escolham um nome de usuário para que possam personalizar suas configurações ou configurar uma conta online. Por exemplo, seu banco pode permitir que você escolha um nome de usuário para acessar suas informações bancárias. Você pode precisar escolher um nome de usuário para postar mensagens em um determinado quadro de mensagens na web. Os serviços de e-mail, como o Hotmail, exigem que os usuários escolham um nome de usuário para usar o serviço.

    Um nome de usuário geralmente é pareado com uma senha. Essa combinação de nome de usuário / senha é conhecida como login e geralmente é necessária para que os usuários façam login em sites. Por exemplo, para acessar seu e-mail pela Web, é necessário inserir seu nome de usuário e senha. Depois de fazer o login, seu nome de usuário pode aparecer na tela, mas sua senha é mantida em segredo. Ao manter sua senha privada, as pessoas podem criar contas seguras para vários sites. A maioria dos nomes de usuário pode conter letras e números, mas não espaços. Quando você escolhe um nome de usuário para uma conta de e-mail, a parte antes de "@" é o seu nome de usuário.

    : um valor (String) que identifica o usuário final. Valores comuns podem ser kube-admin ou [email protected]
  • UID

    Um identificador exclusivo (UID) é uma sequência numérica ou alfanumérica associada a uma única entidade em um determinado sistema. Os UIDs tornam possível endereçar essa entidade para que ela possa ser acessada e interagida. Cada usuário é identificado no sistema por seu UID e os nomes de usuário geralmente são usados apenas como uma interface para humanos.

    : um valor (String) que identifica o usuário final e tenta ser mais consistente e único do que username.
  • Groups: Um conjunto de valores em que cada item indica a associação de um usuário à uma coleção lógica de usuários. Valores comuns podem ser system:masters ou devops-team.
  • Campos extras: um mapa que pode conter uma lista de atributos que armazena informações adicionais em que autorizadores podem achar útil.

Todos os valores são transparentes para o sistema de autenticação e somente trazem significado quando interpretados por um autorizador.

É possível habilitar múltiplos métodos de autenticação. Deve-se normalmente usar pelo menos dois métodos:

  • Tokens para contas de serviço;
  • Pelo menos um outro método de autenticação para usuários.

Quando múltiplos módulos de autenticação estão habilitados, o primeiro módulo a autenticar com sucesso uma requisição termina, o fluxo de avaliação da mesma.

O servidor de API não garante a ordem em que os autenticadores são processados.

O grupo system:authenticated é incluído na lista de grupos de todos os usuários autenticados.

Integrações com outros protocolos de autenticação, como LDAP

Abreviatura para "Lightweight Directory Access Protocol". Se você deseja disponibilizar informações de diretório na Internet, esta é a maneira de fazê-lo. O LDAP é uma versão simplificada de um padrão de diretório anterior denominado X.500. O que torna o LDAP tão útil é que ele funciona muito bem em redes TCP / IP (ao contrário do X.500), de modo que as informações podem ser acessadas por meio do LDAP por qualquer pessoa com uma conexão à Internet. Também é um protocolo aberto, o que significa que os diretórios podem ser armazenados em qualquer tipo de máquina (por exemplo, Windows 2000, Red Hat Linux, Mac OS X).

Para dar uma ideia de como um diretório LDAP é organizado, aqui estão os diferentes níveis de uma hierarquia de árvore LDAP simples:

O diretório raiz Países Organizações Divisões, departamentos, etc. Indivíduos Recursos individuais, como arquivos e impressoras. A maior parte da conectividade LDAP é feita nos bastidores, então o usuário típico provavelmente não notará ao navegar na web. No entanto, é uma boa tecnologia para se conhecer. Se nada mais, é outro termo para impressionar seus pais.

, SAML

SAML significa Linguagem de Marcação para Asserção de Segurança. É um padrão aberto baseado em XML para transferência de dados de identidade entre duas partes: um provedor de identidade (IdP) e um provedor de serviços (SP).

Provedor de identidade - executa autenticação e passa a identidade do usuário e o nível de autorização para o provedor de serviços.

Provedor de serviços - confia no provedor de identidade e autoriza o usuário fornecido a acessar o recurso solicitado.

A autenticação de logon único SAML normalmente envolve um provedor de serviços e um provedor de identidade. O fluxo do processo geralmente envolve os estágios de estabelecimento de confiança e fluxo de autenticação.

Considere este exemplo:

Nosso provedor de identidade é Auth0 Nosso provedor de serviços é um serviço fictício, Zagadat Nota: O provedor de identidade pode ser qualquer plataforma de gerenciamento de identidade.

Agora, um usuário está tentando obter acesso ao Zagadat usando a autenticação SAML.

Este é o fluxo do processo:

O usuário tenta fazer login no Zagadat a partir de um navegador. O Zagadat responde gerando uma solicitação SAML.

, Kerberos

Kerberos é um protocolo de rede que usa criptografia de chave secreta para autenticar aplicativos cliente-servidor. O Kerberos solicita um tíquete criptografado por meio de uma sequência de servidor autenticada para usar os serviços.

Kerberos foi desenvolvido pelo Project Athena - um projeto conjunto entre o Massachusetts Institute of Technology (MIT), Digital Equipment Corporation e IBM que funcionou entre 1983 e 1991.

Um servidor de autenticação usa um tíquete Kerberos para conceder acesso ao servidor e, em seguida, cria uma chave de sessão com base na senha do solicitante e outro valor aleatório. O tíquete de concessão de tíquete (TGT) é enviado ao servidor de concessão de tíquete (TGS), que é necessário para usar o mesmo servidor de autenticação.

O solicitante recebe uma chave TGS criptografada com um registro de data e hora e um tíquete de serviço, que é retornado ao solicitante e descriptografado. O solicitante envia ao TGS essas informações e encaminha a chave criptografada ao servidor para obter o serviço desejado. Se todas as ações forem tratadas corretamente, o servidor aceita o tíquete e realiza o atendimento ao usuário desejado, que deve descriptografar a chave, verificar a data e hora e entrar em contato com o centro de distribuição para obter as chaves de sessão. Essa chave de sessão é enviada ao solicitante, que descriptografa o tíquete.

Se as chaves e o carimbo de data / hora forem válidos, a comunicação cliente-servidor continuará. O tíquete TGS tem carimbo de data / hora, o que permite solicitações simultâneas dentro do período de tempo alocado.

, alternate x509 schemes

X.509 é um formato padrão para certificados de chave pública, documentos digitais que associam com segurança pares de chaves criptográficas a identidades como sites, indivíduos ou organizações.

Introduzido pela primeira vez em 1988 junto com os padrões X.500 para serviços de diretório eletrônico, o X.509 foi adaptado para uso na Internet pelo grupo de trabalho Public-Key Infrastructure (X.509) (PKIX) da IETF. O RFC 5280 define o perfil do certificado X.509 v3, a lista de revogação de certificado X.509 v2 (CRL) e descreve um algoritmo para a validação do caminho do certificado X.509.

As aplicações comuns de certificados X.509 incluem:

- SSL / TLS e HTTPS para navegação na web autenticada e criptografada
- E-mail assinado e criptografado por meio do protocolo S / MIME
- Assinatura de código
- Assinatura de documento
- Autenticação de cliente
- Identificação eletrônica emitida pelo governo
, etc, podem ser alcançadas utilizando-se de um proxy ou webhook de autenticação.

Certificados de cliente X509

Autenticação via certificados de cliente pode ser habilitada ao passar a opção --client-ca-file=ARQUIVO para o servidor de API. O arquivo referenciado deve conter um ou mais autoridades de certificação usadas para validar o certificado de cliente passado para o servidor de API. Se o certificado de cliente é apresentado e verificado, o common name

O nome comum é normalmente composto de Host + Nome de domínio e será semelhante a www.seusite.com ou seusite.com. Os certificados de servidor SSL são específicos para o nome comum para o qual foram emitidos no nível do host.

O nome comum deve ser igual ao endereço da Web que você acessará ao se conectar a um site seguro. Por exemplo, um certificado de servidor SSL para o domínio domínio.com receberá um aviso do navegador se o acesso a um site chamado www.domain.com ou secure.domain.com, pois www.domain.com e secure.domain.com são diferentes de dominio.com. Você precisaria criar um CSR para o nome comum correto.

do sujeito é usado como o nome de usuário para a requisição. A partir da versão 1.4, certificados de cliente podem também indicar o pertencimento de um usuário a um grupo utilizando o campo de organização do certificado. Para incluir múltiplos grupos para o usuário, deve-se incluir múltiplos campos de organização no certificado.

Por exemplo, utilizando o comando de linha openssl para gerar uma requisição de assinatura de certificado:

openssl req -new -key jbeda.pem -out jbeda-csr.pem -subj "/CN=jbeda/O=app1/O=app2"

Isto criaria um arquivo de tipo CSR (requisição de assinatura de certificado) para o usuário "jbeda" pertencendo a dois grupos: "app1" e "app2".

Veja como gerar um certificado de cliente em Gerenciando Certificados

Arquivo estático de Token

O servidor de API lê bearer tokens de um arquivo quando recebe uma requisição contendo a opção --token-auth-file=ARQUIVO via linha de comando. Atualmente, tokens têm duração indefinida, e a lista de tokens não pode ser modificada sem reiniciar o servidor de API.

O arquivo de token é do tipo CSV contendo no mínimo 3 colunas: token, nome de usuário, identificador de usuário (uid), seguido pelos nomes de grupos (opcional).

Adicionando um bearer token em uma requisição

Quando utilizando-se de bearer token para autenticação de um cliente HTTP, o servidor de API espera um cabeçalho Authorization com um valor Bearer TOKEN. O token deve ser uma sequência de caracteres que pode ser colocada como valor em um cabeçalho HTTP não utilizando-se mais do que as facilidades de codificação e citação de HTTP. Por exemplo, se o valor de um token é 31ada4fd-adec-460c-809a-9e56ceb75269 então iria aparecer dentro de um cabeçalho HTTP como:

Authorization: Bearer 31ada4fd-adec-460c-809a-9e56ceb75269

Tokens de inicialização

FEATURE STATE: Kubernetes v1.18 [stable]

Para permitir a inicialização simplificada para novos clusters, Kubernetes inclui um token dinamicamente gerenciado denominado Bootstrap Token. Estes tokens são armazenados como Secrets dentro do namespace kube-system, onde eles podem ser dinamicamente criados e gerenciados. O componente Gerenciador de Controle (Controller Manager) possui um controlador "TokenCleaner" que apaga os tokens de inicialização expirados.

Os tokens seguem o formato [a-z0-9]{6}.[a-z0-9]{16}. O primeiro componente é um identificador do token e o segundo é o segredo. Você pode especificar o token como um cabeçalho HTTP como:

Authorization: Bearer 781292.db7bc3a58fc5f07e

Deve-se habilitar os tokens de inicialização com a opção --enable-bootstrap-token-auth no servidor de API. Deve-se habilitar o controlador TokenCleaner através da opção --controllers no Gerenciador de Controle. Isso é feito, por exemplo, como: --controllers=*,tokencleaner. O kubeadm, por exemplo, irá realizar isso caso seja utilizado para a inicialização do cluster.

O autenticador o autentica como system:bootstrap:<Token ID> e é incluído no grupo system:bootstrappers. O nome e grupo são intencionalmente limitados para desencorajar usuários a usarem estes tokens após inicialização. Os nomes de usuários e grupos podem ser utilizados (e são utilizados pelo kubeadm) para elaborar as políticas de autorização para suportar a inicialização de um cluster.

Por favor veja Bootstrap Tokens para documentação detalhada sobre o autenticador e controladores de Token de inicialização, bem como gerenciar estes tokens com kubeadm.

Tokens de Contas de serviço

Uma conta de serviço é um autenticador habilitado automaticamente que usa bearer tokens para verificar as requisições. O plugin aceita dois parâmetros opcionais:

  • --service-account-key-file Um arquivo contendo uma chave codificada no formato PEM para assinar bearer tokens. Se não especificado, a chave privada de TLS no servidor de API será utilizada
  • --service-account-lookup Se habilitado, tokens deletados do servidor de API serão revogados.

Contas de serviço são normalmente criadas automaticamente pelo servidor de API e associada a pods rodando no cluster através do controlador de admissão Admission Controller de ServiceAccount. Os tokens de contas de serviços são montados nos Pods, em localizações já pré definidas e conhecidas e permitem processos dentro do cluster a se comunicarem com o servidor de API. Contas podem ser explicitamente associadas com pods utilizando o campo serviceAccountName na especificação do pod (PodSpec):

apiVersion: apps/v1 
kind: Deployment
metadata:
 name: nginx-deployment
 namespace: default
spec:
 replicas: 3
 template:
   metadata:
   # ...
   spec:
     serviceAccountName: bob-the-bot
     containers:
     - name: nginx
       image: nginx:1.14.2

Os tokens de contas de serviço são perfeitamente válidos para ser usados fora do cluster e podem ser utilizados para criar identidades para processos de longa duração que desejem comunicar-se com a API do Kubernetes. Para criar manualmente uma conta de serviço, utilize-se simplesmente o comando kubectl create serviceaccount (NOME). Isso cria uma conta de serviço e um segredo associado a ela no namespace atual.

kubectl create serviceaccount jenkins
serviceaccount "jenkins" created

Verificando um segredo associado:

kubectl get serviceaccounts jenkins -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
 # ...
secrets:
- name: jenkins-token-1yvwg

O segredo criado irá armazenar a autoridade de certificado do servidor de API e um JSON Web Token (JWT) digitalmente assinado.

kubectl get secret jenkins-token-1yvwg -o yaml
apiVersion: v1
data:
 ca.crt: (APISERVER'S CA BASE64 ENCODED)
 namespace: ZGVmYXVsdA==
 token: (BEARER TOKEN BASE64 ENCODED)
kind: Secret
metadata:
 # ...
type: kubernetes.io/service-account-token

O JWT assinado pode ser usado como um bearer token para autenticar-se como a conta de serviço. Veja acima como o token pode ser incluído em uma requisição. Normalmente esses segredos são montados no pod para um acesso interno ao cluster ao servidor de API, porém pode ser utilizado fora do cluster também.

Contas de serviço são autenticadas com o nome de usuário system:serviceaccount:(NAMESPACE):(SERVICEACCOUNT) e são atribuídas aos grupos system:serviceaccounts e system:serviceaccounts:(NAMESPACE).

AVISO: porque os tokens das contas de serviço são armazenados em segredos, qualquer usuário com acesso de leitura a esses segredos podem autenticar-se como a conta de serviço. Tome cuidado quando conceder permissões a contas de serviços e capacidade de leitura de segredos.

Tokens OpenID Connect

OpenID Connect é uma variação do framework de autorização OAuth2 que suporta provedores como Azure Active Directory, Salesforce, e Google. A principal extensão do OAuth2 é um campo adicional de token de acesso chamado ID Token. Este token é um tipo de JSON Web Token (JWT) com campos bem definidos, como usuário, e-mail e é assinado pelo servidor de autorização.

Para identificar o usuário, o autenticador usa o id_token (e não access_token) do bearer token da resposta de autorização do OAuth2 token response. Veja acima como incluir um token em uma requisição.

sequenceDiagram participant usuário as Usuário participant IDP as Provedor
de Identidade participant kube as Kubectl participant API as API Server usuário ->> IDP: 1. Realizar Login no IdP activate IDP IDP -->> usuário: 2. Fornece access_token,
id_token, e refresh_token deactivate IDP activate usuário usuário ->> kube: 3. Entrar Kubectl
com --token sendo id_token
ou adiciona tokens no arquivo .kube/config deactivate usuário activate kube kube ->> API: 4. Emite requisição incluindo o cabeçalho HTTP Authorization: Bearer... deactivate kube activate API API ->> API: 5. O token do tipo JWT possui assinatura válida ? API ->> API: 6. O token está expirado ? (iat+exp) API ->> API: 7. Usuário autorizado ? API -->> kube: 8. Autorizado: Realiza
ação e retorna resultado deactivate API activate kube kube --x usuário: 9. Retorna resultado deactivate kube
  1. Login no seu provedor de identidade.
  2. Seu provedor de identidade ira fornecer um access_token, id_token e um refresh_token.
  3. Quando utilizando kubectl, utilize do seu id_token com a opção --token ou adicione o token diretamente no seu arquivo de configuração kubeconfig.
  4. kubectl envia o seu id_token em um cabeçalho HTTP chamado Authorization para o servidor de API.
  5. O servidor de API irá garantir que a assinatura do token JWT é válida, verificando-o em relação ao certificado mencionado na configuração.
  6. Verificação para garantir que oid_token não esteja expirado.
  7. Garantir que o usuário é autorizado.
  8. Uma vez autorizado o servidor de API retorna a resposta para o kubectl.
  9. kubectl fornece retorno ao usuário.

Uma vez que todos os dados necessários para determinar sua identidade encontram-se no id_token, Kubernetes não precisa realizar outra chamada para o provedor de identidade. Em um modelo onde cada requisição não possui estado, isso fornece uma solução escalável para autenticação. Isso, porem, apresenta alguns desafios:

  1. Kubernetes não possui uma "interface web" para disparar o processo de autenticação. Não há browser ou interface para coletar credenciais que são necessárias para autenticar-se primeiro no seu provedor de identidade.
  2. O id_token não pode ser revogado, funcionando como um certificado, portanto deve possuir curta validade (somente alguns minutos) o que pode tornar a experiência um pouco desconfortável, fazendo com que se requisite um novo token toda vez em um curto intervalo (poucos minutos de validade do token)
  3. Para autenticar-se ao dashboard Kubernetes, você deve executar o comando kubectl proxy ou um proxy reverso que consiga injetar o id_token.

Configurando o Servidor de API

Para habilitar o plugin de autorização, configure as seguintes opções no servidor de API:

Parâmetro Descrição Exemplo Obrigatório
--oidc-issuer-url URL do provedor que permite ao servidor de API descobrir chaves públicas de assinatura. Somente URLs que usam o esquema https:// são aceitas. Isto normalmente é o endereço de descoberta do provedor sem o caminho, por exemplo "https://accounts.google.com" ou "https://login.salesforce.com". Esta URL deve apontar para o nível abaixo do caminho .well-known/openid-configuration Se o valor da URL de descoberta é https://accounts.google.com/.well-known/openid-configuration, entao o valor deve ser https://accounts.google.com Sim
--oidc-client-id Identificador do cliente para o qual todos os tokens são gerados. kubernetes Sim
--oidc-username-claim Atributo do JWT a ser usado como nome de usuário. Por padrão o valor sub, o qual é esperado que seja um identificador único do usuário final. Administradores podem escolher outro atributo, como email ou name, dependendo de seu provedor de identidade. No entanto, outros atributos além de email serão prefixados com a URL do emissor issuer URL para prevenir conflitos de nome com outros plugins. sub Não
--oidc-username-prefix Prefixos adicionados ao atributo de nome de usuário para prevenir conflitos de nomes existentes (como por exemplo usuários system:). Por exemplo, o valor oidc: irá criar usuários como oidc:jane.doe. Se esta opção não for fornecida --oidc-username-claim e um valor diferente de email irá conter um prefixo padrão com o valor de ( Issuer URL )# onde ( Issuer URL ) era o valor da opção --oidc-issuer-url. O valor - pode ser utilizado para desabilitar todos os prefixos. oidc: Não
--oidc-groups-claim Atributo do JWT a ser utilizado para mapear os grupos dos usuários. Se o atributo está presente, ele deve ser do tipo vetor de Strings. groups Não
--oidc-groups-prefix Prefixo adicionados ao atributo de grupo para prevenir conflitos de nomes existentes (como por exemplo system: grupos). Por exemplo, o valor oidc: irá criar nomes de grupos como oidc:engineering e oidc:infra. oidc: Não
--oidc-required-claim Um par de chave=valor que descreve atributos obrigatórios no ID Token. Se configurado, a presença do atributo é verificado dentro do ID Token com um valor relacionado. Repita esta opção para configurar múltiplos atributos obrigatórios. claim=value Não
--oidc-ca-file O caminho para o arquivo de certificado da autoridade de certificados (CA) que assinou o certificado do provedor de identidades. /etc/kubernetes/ssl/kc-ca.pem Não

É importante ressaltar que o servidor de API não é um cliente Oauth2, ao contrário, ele só pode ser configurado para confiar em um emissor. Isso permite o uso de emissores públicos, como Google, sem confiar em credenciais emitidas por terceiros. Administradores que desejam utilizar-se de múltiplos clientes OAuth2 devem explorar provedores os quais suportam atributos azp (parte autorizada), que é um mecanismo para permitir um cliente a emitir tokens em nome de outro.

Kubernetes não oferece um provedor de identidade OpenID Connect. Pode-se utilizar provedores públicos existentes como Google ou outros. Ou, pode-se rodar o próprio provedor de identidade no cluster, como dex, Keycloak, CloudFoundry UAA, ou Tremolo Security's OpenUnison.

Para um provedor de identidades funcionar no Kubernetes, ele deve:

  1. Suportar o framework OpenID connect discovery; Nem todos suportam.
  2. Executar TLS com cifras criptográficas não obsoletos.
  3. Possuir certificados assinados por uma Autoridade certificadora (mesmo que o CA não seja comercial ou seja auto-assinado)

Uma nota sobre o requisito #3 acima. Se você instalar o seu próprio provedor de identidades (ao invés de utilizar um provedor como Google ou Microsoft) você DEVE ter o certificado web do seu provedor de identidades assinado por um certificado contendo a opção CA configurada para TRUE, mesmo que seja um certificado auto assinado. Isso deve-se a implementação do cliente TLS em Golang que é bastante restrito quanto aos padrões em torno da validação de certificados. Se você não possui um CA em fácil alcance, você pode usar este script criado pelo time Dex para criar um simples CA, um par de chaves e certificado assinados. Ou você pode usar este script similar o qual gera certificados SHA256 com uma vida mais longa e tamanho maior de chave.

Instruções de configuração para sistemas específicos podem ser encontrados em:

Utilizando kubectl

Opção 1 - Autenticador OIDC

A primeira opção é utilizar-se do autenticador oidc do kubectl, o qual define o valor do id_token como um bearer token para todas as requisições e irá atualizar o token quando o mesmo expirar. Após você efetuar o login no seu provedor, utilize o kubectl para adicionar os seus id_token, refresh_token, client_id, e client_secret para configurar o plugin.

Provedores os quais não retornem um id_token como parte da sua resposta de refresh token não são suportados por este plugin e devem utilizar a opção 2 abaixo.

kubectl config set-credentials USER_NAME \
  --auth-provider=oidc \
  --auth-provider-arg=idp-issuer-url=( issuer url ) \
  --auth-provider-arg=client-id=( your client id ) \
  --auth-provider-arg=client-secret=( your client secret ) \
  --auth-provider-arg=refresh-token=( your refresh token ) \
  --auth-provider-arg=idp-certificate-authority=( path to your ca certificate ) \
  --auth-provider-arg=id-token=( your id_token )

Um exemplo, executando o comando abaixo após autenticar-se no seu provedor de identidades:

kubectl config set-credentials mmosley  \
       --auth-provider=oidc  \
       --auth-provider-arg=idp-issuer-url=https://oidcidp.tremolo.lan:8443/auth/idp/OidcIdP  \
       --auth-provider-arg=client-id=kubernetes  \
       --auth-provider-arg=client-secret=1db158f6-177d-4d9c-8a8b-d36869918ec5  \
       --auth-provider-arg=refresh-token=q1bKLFOyUiosTfawzA93TzZIDzH2TNa2SMm0zEiPKTUwME6BkEo6Sql5yUWVBSWpKUGphaWpxSVAfekBOZbBhaEW+VlFUeVRGcluyVF5JT4+haZmPsluFoFu5XkpXk5BXqHega4GAXlF+ma+vmYpFcHe5eZR+slBFpZKtQA= \
       --auth-provider-arg=idp-certificate-authority=/root/ca.pem \
       --auth-provider-arg=id-token=eyJraWQiOiJDTj1vaWRjaWRwLnRyZW1vbG8ubGFuLCBPVT1EZW1vLCBPPVRybWVvbG8gU2VjdXJpdHksIEw9QXJsaW5ndG9uLCBTVD1WaXJnaW5pYSwgQz1VUy1DTj1rdWJlLWNhLTEyMDIxNDc5MjEwMzYwNzMyMTUyIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJodHRwczovL29pZGNpZHAudHJlbW9sby5sYW46ODQ0My9hdXRoL2lkcC9PaWRjSWRQIiwiYXVkIjoia3ViZXJuZXRlcyIsImV4cCI6MTQ4MzU0OTUxMSwianRpIjoiMm96US15TXdFcHV4WDlHZUhQdy1hZyIsImlhdCI6MTQ4MzU0OTQ1MSwibmJmIjoxNDgzNTQ5MzMxLCJzdWIiOiI0YWViMzdiYS1iNjQ1LTQ4ZmQtYWIzMC0xYTAxZWU0MWUyMTgifQ.w6p4J_6qQ1HzTG9nrEOrubxIMb9K5hzcMPxc9IxPx2K4xO9l-oFiUw93daH3m5pluP6K7eOE6txBuRVfEcpJSwlelsOsW8gb8VJcnzMS9EnZpeA0tW_p-mnkFc3VcfyXuhe5R3G7aa5d8uHv70yJ9Y3-UhjiN9EhpMdfPAoEB9fYKKkJRzF7utTTIPGrSaSU6d2pcpfYKaxIwePzEkT4DfcQthoZdy9ucNvvLoi1DIC-UocFD8HLs8LYKEqSxQvOcvnThbObJ9af71EwmuE21fO5KzMW20KtAeget1gnldOosPtz1G5EwvaQ401-RPQzPGMVBld0_zMCAwZttJ4knw

O qual irá produzir a configuração abaixo:

users:
- name: mmosley
 user:
   auth-provider:
     config:
       client-id: kubernetes
       client-secret: 1db158f6-177d-4d9c-8a8b-d36869918ec5
       id-token: eyJraWQiOiJDTj1vaWRjaWRwLnRyZW1vbG8ubGFuLCBPVT1EZW1vLCBPPVRybWVvbG8gU2VjdXJpdHksIEw9QXJsaW5ndG9uLCBTVD1WaXJnaW5pYSwgQz1VUy1DTj1rdWJlLWNhLTEyMDIxNDc5MjEwMzYwNzMyMTUyIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJodHRwczovL29pZGNpZHAudHJlbW9sby5sYW46ODQ0My9hdXRoL2lkcC9PaWRjSWRQIiwiYXVkIjoia3ViZXJuZXRlcyIsImV4cCI6MTQ4MzU0OTUxMSwianRpIjoiMm96US15TXdFcHV4WDlHZUhQdy1hZyIsImlhdCI6MTQ4MzU0OTQ1MSwibmJmIjoxNDgzNTQ5MzMxLCJzdWIiOiI0YWViMzdiYS1iNjQ1LTQ4ZmQtYWIzMC0xYTAxZWU0MWUyMTgifQ.w6p4J_6qQ1HzTG9nrEOrubxIMb9K5hzcMPxc9IxPx2K4xO9l-oFiUw93daH3m5pluP6K7eOE6txBuRVfEcpJSwlelsOsW8gb8VJcnzMS9EnZpeA0tW_p-mnkFc3VcfyXuhe5R3G7aa5d8uHv70yJ9Y3-UhjiN9EhpMdfPAoEB9fYKKkJRzF7utTTIPGrSaSU6d2pcpfYKaxIwePzEkT4DfcQthoZdy9ucNvvLoi1DIC-UocFD8HLs8LYKEqSxQvOcvnThbObJ9af71EwmuE21fO5KzMW20KtAeget1gnldOosPtz1G5EwvaQ401-RPQzPGMVBld0_zMCAwZttJ4knw
       idp-certificate-authority: /root/ca.pem
       idp-issuer-url: https://oidcidp.tremolo.lan:8443/auth/idp/OidcIdP
       refresh-token: q1bKLFOyUiosTfawzA93TzZIDzH2TNa2SMm0zEiPKTUwME6BkEo6Sql5yUWVBSWpKUGphaWpxSVAfekBOZbBhaEW+VlFUeVRGcluyVF5JT4+haZmPsluFoFu5XkpXk5BXq
     name: oidc

Uma vez que seu id_token expire, kubectl irá tentar atualizar o seu id_token utilizando-se do seu refresh_token e client_secret armazenando os novos valores para refresh_token e id_token no seu arquivo de configuração .kube/config.

Opção 2 - Utilize a opção --token

O comando kubectl o permite passar o valor de um token utilizando a opção --token. Copie e cole o valor do seu id_token nesta opção:

kubectl --token=eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwczovL21sYi50cmVtb2xvLmxhbjo4MDQzL2F1dGgvaWRwL29pZGMiLCJhdWQiOiJrdWJlcm5ldGVzIiwiZXhwIjoxNDc0NTk2NjY5LCJqdGkiOiI2RDUzNXoxUEpFNjJOR3QxaWVyYm9RIiwiaWF0IjoxNDc0NTk2MzY5LCJuYmYiOjE0NzQ1OTYyNDksInN1YiI6Im13aW5kdSIsInVzZXJfcm9sZSI6WyJ1c2VycyIsIm5ldy1uYW1lc3BhY2Utdmlld2VyIl0sImVtYWlsIjoibXdpbmR1QG5vbW9yZWplZGkuY29tIn0.f2As579n9VNoaKzoF-dOQGmXkFKf1FMyNV0-va_B63jn-_n9LGSCca_6IVMP8pO-Zb4KvRqGyTP0r3HkHxYy5c81AnIh8ijarruczl-TK_yF5akjSTHFZD-0gRzlevBDiH8Q79NAr-ky0P4iIXS8lY9Vnjch5MF74Zx0c3alKJHJUnnpjIACByfF2SCaYzbWFMUNat-K1PaUk5-ujMBG7yYnr95xD-63n8CO8teGUAAEMx6zRjzfhnhbzX-ajwZLGwGUBT4WqjMs70-6a7_8gZmLZb2az1cZynkFRj2BaCkVT3A2RrjeEwZEtGXlMqKJ1_I2ulrOVsYx01_yD35-rw get nodes

Token de autenticação via Webhook

Webhook de autenticação é usado para verificar bearer tokens

  • --authentication-token-webhook-config-file arquivo de configuração descrevendo como acessar o serviço remoto de webhook.
  • --authentication-token-webhook-cache-ttl por quanto tempo guardar em cache decisões de autenticação. Configuração padrão definida para dois minutos.
  • --authentication-token-webhook-version determina quando usar o apiVersion authentication.k8s.io/v1beta1 ou authentication.k8s.io/v1 para objetos TokenReview quando enviar/receber informações do webhook. Valor padrão v1beta1.

O arquivo de configuração usa o formato de arquivo do kubeconfig. Dentro do arquivo, clusters refere-se ao serviço remoto e users refere-se ao servidor de API do webhook. Um exemplo seria:

# versão da API do Kubernetes
apiVersion: v1
# tipo do objeto da API
kind: Config
# clusters refere-se ao serviço remoto
clusters:
 - name: name-of-remote-authn-service
   cluster:
     certificate-authority: /path/to/ca.pem         # CA para verificar o serviço remoto
     server: https://authn.example.com/authenticate # URL para procurar o serviço remoto. Deve utilizar 'https'.
 
# users refere-se a configuração do webhook do servidor de  API
users:
 - name: name-of-api-server
   user:
     client-certificate: /path/to/cert.pem # certificado para ser utilizado pelo plugin de webhook
     client-key: /path/to/key.pem          # chave referente ao certificado
 
# arquivos kubeconfig requerem um contexto. Especifique um para o servidor de API.
current-context: webhook
contexts:
- context:
   cluster: name-of-remote-authn-service
   user: name-of-api-server
 name: webhook

Quando um cliente tenta autenticar-se com o servidor de API utilizando um bearer token como discutido acima, o webhook de autenticação envia um objeto JSON serializado do tipo TokenReview contendo o valor do token para o serviço remoto.

Note que objetos de API do tipo webhook estão sujeitos às mesmas regras de compatibilidade de versão como outros objetos de API Kubernetes. Implementadores devem verificar o campo de versão da API (apiVersion) da requisição para garantir a correta deserialização e devem responder com um objeto do tipo TokenReview da mesma versão da requisição.

{
 "apiVersion": "authentication.k8s.io/v1",
 "kind": "TokenReview",
 "spec": {
   # Bearer token opaco enviado para o servidor de API
   "token": "014fbff9a07c...",
 
   # Lista opcional de identificadores de audiência para o servidor ao qual o token foi apresentado
   # Autenticadores de token  sensíveis a audiência (por exemplo, autenticadores de token OIDC)
   # deve-se verificar que o token foi direcionado a pelo menos um membro da lista de audiência
   # e retornar a interseção desta lista a audiência válida para o token no estado da resposta
   # Isto garante com que o token é válido para autenticar-se no servidor ao qual foi apresentado
   # Se nenhuma audiência for especificada, o token deve ser validado para autenticar-se ao servidor de API do Kubernetes
   "audiences": ["https://myserver.example.com", "https://myserver.internal.example.com"]
 }
}

{
 "apiVersion": "authentication.k8s.io/v1beta1",
 "kind": "TokenReview",
 "spec": {
   # Bearer token opaco enviado para o servidor de API
   "token": "014fbff9a07c...",
 
   # Lista opcional de identificadores de audiência para o servidor ao qual o token foi apresentado
   # Autenticadores de token  sensíveis a audiência (por exemplo, autenticadores de token OIDC)
   # deve-se verificar que o token foi direcionado a pelo menos um membro da lista de audiência
   # e retornar a interseção desta lista a audiência válida para o token no estado da resposta
   # Isto garante com que o token é válido para autenticar-se no servidor ao qual foi apresentado
   # Se nenhuma audiência for especificada, o token deve ser validado para autenticar-se ao servidor de API do Kubernetes
   "audiences": ["https://myserver.example.com", "https://myserver.internal.example.com"]
 }
}

É esperado que o serviço remoto preencha o campo status da requisição para indicar o sucesso do login. O campo spec do corpo de resposta é ignorado e pode ser omitido. O serviço remoto deverá retornar uma resposta usando a mesma versão de API do objeto TokenReview que foi recebido. Uma validação bem sucedida deveria retornar:

{
 "apiVersion": "authentication.k8s.io/v1",
 "kind": "TokenReview",
 "status": {
   "authenticated": true,
   "user": {
     # Obrigatório
     "username": "[email protected]",
     # Opcional
     "uid": "42",
     # Opcional: lista de grupos associados
     "groups": ["developers", "qa"],
     # Opcional: informação adicional  provida pelo autenticador.
     # Isto não deve conter dados confidenciais, pois pode ser registrados em logs ou em objetos de API e estarão disponíveis para webhooks de admissão
     "extra": {
       "extrafield1": [
         "extravalue1",
         "extravalue2"
       ]
     }
   },
   # Lista opcional de Autenticadores de token  sensíveis a audiência que podem ser retornados,
   # contendo as audiências da lista `spec.audiences` válido para o token apresentado.
   # Se este campo for omitido, o token é considerado válido para autenticar-se no servidor de API Kubernetes
   "audiences": ["https://myserver.example.com"]
 }
}

{
 "apiVersion": "authentication.k8s.io/v1beta1",
 "kind": "TokenReview",
 "status": {
   "authenticated": true,
   "user": {
     # Obrigatório
     "username": "[email protected]",
     # Opcional
     "uid": "42",
     # Opcional: lista de grupos associados
     "groups": ["developers", "qa"],
     # Opcional: informação adicional  provida pelo autenticador.
     # Isto não deve conter dados confidenciais, pois pode ser registrados em logs ou em objetos de API e estarão disponíveis para webhooks de admissão
     "extra": {
       "extrafield1": [
         "extravalue1",
         "extravalue2"
       ]
     }
   },
   # Lista opcional de Autenticadores de token  sensíveis a audiência que podem ser retornados,
   # contendo as audiências da lista `spec.audiences` válido para o token apresentado.
   # Se este campo for omitido, o token é considerado válido para autenticar-se no servidor de API Kubernetes
   "audiences": ["https://myserver.example.com"]
 }
}

Uma requisição mal sucedida retornaria:

{
 "apiVersion": "authentication.k8s.io/v1",
 "kind": "TokenReview",
 "status": {
   "authenticated": false,
   # Opcionalmente inclui detalhes sobre o porque a autenticação falhou
   # Se nenhum erro é fornecido, a API irá retornar uma mensagem genérica de "Não autorizado"
   # O campo de erro é ignorado quando authenticated=true.
   "error": "Credenciais expiradas"
 }
}

{
 "apiVersion": "authentication.k8s.io/v1beta1",
 "kind": "TokenReview",
 "status": {
   "authenticated": false,
   # Opcionalmente inclui detalhes sobre o porque a autenticação falhou
   # Se nenhum erro é fornecido, a API irá retornar uma mensagem genérica de "Não autorizado"
   # O campo de erro é ignorado quando authenticated=true.
   "error": "Credenciais expiradas"
 }
}

Autenticando com Proxy

O servidor de API pode ser configurado para identificar usuários através de valores de cabeçalho de requisição, como por exemplo X-Remote-User. Isto é projetado para o uso em combinação com um proxy de autenticação, o qual irá atribuir o valor do cabeçalho da requisição.

  • --requestheader-username-headers Obrigatório, não faz distinção entre caracteres maiúsculos/minúsculos. Nomes de cabeçalhos a serem verificados, em ordem, para a identidade do usuário. O primeiro cabeçalho contendo um valor será usado para o nome do usuário.

  • --requestheader-group-headers 1.6+. Opcional, não faz distinção entre caracteres maiúsculos/minúsculos. "X-Remote-Group" é recomendado. Nomes de cabeçalhos a serem verificados, em ordem, para os grupos do usuário. Todos os valores especificados em todos os cabeçalhos serão utilizados como nome dos grupos do usuário.

  • --requestheader-extra-headers-prefix 1.6+. Opcional, não faz distinção entre caracteres maiúsculos/minúsculos. "X-Remote-Extra-" é recomendado. Prefixos de cabeçalhos para serem utilizados para definir informações extras sobre o usuário (normalmente utilizado por um plugin de autorização). Todos os cabeçalhos que começam com qualquer um dos prefixos especificados têm o prefixo removido. O restante do nome do cabeçalho é transformado em letra minúscula, decodificado percent-decoded e torna-se uma chave extra, e o valor do cabeçalho torna-se um valor extra.

Por exemplo, com esta configuração:

--requestheader-username-headers=X-Remote-User
--requestheader-group-headers=X-Remote-Group
--requestheader-extra-headers-prefix=X-Remote-Extra-

e esta requisição:

GET / HTTP/1.1
X-Remote-User: fido
X-Remote-Group: dogs
X-Remote-Group: dachshunds
X-Remote-Extra-Acme.com%2Fproject: some-project
X-Remote-Extra-Scopes: openid
X-Remote-Extra-Scopes: profile

resultaria nesta informação de usuário:

name: fido
groups:
- dogs
- dachshunds
extra:
 acme.com/project:
 - some-project
 scopes:
 - openid
 - profile

Para prevenir falsificação de cabeçalhos, o proxy de autenticação deverá apresentar um certificado de cliente válido para o servidor de API para que possa ser validado com a autoridade de certificados (CA) antes que os cabeçalhos de requisições sejam verificados. AVISO: não re-utilize uma autoridade de certificados (CA) que esteja sendo utilizado em um contexto diferente ao menos que você entenda os riscos e os mecanismos de proteção da utilização de uma autoridade de certificados.

  • --requestheader-client-ca-file Obrigatório. Pacote de certificados no formato PEM. Um certificado válido deve ser apresentado e validado com a autoridade de certificados no arquivo especificado antes da verificação de cabeçalhos de requisição para os nomes do usuário.

  • --requestheader-allowed-names Opcional. Lista de valores de nomes comuns (CNs). Se especificado, um certificado de cliente válido contendo uma lista de nomes comuns denominados deve ser apresentado na verificação de cabeçalhos de requisição para os nomes do usuário. Se vazio, qualquer valor de nomes comuns será permitido.

Requisições anônimas

Quando habilitado, requisições que não são rejeitadas por outros métodos de autenticação configurados são tratadas como requisições anônimas e são dadas o nome de usuário system:anonymous e filiação ao grupo system:unauthenticated.

Por exemplo, uma requisição especificando um bearer token invalido chega a um servidor com token de autenticação configurado e acesso anônimo habilitado e receberia um erro de acesso não autorizado 401 Unauthorized. Já uma requisição não especificando nenhum bearer token seria tratada como uma requisição anônima.

Nas versões 1.5.1-1.5.x, acesso anônimo é desabilitado por padrão e pode ser habilitado passando a opção --anonymous-auth=true durante a inicialização do servidor de API.

Na versão 1.6 e acima, acesso anônimo é habilitado por padrão se um modo de autorização diferente de AlwaysAllow é utilizado e pode ser desabilitado passando a opção --anonymous-auth=false durante a inicialização do servidor de API. Começando na versão 1.6, os autorizadores ABAC (Controle de Acesso Baseado em Atributos) e RBAC (Controle de Acesso Baseado em Função) requerem autorização explícita do usuário system:anonymous e do grupo system:unauthenticated, portanto, regras de políticas legadas que permitam acesso a usuário * e grupo * nao incluíram usuários anônimos.

Personificação de usuário

Um usuário pode agir como outro através de cabeçalhos de personificação. Os mesmos permitem que requisições manualmente sobrescrevam as informações ao quais o usuário irá se autenticar como. Por exemplo, um administrador pode utilizar-se desta funcionalidade para investigar um problema com uma política de autorização e assim, temporariamente, personificar um outro usuário e ver se/como sua requisição está sendo negada.

Requisições de personificação primeiramente são autenticadas como o usuário requerente, então trocando para os detalhes de informação do usuário personificado.

O fluxo é:

  • Um usuário faz uma chamada de API com suas credenciais e cabeçalhos de personificação.
  • O servidor de API autentica o usuário.
  • O servidor de API garante que o usuário autenticado possui permissão de personificação.
  • Detalhes de informação do usuário da requisição tem seus valores substituídos com os detalhes de personificação.
  • A requisição é avaliada e a autorização é feita sobre os detalhes do usuário personificado.

Os seguintes cabeçalhos HTTP podem ser usados para realizar uma requisição de personificação:

  • Impersonate-User: O nome do usuário para se executar ações em seu nome.
  • Impersonate-Group: Um nome de grupo para se executar ações em seu nome. Pode ser especificado múltiplas vezes para fornecer múltiplos grupos. Opcional. Requer "Impersonate-User".
  • Impersonate-Extra-( extra name ): Um cabeçalho dinâmico usado para associar campos extras do usuário. Opcional. Requer "Impersonate-User". Para que seja preservado consistentemente, ( extra name ) deve ser somente minúsculo, e qualquer caracter que não seja legal em rótulos de cabeçalhos HTTP DEVE ser utf8 e codificado.

Um exemplo de conjunto de cabeçalhos HTTP:

Impersonate-User: [email protected]
Impersonate-Group: developers
Impersonate-Group: admins
Impersonate-Extra-dn: cn=jane,ou=engineers,dc=example,dc=com
Impersonate-Extra-acme.com%2Fproject: some-project
Impersonate-Extra-scopes: view
Impersonate-Extra-scopes: development

Quando utilizando-se o kubectl especifique a opção --as para determinar o cabeçalho Impersonate-User, especifique a opção --as-group para determinar o cabeçalho Impersonate-Group.

kubectl drain mynode
Error from server (Forbidden): User "clark" cannot get nodes at the cluster scope. (get nodes mynode)

Especificando as opções --as e --as-group:

kubectl drain mynode --as=superman --as-group=system:masters
node/mynode cordoned
node/mynode drained

Para personificar um usuário, grupo ou especificar campos extras, o usuário efetuando a personificação deve possuir a permissão de executar o verbo "impersonate" no tipo de atributo sendo personificado ("user", "group", etc.). Para clusters com o plugin de autorização RBAC habilitados, a seguinte ClusterRole abrange as regras necessárias para definir os cabeçalhos de personificação de usuário e grupo:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
 name: impersonator
rules:
- apiGroups: [""]
 resources: ["users", "groups", "serviceaccounts"]
 verbs: ["impersonate"]

Campos extras são avaliados como sub-recursos de um recurso denominado "userextras". Para permitir ao usuário que utilize os cabeçalhos de personificação para o campo extra "scopes", o usuário deve receber a seguinte permissão:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
 name: scopes-impersonator
rules:
# Pode definir o cabeçalho "Impersonate-Extra-scopes".
- apiGroups: ["authentication.k8s.io"]
 resources: ["userextras/scopes"]
 verbs: ["impersonate"]

Os valores dos cabeçalhos de personificação podem também ser restringidos ao limitar o conjunto de nomes de recursos (resourceNames) que um recurso pode ter.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
 name: limited-impersonator
rules:
# Pode personificar o usuário "[email protected]"
- apiGroups: [""]
 resources: ["users"]
 verbs: ["impersonate"]
 resourceNames: ["[email protected]"]
 
# Pode assumir os grupos "developers" and "admins"
- apiGroups: [""]
 resources: ["groups"]
 verbs: ["impersonate"]
 resourceNames: ["developers","admins"]
 
# Pode personificar os campos extras "scopes" com valores "view" e "development"
- apiGroups: ["authentication.k8s.io"]
 resources: ["userextras/scopes"]
 verbs: ["impersonate"]
 resourceNames: ["view", "development"]

Plugins de credenciais client-go

FEATURE STATE: Kubernetes v1.11 [beta]

Ferramentas como kubectl e kubelet utilizando-se do k8s.io/client-go são capazes de executar um comando externo para receber credenciais de usuário.

Esta funcionalidade é direcionada à integração do lado cliente, com protocolos de autenticação não suportados nativamente pelo k8s.io/client-go como: LDAP, Kerberos, OAuth2, SAML, etc. O plugin implementa a lógica específica do protocolo e então retorna credenciais opacas para serem utilizadas. Quase todos os casos de usos de plugins de credenciais requerem um componente de lado do servidor com suporte para um autenticador de token webhook para interpretar o formato das credenciais produzidas pelo plugin cliente.

Exemplo de caso de uso

Num caso de uso hipotético, uma organização executaria um serviço externo que efetuaria a troca de credenciais LDAP por tokens assinados para um usuário específico. Este serviço seria também capaz de responder requisições do autenticador de token webhook para validar tokens. Usuários seriam obrigados a instalar um plugin de credencial em sua estação de trabalho.

Para autenticar na API:

  • O usuário entra um comando kubectl.
  • O plugin de credencial solicita ao usuário a entrada de credenciais LDAP e efetua troca das credenciais por um token via um serviço externo.
  • O plugin de credenciais retorna um token para o client-go, o qual o utiliza como um bearer token no servidor de API.
  • O servidor de API usa o autenticador de token webhook para submeter um objeto TokenReview para o serviço externo.
  • O serviço externo verifica a assinatura do token e retorna o nome e grupos do usuário.

Configuração

plugins de credencial são configurados através de arquivos de configuração do kubectl como parte dos campos de usuário.

apiVersion: v1
kind: Config
users:
- name: my-user
 user:
   exec:
     # Comando a ser executado. Obrigatório.
     command: "example-client-go-exec-plugin"
 
     # Versão da API a ser utilizada quando decodificar o recurso  ExecCredentials. Obrigatório
     #
     # A versão da API retornada pelo plugin DEVE ser a mesma versão listada aqui.
     #
     # Para integrar com ferramentas que suportem múltiplas versões (tal como client.authentication.k8s.io/v1alpha1),
     # defina uma variável de ambiente ou passe um argumento para a ferramenta que indique qual versão o plugin de execução deve esperar.
     apiVersion: "client.authentication.k8s.io/v1beta1"
 
     # Variáveis de ambiente a serem configuradas ao executar o plugin. Opcional
     env:
     - name: "FOO"
       value: "bar"
 
     # Argumentos a serem passados ao executar o plugin. Opcional
     args:
     - "arg1"
     - "arg2"
 
     # Texto exibido para o usuário quando o executável não parece estar presente. Opcional
     installHint: |
              example-client-go-exec-plugin é necessário para autenticar no cluster atual. Pode ser instalado via:
 
       Em macOS: brew install example-client-go-exec-plugin
 
       Em Ubuntu: apt-get install example-client-go-exec-plugin
 
       Em Fedora: dnf install example-client-go-exec-plugin
 
       ...
 
     # Deve-se ou não fornecer informações do cluster, que podem potencialmente conter grande quantidade de dados do CA,
     # para esse plugin de execução como parte da variável de ambiente KUBERNETES_EXEC_INFO
     provideClusterInfo: true
clusters:
- name: my-cluster
 cluster:
   server: "https://172.17.4.100:6443"
   certificate-authority: "/etc/kubernetes/ca.pem"
   extensions:
   - name: client.authentication.k8s.io/exec # nome de extensão reservado para configuração exclusiva do cluster
     extension:
       arbitrary: config
       this: pode ser fornecido através da variável de ambiente KUBERNETES_EXEC_INFO na configuracao de provideClusterInfo
       you: ["coloque", "qualquer", "coisa", "aqui"]
contexts:
- name: my-cluster
 context:
   cluster: my-cluster
   user: my-user
current-context: my-cluster

Os caminhos relativos do comando são interpretados como relativo ao diretório do arquivo de configuração. Se KUBECONFIG está configurado para o caminho /home/jane/kubeconfig e o comando executado é ./bin/example-client-go-exec-plugin, o binario /home/jane/bin/example-client-go-exec-plugin será executado.

- name: my-user
 user:
   exec:
     # Caminho relativo para o diretorio do kubeconfig
     command: "./bin/example-client-go-exec-plugin"
     apiVersion: "client.authentication.k8s.io/v1beta1"

Formatos de entrada e saída

O comando executado imprime um objeto ExecCredential para o stdout. k8s.io/client-go autentica na API do Kubernetes utilizando as credenciais retornadas no status.

Quando executando uma sessão interativa, stdin é exposto diretamente para o plugin. plugins devem utilizar um TTY check para determinar se é apropriado solicitar um usuário interativamente.

Para usar credenciais do tipo bearer token, o plugin retorna um token no status do objeto ExecCredential.

{
 "apiVersion": "client.authentication.k8s.io/v1beta1",
 "kind": "ExecCredential",
 "status": {
   "token": "my-bearer-token"
 }
}

Alternativamente, um certificado de cliente e chave codificados em PEM podem ser retornados para serem utilizados em autenticação de cliente TLS. Se o plugin retornar um certificado e chave diferentes numa chamada subsequente, k8s.io/client-go Irá fechar conexões existentes com o servidor para forçar uma nova troca TLS.

Se especificado, clientKeyData e clientCertificateData devem ambos estar presentes.

clientCertificateData pode conter certificados intermediários adicionais a serem enviados para o servidor.

{
 "apiVersion": "client.authentication.k8s.io/v1beta1",
 "kind": "ExecCredential",
 "status": {
   "clientCertificateData": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
   "clientKeyData": "-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----"
 }
}

Opcionalmente, a resposta pode incluir a validade da credencial em formato RFC3339 de data/hora. A presença ou ausência de validade pode ter o seguinte impacto:

  • Se uma validade está incluída, o bearer token e as credenciais TLS são guardadas em cache até a o tempo de expiração é atingido ou se o servidor responder com um codigo de status HTTP 401 ou se o processo terminar.

  • Se uma validate está ausente, o bearer token e as credenciais TLS são guardadas em cache até o servidor responder com um código de status HTTP 401 ou até o processo terminar.

{
 "apiVersion": "client.authentication.k8s.io/v1beta1",
 "kind": "ExecCredential",
 "status": {
   "token": "my-bearer-token",
   "expirationTimestamp": "2018-03-05T17:30:20-08:00"
 }
}

Para habilitar o plugin de execução para obter informações específicas do cluster, define provideClusterInfo no campo user.exec dentro do arquivo de configuração kubeconfig. O plugin irá então prover a variável de ambiente KUBERNETES_EXEC_INFO. As informações desta variável de ambiente podem ser utilizadas para executar lógicas de aquisição de credentiais específicas do cluster. O manifesto ExecCredential abaixo descreve um exemplo de informação de cluster.

{
 "apiVersion": "client.authentication.k8s.io/v1beta1",
 "kind": "ExecCredential",
 "spec": {
   "cluster": {
     "server": "https://172.17.4.100:6443",
     "certificate-authority-data": "LS0t...",
     "config": {
       "arbitrary": "config",
       "this": "pode ser fornecido por meio da variável de ambiente KUBERNETES_EXEC_INFO na configuração de provideClusterInfo",
       "you": ["coloque", "qualquer", "coisa", "aqui"]
     }
   }
 }
}

3 - Autenticando com Tokens de Inicialização

FEATURE STATE: Kubernetes v1.18 [stable]

Os tokens de inicialização são um bearer token simples que devem ser utilizados ao criar novos clusters ou para quando novos nós são registrados a clusters existentes. Eles foram construídos para suportar a ferramenta kubeadm, mas podem ser utilizados em outros contextos para usuários que desejam inicializar clusters sem utilizar o kubeadm. Foram também construídos para funcionar, via políticas RBAC, com o sistema de Inicialização do Kubelet via TLS.

Visão geral dos tokens de inicialização

Os tokens de inicialização são definidos com um tipo especifico de secrets (bootstrap.kubernetes.io/token) que existem no namespace kube-system. Estes secrets são então lidos pelo autenticador de inicialização do servidor de API. Tokens expirados são removidos pelo controlador TokenCleaner no gerenciador de controle - kube-controller-manager. Os tokens também são utilizados para criar uma assinatura para um ConfigMap específico usado no processo de descoberta através de um controlador denominado BootstrapSigner.

Formato do Token

Tokens de inicialização tem o formato abcdef.0123456789abcdef. Mais formalmente, eles devem corresponder a expressão regular [a-z0-9]{6}\.[a-z0-9]{16}.

A primeira parte do token é um identificador ("Token ID") e é considerado informação pública. Ele é utilizado para se referir a um token sem vazar a parte secreta usada para autenticação. A segunda parte é o secret do token e somente deve ser compartilhado com partes confiáveis.

Habilitando autenticação com tokens de inicialização

O autenticador de tokens de inicialização pode ser habilitado utilizando a seguinte opção no servidor de API:

--enable-bootstrap-token-auth

Quando habilitado, tokens de inicialização podem ser utilizado como credenciais bearer token para autenticar requisições no servidor de API.

Authorization: Bearer 07401b.f395accd246ae52d

Tokens são autenticados como o usuário system:bootstrap:<token id> e são membros do grupo system:bootstrappers. Grupos adicionais podem ser especificados dentro do secret do token.

Tokens expirados podem ser removidos automaticamente ao habilitar o controlador tokencleaner do gerenciador de controle - kube-controller-manager.

--controllers=*,tokencleaner

Formato do secret dos tokens de inicialização

Cada token válido possui um secret no namespace kube-system. Você pode encontrar a documentação completa aqui.

Um secret de token se parece com o exemplo abaixo:

apiVersion: v1
kind: Secret
metadata:
 # Nome DEVE seguir o formato "bootstrap-token-<token id>"
 name: bootstrap-token-07401b
 namespace: kube-system
 
# Tipo DEVE ser 'bootstrap.kubernetes.io/token'
type: bootstrap.kubernetes.io/token
stringData:
 # Descrição legível. Opcional.
 description: "The default bootstrap token generated by 'kubeadm init'."
 
 # identificador do token e _secret_. Obrigatório.
 token-id: 07401b
 token-secret: f395accd246ae52d
 
 # Validade. Opcional.
 expiration: 2017-03-10T03:22:11Z
 
 # Usos permitidos.
 usage-bootstrap-authentication: "true"
 usage-bootstrap-signing: "true"
 
 # Grupos adicionais para autenticar o token. Devem começar com "system:bootstrappers:"
 auth-extra-groups: system:bootstrappers:worker,system:bootstrappers:ingress

O tipo do secret deve ser bootstrap.kubernetes.io/token e o nome deve seguir o formato bootstrap-token-<token id>. Ele também tem que existir no namespace kube-system.

Os membros listados em usage-bootstrap-* indicam qual a intenção de uso deste secret. O valor true deve ser definido para que seja ativado.

  • usage-bootstrap-authentication indica que o token pode ser utilizado para autenticar no servidor de API como um bearer token.
  • usage-bootstrap-signing indica que o token pode ser utilizado para assinar o ConfigMap cluster-info como descrito abaixo.

O campo expiration controla a expiração do token. Tokens expirados são rejeitados quando usados para autenticação e ignorados durante assinatura de ConfigMaps. O valor de expiração é codificado como um tempo absoluto UTC utilizando a RFC3339. Para automaticamente remover tokens expirados basta habilitar o controlador tokencleaner.

Gerenciamento de tokens com kubeadm

Você pode usar a ferramenta kubeadm para gerenciar tokens em um cluster. Veja documentação de tokens kubeadm para mais detalhes.

Assinatura de ConfigMap

Além de autenticação, os tokens podem ser utilizados para assinar um ConfigMap. Isto pode ser utilizado em estágio inicial do processo de inicialização de um cluster, antes que o cliente confie no servidor de API. O Configmap assinado pode ser autenticado por um token compartilhado.

Habilite a assinatura de ConfigMap ao habilitar o controlador bootstrapsigner no gerenciador de controle - kube-controller-manager.

--controllers=*,bootstrapsigner

O ConfigMap assinado é o cluster-info no namespace kube-public. No fluxo típico, um cliente lê o ConfigMap enquanto ainda não autenticado e ignora os erros da camada de transporte seguro (TLS). Ele então valida o conteúdo do ConfigMap ao verificar a assinatura contida no ConfigMap.

O ConfigMap pode se parecer com o exemplo abaixo:

apiVersion: v1
kind: ConfigMap
metadata:
 name: cluster-info
 namespace: kube-public
data:
 jws-kubeconfig-07401b: eyJhbGciOiJIUzI1NiIsImtpZCI6IjA3NDAxYiJ9..tYEfbo6zDNo40MQE07aZcQX2m3EB2rO3NuXtxVMYm9U
 kubeconfig: |
   apiVersion: v1
   clusters:
   - cluster:
       certificate-authority-data: <really long certificate data>
       server: https://10.138.0.2:6443
     name: ""
   contexts: []
   current-context: ""
   kind: Config
   preferences: {}
   users: []   

O membro kubeconfig do ConfigMap é um arquivo de configuração contendo somente as informações do cluster preenchidas. A informação chave sendo comunicada aqui está em certificate-authority-data. Isto poderá ser expandido no futuro.

A assinatura é feita utilizando-se assinatura JWS em modo "separado". Para validar a assinatura, o usuário deve codificar o conteúdo do kubeconfig de acordo com as regras do JWS (codificando em base64 e descartando qualquer = ao final). O conteúdo codificado e então usado para formar um JWS inteiro, inserindo-o entre os 2 pontos. Você pode verificar o JWS utilizando o esquema HS256 (HMAC-SHA256) com o token completo (por exemplo: 07401b.f395accd246ae52d) como o secret compartilhado. Usuários devem verificar que o algoritmo HS256 (que é um método de assinatura simétrica) está sendo utilizado.

Consulte a seção de detalhes de implementação do kubeadm para mais informações.

4 - Portas e protocolos

Quando o Kubernetes está sendo executado em um ambiente com uma rede mais restritiva, como por exemplo um data center on-premises com firewalls de rede físicos ou redes virtuais em nuvens públicas, é útil saber quais portas e protocolos são utilizados pelos componentes do Kubernetes.

Camada de gerenciamento

Protocolo Direção Intervalo de Portas Propósito Utilizado por
TCP Entrada 6443 Servidor da API do Kubernetes Todos
TCP Entrada 2379-2380 API servidor-cliente do etcd kube-apiserver, etcd
TCP Entrada 10250 API do kubelet kubeadm, Camada de gerenciamento
TCP Entrada 10259 kube-scheduler kubeadm
TCP Entrada 10257 kube-controller-manager kubeadm

Embora as portas do etcd estejam inclusas na seção da Camada de gerenciamento, você também pode hospedar o seu próprio cluster etcd externamente ou em portas customizadas.

Nós de processamento

Protocolo Direção Intervalo de Portas Propósito Utilizado por
TCP Entrada 10250 API do Kubelet O próprio, Camada de gerenciamento
TCP Entrada 30000-32767 Serviços NodePort† Todos

† Intervalo padrão de portas para os serviços NodePort.

Todas as portas padrão podem ser sobrescritas. Quando portas customizadas são utilizadas, essas portas precisam estar abertas, ao invés das mencionadas aqui.

Um exemplo comum é a porta do servidor da API, que as vezes é trocado para a porta 433. Com isso, a porta padrão é mantida e o servidor da API é colocado atrás de um balanceador de carga que escuta na porta 433 e faz o roteamento das requisições para o servidor da API na porta padrão.

5 - kubectl CLI

5.1 - kubectl Cheat Sheet

Veja também: Visão geral do Kubectl e JsonPath Guide.

Esta página é uma visão geral do comando kubectl.

kubectl - Cheat Sheet

Kubectl Autocomplete

BASH

source <(kubectl completion bash) # configuração de autocomplete no bash do shell atual, o pacote bash-completion precisa ter sido instalado primeiro.
echo "source <(kubectl completion bash)" >> ~/.bashrc # para adicionar o autocomplete permanentemente no seu shell bash.

Você também pode usar uma abreviação para o atalho para kubectl que também funciona com o auto completar:

alias k=kubectl
complete -F __start_kubectl k

ZSH

source <(kubectl completion zsh)  # configuração para usar autocomplete no terminal zsh no shell atual
echo "if [ $commands[kubectl] ]; then source <(kubectl completion zsh); fi" >> ~/.zshrc # adicionar auto completar permanentemente para o seu shell zsh

Contexto e Configuração do Kubectl

Defina com qual cluster Kubernetes o kubectl se comunica e modifique os detalhes da configuração. Veja a documentação Autenticando entre clusters com o kubeconfig para informações detalhadas do arquivo de configuração.

kubectl config view # Mostrar configurações do kubeconfig mergeadas.

# use vários arquivos kubeconfig ao mesmo tempo e visualize a configuração mergeada
KUBECONFIG=~/.kube/config:~/.kube/kubconfig2 

kubectl config view

# obtenha a senha para o usuário e2e
kubectl config view -o jsonpath='{.users[?(@.name == "e2e")].user.password}'

kubectl config view -o jsonpath='{.users[].name}'    # exibir o primeiro usuário
kubectl config view -o jsonpath='{.users[*].name}'   # obtenha uma lista de usuários
kubectl config get-contexts                          # exibir lista de contextos
kubectl config current-context                       # exibir o contexto atual
kubectl config use-context my-cluster-name           # defina o contexto padrão como my-cluster-name

# adicione um novo cluster ao seu kubeconfig que suporte autenticação básica
kubectl config set-credentials kubeuser/foo.kubernetes.com --username=kubeuser --password=kubepassword

# salve o namespace permanentemente para todos os comandos subsequentes do kubectl nesse contexto.
kubectl config set-context --current --namespace=ggckad-s2

# defina um contexto utilizando um nome de usuário e o namespace.
kubectl config set-context gce --user=cluster-admin --namespace=foo \
  && kubectl config use-context gce
 
kubectl config unset users.foo                       # excluir usuário foo

Aplicar

apply gerencia aplicações através de arquivos que definem os recursos do Kubernetes. Ele cria e atualiza recursos em um cluster através da execução kubectl apply. Esta é a maneira recomendada de gerenciar aplicações Kubernetes em ambiente de produção. Veja a documentação do Kubectl.

Criando objetos

Manifestos Kubernetes podem ser definidos em YAML ou JSON. A extensão de arquivo .yaml, .yml, e .json pode ser usado.

kubectl apply -f ./my-manifest.yaml            # criar recurso(s)
kubectl apply -f ./my1.yaml -f ./my2.yaml      # criar a partir de vários arquivos
kubectl apply -f ./dir                         # criar recurso(s) em todos os arquivos de manifesto no diretório
kubectl apply -f https://git.io/vPieo          # criar recurso(s) a partir de URL
kubectl create deployment nginx --image=nginx  # iniciar uma única instância do nginx
kubectl explain pods,svc                       # obtenha a documentação de manifesto do pod

# Crie vários objetos YAML a partir de stdin
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: busybox-sleep
spec:
  containers:
  - name: busybox
    image: busybox
    args:
    - sleep
    - "1000000"
---
apiVersion: v1
kind: Pod
metadata:
  name: busybox-sleep-less
spec:
  containers:
  - name: busybox
    image: busybox
    args:
    - sleep
    - "1000"
EOF

# Crie um segredo com várias chaves
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  password: $(echo -n "s33msi4" | base64 -w0)
  username: $(echo -n "jane" | base64 -w0)
EOF

Visualizando e Localizando Recursos

# Obter comandos com saída simples
kubectl get services                          # Listar todos os serviços do namespace
kubectl get pods --all-namespaces             # Listar todos os pods em todos namespaces
kubectl get pods -o wide                      # Listar todos os pods no namespace atual, com mais detalhes
kubectl get deployment my-dep                 # Listar um deployment específico
kubectl get pods                              # Listar todos os pods no namespace
kubectl get pod my-pod -o yaml                # Obter o YAML de um pod

# Descrever comandos com saída detalhada
kubectl describe nodes my-node
kubectl describe pods my-pod

# Listar serviços classificados por nome
kubectl get services --sort-by=.metadata.name

# Listar pods classificados por contagem de reinicializações
kubectl get pods --sort-by='.status.containerStatuses[0].restartCount'

# Listar PersistentVolumes classificado por capacidade
kubectl get pv --sort-by=.spec.capacity.storage

# Obtenha a versão da label de todos os pods com a label app=cassandra
kubectl get pods --selector=app=cassandra -o \
  jsonpath='{.items[*].metadata.labels.version}'

# Obter todos os nós workers (use um seletor para excluir resultados que possuem uma label
# nomeado 'node-role.kubernetes.io/master')
kubectl get node --selector='!node-role.kubernetes.io/master'

# Obter todos os pods em execução no namespace
kubectl get pods --field-selector=status.phase=Running

# Obter ExternalIPs de todos os nós
kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="ExternalIP")].address}'

# Listar nomes de pods pertencentes a um RC particular 
# O comando "jq" é útil para transformações que são muito complexas para jsonpath, pode ser encontrado em https://stedolan.github.io/jq/
sel=${$(kubectl get rc my-rc --output=json | jq -j '.spec.selector | to_entries | .[] | "\(.key)=\(.value),"')%?}
echo $(kubectl get pods --selector=$sel --output=jsonpath={.items..metadata.name})

# Mostrar marcadores para todos os pods(ou qualquer outro objeto Kubernetes que suporte rotulagem)
kubectl get pods --show-labels

# Verifique quais nós estão prontos
JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}' \
 && kubectl get nodes -o jsonpath="$JSONPATH" | grep "Ready=True"

# Listar todos os segredos atualmente em uso por um pod
kubectl get pods -o json | jq '.items[].spec.containers[].env[]?.valueFrom.secretKeyRef.name' | grep -v null | sort | uniq

# Listar todos os containerIDs de initContainer de todos os pods
# Útil ao limpar contêineres parados, evitando a remoção de initContainers.
kubectl get pods --all-namespaces -o jsonpath='{range .items[*].status.initContainerStatuses[*]}{.containerID}{"\n"}{end}' | cut -d/ -f3

# Listar eventos classificados por timestamp
kubectl get events --sort-by=.metadata.creationTimestamp

# Compara o estado atual do cluster com o estado em que o cluster estaria se o manifesto fosse aplicado.
kubectl diff -f ./my-manifest.yaml

Atualizando Recursos

A partir da versão 1.11 rolling-update foi descontinuado (veja CHANGELOG-1.11.md), utilize o comando rollout no lugar deste.

kubectl set image deployment/frontend www=image:v2               # Aplica o rollout nos containers "www" do deployment "frontend", atualizando a imagem
kubectl rollout history deployment/frontend                      # Verifica o histórico do deployment, incluindo a revisão
kubectl rollout undo deployment/frontend                         # Rollback para o deployment anterior
kubectl rollout undo deployment/frontend --to-revision=2         # Rollback para uma revisão específica
kubectl rollout status -w deployment/frontend                    # Acompanhe o status de atualização do "frontend" até sua conclusão sem interrupção 
kubectl rollout restart deployment/frontend                      # Reinício contínuo do deployment "frontend"


# versão inicial descontinuada 1.11
kubectl rolling-update frontend-v1 -f frontend-v2.json           # (descontinuada) Atualização contínua dos pods de frontend-v1
kubectl rolling-update frontend-v1 frontend-v2 --image=image:v2  # (descontinuada) Altera o nome do recurso e atualiza a imagem
kubectl rolling-update frontend --image=image:v2                 # (descontinuada) Atualize a imagem dos pods do frontend
kubectl rolling-update frontend-v1 frontend-v2 --rollback        # (descontinuada) Interromper o lançamento existente em andamento

cat pod.json | kubectl replace -f -                              # Substitua um pod com base no JSON passado para std

# Força a substituição, exclui e recria o recurso. Causará uma interrupção do serviço.
kubectl replace --force -f ./pod.json

# Crie um serviço para um nginx replicado, que serve na porta 80 e se conecta aos contêineres na porta 8000
kubectl expose rc nginx --port=80 --target-port=8000

# Atualizar a versão da imagem (tag) de um pod de contêiner único para a v4
kubectl get pod mypod -o yaml | sed 's/\(image: myimage\):.*$/\1:v4/' | kubectl replace -f -

kubectl label pods my-pod new-label=awesome                      # Adicionar uma label
kubectl annotate pods my-pod icon-url=http://goo.gl/XXBTWq       # Adicionar uma anotação
kubectl autoscale deployment foo --min=2 --max=10                # Escalar automaticamente um deployment "foo"

Recursos de Correção

# Atualizar parcialmente um nó
kubectl patch node k8s-node-1 -p '{"spec":{"unschedulable":true}}'

# Atualizar a imagem de um contêiner; spec.containers[*].name é obrigatório porque é uma chave de mesclagem
kubectl patch pod valid-pod -p '{"spec":{"containers":[{"name":"kubernetes-serve-hostname","image":"new image"}]}}'

# Atualizar a imagem de um contêiner usando um patch json com matrizes posicionais
kubectl patch pod valid-pod --type='json' -p='[{"op": "replace", "path": "/spec/containers/0/image", "value":"new image"}]'

# Desative um livenessProbe de deployment usando um patch json com matrizes posicionais
kubectl patch deployment valid-deployment  --type json   -p='[{"op": "remove", "path": "/spec/template/spec/containers/0/livenessProbe"}]'

# Adicionar um novo elemento a uma matriz posicional
kubectl patch sa default --type='json' -p='[{"op": "add", "path": "/secrets/1", "value": {"name": "whatever" } }]'

Editando Recursos

Edite qualquer recurso da API no seu editor preferido.

kubectl edit svc/docker-registry                      # Edite o serviço chamado docker-registry
KUBE_EDITOR="nano" kubectl edit svc/docker-registry   # Use um editor alternativo

Escalando Recursos

kubectl scale --replicas=3 rs/foo                                 # Escale um replicaset chamado 'foo' para 3
kubectl scale --replicas=3 -f foo.yaml                            # Escale um recurso especificado em "foo.yaml" para 3
kubectl scale --current-replicas=2 --replicas=3 deployment/mysql  # Se o tamanho atual do deployment chamado mysql for dois, assim escale para 3
kubectl scale --replicas=5 rc/foo rc/bar rc/baz                   # Escalar vários replicaset

Exclusão de Recursos

kubectl delete -f ./pod.json                                              # Exclua um pod usando o tipo e o nome especificados em pod.json
kubectl delete pod,service baz foo                                        # Excluir pods e serviços com os mesmos nomes "baz" e "foo"
kubectl delete pods,services -l name=myLabel                              # Excluir pods e serviços com o nome da label = myLabel
kubectl -n my-ns delete pod,svc --all                                     # Exclua todos os pods e serviços no namespace my-ns,
# Excluir todos os pods que correspondem ao awk pattern1 ou pattern2
kubectl get pods  -n mynamespace --no-headers=true | awk '/pattern1|pattern2/{print $1}' | xargs  kubectl delete -n mynamespace pod

Interagindo com Pods em execução

kubectl logs my-pod                                 # despejar logs de pod (stdout)
kubectl logs -l name=myLabel                        # despejar logs de pod, com a label de name=myLabel (stdout)
kubectl logs my-pod --previous                      # despejar logs de pod (stdout) para a instância anterior de um contêiner
kubectl logs my-pod -c my-container                 # despejar logs de um específico contêiner em um pod (stdout, no caso de vários contêineres)
kubectl logs -l name=myLabel -c my-container        # despejar logs de pod, com nome da label = myLabel (stdout)
kubectl logs my-pod -c my-container --previous      # despejar logs de um contêiner específico em um pod (stdout, no caso de vários contêineres) para uma instanciação anterior de um contêiner
kubectl logs -f my-pod                              # Fluxo de logs de pod (stdout)
kubectl logs -f my-pod -c my-container              # Fluxo de logs para um específico contêiner em um pod (stdout, caixa com vários contêineres)
kubectl logs -f -l name=myLabel --all-containers    # transmitir todos os logs de pods com a label name=myLabel (stdout)
kubectl run -i --tty busybox --image=busybox -- sh  # Executar pod como shell interativo
kubectl run nginx --image=nginx --restart=Never -n 
mynamespace                                         # Execute o pod nginx em um namespace específico
kubectl run nginx --image=nginx --restart=Never     # Execute o pod nginx e salve suas especificações em um arquivo chamado pod.yaml
--dry-run -o yaml > pod.yaml

kubectl attach my-pod -i                            # Anexar ao contêiner em execução
kubectl port-forward my-pod 5000:6000               # Ouça na porta 5000 na máquina local e encaminhe para a porta 6000 no my-pod
kubectl exec my-pod -- ls /                         # Executar comando no pod existente (1 contêiner)
kubectl exec my-pod -c my-container -- ls /         # Executar comando no pod existente (pod com vários contêineres)
kubectl top pod POD_NAME --containers               # Mostrar métricas para um determinado pod e seus contêineres

Interagindo com Nós e Cluster

kubectl cordon my-node                                                # Marcar o nó my-node como não agendável
kubectl drain my-node                                                 # Drene o nó my-node na preparação para manutenção
kubectl uncordon my-node                                              # Marcar nó my-node como agendável
kubectl top node my-node                                              # Mostrar métricas para um determinado nó
kubectl cluster-info                                                  # Exibir endereços da master e serviços
kubectl cluster-info dump                                             # Despejar o estado atual do cluster no stdout
kubectl cluster-info dump --output-directory=/path/to/cluster-state   # Despejar o estado atual do cluster em /path/to/cluster-state

# Se uma `taint` com essa chave e efeito já existir, seu valor será substituído conforme especificado.
kubectl taint nodes foo dedicated=special-user:NoSchedule

Tipos de Recursos

Listar todos os tipos de recursos suportados, juntamente com seus nomes abreviados, Grupo de API, se eles são por namespaces, e objetos:

kubectl api-resources

Outras operações para explorar os recursos da API:

kubectl api-resources --namespaced=true      # Todos os recursos com namespace
kubectl api-resources --namespaced=false     # Todos os recursos sem namespace
kubectl api-resources -o name                # Todos os recursos com saída simples (apenas o nome do recurso)
kubectl api-resources -o wide                # Todos os recursos com saída expandida (também conhecida como "ampla")
kubectl api-resources --verbs=list,get       # Todos os recursos que suportam os verbos de API "list" e "get"
kubectl api-resources --api-group=extensions # Todos os recursos no grupo de API "extensions"

Formatação de Saída

Para enviar detalhes para a janela do terminal em um formato específico, adicione a flag -o (ou --output) para um comando kubectl suportado.

Formato de saída Descrição
-o=custom-columns=<spec> Imprimir uma tabela usando uma lista separada por vírgula de colunas personalizadas
-o=custom-columns-file=<filename> Imprima uma tabela usando o modelo de colunas personalizadas no arquivo <nome do arquivo>
-o=json Saída de um objeto de API formatado em JSON
-o=jsonpath=<template> Imprima os campos definidos em uma expressão jsonpath
-o=jsonpath-file=<filename> Imprima os campos definidos pela expressão jsonpath no arquivo <nome do arquivo>
-o=name Imprima apenas o nome do recurso e nada mais
-o=wide Saída no formato de texto sem formatação com qualquer informação adicional e, para pods, o nome do nó está incluído
-o=yaml Saída de um objeto de API formatado em YAML

Verbosidade da Saída do Kubectl e Debugging

A verbosidade do Kubectl é controlado com os sinalizadores -v ou --v seguidos por um número inteiro representando o nível do log. As convenções gerais de log do Kubernetes e os níveis de log associados são descritos aqui.

Verbosidade Descrição
--v=0 Geralmente útil para sempre estar visível para um operador de cluster.
--v=1 Um nível de log padrão razoável se você não deseja verbosidade.
--v=2 Informações úteis sobre o estado estacionário sobre o serviço e mensagens importantes de log que podem se correlacionar com alterações significativas no sistema. Este é o nível de log padrão recomendado para a maioria dos sistemas.
--v=3 Informações estendidas sobre alterações.
--v=4 Detalhamento no nível de debugging.
--v=6 Exibir os recursos solicitados.
--v=7 Exibir cabeçalhos de solicitação HTTP.
--v=8 Exibir conteúdo da solicitação HTTP.
--v=9 Exiba o conteúdo da solicitação HTTP sem o truncamento do conteúdo.

Próximos passos

6 - Ferramentas

O Kubernetes contém várias ferramentas internas para ajudá-lo a trabalhar com o sistema Kubernetes.

Kubectl

kubectl é a ferramenta de linha de comando para o Kubernetes. Ela controla o gerenciador de cluster do Kubernetes.

Kubeadm

kubeadm é a ferramenta de linha de comando para provisionar facilmente um cluster Kubernetes seguro sobre servidores físicos ou na nuvem ou em máquinas virtuais (atualmente em alfa).

Minikube

minikube é uma ferramenta que facilita a execução local de um cluster Kubernetes de nó único em sua estação de trabalho para fins de desenvolvimento e teste.

Dashboard

Dashboard, a interface Web do Kubernetes, permite implantar aplicativos em contêiner em um cluster do Kubernetes, solucionar problemas e gerenciar o cluster e seus próprios recursos.

Helm

Kubernetes Helm é uma ferramenta para gerenciar pacotes de recursos pré-configurados do Kubernetes, também conhecidos como Kubernetes charts.

Use o Helm para:

  • Encontrar e usar softwares populares empacotados como Kubernetes charts
  • Compartilhar seus próprios aplicativos como Kubernetes charts
  • Criar builds reproduzíveis de seus aplicativos Kubernetes
  • Gerenciar de forma inteligente os arquivos de manifesto do Kubernetes
  • Gerenciar versões dos pacotes Helm

Kompose

Kompose é uma ferramenta para ajudar os usuários do Docker Compose a migrar para o Kubernetes.

Use o Kompose para:

  • Converter um arquivo Docker Compose em objetos Kubernetes
  • Ir do desenvolvimento local do Docker ao gerenciamento de seu aplicativo via Kubernetes
  • Converter arquivos yaml do Docker Compose v1 ou v2 ou Bundles de Aplicativos Distribuídos