如何使用 Kubernetes yaml 文件设置动态值
How to set dynamic values with Kubernetes yaml file
例如部署yaml文件:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: guestbook
spec:
replicas: 2
template:
metadata:
labels:
app: guestbook
spec:
container:
- name: guestbook
image: {{Here want to read value from config file outside}}
Kubernetes 有一个 ConfigMap
功能,但这也是将 key/value 写入 yaml 文件。有没有办法设置环境变量的key?
我认为在 Kubernetes 中无法通过变量或 Config Map 设置图像。但是您可以使用 Helm 来使您的部署更加灵活和可配置。
你不能自动完成,你需要使用外部脚本来"compile"你的模板,或者按照@Jakub的建议使用helm。
您可能想要使用自定义 bash 脚本,可能与您的 CI 管道集成。
给定一个名为 deploy.yml.template
的模板 yml 文件,与您提供的文件非常相似,您可以使用如下内容:
#!/bin/bash
# sample value for your variables
MYVARVALUE="nginx:latest"
# read the yml template from a file and substitute the string
# {{MYVARNAME}} with the value of the MYVARVALUE variable
template=`cat "deploy.yml.template" | sed "s/{{MYVARNAME}}/$MYVARVALUE/g"`
# apply the yml with the substituted value
echo "$template" | kubectl apply -f -
我的做法:
tools/jinja2-cli.py
:
#!/usr/bin/env python3
import os
import sys
from jinja2 import Environment, FileSystemLoader
sys.stdout.write(Environment(loader=FileSystemLoader('templates/')).from_string(sys.stdin.read()).render(env=os.environ) + "\n")
制定规则:
_GENFILES = $(basename $(TEMPLATES))
GENFILES = $(_GENFILES:templates/%=%)
$(GENFILES): %: templates/%.j2 $(MKFILES) tools/jinja2-cli.py .env
env $$(cat .env | xargs) tools/jinja2-cli.py < $< > $@ || (rm -f $@; false)
在 .j2
模板文件中,您可以使用任何 jinja 语法结构,例如{{env.GUEST}}
将替换为 .env
中定义的 GUEST
的值
所以你的 templates/deploy.yaml.j2
看起来像:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: guestbook
spec:
replicas: 2
template:
metadata:
labels:
app: guestbook
spec:
container:
- name: guestbook
image: {{env.GUEST}}
另一种方法(仅使用 bash
内置函数和 xargs
)可能是
env $(cat .env | xargs) cat <<EOF | kubectl create -f -
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: guestbook
spec:
replicas: 2
template:
metadata:
labels:
app: guestbook
spec:
container:
- name: guestbook
image: ${GUEST}
EOF
一行:
cat app-deployment.yaml | sed "s/{{BITBUCKET_COMMIT}}/$BITBUCKET_COMMIT/g" | kubectl apply -f -
在 yaml 中:
...
containers:
- name: ulisses
image: niceuser/niceimage:{{BITBUCKET_COMMIT}}
...
我创建了一个名为 kubectl_create
的脚本,并将其用于 运行 创建命令。它将替换环境变量中引用的模板中的任何值。
#!/bin/bash
set -e
eval "cat <<EOF
$(<)
EOF
" | kubectl create -f -
例如,如果模板文件有:
apiVersion: v1
kind: Service
metadata:
name: nginx-external
labels:
app: nginx
spec:
loadBalancerIP: ${PUBLIC_IP}
type: LoadBalancer
ports:
- name: http
port: 80
targetPort: 80
- name: https
port: 443
targetPort: 443
selector:
app: nginx
运行 kubectl_create nginx-service.yaml
然后环境变量 PUBLIC_IP 将在 运行 执行实际的 kubectl create 命令之前被替换。
您也可以在部署时使用envsubst
。
例如
cat $app/deployment.yaml | envsubst | kubectl apply ...
它将用它们的值替换文件中的所有变量。
当部署到多个环境时,我们在 CI 上成功地使用了这种方法,还将 CI_TAG 等注入到部署中。
我一直在用kubetpl
它具有三种不同的模板风格并支持ConfigMap/Secret冻结。
我创建了一个名为 kubectl_apply 的脚本。它从 .env 加载变量,替换 yml 中的 ${CUSTOMVAR} 并将其传递给 kubectl 命令
#!/bin/bash
set -a
source .env
set +a
eval "cat <<EOF
$(<)
EOF
" | kubectl apply -f -
Helm 正是为这些事情而设计的,还有更多。它将复杂的一组资源部署作为一个组等处理
但如果我们仍在寻找一些简单的替代方案,那么使用 ant 怎么样?
如果您想在构建过程或测试过程中修改文件,那么您也可以使用 ant 任务。
使用 ant,您可以将所有环境值加载为 属性,或者您可以简单地加载属性文件,如:
<property environment="env" />
<property file="build.properties" />
然后你可以有一个目标,将模板文件转换成你想要的 yaml 文件。
<target name="generate_from_template">
<!-- Copy task to replaces values and create new file -->
<copy todir="${dest.dir}" verbose="true" overwrite="true" failonerror="true">
<!-- List of files to be processed -->
<fileset file="${source.dir}/xyz.template.yml" />
<!-- Mapper to transform filename. Removes '.template' from the file
name when copying the file to output directory -->
<mapper type="regexp" from="(.*).template(.*)" to="" />
<!-- Filter chain that replaces the template values with actual values
fetched from properties file -->
<filterchain>
<expandproperties />
</filterchain>
</copy>
</target>
当然你可以使用 fileset
而不是 file
以防你想要为多个文件(嵌套或其他)动态更改值
您的模板文件 xyz.template.yml
应如下所示:
apiVersion: v1
kind: Service
metadata:
name: ${XYZ_RES_NAME}-ser
labels:
app: ${XYZ_RES_NAME}
version: v1
spec:
type: NodePort
ports:
- port: ${env.XYZ_RES_PORT}
protocol: TCP
selector:
app: ${XYZ_RES_NAME}
version: v1
env.
属性 从环境变量加载,其他从 属性 文件加载
希望对您有所帮助:)
我已经发布了一个命令行工具 ysed,如果您打算编写脚本,它可以提供帮助。
yaml 不从另一个 yaml 文件中读取值。作为替代方法,您可以试试这个。
kind: Pod
metadata:
creationTimestamp: null
annotations:
namespace: &namespaceId dev
imageId: &imgageId nginx
podName: &podName nginx-pod
containerName: &containerName nginx-container
name: *podName
namespace: *namespaceId
spec:
containers:
- image: *imgageId
name: *containerName
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
ytt
这种事情非常容易:
deployment.yml
#@ load("@ytt:data", "data")
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: guestbook
spec:
replicas: 2
template:
metadata:
labels:
app: guestbook
spec:
container:
- name: guestbook
image: #@ data.values.image
values.yml
#@data/values
image: nginx@sha256:fe2fa7bb1ceb86c6d9c935bc25c3dd8cbd64f2e95ed5b894f93ae7ffbd1e92bb
然后...
$ ytt -f deployment.yml -f values.yml | kubectl apply -f -
甚至更好,使用 ytt
的堂兄 kapp
以获得高度控制的部署体验:
$ ytt -f deployment.yml -f values.yml | kapp deploy -a guestbook -f -
如果您只想在部署 运行 时更改图像或标签,您可以在部署中设置特定容器的图像:
kubectl apply -f k8s
kubectl set image deployments/worker-deployment worker=IMAGE:TAG
在jitsi项目中,tpl
== frep
命令用于替换值,是对envsubst
的扩展
https://github.com/jitsi/docker-jitsi-meet/issues/65
我继续使用旧的 shell 工具,例如 sed 和 friends,但是当这样的代码需要处理的价值不多时,它们很快就变得不可读了。
我认为现在应该使用标准 - Helm 而不是自定义脚本来解决这个问题。无需部署即可在机器上生成 Kubernets yaml。
一个例子:
在你的机器上安装 helm 以便 helm
命令存在
https://artifacthub.io/packages/helm/pauls-helm-charts/helloworld - 安装按钮
helm repo add pauls-helm-charts http://tech.paulcz.net/charts
helm pull pauls-helm-charts/helloworld --version 2.0.0
tar -zxvf helloworld-2.0.0.tgz && cd helloworld
helm template -f values.yaml --output-dir helloworld . --namespace my-namespace --name-template=my-name
因此它从 values.yaml
:
创建了这些文件
wrote helloworld/helloworld/templates/serviceaccount.yaml
wrote helloworld/helloworld/templates/service.yaml
wrote helloworld/helloworld/templates/deployment.yaml
在 values.yaml
中,您可以更改预定义的 repository
(或者 100% 可以根据需要在 Kubernetes yaml 中重复任何值):
image:
repository: paulczar/spring-helloworld
现在,如果您要部署,请确保 kubectl
正常工作,然后使用 kubectl apply -f serviceaccount.yaml
应用这些生成的文件,等等
如下所示创建一个名为 kubectl_advance
的文件,并像 kubectl 命令一样享受调用它的乐趣。
例如
EXPORT MY_VAL="my-v1"
kubectl_advance -c -f sample.yaml # -c option is to call create command
kubectl_advance -r -f sample2.yaml # -r option is to call replace command
假设 yaml 文件的值类似于 ${MY_VAL} 将被环境变量替换。
#!/usr/bin/env bash
helpFunction()
{
echo "Supported option is [-f] for file"
exit 1
}
while getopts "f:cr" opt
do
case "$opt" in
f ) yamlFile="$OPTARG" ;;
c ) COMMAND_IS_CREATE="true" ;;
r ) COMMAND_IS_REPLACE="true" ;;
? ) helpFunction ;; # Print helpFunction in case parameter is non-existent
esac
done
echo 'yaml file is : '$yamlFile
YAML_CONTENT=`eval "cat <<EOF
$(<$yamlFile)
EOF
"`
echo 'Final File Content is :=>'
echo '------------------'
echo "$YAML_CONTENT"
if [[ "$COMMAND_IS_CREATE" == "true" ]]; then
COMMAND="create"
fi
if [[ "$COMMAND_IS_REPLACE" == "true" ]]; then
COMMAND="replace"
fi
echo "$YAML_CONTENT" | kubectl $COMMAND -f -
在尝试了 sed
和 envsubst
之后,我发现 Kustomize the most elegant and Kubernetes-native way. As an alternative also yq 有时会派上用场。
使用 Kustomize 更改图像名称
Install kustomize
CLI(例如,在 Mac 上,这是 brew install kustomize
)并在与你的 deployment.yaml
:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
现在使用kustomize edit set image
命令更改镜像名称
# optionally define image name
IMAGE_NAME=ghcr.io/yourrepo/guestbook:c25a74c8f919a72e3f00928917dc4ab2944ab061
# replace image tag
kustomize edit set image $IMAGE_NAME
最后使用 kubectl apply -k directory/where/your/kustomization/file/is
将您的 kustomized deployment.yml
应用到您的集群,如下所示:
kubectl apply -k .
对于调试你可以看到结果 deployment.yml
如果你 运行 kustomize build .
:
$ kustomize build .
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: guestbook
spec:
replicas: 2
template:
metadata:
labels:
app: guestbook
spec:
containers:
- image: ghcr.io/yourrepo/guestbook:c25a74c8f919a72e3f00928917dc4ab2944ab061
name: guestbook
备选方案:使用 yq 更改图像名称
Install the YAML processor yq(例如通过自制程序 brew install yq
),定义您的变量并让 yq 进行替换:
# define image name
IMAGE_NAME=ghcr.io/yourrepo/guestbook:c25a74c8f919a72e3f00928917dc4ab2944ab061
# replace image tag
yq e ".spec.template.spec.containers[0].image = \"$IMAGE_NAME\"" -i deployment.yaml
现在您的 deployment.yaml
获得了新的图像版本,然后看起来像这样:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: guestbook
spec:
replicas: 2
template:
metadata:
labels:
app: guestbook
spec:
containers:
- image: ghcr.io/yourrepo/guestbook:c25a74c8f919a72e3f00928917dc4ab2944ab061
name: guestbook
仅供参考:您的 deployment.yaml
并不是真正有效的 Kubernetes 配置 - template.spec.container
不应位于 metadata
标签下 - 而且它拼写为 containers
。
例如部署yaml文件:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: guestbook
spec:
replicas: 2
template:
metadata:
labels:
app: guestbook
spec:
container:
- name: guestbook
image: {{Here want to read value from config file outside}}
Kubernetes 有一个 ConfigMap
功能,但这也是将 key/value 写入 yaml 文件。有没有办法设置环境变量的key?
我认为在 Kubernetes 中无法通过变量或 Config Map 设置图像。但是您可以使用 Helm 来使您的部署更加灵活和可配置。
你不能自动完成,你需要使用外部脚本来"compile"你的模板,或者按照@Jakub的建议使用helm。
您可能想要使用自定义 bash 脚本,可能与您的 CI 管道集成。
给定一个名为 deploy.yml.template
的模板 yml 文件,与您提供的文件非常相似,您可以使用如下内容:
#!/bin/bash
# sample value for your variables
MYVARVALUE="nginx:latest"
# read the yml template from a file and substitute the string
# {{MYVARNAME}} with the value of the MYVARVALUE variable
template=`cat "deploy.yml.template" | sed "s/{{MYVARNAME}}/$MYVARVALUE/g"`
# apply the yml with the substituted value
echo "$template" | kubectl apply -f -
我的做法:
tools/jinja2-cli.py
:
#!/usr/bin/env python3
import os
import sys
from jinja2 import Environment, FileSystemLoader
sys.stdout.write(Environment(loader=FileSystemLoader('templates/')).from_string(sys.stdin.read()).render(env=os.environ) + "\n")
制定规则:
_GENFILES = $(basename $(TEMPLATES))
GENFILES = $(_GENFILES:templates/%=%)
$(GENFILES): %: templates/%.j2 $(MKFILES) tools/jinja2-cli.py .env
env $$(cat .env | xargs) tools/jinja2-cli.py < $< > $@ || (rm -f $@; false)
在 .j2
模板文件中,您可以使用任何 jinja 语法结构,例如{{env.GUEST}}
将替换为 .env
GUEST
的值
所以你的 templates/deploy.yaml.j2
看起来像:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: guestbook
spec:
replicas: 2
template:
metadata:
labels:
app: guestbook
spec:
container:
- name: guestbook
image: {{env.GUEST}}
另一种方法(仅使用 bash
内置函数和 xargs
)可能是
env $(cat .env | xargs) cat <<EOF | kubectl create -f -
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: guestbook
spec:
replicas: 2
template:
metadata:
labels:
app: guestbook
spec:
container:
- name: guestbook
image: ${GUEST}
EOF
一行:
cat app-deployment.yaml | sed "s/{{BITBUCKET_COMMIT}}/$BITBUCKET_COMMIT/g" | kubectl apply -f -
在 yaml 中:
...
containers:
- name: ulisses
image: niceuser/niceimage:{{BITBUCKET_COMMIT}}
...
我创建了一个名为 kubectl_create
的脚本,并将其用于 运行 创建命令。它将替换环境变量中引用的模板中的任何值。
#!/bin/bash
set -e
eval "cat <<EOF
$(<)
EOF
" | kubectl create -f -
例如,如果模板文件有:
apiVersion: v1
kind: Service
metadata:
name: nginx-external
labels:
app: nginx
spec:
loadBalancerIP: ${PUBLIC_IP}
type: LoadBalancer
ports:
- name: http
port: 80
targetPort: 80
- name: https
port: 443
targetPort: 443
selector:
app: nginx
运行 kubectl_create nginx-service.yaml
然后环境变量 PUBLIC_IP 将在 运行 执行实际的 kubectl create 命令之前被替换。
您也可以在部署时使用envsubst
。
例如
cat $app/deployment.yaml | envsubst | kubectl apply ...
它将用它们的值替换文件中的所有变量。 当部署到多个环境时,我们在 CI 上成功地使用了这种方法,还将 CI_TAG 等注入到部署中。
我一直在用kubetpl
它具有三种不同的模板风格并支持ConfigMap/Secret冻结。
我创建了一个名为 kubectl_apply 的脚本。它从 .env 加载变量,替换 yml 中的 ${CUSTOMVAR} 并将其传递给 kubectl 命令
#!/bin/bash
set -a
source .env
set +a
eval "cat <<EOF
$(<)
EOF
" | kubectl apply -f -
Helm 正是为这些事情而设计的,还有更多。它将复杂的一组资源部署作为一个组等处理
但如果我们仍在寻找一些简单的替代方案,那么使用 ant 怎么样?
如果您想在构建过程或测试过程中修改文件,那么您也可以使用 ant 任务。
使用 ant,您可以将所有环境值加载为 属性,或者您可以简单地加载属性文件,如:
<property environment="env" />
<property file="build.properties" />
然后你可以有一个目标,将模板文件转换成你想要的 yaml 文件。
<target name="generate_from_template">
<!-- Copy task to replaces values and create new file -->
<copy todir="${dest.dir}" verbose="true" overwrite="true" failonerror="true">
<!-- List of files to be processed -->
<fileset file="${source.dir}/xyz.template.yml" />
<!-- Mapper to transform filename. Removes '.template' from the file
name when copying the file to output directory -->
<mapper type="regexp" from="(.*).template(.*)" to="" />
<!-- Filter chain that replaces the template values with actual values
fetched from properties file -->
<filterchain>
<expandproperties />
</filterchain>
</copy>
</target>
当然你可以使用 fileset
而不是 file
以防你想要为多个文件(嵌套或其他)动态更改值
您的模板文件 xyz.template.yml
应如下所示:
apiVersion: v1
kind: Service
metadata:
name: ${XYZ_RES_NAME}-ser
labels:
app: ${XYZ_RES_NAME}
version: v1
spec:
type: NodePort
ports:
- port: ${env.XYZ_RES_PORT}
protocol: TCP
selector:
app: ${XYZ_RES_NAME}
version: v1
env.
属性 从环境变量加载,其他从 属性 文件加载
希望对您有所帮助:)
我已经发布了一个命令行工具 ysed,如果您打算编写脚本,它可以提供帮助。
yaml 不从另一个 yaml 文件中读取值。作为替代方法,您可以试试这个。
kind: Pod
metadata:
creationTimestamp: null
annotations:
namespace: &namespaceId dev
imageId: &imgageId nginx
podName: &podName nginx-pod
containerName: &containerName nginx-container
name: *podName
namespace: *namespaceId
spec:
containers:
- image: *imgageId
name: *containerName
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
ytt
这种事情非常容易:
deployment.yml
#@ load("@ytt:data", "data")
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: guestbook
spec:
replicas: 2
template:
metadata:
labels:
app: guestbook
spec:
container:
- name: guestbook
image: #@ data.values.image
values.yml
#@data/values
image: nginx@sha256:fe2fa7bb1ceb86c6d9c935bc25c3dd8cbd64f2e95ed5b894f93ae7ffbd1e92bb
然后...
$ ytt -f deployment.yml -f values.yml | kubectl apply -f -
甚至更好,使用 ytt
的堂兄 kapp
以获得高度控制的部署体验:
$ ytt -f deployment.yml -f values.yml | kapp deploy -a guestbook -f -
如果您只想在部署 运行 时更改图像或标签,您可以在部署中设置特定容器的图像:
kubectl apply -f k8s
kubectl set image deployments/worker-deployment worker=IMAGE:TAG
在jitsi项目中,tpl
== frep
命令用于替换值,是对envsubst
https://github.com/jitsi/docker-jitsi-meet/issues/65
我继续使用旧的 shell 工具,例如 sed 和 friends,但是当这样的代码需要处理的价值不多时,它们很快就变得不可读了。
我认为现在应该使用标准 - Helm 而不是自定义脚本来解决这个问题。无需部署即可在机器上生成 Kubernets yaml。
一个例子:
在你的机器上安装 helm 以便
helm
命令存在https://artifacthub.io/packages/helm/pauls-helm-charts/helloworld - 安装按钮
helm repo add pauls-helm-charts http://tech.paulcz.net/charts
helm pull pauls-helm-charts/helloworld --version 2.0.0
tar -zxvf helloworld-2.0.0.tgz && cd helloworld
helm template -f values.yaml --output-dir helloworld . --namespace my-namespace --name-template=my-name
因此它从 values.yaml
:
wrote helloworld/helloworld/templates/serviceaccount.yaml
wrote helloworld/helloworld/templates/service.yaml
wrote helloworld/helloworld/templates/deployment.yaml
在 values.yaml
中,您可以更改预定义的 repository
(或者 100% 可以根据需要在 Kubernetes yaml 中重复任何值):
image:
repository: paulczar/spring-helloworld
现在,如果您要部署,请确保 kubectl
正常工作,然后使用 kubectl apply -f serviceaccount.yaml
应用这些生成的文件,等等
如下所示创建一个名为 kubectl_advance
的文件,并像 kubectl 命令一样享受调用它的乐趣。
例如
EXPORT MY_VAL="my-v1"
kubectl_advance -c -f sample.yaml # -c option is to call create command
kubectl_advance -r -f sample2.yaml # -r option is to call replace command
假设 yaml 文件的值类似于 ${MY_VAL} 将被环境变量替换。
#!/usr/bin/env bash
helpFunction()
{
echo "Supported option is [-f] for file"
exit 1
}
while getopts "f:cr" opt
do
case "$opt" in
f ) yamlFile="$OPTARG" ;;
c ) COMMAND_IS_CREATE="true" ;;
r ) COMMAND_IS_REPLACE="true" ;;
? ) helpFunction ;; # Print helpFunction in case parameter is non-existent
esac
done
echo 'yaml file is : '$yamlFile
YAML_CONTENT=`eval "cat <<EOF
$(<$yamlFile)
EOF
"`
echo 'Final File Content is :=>'
echo '------------------'
echo "$YAML_CONTENT"
if [[ "$COMMAND_IS_CREATE" == "true" ]]; then
COMMAND="create"
fi
if [[ "$COMMAND_IS_REPLACE" == "true" ]]; then
COMMAND="replace"
fi
echo "$YAML_CONTENT" | kubectl $COMMAND -f -
在尝试了 sed
和 envsubst
之后,我发现 Kustomize the most elegant and Kubernetes-native way. As an alternative also yq 有时会派上用场。
使用 Kustomize 更改图像名称
Install kustomize
CLI(例如,在 Mac 上,这是 brew install kustomize
)并在与你的 deployment.yaml
:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
现在使用kustomize edit set image
命令更改镜像名称
# optionally define image name
IMAGE_NAME=ghcr.io/yourrepo/guestbook:c25a74c8f919a72e3f00928917dc4ab2944ab061
# replace image tag
kustomize edit set image $IMAGE_NAME
最后使用 kubectl apply -k directory/where/your/kustomization/file/is
将您的 kustomized deployment.yml
应用到您的集群,如下所示:
kubectl apply -k .
对于调试你可以看到结果 deployment.yml
如果你 运行 kustomize build .
:
$ kustomize build .
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: guestbook
spec:
replicas: 2
template:
metadata:
labels:
app: guestbook
spec:
containers:
- image: ghcr.io/yourrepo/guestbook:c25a74c8f919a72e3f00928917dc4ab2944ab061
name: guestbook
备选方案:使用 yq 更改图像名称
Install the YAML processor yq(例如通过自制程序 brew install yq
),定义您的变量并让 yq 进行替换:
# define image name
IMAGE_NAME=ghcr.io/yourrepo/guestbook:c25a74c8f919a72e3f00928917dc4ab2944ab061
# replace image tag
yq e ".spec.template.spec.containers[0].image = \"$IMAGE_NAME\"" -i deployment.yaml
现在您的 deployment.yaml
获得了新的图像版本,然后看起来像这样:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: guestbook
spec:
replicas: 2
template:
metadata:
labels:
app: guestbook
spec:
containers:
- image: ghcr.io/yourrepo/guestbook:c25a74c8f919a72e3f00928917dc4ab2944ab061
name: guestbook
仅供参考:您的 deployment.yaml
并不是真正有效的 Kubernetes 配置 - template.spec.container
不应位于 metadata
标签下 - 而且它拼写为 containers
。