這篇文章主要記錄 K3s cluster 設定 etcd 的方法
先前在 “Mac M2 安裝 K3s” 介紹如何快速安裝並啟動一個 K3s cluster 。 然而最近發現 control-plane
node 並沒有 etcd
的角色。
對照K3s 文件 - Cluster Datastore,k3s cluster 使用 Kine(embedded SQLite) 作為預設的 cluster datastore。
SQLite is the default datastore, and will be used if no other datastore configuration is present, and no embedded etcd database files are present on disk.
更新既有 cluster
依據官方文件描述,只要增加 --cluster-init
flag 並重新啟動 k3s 服務,就可以無縫轉移到 embedded etcd 服務。 具體操作流程如下
編輯 systemd k3s service
登入到 control-plane
vm , 編輯 /etc/systemd/system/k3s.service
檔案即可
ubuntu@server:~$ sudo vim /etc/systemd/system/k3s.service
# in vim editor
# append '--cluster-init' into ExecStart=/usr/local/bin/k3s
# save to keep change and exit file
ExecStart=/usr/local/bin/k3s \
server \
'--cluster-init' \
# reload service changed content and restart k3s service
ubuntu@server:~$ sudo systemctl daemon-reload
ubuntu@server:~$ sudo systemctl k3s restart
# verify node roles by kubectl
ubuntu@server:~$ sudo kubectl get node
NAME STATUS ROLES AGE VERSION
server Ready control-plane,etcd,master 3d14h v1.27.6+k3s1
worker Ready <none> 3d14h v1.27.6+k3s1
新建立 cluster
下載 etcd
建立一台新的 Ubuntu vm 並依據 K3s 官方文件選擇安裝etcd v.3.5.4版本
# create etcd-1 ubuntu 22.04 VM
$ multipass launch -n etcd-1 -c 1 -m 1G -d 3G 22.04
...
# echo etcd-1 IP
$ multipass info etcd-1 | grep IP
IPv4: 192.168.64.19
# login to etcd-1
$ multipass shell etcd-1
安裝 etcd shell 如下,參考 Install and deploy etcd - systemd
# install etcd shell
ETCD_VER=v3.5.4
PLATFORM=arm64
# choose either URL
GOOGLE_URL=https://storage.googleapis.com/etcd
GITHUB_URL=https://github.com/etcd-io/etcd/releases/download
DOWNLOAD_URL=${GOOGLE_URL}
rm -f /tmp/etcd-${ETCD_VER}-linux-${PLATFORM}.tar.gz
rm -rf /tmp/etcd && mkdir -p /tmp/etcd
curl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-linux-${PLATFORM}.tar.gz -o /tmp/etcd-${ETCD_VER}-linux-${PLATFORM}.tar.gz
tar xzvf /tmp/etcd-${ETCD_VER}-linux-${PLATFORM}.tar.gz -C /tmp/etcd --strip-components=1
rm -f /tmp/etcd-${ETCD_VER}-linux-${PLATFORM}.tar.gz
# verify installation
/tmp/etcd/etcd --version
/tmp/etcd/etcdctl version
/tmp/etcd/etcdutl version
# start a local etcd server
/tmp/etcd/etcd
# terminal local etcd server
^c
# move etcd exec file to /usr/local/bin
sudo cp /tmp/etcd/etcd* /usr/local/bin/
ETCDCTL_API=3 /tmp/etcdctl version
在 systemd 新增 etcd service
重複下列步驟,在 Ubuntu vm 上啟動 etcd-1 服務。
# create etcd.service file
cat > /tmp/etcd-1.service <<EOF
[Unit]
Description=etcd
Documentation=https://github.com/coreos/etcd
Conflicts=etcd.service
Conflicts=etcd2.service
[Service]
Type=notify
Restart=always
RestartSec=5s
LimitNOFILE=40000
TimeoutStartSec=0
ExecStart=/usr/local/bin/etcd --name etcd-1 \
--data-dir /tmp/etcd/etcd-1 \
--listen-client-urls http://192.168.64.19:2379 \
--advertise-client-urls http://192.168.64.19:2379 \
--listen-peer-urls http://192.168.64.19:2380 \
--initial-advertise-peer-urls http://192.168.64.19:2380 \
--initial-cluster etcd-1=http://192.168.64.19:2380 \
--initial-cluster-token tkn \
--initial-cluster-state new
[Install]
WantedBy=multi-user.target
EOF
# move etcd-1.service to /etc/systemd/system
sudo mv /tmp/etcd-1.service /etc/systemd/system/etcd-1.service
# to start service
sudo systemctl daemon-reload
sudo systemctl cat etcd-1.service
sudo systemctl enable etcd-1.service
sudo systemctl start etcd-1.service
# to get logs from service
sudo systemctl status etcd-1.service -l --no-pager
sudo journalctl -u etcd-1.service -l --no-pager|less
sudo journalctl -f -u etcd-1.service
# Check status on vm
ETCDCTL_API=3 /usr/local/bin/etcdctl \
--endpoints 192.168.64.19:2379 \
endpoint health
檢查 etcd 服務
在 local 環境下載 etcdctl ,驗證 etcd vm 服務是否允許內部網路連接。 我選擇下載 MacOS 版本
ETCD_VER=v3.5.4
# choose either URL
GOOGLE_URL=https://storage.googleapis.com/etcd
GITHUB_URL=https://github.com/etcd-io/etcd/releases/download
DOWNLOAD_URL=${GOOGLE_URL}
rm -f /tmp/etcd-${ETCD_VER}-darwin-amd64.zip
rm -rf /tmp/etcd-download-test && mkdir -p /tmp/etcd-download-test
curl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-darwin-amd64.zip -o /tmp/etcd-${ETCD_VER}-darwin-amd64.zip
unzip /tmp/etcd-${ETCD_VER}-darwin-amd64.zip -d /tmp && rm -f /tmp/etcd-${ETCD_VER}-darwin-amd64.zip
mv /tmp/etcd-${ETCD_VER}-darwin-amd64/* /tmp/etcd-download-test && rm -rf /tmp/etcd-${ETCD_VER}-darwin-amd64
然後一樣在 local 使用 etcdctl 驗證 endpoint 是否能夠聯通
$ etcd-test ETCDCTL_API=3 ./etcdctl \
--endpoints 192.168.64.19:2379 \
endpoint health
192.168.64.19:2379 is healthy: successfully committed proposal: took = 8.304625ms
建立 cluster 並採用 external etcd
參考k3s 文件 - High Availability External DB,步驟 1.Create an External Datastore 已經在前述過程中完成,因此從步驟 2 開始。
# create new vm
$ multipass launch -n c1-server-1 -c 1 -m 1G -d 3G 22.04
$ multipass shell c1-server-1
...
# install k3s cluster with external etcd
ubuntu@c1-server-1:~$ curl -sfL https://get.k3s.io | sh -s - server --datastore-endpoint="http://192.168.64.19:2379"
[INFO] Finding release for channel stable
[INFO] Using v1.27.6+k3s1 as release
[INFO] Downloading hash https://github.com/k3s-io/k3s/releases/download/v1.27.6+k3s1/sha256sum-arm64.txt
[INFO] Skipping binary downloaded, installed k3s matches hash
[INFO] Skipping installation of SELinux RPM
[INFO] Skipping /usr/local/bin/kubectl symlink to k3s, already exists
[INFO] Skipping /usr/local/bin/crictl symlink to k3s, already exists
[INFO] Skipping /usr/local/bin/ctr symlink to k3s, already exists
[INFO] Creating killall script /usr/local/bin/k3s-killall.sh
[INFO] Creating uninstall script /usr/local/bin/k3s-uninstall.sh
[INFO] env: Creating environment file /etc/systemd/system/k3s.service.env
[INFO] systemd: Creating service file /etc/systemd/system/k3s.service
[INFO] systemd: Enabling k3s unit
Created symlink /etc/systemd/system/multi-user.target.wants/k3s.service → /etc/systemd/system/k3s.service.
[INFO] systemd: Starting k3s
ubuntu@c1-server-1:~$ sudo kubectl get node
NAME STATUS ROLES AGE VERSION
c1-server-1 Ready control-plane,master 8s v1.27.6+k3s1
ubuntu@c1-server-1:~$ exit
驗證 external etcd 運作情況
導出新建立的 cluster kubeconfg
檔案,並透過 alias
建立指定 kubconfig 檔案的 kubectl shortcut
# export kubeconfig
$ multipass exec c1-server-1 sudo cat /etc/rancher/k3s/k3s.yaml > c1-kubeconfig
# alias kubectl shortcut with kubeconfig
$ alias kc1='kubectl --kubeconfig /Users/eric/devops/etcd-test/c1-kubeconfig'
# test alias
$ kc1 get node
NAME STATUS ROLES AGE VERSION
c1-server-1 Ready control-plane,master 12m v1.27.6+k3s1
# create a new namespace of cluster
$ kc1 create ns nginx
namespace/nginx created
# verify external etcd
$ ETCDCTL_API=3 ./etcdctl --endpoints=http://192.168.64.19:2379 get / --prefix --keys-only | grep nginx
/registry/configmaps/nginx/kube-root-ca.crt
/registry/namespaces/nginx
/registry/serviceaccounts/nginx/default
從最後驗證 external etcd 的步驟可以看到,當 namespace nginx
建立之後, external etcd 就會產生對應的 key-value 紀錄。