如何找到我的 AKS 群集的服务主体机密?
Posted
技术标签:
【中文标题】如何找到我的 AKS 群集的服务主体机密?【英文标题】:How can I find the service principal secret of my AKS cluster? 【发布时间】:2019-01-29 19:40:05 【问题描述】:好的,所以我搞砸了,我不小心对运行 AKS 集群的服务主体运行了 az ad sp reset-credentials
。现在我们收到如下错误:
创建负载均衡器时出错(将重试):为服务 test/admin-api 获取 LB 时出错:azure.BearerAuthorizer#WithAuthorization:无法刷新令牌以请求https://management.azure.com/subscriptions/****/resourceGroups/MC_** **/providers/Microsoft.Network/loadBalancers?api-version=2017-09-01:StatusCode=0——原始错误:adal:刷新请求失败。状态码 = '401'。响应正文:"error":"invalid_client","error_description":"AADSTS70002:验证凭据时出错。AADSTS50012:提供了无效的客户端密码。\r\n跟踪 ID:****\r\n相关 ID:*** * \r\n时间戳:2018-08-23 12:01:33Z","error_codes":[70002,50012],"timestamp":"2018-08-23 12:01:33Z","trace_id":" ****","correlation_id":"****"
和
无法提取图像“****.azurecr.io/****:****”:rpc 错误:代码 = 未知 desc = 来自守护进程的错误响应:获取 https://**** .azurecr.io/v2/****/manifests/****:未经授权:需要身份验证
所以现在我想找到服务主体使用的原始客户端密钥,以便我可以将其重新添加为服务主体的密钥。除了重新创建整个集群之外,这是我能想到的唯一解决方案。
有什么想法吗?
【问题讨论】:
【参考方案1】:这是你想做的一件烦人的事。对于您的问题,您无法在未经身份验证的情况下提取图像。
首先,您必须找出容器注册表的服务主体。您可以在 Azure 门户中执行此操作并导航到注册表面板,然后您可以像这样找到服务主体:
或者您可以使用 Azure CLI 命令来查找注册表 ID,如下所示:
az acr show --resource-group groupName --name registryName --query id --output tsv
然后使用命令查找服务主体 ID,如下所示:
az role assignment list --scope registryID
您可以选择所需的服务主体。
然后你会使用命令kubectl get secrets
和kubectl get secrets secretName -o yaml
得到所有的秘密来获取秘密的令牌。然后一一分析,检查用户名是否与服务主体ID相同。您可以使用 JWT 等工具来分析秘密令牌。结果会是这样的:
如果用户名与您找到的服务主体 ID 相同,那就是您想要的秘密。这一步很麻烦。您应该逐个检查秘密,否则您将有更好的方法来检查它们。
顺便说一句,创建服务主体的密码似乎只能看到一次。 Azure 不会再向您展示。但是,如果您创建 Kubernetes 密钥,密码就会存储在其中。
【讨论】:
谢谢查尔斯,但我认为这不会奏效。问题不仅仅是集群失去了对 ACR 的访问权限。集群使用错误的密码连接到 Azure 以创建负载均衡器、IP 地址等。我不认为该密码存储在 K8s 机密中。根据文档“在 Kubernetes 集群中的主虚拟机和代理虚拟机上,服务主体凭据存储在文件 /etc/kubernetes/azure.json 中”。所以我认为我需要以某种方式获取该文件。 @PeterH 我发布的结果是我测试过的。你可以试试看。正如您所说,文件 /etc/kubernetes/azure.json 中的秘密存储。 master 和 agent 是容器,文件 /etc/kubernetes/azure.json 在里面。如果你是对的。您可以在外部检查秘密或连接到容器以获取内部信息。你觉得哪个更方便。 连接到容器是我的首选,但如何连接到容器? 我已经尝试过您的方法,但没有一个令牌采用您显示的格式。我认为那是因为我从未创建秘密,因为我们没有使用 ImagePullSecrets,只是授予服务主体访问 ACR 的权限,因此不需要秘密。 我找到了解决方案,您只需通过 Azure 门户运行命令即可。我已经在答案中提供了解决方案。【参考方案2】:最终解决方案非常简单。
在 Azure 门户中,导航到名为MC_<resourcegroup>_<aksName>_<region>
的资源组。
单击“虚拟机”类型的资源之一。
向下滚动到“运行命令”
选择“RunShellScript”
输入cat /etc/kubernetes/azure.json
并点击“运行”
该命令将返回 JSON 文件的内容。你需要的属性是aadClientSecret
【讨论】:
【参考方案3】:谁遇到了这个问题,微软提供了一个更新的解决方案
https://docs.microsoft.com/en-us/azure/aks/update-credentials#update-aks-cluster-with-new-credentials
他们还提到(一些不明显的): 默认情况下,AKS 群集是使用具有一年到期时间的服务主体创建的。
另外, 从 Azure CLI 2.0.68 开始,不再支持使用 --password 参数创建具有用户定义密码的服务主体,以防止意外使用弱密码。 因此更改服务主体密码的初始解决方案不再起作用。
【讨论】:
【参考方案4】:Azure 门户中提供了新功能,可以在不使用 CLI 的情况下查看集群配置。 转到 Azure 门户 -> 您的集群资源 -> 概述
在右侧有一个按钮,上面写着“JSON 视图”。单击它,您将看到一个包含集群详细信息的 json 文件。服务主体 ID 可见于:“servicePrincipalProfile”。
【讨论】:
问题是关于服务主体 secret,而不是 ID以上是关于如何找到我的 AKS 群集的服务主体机密?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 terraform 中由 AKS 群集资源创建的虚拟机规模集或负载均衡器上启用诊断日志?
使用 Terraform 创建具有托管标识的 Azure AKS 会导致 AutoUpgradePreview 未启用错误
无法从连接到 Azure *** 的本地计算机(在家庭网络上)访问专用 AKS 群集