# K3D
k3d 顧名思義就是 k3s in docker,可以在 docker 中創建單節點和多節點的 k3s cluster。
## Docker 安裝
k3d 是 k3s in docker,所以要先有 docker,可參考[官網的安裝文件](https://docs.docker.com/engine/install/ubuntu/)。
## K3D 安裝
### 透過腳本進行安裝
+ **安裝最新版本**
+ wget:
```
wget -q -O - https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | bash
```
+ curl:
```
curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | bash
```
+ **安裝特定版本**
使用安裝腳本取得特定版本(透過 **`TAG`** 環境變數):
+ wget:
```
https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | TAG=v5.0.0 bash
```
+ curl:
```
curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | TAG=v5.0.0 bash
```
### 下載 GitHub 版本
+ **下載 k3d 二進制文件**
從發布標籤中取得一個發布二進制文件。[**k3d GitHub Releases**](https://github.com/k3d-io/k3d/releases)
+ **將 k3d 二進制文件複製到 PATH 中**
將下載的 k3d 二進制文件複製或移動到你的 **`PATH`** 環境變數,例如:'**`~/.local/bin`**' 或 '**`/user/local/bin`**'(如果你對這些目錄有寫權限的話)。
```bash
chmod +x k3d-linux-amd64
mkdir -p ~/.local/bin
mv ./k3d-linux-amd64 ~/.local/bin/k3d
# and then append (or prepend) ~/.local/bin to $PATH
```
這樣,你就可以通過在任意位置執行 **`k3d`** 命令來使用 k3d 了。
### 快速開始
建立一個名為 `mycluster` 且只有一個 server node 的 cluster:
```bash
# k3d cluster create <cluster name>
k3d cluster create mycluster
```
如果沒有指定 cluster name 則會是 k3s-default。
```bash
k3d cluster create
```
預設的 cluster 會有 1 個 server node,並裝好 Load Balancer,可用 **`k3d cluster list`** 列出 clusters。
```bash
k3d cluster list
# NAME SERVERS AGENTS LOADBALANCER
# k3s-default 1/1 0/0 true
```
執行 **`k3d node list`** 列出目前的 node。
```bash
k3d node list
# NAME ROLE CLUSTER STATUS
# k3d-k3s-default-server-0 server k3s-default running
# k3d-k3s-default-serverlb loadbalancer k3s-default running
```
也可以透過 **`docker ps -a`** 來觀察,有一個 Load Balancer 和一個 Server。目前只有一個 node,如果有多個 node 就會有多個 Container。
```bash
docker ps -a
# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# 3101e4c455e3 ghcr.io/k3d-io/k3d-proxy:5.6.0 "/bin/sh -c nginx-pr…" 8 minutes ago Up 8 minutes 80/tcp, 0.0.0.0:37115->6443/tcp k3d-k3s-default-serverlb
# 884222f5d1a5 rancher/k3s:v1.27.4-k3s1 "/bin/k3d-entrypoint…" 8 minutes ago Up 8 minutes k3d-k3s-default-server-0
```
## Kubectl 安裝
透過 **`kubectl`** 指令可以部署應用程式、管理 cluster 資源、看 log 等。[**Install kubectl on Linux**](https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/)
### 在你開始之前
您使用的 kubectl 版本必須與 cluster 的次要版本差異不超過一個版本。例如,v1.29 用戶端可以與 v1.28、v1.29 和 v1.30 控制平面通訊。使用 kubectl 的最新相容版本有助於避免不可預見的問題。
### 在 Linux 上使用 curl 安裝 kubectl 二進制文件
1. 使用以下指令下載最新版本:
```bash
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
```
:::success
:notebook: **Note:**
若要下載特定版本,請將指令的 **`$(curl -L -s https://dl.k8s.io/release/stable.txt)`** 部分替換為特定版本。
例如,若要在 Linux x86-64 上下載版本 1.29.0,請輸入:
```bash
curl -LO https://dl.k8s.io/release/v1.29.0/bin/linux/amd64/kubectl
```
對於 Linux ARM64,輸入:
```
curl -LO https://dl.k8s.io/release/v1.29.0/bin/linux/arm64/kubectl
```
:::
2. 驗證二進制檔案(可選)
下載 kubectl 校驗檔案:
```bash
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl.sha256"
```
根據校驗檔案驗證 kubectl 二進制檔案:
```bash
echo "$(cat kubectl.sha256) kubectl" | sha256sum --check
```
如果有效,則輸出為:
```bash
kubectl: OK
```
如果檢查失敗,sha256 將以非零狀態退出並列印類似以下內容的輸出:
```bash
kubectl: FAILED
sha256sum: WARNING: 1 computed checksum did NOT match
```
:::warning
:warning: **Note:**
下載相同版本的二進制檔案和校驗和。
:::
3. 安裝 kubectl
```bash
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
```
:::success
:notebook: Note:
如果您沒有目標系統的 root 存取權限,您仍然可以將 kubectl 安裝到 **`~/.local/bin`** 目錄:
```bash
chmod +x kubectl
mkdir -p ~/.local/bin
mv ./kubectl ~/.local/bin/kubectl
# and then append (or prepend) ~/.local/bin to $PATH
```
:::
4. 測試以確保您安裝的版本是最新的:
```bash
kubectl version --client
```
或使用它來詳細查看版本:
```bash
kubectl version --client --output=yaml
```
### 驗證 kubectl 配置
為了讓 kubectl 找到並存取 Kubernetes 集群,它需要一個 [**kubeconfig**](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/) 文件,該文件是在您使用 [**kube-up.sh**](https://github.com/kubernetes/kubernetes/blob/master/cluster/kube-up.sh) 建立集群或成功部署 Minikube 集群時自動建立的。預設情況下,kubectl 配置位於 **`~/.kube/config`**。
:::success
:notebook: **Note:**
過去建立完 cluster 後還需要將 k3d kubeconfig 與 kubectl kubeconfig 連接 (**`export KUBECONFIG="$(k3d kubeconfig write k3s-default`**),但現在下 **`k3d cluster create`** 指令時已經會 merge k3d kubeconfig file 進 default kubeconfig file
:::
透過取得 cluster 狀態來檢查 kubectl 是否已正確配置:
```bash
kubectl cluster-info
```
如果您看到 URL 回應,則表示 kubectl 已正確配置為存取您的 cluster。
如果您看到類似以下內容的訊息,則 kubectl 未正確設定或無法連線到 Kubernetes cluster。
```bash
The connection to the server <server-name:port> was refused - did you specify the right host or port?
```
例如,如果您打算在筆記型電腦上(本地)運行 Kubernetes 集群,則需要先安裝 Minikube 等工具,然後重新執行上述命令。
如果 **`kubectl cluster-info`** 返回 url 回應,但您無法存取集群,要檢查它是否配置正確,請使用:
```bash
kubectl cluster-info dump
```
### 快速開始
查看 cluster 資訊:
```bash
kubectl cluster-info
# Kubernetes control plane is running at https://0.0.0.0:39829
# CoreDNS is running at https://0.0.0.0:39829/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
# Metrics-server is running at https://0.0.0.0:39829/api/v1/namespaces/kube-system/services/https:metrics-server:https/proxy
```
將 cluster 與 kubectl 一起使用,例如:
```bash
kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# k3d-k3s-default-server-0 Ready control-plane,master 19s v1.27.4+k3s1
```
:::info
:::spoiler **取得 cluster 的 kubeconfig(包含在 `k3d cluster create` 中)**
將新 cluster 的連線詳細資訊合併到預設 kubeconfig(通常使用 **`KUBECONFIG`** 環境變數或預設路徑 **`$HOME/.kube/config`** 指定)並直接切換到新上下文:
```bash
k3d kubeconfig merge mycluster --kubeconfig-switch-context
```
:::
#### 使用 kubectl config 管理上下文
每個 cluster 在 kubeconfig 文件中都有一個相對應的上下文(context)。你可以使用以下 **`kubectl config`** 命令來列出所有可用的上下文:
:::success
:notebook: **Note:**
執行 **`k3d cluster create <cluster name>`** 指令之後,**`kubectl`** 會自動切換到該 cluster 且連線資訊也會 merge 到預設 kubeconfig
:::
```bash
kubectl config get-contexts
# CURRENT NAME CLUSTER AUTHINFO NAMESPACE
# k3d-k3s-default k3d-k3s-default admin@k3d-k3s-default
# * k3d-mycluster k3d-mycluster admin@k3d-mycluster
```
然後,你可以使用以下命令來切換到特定的上下文,即切換到控制特定 cluster:
```bash
kubectl config use-context <context-name>
```
這裡的 **`<context-name>`** 是你想要切換到的 cluster 的上下文名稱。
#### 驗證當前上下文
執行以下命令來確認當前上下文(即當前控制的 cluster):
```bash
kubectl config current-context
# k3d-mycluster
```
### 建立 multi-server clusters
使用容器化節點建立新的 k3s cluster(k3s in docker)。每個 cluster 將由一個或多個容器組成:[**k3d cluster create**](https://k3d.io/v5.6.0/usage/commands/k3d_cluster_create/)
+ 1(或更多)server 節點容器(k3s)
+ (可選)1 個 loadbalancer 容器作為 cluster 的入口點 (nginx)
+ (可選)1(或更多)agent 節點容器(k3s)
```bash
k3d cluster create <cluster name> [flags]
```
例如:
```bash
k3d cluster create mycluster --servers 2 --agents 3 -p "7777:80@agent:0"
```
+ **`--servers 2`**:指定 cluster 將包含 2 個 server 節點(也稱為主節點或控制平面節點)。server 節點負責 cluster 的管理和狀態控制。
+ **`--agents 3`**:此指定 cluster 將包含 3 個 agent 節點(也稱為工作節點)。工作節點用於運行應用程序容器和處理其他工作負載。
+ **`-p "7777:80@agent:0"`**:這是端口映射的配置。
+ **`7777:80`**:表示將本地主機的 7777 端口映射到 cluster 中的 80 端口
+ **`@agent:0`**:指定映射應用於第一個 agent 節點(agent 節點的編號從 0 開始)。這意味著,訪問您主機上的 7777 端口實際上是訪問 cluster 中第一個 agent 節點上的 80 端口。
### Kubectl 指令簡化
依照 [**kubectl cheat sheet**](https://kubernetes.io/docs/reference/kubectl/cheatsheet/) 設定 autocomplete & alias
+ **autocomplete**
+ BASH
```bash
# set up autocomplete in bash into the current shell, bash-completion package
# should be installed first.
source <(kubectl completion bash)
# add autocomplete permanently to your bash shell.
echo "source <(kubectl completion bash)" >> ~/.bashrc
```
+ **alias**
您還可以使用 **`kubectl`** 的簡寫別名,這也適用於命令自動完成:
```bash
alias k=kubectl
complete -o default -F __start_kubectl k
echo "alias k=kubectl" >> ~/.bashrc
echo "complete -o default -F __start_kubectl k" >> ~/.bashrc
```