Azure AKS 部署
对应的官方文档地址
本文将指导您使用 Azure 和 AKS 的特定功能来修改您的 Bitwarden 自托管 Helm Chart 部署。
入口控制器
nginx
默认情况下在 my-values.yaml
中定义了一个 nginx 入口控制器。如果您使用这个选项:
创建一个基本的 nginx 入口控制器。
在
general.ingress.annotations:
部分取消注释数值,并根据需要进行自定义。
Azure 应用程序网关
Azure 客户可能更倾向于使用 Azure 应用程序网关作为他们 AKS 集群的入口控制器。
安装图表前
如果您喜欢这个选项,在安装图表之前,您必须:
2、更新您的 my-values.yaml 文件,特别是 general.ingress.className:
, general.ingress.annotations:
和 general.ingress.paths:
:
general:
domain: "replaceme.com"
ingress:
enabled: true
className: "azure-application-gateway" # This value might be different depending on how you created your ingress controller. Use "kubectl get ingressclasses -A" to find the name if unsure.
## - Annotations to add to the Ingress resource.
annotations:
appgw.ingress.kubernetes.io/ssl-redirect: "true"
appgw.ingress.kubernetes.io/use-private-ip: "false" # This might be true depending on your setup.
appgw.ingress.kubernetes.io/rewrite-rule-set: "bitwarden-ingress" # Make note of whatever you set this value to. It will be used later.
appgw.ingress.kubernetes.io/connection-draining: "true" # Update as necessary.
appgw.ingress.kubernetes.io/connection-draining-timeout: "30" # Update as necessary.
## - Labels to add to the Ingress resource.
labels: {}
# Certificate options.
tls:
# TLS certificate secret name.
name: tls-secret
# Cluster cert issuer (e.g. Let's Encrypt) name if one exists.
clusterIssuer: letsencrypt-staging
paths:
web:
path: /*
pathType: ImplementationSpecific
attachments:
path: /attachments/*
pathType: ImplementationSpecific
api:
path: /api/*
pathType: ImplementationSpecific
icons:
path: /icons/*
pathType: ImplementationSpecific
notifications:
path: /notifications/*
pathType: ImplementationSpecific
events:
path: /events/*
pathType: ImplementationSpecific
scim:
path: /scim/*
pathType: ImplementationSpecific
sso:
path: /sso/*
pathType: ImplementationSpecific
identity:
path: /identity/*
pathType: ImplementationSpecific
admin:
path: /admin*
pathType: ImplementationSpecific
3、如果您要使用提供的 Let's Encrypt 示例来生成 TLS 证书,请将此处链接的脚本中的 spec.acme.solvers.ingress.class:
的值更新为 "azure/application-gateway"
。
4、在 Azure 门户中为应用程序网关创建一个空的重写集:
转到 Azure 门户中的负载均衡 → 应用程序网关,选择您的应用程序网关。
选择重写选项卡。
选择重写集按钮。
在此示例中,将名称设置为
my-values.yaml
中appgw.ingress.kubernetes.io/rewrite-rule-set:
指定的值,即bitwarden-ingress
。选择下一步然后选择创建。
安装图表后
安装图表之后,您还需要为重写集创建规则:
1、重新打开您在安装图表之前创建的空重写集。
2、选择所有以 pr-bitwarden-self-host-ingress...
开头的路由路径,取消选择任何不以该前缀开头的路径,然后选择下一步。
3、选择添加重写规则按钮。您可以为重写规则指定任何名称和任何顺序。
4、添加以下条件:
要检查的变量类型:服务器变量
服务器变量:uri_path
区分大小写:否
操作符:等于 (=)
Pattern to match:
^(\/(?!admin)(?!identity)(?!sso)[^\/]*)\/(.*)
5、添加以下操作:
重写类型:URL
操作类型:设置
组件:URL 路径
URL 路径值:
/{var_uri_path_2}
重新评估路径图:未选中
6、选择创建。
创建存储类
部署需要使用您提供的支持 ReadWriteMany 的共享存储类。以下示例是一个可以在 Azure Cloud Shell 中运行的脚本,用于创建满足要求的 Azure 文件存储类。
以下是一个说明性的示例,请根据您自己的安全要求分配权限。
cat <<EOF | kubectl apply -n bitwarden -f -
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: azure-file
namespace: bitwarden
provisioner: file.csi.azure.com
allowVolumeExpansion: true
mountOptions:
- dir_mode=0777
- file_mode=0777
- uid=0
- gid=0
- mfsymlinks
- cache=strict
- actimeo=30
parameters:
skuName: Standard_LRS
EOF
您必须在 my-values.yaml
中设置 sharedStorageClassName
的值,值应与您给予类的名称相同,在本例中为:
sharedStorageClassName: "azure-file"
使用 Azure Key Vault CSI 驱动程序
部署需要使用 Kubernetes secrets 对象为您的部署设置敏感值。虽然 kubectl create secret
命令可用于设置机密,但 Azure 客户可能更倾向于使用 Azure Key Vault 和 AKS Secrets Store CSI Driver。
这些说明假设您已经设置了 Azure Key Vault。如果没有,请立即创建一个。
1、使用以下命令为您的集群添加 Secrets Store CSI Driver 支持:
az aks enable-addons --addons azure-keyvault-secrets-provider --name myAKSCluster --resource-group myResourceGroup
该插件创建了一个用户分配的托管身份,您可以用它来进行密钥库的身份验证,然而您还有其他选择来进行身份访问控制。如果您使用已创建的用户分配的托管身份,您需要显式地为其分配 Secret > Get 的访问权限(点击这里了解)。
2、创建一个 SecretProviderClass,就像以下示例中所示。请注意,这个示例包含了必须替换的 <REPLACE>
占位符,其取决于您使用的是附带的 SQL pod 还是使用您自己的 SQL 服务器。
cat <<EOF | kubectl apply -n bitwarden -f -
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: bitwarden-azure-keyvault-csi
labels:
app.kubernetes.io/component: secrets
annotations:
spec:
provider: azure
parameters:
useVMManagedIdentity: "true" # Set to false for workload identity
userAssignedIdentityID: "<REPLACE>" # Set the clientID of the user-assigned managed identity to use
# clientID: "<REPLACE>" # Setting this to use workload identity
keyvaultName: "<REPLACE>"
cloudName: "AzurePublicCloud"
objects: |
array:
- |
objectName: installationid
objectAlias: installationid
objectType: secret
objectVersion: ""
- |
objectName: installationkey
objectAlias: installationkey
objectType: secret
objectVersion: ""
- |
objectName: smtpusername
objectAlias: smtpusername
objectType: secret
objectVersion: ""
- |
objectName: smtppassword
objectAlias: smtppassword
objectType: secret
objectVersion: ""
- |
objectName: yubicoclientid
objectAlias: yubicoclientid
objectType: secret
objectVersion: ""
- |
objectName: yubicokey
objectAlias: yubicokey
objectType: secret
objectVersion: ""
- |
objectName: hibpapikey
objectAlias: hibpapikay
objectType: secret
objectVersion: ""
- |
objectName: sapassword #-OR- dbconnectionstring if external SQL
objectAlias: sapassword #-OR- dbconnectionstring if external SQL
objectType: secret
objectVersion: ""
tenantId: "<REPLACE>"
secretObjects:
- secretName: "bitwarden-secret"
type: Opaque
data:
- objectName: installationid
key: globalSettings__installation__id
- objectName: installationkey
key: globalSettings__installation__key
key: globalSettings__mail__smtp__username
- objectName: smtppassword
key: globalSettings__mail__smtp__password
- objectName: yubicoclientid
key: globalSettings__yubico__clientId
- objectName: yubicokey
key: globalSettings__yubico__key
- objectName: hibpapikey
key: globalSettings__hibpApiKey
- objectName: sapassword #-OR- dbconnectionstring if external SQL
key: SA_PASSWORD #-OR- globalSettings__sqlServer__connectionString if external SQL
EOF
3、使用下列命令在密钥库中设置所需的机密值:
此示例将命令记录到您的 shell 历史记录中。可以考虑使用其他方法来安全地设置机密。
kvname=<REPLACE>
az keyvault secret set --name installationid --vault-name $kvname --value <REPLACE>
az keyvault secret set --name installationkey --vault-name $kvname --value <REPLACE>
az keyvault secret set --name smtpusername --vault-name $kvname --value <REPLACE>
az keyvault secret set --name smtppassword --vault-name $kvname --value <REPLACE>
az keyvault secret set --name yubicoclientid --vault-name $kvname --value <REPLACE>
az keyvault secret set --name yubicokey --vault-name $kvname --value <REPLACE>
az keyvault secret set --name hibpapikey --vault-name $kvname --value <REPLACE>
az keyvault secret set --name sapassword --vault-name $kvname --value <REPLACE>
# - OR -
# az keyvault secret set --name dbconnectionstring --vault-name $kvname --value <REPLACE>
4、在您的 my-values.yaml
文件中,设置以下值:
secrets.secretName
:将此值设置为 SecretProviderClass 中定义的secretName
值。secrets.secretProviderClass
:将此值设置为 SecretProviderClass 中定义的metadata.name
值。
最后更新于