# Set timezone
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Asia/Shanghai" > /etc/timezone
...
containers:
- name: xxx
...
volumeMounts:
- name: timezone
mountPath: /etc/localtime
volumes:
- name: timezone
hostPath:
path: /usr/share/zoneinfo/Asia/Shanghai
TZ
定义时区...
containers:
- name: xxx
...
env:
- name: TZ
value: Asia/Shanghai
PodPreset
可以在容器启动的时候注入一些信息,PodPreset
在1.20
版本后被移除了
# 1.20版本之后 启用 PodPreset
## 在 kube-apiserver 启动参数 -runtime-config 增加 settings.k8s.io/v1alpha1=true;
—runtime-config=rbac.authorization.k8s.io/v1alpha1=true,settings.k8s.io/v1alpha1=true
## 然后在 --admission-control 增加 PodPreset 启用
—admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota,PodPreset
# 查看是否应用上
kubectl api-resources |grep podpresets
#创建PodPresents资源对象
apiVersion: settings.k8s.io/v1alpha1
kind: PodPreset
metadata:
name: tz-env
spec:
selector:
matchLabels:
env:
- name: TZ
values: Asia/Shanghai
在
pod
容器中调整时间,主要原理是在OS
层面拦截系统时间欺骗应用,实现返回任意的时间给应用层使用拦截的主要思路是以动态库的加载为基础的,采用
LD_PRELOAD
机制,自行实现这个方法并编译成动态库依靠动态库加载的先后顺序来覆盖原始的方法
已经有libfaketime 项目实现,按照其文档,主要步骤为
git clone https://github.com/wolfcw/libfaketime.git
cd libfaketime && make install
docker cp /usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1 e6e239e5fba7:/usr/local/lib/
export LD_PRELOAD=/usr/local/lib/libfaketime.so.1 FAKETIME="-5d"
容器环境下,手动按照上面的步骤操作是可以生效的,唯一不足的就是一旦容器重启就会失效
在容器 (k8s
环境) 中如何解决?
前面的步骤可以将编译完的库文件通过dockerfile
打包到镜像中,如果需要修改时间,只需要在Pod
控制器定义时添加环境变量即可
...
containers:
- name: xxx
...
env:
- name: LD_PRELOAD
value: "/usr/local/lib/libfaketime.so.1"
- name: FAKETIME
value: "-5d"
另外一种思路是,时间调整一般是暂时的,以及多pod
时间同步的需求,将LD_PRELOAD
的打开与否放到应用的运行环境中,采用configmap
作为应用时间的标准,将时间变更值faketime
作为configmap
apiVersion: v1
kind: ConfigMap
metadata:
name: faketimerc
namespace: default
data:
faketimerc: |
+10d
最后所有的pod
都以volume
的形式挂载该configmap
...
containers:
- name: xxx
...
volumeMounts:
- name: faketimerc
mountPath: /etc/faketimerc
volumes:
- name: faketimerc
configMap:
name: faketimerc
items:
- key: faketimerc
path: faketimerc