欢迎大家进群,一起探讨学习
博主技术文档地址
博主开源微服架构前后端分离技术博客项目源码地址,欢迎各位star
Kubernetes api-server 安全访问机制
kube-apiserver 是 k8s 整个集群的入口,是一个 REST API 服务,提供的 API 实现了 Kubernetes 各类资源对象(如 Pod,RC,Service 等)的增、删、改、查,API Server 也是集群内各个功能模块之间交互和通信的枢纽,是整个集群的总线和数据中心。![在这里插入图片描述](https://img-blog.csdnimg.cn/img_convert/f430da02671698686476f3d6e8076a48.png)
由此可见 API Server 的重要性了,我们用 kubectl、各种语言提供的客户端库或者发送 REST 请求和集群交互,其实底层都是以 HTTP REST 请求的方式同 API Server 交互,那么访问的安全机制是如何保证的呢,总不能随便来一个请求都能接受并响应吧。API Server 为此提供了一套特有的、灵活的安全机制,每个请求到达 API Server 后都会经过:认证(Authentication)–>授权(Authorization)–>准入控制(Admission Control) 三道安全关卡,通过这三道安全关卡的请求才给予响应:
![在这里插入图片描述](https://img-blog.csdnimg.cn/img_convert/7592034df7b7c7ab701a773d62bdff65.png)
认证(Authentication)
认证阶段的工作是识别用户身份,支持的认证方式有很多,比如:HTTP Base,HTTP token,TLS,Service Account,OpenID Connect 等,API Server 启动时可以同时指定多种认证方式,会逐个使用这些方法对客户请求认证,只要通过任意一种认证方式,API Server 就会认为 Authentication 成功。高版本的 Kubernetes 默认认证方式是 TLS。在 TLS 认证方案中,每个用户都拥有自己的 X.509 客户端证书,API 服务器通过配置的证书颁发机构(CA)验证客户端证书。授权(Authorization)
授权阶段判断请求是否有相应的权限,授权方式有多种:AlwaysDeny,AlwaysAllow,ABAC,RBAC,Node 等。API Server 启动时如果多种授权模式同时被启用,Kubernetes 将检查所有模块,如果其中一种通过授权,则请求授权通过。 如果所有的模块全部拒绝,则请求被拒绝(HTTP状态码403)。高版本 Kubernetes 默认开启的授权方式是 RBAC 和 Node。
准入控制(Admission Control)
准入控制判断操作是否符合集群要求,准入控制配备有一个“准入控制器”的列表,发送给 API Server 的每个请求都需要通过每个准入控制器的检查,检查不通过,则 API Server 拒绝调用请求,有点像 Web 编程的拦截器的意思。具体细节在这里不进行展开了,如想进一步了解见这里:Using Admission Controllers。
Kubernetes 认证方式之客户端证书(TLS)
通过上一节介绍我们知道 Kubernetes 认证方式有多种,这里我们简单介绍下客户端证书(TLS)认证方式,也叫 HTTPS 双向认证。一般我们访问一个 https 网站,认证是单向的,只有客户端会验证服务端的身份,服务端不会管客户端身份如何。我们来大概看下 HTTPS 握手过程(单向认证):
客户端发送 Client Hello 消息给服务端;
服务端回复 Server Hello 消息和自身证书给客户端;
客户端检查服务端证书的合法性,证书检查通过后根据双方发送的消息生成 Premaster Key,然后用服务端的证书里面的公钥加密 Premaster Key 并发送给服务端 ;
服务端通过自己的私钥解密得到 Premaster Key,然后通过双方协商的算法和交换的消息生成 Session Key(后续双方数据加密用的对称密钥,客户端也能通过同样的方法生成同样的 Key),然后回复客户端一个消息表明握手结束,后续发送的消息会以协商的对称密钥加密。
Kubernetes 授权方式之 RBAC 介绍
基于角色的访问控制(Role-Based Access Control, 即 RBAC),是 k8s 提供的一种授权策略,也是新版集群默认启用的方式。RBAC 将角色和角色绑定分开,角色指的是一组定义好的操作集群资源的权限,而角色绑定是将角色和用户、组或者服务账号实体绑定,从而赋予这些实体权限。可以看出 RBAC 这种授权方式很灵活,要赋予某个实体权限只需要绑定相应的角色即可。针对 RBAC 机制,k8s 提供了四种 API 资源: Role、ClusterRole、RoleBinding、ClusterRoleBinding。查看命名空间
kubectlget ns;
创建命名空间
kubectl create ns roletest
![](https://img-blog.csdnimg.cn/img_convert/4a9e5eb36d82dcf57360d58ae909dd61.png)
在创建roletest命名空间下pod
kubectlrun nginx --image=nginx -n roletest
查看
kubectlget pod -n roletest
![](https://img-blog.csdnimg.cn/img_convert/b00ef0d8aa8052fe64485327604402d6.png)
Role: 只能用于授予对某一单一命名空间中资源的访问权限,因此在定义时必须指定 namespace;
以下示例描述了 default 命名空间中的一个 Role 对象的定义,用于授予对 pod 的读访问权限:
角色
rbac-role.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: roletest
name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
kubectl apply -f rbac-role.yaml
rules.verbs 动作 权限
create 创建 写入 Pod 动作/资源
update 更新 写入 Pod 动作/资源
delete 删除 写入 Pod 动作/资源
watch 读取 Pod 动作/资源
list 列出 读取 Pod 动作/资源
patch 写入 Pod 动作/资源
get 查看 读取 Pod 动作/资源resources:[“deployments”,“jobs”,“pods”,“configmaps”,“nodes”] 不管是什么资源控制器都需要加上 s
查看
kubectl getrole -n roletest
![](https://img-blog.csdnimg.cn/img_convert/b492c2f29c1d0f2a18dd311e857d24d3.png)
角色绑定
rbac-rolebinding.yaml
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-pods
namespace: roletest
subjects:
- kind: User
name: mary # Name is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role #this must be Role or ClusterRole
name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to
apiGroup: rbac.authorization.k8s.io
kubectl apply -f rbac-rolebinding.yaml
kubectlget RoleBinding -n roletest
![](https://img-blog.csdnimg.cn/img_convert/8d206975bbfc4a8ecfc9c3486c81c965.png)
cfssl 是一个开源的证书管理工具,使用 json 文件生成证书,相比 openssl 更方便使用。 找任意一台服务器操作,这里用 Master 节点
wgethttps://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
chmod +x cfssl_linux-amd64 cfssljson_linux-amd64 cfssl-certinfo_linux-amd64
mv cfssl_linux-amd64 /usr/local/bin/cfssl
mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
mv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo
chmod +x /usr/bin/cfssl*
创建目录mary
mkdir mary;
cd mary;
cat > ca-config.json << EOF
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"kubernetes": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
EOF
#国家名=User "CN": "mary",
#组织=Group "O": "k8s",
cat > ca-csr.json << EOF
{ "CN": "kubernetes", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "Beijing", "ST": "Beijing", "O": "k8s", "OU": "System" } ] }
EOF
cfssl gencert -initcaca-csr.json | cfssljson -bare ca -
ls *pem
脚本执行
rabc-user.sh
cat > mary-csr.json <<EOF
{"CN": "mary",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "BeiJing",
"ST": "BeiJing"
}
]
}
EOF
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes mary-csr.json | cfssljson -bare mary
kubectl config set-cluster kubernetes \
--certificate-authority=ca.pem \
--embed-certs=true \
--server=https://192.168.31.63:6443 \
--kubeconfig=mary-kubeconfig
kubectl config set-credentials mary \
--client-key=mary-key.pem \
--client-certificate=mary.pem \
--embed-certs=true \
--kubeconfig=mary-kubeconfig
kubectl config set-context default \
--cluster=kubernetes \
--user=mary \
--kubeconfig=mary-kubeconfig
kubectl config use-context default --kubeconfig=mary-kubeconfig
bash rabc-user.sh
![](https://img-blog.csdnimg.cn/img_convert/6bbcb520fe8f57953e9fc2e710fe8373.png)
mkdir -pv /home/mary/.kube
cp mary-kubeconfig /home/mary/.kube
chown mary:mary -R /home/mary/.kube
采用 mary 用户登录 xshell
mv devuser.kubeconfigconfig
这样就可以切换mary用户测试了