Skip to content
This repository was archived by the owner on Jun 29, 2022. It is now read-only.

Commit f483143

Browse files
committed
packet: Read BGP peer address from metadata service
In some Packet facilities the BGP peer address isn't the same as the gateway address allocated for a host. Rather, it is a loopback address that's reachable via the gateway. The Packet metadata service now exposes BGP info to hosts, so we can query the metadata service for the BGP peer address. We currently use the first peer address only since MetalLB doesn't support multiple node peers yet. The source address is explicitly specified since when the peer address is a loopback address, the source IP addresses which ends up getting selected by the kernel is the node's *public* address which doesn't work. In cases where the peer address is the gateway address there is no harm in explicitly specifying the source. Removing the `/bin/sh -c ""` wrapper in ExecStart because we no longer need a shell since now we read the peer address from an environment file. Removing the TODO about using Afterburn for the peer address since we no longer use the gateway address as the peer address. Fixes #1009.
1 parent 3008e5a commit f483143

File tree

2 files changed

+84
-39
lines changed

2 files changed

+84
-39
lines changed

assets/terraform-modules/packet/flatcar-linux/kubernetes/workers/cl/worker.yaml.tmpl

Lines changed: 82 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,20 @@ systemd:
3434
ExecStart=/bin/sh -c 'while ! /usr/bin/grep '^[^#[:space:]]' /etc/resolv.conf > /dev/null; do sleep 1; done; /opt/wait-for-dns ${dns_zone} ${cluster_name}-private 3600'
3535
[Install]
3636
RequiredBy=kubelet.service
37+
%{~ if bgp_node_labels != "" ~}
38+
- name: bgp-metadata.service
39+
enable: true
40+
contents: |
41+
[Unit]
42+
Description=Write BGP metadata to disk
43+
Before=kubelet.service
44+
[Service]
45+
Type=oneshot
46+
RemainAfterExit=true
47+
ExecStart=/opt/bgp-metadata
48+
[Install]
49+
RequiredBy=kubelet.service
50+
%{~ endif ~}
3751
- name: coreos-metadata.service
3852
enable: true
3953
contents: |
@@ -54,6 +68,7 @@ systemd:
5468
After=coreos-metadata.service
5569
[Service]
5670
EnvironmentFile=/run/metadata/flatcar
71+
EnvironmentFile=-/run/metadata/bgp
5772
EnvironmentFile=/etc/kubernetes/kubelet.env
5873
Environment="RKT_RUN_ARGS=--uuid-file-save=/var/cache/kubelet-pod.uuid \
5974
--volume=resolv,kind=host,source=/etc/resolv.conf \
@@ -82,43 +97,38 @@ systemd:
8297
ExecStartPre=/usr/bin/bash -c "grep 'certificate-authority-data' /etc/kubernetes/kubeconfig | awk '{print $2}' | base64 -d > /etc/kubernetes/ca.crt"
8398
ExecStartPre=-/usr/bin/rkt rm --uuid-file=/var/cache/kubelet-pod.uuid
8499
ExecStartPre=/etc/kubernetes/configure-kubelet-cgroup-driver
85-
# TODO: Workaround until https://github.com/coreos/afterburn/pull/358
86-
# makes it into Flatcar. Then we can read COREOS_PACKET_IPV4_PRIVATE_GATEWAY_0
87-
# from /run/metadata/flatcar and disable the template conditionals below.
88-
ExecStart=/bin/sh -c \
89-
"%{~ if bgp_node_labels != "" ~}
90-
BGP_PEER_ADDRESS=$(ip route | grep '10.0.0.0/8' | awk {'print $3'}); \
91-
%{~ endif ~}
92-
/usr/lib/coreos/kubelet-wrapper \
93-
--node-ip=$${COREOS_PACKET_IPV4_PRIVATE_0} \
94-
--anonymous-auth=false \
95-
--authentication-token-webhook \
96-
--authorization-mode=Webhook \
97-
--client-ca-file=/etc/kubernetes/ca.crt \
98-
--cluster_dns=${k8s_dns_service_ip} \
99-
--cluster_domain=${cluster_domain_suffix} \
100-
--cni-conf-dir=/etc/cni/net.d \
101-
--config=/etc/kubernetes/kubelet.config \
102-
--exit-on-lock-contention \
103-
%{~ if enable_tls_bootstrap ~}
104-
--kubeconfig=/var/lib/kubelet/kubeconfig \
105-
--bootstrap-kubeconfig=/etc/kubernetes/kubeconfig \
106-
--rotate-certificates \
107-
%{~ else ~}
108-
--kubeconfig=/etc/kubernetes/kubeconfig \
109-
%{~ endif ~}
110-
--lock-file=/var/run/lock/kubelet.lock \
111-
--network-plugin=cni \
112-
--node-labels=$${NODE_LABELS} \
113-
--node-labels=lokomotive.alpha.kinvolk.io/public-ipv4=$${COREOS_PACKET_IPV4_PUBLIC_0} \
114-
%{~ if bgp_node_labels != "" ~}
115-
--node-labels=$${BGP_NODE_LABELS},metallb.lokomotive.io/peer-address=$BGP_PEER_ADDRESS \
116-
%{~ endif ~}
117-
--pod-manifest-path=/etc/kubernetes/manifests \
118-
--read-only-port=0 \
119-
--register-with-taints=$${NODE_TAINTS} \
120-
--address=$${COREOS_PACKET_IPV4_PRIVATE_0} \
121-
--volume-plugin-dir=/var/lib/kubelet/volumeplugins"
100+
ExecStart=/usr/lib/coreos/kubelet-wrapper \
101+
--node-ip=$${COREOS_PACKET_IPV4_PRIVATE_0} \
102+
--anonymous-auth=false \
103+
--authentication-token-webhook \
104+
--authorization-mode=Webhook \
105+
--client-ca-file=/etc/kubernetes/ca.crt \
106+
--cluster_dns=${k8s_dns_service_ip} \
107+
--cluster_domain=${cluster_domain_suffix} \
108+
--cni-conf-dir=/etc/cni/net.d \
109+
--config=/etc/kubernetes/kubelet.config \
110+
--exit-on-lock-contention \
111+
%{~ if enable_tls_bootstrap ~}
112+
--kubeconfig=/var/lib/kubelet/kubeconfig \
113+
--bootstrap-kubeconfig=/etc/kubernetes/kubeconfig \
114+
--rotate-certificates \
115+
%{~ else ~}
116+
--kubeconfig=/etc/kubernetes/kubeconfig \
117+
%{~ endif ~}
118+
--lock-file=/var/run/lock/kubelet.lock \
119+
--network-plugin=cni \
120+
--node-labels=$${NODE_LABELS} \
121+
--node-labels=lokomotive.alpha.kinvolk.io/public-ipv4=$${COREOS_PACKET_IPV4_PUBLIC_0} \
122+
%{~ if bgp_node_labels != "" ~}
123+
--node-labels=$${BGP_NODE_LABELS} \
124+
--node-labels=metallb.lokomotive.io/peer-address=$${BGP_PEER_ADDRESS_0} \
125+
--node-labels=metallb.lokomotive.io/src-address=$${COREOS_PACKET_IPV4_PRIVATE_0} \
126+
%{~ endif ~}
127+
--pod-manifest-path=/etc/kubernetes/manifests \
128+
--read-only-port=0 \
129+
--register-with-taints=$${NODE_TAINTS} \
130+
--address=$${COREOS_PACKET_IPV4_PRIVATE_0} \
131+
--volume-plugin-dir=/var/lib/kubelet/volumeplugins
122132
ExecStop=-/usr/bin/rkt stop --uuid-file=/var/cache/kubelet-pod.uuid
123133
Restart=always
124134
RestartSec=5
@@ -421,6 +431,41 @@ storage:
421431
done
422432
echo "$record.$zone is available on all nameservers"
423433
exit 0
434+
- path: /opt/bgp-metadata
435+
filesystem: root
436+
mode: 0544
437+
contents:
438+
inline: |
439+
#!/bin/bash
440+
set -o pipefail
441+
max_attempts=3600
442+
target=/run/metadata/bgp
443+
echo "Polling metadata service for BGP information"
444+
counter=0
445+
while [[ $counter -lt $max_attempts ]]; do
446+
out=$(curl -s -f --connect-timeout 5 \
447+
https://metadata.packet.net/metadata | jq -r .bgp_neighbors[0].peer_ips[0])
448+
ret=$?
449+
if [[ $ret -ne 0 ]]; then
450+
echo "Non-zero exit code: $ret"
451+
elif [[ "$out" = "" ]]; then
452+
echo "Empty response"
453+
elif [[ "$out" = "null" ]]; then
454+
echo "Null response"
455+
else
456+
echo "BGP metadata is available!"
457+
if [[ ! "$out" =~ ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}$ ]]; then
458+
echo "Invalid IP $out"
459+
exit 1
460+
fi
461+
echo "BGP_PEER_ADDRESS_0=$out" > "$target"
462+
exit $?
463+
fi
464+
sleep 1
465+
counter=$((counter+1))
466+
done
467+
echo "BGP metadata did not become available in time"
468+
exit 1
424469
passwd:
425470
users:
426471
- name: core

0 commit comments

Comments
 (0)