CKS-集群的强化-Kubernetes API的访问

集群的强化

通过设置提高集群的安全性

 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 59 16:05 john.csr
-rw-r--r-- 1 root root 1675 59 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

授权的方式主要有

  1. RBAC # 不管在什么情况下,授权方式都要选择RBAC
  2. NODE # worker 向 master 查询数据 # 必须和 -
    –enable-admission-plugins=NodeRestriction 准入控制器必须一起开启
  3. Webhook
  4. ABAC # 不要使用ABAC,使用RABAC
  5. AlwaysAllow # 总是允许
  6. 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 挂载到容器**

有两种方法

  1. 从pod层面来实现
  2. 从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 并拥有执行容器命令的权限。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一些可能出现在CKS考试中的真题,以及对应的详细答案: 1. 如何禁用Kubernetes API Server的匿名访问? 答:可以通过修改Kubernetes API Server的配置文件来禁用匿名访问。具体方法如下: 在Kubernetes API Server的配置文件中添加以下选项: ``` - --anonymous-auth=false ``` 然后重新启动Kubernetes API Server即可。 2. 如何配置Kubernetes API Server使用TLS证书进行双向认证? 答:可以通过修改Kubernetes API Server的配置文件来配置TLS证书进行双向认证。具体方法如下: 首先,生成CA证书和服务器证书: ``` $ openssl genrsa -out ca.key 2048 $ openssl req -new -key ca.key -out ca.csr $ openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt $ openssl genrsa -out server.key 2048 $ openssl req -new -key server.key -out server.csr $ openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -out server.crt ``` 然后,在Kubernetes API Server的配置文件中添加以下选项: ``` - --tls-cert-file=server.crt - --tls-private-key-file=server.key - --client-ca-file=ca.crt - --tls-cert-file=server.crt - --tls-private-key-file=server.key ``` 最后,重新启动Kubernetes API Server即可。 3. 如何为Kubernetes Pod中的应用程序提供安全的服务发现? 答:可以通过使用Kubernetes的Service来为Pod中的应用程序提供安全的服务发现。具体方法如下: 首先,创建一个Service,并将其类型设置为ClusterIP: ``` apiVersion: v1 kind: Service metadata: name: my-service spec: type: ClusterIP ports: - name: http port: 80 targetPort: 8080 ``` 然后,在Pod的配置文件中添加以下环境变量: ``` env: - name: MY_SERVICE_HOST value: my-service - name: MY_SERVICE_PORT value: "80" ``` 这样,在Pod中就可以通过访问MY_SERVICE_HOST和MY_SERVICE_PORT来访问Service提供的服务了。 4. 如何保护Kubernetes Pod中的敏感信息? 答:可以通过使用Kubernetes的Secret来保护Pod中的敏感信息。具体方法如下: 首先,创建一个Secret对象,并将需要保护的密钥和值存储在其中: ``` apiVersion: v1 kind: Secret metadata: name: my-secret type: Opaque data: username: dXNlcm5hbWU= password: cGFzc3dvcmQ= ``` 接着,在Pod的配置文件中使用该Secret: ``` apiVersion: v1 kind: Pod metadata: name: my-pod spec: containers: - name: my-container image: my-image env: - name: DB_USERNAME valueFrom: secretKeyRef: name: my-secret key: username - name: DB_PASSWORD valueFrom: secretKeyRef: name: my-secret key: password ``` 这样,在Pod中就可以通过访问DB_USERNAME和DB_PASSWORD来访问Secret中存储的敏感信息了。 5. 如何检查Kubernetes集群中的Pod是否使用了最新的安全补丁? 答:可以通过使用Kubernetes的SecurityContext来检查Pod是否使用了最新的安全补丁。具体方法如下: 首先,在Pod的配置文件中添加以下SecurityContext: ``` securityContext: runAsNonRoot: true readOnlyRootFilesystem: true allowPrivilegeEscalation: false ``` 然后,在容器中运行以下命令: ``` apt-get update apt-get upgrade ``` 这样就可以检查Pod中的容器是否使用了最新的安全补丁。 6. 如何限制用户在Kubernetes集群中的访问权限? 答:可以通过使用Kubernetes的Role和RoleBinding来限制用户在Kubernetes集群中的访问权限。具体方法如下: 首先,创建一个Role对象,指定该对象可以访问的资源和操作: ``` apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: my-role rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "watch", "list"] ``` 接着,创建一个RoleBinding对象,将该Role对象绑定到指定的用户或组: ``` apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: my-role-binding subjects: - kind: User name: my-user roleRef: kind: Role name: my-role apiGroup: rbac.authorization.k8s.io ``` 这样,用户my-user就可以访问该Role对象指定的资源和操作了。 7. 如何配置Kubernetes集群的网络策略以保护Pod之间的通信? 答:可以通过使用Kubernetes的NetworkPolicy来配置网络策略以保护Pod之间的通信。具体方法如下: 首先,创建一个NetworkPolicy对象,指定该对象可以访问的Pod标签和端口: ``` apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: my-network-policy spec: podSelector: matchLabels: app: my-app ingress: - from: - podSelector: matchLabels: role: my-role ports: - protocol: TCP port: 80 ``` 然后,在Pod的配置文件中添加以下标签: ``` metadata: labels: app: my-app role: my-role ``` 这样,只有包含标签app=my-app且来自Pod标签为role=my-role的流量才可以访问Pod。 8. 如何为Kubernetes集群中的节点和Pod提供安全的存储? 答:可以通过使用Kubernetes的StorageClass和PersistentVolumeClaim来为集群中的节点和Pod提供安全的存储。具体方法如下: 首先,创建一个StorageClass对象,指定该对象可以使用的存储类型和访问模式: ``` apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: my-storage-class provisioner: my-provisioner parameters: type: my-type accessMode: ReadWriteOnce ``` 然后,在Pod的配置文件中创建一个PersistentVolumeClaim对象,用于申请存储: ``` apiVersion: v1 kind: PersistentVolumeClaim metadata: name: my-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi storageClassName: my-storage-class ``` 这样,Pod就可以通过挂载PersistentVolumeClaim来访问安全的存储了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值