Request is invalid when kubectl patch a lifecycle to container

9/7/2021

In my case, I have to deploy a deployment first and then patch a preStop hook to the deployment in jenkins.

I try to use

kubectl -n mobile patch deployment hero-orders-app --type "json" -p '[
{"op":"add","path":"/spec/template/spec/containers/0/lifecycle/preStop/exec/command","value":[]},
{"op":"add","path":"/spec/template/spec/containers/0/lifecycle/preStop/exec/command/-","value":"/bin/sleep"},
{"op":"add","path":"/spec/template/spec/containers/0/lifecycle/preStop/exec/command/-","value":"10"}]'

but it returns

the request is invaild

If patch command can add non-existence path? or I need to change another solution?

And here is hero-orders-app deployment file

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hero-orders-app$SUFFIX
  namespace: $K8S_NAMESPACE
  labels:
    branch: $LABEL
    run: hero-orders-app$SUFFIX
spec:
  selector:
    matchLabels:
      run: hero-orders-app$SUFFIX
  revisionHistoryLimit: 5
  minReadySeconds: 10
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%
  template:
    metadata:
      labels:
        run: hero-orders-app$SUFFIX
        namespace: $K8S_NAMESPACE
        branch: $LABEL
        role: hero-orders-app
    spec:
      dnsConfig:
        options:
          - name: ndots
            value: "1"
      topologySpreadConstraints:
      - maxSkew: 1
        topologyKey: topology.kubernetes.io/zone
        whenUnsatisfiable: ScheduleAnyway
        labelSelector:
          matchLabels:
            run: hero-orders-app$SUFFIX
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 100
              podAffinityTerm:
                labelSelector:
                  matchExpressions:
                    - key: run
                      operator: In
                      values:
                        - hero-orders-app$SUFFIX
                topologyKey: kubernetes.io/hostname
      imagePullSecrets:
        - name: $K8S_IMAGE_SECRETS
      containers:
        - name: hero-orders-$CLUSTER_NAME
          image: $K8S_IMAGE
          imagePullPolicy: IfNotPresent
          securityContext:
            runAsUser: 1000
            allowPrivilegeEscalation: false
            capabilities:
              drop:
                - CHOWN
                - NET_RAW
                - SETPCAP
          ports:
            - containerPort: 3000
              protocol: TCP
          resources:
            limits:
              cpu: $K8S_CPU_LIMITS
              memory: $K8S_RAM_LIMITS
            requests:
              cpu: $K8S_CPU_REQUESTS
              memory: $K8S_RAM_REQUESTS
          readinessProbe:
            httpGet:
              path: /gw-api/v2/_manage/health
              port: 3000
            initialDelaySeconds: 15
            timeoutSeconds: 10
          livenessProbe:
            httpGet:
              path: /gw-api/v2/_manage/health
              port: 3000
            initialDelaySeconds: 20
            timeoutSeconds: 10
            periodSeconds: 45

And it running on AWS with service, pdb and hpa.

here is my kubectl version

Client Version: version.Info{Major:"1", Minor:"21", GitVersion:"v1.21.2", GitCommit:"092fbfbf53427de67cac1e9fa54aaa09a28371d7", GitTreeState:"clean", BuildDate:"2021-06-16T12:59:11Z", GoVersion:"go1.16.5", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"20", GitVersion:"v1.20.9", GitCommit:"7a576bc3935a6b555e33346fd73ad77c925e9e4a", GitTreeState:"clean", BuildDate:"2021-07-15T20:56:38Z", GoVersion:"go1.15.14", Compiler:"gc", Platform:"linux/amd64"}
-- tingyu gu
kubectl
kubernetes

1 Answer

10/21/2021

I will use a simpler deployment to demonstrate patching a lifecycle hook, where you can use the same technique for your own deployment.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: busybox
spec:
  replicas: 1
  selector:
    matchLabels:
      app: busybox
  template:
    metadata:
      labels:
        app: busybox
    spec:
      containers:
      - name: busybox
        image: busybox
        command: ["ash","-c","while :; do echo $(date); sleep 1; done"]

The path is up to /spec/template/spec/containers/0/lifecycle or you will get the response "The request is invalid."

kubectl patch deployment busybox --type json -p '[{"op":"add","path":"/spec/template/spec/containers/0/lifecycle","value":{"preStop": {"exec": {"command": ["/bin/sleep","10"]}}}}]'

deployment.apps/busybox patched

Upon patched the deployment will restart. You can do a kubectl get deployment busybox -o yaml to examine the patched. If you patch again with same value there will be no change.

-- gohm'c
Source: StackOverflow