在kubernetes集群,可以登陆到master集群,可以使用私钥证书的方式访问。证书路径:master的/etc/kubernetes/pki/(ca.crt / apiserver.crt / apiserver.key) 下面。
# server是apiserver公网访问地址
$ curl --cacert ca.crt --cert apiserver.crt --key apiserver.key https://$server/api
这里再介绍一下使用ServiceAccount Token的方式访问集群。
serviceaccount的权限由集群中对应的rolebinding决定,官方文档:
https://kubernetes.io/docs/reference/access-authn-authz/rbac
# 请选择对应权限的ServiceAccount来获取token,这边选择的是admin ServiceAccount
$ kubectl get sa admin -n kube-system -o yaml
# 查看对应的clusterrolebinding:
$ kubectl get clusterrolebinding admin -o yaml
# 查看admin sa绑定的clusterrole和对应的权限。命令:
$ kubectl get clusterrole admin -o yaml
# 获取对应sa的secret从中获取token。并进行base64解码。
$ kubectl get secret admin-token-5tctj -n kube-system -o jsonpath={".data.token"} | base64 -d
最后使用该token访问apiserver:
最后使用公网slb地址访问。
# 如 curl -k -H 'Authorization: Bearer token' https://10.182.101.255:6443/api/v1/namespaces
curl -k -H 'Authorization: Bearer token' https://111.111.111.111:6443/path(api接口)
例如:
$ curl -k -H 'Authorization: Bearer hbGciOiJSUzI1NiIsImtpZCI6Ilg3RHRVOEZZdW0zVmZLV0JZeGlfVjJSTG1TQ1A3LWRPX0w1SUVvdldEWkkifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkZWZhdWx0LXRva2VuLXBycjJsIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImRlZmF1bHQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiIxN2U3NjAxMi1lYTE5LTRkNDktODM1NS0zMmQ4OGIzY2Y2YWEiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06ZGVmYXVsdCJ9.dLNfDTlxoEAMw115yT4NPsOgRcN1rOp9rCZYj9mAzbfKX3L1LNzLlCAYgcBjWdro5u-8NncOyWp9--vAyADq7yaa0T-tBfVALg8dESuwSQpSN-I5YOh7G8ua81HFjWFWX6dvq1GW2fbHPeXCJDlkBnJAbTGLb-487lbK0VWkSdLl1tsT435eZS5e6rRNIWAJJizVBrxDliND_7IXE6zILOR5u-A3z3wk3ngCv4e2FLNOR6z4qr2l-xyQG3pLXH2YQt_TjCkaR9kg57CRQRpwSiN6DfMfeq_qwI7d_iCawNSbLEBWRPEjA3j4juE64CcrA1fr58LIFxEr_ga949XgWw' https://10.182.101.255:6443/api/v1/namespaces
$ curl -k -H 'Authorization: Bearer hbGciOiJSUzI1NiIsImtpZCI6Ilg3RHRVOEZZdW0zVmZLV0JZeGlfVjJSTG1TQ1A3LWRPX0w1SUVvdldEWkkifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkZWZhdWx0LXRva2VuLXBycjJsIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImRlZmF1bHQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiIxN2U3NjAxMi1lYTE5LTRkNDktODM1NS0zMmQ4OGIzY2Y2YWEiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06ZGVmYXVsdCJ9.dLNfDTlxoEAMw115yT4NPsOgRcN1rOp9rCZYj9mAzbfKX3L1LNzLlCAYgcBjWdro5u-8NncOyWp9--vAyADq7yaa0T-tBfVALg8dESuwSQpSN-I5YOh7G8ua81HFjWFWX6dvq1GW2fbHPeXCJDlkBnJAbTGLb-487lbK0VWkSdLl1tsT435eZS5e6rRNIWAJJizVBrxDliND_7IXE6zILOR5u-A3z3wk3ngCv4e2FLNOR6z4qr2l-xyQG3pLXH2YQt_TjCkaR9kg57CRQRpwSiN6DfMfeq_qwI7d_iCawNSbLEBWRPEjA3j4juE64CcrA1fr58LIFxEr_ga949XgWw' https://10.182.101.255:6443/api
{
"kind": "APIVersions",
"versions": [
"v1"
],
"serverAddressByClientCIDRs": [
{
"clientCIDR": "0.0.0.0/0",
"serverAddress": "172.20.8.14:6443"
}
]
}
在 Kubernetes 中,admin
和 cluster-admin
是两个不同的角色,它们在权限层级上有所不同。
admin
角色:
admin
角色通常是指拥有特定命名空间(namespace)的管理员权限的用户或服务账户。这个角色允许用户执行一些与特定命名空间相关的管理任务,如创建、删除资源对象,以及查看和修改特定命名空间内的资源。admin
角色没有集群范围的管理权限,只能对某个命名空间内的资源进行操作。该角色通常用于限定用户的权限,使其只能管理特定的资源。cluster-admin
角色:
cluster-admin
角色是 Kubernetes 中的超级管理员角色,具有对整个集群的完全控制权限。拥有 cluster-admin
角色的用户或服务账户可以对所有命名空间中的任何资源进行任意操作,包括创建、删除、修改以及访问集群级别的信息。cluster-admin
角色通常用于赋予用户对整个集群的高级管理权限,比如执行集群范围的配置更改、安装插件或进行集群级别的监控。总的来说,admin
角色是针对某个命名空间的管理员权限,而 cluster-admin
角色是对整个集群的超级管理员权限。在实践中,为了最小化权限并遵循最小权责原则,应该尽可能使用 admin
角色,只在必要时才授予用户或服务账户 cluster-admin
角色。
$ kubectl get clusterrole | grep admin
admin 2023-11-16T07:21:29Z
cluster-admin 2023-11-16T07:21:29Z
system:aggregate-to-admin 2023-11-16T07:21:29Z
system:kubelet-api-admin 2023-11-16T07:21:29Z
# 可以看出 cluster-admin 具有所有资源的所有权限
$ kubectl describe clusterrole cluster-admin
Name: cluster-admin
Labels: kubernetes.io/bootstrapping=rbac-defaults
Annotations: rbac.authorization.kubernetes.io/autoupdate: true
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
*.* [] [] [*]
[*] [] [*]
# 可以看出 admin 具有所有资源的部分权限(下面没有粘贴上全部内容,请自行查看自己的集群)
$ kubectl describe clusterrole admin
Name: admin
Labels: kubernetes.io/bootstrapping=rbac-defaults
Annotations: rbac.authorization.kubernetes.io/autoupdate: true
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
pods/attach [] [] [get list watch create delete deletecollection patch update]
pods/exec [] [] [get list watch create delete deletecollection patch update]
pods/portforward [] [] [get list watch create delete deletecollection patch update]
pods/proxy [] [] [get list watch create delete deletecollection patch update]
secrets [] [] [get list watch create delete deletecollection patch update]
services/proxy [] [] [get list watch create delete deletecollection patch update]
bindings [] [] [get list watch]
endpoints [] [] [get list watch]
limitranges [] [] [get list watch]
namespaces/status [] [] [get list watch]
namespaces [] [] [get list watch]
persistentvolumeclaims/status [] [] [get list watch]
pods/log [] [] [get list watch]
# 1. 创建 ServiceAccount
$ kubectl create sa cluster-admin-test -n kube-system
# 2. 创建 ClusterRoleBinding
$ kubectl create clusterrolebinding cluster-admin-test-crb --clusterrole=cluster-admin --serviceaccount=kube-system:cluster-admin-test
# 3. 由于现在 创建 sa 不自动生成 secret,因此创建个 secret 保持永久有效的 token, 使用 kubectl 执行下面内容
apiVersion: v1
kind: Secret
metadata:
name: cluster-admin-test-secret
namespace: kube-system
annotations:
kubernetes.io/service-account.name: "cluster-admin-test" # 这里填写serviceAccountName
type: kubernetes.io/service-account-token
# 4. 获取对应sa的secret从中获取token。并进行base64解码。
$ kubectl get secret cluster-admin-test-secret -n kube-system -o jsonpath={".data.token"} | base64 -d
# 注意要去掉后面的 % 号
eyJ....7X6Vd5sdVViZEr3Cv2xiGa2gzWRDgVXxZc1yJ64OKBOYHkEtay5t9bTulof1x4D-HefAPNGd5hdw% # 错误
eyJ....7X6Vd5sdVViZEr3Cv2xiGa2gzWRDgVXxZc1yJ64OKBOYHkEtay5t9bTulof1x4D-HefAPNGd5hdw # 正确
果然两天不看就跟不上了,我的集群版本是 1.25.3,今天需要用 token 来做些事情,创建 serviceAccount 的时候发现没有生成 secret,查了一下发现从 1.24 开始就不会自动生成 secret 了,chanagelog 在这里.
内容如下 LegacyServiceAccountTokenNoAutoGeneration 功能门是测试版,默认启用。启用后,不再为每个 ServiceAccount 自动生成包含服务帐户令牌的 Secret API 对象。使用 TokenRequest API 获取服务帐户令牌,或者如果需要未过期的令牌,请按照本指南为令牌控制器创建一个 Secret API 对象以填充服务帐户令牌
pr: https://github.com/kubernetes/kubernetes/pull/108309
在上面提到的两种方式要怎么用呢
方式 1 使用 TokenRequest API
来生成 token,获取方式如下
kubectl create token -n xxx
来获取一个临时的 token, 默认 1 小时方式 2 创建 secret token,创建后从 secret 的 token 字段拿就可以了
apiVersion: v1
kind: Secret
metadata:
name: secret-sa-sample
annotations:
kubernetes.io/service-account.name: "sa-name" # 这里填写serviceAccountName
type: kubernetes.io/service-account-token
在 Kubernetes 的 kubeconfig
文件中,以下三个字段用于配置客户端认证:
client-certificate-data
:
client-key-data
:
certificate-authority-data
:
这些字段是客户端认证的一部分,通常与 users
部分的某个具体用户配置关联。以下是一个示例 kubeconfig 文件片段,演示了如何配置客户端认证:
apiVersion: v1
clusters:
- cluster:
server: https://-api-server>
certificate-authority-data: -encoded-ca-cert>
name: my-cluster
contexts:
- context:
cluster: my-cluster
user: my-user
name: my-context
current-context: my-context
kind: Config
preferences: {}
users:
- name: my-user
user:
client-certificate-data: -encoded-client-cert>
client-key-data: -encoded-client-key>
----
# 实际环境信息
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTi......NG1DN1NqeUJDNUkKKzZFPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
server: https://127.0.0.1:63522
name: kind-12403-k8s-cluster
contexts:
- context:
cluster: kind-12403-k8s-cluster
user: kind-12403-k8s-cluster
name: kind-12403-k8s-cluster
current-context: kind-12403-k8s-cluster
kind: Config
preferences: {}
users:
- name: kind-12403-k8s-cluster
user:
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ......RVJUSUZJQ0FURS0tLS0tCg==
client-key-data: LS0tLS1CRUdJTi......NzBIWUg1Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==
请注意,
、
、
分别是 Base64 编码的 CA 证书、客户端证书和客户端私钥数据。这些字段的值可以通过将相应的 PEM 格式文件内容进行 Base64 编码获得。
Kubernetes是一个完全基于API的系统。使用curl或Postman等简单工具,在构建应用程序之前获取API信息更方便。
1、从查看 kubectl 的配置文件开始,需要:三个证书和 API server 的地址
# cat /root/.kube/config
2、我们将会把证书设为环境变量,在设置时候请检查每一个参数。我们从 client-certificate-data 开始。
export clientcert=$(grep client-cert ~/.kube/config |cut -d" " -f 6)
echo $clientcert
3、使用类似的命令将 client-key-data 保存为环境变量
export clientkey=$(grep client-key-data ~/.kube/config |cut -d" " -f 6)
echo $clientkey
4、然后是 certificate-authority-data
export certauth=$(grep certificate-authority-data ~/.kube/config |cut -d" " -f 6)
echo $certauth
5、加密这些变量,供 curl 使用:
[root@master k8s-cert\]# echo $clientcert | base64 -d > ./client.pem
[root@master k8s-cert\]# echo $clientkey | base64 -d > ./client-key.pem
[root@master k8s-cert\]# echo $certauth | base64 -d > ./ca.pem
6、从配置文件中读取 server 地址:
$ kubectl config view |grep server
server: https://10.182.101.255:6443
7、使用 curl 和刚刚加密的密钥文件来访问 API server:
curl --cert ./client.pem --key ./client-key.pem --cacert ./ca.pem https://10.182.101.255:6443/api/v1/pods
curl --cert ./client.pem --key ./client-key.pem --cacert ./ca.pem https://10.182.101.255:6443/api/v1/namespace
export clientcert=$(grep client-cert ~/.kube/config |cut -d" " -f 6)
export clientkey=$(grep client-key-data ~/.kube/config |cut -d" " -f 6)
export certauth=$(grep certificate-authority-data ~/.kube/config |cut -d" " -f 6)
echo $clientcert | base64 -d > ./client.pem
echo $clientkey | base64 -d > ./client-key.pem
echo $certauth | base64 -d > ./ca.pem
curl --cert ./client.pem --key ./client-key.pem --cacert ./ca.pem https://10.182.101.255:6443/api/v1/pods