变更记录

版本号 作者 修订内容 发布日期
1.0 发布文档 2022-05-17

项目背景

  1. Kubernetes集群中所有资源的访问和变更都是通过Kubernetes APl Server RESTAPI来实现的,所以集群安全的关键点就在于如何识别并认证客户端身份(Authentication),以及随后访问权限的授权(Authorization)这两个关键问题。<br />Kubernetes集群提供了3种级别的客户端身份认证方式。
  • 最严格的HTTPS证书认证:基于CA根证书签名的双向数字证书认证方式。
  • HTTP Token认证:通过一个Token来识别合法用户。
  • HTTP Base认证:通过用户名+密码的方式认证。这种认证方式被报告有安全问题,在 Kubernetes v1.19版本被删除,问题链接

综上,我们采用前两种认证方式。

参考资料

  1. 官网资料:https://kubernetes.io/zh/docs/reference/access-authn-authz/authentication/#users-in-kubernetes
  2. Token Point的身份验证:https://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint
  3. 参考书籍:Kubernetes权威指南:从Docker到Kubernetes实践全接触(第2版)-2016.10-电工-P519-龚正,吴治辉,王伟 等.pdf
  4. 需求文档

    功能模块

    主要涉及到的功能是添加集群以及修改集群,用户可选择不同的添加或修改集群的方式。

  5. kubeconfig:用户需要获取到集群的kubeconfig文件从而实现添加或修改操作。

  6. Service Account:用户需要在集群中创建service account账号并绑定角色为其授予权限。

具体操作如下:

  1. #获取集群端点
  2. kubectl config view
  3. #创建一个名称空间,也可在default下
  4. kubectl create ns namespace
  5. #在kubectl命令行工具中执行create命令创建serviceaccount帐户test。
  6. kubectl create serviceaccount test -n default
  7. #将serviceaccount帐号加入到绑定的集群角色default-sa-crb中,权限是cluster-admin
  8. kubectl create clusterrolebinding default-sa-crb \
  9. --clusterrole=cluster-admin \
  10. --serviceaccount=default:test
  11. # 提取服务帐号token。
  12. kubectl describe secret -n default $(kubectl get secret -n default -o jsonpath="{.items[?(@.metadata.annotations['kubernetes\.io/service-account\.name']=='test')].metadata.name}")
  13. #访问api测试
  14. curl -k -XGET -H "Authorization: Bearer xxx" 'https://x.x.x.x:6443/api'

流程图

以下是添加集群的流程,修改集群类似。
多种集群认证方式逻辑设计 - 图1

时序图

  1. 使用http token的验证方式实现访问K8S-APIServer的效果,主要是依赖于kubernetes的自身特性。如下图,该图表示的是用户在获取到身份验证的token之后,即可使用token连接kubectl,在通过JWT认证后,就能成功获取到数据。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2639475/1652934444929-51a8396e-82c0-4d49-92ee-243fc8b02db3.png#clientId=uf697f2c7-f004-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=487&id=u83a0513a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=730&originWidth=889&originalType=binary&ratio=1&rotation=0&showTitle=false&size=73743&status=done&style=none&taskId=u893c8bcf-21ed-4716-a0c4-0bc9c05ac04&title=&width=592.6666666666666)

API 设计

url(不变)

  1. POST /clouldnative/v1/kubernetes_clusters
  2. PUT /clouldnative/v1/kubernetes_cluster/{clusterId}

接口参数修改

参数 描述 备注
authType kubernetes集群认证类型 0:未指定 1:kubeconfig认证 2:用户认证(删掉) 2:service account认证
authUserName 用户名
authUserPassowrd 用户密码
authServiceAccount kubernetes服务账号 这一项可以删去,因为JWT token中已经包含服务账号的信息
authServiceToken kubernetes服务令牌 这一项的可以支持两种类型,一是string类型,二是可以使用token文件
host kubernetes端点 新增

PS:解码JWT token,可以看到其中包含了服务账号信息等。
image.png

ok,加一个时序图
以添加集群为例:
多种集群认证方式逻辑设计 - 图3

编辑集群
多种集群认证方式逻辑设计 - 图4
类图
多种集群认证方式逻辑设计 - 图5
在更新集群信息之后,保护服务调了监控集群的方法,资源管理服务通知所有节点删除缓存的客户端,并构建新的客户端,通知cache进程对该集群重新cache,
但是它没有把这个新的客户端给它存到etcd里
而是将集群的clusterId设置租约打上tag放到etcd里,监控集群时先要在集合里查这个clusterId,如果有的话就继续监控,

验证集群连通性
多种集群认证方式逻辑设计 - 图6