kube-system命名空间
在k8s中,每个命名空间下,都会有一个default serviceAccount,这是ServiceAccount准入控制器所设置的,kube-system命名空间也不例外;并且如果一个 Pod 没有声明 serviceAccountName,Kubernetes 会自动将 Namespace 下名叫 default 的默认 ServiceAccount分配给这个 Pod,但在这种情况下,这个默认 ServiceAccount 并没有关联任何 Role。
而且我们知道,ServiceAccount为了集群内的应用和apiserver交互而生的,它充当了账号的功能。再结合RABC权限管理,就能够控制一个账号的访问权限了。
那么诸如controller-manager、kube-scheduler、etcd是否会持有default serviceAccount,从而和apiserver进行认证和授权呢?如果是这样的,是怎样进行认证和授权的呢?
另外延伸一下普通命名空间下的serviceaccount是否也遵循同样的认证和授权规则呢?
带着上面的问题,我们来到了kube-system命名空间下。在查看了kubeadm方式安装的k8s,像controller-manager、kube-scheduler的POD yaml定义中,spec字段中并没有绑定serviceAccount,这是为什么呢?
是因为这些组件比较的特殊,它们是静态POD,而静态 Pod 的 spec 不能引用其他的 API 对象(例如: ServiceAccount、 ConfigMap、 Secret 等)。
那么问题随之而来,它们使用什么样的账号和apiserver进行认证呢?
我们在查看/etc/kubernetes/pki(有些时候,证书会以base64编码到/etc/kubernetes/*conf文件中)下,可以看到有很多的证书文件,正是使用了这些证书文件来通过kubernetes认证检查的。有关证书认证的细节,可以查看《kubernetes权威指南-6.1.1 HTTPS证书认证》。
接着再考虑鉴权问题。kubernetes中为核心组件定义了各种角色和角色绑定,如角色system:kube-controller-manager,角色绑定system:kube-controller-manager,并且角色绑定了所关联的用户正是证书中所定义的CN字段值。
如,在/etc/kubernetes/controller-manager.conf中,指定了base64所编码的证书,解码后得到Subject: CN=system:kube-controller-manager
而查看角色绑定,system:kube-controller-manager其中所绑定的用户正是证书中cn字段的值
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
creationTimestamp: "2022-09-26T09:31:13Z"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: system:kube-controller-manager
resourceVersion: "141"
uid: 7f80fca5-8a95-42fa-877a-1f51bbaaa70c
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:kube-controller-manager
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: system:kube-controller-manager
其他一些核心组件,如etcd、kube-scheduler的认证和鉴权也是如此。
普通命名空间
我们将视角转到普通命名空间下,观察它的认证和授权。
首先创建一个POD:
kubectl run nginx --image=nginx
然后查看该POD的YAML定义,发现spec.serviceAccountName为default
$ kubectl get pod/nginx -oyaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: "2022-11-15T04:01:58Z"
labels:
run: nginx
name: nginx
namespace: default
resourceVersion: "5892284"
uid: ab98dbe1-9ed7-4e46-aae8-ca02ec68204e
spec:
containers:
- image: nginx
imagePullPolicy: Always
name: nginx
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: kube-api-access-l8prv
readOnly: true
dnsPolicy: ClusterFirst
enableServiceLinks: true
serviceAccount: default
serviceAccountName: default
另外ServiceAccout,会被Projected到容器的/run/secrets/kubernetes.io/serviceaccount下
...
spec:
containers:
- image: nginx
imagePullPolicy: Always
name: nginx
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: kube-api-access-xs8cp
readOnly: true
...
volumes:
- name: kube-api-access-xs8cp
projected:
defaultMode: 420
sources:
- serviceAccountToken:
expirationSeconds: 3607
path: token
- configMap:
items:
- key: ca.crt
path: ca.crt
name: kube-root-ca.crt
- downwardAPI:
items:
- fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
path: namespace
到容器内部查看Secret信息:
root@nginx:/run/secrets/kubernetes.io/serviceaccount# ls -l
total 0
lrwxrwxrwx 1 root root 13 Nov 10 04:53 ca.crt -> ..data/ca.crt
lrwxrwxrwx 1 root root 16 Nov 10 04:53 namespace -> ..data/namespace
lrwxrwxrwx 1 root root 12 Nov 10 04:53 token -> ..data/token
root@nginx:/run/secrets/kubernetes.io/serviceaccount#
ca.crt
eyJhbGciOiJSUzI1NiIsImtpZCI6ImlSbjhteGZ0MlRlUV9yUjlUbk1Na0VMZngxODhBTlg0MTZtT1lJWFhUREkifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNjk5NjY1MTY5LCJpYXQiOjE2NjgxMjkxNjksImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJkZWZhdWx0IiwicG9kIjp7Im5hbWUiOiJuZ2lueCIsInVpZCI6ImU1YjkzODFjLWExY2EtNDYzMi1hYmIwLWFmYmM5Y2I1NmUwYiJ9LCJzZXJ2aWNlYWNjb3VudCI6eyJuYW1lIjoiZGVmYXVsdCIsInVpZCI6IjJmNTE2ODVjLTM0MjUtNDNjOS04OTFlLWJhYWRlNzg0MzFjMCJ9LCJ3YXJuYWZ0ZXIiOjE2NjgxMzI3NzZ9LCJuYmYiOjE2NjgxMjkxNjksInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.h7SNcZTAz9rn2jQah3A37HRwrp2aKDn4rdEttBPGQY_ZQW61dN09UluObH6p3SJxxabp5Diw1--VaeP5EEved3rLw6YwUQg3rxDnoA1Xuy5tfRPJXmMlW6_dxfSEEJ6tTMvx0UgLTOIyikYZ3gj6bdz6f7PJC-hfPTcnqPkkkQA7w1h0h1w6Aj5vgy3EUVGXEK8xQynZDNUS9J-TRIh_Lptepl5AzQeoRM8qgFT4U6MvM0Cl4gbPR7gXy1LkOomQJFsQWEBJ5yV3-e90tY5s4JZPYPkDS0YiEufcBg1rrsP42WYOLVMPKkhrStSMRygL4IpfIO0Diflb9_Zf3oP2Fw
token
-----BEGIN CERTIFICATE-----
MIIDBjCCAe6gAwIBAgIBATANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwptaW5p
a3ViZUNBMB4XDTIyMTEwNzEyMDQ1OFoXDTMyMTEwNTEyMDQ1OFowFTETMBEGA1UE
AxMKbWluaWt1YmVDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL/s
NbBzIflL83iGloIh3MhfKW05H4HSh+bYFUho5Kc6emNcca14h/A+l8NZw2vjH1GV
uIQZ6vu29n7pCESB1rc01oHOBx4xfrOUsnD7CDT9fe5CUmx6MmYKfWoExWxn1Mpc
Wrxk3kPVikOoDoleGc3syEVJatbXte0db6lxMA2BpZqFrztypVRNaYx4P6guR0Kn
HhDv+JIfzkcOOGAsZlwwc9jdP+dQj3t+2SBjM84m07bVJIzdr7ChNlkP07VP1dAp
LBGZqvKuy0gtbsn2W+nfF/DXscG0ZSiF4Vp5p/QmbIlJ8Ks6KtGovj24BWkNJSOQ
Ix1VnCgKfwQsrnZiCqkCAwEAAaNhMF8wDgYDVR0PAQH/BAQDAgKkMB0GA1UdJQQW
MBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
BBSX+0UH4kjXeUl9X6xaXYmWRimADjANBgkqhkiG9w0BAQsFAAOCAQEAN2XYgE5C
2s84uix5Qe9NKC9t9SVcnlnf4ZS4EBARH567gYSfxdh1q9DiCJCnP4xtd0noKpPP
e+FeBxkDBrtfBbytIsC5Lq8n+97iwEvdonVXOMJUFZiUC8XtrCmD9f7xCU+iUEva
GmYXP6hygWive1hcMZqHTVzhdOPSTEuPOLAyGiNJVpPbEZqkjUU443VgWpL0CtR6
7BQeluxTSJq5qJCaCetq7gy4RRaphAcBPKeRIxT8sLOrBUzsiQ1tT1BHHBQ0Jfpt
Kb5sX5+rXbQyWPepRNhcSjuNqTx+MukkkIk1rr0PTDM0XtN2Z3iQAX1OhnPIwwRm
dge/2sobKt5XzQ==
-----END CERTIFICATE-----
namespace
default
我们尝试使用该serviceaccount访问集群中的资源
$ kubectl exec -it nginx -- sh
# Point to the internal API server hostname
APISERVER=https://kubernetes.default.svc
# Path to ServiceAccount token
SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
# Read this Pod's namespace
NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace)
# Read the ServiceAccount bearer token
TOKEN=$(cat ${SERVICEACCOUNT}/token)
# Reference the internal certificate authority (CA)
CACERT=${SERVICEACCOUNT}/ca.crt
# Explore the API with TOKEN
$ curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api
{
"kind": "APIVersions",
"versions": [
"v1"
],
"serverAddressByClientCIDRs": [
{
"clientCIDR": "0.0.0.0/0",
"serverAddress": "192.168.0.41:6443"
}
]
}
$ curl --cacert ${CACERT} \
--header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/versions
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {
},
"status": "Failure",
"message": "forbidden: User \"system:serviceaccount:default:default\" cannot get path \"/versions\"",
"reason": "Forbidden",
"details": {
},
"code": 403
}
发现虽然通过了认证检查,但是没有通过鉴权检查(403),表明我们没有权限来操作集群中的资源。
能够看到这个default serviceaccout权限太小了,默认情况下它继承了system:serviceaccounts的权限,只能操作一些非资源类型,如果提升权限,就只能创建对应角色并绑定它了。
system:serviceaccounts组的角色和角色绑定,
角色绑定:system:service-account-issuer-discovery
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
creationTimestamp: "2022-09-26T09:31:13Z"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: system:service-account-issuer-discovery
resourceVersion: "146"
uid: d6ce5a27-41ae-4e26-a860-6c8a1008b41e
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:service-account-issuer-discovery
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:serviceaccounts
角色内容:service-account-issuer-discovery
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
creationTimestamp: "2022-09-26T09:31:13Z"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: system:service-account-issuer-discovery
resourceVersion: "101"
uid: a301c134-7d65-45d6-8890-1c13311a3fc9
rules:
- nonResourceURLs:
- /.well-known/openid-configuration
- /openid/v1/jwks
verbs:
- get
今天的文章认证和鉴权的区别_serviceaccount有什么用分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/48500.html