Configurar o driver CSI do Secrets Store para habilitar o NGINX Ingress Controller com TLS
Este artigo orienta você pelo processo de proteção de um Controlador de Ingresso NGINX com TLS com um cluster do Serviço Kubernetes do Azure (AKS) e uma instância do Azure Key Vault (AKV). Para obter mais informações, consulte TLS no Kubernetes.
Você pode importar o certificado TLS de entrada para o cluster usando um dos seguintes métodos:
- Aplicativo: O manifesto de implantação do aplicativo declara e monta o volume do provedor. Somente quando você implanta o aplicativo é que o certificado é disponibilizado no cluster. Quando você remove o aplicativo, o segredo também é removido. Esse cenário se encaixa nas equipes de desenvolvimento responsáveis pela infraestrutura de segurança do aplicativo e sua integração com o cluster.
- Ingress Controller: A implantação de ingresso é modificada para declarar e montar o volume do provedor. O segredo é importado quando os pods de entrada são criados. Os pods do aplicativo não têm acesso ao certificado TLS. Esse cenário se adapta a cenários em que uma equipe (por exemplo, TI) gerencia e cria componentes de infraestrutura e rede (incluindo certificados HTTPS TLS) e outras equipes gerenciam o ciclo de vida do aplicativo.
Pré-requisitos
- Se não tiver uma subscrição do Azure, crie uma conta gratuita antes de começar.
- Antes de começar, verifique se a versão da CLI do Azure é >=
2.30.0
ou instale a versão mais recente. - Um cluster AKS com o driver CSI do Secrets Store configurado.
- Uma instância do Azure Key Vault.
Gerar um certificado TLS
Gere um certificado TLS usando o seguinte comando.
export CERT_NAME=aks-ingress-cert openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -out aks-ingress-tls.crt \ -keyout aks-ingress-tls.key \ -subj "/CN=demo.azure.com/O=aks-ingress-tls"
Importar o certificado para AKV
Exporte o certificado para um arquivo PFX usando o seguinte comando.
export AKV_NAME="[YOUR AKV NAME]" openssl pkcs12 -export -in aks-ingress-tls.crt -inkey aks-ingress-tls.key -out $CERT_NAME.pfx # skip Password prompt
Importe o certificado usando o
az keyvault certificate import
comando.az keyvault certificate import --vault-name $AKV_NAME --name $CERT_NAME --file $CERT_NAME.pfx
Implantar um SecretProviderClass
Exporte um novo namespace usando o comando a seguir.
export NAMESPACE=ingress-basic
Crie o namespace usando o
kubectl create namespace
comando.kubectl create namespace $NAMESPACE
Selecione um método para fornecer uma identidade de acesso e configure seu YAML SecretProviderClass de acordo.
- Certifique-se de usar
objectType=secret
, que é a única maneira de obter a chave privada e o certificado da AKV. - Defina
kubernetes.io/tls
como otype
na suasecretObjects
seção.
Veja o exemplo a seguir de como seu SecretProviderClass pode parecer:
apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: azure-tls spec: provider: azure secretObjects: # secretObjects defines the desired state of synced K8s secret objects - secretName: ingress-tls-csi type: kubernetes.io/tls data: - objectName: $CERT_NAME key: tls.key - objectName: $CERT_NAME key: tls.crt parameters: usePodIdentity: "false" useVMManagedIdentity: "true" userAssignedIdentityID: <client id> keyvaultName: $AKV_NAME # the name of the AKV instance objects: | array: - | objectName: $CERT_NAME objectType: secret tenantId: $TENANT_ID # the tenant ID of the AKV instance
- Certifique-se de usar
Aplique o SecretProviderClass ao cluster do Kubernetes usando o
kubectl apply
comando.kubectl apply -f secretProviderClass.yaml -n $NAMESPACE
Implantar o controlador de ingresso
Adicione o repositório oficial do gráfico de entrada
Adicione o repositório oficial do gráfico de entrada usando os seguintes
helm
comandos.helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo update
Configurar e implantar a entrada NGINX
Dependendo do cenário, você pode optar por vincular o certificado ao aplicativo ou ao controlador de entrada. Siga as instruções abaixo de acordo com a sua seleção:
Vincular certificado ao aplicativo
Vincule o certificado ao aplicativo usando o
helm install
comando. A implantação do aplicativo faz referência ao provedor do Azure Key Vault do Driver CSI do Secrets Store.helm install ingress-nginx/ingress-nginx --generate-name \ --namespace $NAMESPACE \ --set controller.replicaCount=2 \ --set controller.nodeSelector."kubernetes\.io/os"=linux \ --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-health-probe-request-path"=/healthz \ --set defaultBackend.nodeSelector."kubernetes\.io/os"=linux
Vincular certificado ao controlador de ingresso
Vincule o certificado ao controlador de entrada usando o
helm install
comando. A implantação do controlador de ingresso faz referência ao provedor do Azure Key Vault do Driver CSI do Secrets Store.Nota
Se não estiver usando a identidade gerenciada pelo pod do Microsoft Entra como método de acesso, remova a linha com
--set controller.podLabels.aadpodidbinding=$AAD_POD_IDENTITY_NAME
.Além disso, vincular o SecretProviderClass a um pod é necessário para que o driver CSI do Secrets Store o monte e gere o segredo do Kubernetes. Consulte Sincronizar conteúdo montado com um segredo do Kubernetes .
helm install ingress-nginx/ingress-nginx --generate-name \ --namespace $NAMESPACE \ --set controller.replicaCount=2 \ --set controller.nodeSelector."kubernetes\.io/os"=linux \ --set defaultBackend.nodeSelector."kubernetes\.io/os"=linux \ --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-health-probe-request-path"=/healthz \ --set controller.podLabels.aadpodidbinding=$AAD_POD_IDENTITY_NAME \ -f - <<EOF controller: extraVolumes: - name: secrets-store-inline csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: "azure-tls" extraVolumeMounts: - name: secrets-store-inline mountPath: "/mnt/secrets-store" readOnly: true EOF
Verifique se o segredo do Kubernetes foi criado usando o
kubectl get secret
comando.kubectl get secret -n $NAMESPACE NAME TYPE DATA AGE ingress-tls-csi kubernetes.io/tls 2 1m34s
Implementar a aplicação
Novamente, as instruções mudam ligeiramente dependendo do seu cenário. Siga as instruções correspondentes ao cenário selecionado.
Implantar o aplicativo usando uma referência de aplicativo
Crie um arquivo nomeado
aks-helloworld-one.yaml
com o seguinte conteúdo.apiVersion: apps/v1 kind: Deployment metadata: name: aks-helloworld-one spec: replicas: 1 selector: matchLabels: app: aks-helloworld-one template: metadata: labels: app: aks-helloworld-one spec: containers: - name: aks-helloworld-one image: mcr.microsoft.com/azuredocs/aks-helloworld:v1 ports: - containerPort: 80 env: - name: TITLE value: "Welcome to Azure Kubernetes Service (AKS)" volumeMounts: - name: secrets-store-inline mountPath: "/mnt/secrets-store" readOnly: true volumes: - name: secrets-store-inline csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: "azure-tls" --- apiVersion: v1 kind: Service metadata: name: aks-helloworld-one spec: type: ClusterIP ports: - port: 80 selector: app: aks-helloworld-one
Crie um arquivo nomeado
aks-helloworld-two.yaml
com o seguinte conteúdo.apiVersion: apps/v1 kind: Deployment metadata: name: aks-helloworld-two spec: replicas: 1 selector: matchLabels: app: aks-helloworld-two template: metadata: labels: app: aks-helloworld-two spec: containers: - name: aks-helloworld-two image: mcr.microsoft.com/azuredocs/aks-helloworld:v1 ports: - containerPort: 80 env: - name: TITLE value: "AKS Ingress Demo" volumeMounts: - name: secrets-store-inline mountPath: "/mnt/secrets-store" readOnly: true volumes: - name: secrets-store-inline csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: "azure-tls" --- apiVersion: v1 kind: Service metadata: name: aks-helloworld-two spec: type: ClusterIP ports: - port: 80 selector: app: aks-helloworld-two
Aplique os arquivos YAML ao cluster usando o
kubectl apply
comando.kubectl apply -f aks-helloworld-one.yaml -n $NAMESPACE kubectl apply -f aks-helloworld-two.yaml -n $NAMESPACE
Verifique se o segredo do Kubernetes foi criado usando o
kubectl get secret
comando.kubectl get secret -n $NAMESPACE NAME TYPE DATA AGE ingress-tls-csi kubernetes.io/tls 2 1m34s
Implantar o aplicativo usando uma referência de controlador de entrada
Crie um arquivo nomeado
aks-helloworld-one.yaml
com o seguinte conteúdo.apiVersion: apps/v1 kind: Deployment metadata: name: aks-helloworld-one spec: replicas: 1 selector: matchLabels: app: aks-helloworld-one template: metadata: labels: app: aks-helloworld-one spec: containers: - name: aks-helloworld-one image: mcr.microsoft.com/azuredocs/aks-helloworld:v1 ports: - containerPort: 80 env: - name: TITLE value: "Welcome to Azure Kubernetes Service (AKS)" --- apiVersion: v1 kind: Service metadata: name: aks-helloworld-one spec: type: ClusterIP ports: - port: 80 selector: app: aks-helloworld-one
Crie um arquivo nomeado
aks-helloworld-two.yaml
com o seguinte conteúdo.apiVersion: apps/v1 kind: Deployment metadata: name: aks-helloworld-two spec: replicas: 1 selector: matchLabels: app: aks-helloworld-two template: metadata: labels: app: aks-helloworld-two spec: containers: - name: aks-helloworld-two image: mcr.microsoft.com/azuredocs/aks-helloworld:v1 ports: - containerPort: 80 env: - name: TITLE value: "AKS Ingress Demo" --- apiVersion: v1 kind: Service metadata: name: aks-helloworld-two spec: type: ClusterIP ports: - port: 80 selector: app: aks-helloworld-two
Aplique os arquivos YAML ao cluster usando o
kubectl apply
comando.kubectl apply -f aks-helloworld-one.yaml -n $NAMESPACE kubectl apply -f aks-helloworld-two.yaml -n $NAMESPACE
Implantar um recurso de entrada fazendo referência ao segredo
Agora podemos implantar um recurso de ingresso do Kubernetes fazendo referência ao segredo.
Crie um nome
hello-world-ingress.yaml
de arquivo com o seguinte conteúdo.apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-tls annotations: nginx.ingress.kubernetes.io/rewrite-target: /$2 spec: ingressClassName: nginx tls: - hosts: - demo.azure.com secretName: ingress-tls-csi rules: - host: demo.azure.com http: paths: - path: /hello-world-one(/|$)(.*) pathType: Prefix backend: service: name: aks-helloworld-one port: number: 80 - path: /hello-world-two(/|$)(.*) pathType: Prefix backend: service: name: aks-helloworld-two port: number: 80 - path: /(.*) pathType: Prefix backend: service: name: aks-helloworld-one port: number: 80
Anote a
tls
seção que faz referência ao segredo criado anteriormente e aplique o arquivo ao cluster usando okubectl apply
comando.kubectl apply -f hello-world-ingress.yaml -n $NAMESPACE
Obter o endereço IP externo do controlador de entrada
Obtenha o endereço IP externo para o controlador de entrada usando o
kubectl get service
comando.kubectl get service --namespace $NAMESPACE --selector app.kubernetes.io/name=ingress-nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-ingress-1588032400-controller LoadBalancer 10.0.255.157 EXTERNAL_IP 80:31293/TCP,443:31265/TCP 19m nginx-ingress-1588032400-default-backend ClusterIP 10.0.223.214 <none> 80/TCP 19m
Ingresso de teste protegido com TLS
Verifique se sua entrada está configurada corretamente com TLS usando o comando a seguir
curl
. Certifique-se de usar o IP externo da etapa anterior.curl -v -k --resolve demo.azure.com:443:EXTERNAL_IP https://demo.azure.com
Como outro caminho não foi fornecido com o endereço, o controlador de entrada assume como padrão a / rota. O primeiro aplicativo de demonstração é retornado, como mostrado na seguinte saída de exemplo condensado:
[...] <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <link rel="stylesheet" type="text/css" href="/static/default.css"> <title>Welcome to Azure Kubernetes Service (AKS)</title> [...]
O parâmetro -v no
curl
comando produz informações detalhadas, incluindo o certificado TLS recebido. Na metade da saída de ondulação, você pode verificar se seu próprio certificado TLS foi usado. O parâmetro -k continua carregando a página mesmo que estejamos usando um certificado autoassinado. O exemplo a seguir mostra o emissor: CN=demo.azure.com; O=aks-ingress-tls foi utilizado certificado:[...] * Server certificate: * subject: CN=demo.azure.com; O=aks-ingress-tls * start date: Oct 22 22:13:54 2021 GMT * expire date: Oct 22 22:13:54 2022 GMT * issuer: CN=demo.azure.com; O=aks-ingress-tls * SSL certificate verify result: self signed certificate (18), continuing anyway. [...]
Adicione o caminho /hello-world-two ao endereço, como
https://demo.azure.com/hello-world-two
, e verifique se o segundo aplicativo de demonstração está configurado corretamente.curl -v -k --resolve demo.azure.com:443:EXTERNAL_IP https://demo.azure.com/hello-world-two
O segundo aplicativo de demonstração com o título personalizado é retornado, conforme mostrado na seguinte saída de exemplo condensado:
[...] <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <link rel="stylesheet" type="text/css" href="/static/default.css"> <title>AKS Ingress Demo</title> [...]
Azure Kubernetes Service
Comentários
https://aka.ms/ContentUserFeedback.
Brevemente: Ao longo de 2024, vamos descontinuar progressivamente o GitHub Issues como mecanismo de feedback para conteúdos e substituí-lo por um novo sistema de feedback. Para obter mais informações, veja:Submeter e ver comentários