Kubernetes Serviceaccount
SericeAccount基础
为何需要Service Account?
#Kubernetes原生(kubernetes-native) 托管运行于Kubernetes之上,通常需要直接与API Server进行交互以获取必要的信息
#API Server同样需要对这类来自于Pod资源中客户端程序进行身份验证,Service Account也就是设计专用于这类场景的账号
#ServiceAccount是API Server支持的标准资源类型之
在Pod 上使用Service Account
#自动设定: Service Account通常由API Server自动创建并通过 ServiceAccount准入控制器自动关联到集群中创建的每个Pod上
#自定义:在Pod规范上,使用serviceAccountName指定要使用的特定ServiceAccount
ServiceAccount资源
ServiceAccount是Kubernetes API上的标准资源类型
#基于资源对象保存ServiceAccount的数据
#认证信息保存于ServiceAccount对象专用的Secret中 (v1.23及之前的版本)
#隶属名称空间级别,专供集群上的Pod中的进程访问API Server时使用
Kubernetes基于三个组件完成Pod serviceacccunt的自动化
ServiceAccount Admission Controller: 负责完成Pod上的ServiceAccount的自动化
#为每个名称空间生成一个默认的defaultScrviceAccount及其依赖到的Secret对象 (如果用得到)
#为未定义serviceAccountName的Pod资源自动附加名称空河下的serviceaccounts/default;\
#为定义了serviceAccountName的Pod资源检查其引用的目标对象是否存在
Token Controller
ServiceAccount Controller
提示: 需要用到特殊权限时,可为Pod指定要使用的自定义ServiceAccount资源对象
ServiceAccount Secret Token
ServiceAccount使用专用的Secret对象(Kubernetes v1.23-) 存储相关的敏感信息
Secret对象的类型标识为“kubernetes.io/serviceaccount
该Secret对象会自动附带认证到API Server用到的Token,也称为ServiceAccount Token
ServiceAccount Token的不同实现方式
#Kubernetes v1.20-
系统自动生成专用的Secrct对象,并基于secret卷插件关联至相关的Pod;
Secret中会自动附带Token,且永久有效
#Kubernetes v1.21-v1.23 :
系统自动生成专用的Secret对象,并通过projected卷插关联至相关的Pod;
Pod不会使用Secret上的Token,而是由Kubelet同TokenRequest API请求生成,默认有效期为一年,且每小时更新一次;
#Kubernetes v1.24+ :
系统不再自动生成专用的Secret对象
由Kubelet负责向TokenRequest API请求生成Token
ServiceAccount中的数据
ServiceAccount专用的Secret对象有三个固定的数据项,它们的键名称分别为 pod中挂载路径: /var/run/secrets/kubernetes.io/serviceaccount
#ca.crt: Kubernetes CA的数字证书
#namespace: 该ServiceAcccunt可适用的名称空间
#token: 认证到API Server的令牌,其生成方式曾多次变动
Kubernetes v1.21及之后的版本中,Pod加载上面三种数据的方式,改变为基于projected卷插件,通过三个数据源 (source) 分别进行
#serviceAccountToken: 提供由Kubelet负责向TokenRequest API请求生成的Token
#configMap: 经由kube-root-ca.crt这个ConfigMap对象的ca.crt键,引用Kubernetes CA的证书
#downwardAPI:基于fieldRef,获取当前Pod所处的名称空间
特殊场景
若需要一个永不过期的Token,可手动创建ServiceAccount专用类型的Secret,并将其关联到ServiceAccount之上
实践
[root@k8s-master01 metalLB]# kubectl create sa sheca
[root@k8s-master01 metalLB]# cat serviceaccount-pod.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: demoapp
name: demoapp
spec:
replicas: 1
selector:
matchLabels:
app: demoapp
template:
metadata:
labels:
app: demoapp
spec:
serviceAccountName: sheca
containers:
- image: ikubernetes/demoapp:v1.0
name: demoapp
[root@k8s-master01 metalLB]# kubectl apply -f serviceaccount-pod.yaml
[root@k8s-master01 metalLB]# kubectl get pods | grep demo
demoapp-8f996d868-c4lpt 1/1 Running 0 9s
[root@k8s-master01 metalLB]# kubectl exec -it demoapp-8f996d868-c4lpt /bin/sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
[root@demoapp-8f996d868-c4lpt /]# cd /var/run/secrets/kubernetes.io/serviceaccount
[root@demoapp-8f996d868-c4lpt /run/secrets/kubernetes.io/serviceaccount]# ls
ca.crt namespace token
#此时没有权限 需要绑定权限才可以查看
[root@demoapp-8f996d868-c4lpt /run/secrets/kubernetes.io/serviceaccount]# curl -H "Authorization: Bearer $(cat token)" -k https://192.168.40.101:6443
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "forbidden: User \"system:serviceaccount:default:sheca\" cannot get path \"/\"",
"reason": "Forbidden",
"details": {},
"code": 403
}
#设置 sheca sa 拥有cluster-admin权限
[root@k8s-master01 metalLB]# kubectl create clusterrolebinding sheca-clusterrolebinding --clusterrole=cluster-admin --serviceaccount=default:sheca
clusterrolebinding.rbac.authorization.k8s.io/sheca-clusterrolebinding created
[root@k8s-master01 metalLB]# kubectl exec -it demoapp-8f996d868-c4lpt /bin/sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
[root@demoapp-8f996d868-c4lpt /]# cd /var/run/secrets/kubernetes.io/serviceaccount/
[root@demoapp-8f996d868-c4lpt /run/secrets/kubernetes.io/serviceaccount]# curl -H "Authorization: Bearer $(cat token)" -k https://192.168.40.101:6443
{
"paths": [
"/.well-known/openid-configuration",
"/api",
"/api/v1",
"/apis",
"/apis/",
"/apis/admissionregistration.k8s.io",
"/apis/admissionregistration.k8s.io/v1",
"/apis/agent.k8s.elastic.co",
"/apis/agent.k8s.elastic.co/v1alpha1",
"/apis/apiextensions.k8s.io",
"/apis/apiextensions.k8s.io/v1",
"/apis/apiregistration.k8s.io",
"/apis/apiregistration.k8s.io/v1",
"/apis/apm.k8s.elastic.co",
"/apis/apm.k8s.elastic.co/v1",
"/apis/apm.k8s.elastic.co/v1beta1",
"/apis/apps",
"/apis/apps/v1",
"/apis/authentication.k8s.io",
"/apis/authentication.k8s.io/v1",
"/apis/authorization.k8s.io",
"/apis/authorization.k8s.io/v1",
"/apis/autoscaling",
"/apis/autoscaling.k8s.elastic.co",
"/apis/autoscaling.k8s.elastic.co/v1alpha1",
"/apis/autoscaling/v1",
"/apis/autoscaling/v2",
"/apis/batch",
"/apis/batch/v1",
"/apis/beat.k8s.elastic.co",
"/apis/beat.k8s.elastic.co/v1beta1",
"/apis/certificates.k8s.io",
"/apis/certificates.k8s.io/v1",
"/apis/coordination.k8s.io",
"/apis/coordination.k8s.io/v1",
"/apis/crd.projectcalico.org",
"/apis/crd.projectcalico.org/v1",
"/apis/discovery.k8s.io",
"/apis/discovery.k8s.io/v1",
"/apis/elasticsearch.k8s.elastic.co",
"/apis/elasticsearch.k8s.elastic.co/v1",
"/apis/elasticsearch.k8s.elastic.co/v1beta1",
"/apis/enterprisesearch.k8s.elastic.co",
"/apis/enterprisesearch.k8s.elastic.co/v1",
"/apis/enterprisesearch.k8s.elastic.co/v1beta1",
"/apis/events.k8s.io",
"/apis/events.k8s.io/v1",
"/apis/flowcontrol.apiserver.k8s.io",
"/apis/flowcontrol.apiserver.k8s.io/v1beta2",
"/apis/flowcontrol.apiserver.k8s.io/v1beta3",
"/apis/kibana.k8s.elastic.co",
"/apis/kibana.k8s.elastic.co/v1",
"/apis/kibana.k8s.elastic.co/v1beta1",
"/apis/logstash.k8s.elastic.co",
"/apis/logstash.k8s.elastic.co/v1alpha1",
"/apis/maps.k8s.elastic.co",
"/apis/maps.k8s.elastic.co/v1alpha1",
"/apis/metallb.io",
"/apis/metallb.io/v1alpha1",
"/apis/metallb.io/v1beta1",
"/apis/metallb.io/v1beta2",
"/apis/networking.k8s.io",
"/apis/networking.k8s.io/v1",
"/apis/node.k8s.io",
"/apis/node.k8s.io/v1",
"/apis/openebs.io",
"/apis/openebs.io/v1",
"/apis/openebs.io/v1alpha1",
"/apis/policy",
"/apis/policy/v1",
"/apis/rbac.authorization.k8s.io",
"/apis/rbac.authorization.k8s.io/v1",
"/apis/scheduling.k8s.io",
"/apis/scheduling.k8s.io/v1",
"/apis/stackconfigpolicy.k8s.elastic.co",
"/apis/stackconfigpolicy.k8s.elastic.co/v1alpha1",
"/apis/storage.k8s.io",
"/apis/storage.k8s.io/v1",
"/healthz",
"/healthz/autoregister-completion",
"/healthz/etcd",
"/healthz/log",
"/healthz/ping",
"/healthz/poststarthook/aggregator-reload-proxy-client-cert",
"/healthz/poststarthook/apiservice-discovery-controller",
"/healthz/poststarthook/apiservice-openapi-controller",
"/healthz/poststarthook/apiservice-openapiv3-controller",
"/healthz/poststarthook/apiservice-registration-controller",
"/healthz/poststarthook/apiservice-status-available-controller",
"/healthz/poststarthook/bootstrap-controller",
"/healthz/poststarthook/crd-informer-synced",
"/healthz/poststarthook/generic-apiserver-start-informers",
"/healthz/poststarthook/kube-apiserver-autoregistration",
"/healthz/poststarthook/priority-and-fairness-config-consumer",
"/healthz/poststarthook/priority-and-fairness-config-producer",
"/healthz/poststarthook/priority-and-fairness-filter",
"/healthz/poststarthook/rbac/bootstrap-roles",
"/healthz/poststarthook/scheduling/bootstrap-system-priority-classes",
"/healthz/poststarthook/start-apiextensions-controllers",
"/healthz/poststarthook/start-apiextensions-informers",
"/healthz/poststarthook/start-cluster-authentication-info-controller",
"/healthz/poststarthook/start-deprecated-kube-apiserver-identity-lease-garbage-collector",
"/healthz/poststarthook/start-kube-aggregator-informers",
"/healthz/poststarthook/start-kube-apiserver-admission-initializer",
"/healthz/poststarthook/start-kube-apiserver-identity-lease-controller",
"/healthz/poststarthook/start-kube-apiserver-identity-lease-garbage-collector",
"/healthz/poststarthook/start-legacy-token-tracking-controller",
"/healthz/poststarthook/start-service-ip-repair-controllers",
"/healthz/poststarthook/start-system-namespaces-controller",
"/healthz/poststarthook/storage-object-count-tracker-hook",
"/livez",
"/livez/autoregister-completion",
"/livez/etcd",
"/livez/log",
"/livez/ping",
"/livez/poststarthook/aggregator-reload-proxy-client-cert",
"/livez/poststarthook/apiservice-discovery-controller",
"/livez/poststarthook/apiservice-openapi-controller",
"/livez/poststarthook/apiservice-openapiv3-controller",
"/livez/poststarthook/apiservice-registration-controller",
"/livez/poststarthook/apiservice-status-available-controller",
"/livez/poststarthook/bootstrap-controller",
"/livez/poststarthook/crd-informer-synced",
"/livez/poststarthook/generic-apiserver-start-informers",
"/livez/poststarthook/kube-apiserver-autoregistration",
"/livez/poststarthook/priority-and-fairness-config-consumer",
"/livez/poststarthook/priority-and-fairness-config-producer",
"/livez/poststarthook/priority-and-fairness-filter",
"/livez/poststarthook/rbac/bootstrap-roles",
"/livez/poststarthook/scheduling/bootstrap-system-priority-classes",
"/livez/poststarthook/start-apiextensions-controllers",
"/livez/poststarthook/start-apiextensions-informers",
"/livez/poststarthook/start-cluster-authentication-info-controller",
"/livez/poststarthook/start-deprecated-kube-apiserver-identity-lease-garbage-collector",
"/livez/poststarthook/start-kube-aggregator-informers",
"/livez/poststarthook/start-kube-apiserver-admission-initializer",
"/livez/poststarthook/start-kube-apiserver-identity-lease-controller",
"/livez/poststarthook/start-kube-apiserver-identity-lease-garbage-collector",
"/livez/poststarthook/start-legacy-token-tracking-controller",
"/livez/poststarthook/start-service-ip-repair-controllers",
"/livez/poststarthook/start-system-namespaces-controller",
"/livez/poststarthook/storage-object-count-tracker-hook",
"/logs",
"/metrics",
"/metrics/slis",
"/openapi/v2",
"/openapi/v3",
"/openapi/v3/",
"/openid/v1/jwks",
"/readyz",
"/readyz/autoregister-completion",
"/readyz/etcd",
"/readyz/etcd-readiness",
"/readyz/informer-sync",
"/readyz/log",
"/readyz/ping",
"/readyz/poststarthook/aggregator-reload-proxy-client-cert",
"/readyz/poststarthook/apiservice-discovery-controller",
"/readyz/poststarthook/apiservice-openapi-controller",
"/readyz/poststarthook/apiservice-openapiv3-controller",
"/readyz/poststarthook/apiservice-registration-controller",
"/readyz/poststarthook/apiservice-status-available-controller",
"/readyz/poststarthook/bootstrap-controller",
"/readyz/poststarthook/crd-informer-synced",
"/readyz/poststarthook/generic-apiserver-start-informers",
"/readyz/poststarthook/kube-apiserver-autoregistration",
"/readyz/poststarthook/priority-and-fairness-config-consumer",
"/readyz/poststarthook/priority-and-fairness-config-producer",
"/readyz/poststarthook/priority-and-fairness-filter",
"/readyz/poststarthook/rbac/bootstrap-roles",
"/readyz/poststarthook/scheduling/bootstrap-system-priority-classes",
"/readyz/poststarthook/start-apiextensions-controllers",
"/readyz/poststarthook/start-apiextensions-informers",
"/readyz/poststarthook/start-cluster-authentication-info-controller",
"/readyz/poststarthook/start-deprecated-kube-apiserver-identity-lease-garbage-collector",
"/readyz/poststarthook/start-kube-aggregator-informers",
"/readyz/poststarthook/start-kube-apiserver-admission-initializer",
"/readyz/poststarthook/start-kube-apiserver-identity-lease-controller",
"/readyz/poststarthook/start-kube-apiserver-identity-lease-garbage-collector",
"/readyz/poststarthook/start-legacy-token-tracking-controller",
"/readyz/poststarthook/start-service-ip-repair-controllers",
"/readyz/poststarthook/start-system-namespaces-controller",
"/readyz/poststarthook/storage-object-count-tracker-hook",
"/readyz/shutdown",
"/version"
]
}