[Kubernetes]離線斷網下跑kubernetes

Morpheus Huang
8 min readSep 25, 2023

--

因為某個奇妙的需求,導致部署在單節點kubernetes上的demo平台,需要在斷網的環境下跑起來,想當然爾,安裝時候都是有接網路的,然後斷網重開機後就死了XD

最慘的是這件事在要demo前一天下班才發現,只好demo當天,早上緊急做處置,前後大概花了一個小時多,總算讓整個kubernetes環境與demo平台正常運作,順利完成demo。

不過當天解決方式可能會變成連網後會有問題。因此,這篇算是讓單節點裸機的kubernetes在不管斷網或者連網的情況下,都能不需要再修改任何設定的一個workaround的方式,不過這個方式僅適用於單節點裸機安裝就是了 ,如果要多節點可能要考慮minikube or k3s的方式比較適合。

測試環境:

  • OS: ubuntu 22.04
  • Container Runtime: Containerd
  • Kubernetes: v1.26.1 (Without kube-proxy)
  • CNI: cilium 1.14.2

Solution:

在拔掉網路線斷網環境,預設路由會不見,但kubernetes本身又需要預設路由來讓ClusterIP路由正常,既然如此,那就新增一個dummy interface給kubernetes用。

Step1: 設定dummy interface

為了保證重開機後,dummy interface會自動啟用,因此這裡透過ubuntu systemd-networkd來做相關的dummy interface設定,首先於/etc/systemd/network/中,新增以下兩個檔案:

  • 10-dummy0.netdev
[NetDev]
Name=dummy0
Kind=dummy
  • 20-dummy0.network
[Match]
Name=dummy0

[Network]
Address=192.168.255.254/31
DNS=8.8.8.8
[Route]
Gateway=192.168.255.255
Metric=1000

執行以下命令,確保開機時自動啟動systemd-networkd

systemctl enable systemd-networkd

接著直接重開機,確認dummy interface是否正常啟用,以及路由是否符合預期。

0.0.0.0         172.16.142.2    0.0.0.0         UG    100    0        0 ens160
0.0.0.0 192.168.255.255 0.0.0.0 UG 1000 0 0 dummy0
169.254.0.0 0.0.0.0 255.255.0.0 U 1000 0 0 dummy0
172.16.142.0 0.0.0.0 255.255.255.0 U 100 0 0 ens160
192.168.255.254 0.0.0.0 255.255.255.254 U 0 0 0 dummy0

上面的路由資訊,除了dummy相跟關的路由外,還有實際對外網卡ens160的路由,因為我的目的是讓kubernetes在斷網與連網下都能正常運作,如果斷網情況下,那基本上就只會有dummy0的路由資訊。

Step2 安裝kubernetes與cilium

Note: 此步驟是在有連網的情況下安裝的

Kubernetes安裝前置作業此處就不多加贅述了,請參考kubernetes 官方網站。

假設前置作業都完成,接著直接使用kubeadm init來安裝kubernetes,並指定--apiserver-advertise-address 為前面設定的dummy0的ip 192.168.255.254

# create k8s cluster
sudo kubeadm init --service-cidr 10.96.0.0/12 --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.255.254 --skip-phases=addon/kube-proxy

# copy kubeconfig
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# UnTaint Control-Plane
kubectl taint nodes --all node-role.kubernetes.io/control-plane-

安裝helm與cilium cni

# 安裝helm
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# 新增cilium與安裝
# k8sServiceHost同樣設定為dummy0的ip 192.168.255.254
# 並且使用cilium取代kube-proxy
helm repo add cilium https://helm.cilium.io
helm repo update
helm install cilium cilium/cilium --namespace kube-system --set tunnel=vxlan --set kubeProxyReplacement=strict --set ipv4NativeRoutingCIDR=10.244.0.0/16 --set ipam.mode=kubernetes --set k8sServicePort=6443 --set bpf.masquerade=true --set k8sServiceHost=192.168.255.254

Step3: 測試

上面都安裝好後,我們可以建立一個nginx service來測試

# create nginx deployment
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: nginx
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: nginx
resources: {}
# create nginx service
kubectl expose deployment nginx --port=80 --type=NodePort

查看80對應的nodePort, kubectl get

nginx        NodePort    10.104.163.87   <none>        80:32523/TCP   89s

使用curl or browser測試, curl 192.168.254.255:32523

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

Step4:拔線斷網重開

因為Step3測試是在有連網的情況,既然目的是斷網與連網都要能正常運作,當然也要確認拔線斷網的情境下是否正常。拔線斷網重開後,先確定所有Pod都已經為Running的狀態,然後再用curl或開browser測試看是否能存取nginx服務。

如果Step3與Step4都測試正常,那就表示安裝完成了,之後可以視需求,部署ingress-controller,並於 /etc/hosts 設定domain,讓服務可以藉由domain,並經由ingress存取。

--

--