在Kubernetes部署Magento:后置安装脚本执行异常问题咨询
问题描述
我正尝试在Kubernetes上部署Magento,基础部署可正常运行,但使用如下后置安装脚本时,通过ConfigMap挂载该脚本后,Pod运行一段时间就会重启,且重启后会再次执行该脚本。
安装脚本
### INSTALL MAGENTO ### #!/bin/bash cd /var/www/html/magento php bin/magento setup:install \ --admin-firstname=Magento \ --admin-lastname=Admin \ --admin-email=admin.magento@gmail.com \ --admin-user=admin \ --admin-password='SomePassword123' \ --base-url=http://148.251.11.4:8080 \ --backend-frontname=admin \ --db-host=mysql:3306 \ --db-name=magento \ --db-user=root \ --db-password=keepitsecret \ --use-rewrites=1 \ --language=en_US \ --currency=USD \ --session-save=redis \ --session-save-redis-host=redis \ --session-save-redis-port=6379 \ --session-save-redis-persistent-id=db0 \ --cache-backend=redis \ --cache-backend-redis-server=redis \ --cache-backend-redis-port=6379 \ --cache-backend-redis-db=db1 \ --search-engine=elasticsearch7 \ --elasticsearch-host=elasticsearch \ --elasticsearch-port=9200 \ --elasticsearch-enable-auth=1 \ --elasticsearch-username=elastic \ --elasticsearch-password=keepitsecret \ --amqp-host=rabbitmq \ --amqp-port=5672 \ --amqp-user=guest \ --amqp-password='guest' \ --amqp-virtualhost='/'
Deployment清单文件
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment-2 spec: replicas: 1 selector: matchLabels: app: frontend template: metadata: name: frontend e labels: app: frontend spec: containers: - name: magento-setup command: ["/mag/magentoinstaller.sh"] image:magentonew ports: - containerPort: 8080 - containerPort: 9000 volumeMounts: - name: magento-setup mountPath: /mag volumes: - name: magento-setup configMap: name: magento-setup-cm defaultMode: 0777
疑问
请问我当前使用的后置安装脚本部署方式是否正确?
回答
你的部署方式存在两个核心问题,直接导致了Pod反复重启和脚本重复执行:
容器主进程设计错误
你把一次性的安装脚本设为容器的command,脚本执行完成后进程就会退出。Kubernetes默认认为容器主进程退出是故障,会自动重启Pod,重启后又会重新执行脚本,形成死循环。
Magento容器的主进程应该是持续运行的Web服务(比如nginx或php-fpm),而非一次性初始化脚本。安装脚本执行逻辑错误
setup:install是Magento的一次性初始化操作,重复执行会导致数据库初始化冲突、配置重复写入等异常,同时也完全不符合容器启动的预期逻辑。
正确部署方案
1. 拆分初始化与运行阶段
使用Kubernetes的initContainer专门执行Magento安装脚本,初始化完成后再启动主容器(Web服务)。initContainer只会在Pod首次启动时运行,且必须成功完成后才会启动主容器。
2. 加入脚本防重复执行逻辑
在安装脚本中增加判断,检查Magento是否已完成初始化(比如检测数据库核心表是否存在),避免重复执行setup:install。
3. 修正Deployment清单语法错误
你的清单存在多处yaml语法问题:
image:magentonew缺少空格,应为image: magentonewvolumeMounts缩进错误,需嵌套在containers或initContainers节点下template下的spec层级错误,需与metadata同级
修正后的Deployment示例(关键部分)
apiVersion: apps/v1 kind: Deployment metadata: name: magento-frontend spec: replicas: 1 selector: matchLabels: app: frontend template: metadata: labels: app: frontend spec: # 初始化容器:仅执行一次安装操作 initContainers: - name: magento-init image: magentonew command: ["/bin/bash", "/mag/magentoinstaller.sh"] volumeMounts: - name: magento-setup mountPath: /mag # 挂载持久化存储,保存Magento代码与配置 - name: magento-code mountPath: /var/www/html/magento # 主容器:运行Web服务 containers: - name: magento-web image: magentonew ports: - containerPort: 8080 - containerPort: 9000 # 启动持续运行的Web服务,示例为nginx command: ["nginx", "-g", "daemon off;"] volumeMounts: - name: magento-code mountPath: /var/www/html/magento volumes: - name: magento-setup configMap: name: magento-setup-cm defaultMode: 0777 # 使用持久化存储保存Magento代码 - name: magento-code persistentVolumeClaim: claimName: magento-pvc
改进后的安装脚本(带防重复逻辑)
#!/bin/bash set -e MAGENTO_DIR="/var/www/html/magento" cd $MAGENTO_DIR # 检查Magento是否已初始化:尝试获取后台URI,失败则执行安装 if ! php bin/magento info:adminuri >/dev/null 2>&1; then php bin/magento setup:install \ --admin-firstname=Magento \ --admin-lastname=Admin \ --admin-email=admin.magento@gmail.com \ --admin-user=admin \ --admin-password='SomePassword123' \ --base-url=http://148.251.11.4:8080 \ --backend-frontname=admin \ --db-host=mysql:3306 \ --db-name=magento \ --db-user=root \ --db-password=keepitsecret \ --use-rewrites=1 \ --language=en_US \ --currency=USD \ --session-save=redis \ --session-save-redis-host=redis \ --session-save-redis-port=6379 \ --session-save-redis-persistent-id=db0 \ --cache-backend=redis \ --cache-backend-redis-server=redis \ --cache-backend-redis-port=6379 \ --cache-backend-redis-db=db1 \ --search-engine=elasticsearch7 \ --elasticsearch-host=elasticsearch \ --elasticsearch-port=9200 \ --elasticsearch-enable-auth=1 \ --elasticsearch-username=elastic \ --elasticsearch-password=keepitsecret \ --amqp-host=rabbitmq \ --amqp-port=5672 \ --amqp-user=guest \ --amqp-password='guest' \ --amqp-virtualhost='/' else echo "Magento已完成初始化,跳过安装步骤" fi
额外注意事项
- 必须使用持久化存储挂载Magento代码目录,否则
initContainer的初始化内容会随Pod销毁而丢失。 - 确保MySQL、Redis等依赖服务在
initContainer执行前已就绪,可通过initContainer的readinessProbe或服务端点检查实现。
内容的提问来源于stack exchange,提问作者user19638380
相关产品推荐
相关产品推荐

