kubernetes 使用PodPreset 统一修改pod时区

前言

默认的情况,在K8S里启动一个容器,该容器的设置的时区是UTC0,但是对于很多客户而言,其主机环境并不在UTC0。例如中国客户在UTC8。如果不把容器的时区和主机主机设置为一致,则在查找日志等时候将非常不方便,也容易造成误解。

了解Pod预设

Pod Preset是一种API资源,该对象用来在 Pod 创建的时候向 Pod 中注入某些特定信息,可以包括 secret、volume、volume mount 和环境变量等。

使用Pod预设允许pod模板作者不必显式提供每个pod的所有信息。这样,使用特定服务的pod模板的作者不需要知道有关该服务的所有详细信息。

 

PodPreset

PodPreset是用来在 Pod 被创建的时候向其中注入额外的信息的API 资源。您可以使用label selector 来匹配为哪些 Pod 应用PodPreset

kubernetes提供了一个准入控制器(PodPreset),当启用后,PodPreset会将应用创建请求传入到该控制器上。当有 Pod 创建请求发生时,系统将执行以下操作:

  • 检索所有可用的PodPresets
  • 检查有PodPreset的标签选择器上的标签与正在创建的Pod 上的标签是否匹配。
  • 尝试将由PodPreset定义的各种资源合并到正在创建的Pod 中。
  • 出现错误时,在该 Pod 上引发记录合并错误的事件,PodPreset 不会注入任何资源到创建的 Pod 中。
  • 注释刚生成的修改过的 Pod spec,以表明它已被 PodPreset 修改过。注释的格式为 podpreset.admission.kubernetes.io/podpreset-<pod-preset name>": "<resource version>"

 

禁用特定Pod的PodPreset

在某些情况下,您希望Pod不会被任何Pod Preset突变改变。在这些情况下,您可以在表单的Pod Spec中添加注释:podpreset.admission.kubernetes.io/exclude: "true"

 

 

启用PodPreset

要在群集中使用Pod预设,您必须确保以下内容:

  1. 您已启用API类型settings.k8s.io/v1alpha1/podpreset。例如,这可以通过包含settings.k8s.io/v1alpha1=true--runtime-configAPI服务器的选项中来完成。
  2. 您已启用准入控制器PodPreset。执行此操作的一种方法是包含PodPreset--enable-admission-plugins为API服务器指定的选项值中。
  3. 您已通过PodPreset在将使用的命名空间中创建对象来定义Pod预设。

 

注意:PodPreset资源对象只有kubernetes 1.8以上版本才支持。

 

要启用PodPreset功能,需要确保你使用的是kubernetes 1.8版本以上,然后需要在准入控制中加入PodPreset,另外为了定义PodPreset对象,还需要其中podpreset的API 类型:

KUBE_ADMISSION_CONTROL="--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota,PodPreset"
KUBE_APISERVER_ARGS="--enable-admission-plugins=Initializers --runtime-config=admissionregistration.k8s.io/v1alpha1,settings.k8s.io/v1alpha1=true --allow-privileged=true --authorization-mode=Node,RBAC --enable-bootstrap-token-auth=true --token-auth-file=/etc/kubernetes/token.csv --service-node-port-range=30000-40000 --tls-cert-file=/etc/kubernetes/pki/kube-apiserver.pem --tls-private-key-file=/etc/kubernetes/pki/kube-apiserver-key.pem --client-ca-file=/etc/kubernetes/pki/ca.pem --service-account-key-file=/etc/kubernetes/pki/sa.pub --enable-swagger-ui=true --secure-port=6443 --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname --anonymous-auth=false --kubelet-client-certificate=/etc/kubernetes/pki/admin.pem --kubelet-client-key=/etc/kubernetes/pki/admin-key.pem"

注意上面的kube-apiserver中的启动参数(前面是两个),参数修改完成后,重启kube-apiserver即可。

kubectl可以查询Pod Preset。在开关没有开启成功前,是无法调用以下命令的

[root@k8s-master1-192-168-1-16 ~]# kubectl  get  podpresets
error: the server doesn't have a resource type "podpresets"


[root@k8s-master1-192-168-1-16 ~]# kubectl  get podpresets
No resources found.

示例

1、配置设置时区的Pod Preset

cat allow-tz-env.yaml apiVersion: settings.k8s.io/v1alpha1 kind: PodPreset metadata: name: allow-tz-env spec: selector: matchLabels: env: - name: TZ value: Asia/Shanghai
kubectl apply -f allow-tz-env.yaml
podpreset.settings.k8s.io/allow-tz-env created

[root@k8s-master1-192-168-1-16 init]# kubectl  get podpreset
NAME           CREATED AT
allow-tz-env   2019-01-14T03:55:34Z

这里需要注意的地方是,一定需要写selector...matchLabels,但是matchLabels为空,表示应用于所有容器。podpreset namespace级别的对象, 其作用范围只能是同一个命名空间下的容器

 

2、为单个容器设置时区

apiVersion: settings.k8s.io/v1alpha1
kind: PodPreset
metadata:
  name: allow-tz-env
spec:
  selector:
    matchLabels:
      TZ: Shanghai
  env:
    - name: TZ
      value: Asia/Shanghai

注意:PodPreset匹配了一个标签:TZ: Shanghai,所有带有该标签的 POD 都会被注入上面的环境变量

 

3、测试

apiVersion: v1
kind: Pod
metadata:
  name: pod-no-tz
  labels:
    TZ: Shanghai
spec:
  containers:
  - name: ngx
    image: nginx:latest
    imagePullPolicy: IfNotPresent

 

然后执行命令:

[root@k8s-master1-192-168-1-16 init]# kubectl  apply -f nginx.yaml 
pod/pod-no-tz created
#未启用PodPreset
[root@k8s-master1-192-168-1-16 init]# kubectl exec -it pod-no-tz date -n zatgo-test
Mon Jan 14 05:37:40 UTC 2019
#启用后
[root@k8s-master1-192-168-1-16 init]# kubectl  exec -it pod-no-tz  date  -n zatgo-test
Mon Jan 14 13:38:06 CST 2019

[root@k8s-master1-192-168-1-16 init]# kubectl  exec -it pod-no-tz  env  -n zatgo-test
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=pod-no-tz
TERM=xterm
TZ=Asia/Shanghai

 

至此,我们就完成了容器的时区的”自动”配置了。Pod Preset的预设功能还是非常便利的,目前这块还在演进中,但是已经能大大简化了相关的管理工作,将这些配置从开发者手中解脱出来,变成系统管理配置。

参考:

https://kubernetes.io/docs/concepts/workloads/pods/podpreset/#enable-pod-preset

 

发表评论