百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

Kubernetes 安全框架

ztj100 2024-11-23 00:03 15 浏览 0 评论


? K8S安全控制框架主要由下面3个阶段进行控制,每一个阶段都 支持插件方式,通过API Server配置来启用插件。


1. Authentication(认证)

2. Authorization(授权)

3. Admission Control(准入控制)


? 客户端要想访问K8s集群API Server,一般需要证书、Token或 者用户名+密码;如果Pod访问,需要ServiceAccount



认证(Authentication)


三种客户端身份认证:


? HTTPS 证书认证:基于CA证书签名的数字证书认证


? HTTP Token认证:通过一个Token来识别用户


? HTTP Base认证:用户名+密码的方式认证 [基本弃用】


鉴权(Authentication)


RBAC(Role-Based Access Control,基于角色的访问控制):负责完成授权(Authorization)工作。

RBAC根据API请求属性,决定允许还是拒绝。


比较常见的授权维度:

? user:用户名

? group:用户分组

? 资源,例如pod、deployment

? 资源操作方法:get,list,create,update,patch,watch,delete

? 命名空间

? API组


准入控制(Admission Control)


Adminssion Control实际上是一个准入控制器插件列表,发送到API Server 的 请求都需要经过这个列表中的每个准入控制器插件的检查,检查不通过, 则拒绝请求。

#查看准入控制的帮助信息


[root@master-1 bin]# /opt/kubernetes/bin/kube-apiserver -h | grep enable-admission


基于角色的权限访问控制:RBAC


RBAC(Role-Based Access Control,基于角色的访问控 制),允许通过Kubernetes API动态配置策略。


角色

? Role:授权特定命名空间的访问权限

? ClusterRole:授权所有命名空间的访问权限


角色绑定

? RoleBinding:将角色绑定到主体(即subject)

? ClusterRoleBinding:将集群角色绑定到主体


主体(subject)


? User:用户

? Group:用户组

? ServiceAccount:服务账号



案例:为新来的同事,指定用户授权访问特定的命名空间


示例:为fxkj用户授权default命名空间Pod读取权限(只能查看,不能删除)


实验过程:

1. 用K8S CA签发客户端证书 基于证书的客户端认证方式

2. 生成kubeconfig授权文件 kubectl使用kubeconfig连接集群

3. 创建RBAC权限策略 做一定的权限分配


也就是生成一个kubeconfig文件,让指定用户拿着这个文件去访问集群,如何查看资源


CA签发客户端证书


#查看之前生成的ca证书


[root@manager ssl]# ls ca*

ca-config.json ca.csr ca-csr.json ca-key.pem ca.pem


#拷贝之前生成的ca证书到本机的/fxkj目录下

[root@manager fxkj]# mkdir /root/fxkj

[root@manager fxkj]# cp /opt/kubernetes/ssl/ca* /root/fxkj

[root@manager fxkj]# ls ca*

ca-config.json ca.csr ca-csr.json ca-key.pem ca.pem


配置证书: 生成请求证书文件


API Server会把客户端证书的CN字段作为User,把names.O字段作为Group。

[root@manager fxkj]# vim fxkj-csr.json
{
"CN": "fxkj",    	#CN ,apiserver 通过CN 来确认用户名
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "BeiJing",
"ST": "BeiJing",
"O": "k8s",		#O ,apiserver 通过O 来确认组
"OU": "System"
}
 ]
}

#签发证书使用的cfssl 工具,安装生成证书工具

[root@manager fxkj]# curl -L https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -o /usr/local/bin/cfssl

[root@manager fxkj]#  curl -L https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -o /usr/local/bin/cfssljson

[root@manager fxkj]#  curl -L https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -o /usr/local/bin/cfssl-certinfo

[root@manager fxkj]# chmod +x /usr/local/bin/cfssl*


生成fxkj 客户端证书

#需要指定k8s根证书,如果使用的kubeadm 部署的话,指定的根证书 在 /etc/kubernetes/pki/下;二进制部署手动指定ca证书路径


[root@manager fxkj]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes fxkj-csr.json | cfssljson -bare fxkj


[root@ansible fxkj]# ll fxkj*

-rw-r--r-- 1 root root 993 Jan 23 14:26 fxkj.csr

-rw-r--r-- 1 root root 217 Jan 23 14:23 fxkj-csr.json

-rw------- 1 root root 1675 Jan 23 14:26 fxkj-key.pem

-rw------- 1 root root 6235 Jan 23 14:28 fxkj.kubeconfig

-rw-r--r-- 1 root root 1383 Jan 23 14:26 fxkj.pem

生成kubeconfig授权文件


集群参数设置

使用kubectl config这条命令生成kubeconfig证书,逐步生成kubeconfig里面的信息,生成证书的格式和/$HOME 目录的config内容是一样的

# 本段设置了所需要访问的集群的信息

  • 使用set-cluster设置了需要访问的集群,如上为kubernetes,这只是个名称,实际为--server指向的apiserver
  • --certificate-authority 设置了该集群的公钥
  • --enabed-certs为true 表示将--certificate-authority 证书写入到kubeconfig中

  • --server则表示该集群的kube-apiserver地址
  • 当然生成的kubeconfig 内容 被保存到当前目录中的 fxkj.kubeconfig文件

    [root@ansible fxkj]# kubectl config set-cluster kubernetes \
    
    --certificate-authority=ca.pem \
    
    --embed-certs=true \
    
    --server=https://192.168.31.61:6443 \
    
    --kubeconfig=fxkj.kubeconfig

    设置客户端认证

    #本段主要设置用户的相关信息,主要是用户证书。如上的用户名为fxkj,证书为:fxkj.pem,私钥为:fxkj-key.pem

    注意客户端的证书首先要经过集群CA的签署,否则不会被集群认可,此处使用的是ca认证方式;

    也可以使用token认证,如kubelet的 TLS Boostrap机制下的bootstrapping使用的就是token认证方式

    [root@ansible fxkj]# kubectl config set-credentials fxkj \
    
    --client-key=fxkj-key.pem \
    
    --client-certificate=fxkj.pem \
    
    --embed-certs=true \
    
    --kubeconfig=fxkj.kubeconfig

    设置默认上下文

    # 集群参数和用户参数可以同时设置多对,在上下文参数中将集群参数用户参数关联起来。上面的上下文名称为kubenetes,集群为kubenetes,用户为fxkj,

    表示使用fxkj的用户凭证来访问kubenetes集群的default命名空间,也可以增加--namspace来指定访问的命名空间。

    最后使用kubectl config use-context kubernetes来使用名为kubenetes的环境项来作为配置。如果配置了多个环境项,可以通过切换不同的环境项名字来访问到不同的集群环境。

    [root@ansible fxkj]# kubectl config set-context kubernetes \
    
    --cluster=kubernetes \
    
    --user=fxkj \
    
    --kubeconfig=fxkj.kubeconfig


    设置当前使用配置

    [root@ansible fxkj]# kubectl config use-context kubernetes --kubeconfig=fxkj.kubeconfig


    #验证连接apiserver

    #--kubeconfig 指定kubeconfig 配置文件路径

    [root@ansible fxkj]# kubectl --kubeconfig=fxkj.kubeconfig get pods
    
    Error from server (Forbidden): pods is forbidden: User "fxkj" cannot list resource "pods" in API group "" in the namespace "default"


    可以看到上面配置是没有问题的,给出的提示是用户fxkj是不能列出这方面资源

    但是通过管理员的配置文件是可以访问到的

    [root@master-1 .kube]# kubectl --kubeconfig=/root/.kube/config get pods
    NAME                                          READY   STATUS    RESTARTS   AGE
    nfs-client-provisioner-5c75c654c7-kc8r4       1/1     Running   2          26h
    nfs-client-provisioner-nfs-85fcbf6445-6czb7   1/1     Running   1          26h
    web-0                                         1/1     Running   1          26h
    web-1                                         1/1     Running   1          26h
    web-1-74d7d458df-kv6b5                        1/1     Running   5          8d
    web-2                                         1/1     Running   1          26h
    web-2-84868454c9-4jvt8                        1/1     Running   5          8d

    上面说明了配置文件是没有问题的,只是缺少相应的权限 ,这个时候需要去配置RBAC 权限策略


    创建RBAC权限策略:

    需要创建role和rolebinding,role是权限的集合,rolebinding是要将role里面权限绑定到指定的用户,也就是我们上面的fxkj用户

    比较常见的授权维度:


    ? user:用户名


    ? group:用户分组


    ? 资源,例如pod、deployment


    ? 资源操作方法:get,list,create,update,patch,watch,delete


    ? 命名空间


    ? API组


    
    [root@ansible RBAC]# vim rbac.yaml
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      namespace: default
      name: pod-reader
    rules:
    - apiGroups: [""] 		       # "" 指定核心 API 组
      resources: ["pods"]
      verbs: ["get", "watch", "list"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    # 此角色绑定使得用户 "fxkj" 能够读取 "default" 命名空间中的 Pods
    kind: RoleBinding
    metadata:
      name: read-pods
      namespace: default
    subjects:
    - kind: User
      name: fxkj 			# 此角色绑定使得用户 "fxkj" 
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: Role 			#this must be Role or ClusterRole,与上面保持一致
      name: pod-reader 			# 这里的名称必须与你想要绑定的 Role 或 ClusterRole 名称一致
      apiGroup: rbac.authorization.k8s.io


    已经授权了,只能查看default 命名空间下的Pod,其他资源不能查看,且只有查看的权限


    [root@ansible fxkj]# kubectl --kubeconfig=/root/fxkj/fxkj.kubeconfig get pods
    NAME                                          READY   STATUS    RESTARTS   AGE
    nfs-client-provisioner-5c75c654c7-kc8r4       1/1     Running   2          26h
    nfs-client-provisioner-nfs-85fcbf6445-6czb7   1/1     Running   1          26h
    web-0                                         1/1     Running   1          26h
    web-1                                         1/1     Running   1          26h
    web-1-74d7d458df-kv6b5                        1/1     Running   5          8d
    web-2                                         1/1     Running   1          26h
    web-2-84868454c9-4jvt8                        1/1     Running   5          8d


    #同样也是无法删除POD

    [root@ansible fxkj]# kubectl --kubeconfig=/root/fxkj/fxkj.kubeconfig delete pod web-0


    Error from server (Forbidden): pods "web-0" is forbidden: User "fxkj" cannot delete resource "pods" in API group "" in the namespace "default"


    现在我们给fxkj 这个用户 再添加一个查看deployment控制器,service 的权限


    修改 rbac.yaml 文件

    kind: Role
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      namespace: default
      name: pod-reader
    rules:
    - apiGroups: [""]
      resources: ["pods","deployments","services"]
      verbs: ["get", "watch", "list"]
    
    .............


    [root@master-1 RBAC]# kubectl apply -f rbac.yaml 
    role.rbac.authorization.k8s.io/pod-reader configured
    rolebinding.rbac.authorization.k8s.io/read-pods unchanged
    
    [root@ansible ~]# kubectl --kubeconfig=/root/fxkj/fxkj.kubeconfig get service
    NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
    kubernetes   ClusterIP   10.0.0.1     <none>        443/TCP        26d
    web          ClusterIP   None         <none>        80/TCP         28h
    web-1        NodePort    10.0.0.16    <none>        80:30588/TCP   18d
    web-2        NodePort    10.0.0.80    <none>        80:31620/TCP   18d	
    
    [root@ansible ~]# kubectl --kubeconfig=/root/fxkj/fxkj.kubeconfig get deployment 
    Error from server (Forbidden): deployments.apps is forbidden: User "fxkj" cannot list resource "deployments" in API group "apps" in the namespace "default"


    发现 service 可以查询,但是deployment 无法查询到


    原因是 ,deployment 控制器 属于 apps 组名里的,而默认的 apiGroups: [""] 核心组名里不包含deployment 控制器

    如果不确定 Role 里的一些resources


    方法1: 可以去官网查看示例: https://kubernetes.io/zh/docs/reference/access-authn-authz/rbac/


    方法2: 查看k8s 下有哪些api-service 组名

    [root@master-1 ~]# kubectl api-versions 
    admissionregistration.k8s.io/v1
    admissionregistration.k8s.io/v1beta1
    apiextensions.k8s.io/v1
    apiextensions.k8s.io/v1beta1
    apiregistration.k8s.io/v1
    apiregistration.k8s.io/v1beta1
    apps/v1
    authentication.k8s.io/v1
    authentication.k8s.io/v1beta1
    authorization.k8s.io/v1
    authorization.k8s.io/v1beta1
    autoscaling/v1
    autoscaling/v2beta1
    autoscaling/v2beta2
    batch/v1
    batch/v1beta1
    certificates.k8s.io/v1beta1
    coordination.k8s.io/v1
    coordination.k8s.io/v1beta1
    discovery.k8s.io/v1beta1
    events.k8s.io/v1beta1
    extensions/v1beta1
    metrics.k8s.io/v1beta1
    networking.k8s.io/v1
    networking.k8s.io/v1beta1
    node.k8s.io/v1beta1
    policy/v1beta1
    rbac.authorization.k8s.io/v1
    rbac.authorization.k8s.io/v1beta1
    scheduling.k8s.io/v1
    scheduling.k8s.io/v1beta1
    storage.k8s.io/v1
    storage.k8s.io/v1beta1
    v1
    
    或者  使用  kubectl get api-service  也能查看到

    现在 我们只需要修改下rbac.yaml 文件 ,在apiGroups: [""] 里添加 apps 组名即可

    [root@master-1 RBAC]# cat rbac.yaml 
    
    kind: Role
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      namespace: default
      name: pod-reader
    rules:
    - apiGroups: ["","apps"]
      resources: ["pods","deployments","services"]
      verbs: ["get", "watch", "list"]
    ............

    添加完之后 apply 从新加载下yaml 文件,就可以看到 deployment 控制器了

    [root@ansible ~]# kubectl --kubeconfig=/root/fxkj/fxkj.kubeconfig get deployment
    NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
    nfs-client-provisioner       1/1     1            1           40h
    nfs-client-provisioner-nfs   1/1     1            1           26h
    web-1                        1/1     1            1           18d
    web-2                        1/1     1            1           18d


    现在 就可以把配置好的 fxkj.kubeconfig 拷贝给你的新同事


    如果不想每次输入kubeconfig 路径 kubectl --kubeconfig=/root/fxkj/fxkj.kubeconfig


    可以这样做:


    [root@ansible ~]# mv fxkj.kubeconfig /root/.kube/config

    #同样可以查看POD
    [root@ansible .kube]# kubectl get pods
    NAME                                          READY   STATUS    RESTARTS   AGE
    nfs-client-provisioner-5c75c654c7-kc8r4       1/1     Running   2          26h
    nfs-client-provisioner-nfs-85fcbf6445-6czb7   1/1     Running   1          26h
    web-0                                         1/1     Running   1          26h
    web-1                                         1/1     Running   1          26h
    web-1-74d7d458df-kv6b5                        1/1     Running   5          8d
    web-2                                         1/1     Running   1          26h
    web-2-84868454c9-4jvt8                        1/1     Running   5          8d

    总结


    当使用kucetl调用其api或者使用K8S-UI 其实都是向apiserver组件发送的请求。

    提取出证书里面的CN字段,该字段作为你的用户名。也就是从CA签发客户端证书当中提取出用户名 "CN": "fxkj",


    - kind: User
    name: fxkj


    同样也可以基于组 "O": "k8s"


    使用 ClusterRoleBinding 可以对整个集群中的所有命名空间资源权限进行授权;


    下面k8s 官方的 ClusterRoleBinding 样例展示了授权 manager 组内所有用户在全部命名空间中对 secrets 进行访问

    补充内容: serviceaccounts 主体


    主体里的 user,Group 的都是针对人的身份 来进行验证 来访问 apiserver

    而 服务账户 serviceaccounts 是针对 程序来验证 来访问apiserver ,比如 我们部署的coredns, k8s-ui,calico,falnel 等等

    访问流程:K8S-UI ——> token ——> apiserver ——> rbac


    例如: 看下之前部署的kubernetes-dashboard 的serviceaccounts :

    [root@master-1 ~]# kubectl get serviceaccounts -n kubernetes-dashboard 
    NAME                   SECRETS   AGE
    dashboard-admin        1         26d
    default                1         26d


    通过创建serviceaccounts 来 创建secrets 中的 token

    [root@master-1 ~]# kubectl get secrets -n kubernetes-dashboard 
    NAME                               TYPE                                  DATA   AGE
    dashboard-admin-token-25b5h        kubernetes.io/service-account-token   3      26d
    
    [root@master-1 ~]# kubectl describe secrets -n kubernetes-dashboard dashboard-admin-token-25b5h
    Name:         dashboard-admin-token-25b5h
    Namespace:    kubernetes-dashboard
    Labels:       <none>
    Annotations:  kubernetes.io/service-account.name: dashboard-admin
                  kubernetes.io/service-account.uid: fdf94e5a-5b5f-4d40-95d9-4cb5d2409991
    
    Type:  kubernetes.io/service-account-token
    
    Data
    ====
    ca.crt:     1359 bytes
    namespace:  20 bytes
    token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IjVReUxQWFQyVzdvRjQ3TTRCZWtjR1Rja01CSUc4Qi1PNjdib1pfQXBURjgifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkYXNoYm9hcmQtYWRtaW4tdG9rZW4tMjViNWgiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGFzaGJvYXJkLWFkbWluIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiZmRmOTRlNWEtNWI1Zi00ZDQwLTk1ZDktNGNiNWQyNDA5OTkxIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmVybmV0ZXMtZGFzaGJvYXJkOmRhc2hib2FyZC1hZG1pbiJ9.U4NEeAg1hg0hkCcZrfA4nFPfqNGUlEKIcIEMSrXuxoOIi2wrFJadohzpipmAb0DUItx-K0QPprQ7V0EYJlZbDnKExp2uqJqFsG_TmcZ4T741OUpkTRX9sy0AqC_XkB-2GUj9KHRhi_2M_QMYif4XfB9kS_EpEfMUg9l8K97LnHSMo2ZFbCk2XcpCUe21uNegOtFqVka7RbtiikqVc4sJEPJuA0nwmtqehaJZB7obBHTmACzYMU2WlILzv0QJdL2b--Koa8dkekERsd89ExTZBnxVZw5eB26cFwSUFZzpEZuq8SVicokh90JgswyV3REQwPwU85lpO6yF3tbhIU6jXQ
    


    最后使用这个token 去登陆k8s-ui 的控制台


    这个就是就是 serviceaccounts 来创建token 的案例

    相关推荐

    利用navicat将postgresql转为mysql

    导航"拿来主义"吃得亏自己动手,丰衣足食...

    Navicat的详细教程「偷偷收藏」(navicatlite)

    Navicat是一套快速、可靠并价格适宜的数据库管理工具,适用于三种平台:Windows、macOS及Linux。可以用来对本机或远程的MySQL、SQLServer、SQLite、...

    Linux系统安装SQL Server数据库(linux安装数据库命令)

    一、官方说明...

    Navicat推出免费数据库管理软件Premium Lite

    IT之家6月26日消息,Navicat推出一款免费的数据库管理开发工具——NavicatPremiumLite,针对入门级用户,支持基础的数据库管理和协同合作功能。▲Navicat...

    Docker安装部署Oracle/Sql Server

    一、Docker安装Oracle12cOracle简介...

    Docker安装MS SQL Server并使用Navicat远程连接

    ...

    Web性能的计算方式与优化方案(二)

    通过前面《...

    网络入侵检测系统之Suricata(十四)——匹配流程

    其实规则的匹配流程和加载流程是强相关的,你如何组织规则那么就会采用该种数据结构去匹配,例如你用radixtree组织海量ip规则,那么匹配的时候也是采用bittest确定前缀节点,然后逐一左右子树...

    使用deepseek写一个图片转换代码(deepnode处理图片)

    写一个photoshop代码,要求:可以将文件夹里面的图片都处理成CMYK模式。软件版本:photoshop2022,然后生成的代码如下://Photoshop2022CMYK批量转换专业版脚...

    AI助力AUTOCAD,生成LSP插件(ai里面cad插件怎么使用)

    以下是用AI生成的,用AUTOLISP语言编写的cad插件,分享给大家:一、将单线偏移为双线;;;;;;;;;;;;;;;;;;;;;;单线变双线...

    Core Audio音频基础概述(core 音乐)

    1、CoreAudioCoreAudio提供了数字音频服务为iOS与OSX,它提供了一系列框架去处理音频....

    BlazorUI 组件库——反馈与弹层 (1)

    组件是前端的基础。组件库也是前端框架的核心中的重点。组件库中有一个重要的板块:反馈与弹层!反馈与弹层在组件形态上,与Button、Input类等嵌入界面的组件有所不同,通常以层的形式出现。本篇文章...

    怎样创建一个Xcode插件(xcode如何新建一个main.c)

    译者:@yohunl译者注:原文使用的是xcode6.3.2,我翻译的时候,使用的是xcode7.2.1,经过验证,本部分中说的依然是有效的.在文中你可以学习到一系列的技能,非常值得一看.这些技能不单...

    让SSL/TLS协议流行起来:深度解读SSL/TLS实现1

    一前言SSL/TLS协议是网络安全通信的重要基石,本系列将简单介绍SSL/TLS协议,主要关注SSL/TLS协议的安全性,特别是SSL规范的正确实现。本系列的文章大体分为3个部分:SSL/TLS协...

    社交软件开发6-客户端开发-ios端开发验证登陆部分

    欢迎订阅我的头条号:一点热上一节说到,Android客户端的开发,主要是编写了,如何使用Androidstudio如何创建一个Android项目,已经使用gradle来加载第三方库,并且使用了异步...

    取消回复欢迎 发表评论: