如何让 kubernetes “kubectl apply”不更新现有部署
Posted
技术标签:
【中文标题】如何让 kubernetes “kubectl apply”不更新现有部署【英文标题】:How to kubernetes "kubectl apply" does not update existing deployments 【发布时间】:2020-02-07 22:16:13 【问题描述】:我有一个 .NET-core Web 应用程序。这将部署到 Azure 容器注册表。我使用
将它部署到我的 Azure Kubernetes 服务kubectl apply -f 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 删除部署 myweb
我应该怎么做才能让它覆盖部署的任何内容?我想在我的 yaml 文件中添加一些内容。 (我试图在 Azure DevOps 中使用它进行持续交付)。
【问题讨论】:
您是否尝试使用图片中的版本而不是最新版本? 【参考方案1】:这里的问题是在 kubernetes 中运行的用于此部署的 pod 是旧的。这就是您在应用程序中看不到更改的原因。
每当您部署或推送新代码时,您都必须删除正在运行的 pod。然后,它会从容器注册表中拉取镜像,您将可以看到新的更改。
我建议您在应用部署文件后将其作为 CI/CD 管道中的一个步骤。如果您要手动应用 deployment.yml 文件,则必须使用以下命令手动删除 pod:kubectl delete pod
【讨论】:
你介意解释一下“这里的问题是在 kubernetes 中运行的用于此部署的 pod 是旧的。”当然 pod 是旧的,因此人们希望通过应用新部署来更新它 是 -> 假设您有一个部署 1 与一些 pod-1 一起运行。当您重新应用 deployment-1.yml(yml 文件中没有任何更改,仅更改代码)时,deployment-1 保持不变,并且 pod-1 不会被删除或更新。因此,您要么需要进行滚动更新,要么只是删除 pod,然后从注册表中提取最新的图像。但如果我错了,请纠正我。【参考方案2】: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 管道添加了一个示例。 我想这是一个更好的解决方案,但如果我必须为我的问题选择正确的答案,我必须是 Daniel Lee。我希望我不会引起太多混乱 问题是,这是错误的。当您使用latest
标签时,imagePullPolicy
默认为Always
。
是的,我同意,通过查看文档。但是,当我最初写问题时,我确实使用了 :latest-tag。
对,省略标签的行为完全相同。最新的、无标签的、imagePullPolicy:总是 = 都是一样的东西。重新运行您的示例,您会发现如果您的 yaml 没有更改,则没有任何更改。 kubernetes.io/docs/concepts/configuration/overview/…【参考方案3】:
我相信您正在寻找的是 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) ..Ehr.. .too仓促...没用...根据kubernetes.io/docs/concepts/configuration/overview/…,如果您引用容器:最新并省略imagePullPolicy .. .所以它应该已经是“始终”...我还需要删除 :latest 以使其按预期工作...(尽管您在理论上/规范上是正确的)。您能否在没有 :latest 的情况下更新您的示例,然后我可以将其设置为正确,以帮助其他人 (使用或不使用 imagePullPolicy,它更多地取决于:最新与否) 根据上面的评论更新 如果部署定义没有改变,它仍然不会应用任何东西。如果它必须重新创建 pod,它会再次拉出“最新”版本,但不是在kubectl apply
以上是关于如何让 kubernetes “kubectl apply”不更新现有部署的主要内容,如果未能解决你的问题,请参考以下文章
如何让 kubernetes “kubectl apply”不更新现有部署