基於 Sealos 的鏡像構建能力,快速部署自定義 k8s 集群
- 2022 年 11 月 17 日
- 筆記
- Kubernetes, 雲原生
Sealos 是一個快速構建高可用 k8s 集群的命令行工具,該工具部署時會在第一個 k8s master 節點部署 registry 服務(sealos.hub),該域名通過 hosts 解析到第一個 k8s master 節點 ip;基於內核 ipvs 對 apiserver 進行負載均衡,其默認虛擬 ip 地址為 10.103.97.2(apiserver.cluster.local),所有 k8s Worker 節點通過該虛擬 ip 訪問 kube-apiserver
建議通過 PC 端訪問本文章,以獲取更好閱讀體驗,由於精力有限,該文章的後續更新、完善僅限於站點 運維技術幫 (//ywjsbang.com) 望理解 !!
環境配置
# 各組件版本
CenOS7.9 Min(Kernel 5.4.220)
Sealos:v4.1.3
flannel:v0.20.0
kubernetes:v1.25.3
kubernetes-dashboard:v2.7.0
# 設置各節點主機名與 IP 地址映射關係
cat >> /etc/hosts << EOF
192.168.31.51 t1
192.168.31.52 t2
192.168.31.53 t3
192.168.31.54 t4
192.168.31.55 t5
EOF
# 安裝依賴
yum install socat conntrack-tools -y
flanneld 默認容器
flanneld 默認配置清單 kube-flannel.yml 中的容器配置,簡要說明如下
initContainers:
docker.io/rancher/mirrored-flannelcni-flannel-cni-plugin:v1.1.0 # 通過卷掛載方式,將 CNI 插件 /opt/cni/bin/flannel 掛載到宿主機對應位置
docker.io/rancher/mirrored-flannelcni-flannel:v0.20.0 # 通過卷掛載方式,將配置目錄 /etc/cni/net.d 和 /etc/kube-flannel/ 掛載到宿主機對應位置
containers
docker.io/rancher/mirrored-flannelcni-flannel:v0.20.0 # flanneld 守護進程
自定義 kube-flannel.yml
修改 pod 網段
修改 kube-flannel.yml 配置,其默認 pod 網段為 10.244.0.0/16,可按需修改
wget //raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml -C ./manifests/
kind: ConfigMap
apiVersion: v1
metadata:
name: kube-flannel-cfg
namespace: kube-flannel
labels:
tier: node
app: flannel
data:
...
...
net-conf.json: |
{
"Network": "10.15.0.0/16", # pod 網段, 該網段必須與 kube-controller-manager 配置參數 --cluster-cidr 值匹配
"Backend": {
"Type": "vxlan"
}
}
添加 init 容器
修改 kube-flannel.yml 添加 Init 容器 install-cni-plugin-sealos
,其作用是通過卷掛載,將宿主機目錄 /opt/cni/bin 掛載到容器目錄 /opt/cni/bin
initContainers:
- name: install-cni-plugin-sealos
image: docker.io/labring/docker-cni-plugins:v1.1.0
command: ["/bin/sh"]
args: ["-c", "cp -f /cni-plugins/* /opt/cni/bin/"]
volumeMounts:
- name: cni-plugin-sealos
mountPath: /opt/cni/bin
# 定義卷 cni-plugin-sealos
volumes:
- name: cni-plugin-sealos
hostPath:
path: /opt/cni/bin
部署 Sealos
wget //github.com/labring/sealos/releases/download/v4.1.3/sealos_4.1.3_linux_amd64.tar.gz && \
tar -zxvf sealos_4.1.3_linux_amd64.tar.gz sealos && \
chmod +x sealos && mv sealos /usr/bin
創建 Dockerfile
1、創建鏡像構建配置文件,目錄 registry 構建時會自動生成,用於存放構建該鏡像時依賴的其它鏡像信息 !!
cat > Dockerfile << EOF
FROM scratch
COPY manifests ./manifests
COPY registry ./registry
CMD ["kubectl apply -f manifests/kube-flannel.yml"]
EOF
2、使用 sealos 打包構建鏡像
# 執行自定義鏡像構建
sealos build -f Dockerfile -t it123.me/flannel:v0.20.0 .
# 查看本地鏡像
sealos images
# > REPOSITORY TAG IMAGE ID CREATED SIZE
# > it123.me/flannel v0.20.0 6f0563e3df50 19 minutes ago 72.9 MB
# > docker.io/labring/kubernetes v1.25.3 6f1de58f84c4 8 days ago 589 MB
# > docker.io/labring/calico v3.24.1 e2122fc58fd3 8 weeks ago 354 MB
# > docker.io/labring/helm v3.8.2 1123e8b4b455 3 months ago 45.1 MB
# > docker.io/labring/calico v3.22.1 29516dc98b4b 4 months ago 546 MB
生成 Clusterfile
1、生成集群配置文件
sealos gen labring/kubernetes:v1.25.3 it123.me/flannel:v0.20.0 --masters 192.168.31.51 --nodes 192.168.31.54 -p rootroot > Clusterfile
# 參數解析
--masters # 集群 master 節點,可逗號分隔指定多個
--nodes # 集群 worker 節點,可逗號分隔指定多個
-p rootroot # 部署時的 ssh 密碼,默認 ssh 用戶 root,可通過 -u 參數修改
# 創建集群時需要的鏡像
it123.me/flannel:v0.20.0
labring/kubernetes:v1.25.3
2、配置文件 Clusterfile 內容如下
apiVersion: apps.sealos.io/v1beta1
kind: Cluster
metadata:
creationTimestamp: null
name: default
spec:
hosts:
- ips:
- 192.168.31.51:22
roles:
- master
- amd64
- ips:
- 192.168.31.54:22
roles:
- node
- amd64
image:
- labring/kubernetes:v1.25.3
- it123.me/flannel:v0.20.0
ssh:
passwd: rootroot
pk: /root/.ssh/id_rsa
port: 22
status: {}
3、向 Clusterfile 文件尾行添加如下內容,以自定義集群的 pod 和 service 網段,將會分別用於設置組件 kube-controller-manager 啟動參數 –cluster-cidr 和 –service-cluster-ip-range 的值
---
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
networking:
podSubnet: 10.15.0.0/16 # 該值必須與 flanneld 配置清單 kube-flannel.yaml 中的配置一致,
serviceSubnet: 10.16.0.0/16
創建集群
1、基於如上配置創建集群
# 創建集群, 並驗證節點狀態
sealos apply -f Clusterfile
kubectl get node -o wide
# > NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
# > t1 Ready control-plane 41m v1.25.3 192.168.31.51 <none> CentOS Linux 7 (Core) 5.4.220-1.el7.elrepo.x86_64 containerd://1.6.2
# > t4 Ready <none> 41m v1.25.3 192.168.31.54 <none> CentOS Linux 7 (Core) 5.4.220-1.el7.elrepo.x86_64 containerd://1.6.2
2、在需要執行集群管理的節點添加 kubeconfig 配置
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
集群維護
添加 Work 節點
1、添加工作節點 192.168.31.55
sealos add --nodes 192.168.31.55 # 執行 sealos delete --nodes 192.168.31.50 刪除節點
kubectl get node -o wide
# > NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
# > t1 Ready control-plane 41m v1.25.3 192.168.31.51 <none> CentOS Linux 7 (Core) 5.4.220-1.el7.elrepo.x86_64 containerd://1.6.2
# > t4 Ready <none> 41m v1.25.3 192.168.31.54 <none> CentOS Linux 7 (Core) 5.4.220-1.el7.elrepo.x86_64 containerd://1.6.2
# > t5 Ready <none> 38s v1.25.3 192.168.31.55 <none> CentOS Linux 7 (Core) 5.4.221-1.el7.elrepo.x86_64 containerd://1.6.2
2、驗證 pod 、service 網段
kubectl get pod,svc -o wide -A
# > NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
# > kube-system pod/coredns-565d847f94-4lr8z 1/1 Running 0 44m 10.15.0.5 t8 <none> <none>
# > kube-system pod/coredns-565d847f94-65v47 1/1 Running 0 44m 10.15.0.4 t8 <none> <none>
# > NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
# > default service/kubernetes ClusterIP 10.16.0.1 <none> 443/TCP 44m <none>
# > kube-system service/kube-dns ClusterIP 10.16.0.10 <none> 53/UDP,53/TCP,9153/TCP 44m k8s-app=kube-dns
添加 Master 節點
1、添加控制器節點 192.168.31.52 和 192.168.31.53
sealos add --masters 192.168.31.52,192.168.31.53
執行該操作時,sealos 會自動在對應 master 節點添加 etcd 服務,但是集群 kube-apiserver 配置項 –etcd-servers 並未更新,因此、還需到各 master 節點更新配置文件 /etc/kubernetes/manifests/kube-apiserver.yaml,設置配置項--etcd-servers=//192.168.31.51:2379,//192.168.31.52:2379,//192.168.31.53:2379
實現 etcd 服務的高可用
備註: 該配置項修改後會自動生效,因為 k8s 會自動監視這些配置文件,當被修改時,k8s 會自動重建對應節點 kube-apiserver 的 pod 實例
2、驗證節點
kubectl get node -o wide
# > NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
# > t1 Ready control-plane 54m v1.25.3 192.168.31.51 <none> CentOS Linux 7 (Core) 5.4.220-1.el7.elrepo.x86_64 containerd://1.6.2
# > t2 Ready control-plane 2m v1.25.3 192.168.31.52 <none> CentOS Linux 7 (Core) 5.4.220-1.el7.elrepo.x86_64 containerd://1.6.2
# > t3 Ready control-plane 2m v1.25.3 192.168.31.53 <none> CentOS Linux 7 (Core) 5.4.220-1.el7.elrepo.x86_64 containerd://1.6.2
# > t4 Ready <none> 54m v1.25.3 192.168.31.54 <none> CentOS Linux 7 (Core) 5.4.220-1.el7.elrepo.x86_64 containerd://1.6.2
# > t5 Ready <none> 13m v1.25.3 192.168.31.55 <none> CentOS Linux 7 (Core) 5.4.220-1.el7.elrepo.x86_64 containerd://1.6.2
部署 dashboard
sealos run --cluster demo01 labring/kubernetes-dashboard:v2.7.0
清理集群
sealos reset
Q&A
1、error execution phase control-plane-prepare/certs: error creating PKI assets: failed to write or validate certificate "apiserver": certificate apiserver is invalid: x509: certificate is valid for 192.168.31.53, 10.96.0.1, 10.103.97.2, 127.0.0.1, 192.168.31.51, 192.168.31.52, not 10.16.0.1
(生成的 apiserver.cert 證書不包含 10.16.0.1)
使用 sealos apply -f Clusterfile
創建集群時,並未將 Clusterfile 中 kubeadm 的自定義集群配置 ClusterConfiguration 添加至 .sealos/demo01/Clusterfile 文件,因此當使用如下命令添加 master 節點時報錯提示,生成的 apiserver.cert 證書中不包含自定義的 service 網段 ip
# 使用默認配置文件 .sealos/demo01/Clusterfile
sealos add --cluster demo01 --masters 192.168.31.52,192.168.31.53
解決方案:在文件 .sealos/demo01/Clusterfile 尾行添加如下配置, 再執行 master 節點添加命令:
---
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
networking:
podSubnet: 10.15.0.0/16
serviceSubnet: 10.16.0.0/16
2、若執行 sealos apply -f Clusterfile 操作時,提示 no change apps | nodes
, 則需要用 Clusterfile 覆蓋 /root/.sealos/default/Clusterfile 文件
cp Clusterfile /root/.sealos/default/Clusterfile 或刪除 /root/.sealos/default/Clusterfile 狀態部分 status:{} 或 sealos reset
3、socat not found in system path
!!
集群所有節點安裝 yum install socat -y
4、ERROR [2022-11-02 20:11:43] >> Port: 10249 occupied. Please turn off port service
.
本次安裝受到環境殘留干擾,需清理節點環境
5、error execution phase preflight: couldn't validate the identity of the API Server: could not find a JWS signature in the cluster-info ConfigMap for token ID "fk63j7"
新建 default 集群時,執行 sealos reset –cluster default 清除之前創建的集群證書及其它信息
重 要 提 醒: 由於筆者時間、視野、認知有限,本文難免出現錯誤、疏漏等問題,期待各位讀者朋友、業界大佬指正交流, 共同進步 !!