Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
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 ingress é modificada para declarar e montar o volume do provedor. O segredo é importado quando os pods de entrada são criados. Os pods da aplicação não têm acesso ao certificado TLS. Esse cenário se encaixa em 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.
Prerequisites
- 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.0ou instale a versão mais recente. - Um cluster AKS com o Secrets Store CSI Driver 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 promptImporte o certificado usando o
az keyvault certificate importcomando.az keyvault certificate import --vault-name $AKV_NAME --name $CERT_NAME --file $CERT_NAME.pfx
Implantar uma SecretProviderClass
Exporte um novo namespace usando o comando a seguir.
export NAMESPACE=ingress-basicCrie o namespace usando o
kubectl create namespacecomando.kubectl create namespace $NAMESPACESelecione 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/tlscomo otypena suasecretObjectsseçã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 applycomando.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
helmcomandos.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 installcomando. A implantação do aplicativo faz referência ao fornecedor Key Vault da Azure do Driver CSI da 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 installcomando. A implantação do controlador de ingresso faz referência ao provedor do Azure Key Vault do Driver CSI do Secrets Store.Note
Se não estiver usando a identidade gerenciada pelo pod do Microsoft Entra como seu 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. Veja 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 EOFVerifique se o segredo do Kubernetes foi criado usando o
kubectl get secretcomando.kubectl get secret -n $NAMESPACE NAME TYPE DATA AGE ingress-tls-csi kubernetes.io/tls 2 1m34s
Implementar a aplicação
Mais uma vez, 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.yamlcom 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-oneCrie um arquivo nomeado
aks-helloworld-two.yamlcom 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-twoAplique os arquivos YAML ao cluster usando o
kubectl applycomando.kubectl apply -f aks-helloworld-one.yaml -n $NAMESPACE kubectl apply -f aks-helloworld-two.yaml -n $NAMESPACEVerifique se o segredo do Kubernetes foi criado usando o
kubectl get secretcomando.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.yamlcom 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-oneCrie um arquivo nomeado
aks-helloworld-two.yamlcom 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-twoAplique os arquivos YAML ao cluster usando o
kubectl applycomando.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.yamlde 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: 80Anote a
tlsseção que faz referência ao segredo criado anteriormente e aplique o arquivo ao cluster usando okubectl applycomando.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 servicecomando.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.comComo 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 do comando
curlproduz 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 que o certificado com o emissor: CN=demo.azure.com; O=aks-ingress-tls foi utilizado:[...] * 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-twoO 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> [...]