1. 程式人生 > 其它 >基於 Jenkins + Kubernetes + Argo CD 的完整 DevOps 流程記錄(1) - 環境部署

基於 Jenkins + Kubernetes + Argo CD 的完整 DevOps 流程記錄(1) - 環境部署

一、環境準備

1.1 映象倉庫

整套 DevOps 流程使用 Harbor 作為內部映象倉庫,所有構建產物(映象)都會推送到 Harbor,以備後續進行專案部署。Harbor 從 2.x 版本開始支援 OCI 標準映象,如果是安裝的 1.x 版本,在使用 Podman 構建映象的時候,需要加上 --format docker 引數,以便生成 Docker 格式的映象檔案。

1.1.1 前置條件

  • 配置要求: 雙核 CPU,4 GB 記憶體, 硬碟 100 GB+
  • 系統要求: Rocky Linux 8 或 CentOS 7.x
  • 軟體要求: Docker CE、Docker-Compose

1.1.2 安裝配置

解壓 tar 檔案之後,會得到一個 harbor.yml 檔案,裡面可以對一些引數進行配置,例如監聽埠與預設的密碼資料。

需要進行配置的選項是 hostnamehttpsharbor_admin_password,預設情況下, 其他的引數不需要做特殊調整。針對 https 我們預設禁用掉,因為需要有效證書才能暴露 https 給外部服務,否則後續映象的推送會有問題。

關於 SSL 證書,必須要 全鏈(Full-Chain)證書 才能正常工作,可使用 amch.sh 等工具進行申請。

hostname: 10.0.0.203

# http related config
http:
  # port for http, default is 80. If https enabled, this port will redirect to https port
  port: 8088

# https related config
#https:
  # https port for harbor, default is 443
  # port: 443
  # The path of cert and key files for nginx
#  certificate: /your/certificate/path
#  private_key: /your/private/key/path

harbor_admin_password: audatex

# ... Other info.

harbor.yml 檔案配置完成之後,執行 install.sh 指令碼,一切正常的話,安裝完成之後,可以輸入 docker ps -a 命令檢視正在執行的容器資訊。

安裝成功之後,Harbor 會為我們建立一個 docker-compose.yml 檔案,如果需要手動重啟 Harbor 相關服務,可以直接安裝 Docker-Compose 工具進行操作。

1.2 原始碼託管

本地環境我使用的是 Gogs 作為原始碼託管平臺。它們的作用基本一致,都支援倉庫級別的 WebHook 配置,以便後續進行流水線的自動觸發工作。

1.2.1 前置條件

  • 配置要求: 雙核 CPU,4 GB 記憶體, 硬碟 100 GB+
  • 系統要求: Rocky Linux 8 或 CentOS 7.x
  • 軟體要求: Docker CE、Docker-Compose

1.2.2 快速安裝

Gogs 的安裝需要外掛一個目錄,用於儲存具體的資料庫資料和配置資訊,這裡我們在 docker-compose.yaml 的同目錄下,建立一個 Volume 資料夾,用於存放持久化資料。需要注意的是,由於容器許可權要求,必須設定對應資料夾的所有者為 1000:1000,執行 chown -R 1000:1000 ./Volume 命令進行設定。

對應的 Docker-Compose 檔案內容如下:

version: '3.5'
services:
 gogs:
   image: gogs/gogs
   container_name: gogs
   volumes:
     - ./Volume:/data
   ports:
     - 8080:3000
   restart: always

檔案編寫完成之後,儲存為 docker-compose.yaml 檔案,在對應目錄下指定 docker-compose -d 命令,等待映象拉取完成之後,程式就會自動執行。

1.2.3 Gogs 配置

執行了 Docker Compose 命令之後,在瀏覽器輸入 http://<宿主機 IP>:8080 即可對 Gogs 進行一些基本的配置,根據 UI 上面的提示配置即可。在 DEMO 環境當中,我選擇的是 SQLite,免去了啟動一個單獨資料庫例項的問題。

1.4 NFS 伺服器配置

NFS 伺服器主要是為了 Pod 持久化,我們需要在某臺機器上部署 NFS 服務。

1.4.1 前置條件

  • 配置要求: 雙核 CPU,記憶體 4 G,硬碟 100 GB+
  • 系統要求: Rocky Linux 8 或 CentOS 7.x

1.4.2 快速安裝

  1. 在 Shell 當中執行以下命令,安裝 NFS 服務所需要的相關依賴。

    yum install rpcbind nfs-utils
    
  2. 將對應的服務設定為開機自啟動。

    systemctl start rpcbind
    systemctl enable rpcbind
    
    systemctl start nfs-server
    systemctl enable nfs-server
    
  3. 建立所需要共享的資料夾,建議每個 Deployment 分開建立,這裡我以 Jenkins 為例。

    mkdir -p /share/jenkins
    
  4. 編輯 /etc/exports 檔案,在檔案內加入以下內容。

    /share/jenkins *(rw,sync,no_root_squash,no_all_squash)
    

    關於 exports 檔案的內容,可以參考 https://www.cnblogs.com/rootq/articles/1310888.html 裡面的詳細描述。

  5. 過載配置檔案。

    exportfs -rv
    
  6. 關閉防火牆,這裡我為了進行 DEMO 測試,是將防火牆進行了關閉處理。

    systemctl stop firewalld.service
    systemctl disable firewalld.service
    

1.5 Linux 叢集初始化

目前的測試叢集構成是 1 臺 Master 節點,1 臺工作節點,Kubernetes 混合叢集的控制面都是基於 Linux 進行排程的。

1.5.1 前置條件

角色 作業系統 配置 硬碟
Master CentOS 7.x 4 核 8G 50 GB 硬碟
Node-1 CentOS 7.x 4 核 8 G 50 GB 硬碟

1.5.2 安裝叢集

在測試 DEMO 中,我直接使用的 sealos 一鍵部署的 Kubernetes Linux 叢集。sealos 類似於 Kubeadm,它將具體的部署細節進行了簡化。

首先我們在 Master 節點,先下載 sealos 的二進位制包,執行以下命令進行下載:

wget -c https://sealyun-home.oss-cn-beijing.aliyuncs.com/sealos/latest/sealos && chmod +x sealos && mv sealos /usr/bin

PS: 如果提示 -bash: wget: command not found 的話,需要執行 yum install -y wget 安裝 wget 工具。

sealos 下載完成之後,需要下載對應的叢集安裝檔案,這裡我使用的是 [Kubernetes 1.20.15](./Attachment Files/Kubernetes/1.20.15/kube1.20.15.tar.gz) 版本,將其上傳到 /root 目錄,執行以下命令即可進行安裝。

sealos init --passwd 'Password for all Linux nodes' \
	--master <Master IP> \
	--node <Node IP> \
	# Your kubernetes compressed package.
	--pkg-url /root/kube1.20.15.tar.gz \
	# The version of kubernetes you need to install.
	--version v1.20.15

預設情況下,如果沒有指定其他的安裝引數,Kubectl 會使用 Calico 作為網路外掛。等待 sealos 安裝完成後,輸入 kubectl get nodes 查詢當前叢集的狀態,一切準備就緒後就可以開始下一步操作了。

[root@k8s-master ~]# kubectl get nodes
NAME         STATUS   ROLES                  AGE   VERSION
k8s-master   Ready    control-plane,master   69s   v1.20.15
k8s-node-1   Ready    <none>                 37s   v1.20.15

1.5.3 網路調整

所有網路相關步驟,都是參考的 Calico 官網文件 進行操作。

  1. 首先要在 Master 節點下載並安裝 calicoctl,以便關閉 IPIP 模式,對應的二進位制檔案在資料夾 [Calico](./Attachment Files/Calico) 中。

    • calicoctl 檔案上傳到 /usr/local/bin/ ,執行以下命令設定為可執行模式。

      cd /usr/local/bin/
      mv calicoctl-linux-amd64 calicoctl
      chmod +x calicoctl
      
    • 獲取對應的 IP Pool 資訊,並將其寫入到 ippool.yaml 檔案當中。

      calicoctl --allow-version-mismatch get ipPool default-ipv4-ippool  -o yaml > ippool.yaml
      
    • 使用 VI 編輯對應的 ippool.yaml 檔案,修改內容如下。

      apiVersion: projectcalico.org/v3
      kind: IPPool
      metadata:
        creationTimestamp: "2022-03-26T16:14:19Z"
        name: default-ipv4-ippool
        resourceVersion: "551"
        uid: 17ef6755-a95e-458a-96ee-27242486a5e5
      spec:
        allowedUses:
        - Workload
        - Tunnel
        blockSize: 26
        cidr: 100.64.0.0/10
        ipipMode: Never	# 修改 Always 為 Never.
        natOutgoing: true
        nodeSelector: all()
        vxlanMode: Never
      
    • 應用 ippool.yaml 的變更。

      calicoctl --allow-version-mismatch apply -f ippool.yaml
      
    • 執行以下命令,繼續關閉 IPIP 功能。

      calicoctl --allow-version-mismatch patch felixconfiguration default -p '{"spec":{"ipipEnabled":false}}'
      
    • 防止 Pod 分配到 Windows 的 IP 網段。

      calicoctl --allow-version-mismatch ipam configure --strictaffinity=true
      

1.5.4 信任映象倉庫

叢集內的其他 Linux 節點都是使用的 Container-D 作為容器引擎,它們的配置和 Docker 是不一樣的。預設安裝 Kubernetes 叢集的時候,Container-D 也沒有預設的配置檔案,需要執行 mkdir -p /etc/containerd && containerd config default > /etc/containerd/config.toml 命令,將預設配置的 toml 檔案輸出到指定目錄。在 [plugins."io.containerd.grpc.v1.cri".registry] 節附近,新增如下內容:

[plugins."io.containerd.grpc.v1.cri".registry.mirrors."<host>:<port>"]
endpoint = ["http://<host>:<port>"]

其中 host 指代的映象倉庫的主機地址,port 指的是映象倉庫的埠號。修改完成之後,執行 systemctl restart containerd.service 重新啟動 Container-D 服務。

1.5.5 NFS 客戶端的安裝

在 DEMO 環境當中,如果存在多個 Node 節點,就不適用 hostPath 的方式對 Pod 資料進行持久化。所以會直接採用 NFS 的方式,提供 PV 所需要的持久化卷,在前面我們針對 NFS 進行了伺服器配置,不過這還不夠,如果不在對應的節點安裝 NFS 客戶端的話,會導致 Pod 建立失敗。

執行以下命令,在節點上安裝 NFS 客戶端:

yum install nfs-utils

執行以下命令,看是否掛載成功:

showmount -e <NFS-Server IP>

Example Output:

[root@k8s-node-1 containerd]# showmount -e 10.0.0.203
Export list for 10.0.0.203:
/share/Jenkins *

參考資料: https://juejin.cn/post/6943424989961928711

1.6 Windows 節點初始化

Windows 節點上 Docker EE 的 Docker in Docker 機制,並不支援掛載 Windows 宿主機上的 Docker 程序,所以不能通過 Jenkins 的 Kubernetes Cloud Node 動態生成 Slave。在 Linux 節點上能夠使用的 Podman,在 Windows 容器中也 不受支援。因此只能選擇直接部署一臺 Windows Server Node,並在機器上安裝相關工具,在 Pipeline 中通過 Powershell 的方式進行呼叫。

1.6.1 前置條件

  • 配置要求: 4 核 CPU,8GB 記憶體
  • 系統要求: Windows Server 2019 - 1809

1.6.2 安裝 Docker EE

在執行所有操作之前,請確保 Windows Server 處在最新的版本,後續所有操作,我們都假設你處在 PowerShell(管理員模式) 當中。

  1. 首先我們需要為 Windows Server 安裝容器功能,開啟 Powershell,在其內部輸入以下命令關閉防火牆設定,以防安裝失敗。

    New-NetFireWallRule -DisplayName "Allow All Traffic" -Direction OutBound -Action Allow 
    New-NetFireWallRule -DisplayName "Allow All Traffic" -Direction InBound -Action Allow
    
  2. 為 Windows Server 啟用容器功能並重啟。

    Install-WindowsFeature -Name containers
    Restart-Computer -Force
    
  3. 在資料夾 [Docker EE](./Attachment Files/Docker EE) 中,存有 Docker EE 的二進位制安裝包,在 C:\Program Files\Docker 建立一個資料夾,將對應的壓縮檔案解壓到對應目錄。

    隨後,在環境變數的 Path 節中,新增 Docker 目錄,隨後在 PowerShell 執行以下命令重啟並設定為自動啟動服務。

    dockerd --register-service
    Set-Service -Name docker -StartupType 'Automatic'
    Restart-Computer -Force
    
  4. 執行 docker info 命令與 docker ps -a 命令,確認 Docker EE 已經可以正常執行。

    PS C:\Users\Administrator> docker info
    Client:
     Context:    default
     Debug Mode: false
     Plugins:
      app: Docker App (Docker Inc., v0.9.1-beta3)
      cluster: Manage Mirantis Container Cloud clusters (Mirantis Inc., v1.9.0)
      registry: Manage Docker registries (Docker Inc., 0.1.0)
    
    Server:
     Containers: 0
      Running: 0
      Paused: 0
      Stopped: 0
     Images: 0
     Server Version: 20.10.9
     Storage Driver: windowsfilter
      Windows:
     Logging Driver: json-file
     Plugins:
      Volume: local
      Network: ics internal l2bridge l2tunnel nat null overlay private transparent
      Log: awslogs etwlogs fluentd gcplogs gelf json-file local logentries splunk syslog
     Swarm: inactive
     Default Isolation: process
     Kernel Version: 10.0 17763 (17763.1.amd64fre.rs5_release.180914-1434)
     Operating System: Windows Server 2019 Standard Version 1809 (OS Build 17763.2746)
     OSType: windows
     Architecture: x86_64
     CPUs: 4
     Total Memory: 5.999GiB
     Name: WIN-F4GQN7VJPQP
     ID: Y7WJ:F3XG:XRV7:K36J:C7WU:JVGF:QLIY:AXBK:CKOH:AM2Y:7VIV:VF2K
     Docker Root Dir: C:\ProgramData\docker
     Debug Mode: false
     Registry: https://index.docker.io/v1/
     Labels:
     Experimental: false
     Insecure Registries:
      127.0.0.0/8
     Live Restore Enabled: false
    PS C:\Users\Administrator> docker ps -a
    CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
    

1.6.3 信任映象倉庫

針對 Windows 節點,因為是基於 Docker 引擎的,只需要在 C:\ProgramData\docker\config 建立一個 daemon.json 檔案,並配置相關的倉庫地址即可。這裡以 10.0.0.203:8088 的倉庫為例:

{
    "insecure-registries": ["10.0.0.203:8088"]
}

配置完成之後,在 Windows 服務當中,重啟 Docker Engine 服務即可生效。

1.6.4 Hosts 檔案調整

使用 sealos 快速安裝的 Kubernetes 叢集,其 Kubernetes API 地址是一個偽造的域名 apiserver.cluster.local,在 Windows 節點上,如果要加入這個叢集,就需要修改 Windows 節點的 Hosts 檔案。(當然,最好的做法是叢集內部署一臺 DNS 伺服器。)

<Master 節點 IP> apiserver.cluster.local

1.6.5 配置 Windows 服務

針對 BGP 模式,需要安裝以下服務,然後重啟系統。

Install-WindowsFeature RemoteAccess
Install-WindowsFeature RSAT-RemoteAccess-PowerShell
Install-WindowsFeature Routing
Restart-Computer -Force

重啟完成之後,繼續執行以下命令。

Install-RemoteAccess -VpnType RoutingOnly
Start-Service RemoteAccess

1.6.6 安裝 Calico 網路

  1. 在 C 盤建立一個 k 資料夾。

    mkdir c:\k
    
  2. 從 Linux 的 Master 節點上,複製 ~/.kube/config 檔案到 Windows 節點上的 c:\k\config

  3. 下載 Calico 對應的安裝指令碼,準備開始安裝。

    Invoke-WebRequest https://projectcalico.docs.tigera.io/scripts/install-calico-windows.ps1 -OutFile c:\install-calico-windows.ps1
    
  4. 執行安裝指令碼,記得傳入你的 Kubernetes 叢集版本作為安裝引數,隨後等待 Calico 安裝完成。

    c:\install-calico-windows.ps1 -KubeVersion 1.20.15
    
  5. 執行以下命令,驗證 Calico 服務安裝成功。

    Get-Service -Name CalicoNode
    Get-Service -Name CalicoFelix
    
  6. 安裝 Windows 節點上的 Kubernetes 元件服務。

    C:\CalicoWindows\kubernetes\install-kube-services.ps1
    Start-Service -Name kubelet
    Start-Service -Name kube-proxy
    
  7. 驗證 Kubernetes 元件服務啟動成功。

    Get-Service -Name kubelet
    Get-Service -Name kube-proxy
    

以上操作完成以後,執行 kubectl get nodes -o wide 命令,就可以看到叢集已經準備就緒了。

[root@k8s-master .kube]# kubectl get nodes -o wide
NAME              STATUS   ROLES                  AGE    VERSION    INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                       KERNEL-VERSION           CONTAINER-RUNTIME
k8s-master        Ready    control-plane,master   54m    v1.20.15   10.0.0.60     <none>        CentOS Linux 7 (Core)          3.10.0-1160.el7.x86_64   containerd://1.5.5
k8s-node-1        Ready    <none>                 53m    v1.20.15   10.0.0.61     <none>        CentOS Linux 7 (Core)          3.10.0-1160.el7.x86_64   containerd://1.5.5
win-f4gqn7vjpqp   Ready    <none>                 103s   v1.20.15   10.0.0.62     <none>        Windows Server 2019 Standard   10.0.17763.2746          docker://20.10.9

1.6.7 汙點設定

為了防止 Linux Pod 排程到 Windows 節點,導致容器無法執行的情況,我們需要為 Windows 節點都新增一個特殊的汙點,只有當 Pod 顯式制定了容忍度以後才會被排程到 Windows 節點。

kubectl taint nodes <Windows 節點名稱> cattle.io/os=windows:NoSchedule

1.6.8 驗證網路互通

在 [IIS-Demo](./Attachment Files/Manifest/IIS-Demo) 資料夾中,存放有基於 IIS 的一個示例,執行之後我們可以通過 kubetl get pods -o wide 獲得它的 Pod IP 地址。

➜  IIS-Demo kubectl get pods -o wide 
NAME                                READY   STATUS    RESTARTS   AGE   IP              NODE             NOMINATED NODE   READINESS GATES
busybox                             1/1     Running   0          10m   100.85.249.1    linux-node       <none>           <none>
iis-site-windows-784844b499-4vccd   1/1     Running   0          87s   100.114.137.3   windows-node-1   <none>           <none>

獲得 IP 地址之後,使用命令 kubectl run -it --rm --restart=Never --overrides='{"spec": { "nodeSelector": { "kubernetes.io/os": "linux" } } }' busybox --image=busybox sh 在 Linux Node 上執行一個 busybox 服務。

執行成功以後,在 busybox 的 Bash,執行 ping 100.82.16.4 命令,檢視是否能夠 Ping 通,如果能夠 Ping 通,說明 Linux Pod -> Windows Pod 已經可以正常通訊。

後續使用 docker exec -ti <Container Name> powershell 進入 Windows Pod 內部,執行 ping 100.85.249.1 命令,如果有返回值說明 ·Windows Pod -> Linux Pod 網路通訊是正常的。

最後在 Windows Pod 內部,執行 ping baidu.com 檢視是否能夠獲取到以下內容,如果獲取成功則說明 Windows Pod -> Internet 是互通的。

PS C:\> Invoke-RESTMethod http://baidu.com
<html>
<meta http-equiv="refresh" content="0;url=http://www.baidu.com/">
</html>

最後是確認 Windows Pod 能夠訪問叢集內部的服務,