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级别的对象,其作用范围只能是同一个命名空间下容器。
当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>"
编辑/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资源。
背景:
默认的情况,在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不受任何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