description: How to setup a working ipv4/ipv6 service on k3s
tags:
- kubernetes
---
## Introduction
I have yet to write a lot about the kubernetes setup I use for pieces of my personal infrastructure, because I was not satisfied with what I had to show. Today I picked up k3s again which I like quite a lot for it being a light implementation. Consuming 800M of ram before you get any workload running is hardly lightweight, but it is the lightest I have experienced for kubernetes. An entry level virtual machine at ovh or hetzner having 2G of ram for 3€/month is sufficient to run it, that's what I have been doing for the last year.
The main thing I was not satisfied was ipv6 support. I do not know what changed since last year when I tried and failed to make it work in k3s 1.19, but now with 1.21 and some effort it does work! Here is how.
## Installation
Let's start with a freshly reinstalled ovh vps with Ubuntu 20.04. Make sure to properly configure ipv6 on it, for this ovh machine I configured a netplan that looks like this :
```yaml
network:
version: 2
ethernets:
ens3:
dhcp4: true
match:
macaddress: fa:16:3e:82:71:b7
mtu: 1500
set-name: ens3
dhcp6: no
addresses:
- 2001:41d0:401:3100:0:0:0:fd5/128
gateway6: 2001:41d0:0401:3100:0000:0000:0000:0001
routes:
- to: 2001:41d0:0401:3100:0000:0000:0000:0001
scope: link
```
After installation I just ran an `apt dist-upgrade` then installed `ipvsadm`. Afterwards it's all k3s :
If you are replicating this on your own setup make sure the node-ip addresses are the ones configured on your node, if the cluster-cidr and service-cidr do not conflict with your own you can keep those.
Once ready review the k3s installation script then run it :
```sh
wget https://get.k3s.io -O k3s.sh
less k3s.sh
bash k3s.sh
```
With k3s installed you should be able to access the kubernetes cli with `kubectl get nodes` but basic services like coredns pod won't start before calico is setup.
Edit this file and locate the ingress-nginx-controller Service, which is by default of type NodePort. We are going to replace it with two services of type LoadBalancer, one for ipv4 and one for ipv6. Theoretically a single DualStack service should be supported but it does not work for me, the service only listens on its ipv6 address. So we are going to replace the whole ingress-nginx-controller Service with these two entries :
```yaml
apiVersion: v1
kind: Service
metadata:
annotations:
labels:
helm.sh/chart: ingress-nginx-3.34.0
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 0.48.1
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-nginx-controller-v4
namespace: ingress-nginx
spec:
type: LoadBalancer
ipFamilies:
- IPv4
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
- name: https
port: 443
protocol: TCP
targetPort: https
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/component: controller
---
apiVersion: v1
kind: Service
metadata:
annotations:
labels:
helm.sh/chart: ingress-nginx-3.34.0
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 0.48.1
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-nginx-controller-v6
namespace: ingress-nginx
spec:
type: LoadBalancer
ipFamilies:
- IPv6
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
- name: https
port: 443
protocol: TCP
targetPort: https
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/component: controller
```
Note the metadata names with `-v4` and `-v6` suffixes, the `type: LoadBalancer` and the respective ipFamilies. You can now apply this manifest :
```sh
kubectl apply -f ingress-nginx-0.48.1.yaml
```
Give it some time, then check that the two controller services each get the ipv4 or ipv6 address of your node :