Kubernetes Initializer功能的使用方法:在Pod等Resource落地前修改Pod

栏目: 编程工具 · 发布时间: 5年前

内容简介:在研究注意

说明

在研究 通过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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

设计原本

设计原本

Frederick P. Brooks, Jr. / InfoQ中文站、王海鹏、高博 / 机械工业出版社 / 2011-1-1 / 55.00元

无论是软件开发、工程还是建筑,有效的设计都是工作的核心。《设计原本:计算机科学巨匠Frederick P. Brooks的思考》将对设计过程进行深入分析,揭示进行有效和优雅设计的方法。 本书包含了多个行业设计者的特别领悟。Frederick P. Brooks, Jr.精确发现了所有设计项目中内在的不变因素,揭示 了进行优秀设计的过程和模式。通过与几十位优秀设计者的对话,以及他自己在几个设计......一起来看看 《设计原本》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具