API Server作为Kubernetes网关,是访问和管理资源对象的唯一入口,其各种集群组件访问资源都需要经过网关才能进行正常访问和管理。每一次的访问请求都需要进行合法性的检验,其中包括身份验证、操作权限验证以及操作规范验证等,需要通过一系列验证通过之后才能访问或者存储数据到etcd当中。如下图:
一、ServiceAccount
Service account是为了方便Pod里面的进程调用Kubernetes API或其他外部服务而设计的。它与User account不同
User account是为人设计的,而service account则是为Pod中的进程调用Kubernetes API而设计;
User account是跨namespace的,而service account则是仅局限它所在的namespace;
从上面可以看到每个Pod无论定义与否都会有个存储卷,这个存储卷为default-token-*** token令牌,这就是pod和serviceaccount认证信息。通过secret进行定义,由于认证信息属于敏感信息,所以需要保存在secret资源当中,并以存储卷的方式挂载到Pod当中。从而让Pod内运行的应用通过对应的secret中的信息来连接apiserver,并完成认证。每个 namespace 中都有一个默认的叫做 default 的 service account 资源。进行查看名称空间内的secret,也可以看到对应的default-token。让当前名称空间中所有的pod在连接apiserver时可以使用的预制认证信息,从而保证pod之间的通信。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
[root@k8s-master ~]# kubectl get sa NAME SECRETS AGE default 1 50d [root@k8s-master ~]# kubectl get sa -n ingress-nginx #前期创建的ingress-nginx名称空间也存在这样的serviceaccount NAME SECRETS AGE default 1 11d nginx-ingress-serviceaccount 1 11d [root@k8s-master ~]# kubectl get secret NAME TYPE DATA AGE default-token-j5pf5 kubernetes.io/service-account-token 3 50d mysecret Opaque 2 1d tomcat-ingress-secret kubernetes.io/tls 2 10d [root@k8s-master ~]# kubectl get secret -n ingress-nginx NAME TYPE DATA AGE default-token-zl49j kubernetes.io/service-account-token 3 11d nginx-ingress-serviceaccount-token-mcsf4 kubernetes.io/service-account-token 3 11d
[root@k8s-master ~]# kubectl explain sa KIND: ServiceAccount VERSION: v1
DESCRIPTION: ServiceAccount binds together: * a name, understood by users, and perhaps by peripheral systems, for an identity * a principal that can be authenticated and authorized * a set of secrets
FIELDS: apiVersion <string> APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources
automountServiceAccountToken <boolean> AutomountServiceAccountToken indicates whether pods running as this service account should have an API token automatically mounted. Can be overridden at the pod level.
imagePullSecrets <[]Object> ImagePullSecrets is a list of references to secrets in the same namespace to use for pulling any images in pods that reference this ServiceAccount. ImagePullSecrets are distinct from Secrets because Secrets can be mounted in the pod, but ImagePullSecrets are only accessed by the kubelet. More info: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod
kind <string> Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
metadata <Object> Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
secrets <[]Object> Secrets is the list of secrets allowed to be used by pods running using this ServiceAccount. More info: https://kubernetes.io/docs/concepts/configuration/secret
看到有一个 token 已经被自动创建,并被 service account 引用。设置非默认的 service account,只需要在 pod 的spec.serviceAccountName 字段中将name设置为您想要用的 service account 名字即可。在 pod 创建之初 service account 就必须已经存在,否则创建将被拒绝。需要注意的是不能更新已创建的 pod 的 service account。
[root@k8s-master pki]# kubectl config use-context magedu@kubernetes Switched to context "magedu@kubernetes". [root@k8s-master pki]# kubectl get pods No resources found. Error from server (Forbidden): pods is forbidden: User "magedu" cannot list pods in the namespace "default"
[root@k8s-master ~]# kubectl create role -h #查看角色创建帮助 Create a role with single rule.
Examples: # Create a Role named "pod-reader" that allows user to perform "get", "watch" and "list" on pods kubectl create role pod-reader --verb=get --verb=list --verb=watch --resource=pods # Create a Role named "pod-reader" with ResourceName specified kubectl create role pod-reader --verb=get --resource=pods --resource-name=readablepod --resource-name=anotherpod # Create a Role named "foo" with API Group specified kubectl create role foo --verb=get,list,watch --resource=rs.extensions # Create a Role named "foo" with SubResource specified kubectl create role foo --verb=get,list,watch --resource=pods,pods/status
Options: --allow-missing-template-keys=true: If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. --dry-run=false: If true, only print the object that would be sent, without sending it. -o, --output='': Output format. One of: json|yaml|name|go-template|go-template-file|templatefile|template|jsonpath|jsonpath-file. --resource=[]: Resource that the rule applies to --resource-name=[]: Resource in the white list that the rule applies to, repeat this flag for multiple items --save-config=false: If true, the configuration of current object will be saved in its annotation. Otherwise, the annotation will be unchanged. This flag is useful when you want to perform kubectl apply on this object in the future. --template='': Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview]. --validate=true: If true, use a schema to validate the input before sending it --verb=[]: Verb that applies to the resources contained in the rule
Usage: kubectl create role NAME --verb=verb --resource=resource.group/subresource [--resource-name=resourcename] [--dry-run] [options] 使用kubectl create进行创建角色,指定角色名称,--verb指定权限,--resource指定资源或者资源组,--dry-run单跑模式并不会创建 Use "kubectl options" for a list of global command-line options (applies to all commands).
[root@k8s-master ~]# kubectl create rolebinding -h #角色绑定创建帮助 Create a RoleBinding for a particular Role or ClusterRole.
Examples: # Create a RoleBinding for user1, user2, and group1 using the admin ClusterRole kubectl create rolebinding admin --clusterrole=admin --user=user1 --user=user2 --group=group1
Options: --allow-missing-template-keys=true: If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. --clusterrole='': ClusterRole this RoleBinding should reference --dry-run=false: If true, only print the object that would be sent, without sending it. --generator='rolebinding.rbac.authorization.k8s.io/v1alpha1': The name of the API generator to use. --group=[]: Groups to bind to the role -o, --output='': Output format. One of: json|yaml|name|templatefile|template|go-template|go-template-file|jsonpath-file|jsonpath. --role='': Role this RoleBinding should reference --save-config=false: If true, the configuration of current object will be saved in its annotation. Otherwise, the annotation will be unchanged. This flag is useful when you want to perform kubectl apply on this object in the future. --serviceaccount=[]: Service accounts to bind to the role, in the format <namespace>:<name> --template='': Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview]. --validate=true: If true, use a schema to validate the input before sending it
Usage: kubectl create rolebinding NAME --clusterrole=NAME|--role=NAME [--user=username] [--group=groupname] [--serviceaccount=namespace:serviceaccountname] [--dry-run] [options] 使用kubectl create进行创建角色绑定,指定角色绑定的名称,--role|--clusterrole指定绑定哪个角色,--user指定哪个用户 Use "kubectl options" for a list of global command-line options (applies to all commands).
[root@k8s-master mainfests]# kubectl get rolebinding #获取角色绑定信息 NAME AGE magedu-read-pods 1h [root@k8s-master mainfests]# kubectl delete rolebinding magedu-read-pods #删除前面的绑定 rolebinding.rbac.authorization.k8s.io "magedu-read-pods" deleted
[ik8s@k8s-master ~]$ kubectl get pods #删除后,在ik8s普通用户上进行获取pods资源信息,就立马出现forbidden了 No resources found. Error from server (Forbidden): pods is forbidden: User "magedu" cannot list pods in the namespace "default"
[root@k8s-master mainfests]# kubectl apply -f clusterrolebinding-demo.yaml clusterrolebinding.rbac.authorization.k8s.io/magedu-read-all-pods created [root@k8s-master mainfests]# kubectl get clusterrolebinding NAME AGE ...... magedu-read-all-pods 10s
[ik8s@k8s-master ~]$ kubectl get pods #角色绑定后在ik8s终端上进行获取pods信息,已经不会出现forbidden了 NAME READY STATUS RESTARTS AGE filebeat-ds-hxgdx 1/1 Running 1 36d filebeat-ds-s466l 1/1 Running 2 36d myapp-0 1/1 Running 0 2d myapp-1 1/1 Running 0 2d myapp-2 1/1 Running 0 2d myapp-3 1/1 Running 0 2d pod-sa-demo 1/1 Running 0 1d pod-vol-demo 2/2 Running 0 4d redis-5b5d6fbbbd-q8ppz 1/1 Running 1 4d [ik8s@k8s-master ~]$ kubectl get pods -n ingress-nginx #更换名称空间进行查看也是可行的 NAME READY STATUS RESTARTS AGE default-http-backend-7db7c45b69-nqxw9 1/1 Running 1 4d nginx-ingress-controller-6bd7c597cb-9fzbw 1/1 Running 0 4d
[ik8s@k8s-master ~]$ kubectl delete pods pod-sa-demo #但是进行删除pod就无法进行,因为在授权时是没有delete权限的 Error from server (Forbidden): pods "pod-sa-demo" is forbidden: User "magedu" cannot delete pods in the namespace "default"