Como preparar um ambiente do Google Kubernetes Engine para produção

Nesta solução, apresentamos um esquema e uma metodologia para integrar as cargas de trabalho ao Google Kubernetes Engine de maneira mais segura, confiável e econômica. Ela orienta na configuração do acesso administrativo e de rede aos clusters. Para acompanhar este artigo, é recomendado ter uma compreensão funcional dos recursos do Kubernetes e da administração de cluster, bem como uma familiaridade com os recursos de rede do Google Cloud Platform (GCP).

Como estruturar projetos, redes de nuvem privada virtual (VPC, na sigla em inglês) e clusters

O diagrama a seguir mostra a melhor estrutura de projetos, redes VPC, regiões, sub-redes, zonas e clusters.

Estrutura de projeto, rede e cluster

Projetos

O GCP cria todos os recursos próprios em uma entidade de projeto. Os projetos são a unidade de faturamento e permitem que os administradores associem os papéis do Cloud Identity e Access Management (Cloud IAM) aos usuários. Quando aplicados no nível do projeto, os papéis são pertinentes a todos os recursos encapsulados no projeto.

Use projetos para encapsular vários ambientes operacionais. Por exemplo, você pode ter projetos de production e staging para equipes de operações, bem como um projeto de test-dev para desenvolvedores. Você pode aplicar políticas mais granulares e estritas aos projetos que contêm os dados e cargas de trabalho mais críticos e confidenciais, ao mesmo tempo que aplica políticas de permissão flexíveis para os desenvolvedores do ambiente test-dev fazerem experiências.

Clusters

Um projeto pode conter vários clusters. Se você tiver várias cargas de trabalho para implantar, poderá optar por usar um único cluster compartilhado ou clusters separados para essas cargas de trabalho. Para tomar a melhor decisão, veja nossas práticas recomendadas no artigo sobre como escolher o tamanho e o escopo de um cluster do GKE.

Redes e sub-redes

Dentro de cada projeto, você pode ter uma ou mais redes VPC, que são versões virtuais de redes físicas. Cada rede VPC é um recurso global que contém outros recursos relacionados à rede, como sub-redes, endereços IP externos, regras de firewall, rotas, VPN e o Cloud Router. Em uma rede VPC, é possível usar sub-redes, que são recursos regionais, para isolar e controlar o tráfego recebido ou enviado por cada região entre os clusters do GKE.

Cada projeto inclui uma única rede padrão. É possível criar e configurar uma rede extra para mapear para convenção atual de gerenciamento de endereços IP (IPAM, na sigla em inglês). Aplique, então, as regras de firewall à rede para filtrar o tráfego de entrada e saída dos nós do GKE. Por padrão, todo o tráfego da Internet recebido pelos nós do GKE é negado.

Para controlar a comunicação entre sub-redes, é necessário criar regras de firewall que permitam que o tráfego passe entre as sub-redes. Use a sinalização --tags durante a criação do pool de nós ou cluster para marcar devidamente os nós do GKE para que as regras de firewall tenham efeito. Também é possível usar tags para criar rotas entre as sub-redes, se necessário.

Clusters de várias zonas e regionais

Por padrão, um cluster cria os respectivos mestre e nodes em uma única zona, que você especifica no momento da criação. Para melhorar a disponibilidade e a resiliência dos clusters, crie clusters de várias zonas ou regionais. Eles distribuem os recursos do Kubernetes em várias zonas dentro de uma região.

Os clusters de várias zonas:

  • criam um único mestre em uma zona;
  • criam nodes em várias zonas.

Os clusters regionais:

  • criam três mestres em três zonas;
  • por padrão, criam nodes em três zonas, mas podem criar em quantas você quiser.

A principal diferença entre eles é que os clusters regionais criam três mestres, e os de várias zonas apenas um. Nos dois casos, o tráfego entre nodes nas zonas é cobrado.

No momento da criação do cluster, você escolhe se ele será de várias zonas ou regional. Você pode adicionar novas zonas a um cluster existente para torná-lo de várias zonas. No entanto, não é possível modificar um cluster existente para ser regional. Também não é possível transformar um cluster regional em não regional.

Para saber mais sobre clusters regionais e de várias zonas, consulte a documentação do GKE.

Como gerenciar identidades e acesso

Acesso no nível do projeto

A seção anterior mostrou que você pode vincular papéis de IAM a usuários no nível do projeto. Além de conceder papéis a usuários individuais, você também pode usar grupos para simplificar a aplicação de papéis.

Veja abaixo uma ilustração do layout da política de IAM que fornece o princípio do menor privilégio para um projeto dev que está configurado para desenvolvedores desenvolverem e testarem os próximos recursos e correções de bugs, bem como um projeto prod para o tráfego de produção:

Gerenciamento de identidade e acesso

Como mostra a tabela a seguir, há quatro grupos de usuários dentro da organização com diferentes níveis de permissões, concedidas por meio de papéis de IAM entre os dois projetos:

Equipe Papel de IAM Projeto Permissões
Desenvolvedores container.developer dev Pode criar recursos do Kubernetes para os clusters existentes no projeto, sem permissão para criar ou excluir clusters.
Operações container.admin prod Acesso administrativo completo aos clusters e recursos do Kubernetes em execução no projeto.
Segurança container.viewer
security.admin
prod Criar, modificar e excluir regras de firewall e certificados SSL, bem como ver os recursos que foram criados dentro de cada cluster, incluindo os registros dos pods em execução.
Rede network.admin prod Criar, modificar e excluir recursos de rede, exceto regras de firewall e certificados SSL.

Além das três equipes com acesso ao projeto prod, uma conta de serviço extra é fornecida ao papel container.developer para prod, dando permissão para criar, listar e excluir recursos no cluster. As contas de serviço podem ser usadas para dar a scripts de automação ou bibliotecas de implantação a capacidade de agir por você. As implantações no projeto de produção e nos clusters devem passar por um pipeline automatizado.

No projeto dev, há vários desenvolvedores que trabalham no mesmo aplicativo dentro do mesmo cluster. Isso é facilitado pelos namespaces, que o usuário do cluster pode criar. Cada desenvolvedor pode criar recursos dentro do próprio namespace, o que evita conflitos de nome. Eles também podem reutilizar os mesmos arquivos de configuração YAML nas implantações para manter a maior semelhança possível entre as configurações durante as iterações de desenvolvimento. Os namespaces também podem ser usados para criar cotas para uso de CPU, memória e armazenamento no cluster, assegurando que um desenvolvedor não esteja usando recursos demais no cluster. A próxima seção aborda a restrição à operação de certos namespaces por parte dos usuários.

Autorização RBAC

Os clusters do GKE que executam o Kubernetes 1.6 e posterior podem utilizar outras restrições relativas ao que os usuários estão autorizados a fazer em clusters individuais. O Cloud IAM pode fornecer aos usuários acesso a clusters completos e aos recursos dentro deles. No entanto, o controle de acesso baseado em papéis do Kubernetes (RBAC, na sigla em inglês) permite usar a API do Kubernetes para limitar ainda mais as ações que os usuários podem executar nos próprios clusters.

Com o RBAC, os administradores de cluster aplicam políticas detalhadas a namespaces individuais dentro dos próprios clusters ou ao cluster como um todo. A interface de linha de comando do Kubernetes kubectl usa as credenciais ativas da ferramenta gcloud, permitindo que os administradores de cluster mapeiem os papéis para as identidades do GCP (usuários e contas de serviço) como sujeitos em RoleBindings.

Por exemplo, a figura abaixo tem dois usuários, user-a e user-b, aos quais foram concedidos os papéis config-reader e pod-reader no namespace app-a.

Autorização RBAC

Como em outro exemplo, o GCP tem papéis de IAM em nível de projeto que dão a certos usuários acesso a todos os clusters de um projeto. Além disso, são adicionadas vinculações individuais de papel (em nível de namespace e de cluster) por meio do RBAC para dar acesso detalhado a recursos dentro de clusters ou namespaces específicos.

Vinculações de papéis do IAM

O Kubernetes inclui alguns papéis padrão, mas, como administrador de cluster, você pode criar o próprio mapa, mais específico às necessidades organizacionais. Veja abaixo um papel de exemplo que permite aos usuários apenas ver, editar e atualizar o ConfigMaps, mas não excluí-los, porque o verbo delete não está incluído:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  namespace: default
  name: config-editor
rules:
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["get", "list", "watch", "create", "update", "patch"]

Depois de definir papéis, você pode aplicá-los ao cluster ou namespace por meio de vinculações. As vinculações associam os papéis aos respectivos usuários, grupos ou contas de serviço. Veja abaixo um exemplo de vinculação do papel criado anteriormente (config-editor) ao usuário bob@example.org e ao namespace development.

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: config-editors
  namespace: development
subjects:
- kind: User
  name: bob@example.org
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: config-editor
  apiGroup: rbac.authorization.k8s.io

Para saber mais informações sobre o RBAC, consulte a documentação do GKE.

Acesso e compartilhamento de imagens

As imagens no Container Registry são armazenadas no Cloud Storage. Nesta seção, abordaremos duas maneiras de compartilhar imagens. Uma delas é tornando-as públicas, a outra é compartilhando-as entre projetos.

Como tornar públicas as imagens

Para tornar públicas as imagens, você pode tornar públicos os objetos e intervalos que as sustentam. Para instruções mais detalhadas, consulte a documentação de controle de acesso do Container Registry.

Acessar imagens entre projetos

Você pode compartilhar imagens de contêiner entre projetos, basta garantir que os nodes do Kubernetes usem uma conta de serviço. A conta de serviço padrão associada ao projeto tem o formato [PROJECT_ID]-compute@developer.gserviceaccount.com. Com esse identificador, é possível conceder à conta de serviço acesso como storage.viewer nos projetos que usarão o Container Registry. Use uma conta de serviço personalizada que tenha permissões restritas porque a conta padrão tem acesso de editor no projeto inteiro.

Para usar outra conta de serviço para os clusters, forneça a conta de serviço na criação do cluster ou do pool de nós usando a sinalização --service-account. Por exemplo, para usar a conta de serviço gke-sa no projeto my-project:

gcloud container clusters create west --service-account \
  gke-sa@my-project.google.com.iam.gserviceaccount.com

Como configurar a rede

O Kubernetes fornece a abstração de serviço que proporciona o balanceamento de carga e a descoberta de serviço em conjuntos de pods dentro de um cluster, bem como em sistemas legados executados fora do cluster. As seções abaixo descrevem as práticas recomendadas para a comunicação entre os pods do Kubernetes e com outros sistemas, incluindo outros clusters do Kubernetes.

Comunicar-se no mesmo cluster

Descoberta de serviço

O Kubernetes permite definir serviços que agrupam pods em execução no cluster com base em um conjunto de rótulos. Esse grupo de pods pode ser descoberto no cluster usando DNS. Para mais informações sobre a descoberta de serviço no Kubernetes, acesse a documentação Como conectar aplicativos a serviços.

DNS

Um servidor DNS de cluster local, kube-dns, é implantado em cada cluster do GKE que gerencia o mapeamento de nomes de serviço para IPs de pods íntegros. Por padrão, o servidor DNS do Kubernetes retorna o endereço IP do cluster do serviço. Esse endereço IP é estático por toda a vida do serviço. Ao enviar tráfego a esse IP, os iptables no node farão o balanceamento de carga dos pacotes pelos pods prontos que correspondem aos seletores do serviço. Esses iptables são programados automaticamente pelo serviço kube-proxy em execução em cada node.

Se você quer a descoberta de serviço e o monitoramento de integridade, mas prefere que o serviço DNS retorne os IPs dos pods em vez de um IP virtual, provisione o serviço com o campo ClusterIP definido com "Nenhum", o que torna o serviço sem comando. Nesse caso, o servidor DNS retorna uma lista de registros A que mapeiam o nome DNS do serviço para os registros A dos pods prontos que correspondem aos seletores de rótulo definidos pelo serviço. Os registros da resposta se alternam para facilitar a propagação da carga em vários pods. Algumas ferramentas de resolução de DNS do lado do cliente podem armazenar respostas de DNS em cache, tornando ineficaz a alternância do registro A. As vantagens do uso do ClusterIP estão listadas na documentação do Kubernetes.

Um caso de uso típico para serviços sem comando é StatefulSets. StatefulSets é ideal para executar aplicativos com estado que exigem estabilidade de armazenamento e rede entre as réplicas. Esse tipo de implantação provisiona pods que têm uma identidade de rede estável, o que significa que os respectivos nomes de host podem ser resolvidos no cluster. O IP do pod pode mudar, mas a entrada DNS do nome do host permanecerá atualizada e poderá ser resolvida.

Fluxo de pacotes: ClusterIP

O diagrama a seguir mostra a resposta DNS e o fluxo de pacotes de um serviço padrão do Kubernetes. Os endereços IP do pod são roteáveis de fora do cluster, mas o endereço IP do cluster de um serviço só é acessível dentro do cluster. Esses endereços IP virtuais são implementados por meio da conversão de endereços de rede de destino (DNAT, na sigla em inglês) em cada node do Kubernetes. O serviço kube-proxy em execução em cada node mantém as regras de encaminhamento atualizadas em cada node que mapeia o IP do cluster para os IPs de pods íntegros pelo cluster. Se houver um pod do serviço em execução no node local, esse pod será usado. Caso contrário, será escolhido um pod aleatório no cluster.

Serviço de IP de cluster

Para saber mais informações sobre como os IPs de serviço são implementados, consulte a documentação do Kubernetes. Para ter uma compreensão mais aprofundada sobre a rede do GKE, assista à palestra do Next 2017 no YouTube:

Serviços sem comando

Veja abaixo um exemplo da resposta DNS e do padrão de tráfego referente a um serviço sem comando. Os endereços IP do pod podem ser roteados por meio das tabelas de rotas da sub-rede do GCP padrão e são acessados diretamente pelo seu aplicativo.

Exemplo de resposta DNS e padrão de tráfego para o serviço sem comando

Políticas de rede

Use a aplicação da política de rede do Kubernetes Engine para controlar a comunicação entre os pods e os serviços do cluster. Para definir uma política de rede no Kubernetes Engine, é possível usar a API Kubernetes Network Policy para criar regras de firewall no nível do pod. Essas regras de firewall determinam quais pods e serviços podem acessar um ao outro dentro do cluster.

As políticas de rede são um tipo de defesa que aumenta a segurança das cargas de trabalho em execução no seu cluster. Por exemplo, você pode criar uma política de rede para garantir que um serviço comprometido de front-end no aplicativo não possa se comunicar diretamente com um serviço de cobrança ou contabilidade vários níveis abaixo.

As políticas de rede também podem ser usadas para isolar cargas de trabalho pertencentes a locatários diferentes. Por exemplo, você pode fornecer multilocação segura definindo um modelo de locatário por namespace. Nesse modelo, as regras de política de rede podem garantir que pods e serviços em um determinado namespace não acessem outros pods ou serviços em um namespace diferente.

Para saber mais sobre as políticas de rede, consulte a documentação do GKE.

Como se conectar a um cluster do GKE usando o Google Cloud Platform

Para se conectar aos serviços externamente ao cluster, mas dentro do espaço de IP privado da rede do GCP, use o balanceamento de carga interno. Durante a criação de um serviço com type: Load Balancer e de uma anotação cloud.google.com/load-balancer-type: Internal no Kubernetes, um balanceador de carga de rede interno também é criado no projeto do GCP e configurado para distribuir o tráfego TCP e UDP entre os pods.

Como se conectar a serviços externos de dentro de um cluster

Em muitos casos, pode ser necessário conectar os aplicativos em execução dentro do Kubernetes a um serviço, banco de dados ou aplicativo que esteja fora do cluster. Há três opções, descritas abaixo.

Domínios Stub

No Kubernetes 1.6 e posterior, você pode configurar o serviço DNS interno do cluster (kube-dns) para encaminhar consultas DNS referentes a um determinado domínio a um servidor DNS externo. Isso é útil quando você tem servidores DNS autorizados que precisam ser consultados em relação a um domínio que os pods do Kubernetes precisarão aproveitar.

Serviços de nomes externos

Os serviços de nomes externos permitem mapear um registro DNS para um nome de serviço dentro do cluster. Nesse caso, as buscas DNS quanto ao serviço no cluster retornarão um registro CNAME que você escolher. Isso precisa ser usado se você tiver apenas alguns registros dos quais quer fazer o mapeamento retroativo aos serviços DNS existentes.

Serviços sem seletores

Você pode criar serviços sem seletor e depois adicionar a eles os pontos de extremidade manualmente para preencher a descoberta de serviço com os valores corretos. Com isso, você pode usar o mesmo mecanismo de descoberta de serviço para os serviços internos ao cluster, ao mesmo tempo em que assegura que os sistemas sem descoberta de serviço por meio do DNS ainda estão acessíveis. Essa abordagem é a mais flexível, mas também requer mais configuração e manutenção a longo prazo.

Para mais informações sobre o DNS, acesse a página de documentação em Pods e serviços DNS do Kubernetes.

Como receber tráfego da Internet para o cluster

O tráfego da Internet pode ser direcionado para os serviços executados no Kubernetes usando dois métodos diferentes: balanceamento de carga de rede ou HTTP(s).

Os serviços do Kubernetes precisam ser criados como o tipo LoadBalancer para balanceamento de carga TCP/UDP externa. O Kubernetes cria um balanceador de carga de rede no projeto do GCP e o mapeia para os nodes do cluster do Kubernetes Engine. Assim, fica fácil ter balanceamento de carga para as cargas de trabalho TCP e UDP com configuração mínima. O balanceador de carga de rede tem escopo regional, portanto, só pode balancear o tráfego de pods em execução na mesma região.

Balanceador de carga de rede na região us-west1

No caso do balanceamento de carga HTTP(S), você precisa aproveitar o balanceador de carga HTTP(S) global do Google, que pode fazer o balanceamento de carga do tráfego entre várias regiões usando um único endereço IP anycast. No Kubernetes, você pode criar recursos de entrada que permitam mapear caminhos e nomes de host para serviços no cluster. Para que a entrada funcione corretamente, é preciso criar os serviços com type: NodePort.

balanceamento de carga em várias regiões

Firewall

Os nós do GKE são provisionados como instâncias no Compute Engine. Portanto, eles seguem o mesmo mecanismo de firewall com estado que outras instâncias. Essas regras de firewall são aplicadas dentro da rede a instâncias com o uso de tags. Cada pool de node recebe o próprio conjunto de tags, que você pode usar nas regras. Por padrão, cada instância pertencente a um pool de nós recebe uma tag que identifica um cluster específico do Kubernetes Engine do qual esse pool de nós faz parte. Essa tag é usada em regras de firewall criadas automaticamente pelo Kubernetes Engine. É possível adicionar as próprias tags personalizadas no momento da criação do pool de nós ou do cluster usando a sinalização --tags na linha de comando do gcloud.

Por exemplo, para permitir que um balanceador de carga interno acesse a porta 8080 em todos os nós, use os comandos a seguir:

gcloud compute firewall-rules create \
  allow-8080-fwr --target-tags allow-8080 --allow tcp:8080 \
  --network gke --source-range 130.211.0.0/22
gcloud container clusters create my-cluster --tags allow-8080

O exemplo a seguir mostra como marcar um cluster para que o tráfego da Internet possa acessar nodes na porta 30000 enquanto o outro cluster é marcado para permitir o tráfego da VPN para a porta 40000. Isso é útil ao expor um serviço por meio de um NodePort que só precisa ser acessível por redes com privilégio, como uma VPN, em direção a um data center corporativo ou a partir de outro cluster no projeto.

como atribuir tags a dois clusters de maneira diferente

Como se conectar a um data center local

O Cloud Interconnect oferece várias opção para a conexão com data centers locais. Por não serem mutuamente excludentes, é possível combiná-las de acordo com a carga de trabalho e os requisitos:

  1. Internet para cargas de trabalho sem uso intenso de dados ou relacionadas à latência. O Google tem mais de 100 pontos de presença (PoPs, na sigla em inglês) que se conectam a provedores de serviços em todo o mundo.
  2. Peering direto para cargas de trabalho que exigem largura de banda dedicada, são relacionadas à latência e acessam todos os serviços do Google, incluindo o pacote completo de produtos do GCP. O peering direto é uma conexão de camada 3, efetuada pela troca de rotas BGP e, portanto, requer um ASN registrado.
  3. Peering de operadora é o mesmo que peering direto, só que feito por meio de um provedor de serviços. É uma ótima opção quando você não tem um ASN registrado ou tem relações existentes com um provedor de serviços preferencial.
  4. O Cloud VPN é configurado na interconexão de camada 3 e nas opções de Internet (1, 2 e 3) caso a criptografia IPsec seja obrigatória ou caso você queira estender a rede privada à rede privada do Compute Engine.

Próximas etapas

  • Teste outros recursos do Google Cloud Platform. Veja nossos tutoriais.
Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…