0
点赞
收藏
分享

微信扫一扫

AWS概述

pipu 2024-06-15 阅读 13

目录

引言

一、Kubernetes安全机制概述

二、认证机制

(一)认证方式

1.HTTPS证书认证

1.1 证书颁发

1.2 config文件

1.3 认证类型

1.4 Service Account

1.4.1 作用

1.4.2 包含内容

1.4.3 与Secret的关系

2.Bearer Tokens

3.基本认证

三、鉴权

(一)鉴权机制

1.基于RBAC

2.其它鉴权机制

(二)RBAC的API资源对象

1.Role(角色)

2.ClusterRole(集群角色)

3.RoleBinding(角色绑定)

4.ClusterRoleBinding(集群角色绑定)

5. 主体(subject)类型

5.1 User

5.2 Group

5.3 ServiceAccount

(三)创建角色及绑定

1.创建服务账号

2.创建Role

3.创建RoleBinding

4.创建pod

5.示例总结

四、准入控制

(一)准入控制器的工作流程

(二)准入控制器的类型

五、对用户的权限设置

(一)创建证书

1.获取工具

2.创建生成证书的配置文件

3.生成证书

(二)生成config文件

(三)RBAC授权

1.创建Role资源

2.Role绑定

(四)切换用户使用

1.创建pod

2.其它权限

3.获取管理员权限


引言

随着云计算和容器技术的蓬勃发展,Kubernetes(K8s)作为容器编排的领头羊,其安全性成为了众多企业和开发者关注的焦点。本文将详细解析Kubernetes的安全机制,包括认证、鉴权和准入控制,以确保集群的稳定性和数据的安全。

一、Kubernetes安全机制概述

Kubernetes的安全机制主要围绕三个核心组件:认证、鉴权和准入控制。认证是安全机制的第一道防线,负责确认请求者的身份;鉴权则是根据用户的身份和权限策略,确定其是否有权执行特定操作;最后,准入控制对API资源对象的修改和校验进行把关。

二、认证机制

(一)认证方式

1.HTTPS证书认证

HTTPS证书认证:基于CA(证书颁发机构)证书签名的数字证书认证。

适用于kube-apiserver、etcd、kubelet等组件之间的连接,确保通信的安全性。

当Pod在Kubernetes集群中启动时,Service Account通常会使用客户端证书进行身份验证。

1.1 证书颁发

手动签发:使用二进制部署时,需要先手动跟 CA 进行签发 HTTPS 证书

自动签发:kubelet 首次访问 API Server 时,使用 token 做认证,通过后,Controller Manager 会为 kubelet 生成一个证书, 以后的访问都是用证书做认证了

1.2 config文件
[root@master01 ~]#ll ~/.kube/config
-rw------- 1 root root 5565 5月  16 15:19 /root/.kube/config
#家目录下的.kube/config文件,用于存储用户的认证信息
#kubectl通过该文件的令牌信息,确定使用的用户,以及对应的权限
1.3 认证类型

注释:访问安全性要求

kubernetes中,API Server会启动8080端口(非安全端口)与6443端口(安全端口)

安全性:8080端口没有认证和授权检查,存在安全风险;而6443端口有TLS保护,更加安全。

用途:8080端口主要用于调试或内部通信;而6443端口是Kubernetes集群的官方通信端口,用于与外部工具和组件进行交互。

配置:两个端口的配置都可以通过apiserver的启动参数进行修改。在生产环境中,通常建议只开启6443端口,并确保其安全性。

1.4 Service Account
1.4.1 作用
1.4.2 包含内容

每个命名空间都有一个默认的ServiceAccount,如果用户不指定ServiceAccount,Pod将自动关联到该默认的ServiceAccount上。

1.4.3 与Secret的关系

当Service Account创建时,Kubernetes会自动为每个ServiceAccount创建一个与之关联的Secret,其中包含了ServiceAccount的身份令牌。

[root@master01 opt]#kubectl describe pod nginx
...... 
  Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-vgx6f (ro)
......

2.Bearer Tokens

令牌认证:用户或服务可以通过获取一个令牌(Token)并在请求中携带该令牌来进行身份验证。

在node节点加入master时,就需要令牌来进行连接

3.基本认证

HTTP Basic Auth:使用用户名和密码进行基本的HTTP认证。

在Kubernetes中,这种认证方式相对较少使用,因为它不如其他方式安全。

注释:Token 认证和 Base 认证方式只能进行服务端对客户端的单向认证,而客户端不知道服务端是否合法;而 HTTPS 证书认证方式 则可以实现双向认证。

三、鉴权

(一)鉴权机制

1.基于RBAC

Kubernetes的鉴权机制主要基于Role-Based Access Control(RBAC)实现。RBAC允许管理员定义角色(Role)和角色绑定(RoleBinding),以控制用户对资源的访问权限。角色定义了用户可以执行的操作和可以访问的资源,而角色绑定则将角色与用户或用户组进行关联。通过这种方式,管理员可以灵活地配置权限策略,确保只有授权用户才能执行特定操作。

2.其它鉴权机制

●AlwaysDeny:表示拒绝所有的请求,一般用于测试 
●AlwaysAllow:允许接收所有请求,如果集群不需要授权流程,则可以采用该策略,一般用于测试
●ABAC(Attribute-Based Access Control):基于属性的访问控制,表示使用用户配置的授权规则对用户请求进行匹配和控制。也就是说定义一个访问类型的属性,用户可以使用这个属性访问对应的资源。此方式设置较为繁琐,每次设置需要定义一长串的属性才可以。
●Webhook:通过调用外部 REST 服务对用户进行授权,即可在集群外部对K8S进行鉴权

(二)RBAC的API资源对象

1.Role(角色)

2.ClusterRole(集群角色)

3.RoleBinding(角色绑定)

4.ClusterRoleBinding(集群角色绑定)

5. 主体(subject)类型

在Kubernetes中,User、Group 和 ServiceAccount 都是安全认证和授权模型中的主体(subject)类型。这些主体代表了可以执行操作的实体,并且与特定的权限相关联

5.1 User
5.2 Group
5.3 ServiceAccount

(三)创建角色及绑定

1.创建服务账号

首先创建一个服务账号(Service Account)

[root@master01 rbac]#vim sa.yaml
[root@master01 rbac]#cat sa.yaml
apiVersion: v1
kind: Namespace          #创建命名空间
metadata:
  name: web              #指定命名空间名称
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: rbac-sa          #服务账号名称
  namespace: web         #所在命名空间
[root@master01 rbac]#kubectl apply -f sa.yaml 
namespace/web created
serviceaccount/rbac-sa created
[root@master01 rbac]#kubectl get serviceaccounts rbac-sa -n web 
NAME      SECRETS   AGE
rbac-sa   1         26s

2.创建Role

[root@master01 rbac]#cat role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: rbac-role
  namespace: web
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "watch", "list"]
[root@master01 rbac]#kubectl apply -f role.yaml
role.rbac.authorization.k8s.io/rbac-role created
[root@master01 rbac]#kubectl get role rbac-role -n web
NAME        CREATED AT
rbac-role   2024-06-05T16:07:54Z
------------------------------------------------------------------------------
apiGroups
apiGroups字段指定了资源所属的API群组。常用apiGroups的有

""(空字符串):核心API群组,例如Pods、Services、Endpoints等。
"apps":包含Deployments、StatefulSets、DaemonSets等应用相关的资源。
"batch":包含Jobs、CronJobs等资源。
"extensions":在旧版Kubernetes中用于某些beta API,但在新版中很多资源已经移至其他群组。
"networking.k8s.io":网络相关的资源,如Ingress。
"rbac.authorization.k8s.io":RBAC相关的资源,如Role、RoleBinding等。
----------------------------------------------------------------------------------
resources
resources字段列出了该角色可以访问的具体资源类型。这些资源类型必须是Kubernetes API中定义的。
以下是一些常见的资源类型示例:
pods
services
deployments
configmaps
secrets
ingresses
nodes(对于ClusterRole)
roles 或 rolebindings(对于ClusterRole,允许管理RBAC资源)
-----------------------------------------------------------------------------------
verbs
verbs字段定义了可以对资源执行的操作。以下是一些常用的verbs示例:

get:读取资源。
list:列出所有资源。
watch:观察资源的更改。
create:创建资源。
update:更新资源。
patch:部分更新资源。
delete:删除资源。
deletecollection:删除资源集合。
exec:在Pod中执行命令(通常与Pod资源一起使用)
------------------------------------------------------------------------------------

3.创建RoleBinding

[root@master01 rbac]#cat rolebind.yaml
apiVersion: rbac.authorization.k8s.io/v1  
kind: RoleBinding  
metadata:  
  name: rbac-rolebind
  namespace: web      #RoleBinding所属的命名空间(RoleBinding也是命名空间作用域的,必须指定)
subjects:               #定义主体类型
- kind: ServiceAccount  #主体类型为ServiceAccount
  name: rbac-sa         #ServiceAccount名称
  namespace: web        #指定的ServiceAccount所在命名空间
roleRef:                #引用Role或者ClusterRole
  kind: Role            #引用的资源类型为Role
  name: rbac-role       #引用的Role的名称
  apiGroup: rbac.authorization.k8s.io  #表示RBAC API群组
[root@master01 rbac]#kubectl apply -f rolebind.yaml 
rolebinding.rbac.authorization.k8s.io/rbac-rolebind created
[root@master01 rbac]#kubectl get rolebindings rbac-rolebind -n web -owide
NAME            ROLE             AGE   USERS   GROUPS   SERVICEACCOUNTS
rbac-rolebind   Role/rbac-role   35s                    web/rbac-sa

4.创建pod

创建pod是为了验证角色绑定后的权限效果

[root@master01 rbac]#cat rbac-pod.yaml
apiVersion: v1  
kind: Pod  
metadata:  
  name: rbac-centos 
  namespace: web
spec:  
  serviceAccountName: rbac-sa
  containers:  
  - name: centos
    image: centos:7
    command: ["/bin/sh","-c","sleep 36000"]
[root@master01 rbac]#kubectl apply -f rbac-pod.yaml 
pod/rbac-centos created

在pod内部,使用curl命令的方式,获取到pod的信息,类似于执行了get权限

创建一个不指定serviceaccount的pod,它就不具备权限,使用curl命令访问会出现403报错,表示权限拒绝

[root@master01 rbac]#vim rbac-pod.yaml 
[root@master01 rbac]#cat rbac-pod.yaml 
apiVersion: v1  
kind: Pod  
metadata:  
  name: rbac-centos-test
  namespace: web
spec:  
#  serviceAccountName: rbac-sa    #注释serviceAccountName字段信息
  containers:  
  - name: centos
    image: centos:7
    command: ["/bin/sh","-c","sleep 36000"]
[root@master01 rbac]#kubectl apply -f rbac-pod.yaml 
pod/rbac-centos-test created
[root@master01 rbac]#kubectl get pod rbac-centos-test -n web
NAME               READY   STATUS    RESTARTS   AGE
rbac-centos-test   1/1     Running   0          25s

5.示例总结

四、准入控制

准入控制是Kubernetes安全机制的最后一道防线,对API资源对象的修改和校验进行把关。Kubernetes提供了一个插件列表,所有请求都需要经过这个列表中的每个准入控制插件进行处理。这些插件可以对请求进行各种检查和修改,如检查请求是否符合特定的规范、限制请求的资源配额等。通过启用不同的准入控制插件,管理员可以实现对集群的细粒度控制和管理。一般建议直接采用官方默认的准入控制器

(一)准入控制器的工作流程

当向Kubernetes API服务器提交一个请求(如创建、更新或删除资源)时,API服务器会将请求传递给一系列注册的准入控制器进行检查。每个控制器都会根据其配置的规则来决定是否允许请求继续。如果任何一个控制器拒绝了请求,那么整个操作将不会被执行。

(二)准入控制器的类型

Kubernetes提供了多种内置的准入控制器,包括但不限于:

五、对用户的权限设置

平时我们都是默认的root用户进行操作,因为在~/.kube/config的配置文件中进行了令牌认证,它与k8s的admin用户进行了绑定,所以,它会有k8s的所有操作权限。如果使用其它用户进行操作就无法使用

[root@master01 ~]#useradd rbac        #创建一个普通用户
[root@master01 pki]#passwd rbac
更改用户 rbac 的密码 。
新的 密码:
无效的密码: 密码少于 8 个字符
重新输入新的 密码:
passwd:所有的身份验证令牌已经成功更新。
[root@master01 ~]#su - rbac
[rbac@master01 ~]$ kubectl get pod    #以普通用户的身份执行kubectl命令
The connection to the server localhost:8080 was refused - did you specify the right host or port?
[rbac@master01 ~]$ ls ~/.kube/config
ls: 无法访问/home/rbac/.kube/config: 没有那个文件或目录
#错误信息表示kubectl命令试图连接到默认的Kubernetes API服务器地址(localhost:8080),但连接被拒绝了
#因为APIServer的监听端口是6443,而使用kubectl命令在没有kubeconfig文件的指定情况下
#连接的是8080端口(非安全端口),所以需要进行证书认证并访问644端口

比如现在的需求是创建一个用户只能管理指定的命名空间,首先要做的就是创建用户用于连接到 API Server 所需的证书和 kubeconfig 文件

(一)创建证书

下载生成TSL证书工具并上传到系统当中

下载地址

1.获取工具

[root@master01 cfssl]#ls
cfssl  cfssl-certinfo  cfssljson
[root@master01 cfssl]#chmod +x ./*
[root@master01 cfssl]#ll
总用量 18808
-rwxr-xr-x 1 root root 10376657 2月  17 2021 cfssl
-rwxr-xr-x 1 root root  6595195 2月  17 2021 cfssl-certinfo
-rwxr-xr-x 1 root root  2277873 2月  17 2021 cfssljson
[root@master01 cfssl]#mv * /usr/local/sbin/

2.创建生成证书的配置文件

以下JSON文件是一个CFSSL(Cloudflare's PKI/TLS toolkit)的配置文件,用于生成一个TLS证书和私钥

[root@master01 cfssl]#mkdir -p /k8s/rbac
[root@master01 cfssl]#vim /k8s/rbac/rbac-csr.json
[root@master01 cfssl]#cat /k8s/rbac/rbac-csr.json
{
  "CN": "rbac",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
	  "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
	  "OU": "System"
    }
  ]
}

3.生成证书

[root@master01 pki]#cfssl gencert -ca=ca.crt -ca-key=ca.key -profile=kubernetes /k8s/rbac/rbac-csr.json | cfssljson -bare rbac
2024/06/06 08:51:45 [INFO] generate received request
2024/06/06 08:51:45 [INFO] received CSR
2024/06/06 08:51:45 [INFO] generating key: rsa-2048
2024/06/06 08:51:45 [INFO] encoded CSR
2024/06/06 08:51:45 [INFO] signed certificate with serial number 6178924093556289309011739985572884710402992043
2024/06/06 08:51:45 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
[root@master01 pki]#ls rbac*
rbac.csr  rbac-key.pem  rbac.pem
-----------------------------------------------------------------------------------------

(二)生成config文件

[root@master01 pki]#cd  /k8s/rbac/
[root@master01 rbac]#vim rbac-config.sh
[root@master01 rbac]#cat rbac-config.sh
#!/bin/bash
APISERVER=$1
export KUBE_APISERVER="https://$APISERVER:6443"
kubectl config set-cluster kubernetes \
  --certificate-authority=/etc/kubernetes/pki/ca.crt \
  --embed-certs=true \
  --server=${KUBE_APISERVER} \
  --kubeconfig=rbac.kubeconfig
kubectl config set-credentials rbac \
  --client-key=/etc/kubernetes/pki/rbac-key.pem \
  --client-certificate=/etc/kubernetes/pki/rbac.pem \
  --embed-certs=true \
  --kubeconfig=rbac.kubeconfig
kubectl config set-context kubernetes \
  --cluster=kubernetes \
  --user=rbac \
  --namespace=kgc \
  --kubeconfig=rbac.kubeconfig
kubectl config use-context kubernetes --kubeconfig=rbac.kubeconfig
-----------------------------------------------------------------------------------
#以脚本的形式创建,或者以命令的方式,分别执行
[root@master01 rbac]#kubectl create ns rbac-ns
namespace/rbac-ns created
#创建默认的命名空间,与上述文件中指定命名空间一致
[root@master01 rbac]#chmod +x rbac-config.sh
[root@master01 rbac]#./rbac-config.sh 192.168.83.30
Cluster "kubernetes" set.
User "rbac" set.
Context "kubernetes" created.
Switched to context "kubernetes".

查看config文件

这样看起来是不是与~/.kube/config文件很相似,而后将文件移动到用户的目录下,改名为config

[root@master01 rbac]#mkdir -p /home/rbac/.kube
[root@master01 rbac]#mv rbac.kubeconfig /home/rbac/.kube/config
[root@master01 rbac]#chown -R rbac:rbac /home/rbac/.kube/
[root@master01 rbac]#ls /home/rbac/.kube/
config

(三)RBAC授权

1.创建Role资源

[root@master01 rbac]#vim role.yaml
[root@master01 rbac]#cat role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role                  #创建Role资源
metadata:
  namespace: rbac-ns
  name: rbac-pod
rules:                      #定义授权的信息
- apiGroups: [""]           #指定资源核心组,例如Pod、Service等
  resources: ["pods"]       #指定对pod资源进行授权
  verbs: ["get", "watch", "list", "create"]
#授与get(获取)、watch(监听)、list(列出)、create(创建)权限
[root@master01 rbac]#kubectl apply -f role.yaml 
role.rbac.authorization.k8s.io/rbac-pod created
[root@master01 rbac]#kubectl get role -n rbac-ns 
NAME       CREATED AT
rbac-pod   2024-06-06T01:30:44Z
[root@master01 rbac]#kubectl describe role rbac-pod -n rbac-ns 
Name:         rbac-pod
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  pods       []                 []              [get watch list create]

2.Role绑定

[root@master01 rbac]#vim rolebind.yaml 
[root@master01 rbac]#cat rolebind.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding             #创建角色绑定资源
metadata:
  name: rolebind-pod
  namespace: rbac-ns
subjects:                     #定义了哪些用户、组或服务账户可以被这个RoleBinding授权
- kind: User                  #指定授权的主体类型是User(用户)
  name: rbac                  #指定用户的名称
  apiGroup: rbac.authorization.k8s.io  #指定API组,对于用户而言,不需要指定,可省略
roleRef:                      #引用Role或者ClusterRole
  kind: Role                  #定义了被引用的资源的类型为Role
  name: rbac-pod              #被引用的角色的名称
  apiGroup: rbac.authorization.k8s.io   #表示它们来自RBAC API组
[root@master01 rbac]#kubectl apply -f rolebind.yaml 
rolebinding.rbac.authorization.k8s.io/rolebind-pod created
[root@master01 rbac]#kubectl get rolebindings -n rbac-ns 
NAME           ROLE            AGE
rolebind-pod   Role/rbac-pod   9s
[root@master01 rbac]#kubectl describe rolebindings rolebind-pod -n rbac-ns 
Name:         rolebind-pod
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  Role
  Name:  rbac-pod
Subjects:
  Kind  Name  Namespace
  ----  ----  ---------
  User  rbac

(四)切换用户使用

在rbac用户指定操作内容

1.创建pod

[root@master01 ~]#su - rbac
上一次登录:四 6月  6 08:01:29 CST 2024pts/5 上
[rbac@master01 ~]$ kubectl get pod
No resources found in rbac-ns namespace. 
#默认的命名空间为rbac-ns
[rbac@master01 ~]$ kubectl run nginx --image=nginx:1.18.0
pod/nginx created
[rbac@master01 ~]$ kubectl get pod
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          6s
--------------------------------------------------------------------------------------
#可以看到,rbac用于经过授权之后,可以进行查看以及创建pod的操作

2.其它权限

[rbac@master01 ~]$ kubectl get ns
Error from server (Forbidden): namespaces is forbidden: User "rbac" cannot list resource "namespaces" in API group "" at the cluster scope
#查看命名空间被权限拒绝
[rbac@master01 ~]$ kubectl get svc
Error from server (Forbidden): services is forbidden: User "rbac" cannot list resource "services" in API group "" in the namespace "rbac-ns"
#查看service资源被权限拒绝
[rbac@master01 ~]$ kubectl delete pod nginx
Error from server (Forbidden): pods "nginx" is forbidden: User "rbac" cannot delete resource "pods" in API group "" in the namespace "rbac-ns"
#同样的,没有对pod资源授予删除权限,所以无法删除
[rbac@master01 ~]$ kubectl get pod nginx
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          4m

-------------------------------------------------------------------------------------[root@master01 rbac]#kubectl get pod -n rbac-ns 
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          5m40s
#在root用户,同样可以查看到新建的pod

3.获取管理员权限

//在root用户中操作
[root@master01 rbac]#kubectl create rolebinding rbac-admin-binding --clusterrole=admin --user=rbac -n rbac-ns
#将rbac用户与admin集群角色进行绑定,并指定rbac-ns命名空间
#执行此命令后,rbac用户会拥有rbac-ns命名空间中所有的资源的管理权限
rolebinding.rbac.authorization.k8s.io/rbac-admin-binding created
[root@master01 rbac]#kubectl get rolebindings rbac-admin-binding -n rbac-ns 
NAME                 ROLE                AGE
rbac-admin-binding   ClusterRole/admin   20s

//在rbac用户中操作
[rbac@master01 ~]$ kubectl get service
No resources found in rbac-ns namespace.
[rbac@master01 ~]$ kubectl expose pod nginx --port=80 --target-port=80 --name=nginx-svc --type=NodePort
service/nginx-svc exposed
[rbac@master01 ~]$ kubectl get service -owide
NAME        TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE   SELECTOR
nginx-svc   NodePort   10.96.211.179   <none>        80:30309/TCP   8s    run=nginx
#可以看到,rbac用于拥有对其它资源的同样拥有操作权限

但是该管理员权限,仅限于指定的命名空间,无法所其它命名空间进行操作

在工作环境中,对于不同的层次,可以对指定的命令空间有不同的权限,负责人或领导也可能需要一个命名空间的所有权限,类似于一个项目,每个人都有不同的职责,一个人负责pod创建,一个人负责对外发布,各司其职,所有需要不同的权限,但是在赋权时一定要谨慎

声明式删除资源

[rbac@master01 ~]$ kubectl delete svc nginx-svc
service "nginx-svc" deleted
[rbac@master01 ~]$ kubectl delete pod nginx
pod "nginx" deleted
[rbac@master01 ~]$ kubectl get svc,pod
No resources found in rbac-ns namespace.
举报

相关推荐

AWS

AWS认证

AWS VPC

AWS CLI

AWS 网络

aws凭证

aws slb

0 条评论