kubernetes: kubectl apply doesn't remove container args

I’m running into an oddity where, as the title says, an update to a Deployment is not fully applying the new PodTemplateSpec onto the previous version, as components of the previous version remain around after the update.

I’m running v1.2.0-alpha8 on CoreOS 835.9.0

Here’s an example of creating a Deployment (v1), and applying an update (v2) which simply removes certain parts of the original spec (the args key in this case), to showcase that the new spec isn’t fully being applied, even though the Deployment’s last-applied-configuration says it should have.

git-deployment-v1.yaml:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: git-deployment
  labels:
    name: git-deployment
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: git-deployment
    spec:
      containers:
        - name: git-sync
          image: gcr.io/google_containers/git-sync
          imagePullPolicy: Always
          args:
            - -rev=origin/gh-pages
          volumeMounts:
            - name: markdown
              mountPath: /git
              readOnly: false
          env:
            - name: GIT_SYNC_REPO
              value: https://github.com/kubernetes/kubernetes
            - name: GIT_SYNC_DEST
              value: /git
            - name: GIT_SYNC_WAIT
              value: "120"
      volumes:
        - name: markdown
          emptyDir: {}

We create the Deployment:

kubectl create -f git-deployment-v1.yaml

When the Pod is running, it should not have any annotations regarding the Deployment as it was the initial deployment, and there are no history of updates. We can verify that it is not set by seeing that this cmd returns: <no value>

kubectl get deployment git-deployment -o go-template='{{index .metadata.annotations "kubectl.kubernetes.io/last-applied-configuration"}}'

…and we can check that the args key was set, in this case, to pass an arg of -rev=origin/gh-pages to the container’s entry cmd, by checking:

kubectl get po git-deployment-<ID> -o yaml | grep -A 1 "args"

it returns:

 - args:
  - -rev=origin/gh-pages

…which is what we expect as we set it as such in the v1 Deployment


After making a change in the PodTemplateSpec, specifically, removing the args key all-together (this is the only change made in the spec), we have a v2 Deployment to apply as an update to v1:

git-deployment-v2.yaml:

 apiVersion: extensions/v1beta1
 kind: Deployment
 metadata:
   name: git-deployment
   labels:
     name: git-deployment
 spec:
   replicas: 1
   template:
     metadata:
       labels:
         name: git-deployment
     spec:
       containers:
         - name: git-sync
           image: gcr.io/google_containers/git-sync
           imagePullPolicy: Always
           volumeMounts:
             - name: markdown
               mountPath: /git
               readOnly: false
           env:
             - name: GIT_SYNC_REPO
               value: https://github.com/kubernetes/kubernetes
             - name: GIT_SYNC_DEST
               value: /git
             - name: GIT_SYNC_WAIT
               value: "60"
       volumes:
         - name: markdown
           emptyDir: {}

We apply the update:

kubectl apply -f git-deployment-v2.yaml

…and we can verify that the new PodSpecTemplate for the v2 Deployment is what we wanted it to be by examining the output of the last-applied-configuration key for the newly updated Pod:

kubectl get deployment git-deployment -o go-template='{{index .metadata.annotations "kubectl.kubernetes.io/last-applied-configuration"}}' | python -m json.tool

(this output and the git-deployment-v2.yaml manifest should match, and neither should have the args key as we specified)


However, if you examine the new Pod’s args again using

kubectl get po git-deployment-<NEW_ID> -o yaml | grep -A 1 "args"

…it still returns:

 - args:
  - -rev=origin/gh-pages

…which should not be the case 👎

So in my case, its still passing a flag via the args key, which in v2 I determined I did not want by removing it, and the existing flag is messing with the updated Pod’s execution.

Any ideas what could be taking place? Thanks!

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 26 (18 by maintainers)

Commits related to this issue

Most upvoted comments

Still happening for me

Client Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.4", GitCommit:"d360454c9bcd1634cf4cc52d1867af5491dc9c5f", GitTreeState:"clean", BuildDate:"2020-11-12T01:09:16Z", GoVersion:"go1.15.4", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.8", GitCommit:"c86ad89b8715ed17fd55b87cbb2888ccc6fa9878", GitTreeState:"clean", BuildDate:"2020-09-25T01:53:27Z", GoVersion:"go1.13.15", Compiler:"gc", Platform:"linux/amd64"}

Very similar situation to what @relaxdiego posted. Had two volumes, volumeMounts in the original deployment. Updated deployment YAML to change one of them to a different PVC and mount point. Applied YAML, and now I have three volumes and three volume mount points!

Hi, it seems like this bug is still present. I’m using:

Client Version: version.Info{Major:"1", Minor:"10", GitVersion:"v1.10.1", GitCommit:"d4ab47518836c750f9949b9e0d387f20fb92260b", GitTreeState:"clean", BuildDate:"2018-04-13T22:29:03Z", GoVersion:"go1.9.5", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"9", GitVersion:"v1.9.2+coreos.0", GitCommit:"b427929b2982726eeb64e985bc1ebb41aaa5e095", GitTreeState:"clean", BuildDate:"2018-01-18T22:56:14Z", GoVersion:"go1.9.2", Compiler:"gc", Platform:"linux/amd64"}

Running kubectl get deploy XXXXX -o go-template='{{index .metadata.annotations "kubectl.kubernetes.io/last-applied-configuration"}}' shows the applied config as:

(snipped to just the relevant parts)

{"apiVersion":"apps/v1","kind":"Deployment"...,"volumes":[{"name":"quantum-master-b13-3496bd1","secret":{"items":[{"key":"config","path":".env"}],"secretName":"quantum-master-b13-3496bd1"}}]}}}}

However, running kubectl describe on the same deployment yields:

...
  Volumes:
   quantum-master-b13-3496bd1:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  quantum-master-b13-3496bd1
    Optional:    false
   quantum-master-b10-ad15424:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  quantum-master-b10-ad15424
    Optional:    false
   quantum-master-b7-6b60310:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  quantum-master-b7-6b60310
    Optional:    false

I can’t reproduce it all the time, however. I’ve only observed it happening twice. Also note that I used kubectl apply to create the initial version of the deployment.

Oh, sorry @AdoHe @metral! I didn’t look at this carefully enough initially.

@metral If you want to use apply, please use apply to create the resource initially, as well, or use create --save-config.

@metral as a workaround, you can use two apply to remove the args. Like this:

[tony@localhost kubernetes]$ cluster/kubectl.sh apply -f ~/Desktop/yaml/git-deployment-v1.yaml
[tony@localhost kubernetes]$ cluster/kubectl.sh apply -f ~/Desktop/yaml/git-deployment-v2.yaml

The first apply will create the deployment, the second will apply your new configuration.

In terms of getting up to speed, take a look at the developer docs: https://github.com/kubernetes/kubernetes/tree/master/docs/devel

@AdoHe @metral That would be great. There are plenty of apply-related issues to go around if you’re interested in that specifically. It would be great to work out all the kinks for 1.3.

#15493, #19809, #19767, #17238, #16569, #13576, …

@ghodss and/or @jackgr should be able to help review

@kargakis

I just confirmed that using kubectl replace instead of kubectl apply does in fact work to eliminate the lingering args left in v2 from using kubectl apply on v1, so it appears that kubectl apply is the culprit here.

Thanks for the tip!