• k8s最新版本1.24.3基于containerd的集群部署、打包和Jenkins流水线定义


    基于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/
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    创建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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    创建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/
    
    • 1
    • 2
    • 3

    修改config.toml文件,

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

    找到[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]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    找到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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    重启containerd服务:

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

    如果启动没有问题,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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

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

    leoly@service-tools:~$ ctr --help
    NAME:
       ctr - 
            __
      _____/ /______
     / ___/ __/ ___/
    / /__/ /_/ /
    \___/\__/_/
    
    containerd CLI
    
    
    USAGE:
       ctr [global options] command [command options] [arguments...]
    
    VERSION:
       v1.6.6
    ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    至此,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/
    
    • 1
    • 2
    • 3

    至此,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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    至此,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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    集群初始化成功后,根据初始化提示,将所有的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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    至此,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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    其次,需要在所有的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
    
    • 1
    • 2
    • 3

    最后,在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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    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"]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    构建之前,需要使用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
    
    • 1
    • 2
    • 3

    使用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
    
    • 1
    • 2

    至此,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 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    有了这两个脚本,就可以在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'
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
  • 相关阅读:
    【LeetCode热题100】--55.跳跃游戏
    ElasticSearch集群内存占用高?如何降低内存占用看这篇文章就够啦!(冻结索引)
    STM32 I2C学习
    [kruskal]Darnassus 2022杭电多校第8场 1007
    Go语言 结构体
    Fultter学习日志(2)-构建第一个flutter应用
    vue3 斗兽棋游戏
    给 zsh 自定义命令添加参数自动补全
    ansible的安装和相关操作
    SpringBoot SpringBoot 开发实用篇 1 热部署 1.2 自动启动热部署
  • 原文地址:https://blog.csdn.net/Leoly003/article/details/126135170