k8s-API 访问控制

目录

[一 kubernetes API 访问控制](#一 kubernetes API 访问控制)

[1.1 UserAccount与ServiceAccount](#1.1 UserAccount与ServiceAccount)

[1.1.1 ServiceAccount](#1.1.1 ServiceAccount)

[1.1.2 ServiceAccount示例:](#1.1.2 ServiceAccount示例:)

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

[2.1 创建UserAccount](#2.1 创建UserAccount)

[2.2 RBAC(Role Based Access Control)](#2.2 RBAC(Role Based Access Control))

[2.2.1 基于角色访问控制授权:](#2.2.1 基于角色访问控制授权:)

[2.2.2 role授权实施](#2.2.2 role授权实施)

[2.2.3 clusterrole授权实施](#2.2.3 clusterrole授权实施)

[2.2.4 服务账户的自动化](#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 howe
serviceaccount/howe created

[root@k8s-master ~]# kubectl get sa
NAME      SECRETS   AGE
default   0         7d9h
howe      0         24m

[root@k8s-master ~]# kubectl describe sa howe 
Name:                howe
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.exam.com --docker-email howe@howe.com
secret/docker-login created

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

Type:  kubernetes.io/dockerconfigjson

Data
====
.dockerconfigjson:  117 bytes

将secrets注入到sa中

[root@k8s-master ~]# kubectl edit sa howe
apiVersion: v1
imagePullSecrets:			#注入
- name: docker-login		#
kind: ServiceAccount
metadata:
  creationTimestamp: "2024-09-10T12:10:28Z"
  name: howe
  namespace: default
  resourceVersion: "329362"
  uid: 94fb5724-b7fd-4464-841a-97cb01b802d1
  
[root@k8s-master ~]# kubectl describe sa howe
Name:                howe
Namespace:           default
Labels:              <none>
Annotations:         <none>
Image pull secrets:  docker-login
Mountable secrets:   <none>
Tokens:              <none>
Events:              <none>

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

#已经建立名为api的仓库	上传nginx镜像
[root@k8s-master ~]# docker tag nginx:latest reg.exam.com/api/nginx
[root@k8s-master ~]# docker push reg.exam.com/api/nginx

[root@k8s-master ~]# kubectl run testpod --image api/nginx
pod/testpod created

[root@k8s-master ~]# kubectl describe sa default 
Name:                default
Namespace:           default
Labels:              <none>
Annotations:         <none>
Image pull secrets:  <none>
Mountable secrets:   <none>
Tokens:              <none>
Events:              <none>

#如果显示为未拉取 是因为认证未通过 未将secrets注入到sa中
[root@k8s-master ~]# kubectl get pods 
NAME		READY   	STATUS    			RESTARTS      AGE
testpod		0/1     	ImagePullBackOff 	 0             25s

#如果认证通过 会显示running
[root@k8s-master ~]# kubectl get pods 
NAME                        READY   STATUS    RESTARTS      AGE
testpod                     1/1     Running   0             25s

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

pod绑定sa

[root@k8s-master auth]# vim example1.yml
apiVersion: v1
kind: Pod
metadata:
  name: testpod
spec:
  serviceAccountName: howe			#指定了这个 Pod 要使用的服务账号为 howe
  containers:
  - image: reg.exam.com/api/nginx:latest	#制定私有仓库
    name: testpod
    
[root@k8s-master auth]# kubectl apply -f example1.yml 
pod/testpod created

[root@k8s-master auth]# kubectl get pods 
NAME                        READY   STATUS    RESTARTS      AGE
testpod                     1/1     Running   0             11s

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

2.1 创建UserAccount

#建立证书
[root@k8s-master auth]# cd /etc/kubernetes/pki/
[root@k8s-master pki]# openssl genrsa -out howe.key 2048	#建立key

[root@k8s-master pki]# openssl req -new -key howe.key -out howe.csr -subj "/CN=superhowe"
#openssl req -new:表示生成一个新的证书签名请求。
-key howe.key:指定用于生成 CSR 的私钥文件为 howe.key。
-out howe.csr:指定输出的 CSR 文件为 howe.csr。
-subj "/CN=superhowe":设置证书的主题,这里指定通用名称(Common Name)为 superhowe

#生成证书
[root@k8s-master pki]# openssl x509 -req  -in howe.csr -CA ca.crt -CAkey ca.key -CAcreateserial  -out howe.crt -days 365
Certificate request self-signature ok
subject=CN = superhowe

#查看证书
[root@k8s-master pki]# openssl x509 -in howe.crt -text -noout

建立k8s中的用户

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

#补充参数 --embed-certs=true
[root@k8s-master pki]# cat ~/.bash_profile 
export KUBECONFIG=/etc/kubernetes/admin.conf
表示将证书嵌入到配置中,这样配置文件可以更加自包含,无需依赖外部的证书文件


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

切换用户,用户在集群中只有用户身份没有授权

#切换 Kubernetes 上下文到名为 howe@kubernetes 的上下文
[root@k8s-master pki]# kubectl config use-context howe@kubernetes
error: no context exists with the name: "howe@kubernetes"

#以上报错不存在  需要先设置上下文
[root@k8s-master pki]# kubectl config set-context howe@kubernetes --cluster kubernetes --user howe
Context "howe@kubernetes" created.

[root@k8s-master pki]# kubectl config use-context howe@kubernetes
Switched to context "howe@kubernetes".

#只通过认证 并未集群授权
[root@k8s-master pki]# kubectl get pods 
Error from server (Forbidden): pods is forbidden: User "superhowe" cannot list resource "pods" in API group "" in the namespace "default"

切换会集群管理

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

如果需要删除用户

[root@k8s-master pki]# kubectl config delete-user howe 
deleted user howe 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授权实施

生成role的yaml文件

[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:
  creationTimestamp: null
  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 howe --role myrole --namespace default --user howe --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: howe
  namespace: default				#角色绑定必须指定namespace
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: myrole
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: howe
  
[root@k8s-master rbac]# kubectl apply -f rolebinding-myrole.yml 
rolebinding.rbac.authorization.k8s.io/howe created

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

切换用户测试授权

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

[root@k8s-master rbac]# kubectl get pods
No resources found in default namespace.

#只针对pod进行了授权,所以svc依然不能操作
[root@k8s-master rbac]# kubectl get svc
Error from server (Forbidden): services is forbidden: User "system:anonymous" 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".

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 howe --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: howe


[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  howe  

测试:

[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

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" 的服务账户

相关推荐
huaqianzkh21 分钟前
了解华为云容器引擎(Cloud Container Engine)
云原生·架构·华为云
Alone804630 分钟前
K8s中HPA自动扩缩容及hml
云原生·容器·kubernetes
神秘的土鸡1 小时前
Linux中使用Docker容器构建Tomcat容器完整教程
linux·运维·服务器·docker·容器·tomcat
玖石书1 小时前
docker 数据管理
docker·容器
星辰@Sea2 小时前
服务注册中心对比及使用场景分析
java·云原生
Alluxio官方3 小时前
Alluxio Enterprise AI on K8s 部署教程
人工智能·机器学习·kubernetes
shelby_loo4 小时前
通过 Docker 部署 WordPress 服务器
服务器·docker·容器
专家大圣6 小时前
云原生信息安全:筑牢数字化时代的安全防线
安全·云原生
方圆师兄7 小时前
docker快速搭建kafka
docker·容器·kafka