这是一种同时使用gcloud 和Pulumi 的混合方法。
高水平:
- 创建docker container并上传到Google Container Registry
- 使用gcloud 创建一个instance template
- 创建托管实例组,从 Pulumi 脚本中引用实例模板
#1 创建 Docker 容器
使用CloudBuild 检测 Git 存储库中的更改、创建 docker 容器并将其上传到 Google Container Registry。
在我的仓库中,我有一个 Dockerfile 文件,其中包含有关如何构建将用于我的实例的容器的说明。我使用Supervisord 来启动和监控我的应用程序。
它的外观如下:
# my-app-repo/Dockerfile
FROM ubuntu:22.04
RUN apt update
RUN apt -y install software-properties-common
RUN apt install -y supervisor
COPY supervisord.conf /etc/supervisord.conf
RUN chmod 0700 /etc/supervisord.conf
COPY ./my-app /home/my-app
RUN chmod u+x /home/my-app
EXPOSE 443/tcp # HTTPS
EXPOSE 9001/tcp # supervisord support
CMD ["supervisord", "-c", "/etc/supervisord.conf"]
第二部分是构建 docker 容器并上传到 Google Container Registry。我通过 CloudBuild 做到这一点。以下是对应的 Pulumi 代码(构建 Golang 应用):
注意:请确保您首先通过 GCP 网站的 CloudBuild section 连接了 repo
const myImageName = pulumi.interpolate`gcr.io/${project}/my-image-name`
const buildTrigger = new gcp.cloudbuild.Trigger("my-app-build-trigger", {
name: "my-app",
description: "Builds My App image",
build: {
steps: [
{
name: "golang",
id: "build-server",
entrypoint: "bash",
timeout: "300s",
args: ["-c", "go build"],
},
{
name: "gcr.io/cloud-builders/docker",
id: "build-docker-image",
args: [
"build",
"-t", pulumi.interpolate`${myImageName}:$BRANCH_NAME-$REVISION_ID`,
"-t", pulumi.interpolate`${myImageName}:latest`,
'.',
],
},
],
images: [myImageName]
},
github: {
name: "my-app-repo",
owner: "MyGithubUsername",
push: {
branch: "^main$"
}
},
});
#2 创建实例模板
由于我无法弄清楚如何通过 Pulumi 轻松创建实例模板,我决定通过 gcloud 命令行工具使用 Google SDK。
gcloud compute instance-templates create-with-container my-template-name-01 \
--region us-central1 \
--container-image=gcr.io/my-project/my-image-name:main-e286d94217719c3be79aac1cbd39c0a629b84de3 \
--machine-type=e2-micro \
--network=my-network-name-59c9c08 \
--tags=my-tag-name \
--service-account=my-service-account@my-project.iam.gserviceaccount.com
上面的值(容器、网络名称等)我只需在 GCP website 上浏览我的项目即可获得。
#3 创建托管实例组
创建实例模板后,您现在可以在 Pulumi 脚本中引用该模板
const myHealthCheck = new gcp.compute.HealthCheck("my-app-health-check", {
checkIntervalSec: 5,
timeoutSec: 5,
healthyThreshold: 2,
unhealthyThreshold: 5,
httpHealthCheck: {
requestPath: "/health-check",
port: 80,
},
});
const instanceGroupManager = new gcp.compute.InstanceGroupManager("my-app-instance-group", {
baseInstanceName: "my-app-name-prefix",
zone: hostZone,
targetSize: 2,
versions: [
{
name: "my-app",
instanceTemplate: "https://www.googleapis.com/compute/v1/projects/my-project/global/instanceTemplates/my-template-name-01",
},
],
autoHealingPolicies: {
healthCheck: myHealthCheck.id,
initialDelaySec: 300,
},
});
为了完整起见,我还包含了我的 Pulumi 脚本的另一部分,它创建一个后端服务并通过 InstanceGroupManager 调用将其连接到上面创建的实例组。请注意,此示例中的负载均衡器使用 TCP 而不是 HTTPS(我的应用正在处理 SSL 连接,因此使用TCP Network Load Balancer)。
const backendService = new gcp.compute.RegionBackendService("my-app-backend-service", {
region: hostRegion,
enableCdn: false,
protocol: "TCP",
backends: [{
group: instanceGroupManager.instanceGroup,
}],
healthChecks: defaultHttpHealthCheck.id,
loadBalancingScheme: "EXTERNAL",
});
const myForwardingRule = new gcp.compute.ForwardingRule("my-app-forwarding-rule", {
description: "HTTPS forwarding rule",
region: hostRegion,
ipAddress: myIPAddress.address,
backendService: backendService.id,
portRange: "443",
});
注意:理想情况下,第 2 步也可以使用 Pulumi 完成,但我还没有完成那部分。