中文 | English
fake-time-injector is a lightweight and flexible tool. using this tool, you can easily inject future fake time values into containers in order to simulate and test the behavior of your application in different time scenarios.
fake-time-injector is a component used to modify simulation time in cloud-native scenarios, open-sourced by Aliyun and Lilith Games together through the CloudNativeGame community.
- Go
- C
- C++
- Erlang
- Ruby
- PHP
- JavaScript
- Python
- Java
Here's an example of how you can modify a container's process time using Fake-Time-Injector. This tool uses the webhook mechanism in Kubernetes to implement request parsing changes. Once you deploy this component in your container, you can modify the specific container time in your pod by writing a YAML file according to certain rules. The basic principle is to enable this component to modify the container time by configuring the FAKETIME plugin and LIBFAKETIME plugin.
Deploy fake-time-injector using the following YAML file:
apiVersion: v1
kind: ServiceAccount
metadata:
name: fake-time-injector-sa
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: fake-time-injector-cr
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "patch", "update", "watch"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list"]
- apiGroups: ["admissionregistration.k8s.io"]
resources: ["mutatingwebhookconfigurations"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: fake-time-injector-rb
subjects:
- kind: ServiceAccount
name: fake-time-injector-sa
namespace: kube-system
roleRef:
kind: ClusterRole
name: fake-time-injector-cr
apiGroup: rbac.authorization.k8s.io
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: kubernetes-faketime-injector
namespace: kube-system
labels:
app: kubernetes-faketime-injector
spec:
replicas: 1
selector:
matchLabels:
app: kubernetes-faketime-injector
template:
metadata:
labels:
app: kubernetes-faketime-injector
spec:
containers:
- image: registry-cn-hangzhou.ack.aliyuncs.com/acs/fake-time-injector:v5 # docker build -t fake-time-injector:v5 . -f fake-time-injector/Dockerfile
imagePullPolicy: Always
name: kubernetes-faketime-injector
resources:
limits:
cpu: 100m
memory: 100Mi
requests:
cpu: 100m
memory: 100Mi
env:
- name: CLUSTER_MODE # When CLUSTER_MODE is true,all pods in the namespace get a consistent offset when started within a certain time range (40s).
value: "true"
- name: Namespace_Delay_Timeout # All pods in the namespace get a consistent offset when they are started within a certain time range (120s), the default value is 40s.
value: "120"
- name: LIBFAKETIME_PLUGIN_IMAGE
value: "registry.cn-hangzhou.aliyuncs.com/acs/libfaketime:v1"
- name: FAKETIME_PLUGIN_IMAGE
value: "registry-cn-hangzhou.ack.aliyuncs.com/acs/fake-time-sidecar:v4.1" # docker build -t fake-time-sidecar:v1 . -f fake-time-injector/plugins/faketime/build/Dockerfile
serviceAccountName: fake-time-injector-sa
---
kind: Service
apiVersion: v1
metadata:
name: kubernetes-faketime-injector
namespace: kube-system
spec:
ports:
- port: 443
targetPort: 443
name: webhook
selector:
app: kubernetes-faketime-injector
Save this YAML file to a local file named deploy.yaml. Then, use the following command to deploy it:
kubectl apply -f deploy.yaml
We provide two ways to modify process time, the watchmaker command and the libfaketime link library.
The libfaketime link library configuration method, add annotation: Supported languages: python, c, ruby, php, c++, js, java, erlang
- cloudnativegame.io/fake-time: sets the fake time
example of yaml configuration:
apiVersion: v1
kind: Pod
metadata:
name: test
namespace: kube-system
labels:
app: myapp
version: v1
annotations:
cloudnativegame.io/fake-time: "2024-01-01 00:00:00" # Here you can also configure '+3h40s' or '-7h20m40s', relative date offsets can be positive or negative. the "m", "h", "d" and "y" can be used to specify the offset in minutes, hours, days and years (365 days each)
spec:
containers:
- name: test
image: registry.cn-hangzhou.aliyuncs.com/acs/testc:v1
If you are using Kruise-Game, you can modify the time of the game service by configuring it as follows.
apiVersion: game.kruise.io/v1alpha1
kind: GameServerSet
metadata:
name: minecraft
namespace: default
spec:
replicas: 3
updateStrategy:
rollingUpdate:
podUpdatePolicy: InPlaceIfPossible
gameServerTemplate:
metadata:
annotations:
cloudnativegame.io/fake-time: "2024-01-01 00:00:00"
spec:
containers:
- image: registry.cn-hangzhou.aliyuncs.com/acs/minecraft-demo:1.12.2
name: minecraft
Add the following annotation to the watchmaker configuration method. Supported languages: go, python, ruby, php, c++
- cloudnativegame.io/process-name: sets the process that needs to modify the time
- cloudnativegame.io/fake-time: sets the fake time
example of yaml configuration:
apiVersion: v1
kind: Pod
metadata:
name: testpod
namespace: kube-system
labels:
app: myapp
version: v1
annotations:
cloudnativegame.io/process-name: "hello" # If you need to modify multiple processes at the same time, just separate the process names with `,`
cloudnativegame.io/fake-time: "2030-01-01 00:00:00" # Here you can also configure the number of seconds to adjust, '86400' means that the time drifts back one day, watchmaker does not support past times.
spec:
containers:
- name: myhello
image: registry.cn-hangzhou.aliyuncs.com/acs/hello:v1
env:
- name: Modify_Sub_Process # When Modify_Sub_Process is true, modify the time of the sub-process at the same time.
value: "true"
Save this YAML file to a local file named testpod.yaml. Then, use the following command to deploy it:
kubectl apply -f testpod.yaml
To enter the myhello container and test that the time is modified, use the following command:
kubectl exec -it testpod -c myhello /bin/bash -n kube-system
We also provide another method to modify the container's time, you can also have the command executed in virtual time
We also recommend another approach for modifying time, which involves adding a sidecar container directly to the Pod. here's how you can do it:
apiVersion: v1
kind: Pod
metadata:
labels:
name: hello
name: hello
spec:
containers:
- image: 'registry.cn-hangzhou.aliyuncs.com/acs/hello:v1'
imagePullPolicy: IfNotPresent
name: myhello
- env:
- name: modify_process_name
value: hello # If you need to modify multiple processes at the same time, just separate the process names with `,`
- name: delay_second
value: '86400'
image: 'registry-cn-hangzhou.ack.aliyuncs.com/acs/fake-time-sidecar:v4.1'
imagePullPolicy: Always
name: fake-time-sidecar
shareProcessNamespace: true
In this approach, you need to set two environment variables for the sidecar container: modify_process_name and delay_second. this will allow you to specify which process needs to modify the time, and the future time difference from this moment.
Also, note that we've added shareProcessNamespace to the spec to ensure that both containers share the same process namespace.
This project uses the following open-source software:
- Chaos-mesh - Reference chaos-mesh's watchmaker component to simulate process time
- Libfaketime - Reference the libfaketime dynamic link library to simulate time