---
# System prepended metadata

title: k3s
tags: [k3s]

---

# k3s

## step 1 啟動 ubuntu

### windows 開啟 microsoft store 搜尋 ubuntu

![microsoft-store](https://hackmd.io/_uploads/Hyh1vNmcgx.jpg)

### 安裝或開啟 ubuntu

![ubuntu](https://hackmd.io/_uploads/BJpHDEQ9xg.jpg)

### 輸入使用者名稱

![image](https://hackmd.io/_uploads/rkp_PE75ge.png)

### 輸入使用者密碼

![image](https://hackmd.io/_uploads/HkZcPEQqex.png)

### 再次輸入使用者密碼

![image](https://hackmd.io/_uploads/B1WivN7cle.png)

### 進入 ubuntu

![image](https://hackmd.io/_uploads/HkG3PVQ5gg.png)

### 設置 root 密碼 (可略過)

```shell!
sudo passwd
```

![image](https://hackmd.io/_uploads/SJkAwEQcle.png)

### 輸入 root 密碼

![image](https://hackmd.io/_uploads/BkbkuEQcll.png)

### 再次輸入 root 密碼

![image](https://hackmd.io/_uploads/HJWxOEmqlg.png)

### 設置完成

![image](https://hackmd.io/_uploads/BJWZ_Emclx.png)

### 更新套件

```shell!
sudo apt update && sudo apt upgrade -y
```

### 安裝 ssh 之後可以透過 winscp 上傳檔案或下載檔案 (需要設定目錄權限)

```shell!
sudo apt install ssh -y
```

![image](https://hackmd.io/_uploads/BkGXONQqgg.png)

### 安裝 net-tools

```shell!
sudo apt install net-tools -y
```

![image](https://hackmd.io/_uploads/HkS4OEm5el.png)

### 查看系統所有的網路介面及其完整設定，記下 eth0 網卡 IP (inet 172.19.101.145 切勿照抄，每個 ubuntu 環境裡的 IP 都可能不同)

```shell!
ifconfig -a
```

![image](https://hackmd.io/_uploads/SkFrOVQ9gg.png)

## step 2 安裝 [k3s](https://docs.k3s.io/zh/)

### 停用 servicelb 、 traefik 、 關閉 network policy 、 設定 cluster-cidr 與 service-cidr、 kubeconfig mode

> [!NOTE]
> k3s 啟動完畢，需要再安裝與設定 helm, calico, metallb, ingress nginx

```shell!
export K3S_VERSION="v1.33.3+k3s1"
export CLUSTER_CIDR="10.42.0.0/16"
export SERVICE_CIDR="10.43.0.0/16"
export K3S_KUBECONFIG_MODE="644"
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=${K3S_VERSION} \
INSTALL_K3S_EXEC="\
--flannel-backend=none \
--disable=servicelb \
--disable=traefik \
--disable-network-policy \
--cluster-cidr=${CLUSTER_CIDR} \
--service-cidr=${SERVICE_CIDR} \
--write-kubeconfig-mode=${K3S_KUBECONFIG_MODE} \
--kube-proxy-arg=proxy-mode=ipvs \
" \
sh -s - server --cluster-init
```

![image](https://hackmd.io/_uploads/SySw_4X9le.png)

### 檢查 k3s 版本

```shell!
k3s version
```

![image](https://hackmd.io/_uploads/HyH_uN7cge.png)

### 確認服務是否正在運作，它應該會自動啟動

```shell!
sudo systemctl status k3s.service
```

![image](https://hackmd.io/_uploads/ryTKu4Q5ge.png)

### 複製設定檔 ~/.kube/config

#### 建立目錄

```shell!
mkdir ~/.kube
```

#### 載入設定

> [!NOTE]
> 1. k3s 預設產生的 kubeconfig 設定檔從 /etc/rancher/k3s/k3s.yaml 複製到使用者目錄下的 .kube/config 這是為了讓 kubectl 工具能讀取這個設定與 Kubernetes 叢集連線
>
> 2. 複製後的 ~/.kube/config 檔案預設是 root 使用者擁有，這行指令改變該檔的擁有者與群組為目前使用者（$USER），確保當前用戶可以讀取及寫入這份設定檔
>
> 3. 將環境變數 KUBECONFIG 設定為 ~/.kube/config，並將這行設定追加（-a）寫入使用者的 ~/.bashrc 檔案中，使得每次新開啟 shell 都會自動載入此變數，kubectl 可以自動使用這個 kubeconfig 檔
>
> 4. 這行指令立即重新載入 ~/.bashrc，使剛剛加入的 KUBECONFIG 環境變數設定立即生效

```shell!
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $USER:$USER  ~/.kube/config
echo 'export KUBECONFIG=~/.kube/config'|tee -a ~/.bashrc
source ~/.bashrc
```

![image](https://hackmd.io/_uploads/ByESFVm9le.png)

## step 3 安裝 helm [From Apt (Debian/Ubuntu)](https://helm.sh/docs/intro/install/#from-apt-debianubuntu)

> [!Tip]
> k3s 已內建 helm 可略過此安裝。自行託管 k8s 視需要安裝 helm 或使用 kubectl apply, create

> [!NOTE]
> Kubernetes 的套件管理工具，可以幫助管理 Kubernetes 應用程式。主要用途是打包、安裝、升級 Kubernetes 上的應用程式（稱為 Charts），並能夠透過模板與參數實現多環境的客製化配置。類似 Linux 的 apt 或 yum 套件管理，Helm 讓應用程式部署與版本管理更方便和有序，也支援依賴管理和部署回滾等功能

```shell!
curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
sudo apt-get install apt-transport-https --yes
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
sudo apt-get update
sudo apt-get install helm
```

## step 4 安裝 [calico](https://docs.tigera.io/calico/latest/getting-started/kubernetes/k3s/quickstart#install-calico)

> [!NOTE]
> Kubernetes 的網路及網路安全解決方案，提供容器的網路連接與網路策略管理。它讓 Kubernetes 集群中的 Pod 之間可以安全通信，並支援高效能的路由與防火牆功能。Calico 既可作為容器的網路插件，也能管理網路安全策略，增強集群的網路隔離與保護能力

### 切換至 manifest

![calico-manifest](https://hackmd.io/_uploads/BkYy54mcee.jpg)

#### 下載 calico.yaml

```shell!
wget -O calico.yaml https://raw.githubusercontent.com/projectcalico/calico/v3.30.3/manifests/calico.yaml
```

![image](https://hackmd.io/_uploads/rJnZ9Emqle.png)

#### 修改 calico.yaml 找到 CALICO_IPV4POOL_CIDR

```shell!
sudo vim calico.yaml
```

![image](https://hackmd.io/_uploads/r1yQcEQqxx.png)

#### 移除註解，192.168.0.0/16 改為 k3s 設置的 CLUSTER_CIDR，修改完畢後儲存, 如果 cluster cidr 為 192.168.0.0/16 可略過此步驟，不需要修改

![image](https://hackmd.io/_uploads/SkqBqVXcxe.png)

#### kubectl apply 指令

> [!NOTE]
> kubectl apply 指令用於使用 YAML （或 JSON） 資訊清單檔案以宣告方式在叢集上建立或更新資源

```shell!
kubectl apply -f calico.yaml
```

![image](https://hackmd.io/_uploads/Bk-w5Vm5ll.png)

#### 確認 cluster is ready

```shell!
kubectl get nodes
```

![image](https://hackmd.io/_uploads/BkXYqVQqle.png)

## step 5 安裝 [metallb](https://metallb.io/)

> [!NOTE]
> Kubernetes 的一個 LoadBalancer 方案，用在裸機或私有數據中心部署 Kubernetes，實現對外的負載均衡。它透過配置 IP 地址池及廣播模式（Layer 2 或 BGP）分配外部 IP，讓 Kubernetes 服務可以擁有類似雲端 LoadBalancer 的能力，方便外部直接訪問 Cluster 服務

```shell!
helm repo add metallb https://metallb.github.io/metallb
helm install metallb metallb/metallb --namespace metallb-system --create-namespace
```

![image](https://hackmd.io/_uploads/B1Lj94X5xg.png)

### 確認 pod

```shell!
kubectl get pods -A
```

![image](https://hackmd.io/_uploads/SyvhcNX9xx.png)

### 設置 IPAddressPool 這裡只分配1個 IP

> [!NOTE]
> 
> 用來定義 MetalLB 可分配給 LoadBalancer 類型服務的 IP 地址範圍。這些 IP 可以是單一 IP、IP 範圍或整個子網段，MetalLB 會從這些地址池中分配對應的 IP 給 Kubernetes 服務。配置中也可以設定是否自動分配（autoAssign），以及避免某些問題 IP（如 .0 或 .255）
> 
> #### 進階配置 [Advanced AddressPool configuration](https://metallb.io/configuration/_advanced_ipaddresspool_configuration/)

```shell!
kubectl apply -f - <<EOF
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: first-pool
  namespace: metallb-system
spec:
  addresses:
  - 172.19.101.145/32
EOF
```

![image](https://hackmd.io/_uploads/SJqp5V75lg.png)

### [進階 L2 配置](https://metallb.io/configuration/_advanced_l2_configuration/)

> [!NOTE]
> 宣告該 Layer 2 模式下要使用哪些 AddressPool。L2 模式主要是透過回應 ARP（IPv4）或 NDP（IPv6）請求，讓外部網路以 MAC 地址認得並導向該服務 IP。L2Advertisement 定義了 MetalLB 會在哪些接口與哪些 IP 地址池上回應 ARP，以讓服務 IP 可被外部節點發現

```shell
kubectl apply -f - <<EOF
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: l2a
  namespace: metallb-system
spec:
  ipAddressPools:
  - first-pool
EOF
```

![image](https://hackmd.io/_uploads/HJs05Em5ll.png)

## step 6 安裝 ingress-nginx

> [!NOTE]
> 基於 NGINX 實作的 Kubernetes Ingress 控制器，用來管理集群內服務對外的 HTTP/HTTPS 訪問路由。它可以根據 Ingress 規則將外部請求路由到相應的服務，支援 TLS 終端、負載均衡及反向代理，並且透過 Helm Chart 進行部署與設定。Ingress NGINX 是 Kubernetes 很常用的入口流量管理解決方案

```shell!
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm install ingress-nginx ingress-nginx/ingress-nginx --namespace ingress-nginx --create-namespace
```

### 完成

![image](https://hackmd.io/_uploads/BkYusEmqel.png)

## step 7 部署 nginx 測試服務

```shell!
kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80 --type=ClusterIP
```

## step 8 使用 Lens 管理 k3s

> [!NOTE]
> 功能強大的開源 Kubernetes IDE（集成開發環境），主要用途是為 Kubernetes 開發者與運維人員提供一個直觀且統一的圖形化介面，用於管理、監控和排查 Kubernetes 叢集。它支援多集群管理、多命名空間操作，可以查看 Pods、Deployments、Services 等資源的詳細狀態，並支援日誌查看和終端訪問以便直接調試容器。Lens 內建 Prometheus 等監控整合，提供豐富的資源監控面板，方便用戶掌握叢集性能與資源使用情況。此外，它也支援透過 Helm 進行應用部署與管理，並可用 kubeconfig 連接叢集，且具備多平台（Windows、macOS、Linux）兼容性，使 Kubernetes 叢集管理變得更加簡單高效

### [下載](https://k8slens.dev/download) 選擇適用系統的安裝檔

![image](https://hackmd.io/_uploads/Ska9o4X5gg.png)

### 查看 Kubernetes 配置文件（kubeconfig 文件）內容，全選並複製

> [!Warning]
> 不可揭露任何機敏性資料 (此範例不在此限內)

```shell!
cat ~/.kube/config
```

![image](https://hackmd.io/_uploads/SyB3oV75lg.png)

### 取得 External IP

```shell!
kubectl get svc -A
```

> [!NOTE]
> 在 Kubernetes 中，EXTERNAL-IP 是指服務（Service）對外暴露的 IP 地址，這個 IP 能夠讓集群外部的客戶端或用戶能夠訪問該服務。它代表的是服務在集群外部的可達地址

#### Lens 新增叢集，External IP 用來替換 kubeconfig 的 server: `https://127.0.0.1:6443`

![image](https://hackmd.io/_uploads/r1W4nEmcll.png)

### 開啟 Lens 新增叢集

![add-kubeconfig-by-paste](https://hackmd.io/_uploads/rk5unVmcxl.jpg)

### 貼上 kubeconfig，原先 `server: https://127.0.0.1:6443` 改為 `server: https://172.19.101.145:6443` 按下 Add Clusters

![edit-kubeconfig-server](https://hackmd.io/_uploads/Bymhn4Xqxg.jpg)

### 檢視 k3s

![image](https://hackmd.io/_uploads/HkzT24Qqee.png)

## step 9 nginx 服務，設置 ingress

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - host: nginx.foo.local
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx
            port:
              number: 80
```

![image](https://hackmd.io/_uploads/HJ5l6EQ5ee.png)

### 使用系統管理者權限，修改本機電腦 hosts

> [!NOTE]
> Kubernetes 中使用 Ingress 服務，如果設定的 host 是像 nginx.test.local 這種非正式域名（non-real domain），瀏覽器和本機系統是無法直接解析此名稱的，因為它沒有對應的 DNS 記錄
> 因此，在 Windows 環境下，必須手動在系統的 hosts 檔案中新增一條對應記錄，將該域名指向要訪問的 IP（通常是 ingress controller 的 IP 或本地 loopback IP，例如 127.0.0.1）。這樣系統在解析 nginx.test.local 時，才會知道指向哪個 IP，才能正常連線到 Kubernetes Ingress

![image](https://hackmd.io/_uploads/By5Z6VQ5lx.png)

### 開啟網站

![image](https://hackmd.io/_uploads/HJtGTV7cxg.png)

## step 10 [移除 k3s](https://docs.k3s.io/zh/installation/uninstall)

### Control plane

```shell!
/usr/local/bin/k3s-uninstall.sh
```

### worker

```shell!
/usr/local/bin/k3s-agent-uninstall.sh
```