Konfigurowanie sterownika CSI magazynu wpisów tajnych w celu włączenia kontrolera ruchu przychodzącego NGINX za pomocą protokołu TLS
W tym artykule przedstawiono proces zabezpieczania kontrolera ruchu przychodzącego NGINX przy użyciu protokołu TLS z klastrem usługi Azure Kubernetes Service (AKS) i wystąpieniem usługi Azure Key Vault (AKV). Aby uzyskać więcej informacji, zobacz TLS w rozwiązaniu Kubernetes.
Certyfikat TLS ruchu przychodzącego można zaimportować do klastra przy użyciu jednej z następujących metod:
- Aplikacja: manifest wdrożenia aplikacji deklaruje i instaluje wolumin dostawcy. Tylko podczas wdrażania aplikacji jest certyfikat udostępniony w klastrze. Usunięcie aplikacji spowoduje również usunięcie wpisu tajnego. Ten scenariusz pasuje do zespołów programistycznych odpowiedzialnych za infrastrukturę zabezpieczeń aplikacji i jej integrację z klastrem.
- Kontroler ruchu przychodzącego: wdrożenie ruchu przychodzącego jest modyfikowane w celu deklarowania i instalowania woluminu dostawcy. Wpis tajny jest importowany podczas tworzenia zasobników ruchu przychodzącego. Zasobniki aplikacji nie mają dostępu do certyfikatu TLS. Ten scenariusz pasuje do scenariuszy, w których jeden zespół (na przykład IT) zarządza i tworzy składniki infrastruktury i sieci (w tym certyfikaty PROTOKOŁU TLS PROTOKOŁU HTTPS) i inne zespoły zarządzają cyklem życia aplikacji.
Wymagania wstępne
- Jeśli nie masz subskrypcji platformy Azure, przed rozpoczęciem utwórz bezpłatne konto.
- Przed rozpoczęciem upewnij się, że wersja interfejsu wiersza polecenia platformy Azure to >=
2.30.0
lub zainstaluj najnowszą wersję. - Klaster usługi AKS ze skonfigurowanym sterownikiem CSI magazynu wpisów tajnych.
- Wystąpienie usługi Azure Key Vault.
Generowanie certyfikatu TLS
Wygeneruj certyfikat TLS przy użyciu następującego polecenia.
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"
Importowanie certyfikatu do usługi AKV
Wyeksportuj certyfikat do pliku PFX przy użyciu następującego polecenia.
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
Zaimportuj
az keyvault certificate import
certyfikat przy użyciu polecenia .az keyvault certificate import --vault-name $AKV_NAME --name $CERT_NAME --file $CERT_NAME.pfx
Wdrażanie klasy SecretProviderClass
Wyeksportuj nową przestrzeń nazw przy użyciu następującego polecenia.
export NAMESPACE=ingress-basic
Utwórz przestrzeń nazw przy użyciu
kubectl create namespace
polecenia .kubectl create namespace $NAMESPACE
Wybierz metodę , aby zapewnić tożsamość dostępu i odpowiednio skonfigurować klucz YAML SecretProviderClass.
- Pamiętaj, aby użyć metody
objectType=secret
, która jest jedynym sposobem uzyskania klucza prywatnego i certyfikatu z usługi AKV. - Ustaw
kubernetes.io/tls
jako elementtype
wsecretObjects
sekcji .
Zapoznaj się z poniższym przykładem tego, jak może wyglądać klasa SecretProviderClass:
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
- Pamiętaj, aby użyć metody
Zastosuj klasę SecretProviderClass do klastra Kubernetes przy użyciu
kubectl apply
polecenia .kubectl apply -f secretProviderClass.yaml -n $NAMESPACE
Wdrażanie kontrolera ruchu przychodzącego
Dodawanie oficjalnego repozytorium wykresu przychodzącego
Dodaj oficjalne repozytorium wykresów przychodzących przy użyciu następujących
helm
poleceń.helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo update
Konfigurowanie i wdrażanie ruchu przychodzącego NGINX
W zależności od scenariusza można powiązać certyfikat z aplikacją lub z kontrolerem ruchu przychodzącego. Postępuj zgodnie z poniższymi instrukcjami zgodnie z wyborem:
Wiązanie certyfikatu z aplikacją
Powiąż certyfikat z aplikacją przy użyciu
helm install
polecenia . Wdrożenie aplikacji odwołuje się do dostawcy usługi Azure Key Vault sterownika CSI magazynu wpisów tajnych.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
Wiązanie certyfikatu z kontrolerem ruchu przychodzącego
Powiąż certyfikat z kontrolerem ruchu przychodzącego
helm install
przy użyciu polecenia . Wdrożenie kontrolera ruchu przychodzącego odwołuje się do dostawcy usługi Azure Key Vault sterownika CSI magazynu wpisów tajnych.Uwaga
Jeśli nie używasz tożsamości zarządzanej przez zasobnika firmy Microsoft jako metody dostępu, usuń wiersz za pomocą polecenia
--set controller.podLabels.aadpodidbinding=$AAD_POD_IDENTITY_NAME
.Ponadto powiązanie klasy SecretProviderClass z zasobnikiem jest wymagane, aby sterownik CSI magazynu wpisów tajnych zainstalować go i wygenerować wpis tajny Kubernetes. Zobacz Synchronizowanie zainstalowanej zawartości za pomocą wpisu tajnego platformy 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
Sprawdź, czy wpis tajny kubernetes został utworzony przy użyciu
kubectl get secret
polecenia .kubectl get secret -n $NAMESPACE NAME TYPE DATA AGE ingress-tls-csi kubernetes.io/tls 2 1m34s
Wdrażanie aplikacji
Ponownie instrukcje zmieniają się nieco w zależności od scenariusza. Postępuj zgodnie z instrukcjami odpowiadającymi wybranemu scenariuszowi.
Wdrażanie aplikacji przy użyciu odwołania do aplikacji
Utwórz plik o nazwie z
aks-helloworld-one.yaml
następującą zawartością.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
Utwórz plik o nazwie z
aks-helloworld-two.yaml
następującą zawartością.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
Zastosuj pliki YAML do klastra
kubectl apply
przy użyciu polecenia .kubectl apply -f aks-helloworld-one.yaml -n $NAMESPACE kubectl apply -f aks-helloworld-two.yaml -n $NAMESPACE
Sprawdź, czy wpis tajny kubernetes został utworzony przy użyciu
kubectl get secret
polecenia .kubectl get secret -n $NAMESPACE NAME TYPE DATA AGE ingress-tls-csi kubernetes.io/tls 2 1m34s
Wdrażanie aplikacji przy użyciu odwołania kontrolera ruchu przychodzącego
Utwórz plik o nazwie z
aks-helloworld-one.yaml
następującą zawartością.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
Utwórz plik o nazwie z
aks-helloworld-two.yaml
następującą zawartością.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
Zastosuj pliki YAML do klastra
kubectl apply
przy użyciu polecenia .kubectl apply -f aks-helloworld-one.yaml -n $NAMESPACE kubectl apply -f aks-helloworld-two.yaml -n $NAMESPACE
Wdrażanie zasobu przychodzącego odwołującego się do wpisu tajnego
Teraz możemy wdrożyć zasób przychodzący Kubernetes odwołujący się do wpisu tajnego.
Utwórz nazwę
hello-world-ingress.yaml
pliku z następującą zawartością.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
Zanotuj
tls
sekcję odwołującą się do utworzonego wcześniej wpisu tajnego i zastosuj plik do klastrakubectl apply
przy użyciu polecenia .kubectl apply -f hello-world-ingress.yaml -n $NAMESPACE
Uzyskiwanie zewnętrznego adresu IP kontrolera ruchu przychodzącego
Pobierz zewnętrzny adres IP kontrolera ruchu przychodzącego przy użyciu
kubectl get service
polecenia .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
Testowanie ruchu przychodzącego zabezpieczonego przy użyciu protokołu TLS
Sprawdź, czy ruch przychodzący został prawidłowo skonfigurowany przy użyciu protokołu TLS, używając następującego
curl
polecenia. Upewnij się, że używasz zewnętrznego adresu IP z poprzedniego kroku.curl -v -k --resolve demo.azure.com:443:EXTERNAL_IP https://demo.azure.com
Ponieważ inna ścieżka nie została podana z adresem, kontroler ruchu przychodzącego domyślnie jest kierowany do / trasy. Zwracana jest pierwsza aplikacja demonstracyjna, jak pokazano w następujących skondensowanych przykładowych danych wyjściowych:
[...] <!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> [...]
Parametr -v w poleceniu
curl
zwraca pełne informacje, w tym odebrany certyfikat TLS. W połowie danych wyjściowych narzędzia curl możesz sprawdzić, czy użyto własnego certyfikatu TLS. Parametr -k kontynuuje ładowanie strony, mimo że używamy certyfikatu z podpisem własnym. W poniższym przykładzie przedstawiono wystawcę : CN=demo.azure.com; Użyto certyfikatu O=aks-ingress-tls :[...] * 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. [...]
Dodaj /hello-world-two ścieżkę do adresu, na przykład
https://demo.azure.com/hello-world-two
, i sprawdź, czy druga aplikacja demonstracyjna jest poprawnie skonfigurowana.curl -v -k --resolve demo.azure.com:443:EXTERNAL_IP https://demo.azure.com/hello-world-two
Zwracana jest druga aplikacja demonstracyjna z tytułem niestandardowym, jak pokazano w następujących skondensowanych przykładowych danych wyjściowych:
[...] <!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