在 gitlab-runner 环境中使用服务帐户令牌时,kubectl 未经授权
kubectl unauthorized when using service account token inside gitlab-runner environment
我们是 运行 gitlab-runner
实例,通过 kubernetes 集群中的 kubernetes 执行器(我们称之为 KUBE01)。这些实例构建并部署到 kubernetes 集群,并为运行器提供一个环境变量 KUBECONFIG
(指向配置文件),如下所示:
$ cat $KUBECONFIG
---
apiVersion: v1
clusters:
- name: gitlab-deploy
cluster:
server: https://KUBE01:6443
certificate-authority-data: <CA_B64>
contexts:
- name: gitlab-deploy
context:
cluster: gitlab-deploy
namespace: dev
user: gitlab-deploy
current-context: gitlab-deploy
kind: Config
users:
- name: gitlab-deploy
user:
token: gitlab-deploy-token-<secret>
我们可以验证kubectl
实际上是在使用上面的gitlab-deploy
上下文:
$ kubectl config current-context
gitlab-deploy
但是,尝试实际影响 KUBE01 失败了:
$ kubectl get pods
error: You must be logged in to the server (Unauthorized)
在我的机器上,我们可以验证名称空间和服务帐户令牌是否正确:
$ kubectl get sa/gitlab-deploy -o yaml --namespace dev
apiVersion: v1
kind: ServiceAccount
metadata:
<snip metadata>
name: gitlab-deploy
namespace: dev
secrets:
- name: gitlab-deploy-token-<secret>
除了 它应该可以正常工作,我找不到任何关于此的文档,而且我发现的关于此错误消息的所有 forum/stack 交换问题都是错误的 user/pass组合;但据我所知,我的令牌、命名空间和集群都是正确的。
在更详细地阅读 kuberneter authentication documentation 和一些反复试验之后,我找到了问题所在。
"secret tokens" 内部服务帐户对象不是我们用于服务帐户身份验证的实际 秘密令牌;相反,它是指向秘密对象的指针,而秘密对象又持有真实(承载)令牌。可以找到如下:
$ kubectl get secret gitlab-deploy-token-<secret> -o yaml
apiVersion: v1
data:
ca.crt: <CA_B64>
namespace: ZGV2
token: <BEARER_TOKEN_B64>
kind: Secret
metadata:
<snip metadata>
name: gitlab-deploy-token-<secret>
namespace: dev
type: kubernetes.io/service-account-token
不记名令牌当然是 base64 编码的,因为它是一个秘密;但奇怪的是,我们没有在 KUBECONFIG
文件中对其进行 base64 编码(就像我们对 CA 所做的那样)。因此,我们要做的就是找到上面的 bearer token,将其从 base64 解码,并将其作为我们的 token 添加到 gitlab-deploy
用户下。然后,身份验证工作。
我们是 运行 gitlab-runner
实例,通过 kubernetes 集群中的 kubernetes 执行器(我们称之为 KUBE01)。这些实例构建并部署到 kubernetes 集群,并为运行器提供一个环境变量 KUBECONFIG
(指向配置文件),如下所示:
$ cat $KUBECONFIG
---
apiVersion: v1
clusters:
- name: gitlab-deploy
cluster:
server: https://KUBE01:6443
certificate-authority-data: <CA_B64>
contexts:
- name: gitlab-deploy
context:
cluster: gitlab-deploy
namespace: dev
user: gitlab-deploy
current-context: gitlab-deploy
kind: Config
users:
- name: gitlab-deploy
user:
token: gitlab-deploy-token-<secret>
我们可以验证kubectl
实际上是在使用上面的gitlab-deploy
上下文:
$ kubectl config current-context
gitlab-deploy
但是,尝试实际影响 KUBE01 失败了:
$ kubectl get pods
error: You must be logged in to the server (Unauthorized)
在我的机器上,我们可以验证名称空间和服务帐户令牌是否正确:
$ kubectl get sa/gitlab-deploy -o yaml --namespace dev
apiVersion: v1
kind: ServiceAccount
metadata:
<snip metadata>
name: gitlab-deploy
namespace: dev
secrets:
- name: gitlab-deploy-token-<secret>
除了 它应该可以正常工作,我找不到任何关于此的文档,而且我发现的关于此错误消息的所有 forum/stack 交换问题都是错误的 user/pass组合;但据我所知,我的令牌、命名空间和集群都是正确的。
在更详细地阅读 kuberneter authentication documentation 和一些反复试验之后,我找到了问题所在。
"secret tokens" 内部服务帐户对象不是我们用于服务帐户身份验证的实际 秘密令牌;相反,它是指向秘密对象的指针,而秘密对象又持有真实(承载)令牌。可以找到如下:
$ kubectl get secret gitlab-deploy-token-<secret> -o yaml
apiVersion: v1
data:
ca.crt: <CA_B64>
namespace: ZGV2
token: <BEARER_TOKEN_B64>
kind: Secret
metadata:
<snip metadata>
name: gitlab-deploy-token-<secret>
namespace: dev
type: kubernetes.io/service-account-token
不记名令牌当然是 base64 编码的,因为它是一个秘密;但奇怪的是,我们没有在 KUBECONFIG
文件中对其进行 base64 编码(就像我们对 CA 所做的那样)。因此,我们要做的就是找到上面的 bearer token,将其从 base64 解码,并将其作为我们的 token 添加到 gitlab-deploy
用户下。然后,身份验证工作。