Skip to content

How to do "patchNamespacedPod" using AppsV1Api #4393

@pmulfl

Description

@pmulfl

Hi All,

Hoping someone can shed a bit of light on this (newbie alert):
I am trying to get into k8s to use for a stateful solution (two pods, one active, one standby). I have been following this example (http://wdmartins.medium.com/active-passive-kubernetes-deployment-for-high-availability-stateful-applications-b7e6fa068944) as template.

One thing it does, is to use the k8s API to modify the value of a label, from inside the pod, using something like this (in JS):

const patch = {
    op: 'replace',
    path: '/metadata/labels/mode',
    value: "some value"
};


const options = { headers: { 'Content-type': k8s.PatchUtils.PATCH_FORMAT_JSON_PATCH} };
ksApi.patchNamespacedPod(HOSTNAME, 'default', [patch], undefined, undefined, undefined, undefined, options)

I need to work in Java, so I tried to replicate this using the official Java Client (V24), like this:

String jsonPatchStr =
        "[{\"op\":\"replace\",\"path\":\"/metadata/labels/mode\",\"value\":\"some value\"}]";

CoreV1Api k8sApi = new CoreV1Api();
String podName = System.getenv("HOSTNAME");
k8sApi.patchNamespacedPod(podName, "default", body);

this does not work as there is no way (that I could find) to specify that the patch is PATCH_FORMAT_JSON_PATCH.

OK, so I looked at PachUtils, and got this far:

String jsonPatchStr =
        "[{\"op\":\"replace\",\"path\":\"/metadata/labels/mode\",\"value\":\"some value\"}]";
AppsV1Api api = new AppsV1Api(ClientBuilder.standard().build());
V1Deployment deploy2 =
        PatchUtils.patch(
                V1Deployment.class,
                () -> api.patchNamespacedDeployment(
                                "k8s-test-app",//cannot specify pod here?,
                                "default",
                                new V1Patch(jsonPatchStr))
                        .buildCall(null),
                V1Patch.PATCH_FORMAT_JSON_PATCH,
                k8sApi.getApiClient());

And this works, but only sets the attribute in the deployment (as the api patchNamespacedDeployment() suggests). So yeah, but not what I need. I was unable to find any way to patch a specific pod with AppsV1Api

With CoreV1Api I can address a specific pod, but cannot specify PATCH_FORMAT_JSON_PATCH.
With AppsV1Api I can specify PATCH_FORMAT_JSON_PATCH, but cannot specify the pod.

Am I barking up the wrong tree (i.e. “don’t/you can’t do that”), or am I missing something here?

Cluster information: Minikube
Kubernetes version: Client Version: v1.34.1, Kustomize Version: v5.7.1, Server Version: v1.34.0
Cloud being used: bare-metal
Installation method: directly installed on WLS with apt
Host OS: WSL on W11

My app.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: k8s-test-app
  labels:
    app: k8s-test
spec:
  replicas: 1
  selector:
    matchLabels:
      app: k8s-test
  template:
    metadata:
      labels:
        app: k8s-test
        mode: unknown
    spec:
      containers:
      - name: k8s-test
        image: k8s-test-app
        imagePullPolicy: Never
        ports:
        - containerPort: 80

My rbac.yaml:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default
  name: update-pods
rules:
  - apiGroups: ["*"] # "" indicates the core API group
    resources: ["apps", "deployments", "pods"]
    verbs: ["get", "delete", "list", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: update-pods-rb
subjects:
  - kind: ServiceAccount
    name: default
    namespace: default
roleRef:
  kind: Role
  name: update-pods
  apiGroup: ""

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions