Como configurar objetos do Kubernetes

Este tópico demonstra como criar configs, os arquivos que o Anthos Config Management lê no Git e se aplica aos clusters automaticamente.

Antes de começar

  • Você precisa entender a estrutura do repositório. A localização de uma configuração dentro do repositório afeta os clusters e os namespaces em que ela é aplicada. Isso é especialmente importante para o diretório namespaces/, porque os subdiretórios de namespaces/ podem herdar configurações dos diretórios de namespaces abstratos.

  • Você precisa entender o básico da sintaxe YAML ou JSON, porque as configurações são gravadas em um desses dois formatos. O YAML é usado em todos os exemplos desta documentação porque a leitura dele é mais fácil.

  • Tipos diferentes de objetos do Kubernetes têm opções configuráveis distintas. É útil entender como você consegue a configuração desejada manualmente antes de gravar um config para esse tipo de objeto.

  • Criamos um repo de exemplo (em inglês) canônico para ilustrar como o Anthos Config Management funciona. Os exemplos neste tópico foram retirados desse repo, então pode ser útil manter o repo aberto em um navegador ou cloná-lo em seu sistema local.

Como criar um config

Ao criar um config, decida a melhor localização no repo e os campos a serem incluídos.

Localização no repositório

A localização de um config no repo é um fator que determina a quais clusters ele se aplica.

  • As configurações de objetos com escopo de cluster, exceto os namespaces, são armazenadas no diretório cluster/ do repositório.
  • As configurações de namespaces e objetos com escopo de namespace são armazenadas no diretório namespaces/ do repositório.
  • Os configs dos componentes do Anthos Config Management são armazenados no diretório system/ do repo.
  • O config do Config Management Operator não é armazenado diretamente no repositório e não é sincronizado.

Conteúdo da configuração

Os configs usam uma abordagem aditiva, semelhante ao kubectl (em inglês). Ao criar novos objetos, você precisa incluir todos os campos obrigatórios. No entanto, ao atualizar objetos atuais, você só precisa fornecer os campos que precisa modificar.

O config, quando aplicado, precisa resultar em um objeto válido do Kubernetes.

Como configurar objetos do Kubernetes atuais

É possível criar um config para um objeto do Kubernetes atual, como um namespace que já existe em seu cluster, antes de instalar o Anthos Config Management. No entanto, essa configuração será ignorada a menos que o objeto tenha a anotação configmanagement.gke.io/managed: enabled. Para um objeto atual, você precisa aplicar a anotação manualmente.

No caso específico dos namespaces, o Anthos Config Management aplica configurações que criam novos objetos em um namespace não anotado e inclui neles a anotação configmanagement.gke.io/managed: enabled. No entanto, o Anthos Config Management se recusa a modificar ou remover qualquer objeto com escopo de cluster não anotado de um cluster. Isso é ilustrado no diagrama em Como trabalhar com configurações ao longo do tempo.

Como configurar CustomResourceDefinitions

O Anthos Config Management permite sincronizar CustomResourceDefinitions (CRDs) da mesma maneira que você sincronizaria qualquer outro recurso. Ao sincronizar CRDs, você precisa considerar alguns fatores.

  • Os CRDs, mesmo ao declarar um Recurso Customizado com namespace, precisam ser colocados no diretório cluster/.

  • As atualizações nos CRDs e nos respectivos CustomResources não ocorrem em uma ordem previsível. Quando essas modificações são feitas na mesma confirmação, as atualizações de CRD não necessariamente ocorrem antes dos CustomResources. Isso pode fazer com que os registros syncer informem um erro transitório por um breve período, até que o CustomResource e o CRD estejam presentes no cluster.

  • O Anthos Config Management não permite a remoção de um CRD se algum CustomResource no repositório depender dele. Para remover um CRD, você também precisa excluir o respectivo CustomResource. É recomendado remover ambos na mesma confirmação do repositório.

  • É possível sincronizar apenas um CustomResource, e não o respectivo CRD. Para isso, você precisa garantir que o CRD já exista no cluster.

Configs de exemplo

Os configs de exemplo a seguir são todos tirados do repo de exemplo. Com base neles, você conseguirá gravar seus próprios configs. Essa lista não é exaustiva. É possível configurar qualquer tipo de objeto do Kubernetes usando o Anthos Config Management.

Config Namespace

Esta configuração cria um namespace chamado audit.

apiVersion: v1
kind: Namespace
metadata:
  name: audit

Ao criar uma configuração de namespace, também é possível adicionar rótulos ou anotações ao namespace. Os rótulos são necessários ao usar um NamespaceSelector.

O exemplo de configuração a seguir cria um namespace chamado shipping-prod quando ele não existe ou não é gerenciado. O namespace tem o rótulo env: prod e a anotação audit: true. Se alguém modificar manualmente qualquer um dos metadados do objeto, o Anthos Config Management o redefinirá rapidamente para o valor na configuração.

apiVersion: v1
kind: Namespace
metadata:
  name: shipping-prod
  labels:
    env: prod
  annotations:
    audit: "true"

Para mais informações sobre como trabalhar com namespaces, consulte Como configurar namespaces e objetos com escopo de namespace.

Config ClusterRole

Essa configuração cria um ClusterRole chamado namespace-reader, que fornece a capacidade de ler (acessar, monitorar e listar) todos os objetos namespace no cluster. Um config ClusterRole costuma ser usado com um config ClusterRoleBinding.

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: namespace-reader
rules:
- apiGroups: [""]
  resources: ["namespaces"]
  verbs: ["get", "watch", "list"]

Config ClusterRoleBinding

Esta configuração cria um ClusterRoleBinding chamado namespace-readers. Ele concede ao usuário cheryl@foo-corp.com o ClusterRole namespace-reader.

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: namespace-readers
subjects:
- kind: User
  name: cheryl@foo-corp.com
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: namespace-reader
  apiGroup: rbac.authorization.k8s.io

ClusterRoleBindings têm escopo de cluster e não podem ser colocadas em diretórios de namespace ou namespaces abstratos.

Config PodSecurityPolicy

Neste exemplo, você cria um PodSecurityPolicy chamado psp. Ele proíbe a execução de contêineres privilegiados e permite que contêineres sejam executados como qualquer usuário válido no nó.

apiVersion: extensions/v1beta1
kind: PodSecurityPolicy
metadata:
  name: psp
spec:
  privileged: false
  seLinux:
    rule: RunAsAny
  supplementalGroups:
    rule: RunAsAny
  runAsUser:
    rule: RunAsAny
  fsGroup:
    rule: RunAsAny
  volumes:
  - '*'

PodSecurityPolicies têm escopo de cluster e não podem ser colocadas em diretórios de namespace ou namespaces abstratos.

Config NetworkPolicy

Neste exemplo, você cria um NetworkPolicy chamado default-deny-all-traffic.

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: default-deny-all-traffic
spec:
  podSelector: {}

NetworkPolicies têm escopo de namespace e só podem ser colocadas em diretórios de namespace ou namespaces abstratos.

Quando você aplica a NetworkPolicy acima a um único namespace, ela isola todos os pods desse namespace do tráfego de entrada e saída.

Quando você aplica a mesma NetworkPolicy a vários namespaces, colocando-a em um namespace abstrato com os namespaces descendentes, cada um desses namespaces herda a NetworkPolicy. No exemplo de repositório (em inglês), o shipping-app-backend é um namespace abstrato que contém configurações para shipping-dev, shipping-prod e shipping-stage. Se você adicionar o exemplo NetworkPolicy acima a eles, cada um herdará a NetworkPolicy, para que cada um de seus pods seja protegido do tráfego de entrada e saída.

É possível usar a herança de namespace para impor uma abordagem de privilégio mínimo à segurança. Por exemplo, se o exemplo anterior for aplicado a shipping-app-backend, e a NetworkPolicy a seguir for adicionada ao namespace shipping-dev, o tráfego de entrada será permitido apenas para os pods nesse namespace com o rótulo app:nginx. Os namespaces shipping-prod e shipping-staging não são impactados por essa NetworkPolicy.

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-nginx-ingress
spec:
  podSelector:
    matchLabels:
      app: nginx
  ingress:
  - {}

Config ResourceQuota

Neste exemplo, você cria uma configuração ResourceQuota (em inglês) chamada quota. Ela define um limite absoluto de um pod, 100 mili-CPUs e 100 mebibytes (MiB) de memória.

kind: ResourceQuota
apiVersion: v1
metadata:
  name: quota
spec:
  hard:
    pods: "1"
    cpu: "100m"
    memory: 100Mi

Se a criação de um novo objeto de um determinado tipo violar um ResourceQuota atual, o Kubernetes não poderá criar esse objeto até que isso não viole mais o ResourceQuota.

A seguir