【发布时间】:2020-11-11 09:10:28
【问题描述】:
我目前正在尝试学习使用 Google Kubernetes Engine 和 Google Cloud SQL。为此,我在我的 Visual Studio 2019 中创建了一个 AspnetCore 3.1 Web Api 项目,用作培训项目。
目前我能够做到以下几点。
- 使用 Google Cloud Tools for Visual Studio 将 Web Api 部署到 GKE
- 使用 SSMS 和 Cloud SQL Proxy 从自己的 PC 连接到 Cloud SQL
我想要做的如下。
- 将 Web Api 部署到 GKE,使用 Google Cloud Tools for Visual Studio,附带一个包含 Cloud SQL Proxy 的 sidecar
根据我对 Cloud SQL 的理解,最好始终通过代理访问它,因为它更安全,这就是我想要 sidecar 的原因。然而,为了让代理工作,我需要保存在 GKE 中我的秘密中的凭据文件。我还有一些与数据库相关的变量需要作为环境变量传入,同样来自 GKE 中的机密。
目前在我的解决方案中,在我的 api 项目文件旁边,我有一个 Dockerfile,如下所示。
FROM gcr.io/google-appengine/aspnetcore:3.1
COPY . /app
WORKDIR /app
ENTRYPOINT ["dotnet", "HelloCloud.Api.dll"]
#FROM gcr.io/cloudsql-docker/gce-proxy
#COPY . /app
#WORKDIR /app
#CMD ["/cloud_sql_proxy -instances=noble-cubist-294511:europe-west2:helloclouddb=tcp:1433 -credential_file=/app/secrets/cloudsql/key.json"]
如您所见,Dockerfile 的第二部分已被注释掉。这样做是因为它使 GKE 上的 Pod 崩溃,因为它缺少需要从 Secret 挂载的凭据文件。
在Dockerfile之外,还有一个名为deployment.yaml的文件,内容如下。
apiVersion: apps/v1
kind: Deployment
metadata:
name: hellocloud
spec:
selector:
matchLabels:
app: hellocloud
template:
metadata:
labels:
app: hellocloud
spec:
containers:
- name: hellocloud
image: gcr.io/noble-cubist-294511/hello-cloud-api
env:
- name: DB_USER
valueFrom:
secretKeyRef:
name: helloclouddb-db-credentials
key: username
- name: DB_PASS
valueFrom:
secretKeyRef:
name: helloclouddb-db-credentials
key: password
- name: DB_NAME
valueFrom:
secretKeyRef:
name: helloclouddb-db-credentials
key: database
resources:
limits:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 80
- name: cloudsql-proxy
image: gcr.io/cloudsql-docker/gce-proxy
command: ["/cloud_sql_proxy",
"-instances=noble-cubist-294511:europe-west2:helloclouddb=tcp:1433",
"-credential_file=/secrets/cloudsql/key.json"]
resources:
limits:
memory: "128Mi"
cpu: "500m"
volumeMounts:
- name: credentials-volumn
mountPath: /secrets/cloudsql
readOnly: true
volumes:
- name: credentials-volumn
secret:
secretName: helloclouddb-instance-credentials
我按照本网站上的指南创建了上述 deployment.yaml:Connecting Cloud SQL
通过研究,我发现Google Cloud Tools for Visual Studio 对 Dockerfile 有反应,这也是我尝试注释掉的部分的原因。我一直在试图弄清楚我是否可以通过 Dockerfile 指示 GKE 使用 deployment.yaml 文件,因为据我了解这应该可以解决问题。
我喜欢 DRY(不要重复自己)的开发概念,这是它想要通过 Google Cloud Tools for Visual Studio 做到这一点的另一个原因。我曾尝试直接在 GKE 上创建部署,这花了我大约 10 分钟的时间,结果甚至没有工作。当然,如果我更习惯于在 GKE 上创建部署,它会减少时间,最终也可以工作,但这将是一种 WET(每次写入)方式。
在我的头撞在桌子上两天之后,我没有靠近,这就是我写这个 Stackoverflow 任务的原因,希望对 Docker、GKE 和 Cloud SQL 更有经验的人可以给我一些指示。
如果我可能遗漏了重要的内容,请随时询问更多细节。
[编辑 1]
作为一种解决方法,我试图将文件放在我的驱动器上,Dockerfile 中的副本将从那里获取它,至少根据我的理解。下面是我在 Visual Studio 中的项目图像,后面是我更新的 Dockerfile。
FROM gcr.io/google-appengine/aspnetcore:3.1
COPY . /app
WORKDIR /app
ENTRYPOINT ["dotnet", "HelloCloud.Api.dll"]
FROM gcr.io/cloudsql-docker/gce-proxy
COPY . /app
WORKDIR /app/Secrets/CloudSQL
CMD ["/cloud_sql_proxy -instances=noble-cubist-294511:europe-west2:helloclouddb=tcp:1433 -credential_file=key.json"]
在我的计算机上构建 Dockerfile 并使用Dive 命令查看映像的内容,它在指定位置包含“key.json”。即使这样,当部署到 GKE 时,Cloud Build 也可以很好地构建它,但是在启动 pod 时,它会抛出 RunContainerError,抱怨“没有这样的文件或目录”。完整错误的图像如下所示。
【问题讨论】:
-
创建了一个 Api 方法,当调用它时,它只会告诉我 database.json 和 key.json 文件是否存在,它说它们确实存在。那么为什么 GKE 会抛出该错误...
-
我可以在您的部署文件中看到您使用的是绝对路径,但错误显示
--credential_file带有相对路径。此外,您的部署文件中的路径是小写的,并且在您的 Dockerfile/项目中它是 CamelCase ......您是否尝试过让所有人都保持相同?我问是因为对于 linux,如果你说cd Secrets/CloudSQL和cd /secret/cloudsql -
从 Visual Studio 部署我的项目后,我确实看到了任何关于 deployment.yaml 文件执行任何操作的建议。影响部署的是 Dockerfile。我已经匹配了两个文件中的路径,以防万一,它们现在都说:“app/Secrets/CloudSQL/key.json”。与他们匹配部署仍然会导致错误。我还认为它丢失的是 cloud_sql_proxy 文件,因此最新的 Dockerfile 将 CMD 之前的命令设置为“WORKDIR”。通过 Dive 查看图像,这就是 cloud_sql_proxy 所在的位置。
-
您解决了这个问题吗?丢失的 cloud_sql_file 解决了问题?
-
@KoopaKiller 看看下面我的回答。
标签: docker asp.net-core google-kubernetes-engine google-cloud-sql