CKS-集群的强化-Kubernetes API的访问
集群的强化通过设置提高集群的安全性1. 验证方式2. 授权方式3. SA的安全设置登入k8s的验证方式1. token方式2. kubeconfig方式3. oauth2方式4. 其他第三方登录 https://www.tremolosecurity.com/products/orchestra-for-kubernetestoken方式1.在master上开启 token 认证并关联用户root
·
集群的强化
通过设置提高集群的安全性
1. 验证方式
2. 授权方式
3. SA的安全设置
登入k8s的验证方式
1. token方式
2. kubeconfig方式
3. oauth2方式
4. 其他第三方登录 https://www.tremolosecurity.com/products/orchestra-for-kubernetes
token方式
1.在master上开启 token 认证并关联用户
root@vms81:~/cks/day2# openssl rand -hex 10
40c83e0eb790664bad2c
1.1.token关联用户
**格式为token,用户名,UID**
root@vms81:~/cks/day2# cat /etc/kubernetes/pki/bb.csv
40c83e0eb790664bad2c,bob,3
**把用户bob和token关联在一起**
1.2修改配置文件开启token认证
root@vms81:~/cks/day2# vim /etc/kubernetes/manifests/kube-apiserver.yaml
添加 - --token-auth-file=/etc/kubernetes/pki/bb.csv
root@vms81:~/cks/day2# systemctl restart kubelet.service
2.客户端登入
**需要指定api地址** kubectl options
[root@vms70 ~]# kubectl get nodes -s https://192.168.26.81:6443 --token="40c83e0eb790664bad2c"
Unable to connect to the server: x509: certificate signed by unknown authority
**-s https://192.168.26.81:6443 -s 指定集群地址(kubectl cluster-info)**
**--token 指定token**
**报错原因是链接是需要mTLS的,客户端没有证书供apiserver去验证**
[root@vms70 ~]# kubectl get nodes -s https://192.168.26.81:6443 --token="40c83e0eb790664bad2c" --insecure-skip-tls-verify=true
Error from server (Forbidden): nodes is forbidden: User "bob" cannot list resource "nodes" in API group "" at the cluster scope
**--insecure-skip-tls-verify=true 跳过验证去tls链接,默认是false,改成true**
**报错原因是bob这个用户没有list权限**
[root@vms70 ~]# kubectl get nodes -s https://192.168.26.81:6443 --token="555555555555555555" --insecure-skip-tls-verify=true
error: You must be logged in to the server (Unauthorized)
**报错原因是改了 token ,没有读取到相关权限配置,提示必须登入**
kubeconfig认证方式
**这边的kubeconfig文件,是指可以用户认证的文件,名字可以自定义**
root@vms81:~/cks/day2# kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED # 指定CA证书
server: https://192.168.26.81:6443 # 指定集群地址
name: kubernetes
contexts:
- context: # 上下文,指定哪个用户和哪个集群关联在一起
cluster: kubernetes
namespace: day2
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
*在客户端操作**
指定集群信息及CA证书
上下文
用户信息
证书--公钥、私钥
1.客户端需要一个密钥对,首先需要生成一个私钥
**master上操作**
创建私钥,名字为 john.key
root@vms81:~/cks/day2/user# openssl genrsa -out john.key 2048
Generating RSA private key, 2048 bit long modulus
...+++
...........................................................................................+++
e is 65537 (0x10001)
利用刚生成的私有 john.key 生成证书请求文件 john.csr
root@vms81:~/cks/day2/user# openssl req -new -key john.key -out john.csr -subj "/CN=john/O=cka2020"
root@vms81:~/cks/day2/user# ll
总用量 8
-rw-r--r-- 1 root root 907 5月 9 16:05 john.csr
-rw-r--r-- 1 root root 1675 5月 9 16:03 john.key
**CN=用户 表示这个请求文件是针对这个用户去授权的**
对证书请求文件进行 base64 编码:
root@vms81:~/cks/day2/user# cat john.csr | base64 | tr -d "\n"
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1pqQ0NBVTRDQVFBd0lURU5NQXNHQTFVRUF3d0VhbTlvYmpFUU1BNEdBMVVFQ2d3SFkydGhNakF5TURDQwpBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQVBlQjBFQXZMa3NTZktHTktyNU8yaWVSCjJXcmtQMk9sWmhuYVNKbTRKTE8xcU1lQTA0MVUzWW1UQzZCWWtjd3F5cENLMTNDd3FhanNiMDZValplcFBXR2UKTVVlRlJiQjFFT1ExQ2syazFIcjZGQzYydEsvcWE5bTlGS3phajFvWXFqcFVlYkVmdUhGdk5OV3M4aU9mY3FQawpGdTlzTUhIbDNnL1ZYYmhEM29ieFpJc2hlN01oSzhMbDVLNWJDL1hzeE0vVUF3OG5NMnlaTVFyTkVKbEUvM1ZqCk8wNXoyMmcwaWFMZUlZb29YSFprV1FQK09FWDk2d0g4Ly8wYkptaS9pY2VXTmsyKzgrZ24xVzdqV3lWSzlaaFgKcnMvWjJQeWNOUFVUT2F1YzlzY0s3cnJIdlA3bmxSUXAzOXFDZjlMRGVNcko5bWJmL3N2cDZuSjZ1L1dzRWtrQwpBd0VBQWFBQU1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQnVYc3BQZVZGeWV4WWZQV0lkRjM5TmFTMVRISmRuCnBNcWI0MWQ2Nzd5UWlObTQ1Y3k5ejRpeWRPTHZvYmNXVm9VVHBSa1pJSkRrTCtVVmJTcHh0QmtUaXVlWUdPYVIKQnNJcGNtWXd3OWtDSzBkeHVGRGpQRWtEbmtvbHI2NTByMGlkN2tGcjVRUy9iZW5jdSt5d0hHeXl0TGtQa1o1awptT1d0a0trMkt0T2pqazk5cjUrQnBESzNkd0hjRGhndlJkc1Z3eDM4bUpPMVJVU1lSR05FUmwrYkovbHIzallXCnR6ek1ZaUwwS3RoYnVSUVBHZWpXQU1KaXB6amJteHdjbGNXYmViSTVKZll2anF3TWxlZVZCY2RUd0RpVVVzT0cKTWljNDRZc1VJREg3UDBKbHJYaFhDczloL1BUU0V2aStoTzdGK1FOYzArTjlFemR2Q0RobDZneloKLS0tLS1FTkQgQ0VSVElGSUNBVEUgUkVRVUVTVC0tLS0tCg==
**获得转码后的文件**
创建csr (申请证书请求文件的 yaml 文件)
vim csr.yaml
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: john
spec:
groups:
- system:authenticated
signerName: kubernetes.io/kube-apiserver-client
request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1pqQ0NBVTRDQVFBd0lURU5NQXNHQTFVRUF3d0VhbTlvYmpFUU1BNEdBMVVFQ2d3SFkydGhNakF5TURDQ
wpBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQVBlQjBFQXZMa3NTZktHTktyNU8yaWVSCjJXcmtQMk9sWmhuYVNKbTRKTE8xcU1lQTA0MVUzWW1UQzZCWWtjd3F5c
ENLMTNDd3FhanNiMDZValplcFBXR2UKTVVlRlJiQjFFT1ExQ2syazFIcjZGQzYydEsvcWE5bTlGS3phajFvWXFqcFVlYkVmdUhGdk5OV3M4aU9mY3FQawpGdTlzTUhIbDNnL1ZYYmhEM29ie
FpJc2hlN01oSzhMbDVLNWJDL1hzeE0vVUF3OG5NMnlaTVFyTkVKbEUvM1ZqCk8wNXoyMmcwaWFMZUlZb29YSFprV1FQK09FWDk2d0g4Ly8wYkptaS9pY2VXTmsyKzgrZ24xVzdqV3lWSzlaa
FgKcnMvWjJQeWNOUFVUT2F1YzlzY0s3cnJIdlA3bmxSUXAzOXFDZjlMRGVNcko5bWJmL3N2cDZuSjZ1L1dzRWtrQwpBd0VBQWFBQU1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQnVYc3BQZ
VZGeWV4WWZQV0lkRjM5TmFTMVRISmRuCnBNcWI0MWQ2Nzd5UWlObTQ1Y3k5ejRpeWRPTHZvYmNXVm9VVHBSa1pJSkRrTCtVVmJTcHh0QmtUaXVlWUdPYVIKQnNJcGNtWXd3OWtDSzBkeHVGR
GpQRWtEbmtvbHI2NTByMGlkN2tGcjVRUy9iZW5jdSt5d0hHeXl0TGtQa1o1awptT1d0a0trMkt0T2pqazk5cjUrQnBESzNkd0hjRGhndlJkc1Z3eDM4bUpPMVJVU1lSR05FUmwrYkovbHIza
llXCnR6ek1ZaUwwS3RoYnVSUVBHZWpXQU1KaXB6amJteHdjbGNXYmViSTVKZll2anF3TWxlZVZCY2RUd0RpVVVzT0cKTWljNDRZc1VJREg3UDBKbHJYaFhDczloL1BUU0V2aStoTzdGK1FOY
zArTjlFemR2Q0RobDZneloKLS0tLS1FTkQgQ0VSVElGSUNBVEUgUkVRVUVTVC0tLS0tCg==
usages:
- client auth
申请证书
root@vms81:~/cks/day2/user# kubectl apply -f csr.yaml
certificatesigningrequest.certificates.k8s.io/john created
**查询到john用户已经申请证书**
root@vms81:~/cks/day2/user# kubectl get csr
NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION
john 8s kubernetes.io/kube-apiserver-client kubernetes-admin <none> Pending
用k8s的CA证书进行证书审批
**证书地址/etc/kubernetes/pki/**
root@vms81:~/cks/day2/user# kubectl certificate approve john
certificatesigningrequest.certificates.k8s.io/john approved
**certificate approve 用户**
root@vms81:~/cks/day2/user# kubectl get csr
NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION
john 5m11s kubernetes.io/kube-apiserver-client kubernetes-admin <none> Approved,Issued
**状态已变更**
导出john的证书
root@vms81:~/cks/day2/user# kubectl get csr john -o jsonpath='{.status.certificate}' |base64 -d > john.crt
**base64 解码重定向到john.crt**
root@vms81:~/cks/day2/user# cp /etc/kubernetes/pki/ca.crt .
**复制k8s的ca证书**
root@vms81:~/cks/day2/user# ll
total 28
-rw-r--r-- 1 root root 1099 May 9 16:29 ca.crt # K8s CA证书
-rw-r--r-- 1 root root 1440 May 9 16:16 csr.yaml #
-rw-r--r-- 1 root root 1111 May 9 16:26 john.crt # 导出john的证书
-rw-r--r-- 1 root root 907 May 9 16:14 john.csr # csr 申请证书请求文件
-rw------- 1 root root 1679 May 9 16:12 john.key # john的私钥
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rM7F36Ci-1653553180829)(./images/20220509-1636.png)]
生成kubeconfig文件(命令行方式)
创建kubeconfig文件
# 创建 kubeconfig 模板文件 复制admin.conf或者执行命令
root@vms81:~/cks/day2/user# kubectl config --kubeconfig=kc1 set-cluster cluster1 --server=https://192.168.26.81:6443 --certificate-authority=ca.crt --embed-certs=true
Cluster "cluster1" set.
**--kubeconfig=名字 设置kubeconfig名字**
**set-cluster 名字 设置集群名字 随意**
**--server= 指定集群**
**--embed-certs=true 是否把指定的信息嵌入文档,如果不嵌入,CA信息那边就是个文件,后面使用时就必须要在同目录下也有ca证书文件才行**
设置用户
root@vms81:~/cks/day2/user# kubectl config --kubeconfig=kc1 set-credentials john --client-certificate=john.crt --client-key=john.key --embed-certs=true
User "john" set.
设置上下文 把用户和集群捆绑在一起
kubectl config --kubeconfig=kc1 set-context context1 --cluster=cluster1 --namespace=day2 --user=john
Context "context1" created.
**上下文,把用户信息和集群关联起来**
**--cluster=集群名字**
还需要配置当前上下文
namespace: day2
user: john
name: context1
current-context: "context1" # 默认当前上下文为空
kind: Config
preferences: {}
测试
复制kubeconfig文件到客户端
scp kc1 root@192.168.26.70:~
# 在客户端操作
[root@vms70 ~]# kubectl get nodes --kubeconfig=./kc1
Error from server (Forbidden): nodes is forbidden: User "john" cannot list resource "nodes" in API group "" at the cluster scope
**指定kubeconfig文件**
简化命令
**1.不需要指定kubeconfig文件,export KUBECONFIG=kc1 执行kubectl时候会默认读取变量KUBECONFIG,unset KUBECONFIG 取消变量设置**
**cp kc1 ./kube/config**
**什么都不指定的话,默认使用~/.kube/config这个文件**
# 先后级 先读取变量,如果变量没有定义再读取~/.kube/config
用admin.config来授权
# master
root@vms81:/etc/kubernetes/pki# cp /etc/kubernetes/admin.conf ~tom/config # 复制配置文件
root@vms81:/etc/kubernetes/pki# chown tom.tom ~tom/config # 授权
tom@vms81:~$ su tom
tom@vms81:~$ kubectl get nodes --kubeconfig=config
NAME STATUS ROLES AGE VERSION
vms81.rhce.cc Ready control-plane,master 3d8h v1.23.2
vms82.rhce.cc Ready <none> 3d8h v1.23.2
**tom用户已经有权限 这个就是kubeadm init 后要进行的操作**
集群的授权
通过修改- --authorization-mode=Node,RBAC
vim /etc/kubernetes/manifests/kube-apiserver.yaml
授权的方式主要有
- RBAC # 不管在什么情况下,授权方式都要选择RBAC
- NODE # worker 向 master 查询数据 # 必须和 -
–enable-admission-plugins=NodeRestriction 准入控制器必须一起开启 - Webhook
- ABAC # 不要使用ABAC,使用RABAC
- AlwaysAllow # 总是允许
- AlwaysDeny # 总是禁止
权限不会直接给到用户
**权限会先给予一个角色role(),然后再rolebinding到用户john,这时候john就有了在与role所在的namespace下的权限**
**clusterrole 是集群内的,不限制于namespace,用户是否有权限在于是用rolebinding还是clusterrolebinding**
**clusterrole也可以是用rolebinding到用户,这时候用户只有对应rolebinding指定的namespace内的权限**
**一个用户可以与多个rolebinding 关联**
开始授权
1.首先判断john是否有权限查看pod
[root@vms70 ~]# kubectl auth can-i get ns
Warning: resource 'namespaces' is not namespace scoped
no
root@vms81:~# kubectl auth --as=john can-i get pod
no
**auth can-i 查看当前用户**
**--as=john 指定用户**
2.创建role 角色role
root@vms81:~/cks# kubectl create role role1 --resource=po --verb=get,list
role.rbac.authorization.k8s.io/role1 created
root@vms81:~/cks# kubectl get role
NAME CREATED AT
role1 2022-05-10T07:26:21Z
**创建rolebinding 指定role --role= 指定用户 --user= **
root@vms81:~/cks# kubectl create rolebinding rbind1 --role=role1 --user=john
rolebinding.rbac.authorization.k8s.io/rbind1 created
root@vms81:~/cks# kubectl get rolebindings.rbac.authorization.k8s.io
NAME ROLE AGE
rbind1 Role/role1 8s
3.测试
**再次查询是否有权限**
root@vms81:~# kubectl auth can-i --as=john get po
yes
**客户端 由于只在ns day2中授权**
[root@vms70 ~]# kubectl get pod --kubeconfig=kc1
No resources found in day2 namespace.
**让70客户端可以创建pod**
**master添加create权限**
root@vms81:~/cks# vim role1.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
creationTimestamp: null
name: role1
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- create # 增加
root@vms81:~/cks# kubectl apply -f role1.yaml
**客户端查询**
[root@vms70 ~]# kubectl --kubeconfig=kc1 run web1 --image=nginx
pod/web1 created
[root@vms70 ~]# kubectl get pod --kubeconfig=kc1
NAME READY STATUS RESTARTS AGE
web1 1/1 Running 0 73s
[root@vms70 ~]# kubectl delete pod web1 --kubeconfig=kc1
Error from server (Forbidden): pods "web1" is forbidden: User "john" cannot delete resource "pods" in API group "" in the namespace "day2"
没有delete权限
授权yaml文件详解
root@vms81:~/cks# vim role1.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
creationTimestamp: null
name: role1
rules:
- apiGroups: # 这边有个api群组
- ""
resources:
- pods # 针对分别授权
verbs:
- get
- list
- apiGroups:
- ""
resources:
- service # 针对分别授
verbs:
- get
- list
- create
apiGroups
kubectl api-resources
**NAME SHORTNAMES APIVERSION NAMESPACED KIND**
pods po v1 true Pod
...
deployments deploy apps/v1 true Deployment
**每一种资源类型都会对应一个apiversion**
APIVERSION的结构
# xx ---- 单级,没有父级,用"" 表示
role的yaml文件里,apiGroup写的是apiversion的父级
rules:
- apiGroups: # 这边有个api群组,指定了apiversion的父级
- "" # 当父级为空是,只对父级为空的生效
resources:
- service
- pod
# yy/zz ---- 两级的,
role的yaml文件里,apiGroup写的是apiversion的父级
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
creationTimestamp: null
name: role1
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- create
- apiGroups: # 由于deployments 父级不为空,这边apps指定父级
- "apps"
resources:
- deployments
verbs: # deploy也需要授权
- get
- list
- create
需求:找出所有授权给john的 role,然后把对应的rolebinding删除
root@vms81:~/cks# kubectl get rolebindings.rbac.authorization.k8s.io -A -o wide
NAMESPACE NAME ROLE AGE USERS GROUPS SERVICEACCOUNTS
day2 rbind1 Role/role1 49m john
kube-public kubeadm:bootstrap-signer-clusterinfo Role/kubeadm:bootstrap-signer-clusterinfo 4d6h system:anonymous
root@vms81:~/cks# kubectl get rolebindings.rbac.authorization.k8s.io -A -o wide |grep john
day2 rbind1 Role/role1 51m john
root@vms81:~/cks# kubectl delete rolebindings.rbac.authorization.k8s.io rbind1
rolebinding.rbac.authorization.k8s.io "rbind1" deleted
SERVICEACCOUNT
** 我们创建你的pod都会以某个sa的身份运行**
**如果没有指定sa,会默认使用default这个sa,每个ns里面都会有default这个sa**
sa的作用
user account 用户账户
service account sa ---pod以哪个身份来运行
**每创建一个sa,都会创建一个secret,格式为sa名字-token-xxx,secret会绑定一个token并挂载到到容器的一个目录, pod就会根据token判断用户是否有对应操作权限,也可以拿着拥有对应权限的token去访问k8s**
**给sa授权,对应的token就也有了权限,容器可以使用这token去请求k8s集群**
[root@vms51 ac]# kubectl create sa sa1
serviceaccount/sa1 created
[root@vms51 ac]# kubectl get secrets
NAME TYPE DATA AGE
default-token-crhwp kubernetes.io/service-account-token 3 97m
**sa1-token-lszh5 kubernetes.io/service-account-token 3 1s**
[root@vms51 ac]# kubectl describe secrets sa1-token-lszh5
Name: sa1-token-lszh5
Namespace: 13-safe
Labels: <none>
Annotations: kubernetes.io/service-account.name: sa1
kubernetes.io/service-account.uid: b769eed9-7a0c-4df9-a0d9-a12fad0f0f97
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1099 bytes
namespace: 7 bytes
token: eyJhbGciOiJSUzI...
我们创建pod时,默认使用了名叫default的sa
[root@vms51 ac]# kubectl get sa -o wide
NAME SECRETS AGE
**default 1 99m**
sa1 1 2m8s
通过查看pod的yaml文件可以看到使用的默认default的sa
pod引用sa
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod1
name: pod1
spec:
serviceAccount: sa名字
root@pod1:/# df -h
Filesystem Size Used Avail Use% Mounted on
overlay 50G 6.4G 41G 14% /
tmpfs 64M 0 64M 0% /dev
tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
/dev/vda1 50G 6.4G 41G 14% /etc/hosts
shm 64M 0 64M 0% /dev/shm
**tmpfs 3.7G 12K 3.7G 1% /run/secrets/kubernetes.io/serviceaccount**
tmpfs 1.9G 0 1.9G 0% /proc/acpi
tmpfs 1.9G 0 1.9G 0% /proc/scsi
tmpfs 1.9G 0 1.9G 0% /sys/firmware
系统会自动在容器内挂载sa
root@web1:/# ls /run/secrets/kubernetes.io/serviceaccount **在容器里查看**
ca.crt namespace token
root@vms81:~# kubectl create sa sa1
serviceaccount/sa1 created
root@vms81:~# kubectl --as=system:serviceaccount:day2:sa1 auth can-i get secret
no
**--as=system:serviceaccount: 指定ns名字:sa名字**
给sa授权
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
creationTimestamp: null
name: role1
rules:
- apiGroups:
- ""
resources:
- pods
- services # 必须是全称,不能缩写,kubectl api-resources 查询
verbs:
- get
- list
- create
- apiGroups:
- "apps"
resources:
- deployments
verbs:
- get
- list
- create
root@vms81:~/cks# kubectl apply -f role1.yaml
role.rbac.authorization.k8s.io/role1 configured
root@vms81:~/cks# kubectl get role
NAME CREATED AT
role1 2022-05-10T07:26:21Z
**rolebinding sa1**
root@vms81:~/cks# kubectl create rolebinding rbind1 --role=role1 --serviceaccount=day2:sa1
rolebinding.rbac.authorization.k8s.io/rbind1 created
root@vms81:~/cks# kubectl describe rolebindings.rbac.authorization.k8s.io rbind1
Name: rbind1
Labels: <none>
Annotations: <none>
Role:
Kind: Role
Name: role1
Subjects:
Kind Name Namespace
---- ---- ---------
ServiceAccount sa1 day2
root@vms81:~/cks# kubectl --as=system:serviceaccount:day2:sa1 auth can-i get svc
yes
**已有权限**
**如果pod里运行是一个普通的进程比如web,那就没有必要给sa过多权限,避免用户通过浏览器提交恶意代码,利用sa关联的token继而访问k8s资源**
**如果是开发的一套用户管理k8s的程序,可以给他高权限**
给sa授权。admin权限
kubectl create clusterrolebinding cbind1 --clusterrole=cluster-admin --serveraccount=day2:sa1
--serveraccount=namespace:对应sa
****
kubectl describe secrets sa1-token-9c4tm
Name: sa1-token-9c4tm
Namespace: day2
Labels: <none>
Annotations: kubernetes.io/service-account.name: sa1
s.io/service-account.uid: bd04029f-db9d-4623-b079-11d96974b2e0
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1099 bytes
namespace: 7 bytes
token: eyJhbGciOiJSUzI1Ni...
用这个token就有权限
为了安全,在创建容器时不把token 挂载到容器**
有两种方法
- 从pod层面来实现
- 从sa层面来实现
从pod层面来实现
root@vms81:~/cks# vim pod1.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: web1
name: web1
spec:
automountServiceAccountToken: false # 默认挂载serviceaccount :关闭
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: web1
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
root@vms81:~/cks# kubectl apply -f pod1.yaml
pod/web1 created
root@vms81:~/cks# kubectl exec -it web1 -- bash
root@web1:/# df -h
Filesystem Size Used Avail Use% Mounted on
overlay 97G 4.8G 88G 6% /
tmpfs 64M 0 64M 0% /dev
tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup
/dev/mapper/tom--vg-root 97G 4.8G 88G 6% /etc/hosts
shm 64M 0 64M 0% /dev/shm
tmpfs 2.0G 0 2.0G 0% /proc/acpi
tmpfs 2.0G 0 2.0G 0% /proc/scsi
tmpfs 2.0G 0 2.0G 0% /sys/firmware
**sa没有挂载,容器就不能通过有权限的token去访问集群**
**问题这个pod没有挂载sa的token,但是其他没有配置关闭挂载的还会**
从sa层面来实现不挂载
kubectl explain serviceaccount
automountServiceAccountToken
root@vms81:~/cks# vim sa1.yaml
apiVersion: v1
kind: ServiceAccount
automountServiceAccountToken: false # 新增,以后凡是使用这个sa1的pod,都不自动挂载token
metadata:
creationTimestamp: null
name: sa1
root@vms81:~/cks# vim pod1.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: web1
name: web1
spec:
serviceAccount: sa1 # pod指定sa1
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: web1
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
实践-管理RBAC权限
- 在实际使用时,无论是 kubernetes 的 Dashboard 还是其他方式操作 kubernetes 集群的资源,其所做的主要工作无非就是增删改查,对非 kubernetes 管理人员进行授权,权限一般不会太高,并且大部分情况下可授予相同的权限。
- 比如查看某个 Namespace 下 Pod 的日志或在 Pod 中执行命令,此类权限是统一的,只不过是授权到不同的 Serviceaccount,所以可以使用 ClusterRole 定义一些权限‘模板’,然后使用 Rolebinding 绑定到指定 Serviceaccount 即可
创建一个 kube-users 命令空间,用于统一存放 Serviceaccount 便于管理维护
1. 创建 kube-users
[root@vms120 11]# kubectl create ns kube-users
namespace/kube-users created
将 kubernetes 自带的 kube-system 当作一个项目,在 kube-users 命名空间下创建一个同名的 Serviceaccount
2. 创建 Serviceaccount
[root@vms120 11]# kubectl create sa -n kube-users kube-system
serviceaccount/kube-system created
[root@vms120 11]# kubectl get sa -n kube-users
NAME SECRETS AGE
default 1 3m15s
kube-system 1 11s
对于相同的权限可以使用 ClusterRole 进行配置,然后使用 RoleBinding 绑定到指定的 User、Group或者 Serviceaccount
3. 全局权限配置
# 配置全局Namespace 只读权限
[root@vms120 11]# cat ns-readonly.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: namespace-readonly
rules:
- apiGroups:
- ""
resources: ["namespaces"]
verbs: ["get", "list","watch"]
- apiGroups:
- metrics.k8s.io
resources: ["pods"]
verbs: ["get", "list","watch"]
[root@vms120 11]# cat pod-exec-cr.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: pod-exec
rules:
- apiGroups:
- ""
resources: ["pods","pods/log"]
verbs: ["get", "list"]
- apiGroups:
- ""
resources: ["pods/exec"]
verbs: ["create"]
首先使用 ClusterRoleBinding 将查看 Namespace 列表的权限授权给 kube-users 命名空间下所有的 ServiceAccount,这样在 kube-users 命名空间下的用户就有了查看 Namespace 列表的权限
[root@vms120 11]# kubectl create clusterrolebinding namespace-readonly --clusterrole=namespace-readonly --group=system:serviceaccount:kube-users
clusterrolebinding.rbac.authorization.k8s.io/namespace-readonly created
[root@vms120 11]# kubectl describe clusterrolebindings.rbac.authorization.k8s.io namespace-readonly
Name: namespace-readonly
Labels: <none>
Annotations: <none>
Role:
Kind: ClusterRole
Name: namespace-readonly
Subjects:
Kind Name Namespace
---- ---- ---------
Group system:serviceaccount:kube-users
之后使用 RoleBinding 将 Pod 的相关收钱给指定用户
[root@vms120 11]# kubectl create clusterrolebinding sa-kube-system-pod-exec --clusterrole=pod-exec --serviceaccount=kube-users:kube-system --namespace=kube-system
clusterrolebinding.rbac.authorization.k8s.io/sa-kube-system-pod-exec created
在创建的 sa 后,会自动创建一个以 sa 名称开头的 secret
[root@vms120 11]# kubectl get sa -n kube-users kube-system -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: "2022-10-12T05:58:09Z"
name: kube-system
namespace: kube-users
resourceVersion: "1377071"
selfLink: /api/v1/namespaces/kube-users/serviceaccounts/kube-system
uid: 487a20a0-0adb-4f40-8592-7a1570c809cb
secrets:
- name: kube-system-token-9hn4t
可以通过 secret kube-system-token-9hn4t 找到改 sa 的 token
[root@vms120 11]# kubectl -n kube-users get secrets $(kubectl -n kube-users get secret|grep kube-system-token-9hn4t | awk '{print $1}') -o go-template='{{.data.token}}' | base64 -d
eyJhbGciOiJSUzI1NiIsImtpZCI6Ik9IcC1TVENBZmhpNmYxMkdWUDFCangzSmhpSE9WLWg3a3BpaURJWVRlancifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXVzZXJzIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6Imt1YmUtc3lzdGVtLXRva2VuLTlobjR0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6Imt1YmUtc3lzdGVtIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiNDg3YTIwYTAtMGFkYi00ZjQwLTg1OTItN2ExNTcwYzgwOWNiIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmUtdXNlcnM6a3ViZS1zeXN0ZW0ifQ.Ink_pZ8iNd1sr12NHMRCxyz2AzHqgUW1SkEe7c7_h1hN4Ahq7Ei36061RV-TYsYclboo0_cJhRRKX6d2BFxNOJp6aWVkRi_ZdCyxQy0hyxuQxe1ugAzb0721o_wCjWDWKygUZbGnPoxFoYTjXnW_6tMhS6qpGvw3pM52SOnRd5ap6SuDaHki9isyrxGi-zhSm97o2RMfukF123AFNDGYOQEnaZxg-t63qo6QXAP_j9UPL2_Q0z9xbVZJrDKfV5EiPRyc2sAskedw1zL9kQeqqFeSaZrIzacL2d3NefHfvcNyfxA6GrR2alkj78stKdfT_dN5rsGUqQlqsjdSLzpOsQ
此 token 可以登入 Dashboard 并拥有执行容器命令的权限。
更多推荐
已为社区贡献11条内容
所有评论(0)