7 min read

從零搭建 K3s 集群與 K9s 終端面板

從零搭建 K3s 集群與 K9s 終端面板

以往都是 docker-compose 部署專案,統一使用nginx 進行反向代理及管理,使用docker network 進行溝通,但很常遇到更新容器後 忘記 nginx -s reload 進而造成服務異常。

隨著容器化越來越重,有時候小專案需要一個小型的K8s集群來託管容器化,所以就選擇了K3s。

以下將會記錄 k3s 及k9s 從零開始的搭建部署以及測試運行容器。

k3s 官網 而安裝過程主要都是在 k3s官網上面

k9s Github - 本次安裝是直接使用 k9s 二進制


K3s 搭建

官網提供安裝腳本,可以一鍵部署k3s,會自動安裝一切所需資源包含ContainerD/traefik...等。

curl https://get.k3s.io/ -o get-k3s.sh
chmod +x get-k3s.sh
./get-k3s.sh

# 若不想啟用 traefik 
想自行安裝 ingress-nginx 可以取消預設安裝 
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--disable=traefik" sh -
kubectl get no

建立好之後若要測試運行狀況,可以使用以下範例測試部署狀況,創建好後運行kubectl apply -f nginx-demo.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginxdemos/hello:0.4
        ports:
        - containerPort: 80
        resources:
          limits:
            cpu: "200m"
            memory: "150Mi"
          requests:
            cpu: "100m"
            memory: "128Mi"
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
  type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-service
            port:
              number: 80

創建完成後可以直接查看部署狀況

kubectl get all


然而有時候透過指令不太方便快速的查看部署狀況,此時就可以結合K9s,部署的方式可以直接使用官網的二進制,依照自己的作業系統以及cpu架構去下載相對應的版本即可。

K9s Github releases

下載後解包會獲得類似以下目錄。

因為k3s不像k8s會將配置檔案放到/root/.kube/config ,配置檔會在 /etc/rancher/k3s/k3s.yaml

k9s --kubeconfig /etc/rancher/k3s/k3s.yaml

為了解決不要每次開啟k9s 這麼麻煩

  1. 將k9s 執行檔 移動至 /usr/bin 即可直接執行
  2. k3s配置目錄軟連結到k9s 讀取目錄
#將k9s 移動至目錄
mv k9s /usr/bin/

#創建 .kube 目錄(如果不存在)
mkdir -p /root/.kube

# 創建符號鏈接而不是複製文件
ln -sf /etc/rancher/k3s/k3s.yaml /root/.kube/config

這時候就可以直接使用 k9s 訪問k3s集群。

文末提供一個自動判斷 CPU會自動下載相對應的二進制執行檔的shell。

#!/bin/bash

# 顏色定義
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # 無顏色

# 檢測必要的依賴工具
check_dependencies() {
  echo "檢測必要的依賴工具..."
  local missing_deps=0
  
  for cmd in curl tar grep; do
    if ! command -v $cmd &> /dev/null; then
      echo -e "${RED}錯誤: 缺少必要的工具 '$cmd'${NC}"
      missing_deps=1
    fi
  done
  
  if [ $missing_deps -eq 1 ]; then
    echo -e "${RED}請安裝缺少的依賴後重試${NC}"
    echo "例如: sudo apt-get install curl tar grep 或 sudo yum install curl tar grep"
    return 1
  else
    echo -e "${GREEN}所有必要的依賴已安裝${NC}"
    return 0
  fi
}

# 檢測網絡連接
check_network() {
  echo "檢測網絡連接..."
  if curl -s --connect-timeout 5 https://api.github.com > /dev/null; then
    echo -e "${GREEN}網絡連接正常,可以訪問GitHub${NC}"
    return 0
  else
    echo -e "${RED}錯誤: 無法連接到GitHub,請檢查網絡連接${NC}"
    return 1
  fi
}

# 檢測系統架構
detect_arch() {
  echo "檢測系統架構..."
  ARCH=$(uname -m)
  
  case $ARCH in
    x86_64)
      K9S_ARCH="amd64"
      ;;
    aarch64)
      K9S_ARCH="arm64"
      ;;
    arm*)
      K9S_ARCH="arm"
      ;;
    *)
      echo -e "${RED}不支持的架構: $ARCH${NC}"
      return 1
      ;;
  esac
  
  echo -e "${GREEN}檢測到的系統架構: $ARCH,對應的 k9s 架構: $K9S_ARCH${NC}"
  return 0
}

# 檢測操作系統
detect_os() {
  echo "檢測操作系統..."
  if [[ "$OSTYPE" == "linux-gnu"* ]]; then
    OS="Linux"
  elif [[ "$OSTYPE" == "darwin"* ]]; then
    OS="Darwin"
  else
    echo -e "${YELLOW}警告: 未識別的操作系統類型: $OSTYPE,假設為Linux${NC}"
    OS="Linux"
  fi
  
  echo -e "${GREEN}檢測到的操作系統: $OS${NC}"
  return 0
}

# 檢測已有安裝
check_existing_install() {
  echo "檢測是否已安裝k9s..."
  if command -v k9s &> /dev/null; then
    local current_version=$(k9s version | grep Version | awk '{print $2}' | tr -d '[:space:]')
    echo -e "${YELLOW}發現已安裝k9s版本: $current_version${NC}"
    read -p "是否繼續下載新版本? (y/n): " -n 1 -r
    echo
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
      echo "下載已取消"
      return 1
    fi
  else
    echo "未檢測到已安裝的k9s"
  fi
  return 0
}

# 主函數
main() {
  echo "================= k9s 下載工具 ================="
  
  # 運行所有檢測
  check_dependencies || exit 1
  check_network || exit 1
  detect_arch || exit 1
  detect_os || exit 1
  check_existing_install || exit 0
  
  # 獲取最新的 k9s 版本
  echo "獲取最新的 k9s 版本..."
  LATEST_VERSION=$(curl -s https://api.github.com/repos/derailed/k9s/releases/latest | grep -oP '"tag_name": "\K[^"]+')
  
  if [ -z "$LATEST_VERSION" ]; then
    echo -e "${YELLOW}警告: 無法獲取最新版本,使用默認版本 v0.27.4${NC}"
    LATEST_VERSION="v0.27.4"
  fi
  
  # 移除版本號前的'v'
  VERSION=${LATEST_VERSION#v}
  echo -e "${GREEN}最新版本: $LATEST_VERSION (${VERSION})${NC}"
  
  # 構建下載 URL
  DOWNLOAD_URL="https://github.com/derailed/k9s/releases/download/${LATEST_VERSION}/k9s_${OS}_${K9S_ARCH}.tar.gz"
  
  # 創建臨時目錄
  TMP_DIR=$(mktemp -d)
  echo "臨時目錄: $TMP_DIR"
  
  # 下載 k9s
  echo "從 $DOWNLOAD_URL 下載 k9s..."
  curl -Lo $TMP_DIR/k9s.tar.gz $DOWNLOAD_URL
  
  # 檢查下載是否成功
  if [ $? -eq 0 ]; then
    echo -e "${GREEN}下載成功: k9s.tar.gz${NC}"
    
    # 解壓文件
    echo "正在解壓文件..."
    tar -xzf $TMP_DIR/k9s.tar.gz -C $TMP_DIR
    
    if [ $? -eq 0 ]; then
      echo -e "${GREEN}解壓成功,k9s 已準備就緒${NC}"
      
      # 詢問是否安裝到系統路徑
      read -p "是否安裝 k9s 到 /usr/local/bin? (y/n): " -n 1 -r
      echo
      if [[ $REPLY =~ ^[Yy]$ ]]; then
        sudo mv $TMP_DIR/k9s /usr/local/bin/
        echo -e "${GREEN}k9s 已安裝到 /usr/local/bin/k9s${NC}"
        echo -e "${GREEN}您可以直接運行 'k9s' 命令使用${NC}"
      else
        # 複製到當前目錄
        cp $TMP_DIR/k9s ./
        echo -e "${GREEN}k9s 已複製到當前目錄${NC}"
        echo -e "${YELLOW}提示: 您可以手動運行以下命令將 k9s 移動到系統路徑:${NC}"
        echo "sudo mv ./k9s /usr/local/bin/"
      fi
    else
      echo -e "${RED}解壓失敗${NC}"
      exit 1
    fi
  else
    echo -e "${RED}下載失敗${NC}"
    exit 1
  fi
  
  # 清理臨時文件
  rm -rf $TMP_DIR
  echo "臨時文件已清理"
  echo -e "${GREEN}================= 操作完成 =================${NC}"
}

# 執行主函數
main


Kubernetes Helm
類似於 centos yum , ubuntu apt 安裝包的概念
K8S 安裝ingress-nginx 透過Helm
透過Helm 下載 ingress-nginx