7.jenkins自动部署springboot到swarm集群
一.jenkins - 打包 - 制作镜像上传到仓库
通过maven插件进行可以制作镜像,并上传到docker registry.
1.pom.xml添加对应插件配置
<properties> <java.version>1.8</java.version> <dockerfile.maven.version>1.4.0</dockerfile.maven.version> <!-- 镜像名称前缀,上传到私有仓库,必须配置 --> <docker.registry.name.prefix>manager62:7000</docker.registry.name.prefix> </properties> <plugin> <groupId>com.spotify</groupId> <artifactId>dockerfile-maven-plugin</artifactId> <version>${dockerfile.maven.version}</version> <dependencies> <dependency> <groupId>javax.activation</groupId> <artifactId>activation</artifactId> <version>1.1.1</version> </dependency> </dependencies> <executions> <execution> <id>default</id> <goals> <goal>build</goal> <goal>push</goal> </goals> </execution> </executions> <configuration> <repository>${docker.registry.name.prefix}/${project.artifactId}</repository> <tag>${project.version}</tag> <!--<username>username</username>--> <!--<password>password</password>--> <buildArgs> <JAR_FILE>${project.build.finalName}.jar</JAR_FILE> </buildArgs> </configuration> </plugin> <!-- windows 环境配置变量DOCKER_HOST=tcp://192.168.10.10:2375 可以在本地开发环境上传镜像到仓库,但是注意开放对应防火墙端口 --> <!-- centos操作完防火墙后,遇到问题一般要重启docker服务 systemctl restart docker -->
2.添加dockerfile文件,这个maven插件需要dockerfile才能工作
FROM java:8 MAINTAINER lhnonline 0376lhn@gmail.com COPY target/docker-test-1.0.0.jar /app.jar EXPOSE 8080 ENV CE=$CE ENV JAVA_OPTS=$JAVA_OPTS ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar --spring.profiles.active=$CE" ]
二.jenkins到swarm服务器上执行部署命令
1.先push镜像到私有仓库
#直接在jenkins中添加post step/execute shell
#注意/etc/hosts中要有manager62的映射,/etc/docker/daemon.json要有manager62:7000的配置
echo "push 镜像到私有仓库"
docker push manager62:7000/docker-test:1.0.0
2.再ssh到swarm执行启动任务
#再添加一个post step / send file or execute command over ssh执行swarm上的脚本进行部署,下面是我的脚本 #!/bin/bash project_name=docker_test work_dir=/data/project/$project_name outter_port=8080 inner_port=8080 docker_mirror_name=manager62:7000/docker-test:1.0.0 network_name=docker_test_network java_opts="-Xmx128m -Xss512k" cd="dev" init_create_network(){ echo "`echo $(date +%F%n%T)` creating network ..." >> $work_dir/log.txt docker network create --driver overlay $network_name } #把/var/lib/docker/volume/$project 挂载到 容器的/logs目录 #不要挂载到/tmp,有时候会有问题。 init_create_docker_service(){ echo "`echo $(date +%F%n%T)` create docker service ..." >> $work_dir/log.txt docker service create --replicas 1 \ --network $network_name \ --name $project_name \ --mount type=volume,src=$project_name,dst=/logs \ -e CE="$ce" \ -e JAVA_OPTS="$java_opts" \ -p $outter_port:$inner_port $docker_mirror_name } update_docker_service(){ echo "`echo $(date +%F%n%T)` update docker service ..." >> $work_dir/log.txt docker service update --image $docker_mirror_name $project_name } #如果work_dir存在,更新docker service if [ -d $work_dir ];then update_docker_service fi #如果work_dir不存在初始化项目(创建网络,创建docker service) if [ ! -d $work_dir ];then mkdir -p $work_dir init_create_network init_create_docker_service fi
三.可能会出现的问题
1.提交到git,触发jenkins打包是执行构建docker镜像时候出现(java.io.IOException) caught when processing request to {}->unix://localhost:80: Permission denied
chmod 777 /var/run/docker.sock
2.构建docker镜像的时候提示 ADD failed: stat /var/lib/docker/tmp/docker-builder964944550/software/jdk8/jdk1.8.0_191: no such file or directory
# docker file 中添加构件xx-verison.jar 时候使用相对路径,类似如下
ADD target/xx-version.jar /xx-version.jar
3.windows开发环境远程构建docker镜像提示 Connect to localhost:2375 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused,或者配置好DOCKER_HOST后依然 connection refused

#修改/usr/lib/systemd/system/docker.service文件
sudo vi /usr/lib/systemd/system/docker.service
#保证 ExecStart中包含-H tcp://0.0.0.0:2375,修改后应该是类似这样的
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
#保存/usr/lib/systemd/system/docker.service
Shift zz
#重新加载配置文件
systemctl daemon-reload
#重启docker
service docker restart
#并保证2375不被防火墙拦截,应该就可以了
4.jenkins和docker私有仓库不在同一个服务器
#执行docker push 就好了,镜像已经打上了私有仓库的标签了
docker push 镜像
5.尝试在swarm集群任意worker启动刚上传到私有仓库的镜像提示Error response from daemon: Get https://manager62:7000/v2/: http: server gave HTTP response to HTTPS client
检查/etc/docker/daemon.json中是否有私有仓库的配置即manager62:7000是否在"insecure-registries"列表中。,一定要检查每一个节点的配置是否ok。
6.swarm集群scale的时候提示有些节点起不来,通过inspect查看启动失败的容器发现:"Err": "starting container failed: error evaluating symlinks from mount source xxxxx no such file or directory",
删除,重新创建服务,另起一个volume名称就好了。。。
7.我把应用日志输出到/tmp/下面,但是我在/var/lib/docker/volumes/对应的volume下找不到日志文件,
volume mount,不同于bind mount. 发生问题的原因是,volume mount有覆盖的操作。 1.容器内目录不为空,外面的volume为空,容器内目录数据填充到volume; 2.volume不为空,volume覆盖容器内目录。 我遇到的问题可能是,continer内/tmp目录被tomcat占用,里面有内容,覆盖了volume,但是搞不懂为啥日志输入不到那个目录。我更改了日志输入的路径,在volume里面就看到日志了。
补充一些截图