k3s-io / k3s

Lightweight Kubernetes
https://k3s.io
Apache License 2.0
26.62k stars 2.24k forks source link

Fix #10012 - empty string as a parameter in etcd extra args #10018

Open jordanorc opened 3 weeks ago

jordanorc commented 3 weeks ago

Proposed Changes

This modification checks if a parameter passed in --etcd-arg is an empty string, preventing it from being wrongly converted to an empty array by the function ToConfigFile.

Types of Changes

BugFix

Verification

  1. Build k3s following the tutorial in https://github.com/k3s-io/k3s/blob/master/BUILDING.md
  2. Run ./dist/artifacts/k3s server --cluster-init --etcd-arg=listen-metrics-urls=

Instead of throwing the error: error unmarshaling JSON: while decoding JSON: json: cannot unmarshal array into Go struct field configYAML.listen-metrics-urls of type string, k3s will continue the startup process.

Testing

See linked issue

Linked Issues

https://github.com/k3s-io/k3s/issues/10012

User-Facing Change

NONE

brandond commented 3 weeks ago

etcd args are already somewhat unique in that they are converted to config json, which has a side effect of deduplicating flags. Most other flags are simply appended to our defaults and passed into the component CLI for the component's internal flag parser to figure out.

With this change you will be able to unset/mask k3s default flags by setting them to an empty string, which will make the etcd args even more unique.

jordanorc commented 3 weeks ago

I think that might be the source of some confusion - the default isn't an empty value, and for the other --COMPONENT-arg flags, passing through an arg with an empty value won't restore the default. What you're asking for is the ability to unset or mask a default value that is set internally by k3s. That isn't currently possible.

@brandond I partially agree with you. Actually, the behavior between the --COMPONENT-arg is divergent. See an example of the --kube-apiserver-arg behavior. If I change some arg to empty, it is forwarded to kube-apiserver as an empty string (not an empty map).

Running the command:

k3s server --cluster-init --kube-apiserver-arg=authorization-mode=

Results in the log:

INFO[0000] Running kube-apiserver --advertise-port=6443 --allow-privileged=true --anonymous-auth=false --api-audiences=https://kubernetes.default.svc.cluster.local,k3s --authorization-mode= --bind-address=127.0.0.1 ...

The current behavior of --etcd-arg is to translate "" or null into an empty map ([]) and forward this value to etcd. Many of etcd values can be an empty string, and I cannot set it with --etcd-arg because of this bug.

Despite the fact that it is not possible to unset a value with --etcd-arg, it should be possible to set it to an empty string once many etcd args can be set to an empty string.