1、使用初始化容器

使用初始化容器根据不同的pod名称来写入不同的文件
  1. # 如果主机名是sidecar-0,则输出sidecar-0,是sidecar-1则输出sidecar-1(判断)
  2. hostname=`hostname` ;
  3. hostname=sidecar-1 ;
  4. if [[ $hostname = sidecar-0 ]]; then
  5. echo "sidecar-0" ;
  6. elif [[ $hostname = sidecar-1 ]]; then
  7. echo "sidecar-1" ;
  8. elif [[ $hostname = sidecar-2 ]]; then
  9. echo "sidecar-2" ;
  10. else
  11. else echo "error";
  12. fi
  13. ############# 将输出写入到文件
  14. hostname=`hostname` ; if [[ $hostname = sidecar-0 ]]; then echo "sidecar-0" > /app/a.txt ; elif [[ $hostname = sidecar-1 ]]; then echo "sidecar-1" > /app/a.txt ; elif [[ $hostname = sidecar-2 ]]; then echo "sidecar-2" > /app/a.txt; else echo "error" /app/a.txt; fi
  15. #############
  16. hostname=`hostname` ; if [[ $hostname = sidecar-0 ]]; then echo "sidecar-0" ; elif [[ $hostname = sidecar-1 ]]; then echo "sidecar-1" ; elif [[ $hostname = sidecar-2 ]]; then echo "sidecar-2"; else echo "error"; fi
  17. #############
  1. initContainers:
  2. - name: busybox
  3. image: 'busybox:latest'
  4. command: ['sh', '-c', 'hostname=`hostname` ; if [[ $hostname = sidecar-0 ]]; then echo "sidecar-0" > /app/a.txt ; elif [[ $hostname = sidecar-1 ]]; then echo "sidecar-1" > /app/a.txt ; elif [[ $hostname = sidecar-2 ]]; then echo "sidecar-2" > /app/a.txt; else echo "error" /app/a.txt; fi']
  5. containers:
  6. - name: container-z64ciz
  7. image: nginx
  8. ports:
  9. - name: tcp-80
  10. containerPort: 80
  11. protocol: TCP
  12. resources: {}
  13. terminationMessagePath: /dev/termination-log
  14. terminationMessagePolicy: File
  15. imagePullPolicy: IfNotPresent
  16. restartPolicy: Always

多个Pod副本需要不同的配置文件(statefulset) - 图1

多个Pod副本需要不同的配置文件(statefulset) - 图2

最佳方案:

先使用平台创建容器后,添加init容器,然后进行挂载

  • 打一个init的镜像(具备需要启动的jar包,比如到/tmp)(有待测试,如果不行就打包到其他目录,最后启动容器使用cp拷贝到挂载的目录下)
  • 启动init容器时写入配置文件到/tmp下
  • 对tmp进行挂载
  1. kind: StatefulSet
  2. apiVersion: apps/v1
  3. metadata:
  4. name: test
  5. namespace: default
  6. labels:
  7. app: test
  8. annotations:
  9. kubesphere.io/creator: admin
  10. spec:
  11. replicas: 1
  12. selector:
  13. matchLabels:
  14. app: test
  15. template:
  16. metadata:
  17. creationTimestamp: null
  18. labels:
  19. app: test
  20. annotations:
  21. kubesphere.io/creator: admin
  22. kubesphere.io/imagepullsecrets: '{}'
  23. logging.kubesphere.io/logsidecar-config: '{}'
  24. spec:
  25. volumes:
  26. - name: workdir
  27. emptyDir: {}
  28. initContainers:
  29. - name: busybox
  30. image: 'busybox:latest'
  31. command:
  32. - sh
  33. - '-c'
  34. - >-
  35. hostname=`hostname` ; if [[ $hostname = sidecar-0 ]]; then echo
  36. "sidecar-0" >/tmp/a.txt ; elif [[ $hostname = sidecar-1 ]]; then
  37. echo "sidecar-1" > /tmp/a.txt ; elif [[ $hostname = sidecar-2 ]];
  38. then echo "sidecar-2" > /tmp/a.txt; else echo "error" >
  39. /tmp/a.txt; fi
  40. resources: {}
  41. volumeMounts:
  42. - name: workdir
  43. mountPath: /tmp
  44. terminationMessagePath: /dev/termination-log
  45. terminationMessagePolicy: File
  46. imagePullPolicy: Always
  47. containers:
  48. - name: container-y2bal0
  49. image: nginx
  50. ports:
  51. - name: tcp-80
  52. containerPort: 80
  53. protocol: TCP
  54. resources: {}
  55. volumeMounts:
  56. - name: workdir
  57. mountPath: /tmp/
  58. terminationMessagePath: /dev/termination-log
  59. terminationMessagePolicy: File
  60. imagePullPolicy: IfNotPresent
  61. restartPolicy: Always
  62. terminationGracePeriodSeconds: 30
  63. dnsPolicy: ClusterFirst
  64. serviceAccountName: default
  65. serviceAccount: default
  66. securityContext: {}
  67. schedulerName: default-scheduler
  68. serviceName: test-8g4t
  69. podManagementPolicy: OrderedReady
  70. updateStrategy:
  71. type: RollingUpdate
  72. rollingUpdate:
  73. partition: 0
  74. revisionHistoryLimit: 10

2. 实际解决案例

  • 打一个init的镜像(具备需要启动的jar包,比如到/tmp)(有待测试,如果不行就打包到其他目录,最后启动容器使用cp拷贝到挂载的目录下)
  • 启动init容器时写入相关配置文件到/tmp下
  • 对tmp进行挂载,分别挂载到init容器和工作容器,使工作容器能够加载到init容器挂载出来的jar包和配置文件

这里为什么必须要在init容器镜像中打入工作容器所需要的包?

  1. 没办法,该jar包,启动会在当前jar包产生一个配置文件,而且该配置文件每次启动时内容不固定(如果可以通过配置文件来改变该配置文件的位置也就没有这么麻烦了,所以必须要重新构建init容器镜像和工作容器镜像)

1)准备构建一个具备项目包的init容器镜像和工作容器镜像

  • init容器所需镜像
  1. FROM busybox:1.28.4
  2. COPY *.jar /tmp/app.jar
  3. VOLUME /tmp/
  • 工作容器镜像

2)部署服务statefulset

3)注入init容器,注入配置文件

  • 通过多分支判断主机名生产相关的配置间

2、使用storageclass

StatefulSet对应Pod的存储最好通过StorageClass来动态创建:每个Pod都会根据StatefulSet中定义的VolumeClaimTemplate来创建一个对应的PVC,然后PVS通过StorageClass自动创建对应的PV,并挂载给Pod