Files
garden/KaraKeep/attachments/22d9b6ff-a6f6-4d92-b16f-bebe89b6fd70-How-to-Configure-K3s-for-IPv6.jpg

169 lines
13 KiB
Plaintext
Raw Permalink Normal View History

2026-04-23 20:22:46 -05:00
<div id="readability-page-1" class="page"><div>
<h2 id="introduction">Introduction<a href="#introduction" aria-label="Link to Introduction"><svg fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"></path></svg></a></h2><p>As IPv4 addresses become scarce and IPv6 adoption grows, running Kubernetes with IPv6 is increasingly important. K3s supports IPv6 single-stack mode where pods, services, and nodes communicate exclusively over IPv6. This guide covers configuring K3s for IPv6 operation, including network requirements, installation, and verification.</p><h2 id="prerequisites">Prerequisites<a href="#prerequisites" aria-label="Link to Prerequisites"><svg fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"></path></svg></a></h2><ul><li>Linux host with IPv6 network connectivity</li><li>IPv6 subnet available for pod and service CIDR allocation</li><li>Kernel with IPv6 support (all modern Linux kernels)</li><li>No IPv4-only constraints in your environment</li></ul><h2 id="step-1-verify-ipv6-support-on-the-host">Step 1: Verify IPv6 Support on the Host<a href="#step-1-verify-ipv6-support-on-the-host" aria-label="Link to Step 1: Verify IPv6 Support on the Host"><svg fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"></path></svg></a></h2><pre><code data-highlighted="yes"><span># Check if IPv6 is enabled</span>
<span>cat</span> /proc/sys/net/ipv6/conf/all/disable_ipv6
<span># 0 = enabled, 1 = disabled</span>
<span># If disabled, enable it</span>
<span>echo</span> 0 &gt; /proc/sys/net/ipv6/conf/all/disable_ipv6
<span># Make permanent</span>
<span>cat</span> &gt;&gt; /etc/sysctl.conf &lt;&lt; <span>'EOF'</span>
net.ipv6.conf.all.disable_ipv6 = 0
net.ipv6.conf.default.disable_ipv6 = 0
net.ipv6.conf.lo.disable_ipv6 = 0
EOF
sysctl -p
<span># Check the host's IPv6 address</span>
ip -6 addr show
<span># Should show your IPv6 addresses</span>
<span># Test IPv6 connectivity</span>
ping6 -c 4 2001:4860:4860::8888 <span># Google's IPv6 DNS</span></code></pre><h2 id="step-2-configure-ipv6-forwarding">Step 2: Configure IPv6 Forwarding<a href="#step-2-configure-ipv6-forwarding" aria-label="Link to Step 2: Configure IPv6 Forwarding"><svg fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"></path></svg></a></h2><p>Kubernetes requires IP forwarding to route pod traffic:</p><pre><code data-highlighted="yes"><span># Enable IPv6 forwarding</span>
<span>cat</span> &gt;&gt; /etc/sysctl.conf &lt;&lt; <span>'EOF'</span>
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.default.forwarding = 1
EOF
sysctl -p
<span># Verify</span>
<span>cat</span> /proc/sys/net/ipv6/conf/all/forwarding
<span># Should output: 1</span></code></pre><h2 id="step-3-install-k3s-with-ipv6-configuration">Step 3: Install K3s with IPv6 Configuration<a href="#step-3-install-k3s-with-ipv6-configuration" aria-label="Link to Step 3: Install K3s with IPv6 Configuration"><svg fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"></path></svg></a></h2><pre><code data-highlighted="yes"><span># Plan your IPv6 subnets:</span>
<span># Cluster CIDR (pod IPs): fd42::/24</span>
<span># Service CIDR: fd43::/112</span>
<span># Node CIDR size: /80 per node</span>
<span># Install K3s server with IPv6</span>
curl -sfL https://get.k3s.io | \
INSTALL_K3S_EXEC=<span>"
--cluster-cidr=fd42::/24
--service-cidr=fd43::/112
--cluster-dns=fd43::10
--flannel-ipv6-masq=true
"</span> \
sh -</code></pre><p>Or using a config file:</p><pre><code data-highlighted="yes"><span># /etc/rancher/k3s/config.yaml</span>
<span># IPv6 single-stack configuration</span>
<span>cluster-cidr:</span> <span>"fd42::/24"</span>
<span>service-cidr:</span> <span>"fd43::/112"</span>
<span>cluster-dns:</span> <span>"fd43::10"</span>
<span># Flannel IPv6 settings</span>
<span>flannel-ipv6-masq:</span> <span>true</span>
<span># Optional: specify flannel backend</span>
<span>flannel-backend:</span> <span>vxlan</span></code></pre><h2 id="step-4-install-k3s-agent-with-ipv6">Step 4: Install K3s Agent with IPv6<a href="#step-4-install-k3s-agent-with-ipv6" aria-label="Link to Step 4: Install K3s Agent with IPv6"><svg fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"></path></svg></a></h2><pre><code data-highlighted="yes"><span># Agent nodes need the server's IPv6 address</span>
curl -sfL https://get.k3s.io | \
K3S_URL=https://[&lt;server-ipv6&gt;]:6443 \
K3S_TOKEN=&lt;node-token&gt; \
sh -
<span># Note: IPv6 addresses in URLs must be enclosed in brackets</span>
<span># Example: https://[2001:db8::1]:6443</span></code></pre><h2 id="step-5-verify-ipv6-cluster">Step 5: Verify IPv6 Cluster<a href="#step-5-verify-ipv6-cluster" aria-label="Link to Step 5: Verify IPv6 Cluster"><svg fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"></path></svg></a></h2><pre><code data-highlighted="yes"><span># Check nodes have IPv6 addresses</span>
kubectl get nodes -o wide
<span># Internal-IP should show IPv6 addresses</span>
<span># Check pods have IPv6 IPs</span>
kubectl get pods -A -o wide
<span># Pod IP should be from the fd42::/24 range</span>
<span># Check services have IPv6 cluster IPs</span>
kubectl get svc -A
<span># Cluster IP should be from fd43::/112 range</span>
<span># Verify DNS is using IPv6</span>
kubectl run dns-test --image=busybox --restart=Never -- <span>sleep</span> 3600
kubectl <span>exec</span> dns-test -- nslookup kubernetes.default.svc.cluster.local
<span># Should resolve to IPv6 address</span>
kubectl delete pod dns-test</code></pre><h2 id="step-6-test-ipv6-pod-communication">Step 6: Test IPv6 Pod Communication<a href="#step-6-test-ipv6-pod-communication" aria-label="Link to Step 6: Test IPv6 Pod Communication"><svg fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"></path></svg></a></h2><pre><code data-highlighted="yes"><span># Deploy a test application</span>
<span>cat</span> &lt;&lt;<span>'EOF'</span> | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: ipv6-server
spec:
containers:
- name: server
image: nginx:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: ipv6-server-svc
spec:
selector:
name: ipv6-server <span># Note: need proper label</span>
ports:
- port: 80
targetPort: 80
<span>type</span>: ClusterIP
EOF
<span># Get the service ClusterIP (should be IPv6)</span>
kubectl get svc ipv6-server-svc
<span># Test connectivity from another pod</span>
kubectl run test-client --image=curlimages/curl --restart=Never \
-- curl -v http://ipv6-server-svc/
kubectl logs test-client
<span># Clean up</span>
kubectl delete pod ipv6-server test-client
kubectl delete svc ipv6-server-svc</code></pre><h2 id="step-7-configure-ipv6-aware-ingress">Step 7: Configure IPv6-Aware Ingress<a href="#step-7-configure-ipv6-aware-ingress" aria-label="Link to Step 7: Configure IPv6-Aware Ingress"><svg fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"></path></svg></a></h2><p>For Traefik to listen on IPv6:</p><pre><code data-highlighted="yes"><span># /var/lib/rancher/k3s/server/manifests/traefik-ipv6.yaml</span>
<span>apiVersion:</span> <span>helm.cattle.io/v1</span>
<span>kind:</span> <span>HelmChartConfig</span>
<span>metadata:</span>
<span>name:</span> <span>traefik</span>
<span>namespace:</span> <span>kube-system</span>
<span>spec:</span>
<span>valuesContent:</span> <span>|-
additionalArguments:
# Listen on all interfaces including IPv6
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
# Ensure Traefik binds to IPv6
service:
ipFamilies:
- IPv6
ipFamilyPolicy: SingleStack</span></code></pre><h2 id="step-8-coredns-ipv6-configuration">Step 8: CoreDNS IPv6 Configuration<a href="#step-8-coredns-ipv6-configuration" aria-label="Link to Step 8: CoreDNS IPv6 Configuration"><svg fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"></path></svg></a></h2><p>Ensure CoreDNS is configured for IPv6:</p><pre><code data-highlighted="yes"><span># Verify CoreDNS has IPv6 service IP</span>
kubectl get svc coredns -n kube-system
<span># The cluster-dns flag should point to an IPv6 address</span>
<span># Default: fd43::10 (from service CIDR)</span>
<span># Verify DNS resolution works over IPv6</span>
kubectl run dns-test --image=busybox --restart=Never -- \
nslookup kubernetes.default.svc.cluster.local fd43::10
kubectl logs dns-test
kubectl delete pod dns-test</code></pre><h2 id="step-9-network-policy-with-ipv6">Step 9: Network Policy with IPv6<a href="#step-9-network-policy-with-ipv6" aria-label="Link to Step 9: Network Policy with IPv6"><svg fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"></path></svg></a></h2><pre><code data-highlighted="yes"><span># ipv6-network-policy.yaml</span>
<span>apiVersion:</span> <span>networking.k8s.io/v1</span>
<span>kind:</span> <span>NetworkPolicy</span>
<span>metadata:</span>
<span>name:</span> <span>allow-internal-ipv6</span>
<span>namespace:</span> <span>default</span>
<span>spec:</span>
<span>podSelector:</span> {}
<span>policyTypes:</span>
<span>-</span> <span>Ingress</span>
<span>-</span> <span>Egress</span>
<span>ingress:</span>
<span>-</span> <span>from:</span>
<span>-</span> <span>ipBlock:</span>
<span># Allow from the pod CIDR</span>
<span>cidr:</span> <span>fd42::/24</span>
<span>egress:</span>
<span>-</span> <span>to:</span>
<span>-</span> <span>ipBlock:</span>
<span>cidr:</span> <span>fd42::/24</span>
<span>-</span> <span>ports:</span>
<span># Allow DNS over IPv6</span>
<span>-</span> <span>port:</span> <span>53</span>
<span>protocol:</span> <span>UDP</span>
<span>-</span> <span>port:</span> <span>53</span>
<span>protocol:</span> <span>TCP</span></code></pre><h2 id="conclusion">Conclusion<a href="#conclusion" aria-label="Link to Conclusion"><svg fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"></path></svg></a></h2><p>K3s supports IPv6 single-stack networking with a clean configuration experience. The key requirements are choosing appropriate IPv6 CIDRs for pods and services, enabling IPv6 forwarding on all nodes, and configuring Flannel for IPv6 masquerading. IPv6-only clusters are well-suited for modern data centers and IoT deployments where IPv6 is the primary or sole network protocol. Always verify end-to-end connectivity after configuration with test pods before deploying production workloads.</p> </div></div>