Kubernates pods with :latest Image issue

3/6/2020

I'm using Kubernates for production environment (I'm new for these kinds of configuration), This is an example for one of my depolyment files(with changes):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myProd
  labels:
    app: thisIsMyProd
spec:
  replicas: 3
  selector:
    matchLabels:
      app: thisIsMyProd
  template:
    metadata:
      labels:
        app: thisIsMyProd
    spec:
      containers:
        - name: myProd
          image: DockerUserName/MyProdProject  # <==== Latest
          ports:
           - containerPort: 80

Now, I wanted to make it works with the travis ci, So I made something similar to this:

sudo: required

services:
  - docker

env:
  global:
    - LAST_COMMIT_SHA=$(git rev-parse HEAD)
    - SERVICE_NAME=myProd
    - DOCKER_FILE_PATH=.
    - DOCKER_CONTEXT=.

addons:
  apt:
    packages:
      - sshpass

before_script:
  - docker build -t $SERVICE_NAME:latest -f $DOCKER_FILE_PATH $DOCKER_CONTEXT

script:
  # Mocking run test cases

deploy:
  - provider: script
    script: bash ./deployment/deploy-production.sh
    on:
      branch: master

And finally here is the deploy-production.sh script:

#!/usr/bin/env bash

# Log in to the docker CLI
echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin

# Build images
docker build -t $DOCKER_USERNAME/$SERVICE_NAME:latest -t $DOCKER_USERNAME/$SERVICE_NAME:$LAST_COMMIT_SHA -f $DOCKER_FILE_PATH $DOCKER_CONTEXT

# Take those images and push them to docker hub
docker push $DOCKER_USERNAME/$SERVICE_NAME:latest
docker push $DOCKER_USERNAME/$SERVICE_NAME:$LAST_COMMIT_SHA

# Run deployment script in deployment machine
export SSHPASS=$DEPLOYMENT_HOST_PASSWORD
ssh-keyscan -H $DEPLOYMENT_HOST >> ~/.ssh/known_hosts

# Run Kubectl commands
kubctl apply -f someFolder
kubctl set image ... # instead of the `...` the rest command that sets the image with SHA to the deployments

Now here are my questions:

  1. When travis finish its work, the deploy-production.sh script with run when it is about merging to the master branch, Now I've a concern about the kubectl step, for the first time deployment, when we apply the deployment it will pull the image from dockerhup and try to run them, after that the set image command will run changing the image of these depolyment. Does this will make the deployment to happen twice?

  2. When I try to deploy for the second time, I noticed the deployment used old version from the latest image because it found it locally. After searching I found imagePullPolicy and I set it to always. But imagine that I didn't use that imagePullPolicy attribute, what would really happen in this case? I know that old-version code containers for the first apply command. But isn't running the set image will fix that? To clarify my question, Is kubernetes using some random way to select pods that are going to go down? Like it doesn't mark the pods with the order which the commands run, so it will detect that the set image pods should remain and the apply pods are the one who needs to be terminated?

  3. Doesn't pulling every time is harmful? Should I always make the deployment image somehow not to use the latest is better to erase that hassle?

Thanks

-- Amr Adel
docker
kubernetes
travis-ci

1 Answer

3/7/2020
  1. If the image tag is the same in both apply and set image then only the apply action re-deploy the Deployment (in which case you do not need the set image command). If they refer to different image tags then yes, the deployment will be run twice.

  2. If you use latest tag, applying a manifest that use the latest tag with no modification WILL NOT re-deploy the Deployment. You need to introduce a modification to the manifest file in order to force Kubernetes to re-deploy. Like for my case, I use date command to generate a TIMESTAMP variable that is passed as in the env spec of the pod container which my container does not use in any way, just to force a re-deploy of the Deployment. Or you can also use kubectl rollout restart deployment/name if you are using Kubernetes 1.15 or later.

  3. Other than wasted bandwidth or if you are being charged by how many times you pull a docker image (poor you), there is no harm with additional image pull just to be sure you are using the latest image version. Even if you use a specific image tag with version numbers like 1.10.112-rc5, they will be case where you or your fellow developers forget to update the version number when pushing a modified image version. IMHO, imagePullPolicy=always should be the default rather than explicitly required.

-- Lukman
Source: StackOverflow