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

10/10/2019

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).

-- Cowborg
azure-aks
azure-kubernetes
kubernetes

3 Answers

10/10/2019

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}#).

-- Markus Dresch
Source: StackOverflow

10/10/2019

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
-- Daniel Lee
Source: StackOverflow

10/10/2019

The problem here is that the pod running in the kubernetes for this deployment is old. That is why you don't see the changes in the application.

Whenever you deploy or push new code you have to delete the pod running. It will then pull down the image from the container registry and your new changes would be visible to you.

I suggest you make it a step in your CI/CD pipeline after your deployment file is applied. If you are applying your deployment.yml file manually then you have to delete the pod manually using the command: kubectl delete pod

-- Ali
Source: StackOverflow