kubectl apply -f works on PC but not in Gitlab Runner

1/20/2020

I am trying to deploy to kubernetes using Gitlab CICD. No matter what I do, kubectl apply -f helloworld-deployment.yml --record in my .gitlab-ci.yml always returns that the deployment is unchanged:

$ kubectl apply -f helloworld-deployment.yml --record
 deployment.apps/helloworld-deployment unchanged

Even if I change the tag on the image, or if the deployment doesn't exist at all. However, if I run kubectl apply -f helloworld-deployment.yml --record from my own computer, it works fine and updates when a tag changes and creates the deployment when no deployment exist. Below is my .gitlab-ci.yml that I'm testing with:

image: docker:dind
services:
    - docker:dind

stages:
    - deploy

deploy-prod:
    stage: deploy
    image: google/cloud-sdk
    environment: production
    script:
        - kubectl apply -f helloworld-deployment.yml --record

Below is helloworld-deployment.yml:

apiVersion: apps/v1
kind: Deployment
metadata:
    name: helloworld-deployment
spec:
    replicas: 2
    selector:
        matchLabels:
            app: helloworld
    template:
        metadata:
            labels:
                app: helloworld
        spec:
            containers:
                - name: helloworld
                  image: registry.gitlab.com/repo/helloworld:test
                  imagePullPolicy: Always
                  ports:
                  - containerPort: 3000
            imagePullSecrets:
                - name: regcred

Update:

This is what I see if I run kubectl rollout history deployments/helloworld-deployment and there is no existing deployment:

Error from server (NotFound): deployments.apps "helloworld-deployment" not found

If the deployment already exists, I see this:

REVISION  CHANGE-CAUSE
1         kubectl apply --filename=helloworld-deployment.yml --record=true

With only one revision.

I did notice this time that when I changed the tag, the output from my Gitlab Runner was:

deployment.apps/helloworld-deployment configured

However, there were no new pods. When I ran it from my PC, then I did see new pods created.

Update:

Running kubectl get pods shows two different pods in Gitlab runner than I see on my PC.

I definitely only have one kubernetes cluster, but kubectl config view shows some differences (the server url is the same). The output for contexts shows different namespaces. Does this mean I need to set a namespace either in my yml file or pass it in the command? Here is the output from the Gitlab runner:

 apiVersion: v1
 clusters:
 - cluster:
     certificate-authority-data: DATA+OMITTED
     server: URL
   name: gitlab-deploy
 contexts:
 - context:
     cluster: gitlab-deploy
     namespace: helloworld-16393682-production
     user: gitlab-deploy
   name: gitlab-deploy
 current-context: gitlab-deploy
 kind: Config
 preferences: {}
 users:
 - name: gitlab-deploy
   user:
     token: [MASKED]

And here is the output from my PC:

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: URL
contexts:
- context:
    cluster: do-nyc3-helloworld
    user: do-nyc3-helloworld-admin
  name: do-nyc3-helloworld
current-context: do-nyc3-helloworld
kind: Config
preferences: {}
users:
- name: do-nyc3-helloworld-admin
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1beta1
      args:
      - kubernetes
      - cluster
      - kubeconfig
      - exec-credential
      - --version=v1beta1
      - --context=default
      - VALUE
      command: doctl
      env: null

It looks like Gitlab adds their own default for namespace:

<project_name>-<project_id>-<environment>

Because of this, I put this in the metadata section of helloworld-deployment.yml:

namespace: helloworld-16393682-production

And then it worked as expected. It was deploying before, but kubectl get pods didn't show it since that command was using the default namespace.

-- srchulo
gitlab
gitlab-ci
gitlab-ci-runner
kubernetes
kubernetes-deployment

1 Answer

1/22/2020

Since Gitlab use a custom namespace you need to add a namespace flag to you command to display your pods:

kubectl get pods -n helloworld-16393682-production

You can set the default namespace for kubectl commands. See here.

You can permanently save the namespace for all subsequent kubectl commands in that contex

In your case it could be:

kubectl config set-context --current --namespace=helloworld-16393682-production

Or if you are using multiples cluster, you can switch between namespaces using:

kubectl config use-context helloworld-16393682-production

In this link you can see a lot of useful commands and configurations.

I hope it helps! =)

-- KoopaKiller
Source: StackOverflow