[TOC]
基于角色(Role)的访问控制(RBAC)是一种基于组织中用户的角色来调节控制对 计算机或网络资源的访问的方法。
RBAC 鉴权机制使用 `rbac.authorization.k8s.io` API组来驱动鉴权决定,允许你通过 Kubernetes API 动态配置策略。
要启用 RBAC,在启动 kube-apiserver 时将 `--authorization-mode` 参数设置为一个逗号分隔的列表并确保其中包含 RBAC。
## Role 和 ClusterRole
RBAC 的 Role 或 ClusterRole 中包含一组代表相关权限的规则。 这些权限是纯粹累加的(不存在拒绝某操作的规则)。
Role 总是用来在某个名字空间 内设置访问权限;在你创建 Role 时,你必须指定该 Role 所属的名字空间。
与之相对,ClusterRole 则是一个集群作用域的资源。这两种资源的名字不同(Role 和 ClusterRole)是因为 Kubernetes 对象要么是名字空间作用域的,要么是集群作用域的, 不可两者兼具。
Role 示例
```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: jiaxzeng
namespace: default
rules:
# pod资源只有create get list watch的操作
- apiGroups: [""]
resources: ["pods"]
verbs: ["create", "get", "list", "watch"]
# 登录pod容器,查看pod日志
- apiGroups: [""]
resources: ["pods/exec", "pods/log"]
verbs: ["get", "create"]
# deployment资源只有get list watch的操作,其他权限均没有
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch"]
```
> - Role 与 ClusterRole,除了 `kind` 和 `ClusterRole` 资源清单不需要 `cluster.namespace` 字段外,其他都一致。
> - verbs具体有什么操作,请看下面的 [查看资源操作](#verbs) 的段落
## serviceaccount 和 user
### serviceaccount
```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: jiaxzeng
namespace: default
```
### user
查看 kube-apiserver 的配置文件,确定 ca 证书的相关文件路径。这里演示路径是在 `/data/k8s/certs/`
创建一个 JSON 配置文件,用来为 kube-apiserver 生成秘钥和证书,例如:server-csr.json。 确认用你需要的值替换掉尖括号中的值。USER 是为 kube-apiserver绑定的用户名,MASTER_CLUSTER_IP 是为 kube-apiserver 指定的服务集群IP,就像前面小节描述的那样。 以下示例假定你的默认 DSN 域名为cluster.local。
```json
{
"CN": "<USER>",
"hosts": [
"127.0.0.1",
"<MASTER_IP>",
"<MASTER_CLUSTER_IP>",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [{
"C": "CN",
"L": "GuangDong",
"O": "ecloud",
"OU": "ecloud"
}]
}
```
为 kube-apiserver 生成秘钥和证书,默认会分别存储为server-key.pem 和 server.pem 两个文件。
```shell
$ cfssl gencert -ca /data/k8s/certs/ca.pem -ca-key /data/k8s/certs/ca-key.pem --config /data/k8s/certs/ca-config.json -profile kubernetes jiaxzeng-csr.json | cfssljson -bare jiaxzeng
2022/01/28 15:51:28 [INFO] generate received request
2022/01/28 15:51:28 [INFO] received CSR
2022/01/28 15:51:28 [INFO] generating key: rsa-2048
2022/01/28 15:51:28 [INFO] encoded CSR
2022/01/28 15:51:28 [INFO] signed certificate with serial number 89734874854127747600656517401688932704615436370
2022/01/28 15:51:28 [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").
```
> 踩坑:第二行的CN要填写用户名,hosts添加主机的IP地址
## RoleBinding 和 ClusterRoleBinding
角色绑定(Role Binding)是将角色中定义的权限赋予一个或者一组用户。 它包含若干 主体(用户、组或服务账户)的列表和对这些主体所获得的角色的引用。 RoleBinding 在指定的名字空间中执行授权,而 ClusterRoleBinding 在集群范围执行授权。
一个 RoleBinding 可以引用同一的名字空间中的任何 Role。 或者,一个 RoleBinding 可以引用某 ClusterRole 并将该 ClusterRole 绑定到 RoleBinding 所在的名字空间。 如果你希望将某 ClusterRole 绑定到集群中所有名字空间,你要使用 ClusterRoleBinding。
创建了绑定之后,你不能再修改绑定对象所引用的 Role 或 ClusterRole。 试图改变绑定对象的 roleRef 将导致合法性检查错误。 如果你想要改变现有绑定对象中 roleRef 字段的内容,必须删除重新创建绑定对象。
### RoleBinding ServiceAccount
```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: jiaxzeng
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: jiaxzeng
subjects:
- apiGroup: ""
kind: ServiceAccount
name: jiaxzeng
```
### RoleBinding User
```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: jiaxzeng
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: jiaxzeng
subjects:
- apiGroup: "rbac.authorization.k8s.io"
kind: User
name: jiaxzeng
```
## 创建kubectl命令的鉴权文件
### ServiceAccount
```shell
# 获取sa的token
TOKEN=$(kubectl describe secrets "$(kubectl describe serviceaccount jiaxzeng | grep -i Tokens | awk '{print $2}')" | grep token: | awk '{print $2}')
# 设置集群信息。如果有集群信息,则无需再设置
kubectl config set-cluster jiaxzeng-k8s --server=https://192.168.31.103:6443 --insecure-skip-tls-verify
# 设置token
kubectl config set-credentials jiaxzeng --token=$TOKEN
# 设置上下文
kubectl config set-context jiaxzeng --cluster=jiaxzeng-k8s --user=jiaxzeng
# 切换上下文
kubectl config use-context jiaxzeng
```
### User
```shell
# 设置集群信息。如果有集群信息,则无需再设置
KUBE_APISERVER="https://192.168.31.103:6443"
kubectl config set-cluster kubernetes \
--certificate-authority=/data/k8s/certs/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER}
# 设置证书
kubectl config set-credentials jiaxzeng \
--client-certificate=jiaxzeng.pem \
--client-key=jiaxzeng-key.pem \
--embed-certs=true
# 设置上下文
kubectl config set-context jiaxzeng \
--cluster=kubernetes \
--user=jiaxzeng
# 切换上下文
kubectl config use-context jiaxzeng
```
## <a name="verbs"> 查看资源操作 </a>
### 暴露apiserver接口
```shell
kubectl proxy --address='192.168.31.103' --port=8001 --accept-hosts='^*$'
```
> 启动 `kubectl proxy` 使用网卡IP,从其他机器访问, `--accept-hosts='^*$'` 表示接受所有源IP,否则会显示不被授权
访问 `http://192.168.31.103:8001/` ,显示所有可用的api接口。根据 `apiVersion` 来找出对应的api接口。进入对应的api接口,查看 `resources` 类型,`resources` 类型可以还有子资源。可根据 `kind` 的关键字来确认。
### 查看资源操作的示例
这里演示的查看deployment的资源情况以及有什么可用的操作
1. 查看deployment的 apiVersion 信息
```shell
kubectl explain deployment | grep 'VERSION'
VERSION: apps/v1
```
2. 查看对应的deployment api接口信息
![](https://img.kancloud.cn/c2/aa/c2aaaa263006cffdf755562f381e218d_1920x505.png)
3. 过滤deployment类型, 确认资源以及可用操作
![](https://img.kancloud.cn/c6/e8/c6e8101e72d745b623c34039bc0706c9_1920x922.png)
> 说明:
> - 访问的url,根据上面查出来的接口查询
> - 过滤kind的类型,显示如果有多少条记录,则有多个资源。资源名称是name对应的值
> - 资源对应的操作是verbs中的值
## 验证
```shell
# 确认使用的上下文
$ kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
default kubernetes system:admin
* jiaxzeng kubernetes jiaxzeng
# 切换上下文
$ kubectl config use-context jiaxzeng
Switched to context "jiaxzeng".
# 检验权限
$ kubectl auth can-i get deployment
yes
$ kubectl auth can-i create deployment
no
$ kubectl auth can-i create pod
yes
$ kubectl auth can-i watch pod
yes
$ kubectl auth can-i get pod -n kube-system
no
```
## 参考文章
- 创建证书:https://kubernetes.io/zh/docs/tasks/administer-cluster/certificates/
- rbdc文档:https://kubernetes.io/zh/docs/reference/access-authn-authz/rbac/
- api文档:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/
- 前言
- 架构
- 部署
- kubeadm部署
- kubeadm扩容节点
- 二进制安装基础组件
- 添加master节点
- 添加工作节点
- 选装插件安装
- Kubernetes使用
- k8s与dockerfile启动参数
- hostPort与hostNetwork异同
- 应用上下线最佳实践
- 进入容器命名空间
- 主机与pod之间拷贝
- events排序问题
- k8s会话保持
- 容器root特权
- CNI插件
- calico
- calicoctl安装
- calico网络通信
- calico更改pod地址范围
- 新增节点网卡名不一致
- 修改calico模式
- calico数据存储迁移
- 启用 kubectl 来管理 Calico
- calico卸载
- cilium
- cilium架构
- cilium/hubble安装
- cilium网络路由
- IP地址管理(IPAM)
- Cilium替换KubeProxy
- NodePort运行DSR模式
- IP地址伪装
- ingress使用
- nginx-ingress
- ingress安装
- ingress高可用
- helm方式安装
- 基本使用
- Rewrite配置
- tls安全路由
- ingress发布管理
- 代理k8s集群外的web应用
- ingress自定义日志
- ingress记录真实IP地址
- 自定义参数
- traefik-ingress
- traefik名词概念
- traefik安装
- traefik初次使用
- traefik路由(IngressRoute)
- traefik中间件(middlewares)
- traefik记录真实IP地址
- cert-manager
- 安装教程
- 颁布者CA
- 创建证书
- 外部存储
- 对接NFS
- 对接ceph-rbd
- 对接cephfs
- 监控平台
- Prometheus
- Prometheus安装
- grafana安装
- Prometheus配置文件
- node_exporter安装
- kube-state-metrics安装
- Prometheus黑盒监控
- Prometheus告警
- grafana仪表盘设置
- 常用监控配置文件
- thanos
- Prometheus
- Sidecar组件
- Store Gateway组件
- Querier组件
- Compactor组件
- Prometheus监控项
- grafana
- Querier对接grafana
- alertmanager
- Prometheus对接alertmanager
- 日志中心
- filebeat安装
- kafka安装
- logstash安装
- elasticsearch安装
- elasticsearch索引生命周期管理
- kibana安装
- event事件收集
- 资源预留
- 节点资源预留
- imagefs与nodefs验证
- 资源预留 vs 驱逐 vs OOM
- scheduler调度原理
- Helm
- Helm安装
- Helm基本使用
- 安全
- apiserver审计日志
- RBAC鉴权
- namespace资源限制
- 加密Secret数据
- 服务网格
- 备份恢复
- Velero安装
- 备份与恢复
- 常用维护操作
- container runtime
- 拉取私有仓库镜像配置
- 拉取公网镜像加速配置
- runtime网络代理
- overlay2目录占用过大
- 更改Docker的数据目录
- Harbor
- 重置Harbor密码
- 问题处理
- 关闭或开启Harbor的认证
- 固定harbor的IP地址范围
- ETCD
- ETCD扩缩容
- ETCD常用命令
- ETCD数据空间压缩清理
- ingress
- ingress-nginx header配置
- kubernetes
- 验证yaml合法性
- 切换KubeProxy模式
- 容器解析域名
- 删除节点
- 修改镜像仓库
- 修改node名称
- 升级k8s集群
- 切换容器运行时
- apiserver接口
- 其他
- 升级内核
- k8s组件性能分析
- ETCD
- calico
- calico健康检查失败
- Harbor
- harbor同步失败
- Kubernetes
- 资源Terminating状态
- 启动容器报错