Kubernetes精讲之认证授权

目录

一 kubernetes API 访问控制

1.1 UserAccount与ServiceAccount

1.1.1 ServiceAccount

1.1.2 ServiceAccount示例:

二 认证(在k8s中建立认证用户)

2.1 创建UserAccount

2.2 RBAC(Role Based Access Control)

2.2.1 基于角色访问控制授权:

2.2.2 role授权实施

2.2.3 clusterrole授权实施

2.2.4 服务账户的自动化


一 kubernetes API 访问控制

Authentication(认证)

  • 认证方式现共有8种,可以启用一种或多种认证方式,只要有一种认证方式通过,就不再进行其它方式的认证。通常启用X509 Client Certs和Service Accout Tokens两种认证方式。
  • Kubernetes集群有两类用户:由Kubernetes管理的Service Accounts (服务账户)和(Users Accounts) 普通账户。k8s中账号的概念不是我们理解的账号,它并不真的存在,它只是形式上存在。

Authorization(授权)

  • 必须经过认证阶段,才到授权请求,根据所有授权策略匹配请求资源属性,决定允许或拒绝请求。授权方式现共有6种,AlwaysDeny、AlwaysAllow、ABAC、RBAC、Webhook、Node。默认集群强制开启RBAC。

Admission Control(准入控制)

  • 用于拦截请求的一种方式,运行在认证、授权之后,是权限认证链上的最后一环,对请求API资源对象进行修改和校验。

1.1 UserAccount与ServiceAccount

  • 用户账户是针对人而言的。 服务账户是针对运行在 pod 中的进程而言的。
  • 用户账户是全局性的。 其名称在集群各 namespace 中都是全局唯一的,未来的用户资源不会做 namespace 隔离, 服务账户是 namespace 隔离的。
  • 集群的用户账户可能会从企业数据库进行同步,其创建需要特殊权限,并且涉及到复杂的业务流程。 服务账户创建的目的是为了更轻量,允许集群用户为了具体的任务创建服务账户 ( 即权限最小化原则 )。

1.1.1 ServiceAccount

  • 服务账户控制器(Service account controller)
    • 服务账户管理器管理各命名空间下的服务账户
    • 每个活跃的命名空间下存在一个名为 “default” 的服务账户
  • 服务账户准入控制器(Service account admission controller)
    • 相似pod中 ServiceAccount默认设为 default。
    • 保证 pod 所关联的 ServiceAccount 存在,否则拒绝该 pod。
    • 如果pod不包含ImagePullSecrets设置那么ServiceAccount中的ImagePullSecrets 被添加到pod中
    • 将挂载于 /var/run/secrets/kubernetes.io/serviceaccount 的 volumeSource 添加到 pod 下的每个容器中
    • 将一个包含用于 API 访问的 token 的 volume 添加到 pod 中

1.1.2 ServiceAccount示例:

建立名字为admin的ServiceAccount

[root@K8s-master ~]# kubectl create sa haha
serviceaccount/haha created
[root@K8s-master ~]# kubectl create sa haha
serviceaccount/haha created
[root@K8s-master ~]# kubectl describe  sa haha
Name:                haha
Namespace:           default
Labels:              <none>
Annotations:         <none>
Image pull secrets:  <none>
Mountable secrets:   <none>
Tokens:              <none>
Events:              <none>

建立secrets

[root@K8s-master ~]# kubectl create secret docker-registry docker-login --docker-username admin --docker-password redhat --docker-server reg.harbor.org --docker-email haha@harbor.org

[root@K8s-master ~]# kubectl describe secrets docker-login
Name:         docker-login
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  kubernetes.io/dockerconfigjson

Data
====
.dockerconfigjson:  121 bytes

将secrets注入到sa中

[root@K8s-master ~]# kubectl edit sa haha 
apiVersion: v1
imagePullSecrets:
- name: docker-login
kind: ServiceAccount
metadata:
  creationTimestamp: "2024-09-10T16:56:03Z"
  name: haha
  namespace: default
  resourceVersion: "262633"
  uid: 9a784d89-879c-4b8e-b4f9-2c87eac3e336


#查看sa发现资源已经注入
[root@K8s-master ~]# kubectl describe  sa haha
Name:                haha
Namespace:           default
Labels:              <none>
Annotations:         <none>
Image pull secrets:  docker-login
Mountable secrets:   <none>
Tokens:              <none>
Events:              <none>

建立私有仓库并且利用pod访问私有仓库

[root@K8s-master ~]# vim example1.yml
apiVersion: v1
kind: Pod
metadata:
  name: testpod
spec:
  containers:
  - image: reg.harbor.org/zhang/nginx:latest
    name: testpod

[root@K8s-master ~]# kubectl apply -f example1.yml

#无法成功
[root@K8s-master ~]# kubectl get pod
NAME      READY   STATUS              RESTARTS   AGE
testpod   0/1     ContainerCreating   0          28s

[root@k8s-master auth]# vim example1.yml
[root@k8s-master auth]# kubectl apply -f example1.yml
pod/testpod created
[root@k8s-master auth]# kubectl describe pod testpod
 Warning  Failed     5s               kubelet            Failed to pull image "reg.timinglee.org/lee/nginx:latest": Error response from daemon: unauthorized: unauthorized to access repository: lee/nginx, action: pull: unauthorized to access repository: lee/nginx, action: pull
  Warning  Failed     5s               kubelet            Error: ErrImagePull
  Normal   BackOff    3s (x2 over 4s)  kubelet            Back-off pulling image "reg.timinglee.org/lee/nginx:latest"
  Warning  Failed     3s (x2 over 4s)  kubelet            Error: ImagePullBackOff

在创建pod时会镜像下载会受阻,因为docker私有仓库下载镜像需要认证

pod绑定sa

[root@K8s-master ~]# vim example1.yml
apiVersion: v1
kind: Pod
metadata:
  name: testpod
spec:
  serviceAccountName: haha
  containers:
  - image: reg.harbor.org/zhang/nginx:latest
    name: testpod

[root@K8s-master ~]# kubectl apply -f example1.yml
pod/testpod created

[root@K8s-master ~]# kubectl get pods
NAME      READY   STATUS    RESTARTS   AGE
testpod   1/1     Running   0          2s

二 认证(在k8s中建立认证用户)

2.1 创建UserAccount

#建立证书
[root@k8s-master auth]# cd /etc/kubernetes/pki/
[root@K8s-master pki]# openssl genrsa -out zhang.key 2048
[root@K8s-master pki]# openssl req  -new -key zhang.key -out zhang.csr -subj "/CN=zhang"

[root@K8s-master pki]# openssl x509 -req  -in zhang.csr -CA ca.crt -CAkey ca.key -CAcreateserial  -out zhang.crt -days 365
Certificate request self-signature ok
subject=CN = zhang

#查看证书
[root@K8s-master pki]# openssl x509 -in zhang.crt -text -noout
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            25:cc:3c:16:19:c0:f1:76:1e:d0:9c:94:b1:66:41:21:53:f7:eb:8f
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN = kubernetes
        Validity
            Not Before: Sep 10 17:25:36 2024 GMT
            Not After : Sep 10 17:25:36 2025 GMT
        Subject: CN = zhang
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:8f:63:e4:f4:2c:a2:fc:8c:c6:cc:8b:54:6d:32:
                    63:39:df:04:d7:33:78:21:8a:6c:24:ac:96:41:b7:
                    c0:93:bc:a9:ac:4f:a7:00:a4:f7:dd:ed:9b:6e:da:
                    40:0b:81:82:52:51:9e:2c:9b:82:fc:ea:c6:9d:32:
                    d8:28:21:04:82:a9:2a:5b:51:fc:ab:c6:4f:d3:c5:
                    cf:69:ec:d3:9b:b8:7d:85:93:8b:76:f2:a2:5c:cc:
                    41:e4:7d:98:d7:d4:dc:6e:d4:29:f8:07:24:24:43:
                    40:e5:08:a7:41:75:5e:eb:ff:3e:4f:f0:2a:3d:76:
                    e7:e0:26:57:4a:1a:cf:13:8a:21:1c:9c:9b:a3:f9:
                    4c:fe:a3:84:b1:c3:a4:0b:fd:79:9c:1d:31:db:ff:
                    e0:af:19:6a:42:67:ce:a0:51:05:a1:f5:c7:22:1c:
                    32:ea:8f:94:4f:c0:8c:6f:85:e7:66:d2:cb:93:dd:
                    e7:a4:99:7a:f2:fa:dc:98:ed:93:f2:b9:59:1d:95:
                    d2:be:e2:18:12:73:91:8f:a4:69:c0:42:9e:16:d6:
                    cc:fb:87:a3:36:19:40:65:13:1d:46:8f:5a:48:5c:
                    fe:a6:94:91:6f:ee:36:c7:77:bc:0c:7e:1a:8c:39:
                    ea:ba:7c:cc:91:79:dd:8b:68:2b:37:84:44:00:4d:
                    71:e5
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha256WithRSAEncryption
    Signature Value:
        8b:a4:35:f1:3a:46:13:b4:c3:d6:b6:8b:6a:91:4f:8d:05:4a:
        49:d7:aa:77:a2:99:f4:0d:5b:b3:f3:17:4d:74:ba:ec:2e:f3:
        bc:88:a2:7e:41:c5:ea:cc:17:85:dd:42:d0:2e:2d:6b:be:f1:
        e9:ae:cd:ae:7f:16:ec:f0:56:19:27:3f:ca:44:dc:bf:ff:70:
        1a:92:14:80:48:e4:bb:32:04:41:dd:fc:38:84:5e:d0:d8:85:
        1c:dd:0f:51:e6:19:4b:cb:d7:44:cc:84:4c:d1:bb:58:b2:71:
        21:ad:99:68:af:5b:c0:60:56:ce:8f:ae:06:b9:37:2c:96:48:
        d2:28:ec:95:1b:55:36:59:94:b6:76:95:ad:2b:ac:4e:88:70:
        d7:ed:dc:50:44:85:83:33:f9:3d:05:95:da:5c:35:07:63:5e:
        10:09:82:5c:87:bc:6f:cb:48:d6:56:71:d3:ba:1e:35:d0:d9:
        94:37:23:e3:38:15:54:0d:00:28:eb:96:ab:57:9a:b6:2a:a7:
        f5:e5:51:df:05:3d:00:30:6a:08:dc:48:66:bf:d1:d1:32:e4:
        0b:e9:62:cd:bd:b9:bf:12:3e:13:ef:67:1b:91:11:a7:d9:de:
        b5:fb:df:b0:72:70:28:60:cb:4e:7a:fa:79:b4:50:d9:df:09:
        c1:83:db:21


[root@K8s-master pki]# ls
apiserver.crt                 ca.key                  sa.key
apiserver-etcd-client.crt     ca.srl                  sa.pub
apiserver-etcd-client.key     etcd                    zhang.crt
apiserver.key                 front-proxy-ca.crt      zhang.csr
apiserver-kubelet-client.crt  front-proxy-ca.key      zhang.key
apiserver-kubelet-client.key  front-proxy-client.crt
ca.crt                        front-proxy-client.key

#建立k8s中的用户
[root@K8s-master pki]# kubectl config set-credentials zhang --client-certificate /etc/kubernetes/pki/zhang.crt --client-key /etc/kubernetes/pki/zhang.key --embed-certs=true
User "zhang" set.
#set-credentials是设置用户的名字,--embed-certs=true表示要把动作写到配置文件中

#查看用户
[root@K8s-master pki]# kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://172.25.254.100: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: DATA+OMITTED
    client-key-data: DATA+OMITTED
- name: zhang
  user:
    client-certificate-data: DATA+OMITTED
    client-key-data: DATA+OMITTED

#设置用户集群的安全上下文
[root@K8s-master pki]# kubectl config set-context zhang@kubernetes --cluster kubernetes --user zhang
Context "zhang@kubernetes" created.

#切换用户,用户在集群中只有用户身份没有授权
[root@K8s-master pki]# kubectl config use-context zhang@kubernetes
Switched to context "zhang@kubernetes".
[root@K8s-master pki]# kubectl get pods
Error from server (Forbidden): pods is forbidden: User "zhang" cannot list resource "pods" in API group "" in the namespace "default"

#切换会集群管理
[root@k8s-master ~]# kubectl config use-context kubernetes-admin@kubernetes
Switched to context "kubernetes-admin@kubernetes".

#如果需要删除用户
[root@k8s-master pki]# kubectl config delete-user zhang
deleted user zhang from /etc/kubernetes/admin.conf

#建立k8s中的用户
[root@k8s-master pki]# kubectl config set-credentials timinglee --client-certificate /etc/kubernetes/pki/timinglee.crt --client-key /etc/kubernetes/pki/timinglee.key --embed-certs=true
User "timinglee" set.

[root@k8s-master pki]# kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://172.25.254.100: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: DATA+OMITTED
    client-key-data: DATA+OMITTED
- name: timinglee
  user:
    client-certificate-data: DATA+OMITTED
    client-key-data: DATA+OMITTED

#切换用户,用户在集群中只有用户身份没有授权
[root@k8s-master ~]# kubectl config use-context timinglee@kubernetes
Switched to context "timinglee@kubernetes".
[root@k8s-master ~]# kubectl get pods
Error from server (Forbidden): pods is forbidden: User "timinglee" cannot list resource "pods" in API group "" in the namespace "default"

#切换会集群管理
[root@k8s-master ~]# kubectl config use-context kubernetes-admin@kubernetes
Switched to context "kubernetes-admin@kubernetes".

#如果需要删除用户
[root@k8s-master pki]# kubectl config delete-user timinglee
deleted user timinglee from /etc/kubernetes/admin.conf

2.2 RBAC(Role Based Access Control)

2.2.1 基于角色访问控制授权:

  • 允许管理员通过Kubernetes API动态配置授权策略。RBAC就是用户通过角色与权限进行关联。
  • RBAC只有授权,没有拒绝授权,所以只需要定义允许该用户做什么即可
  • RBAC的三个基本概念
    • Subject:被作用者,它表示k8s中的三类主体, user, group, serviceAccount
  • Role:角色,它其实是一组规则,定义了一组对 Kubernetes API 对象的操作权限。
  • RoleBinding:定义了“被作用者”和“角色”的绑定关系
  • RBAC包括四种类型:Role、ClusterRole、RoleBinding、ClusterRoleBinding
  • Role 和 ClusterRole
    • Role是一系列的权限的集合,Role只能授予单个namespace (命名空间)中资源的访问权限。
  • ClusterRole 跟 Role 类似,但是可以在集群中全局使用。
  • Kubernetes 还提供了四个预先定义好的 ClusterRole 来供用户直接使用
  • cluster-amdin、admin、edit、view
2.2.2 role授权实施
#注意:要先切换为管理员用户
[root@K8s-master ~]# mkdir rbac
[root@K8s-master ~]# cd rbac
#verb=get为权限可以看,resource pods设置为可以看pods
[root@K8s-master rbac]#  kubectl create role myrole --dry-run=client --verb=get --resource pods -o yaml > myrole.yml
[root@K8s-master rbac]# vim myrole.yml 
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: myrole
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get    #查看
  - watch   #监控
  - list    #列出
  - create
  - update    #更新
  - path
  - delete

#创建role
root@K8s-master rbac]# kubectl apply -f  myrole.yml
role.rbac.authorization.k8s.io/myrole created
[root@K8s-master rbac]# kubectl describe role myrole
Name:         myrole
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  pods       []                 []              [get watch list create update path delete]

#建立角色绑定
[root@K8s-master rbac]# kubectl create rolebinding rolebinding-myrole --role myrole --namespace default --user zhang --dry-run=client -o yaml  > rolebinding-myrole.yml
[root@K8s-master rbac]# vim rolebinding-myrole.yml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: rolebinding-myrole
  namespace: default     #角色绑定必须指定namespace
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: myrole
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: zhang

[root@K8s-master rbac]# kubectl apply -f rolebinding-myrole.yml
rolebinding.rbac.authorization.k8s.io/rolebinding-myrole created

[root@K8s-master rbac]# kubectl get rolebindings.rbac.authorization.k8s.io rolebinding-myrole 
NAME                 ROLE          AGE
rolebinding-myrole   Role/myrole   26s

#切换用户测试授权
[root@K8s-master rbac]# kubectl config use-context zhang@kubernetes
Switched to context "zhang@kubernetes".

[root@K8s-master rbac]# kubectl get pods
NAME      READY   STATUS    RESTARTS   AGE
test      1/1     Running   0          8h
testpod   1/1     Running   0          8h

[root@K8s-master rbac]# kubectl get svc   #只针对pod进行了授权,所以svc依然不能操作
Error from server (Forbidden): services is forbidden: User "zhang" cannot list resource "services" in API group "" in the namespace "default"

[root@K8s-master rbac]# kubectl config use-context kubernetes-admin@kubernetes
Switched to context "kubernetes-admin@kubernetes".
[root@K8s-master rbac]# 

2.2.3 clusterrole授权实施
#建立集群角色
[root@K8s-master rbac]# kubectl create clusterrole myclusterrole --resource=deployment --verb get --dry-run=client -o yaml > myclusterrole.yml
[root@K8s-master rbac]# vim myclusterrole.yml 
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: myclusterrole
rules:
- apiGroups:
  - apps
  resources:
  - deployments
  verbs:
  - get
  - list
  - watch
  - create
  - update
  - path
  - delete
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
  - watch
  - create
  - update
  - path
  - delete

[root@K8s-master rbac]# kubectl apply -f myclusterrole.yml 
clusterrole.rbac.authorization.k8s.io/myclusterrole created

[root@K8s-master rbac]# kubectl describe clusterrole myclusterrole
Name:         myclusterrole
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources         Non-Resource URLs  Resource Names  Verbs
  ---------         -----------------  --------------  -----
  pods              []                 []              [get list watch create update path delete]
  deployments.apps  []                 []              [get list watch create update path delete]


#建立集群角色绑定
[root@K8s-master rbac]# kubectl create clusterrolebinding  clusterrolebind-myclusterrole --clusterrole myclusterrole  --user zhang --dry-run=client -o yaml > clusterrolebind-myclusterrole.yml
[root@k8s-master rbac]# vim clusterrolebind-myclusterrole.yml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: clusterrolebind-myclusterrole
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: myclusterrole
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: zhang

[root@K8s-master rbac]# kubectl apply -f clusterrolebind-myclusterrole.yml 
clusterrolebinding.rbac.authorization.k8s.io/clusterrolebind-myclusterrole created
[root@K8s-master rbac]# kubectl describe clusterrolebindings.rbac.authorization.k8s.io clusterrolebind-myclusterrole
Name:         clusterrolebind-myclusterrole
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  ClusterRole
  Name:  myclusterrole
Subjects:
  Kind  Name   Namespace
  ----  ----   ---------
  User  zhang  

#切换角色
[root@K8s-master rbac]# kubectl config use-context zhang@kubernetes
Switched to context "zhang@kubernetes".


#测试:
[root@k8s-master rbac]# kubectl get pods  -A
[root@k8s-master rbac]# kubectl get deployments.apps -A
[root@k8s-master rbac]# kubectl get svc -A
Error from server (Forbidden): services is forbidden: User "timinglee" cannot list resource "services" in API group "" at the cluster scope

2.2.4 服务账户的自动化

服务账户准入控制器(Service account admission controller)

  • 如果该 pod 没有 ServiceAccount 设置,将其 ServiceAccount 设为 default。
  • 保证 pod 所关联的 ServiceAccount 存在,否则拒绝该 pod。
  • 如果 pod 不包含 ImagePullSecrets 设置,那么 将 ServiceAccount 中的 ImagePullSecrets 信息添加到 pod 中。
  • 将一个包含用于 API 访问的 token 的 volume 添加到 pod 中。
  • 将挂载于 /var/run/secrets/kubernetes.io/serviceaccount 的 volumeSource 添加到 pod 下的每个容器中。

服务账户控制器(Service account controller)

服务账户管理器管理各命名空间下的服务账户,并且保证每个活跃的命名空间下存在一个名为 “default” 的服务账户

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值