Scripted editing of a running Kubernetes pod

12/16/2019

I have a pod that is defined by a deployment, and the yaml definition is stored in my codebase. There are time when I'd like to have a volume mount configured for the pod/container, so it would be great to have a script that could enable this. I know I can use kubectl edit to open up an editor and do this (then restart the pod), but it would be more applicable if our devs could simply do something like ./our_scripts/enable_mount.sh.

One option would be to simply have a copy of the YAML definition and create/apply that while deleting the other, but it would be nicer to modify the existing one in place.

Is there a way to achieve this? Does kubectl edit have any flags that I'm missing to achieve this?

-- s g
kubectl
kubernetes

3 Answers

12/16/2019

Use Declarative Management of Kubernetes Objects Using Kustomize. You already have a deployment.yaml manifest in your codebase. Now, move that to base/deployment.yaml and also create a overlays/with-mount/deployment-with-mount.yaml that overrides with an mount when you want.

To deploy the base, you use

kubectl apply -k base/deployment.yaml

and when you want to deploy and also override so you get a mount, you use

kubectl apply -k overlays/with-mount/deployment-with-mount.yaml
-- Jonas
Source: StackOverflow

12/16/2019

You want to deploy pod differently on different conditions on environment. Helm allows you do it. You could have one template for the pod and then pass in values that change based on environment or conditions you want to run.

helm install --values ./k8s/charts/values1.yaml <chartname>

or

helm install --values ./k8s/charts/values2.yaml <chartname>

If this only need for templating then using helm may seem more involved. Potentially other solution could be to use a python script that manipulates yaml Below is quick sample that works for python 2.7

import yaml
document = """
apiVersion: v1
kind: Pod
metadata:
  name: myapp
  labels:
    name: myapp
spec:
  containers:
  - name: myapp
    image: nginx
"""

volumemount = True
podSpec = yaml.load(document)
if volumemount:
    volumeSpecDoc = """
    volumes:
     - configMap:
         name:  app-config
       name : app-config-volume
    """
    volumeSpec = yaml.load(volumeSpecDoc, Loader=yaml.FullLoader)

    podSpec['spec'].update(volumeSpec)
    containerVolumeMountDoc = """
    volumeMounts:
        - name: app-config-volume
          mountPath: /etc/config
    """
    containerVolumeMount = yaml.load(containerVolumeMountDoc,Loader=yaml.FullLoader)
    original = podSpec['spec']['containers'][0]
    original.update(containerVolumeMount)
    podSpec['spec']['containers'][0] = original


print yaml.dump(podSpec)
-- Shambu
Source: StackOverflow

12/17/2019

I'd like to elaborate on reply made by @jonas .

One of the "advanced" commands for kubectl is kustomize. It builds a kustomization target from a directory or a remote url. Available from v1.14 it supports a few types of functionality

  • generating resources from other sources
  • setting cross-cutting fields for resources
  • composing and customizing collections of resources

I know I can use kubectl edit to open up an editor and do this (then restart the pod), but it would be more applicable if our devs could simply do something like ./our_scripts/enable_mount.sh.

"composing and customizing collections of resources" feature looks like the one you may consider in this context.

it may be an overkill if you like to bring up single pod (single yaml file); however it is useful if you need to do something that is a bit more complex :)

$ ls -go
total 28
-rw-r--r-- 1    49 Dec 17 13:23 kustomization.yaml
-rw-r--r-- 1   119 Dec 17 13:22 pod_no_volume.yaml
-rw-r--r-- 1   275 Dec 17 13:22 pod_with_volume.yaml
-rw-r--r-- 1   160 Dec 17 13:19 service.yaml

$ cat kustomization.yaml 
resources:
- pod_with_volume.yaml
- service.yaml

If you run kubectl kustomize <dir> (here dir stands for the directory, your kustomization.yaml sits in and in my example it's just a . ) ,you can see that kubectl come up with the new objects to be applied:

$ kubectl kustomize .
apiVersion: v1
kind: Service
metadata:
  labels:
    run: my-nginx
  name: my-nginx
spec:
  ports:
  - port: 80
    protocol: TCP
  selector:
    run: my-nginx
---
apiVersion: v1
kind: Pod
metadata:
  name: test-nginx-with-volume
spec:
  containers:
  - image: nginx
    name: nginx
    volumeMounts:
    - mountPath: /etc/nginx/conf.d/
      name: nginx-path
  volumes:
  - hostPath:
      path: /tmp/somePath/conf.d
    name: nginx-path

As you can guess it is merely a "concat" of

  • pod_with_volume.yaml
  • service.yaml

The only peculiarity of this method is that the file you are referring to shall be in or below the directory the kustomization.yaml sits in.

As you can see, ./our_scripts/enable_mount.sh can merely call properly formatted kubectl kustomize <dir> command

Hope you'll find this answer useful :)

-- Nick
Source: StackOverflow