k8s中的访问控制
本文主要介绍了k8s中的访问控制,包括认证、授权、准入控制,最后通过几个小case进行案例演示。
k8s中的访问控制
1. 概述
用户可以通过 kubectl
命令行、客户端库或者通过发送 REST 请求访问 API Server
。用户被分为用户账户和 Kubernetes 服务账户,二者都可以被授权进行 API Server
访问。 请求到达 API Server
后会经过几个阶段,具体说明如图:
如果客户端想要访问Api server
需要经过如下三个步骤:
- 认证(
Authenticating
) - 授权(
Authorization
) - 准入控制(
Admission Controllers
)
认证可以理解为Api Server
需要知道你是谁。
授权可以理解为在知道你是谁的情况下,你可以对哪些资源进行哪些操作。
准入控制可以理解为对于一些存在关联关系的资源,需要进行进一步的权限判断。
2. 认证
客户端想要访问Api Server
首先需要的就是进行认证,只有认证通过了,k8s知道你是谁,才有后面的授权和准入控制。如果请求认证失败,则请求被拒绝,返回 401 状态码。
在k8s中有两种用户:用户账户和服务账户。
用户账户可以理解为人类使用的账号,服务账户可以理解为k8s的组件或者是集群中的Pod中的进程访问Api Server
的账号
Kubernetes 区分用户账户和服务账户的概念主要基于以下原因:
- 用户账户是针对人而言的。 服务账户是针对运行在 pod 中的进程而言的。
- 用户账户是全局性的。 其名称在集群各 namespace 中都是全局唯一的,未来的用户资源不会做 namespace 隔离, 服务账户是 namespace 隔离的。
- 通常情况下,集群的用户账户可能会从企业数据库进行同步,其创建需要特殊权限,并且涉及到复杂的业务流程。 服务账户创建的目的是为了更轻量,允许集群用户为了具体的任务创建服务账户 ( 即权限最小化原则 )。
- 对人员和服务账户审计所考虑的因素可能不同。
- 针对复杂系统的配置可能包含系统组件相关的各种服务账户的定义。 因为服务账户可以定制化地创建,并且有 namespace 级别的名称,这种配置是很轻量的。
下面的图片描述了认证的流程。
2.1 服务账户-ServiceAccount
ServiceAccount
是 Kubernetes API 所管理的用户。它们被绑定到特定的名称空间, 或者由 API 服务器自动创建,或者通过 API 调用创建。
ServiceAccount
与一组以 Secret
保存的凭据相关,这些凭据会被通过volume
的方式自动挂载到 Pod 中的/var/run/secrets/kubernetes.io/serviceaccount
路径下,且文件名是secret的名称,从而允许集群内的进程访问 Kubernetes API。可以认为ServiceAccount
就是集群中的Pod中的进程访问Api server
的凭证。
查看一下k8s集群中默认存在的ServiceAccount
。sa是ServiceAccount
的简写。
# sa 是 serviceaccount的简写
[root@k8s-master01 access-control]$ kubectl get sa --all-namespaces
NAMESPACE NAME SECRETS AGE
default default 1 23h
kube-node-lease default 1 23h
kube-public default 1 23h
kube-system attachdetach-controller 1 23h
kube-system bootstrap-signer 1 23h
kube-system certificate-controller 1 23h
kube-system clusterrole-aggregation-controller 1 23h
kube-system coredns 1 23h
kube-system cronjob-controller 1 23h
正是这些ServiceAccount
的存在,才可以让集群中的Pod(例如coredns)能够访问Api Server
。
[root@k8s-master01 ~]# kubectl describe pod -n kube-system coredns-9d85f5447-b8pdz
Name: coredns-9d85f5447-b8pdz
Namespace: kube-system
......
Containers:
coredns:
Container ID: docker://b260fe1bcaea002a40679d86ae3b992d0ccbe05ef73592bea1cf608388eb0f9f
......
Mounts:
/etc/coredns from config-volume (ro)
/var/run/secrets/kubernetes.io/serviceaccount from coredns-token-hpr7b (ro)
2.1.1 ServiceAccount的基本操作
ServiceAccount
是标准的k8s资源对象,可以使用命令行或者是资源清单进行创建。
命令行的方式创建
# sa 是 serviceaccount的简写
[root@k8s-master01 access-control]# kubectl create sa my-sa
serviceaccount/my-sa created
使用资源清单的方式创建
[root@k8s-master01 access-control]# cat > create-sa.yaml << EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-sa2
EOF
创建my-sa2
[root@k8s-master01 access-control]# kubectl create -f create-sa.yaml
使用kubectl delete sa <service-account-name> -n <namespace-name>
或者是 kubectl delete -f xxx.yaml
命令删除创建的ServiceAccount
。
查看一下创建的ServiceAccount
[root@k8s-master01 access-control]# kubectl get sa my-sa
NAME SECRETS AGE
my-sa 1 7s
[root@k8s-master01 access-control]# kubectl describe sa my-sa
Name: my-sa
Namespace: default
Labels: <none>
Annotations: <none>
Image pull secrets: <none>
# 有一个类型为serviceaccount-token的secret与之关联
Mountable secrets: my-sa-token-cd85c
Tokens: my-sa-token-cd85c
Events: <none>
我们每创建一个ServiceAccount
就会有类型为service-account-token
的Secret
与之关联。
查看与my-sa
关联的Secret
[root@k8s-master01 access-control] # kubectl get secret my-sa-token-fdwdl
NAME TYPE DATA AGE
my-sa-token-fdwdl kubernetes.io/service-account-token 3 19s
#查看secret中的数据
[root@k8s-master01 access-control] # kubectl describe secret my-sa-token-fdwdl
Name: my-sa-token-fdwdl
Namespace: default
Labels: <none>
Annotations: kubernetes.io/service-account.name: my-sa
kubernetes.io/service-account.uid: a183161e-1816-4a44-9d15-a085df6e741d
Type: kubernetes.io/service-account-token
Data
====
token: ......
ca.crt: 1025 bytes
namespace: 7 bytes
ServiceAccount
可以包含imagePullSecrets
、secrets
。我们可以将拉取docker镜像的凭证,隐藏在ServiceAccount
中,而不是直接暴露在pod.spec
的定义中。
如果创建的Pod没有指定ServiceAccount
,那么就会使用集群中,Pod所在名称空间的名为default
的ServiceAccount
。default
的ServiceAccount
的权限非常小,只能访问当前Pod自己的资源。
查看一下各个名称空间下默认的ServiceAccount
[root@k8s-master01 access-control]# kubectl get sa --all-namespaces
NAMESPACE NAME SECRETS AGE
default default 1 23h
kube-node-lease default 1 23h
kube-public default 1 23h
kube-system default 1 23h
......
2.1.2 Pod使用自定义的ServiceAccount
除了名称空间下默认的ServiceAccount
,我们还可以让Pod使用自定义的ServiceAccount
,当我们给这个自定义的ServiceAccount
赋予了相应的权限,那么这Pod就可以访问集群中的资源,一个典型的例子就是dashboard。
案例演示
[root@k8s-master01 access-control]# cat > pod-sa.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
name: pod-sa
spec:
serviceAccountName: my-sa
containers:
- name: pod-sa
image: wangyanglinux/myapp:v1
imagePullPolicy: IfNotPresent
EOF
创建这个Pod,并且查看Pod使用的ServiceAccount
[root@k8s-master01 access-control]# kubectl create -f pod-sa.yaml
pod/pod-sa created
[root@k8s-master01 access-control]# kubectl describe pod pod-sa
......
pullable://wangyanglinux/myapp@sha256:9c3dc30b5219788b2b8a4b065f548b922a34479577befb54b03330999d30d513
Port: <none>
Host Port: <none>
State: Running
Started: Mon, 12 Oct 2020 22:36:44 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from my-sa-token-cd85c (ro)
......
Volumes:
my-sa-token-cd85c:
Type: Secret (a volume populated by a Secret)
SecretName: my-sa-token-cd85c
Optional: false
另外ServiceAccount
关联的类型为service-account-token
的Secret
会被自动挂载到容器的/var/run/secrets/kubernetes.io/serviceaccount
路径下。文件名token的名称,文件内容为经过base64解密后的字符串。
[root@k8s-master01 access-control]# kubectl exec pod-sa -- ls -al /var/run/secrets/kubernetes.io/serviceaccount
total 4
drwxrwxrwt 3 root root 140 Oct 14 02:35 .
drwxr-xr-x 3 root root 4096 Feb 25 2018 ..
drwxr-xr-x 2 root root 100 Oct 14 02:35 ..2020_10_14_02_35_57.281690733
lrwxrwxrwx 1 root root 31 Oct 14 02:35 ..data -> ..2020_10_14_02_35_57.281690733
lrwxrwxrwx 1 root root 13 Oct 14 02:35 ca.crt -> ..data/ca.crt
lrwxrwxrwx 1 root root 16 Oct 14 02:35 namespace -> ..data/namespace
lrwxrwxrwx 1 root root 12 Oct 14 02:35 token -> ..data/token
[root@k8s-master01 access-control]# kubectl exec pod-sa -- cat /var/run/secrets/kubernetes.io/serviceaccount/token
eyJhbGciOiJSUzI1NiIsImtpZCI6IlFfX3o4OVVzYUgyMUVGWDJ1RU9nNEl5YlFhX01RYWhlTEVtd3EwU0dpblUif
......
2.2 用户账户
我们可以使用kubectl
命令行去访问k8s集群,那么这是怎么经过Api Server
的认证呢?
在k8s中使用 kubeconfig
文件来组织有关集群、用户、命名空间和身份认证机制的信息。kubectl
命令行工具使用 kubeconfig
文件来查找选择集群所需的信息,并与集群的 API 服务器进行通信。
默认情况下,kubectl
在 $HOME/.kube
目录下查找名为 config
的文件。 可以通过设置 KUBECONFIG
环境变量或者设置 --kubeconfig
参数来指定其他 kubeconfig
文件。
使用 kubeconfig
文件,可以组织集群、用户和命名空间。还可以定义上下文,以便在集群和命名空间之间快速轻松地切换。
使用 kubectl config --help
查看一下命令的使用
[root@k8s-master01 access-control] $ kubectl config --help
Modify kubeconfig files using subcommands like "kubectl config set current-context my-context"
The loading order follows these rules:
1. If the --kubeconfig flag is set, then only that file is loaded. The flag may only be set once and no merging takes place.
2. If $KUBECONFIG environment variable is set, then it is used as a list of paths (normal path delimiting rules for your system). These paths are merged. When a value is modified, it is modified in the file that defines the stanza. When a value is created, it is created in the first file that exists. If no files in the chain exist, then it creates the last file in the list.
3. Otherwise, ${HOME}/.kube/config is used and no merging takes place.
Available Commands:
current-context Displays the current-context
delete-cluster Delete the specified cluster from the kubeconfig
delete-context Delete the specified context from the kubeconfig
get-clusters Display clusters defined in the kubeconfig
get-contexts Describe one or many contexts
rename-context Renames a context from the kubeconfig file.
set Sets an individual value in a kubeconfig file
set-cluster Sets a cluster entry in kubeconfig
set-context Sets a context entry in kubeconfig
set-credentials Sets a user entry in kubeconfig
unset Unsets an individual value in a kubeconfig file
use-context Sets the current-context in a kubeconfig file
view Display merged kubeconfig settings or a specified kubeconfig file
Usage:
kubectl config SUBCOMMAND [options]
Use "kubectl <command> --help" for more information about a given command.
Use "kubectl options" for a list of global command-line options (applies to all commands).
上面的英文主要是在强调如果存在多个 kubeconfig
配置文件,配置优先级的问题。
--kubeconfig
命令行、KUBECONFIG
环境变量、${HOME}/.kube/config
,这三个配置文件的优先级
- 只要在命令行中设置
--kubeconfig
命令行,那么所有的配置都以命令行中指定的配置文件中的配置信息为准。 - 如果没有设置
--kubeconfig
命令行,并且设置了KUBECONFIG
环境变量,那么将它用作应合并的文件列表。合并的原则是就近原则。例如如果两个文件都指定了red-user
,则仅使用第一个文件的red-user
中的值。即使第二个文件在red-user
下有非冲突条目,也要丢弃它们。
一个环境变量可以设置多个值,在linux中通过":"
分割。例如export KUBECONFIG=$KUBECONFIG:$HOME/.kube/config
。 - 如果既没有设置
--kubeconfig
命令行,也没有设置KUBECONFIG
环境变量,使用${HOME}/.kube/config
配置文件。
主要的命令有:
- 对于context上下文的增删改查,以及切换上下文context。
current-context
、delete-context
、get-contexts
、rename-context
、set-context
、use-context
- 对于cluster集群的增删改查。
get-clusters
、delete-cluster
、set-cluster
- 对于user的新增。
set-credentials
set
和unset
可以设置或者是删除cluster、context、user
先使用kubectl config view
命令,查看一下当前的cluster、context、user、namespace
[root@k8s-master01 access-control] $ kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://192.168.1.180:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: kubernetes-admin
name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
可以看到配置文件中存在着集群名为kubernetes
,用户名为kubernetes-admin
,context为kubernetes-admin@kubernetes
。context一般定义的格式为用户名@集群名称
这是使用kubeadm
工具初始化集群之后,默认生成的配置文件。
2.2.1 cluster
cluster可以理解为是对集群的抽象,主要的配置有 Api Server
服务器地址和端口号、certificate-authority ca证书地址等。
使用kubectl config set-cluster --help
命令查看一下如何设置一个集群
[root@k8s-master01 access-control] # kubectl config set-cluster --help
Sets a cluster entry in kubeconfig.
......
Usage:
kubectl config set-cluster NAME [--server=server] [--certificate-authority=path/to/certificate/authority]
[--insecure-skip-tls-verify=true] [--tls-server-name=example.com] [options]
Use "kubectl options" for a list of global command-line options (applies to all commands).
这里我们使用--kubeconfig
命令,将配置信息保存到指定路径下的文件中。我们先创建一个集群
[root@k8s-master01 access-control]# kubectl config set-cluster k8s1 --server=https://192.168.1.180:6443 --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs=true --kubeconfig=/temp/k8s/config
Cluster "k8s1" set.
解释一下上面的命令
--server=https://192.168.1.180:6443
指定Api Server
的ip和端口
--certificate-authority
指定kubernetes集群中ca.crt证书的地址。
--embed-certs=true
是否嵌入证书信息,默认不嵌入,true表示嵌入。
--kubeconfig=/temp/k8s/config
将配置信息保存到指定文件中,如果没有就创建或者是读取配置文件
查看一下新定义的配置信息,这里需要带上--kubeconfig=/temp/k8s/config
。
[root@k8s-master01 access-control]# kubectl config view --kubeconfig=/temp/k8s/config
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://192.168.1.180:6443
name: k8s1
contexts: null
current-context: ""
kind: Config
preferences: {}
users: null
#查看一下生成的配置文件
[root@k8s-master01 access-control]# cat /temp/k8s/config
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: ......
server: https://192.168.1.180:6443
name: k8s1
contexts: null
current-context: ""
kind: Config
preferences: {}
users: null
如果要删除cluser,可以使用kubectl config delete-cluster NAME [options]
或者是kubectl config unset clusters.<NAME> [options]
命令,当然了如果使用了自定义的配置文件,需要使用--kubeconfig=path
,指定配置文件的路径。
2.2.1 user、gruop
这里使用OpenSSL的方式,其他方式类似,可以参照官方文档。
这里如果要定义用户或者是组,就需要由集群的ca.crt
和ca.key
签署客户端的私钥和证书
这里需要先自己定义生成私钥,然后生成证书签署请求,定义签署的用户和组,最后根据集群中的ca.crt
和ca.key
签署证书签署请求,生成对应的客户端的.crt
文件。
集群中的ca.crt
和key.crt
默认放置在/etc/kubernetes/pki/
路径下。
[root@k8s-master01 /]# cd /etc/kubernetes/pki/
[root@k8s-master01 pki]# ls
apiserver.crt apiserver.key ca.crt etcd front-proxy-client.crt sa.pub
apiserver-etcd-client.crt apiserver-kubelet-client.crt ca.key front-proxy-ca.crt front-proxy-client.key
apiserver-etcd-client.key apiserver-kubelet-client.key ca.srl front-proxy-ca.key sa.key
2.2.1.1 生成私钥
#生成私钥
[root@k8s-master01 pki]# openssl genrsa -out magedu.key 2048
Generating RSA private key, 2048 bit long modulus
.............+++
......+++
e is 65537 (0x10001)
#查看生成的私钥
[root@k8s-master01 pki]# cat magedu.key
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAtvVU8oAmvG+cFu6O+ewz/1qJbV13tghP2DlAUgYjo5jqjJNM
......
pIimlmxTFWnSKiOF56lkBSDaHUtQEQs8Kqh7mfzAg7r7cx7nLrRp5w==
-----END RSA PRIVATE KEY-----
2.2.1.2 基于配置文件生成证书签名请求
#这里的magedu就是用户
[root@k8s-master01 pki]# openssl req -new -key magedu.key -out magedu.csr -subj "/CN=magedu/O=app1/O=app2"
[root@k8s-master01 pki]# cat magedu.csr
-----BEGIN CERTIFICATE REQUEST-----
......
gv9vfI83POMCeNYvaIuAZy87pLjj5uA65rU=
-----END CERTIFICATE REQUEST----
这里CN字段表示为用户名,O字段表示用户组。
2.2.1.3 由ca.crt和ca.key签署生成证书
[root@k8s-master01 pki]# openssl x509 -req -in magedu.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out magedu.crt -days 365
Signature ok
subject=/CN=magedu
Getting CA Private Key
[root@k8s-master01 pki]# cat magedu.crt
-----BEGIN CERTIFICATE-----
MIICojCCAYoCCQDVh+opYUNFDDANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwpr
......
#查看一下证书中的内容
[root@k8s-master01 pki]# openssl x509 -in magedu.crt -text -noout
Certificate:
Data:
Version: 1 (0x0)
Serial Number:
d5:87:ea:29:61:43:45:0c
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=kubernetes
Validity
Not Before: Oct 18 01:55:53 2020 GMT
Not After : Oct 18 01:55:53 2021 GMT
Subject: CN=magedu
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:b6:f5:54:f2:80:26:bc:6f:9c:16:ee:8e:f9:ec:
......
Exponent: 65537 (0x10001)
Signature Algorithm: sha256WithRSAEncryption
74:5b:f2:a7:10:4f:c1:e1:85:37:b3:08:44:64:18:12:57:10:
......
2.2.1.4 生成user
#查看一下生成用户的帮助信息
[root@k8s-master01 pki]# kubectl config set-credentials -h
Sets a user entry in kubeconfig
......
Usage:
kubectl config set-credentials NAME [--client-certificate=path/to/certfile] [--client-key=path/to/keyfile]
[--token=bearer_token] [--username=basic_user] [--password=basic_password] [--auth-provider=provider_name]
[--auth-provider-arg=key=value] [--exec-command=exec_command] [--exec-api-version=exec_api_version] [--exec-arg=arg]
[--exec-env=key=value] [options]
Use "kubectl options" for a list of global command-line options (applies to all commands).
可以看出需要指定ca.crt证书的地址、私钥的地址等。当然了也可以指定名称空间,将用户限制在指定的名称空间下。
接下来创建magedu这个用户,指定客户端的.crt
证书的地址、私钥的地址,指定使用的配置文件/temp/k8s/config
[root@k8s-master01 pki]# kubectl config set-credentials magedu --client-certificate=./magedu.crt --client-key=./mageedu.key --kubeconfig=/temp/k8s/config
User "magedu" set.
查看一下定义的配置文件/temp/k8s/config
[root@k8s-master01 pki]# kubectl config view --kubeconfig=/temp/k8s/config
apiVersion: v1
clusters:
- cluster:
certificate-authority: /etc/kubernetes/pki/ca.crt
server: https://192.168.1.180:6443
name: k8s1
contexts: null
current-context: ""
kind: Config
preferences: {}
users:
- name: magedu
user:
client-certificate: /etc/kubernetes/pki/magedu.crt
client-key: /etc/kubernetes/pki/mageedu.key
可以看到已经定义了一个cluser和一个user。
如果要删除用户,可以使用kubectl config unset users.<username>
命令
[root@k8s-master01 pki]# kubectl config unset users.magedu --kubeconfig=/temp/k8s/config
Property "users.magedu" unset.
2.2.1 context
通过 kubeconfig
文件中的 context 元素,使用简便的名称来对访问参数进行分组。每个上下文都有三个参数:cluster、namespace 和 user。可以认为context是对cluster、namespace、user的一个封装。默认情况下,kubectl
命令行工具使用当前上下文中的参数与集群进行通信。
#查看一下当前使用的context
[root@k8s-master01 access-control]# kubectl config current-context
kubernetes-admin@kubernetes
#列举出所有的context
[root@k8s-master01 access-control]# kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* kubernetes-admin@kubernetes kubernetes kubernetes-admin
#创建一个context
[root@k8s-master01 access-control]# kubectl config set-context magedu@k8s1 --cluster=k8s1 --user=magedu --kubeconfig=/temp/k8s/config
解析一下上面的命令
--cluser
指定集群的名称。context的名称一般的格式为:username[-namespace]@clsurer_name,如果设置了namespace,可以将namespace也设置到对应的context的名称中。--user
指定用户。--kubeconfig
指定使用的配置文件。
查看一下创建的context
[root@k8s-master01 pki]# kubectl config get-contexts --kubeconfig=/temp/k8s/config
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
magedu@k8s1 k8s1 magedu
删除context,可以使用kubectl config delete-context NAME [options]
或者是kubectl config unset contexts.<NAME> [options]
命令
使用刚才创建的名为magedu@k8s1的context
[root@k8s-master01 access-control]# kubectl config use-context magedu@k8s1 --kubeconfig=/temp/k8s/config
Switched to context "magedu@k8s1".
[root@k8s-master01 pki]# kubectl config current-context --kubeconfig=/temp/k8s/config
magedu@k8s1
我们使用一下刚才创建的context去访问k8s集群
[root@k8s-master01 pki]# kubectl get pod -n kube-system --kubeconfig=/temp/k8s/config
Error from server (Forbidden): pods is forbidden: User "magedu" cannot list resource "pods" in API group "" at the cluster scope
我们发现返回Forbidden,状态码为403。在restful风格的api中,403表示为未授权。这说明我们没有为magedu这个账号授予访问kube-system名称空间下pod的访问权限。接下来我们继续讲解如何为用户账号和服务账号进行授权。
3. 授权
我们使用用户账号或者是服务账号去访问k8s中的资源,通过认证之后,就要校验其是否有关于相关资源操作的权限了。
在k8s中授权有4中方式:
- Node - 一个专用授权程序,根据计划运行的 pod 为 kubelet 授予权限。了解有关使用节点授权模式的更多信息,请参阅节点授权。
- ABAC - 基于属性的访问控制(ABAC)定义了一种访问控制范例,通过使用将属性组合在一起的策略,将访问权限授予用户。策略可以使用任何类型的属性(用户属性,资源属性,对象,环境属性等)。要了解有关使用 ABAC 模式的更多信息,请参阅 ABAC 模式。
- RBAC - 基于角色的访问控制(RBAC)是一种基于企业内个人用户的角色来管理对计算机或网络资源的访问的方法。在此上下文中,权限是单个用户执行特定任务的能力,例如查看,创建或修改文件。要了解有关使用 RBAC 模式的更多信息,请参阅 RBAC 模式。
当指定的 RBAC(基于角色的访问控制)使用 rbac.authorization.k8s.io API 组来驱动授权决策时,允许管理员通过 Kubernetes API 动态配置权限策略。
要启用 RBAC,请使用 --authorization-mode = RBAC 启动 apiserver 。 - Webhook - WebHook 是一个 HTTP 回调:发生某些事情时调用的 HTTP POST;通过 HTTP POST 进行简单的事件通知。实现 WebHook 的 Web 应用程序会在发生某些事情时将消息发布到 URL。要了解有关使用 Webhook 模式的更多信息,请参阅 Webhook 模式。
基于角色(Role)的访问控制(RBAC)是一种基于企业中用户的角色来调节控制对计算机或网络资源的访问方法。
RBAC
使用 rbac.authorization.k8s.io
API 组 来驱动鉴权操作,允许管理员通过 Kubernetes API 动态配置策略。
在 1.8 版本中,RBAC 模式是稳定的并通过 rbac.authorization.k8s.io/v1
API 提供支持。要启用 RBAC,在启动 API 服务器时添加 --authorization-mode=RBAC
参数。
配置多个授权模块时,将按顺序检查每个模块。 如果任何授权模块批准或拒绝请求,则立即返回该决定,并且不会与其他授权模块协商。 如果所有模块对请求没有意见,则拒绝该请求。一个拒绝响应返回 HTTP 状态代码 403 。
下面这个图描述了用户账户和服务账户去访问Api Server
的交互过程
3.1 k8s中的resources
在k8s中对于资源的操作的定义与Restful风格类似,请求方式代表一种对资源的操作类型。
下面的表格列举了这些操作和定义
HTTP 动词 | request 动词 |
---|---|
POST | create |
GET,HEAD | get (单个资源),list (资源集合) |
PUT | update |
PATCH | patch |
DELETE | delete (单个资源),deletecollection (资源集合) |
我们可以使用kube-proxy
开启一个代理,去访问api server
[root@k8s-master01 ~]# kubectl proxy -p 8080
Starting to serve on 127.0.0.1:8080
-p 就是指定端口
我们使用curl命令去访问一下proxy,进而访问Api Server。
[root@k8s-master01 access-control]# curl http://127.0.0.1:8080/api/v1/namespaces/kube-system
{
"kind": "Namespace",
"apiVersion": "v1",
"metadata": {
"name": "kube-system",
"selfLink": "/api/v1/namespaces/kube-system",
"uid": "101cd2e4-56b0-49c5-98df-288b2fe7e8c5",
"resourceVersion": "15",
"creationTimestamp": "2020-10-11T15:08:35Z"
},
"spec": {
"finalizers": [
"kubernetes"
]
},
"status": {
"phase": "Active"
}
}
在k8s中一些资源一般以其名称字符串来表示,这些字符串一般会在API的URL地址中出现;同时某些资源也会包含子资源,例如logs资源就属于pods的子资源,API中的URL样例如下
GET /apis/apps/v1/namespaces/{namespace}/pods/{name}/log
我们查看一下kube-system名称空间中的名为coredns的deployment
[root@k8s-master01 access-control]# curl http://127.0.0.1:8080/apis/apps/v1/namespaces/kube-system/deployments/coredns
{
"kind": "Deployment",
"apiVersion": "apps/v1",
......
}
3.2 Role、ClusterRole
在 RBAC API 中,一个角色包含一组相关权限的规则。权限是纯粹累加的(不存在拒绝某操作的规则)。 角色可以用 Role
来定义到某个命名空间上, 或者用 ClusterRole
来定义到整个集群作用域。
3.2.1 Role
一个 Role
只可以用来对某一命名空间中的资源赋予访问权限。 下面的 Role
示例定义到名称为 "default"
的命名空间,可以用来授予对该命名空间中的 Pods 的读取权限:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
# "" 指定核心 API 组
- apiGroups:
- ""
resources:
- "pods"
verbs:
- "get"
- "watch"
- "list"
3.2.2 ClusterRole
ClusterRole
可以授予的权限和 Role
相同, 但是因为 ClusterRole
属于集群范围,所以它也可以授予以下访问权限:
- 集群范围资源 (比如 nodes)
- 非资源端点(比如 “/healthz”)
- 跨命名空间访问的有名字空间作用域的资源(如 Pods),比如运行命令
kubectl get pods --all-namespaces
时需要此能力
需要特别注意的是ClusterRole
是属于集群范围,不属于任何名称空间。
下面的 ClusterRole
示例可用来对某特定命名空间下的 Secrets
的读取操作授权, 或者跨所有命名空间执行授权(取决于它是如何绑定的):
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
# 此处的 "namespace" 被省略掉是因为 ClusterRoles 是没有命名空间的。
name: secret-reader
rules:
- apiGroups:
- ""
resources:
- "secrets"
verbs:
- "get"
- "watch"
- "list"
查看一下集群中默认存在的ClusterRole
[root@k8s-master01 access-control]# kubectl get clusterrole
NAME AGE
admin 8d
cluster-admin 8d
edit 8d
flannel 8d
nginx-ingress-clusterrole 5d1h
system:aggregate-to-admin 8d
......
view 8d
3.2.3 对资源的引用
我们想要对pod的log这个资源进行定义,在这种情况下,“pods” 是有命名空间的资源,而 “log” 是 pods 的子资源。在 RBAC 角色中, 使用"/"分隔资源和子资源。允许一个主体要同时读取 pods 和 pod logs,你可以这么写:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-and-pod-logs-reader
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list"]
对于某些请求,也可以通过 resourceNames
列表按名称引用资源。 在指定时,可以将请求类型限制资源的单个实例。限制只可以 “get” 和 “update” 的单一configmap,你可以这么写:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: configmap-updater
rules:
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["my-configmap"]
verbs: ["update", "get"]
3.3 RoleBinding 和 ClusterRoleBinding
角色绑定(RoleBinding
)是将角色中定义的权限赋予一个或者一组用户。 它包含若干主体(用户,组和服务账户)的列表和对这些主体所获得的角色的引用。 可以使用 RoleBinding
在指定的命名空间中执行授权, 或者在集群范围的命名空间使用 ClusterRoleBinding
来执行授权。
RoleBinding
或者 ClusterRoleBinding
需要绑定角色到主体。主体可以是组,人类用户或者服务账户。
人类用户是由字符串表示,它们可以是普通的用户名,像 “alice”,或者是 邮件格式 “bob@example.com”,或者是数字ID。由 Kubernetes 管理员配置身份认证模块需要的格式。RBAC 鉴权系统不对格式作任何要求,但是前缀 system:
是 Kubernetes 系统保留的, 所以管理员要确保配置的用户名不能出现上述前缀格式。
用户组信息是 Kubernetes 现在提供的一种身份验证模块,与用户一样,对组的字符串没有格式要求, 只是不能使用保留的前缀 system:
。
服务账号的用户名前缀为system:serviceaccount:
, 属于前缀为 system:serviceaccounts:
的用户组。
用户和角色都是多对多的关系,可以理解RoleBinding
和ClusterRoleBinding
就是多对多的中间表,将用户和角色进行绑定
3.3.1 Role绑定RoleBinding
一个 RoleBinding
可以引用同一的命名空间中的 Role
。 下面的例子 RoleBinding
将 “pod-reader” 角色授予在 “default” 命名空间中的用户 “jane”; 这样,用户 “jane” 就具有了读取 “default” 命名空间中 pods 的权限。
roleRef
里的内容决定了实际创建绑定的方法。kind
可以是 Role
或 ClusterRole
, name
将引用你要指定的 Role
或 ClusterRole
的名称。在下面的例子中,角色绑定使用 roleRef
将用户 “jane” 绑定到前文创建的角色 Role
,其名称是 pod-reader
。
apiVersion: rbac.authorization.k8s.io/v1
# 此角色绑定使得用户 "jane" 能够读取 "default" 命名空间中的 Pods
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: jane # Name is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role #this must be Role or ClusterRole
name: pod-reader # 这里的名称必须与你想要绑定的 Role 或 ClusterRole 名称一致
apiGroup: rbac.authorization.k8s.io
3.3.2 RoleBinding绑定ClusterRole
RoleBinding
也可以引用 ClusterRole
,对 ClusterRole
所定义的、位于 RoleBinding
命名空间内的资源授权。 这可以允许管理者在整个集群中定义一组通用的角色,然后在多个命名空间中重用它们。可以理解为将ClusterRole
进行降级,降级到RoleBinding
所在名称空间,然后其所绑定的user
、sa
、group
只有RoleBinding
所在名称空间的权限。
例如下面的例子,RoleBinding
绑定的是 ClusterRole
, “dave” (主体,区分大小写)将只可以读取在"development" 命名空间( RoleBinding 的命名空间)中的"secrets"。
apiVersion: rbac.authorization.k8s.io/v1
# 这个角色绑定允许 "dave" 用户在 "development" 命名空间中有读取 secrets 的权限。
kind: RoleBinding
metadata:
name: read-secrets
namespace: development # 这里只授予 "development" 命名空间的权限。
subjects:
- kind: User
name: dave # 名称区分大小写
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
3.3.3 ClusterRoleBingding绑定ClusterRole
最后,ClusterRoleBinding
可用来在集群级别或对所有命名空间执行授权。 下面的例子允许 “manager” 组中的任何用户读取任意命名空间中 “secrets”。
apiVersion: rbac.authorization.k8s.io/v1
# 这个集群角色绑定允许 "manager" 组中的任何用户读取任意命名空间中 "secrets"。
kind: ClusterRoleBinding
metadata:
name: read-secrets-global
subjects:
- kind: Group
name: manager # 名称区分大小写
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
你不能修改绑定对象所引用的 Role
或 ClusterRole
。 试图改变绑定对象的 roleRef
将导致验证错误。想要 改变现有绑定对象中 roleRef
字段的内容,必须删除并重新创建绑定对象。
这种限制有两个主要原因:
- 关于不同角色的绑定是完全不一样的。更改
roleRef
需要删除/重建绑定,确保要赋予绑定的完整主体列表是新的角色(而不是只是启用修改roleRef
在不验证所有现有 主体的情况下的,应该授予新角色对应的权限)。 - 使得
roleRef
不可以改变现有绑定主体用户的update
权限, 这样可以让它们能够管理主体列表,而不能更改授予这些主体相关的角色。
4 案例演示
前面我们在k8s集群中创建了一个名为magedu的用户,接下来使用magedu这个用户进行权限演示。
4.1 前置准备工作
下面是前期的准备工作:
- 创建一个名为magedu的linux用户,并且设置密码。
- 将root用户的
.kube
文件夹下的内容复制到/home/magedu/
路径下 - 将
/temp/k8s/config
复制到/home/magedu/.kube/
路径下,如果存在config文件,直接覆盖 - 修改
/home/magedu/.kube
文件夹的权限为magedu:magedu
下面使用root账号进行操作
#添加magedu用户
[root@k8s-master01 access-control]# useradd magedu
#设置magedu用户的密码
[root@k8s-master01 ~]# passwd magedu
更改用户 magedu 的密码 。
新的 密码:
无效的密码: 密码少于 8 个字符
重新输入新的 密码:
passwd:所有的身份验证令牌已经成功更新。
#将.kube文件夹中的内容复制到/home/magedu目录下
[root@k8s-master01 access-control]# cp -rp /root/.kube/ /home/magedu/
#用/temp/k8s/config覆盖/home/magedu/.kube/config文件
[root@k8s-master01 access-control]# cp /temp/k8s/config /home/magedu/.kube/
#提示是否修改,修改
cp:是否覆盖"/home/magedu/.kube/config"? yes
#修改/home/mageud路径下的文件的所在用户和用户组
[root@k8s-master01 access-control]# chown -R magedu:magedu /home/magedu/
重新打开一个shell窗口,使用magedu登录k8s-master01服务器。
#查看当前的配置信息
[magedu@k8s-master01 ~]$ kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority: /etc/kubernetes/pki/ca.crt
server: https://192.168.1.180:6443
name: k8s1
contexts:
- context:
cluster: k8s1
user: magedu
name: magedu@k8s1
current-context: magedu@k8s1
kind: Config
preferences: {}
users:
- name: magedu
user:
client-certificate: /etc/kubernetes/pki/magedu.crt
client-key: /etc/kubernetes/pki/mageedu.key
#查看当前正在使用的context
[magedu@k8s-master01 ~]$ kubectl config current-context
magedu@k8s1
#查看Pod
[magedu@k8s-master01 ~]$ kubectl get pod --all-namespaces
Error from server (Forbidden): pods is forbidden: User "magedu" cannot list resource "pods" in API group "" at the cluster scope
我们发现并没有权限,接下来我们为magedu
这个账号赋予相应的权限,进行访问。
4.2 只能对kube-system名称空间下pod的查看的权限
这里我们先使用root账号进行操作
定义Role
[root@k8s-master01 access-control]# kubectl create role pod-reader --verb=list --resource=pod --namespace=kube-system
role.rbac.authorization.k8s.io/pod-reader created
这里我们创建一个Role,只有kube-system名称空间下pod的list权限。
定义RoleBinding
,将上面定义的Role
绑定到magedu上,同时指定名称空间为kube-system
[root@k8s-master01 access-control]# kubectl create rolebinding magedu-pod-reader --role=pod-reader --user=magedu -n kube-system
rolebinding.rbac.authorization.k8s.io/magedu-pod-reader created
现在使用magedu这个账号进行操作,打开magedu的shell界面
我们查看kube-system名称空间下的pod,发现是可以查看的。
[magedu@k8s-master01 ~]$ kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-9d85f5447-b8pdz 1/1 Running 4 8d
coredns-9d85f5447-hrmzh 1/1 Running 4 8d
etcd-k8s-master01 1/1 Running 4 8d
kube-apiserver-k8s-master01 1/1 Running 4 8d
kube-controller-manager-k8s-master01 1/1 Running 4 8d
kube-flannel-ds-amd64-9zbxf 1/1 Running 4 8d
kube-flannel-ds-amd64-kqfjs 1/1 Running 4 8d
kube-flannel-ds-amd64-txqpc 1/1 Running 4 8d
kube-proxy-hltxq 1/1 Running 4 8d
kube-proxy-nmg8b 1/1 Running 4 8d
kube-proxy-rzghv 1/1 Running 4 8d
kube-scheduler-k8s-master01 1/1 Running 4 8d
我们查看其它名称空间例如ingress-nginx中的Pod
[magedu@k8s-master01 ~]$ kubectl get pod -n ingress-nginx
Error from server (Forbidden): pods is forbidden: User "magedu" cannot list resource "pods" in API group "" in the namespace "ingress-nginx"
我们发现并没有查看ingress-nginx名称空间的Pod的权限,这是因为我们并没有赋予相应的权限。
4.3 使用RoleBinding去绑定ClusterRole
在k8s集群中存在着许多默认的ClusterRole
。其中一个是admin
,意思是管理员,该角色几乎拥有对资源的所有操作的权限。
现在我们有这样一个需求,为每个名称空间设置一个管理员,那么该如何实现呢?
在每个名称空间中创建一个RoleBinding
,然后使用RoleBinding
去绑定admin
这个ClusterRole
,那么就完成了需求为每个名称空间设置一个管理员。不需要在每个名称空间定义一个Role
,即可完成批量绑定的操作。
查看一下k8s集群中默认存在的ClusterRole
。
[root@k8s-master01 access-control]# kubectl get clusterrole
NAME AGE
admin 8d
cluster-admin 8d
edit 8d
......
假如我们现在需要为ingress-nginx设置管理员,使用root账号进行操作。
在ingress-nginx名称空间中创建RoleBinding
去绑定ClusterRole
到magedu这个账户中。
[root@k8s-master01 access-control]# kubectl create rolebinding magedu-admin-ingress-nginx --clusterrole=admin --user=magedu -n ingress-nginx
rolebinding.rbac.authorization.k8s.io/magedu-admin-ingress-nginx created
接下来使用magedu这个账户进行验证。对ingress-nginx名称空间中的pod进行增删改查,发现都能够进行操作。
#查看Pod
[magedu@k8s-master01 ~]$ kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-c699bd4f-lfgtv 1/1 Running 2 5d1h
#删除Pod
[magedu@k8s-master01 ~]$ kubectl delete pod --all -n ingress-nginx
pod "nginx-ingress-controller-c699bd4f-lfgtv" deleted
[magedu@k8s-master01 ~]$ kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-c699bd4f-xt5w4 0/1 Running 0 19s
5. 准入控制
准入控制是Api Server插件的集合,通过添加不同的插件,实现额外的准入控制规则。甚至基于Api Server的一些主要功能都需要通过Admission Controller实现,比如ServiceAccount。
官方文档上有一份针对不同版本的准入控制器推荐列表:
NamespaceLifecycle, LimitRanger, ServiceAccount, TaintNodesByCondition, Priority, DefaultTolerationSeconds, DefaultStorageClass, StorageObjectInUseProtection, PersistentVolumeClaimResize, MutatingAdmissionWebhook, ValidatingAdmissionWebhook, RuntimeClass, ResourceQuota
列举几个插件的功能:
- NamespaceLifecycle:防止在不存在的namespace上创建对象,防止删除系统预置namespace,删除namespace时,连带删除它的所有资源。
- LimitRanger:确保请求的资源不会超过资源所在Namespace的LimitRange的限制。
- SerivceAccount:实现了自动化添加ServiceAccount。
- ResourceQuota:确保请求的资源不会超过资源的ResourceQuota限制。
由于准入控制用得不是很多,这里就不多介绍了。
6. 使用dashboard练习访问控制
前面一直在使用命令行进行操作,现在k8s官方提供了一个可视化界面dashboard,用于简化k8s的操作。
当然了还有更多强大的k8s的发行版,例如Rancher、Kubesphere等。
Dashboard可以取访问k8s集群,是使用ServiceAccount
作为访问的凭证,同时创建了一系列的Role
、ClusterRole
。这些Role
、ClusterRole
具有一定的权限去获取集群中的资源,同时将Role
、ClusterRole
绑定到对应的ServiceAccount
上,那么Dashboard就可以取访问k8s集群。进而我们通过UI可视化界面进行操作集群了。
dashboard的github地址 和k8s官方文档dashboard
6.1 安装dashboard
安装dashboard的方式有两种:helm安装、资源清单的方式安装。
这里使用资源清单的方式进行演示
首先下载资源清单
[root@k8s-master01 access-control]# wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.4/aio/deploy/recommended.yaml
--2020-10-24 11:08:19-- https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.4/aio/deploy/recommended.yaml
正在解析主机 raw.githubusercontent.com (raw.githubusercontent.com)... 199.232.68.133
正在连接 raw.githubusercontent.com (raw.githubusercontent.com)|199.232.68.133|:443... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:7552 (7.4K) [text/plain]
正在保存至: “recommended.yaml”
100%[===================================================================================================================>] 7,552 16.6KB/s 用时 0.4s
2020-10-24 11:08:22 (16.6 KB/s) - 已保存 “recommended.yaml” [7552/7552])
[root@k8s-master01 access-control]# ll
总用量 16
-rw-r--r-- 1 root root 7552 10月 24 11:08 recommended.yaml
执行配置文件recommended.yaml
[root@k8s-master01 access-control]# kubectl apply -f recommended.yaml
namespace/kubernetes-dashboard created
serviceaccount/kubernetes-dashboard created
service/kubernetes-dashboard created
secret/kubernetes-dashboard-certs created
secret/kubernetes-dashboard-csrf created
secret/kubernetes-dashboard-key-holder created
configmap/kubernetes-dashboard-settings created
role.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrole.rbac.authorization.k8s.io/kubernetes-dashboard created
rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
deployment.apps/kubernetes-dashboard created
service/dashboard-metrics-scraper created
deployment.apps/dashboard-metrics-scraper created
等待大概2分钟后,查看运行情况
[root@k8s-master01 access-control]# kubectl get sa,secret,cm,role,clusterrole,rolebinding,clusterrolebinding,svc,deploy -n kubernetes-dashboard -l k8s-app
NAME SECRETS AGE
serviceaccount/kubernetes-dashboard 1 5m52s
NAME TYPE DATA AGE
secret/kubernetes-dashboard-certs Opaque 0 5m52s
secret/kubernetes-dashboard-csrf Opaque 1 5m52s
NAME DATA AGE
configmap/kubernetes-dashboard-settings 0 5m52s
NAME AGE
role.rbac.authorization.k8s.io/kubernetes-dashboard 5m52s
NAME AGE
clusterrole.rbac.authorization.k8s.io/kubernetes-dashboard 5m52s
NAME AGE
rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard 5m52s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/dashboard-metrics-scraper ClusterIP 10.96.46.142 <none> 8000/TCP 5m52s
service/kubernetes-dashboard ClusterIP 10.101.195.224 <none> 443/TCP 5m52s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/dashboard-metrics-scraper 1/1 1 1 5m51s
deployment.apps/kubernetes-dashboard 1/1 1 1 5m52s
6.2 进入dashboard
首先将Dashboard的Service类型修改为NodePort,当然了也可以使用Ingress的方式。
这里使用path打补丁的方式修改Service为NodePort的方式,然后查看暴露出的端口
[root@k8s-master01 access-control]# kubectl patch svc kubernetes-dashboard -p '{"spec":{"type":"NodePort"}}' -n kubernetes-dashboard
service/kubernetes-dashboard patched
[root@k8s-master01 access-control]# kubectl get svc kubernetes-dashboard -n kubernetes-dashboard
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes-dashboard NodePort 10.99.194.5 <none> 443:32240/TCP 11m
在浏览器输入htts://192.168.180:32240
需要注意的是这里使用的是https而不是http
初始化之后需要配置token或者是kubeconfig
这里两种方式都进行演示
6.3 配置token
使用token的方式
我们先查看Dashboard
组件使用的ServiceAccount
所关联的Secret
的token的值
[root@k8s-master01 access-control]# kubectl get secret kubernetes-dashboard-token-tnmbz -n kubernetes-dashboard -o jsonpath='{.data.token}' | base64 -d && echo
eyJhbGciOiJSUzI1NiIsImtpZCI6Il9tRWROYTg2Y2VZSkQ15NTWczRHR2Zjl6X2tqSTFNODlYMWsifQ.eyJpc3MiOiJrdW......
这里token的值是经过base64加密的,需要使用base64进行解密,然后将其复制粘贴到输入框中。点击确认,进入Dashboard
。
进入之后发现疯狂报错
这是为什么呢?这是由于Dashboard默认创建以及绑定的Role
、ClusterRole
的权限非常小,没有对Role
、ServiceAccount
等资源进行定义。
我们可以查看一下默认创建以及绑定的Role
、ClusterRole
查看创建的Role
[root@k8s-master01 access-control]# kubectl get role kubernetes-dashboard -n kubernetes-dashboard -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{......}
creationTimestamp: "2020-10-24T03:16:47Z"
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
resourceVersion: "134085"
selfLink: /apis/rbac.authorization.k8s.io/v1/namespaces/kubernetes-dashboard/roles/kubernetes-dashboard
uid: f2c7ae8f-b5b7-4f67-b591-6f24c625f0b7
rules:
- apiGroups:
- ""
resourceNames:
- kubernetes-dashboard-key-holder
- kubernetes-dashboard-certs
- kubernetes-dashboard-csrf
resources:
- secrets
verbs:
- get
- update
- delete
- apiGroups:
- ""
resourceNames:
- kubernetes-dashboard-settings
resources:
- configmaps
verbs:
- get
- update
- apiGroups:
- ""
resourceNames:
- heapster
- dashboard-metrics-scraper
resources:
- services
verbs:
- proxy
- apiGroups:
- ""
resourceNames:
- heapster
- 'http:heapster:'
- 'https:heapster:'
- dashboard-metrics-scraper
- http:dashboard-metrics-scraper
resources:
- services/proxy
verbs:
- get
查看创建的ClusterRole
[root@k8s-master01 access-control]# kubectl get clusterrole kubernetes-dashboard -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"rbac.authorization.k8s.io/v1","kind":"ClusterRole","metadata":{"annotations":{},"labels":{"k8s-app":"kubernetes-dashboard"},"name":"kubernetes-dashboard"},"rules":[{"apiGroups":["metrics.k8s.io"],"resources":["pods","nodes"],"verbs":["get","list","watch"]}]}
creationTimestamp: "2020-10-24T03:16:47Z"
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
resourceVersion: "134086"
selfLink: /apis/rbac.authorization.k8s.io/v1/clusterroles/kubernetes-dashboard
uid: b864995a-87cc-4757-8ae3-3b68517025c3
rules:
- apiGroups:
- metrics.k8s.io
resources:
- pods
- nodes
verbs:
- get
- list
- watch
我们想要为kubernetes-dashboard这个ServiceAccount
赋予更大的权限如何做呢?
这里我们创建一个ClusterRolebinding
,去绑定集群中的名为admin
的CluserRole
,该ClusterRole
几乎拥有所有的权限。然后将创建的ClusterRolebinding
,绑定到kubernetes-dashboard
这个ServiceAccount
中。这样在UI界面就几乎能够进行访问所有名称空间下的所有的资源了。
[root@k8s-master01 access-control]# kubectl create clusterrolebinding kubernetes-dashboard-admin \
--clusterrole=admin --serviceaccount=kubernetes-dashboard:kubernetes-dashboard
clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard-admin created
重新登录即可。
6.4 配置kubeconfig
具体步骤为:
- 创建名为kubernetes的
cluster
- 保存
kubernetes-dashboard
这个ServiceAccount
对应的Secret
的值 - 创建
user
- 创建
context
- 定义使用的上下文
dashboard-kubeconfig@kubernetes
- 复制
kubeconfig
文件到window环境下,进行访问测试
创建名为kubernetes的cluster,然后指定配置文件为/temp/k8s2/config
[root@k8s-master01 access-control]# kubectl config set-cluster kubernetes --server="https://192.168.1.180:6443" --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs=true --kubeconfig=/temp/k8s2/config
Cluster "kubernetes" set.
查看刚才创建的cluster
[root@k8s-master01 access-control]# kubectl config get-clusters --kubeconfig=/temp/k8s2/config
NAME
kubernetes
保存Secret
的值
[root@k8s-master01 access-control]# token=$(kubectl get secret kubernetes-dashboard-token-89q9w -n kubernetes-dashboard -o jsonpath='{.data.token}' | base64 -d)
[root@k8s-master01 access-control]# echo $token
......
创建dashboard-kubeconfig用户,创建用户的方式有很多,这里使用token的方式,这里的token指的就是ServiceAccount
与之关联的Secret
的值
#这里使用上一步保存的token
[root@k8s-master01 access-control]# kubectl config set-credentials dashboard-kubeconfig --token=$token --kubeconfig=/temp/k8s2/config
User "dashboard-kubeconfig" set.
查看创建的用户
[root@k8s-master01 access-control]# kubectl config view --kubeconfig=/temp/k8s2/config
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://192.168.1.180:6443
name: kubernetes
contexts: null
kind: Config
preferences: {}
users:
- name: dashboard-kubeconfig
user:
token: ......
创建名为dashboard-kubeconfig@kubernetes
的上下文context
,上下文context
命名方式一般为username@clustername
[root@k8s-master01 access-control]# kubectl config set-context dashboard-kubeconfig@kubernetes --cluster=kubernetes --user=dashboard-kubeconfig --kubeconfig=
/temp/k8s2/config
Context "dashboard-kubeconfig@kubernetes" created.
查看创建的上下文context
[root@k8s-master01 access-control]# kubectl config get-contexts --kubeconfig=/temp/k8s2/config
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* dashboard-kubeconfig@kubernetes kubernetes dashboard-kubeconfig
使用刚才创建的上下文,并且查看上下文是否切换
[root@k8s-master01 access-control]# kubectl config use-context dashboard-kubeconfig@kubernetes --kubeconfig=/temp/k8s2/config
Switched to context "dashboard-kubeconfig@kubernetes".
[root@k8s-master01 access-control]# kubectl config current-context
kubernetes-admin@kubernetes
查看kubeconfig中的内容
[root@k8s-master01 access-control]# cat /temp/k8s2/config
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: ......
server: https://192.168.1.180:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: dashboard-kubeconfig
name: dashboard-kubeconfig@kubernetes
current-context: dashboard-kubeconfig@kubernetes
kind: Config
preferences: {}
users:
- name: dashboard-kubeconfig
user:
token: ......
将config文件复制到window系统中,进行访问测试。
更多推荐
所有评论(0)