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

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

查看所有标签

猜你喜欢:

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

Trading and Exchanges

Trading and Exchanges

Larry Harris / Oxford University Press, USA / 2002-10-24 / USD 95.00

This book is about trading, the people who trade securities and contracts, the marketplaces where they trade, and the rules that govern it. Readers will learn about investors, brokers, dealers, arbit......一起来看看 《Trading and Exchanges》 这本书的介绍吧!

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

Markdown 在线编辑器

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具