Kubernetes环境鉴权与自动发现

优采云 发布时间: 2022-09-03 04:50

  Kubernetes环境鉴权与自动发现

  概览文章中提到了k8s的鉴权模式,简单回顾下:

  有细心的小伙伴指出,RBAC的角色可以作为ABAC的属性来配置。感谢小伙伴指正,ABAC可以更细粒度的控制权限,相应配置起来也更复杂。

  kubernetes 鉴权

  选定RBAC模式后,关于角色,有Role和ClusterRole,对应对象的绑定分别为: RoleBinding 和 ClusterRoleBinding。Role创建后归属于特定的namespace,一般与特定namespace的权限绑定,而ClusterRole 不属于任何namespace,通常与一组权限绑定。

  ClusterRole通常用于

  官方文档推荐,如果在单个namespace内定义角色则使用Role,如果是定义集群范围的角色,则使用ClusterRole。要监控kubernetes组件和集群范围内业务以及为了通用性,所以我们选择ClusterRole 和 ClusterRoleBinding。

  权限盘点

  我们来盘点需要监控的对象。

  不论需要多少权限, 一个原则就是按需申请,最小化申请。指标采集都是读权限,基本都是get、list。自动发现要达到发现及时,需要watch endpoints变化。

  如何确定资源对象的api groups和version呢?可以使用kubectl api-resources -o wide来查看。新版本的APIVERSION包含了api groups和version信息。

  权限配置

  

  基本的权限配置如下

    - apiGroups: [""]<br style="box-sizing: border-box;" />    resources:<br style="box-sizing: border-box;" />      - pods<br style="box-sizing: border-box;" />      - nodes<br style="box-sizing: border-box;" />      - nodes/stats<br style="box-sizing: border-box;" />      - nodes/metrics<br style="box-sizing: border-box;" />      - nodes/proxy<br style="box-sizing: border-box;" />      - services<br style="box-sizing: border-box;" />      - endpoints<br style="box-sizing: border-box;" />    verbs: ["get", "list", "watch"]<br style="box-sizing: border-box;" />  - nonResourceURLs: ["/metrics"]<br style="box-sizing: border-box;" />    verbs: ["get"]<br style="box-sizing: border-box;" />

  将权限填充到ClusterRole中

  apiVersion: rbac.authorization.k8s.io/v1<br style="box-sizing: border-box;" />kind: ClusterRole<br style="box-sizing: border-box;" />metadata:<br style="box-sizing: border-box;" />  annotations: {}<br style="box-sizing: border-box;" />  labels:<br style="box-sizing: border-box;" />    app: n9e<br style="box-sizing: border-box;" />    component: categraf<br style="box-sizing: border-box;" />  name: categraf-role<br style="box-sizing: border-box;" />rules:<br style="box-sizing: border-box;" />  - apiGroups: [""]<br style="box-sizing: border-box;" />    resources:<br style="box-sizing: border-box;" />      - nodes<br style="box-sizing: border-box;" />      - nodes/stats<br style="box-sizing: border-box;" />      - nodes/metrics<br style="box-sizing: border-box;" />      - nodes/proxy<br style="box-sizing: border-box;" />      - services<br style="box-sizing: border-box;" />      - endpoints<br style="box-sizing: border-box;" />      - pods<br style="box-sizing: border-box;" />    verbs: ["get", "list", "watch"]<br style="box-sizing: border-box;" />  - nonResourceURLs: ["/metrics"]<br style="box-sizing: border-box;" />    verbs: ["get"]<br style="box-sizing: border-box;" />

  有了ClusterRole, 创建ClusterRoleBinding之前,还需要一个ServiceAccount,用于存储api的访问凭据,这个凭据可以以token形式挂载到Pod内。也可以直接解析用于Pod外部使用。

  apiVersion: v1<br style="box-sizing: border-box;" />kind: ServiceAccount<br style="box-sizing: border-box;" />metadata:<br style="box-sizing: border-box;" />  annotations: {}<br style="box-sizing: border-box;" />  labels:<br style="box-sizing: border-box;" />    app: n9e<br style="box-sizing: border-box;" />    component: categraf<br style="box-sizing: border-box;" />  name: categraf-serviceaccount<br style="box-sizing: border-box;" />  namespace: ${NAMESPACE}<br style="box-sizing: border-box;" />

  注意,ServiceAccount需要指定namespace,需要跟categraf即将部署的namespace保持一致。利用ClusterRoleBinding 将ClusterRole和ServiceAccount关联起来

  apiVersion: rbac.authorization.k8s.io/v1<br style="box-sizing: border-box;" />kind: ClusterRoleBinding<br style="box-sizing: border-box;" />metadata:<br style="box-sizing: border-box;" />  annotations: {}<br style="box-sizing: border-box;" />  labels:<br style="box-sizing: border-box;" />    app: n9e<br style="box-sizing: border-box;" />    component: categraf<br style="box-sizing: border-box;" />  name: categraf-rolebinding<br style="box-sizing: border-box;" />roleRef:<br style="box-sizing: border-box;" />  apiGroup: rbac.authorization.k8s.io<br style="box-sizing: border-box;" />  kind: ClusterRole<br style="box-sizing: border-box;" />  name: categraf-role<br style="box-sizing: border-box;" />subjects:<br style="box-sizing: border-box;" />- kind: ServiceAccount<br style="box-sizing: border-box;" />  name: categraf-serviceaccount<br style="box-sizing: border-box;" />  namespace: ${NAMESPACE}<br style="box-sizing: border-box;" />

  现在ClusterRoleBinding 已经将权限和票据关联起来了。备注:创建完成后,ServiceAccount会自动创建一个secret,这个secret 会自动挂载到后续创建的categraf pod内。

  可以通过kubectl get secrets -n monitoring categraf-serviceaccount-token-xxxx -o jsonpath={.data.token} | base64 -d获得token内容,这样通过curl -s -k -H "Authorization: Bearer $TOKEN"即可访问apiserver,用来调试。

  kubernetes 组件的服务发现1. 监控对象部署在pod内

  当创建service(带选择符)时,k8s会自动为pod创建endpoint,这样service和pod就关联起来了。利用这个特性,我们可以及时发现pod的变化。如果组件是部署在pod内,我们就可以直接利用这个特性进行采集。比如kubeadm部署的集群,apiserver 本身就已经创建了对应的service。

  ...<br style="box-sizing: border-box;" />  - job_name: "apiserver"<br style="box-sizing: border-box;" />    metrics_path: "/metrics"<br style="box-sizing: border-box;" />    kubernetes_sd_configs:<br style="box-sizing: border-box;" />      - role: endpoints # 看这里<br style="box-sizing: border-box;" />    scheme: https<br style="box-sizing: border-box;" />    tls_config:<br style="box-sizing: border-box;" />      insecure_skip_verify: true<br style="box-sizing: border-box;" />    authorization:<br style="box-sizing: border-box;" />      credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token<br style="box-sizing: border-box;" />    relabel_configs:<br style="box-sizing: border-box;" />      - source_labels:<br style="box-sizing: border-box;" />          [<br style="box-sizing: border-box;" />            __meta_kubernetes_namespace,<br style="box-sizing: border-box;" />            __meta_kubernetes_service_name,<br style="box-sizing: border-box;" />            __meta_kubernetes_endpoint_port_name,<br style="box-sizing: border-box;" />          ]<br style="box-sizing: border-box;" />        action: keep<br style="box-sizing: border-box;" />        regex: default;kubernetes;https<br style="box-sizing: border-box;" />...<br style="box-sizing: border-box;" />

  

  2. 监控对象部署在物理机 (文件服务发现)

  如果组件是以二进制方式部署在物理机,又没有其他服务发现的手段。那可以利用prometheus类似的文件服务发现,当组件有变更时,直接在目录中添加删除包含目标信息的文件就好了。这里多提一点,之前有小伙伴提出,categraf提供一个注册接口,服务向categraf注册,然后categraf去拉注册目标指标。categraf本身的定位是一个采集器,没有服务发现的功能。提一个最简单的问题,如果categraf挂了重启,但是采集目标没有发现,这里就会有很多数据不能被采集了。再有就是集中式拉取方式,提供push接口,会把业务和采集器耦合更深了。这种方式 并不可取。

  ....<br style="box-sizing: border-box;" />  - job_name: 'coredns'<br style="box-sizing: border-box;" />    file_sd_configs:<br style="box-sizing: border-box;" />    - files:<br style="box-sizing: border-box;" />      - /home/work/prometheus/file_sd_config/*.json<br style="box-sizing: border-box;" />...<br style="box-sizing: border-box;" />

  在file_sd_config目录下放一个json文件,如下:

  [<br /> {<br /> "labels": {<br /> "job": "coredns"<br /> },<br /> "targets": [<br /> "172.16.6.160:9153"<br /> ]<br /> }<br />]

  等增加新的coredns后,只需要再增加一份json配置(这里只是为了举例说明,直接修改coredns.json效果一样)。不需要再做任何其他操作

  [<br /> {<br /> "labels": {<br /> "job": "coredns"<br /> },<br /> "targets": [<br /> "172.16.0.85:9153"<br /> ]<br /> }<br />]

  3. 其他服务发现方式

  采集器categraf集成了prometheus的agent mode模式, 如果你使用了其他服务发现方式, 例如consul,则可以和categraf无缝对接了。除此之外,还支持docker_swarm_sd_configs,docker_sd_config, dns_sd_configs, http_sd_configs等prometheus所支持的服务发现方式。

  关于作者

  本文作者是孔飞,来自快猫星云( ),是Kubernetes和Prometheus专家,快猫团队致力于让监控更简单,为企业提供稳定性保障的产品,也提供高性价比的夜莺监控技术支持服务,有兴趣的小伙伴欢迎联系下文微信。

  关于夜莺监控

  夜莺监控是一款开源云原生监控分析系统,采用 All-In-One 的设计,集数据采集、可视化、监控告警、数据分析于一体,与云原生生态紧密集成,提供开箱即用的企业级监控分析和告警能力,已有众多企业选择将 Prometheus + AlertManager + Grafana 的组合方案升级为使用夜莺监控。夜莺监控,由滴滴开发和开源,并于 2022 年 5 月 11 日,捐赠予中国计算机学会开源发展委员会(CCF ODC),为 CCF ODC 成立后接受捐赠的第一个开源项目。

  点击原文可访问夜莺站点

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线