kubernetes initializer 功能的使用方法: 在 Pod 等 Resource 落地前进行修改

Tags: kubernetes 

目录

说明

在研究通过LXCFS,在容器内显示容器的CPU、内存状态的时候,遇到了Kubernetes Initializers,学习一下。

注意Kubernetes InitializersKubernetes Init Containers是不同的,前者可以修改Pod的定义,后者是在Pod中正式容器启动前,进行一些准备工作。两者发生作用的时机也不一样。

用途

Kubernetes Initializers可以在pod/的pending阶段对pod进行修改,譬如注入新的容器、挂载volume等。

例如通过LXCFS,在容器内显示容器的CPU、内存状态中,就是用Initializer的方式,为每个pod自动挂载了lxcfs维护的/proc文件。

Initializer功能开启

在Kubernetes 1.13中initializers还是一个alpha特性,需要在Kube-apiserver中添加参数开启。

这里使用的是kubernets 1.12,设置方法是一样的:

--enable-admission-plugins="Initializers,NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota"
--runtime-config=admissionregistration.k8s.io/v1alpha1

--enable-admission-plugins--admission-control互斥,如果同时设置,kube-apiserver启动报错:

error: [admission-control and enable-admission-plugins/disable-admission-plugins flags are mutually exclusive, 
enable-admission-plugins plugin "--runtime-config=admissionregistration.k8s.io/v1alpha1" is unknown]

InitializerConfiguration

InitializerConfiguration资源中定义了一组的initializers

每个initializer有一个名字和多个规则,规则中是它要作用的资源,例如下面的initializers中只有一个initializer,名称为podimage.example.com,作用于v1版本的pods。


apiVersion: admissionregistration.k8s.io/v1alpha1
kind: InitializerConfiguration
metadata:
  name: example-config
initializers:
  # the name needs to be fully qualified, i.e., containing at least two "."
  - name: podimage.example.com
    rules:
      # apiGroups, apiVersion, resources all support wildcard "*".
      # "*" cannot be mixed with non-wildcard.
      - apiGroups:
          - ""
        apiVersions:
          - v1
        resources:
          - pods

在kubernets中创建了上面的initializers之后,新建的pod在pending阶段,metadata中会添加一个initializer列表:

  metadata:
    creationTimestamp: 2019-01-09T08:56:36Z
    generateName: echo-7cfbbd7d49-
    initializers:
      pending:
      - name: podimage.example.com

注意需要加上参数--include-uninitialized=true才能看到处于这个阶段的Pod:

 ./kubectl.sh -n demo-echo get pod --include-uninitialized=true -o yaml

metadata中initializers列表不为空的Pod,处于正在等待初始化状态,需要部署一个initializer controller对处于这个阶段中的pod完成初始化后, pod才能退出pending状态。。

initializer controller需要自己根据需要实现。

Initializer Controller

initializer controller监听指定类型的resource,当发现有新创建的resouce创建时,通过检查resource的metadata中的initializer名单,决定是否要对resource进行初始化设置,并且在完成设置之后,需要将对应的initializer名单从resource的metadata中删除,否则resource就一直处于等待初始化设置的状态。

具体实现可以参考lxcfs-initializer

如果有多个InitializerConfiguration和多个Initializer Controller,会怎样?

没有在文档中找到具体的说明,k8s的文档中Initializer章节的内容很少,这里通过实验,判断一下。

创建了两个不同名的但是包含相同rule的InitializerConfiguration:

apiVersion: admissionregistration.k8s.io/v1alpha1
kind: InitializerConfiguration
metadata:
  name: example-config
initializers:
  # the name needs to be fully qualified, i.e., containing at least two "."
  - name: podimage.example.com
    rules:
      # apiGroups, apiVersion, resources all support wildcard "*".
      # "*" cannot be mixed with non-wildcard.
      - apiGroups:
          - ""
        apiVersions:
          - v1
        resources:
          - pods

apiVersion: admissionregistration.k8s.io/v1alpha1
kind: InitializerConfiguration
metadata:
  name: example-config-2
initializers:
  # the name needs to be fully qualified, i.e., containing at least two "."
  - name: podimage-2.example.com rules:
      # apiGroups, apiVersion, resources all support wildcard "*".
      # "*" cannot be mixed with non-wildcard.
      - apiGroups:
          - ""
        apiVersions:
          - v1
        resources:
          - pods
  - name: podimage.example.com
    rules:
      # apiGroups, apiVersion, resources all support wildcard "*".
      # "*" cannot be mixed with non-wildcard.
      - apiGroups:
          - ""
        apiVersions:
          - v1
        resources:
          - pods

Pod中的metadata是这样的:

  metadata:
    creationTimestamp: 2019-01-10T04:03:12Z
    generateName: echo-7cfbbd7d49-
    initializers:
      pending:
      - name: podimage.example.com
      - name: podimage-2.example.com
      - name: podimage.example.com

之后又通过调整InitializerConfiguration的名称排序、创建的先后顺序、内部的rules的顺序,多次试验之后发现,多个InitializerConfiguration的在metadata中是按照它们的名称排序的,和创建时间无关。

每个InitializerConfiguration中的rules在metadata中顺序与它们定义的顺序一致。

根据lxcfs-initializer的实现以及k8s的文档,Initializer Controller对目标Resource完成设置之后,需要从metadata中移除对应的Initializer。

如果定义了多个Initializer,并且有多个Initializer Controller各自负责不同的Initializer,这时候需要小心设计,既要防止“漏掉”应当处理的Resource,导致Resource长期不落地,又要防止已经被删除的Initializer又被重新写上了,重复处理时出现错误。

根据现在掌握的信息,目前比较稳妥的做法是,将多个Initializer设计为顺序无关,谁先执行都可以,否则只有创建一个InitializerConfiguration,rules的顺序就是Initiliazer的顺序。只设计一个Initializer Controller,或者将多个Initializer Controller设计成串行执行,让它们监测Resource的创建和变化,不仅仅是刚创建,否则一些Initializer可能被漏掉。

lxcfs-initializer这个Initializer只关心ADD事件,如果同时有其它的Initializer Controller存在,可能会漏掉一些Resource。

_, controller := cache.NewInformer(includeUninitializedWatchlist, &v1.Deployment{}, resyncPeriod,
	cache.ResourceEventHandlerFuncs{
		AddFunc: func(obj interface{}) {
			err := initializeDeployment(obj.(*v1.Deployment), c, clientset)
			if err != nil {
				log.Println(err)
			}
		},
	},
)

参考

  1. Kubernetes之路 2 - 利用LXCFS提升容器资源可见性
  2. Kubernetes Initializers
  3. 通过LXCFS,在容器内显示容器的CPU、内存状态
  4. Kubernetes Init Containers
  5. lxcfs-initializer

kubernetes

  1. Prometheus 采集 Kubernetes 中的 pod 的 metrics 的方法
  2. kubernetes configmap 热加载,inotifywatch 监测文件触发热更新
  3. kubernetes 百变定制: 支持的扩展点和扩展方法(api/crd/plugin...)
  4. kubernetes 调度组件 kube-scheduler 1.16.3 源代码阅读指引
  5. kubernetes 代码中的 k8s.io 是怎么回事?
  6. 旌旗招展,向网格而行!
  7. 《不一样的 双11 技术,阿里巴巴经济体云原生实践》阅读笔记
  8. kubernetes ingress-nginx 启用 upstream 长连接,需要注意,否则容易 502
  9. ingress-nginx 的限速功能在 nginx.conf 中的对应配置
  10. kubernetes 中的容器设置透明代理,自动在 HTTP 请求头中注入 Pod 信息
  11. kubernetes ingress-nginx 的测试代码(单元测试+e2e测试)
  12. kubernetes ingress-nginx http 请求复制功能与 nginx mirror 的行为差异
  13. kubernetes 基于 openresty 的 ingress-nginx 的状态和配置查询
  14. Kubernetes ingress-nginx 0.25 源代码走读笔记
  15. kubernetes ingress-nginx 的金丝雀(canary)/灰度发布功能的使用方法
  16. kubernetes code-generator 用法: 生成 kubernetes-style 的 api 和 client 代码
  17. kubernetes 操作命令 kubectl 在 shell 中的自动补全配置
  18. flannel ip 地址段扩容方法
  19. kubernetes 组件 kube-proxy 的 IPVS 功能的使用
  20. lxcfs 是什么? 怎样通过 lxcfs 在容器内显示容器的 CPU、内存状态
  21. kubernetes initializer 功能的使用方法: 在 Pod 等 Resource 落地前进行修改
  22. kubernetes 版本特性: 新特性支持版本和组件兼容版本
  23. kubernetes API 与 Operator: 不为人知的开发者战争(完整篇)
  24. kubernetes 1.12 从零开始(七): kubernetes开发资源
  25. kubernetes 1.12 从零开始(六): 从代码编译到自动部署
  26. kubernetes 网络方案 Flannel 的学习笔记
  27. kubernetes 1.12 从零开始(五): 自己动手部署 kubernetes
  28. kubernetes 1.12 从零开始(四): 必须先讲一下基本概念
  29. kubernetes 1.12 从零开始(三): 用 kubeadm 部署多节点集群
  30. kubernetes 1.12 从零开始(二): 用 minikube 部署开发测试环境
  31. kubernetes 1.12 从零开始(一): 部署环境准备
  32. kubernetes 1.12 从零开始(零): 遇到的问题与解决方法
  33. kubernetes 1.12 从零开始(初): 课程介绍与官方文档汇总
  34. 通过Prometheus查询计算Kubernetes集群中的容器CPU、内存使用率等指标
  35. 使用 grafana 和 prometheus 监控 kubernetes 集群状态
  36. 一些比较有意思的Kubernetes周边产品
  37. Borg论文阅读笔记
  38. kubelet下载pod镜像时,docker口令文件的查找顺序
  39. kubernetes 的 Client Libraries 的使用
  40. kubernetes的网络隔离networkpolicy
  41. kube-router的源码走读
  42. 使用calico的ipip模式解决k8s的跨网段通信
  43. kubernetes的调试方法
  44. kubernetes 与 calico 的衔接过程
  45. 怎样理解 kubernetes 以及微服务?
  46. kubernetes中部署有状态的复杂分布式系统
  47. kubernetes的apiserver的启动过程
  48. kubernetes的api定义与装载
  49. kubernetes的federation部署,跨区Service
  50. kubernetes的编译、打包、发布
  51. kubernetes的第三方包的使用
  52. kubernetes的Storage的实现
  53. kubernetes 的 Apiserver 的 storage 使用
  54. kubernetes的Controller-manager的工作过程
  55. kubernetes的Client端Cache
  56. kubernetes 的 Apiserver 的工作过程
  57. kubernetes的CNI插件初始化与Pod网络设置
  58. kubernetes的Pod变更过程
  59. kubernetes的kubelet的工作过程
  60. kuberntes 的 Cmdline 实现
  61. kubernetes的Pod内挂载的Service Account的使用方法
  62. kubernetes的社区资源与项目参与方式
  63. kubernetes的Kube-proxy的转发规则分析
  64. kubernetes的基本操作
  65. kubernetes在CentOS上的集群部署
  66. kubernetes在CentOS上的All In One部署
  67. 怎样选择集群管理系统?

推荐阅读

Copyright @2011-2019 All rights reserved. 转载请添加原文连接,合作请加微信lijiaocn或者发送邮件: [email protected],备注网站合作

友情链接:  李佶澳的博客  小鸟笔记  软件手册  编程手册  运营手册  网络课程  收藏文章  发现知识星球  百度搜索 谷歌搜索