一.简介
gitlab创建项目,
源码(包含dockerfile,研发写或运维写)上传到gitlab
创建jenkins任务(拉取源代码、maven打包、执行shell分发部署运行容器)
二.jenkins构建docker版nginxWebUI示例
1.gitlab新建项目
2.gitee上下载一个nginxWebUI(包含dockerfile) 解压后Open Git Bash here 上传到gitlab
#查看有无远程仓库地址 这里无 不需要删除或重命名
git remote -v
#全局配置
git config --global "Administrator"
git config --global user.email "admin@example.com"
#初始化目录
git init
#添加缓存区并起交到仓库
git add .
git commit -m "V1.0"
#添加远程仓库地址
git remote add origin git@192.168.77.147:root/docker-nginxwebui.git
#打标签
git tag -a v1.0 -m "v1.0"
#推送到远程仓库
git push -u origin --all
git push -u origin --tags
3.dockerfile alpine:3.20海外镜像获取,这里提前传pull到jenkins上了
FROM alpine:3.20
ENV LANG=zh_CN.UTF-8 \
TZ=Asia/Shanghai \
PS1="\u@\h:\w \$ "
# RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
RUN apk add --update --no-cache \
nginx \
nginx-mod-stream \
nginx-mod-http-headers-more \
nginx-mod-http-lua \
nginx-mod-http-brotli \
nginx-mod-rtmp \
openjdk8-jre \
net-tools \
curl \
wget \
ttf-dejavu \
fontconfig \
tzdata \
logrotate \
tini \
acme.sh \
&& fc-cache -f -v \
&& ln -sf /usr/share/zoneinfo/${TZ} /etc/localtime \
&& echo "${TZ}" > /etc/timezone \
&& rm -rf /var/cache/apk/* /tmp/*
COPY target/nginxWebUI-*.jar /home/nginxWebUI.jar
COPY /usr/local/bin/
RUN ["chmod", "+x", "/usr/local/bin/"]
VOLUME ["/home/nginxWebUI"]
ENTRYPOINT ["tini", ""]
4.jenkins创建maven任务 (maven和docker已安装在jenkins)
General---丢弃旧的构建(可选)
General---参数化构建过程---Git参数
填写Git参数---自定义名称---自定义描述---参数类型(标签)---默认值${tag} 需要指定版本
Git参数---高级---排序方式---已选值
源码管理---Git---添加源码项目地址和认证信息(之前已配置)
Pre Steps---Goals and options---填写clean package maven构建war包
Post Steps---Run only if build succeeds---执行shell命令
执行shell的命令
#变量设置
web_server_list="192.168.77.142 192.168.77.144"
#判断tag是否为默认origin/master,origin/master作为版本容易产生歧义
if [ "$tag" = "origin/master" ]
then
tag=latest
fi
#构建镜像 镜像名字按照harbor的格式
docker build -t /nginxwebui/nginxwebui:${tag} .
#推送到私有仓库
#登录harbor
docker login -ualibaby -pxxxxxxx
#推送到harbor
docker push /nginxwebui/nginxwebui:${tag}
#部署到web服务器
for ip in ${web_server_list}
do
ssh root@${ip} "
#登录harbot
docker login -ualibaby -pxxxxxxx
#运行容器
docker run -itd --name nginxwebui \
-v /home/nginxWebUI:/home/nginxWebUI \
-p 8888:8080 \
--restart=always \
/nginxwebui/nginxwebui:${tag}"
done
说明 :前期准备
#jenkins到web服务器的ssh免密认证已配置好(通过ssh命令的方式,在web服务器上执行命令需要)
##jenkins上执行
ssh-keygen
ssh-copy-id root@192.168.77.142
ssh-copy-id root@192.168.77.144
#镜像仓库harbor已单独安装在其他服务器上,客户端pull/push都要先登录
#jenkins作为harbor的客户端,hosts解析和https证书已在jenkins上配置完成(push/pull镜像需要)
#harbor的域名 用户名和密码-ualibaby -pxxxxxxx
#jenkins和web服务器需要配置
echo "192.168.77.133 " >>/etc/hosts
mkdir -p /etc/docker/certs.d//
cd /etc/docker/certs.d//
scp root@192.168.77.133:/home/harbor/ssl/.crt .
#添加harbor仓库地址 可配置可不配置
cat /etc/docker/daemon.json
{
"insecure-registries" : [""]
}
#web服务器已安装docker
yum -y install docker
systemctl enable docker
systemctl start docker
构建 Build with Patameters---选tag---Build
控制台输出
成功构建并推送到harbor,2台web服务器均已OK
三.调试过程报错
报错1:防火墙失败 /usr/bin/docker-current: Error response from daemon: driver failed programming external connectivity on endpoint nginxwebui (27b3fe300f7076010da71fc40443de7743994afe4046e909e54455c7b395a722): (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 8888 -j DNAT --to-destination 172.17.0.2:8080 ! -i docker0: iptables: No chain/target/match by that name.(exit status 1)).
原因:Docker试图在iptables中添加或修改一个不存在的规则。这可能是因为Docker服务没有正确初始化或iptables规则被意外删除。
解决:
#重启防火墙
systemctl restart firewalld
#重启docker
systemctl restart docker
报错2: Restarting (1) 51 seconds ago 容器一直重启
#关闭SELINUX
sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config
setenforce 0
#手动重启这个容器 --restart=always的策略 重启次数增多,下次重启的时间逐渐增加
docker restart 容器ID
报错3:容器已经存在 /usr/bin/docker-current: Error response from daemon: Conflict. The container name "/nginxwebui" is already in use by container b764356402485b7c65a4765c6ac71153942846da657dbe12c166ee41a374037c. You have to remove (or rename) that container to be able to reuse that name..
解决:下次Build with Parameters前,手动删除容器和镜像
#删除容器
docker rm -f 容器ID
#删除镜像
docker rmi -f 镜像ID
未解决:执行shell中无法执行,变量取的是jenkins的,不是web服务器的
#判断容器端口是否存在
if [ `docker ps -s | grep -w 8888- | wc -l` -eq 1 ]
then
docker rm -f `docker ps | grep -w 8888- | awk '{print $NF}'`
fi
#判断容器是否存在
if [ `docker ps -a | grep -w "nginxwebui" | wc -l` -eq 1 ]
then
docker rm -f nginxwebui
fi