【kubernetes】kubernetes中的安全和认证

1 kubernetes是如何进行安全控制的?

Authentication(认证,确认双方是可信的):

  • Http Token:http header中存放Token
  • Http Base:用户名和密码
  • https证书:基于CA根证书签名的客户端身份认证

1 ControllerManager、Scheduler于API Server部署在同一台机器,可以直接用API Server的非安全端口访问:--insecure-bind-address=127.0.0.1
2 kubectl、kube-proxy访问API Server时手动颁发证书进行HTTPS双向认证
3 kubelet
4 Pod通过ServiceAccount进行访问:service-account-token

Authorization(授权,是否可以执行某项操作):

授权策略(–authorization-mode):

  • AlwaysDeny:拒绝所有请求
  • AlwaysAllow:允许所有请求
  • ABAC(Attribute-Based Access Control):基于属性的访问控制,表示使用用户配置的授权规则队用户请求进行匹配和控制
  • Webbook:通过调用外部REST服务队用户进行授权
  • RBAC(Role-Based Access Control):基于角色的访问控制,默认策略

Admission(准入控制,对资源的变更加上一些逻辑限制):

apiserver在将数据写入etcd前做一次拦截,对资源的操作进行一些逻辑控制。

2 RBAC

引入了4个顶级资源:

  • Role
  • RoleBinding
  • ClusterRole
  • ClusterRoleBinding

Role是资源操作权限的集合,而RoleBinding则是将User、Group、ServiceAccount与Role绑定。

Role在创建时,需要与namespace绑定,如果需要创建跨namespace的角色,可以用ClusterRole。ClusterRole通常用于:

  • 集群级别的资源控制
  • 非资源型endpoints
  • 所有命名空间资源控制

RoleBinding不一定只能使用Role绑定,而ClusterRoleBinding只能使用在ClusterRole。另外,由于Role在创建时必须指定namespace,实际使用时不太方便,因此,通常的使用方式是:创建ClusterRole,然后使用RoleBinding将ClusterRole与用户绑定。

3 用户角色管理

k8s提供了4个顶级资源进行权限的授予,那么,在实际中该如何使用呢?

下面提供一种思路:

  • 以项目为单位管理
  • 创建普通用户的ClusterRole
  • 当创建一个项目时就创建一个命名空间
  • 当用户访问平台时需要添加到某个项目或者若干项目中,此时就会将用户与普通用户的ClusterRole绑定
  • 后续用户就可以访问一个或者若干项目的命名空间

4 实践

4.1 User & ServiceAccount

apiserver是K8S集群中所有组件协同工作的桥梁,因此,任何组件在实现时都需要访问apiserver。K8S将访问集群的用户分成两类:User和ServiceAccount。User是访问集群实际的用户,例如,使用kubectl访问集群的用户;而ServiceAccount则是访问集群的应用,也称为服务账号。

假设现在的场景是,我们需要创建一个用户,这个用户只能在develop这个命名空间中操作资源,SA虽然通常是Pod访问apiserver的方式,但是,也可以在外部通过SA访问集群。

// 创建命名空间
kubectl create namespace develop// 创建SA(类似于创建用户),这个SA的名命名空间是develop
kubectl create sa my-sa -n develop// 将admin集群角色绑定到develop命名空间的SA
kubectl create rolebinding my-rb --clusterrole=admin --serviceaccount=develop:my-sa -n develop

通过上面的方式,my-sa这个SA就只能访问develop这个命名空间中的所有资源,那么剩下的问题就是,如果客户端要用这个SA访问该怎么办呢?那就只有为用户生成kubeconfig文件。

如果是通过TOKEN的方式认证:

apiVersion: v1
clusters:- name: $CLUSTER_NAMEcluster:certificate-authority-data: $CAserver: $CLUSTER_URL
contexts:- name: $USERNAMEcontext:cluster: $CLUSTER_NAMEuser: $USERNAMEnamespace: $NAMESPACE
current-context: $USERNAME
kind: Config
preferences: {}
users:- name: $USERNAMEuser:token: $TOKEN

从上面的文件结构来看,整个kubeconfig中有几个变量:

  • 集群名称
  • 集群域名
  • 命名空间
  • 用户名称
  • 用户Token
  • 用户证书

集群名称、集群域名、命名空间可以直接得到,剩下的用户名称、token和证书该如何得到呢?

SA包含三个部分:命名空间、token、证书。因此,可以直接用SA的名称、SA的token和SA的证书代替。有了上面的信息,就可以生成最终的kubeconfig文件。

同样的,如果使用User进行认证就需要使用证书,例如下面的kubeconfig文件:

apiVersion: v1
clusters:
- cluster:certificate-authority-data: $CERTIFICATE_AUTHORITY_DATAserver: $CLUSTER_URLname: default
contexts:
- context:cluster: defaultuser: defaultname: default
current-context: default
kind: Config
preferences: {}
users:
- name: $USERNAMEuser:client-certificate-data: $CLIENT_CERTIFICATE_DATAclient-key-data: $CLIENT_KEY_DATA
  • CERTIFICATE_AUTHORITY_DATA:CA证书,用于验证服务端发送来的证书
  • CLIENT_CERTIFICATE_DATA:客户端证书,发送给服务端,从中提取出公钥
  • CLIENT_KEY_DATA:客户端私钥

因此,要想让我们的客户端能够通过k8s的认证,就需要使用k8s的CA证书对私钥生成证书即可,然后就可以生成kubeconfig,那么k8s怎么知道当前用户是谁呢?因此,在生成证书时,提供的信息中就需要将CN(CommonName)设置为用户名,然后在k8s中再对用户进行授权,就可以进行访问了。

这种方式的认证流程就是:

  • 客户端连接server中指定的集群地址
  • 服务端返回证书,客户端用指定的CA证书对服务端返回的证书进行验证,并从中提取出服务端的公钥
  • 客户端将自己的证书发送给服务端
  • 服务端同样对客户端发送的证书进行验证,并从中提取出客户端的公钥
  • 客户端生成随机数,使用服务端的公钥进行加密
  • 服务端收到数据后,使用私钥进行解密,然后提取出随机数
  • 客户端与服务端使用随机数作为对称密钥进行通信

因此,使用https相比于token的好处就是:token只验证了服务端,而https会对服务端和客户端都进行验证。

5 公钥、私钥、签名、证书

加密是为了保证数据的安全性
签名是为了保证数据的完整性
证书是为了保证公钥的完整性

加密一般分为对称加密和非对称加密:

  • 对称加密指的是通信的双方用相同的密钥对数据进行加解密:明文+密钥->密文,密文+密钥->明文
  • 非对称加密指的是通信的双方用不同的密钥对数据进行加解密:用公钥加密的密文只能用私钥解密,用私钥加密的密文只能用公钥解密

对称加密的好处在于简单并且效率高,不好的当然就是密钥的分发问题。非对称加密的好处在于安全性高,不好的就是加解密效率比对称加密低。

签名就是对通信的数据打上标签,可以防止数据被篡改以及保证数据的真实性。

生成签名的过程:

  • 对数据计算HASH值
  • 用私钥对HASH值加密,生成签名
  • 将签名放在消息后面一起发送

验证签名的过程:

  • 用公钥对数据中的签名进行解密,得到HASH1
  • 对数据中的正文计算哈希值,得到HASH2
  • 比较HASH1和HASH2,如果相同,则验证成功

生成证书的过程:

  • 服务器将公钥A给CA
  • CA用自己的私钥B对公钥A加密,生成数字签名
  • CA把公钥A、数字签名、服务器信息整合生成证书
  • CA将证书分发给服务器

通过上面生成证书的过程可以知道,证书主要包含两部分信息:自己的公钥和数字签名(只有用CA的公钥才能对数字签名进行验证)。

验证证书的过程:

  • 当客户端与服务端通信时,服务端将自己的证书发给客户端
  • 客户端收到服务端发送的证书,需要从证书中得到服务端的公钥。为了得到公钥,又需要验证公钥没有被篡改,就只能用签发证书的CA的公钥进行验证。
  • 假设客户端已经有签发证书的CA的公钥,用该公钥对证书进行解密并计算哈希值,然后与证书中的公钥计算的哈希值进行对比,如果相同,说明公钥没有被篡改
  • 客户端就得到了服务端的公钥,然后客户端在发送数据时就使用服务端的公钥,服务端返回收据时就使用服务端的私钥

根证书:

上面验证证书的过程中,有个问题没有解答:客户端如何得到签发证书的CA的公钥?

举个例子,当访问www.baidu.com时,返回了百度的证书,为了得到并验证百度的公钥,又必须有签发给百度证书的GlobalSign Organization Validation CA机构的公钥,因此,客户端又必须有GlobalSign Organization Validation CA机构的证书,从而可以从中提取出百度的公钥。但是,怎么去验证GlobalSign Organization Validation CA的证书呢?又必须有签发给GlobalSign Organization Validation CA的证书公钥,即GlobalSign Root CA的公钥。这就构成了一个信任链,那么这个链在哪里结束呢?就是根证书,根证书是由权威机构给自己颁发的证书。

当前,权威的颁发根证书的机构并不多,可以认为,电脑中已经默认保存了大部分的权威机构的根证书,也就是这些证书是可以信任的。然后再用这些根证书去验证下面的机构或者网站的证书。

6 HTTPS

前面提到过对称加密和非对称加密的优缺点,而HTTPS就刚好结合了两者的优点:

  • 对称加密的高效性
  • 非对称加密的安全性
6.1 单向认证

单向认证就是我们通常访问网站的方式:只验证服务端是否是安全的。

认证流程:

  • 客户端建立HTTPS请求
  • 服务端返回证书
  • 客户端通过上面的验证流程从证书中提取并验证服务端的公钥
  • 客户端生成随机数R,用服务端的公钥加密,发送给服务端
  • 服务端使用私钥解密得到随机数R
  • 客户端和服务端使用随机数R作为对称密钥进行通信

上述过程只验证服务端是否安全,而没有验证客户端。

6.2 双向认证

双向认证既需要验证服务端,又需要验证客户端。单向认证只为服务端生成了私钥和证书,而双向认证就需要为客户端和服务端分别生成私钥和证书。

认证流程:

  • 客户端建立HTTPS请求
  • 服务端返回证书server.crt
  • 客户端验证证书并从中提取出服务端的公钥server.pub
  • 客户端将自己的证书client.crt发送给服务端
  • 服务端验证证书并从中提取出客户端的公钥client.pub
  • 客户端生成随机数R,使用服务端公钥加密后发送给服务端
  • 服务端使用私钥解密得到随机数R
  • 客户端和服务端使用随机数R作为对称密钥进行通信

7 kubernetes中的证书

kubernetes中的所有组件通信时都采用HTTPS双向认证,而部署时不可能为他们申请证书,因此,在部署kuberentes时通常都是先生成自签名证书,然后用该证书作为根证书,后续的证书都通过它签发。

mkdir -p /etc/crt
pushd /etc/crt# 使用RSA算法生成私钥
openssl genrsa -out cakey.pem# 根据私钥得到公钥,然后生成证书
# -new:生成新的证书请求文件
# -x509:结合-new表示生成证书文件
# -key:私钥
# -subj:机构信息(网站信息)
# -days:有效期
openssl req -new -x509 -key cakey.pem -out cacert.pem -subj '/CN=Mirror CA/O=UCloud/ST=GuangDong/L=Shenzhen/C=CN' -days 3650
cat cacert.pem >>/etc/pki/tls/certs/ca-bundle.crt# 使用RSA算法生成私钥
openssl genrsa -out k8s.io.key 2048# 生成证书请求文件
openssl req -new -key k8s.io.key -out k8s.io.csr -subj '/CN=*.k8s.io/O=UCloud/ST=GuangDong/L=Shenzhen/C=CN'# 依据上面生成的CA证书和CA私钥,根据证书请求文件生成证书
# -in 证书请求文件
# -CA ca的证书
# -CAkey ca的私钥
# -CAcreateserial
# -extensions 
openssl x509 -req -in k8s.io.csr -CA cacert.pem -CAkey cakey.pem -CAcreateserial -out k8s.io.crt -days 3650 -config ./openssl.cfg -extensions k8s.io
popd

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/98469.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux自用笔记

✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: Linux相关 ✨特色专栏: My…

【网络安全 ---- 靶场搭建】凡诺企业网站管理系统靶场详细搭建过程(asp网站,练习sql注入)

一,资源下载 百度网盘资源下载链接:百度网盘 请输入提取码百度网盘为您提供文件的网络备份、同步和分享服务。空间大、速度快、安全稳固,支持教育网加速,支持手机端。注册使用百度网盘即可享受免费存储空间https://pan.baidu.com…

C++开发学习笔记3

C 中枚举的使用 在C中,枚举常量(Enumeration Constants)是一种定义命名常量的方式。枚举类型允许我们为一组相关的常量赋予有意义的名称,并将它们作为一个独立的类型来使用。 以下是定义和使用枚举常量的示例: enum…

启动springboot项目后运行时报错The driver has not received any packets from the server

2023/10/9记录错误 今天导入了一个springboot项目,启动成功了,但是在前端操作登陆后就要调后端了嘛,然后后端报错了The driver has not received any packets from the server。 然后在网上参考别人的解决办法,有说mysql版本不匹…

HDMI简介

VGA接口 VGA传输红绿蓝模拟信号和同步信号。因传输的模拟信号,易受干扰,因此,在高分辨率下字体容易虚,信号线长的话,图像有拖尾现象。目前一些显示器已经不带VGA接口,取而代之的是HDMI和DP接口。 如下图所示…

Python元组解密:不可变的数据之美

更多资料获取 🤓 作者主页:涛哥聊Python 📚 个人网站:涛哥聊Python 元组是Python中一种有用的数据类型,用于存储不可变的有序集合。 本文将带您深入了解Python元组,包括定义、特点、创建、基本操作、不可…

SpringBoot 整合 jetcache缓存

目前 jetcache 支持的本地缓存方案有两种&#xff0c;远程缓存支持两种&#xff0c;分别如下&#xff1a; 本地缓存&#xff08;Local&#xff09; LinkedHashMapCaffeine 远程缓存&#xff08;Remote&#xff09; Redis Tair 依赖导入 <dependency><groupId>…

第86步 时间序列建模实战:Transformer回归建模

基于WIN10的64位系统演示 一、写在前面 这一期&#xff0c;我们介绍Transformer回归。 同样&#xff0c;这里使用这个数据&#xff1a; 《PLoS One》2015年一篇题目为《Comparison of Two Hybrid Models for Forecasting the Incidence of Hemorrhagic Fever with Renal Sy…

系统架构设计:9 论软件系统架构评估及其应用

目录 一 架构评估的意义 1 性能 2 可用性 3 安全性 4 可修改性 5 易用性

机器学习必修课 - 交叉验证 Cross-Validation

想象一下你有一个包含5000行数据的数据集。通常情况下&#xff0c;你会将约20%的数据保留作为验证数据集&#xff0c;即1000行。但这会在确定模型得分时引入一些随机性。也就是说&#xff0c;一个模型可能在一组1000行数据上表现良好&#xff0c;即使在另一组1000行数据上表现不…

Vue--1.7watch侦听器(监视器)

作用&#xff1a;监视数据变化&#xff0c;执行一些业务逻辑或异步操作。 语法&#xff1a; 1.简单写法->简单类型数据&#xff0c;直接监视 const app new Vue({el: #app,data: {words:},watch:{words(newValue,oldValue){}}}) const app new Vue({el: #app,data: {obj…

cv2.split函数与cv2.merge函数

split函数用于图像BGR通道的分离 merge函数用于可将分开的图像通道合并到一起 1.split函数的使用 这是原图&#xff0c;我们使用split函数对其三个通道进行分离。 注意&#xff1a;split函数分离通道的顺序是B、G、R。 以下方法是将三个通道的值都设置为与某一个通道相同。…

【Mysql】 blob 转text

有个数据表字段存储的字段类型是blob&#xff0c;想查看字段内容。 blob是二进制的无法直接查看怎么办&#xff1f; 写sql&#xff0c;blob 转text SELECT CONVERT(content USING utf8) FROM article_content ; 我想把原来content字段完全转成text 新建 text 类型字段conten…

k8s-8 ingress-nginx

nodeport 默认端口 nodeport默认端口是30000-32767&#xff0c;超出会报错 添加如下参数&#xff0c;端口范围可以自定义 externalname ingress-nginx 通过一个外部的vip 地址 访问到集群内的多个service 一种全局的、为了代理不同后端 Service 而设置的负载均衡服务&…

uniapp:swiper-demo效果

单元格轮播 <swiper class"swiper1" :circular"true" :autoplay"true" interval"3000" previous-margin"195rpx" next-margin"195rpx"><swiper-item v-for"(item,index) in 5" :key"inde…

虹科方案 | 车载以太网解决方案

全文导读&#xff1a;针对车载以太网&#xff0c;虹科为您提供转换器/交换机/捕捉模块/测试分析软件等相关专业工具、一体化培训以及“交钥匙”的解决方案&#xff0c;助力您的车载以太网数据传输、远程诊断、及时检测等项目。 文章目录 一、车载以太网的重要性&#xff1f;二、…

webstorm自定义文件模板(Vue + Scss)

最终效果如下&#xff1a; 具体配置如下&#xff1a; 新增文件代码如下&#xff1a; <!--* Description: ${COMPONENT_NAME} 页面* Author: mhf* Date: ${DATE} --> <template><div>${COMPONENT_NAME} </div> </template><script&g…

江西省TEWA 700G光猫拿到河北地区不刷固件使能用

大家好&#xff0c;第一次在这里发布教程&#xff0c;请互相学习&#xff0c;原由&#xff1a;本人在网上购买一部光猫&#xff0c;型号&#xff1a;天邑TEWA 700G gpon光猫&#xff0c;卖家是江西的&#xff0c;到货就注册sn码&#xff0c;这个需要有一定装维支持才能完成这个…

TensorFlow入门(十三、动态图Eager)

一个图(Graph)代表一个计算任务,且在模型运行时,需要把图放入会话(session)里被启动。一旦模型开始运行,图就无法修改了。TensorFlow把这种图一般称为静态图。 动态图是指在Python中代码被调用后,其操作立即被执行的计算。 它与静态图最大的区别是不需要使用session来建立会话…

Scala第二十章节

Scala第二十章节 scala总目录 文档资料下载 章节目标 理解Akka并发编程框架简介掌握Akka入门案例掌握Akka定时任务代码实现掌握两个进程间通信的案例掌握简易版spark通信框架案例 1. Akka并发编程框架简介 1.1 Akka概述 Akka是一个用于构建高并发、分布式和可扩展的基于事…