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可以克隆代码
- 创建群组和项目
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
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
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,创建一个项目
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凭证
创建新构建任务
构建参数选: git参数,点击高级部分
新建第二个构建参数,选择: 选项参数
用于配置k8s控制节点,也就是可以执行Kubectl的部署节点
源码管理: 添加git仓库,指定访问gitlab的凭证,其他默认即可
最后在构建步骤: 选择执行shell
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最终是这样的配置
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配置完成后,测试发布一下
可以看到,新版本镜像构建成功,且推送到harbor.deploy控制器也更新成功
浏览器访问成功