打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Kubernetes的安全三板斧
如何保证`Kubernetes`系统安全?我们可以从以下三大部分进行学习、研究和设计:


// Apiserver //

首当其冲的就是`apiserver`,他是系统安全三板斧中的第一道关卡,其作用为:who?谁能进入我们的`kubernetes`集群,这个谁可以是客户端用户、应用程序,也可以是集群中的`node`节点。

你可能对后半句话有些疑虑。防范外部的访问我是知道的,为什么还要防范集群内部的请求呢?容我先来举个栗子,如果你了解、运维过`spring cloud`,那你应该会碰到这个难题:

每个环境我们都有注册中心`eureka`,那我们如何保障应用不会出现乱注册的情况呢? 比如:生产环境的应用注册到测试环境的`eureka`?测试环境的应用注册到生产环境的`eureka`?无论哪个情况发生,都是很致命的!

也许你会考虑,借助一系列配置管理的规范或者`ITIL`流程,又或者基于人员角色的分而治之来规避这个情况的发生,但这都是治标不治本的!重点在于缺少双向认证的功能!换句话来说就是:谁能注册到我这里来,我是要有验证的,而不是随便让你可以进行服务的注册。

这个双向认证的思想,在`kubernetes`中尤为重要,不是所有知道我们集群主节点信息或者`join`信息的节点都可以肆意加入集群,这是很有风险的。

`kubernetes`的`bootstrap token`引导令牌(会在后面章节讲解)就此诞生!他会向已知可信任的`node`节点颁发一个引导令牌,其中会有一个失效期,可能是12小时,也可能是1天,这取决于集群管理员的配置。   他会告诉`node`节点,你必须要在这段时间内加入集群,否则我就不信任你了,你也就不能再加入集群了。同时`apiserver`也通过各种`https`证书,保证了集群内外部的数据交互的安全。

// RBAC //

接着就是系统安全三板斧中的第2道关卡:RBAC!

基于角色的访问控制(`Role-Based Access Control`, 即”RBAC”)使用”rbac.authorization.k8s.io” API Group实现授权决策,允许管理员通过`Kubernetes API`动态配置策略,其职责为:what?对于已知的客户端用户,他们需要什么的权限,他们能够操作什么类型的资源,这就是他所负责的事情了。

`RBAC`的配置顺序:

 首先,定义一个服务账号`service account`,也就是定义角色;

✔ 接着,定义一个`role`策略,比如:允许查看`pod`,禁止`describe`pod等;

 最后,将定义好的角色和`role`策略进行绑定(`binding`)即可。


`RBAC`中配置生效的经验之谈:


 `role`+`rolebinding`=作用于对应名称空间的策略;

✔ `clusterrole`+`clusterrolebinding`=作用域集群级别的策略;

 `clusterrole`+`rolebinding`=作用于对应名称空间的策略,作用同第一条。其好处是更灵活更简洁。


如果你配置过jumpserver的用户组、机器组和授权,想必很好理解。

// Admission Controller //

最后,把手整个系统安全的就是`Admission Controller`准入控制器了。 

对于已知用户,他可以管理(可能是查看、也可能是新建、也可能会删除等等)其命名空间或者对应集群下的所有授权资源。但这里有一个问题!不知道,你想到了没有?

如何去校验用户的操作是否合规呢?例如:是否在`yaml`中配置了`limits`和`requets`字段,又或者研发人员配置的这两个字段是否合理?

这也是十分重要的一个环节,对于初创公司或者是`kubernetes`初建设团队,这个环节可能也可容许暂时被忽略,大家基于一定的自觉、团队研发和上线流程的规范,来软限制这点。

但当你的团队、集群越来越大的时候,`Admission Controller`准入控制器的上线和把控是缺一不可的!

// 实战:RBAC //

以下所有操作都基于创建的`ilinux`用户进行,并且每个操作之前需要删除之前配置过的权限,否则会相互影响

1.Role+RoleBinding
  
应用场景:某个名称空间级别的权限授权
我们先编辑`role:res-reader.yaml`,定义规则为:`default`名称空间下,只能`get`、`list`和`watch`相关资源:

kind: Role #名称空间权限apiVersion: rbac.authorization.k8s.io/v1metadata: namespace: default #只能读取default名称空间下的对应规则 name: res-readerrules:- apiGroups: [''] # '' 表示核心群组:core API group resources: ['pods', 'pods/log', 'services'] verbs: ['get', 'list', 'watch']

然后我们来定义授权绑定`rolebinding:ilinux-res-reader.yaml`,其作用是将`ilinux`用户,绑定到我们上面定义的名为`res-reader`的权限上。

kind: RoleBinding                 #名称空间级别权限绑定;ClusterRoleBinding为集群级别的权限绑定apiVersion: rbac.authorization.k8s.io/v1metadata:  name: ilinux-res-reader                   #增加可读性,命名规则:<用户>-<权限>  namespace: defaultsubjects:- kind: User  name: ilinux  apiGroup: rbac.authorization.k8s.ioroleRef:  kind: Role  name: res-reader  apiGroup: rbac.authorization.k8s.io

依次`apply`配置文件,发现`ilinux`用户在`default`名称空间下有对应`pods`, `pods/log`, `services`的对应权限,和预期一样

[root@centos-1 RBAC]# kubectl get pod --kubeconfig=/tmp/ilinux.kubeconfig NAME READY STATUS RESTARTS AGEngx-new-cb79d555-hfc7h 1/1 Running 0 10d[root@centos-1 RBAC]# kubectl get service --kubeconfig=/tmp/ilinux.kubeconfigNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEkubernetes ClusterIP 10.96.0.1 <none> 443/TCP 11d[root@centos-1 RBAC]# kubectl get service --kubeconfig=/tmp/ilinux.kubeconfig -n ingress-nginxError from server (Forbidden): services is forbidden: User 'ilinux' cannot list resource 'services' in API group '' in the namespace 'ingress-nginx'
  
2.ClusterRole+ClusterRoleBinding

应用场景:k8s集群级别的权限授权
编辑`ClusterRole:cluster-res-reader.yaml`。


kind: ClusterRole             #集群范围权限apiVersion: rbac.authorization.k8s.io/v1metadata:  name: cluster-res-readerrules:- apiGroups: ['']   # '' 表示核心群组:core API group  resources: ['pods', 'pods/log', 'services']  verbs: ['get', 'list', 'watch']

编辑`ClusterRoleBinding:cluster-ilinux-res-reader.yaml`。

kind: ClusterRoleBinding #ClusterRoleBinding为集群级别的权限绑定apiVersion: rbac.authorization.k8s.io/v1metadata: name: cluster-ilinux-res-reader #增加可读性,命名规则:<用户>-<权限>subjects:- kind: User name: ilinux apiGroup: rbac.authorization.k8s.ioroleRef: kind: ClusterRole name: cluster-res-reader apiGroup: rbac.authorization.k8s.io

依次`apply`配置文件,并通过以下命令观察权限生成情况。

[root@centos-1 RBAC]# kubectl get clusterrole[root@centos-1 RBAC]# kubectl get clusterrolebinding

这时,我们发现`ilinux`用户已经具有集群级别(所有名称空间)的对应权限。

[root@centos-1 RBAC]# kubectl get service --kubeconfig=/tmp/ilinux.kubeconfig -n ingress-nginxNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEnginx-ingress-controller NodePort 10.99.160.254 <none> 80:30080/TCP,443:30443/TCP 26h [root@centos-1 RBAC]# kubectl get service --kubeconfig=/tmp/ilinux.kubeconfig NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEkubernetes ClusterIP 10.96.0.1 <none> 443/TCP 11d

3.ClusterRole+RoleBinding

应用场景:交叉使用,其中`ClusterRole`策略会降级成`rolebinding`名称空间级别的策略,效果和`role+rolebinding`一样。

好处:在名称空间很多的时候,重复权限的配置文件会少一半,而且更灵活。

使用上面的`ClusterRole`(`cluster-res-reader.yaml`),并`apply-f`,编辑`rolebinding`:`cluster-default-ilinux-res-reader.yaml`。

kind: RoleBinding                 #名称空间级别权限绑定;ClusterRoleBinding为集群级别的权限绑定apiVersion: rbac.authorization.k8s.io/v1metadata:  name: cluster-default-ilinux-res-reader                   #增加可读性,命名规则:<用户>-<权限>  namespace: defaultsubjects:- kind: User  name: ilinux  apiGroup: rbac.authorization.k8s.ioroleRef:  kind: ClusterRole  name: cluster-res-reader  apiGroup: rbac.authorization.k8s.io

测试和预期一样,`ClusterRole`降级成`default`名称空间的权限了

[root@centos-1 RBAC]# kubectl get service --kubeconfig=/tmp/ilinux.kubeconfig NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEkubernetes ClusterIP 10.96.0.1 <none> 443/TCP 11d [root@centos-1 RBAC]# kubectl get service --kubeconfig=/tmp/ilinux.kubeconfig -n ingress-nginxError from server (Forbidden): services is forbidden: User 'ilinux' cannot list resource 'services' in API group '' in the namespace 'ingress-nginx'
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
容器编排系统K8s之访问控制--RBAC授权
Kubernetes基础:RBAC权限设置的两种方式
创建和分配Kubernetes Pod安全策略
多k8s集群管理
二进制部署kubernetes1.8.0集群高可用环境
Kubernetes v1.10.x HA 全手动安装教程(TL;DR)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服