Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Расширение хранилища секретов Azure Key Vault для Kubernetes ("SSE") автоматически синхронизирует секреты из Azure Key Vault с кластером Kubernetes с поддержкой Azure Arc для автономного доступа. Это означает, что Azure Key Vault можно использовать для хранения, обслуживания и смены секретов даже когда вы запускаете кластер Kubernetes в условиях частичного отключения. Синхронизированные секреты хранятся в хранилище секретов кластера, что делает их доступными в качестве секретов Kubernetes, которые могут использоваться всеми обычными способами: монтироваться как тома данных или предоставляться в виде переменных среды для контейнера в pod.
Синхронизированные секреты являются критически важными бизнес-ресурсами, поэтому служба SSE защищает их с помощью изолированных пространств имен и узлов, политик управления доступом на основе ролей (RBAC) и ограниченных разрешений для синхронизатора секретов. Для дополнительной защиты зашифруйте хранилище секретов Kubernetes в кластере.
Подсказка
SSE рекомендуется для сценариев, когда требуется автономный доступ, или если вам нужны секреты, синхронизированные с хранилищем секретов Kubernetes. Если эти функции не нужны, вы можете использовать расширение поставщика секретов Azure Key Vault для управления секретами в кластерах Kubernetes с поддержкой Arc. Не рекомендуется запускать онлайн-расширение поставщика секретов Azure Key Vault и офлайн-SSE параллельно в кластере.
В этой статье показано, как установить и настроить SSE в качестве расширения Kubernetes с поддержкой Azure Arc.
Это важно
В настоящее время SSE находится в предварительной версии. Ознакомьтесь с Дополнительными условиями использования для предварительных версий Microsoft Azure, чтобы узнать юридические условия, применимые к функциям Azure, которые находятся в статусе бета, предварительного просмотра или иначе еще не выпущены в общий доступ.
Предпосылки
- Кластер с поддержкой Arc. Это может быть кластер, который вы настроили самостоятельно (в примерах этого руководства используется кластер K3s), или управляемый корпорацией Майкрософт кластер AKS, активированный с помощью Azure Arc. Кластер должен работать под управлением Kubernetes версии 1.27 или выше.
- Убедитесь, что выполнены общие предварительные требования для расширений
k8s-extension
кластера, включая последнюю версию расширения Azure CLI. - cert-manager необходим для поддержки TLS в целях внутрикластерного обмена журналами. Примеры в этом руководстве помогут вам пройти через процесс установки. Дополнительные сведения о диспетчере сертификатов см. в cert-manager.io
Установите Azure CLI и выполните вход, если вы еще не выполнили следующие действия.
az login
Прежде чем начать, задайте переменные среды для настройки ресурсов Azure и кластера. Если у вас уже есть управляемое удостоверение, например, Azure Key Vault или другой ресурс, указанный здесь, обновите имена в переменных среды, чтобы отразить эти ресурсы. Обратите внимание, что KEYVAULT_NAME должно быть глобально уникальным; создание keyvault завершится сбоем позже, если это имя уже используется в Azure.
export RESOURCE_GROUP="AzureArcTest"
export CLUSTER_NAME="AzureArcTest1"
export LOCATION="EastUS"
export SUBSCRIPTION="$(az account show --query id --output tsv)"
az account set --subscription "${SUBSCRIPTION}"
export AZURE_TENANT_ID="$(az account show -s $SUBSCRIPTION --query tenantId --output tsv)"
export CURRENT_USER="$(az ad signed-in-user show --query userPrincipalName --output tsv)"
export KEYVAULT_NAME="my-UNIQUE-kv-name"
export KEYVAULT_SECRET_NAME="my-secret"
export USER_ASSIGNED_IDENTITY_NAME="my-identity"
export FEDERATED_IDENTITY_CREDENTIAL_NAME="my-credential"
export KUBERNETES_NAMESPACE="my-namespace"
export SERVICE_ACCOUNT_NAME="my-service-account"
Активируйте федерацию удостоверений рабочих нагрузок в вашем кластере
Служба SSE использует функцию, называемую федерацией идентификации нагрузки, для доступа к секретам Azure Key Vault и их синхронизации. В этом разделе описывается настройка функции. В следующих разделах описано, как оно используется подробно.
Подсказка
Следующие шаги основаны на практическом руководстве по настройке Kubernetes с поддержкой Arc и федерацией удостоверений рабочей нагрузки. Дополнительные сведения см. в этой документации.
Если кластер еще не подключен к Azure Arc, выполните следующие действия. В ходе этих действий включите федерацию удостоверений рабочей нагрузки connect
в рамках команды:
az connectedk8s connect --name ${CLUSTER_NAME} --resource-group ${RESOURCE_GROUP} --enable-oidc-issuer
Для включения удостоверения рабочей нагрузки, если ваш кластер уже подключен к Azure Arc, используйте команду update
.
az connectedk8s update --name ${CLUSTER_NAME} --resource-group ${RESOURCE_GROUP} --enable-oidc-issuer
Теперь настройте кластер для выдачи маркеров учетной записи службы с новым URL-адресом издателя (service-account-issuer
), который позволяет Microsoft Entra ID найти открытые ключи, необходимые для проверки этих маркеров. Эти открытые ключи предназначены для издателя токенов учетной записи службы самого кластера и были получены и размещены в облаке по этому URL-адресу в результате ранее установленного параметра --enable-oidc-issuer
.
При необходимости можно также настроить ограничения на собственные разрешения SSE в качестве привилегированного ресурса, работающего в плоскости управления, настроив OwnerReferencesPermissionEnforcement
контроллер допуска. Этот контроллер допуска ограничивает, сколько SSE может изменить другие объекты в кластере.
Настройте kube-apiserver с полем URL-адреса издателя и принудительным соблюдением разрешений. В следующем примере используется кластер k3s. Ваш кластер может иметь разные средства для изменения аргументов сервера API:
--kube-apiserver-arg="--service-account-issuer=${SERVICE_ACCOUNT_ISSUER}" and --kube-apiserver-arg="--enable-admission-plugins=OwnerReferencesPermissionEnforcement"
Получите URL-адрес издателя учетной записи службы.
export SERVICE_ACCOUNT_ISSUER="$(az connectedk8s show --name ${CLUSTER_NAME} --resource-group ${RESOURCE_GROUP} --query "oidcIssuerProfile.issuerUrl" --output tsv)" echo $SERVICE_ACCOUNT_ISSUER
Откройте файл конфигурации сервера K3s.
sudo nano /etc/systemd/system/k3s.service
Измените конфигурацию сервера как в следующем примере, заменив <SERVICE_ACCOUNT_ISSUER> предыдущим выводом из
echo $SERVICE_ACCOUNT_ISSUER
, не забывая включить конечную косую черту этого URL-адреса.ExecStart=/usr/local/bin/k3s \ server --write-kubeconfig-mode=644 \ --kube-apiserver-arg="--service-account-issuer=<SERVICE_ACCOUNT_ISSUER>" \ --kube-apiserver-arg="--enable-admission-plugins=OwnerReferencesPermissionEnforcement"
Перезапустите kube-apiserver.
sudo systemctl daemon-reload sudo systemctl restart k3s
Создание секрета и настройка удостоверения для доступа к нему
Чтобы сервис SSE получил доступ к заданному секрету Azure Key Vault и синхронизировал его, необходим доступ к управляемому удостоверению Azure с соответствующими разрешениями для доступа к этому секрету. Управляемое удостоверение должно быть связано с учетной записью службы Kubernetes с помощью функции удостоверения рабочей нагрузки, активированной ранее. Служба SSE использует ассоциированную федеративную управляемую идентичность Azure для извлечения секретов из Azure Key Vault в секретное хранилище Kubernetes. В следующих разделах описано, как настроить эту настройку.
Создание Azure Key Vault
Создайте Azure Key Vault и добавьте секрет. Если у вас уже есть Azure Key Vault и секрет, этот раздел можно пропустить.
Создайте Azure Key Vault:
az keyvault create --resource-group "${RESOURCE_GROUP}" --location "${LOCATION}" --name "${KEYVAULT_NAME}" --enable-rbac-authorization
Назначьте себе права "администратор секретов" в хранилище, чтобы создать секрет:
az role assignment create --role "Key Vault Secrets Officer" --assignee ${CURRENT_USER} --scope /subscriptions/${SUBSCRIPTION}/resourcegroups/${RESOURCE_GROUP}/providers/Microsoft.KeyVault/vaults/${KEYVAULT_NAME}
Создайте секрет и обновите его, чтобы иметь две версии:
az keyvault secret set --vault-name "${KEYVAULT_NAME}" --name "${KEYVAULT_SECRET_NAME}" --value 'Hello!' az keyvault secret set --vault-name "${KEYVAULT_NAME}" --name "${KEYVAULT_SECRET_NAME}" --value 'Hello2'
Создание управляемой идентичности, назначаемой пользователем
Затем создайте управляемое удостоверение, назначаемое пользователем, и предоставьте ему разрешения на доступ к Azure Key Vault. Если у вас уже есть управляемое удостоверение с разрешениями "Key Vault Reader" и "Key Vault Secrets User" в Azure Key Vault, можно пропустить этот раздел. Дополнительные сведения см. в статье "Создание управляемых удостоверений, назначаемых пользователем" и Использование разрешений на секреты, ключи и сертификаты Azure RBAC с Key Vault.
Создайте назначаемое пользователем управляемое удостоверение:
az identity create --name "${USER_ASSIGNED_IDENTITY_NAME}" --resource-group "${RESOURCE_GROUP}" --location "${LOCATION}" --subscription "${SUBSCRIPTION}"
Предоставьте удостоверению разрешение пользователя Key Vault Reader и Key Vault Secret User. Возможно, потребуется подождать некоторое время, пока не завершится репликация создания удостоверения, прежде чем эти команды будут выполнены успешно.
export USER_ASSIGNED_CLIENT_ID="$(az identity show --resource-group "${RESOURCE_GROUP}" --name "${USER_ASSIGNED_IDENTITY_NAME}" --query 'clientId' -otsv)" az role assignment create --role "Key Vault Reader" --assignee "${USER_ASSIGNED_CLIENT_ID}" --scope /subscriptions/${SUBSCRIPTION}/resourcegroups/${RESOURCE_GROUP}/providers/Microsoft.KeyVault/vaults/${KEYVAULT_NAME} az role assignment create --role "Key Vault Secrets User" --assignee "${USER_ASSIGNED_CLIENT_ID}" --scope /subscriptions/${SUBSCRIPTION}/resourcegroups/${RESOURCE_GROUP}/providers/Microsoft.KeyVault/vaults/${KEYVAULT_NAME}
Создать учетные данные для федеративной идентичности
Создайте учетную запись службы Kubernetes для рабочей нагрузки, требующей доступа к секретам. Затем создайте федеративные учетные данные удостоверения для связи между управляемым удостоверением, издателем учетной записи службы OIDC и учетной записью службы Kubernetes.
Создайте учетную запись службы Kubernetes, которая будет федерально связана с управляемым удостоверением. Заметите его с подробными сведениями о связанном управляемом удостоверении, назначаемом пользователем.
kubectl create ns ${KUBERNETES_NAMESPACE}
cat <<EOF | kubectl apply -f - apiVersion: v1 kind: ServiceAccount metadata: name: ${SERVICE_ACCOUNT_NAME} namespace: ${KUBERNETES_NAMESPACE} EOF
Создайте учетные данные федеративного удостоверения:
az identity federated-credential create --name ${FEDERATED_IDENTITY_CREDENTIAL_NAME} --identity-name ${USER_ASSIGNED_IDENTITY_NAME} --resource-group ${RESOURCE_GROUP} --issuer ${SERVICE_ACCOUNT_ISSUER} --subject system:serviceaccount:${KUBERNETES_NAMESPACE}:${SERVICE_ACCOUNT_NAME} --audience api://AzureADTokenExchange
Установка SSE
Служба SSE доступна как расширение Azure Arc. Кластер Kubernetes с поддержкой Azure Arc можно расширить с помощью расширений Kubernetes с поддержкой Azure Arc. Расширения обеспечивают возможности Azure в подключенном кластере и предоставляют управляемый Azure Resource Manager интерфейс для установки и управления жизненным циклом расширений.
Диспетчер сертификатов и диспетчер доверия также требуются для безопасного взаимодействия журналов между службами кластера и должны быть установлены перед расширением Arc.
Установите cert-manager.
helm repo add jetstack https://charts.jetstack.io/ --force-update helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --version v1.16.2 --set crds.enabled=true
Установите диспетчер доверия.
helm upgrade trust-manager jetstack/trust-manager --install --namespace cert-manager --wait
Установите SSE в кластер с поддержкой Arc, выполнив следующую команду:
az k8s-extension create \ --cluster-name ${CLUSTER_NAME} \ --cluster-type connectedClusters \ --extension-type microsoft.azure.secretstore \ --resource-group ${RESOURCE_GROUP} \ --release-train preview \ --name ssarcextension \ --scope cluster
При необходимости можно изменить интервал опроса поворота по умолчанию, добавив
--configuration-settings rotationPollIntervalInSeconds=<time_in_seconds>
:Имя параметра Описание Значение по умолчанию rotationPollIntervalInSeconds
Указывает, как быстро SSE проверяет или обновляет секрет, которым он управляет. 3600
(1 час)
Настройка SSE
Настройте установленное расширение с информацией о Azure Key Vault и секретах для синхронизации с кластером, определив экземпляры пользовательских ресурсов Kubernetes. Вы создаете два типа пользовательских ресурсов:
-
SecretProviderClass
Объект, определяющий подключение к Key Vault. -
SecretSync
Объект для синхронизации каждого секрета.
Создайте SecretProviderClass
ресурс
Ресурс SecretProviderClass
используется для определения подключения к Azure Key Vault, удостоверения, используемого для доступа к хранилищу, секретов для синхронизации и количества версий каждого секрета для хранения локально.
Для каждого Azure Key Vault, для каждого удостоверения, используемого для доступа к Azure Key Vault, и для каждого целевого пространства имен Kubernetes необходимо иметь отдельное SecretProviderClass
.
Создайте один или несколько SecretProviderClass
файлов YAML с соответствующими для хранилища ключей и секретов значениями, следуя этому примеру.
cat <<EOF > spc.yaml
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: secret-provider-class-name # Name of the class; must be unique per Kubernetes namespace
namespace: ${KUBERNETES_NAMESPACE} # Kubernetes namespace to make the secrets accessible in
spec:
provider: azure
parameters:
clientID: "${USER_ASSIGNED_CLIENT_ID}" # Managed Identity Client ID for accessing the Azure Key Vault with.
keyvaultName: ${KEYVAULT_NAME} # The name of the Azure Key Vault to synchronize secrets from.
objects: |
array:
- |
objectName: ${KEYVAULT_SECRET_NAME} # The name of the secret to synchronize.
objectType: secret
objectVersionHistory: 2 # [optional] The number of versions to synchronize, starting from latest.
tenantID: "${AZURE_TENANT_ID}" # The tenant ID of the Key Vault
EOF
SecretSync
Создание объекта
Объект SecretSync
необходим для определения того, как элементы, извлекаемые SecretsProviderClass
, хранятся в Kubernetes. Секреты Kubernetes — это карты с ключом-значением, как ConfigMaps
, а объект SecretSync
сообщает SSE, как сопоставить элементы, определенные в связанном SecretsProviderClass
, с ключами в секрете Kubernetes. SSE создаст секрет Kubernetes с тем же именем, что и SecretSync
, описывающий его.
Создайте один SecretSync
файл YAML объекта для каждого секрета Kubernetes, следуя этому шаблону. Пространство имен Kubernetes должно соответствовать пространству имен соответствующего SecretProviderClass
.
cat <<EOF > ss.yaml
apiVersion: secret-sync.x-k8s.io/v1alpha1
kind: SecretSync
metadata:
name: secret-sync-name # Name of the object; must be unique per Kubernetes namespace
namespace: ${KUBERNETES_NAMESPACE} # Kubernetes namespace
spec:
serviceAccountName: ${SERVICE_ACCOUNT_NAME} # The Kubernetes service account to be given permissions to access the secret.
secretProviderClassName: secret-provider-class-name # The name of the matching SecretProviderClass with the configuration to access the AKV storing this secret
secretObject:
type: Opaque
data:
- sourcePath: ${KEYVAULT_SECRET_NAME}/0 # Name of the secret in Azure Key Vault with an optional version number (defaults to latest)
targetKey: ${KEYVAULT_SECRET_NAME}-data-key0 # Target name of the secret in the Kubernetes secret store (must be unique)
- sourcePath: ${KEYVAULT_SECRET_NAME}/1 # [optional] Next version of the AKV secret. Note that versions of the secret must match the configured objectVersionHistory in the secrets provider class
targetKey: ${KEYVAULT_SECRET_NAME}-data-key1 # [optional] Next target name of the secret in the K8s secret store
EOF
Подсказка
Не включайте "/0" при упоминании секрета из SecretProviderClass
где objectVersionHistory
< 2. Последняя версия используется неявно.
Примените CR конфигурации
Примените настраиваемые ресурсы конфигурации (CR) с помощью kubectl apply
команды:
kubectl apply -f ./spc.yaml
kubectl apply -f ./ss.yaml
Служба SSE автоматически ищет секреты и начинает синхронизацию их с кластером.
Просмотр параметров конфигурации
Чтобы просмотреть дополнительные параметры конфигурации для этих двух пользовательских типов ресурсов, используйте kubectl describe
команду для проверки CRD в кластере.
# Get the name of any applied CRD(s)
kubectl get crds -o custom-columns=NAME:.metadata.name
# View the full configuration options and field parameters for a given CRD
kubectl describe crd secretproviderclass
kubectl describe crd secretsync
Наблюдение за синхронизацией секретов с кластером
После применения конфигурации секреты начинают синхронизироваться с кластером автоматически с частотой, указанной при установке SSE.
Просмотр синхронизированных секретов
Просмотрите секреты, синхронизированные с кластером, выполнив следующую команду:
# View a list of all secrets in the namespace
kubectl get secrets -n ${KUBERNETES_NAMESPACE}
# View details of all secrets in the namespace
kubectl get secrets -n ${KUBERNETES_NAMESPACE} -o yaml
Просмотр состояния последней синхронизации
Чтобы просмотреть состояние последней синхронизации для заданного секрета, используйте kubectl describe
команду для SecretSync
объекта. Выходные данные включают метку времени создания секрета, версии секрета и подробные сообщения о состоянии для каждого события синхронизации. Эти выходные данные можно использовать для диагностики ошибок подключения или конфигурации, а также для наблюдения за изменением значения секрета.
kubectl describe secretsync secret-sync-name -n ${KUBERNETES_NAMESPACE}
Просмотр значений секретов
Чтобы просмотреть синхронизированные значения секретов, теперь хранящиеся в хранилище секретов Kubernetes, выполните следующую команду:
kubectl get secret secret-sync-name -n ${KUBERNETES_NAMESPACE} -o jsonpath="{.data.${KEYVAULT_SECRET_NAME}-data-key0}" | base64 -d
kubectl get secret secret-sync-name -n ${KUBERNETES_NAMESPACE} -o jsonpath="{.data.${KEYVAULT_SECRET_NAME}-data-key1}" | base64 -d
Устранение неполадок
SSE — это развертывание Kubernetes, содержащее pod с двумя контейнерами: контроллер, управляющий хранением секретов в кластере, и провайдер, контролирующий доступ к Azure Key Vault и извлечение секретов из него. Каждый синхронизированный SecretSync
секрет содержит объект, содержащий состояние синхронизации этого секрета из Azure Key Vault в хранилище секретов кластера.
Чтобы устранить проблему, начните с просмотра состояния объекта, как описано в SecretSync
синхронизации. В следующей таблице перечислены распространенные причины состояния, их значения и возможные действия по устранению ошибок.
Причина состояния SecretSync | Сведения | Шаги для исправления/дальнейшего исследования |
---|---|---|
UpdateNoValueChangeSucceeded |
Секрет в Kubernetes полностью up-to-date to the AKV version. Изменения не были необходимы во время последней проверки. | n/a |
UpdateValueChangeOrForceUpdateSucceeded |
Весь секрет в Kubernetes был успешно обновлен до версии AKV во время последней проверки. | n/a |
PartialSync |
Не удалось обновить некоторые элементы в секретной информации. | Изучите подробнее, посмотрев в status.conditions.message поле объекта SecretSync . Это поле будет содержать сводку в строковом формате в формате JSON об успешном выполнении или сбое для каждого элемента в секрете. |
ProviderError |
Сбой создания секрета из-за некоторых проблем с поставщиком (подключение к Azure Key Vault). Эта ошибка может быть вызвана подключением к Интернету, недостаточными разрешениями для секретов синхронизации удостоверений, неправильной настройки SecretProviderClass или других проблем. |
Сначала расследуйте, как с PartialSync , затем изучите журналы поставщика, используя следующие команды. kubectl get pods -n azure-secret-store kubectl logs <secret-sync-controller-pod-name> -n azure-secret-store --container='provider-azure-installer' |
InvalidClusterSecretLabelError InvalidClusterSecretAnnotationError |
Секрет уже существует с таким именем, который не управляется службой SSE. | Удалите секрет, чтобы разрешить SSE повторно создать секрет: kubectl delete secret <secret-name> Чтобы заставить SSE воссоздать секрет быстрее, чем заданный интервал опроса ротации, удалите объект SecretSync (kubectl delete secretsync <secret-name> ) и повторно примените класс синхронизации секрета kubectl apply -f <path_to_secret_sync> . |
UserInputValidationFailed |
Сбой обновления секрета, так как класс синхронизации секретов настроен неправильно (например, недопустимый тип секрета). | Просмотрите определение класса "secret sync" и исправьте все ошибки. Затем удалите объект (SecretSync ), удалите класс синхронизации секретов (kubectl delete secretsync <secret-name> ), и повторно примените класс синхронизации секретов (kubectl delete -f <path_to_secret_sync> ). |
ControllerSpcError |
Сбой обновления секрета, поскольку SSE не удалось получить класс поставщика или класс поставщика настроен неверно. | Проверьте класс поставщика и исправьте все ошибки. Затем удалите объект (SecretSync ), удалите класс поставщика (kubectl delete secretsync <secret-name> ) и повторно примените класс поставщика (kubectl delete -f <path_to_provider> ). |
ControllerInternalError ValidatingAdmissionPolicyCheckFailed ControllerSyncFailed |
Сбой обновления секрета из-за внутренней ошибки в SSE. | Дополнительные сведения см. в журналах SSE или событиях. kubectl get pods -n azure-secret-store kubectl logs <secret-sync-controller-pod-name> -n azure-secret-store --container='manager' |
UnknownError |
Сбой обновления секрета при изменении значения секрета в Kubernetes. Эта ошибка может произойти, если секрет был изменен кем-либо, кроме SSE, или если во время обновления SSE возникли проблемы. | Попробуйте удалить секрет и SecretSync объект, а затем разрешить SSE повторно создать секрет, повторно применив SecretSync объект: kubectl delete secret <secret-name> kubectl delete secretsync <secret-name> kubectl apply -f <path_to_secret_sync> Если это не поможет, выполните действия для проверки журналов аналогично тому, как с ControllerInternalError . |
Удалите SSE
Чтобы удалить SSE и прекратить синхронизацию секретов, используйте команду az k8s-extension delete
для удаления.
az k8s-extension delete --name ssarcextension --cluster-name $CLUSTER_NAME --resource-group $RESOURCE_GROUP --cluster-type connectedClusters
Удаление расширения не удаляет секреты, SecretSync
объекты или CRD из кластера. Эти объекты должны быть удалены напрямую с помощью kubectl
.
При удалении CRD SecretSync удаляются все объекты SecretSync
, и по умолчанию удаляются все принадлежащие им секреты, но секреты могут сохраниться в следующих случаях:
- Вы изменили владение какими-либо из секретов.
- Вы изменили параметры сборки мусора в кластере, включая настройку различных методов завершения.
В этих случаях секреты необходимо удалить напрямую с помощью kubectl
.
Дальнейшие шаги
- Дополнительные сведения о расширениях Azure Arc.
- Дополнительные сведения об Azure Key Vault.
- Помогите защитить кластер другими способами, следуя инструкциям в книге безопасности для Kubernetes с поддержкой Azure Arc.