Kubernetes容器共享卷丢失PHP容器初始文件问题求助
解决Kubernetes中共享卷丢失PHP容器初始文件的问题
我明白你遇到的困扰了——在Docker Compose里共享卷时,Apache能正常访问PHP容器里的初始项目文件,但切换到Kubernetes后,挂载共享卷就把PHP容器里原有的文件覆盖了,只能看到后续新建的内容。这其实是K8s和Docker Compose在卷挂载逻辑上的核心差异导致的。
问题根源
Docker Compose在第一次将卷挂载到容器非空目录时,会自动把容器目录里的现有文件复制到卷中;但Kubernetes的emptyDir(你当前配置默认使用的卷类型,因为没显式指定)是完全空的,当你把它挂载到容器的/var/www/test路径时,会直接覆盖该路径下原有的所有镜像内置文件,所以你看不到初始的html、js等项目文件。
解决方案:用Init容器复制初始文件
最直接的解决方法是添加一个Init容器,它会在你的PHP和Apache容器启动之前,把PHP镜像里的初始文件复制到共享卷中。这样两个容器挂载共享卷时,就能看到这些初始文件,同时后续新建的文件也能正常共享。
修改后的完整配置如下:
apiVersion: v1 kind: Pod metadata: name: ms spec: restartPolicy: Always volumes: - name: test-pierre-container-vol emptyDir: {} # 显式声明emptyDir,让配置更清晰 # 添加Init容器,负责把PHP镜像里的初始文件复制到共享卷 initContainers: - name: copy-php-source-files image: myappphp:dev # 使用和PHP容器相同的镜像,确保文件版本一致 command: ["sh", "-c", "cp -r /var/www/test/. /shared-volume/"] volumeMounts: - name: test-pierre-container-vol mountPath: /shared-volume # 临时挂载共享卷,避免覆盖镜像原有文件 containers: - name: test-ms-php image: myappphp:dev env: - name: DATABASE_URL value: "mysql://root:root@mysql:3306/azert" - name: APP_ENV value: "PROD" volumeMounts: - name: test-pierre-container-vol mountPath: "/var/www/test" # 现在这个路径会有Init容器复制过来的初始文件 - name: test-ms-apache image: myappapache:dev volumeMounts: - name: test-pierre-container-vol mountPath: "/var/www/html" # Apache也能访问到相同的文件 ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: my-ms-php labels: run: my-ms-php spec: type: NodePort ports: - port: 8099 protocol: TCP name: http targetPort: 80 # 新增这个配置,确保流量正确转发到Apache的80端口
额外注意事项
- 持久化需求:如果你的项目文件需要在Pod删除后保留,不要用
emptyDir,换成PersistentVolumeClaim(比如对接NFS、云厂商存储等),Init容器的复制逻辑依然适用。 - 启动脚本优化:如果你的PHP容器有自定义启动脚本,也可以在脚本里加入文件同步逻辑,但Init容器是更符合K8s最佳实践的方式——它独立于应用容器,能确保文件准备就绪后再启动服务。
- Service配置修正:我在Service里补充了
targetPort: 80,这样外部流量才能正确转发到Apache容器的80端口,之前的配置可能会导致访问失败。
内容的提问来源于stack exchange,提问作者Seb
相关产品推荐
相关产品推荐

