基于Containerd的k8s集群部署

新版本的k8s已经抛弃了docker,而改用CRI接口管理容器,并且建议使用containerd作为容器运行时,所以这里我们跟上潮流,使用containerd作为容器组建
k8s集群,并且使用jenkins完成CI/CD流程。

注意:本文档的服务器环境是:Ubuntu 20.04 LTS Jammy版本

k8s单master集群搭建

由于k8s集群用于测试环境,所以这里只需要使用Kubeadm搭建单master集群即可。如果要在正式环境上使用,需要搭建多master集群。集群规划如下:

hostnameIP描述
service-tools10.81.144.81Master(Control plane)
service-210.81.144.83node
service-310.81.144.84node
service-410.81.144.85node

注意,以下的软件都需要在所有集群节点上进行安装

1、安装Containerd

到containerd的github release页面上下载containerd安装包:https://github.com/containerd/containerd/releases

下载得到:
containerd-1.6.6-linux-amd64.tar.gz,解压,并将bin目录中的文件拷贝到/usr/local/bin中:

leoly@service-tools:~$ tar xf containerd-1.6.6-linux-amd64.tar.gz
leoly@service-tools:~$ ls -l bin/
total 138792
-rwxr-xr-x 1 root root 59592416 Jul 26 15:30 containerd
-rwxr-xr-x 1 root root  7389184 Jul 26 15:30 containerd-shim
-rwxr-xr-x 1 root root  9555968 Jul 26 15:30 containerd-shim-runc-v1
-rwxr-xr-x 1 root root  9580544 Jul 26 15:30 containerd-shim-runc-v2
-rwxr-xr-x 1 root root 25735456 Jul 26 15:30 containerd-stress
-rwxr-xr-x 1 root root 30265088 Jul 26 15:30 ctr
leoly@service-tools:~$ sudo cp -r bin/* /usr/local/bin/

创建containerd.service并设置为开机启动:

leoly@service-tools:~$ sudo vim /etc/systemd/system/containerd.service 
[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target local-fs.target
 
[Service]
ExecStartPre=-/sbin/modprobe overlay
# 这里需要修改为containerd的安装路径
ExecStart=/usr/local/bin/containerd
 
Type=notify
Delegate=yes
KillMode=process
Restart=always
RestartSec=5
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=infinity
# Comment TasksMax if your systemd version does not supports it.
# Only systemd 226 and above support this version.
TasksMax=infinity
OOMScoreAdjust=-999
 
[Install]
WantedBy=multi-user.target

leoly@service-tools:~$ sudo systemctl daemon-reload
leoly@service-tools:~$ sudo systemctl enable containerd --now

创建containerd的配置文件目录/etc/containerd,并生成默认的配置文件:

leoly@service-tools:~$ sudo mkdir /etc/containerd
leoly@service-tools:~$ sudo containerd config default > config.toml
leoly@service-tools:~$ sudo mv config.toml /etc/containerd/

修改config.toml文件,

leoly@service-tools:~$ sudo vim /etc/containerd/config.toml

找到[plugins."io.containerd.grpc.v1.cri".registry],配置config_path = "/etc/containerd/certs.d"
并删除[plugins."io.containerd.grpc.v1.cri".registry.mirrors]的下级配置,最后[plugins."io.containerd.grpc.v1.cri".registry]
项的配置如下:

    [plugins."io.containerd.grpc.v1.cri".registry]
      config_path = "/etc/containerd/certs.d"
      [plugins."io.containerd.grpc.v1.cri".registry.auths]
      [plugins."io.containerd.grpc.v1.cri".registry.configs]
      [plugins."io.containerd.grpc.v1.cri".registry.headers]
      [plugins."io.containerd.grpc.v1.cri".registry.mirrors]

找到sandbox_image = 配置,将配置改为:sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.7"
避免无法从国外镜像仓库拉取镜像。

创建certs.d文件夹,并在文件夹下增加两个仓库配置,一个是阿里云的主仓库dxc7f1d6.mirror.aliyuncs.com
另一个是后面即将使用Docker Registry在此k8s集群上搭建的私有仓库10.81.144.81:30000
我们事先约定好Docker Registry暴露的NodePort端口为:30000,并且不使用SSL的方式(即非HTTPS)搭建Docker Registry,
所以需要配置skip_verify = true

leoly@service-tools:~$ sudo mkdir /etc/containerd/certs.d
leoly@service-tools:~$ sudo mkdir /etc/containerd/certs.d/dxc7f1d6.mirror.aliyuncs.com
leoly@service-tools:~$ sudo vim /etc/containerd/certs.d/dxc7f1d6.mirror.aliyuncs.com/hosts.toml
server = "https://dxc7f1d6.mirror.aliyuncs.com"

leoly@service-tools:~$ sudo mkdir /etc/containerd/certs.d/10.81.144.81:30000
leoly@service-tools:~$ sudo vim /etc/containerd/certs.d/10.81.144.81:30000/hosts.toml
server = "http://10.81.144.81:30000"
[host."http://10.81.144.81:30000"]
  capabilities = ["pull","push","resolve"]
  skip_verify = true
  
leoly@service-tools:~$ tree /etc/containerd/
/etc/containerd/
├── certs.d
│   ├── 10.81.144.81:30000
│   │   └── hosts.toml
│   └── dxc7f1d6.mirror.aliyuncs.com
│       └── hosts.toml
└── config.toml

3 directories, 3 files

重启containerd服务:

leoly@service-tools:~$ sudo systemctl restart containerd
# 查看服务启动状态
leoly@service-tools:~$ sudo systemctl status containerd

如果启动没有问题,containerd安装配置完成。

2、安装runc

这里直接使用Ubuntu的包管理器进行安装:

leoly@service-tools:~$ sudo apt install runc
leoly@service-tools:~$ runc --version
runc version 1.1.0-0ubuntu1
spec: 1.0.2-dev
go: go1.17.3
libseccomp: 2.5.3

安装完成后,containerd就基本完成了。containerd的镜像管理工具是ctr

leoly@service-tools:~$ ctr --help
NAME:
   ctr - 
        __
  _____/ /______
 / ___/ __/ ___/
/ /__/ /_/ /
\___/\__/_/

containerd CLI


USAGE:
   ctr [global options] command [command options] [arguments...]

VERSION:
   v1.6.6
...

ctr管理工具与docker的镜像管理工具使用起来还是有很多区别的,为了更加方便的进行管理,我们安装一款与docker
命令在使用上差不多一致的管理工具:nerdctl

从github的release页面中下载最新版本:https://github.com/containerd/nerdctl/releases

得到nerdctl-0.22.0-linux-amd64.tar.gz,解压后,将nerdctl文件拷贝到/usr/local/containerd/bin下:

leoly@service-tools:~$ tar xvf nerdctl-0.22.0-linux-amd64.tar.gz 
nerdctl
containerd-rootless-setuptool.sh
containerd-rootless.sh

# 这里我们不管那两个sh文件,因为不需要使用非root用户。
leoly@service-tools:~$ sudo mkdir /usr/local/containerd
leoly@service-tools:~$ sudo mkdir /usr/local/containerd/bin
leoly@service-tools:~$ sudo cp nerdctl /usr/local/containerd/bin
# 做一个软链接方便使用nerdctl工具。
leoly@service-tools:~$ sudo ln -s /usr/local/containerd/bin/nerdctl /usr/local/bin/nerdctl
leoly@service-tools:~$ sudo nerdctl version
Client:
 Version:       v0.22.0
 OS/Arch:       linux/amd64
 Git commit:    8e278e2aa61a89d4e50d1a534217f264bd1a5ddf
 buildctl:
  Version:      v0.10.3
  GitCommit:    c8d25d9a103b70dc300a4fd55e7e576472284e31

Server:
 containerd:
  Version:      v1.6.6
  GitCommit:    10c12954828e7c7c9b6e0ea9b0c02b01407d3ae1
 runc:
  Version:      1.1.0-0ubuntu1

nerdctl工具的使用与docker命令基本一致,到此,nerdctl工具安装完成。

containerd中并未包含打包(build)工具,需要另外安装buildkit工具进行打包:

从github上的buildkit release页面下载buildkit:https://github.com/moby/buildkit/releases

解压后进行安装:

leoly@service-tools:~$ sudo mkdir /usr/local/buildkit
leoly@service-tools:~$ tar zxvf buildkit-v0.10.3.linux-amd64.tar.gz 
leoly@service-tools:~$ sudo mv bin/ /usr/local/buildkit/
leoly@service-tools:~$ sudo ln -s /usr/local/buildkit/bin/* /usr/bin/

# 创建buildkitd.service
leoly@service-tools:~$ vim /etc/systemd/system/buildkitd.service
[Unit]
Description=BuildKit
Documentation=https://github.com/moby/buildkit
[Service]
ExecStart=/usr/local/buildkit/bin/buildkitd --oci-worker=false --containerd-worker=true
[Install]
WantedBy=multi-user.target

# 启动buildkitd,并设置为开机启动
leoly@service-tools:~$ sudo systemctl daemon-reload
leoly@service-tools:~$ sudo systemctl enable buildkitd.service --now

# 配置buildkit,结合即将部署的Docker Registry使用
leoly@service-tools:~$ sudo mkdir /etc/buildkit
leoly@service-tools:~$ sudo vim /etc/buildkit/buildkitd.toml
[registry."10.81.144.81:30000"]
  http = true
  insecure = true

至此,buildkit安装完成,由于buildkit的命令比较复杂,所以使用buildkit与nerdctl工具配合更方便的打包。

3、为containerd安装cni网络插件

CNI:Container network interface容器网络接口,为容器分配ip地址网卡等。

从github的release页面下载CNI插件:https://github.com/containernetworking/plugins/releases

得到cni-plugins-linux-amd64-v1.1.1.tgz,解压后拷贝到/opt/cni/bin目录下。这里需要注意的是,
必需将CNI插件安装到/opt/cni/bin目录,因为containerd在使用CNI时默认会检查这个目录:

leoly@service-tools:~$ sudo mkdir /opt/cni
leoly@service-tools:~$ sudo mkdir /opt/cni/bin
leoly@service-tools:~$ sudo tar xf cni-plugins-linux-amd64-v1.1.1.tgz -C /opt/cni/bin/

至此,CNI插件安装完成。

4、使用kubeadm安装k8s集群

添加谷歌的apt key,配置k8s软件源:

leoly@service-tools:~$ curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add -
leoly@service-tools:~$ sudo vim /etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main

leoly@service-tools:~$ sudo apt update
# 查看k8s软件源中的版本
leoly@service-tools:~$ sudo apt-cache madison kubeadm
   kubeadm |  1.24.3-00 | https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages
   kubeadm |  1.24.2-00 | https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages
   kubeadm |  1.24.1-00 | https://mirrors.aliyun.com/kubernetes/apt kubernetes-xenial/main amd64 Packages
# 安装kubeadm、kubeadm和kubectl
leoly@service-tools:~$ sudo apt install kubeadm kubectl kubelet
# 查看kubelet需要安装的k8s镜像
leoly@service-tools:~$ kubeadm config images list
k8s.gcr.io/kube-apiserver:v1.24.3
k8s.gcr.io/kube-controller-manager:v1.24.3
k8s.gcr.io/kube-scheduler:v1.24.3
k8s.gcr.io/kube-proxy:v1.24.3
k8s.gcr.io/pause:3.7
k8s.gcr.io/etcd:3.5.3-0
k8s.gcr.io/coredns/coredns:v1.8.6

至此,kubeadm、kubectl、kubelet安装完成。

下面开始进行k8s的环境准备:

# 1、设置hosts,集群中的每个节点都要设置各自的hostname
leoly@service-tools:~$ sudo hostnamectl set-hostname service-tools
# 2、集群中的每个节点都要配置/etc/hosts
leoly@service-tools:~$ sudo vim /etc/hosts
127.0.0.1 localhost.localdomain localhost
10.81.144.81 service-tools
10.81.144.83 service-2
10.81.144.84 service-3
10.81.144.85 service-4

# 3、安装ipvsadm
leoly@service-tools:~$ sudo apt install ipvsadm
# 4、关闭防火墙
leoly@service-tools:~$ udo ufw disable
# 5、关闭swap
leoly@service-tools:~$ sudo swapoff -a
leoly@service-tools:~$ sudo vim /etc/fstab
#/swap.img      none    swap    sw      0       0
# 6、网络配置
leoly@service-tools:~$ sudo vim /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1

在master节点上进行集群初始化:

# 1、创建集群初始化配置
leoly@service-tools:~$ vim k8s.yaml
apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
kind: InitConfiguration
localAPIEndpoint:
  # 这里要修改为master节点的IP地址
  advertiseAddress: 10.81.144.81
  bindPort: 6443
nodeRegistration:
  # 这里要改成containerd的运行地址,一般情况下是下面的地址
  criSocket: unix:///var/run/containerd/containerd.sock
  imagePullPolicy: IfNotPresent
  # master的hostname
  name: service-tools
  taints: null
---
apiServer:
  timeoutForControlPlane: 4m0s
# 这里要修改为master节点的IP地址  
controlPlaneEndpoint: 10.81.144.81:6443
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
etcd:
  local:
    # ETCD的数据存储目录,如果发现集群始终无法初始化,可以试着清空一下这个目录,或者将目录指向新的地址
    dataDir: /data/k8s/etcd/
# 这里要修改为阿里云镜像地址,避免被墙    
imageRepository: registry.aliyuncs.com/google_containers      
kind: ClusterConfiguration
# 这里是初始化的集群版本,一般与Kubelet一致
kubernetesVersion: 1.24.3
networking:
  dnsDomain: cluster.local
  # 这里是容器内部网段配置
  serviceSubnet: 10.96.0.0/12
scheduler: {}
---
# 这个配置让k8s使用ipvs功能
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs
---
# 这个配置让k8s使用systemd
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd

# 2、使用以上的配置进行集群初始化
leoly@service-tools:~$ sudo kubeadm init --config k8s.yaml --upload-certs
# 3、初始化成功后,配置kubectl可以用于非root用户
leoly@service-tools:~$ mkdir -p $HOME/.kube
leoly@service-tools:~$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
leoly@service-tools:~$ sudo chown $(id -u):$(id -g) $HOME/.kube/config

集群初始化成功后,根据初始化提示,将所有的node节点加入集群:

leoly@service-2:~$ sudo kubeadm join 10.81.144.81:6443 --token ...
leoly@service-3:~$ sudo kubeadm join 10.81.144.81:6443 --token ...
leoly@service-4:~$ sudo kubeadm join 10.81.144.81:6443 --token ...

leoly@service-tools:~$ kubectl get nodes
NAME            STATUS   ROLES           AGE     VERSION
service-2       Ready    <none>          4d22h   v1.24.3
service-3       Ready    <none>          4d22h   v1.24.3
service-4       Ready    <none>          4d22h   v1.24.3
service-tools   Ready    control-plane   4d23h   v1.24.3

# 如果加入集群的指令找不到了,可以打印出来
leoly@service-tools:~$ kubeadm token create --print-join-command
5、为集群安装calico网络插件

在master节点上进行calico网络插件yaml文件配置和使用:

# 1、下载calico.yaml文件
leoly@service-tools:~$ curl -o calico.yaml https://docs.projectcalico.org/manifests/calico.yaml
# 2、修改calico.yaml文件,查找CALICO_IPV4POOL_CIDR,修改value值为k8s.yaml中定义的:serviceSubnet: 10.96.0.0/12
# 并且新增一项配置IP_AUTODETECTION_METHOD,value值为服务器网卡的名称,可以使用ifconfig获取
leoly@service-tools:~$ vim calico.yaml
...
            - name: CALICO_IPV4POOL_CIDR
              value: "10.96.0.0/12"
...
            - name: IP_AUTODETECTION_METHOD
              value: "interface=ens160"
...

# 3、应用calico
leoly@service-tools:~$ kubectl create -f calico.yaml
# 4、查看集群中的pods
leoly@service-tools:~$ kubectl get pods -n kube-system
NAME                                       READY   STATUS    RESTARTS        AGE
calico-kube-controllers-555bc4b957-vmq28   1/1     Running   4 (4d22h ago)   4d23h
calico-node-7vfc6                          1/1     Running   0               4d23h
calico-node-gn8k9                          1/1     Running   0               4d23h
calico-node-hdc5s                          1/1     Running   0               4d23h
calico-node-xwpvv                          1/1     Running   0               4d23h
coredns-74586cf9b6-c4czl                   1/1     Running   0               4d23h
coredns-74586cf9b6-g226m                   1/1     Running   0               4d23h
etcd-service-tools                         1/1     Running   1               4d23h
kube-apiserver-service-tools               1/1     Running   1 (4d22h ago)   4d23h
kube-controller-manager-service-tools      1/1     Running   3 (4d22h ago)   4d23h
kube-proxy-b766s                           1/1     Running   0               4d23h
kube-proxy-fc8dp                           1/1     Running   0               4d23h
kube-proxy-nbll2                           1/1     Running   0               4d23h
kube-proxy-v7whb                           1/1     Running   0               4d23h
kube-scheduler-service-tools               1/1     Running   8 (4d22h ago)   4d23h

# 5、如果发现pods启动不成功,使用以下命令查看
leoly@service-tools:~$ kubectl describe pods calico-node-7vfc6 -n kube-system

至此,k8s集群环境安装完成。

容器镜像构建

容器镜像构建需要使用镜像仓库,这里我们使用Docker Registry作为镜像仓库。使用刚搭建的k8s集群部署Docker Registry,由于仓库需要一个
固定的存储位置,所以需要在k8s中创建基于nfs的StorageClass,为pods提供一个固定的存储位置。

1、搭建StorageClass

首先,需要在master节点的宿主机上搭建NFS共享服务:

# 安装并启动NFS服务
leoly@service-tools:~$ sudo apt install nfs-kernel-server
leoly@service-tools:~$ sudo systemctl enable nfs-kernel-server --now
# 增加需要共享的目录,并配置共享
leoly@service-tools:~$ sudo mkdir nfs-data
leoly@service-tools:~$ sudo vim /etc/exports
/ext_data/nfs-data *(rw,async,no_subtree_check,no_root_squash)

leoly@service-tools:~$ sudo exportfs -a

其次,需要在所有的node节点上安装nfs客户端:

leoly@service-2:~$ sudo apt install nfs-common
leoly@service-3:~$ sudo apt install nfs-common
leoly@service-4:~$ sudo apt install nfs-common

最后,在master节点上创建provisioner和storageclass:

# 创建一个命名空间:kube-storage
leoly@service-tools:~$ kubectl create ns kube-storage
leoly@service-tools:~$ kubectl create -f nfs-rbac.yaml
leoly@service-tools:~$ kubectl create -f nfs-provisioner.yaml
leoly@service-tools:~$ kubectl create -f nfs-storage-class.yaml

# 查看nfs-provisioner运行情况:
leoly@service-tools:~$ kubectl get pods -n kube-storage
NAME                                     READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-b78b56b67-xp6sz   1/1     Running   0          4d7h

# 查看nfs-storage-class运行情况:
leoly@service-tools:~$ kubectl get sc -n kube-storage
NAME                  PROVISIONER        RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
managed-nfs-storage   test-nfs-storage   Retain          Immediate           false                  4d23h
2、搭建Docker Registry

Docker Registry仓库需要挂载两个目录:/var/lib/registry是存放镜像数据的,/etc/docker/registry是存放配置文件(config.yml)的。
由于是内部使用的镜像仓库,我们不使用HTTPS和AUTH功能来搭建Docker Registry,在config.yml中只需要配置镜像可删除即可:

注:所有配置文件在docker-registry目录中可以找到

leoly@service-tools:~$ vim config.yml
# 创建两个PVC,一个用于存储数据,一个用于存储config.yml配置    
leoly@service-tools:~$ vim registry-config-pvc.yaml
leoly@service-tools:~$ vim registry-storage-pvc.yaml
# 创建docker registry的部署文件    
leoly@service-tools:~$ vim docker-registry.yaml
# 创建docker registry UI的部署文件    
leoly@service-tools:~$ vim docker-registry-ui.yaml
# 部署到k8s集群中
leoly@service-tools:~$ kubectl create -f registry-config-pvc.yaml
leoly@service-tools:~$ kubectl create -f registry-storage-pvc.yaml
leoly@service-tools:~$ kubectl create -f docker-registry.yaml
leoly@service-tools:~$ kubectl create -f docker-registry-ui.yaml
3、构建Oracle JDK 11基础镜像包

基于Ubuntu jammy基础镜像,加入Oracle JRE11,打包成JRE基础镜像,构建的Dockerfile内容:

FROM ubuntu:jammy-20220531
LABEL maintainer="softwaredevelop@busuanzi.com"
ADD basejre /home/basejre

RUN echo "Asia/Shanghai" > /etc/timezone
RUN echo "export LC_ALL=C.utf8"  >>  /etc/profile
ENV LANG C.utf8
WORKDIR /home/
ENV JAVA_HOME=/home/basejre
ENV PATH=$PATH:$JAVA_HOME/bin
CMD ["java","-version"]

构建之前,需要使用oracle jdk 11的jlink工具对JDK进行精简,生成精简JRE放在basejre目录:

leoly@service-tools:~$ jlink --no-header-files --no-man-pages --add-modules \
java.base,java.logging,java.desktop,java.naming,java.management,java.management.rmi,java.security.jgss,java.instrument,java.prefs,java.xml,java.rmi,java.scripting,java.transaction.xa,java.sql,java.sql.rowset,jdk.unsupported \
--output basejre

使用Dockerfile进行镜像打包,并推送到Docker Registry:

leoly@service-tools:~$ sudo nerdctl build . -t 10.81.144.81:30000/busuanzi/jre:latest
leoly@service-tools:~$ sudo nerdctl push 10.81.144.81:30000/busuanzi/jre:latest

至此,JRE基础镜像包打包并推送到Docker Registry完成,可以在Docker Registry UI页面上看到。

jenkins自动化

jenkins也可以部署到k8s中,这里我们已经在宿主机上部署,就不再部署了。

jenkins自动化的流程其实就是从gitlab下载代码,使用maven构建,再使用buildkit和nerdctl打包,推送到Docker Registry仓库中,
最后生成k8s需要的yaml文件,在master节点上进行部署。
由于公司使用了VPN连接,下载代码时需要挂VPN,所以我们使用openconnect连接VPN后再下载代码,openconnect配置:

# 安装openconnect
leoly@service-tools:~$ sudo apt install openconnect
# 创建开启VPN的SHELL脚本
leoly@service-tools:~$ vim startVPN.sh
# 先输入密码,便于下面的sudo不再输入
echo "123456789" | sudo -S ls
# 先输入密码,便于下面的sudo不再输入
echo "密码" | sudo openconnect --pid-file /data/openconnect/openconnect.pid  --protocol=fortinet -u 用户名 --passwd-on-stdin --background --servercert pin-sha256:f13ahqcC32xgmlJ6gOAOEW9Z1ECM5qB25KiiMCnhFU4= 服务器IP:端口
echo 'VPN started!'

# 创建关闭VPN的SHELL脚本
leoly@service-tools:~$ vim stopVPN.sh 
pid=`cat /data/openconnect/openconnect.pid`
echo $pid
echo "123456789" | sudo -S ls
sudo kill -15 $pid
echo 'VPN stoped!'

leoly@service-tools:~$ sudo chmod +x startVPN.sh stopVPN.sh 

有了这两个脚本,就可以在jenkins上的pipeline脚本中开启和关闭VPN连接。

在jenkins中增加插件: Extended Choice Parameter Plug-In,增加一个流水线项目,设置项目为“参数化构建项目”,
使用Extended Choice Parameter Plug-In插件进行参数配置,参数名称为“module_name”,pipeline脚本如下:

pipeline {
    agent any
    environment {
        // 根据时间生成构建版本号,作为镜像的tag
       build_version = sh(script: "echo `date '+%Y%m%d%H%M%S'`", returnStdout: true).trim()
    }
    stages{
        stage('Preparation') {
            steps {
                // 开启VPN
                sh 'sh /data/openconnect/startVPN.sh'
                // 从gitlab拉代码
                git branch:'master',credentialsId: 'GitLibAccess', url:'http://10.70.12.12/gitlab/aiup/aiup-backend.git'
            }
        }
        stage('Package') {
            steps {
                // 使用maven构建
                sh 'echo "123456789" | sudo -S /data/apache-maven-3.8.6/bin/mvn -T 4 -Dmaven.test.skip=true clean package'
            }
        }
        stage('Build-Image') {
            steps {
                echo "Image version: ${build_version}"
                script {
                    // 从参数化构建中拿到module_name,循环所选的模块
                    for (module in module_name.tokenize(',')) {
                        // 使用nerdctl配置buildkit构建镜像包,镜像名称中加入Docker Registry地址:10.81.144.81:30000,tag为build_version
                        sh 'echo "123456789" | sudo -S nerdctl build ${WORKSPACE}/' + module + ' -t 10.81.144.81:30000/busuanzi/'+module+':${build_version}'
                        // 推送镜像到Docker Registry:10.81.144.81:30000
                        sh 'echo "123456789" | sudo -S nerdctl push 10.81.144.81:30000/busuanzi/'+module+':${build_version}'
                    }
                }
            }
        }
        stage('Deploy Service') {
            steps {
                // 创建一个临时目录,用于临时存放k8s的yaml文件
                sh 'mkdir k8stmp'
                script {
                    for (module in module_name.tokenize(',')) {
                        // 从yaml文件模板中替换tag版本,从latest替换为build_version
                        sh 'sed -e "s/latest/${build_version}/g" ' + module + '/k8s.' + module + '.yaml > k8stmp/' + module + '.yaml'
                        // 组织k8s部署yaml的命令
                        def command = 'kubectl apply -f ${WORKSPACE}/k8stmp/' + module + '.yaml'
                        echo command
                        // 切换到leoly用户部署yaml文件
                        sh 'ssh leoly@10.81.144.81 "' + command + '"'
                    }
                }
                // 删除临时目录
                sh 'rm -rf k8stmp'
            }
        }
    }
    post {
        always {
          // 关闭VPN
          sh 'sh /data/openconnect/stopVPN.sh'
        }
    }
}

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐