基於 Sealos 的映象構建能力,快速部署自定義 k8s 叢集

2022-11-17 18:01:34

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 端存取本文章,以獲取更好閱讀體驗,由於精力有限,該文章的後續更新、完善僅限於站點 運維技術幫 (https://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 https://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  https://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=https://192.168.31.51:2379,https://192.168.31.52:2379,https://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 清除之前建立的叢集證書及其它資訊

重 要 提 醒: 由於筆者時間、視野、認知有限,本文難免出現錯誤、疏漏等問題,期待各位讀者朋友、業界大佬指正交流, 共同進步 !!