Cowborg
Cowborg

Reputation: 2871

How to kubernetes "kubectl apply" does not update existing deployments

I have a .NET-core web application. This is deployed to an Azure Container Registry. I deploy this to my Azure Kubernetes Service using

kubectl apply -f testdeployment.yaml

with the yaml-file below

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

This works splendid, but when I change some code, push new code to container and run the

kubectl apply -f testdeployment

again, the AKS/website does not get updated, until I remove the deployment with

kubectl remove deployment myweb

What should I do to make it overwrite whatever is deployed? I would like to add something in my yaml-file. (Im trying to use this for continuous delivery in Azure DevOps).

Upvotes: 14

Views: 18177

Answers (3)

jidh
jidh

Reputation: 172

First delete the deployment config file by running below command on the relative path of the deployment file.

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

earlier I used to get

deployment.apps/deployment-file-name unchanged

meaning the deployment file remains cached. It happens while you're fixing some errors / typos on the deployment YAML & the config got cached once the error got cleared.

Only a kubectl delete -f .\deployment-file-name.yaml could remove the cache.

Later you can do the deployment by

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

Sample yaml file as follows :


apiVersion: apps/v1 kind: Deployment metadata: name: deployment-file-name spec: replicas: 1 selector: matchLabels: app: myservicename template: metadata: labels: app: platformservice spec: containers: - name: platformservice image: /platformservice:latest

Upvotes: 0

Daniel Lee
Daniel Lee

Reputation: 8001

I believe what you are looking for is imagePullPolicy. The default is ifNotPresent which means that the latest version will not be pulled.

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

To ensure that the pod is recreated, rather run:

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

Upvotes: 20

Markus Dresch
Markus Dresch

Reputation: 5574

kubectl does not see any changes in your deployment yaml file, so it will not make any changes. That's one of the problems using the latest tag.

Tag your image to some incremental version or build number and replace latest with that tag in your CI pipeline (for example with envsubst or similar). This way kubectl knows the image has changed. And you also know what version of the image is running. The latest tag could be any image version.

Simplified example for Azure DevOps:

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

Pipeline 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

Alternatively you could also use another tool like Replace Tokens (different syntax: #{TAG}#).

Upvotes: 14

Related Questions