灵山网站建设,潍坊seo招聘,提供给他人做视频解析的网站源码,网站建设入门教程视频1 kubernetes是如何进行安全控制的#xff1f;
Authentication(认证#xff0c;确认双方是可信的)#xff1a;
Http Token#xff1a;http header中存放TokenHttp Base#xff1a;用户名和密码https证书#xff1a;基于CA根证书签名的客户端身份认证
1 ControllerMana…1 kubernetes是如何进行安全控制的
Authentication(认证确认双方是可信的)
Http Tokenhttp header中存放TokenHttp Base用户名和密码https证书基于CA根证书签名的客户端身份认证
1 ControllerManager、Scheduler于API Server部署在同一台机器可以直接用API Server的非安全端口访问--insecure-bind-address127.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个顶级资源
RoleRoleBindingClusterRoleClusterRoleBinding
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 --clusterroleadmin --serviceaccountdevelop: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_DATACERTIFICATE_AUTHORITY_DATACA证书用于验证服务端发送来的证书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给CACA用自己的私钥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 /CNMirror CA/OUCloud/STGuangDong/LShenzhen/CCN -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/OUCloud/STGuangDong/LShenzhen/CCN# 依据上面生成的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