使用 Active Directory 单一登录在 Azure Stack HCI 和 Windows Server 上的 Azure Kubernetes 服务中安全连接到 Kubernetes API 服务器

适用于:Azure Stack HCI 和 Windows Server

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

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

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

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

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

注意

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

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

  • 为 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。

  • Azure Stack HCI 和 Windows Server 上的每个 AKS 工作负载群集都有一个 API 服务器 AD 帐户。

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

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

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

安装 AD 身份验证之前,必须先创建 Azure Stack HCI 和 Windows Server 上的 AKS 工作负载群集,并在群集上启用 AD 身份验证加载项。 如果在创建新群集时未启用 AD 身份验证,则稍后将无法启用 AD 身份验证。

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

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,请使用 k8s/apiserver@<realm name> 这种 SPN 格式。 通常,<> 是大写的,但是,如果遇到问题,请使用小写字母创建 SPN。 Kerberos 区分大小写。

方法 2

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

Install-AksHciAdAuth -name mynewcluster1 -keytab .\current.keytab -SPN k8

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

在继续执行后续步骤之前,应注意以下事项:

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

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

你需要确保 AD webhook 在 API 服务器上运行,且 keytab 文件作为 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 和其他文件复制到客户端计算机

应将下面列出的三个文件从 Azure Stack HCI 群集复制到客户端计算机:

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

  • 创建文件夹路径 c:\adsso,并将以下文件从 Azure Stack HCI 群集复制到客户端计算机。

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

步骤 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 name”为前缀。 请注意,名称必须包含域名和用双引号引起来的前缀。

这里是两个示例:

示例 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 
 namespace: sre 
 metadata: 
   name: ad-user-cluster-admin 
 roleRef: 
   apiGroup: rbac.authorization.k8s.io 
   kind: Role 
   name: sre-user-full-access 
 subjects: 
 - apiGroup: rbac.authorization.k8s.io 
   kind: User 
   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 帐户和 keytab 文件

此过程包含两个步骤。 第一步,使用服务主体名称 (SPN) 为 API 服务器创建新的 AD 帐户/用户,第二步,为 AD 帐户创建 keytab 文件。

步骤 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 文件

若要创建 keytab 文件,请使用 ktpass Windows 命令。

使用 ktpass 的示例如下:

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

注意

如果看到错误“DsCrackNames 在名称条目中返回 0x2”,请确保 /mapuser 的参数格式为 mapuser DOMAIN\user,其中 DOMAIN 为回显 %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 服务器。 接下来可以: