If the default ingress controller (Traefik) not ok for you ?
Here are some simple instructions on how to replace it with Nginx
Uninstall traefik from an existing K3S instance
sudo rm -rf /var/lib/rancher/k3s/server/manifests/traefik.yaml
helm uninstall traefik traefik-crd -n kube-system
sudo systemctl restart k3s
Or the proper way to do so on installing k3s:
curl -sfL https://get.k3s.io | sh -s - --cluster-init --disable-traefik
Install Nginx Ingress Controller
helm upgrade --install ingress-nginx ingress-nginx \
--repo https://kubernetes.github.io/ingress-nginx \
--namespace ingress-nginx --create-namespace
Setting Static IP to Nginx (if needed):
If needed, you can provide a static IP to Nginx using the static-ip-svc.yaml
yml:
# This is the backend service
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx-lb
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
externalTrafficPolicy: Local
type: LoadBalancer
loadBalancerIP: <external-ip>
ports:
- port: 80
name: http
targetPort: 80
- port: 443
name: https
targetPort: 443
selector:
# Selects ingress-nginx-controller pods
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
Next, we patch the ingress-nginx-controller
to accept the ingress-nginx
service :
apiVersion: apps/v1
kind: Deployment
metadata:
name: ingress-nginx-controller
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
template:
metadata:
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
# hostNetwork makes it possible to use ipv6 and to preserve the source IP correctly regardless of docker configuration
# however, it is not a hard dependency of the ingress-nginx-controller itself and it may cause issues if port 10254 already is taken on the host
# that said, since hostPort is broken on CNI (https://github.com/kubernetes/kubernetes/issues/31307) we have to use hostNetwork where CNI is used
# like with kubeadm
# hostNetwork: true
terminationGracePeriodSeconds: 60
containers:
- image: registry.k8s.io/ingress-nginx/controller:v1.0.5
name: controller
readinessProbe:
httpGet:
path: /healthz
port: 10254
scheme: HTTP
livenessProbe:
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
timeoutSeconds: 1
ports:
- containerPort: 80
hostPort: 80
- containerPort: 443
hostPort: 443
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
args:
- /nginx-ingress-controller
- --publish-service=$(POD_NAMESPACE)/ingress-nginx-lb
Note: Remember to update <external-ip>
with you external ip address.
Now we are ready to apply the configuration files:
kubectl apply -f static-ip-svc.yaml
kubectl apply -f ingress-nginx-controller.yaml
In the end, we should see the external ip in the nginx-ingress svc:
kubectl get svc ingress-nginx-controller -o wide -n ingress-nginx
With the response:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
ingress-nginx-controller LoadBalancer 10.43.199.51 <external-ip> 80:31859/TCP,443:31992/TCP 43m app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx
Testing Nginx ingress controller
This is an example yml file for a nginx container exposes through a nginx ingress controller:
cat <<EOF > nginx-deployment-ingress-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
labels:
app: nginx
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80
EOF
Another example with a certificate and a host name:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example
namespace: foo
spec:
ingressClassName: nginx
rules:
- host: www.example.com
http:
paths:
- pathType: Prefix
backend:
service:
name: exampleService
port:
number: 80
path: /
# This section is only required if TLS is to be enabled for the Ingress
tls:
- hosts:
- www.example.com
secretName: example-tls
Next we apply the configuration:
kubectl apply -f nginx-deployment-ingress-nginx.yaml
If everything is ok, we should be able to access Nginx on the external-ip
on port 80:
Documentation and links:
- Uninstall Traefik - https://qdnqn.com/k3s-remove-traefik/
- Nginx install guide - https://kubernetes.github.io/ingress-nginx/deploy/
- Nginx static ip guide - https://kubernetes.github.io/ingress-nginx/examples/static-ip/
- Nginx static ip github - https://github.com/kubernetes/ingress-nginx/blob/main/docs/examples/static-ip/static-ip-svc.yaml