Nesta página, mostramos como usar vários certificados SSL para Entrada com balanceamento de carga interno e externo.
Visão geral
Se você quiser aceitar solicitações HTTPS dos seus clientes, o balanceador de carga HTTP(S) interno ou externo precisará ter um certificado para provar sua identidade a eles. Além disso, ele precisa ter uma chave privada para concluir o handshake HTTPS.
Quando o balanceador de carga aceita uma solicitação HTTPS de um cliente, o tráfego entre o cliente e o balanceador de carga é criptografado usando TLS. No entanto, o balanceador de carga encerra a criptografia TLS e encaminha a solicitação sem criptografia para o aplicativo. Ao configurar um balanceador de carga HTTP(S) por meio do Entrada, é possível defini-lo para apresentar até dez certificados TLS ao cliente.
O balanceador de carga usa a indicação de nome do servidor (SNI, na sigla em inglês) para determinar qual certificado precisa ser apresentado ao cliente com base no nome de domínio no handshake de TLS. Se o cliente não usar a SNI ou se o cliente usar um nome de domínio que não corresponda ao nome comum (CN, na sigla em inglês) em um dos certificados, o balanceador de carga usará o primeiro certificado listado em Entrada. O diagrama a seguir descreve o tráfego de envio do balanceador de carga para diferentes back-ends, dependendo do nome de domínio usado na solicitação:
Forneça um balanceador de carga HTTPS com certificados SSL usando um destes três métodos:
Certificados SSL gerenciados pelo Google. Consulte a página de certificados gerenciados para mais informações sobre como usá-los.
Certificado SSL do Google Cloud que você mesmo gerencia. Ele usa um certificado pré-compartilhado enviado anteriormente para seu projeto do Google Cloud.
Secrets do Kubernetes. O secret contém um certificado e uma chave que você mesmo cria. Para usar um secret, adicione o nome dele ao campo
tls
do seu manifesto de Entrada.
É possível usar mais de um método na mesma Entrada. Isso permite migrações sem tempo de inatividade entre os métodos.
Versão mínima do GKE
Você precisa ter a versão 1.10.2 ou posterior do GKE para usar certificados pré-compartilhados ou especificar vários certificados em uma Entrada.
Pré-requisitos
Para fazer os exercícios desta página, você precisa ter dois nomes de domínio. É preciso usar o Google Domains ou outro registrador.
Visão geral
Veja abaixo uma visão geral das etapas deste tópico:
Crie uma implantação.
Crie um serviço.
Crie dois arquivos de certificado e dois arquivos de chaves.
Crie uma Entrada que use as chaves secretas ou os certificados pré-compartilhados. Como resultado da criação da Entrada, o GKE irá criar e configurar um balanceador de carga HTTP(S).
Teste o balanceador de carga HTTP(S).
Antes de começar
Antes de começar, verifique se você realizou as tarefas a seguir:
- Verifique se você ativou a API Google Kubernetes Engine. Ativar a API Google Kubernetes Engine
- Verifique se o SDK do Cloud está instalado.
Defina as configurações padrão da gcloud
usando um dos métodos a seguir:
- Use
gcloud init
se quiser orientações para definir os padrões. - Use
gcloud config
para definir individualmente a região, a zona e o ID do projeto.
Como usar o gcloud init
Se você receber o erro One of [--zone, --region] must be supplied: Please specify
location
, conclua esta seção.
-
Execute
gcloud init
e siga as instruções:gcloud init
Se você estiver usando SSH em um servidor remoto, utilize a sinalização
--console-only
para impedir que o comando inicie um navegador:gcloud init --console-only
-
Siga as instruções para autorizar a
gcloud
a usar sua conta do Google Cloud. - Crie uma nova configuração ou selecione uma atual.
- Escolha um projeto do Google Cloud.
- Escolha uma zona padrão do Compute Engine.
Como usar o gcloud config
- Defina o ID do projeto padrão:
gcloud config set project PROJECT_ID
- Se você estiver trabalhando com clusters zonais, defina a zona do Compute padrão:
gcloud config set compute/zone COMPUTE_ZONE
- Se você estiver trabalhando com clusters regionais, defina a região do Compute padrão:
gcloud config set compute/region COMPUTE_REGION
- Atualize
gcloud
para a versão mais recente:gcloud components update
Como criar uma implantação
Veja aqui um manifesto de uma implantação:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-mc-deployment
spec:
selector:
matchLabels:
app: products
department: sales
replicas: 3
template:
metadata:
labels:
app: products
department: sales
spec:
containers:
- name: hello
image: "gcr.io/google-samples/hello-app:2.0"
env:
- name: "PORT"
value: "50001"
- name: hello-again
image: "gcr.io/google-samples/node-hello:1.0"
env:
- name: "PORT"
value: "50002"
A implantação tem três pods e cada pod tem dois contêineres. Um contêiner executa hello-app
e escuta a porta TCP 50001. O outro contêiner executa node-hello
e escuta a porta TCP 50002.
Copie o manifesto em um arquivo denominado my-mc-deployment.yaml
e crie a implantação:
kubectl apply -f my-mc-deployment.yaml
Como criar um serviço
Veja aqui um manifesto de um serviço.
apiVersion: v1
kind: Service
metadata:
name: my-mc-service
spec:
type: NodePort
selector:
app: products
department: sales
ports:
- name: my-first-port
protocol: TCP
port: 60001
targetPort: 50001
- name: my-second-port
protocol: TCP
port: 60002
targetPort: 50002
O campo selector
no manifesto do serviço diz que qualquer pod que tenha o rótulo app: products
e o rótulo department: sales
é membro do serviço. Assim, os pods da implantação que você criou na etapa anterior são membros do serviço.
O campo ports
do manifesto de Service é uma matriz de objetos ServicePort (em inglês). Quando um cliente envia uma solicitação ao serviço em my-first-port
, a solicitação é encaminhada a um dos pods de membro na porta 50001. Quando um cliente envia uma solicitação para o serviço em my-second-port
, a solicitação é encaminhada a um dos pods de membro na porta 50002.
Copie o manifesto para um arquivo chamado my-mc-service.yaml
e crie o serviço:
kubectl apply -f my-mc-service.yaml
Como criar certificados e chaves
Para fazer os exercícios desta página, você precisa de dois certificados, cada um com uma chave correspondente. Cada certificado precisa ter um Nome comum (CN, na sigla em inglês) que seja igual a um nome de domínio que você tem. Se você já tiver dois arquivos de certificado com os valores apropriados para o nome comum, avance para a próxima seção.
Crie a primeira chave:
openssl genrsa -out test-ingress-1.key 2048
Crie a primeira solicitação de assinatura de certificado:
openssl req -new -key test-ingress-1.key -out test-ingress-1.csr \ -subj "/CN=first-domain"
em que first-domain é um nome de domínio que você tem.
Por exemplo, suponha que você queira que o balanceador de carga exiba solicitações do domínio example.com
. Nesse caso, sua solicitação de assinatura de certificado ficaria assim:
openssl req -new -key test-ingress-1.key -out test-ingress-1.csr \ -subj "/CN=example.com"
Crie o primeiro certificado:
openssl x509 -req -days 365 -in test-ingress-1.csr -signkey test-ingress-1.key \ -out test-ingress-1.crt
Crie a segunda chave:
openssl genrsa -out test-ingress-2.key 2048
Crie a segunda solicitação de assinatura de certificado:
openssl req -new -key test-ingress-2.key -out test-ingress-2.csr \ -subj "/CN=second-domain"
second-domain é outro nome de domínio que você tem.
Por exemplo, suponha que você queira que o balanceador de carga exiba solicitações do domínio examplepetstore.com
. Nesse caso, sua solicitação de assinatura de certificado ficaria assim:
openssl req -new -key test-ingress-2.key -out test-ingress-2.csr \ -subj "/CN=examplepetstore.com"
Crie o segundo certificado:
openssl x509 -req -days 365 -in test-ingress-2.csr -signkey test-ingress-2.key \ -out test-ingress-2.crt
Para mais informações sobre certificados e chaves, consulte a Visão geral dos certificados SSL.
Agora você tem dois arquivos de certificado e dois arquivos de chaves.
As demais tarefas usam os seguintes marcadores para referir-se aos seus domínios, certificados e chaves:
- first-cert-file é o caminho para o primeiro arquivo de certificado.
- first-key-file é o caminho para o arquivo de chave que acompanha o primeiro certificado.
- first-domain é um nome de domínio que pertence a você.
- first-secret-name é o nome do Secret que contém seu primeiro certificado e chave.
- second-cert-file é o caminho para o segundo arquivo de certificado.
- second-key-file é o caminho para o arquivo de chave que acompanha o segundo certificado.
- second-domain é um segundo nome de domínio que você tem.
- second-secret-name é o nome do Secret que contém o segundo certificado e chave.
Como especificar certificados para a Entrada
A próxima etapa é criar um objeto Entrada. No seu manifesto Entrada, é possível usar um dos dois métodos para fornecer certificados ao balanceador de carga:
- Chaves secretas
- Certificados pré-compartilhados
Escolha um dos dois métodos selecionando a guia SECRETS
ou a guia PRE-SHARED CERTS
:
Secrets
Como criar secrets
Crie um secret que contenha seu primeiro certificado e chave:
kubectl create secret tls first-secret-name \ --cert first-cert-file --key first-key-file
Crie um secret que contenha seu segundo certificado e chave:
kubectl create secret tls second-secret-name \ --cert second-cert-file --key second-key-file
Como criar um Ingress
Veja aqui o manifesto de um Ingress.
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: my-mc-ingress
spec:
tls:
- secretName: first-secret-name
- secretName: second-secret-name
rules:
- host: first-domain
http:
paths:
- backend:
serviceName: my-mc-service
servicePort: my-first-port
- host: second-domain
http:
paths:
- backend:
serviceName: my-mc-service
servicePort: my-second-port
Copie o manifesto para um arquivo chamado my-mc-ingress.yaml
. Substitua first-domain e second-domain pelos seus nomes de domínio, por exemplo, example.com
e examplepetstore.com
.
Crie e Entrada:
kubectl apply -f my-mc-ingress.yaml
Quando você cria uma Entrada, o controlador de entrada do GKE cria um balanceador de carga HTTP(S). Aguarde um minuto para que o GKE atribua um endereço IP externo ao balanceador de carga.
Descreva sua Entrada:
kubectl describe ingress my-mc-ingress
A saída mostra que duas chaves secretas estão associadas à Entrada. A saída também mostra o endereço IP externo do balanceador de carga.
Name: my-mc-ingress
Address: 203.0.113.1
...
TLS:
first-secret-name terminates
second-secret-name terminates
Rules:
Host Path Backends
---- ---- --------
example.com
my-mc-service:my-first-port (<none>)
examplepetstore.com
my-mc-service:my-second-port (<none>)
Annotations:
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ADD 3m loadbalancer-controller default/my-mc-ingress
Normal CREATE 2m loadbalancer-controller ip: 203.0.113.1
Certificados pré-compartilhados
Como usar certificados pré-compartilhados
Crie um recurso de certificado no seu projeto do Google Cloud:
gcloud compute ssl-certificates create test-ingress-1 \ --certificate first-cert-file --private-key first-key-file
onde:
- first-cert-file é o primeiro arquivo de certificado;
- first-key-file é o primeiro arquivo de chave.
Crie um segundo recurso de certificado no seu projeto do Google Cloud:
gcloud compute ssl-certificates create test-ingress-2 \ --certificate second-cert-file --private-key second-key-file
em que:
- second-cert-file é o segundo arquivo de certificado;
- second-key-file é o segundo arquivo de chave.
Veja seus recursos de certificado:
gcloud compute ssl-certificates list
A saída mostra que você tem recursos de certificado chamados test-ingres-1
e test-ingress-2
:
NAME CREATION_TIMESTAMP
test-ingress-1 2018-11-03T12:08:47.751-07:00
test-ingress-2 2018-11-03T12:09:25.359-07:00
Veja aqui um manifesto de uma Entrada que lista recursos de certificado pré-compartilhados em uma anotação:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: my-psc-ingress
annotations:
ingress.gcp.kubernetes.io/pre-shared-cert: "test-ingress-1,test-ingress-2"
spec:
rules:
- host: first-domain
http:
paths:
- backend:
serviceName: my-mc-service
servicePort: my-first-port
- host: second-domain
http:
paths:
- backend:
serviceName: my-mc-service
servicePort: my-second-port
Copie o manifesto para um arquivo chamado my-psc-ingress.yaml
. Substitua first-domain e second-domain pelos seus nomes de domínio.
Crie e Entrada:
kubectl apply -f my-psc-ingress.yaml
Aguarde um minuto para que o GKE atribua um endereço IP externo ao balanceador de carga.
Descreva sua Entrada:
kubectl describe ingress my-psc-ingress
A saída mostra que a Entrada está associada a certificados compartilhados anteriormente chamados test-ingress-1
e test-ingress-2
. A saída também mostra o endereço IP externo do balanceador de carga:
Name: my-psc-ingress
Address: 203.0.113.2
...
Rules:
Host Path Backends
---- ---- --------
example.com
my-mc-service:my-first-port (<none>)
examplepetstore.com
my-mc-service:my-second-port (<none>)
Annotations:
...
ingress.gcp.kubernetes.io/pre-shared-cert: test-ingress-1,test-ingress-2
...
ingress.kubernetes.io/ssl-cert: test-ingress-1,test-ingress-2
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ADD 2m loadbalancer-controller default/my-psc-ingress
Normal CREATE 1m loadbalancer-controller ip: 203.0.113.2
Como testar o balanceador de carga
Aguarde cerca de cinco minutos para que o GKE conclua a configuração do balanceador de carga.
Nesta etapa, você precisa ter dois nomes de domínio que precisam resolver o endereço IP externo do balanceador de carga HTTP(S).
Envie uma solicitação ao balanceador de carga usando seu primeiro nome de domínio:
curl -v https://first-domain
A resposta mostra que o primeiro certificado foi usado no handshake de TLS.
Se seu primeiro domínio for example.com
, a resposta será semelhante a esta:
...
* Trying 203.0.113.1...
...
* Connected to example.com (203.0.113.1) port 443 (#0)
...
* TLSv1.2 (IN), TLS handshake, Certificate (11):
...
* Server certificate:
* subject: CN=example.com
...
> Host: example.com
...
<
Hello, world!
Version: 2.0.0
...
Envie uma solicitação ao balanceador de carga usando o segundo nome de domínio:
curl -v https://second-domain
A saída mostra que o segundo certificado foi usado no handshake de TLS.
Se seu segundo domínio for examplepetstore.com
, a resposta será semelhante a esta:
...
* Trying 203.0.113.1...
...
* Connected to examplepetstore.com (203.0.113.1) port 443 (#0)
...
* Server certificate:
* subject: CN=examplepetstore.com
...
> Host: examplepetstore.com
...
Hello Kubernetes!
O campo hosts de um objeto Entrada
No IngressSpec há um campo tls
que é uma matriz de objetos IngressTLS (links em inglês). Cada objeto IngressTLS
tem um campo hosts
e um campo SecretName
.
No GKE, o campo hosts
não é usado. O GKE lê o nome comum (CN, na sigla em inglês) do certificado no secret. Se o Nome comum corresponder ao nome de domínio em uma solicitação do cliente, o balanceador de carga apresentará o certificado correspondente ao cliente.
Qual certificado é apresentado?
O balanceador de carga escolhe um certificado de acordo com estas regras:
Se os Secrets e os certificados pré-compartilhados estiverem listados na Entrada, os certificados pré-compartilhados terão prioridade sobre os Secrets. Ou seja, os Secrets ainda serão incluídos, mas os certificados pré-compartilhados serão apresentados primeiro.
Se nenhum certificado tiver um nome comum que corresponda ao nome de domínio na solicitação do cliente, o balanceador de carga apresentará o certificado principal.
Para os secrets listados no bloco
tls
, o certificado principal está no primeiro secret da lista.Para certificados pré-compartilhados listados na anotação, o certificado principal é o primeiro certificado na lista.
Práticas recomendadas de rotação de certificados
Se você quiser fazer a rotação do conteúdo do certificado (Secret ou pré-compartilhado), veja algumas práticas recomendadas:
- Crie um novo Secret ou certificado pré-compartilhado com um nome diferente que contenha os novos dados do certificado. Anexe esse recurso, com o atual, à Entrada usando as instruções fornecidas anteriormente. Quando as alterações forem finalizadas, será possível remover o certificado antigo da entrada.
- Se você não se importar de interromper o tráfego, poderá remover o recurso antigo da entrada, provisionar um novo recurso com o mesmo nome, mas com conteúdo diferente, e anexá-lo novamente à Entrada.
Para evitar gerenciar a rotação de certificados por conta própria, consulte o recurso SSL gerenciado pelo Google.
Solução de problemas
A especificação de chaves secretas inválidas ou inexistentes resulta em um erro de evento do Kubernetes. Veja os eventos do Kubernetes para verificar se há uma Entrada como esta:
kubectl describe ingress
Esta saída é semelhante a:
Name: my-ingress
Namespace: default
Address: 203.0.113.3
Default backend: hello-server:8080 (10.8.0.3:8080)
TLS:
my-faulty-Secret terminates
Rules:
Host Path Backends
---- ---- --------
* * my-service:443 (10.8.0.3:443)
Events:
Error during sync: cannot get certs for Ingress default/my-ingress:
Secret "my-faulty-ingress" has no 'tls.crt'
A seguir
Leia sobre como usar um objeto Entrada do Kubernetes para configurar um balanceador de carga HTTP(S).
Leia a visão geral da rede do GKE.
Faça o tutorial sobre como configurar o balanceamento de carga HTTP(S) com a Entrada.
Aprenda como configurar um endereço IP estático e um nome de domínio.
Se você tiver um aplicativo em execução em vários clusters do GKE em regiões diferentes, configure um Ingress de vários clusters para rotear o tráfego para um cluster na região mais próxima do usuário.