如何在K8s StatefulSet中仅为首个Pod设置环境变量初始化Galera集群?
问题分析与解决方案
为什么你的initContainer方案无效
init容器与主容器属于完全隔离的进程空间,在init容器中通过export设置的环境变量不会传递到主容器,这是Kubernetes容器隔离机制导致的核心问题。你在bootstrap init容器里的环境变量操作,只对该init容器自身生效,主容器完全感知不到。
方案一:修复现有StatefulSet(无需拆分)
方法1:主容器启动时动态判断并设置环境变量
直接修改主容器的启动命令,在启动服务前判断Pod索引,动态设置环境变量:
containers: - name: galera image: bitnami/mariadb-galera:latest # 替换原有command,先判断索引再启动服务 command: - sh - -c - | # 提取Pod索引(StatefulSet Pod名称格式为{name}-{index}) POD_INDEX=$(hostname | awk -F '-' '{print $NF}') if [[ "$POD_INDEX" == "0" ]]; then export MARIADB_GALERA_CLUSTER_BOOTSTRAP="yes" fi # 执行镜像原启动脚本 exec /opt/bitnami/scripts/mariadb-galera/run.sh # 其余环境变量、端口、挂载配置保持不变
方法2:通过共享卷传递环境变量
用init容器将判断结果写入共享卷的文件,主容器启动时读取该文件加载环境变量:
- 修改bootstrap init容器:
initContainers: # 保留volume-permissions init容器不变 - name: bootstrap image: busybox command: - sh - -c - | POD_INDEX=$(hostname | awk -F '-' '{print $NF}') if [[ "$POD_INDEX" == "0" ]]; then echo 'export MARIADB_GALERA_CLUSTER_BOOTSTRAP="yes"' > /bitnami/mariadb/bootstrap.env else echo 'export MARIADB_GALERA_CLUSTER_BOOTSTRAP="no"' > /bitnami/mariadb/bootstrap.env sleep 60 fi volumeMounts: - name: mysql-datadir mountPath: /bitnami/mariadb
- 修改主容器启动命令:
containers: - name: galera image: bitnami/mariadb-galera:latest command: - sh - -c - | # 加载init容器写入的环境变量 source /bitnami/mariadb/bootstrap.env # 执行原启动脚本 exec /opt/bitnami/scripts/mariadb-galera/run.sh # 其余配置保持不变
方案二:拆分StatefulSet实现独立初始化
如果需要单独部署首个初始化Pod,其余Pod索引从1开始,可以创建两个StatefulSet:
1. 初始化用StatefulSet(仅1个Pod)
apiVersion: apps/v1 kind: StatefulSet metadata: name: galera-ss-bootstrap namespace: mon-zabbix spec: serviceName: galera-ss replicas: 1 selector: matchLabels: app: galera-ss template: metadata: labels: app: galera-ss spec: initContainers: - name: volume-permissions image: busybox command: - sh - -c - chown -R 1001:1001 /bitnami/mariadb && chmod -R 775 /bitnami/mariadb volumeMounts: - name: mysql-datadir mountPath: /bitnami/mariadb containers: - name: galera image: bitnami/mariadb-galera:latest ports: - containerPort: 3306 env: - name: MARIADB_ROOT_PASSWORD valueFrom: secretKeyRef: name: secrets key: MYSQL_ROOT_PASSWORD - name: MARIADB_GALERA_CLUSTER_NAME valueFrom: configMapKeyRef: key: CLUSTER_NAME name: configmap - name: MARIADB_GALERA_NODE_NAME value: "galera-ss-0" - name: MARIADB_GALERA_CLUSTER_ADDRESS value: "gcomm://" # 初始化集群用空地址 - name: MARIADB_GALERA_CLUSTER_BOOTSTRAP value: "yes" - name: MARIADB_GALERA_MARIABACKUP_PASSWORD valueFrom: secretKeyRef: name: secrets key: XTRABACKUP_PASSWORD - name: MARIADB_DATABASE valueFrom: configMapKeyRef: key: MARIADB_DATABASE name: configmap - name: MARIADB_USER valueFrom: secretKeyRef: key: MARIADB_USER name: secrets - name: MARIADB_PASSWORD valueFrom: secretKeyRef: name: secrets key: MARIADB_PASSWORD volumeMounts: - name: mysql-datadir mountPath: /bitnami/mariadb securityContext: allowPrivilegeEscalation: false volumeClaimTemplates: - metadata: name: mysql-datadir spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 1Gi
2. 集群节点用StatefulSet(索引从1开始)
利用Kubernetes 1.24+支持的expressionFieldRef修改Pod名称,让索引从1开始:
apiVersion: apps/v1 kind: StatefulSet metadata: name: galera-ss-nodes namespace: mon-zabbix spec: serviceName: galera-ss replicas: 2 selector: matchLabels: app: galera-ss template: metadata: labels: app: galera-ss spec: initContainers: - name: volume-permissions image: busybox command: - sh - -c - chown -R 1001:1001 /bitnami/mariadb && chmod -R 775 /bitnami/mariadb volumeMounts: - name: mysql-datadir mountPath: /bitnami/mariadb - name: wait-for-bootstrap image: busybox command: - sh - -c - # 等待初始化Pod就绪 until nc -z galera-ss-bootstrap-0.galera-ss.mon-zabbix.svc.cluster.local 3306; do sleep 5; done containers: - name: galera image: bitnami/mariadb-galera:latest ports: - containerPort: 3306 env: - name: MARIADB_ROOT_PASSWORD valueFrom: secretKeyRef: name: secrets key: MYSQL_ROOT_PASSWORD - name: MARIADB_GALERA_CLUSTER_NAME valueFrom: configMapKeyRef: key: CLUSTER_NAME name: configmap - name: MARIADB_GALERA_NODE_NAME valueFrom: expressionFieldRef: fieldPath: metadata.name # 将galera-ss-nodes-0转为galera-ss-1,galera-ss-nodes-1转为galera-ss-2 expression: 'galera-ss-' + (int(replace($, "galera-ss-nodes-", "")) + 1) - name: MARIADB_GALERA_CLUSTER_ADDRESS value: "gcomm://galera-ss-bootstrap-0.galera-ss.mon-zabbix.svc.cluster.local:4567" - name: MARIADB_GALERA_MARIABACKUP_PASSWORD valueFrom: secretKeyRef: name: secrets key: XTRABACKUP_PASSWORD - name: MARIADB_DATABASE valueFrom: configMapKeyRef: key: MARIADB_DATABASE name: configmap - name: MARIADB_USER valueFrom: secretKeyRef: key: MARIADB_USER name: secrets - name: MARIADB_PASSWORD valueFrom: secretKeyRef: name: secrets key: MARIADB_PASSWORD volumeMounts: - name: mysql-datadir mountPath: /bitnami/mariadb securityContext: allowPrivilegeEscalation: false volumeClaimTemplates: - metadata: name: mysql-datadir spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 1Gi
内容的提问来源于stack exchange,提问作者Marco Ferrara
相关产品推荐
相关产品推荐

