Why is my systemd unit not reading env variables properly?

6.6k views Asked by At

I am trying to run kubernetes on coreos. I am using fleet, setup-network-environment, and kube-register to register nodes. However, in my cloud-init file where I write my systemd unit files, the kubelet's unit file won't run this properly:

 ExecStart=/opt/bin/kubelet  \
 --address=0.0.0.0 --port=10250 \
 --hostname_override=${DEFAULT_IPV4} \
 --allow_privileged=true \
 --logtostderr=true \
 --healthz_bind_address=0.0.0.0

Instead of my public ip, ${DEFAULT_IPV4} results in $default_ipv4, which also doesn't result in the ip. I know --host-name-override should just take a string, and it works when I run this line from command line. There are other unit files where ${ENV_VAR} works fine. Why is it that for the kubelet's unit file, it just breaks?

EDIT 1

/etc/network-environment

LO_IPV4=127.0.0.1
ENS33_IPV4=192.168.195.242
DEFAULT_IPV4=192.168.195.242
ENS34_IPV4=172.22.22.238

EDIT 2

kubelet unit file

- name: kube-kubelet.service
  command: start
  content: |
    [Unit]
    Description=Kubernetes Kubelet
    Documentation=https://github.com/GoogleCloudPlatform/kubernetes
    Requires=setup-network-environment.service
    After=setup-network-environment.service
    [Service]
    EnvironmentFile=/etc/network-environment
    ExecStartPre=/usr/bin/curl -L -o /opt/bin/kubelet -z /opt/bin/kubelet https://storage.googleapis.com/kubernetes-release/release/v0.18.2/bin/linux/amd64/kubelet
    ExecStartPre=/usr/bin/chmod +x /opt/bin/kubelet
    # wait for kubernetes master to be up and ready
    ExecStartPre=/opt/bin/wupiao 172.22.22.10 8080
    ExecStart=/opt/bin/kubelet \
    --address=0.0.0.0 \
    --port=10250 \
    --hostname_override=172.22.22.21 \
    --api_servers=172.22.22.10:8080 \
    --allow_privileged=true \
    --logtostderr=true \
    --healthz_bind_address=0.0.0.0 \
    --healthz_port=10248
    Restart=always
    RestartSec=10
2

There are 2 answers

0
Christian Grabowski On BEST ANSWER

It would seem the issue was in the version of coreos in the vagrant box. After an update of the vagrant box the environment variable was able to resolve to the proper value.

7
Greg On

The Exec*=command is not a shell command. In my experimenting it was not very good at figuring out where the variable was unless it was by itself. I went and looked at some examples online and they always show the environment variable by itself. So, given a file like /tmp/myfile:

ENV=1.2.3.4

These [Service] definitions won't do what you think:

EnvironmentFile=/tmp/myfile
ExecStart=echo M$ENV
ExecStart=echo $ENV:8080

but, this will work on a line by itself:

EnvironmentFile=/tmp/myfile
ExecStart=echo $ENV

That doesn't help much when trying to pass an argument, like:

EnvironmentFile=/tmp/myfile
ExecStart=echo --myarg=http://$ENV:8080/v2

To accomplish passing the argument I had to put the entire myarg in a string in /tmp/myfile:

ENV="--myarg=http://1.2.3.4:8080/v2"

Finally I could can get my argument passed:

EnvironmentFile=/tmp/myfile
ExecStart=echo $ENV