1、使用初始化容器
使用初始化容器根据不同的pod名称来写入不同的文件
# 如果主机名是sidecar-0,则输出sidecar-0,是sidecar-1则输出sidecar-1(判断)hostname=`hostname` ;hostname=sidecar-1 ;if [[ $hostname = sidecar-0 ]]; thenecho "sidecar-0" ;elif [[ $hostname = sidecar-1 ]]; thenecho "sidecar-1" ;elif [[ $hostname = sidecar-2 ]]; thenecho "sidecar-2" ;elseelse echo "error";fi############# 将输出写入到文件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#############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#############
initContainers:- name: busyboximage: 'busybox:latest'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']containers:- name: container-z64cizimage: nginxports:- name: tcp-80containerPort: 80protocol: TCPresources: {}terminationMessagePath: /dev/termination-logterminationMessagePolicy: FileimagePullPolicy: IfNotPresentrestartPolicy: Always


最佳方案:
先使用平台创建容器后,添加init容器,然后进行挂载
- 打一个init的镜像(具备需要启动的jar包,比如到/tmp)(有待测试,如果不行就打包到其他目录,最后启动容器使用cp拷贝到挂载的目录下)
- 启动init容器时写入配置文件到/tmp下
- 对tmp进行挂载
kind: StatefulSetapiVersion: apps/v1metadata:name: testnamespace: defaultlabels:app: testannotations:kubesphere.io/creator: adminspec:replicas: 1selector:matchLabels:app: testtemplate:metadata:creationTimestamp: nulllabels:app: testannotations:kubesphere.io/creator: adminkubesphere.io/imagepullsecrets: '{}'logging.kubesphere.io/logsidecar-config: '{}'spec:volumes:- name: workdiremptyDir: {}initContainers:- name: busyboximage: 'busybox:latest'command:- sh- '-c'- >-hostname=`hostname` ; if [[ $hostname = sidecar-0 ]]; then echo"sidecar-0" >/tmp/a.txt ; elif [[ $hostname = sidecar-1 ]]; thenecho "sidecar-1" > /tmp/a.txt ; elif [[ $hostname = sidecar-2 ]];then echo "sidecar-2" > /tmp/a.txt; else echo "error" >/tmp/a.txt; firesources: {}volumeMounts:- name: workdirmountPath: /tmpterminationMessagePath: /dev/termination-logterminationMessagePolicy: FileimagePullPolicy: Alwayscontainers:- name: container-y2bal0image: nginxports:- name: tcp-80containerPort: 80protocol: TCPresources: {}volumeMounts:- name: workdirmountPath: /tmp/terminationMessagePath: /dev/termination-logterminationMessagePolicy: FileimagePullPolicy: IfNotPresentrestartPolicy: AlwaysterminationGracePeriodSeconds: 30dnsPolicy: ClusterFirstserviceAccountName: defaultserviceAccount: defaultsecurityContext: {}schedulerName: default-schedulerserviceName: test-8g4tpodManagementPolicy: OrderedReadyupdateStrategy:type: RollingUpdaterollingUpdate:partition: 0revisionHistoryLimit: 10
2. 实际解决案例
- 打一个init的镜像(具备需要启动的jar包,比如到/tmp)(有待测试,如果不行就打包到其他目录,最后启动容器使用cp拷贝到挂载的目录下)
- 启动init容器时写入相关配置文件到/tmp下
- 对tmp进行挂载,分别挂载到init容器和工作容器,使工作容器能够加载到init容器挂载出来的jar包和配置文件
这里为什么必须要在init容器镜像中打入工作容器所需要的包?
没办法,该jar包,启动会在当前jar包产生一个配置文件,而且该配置文件每次启动时内容不固定(如果可以通过配置文件来改变该配置文件的位置也就没有这么麻烦了,所以必须要重新构建init容器镜像和工作容器镜像)
1)准备构建一个具备项目包的init容器镜像和工作容器镜像
- init容器所需镜像
FROM busybox:1.28.4COPY *.jar /tmp/app.jarVOLUME /tmp/
- 工作容器镜像
2)部署服务statefulset
3)注入init容器,注入配置文件
- 通过多分支判断主机名生产相关的配置间
2、使用storageclass
StatefulSet对应Pod的存储最好通过StorageClass来动态创建:每个Pod都会根据StatefulSet中定义的VolumeClaimTemplate来创建一个对应的PVC,然后PVS通过StorageClass自动创建对应的PV,并挂载给Pod。
