The need to configure a specific pod’s container arguments is a common Kubernetes administration task. As examples, you might need to enable verbose logging, set an explicit value to override a default, or configure a host name or port set in a container’s arguments.
In the example below, we are targeting the ‘metrics-server’ in the kube-system namespace, but the same logic would apply to any resource.
Adding a single argument
# define variables that target deployment deployment_name=metrics-server deployment_ns=kube-system container_name=metrics-server additional_argument="--v=4" # make sure 'jq' utility is installed for json manipulation sudo apt install -y jq # show current arguments kubectl get deployment $deployment_name -n $deployment_ns -o json | jq ".spec.template.spec.containers[] | select (.name == \"$container_name\").args" # get index of pod container container_index=$(kubectl get deployment $deployment_name -n $deployment_ns -o json | jq ".spec.template.spec.containers | to_entries | .[] | select(.value.name | contains (\"$container_name\")) | .key") echo "Going to update arguments of deployment/container/index: $deployment_name/$container_name/$container_index" # do append of single argument to deployment # append if dry run: --dry-run=client -o yaml kubectl patch deployment $deployment_name -n $deployment_ns --type=json -p="[{'op': 'add', 'path': '/spec/template/spec/containers/$container_index/args/-', 'value': '$additional_argument' }]"
Adding multiple arguments
If you wanted to add multiple arguments at the same time, use ‘jq‘.
additional_arguments_json='["--v=4","--kubelet-insecure-tls"]' # append arguments and reapply kubectl get deployment $deployment_name -n $deployment_ns -o json | jq ".spec.template.spec.containers[$container_index].args += $additional_arguments_json" | kubectl apply -f -
This appends to the argument list without checking for existence first. So if these arguments already exist, you will end up with duplicates.
Adding multiple arguments idempotently (no duplicates)
If you need to ensure that added arguments are not duplicates, and that any existing arguments are overwritten with your new value, then use the commands below.
# save all current arguments to temp file argsfile=$(mktemp -t "$container_name.XXXXXXXX.json") kubectl get deployment $deployment_name -n $deployment_ns -o jsonpath="{.spec.template.spec.containers[0].args}" > $argsfile # add argument as test jq ". += [\"--mytestarg\"]" $argsfile | tee $argsfile.temp cp $argsfile.temp $argsfile # remove argument as test jq ". |= map(select(startswith(\"--mytestarg\")|not))" $argsfile | tee $argsfile.temp cp $argsfile.temp $argsfile # do bulk modification. ensure no duplicates by first doing remove, then add arg_array=("--a" "--b=2" "--v=5") for carg in ${arg_array[@]}; do justkey=$(echo $carg | awk -F'[= ]' '{print $1}') jq ". |= map(select(startswith(\"$justkey\")|not))" $argsfile > $argsfile.temp ; cp $argsfile.temp $argsfile jq ". += [\"$carg\"]" $argsfile > $argsfile.temp ; cp $argsfile.temp $argsfile done # show final result jq . $argsfile # apply latest arguments kubectl get deployment $deployment_name -n $deployment_ns -o=json | jq ".spec.template.spec.containers[$container_index].args |= $(cat $argsfile)" | kubectl apply -f -
REFERENCES
stackoverflow, getting index of item in yaml array using jq
stackoverflow, kubectl patch to delete specific object in array without numerical index
jsonpatch reference, library underneath kubectl patch
kubernetes.io, kubectl patch reference
stackoverflow, shows kubectl json patch with add for appending
stackoverflow, jq deletion for array items that startwith
NOTES
jq with ‘|=’ would clear out and replace arguments with our additional argument list (versus ‘+=’ appends)
check for existence of argument first
# if you needed logic to check if argument was already set if kubectl get deployment $deployment_name -n $deployment_ns -o=jsonpath="{.spec.template.spec.containers[$container_index].args}" | grep -q -- "$additional_argument" ; then echo "found argument '$additional_argument' there already"; fi
inline patch to null finalizers
kubectl patch pod pod_name -p '{"metadata":{"finalizers":null}}'