1.1 安全框架
1.1.1 认证框架
基础知识
资源操作
用户访问k8s业务应用的流程:
方法一:无需api_server认证
用户 -- ingress|service -- pod
方法二:基于api_server认证
管理k8s平台上各种应用对象
认证流程
简介
对APIServer的访问一般都要经过的三个步骤,认证(Authn)+授权(Authz)、准入控制(Admission),
它也能在一定程度上提高安全性,不过更多是资源管理方面的作用。
注意:认证和授权功能都是以插件化的方式来实现的,这样可以最大化的用户自定义效果。
认证(Authn)
对用户身份进行基本的认证,只允许被当前系统许可的人进入集群内部
授权(Authz)
不同的用户可以获取不同的资源操作权限,比如普通用户、超级用户、等
准入控制(Admission)
类似于审计,主要侧重于操作动作的校验、语法规范的矫正等写操作场景。
解析
左侧:
对于k8s来说,它主要面对两种用户:
普通人类用户(交互模式) - User Account
集群内部的pod用户(服务进程) - Service Account
中间:
每个部分都是以插件的方式来整合到 k8s 集群环境中:
- 认证和授权是按照插件的顺序进行依次性的检测,并且遵循 "短路模型" 的认证方式
所谓的"短路"即,失败的时候,到此结束,后续的规则不会进行。
- 准入控制 由于仅用户写操作场景,所以它不遵循 "短路模型",而是会全部检测
原因在于,它要记录为什么不执行,原因是什么,方便后续审计等动作。
1.1.2 框架解读
流程解读
认证
认证用户
在我们的认证范围中,有一个术语叫Subject,它表示我们在集群中基于某些规则和动作尝试操作的对象,
在k8s集群中定义了两种类型的subject资源:
User Account:
有外部独立服务进行管理的,对于用户的管理集群内部没有一个关联的资源对象
如果需要操作k8s资源,需要集群内部证书的认证签名。
Service Account
通过Kubernetes API 来管理的一些用户帐号,和 namespace 进行关联的
一般是内部资源对象操作资源的一种方式
用户组
单个控制用户的权限台繁琐,可以借助于用户组的机制实现批量用户的自动化管理,主要有以下几种
system:unauthenticated
未能通过任何一个授权插件检验的账号的所有未通过认证测试的用户统一隶属的用户组;
system:authenticated
认证成功后的用户自动加入的一个专用组,用于快捷引用所有正常通过认证的用户账号;
system:serviceaccounts
所有名称空间中的所有ServiceAccount对象
system:serviceaccounts:<namespace>
特定名称空间内所有的ServiceAccount对象
认证方式
kubernetes的认证方式主要有两种:
证书认证 - 本质上就是TLS双向认证
令牌认证 - 大量手动配置TLS认证比较麻烦,可以将证书生成token进行间接使用。
授权
授权主要是在认证的基础上,用于对集群资源的访问控制权限设置,通过检查请求包含的相关属性值,
与相对应的访问策略相比较,API请求必须满足某些策略才能被处理。常见授权机制有:
Node
主要针对节点的基本通信授权认证,比如kubelet的正常通信。
ABAC(Attribute Based Access Control):
基于属性的访问控制,与apiserver服务的本地策略规则紧密相关,一旦变动需要重启。
RBAC(Role Based Access Control):
基于角色的访问控制,这是1.6+版本主推的授权策略,可以使用API自定义角色和集群角色,并将角色和特定的用户,用户组,Service Account关联起来,可以用来实现多租户隔离功能(基于namespace资源)
准入控制
准入控制(Admission Control),实际上是一个准入控制器插件列表,发送到APIServer的请求都需要经过这个列表中的每个准入控制器插件的检查,
如果某一个控制器插件准入失败,就准入失败;它主要涉及到pod和容器对特定用户和特定权限之间的关联关系。
比如操作的对象是否存在依赖关系、被操作的对象是否能够增删改查等限制。
对象梳理
资源对象
对象简介
认证对象:SA、token
授权对象:Role、ClusterRole、RoleBinding、ClusterRoleBinding
准入对象:LimitRanger、ResourceQuota、PodSecurityPolicy等
1.2 认证实践
1.2.1 用户实践
SA实践
集群内部的pod用户(服务进程) - Service Account
资源属性
apiVersion: v1 # ServiceAccount所属的API群组及版本
kind: ServiceAccount # 资源类型标识
metadata:
name <string> # 资源名称
namespace <string> # ServiceAccount是名称空间级别的资源
automountServiceAccountToken <boolean> # 是否让Pod自动挂载API令牌
secrets <[]Object> # 以该SA运行的Pod所要使用的Secret对象组成的列表
apiVersion <string> # 引用的Secret对象所属的API群组及版本,可省略
kind <string> # 引用的资源的类型,这里是指Secret,可省略
name <string> # 引用的Secret对象的名称,通常仅给出该字段即可
namespace <string> # 引用的Secret对象所属的名称空间
uid <string> # 引用的Secret对象的标识符;
imagePullSecrets <[]Object> # 引用的用于下载Pod中容器镜像的Secret对象列表
name <string> # docker-registry类型的Secret资源的名称
命令解析
命令格式:kubectl create serviceaccount NAME [--dry-run] [options]
作用:创建一个"服务账号"
参数详解
--dry-run=false 模拟创建模式
--generator='serviceaccount/v1' 设定api版本信息
-o, --output='' 设定输出信息格式,常见的有:
json|yaml|name|template|...
--save-config=false 保存配置信息
--template='' 设定配置模板文件
简单实践
创建专属目录
[root@k8s-master1 ~]# mkdir /data/kubernetes/secure -p; cd /data/kubernetes/secure
手工创建SA账号
[root@k8s-master1 /data/kubernetes/secure]# kubectl create serviceaccount mysa
serviceaccount/mysa created
检查效果
[root@k8s-master1 /data/kubernetes/secure]# kubectl get sa mysa
NAME SECRETS AGE
mysa 1 9s
资源清单创建SA
[root@k8s-master1 /data/kubernetes/secure]# 01_k8s_secure_sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: test
---
apiVersion: v1
kind: Pod
metadata:
name: nginx-web
spec:
containers:
- name: nginx-web
image: reg.test.com/test/nginx_web:v0.1
serviceAccountName: test
应用资源清单
[root@k8s-master1 /data/kubernetes/secure]# kubectl apply -f 01_k8s_secure_sa.yaml
serviceaccount/test created
pod/nginx-web created
查看资源属性
[root@k8s-master1 /data/kubernetes/secure]# kubectl describe pod nginx-web
Name: nginx-web
...
Containers:
nginx-web:
...
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-wqb6w (ro)
...
结果显示:
用户信息挂载到容器的 /var/run/secrets/kubernetes