jenkins+gitlab+harbor实现k8s CI/CD

jenkins+gitlab+harbor实现k8s CI/CD

主机 说明
2.2.2.15 jenkins和gitlab(虚拟机运行)、harbor(docker运行)、k8s控制节点
2.2.2.25 k8s node节点
2.2.2.35 k8s node节点

版本说明:

docker:20.10.22
containerd:v1.6.13
k8s:v1.24.13
jenkins:2.401.2
gitlab:16.1.2

安装:

1)安装gitlab

yum install -y https://packages.gitlab.com/gitlab/gitlab-ce/packages/el/8/gitlab-ce-16.1.2-ce.0.el8.x86_64.rpm

sed -ri 's#^(external_url).*#\1 "http://git.hj.com"#' /etc/gitlab/gitlab.rb
gitlab-ctl reconfigure
gitlab-ctl restart
echo 2.2.2.15 git.hj.com >> /etc/hosts

#由于我的环境是gitlab+jenkins在同一台主机,在gitlab中直接导入本地ssh公钥,jenkins即可访问
cat ~/.ssh/id_rsa.pub

说明:

  • 访问http://git.hj.com,登录页面后,添加一个ssh公钥,将上面输出的公钥加入,方便jenkins可以克隆代码
  • 创建群组和项目

image-20230713172444339

2)生成测试数据,用于模拟CI/CD流程

yum install -y git
mkdir /opt/app ; cd  /opt/app
git init

#格式:http://git.hj.com/群组/项目
git remote add origin http://git.hj.com/app1/ngx.git
git checkout -cb main
mkdir -p {scripts,yaml}
#生成dockerfile
cat > Dockerfile <<eof
from nginx:stable-alpine

WORKDIR /usr/share/nginx/html/
add . ./
expose 80
STOPSIGNAL SIGTERM
CMD ["/usr/sbin/nginx","-g","daemon off;"]
eof
#生成index.html文件
cat > index.html <<eof
<h1>v1</h1>
eof
#生成容器构建脚本
cat > scripts/build.sh <<eof
#!/bin/bash

CODE_TAG=\`git tag --sort=v:refname|tail -n1\`
sudo docker build -q --rm -t 2.2.2.15:8443/app/ngx-app:\$CODE_TAG .
sudo docker push -q 2.2.2.15:8443/app/ngx-app:\$CODE_TAG
sudo docker rmi -f 2.2.2.15:8443/app/ngx-app:\$CODE_TAG > /dev/null
eof
#生成k8s控制节点执行部署命令脚本
cat > scripts/remote_node_exec.sh <<eof
#!/bin/bash
set -e

#变量只在远程k8s控制主机有效
cd /code/app/ngx-app-yml

#部署
kubectl get svc |grep -q ngx-svc || kubectl apply -f ngx-svc.yml
NEW_FILE=\`ls -t ngx-app-*.yml |head -n1\`
#CODE_TAG=\`awk -F':' '/2.2.2.15:8443\/app\/ngx-app/{print \$4}' \$NEW_FILE\`
#kubectl set image deploy ngx-dep ngx-app=2.2.2.15:8443/app/ngx-app:\$CODE_TAG
ln -sfT \$NEW_FILE ngx-app.yml
kubectl apply -f ngx-app.yml

#清除旧清单
FILE_NUM=\`ls -t ngx-app-*.yml |wc -l\`
MAX_NUM=5
if [ \$FILE_NUM -ge \$MAX_NUM ] ;then
    CLEAN_FILES=\`ls -t ngx-app-*.yml |awk -v num=\$MAX_NUM 'NR>num'\`
    for file in \$CLEAN_FILES ;do
        unlink \$file
    done
fi
eof
#生成部署脚本
cat > scripts/dep.sh <<eof
#!/bin/bash
set -e

CODE_TAG=\`git tag --sort=v:refname|tail -n1\`

update_conf(){
	sed -ri "s#(.*ngx-app:).*#\1\$CODE_TAG#" yaml/ngx-app.yml
}

deploy_pod(){
	ssh root@\$1 "[ -d /code/app/ngx-app-yml ] || install -d /code/app/ngx-app-yml -m 777"
	rsync yaml/ngx-svc.yml root@\$1:/code/app/ngx-app-yml/
	rsync yaml/ngx-app.yml root@\$1:/code/app/ngx-app-yml/ngx-app-\$CODE_TAG.yml
	ssh root@\$1 < scripts/remote_node_exec.sh
}

update_conf
deploy_pod \$1
eof
#生成ngx-svc配置清单
cat > yaml/ngx-svc.yml <<eof
apiVersion: v1
kind: Service
metadata:
  name: ngx-svc
spec:
  selector:
    app: ngx-app
  type: NodePort
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 31080
eof
#生成ngx-app配置清单
cat > yaml/ngx-app.yml <<eof
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ngx-dep
spec:
  replicas: 2
  selector:
    matchLabels:
      app: ngx-app
  template:
    metadata:
      labels:
        app: ngx-app
    spec:
      containers:
      - image: 2.2.2.15:8443/app/ngx-app:1.1.11
        imagePullPolicy: IfNotPresent
        name: ngx-app
        ports:
        - containerPort: 80
      imagePullSecrets:
      - name: harbor-http-secret
      - name: harbor-https-secret
eof
#生成容器构建忽略配置
cat > .dockerignore <<eof
scripts
yaml
*.yml
*.md
eof

提交代码到gitlab,并创建一个标签

#全部测试文件生成完成后,提交到gitlab
git push -uf origin main

image-20230713201441095

3)安装jenkins

yum install -y https://mirrors.ustc.edu.cn/jenkins/redhat-stable/jenkins-2.401.2-1.1.noarch.rpm

#安装完后建议改一下启动用户,不改的话后续配置麻烦一点,端口可改可不改,我的端口冲突了所以需要改
sed -ri -e 's#^(User).*#\1=root#' \
-e 's#^(Group).*#\1=root#' \
-e 's#^(.*="JENKINS_PORT).*#\1=8081"#' \
/usr/lib/systemd/system/jenkins.service

#修改插件安装地址,使用国内镜像源
sed -i -e '/url/d' \
-e '/<\/site>/i\    <url>https://mirrors.ustc.edu.cn/jenkins/updates/update-center.json</url>' \
/var/lib/jenkins/hudson.model.UpdateCenter.xml

systemctl daemon-reload
systemctl enable --now jenkins.service

#查看随机密码后,访问http://ip:8081 登录,直接安装插件即可
cat /var/lib/jenkins/secrets/initialAdminPassword

4)jenkins安装插件

#需安装插件
gitlab
git parameter

image-20230713170139176

image-20230713170333446

5)安装harbor

生成harbor证书
必须启用https,否则containerd连接会报错

#生成证书创建脚本,创建harbor证书
cat > cert.sh <<-eof
#!/bin/bash
set -eo pipefail
 
RED='\E[31;2m'
GREEN='\E[32;1m'
BLUE='\E[34;1m'
END='\E[0m'

ca_subj='/O=ca-hj/CN=ca.hj.com'
subj='/C=CN/ST=HB/L=WH/O=dev/CN=harbor.hj.com'
serial=34
days=3600
cert_file=harbor.hj.com
 
create_ca() {
  if [ -f ca.key -a -f ca.crt ] ;then
    echo -e "\$GREEN 已有ca证书 \$END"
  else
    (umask 066; openssl genrsa -out ca.key 4096)
    openssl req -new -x509 -key ca.key -out ca.crt -nodes -days \$days -subj \$ca_subj
  fi
}

create_1_cert() {
  (umask 066; openssl genrsa -out \${cert_file}.key 4096)
  openssl req -new -key \${cert_file}.key -out \${cert_file}.csr -nodes -days \$days -subj \$subj
  openssl x509 -req -in \${cert_file}.csr -CA ca.crt -CAkey ca.key -set_serial \$serial -days \$days -out \${cert_file}.crt
  cat \${cert_file}.crt ca.crt > \${cert_file}.pem 
  rm -rf ./*.csr
}

echo -e "\$BLUE 创建证书 \$cert_file \$END"
create_ca
create_1_cert
eof

mkdir -p /data/certs/
cd /data/certs/
bash cert.sh

安装harbor

#先装docker-compose
wget https://github.com/docker/compose/releases/download/1.27.4/docker-compose-Linux-x86_64 -O /bin/docker-compose
chmod +x /bin/docker-compose

wget https://github.com/goharbor/harbor/releases/download/v2.8.2/harbor-offline-installer-v2.8.2.tgz
tar xf harbor-offline-installer-v2.8.2.tgz
cd harbor/
mv harbor.yml.tmpl harbor.yml

#修改haorbor配置
sed -ri -e 's#^(hostname):.*#\1:harbor.hj.com#' \
-e 's#(.*port:).*"#\1 81#' \
-e 's#(.*port:).*#\1 8443#' \
-e 's#^(harbor_admin_password:).*#\1 123456#'
-e 's#(.*certificate:).*#\1 /data/certs/harbor.hj.com.pem#'
-e 's#(.*private_key:).*#\1 /data/certs/harbor.hj.com.key#'
harbor.yml
./install.sh

访问harbor,创建一个项目

image-20230713184802191

6)docker测试登录

jenkins使用docker构建镜像的,如果只是用contianerd,没有装docker,可以下载containerd的工具,功能与docker命令行一样: nerdctl
工具安装可参考前面ingress安装部分

docker login -u admin -p 123456 2.2.2.15:8443

7)jenkins配置gitlab发布

#查看私钥,在gitlab添加私钥,这个私钥是与在gitlab中添加的必须是同一对,jenkins需要用这个私钥去解gitlab中添加的公钥
cat ~/.ssh/id_rsa
根据图片中路径,找到添加选项,添加访问gitlab的ssh凭证

image-20230713185706324
image-20230713190157424

创建新构建任务

image-20230713195249215

构建参数选: git参数,点击高级部分

image-20230713200101975

image-20230713200252779

新建第二个构建参数,选择: 选项参数

用于配置k8s控制节点,也就是可以执行Kubectl的部署节点

image-20230713200513859

源码管理: 添加git仓库,指定访问gitlab的凭证,其他默认即可

image-20230713200646689

最后在构建步骤: 选择执行shell

image-20230713201041654

8)containerd配置信任harbor

所有containerd节点都要配置

sed -i -e '/\[plugins."io.containerd.grpc.v1.cri".registry.configs\]$/a\        [plugins."io.containerd.grpc.v1.cri".registry.configs."2.2.2.15:81".tls]\n          insecure_skip_verify = true\n        [plugins."io.containerd.grpc.v1.cri".registry.configs."2.2.2.15:8443".tls]\n          insecure_skip_verify = true' \
-e '/\[plugins."io.containerd.grpc.v1.cri".registry.mirrors\]/a\        [plugins."io.containerd.grpc.v1.cri".registry.mirrors."2.2.2.15:81"]\n          endpoint = ["http://2.2.2.15:81"]\n        [plugins."io.containerd.grpc.v1.cri".registry.configs."2.2.2.15:8443".tls]\n          insecure_skip_verify = true' \
/etc/containerd/config.toml

systemctl restart containerd.service

containerd最终是这样的配置
image-20230713205154708

9)k8s集群创建登录harbor的secret

为containerd的oci创建登录harbor的账号

kubectl create secret docker-registry harbor-http-secret --docker-server=2.2.2.15:81 --docker-username=admin --docker-password=123456
kubectl create secret docker-registry harbor-https-secret --docker-server=2.2.2.15:8443 --docker-username=admin --docker-password=123456

10)测试发布

jinkens配置完成后,测试发布一下

image-20230713201243804

image-20230713201659637

可以看到,新版本镜像构建成功,且推送到harbor.deploy控制器也更新成功
image-20230713202749708
image-20230713202914709

浏览器访问成功
image-20230713202953571

posted @ 2023-11-06 17:53  suyanhj  阅读(79)  评论(0编辑  收藏  举报