使用 Active Directory 单一登录安全地连接到由 Azure Arc 启用的 AKS 中的 Kubernetes API 服务器

适用于:Azure Stack HCI 22H2 上的 AKS、Windows Server 上的 AKS

可以使用 Active Directory (AD) 单一登录 (SSO) 凭据在 AKS 中创建与已启用的 Kubernetes API 服务器的安全连接。

AKS 混合中的 AD 概述

如果不使用 Active Directory 身份验证,则在通过 kubectl 命令连接到 API 服务器时,用户必须依赖基于证书的 kubeconfig 文件。 kubeconfig 文件包含需要谨慎分发的私钥和证书等秘密,这可能会带来重大的安全风险。

作为使用基于证书的 kubeconfig 的替代方法,可以使用 AD SSO 凭据作为连接到 API 服务器的安全方式。 AD 与 AKS Arc 的集成允许已加入 Windows 域的计算机上的用户使用其 SSO 凭据连接到 API 服务器 kubectl 。 这样就无需管理和分发包含私钥的基于证书的 kubeconfig 文件。

AD 集成使用 AD kubeconfig,它与基于证书的 kubeconfig 文件不同,不包含任何机密。 但是,如果使用 Active Directory 凭据进行连接时出现问题,则可使用基于证书的 kubeconfig 文件进行备份,以方便故障排除。

AD 集成的另一个安全优势在于,用户和组以安全标识符 (SID) 形式存储。 与组名称不同,SID 不可变且唯一,因此不存在命名冲突。

注意

目前,只有工作负载群集支持 AD SSO 连接。

本文将指导你完成以下步骤,将 Active Directory 设置为标识提供者并通过 启用 SSO kubectl

  • 为 API 服务器创建 AD 帐户,然后创建与该帐户相关联的 keytab文件。 若要创建 AD 帐户并生成 keytab 文件,请参阅使用 keytab 文件创建 AD 身份验证
  • 若要在 Kubernetes 群集上安装 AD 身份验证,请使用 keytab 文件。 在此步骤中,将自动创建默认的基于角色的访问控制 (RBAC) 配置。
  • 创建或编辑 RBAC 配置时,将组名称转换为 SID,反之亦然,有关说明,请参阅创建和更新 AD 组角色绑定

准备阶段

在开始配置 Active Directory SSO 凭据的过程之前,应确保已完成以下项:

  • 已安装最新的 Aks-Hci PowerShell 模块。 如果未安装,请参阅下载并安装 AksHci PowerShell 模块

  • 安装并配置 AKS 主机。 如果需要安装主机,请按照配置部署的步骤进行操作。

  • Keytab 文件应可供使用。 如果不可用,请按照创建 API 服务器 AD 帐户和密钥表文件的步骤进行操作。

    注意

    应该为特定的服务主体名称 (SPN) 生成密钥表文件,并且此 SPN 必须与工作负载群集的 API 服务器 AD 帐户相对应。 还必须确保在整个 AD 身份验证过程中使用相同的 SPN。 keytab 文件应命名为 current.keytab。

  • 每个 AKS 工作负载群集都有一个 API 服务器 AD 帐户。

  • 客户端计算机必须是已加入 Windows 域的计算机。

使用 keytab 文件创建 AD 身份验证

步骤 1:创建工作负荷群集并启用 AD 身份验证

在安装 AD 身份验证之前,必须先创建 AKS 工作负载群集并在群集上启用 AD 身份验证加载项。 如果在创建新群集时未启用 AD 身份验证,则以后无法启用它。

以管理员身份打开 PowerShell,并使用 -enableADAuth 命令的 New-AksHciCluster 参数运行以下命令:

New-AksHciCluster -name mynewcluster1 -enableADAuth

对于每个工作负载群集,请确保有一个 API 服务器 AD 帐户可用。

有关创建工作负载群集的信息,请参阅使用 Windows PowerShell 创建 Kubernetes 群集

步骤 2:安装 AD 身份验证

安装 AD 身份验证之前,请确保已安装工作负载群集并在该群集上启用了 AD 身份验证。 若要安装 AD 身份验证,请使用以下选项之一。

选项 1

对于已加入域的 Azure Stack HCI 或 Windows Server 群集,以管理员身份打开 PowerShell 并运行以下命令:

Install-AksHciAdAuth -name mynewcluster1 -keytab .\current.keytab -SPN k8s/apiserver@CONTOSO.COM -adminUser contoso\bob

注意

对于 SPN k8s/apiserver@CONTOSO.com,请使用格式 SPN k8s/apiserver@<realm name>。 首次尝试时,请以大写字母指定 <realm name> 。 但是,如果遇到大写字母的问题,请使用小写字母创建 SPN。 Kerberos 区分大小写。

方法 2

如果群集主机未加入域,请使用 SID 格式的管理员用户名或组名称,如以下示例所示。

如果使用管理员用户:

Install-AksHciAdAuth -name mynewcluster1 -keytab .\current.keytab -SPN k8s/apiserver@CONTOSO.COM -adminUserSID <User SID>

如果使用管理员组:

Install-AksHciAdAuth -name mynewcluster1 -keytab .\current.keytab -SPN k8s/apiserver@CONTOSO.COM -adminGroupSID <Group SID>

若要查找用户帐户的 SID,请参阅确定用户或组的安全标识符

在继续执行后续步骤之前,请记下以下各项:

  • 确保 keytab 文件命名为 current.keytab。
  • 替换与你的环境相对应的 SPN。
  • 参数 -adminGroup 为具有群集管理员权限的指定 AD 组创建相应的角色绑定。 将上面的选项 1 中所示 (替换为 contoso\bob 与环境对应的 AD 组或用户) 。

步骤 3:测试 AD Webhook 和 keytab 文件

确保 AD Webhook 在 API 服务器上运行,并且密钥表文件存储为 Kubernetes 机密。 若要为工作负荷群集获取基于证书的 kubeconfig 文件,请执行以下步骤:

  1. 使用以下命令获取基于证书的 kubeconfig 文件。 使用 kubeconfig 文件以本地主机身份连接到群集:

    Get-AksHciCredential -name mynewcluster1
    
  2. kubectl使用之前) 创建的基于证书的 kubeconfig 文件在连接到 (的服务器上运行 ,然后检查 AD Webhook 部署,确保其格式ad-auth-webhook-xxxx为 :

    kubectl get pods -n=kube-system
    
  3. 运行 kubectl 以检查是否将 keytab 文件部署为机密并作为 Kubernetes 机密列出:

    kubectl get secrets -n=kube-system
    

步骤 4:创建 AD kubeconfig 文件

成功部署 AD Webhook 和 keytab 后,创建 AD kubeconfig 文件。 创建文件后,将 AD kubeconfig 文件复制到客户端计算机,并使用它对 API 服务器进行身份验证。 与基于证书的 kubeconfig 文件不同,AD kubeconfig 不是机密,可以安全地作为纯文本复制。

以管理员身份打开 PowerShell 并运行以下命令:

Get-AksHciCredential -name mynewcluster1 -configPath .\AdKubeconfig -adAuth

步骤 5:将 kubeconfig 和其他文件复制到客户端计算机

应将以下三个文件从 AKS 工作负载群集复制到客户端计算机:

  • 将上一步中创建的 AD kubeconfig 文件复制到 $env:USERPROFILE.kube\config

  • 创建文件夹路径 c:\adsso ,并将以下文件从 AKS 工作负载群集复制到客户端计算机:

    • Kubectl.exe $env:ProgramFiles\AksHci 下的 c:\adsso
    • Kubectl-adsso.exe $env:ProgramFiles\AksHci 下的 c:\adsso

    注意

    运行 Get-AksHciCredential cmdlet 时,会在服务器上生成 adsso.exe 文件。

步骤 6:从客户端计算机连接到 API 服务器

完成前面的步骤后,使用 SSO 凭据登录到已加入 Windows 域的客户端计算机。 打开 PowerShell,然后尝试使用 kubectl 访问 API 服务器。 如果操作成功完成,则表示已正确设置 AD SSO。

创建和更新 AD 组角色绑定

如步骤 2 中所述,将为在安装过程中提供的用户和/或组创建具有群集管理员特权的默认角色绑定。 Kubernetes 中的角色绑定定义 AD 组的访问策略。 此步骤介绍如何使用 RBAC 在 Kubernetes 中创建新的 AD 组角色绑定,以及如何编辑现有角色绑定。 例如,群集管理员可能希望使用 AD 组向用户授予额外的特权(使该过程更高效)。 有关 RBAC 的详细信息,请参阅 使用 RBAC 授权

创建或编辑其他 AD 组 RBAC 条目时,使用者名称应具有 microsoft:activedirectory:CONTOSO\group 名称 前缀。 请注意,名称必须包含域名和用双引号引起来的前缀。

这里是两个示例:

示例 1

apiVersion: rbac.authorization.k8s.io/v1 
kind: ClusterRoleBinding 
metadata: 
  name: ad-user-cluster-admin 
roleRef: 
  apiGroup: rbac.authorization.k8s.io 
  kind: ClusterRole 
  name: cluster-admin 
subjects: 
- apiGroup: rbac.authorization.k8s.io 
  kind: User 
  name: "microsoft:activedirectory:CONTOSO\Bob" 

示例 2

以下示例演示如何为具有 AD 组的 命名空间 创建自定义角色和角色绑定。 在此示例中, SREGroup 是 Contoso Active Directory 中预先存在的组。 将用户添加到 AD 组后,他们会立即被授予特权。

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: sre-user-full-access
  namespace: sre
rules:
- apiGroups: ["", "extensions", "apps"]
  resources: ["*"]
  verbs: ["*"]
- apiGroups: ["batch"]
  resources:
  - jobs
  - cronjobs
  verbs: ["*"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: ad-user-cluster-admin
  namespace: sre
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: sre-user-full-access
subjects:
  - apiGroup: rbac.authorization.k8s.io
    kind: Group
    name: "microsoft:activedirectory:CONTOSO\SREGroup" 

在应用 YAML 文件之前,应始终使用 命令将组和用户名转换为 SID:

kubectl-adsso nametosid <rbac.yml>

同样,若要更新现有 RBAC,可以在进行更改之前将 SID 转换为用户友好的组名。 若要转换 SID,请使用以下命令:

kubectl-adsso sidtoname <rbac.yml>

更改与 API 服务器帐户关联的 AD 帐户密码

如果为 API 服务器帐户更改了密码,则必须先卸载 AD 身份验证加载项,再使用更新过的当前和以前的 keytab 重新安装它。

每次更改密码时,都必须将当前 keytab (current.keytab) 重命名为 previous.keytab。 然后,请确保将新密码命名为 current.keytab。

重要

文件必须分别命名为 current.keytab 和 previous.keytab。 现有角色绑定不受此更改的影响。

卸载并重新安装 AD 身份验证

在更改 API 服务器的帐户、更新密码或排查故障时,可能需要重新安装 AD SSO。

若要卸载 AD 身份验证,请以管理员身份打开 PowerShell 并运行以下命令:

Uninstall-AksHciAdAuth -name mynewcluster1

若要重新安装 AD 身份验证,请以管理员身份打开 PowerShell 并运行以下命令:

Install-AksHciAdAuth -name mynewcluster1 -keytab <.\current.keytab> -previousKeytab <.\previous.keytab> -SPN <service/principal@CONTOSO.COM> -adminUser CONTOSO\Bob

注意

为了避免在客户端具有缓存票证的情况下停机, -previousKeytab 仅在更改密码时需要 参数。

创建 API 服务器 AD 帐户和密钥表文件

创建 AD 帐户和密钥表文件涉及两个步骤。 首先,使用 SPN) 的服务主体名称 (为 API 服务器创建新的 AD 帐户/用户,然后为 AD 帐户创建密钥表文件。

步骤 1:为 API 服务器创建新的 AD 帐户或用户

通过 New-ADUser PowerShell 命令,使用 SPN 创建新的 AD 帐户/用户。 下面是一个示例:

New-ADUser -Name apiserver -ServicePrincipalNames k8s/apiserver -AccountPassword (ConvertTo-SecureString "password" -AsPlainText -Force) -KerberosEncryptionType AES128 -Enabled 1

步骤 2:为 AD 帐户创建 keytab 文件

若要创建密钥表文件,请使用 ktpass Windows 命令。

使用 ktpass 的示例如下:

ktpass /out current.keytab /princ k8s/apiserver@CONTOSO.COM /mapuser contoso\apiserver_acct /crypto all /pass p@$$w0rd /ptype KRB5_NT_PRINCIPAL

注意

如果在 名称条目中看到错误 DsCrackNames 返回0x2,请确保 的 /mapuser 参数的格式 mapuser DOMAIN\user为 ,其中 DOMAIN 是 echo %userdomain%的输出。

确定用户或组安全标识符

使用以下两个选项之一查找帐户或其他帐户的 SID:

  • 若要查找与帐户关联的 SID,请在主目录的命令提示符下键入以下命令:

    whoami /user
    
  • 若要查找与另一个帐户关联的 SID,请以管理员身份打开 PowerShell 并运行以下命令:

    (New-Object System.Security.Principal.NTAccount(<CONTOSO\Bob>)).Translate([System.Security.Principal.SecurityIdentifier]).value
    

排查证书问题

Webhook 和 API 服务器使用证书来相互验证 TLS 连接。 此证书将在 500 天后过期。 若要验证证书是否已过期,请查看 ad-auth-webhook 容器中的日志:

kubectl logs ad-auth-webhook-xxx

如果出现证书验证错误,请完成卸载并重新安装 Webhook 的步骤,并获取新证书。

最佳做法和清理

  • 为每个群集使用唯一的帐户。
  • 不要跨群集重复使用 API 服务器帐户的密码。
  • 创建群集后立即删除 keytab 文件的本地副本,并验证 SSO 凭据是否正常工作。
  • 删除为 API 服务器创建的 Active Directory 用户。 有关详细信息,请参阅 Remove-ADUser

后续步骤

本操作方法指南介绍了如何配置 AD 身份验证,以使用 SSO 凭据安全连接到 API 服务器。 接下来可以: