ljzsdut
GitHubToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage

13 K8s之 Pod Preset

Pod Preset(Pod预设)

参考文档

概述

​ Pod预设是一种API资源,用于在创建Pod时向其注入其他运行时要求。您可以使用标签选择器来指定要应用给定Pod预设的Pod。

​ 每个Pod可以匹配零个或多个Pod预设;并且每个PodPreset可以应用于零个或多个Pod。将PodPreset应用于一个或多个Pod时,Kubernetes会修改Pod Spec。对于Env,EnvFrom和VolumeMounts的更改,Kubernetes修改了Pod中所有容器的spec;对volume的更改,Kubernetes会修改Pod.Spec

​ Pod Preset是namespace级别的对象,其作用范围只能是同一个命名空间下容器。

PodPreset是如何工作的

当Pod创建请求发出时,k8s将执行以下操作:

1、检索所有可用的PodPresets。

2、检查任何PodPreset的标签选择器是否与正在创建的Pod上的标签匹配。

3、尝试将PodPreset定义的各种资源合并到正在创建的Pod中。如果合并发生错误时,会在Pod上引发一个记录合并错误的事件,并在没有PodPreset注入的情况下创建Pod。

4、对修改后的Pod,在annotation生成一条记录,以表明它已被PodPreset修改。注释的格式为podpreset.admission.kubernetes.io/podpreset-<pod-preset name>: "<resource version>"

启用Pod Preset

编辑/etc/kubernetes/manifests/kube-apiserver.yaml,

1、 在--runtime-config中增加settings.k8s.io/v1alpha1=true

 2、在 --enable-admission-plugins 中添加PodPreset

  - command:
    - kube-apiserver
    - --advertise-address=192.168.6.123
    - --allow-privileged=true
    - --authorization-mode=Node,RBAC
    - --client-ca-file=/etc/kubernetes/pki/ca.crt
    - --runtime-config=settings.k8s.io/v1alpha1=true   #此行
    - --enable-admission-plugins=NodeRestriction,PodPreset  #此行
    - ......

修改后kubelet会自动重启kube-apiserver组件 。

3、确认是否配置成功

[root@k8s-master01 ~]# kubectl get podpreset
No resources found in default namespace.

[root@k8s-master01 ~]# kubectl explain podpreset
KIND:     PodPreset
VERSION:  settings.k8s.io/v1alpha1

DESCRIPTION:
     PodPreset is a policy resource that defines additional runtime requirements
     for a Pod.

FIELDS:
   apiVersion   <string>
     APIVersion defines the versioned schema of this representation of an
     object. Servers should convert recognized schemas to the latest internal
     value, and may reject unrecognized values. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources

   kind <string>
     Kind is a string value representing the REST resource this object
     represents. Servers may infer this from the endpoint the client submits
     requests to. Cannot be updated. In CamelCase. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

   metadata     <Object>

   spec <Object>

已经识别podpreset资源。

创建PodPreset资源

背景:

​ 默认的情况,在K8S里启动一个容器,该容器的设置的时区是UTC0,但是对于很多客户而言,其主机环境并不在UTC0。例如中国客户在UTC8。如果不把容器的时区和主机主机设置为一致,则在查找日志等时候将非常不方便,也容易造成误解。我们可以通过向Pod内注入TZ环境变量实现设置Pod的时区,难道每次每个容器都要做这样的配置才可以么?可否在系统层面设置,而无需在对应yaml文件体现呢?不然yaml文件将过于啰嗦。答案是使用K8S的特性Pod Preset来控制容器启动前先配置好对应时区环境变量,或者挂载主机/etc/localtime文件。

下面我们通过使用PodPreset的方式实现自动配置Pod的环境变量TZ:

apiVersion: settings.k8s.io/v1alpha1
kind: PodPreset
metadata:
  name: inject-tz-env
spec:
  selector:
    matchLabels:  #matchLabels为空,标示应用于当前Namespace下的所有容器
  env:
  - name: TZ
    value: Asia/Shangha
[root@k8s-master01 ~]# kubectl apply -f inject-tz-env.yaml -n ljzsdut
podpreset.settings.k8s.io/inject-tz-env created

[root@k8s-master01 ~]# kubectl get podpreset -n ljzsdut
NAME            CREATED AT
inject-tz-env   2019-12-13T03:19:55Z

验证:

以普通方式创建一个没有设置TZ的pod:

apiVersion: v1
kind: Pod
metadata:
  name: pod-no-tz
spec:
  containers:
  - name: nginx
    image: nginx:latest
    imagePullPolicy: IfNotPresent
[root@k8s-master01 ~]# kubectl apply -f ngx.yml -n ljzsdut
pod/pod-no-tz created

[root@k8s-master01 ~]# kubectl exec -it pod-no-tz -n ljzsdut -- env|grep TZ
TZ=Asia/Shanghai

对指定的Pod禁用PodPreset

在某些情况下,您希望Pod不受任何Pod预设所改变。在这种情况下,您可以在Pod.Spec中添加annotation实现:

apiVersion: v1
kind: Pod
metadata:
  name: pod-no-podpreset
  annotations:
    podpreset.admission.kubernetes.io/exclude: "true"
spec:
  containers:
  - name: nginx
    image: nginx:latest
    imagePullPolicy: IfNotPresent
[root@k8s-master01 ~]# kubectl apply -f ngx2.yml -n ljzsdut
pod/pod-no-podpreset created

[root@k8s-master01 ~]# kubectl exec -it -n ljzsdut pod-no-podpreset -- env|grep TZ