0%

K8s中时区问题【使用PodPreset方法】

K8S启动的POD,默认时区与中国相差8小时,在排查问题或者查看日志时非常不方便。

增加容器环境变量,指定时区

docker run -it --rm -e "TZ=Asia/Shanghai" centos

对应k8s中配置:

apiVersion: v1
kind: Pod
metadata:
  name: pod-env-tz
spec:
  containers:
  - name: ngx
    image: nginx:latest
    imagePullPolicy: IfNotPresent
    env:
      - name: TZ
        value: Asia/Shanghai

容器启动时,挂载到宿主机时区文件

docker run -it --rm -v /etc/localtime:/etc/localtime  centos

对应k8s中配置

apiVersion: v1
kind: Pod
metadata:
  name: pod-vol-tz
spec:
  containers:
  - name: ngx
    image: nginx:latest
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: tz-config
      mountPath: /etc/localtime
      readOnly: true
  volumes:
  - name: tz-config
    hostPath:
      path: /etc/localtime

以上两种方法都可以解决问题,但是缺点明显,每次新建POD都需要指定。

推荐使用PodPreset方式

PodPreset(参考中文文档

PodPreset用来给指定标签的Pod注入额外的信息,如环境变量、存储卷等。这样,Pod模板就不需要为每个Pod都显式设置重复的信息。

开启PodPreset

  • 开启API settings.k8s.io/v1alpha1/podpreset
  • 开启准入控制 PodPreset

默认情况下PodPreset不可用

[root@k8s-master ~]# kubectl get podpreset
error: the server doesn't have a resource type "podpreset"

开启之后应该是

[root@k8s-master ~]# kubectl get podpreset
No resources found.

如何开启PodPreset?

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

spec:
  containers:
  - command:
    - kube-apiserver
    - --advertise-address=192.168.1.210
    - --allow-privileged=true
    - --authorization-mode=Node,RBAC
    - --client-ca-file=/etc/kubernetes/pki/ca.crt
    - --enable-admission-plugins=NodeRestriction,PodPreset
    - --enable-bootstrap-token-auth=true
    - --runtime-config=settings.k8s.io/v1alpha1=true
    - --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt

添加一行配置- --runtime-config=settings.k8s.io/v1alpha1=true,enable-admission-plugins后面增加PodPreset

等待ApiServer自动重启完成。

创建PodPreset

apiVersion: settings.k8s.io/v1alpha1
kind: PodPreset
metadata:
  name: allow-tz-env
  namespace: default
spec:
  selector:
    matchLabels:
  env:
    - name: TZ
      value: Asia/Shanghai
[root@k8s-master ~]# kubectl get podpresets
NAME           CREATED AT
allow-tz-env   2019-12-16T07:57:54Z

现在创建一个新的POD,查看其环境变量。

测试

我这边简单测试,删除一个已有的consul容器,等它重启之后,查看它的环境变量
consul

可以看到,容器最后环境变量确实增加的时区配置。

busybox通过时区设置时间不生效问题

原因参考这篇

解决办法,通过挂载磁盘/etc/localtime,也可以通过PodPreset方式,为每个创建的POD自动添加挂载

apiVersion: settings.k8s.io/v1alpha1
kind: PodPreset
metadata:
  name: allow-tz-env
spec:
  selector:
    matchLabels:
  volumeMounts:
    - mountPath: /etc/localtime
      name: tz-config
      readOnly: true
  volumes:
    - name: tz-config
      hostPath: 
        path: /etc/localtime

这样新增的POD会自动挂载宿主机上的时间文件。