Provisionando Balanceadores de Carga do OCI para Serviços do Kubernetes do Tipo LoadBalancer
Descubra como provisionar um balanceador de carga do OCI para um serviço Kubernetes do tipo LoadBalancer usando o Kubernetes Engine (OKE).
Um balanceador de carga do OCI é um proxy da camada 4 (TCP) e da camada 7 (HTTP) do OSI, que suporta recursos como encerramento de SSL e políticas avançadas de roteamento HTTP. Ele oferece a máxima flexibilidade, com escalonamento responsivo para cima e para baixo. Você escolhe uma largura de banda mínima personalizada e uma largura de banda máxima opcional, entre 10 Mbps e 8.000 Mbps. A largura de banda mínima está sempre disponível e fornece prontidão instantânea para suas cargas de trabalho.
Para obter mais informações sobre balanceadores de carga do OCI, consulte Visão Geral do Serviço Load Balancer.
O provisionamento de um balanceador de carga do OCI para um serviço do Kubernetes do tipo LoadBalancer permite:
- tráfego da camada 4 e da camada 7 (TCP e HTTP) de transporte de balanceamento de carga
- encerrar SSL/TLS no balanceador de carga
Observe que, quando o Kubernetes Engine provisiona um balanceador de carga do OCI para um serviço Kubernetes do tipo LoadBalancer, as regras de segurança para permitir tráfego de entrada e saída de e para a sub-rede do balanceador de carga são criadas automaticamente por padrão. Consulte Regras de Segurança para Balanceadores de Carga e Balanceadores de Carga de Rede.
Use métricas do balanceador de carga do OCI para monitorar a integridade de um balanceador de carga do OCI provisionado para um serviço Kubernetes do tipo LoadBalancer (consulte Métricas do Serviço Load Balancer).
Especificando a Anotação para um Balanceador de Carga do OCI
oci.oraclecloud.com/load-balancer-type: "lb"
Observe que lb
é o valor padrão da anotação oci.oraclecloud.com/load-balancer-type
. Se você não incluir explicitamente a anotação na definição de serviço, o valor padrão da anotação será usado.
Por exemplo, considere o seguinte arquivo de configuração, nginx_lb.yaml
. Ele define uma implantação (kind: Deployment
) para o aplicativo nginx
, seguida de uma definição de um serviço do tipo LoadBalancer (type: LoadBalancer
) que equilibra o tráfego http na porta 80 para o aplicativo nginx
.
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: my-nginx-svc
labels:
app: nginx
annotations:
oci.oraclecloud.com/load-balancer-type: "lb"
spec:
type: LoadBalancer
ports:
- port: 80
selector:
app: nginx
A primeira parte do arquivo de configuração define uma implantação Nginx, solicitando que ele seja hospedado em 3 pods executando a imagem nginx:latest
e aceite o tráfego para os contêineres na porta 80.
A segunda parte do arquivo de configuração define o serviço Nginx, que usa o tipo LoadBalancer para equilibrar o tráfego Nginx na porta 80 entre os pods disponíveis.
Para criar a implantação e o serviço definidos em nginx_lb.yaml
enquanto estiver conectado ao cluster do Kubernetes, digite o comando:
kubectl apply -f nginx_lb.yaml
Esse comando gera o seguinte após a criação bem-sucedida da implantação e do balanceador de carga:
deployment "my-nginx" created
service "my-nginx-svc" created
O balanceador de carga pode levar alguns minutos para passar do estado pendente para totalmente operacional. Você pode exibir o estado atual do cluster digitando:
kubectl get all
A saída do comando acima mostra o estado atual:
NAME READY STATUS RESTARTS AGE
po/my-nginx-431080787-0m4m8 1/1 Running 0 3m
po/my-nginx-431080787-hqqcr 1/1 Running 0 3m
po/my-nginx-431080787-n8125 1/1 Running 0 3m
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc/kubernetes 203.0.113.1 <NONE> 443/TCP 3d
svc/my-nginx-svc 203.0.113.7 192.0.2.22 80:30269/TCP 3m
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deploy/my-nginx 3 3 3 3 3m
NAME DESIRED CURRENT READY AGE
rs/my-nginx-431080787 3 3 3 3m
A saída mostra que a implantação my-nginx
está em execução em 3 pods (as entradas po/my-nginx), que o balanceador de carga está em execução (svc/my-nginx-svc) e tem um IP externo (192.0.2.22) que os clientes podem usar para estabelecer conexão com o aplicativo que está implantado nos pods.
Encerrando SSL/TLS no Balanceador de Carga
Quando o Kubernetes Engine provisiona um balanceador de carga para um serviço do Kubernetes do tipo LoadBalancer, você pode especificar que deseja encerrar a SSL no balanceador de carga. Essa configuração é conhecida como SSL frontend. Para implementar o SSL frontend, defina um listener em uma porta como 443 e associe um certificado SSL ao listener.
Observe que você pode implementar criptografia SSL ponto a ponto completa entre clientes e pods de aplicativos em execução nos nós de trabalho. Para fazer isso, crie um balanceador de carga com encerramento de SSL (conforme descrito nesta seção) e também associe um certificado SSL ao conjunto de backend do balanceador de carga (consulte Implementação de SSL/TLS entre o Balanceador de Carga e os Nós de Trabalho).
Este exemplo fornece um passo a passo da configuração e criação de um balanceador de carga com suporte a SSL.
Considere o seguinte arquivo de configuração, nginx-demo-svc-ssl.yaml
, que define uma implantação Nginx e a expõe por meio de um balanceador de carga que fornece http na porta 80, e https na porta 443. Esta amostra cria um balanceador de carga do Oracle Cloud Infrastructure, definindo um serviço com um tipo de LoadBalancer (type: LoadBalancer
).
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
name: nginx-service
annotations:
oci.oraclecloud.com/load-balancer-type: "lb"
service.beta.kubernetes.io/oci-load-balancer-ssl-ports: "443"
service.beta.kubernetes.io/oci-load-balancer-tls-secret: ssl-certificate-secret
spec:
selector:
app: nginx
type: LoadBalancer
ports:
- name: http
port: 80
targetPort: 80
- name: https
port: 443
targetPort: 80
As anotações do Balanceador de Carga são de particular importância. As portas nas quais há suporte para o tráfego https são definidas pelo valor service.beta.kubernetes.io/oci-load-balancer-ssl-ports. É possível declarar várias portas SSL usando uma lista separada por vírgulas para o valor da anotação. Por exemplo, você pode definir o valor da anotação como "443, 3000" para oferecer suporte a SSL nas portas 443 e 3000.
O segredo TLS necessário, ssl-certificate-secret, precisa ser criado no Kubernetes. Este exemplo cria e usa um certificado autoassinado. No entanto, em um ambiente de produção, o cenário mais comum é usar um certificado público que tenha sido assinado por uma autoridade de certificação.
O comando a seguir cria um certificado autoassinado, tls.crt
, com sua chave correspondente, tls.key
:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"
Agora que você criou o certificado, precisa armazená-lo e também sua respectiva chave como um segredo no Kubernetes. O nome do segredo deve corresponder ao nome da anotação service.beta.kubernetes.io/oci-load-balancer-tls-secret da definição do balanceador de carga. Use o comando a seguir para criar um segredo do TLS no Kubernetes, cujos valores de chave e certificado são definidos por --key
e --cert
, respectivamente.
kubectl create secret tls ssl-certificate-secret --key tls.key --cert tls.crt
Você deve criar o segredo Kubernetes antes de criar o serviço, pois ele faz referência ao segredo em sua definição. Crie o serviço usando o seguinte comando:
kubectl create -f manifests/demo/nginx-demo-svc-ssl.yaml
Observe o serviço e aguarde que um endereço IP público (EXTERNAL-IP) seja designado ao serviço Nginx (nginx-service) digitando:
kubectl get svc --watch
A saída do comando acima mostra o IP do balanceador de carga a ser usado para estabelecer conexão com o serviço.
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-service 192.0.2.1 198.51.100.1 80:30274/TCP 5m
O balanceador de carga agora está em execução, o que significa que o serviço agora pode ser acessado da seguinte maneira:
- usando http, digitando:
curl http://198.51.100.1
- usando https, digitando:
curl --insecure https://198.51.100.1
O flag "
--insecure
" é usado para acessar o serviço usando https em decorrência do uso de certificados autoassinados neste exemplo. Não use esse flag em um ambiente de produção no qual o certificado público tenha sido assinado por uma autoridade de certificação.
Observação: Quando um cluster é excluído, um balanceador de carga criado de forma dinâmica quando um serviço é criado não será removido. Antes de excluir um cluster, exclua o serviço, o que, por sua vez, resultará na remoção do balanceador de carga. A sintaxe desse comando é a seguinte:
kubectl delete svc SERVICE_NAME
Por exemplo, para excluir o serviço do exemplo anterior, digite:
kubectl delete svc nginx-service
Atualizando os Certificados TLS dos Balanceadores de Carga Existentes
- Obtenha um novo certificado TLS. Em um ambiente de produção, o cenário mais comum é usar um certificado público que tenha sido assinado por uma autoridade de certificação.
-
Crie um novo segredo do Kubernetes. Por exemplo, informando:
kubectl create secret tls new-ssl-certificate-secret --key new-tls.key --cert new-tls.crt
- Modifique a definição de serviço para referenciar o novo segredo do Kubernetes alterando a anotação
service.beta.kubernetes.io/oci-load-balancer-tls-secret
na configuração do serviço. Por exemplo:apiVersion: v1 kind: Service metadata: name: nginx-service annotations: service.beta.kubernetes.io/oci-load-balancer-ssl-ports: "443" service.beta.kubernetes.io/oci-load-balancer-tls-secret: new-ssl-certificate-secret spec: selector: app: nginx type: LoadBalancer ports: - name: http port: 80 targetPort: 80 - name: https port: 443 targetPort: 80
- Atualize o serviço. Por exemplo, informando:
kubectl apply -f new-nginx-demo-svc-ssl.yaml
Implementando SSL/TLS entre o Balanceador de Carga e os Nós de Trabalho
Quando o Kubernetes Engine provisiona um balanceador de carga para um serviço do Kubernetes do tipo LoadBalancer, você pode especificar que deseja implementar SSL entre o balanceador de carga e os servidores de backend (nós do colaborador) no conjunto de backend. Essa configuração é conhecida como SSL de backend. Para implementar SSL de backend, associe um certificado SSL ao conjunto de backend do balanceador de carga.
Observe que você pode implementar criptografia SSL ponto a ponto completa entre clientes e pods de aplicativos em execução nos nós de trabalho. Para fazer isso, associe um certificado SSL ao conjunto de backend do balanceador de carga (conforme descrito nesta seção) e também crie um balanceador de carga com encerramento de SSL (consulte Encerrando SSL/TLS no Balanceador de Carga).
Para especificar o certificado a ser associado ao conjunto de backend, adicione a seguinte anotação na seção de metadados do arquivo de manifesto:
service.beta.kubernetes.io/oci-load-balancer-tls-backendset-secret: <value>
em que <value>
é o nome de um segredo do Kubernetes que você criou para conter um certificado assinado e a chave privada do certificado. Observe que você deve criar o segredo Kubernetes antes de criar o serviço, pois ele faz referência ao segredo em sua definição.
O exemplo a seguir cria e usa um certificado autoassinado, que geralmente é aceitável para comunicação interna entre o balanceador de carga e o conjunto de backend. No entanto, se preferir, pode usar um certificado público que tenha sido assinado por uma autoridade de certificação.
Por exemplo:
Gere uma chave privada informando:
openssl genrsa -out ca.key 2048
Gere um certificado digitando:
openssl req -x509 -new -nodes -key ca.key -subj "/CN=nginxsvc/O=nginxsvc" -days 10000 -out ca.crt
Armazene o certificado e a chave como segredo no Kubernetes digitando:
kubectl create secret generic ca-ser-secret --from-file=tls.crt=tls.crt --from-file=tls.key=tls.key --from-file=ca.crt=ca.crt
- Defina uma implantação do Nginx e exponha-a por meio de um balanceador de carga que serve http na porta 80 e https na porta 443. Esta amostra cria um balanceador de carga do Oracle Cloud Infrastructure, definindo um serviço com um tipo de LoadBalancer
(type: LoadBalancer
).apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80 --- apiVersion: v1 metadata: name: nginx-service annotations: oci.oraclecloud.com/load-balancer-type: "lb" service.beta.kubernetes.io/oci-load-balancer-tls-backendset-secret: ca-ser-secret service.beta.kubernetes.io/oci-load-balancer-ssl-ports: "443" spec: selector: app: nginx type: LoadBalancer ports: - name: http port: 80 targetPort: 80 - name: https port: 443 targetPort: 443
A comunicação entre o balanceador de carga e os nós de trabalho no conjunto de backend é criptografada usando a chave e o certificado armazenados no segredo do Kubernetes ca-ser-secret
criado anteriormente.
Especificando Formas Alternativas de Balanceador de Carga
A forma de um balanceador de carga do Oracle Cloud Infrastructure especifica sua largura de banda total máxima (ou seja, entrada e saída). Por padrão, os balanceadores de carga são criados com uma forma de 100 Mbps. Outras formas estão disponíveis, incluindo 400 Mbps e 8.000 Mbps.
Para especificar uma forma alternativa para um balanceador de carga, adicione a seguinte anotação na seção de metadados do arquivo de manifesto:
service.beta.kubernetes.io/oci-load-balancer-shape: <value>
em que value
corresponde à largura de banda da forma (por exemplo, 100 Mbps, 400 Mbps, 8.000 Mbps).
Por exemplo:
apiVersion: v1
kind: Service
metadata:
name: my-nginx-svc
labels:
app: nginx
annotations:
oci.oraclecloud.com/load-balancer-type: "lb"
service.beta.kubernetes.io/oci-load-balancer-shape: 400Mbps
spec:
type: LoadBalancer
ports:
- port: 80
selector:
app: nginx
A cota suficiente do balanceador de carga deve estar disponível na região para a forma especificada. Digite o seguinte comando kubectl para confirmar que a criação do balanceador de carga não falhou devido à falta de cota:
kubectl describe service <service-name>
Observe que a Oracle recomenda que você implemente serviços do Kubernetes do tipo LoadBalancer como balanceadores de carga flexíveis econômicos, em vez de como balanceadores de carga de forma fixa (dinâmicos) (consulte Especificando Formas Flexíveis do Balanceador de Carga).
Especificando Formas Flexíveis de Balanceador de Carga
A forma de um balanceador de carga do Oracle Cloud Infrastructure especifica sua largura de banda total máxima (ou seja, entrada e saída). Conforme descrito em Especificando Formas Alternativas de Balanceador de Carga, você pode especificar diferentes formas de balanceador de carga.
Além disso, você também pode especificar uma forma flexível para um balanceador de carga do Oracle Cloud Infrastructure, definindo uma largura de banda mínima e máxima para o balanceador de carga.
Para especificar uma forma flexível para um balanceador de carga, adicione as seguintes anotações na seção de metadados do arquivo de manifesto:
service.beta.kubernetes.io/oci-load-balancer-shape: "flexible"
service.beta.kubernetes.io/oci-load-balancer-shape-flex-min: "<min-value>"
service.beta.kubernetes.io/oci-load-balancer-shape-flex-max: "<max-value>"
em que:
"<min-value>"
é a largura de banda mínima do balanceador de carga, em Mbps (por exemplo, "10")"<max-value>"
é a largura de banda máxima do balanceador de carga, em Mbps (por exemplo, "100")
Observe que você não inclui uma unidade de medida ao especificar valores de largura de banda para formas flexíveis de balanceador de carga (ao contrário de formas predefinidas). Por exemplo, especifique a largura de banda mínima como 10
, não como 10Mbps
.
Por exemplo:
apiVersion: v1
kind: Service
metadata:
name: my-nginx-svc
labels:
app: nginx
annotations:
oci.oraclecloud.com/load-balancer-type: "lb"
service.beta.kubernetes.io/oci-load-balancer-shape: "flexible"
service.beta.kubernetes.io/oci-load-balancer-shape-flex-min: "10"
service.beta.kubernetes.io/oci-load-balancer-shape-flex-max: "100"
spec:
type: LoadBalancer
ports:
- port: 80
selector:
app: nginx
Especificando o Timeout de Conexão do Balanceador de Carga
Ao provisionar um balanceador de carga do Oracle Cloud Infrastructure para um serviço Kubernetes do tipo LoadBalancer, você pode especificar o tempo máximo de inatividade (em segundos) permitido entre duas operações de recebimento sucessivas ou duas operações de envio sucessivas entre o cliente e os servidores de backend.
Para especificar explicitamente um tempo máximo de inatividade, adicione a seguinte anotação na seção de metadados do arquivo de manifesto:
service.beta.kubernetes.io/oci-load-balancer-connection-idle-timeout: <value>
em que value
corresponde ao número de segundos.
Por exemplo:
apiVersion: v1
kind: Service
metadata:
name: my-nginx-svc
labels:
app: nginx
annotations:
oci.oraclecloud.com/load-balancer-type: "lb"
service.beta.kubernetes.io/oci-load-balancer-connection-idle-timeout: 100
spec:
type: LoadBalancer
ports:
- port: 80
selector:
app: nginx
Observe que, se você não especificar explicitamente um tempo máximo de inatividade, será usado um valor padrão. O valor padrão depende do tipo de listener:
- para listeners TCP, o tempo máximo de inatividade padrão é de 300 segundos
- para listeners HTTP, o tempo máximo de inatividade padrão é de 60 segundos
Especificando Protocolos de Listener
Quando o Kubernetes Engine provisiona um balanceador de carga para um serviço do Kubernetes do tipo LoadBalancer, você pode definir o tipo de tráfego aceito pelo listener especificando o protocolo no qual o listener aceita solicitações de conexão.
Observe que, se você não especificar explicitamente um protocolo, "TCP" será usado como o valor padrão.
Para especificar explicitamente o protocolo de listener do balanceador de carga quando o Kubernetes Engine provisionar um balanceador de carga para um serviço Kubernetes do tipo LoadBalancer, adicione a seguinte anotação na seção de metadados do arquivo de manifesto:
service.beta.kubernetes.io/oci-load-balancer-backend-protocol: <value>
em que <value>
corresponde ao protocolo que define o tipo de tráfego aceito pelo listener. Por exemplo, "HTTP". Protocolos válidos incluem "HTTP" e "TCP".
Por exemplo:
apiVersion: v1
kind: Service
metadata:
name: my-nginx-svc
labels:
app: nginx
annotations:
oci.oraclecloud.com/load-balancer-type: "lb"
service.beta.kubernetes.io/oci-load-balancer-backend-protocol: "HTTP"
spec:
type: LoadBalancer
ports:
- port: 80
selector:
app: nginx
Especificando Opções de Gerenciamento da Lista de Segurança ao Provisionar um Balanceador de Carga do OCI
Você poderá encontrar problemas de escalabilidade e outros problemas se usar o recurso de gerenciamento de lista de segurança do Kubernetes em implantações complexas e com ferramentas como o Terraform. Por esses motivos, a Oracle não recomenda o uso do recurso de gerenciamento de lista de segurança do Kubernetes em ambientes de produção.
Observe também que a capacidade de usar listas de segurança para gerenciar regras de segurança será descontinuada em uma release futura. Por esse motivo, a Oracle recomenda o uso de grupos de segurança de rede (NSGs) e a anotação oci.oraclecloud.com/security-rule-management-mode
(consulte Especificando Opções de Gerenciamento de Regra de Segurança para Balanceadores de Carga e Balanceadores de Carga de Rede).
Você pode usar o recurso de gerenciamento de listas de segurança para configurar como as regras de lista de segurança são gerenciadas para um balanceador de carga do Oracle Cloud Infrastructure que o Kubernetes Engine provisiona para um serviço Kubernetes do tipo LoadBalancer. Esse recurso será útil se você for novo no Kubernetes ou para implantações básicas.
Para especificar como o recurso de gerenciamento de lista de segurança do Kubernetes gerencia listas de segurança quando o Kubernetes Engine provisiona um balanceador de carga para um serviço do Kubernetes do tipo LoadBalancer, adicione a seguinte anotação na seção de metadados do arquivo de manifesto:
service.beta.kubernetes.io/oci-load-balancer-security-list-management-mode: <value>
em que <value>
é um dos seguintes:
"None"
: (recomendado) Nenhum gerenciamento da lista de segurança está ativado. Você precisa configurar uma regra de segurança que permita o tráfego de entrada para as portas apropriadas para intervalos de portas de nó, porta de saúde kube-proxy e intervalos de portas de verificação de integridade. Além disso, você precisa configurar regras de segurança para permitir o tráfego de entrada para balanceadores de carga (consulte Regras de Segurança para Balanceadores de Carga e Balanceadores de Carga de Rede)."All"
: (padrão) Todas as regras obrigatórias da lista de segurança para os serviços do balanceador de carga são gerenciadas."Frontend"
: Somente as regras da lista de segurança para entrada nos serviços do balanceador de carga são gerenciadas. Você precisa configurar uma regra de segurança que permita o tráfego de entrada para as portas apropriadas para intervalos de portas de nó, porta de saúde kube-proxy e intervalos de portas de verificação de integridade.
A Oracle recomenda que você defina explicitamente service.beta.kubernetes.io/oci-load-balancer-security-list-management-mode
como None
.
Em clusters com nós gerenciados, se você não especificar explicitamente um modo de gerenciamento ou especificar um valor inválido, todas as regras da lista de segurança serão gerenciadas (equivalente a "All"
). Esteja ciente de que, nesse caso, o Kubernetes Engine cria uma regra de segurança que permite o tráfego de entrada de 0.0.0.0/0 (ou dos intervalos de portas de origem especificados no arquivo de manifesto) para portas de listener. Em clusters com nós virtuais, o gerenciamento da lista de segurança nunca é ativado e você sempre precisa configurar manualmente as regras de segurança (equivalente a "None"
).
Observe que há limites para o número de regras de entrada e saída permitidas em uma lista de segurança (consulte Limites da Lista de Segurança). Se o número de regras de entrada ou saída exceder o limite e <value>
for definido como "All"
ou "Frontend"
, a criação ou atualização do balanceador de carga falhará.
Por exemplo:
apiVersion: v1
kind: Service
metadata:
name: my-nginx-svc
labels:
app: nginx
annotations:
oci.oraclecloud.com/load-balancer-type: "lb"
service.beta.kubernetes.io/oci-load-balancer-security-list-management-mode: "Frontend"
spec:
type: LoadBalancer
ports:
- port: 80
selector:
app: nginx