Editing Kubernetes pod on-the-fly

10/6/2019

For the debug and testing purposes I'd like to find a most convenient way launching Kubernetes pods and altering its specification on-the-fly.

The launching part is quite easy with imperative commands. Running

kubectl run nginx-test --image nginx --restart=Never

gives me exactly what I want: the single pod not managed by any controller like Deployment or ReplicaSet. Easy to play with and cleanup when it needed.

However when I'm trying to edit the spec with

kubectl edit po nginx-test

I'm getting the following warning:

pods "nginx-test" was not valid:
 * spec: Forbidden: pod updates may not change fields other than spec.containers[*].image, spec.initContainers[*].image, spec.activeDeadlineSeconds or spec.tolerations (only additions to existing tolerations)

i.e. only the limited set of Pod spec is editable at runtime.

OPTIONS FOUND SO FAR:

  1. Getting Pod spec saved into the file:

    kubectl get po nginx-test -oyaml > nginx-test.yaml

    edited and recreated with

    kubectl apply -f

    A bit heavy weight for changing just one field though.

  2. Creating a Deployment not single Pod and then editing spec section in Deployment itself.

    The cons are:

    • additional API object needed (Deployment) which you should not forget to cleanup when you are done
    • the Pod names are autogenerated in the form of nginx-test-xxxxxxxxx-xxxx and less convenient to work with.

So is there any simpler option (or possibly some elegant workaround) of editing arbitrary field in the Pod spec? I would appreciate any suggestion.

-- esboych
kubectl
kubernetes
kubernetes-pod

1 Answer

10/7/2019

You should absolutely use a Deployment here.

For the use case you're describing, most of the interesting fields on a Pod cannot be updated, so you need to manually delete and recreate the pod yourself. A Deployment manages that for you. If a Deployment owns a Pod, and you delete the Deployment, Kubernetes knows on its own to delete the matching Pod, so there's not really any more work.

(There's not really any reason to want a bare pod; you almost always want one of the higher-level controllers. The one exception I can think of is kubectl run a debugging shell inside the cluster.)

The Pod name being generated can be a minor hassle. One trick that's useful here: as of reasonably recent kubectl, you can give the deployment name to commands like kubectl logs

kubectl logs deployment/nginx-test

There are also various "dashboard" type tools out there that will let you browse your current set of pods, so you can do things like read logs without having to copy-and-paste the full pod name. You may also be able to set up tab completion for kubectl, and type

kubectl logs nginx-test<TAB>
-- David Maze
Source: StackOverflow