14

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
  • 2,645
  • 3
  • 34
  • 51

3 Answers3

18

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
  • 7,189
  • 2
  • 26
  • 44
  • Even better! ...Yes, that what I was looking for :o) – Cowborg Oct 10 '19 at 13:31
  • ..Ehr.. .too hasty ... didnt work... and according to this https://kubernetes.io/docs/concepts/configuration/overview/#container-images, "Always" should be default if you refer to container:latest and omit imagePullPolicy...so it should already be "Always"... I also need to remove :latest for it to work as wished... (alhough your right in theory/spec). Could you please update your sample without :latest, then I can set it as correct, to help others – Cowborg Oct 10 '19 at 13:48
  • 1
    (works with or without imagePullPolicy, it more depends on :latest or not) – Cowborg Oct 10 '19 at 13:53
  • Updated as per the comment above – Daniel Lee Oct 10 '19 at 14:07
  • if the deployment definition does not change, it still won't apply anything. it would pull the "latest" version again, if it has to recreate the pod, but not on `kubectl apply` – Markus Dresch Oct 10 '19 at 15:03
13

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
  • 5,290
  • 3
  • 20
  • 40
  • I added an example for Azure DevOps pipelines. – Markus Dresch Oct 11 '19 at 04:44
  • I guess this is a better solution, but if I have to choose the correct answer to my question I had to be Daniel Lee. I hope I dont cause too much confusion – Cowborg Oct 11 '19 at 05:25
  • the problem is, that it's wrong. when you use the `latest` tag, `imagePullPolicy` is `Always` by default. – Markus Dresch Oct 11 '19 at 05:40
  • Yes, I agree, by looking at the documentation. However, I did use the :latest-tag to begin with,when I originally wrote the question. – Cowborg Oct 11 '19 at 06:03
  • right, and ommitting the tag behaves exactly the same. latest, no-tag, imagePullPolicy: Always = all the same thing. re-run your example and you'll find out that nothing changed if your yaml didn't change. https://kubernetes.io/docs/concepts/configuration/overview/#container-images – Markus Dresch Oct 11 '19 at 06:10
  • These are the results Ive got. (1) using ":latest" -> image was NOT pulled. (even though it said so in docs, I know (2) using ".latest" and imagePullPolicy : Always -> Same as (1). (3) **Not** using latest -> always overwrite. This is what I need for my development – Cowborg Oct 11 '19 at 06:43
  • @Cowborg the answer by Markus is correct. You can use the :latest tag. What it will do is always overwrite your image in the container registry. But if there is already a deployment running and you changed nothing in the deployment file your pod will not be recreated. (One solution is to delete the pod and it will pull down the latest pod again as i suggested in my answer below). The better solution is to use something dynamic as MarkusDresch suggested. Only downside is your container registry would be very big after sometime. – Ali Oct 11 '19 at 12:51
  • Totally agree with you (and the Markuses) (except that I didnt get that result for :latest) – Cowborg Oct 11 '19 at 12:52
0

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

jidh
  • 172
  • 1
  • 6
  • 22