Sidecar Template

The following content is the common template ConfigMap defined for injecting IOChaos sidecar, you can also find this example here:

Template ConfigMap

  1. ---
  2. apiVersion: v1
  3. kind: ConfigMap
  4. metadata:
  5. name: chaosfs-sidecar
  6. labels:
  7. app.kubernetes.io/component: template
  8. data:
  9. data: |
  10. initContainers:
  11. - name: inject-scripts
  12. image: pingcap/chaos-scripts:latest
  13. imagePullPolicy: Always
  14. command: ["sh", "-c", "/scripts/init.sh -d {{.DataPath}} -f {{.MountPath}}/fuse-data"]
  15. containers:
  16. - name: chaosfs
  17. image: pingcap/chaos-fs:latest
  18. imagePullPolicy: Always
  19. ports:
  20. - containerPort: 65533
  21. securityContext:
  22. privileged: true
  23. command:
  24. - /usr/local/bin/chaosfs
  25. - -addr=:65533
  26. - -pidfile=/tmp/fuse/pid
  27. - -original={{.MountPath}}/fuse-data
  28. - -mountpoint={{.DataPath}}
  29. volumeMounts:
  30. - name: {{.VolumeName}}
  31. mountPath: {{.MountPath}}
  32. mountPropagation: Bidirectional
  33. volumeMounts:
  34. - name: {{.VolumeName}}
  35. mountPath: {{.MountPath}}
  36. mountPropagation: HostToContainer
  37. - name: scripts
  38. mountPath: /tmp/scripts
  39. - name: fuse
  40. mountPath: /tmp/fuse
  41. volumes:
  42. - name: scripts
  43. emptyDir: {}
  44. - name: fuse
  45. emptyDir: {}
  46. postStart:
  47. {{.ContainerName}}:
  48. command:
  49. - /tmp/scripts/wait-fuse.sh

Template config defines some variables by Go Template mechanism. This example has four arguments:

  • DataPath: original data directory
  • MountPath: after injecting chaosfs sidecar, data directory will be mounted to {{.MountPath}}/fuse-data
  • VolumeName: the data volume name used by the pod
  • ContainerName: to which container the sidecar is injected

For fields defined in this template, we have some brief descriptions below:

  • initContainers: defines the initContainer need to be injected.
  • container: defines the sidecar container need to be injected.
  • volumeMounts: defines the new volumeMounts or overwrite the old volumeMounts of each containers in target pods.
  • volume: defines the new volumes for the target pod or overwrite the old volumes in target pods.
  • postStart: called after a container is created first. If the handler fails, the containers will failed.

Note:

Chaos controller-manager only watches template config map with the label selector specified by its flag --template-labels, by default this label is app.kubernetes.io/component=template if your Chaos Mesh is deployed by helm.

Each template config map should be deployed in the same namespace as Chaos Mesh, and it is identified by the name of the config map, which is chaosfs-sidecar in the above example.

The template config content should be in the data field. This means it is not possible to define two templates in one config map, you have to use two config maps like the example below.

  1. ---
  2. apiVersion: v1
  3. kind: ConfigMap
  4. metadata:
  5. name: chaosfs-sidecar0
  6. labels:
  7. app.kubernetes.io/component: template
  8. data:
  9. data: |
  10. xxxx
  11. ---
  12. apiVersion: v1
  13. kind: ConfigMap
  14. metadata:
  15. name: chaosfs-sidecar1
  16. labels:
  17. app.kubernetes.io/component: template
  18. data:
  19. data: |
  20. xxxx

Containers

chaosfs

chaosfs container is designed as a sidecar container and chaosfs process runs in this container.

chaosfs uses fuse libary and fusermount tool to implement a fuse-daemon service and mounts the application’s data directory. chaosfs hijacks all the file system IO actions of the application, so it can be used to simulate various real-world IO faults.

The following configuration injects chaosfs container to the target pods and starts a chaosfs process in this container.

In addition, chaosfs container should be run as privileged and the mountPropagation field in chaosfs Container.volumeMounts should be set to Bidirectional.

chaosfs uses fusermount to mount the data directory of the application container in chaosfs container.

If any Pod with Bidirectional mount propagation to the same volume mounts anything there, the Container with HostToContainer mount propagation will see it.

This mode is equal to rslave mount propagation as described in the Linux kernel documentation.

More detail about Mount propagation can be found here.

  1. containers:
  2. - name: chaosfs
  3. image: pingcap/chaos-fs
  4. imagePullpolicy: Always
  5. ports:
  6. - containerPort: 65534
  7. securityContext:
  8. privileged: true
  9. command:
  10. - /usr/local/bin/chaosfs
  11. - -addr=:65534
  12. - -pidfile=/tmp/fuse/pid
  13. - -original=/var/lib/tikv/fuse-data
  14. - -mountpoint=/var/lib/tikv/data
  15. volumeMounts:
  16. - name: tikv
  17. mountPath: /var/lib/tikv
  18. mountPropagation: Bidirectional

Description of chaosfs:

  • addr: defines the address of the grpc server, default value: “:65534”.
  • pidfile: defines the pid file to record the pid of the chaosfs process.
  • original: defines the fuse directory. This directory is usually set to the same level directory as the application data directory.
  • mountpoint: defines the mountpoint to mount the original directory.

This value should be set to the data directory of the target application.

chaos-scripts

chaos-scripts container is used to inject some scripts to the target pods including wait-fuse.sh.

wait-fuse.sh is used by application container to ensure that the fuse-daemon server is running normally before the application starts.

chaos-scripts is generally used as an initContainer to do some preparations.

The following config uses chaos-scripts container to inject scripts and moves the scripts to /tmp/scripts directory using init.sh. /tmp/scripts is an emptyDir volume used to share the scripts with all containers of the pod.

So you can use wait-fuse.sh script in tikv container to ensure that the fuse-daemon server is running normally before the application starts.

In addition, init.sh creates a directory named fuse-data in the PersistentVolumes directory of the tikv as the original directory for fuse-daemon server and the original directory is required.

You should also create the original directory in the PersistentVolumes directory of the application.

  1. initContainers:
  2. - name: inject-scripts
  3. image: pingcap/chaos-scripts:latest
  4. imagePullpolicy: Always
  5. command: ['sh', '-c', '/scripts/init.sh -d /var/lib/tikv/data -f /var/lib/tikv/fuse-data']

The usage of init.sh:

  1. $ ./scripts/init.sh -h

Expected output:

  1. USAGE: ./scripts/init.sh [-d data directory] [-f fuse directory]
  2. Used to do some preparation
  3. OPTIONS:
  4. -h Show this message
  5. -d <data directory> Data directory of the application
  6. -f <fuse directory> Data directory of the fuse original directory
  7. -s <scripts directory> Scripts directory
  8. EXAMPLES:
  9. init.sh -d /var/lib/tikv/data -f /var/lib/tikv/fuse-data

Tips

  1. The application Container.volumeMounts used to define data directory should be set to HostToContainer.
  2. scripts and fuse emptyDir should be created and should be mounted to all container of the pod.
  3. The application uses wait-fuse.sh script to ensure that the fuse-daemon server is running normally.
  1. postStart:
  2. tikv:
  3. command:
  4. - /tmp/scripts/wait-fuse.sh

The usage of wait-fuse.sh:

  1. $ ./scripts/wait-fuse.sh -h

Expected output:

  1. ./scripts/wait-fuse.sh: option requires an argument -- h
  2. USAGE: ./scripts/wait-fuse.sh [-a <host>] [-p <port>]
  3. Waiting for fuse server ready
  4. OPTIONS:
  5. -h Show this message
  6. -f <host> Set the target file
  7. -d <delay> Set the delay time
  8. -r <retry> Set the retry count
  9. EXAMPLES:
  10. wait-fuse.sh -f /tmp/fuse/pid -d 5 -r 60