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预设,您必须确保以下内容:
- 您已启用API类型
settings.k8s.io/v1alpha1/podpreset
。例如,这可以通过包含settings.k8s.io/v1alpha1=true
在--runtime-config
API服务器的选项中来完成。 - 您已启用准入控制器
PodPreset
。执行此操作的一种方法是包含PodPreset
在--enable-admission-plugins
为API服务器指定的选项值中。 - 您已通过
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