Kubernetes 集群安全- Authorization鉴权,RBAC授权方法,RBAC实例
个人学习记录Kubernetes 集群安全 - 机制说明Authorization 鉴权RBAC 授权模式RBAC 的 API 资源对象说明一、Verbs 动作二、apiGroupsAPI接口组三、JOSN 证书Role and ClusterRole一、Role二、ClusterRoleRoleBinding and ClusterRoleBinding一、Role - RoleBinding二
个人学习记录
Kubernetes 集群安全 - 机制说明
- kubernetes 作为一个分布式集群的管理工具,保证集群的安全性是其一个重要的任务。
- API Server 是集群内部各个组件通信的中介,也是外部控制的入口。
- 所以 kubernetes 的安全机制基本就是围绕保护 API Server 来设计的。
- kubernetes 使用了 认证(Authentication)、鉴权(Authorization)、准入控制(AdmissionControl),三步来保证 API Server 的安全。
API Server 是 k8s 一个非常重要的组件,不管是用户还是 Pod,都会访问 API Server。间接到达 Etcd。
这个过程中间需要经历三个模块,也就是认证、鉴权、准入控制。由管理员来选择通过哪一个模块来做安全认证。
Authorization 鉴权
Authentication认证过程,只是确认通信的双方都确认了对方是可信的,可以互相通信。
而鉴权是确定请求方有哪些资源的权限。
API Server 目前支持以下几种授权策略 (通过 API Server 的启动参数 --authorization-mode
设置)
-
AlwaysDeny:标识拒绝所有的请求,一般用于测试
-
AlwaysAllow:允许接受所有请求,如果集群不需要授权流程,则可以采用该策略
-
ABAC:基于属性的访问控制,表示使用用户配置的授权规则对用户请求进行匹配和控制,淘汰
-
Webbook:通过调用外部 REST 服务对用户进行授权
-
RBAC:基于角色的访问控制,现行默认规则,常用
RBAC 授权模式
RBAC 基于角色的访问控制,在 kubernetes1.5 中引入,现行版本成为默认标准。相对其他访问控制方式,拥有以下优势:
- 对集群中的资源和非资源拥有完整的覆盖
- 整个 RBAC 完全由几个API 对象完成。同其他 API 对象一样,可以用 kubectl 或 API 进行操作。
- 可以在运行时进行调整,无需重启 API Server。
RBAC 的 API 资源对象说明
RBAC 引入了 4个新的顶级资源对象:Role、ClusterRole、RoleBinding、ClusterRoleBinding、4种对象类型均可以通过 kubectl 与 API 操作。
Role:普通角色 | ClusterRole:集群角色
Rolebinding:普通角色绑定 ClusterRoleBinding:集群角色绑定
一、Verbs 动作
rules:
verbs: [“get”, “list”, “watch”, “create”, “update”, “patch”, “delete”]
rules.verbs 动作 | 权限 |
---|---|
create 创建 | 写入 Pod 动作/资源 |
update 更新 | 写入 Pod 动作/资源 |
delete 删除 | 写入 Pod 动作/资源 |
watch | 读取 Pod 动作/资源 |
list 列出 | 读取 Pod 动作/资源 |
patch | 写入 Pod 动作/资源 |
get 查看 | 读取 Pod 动作/资源 |
可以将不同的动作(create、get、update)创建成 Role 角色。比如创建一个pod,将其设置成 create pod 的角色名,然后进行 RoleBinding 绑定。绑定给后端的 user用户、Group组、ServiceAccount(SA)
二、apiGroups API接口组
rules:
- apiGroups:[“extensions”,“apps”,“batch”]
可以指定多个 apiVersion 的API接口
三、JOSN 证书
kubernetes 并不会提供用户管理,那么 User、Group、ServiceAccount 指定的用户又是从哪里来的呢?kubernetes组件 (kubectl、kube-proxy) 或者是其他自定义的用户向 CA 申请证书时,需要提供一个证书请求文件,如下:API Server 会把客户端证书 CN 字段作为 User,把 names.O 字段作为 Group
{
"CN": "admin", #国家名=User
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "HangZhou",
"L": "XS",
"O": "system:masters", #组织=Group
"OU": "System"
}
]
}
- kubelet 使用 TLS Bootstaping 认证时,API Server 可以使用 Bootstrap Tokens 或者 Token authentication file 验证 token,无论哪一种,kubernetes都会为 token 绑定一个默认的 User 和 Group。
- Pod 使用 ServiceAccount 认证时,Service-accout-token 中的 JWT 会保存 User信息。
有了用户信息,再创建一对 角色/角色绑定,集群角色/集群角色绑定 资源对象,就可以完成权限绑定了。
Role and ClusterRole
一、Role
- 在 RBAC API 中, Role 表示一组规则权限,权限只会增加(累加权限),不存在一个资源一开始就有很多权限。可以通过 RBAC 对其进行权限减少的操作。
- Role 可以定义在一个 namespace 名称空间下,如果要跨 namespace 则需要创建 ClusterRole 实现。
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
name: pod-reader # Role角色名称
namespace: default # Role角色名称空间
rules: # 权限规则
- apiGroups: [""] # 为空"" 默认API核心组
resources: ["pods"] # 对象 Pod 容器
verbs: ["get","watch","list"] #动作:获取信息,监听,列出
二、ClusterRole
clusterRole 具有与 Role 相同的权限角色控制能力,不同的是 ClusterRole 是集群级别的, ClusterRole常用于:
- 集群级别的资源控制(例如 node访问)
- 非资源型 endpoints (例如 /healthz访问)
- 所有命名空间资源控制 (例如 pods)
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get","watch","list"]
RoleBinding and ClusterRoleBinding
- RoleBinding 可以将角色中定义的权限授予用户和用户组。RoleBinding 包含一组权限列表(subjects),权限列表中包含有不同形式的待授予权限资源类型 (users, groups, service Account)。
- RoleBinding 同样包含对被 Bind 的 Role 引用;RoleBinding 适用于某个命名空间内授权,而 ClusterRoleBinding 适用于集群范围内的授权。
- RoleBinding 可以绑定 Role and ClusterRole;ClusterRoleBinding 只能绑定 ClusterRole。
一、Role - RoleBinding
例:将 default
命名空间的 pod-reader
Role 授予 jane
用户,此后 jane
用户可以在 default
命名空间中使用 pod-reader
的权限。
apiVersion: rbac.authorization.k8s.io/v1beta1 #API 接口
kind: RoleBinding # 剧本类型
metadata: # 元数据信息
name: read-pods
namespace: default # 名称空间
subjects: # 对象类型
- kind: User # User 对象
name: jane # 对象名称
apiGroup: rbac.authorization.k8s.io # 授予对象API组
roleRef:
kind: Role # Role 角色类型
name: pod-reader # Role 角色权限
apiGroup: rbac.authorization.k8s.io # Role 角色的API组
RoleBinding 同样可以引用 ClusterRole 来对当前 namespace 内用户、用户组、SA 进行授权。
这种操作允许集群管理员在整个集群内定义一些通用的 ClusterRole ,然后在不同的 namespace 中使用 RoleBinding来引用。
二、ClusterRole - RoleBinding
例:RoleBinding 引用了一个 ClusterRole ,这个 ClusterRole 具有整个集群内对 secrets 的访问权限;但是其授权用户 dave
只能访问 development 空间中的 secrets (因为 RoleBinding 定义在 development 命名空间)。
apiVersion: rbac.authorization.k8s.io/v1beta1 # API接口
kind: RoleBinding # RoleBinding
metadata:
name: read-secrets
namespace: development # 名称空间
subjects:
- kind: User # 授权对象用户
name: dave # 授权对象的用户名称
apiGroup: rbac.authorization.k8s.io #授权对象用户API组
roleRef:
kind: ClusterRole # 集群角色
name: secret-reader # 集群角色的权限
apiGroup: rbac.authorization.k8s.io # 集群角色的API组
三、ClusterRole - ClusterRoleBinding
使用 ClusterRoleBinding 可以对整个集群中的所有命名空间资源权限进行授权;
以下 ClusterRoleBinding 样例展示了授权 manager 组内所有用户在全部命名空间中对 secrets 进行访问。
apiVersion: rbac.authorization.k8s.io/v1beta1 #API接口
kind: ClusterRoleBinding #剧本类型
metadata:
name: read-secrets-global
subjects:
- kind: Group #授权对象组
name: manager #授权对象组的名称
apiGroup: rbac.authorization.k8s.io #授权对象组的API接口
roleRef:
kind: ClusterRole #集群角色
name: secret-reader #集群角色名称
apiGroup: rbac.authorization.k8s.io #集群角色的API接口
Resources 资源类型
kubernetes 集群内的一些资源一般会以其名称字符串表示,这些字符串一般会在 API 的 URL 地址中出现;
同时某些资源也会包含子资源,例如 logs 资源就属于 pods 的子资源,API 中 URL 样例如下:
GET /api/v1/namespaces/{namespace}/pods{name}/log
如果要在 RABC 授权模型中控制这些子资源的访问权限,可以通过 / 分隔符来实现,以下是一个定义 Pods 资源 logs 访问权限的 Role 定义样例:
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
name: pod-and-pod-logs-reader
namespace: default
rules:
- apiGroups: [""]
resources: ["pods","pods/log"]
verbs: ["get","list"]
resources:[“deployments”,“jobs”,“pods”,“configmaps”,“nodes”] 不管是什么资源控制器都需要加上 s
Subjects 绑定角色
RoleBinding或ClusterRoleBinding可以将Role绑定到主体subjects。Subjects 可以是groups、users和service accounts。
Users:由字符串表示,可用的格式有,如纯字符“alice”,Emai格式“bob@example.com”或表示为字符串的数字。Users除了需要满足Kubernetes管理员配置的 authentication modules,对Users, RBAC授权系统没有做任何格式限定。除了前缀为system:是为Kubernetes系统使用而保留的用户名格式,除此之外RBAC授权系统可以使用任何格式的Users。
Group:信息目前由Authenticator模块提供。和Users 一样,Group 由字符串表示,而且字符串没有格式要求,除了前缀*system:*是保留的。
Service Account: 使用system:serviceaccount:前缀的用户名,并且属于具有system:serviceaccounts:前缀的Group组。
Role Binding 示例
1、user and Group
绑定名为“alice@example.com”的用户:
subjects:
- kind: User
name: "alice@example.com"
apiGroup: rbac.authorization.k8s.io
绑定名为“frontend-admins”的Group:
subjects:
- kind: Group
name: "frontend-admins"
apiGroup: rbac.authorization.k8s.io
2、ServiceAccount
适合kube-system Namespace中的默认ServiceAccount:
subjects:
- kind: ServiceAccount
name: default
namespace: kube-system
适合自定义“shm”Namespace中的所有ServiceAccount:
subjects:
- kind: Group
name: system:serviceaccounts:shm
apiGroup: rbac.authorization.k8s.io
适合集群中所有ServiceAccount:
subjects:
- kind: Group
name: system:serviceaccounts
apiGroup: rbac.authorization.k8s.io
3、Authenticated 认证
适合所有经过认证的用户(1.5版本以上):
subjects:
- kind: Group
name: system:authenticated
apiGroup: rbac.authorization.k8s.io
适合所有未经认证的用户(1.5版本以上):
subjects:
- kind: Group
name: system:unauthenticated
apiGroup: rbac.authorization.k8s.io
适合所有用户(1.5版本以上):
subjects:
- kind: Group
name: system:authenticated
apiGroup: rbac.authorization.k8s.io
- kind: Group
name: system:unauthenticated
实战:创建一个用户只能管理 dev 空间
一、创建一个 devuser 的用户
useradd devuser
echo '123.com' | passwd devuser --stdin
二、创建证书
mkdir -p /kubernetes/ca/devuser ; cd /kubernetes/ca/devuser
vim devuser-csr.json
{
"CN": "devuser", //User
"hosts": ["192.168.168.11"], //[]代表所有主机使用
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s", //Group
"OU": "System"
}
]
}
三、下载证书生成工具
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
mv cfssl_linux-amd64 /usr/local/bin/cfssl
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
mv cfssl-certinfo_linux-amd64 /usr/local/bin/cfssl-certinfo
chmod +x /usr/local/bin/*
生成证书 cd /etc/kubernetes/pki
cfssl gencert -ca=ca.crt -ca-key=ca.key -profile=kubernetes /kubernetes/ca/devuser/devuser-csr.json | cfssljson -bare devuser
-ca=ca.crt #指定证书
-ca-key=ca.key #指定私钥
-profile=kubernetes /kubernetes/ca/devuser/devuser-csr.json #指定证书申请文件
-bare devuser #输出格式证书文件名devuser
2020/06/24 10:06:33 [INFO] generate received request
2020/06/24 10:06:33 [INFO] received CSR
2020/06/24 10:06:33 [INFO] generating key: rsa-2048
2020/06/24 10:06:34 [INFO] encoded CSR
2020/06/24 10:06:34 [INFO] signed certificate with serial number 65125129704757264070550525068465845596301305983
2020/06/24 10:06:34 [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").
四、设置集群用户 config 文件参数
①、设置集群环境变量
**export KUBE_APISERVER=“https://192.168.168.11:6443” **
②、设置 kubernetes 集群的 用户config文件
cd /kubernetes/ca/devuser/
kubectl config set-cluster kubernetes
–certificate-authority=/etc/kubernetes/pki/ca.crt
–embed-certs=true
–server=${KUBE_APISERVER}
–kubeconfig=devuser.kubeconfig
kubectl config set-cluster kubernetes \ #生成kubernetes的config文件
--certificate-authority=/etc/kubernetes/pki/ca.crt \ #指定CA证书
--embed-certs=true \ #是否加密认证
--server=${KUBE_APISERVER} \ #指定服务器地址信息
--kubeconfig=devuser.kubeconfig #创建出一个用户的 kubeconfig文件
成功后会出现一个 devuser.kubeconfig 文件
五、写入客户端认证参数
kubectl config set-credentials devuser
–client-certificate=/etc/kubernetes/pki/devuser.pem
–client-key=/etc/kubernetes/pki/devuser-key.pem
–embed-certs=true
–kubeconfig=devuser.kubeconfig
kubectl config set-credentials devuser \ #创建客户端 devuser的认证
--client-certificate=/etc/kubernetes/pki/devuser.pem \ #指定 devuser 的证书
--client-key=/etc/kubernetes/pki/devuser-key.pem \ #指定 devuser 的私钥
--embed-certs=true \ #开启证书认证
--kubeconfig=devuser.kubeconfig #指定写入到集群的 config 文件
六、写入上下文参数,绑定名称空间信息
创建 dev 的名称空间:kubectl create namespace dev
绑定 dev 名称空间
kubectl config set-context kubernetes
–cluster=kubernetes
–user=devuser
–namespace=dev
–kubeconfig=devuser.kubeconfig
七、Role/ClusterRole 的角色绑定
将 ClusterRole 的 admin 角色, RoleBinding绑定给 devuser 用户,绑定在 dev 名称空间下,拥有admin角色权限。
kubectl create rolebinding devuser-admin-binding --clusterrole=admin --user=devuser --namespace=dev
八、 devuser 用户的 K8S 上下文设置
①、将 devuser.kubeconfig 文件移动到自己的家目录下并赋权
mkdir -pv /home/devuser/.kube
cp devuser.kubeconfig /home/devuser/.kube
chown devuser:devuser -R /home/devuser/.kube
②、采用 devuser 用户登录 xshell: k8s-master 节点
[devuser@k8s-master ~]$ cd .kube/
[devuser@k8s-master .kube]$ mv devuser.kubeconfig config
③、设置 devuser 用户与 kubernetes 集群的默认上下文
[devuser@k8s-master .kube]$ kubectl config use-context kubernetes --kubeconfig=config
九、验证 devuser 用户 是否具有 dev 空间的所有权限
创建一个 nginx Pod
[devuser@k8s-master .kube]$ kubectl run nginx --image=nginx:1.9.1
查看其在哪个名称空间下运行
[devuser@k8s-master .kube]$ kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 11m
更多推荐
所有评论(0)