如何使 Kubernetes 的“kubectl apply”不更新现有的部署。

14
我有一个.NET Core Web应用程序。它部署到Azure容器注册表中。我使用以下命令将其部署到我的Azure Kubernetes服务:kubectl apply -f testdeployment.yaml,其中testdeployment.yaml是下面的yaml文件。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myweb
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myweb
  template:
    metadata:
      labels:
        app: myweb
    spec:
      containers:
      - name: myweb
        image: mycontainerregistry.azurecr.io/myweb:latest
        ports:
        - containerPort: 80
      imagePullSecrets:
        - name: my-registry-key

这很好,但当我改变一些代码,将新的代码推送到容器并再次运行

kubectl apply -f testdeployment

时,AKS/网站没有更新,直到我使用以下命令删除部署:

kubectl remove deployment myweb

我该怎么做才能覆盖已经部署的内容? 我想在我的yaml文件中添加一些内容。(我正在尝试在Azure DevOps中使用此功能进行持续交付)。


你试过使用镜像中的版本而不是最新版本吗? - night-gold
3个回答

18

我相信你想要的是imagePullPolicy。默认情况下是ifNotPresent,这意味着不会拉取最新版本。

https://kubernetes.io/docs/concepts/containers/images/

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myweb
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myweb
  template:
    metadata:
      labels:
        app: myweb
    spec:
      containers:
      - name: myweb
        image: mycontainerregistry.azurecr.io/myweb
        imagePullPolicy: Always
        ports:
        - containerPort: 80
      imagePullSecrets:
        - name: my-registry-key
为确保重新创建 Pod,请运行以下命令:

kubectl delete -f testdeployment && kubectl apply -f testdeployment

更好的是!...是的,这就是我在寻找的:o) - Cowborg
太匆忙了,没有起作用。根据 https://kubernetes.io/docs/concepts/configuration/overview/#container-images,如果您引用 container:latest 并省略 imagePullPolicy,则应该将 "Always" 作为默认值。所以它应该已经是 "Always" 了。我还需要删除 :latest 才能按照所需的方式工作(尽管在理论/规范上你是正确的)。请更新您的示例,去掉 :latest,然后我可以将其设置为正确的,以帮助其他人。 - Cowborg
1
(可以使用或不使用imagePullPolicy,更取决于是否为:latest) - Cowborg
根据上面的评论进行了更新。 - Daniel Lee
如果部署定义没有更改,它仍然不会应用任何内容。如果必须重新创建 Pod,则会再次拉取“最新”版本,但在 kubectl apply 上不会这样做。 - Markus Dresch

13

kubectl没有发现你的部署yaml文件有任何更改,因此它不会进行任何更改。这是使用“latest”标签的问题之一。

将您的图像标记为某些增量版本或构建编号,并在CI流程中用该标记替换“latest”(例如使用envsubst或类似工具)。这样,kubectl就知道图像已更改。您还可以知道正在运行哪个版本的图像。“latest”标签可以是任何版本的图像。

Azure DevOps的简化示例:

# <snippet>
        image: mycontainerregistry.azurecr.io/myweb:${TAG}
# </snippet>

管道 YAML:

stages:
- stage: Build
  jobs:
  - job: Build
    variables:
    - name: TAG
      value: $(Build.BuildId)
    steps:
    - script: |
        envsubst '${TAG}' < deployment-template.yaml > deployment.yaml
      displayName: Replace Environment Variables

或者你也可以使用另一个工具,例如Replace Tokens(不同的语法:#{TAG}#)。


我为Azure DevOps管道添加了一个示例。 - Markus Dresch
问题在于它是错误的。当您使用“latest”标签时,“imagePullPolicy”默认为“Always”。 - Markus Dresch
是的,我同意,要查看文档。但是,当我最初提出问题时,我使用了:latest-tag。 - Cowborg
正确的,省略标签后的行为完全相同。最新版本、无标签、imagePullPolicy: Always = 完全相同的东西。重新运行您的示例,如果您的yaml文件没有更改,您会发现什么都没有改变。https://kubernetes.io/docs/concepts/configuration/overview/#container-images - Markus Dresch
这是我得到的结果。(1) 使用“:latest”->未拉取镜像。(即使文档中说过,我知道) (2) 使用“.latest”和imagePullPolicy:Always->与(1)相同。 (3) 不要使用最新版本->始终覆盖。这是我开发所需的。 - Cowborg
显示剩余3条评论

0

首先,请在部署文件的相对路径下,运行以下命令删除部署配置文件。

kubectl delete -f .\deployment-file-name.yaml

之前我曾经得到过

deployment.apps/deployment-file-name 未更改

这意味着部署文件仍然被缓存。 当您在部署YAML上修复一些错误/拼写错误时,会发生这种情况,并且一旦错误被清除,配置就被缓存。

只有使用 kubectl delete -f .\deployment-file-name.yaml 才能删除缓存。

稍后您可以通过以下方式进行部署

kubectl apply -f .\deployment-file-name.yaml

示例yaml文件如下:


apiVersion: apps/v1 kind: Deployment metadata: name: 部署文件名 spec: replicas: 1 selector: matchLabels: app: 我的服务名称 template: metadata: labels: app: 平台服务 spec: containers: - name: 平台服务 image: /平台服务:最新版


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接