Skip to content

Commit 542b29b

Browse files
committed
Attempt to add IPv6 to K3s
1 parent 9e05466 commit 542b29b

File tree

2 files changed

+118
-1
lines changed

2 files changed

+118
-1
lines changed

.github/workflows/test_k3s.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,41 +25,66 @@ jobs:
2525
metrics-enabled: "true"
2626
traefik-enabled: "true"
2727
docker-enabled: "false"
28+
ip-mode: "default"
2829

2930
- k3s-version: ""
3031
k3s-channel: latest
3132
helm-version: ""
3233
metrics-enabled: "false"
3334
traefik-enabled: "false"
3435
docker-enabled: "true"
36+
ip-mode: "default"
3537

3638
- k3s-version: ""
3739
k3s-channel: latest
3840
helm-version: ""
3941
metrics-enabled: "true"
4042
traefik-enabled: "true"
4143
docker-enabled: "true"
44+
ip-mode: "default"
4245

4346
- k3s-version: ""
4447
k3s-channel: latest
4548
helm-version: ""
4649
metrics-enabled: "false"
4750
traefik-enabled: "false"
4851
docker-enabled: "false"
52+
ip-mode: "default"
4953

5054
- k3s-version: v1.24.7+k3s1
5155
k3s-channel: ""
5256
helm-version: v3.5.0
5357
metrics-enabled: "true"
5458
traefik-enabled: "true"
5559
docker-enabled: "false"
60+
ip-mode: "default"
5661

5762
- k3s-version: v1.24.7+k3s1
5863
k3s-channel: ""
5964
helm-version: v3.5.0
6065
metrics-enabled: "false"
6166
traefik-enabled: "false"
6267
docker-enabled: "true"
68+
ip-mode: "default"
69+
70+
# Test IPv6 and dual stack
71+
72+
- k3s-version: ""
73+
k3s-channel: latest
74+
helm-version: ""
75+
metrics-enabled: "false"
76+
traefik-enabled: "false"
77+
docker-enabled: "false"
78+
ip-mode: "ipv6"
79+
80+
- k3s-version: ""
81+
k3s-channel: latest
82+
helm-version: ""
83+
metrics-enabled: "false"
84+
traefik-enabled: "false"
85+
docker-enabled: "false"
86+
ip-mode: "dual"
87+
6388

6489
steps:
6590
- uses: actions/checkout@v4
@@ -73,6 +98,7 @@ jobs:
7398
metrics-enabled: ${{ matrix.metrics-enabled }}
7499
traefik-enabled: ${{ matrix.traefik-enabled }}
75100
docker-enabled: ${{ matrix.docker-enabled }}
101+
ip-mode: ${{ matrix.ip-mode }}
76102

77103
- name: Verify action's outputs and env
78104
run: |
@@ -178,6 +204,18 @@ jobs:
178204
- name: Run netpol enforcement test chart's tests
179205
run: helm test test-netpol-enforcement --logs
180206

207+
# https://kubernetes.io/docs/tasks/network/validate-dual-stack/#validate-pod-addressing
208+
- name: Check pods have an IPv6 address
209+
if: matrix.ip-mode == 'dual' || matrix.ip-mode == 'ipv6'
210+
run: |
211+
echo "::group::pod/check-ipv6"
212+
kubectl run check-ipv6 --image=nginx
213+
kubectl wait --for=condition=Ready pod/check-ipv6
214+
kubectl get pod/check-ipv6 -o yaml
215+
echo "::endgroup::"
216+
217+
kubectl get pod/check-ipv6 -o go-template --template='{{range .status.podIPs}}{{printf "%s\n" .ip}}{{end}}' | grep '[0-9a-f]:\S*:[0-9a-f]'
218+
181219
# ref: https://github.com/jupyterhub/action-k8s-namespace-report
182220
- name: Kubernetes namespace report (kube-system)
183221
uses: jupyterhub/action-k8s-namespace-report@v1

action.yml

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ inputs:
4646
description: Enable K3s to use the Docker daemon
4747
required: false
4848
default: "false"
49+
ip-mode:
50+
description: 'Switch between IPv4 and/or IPv6: "default", "dual" or "ipv6"'
51+
required: false
52+
default: default
4953
extra-setup-args:
5054
description: Addition arguments to be passed to the K3S setup script
5155
required: false
@@ -90,6 +94,41 @@ runs:
9094
echo "::endgroup::"
9195
shell: bash
9296

97+
# https://docs.k3s.io/networking/basic-network-options#dual-stack-ipv4--ipv6-networking
98+
- name: Set IP mode variables
99+
run: |
100+
echo "::group::Setting IP variables"
101+
if [[ "${{ inputs.ip-mode }}" != "default" ]]; then
102+
NODE_IP4=$(ip -4 addr show eth0 | grep -oP '(?<=inet\s)([^/]+)')
103+
if [ -z "$NODE_IP4" ]; then
104+
echo "Failed to get node IP4"
105+
exit 1
106+
fi
107+
NODE_IP6=$(ip -6 addr show eth0 | grep -oP '(?<=inet6\s)([^/]+)')
108+
if [ -z "$NODE_IP6" ]; then
109+
echo "Failed to get node IP6"
110+
exit 1
111+
fi
112+
113+
if [[ "${{ inputs.ip-mode }}" = "dual" ]]; then
114+
echo K3S_CLUSTER_CIDR="10.42.0.0/16,2001:cafe:42::/56"
115+
echo K3S_SERVICE_CIDR="10.43.0.0/16,2001:cafe:43::/112"
116+
echo K3S_NODE_IP="${NODE_IP4},{NODE_IP6}"
117+
elif [[ "${{ inputs.ip-mode }}" = "ipv6" ]]; then
118+
echo K3S_CLUSTER_CIDR="2001:cafe:42::/56"
119+
echo K3S_SERVICE_CIDR="2001:cafe:43::/112"
120+
echo K3S_NODE_IP="${NODE_IP6}"
121+
else
122+
echo "Invalid ip-mode: ${{ inputs.ip-mode }}"
123+
exit 1
124+
fi
125+
fi
126+
echo "K3S_CLUSTER_CIDR=$K3S_CLUSTER_CIDR" >> $GITHUB_ENV
127+
echo "K3S_SERVICE_CIDR=$K3S_SERVICE_CIDR" >> $GITHUB_ENV
128+
echo "K3S_NODE_IP=$K3S_NODE_IP" >> $GITHUB_ENV
129+
echo "::endgroup::"
130+
shell: bash
131+
93132
# NOTE: We apply a workaround as of version 3.0.1 by passing
94133
# --egress-selector-mode=disabled by default as not doing so following
95134
# modern versions of k3s has led to issues with `kubectl exec` and
@@ -121,12 +160,25 @@ runs:
121160
if [[ "${{ inputs.extra-setup-args }}" != *--egress-selector-mode* ]]; then
122161
default_extra_setup_args=--egress-selector-mode=disabled
123162
fi
163+
if [[ -n "$K3S_CLUSTER_CIDR" ]]; then
164+
k3s_cluster_cidr="--cluster-cidr=$K3S_CLUSTER_CIDR"
165+
fi
166+
if [[ -n "$K3S_SERVICE_CIDR" ]]; then
167+
k3s_service_cidr="--service-cidr=$K3S_SERVICE_CIDR"
168+
fi
169+
if [[ -n "$K3S_NODE_IP" ]]; then
170+
k3s_node_ip="--service-cidr=$K3S_NODE_IP"
171+
fi
172+
124173
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION="${{ inputs.k3s-version }}" INSTALL_K3S_CHANNEL="${{ inputs.k3s-channel }}" sh -s - \
125174
${k3s_disable_metrics} \
126175
${k3s_disable_traefik} \
127176
--disable-network-policy \
128177
--flannel-backend=none \
129178
${k3s_docker} \
179+
${k3s_cluster_cidr} \
180+
${k3s_service_cidr} \
181+
${k3s_node_ip} \
130182
${{ inputs.extra-setup-args }} \
131183
${default_extra_setup_args}
132184
echo "::endgroup::"
@@ -150,6 +202,8 @@ runs:
150202
#
151203
# ref: https://rancher.com/docs/k3s/latest/en/installation/network-options/
152204
#
205+
# IPv6: https://docs.tigera.io/calico/latest/networking/ipam/ipv6
206+
#
153207
- name: Setup calico
154208
run: |
155209
echo "::group::Setup calico"
@@ -159,12 +213,37 @@ runs:
159213
cd calico
160214
yq -s '"\(.kind)-\(.metadata.name).yaml"' /tmp/calico.yaml
161215
162-
# Modify ConfigMap/calico-config: Look for `"type": "calico"` and add
216+
# ConfigMap/calico-config: Look for `"type": "calico"` and add
163217
# `"container_settings": ...` on the next line
164218
sed -i.bak '/"type": "calico"/a\
165219
"container_settings": {"allow_ip_forwarding": true},'\
166220
ConfigMap-calico-config.yaml
167221
222+
# Optionally configure IPv6
223+
# https://docs.tigera.io/calico/latest/networking/ipam/ipv6
224+
# ConfigMap/calico-config: Look for `"type": "calico-ipam"` and add
225+
# additional properties
226+
if [[ "${{ inputs.ip-mode }}" = "dual" ]]; then
227+
sed -i '/"type": "calico-ipam"/a\
228+
, "assign_ipv4": "true", "assign_ipv6": "true"'\
229+
ConfigMap-calico-config.yaml
230+
fi
231+
if [[ "${{ inputs.ip-mode }}" = "ipv6" ]]; then
232+
sed -i '/"type": "calico-ipam"/a\
233+
, "assign_ipv4": "false", "assign_ipv6": "true"'\
234+
ConfigMap-calico-config.yaml
235+
fi
236+
237+
if [[ "${{ inputs.ip-mode }}" = "dual" || "${{ inputs.ip-mode }}" = "ipv6" ]]; then
238+
# DaemonSet/calico-node: Modify and add environment variables
239+
sed -i.bak -re '/- name: FELIX_IPV6SUPPORT/{n; s/"false"/"true"\n\
240+
- name: IP6\n\
241+
value: autodetect\n\
242+
- name: CALICO_IPV6POOL_CIDR\n\
243+
value: "2001:cafe:42::\/56"/}'\
244+
DaemonSet-calico-node.yaml
245+
fi
246+
168247
for f in *.yaml.bak; do
169248
diff -u "$f" "${f%.bak}" || :
170249
done

0 commit comments

Comments
 (0)