更好的閱讀體驗建議點擊下方原文鏈接。
原文鏈接:http://maoqide.live/post/notes/upgrade-kubernets-from-binary-to-kubeadm/
記一次從二進制部署的 k8s 集群 到 kubeadm 部署的 k8s 遷移測試。
原有 k8s 集群為二進制形式部署,集群管理不太方便,准備在集群升級的機會,將集群部署方式改為 kubeadm部署,本文記錄測試遷移的過程。
部署新的 master 集群
etcd 數據遷移
為了完全不影響原有集群的運行,將 etcd 也做遷移,新的 master 連接新的 etcd,不對老集群造成影響。
首先新建一個 etcd,並使用 etcd 的 make-mirror 功能將原有集群的 etcd 數據同步到新的etcd中。
# 新起一個 etcd,為了方便這里新建不帶證書的 http 端口
docker run -d \
--name etcd \
--net host \
-v /data/etcd:/var/lib/etcd \
quay.io/coreos/etcd:v3.3.13 \
etcd --listen-client-urls http://0.0.0.0:2379 --advertise-client-urls http://0.0.0.0:2379
# 遷移數據
export ETCDCTL_API=3
etcdctl --endpoints=https://etcd-ip:2379 --cert=/etc/kubernetes/ssl/etcd.pem --cacert=/etc/kubernetes/ssl/ca.pem --key=/etc/kubernetes/ssl/etcd-key.pem make-mirror http://destination-ip:2379
由於 kubeadm 會自動新建 dns,所以在新的 etcd 中,將導入過來的 kube-dns 相關數據手動刪掉。
# 執行如下命令知道刪掉所有 kube-dns 相關的key
echo $(etcdctl get / --prefix --keys-only | grep 'kube-dns') | awk -F ' ' '{ print $1}' | xargs etcdctl del
新建 master 集群
使用 kubeadm 新建集群,要注意集群配置要和之前一致,如 serviceSubnet, netSubnet 等,並指定 etcd 為剛才新建的 etcd,以下為 kubeadm 配置文件(用的老版本配置,最新版本的 kubeadm 已經不支持)。
apiVersion: kubeadm.k8s.io/v1alpha1
kind: MasterConfiguration
api:
advertiseAddress: 172.27.32.165
etcd:
endpoints:
- http://172.27.32.165:2379
networking:
serviceSubnet: 10.254.0.0/16
podSubnet: 172.41.0.0/16
kubernetesVersion: 1.10.13
imageRepository: harbor.guahao-inc.com/kubernetes
apiServerExtraArgs:
insecure-bind-address: 172.27.32.165
kubeletConfiguration:
baseConfig:
clusterDNS:
- 10.254.0.2
nodeName: 172.27.32.165
# kubelet.service 加上如下配置
Environment="KUBELET_EXTRA_ARGS=--pod-infra-container-image=harbor.guahao-inc.com/kubernetes/pause-amd64:3.1 --hostname-override=172.27.32.165"
kubeadm 配置文件中設置了nodeName,要同時在 kubelet 的 kubelet.service文件中加上 --hostname-override 參事,否則 kubelet 注冊 apiserver 時會出現node forbidden 錯誤
# 使用配置文件新建 master 節點,目前所用 k8s 集群版本較老,不支持新版本docker,忽略docker版本校驗
# 創建之前可以先 dryrun 進行校驗,沒問題再真正執行,dryrun 會將需要做的步驟模擬執行並輸出,不會真正操作
kubeadm init --dry-run --config kubeadm.yaml --ignore-preflight-errors=SystemVerification
kubeadm init --config kubeadm.yaml --ignore-preflight-errors=SystemVerification
完成后會提示新建成功,並提示后續操作命令,及node節點加入集群的命令。
# 配置 kubectl
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# 加入集群的命令可以用 kubeadm 重新生成
kubeadm token create --print-join-command
此時已經建好新的 master 節點,並且使用 kubectl get no 可以看到原有集群的節點信息,但這時只是導過來的 etcd,實際上此時 master 節點並未控制 node 節點,node 節點的 kubelet 依然是注冊到老的 master 節點,想要將原來的 node 節點遷移到新的 master 節點下,還需要逐台修改每台 node 節點的配置。
遷移 node 節點
遷移 node 節點要注意首先要備份原node節點的 /etc/kubernetes/
、/var/lib/kubelet/
和 /etc/systemd/system/kubelet.service
、/etc/systemd/system/kubelet.service.d/
文件及目錄,以便出現異常時可以快速回滾恢復。
做好備份后,將當前節點kubelet
、kube-proxy
停掉,並執行如下命令,由於節點上 kebelet 已經啟動且已有 pod 在運行,需要加上 --ignore-preflight-errors=all
強制執行,主要是為了生成 kubelet 相關證書及配置文件,並重啟 kubelet 注冊到新的 master 節點的 apiserver,此時 --node-name
要指定和之前一樣的節點名稱,如果 kubelet.service 配置不正確的話,需要手動修改相關配置(參考 kubeadm 新建節點的配置)。
kubeadm join --node-name 192.168.l96.31 172.27.32.165:6443 --token qfr5ff.sd7qn0tlx2a3kxtl --discovery-token-ca-cert-hash sha256:0f7175e3cf8e40d41983688aeb8e80153c2502cd375629379a5abb53f71bce0d --ignore-preflight-errors=all
成功的話,在新的 master 節點執行kubectl get no
會能夠看到遷移的節點已經變成 ready 狀態。
若出現異常,將之前備份的目錄和文件還原,並重啟kubelet
和kube-proxy
,即可恢復節點。
以上是經測試驗證過的一種思路,但是在實際生產中,用這種方式進行遷移,還是會對在運行容器產生影響,若要應用到生產環境,還需更嚴謹詳細的測試,並且此種方式的遷移風險較大,測試中遇到很多坑,應盡量避免。