关于通过Google Cloud Deployment Manager部署PHP应用时自动安装PHP及Linux组件的技术咨询
如何通过Google Cloud Deployment Manager自动在VM上安装PHP及依赖包
问题描述
我希望通过Google Cloud Deployment Manager部署一款PHP应用,要求在VM实例创建完成后,自动在该虚拟机上安装PHP及其他部分Linux软件包。请问该需求是否可以通过模板文件实现?还是必须创建自定义VM镜像?目前我仅成功创建了VM实例,但未找到自动安装软件包的相关实现方法。以下为我当前使用的Jinja模板代码:
{% set COMPUTE_URL_BASE = 'https://www.googleapis.com/compute/v1/' %} {% set BASE_NAME = env['deployment'] + '-' + env['name'] %} {% macro GlobalComputeUrl(project, collection, name) -%} {{ COMPUTE_URL_BASE }}projects/{{ project }}/global/{{ collection }}/{{ name }} {%- endmacro %} {% macro ZonalComputeUrl(project, zone, collection, name) -%} {{ COMPUTE_URL_BASE }}projects/{{ project }}/zones/{{ zone }}/{{ collection }}/{{ name }} {%- endmacro %} resources: - name: {{ BASE_NAME }} type: compute.v1.instance properties: zone: {{ properties['zone'] }} machineType: {{ ZonalComputeUrl(env['project'], properties['zone'], 'machineTypes', 'e2-micro') }} metadata: items: - key: gce-container-declaration value: | {{ imports[properties['containerManifest']]|indent(12) }} disks: - deviceName: boot type: PERSISTENT autoDelete: true boot: true initializeParams: diskName: {{ BASE_NAME }}-disk sourceImage: {{ GlobalComputeUrl('cos-cloud', 'images', properties['containerImage']) }} networkInterfaces: - accessConfigs: - name: external-nat type: ONE_TO_ONE_NAT network: {{ GlobalComputeUrl(env['project'], 'networks', 'default') }} serviceAccounts: - email: default scopes: - https://www.googleapis.com/auth/logging.write - https://www.googleapis.com/auth/monitoring.write
回答
完全不需要创建自定义镜像!你可以直接在Deployment Manager模板里通过**启动脚本(Startup Script)**实现VM创建后自动安装PHP和依赖包,这是GCP里最常用的自动化初始化方式。
核心思路
通过在VM实例的metadata中添加startup-script项,写入Linux shell命令,VM启动时会自动执行这些命令完成软件安装。另外注意你当前用的是Container-Optimized OS(COS)镜像,这个系统是为容器运行优化的,虽然也支持apt,但默认没有启用完整的包管理环境,更推荐换成标准的Debian或Ubuntu镜像(比如debian-cloud/debian-12或者ubuntu-os-cloud/ubuntu-2204-lts),这样安装软件会更顺畅。
修改后的模板示例
下面是调整后的Jinja模板,替换了镜像为Ubuntu 22.04,并添加了启动脚本来安装PHP 8.1及常用依赖:
{% set COMPUTE_URL_BASE = 'https://www.googleapis.com/compute/v1/' %} {% set BASE_NAME = env['deployment'] + '-' + env['name'] %} {% macro GlobalComputeUrl(project, collection, name) -%} {{ COMPUTE_URL_BASE }}projects/{{ project }}/global/{{ collection }}/{{ name }} {%- endmacro %} {% macro ZonalComputeUrl(project, zone, collection, name) -%} {{ COMPUTE_URL_BASE }}projects/{{ project }}/zones/{{ zone }}/{{ collection }}/{{ name }} {%- endmacro %} resources: - name: {{ BASE_NAME }} type: compute.v1.instance properties: zone: {{ properties['zone'] }} machineType: {{ ZonalComputeUrl(env['project'], properties['zone'], 'machineTypes', 'e2-micro') }} metadata: items: # 替换原来的容器声明为启动脚本 - key: startup-script value: | #!/bin/bash # 更新包索引 apt update -y # 安装PHP 8.1及常用扩展 apt install -y php8.1 php8.1-cli php8.1-fpm php8.1-mysql php8.1-curl php8.1-gd php8.1-mbstring php8.1-xml php8.1-zip # 可选:启动并启用PHP-FPM服务 systemctl start php8.1-fpm systemctl enable php8.1-fpm # 可以添加更多你需要的软件包安装命令 disks: - deviceName: boot type: PERSISTENT autoDelete: true boot: true initializeParams: diskName: {{ BASE_NAME }}-disk # 换成Ubuntu 22.04 LTS镜像 sourceImage: {{ GlobalComputeUrl('ubuntu-os-cloud', 'images', 'ubuntu-2204-jammy-v20240515') }} networkInterfaces: - accessConfigs: - name: external-nat type: ONE_TO_ONE_NAT network: {{ GlobalComputeUrl(env['project'], 'networks', 'default') }} serviceAccounts: - email: default scopes: - https://www.googleapis.com/auth/logging.write - https://www.googleapis.com/auth/monitoring.write
关键说明
- 如果坚持要用COS镜像,你需要调整启动脚本适配COS的环境,比如使用
apt-get并加上--allow-unauthenticated(不推荐,存在安全风险),或者用toolbox工具,但体验远不如标准Linux发行版。 - 启动脚本的执行日志可以通过GCP控制台的VM实例详情页的串行端口1查看,或者用命令
gcloud compute instances get-serial-port-output [INSTANCE_NAME] --zone [ZONE]查看,方便调试安装过程中的问题。 - 如果你还是想通过容器部署PHP应用,那应该把PHP预装到容器镜像里,然后通过
gce-container-declaration指定镜像,而不是在VM上直接安装PHP——这两种部署方式要区分开哦。
内容的提问来源于stack exchange,提问作者Ruudy
相关产品推荐
相关产品推荐

