一、基於 Kubernetes/K8S 構建 Jenkins 持續集成平台
服務列表
服務器名稱 | IP地址 | 安裝的軟件 |
代碼托管服務器 | 192.168.10.10 | Gitlab |
持續集成服務器 | 192.168.10.20 | Jenkins,Maven,Docker18.06.1-ce |
slave | 192.168.10.110 |
Jenkins 的 Master-Slave 分布式構建
1、什么是 Master-Slave 分布式構建
Jenkins的Master-Slave分布式構建,就是通過將構建過程分配到從屬Slave節點上,從而減輕Master節 點的壓力,而且可以同時構建多個,有點類似負載均衡的概念。
2、如何實現 Master-Slave 分布式構建
(1)開啟代理程序的TCP端口
Manage Jenkins --> Configure Global Security --> 隨機選取
(2)新建節點
Manage Jenkins --> Manage Node --> 新建節點
這個下載的 jar 包需要傳遞到從節點服務器上
從節點 slave(192.168.10.110)服務器上操作
關閉防火牆
從節點 slave 安裝 git 環境
yum install git -y
執行安裝成功后,執行上述提示的指令
java -jar agent.jar -jnlpUrl http://192.168.10.20:8888/computer/slave1/jenkins-agent.jnlp -secret 8ff8ad31b86e893521b60a4f03ab340186d4e31ed7cde59e417471ca0f1d9ed1 -workDir "/root/jenkins"
回到主節點查看狀態
進行自由風格項目測試
新建 item
直接構建
在 slave1 服務器 /root/jenkins上查看項目代碼拉取
使用流水線項目
創建項目前先連接主節點
新建 item
--> 點擊 流水線語法(在最底部)--> 配置 --> 生成流水線(在底部)
node('slave1') { //拉取代碼 stage('pull code') { checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: '015f1ee4-73cf-4d51-95b0-2954fc32aadb', url: 'git@192.168.10.10:xxx_group/tensquare_back.git']]]) } }
直接構建
在 slave1 服務器 /root/jenkins上查看項目代碼拉取
二、Kubernetes 實現 Master-Slave 分布式構建方案
傳統 Jenkins 的 Master-Slave 方案的缺陷
- Master節點發生單點故障時,整個流程都不可用了
- 每個 Slave節點的配置環境不一樣,來完成不同語言的編譯打包等操作,但是這些差異化的配置導致管理起來非常不方便,維護起來也是比較費勁
- 資源分配不均衡,有的 Slave節點要運行的job出現排隊等待,而有的Slave節點處於空閑狀態
- 資源浪費,每台 Slave節點可能是實體機或者VM,當Slave節點處於空閑狀態時,也不會完全釋放掉資源
以上種種問題,我們可以引入Kubernates來解決!
Kubernetes 簡介
Kubernetes(簡稱,K8S)是Google開源的容器集群管理系統,在Docker技術的基礎上,為容器化的 應用提供部署運行、資源調度、服務發現和動態伸縮等一系列完整功能,提高了大規模容器集群管理的 便捷性。 其主要功能如下:
- 使用Docker對應用程序包裝(package)、實例化(instantiate)、運行(run)。
- 以集群的方式運行、管理跨機器的容器。以集群的方式運行、管理跨機器的容器。
- 解決Docker跨機器容器之間的通訊問題。解決Docker跨機器容器之間的通訊問題。
- Kubernetes的自我修復機制使得容器集群總是運行在用戶期望的狀態。
Kubernates+Docker+Jenkins 持續集成架構圖
大致工作流程:
手動/自動構建 --> Jenkins 調度 K8S API -->動態生成 Jenkins Slave pod --> Slave pod 拉取 Git 代碼/編譯/打包鏡像 -->推送到鏡像倉庫 Harbor --> Slave 工作完成,Pod 自動銷毀 -->部署到測試或生產 Kubernetes平台。(完全自動化,無需人工干預)
Kubernates+Docker+Jenkins 持續集成方案好處
- 服務高可用:
當 Jenkins Master 出現故障時,Kubernetes 會自動創建一個新的 Jenkins Master 容器,並且將 Volume 分配給新創建的容器,保證數據不丟失,從而達到集群服務高可用。
- 動態伸縮,合理使用資源:
每次運行 Job 時,會自動創建一個 Jenkins Slave,Job 完成后,Slave 自動注銷並刪除容器,資源自動釋放,而且 Kubernetes 會根據每個資源的使用情況,動態分配Slave 到空閑的節點上創建,降低出現因某節點資源利用率高,還排隊等待在該節點的情況。
- 擴展性好:
當 Kubernetes 集群的資源嚴重不足而導致 Job 排隊等待時,可以很容易的添加一個Kubernetes Node 到集群中,從而實現擴展。
Kubeadm 安裝 Kubernetes
Kubernetes 的架構
- API Server:
用於暴露Kubernetes API,任何資源的請求的調用操作都是通過kube-apiserver提供的接口進行的。
- Etcd:
是Kubernetes提供默認的存儲系統,保存所有集群數據,使用時需要為etcd數據提供備份計划。
- Controller-Manager:
作為集群內部的管理控制中心,負責集群內的Node、Pod副本、服務端點(Endpoint)、命名空間(Namespace)、服務賬號(ServiceAccount)、資源定額(ResourceQuota)的管理,當某個Node意外宕機時,Controller Manager會及時發現並執行自動化修復流程,確保集群始終處於預期的工作狀態。
- Scheduler:
監視新創建沒有分配到Node的Pod,為Pod選擇一個Node。
- Kubelet:
負責維護容器的生命周期,同時負責Volume和網絡的管理。
- Kube proxy:
是Kubernetes的核心組件,部署在每個Node節點上,它是實現Kubernetes Service的通信與負載均衡機制的重要組件。
安裝環境說明
主機名稱 |
IP地址 |
安裝的軟件 |
代碼托管服務器 |
192.168.10.10 |
Gitlab-12.4.2 |
Harbor倉庫服務器 |
192.168.10.60 |
Harbor1.9.2 |
k8s-master |
192.168.10.90 |
kube-apiserver、kube-controller-manager、kube- scheduler、docker、etcd、calico,NFS |
k8s-node1 |
192.168.10.100 |
kubelet、kubeproxy、Docker18.06.1-ce |
k8s-node2 |
192.168.10.110 | kubelet、kubeproxy、Docker18.06.1-ce |
1、三台服務器都需要完成(192.168.10.90、192.168.10.100、192.168.10.110)
關閉防火牆和關閉SELinux
systemctl stop firewalld
systemctl disable firewalld setenforce 0 臨時關閉
vi /etc/sysconfig/selinux 永久關閉
改為SELINUX=disabled
安裝 docker 環境
//安裝必要的軟件包
yum install -y yum-utils device-mapper-persistent-data lvm2 //設置下載的鏡像倉庫
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum install -y docker-ce systemctl stop firewalld.service systemctl disable firewalld.service setenforce 0 systemctl start docker docker -v sudo systemctl enable docker //添加阿里雲鏡像下載地址
鏡像加速器: sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://31ycpc34.mirror.aliyuncs.com"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker vim /etc/sysctl.conf net.ipv4.ip_forward=1 #添加進去 sysctl -p #立即生效 service network restart systemctl restart docker
vim /etc/docker/daemon.json #harbor鏡像倉庫
"insecure-registries": ["192.168.10.60:85"],
systemctl restart docker
修改3台服務器的 hostname 及 hosts 文件
hostnamectl set-hostname k8s-master hostnamectl set-hostname k8s-node1 hostnamectl set-hostname k8s-node2
vim /etc/hosts 192.168.10.90 k8s-master 192.168.10.100 k8s-node1 192.168.10.110 k8s-node2
#互相 ping 一下,確保互通
ping k8s-node1
設置系統參數,加載 br_netfilter 模塊
modprobe br_netfilter
設置允許路由轉發,不對bridge的數據進行處理創建文件
cat >/etc/sysctl.d/k8s.conf <<'EOF' net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1 vm.swappiness = 0 EOF
執行文件
sysctl -p /etc/sysctl.d/k8s.conf
kube-proxy 開啟 ipvs 的前置條件
cat > /etc/sysconfig/modules/ipvs.modules <<EOF #!/bin/bash modprobe -- ip_vs modprobe -- ip_vs_rr modprobe -- ip_vs_wrr modprobe -- ip_vs_sh modprobe -- nf_conntrack_ipv4 EOF
#給執行權限 chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4
所有節關閉 swap
#臨時關閉 swapoff -a #永久關閉,注釋掉以下字段 vim /etc/fstab #/dev/mapper/cl-swap swap swap defaults 0 0
安裝 kubelet、kubeadm、kubectl
- kubeadm: 用來初始化集群的指令。
- kubelet: 在集群中的每個節點上用來啟動 pod 和 container 等。
- kubectl: 用來與集群通信的命令行工具。
清空yum緩存
yum clean all
設置 yum 安裝源
cat <<EOF > /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1 gpgcheck=0 repo_gpgcheck=0 gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
安裝 kubelet、kubeadm、kubectl
yum install -y kubelet-1.17.0 kubeadm-1.17.0 kubectl-1.17.0
kubelet 設置開機自啟動(注意:先不啟動,現在啟動的話會報錯)
systemctl enable kubelet
查看版本
kubelet --version
2、Master 節點(192.168.10.90)需要完成
(1)運行初始化命令(具備docker環境)
kubeadm init --kubernetes-version=1.17.0 \ --apiserver-advertise-address=192.168.10.90 \ --image-repository registry.aliyuncs.com/google_containers \ --service-cidr=10.1.0.0/16 \ --pod-network-cidr=10.244.0.0/16
注意:apiserver-advertise-address這個地址必須是master機器的IP
常見錯誤:
- 錯誤一:
[WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver
作為Docker cgroup驅動程序。,Kubernetes推薦的Docker驅動程序是“systemd”
- 解決方案:
修改Docker的配置: vim /etc/docker/daemon.json,加入
{ "exec-opts":["native.cgroupdriver=systemd"] }
然后重啟 Docker
- 錯誤二:
[ERROR NumCPU]: the number of available CPUs 1 is less than the required 2
- 解決方案:
修改虛擬機的CPU的個數,至少為2個
最后,會提示節點安裝的命令,必須記下來
kubeadm join 192.168.10.90:6443 --token 5ire0v.3q74rpx1xf55r2wk \ --discovery-token-ca-cert-hash sha256:9b466096f1389ef2175ef5c5a07291fbbbd925ae41cde0a2bc96f0fef02e8161
(2) 配置 kubectl 工具
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
(3)啟動 kubelet
systemctl restart kubelet
systemctl status kubele
(4)安裝 Calico
mkdir k8s cd k8s //不檢查憑證下載calico.yaml
wget --no-check-certificate https://docs.projectcalico.org/v3.10/getting-started/kubernetes/installation/hosted/kubernetes-datastore/calico-networking/1.7/calico.yaml //地址更改,方便從節點通信
sed -i 's/192.168.0.0/10.244.0.0/g' calico.yaml kubectl apply -f calico.yaml
(5)查看所有 Pod 的狀態,確保所有 Pod 都是 Running 狀態
kubectl get pod --all-namespaces -o wide
3、從節點需要完成(192.168.10.100、192.168.10.110)
(1)讓兩個從節點加入集群環境
兩個節點都執行之前 Master 節點產生的命令加入集群
kubeadm join 192.168.10.90:6443 --token 5ire0v.3q74rpx1xf55r2wk \ --discovery-token-ca-cert-hash sha256:9b466096f1389ef2175ef5c5a07291fbbbd925ae41cde0a2bc96f0fef02e8161
(2)啟動 kubelet
systemctl start kubelet
systemctl status kubele
(3)回到Master節點查看,如果Status全部為Ready,代表集群環境搭建成功
kubectl get nodes
kubectl 常用命令
kubectl get nodes #查看所有主從節點的狀態 kubectl get ns #獲取所有namespace資源 kubectl get pods -n {$nameSpace} #獲取指定namespace的pod kubectl describe pod的名稱 -n {$nameSpace} #查看某個pod的執行過程 kubectl logs --tail=1000 pod的名稱 | less #查看日志
kubectl create -f xxx.yml #通過配置文件創建一個集群資源對象
kubectl delete -f xxx.yml #通過配置文件刪除一個集群資源對象