内容简介:在研究注意
说明
在研究 通过LXCFS,在容器内显示容器的CPU、内存状态 的时候,遇到了 Kubernetes Initializers ,学习一下。
注意 Kubernetes Initializers 和 Kubernetes 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) } }, }, )
参考
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
个体与交互
Ken Howard、Barry Rogers / 贾永娜、张凯峰 / 机械工业出版社华章公司 / 2012-3-20 / 45.00元
对敏捷软件开发的关注重点,通常都集中在“机制”方面,即过程和工具。“敏捷宣言”认为,个体与交互的价值要高于过程和工具,但这一点很容易被遗忘。在敏捷开发中,如果你重新将注意力放在人的方面,将会收获巨大利益。 本书展示了如何解决敏捷团队在实际项目中遭遇的问题。同时,本书也是很有实用价值的敏捷用户指南,其中包含的故事、最佳实践方法、经验以及技巧均可应用到实际项目当中。通过逐步实践,你将学会如何让团......一起来看看 《个体与交互》 这本书的介绍吧!