diff --git a/cmd/containerboot/main.go b/cmd/containerboot/main.go index 8e9ff7185..6b50b4654 100644 --- a/cmd/containerboot/main.go +++ b/cmd/containerboot/main.go @@ -4,13 +4,13 @@ //go:build linux -// The containerboot binary is a wrapper for starting tailscaled in a -// container. It handles reading the desired mode of operation out of -// environment variables, bringing up and authenticating Tailscale, -// and any other kubernetes-specific side jobs. +// The containerboot binary is a wrapper for starting tailscaled in a container. +// It handles reading the desired mode of operation out of environment +// variables, bringing up and authenticating Tailscale, and any other +// kubernetes-specific side jobs. // -// As with most container things, configuration is passed through -// environment variables. All configuration is optional. +// As with most container things, configuration is passed through environment +// variables. All configuration is optional. // // - TS_AUTH_KEY: the authkey to use for login. // - TS_ROUTES: subnet routes to advertise. @@ -37,9 +37,13 @@ // compatibility), forcibly log in every time the // container starts. // -// When running on Kubernetes, TS_KUBE_SECRET takes precedence over -// TS_STATE_DIR. Additionally, if TS_AUTH_KEY is not provided and the -// TS_KUBE_SECRET contains an "authkey" field, that key is used. +// When running on Kubernetes, containerboot defaults to storing state in the +// "tailscale" kube secret. To store state on local disk instead, set +// TS_KUBE_SECRET="" and TS_STATE_DIR=/path/to/storage/dir. The state dir should +// be persistent storage. +// +// Additionally, if TS_AUTH_KEY is not set and the TS_KUBE_SECRET contains an +// "authkey" field, that key is used as the tailscale authkey. package main import ( @@ -538,7 +542,7 @@ type settings struct { // defaultEnv returns the value of the given envvar name, or defVal if // unset. func defaultEnv(name, defVal string) string { - if v := os.Getenv(name); v != "" { + if v, ok := os.LookupEnv(name); ok { return v } return defVal diff --git a/cmd/containerboot/main_test.go b/cmd/containerboot/main_test.go index 94adf8b2e..c12269f84 100644 --- a/cmd/containerboot/main_test.go +++ b/cmd/containerboot/main_test.go @@ -346,6 +346,31 @@ func TestContainerBoot(t *testing.T) { }, }, }, + { + Name: "kube_disk_storage", + Env: map[string]string{ + "KUBERNETES_SERVICE_HOST": kube.Host, + "KUBERNETES_SERVICE_PORT_HTTPS": kube.Port, + // Explicitly set to an empty value, to override the default of "tailscale". + "TS_KUBE_SECRET": "", + "TS_STATE_DIR": filepath.Join(d, "tmp"), + "TS_AUTH_KEY": "tskey-key", + }, + KubeSecret: map[string]string{}, + Phases: []phase{ + { + WantCmds: []string{ + "/usr/bin/tailscaled --socket=/tmp/tailscaled.sock --statedir=/tmp --tun=userspace-networking", + "/usr/bin/tailscale --socket=/tmp/tailscaled.sock up --accept-dns=false --authkey=tskey-key", + }, + WantKubeSecret: map[string]string{}, + }, + { + Notify: runningNotify, + WantKubeSecret: map[string]string{}, + }, + }, + }, { Name: "kube_storage_no_patch", Env: map[string]string{