访问控制主要包括三个部分:
认证和授权再apiserver的pod上完成.
认证通或后就可以从etcd里面获取信息了.
[root@server2 ~]# kubectl get sa
NAME SECRETS AGE
default 1 21d
[root@server2 ~]# kubectl describe sa default
Name: default
Namespace: default
Labels:
Annotations:
Image pull secrets:
Mountable secrets: default-token-j7pl7
Tokens: default-token-j7pl7
Events:
Authorization(授权)
Admission Control(准入控制)
访问k8s API Server的客户端主要分为两类:
UserAccount
;而Pod自身去连接API Server时,使用的账号是:ServiceAccount
,生产中后者使用居多。kubectl向apiserver发起的命令,采用的是http
方式,其实就是对URL
发起增删改查的操作。
}[root@server2 ~]#kubectl proxy --port=8888 & 用 proxy 打开一个端口,可以直接用curl访问.
[root@server2 ~]# netstat -tnlp | grep 8888
tcp 0 0 127.0.0.1:8888 0.0.0.0:* LISTEN 18339/kubectl
[root@server2 ~]# curl http://localhost:8888/api/v1/namespaces/default
{
"kind": "Namespace",
"apiVersion": "v1",
"metadata": {
"name": "default",
...
[root@server2 ~]# curl http://localhost:8888/apis/apps/v1/namespaces/default/deployments
{
"kind": "DeploymentList",
"apiVersion": "apps/v1",
"metadata": {
"selfLink": "/apis/apps/v1/namespaces/default/deployments",
"resourceVersion": "793632"
},
"items": [
...
以上两种api的区别是:
UserAccount与serviceaccount的区别:
[root@server2 ~]# kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://172.25.254.2: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
创建serviceaccount:
[root@server2 ~]# kubectl create serviceaccount admin
serviceaccount/admin created
[root@server2 ~]# kubectl get sa
NAME SECRETS AGE
admin 1 5s
default 1 21d
[root@server2 ~]# kubectl describe sa admin
Name: admin
Namespace: default
Labels:
Annotations:
Image pull secrets: /镜像拉取的secrets
Mountable secrets: admin-token-lbb4q /集群自动创建了token令牌.确保sa 建立会后可用
Tokens: admin-token-lbb4q
Events:
此时时没有授权的.但是我们还可以网sa 中加入一些参数,比如镜像拉取的secrets:
[root@server2 cm]# kubectl get secrets
NAME TYPE DATA AGE
admin-token-lbb4q kubernetes.io/service-account-token 3 5m51s
basic-auth Opaque 1 9d
db-user-pass Opaque 2 8d
default-token-j7pl7 kubernetes.io/service-account-token 3 21d
dev-db-secret Opaque 2 8d
myregistrykey kubernetes.io/dockerconfigjson 1 8d /这是我们之前创建的一个用于拉取镜像的secret
tls-secret kubernetes.io/tls 2 9d
[root@server2 cm]# vim pod.yml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: game2048
image: reg.caoaoyuan.org/caoaoyuan/game2048
imagePullSecrets:
- name: myregistrykey 我们在使用的时候必须要再资源清单中指定才可以使用.
[root@server2 cm]# kubectl apply -f pod.yml
kubc pod/mypod created
[root@server2 cm]# kubectl describe pod mypod
Volumes:
default-token-j7pl7:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-j7pl7 /系统进行挂载
我们就可以把这个secret 加入到指定的 sa中,这样每次创建pod就不用指定了.
添加secrets到serviceaccount中:
[root@server2 cm]# kubectl patch serviceaccount admin -p '{"imagePullSecrets": [{"name":"myregistrykey"}]}'
serviceaccount/admin patched
[root@server2 cm]# kubectl describe sa admin
Name: admin
Namespace: default
Labels:
Annotations:
Image pull secrets: myregistrykey /加近来了
Mountable secrets: admin-token-lbb4q
Tokens: admin-token-lbb4q
Events:
更改pod文件;
[root@server2 cm]# vim pod.yml
[root@server2 cm]# cat pod.yml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: game2048
image: reg.caoaoyuan.org/caoaoyuan/game2048
serviceAccountName: admin /直接指定sa即可
[root@server2 scheduler]# kubectl delete -f deployment.yml
deployment.apps "deployment-v1" deleted
[root@server2 scheduler]# kubectl describe pod mypod
Volumes:
admin-token-lbb4q:
Type: Secret (a volume populated by a Secret)
SecretName: admin-token-lbb4q /就是我们指定的admin 的sa了
如果我们不指定的话就会使用默认的sa, 但是里面是没有secret的,就会拉取镜像失败.
[root@server2 cm]# kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name":"myregistrykey"}]}'
serviceaccount/default patched
[root@server2 cm]# kubectl describe sa default
Name: default
Namespace: default
Labels:
Annotations:
Image pull secrets: myregistrykey /加到默认sa中去
Mountable secrets: default-token-j7pl7
Tokens: default-token-j7pl7
Events:
[root@server2 cm]# cat pod.yml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: myapp 没有指定sa
image: myapp:v1
kubec [root@server2 cm]# kubectl apply -f pod.yml
pod/mypod created
[root@server2 cm]# kubectl get pod
NAME READY STATUS RESTARTS AGE
mypod 1/1 Running 0 6s 成功运行起来了
通过这种方式,我们就是 将认证信息添加到serviceAccount中,要比直接在Pod指定imagePullSecrets要安全很多。
创建UserAccount:
用于登陆集群,连接api,给用户使用.
首先给用户创建证书:
[root@server2 cm]# cd /etc/kubernetes/pki/ /证书创建目录
/生成key
[root@server2 pki]# openssl genrsa -out test.key 2048
Generating RSA private key, 2048 bit long modulus
/生成证书请求
[root@server2 pki]# openssl req -new -key test.key -out test.csr -subj "/CN=test"
[root@server2 pki]# ls
test.key test.csr ...
/生成证书
[root@server2 pki]# openssl x509 -req -in test.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out test.crt -days 365
Signature ok
subject=/CN=test
Getting CA Private Key
/设置test用用户,并识别证书和key
[root@server2 pki]# kubectl config set-credentials test --client-certificate=/etc/kubernetes/pki/test.crt --client-key=/etc/kubernetes/pki/test.key --embed-certs=true
User "test" set.
[root@server2 pki]# kubectl config view
...
users:
- name: kubernetes-admin
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
- name: test 用户出现了
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
加入到context\中
[root@server2 pki]# kubectl config set-context test@kubernetes --cluster=kubernetes --user=test
Context "test@kubernetes" created.
[root@server2 pki]# kubectl config view
..
contexts:
- context:
cluster: kubernetes
user: kubernetes-admin
name: kubernetes-admin@kubernetes
- context:
cluster: kubernetes
user: test
name: test@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
...
/切换
[root@server2 pki]# kubectl config use-context test@kubernetes
Switched to context "test@kubernetes".
[root@server2 pki]# kubectl get pod
Error from server (Forbidden): pods is forbidden: User "test" cannot list resource "pods" in API group "" in the namespace "default"
此时用户通过认证,但还没有权限操作集群资源,需要继续添加授权。
我们先切回管理员用户,进行授权
[root@server2 pki]# kubectl config use-context kubernetes-admin@kubernetes
Switched to context "kubernetes-admin@kubernetes".
[root@server2 pki]# kubectl get pod
No resources found in default namespace.
[root@server2 ~]# mkdir rbac
[root@server2 ~]# cd rbac/
[root@server2 rbac]# vim role.yml
[root@server2 rbac]# cat role.yml
kind: Role /rbac类型为role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default /针对默认namespace
name: myrole
rules:
- apiGroups: [""]
resources: ["pods"] /授权对应的资源
verbs: ["get", "watch", "list", "create", "update", "patch", "delete"] /对应的权限,自己定义
[root@server2 rbac]# kubectl apply -f role.yml
kubec role.rbac.authorization.k8s.io/myrole created
[root@server2 rbac]# kubectl get role
NAME CREATED AT
myrole 2020-07-10T04:35:24Z
[root@server2 rbac]# kubectl describe role myrole
Name: myrole
Labels:
Annotations: PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
pods [] [] [get watch list create update patch delete]
绑定:
[root@server2 rbac]# vim role.yml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: myrole
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list", "create", "update", "patch", "delete"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: test-read-pods
namespace: default /针对的默认命名空间
subjects:
- kind: User /绑定用户
name: test /用户名
apiGroup: rbac.authorization.k8s.io /api组
roleRef:
kind: Role /绑定角色
name: myrole
apiGroup: rbac.authorization.k8s.io
[root@server2 rbac]# kubectl apply -f role.yml
role.rbac.authorization.k8s.io/myrole unchanged
rolebinding.rbac.authorization.k8s.io/test-read-pods created
[root@server2 rbac]# kubectl config use-context test@kubernetes
Switched to context "test@kubernetes".
[root@server2 rbac]# kubectl run demo --image=busybox --restart=Never
pod/demo created /可以创建pod
[root@server2 rbac]# kubectl get pod
NAME READY STATUS RESTARTS AGE
demo 0/1 Completed 0 7s 查看pod
[root@server2 rbac]# kubectl delete pod demo
pod "demo" deleted
[root@server2 rbac]# kubectl get svc
Error from server (Forbidden): services is forbidden: User "test" cannot list resource "services" in API group "" in the namespace "default"
[root@server2 rbac]# kubectl get cm
Error from server (Forbidden): configmaps is forbidden: User "test" cannot list resource "configmaps" in API group "" in the namespace "default"
[root@server2 rbac]# kubectl get pod -n kube-system
Error from server (Forbidden): pods is forbidden: User "test" cannot list resource "pods" in API group "" in the namespace "kube-system"
可以看出 test 这个用户账户值可以对 pod 进行相应的操作,对于没有授权的不可以操作.而且只能在授权的命名空间内.
而且创建 控制器 cm,等等都是不可以的.
[root@server2 rbac]# kubectl config use-context kubernetes-admin@kubernetes
Switched to context "kubernetes-admin@kubernetes".
依然先切回管理员,进行授权
[root@server2 rbac]# vim role.yml
..上面不变,只在下面添加:
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: myclusterrole
rules: /多个规则
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list", "delete", "create", "update"]
- apiGroups: ["extensions", "apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
集群角色不仅可以 使用 clusterrolebinding 进行绑定,还可以使用 rolebinding 绑定:
[root@server2 rbac]# vim role.yml
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: myclusterrole
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list", "delete", "create", "update"]
- apiGroups: ["extensions", "apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: rolebind-myclusterrole
namespace: default 同样只能指定一个命名空间.
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole /绑定集群角色
name: myclusterrole
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: test /绑定用户
[root@server2 rbac]# kubectl get deployments.apps
No resources found in default namespace. /可以对控制器进行操作了
[root@server2 rbac]# kubectl get deployments.apps -n kube-system
Error from server (Forbidden): deployments.apps is forbidden: User "test" cannot list resource "deployments" in API group "apps" in the namespace "kube-system"
但是还是不能跨namespace 进行使用,因为我们使用的是角色绑定而不是集群角色绑定.
集群角色绑定:
[root@server2 rbac]# vim role.yml
...
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata: 集群角色绑定不用指定namespace,因为是针对所有namespace的.
name: clusterrolebinding-myclusterrole
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: myclusterrole
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: test
[root@server2 rbac]# kubectl apply -f role.yml
[root@server2 rbac]# kubectl config use-context test@kubernetes
Switched to context "test@kubernetes".
[root@server2 rbac]# kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
kubernetes-admin@kubernetes kubernetes kubernetes-admin
* test@kubernetes kubernetes test
[root@server2 rbac]# kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-76d4774d89-9fp2s 1/1 Running 1 2d23h
calico-node-bg9c4 1/1 Running 9 11d
calico-node-lvxrc 1/1 Running 8 11d
calico-node-smn7b 1/1 Running 9 11d
coredns-5fd54d7f56-2d7h9 1/1 Running 1 2d22h
[root@server2 rbac]# kubectl get deployments.apps -n kube-system
NAME READY UP-TO-DATE AVAILABLE AGE
calico-kube-controllers 1/1 1 1 11d
coredns 2/2 2 2 21d
就可以获取所有namespace下的 pod 和 deployment 的指定操作权限了.
但是只能对pod 和 deployment 进行操作,因为没指定其他的权限,clusterrole 只是可以对所有的命名空间操作,
我们在最初搭建集群的时候,并没有做一些证书,或者token的建立操作,但是我们仍然可以正常使用,这是因为集群自动化的帮我们创建了一些内容.
[root@server2 rbac]# kubectl create namespace linux
namespace/linux created
[root@server2 rbac]# kubectl get sa -n linux
NAME SECRETS AGE
default 1 7s /自动创建的sa
[root@server2 rbac]# kubectl -n kube-system describe pod coredns-5fd54d7f56-2d7h9
/var/run/secrets/kubernetes.io/serviceaccount from coredns-token-t4kqs (ro) /自动创建的token
kubec [root@server2 rbac]# kubectl get sa
NAME SECRETS AGE
admin 1 3h21m /这是我们自己创建的sa
default 1 21d
[root@server2 rbac]# kubectl get secrets
NAME TYPE DATA AGE
admin-token-lbb4q kubernetes.io/service-account-token 3 3h21m secret
basic-auth Opaque 1 9d
..
[root@server2 rbac]# kubectl delete sa admin
serviceaccount "admin" deleted
[root@server2 rbac]# kubectl get secrets
NAME TYPE DATA AGE
basic-auth Opaque 1 9d
删除sa后secret也不见了.
[root@server2 rbac]# kubectl create namespace linux
namespace/linux created
[root@server2 rbac]# kubectl get secrets -n linux
NAME TYPE DATA AGE
default-token-z59zk kubernetes.io/service-account-token 3 9s
[root@server2 rbac]# kubectl -n linux delete sa default /删除默认sa
serviceaccount "default" deleted
[root@server2 rbac]# kubectl get sa -n linux
NAME SECRETS AGE
default 1 7s
[root@server2 rbac]# kubectl get secrets -n linux
NAME TYPE DATA AGE
default-token-qp48s kubernetes.io/service-account-token 3 34s
我们可以看出创建命名空间时会自动创建一个secret,而且当我们删除了创建的默认的sa时,回立即重新拉起一个sa,并删除之前的secret,重新拉起一个.
示例1:表示mynamespace中的所有ServiceAccount
subjects:
- kind: Group
name: system:serviceaccounts:mynamespace
apiGroup: rbac.authorization.k8s.io
示例2:表示整个系统中的所有ServiceAccount
subjects:
- kind: Group
name: system:serviceaccounts 不指定命名空间
apiGroup: rbac.authorization.k8s.io
Kubernetes 还提供了四个预先定义好的 ClusterRole 来供用户直接使用:
他们各自有不同的权限
[root@server2 rbac]# kubectl get clusterrole
NAME CREATED AT
admin 2020-06-18T09:31:41Z
cluster-admin 2020-06-18T09:31:41Z
edit 2020-06-18T09:31:41Z
view 2020-06-18T09:31:42Z
[root@server2 rbac]# 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
--------- ----------------- -------------- -----
*.* [] [] [*]
[*] [] [*]
这是其中嗯权限最大的
例如:
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: readonly-default
subjects:
- kind: ServiceAccount
name: default
namespace: default
roleRef:
kind: ClusterRole
name: view 我们可以用系统的集群角色,赋予给这个sa 权限
apiGroup: rbac.authorization.k8s.io
准入控制主要是通过插件来完成的.