引用 AKS 从 Azure 密钥保管库的入口使用的 TLS 证书



我正在为驻留在AKS中的应用程序设置入口。但是在将证书绑定到入口时遇到了问题。

正如你在下面看到的,我试图从KV引用ingress-cert,并通过SecretProviderClass在入口中使用它

apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: {{ include "secretProvider.name" . }}
spec:
provider: azure
secretObjects:
- secretName: ingress-tls-csi
type: kubernetes.io/tls
data:
- objectName: ingress-cert
key: tls.key
- objectName: ingress-cert
key: tls.crt
parameters:
usePodIdentity: "false"
useVMManagedIdentity: "true"
userAssignedIdentityID: {{ .Values.keyVault.identity }}
keyvaultName: {{ .Values.keyVault.name }}
objects: |
array:
- |
objectName: ingress-cert
objectType: secret
tenantId: {{ .Values.keyVault.tenant }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "ingress.name" . }}
annotations:
kubernetes.io/ingress.class: azure/application-gateway
kubernetes.io/ingress.allow-http: "false"
appgw.ingress.kubernetes.io/override-frontend-port: "443"
spec:
tls:
- hosts:
- {{ .Values.ingress.host }}
secretName: ingress-tls-csi
# Property `rules` is omitted

当通过env从pod访问其他机密时,它工作得很好,但对于入口,这是描述它的输出:

Name:             my-ingress
Namespace:        my-namespace
Address:          x.x.x.x
Default backend:  default-http-backend:80
TLS:
ingress-tls-csi terminates my.example.com
Rules:
Host                   Path  Backends
----                   ----  --------
Annotations:             appgw.ingress.kubernetes.io/override-frontend-port: 443
kubernetes.io/ingress.allow-http: false
kubernetes.io/ingress.class: azure/application-gateway
Events:
Type     Reason          Age                   From                       Message
----     ------          ----                  ----                       -------
Warning  SecretNotFound  3m3s (x2 over 3m10s)  azure/application-gateway  Unable to find the secret associated to secretId: [my-namespace/ingress-tls-csi]

我已经按照AKS集群文档中的Use the Azure Key Vault Provider for Secrets Store CSI Driver设置了KV集成。

但是,在遵循Set up Secrets Store CSI Driver启用具有TLS的NGINX入口控制器后,可以提示如何使用AGIC实现同样的功能。我注意到证书被添加为AKS中的一个秘密,然后在入口中使用secretName: ingress-tls-csi引用。

kubectl get secret -n $NAMESPACE
NAME                                             TYPE                                  DATA   AGE
ingress-tls-csi                                  kubernetes.io/tls                     2      1m34s

我假设ingress不能直接引用SecretProviderClass中的秘密,因为文档中的示例需要使用ingress-tls-csi作为秘密对象,我假设它(再次(由ingress-nginx图表创建。

我的问题是,如何使用AGIC实现与ingress-nginx示例相同的功能?


附加信息:

  • 我在Azure CNI网络中使用了AGIC
  • Ingress当前正在使用kubectl命令手动添加的证书。我需要使用KV的原因是AKS也会被部署在同一域但不同命名空间下的其他人使用,我认为直接访问证书的私钥是个坏主意

由于我找不到将Ingress与Azure密钥库集成的方法,我使用GitHub Actions实现了一个变通方法,以检索证书并将其添加到AKS。因为大多数都是bash命令,所以解决方法并不是GitHub Actions独有的。

name: Assign Cerfiticate from KV to AKS
on:
workflow_dispatch:
jobs:
build-push:
name: Assign Cerfiticate from KV to AKS
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
# Azure Authentication
- uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Authenticate and set context to AKS cluster
run: az aks get-credentials --name "my-aks-cluster" --resource-group "my-rg" --admin
- uses: azure/setup-helm@v3
with:
token: ${{ secrets.PAT }}
# Retrieve certificate and private key from Azure Key Vault
- name: Download certificate and private key in PKCS#12 format
run: |
az keyvault secret download --name my-certificate 
--vault-name my-kv 
--encoding base64 
-f certificate.pfx
- name: Extract private key in RSA format
run: |
openssl pkcs12 -in certificate.pfx -nocerts -nodes -passin pass: | openssl rsa -out private.key
- name: Extract certificate
run: |
openssl pkcs12 -in certificate.pfx -clcerts -nokeys -passin pass: -out certificate.crt
- name: Deploy Kubernetes Configuration
run: |
helm upgrade --install release-name chart-name 
-n my-namespace 
--set-file mychart.ingress.key=private.key 
--set-file mychart.ingress.certificate=certificate.crt

以上内容的简要说明:

  1. 下载.pfx格式的证书和私钥
  2. 使用OpenSSL提取到.crt.key
  3. 使用--set-file将提取的文件传递到helm install/upgrade

这里是秘密和入口配置:

apiVersion: v1
kind: Secret
metadata:
name: ingress-tls
type: kubernetes.io/tls
data:
tls.crt: {{ .Values.ingress.certificate | b64enc }}
tls.key: {{ .Values.ingress.key | b64enc }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "ingress.name" . }}
annotations:
kubernetes.io/ingress.class: azure/application-gateway
kubernetes.io/ingress.allow-http: "false"
appgw.ingress.kubernetes.io/override-frontend-port: "443"
spec:
tls:
- hosts:
- {{ .Values.ingress.host }}
secretName: ingress-tls
# Property `rules` is omitted

无需对SecretProviderClass进行额外修改。

我希望这只是一个变通办法,因为如果Ingress可以直接与Azure密钥库集成会更好。

最新更新