按:宿主机为CentOS7.4,NodeJS环境前端项目,SpringBoot Maven后端项目,Git代码仓库,Jenkins打包部署,Nginx做负载均衡。
安装Docker
CentOS通过yum安装的Docker版本有点低,需要安装Docker-CE:
# 添加安装源
sudo yum-config-manager --add-repo
https://download.docker.com/linux/centos/docker-ce.repo
# 安装Docker-CE
sudo yum install docker-ce
# 启动Docker服务
sudo systemctl start docker
# 设置开机启动
sudo systemctl enable docker
# 修改启动代码支持远程访问(Docker中的Jenkins会调用docker命令远程访问宿主机的Docker)
sudo vi /usr/lib/systemd/system/docker.service
在ExecStart的末尾添加如下启动参数
-H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375
# 重新加载修改后的文件
sudo systemctl daemon-reload
# 重启Docker服务
sudo systemctl restart docker
安装包含Docker命令的Jenkins
Jenkins镜像本身不包含Docker命令,需要自行制作一个包含Docker命令的镜像并启动容器。
mkdir ~/jenkins_with_docker
cd ~/jenkins_with_docker
vi Dockerfile
# 开始Dockerfile
FROM jenkins/jenkins:jdk11
USER root
RUN curl -O https://get.docker.com/builds/Linux/x86_64/docker-latest.tgz \
&& tar zxvf docker-latest.tgz \
&& cp docker/docker /usr/local/bin/ \
&& rm -rf docker docker-latest.tgz
ARG DOCKER_GID=999
USER jenkins:${DOCKER_GID}
# 结束Dockerfile
# 构建镜像
sudo docker build -t myjenkins .
# 创建存放Jenkins文件的目录(删除重建容器时不会破坏原有数据)
sudo mkdir /data/jenkins
# 更改数据目录权限
chown -R 1000:1000 /data/jenkins
# 创建并运行容器
docker run -d --name jenkins --restart=always -p 8080:8080 -p 50000:50000 --privileged=true -v /data/jenkins:/var/jenkins_home myjenkins
# 浏览器访问宿主机的8080端口,安装插件,创建用户
# Unlock Jenkins时需要输入密码,进入jenkins容器交互界面,查询密码
sudo docker exec -it jenkins /bin/bash
cat /var/jenkins_home/secrets/initialAdminPassword
# 安装插件前,把插件地址改为国内镜像以提高安装速度
# 打开地址 http://ip-address:8080/manage/pluginManager/advanced
# 最下面的URL更新为以下地址或者其他有效的插件更新地址:https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
# 安装插件时需要安装Docker plugin, docker-build-step, NodeJS plugin
# 其实docker的插件也可以不装,我们直接执行shell命令操作宿主机的docker
# 配置 Jenkins:在系统设置-全局工具配置中添加NodeJS和Maven。都选择在线安装,如果不同项目用到Node多个版本,可以安装多个。
# 如果使用Docker插件而不是shell操作Docker的话,需要在系统设置中配置docker builder,tcp://xxx.xxx.xxx.xxx:2375
前端项目配置
# 前端项目中需要先准备一个Dockerfile用于构建镜像
# /docker/Dockerfile
FROM nginx:stable-alpine
WORKDIR /usr/local/bin
COPY ./ /usr/share/nginx/html
Jenkins中新建一个自由风格的项目,把git源配置好,在“构建环境”中勾选“ Provide Node & npm bin/ folder to PATH ”,选择项目使用的NodeJS版本。在“构建”中执行Shell命令:
echo $PATH
node -v
npm -v
# 避免被屏蔽国外网站下载失败
npm install chromedriver --chromedriver_cdnurl=http://cdn.npm.taobao.org/dist/chromedriver
npm install
npm run build
Shell方式执行Docker命令
cd ${WORKSPACE}/dist/
cp ../docker/Dockerfile ./
docker -H 宿主机IP build -t front-end-demo .
# 停止指定镜像的容器
docker -H 宿主机IP container ls| awk '$2=="front-end-demo"{system("docker -H 宿主机IP stop " $1)}'
# 删除指定镜像的容器
docker -H 宿主机IP container ls -a| awk '$2=="front-end-demo"{system("docker -H 宿主机IP rm " $1)}'
# 停止指定镜像的容器
docker -H 宿主机IP container ls|grep front-end-demo-container|awk '{system("docker -H 宿主机IP stop " $1)}'
# 删除指定镜像的容器
docker -H 宿主机IP container ls -a|grep front-end-demo-container|awk '{system("docker -H 宿主机IP rm " $1)}'
# 根据需要可以启动多个
docker -H 宿主机IP run -d --name front-end-demo-container-1 -p 9901:80 front-end-demo
docker -H 宿主机IP run -d --name front-end-demo-container-2 -p 9902:80 front-end-demo
# 总是有一个<none>的多余镜像,删掉它
docker -H 宿主机IP image ls|awk '$2=="<none>"{system("docker -H 宿主机IP image rm "$3)}'
配置后端项目
后端项目Dockerfile文件,用于构建镜像:
FROM jdk8
VOLUME /tmp
# 下面这个文件名要根据实际打包的来调整
ADD demo-1-0.0.1-SNAPSHOT.jar /app.jar
RUN touch /app.jar
EXPOSE 80
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
由于没有找到尺寸小的jdk8的官方标准镜像,我们还是自己构建一个,新建一个目录,把下载到的jdk*.tar.gz拷贝到这个目录并新建Dockerfile如下:
FROM frolvlad/alpine-glibc
#FROM centos:7
MAINTAINER sunits
WORKDIR /usr
RUN mkdir /usr/local/java
ADD jdk-8u211-linux-x64.tar.gz /usr/local/java/
ENV JAVA_HOME /usr/local/java/jdk1.8.0_211
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH
构建镜像:
sudo docker build -t jdk8 .
这里按SpringBoot项目打jar包的情况来配置。
Jenkins中新建一个Maven项目,如果没有这个选项,就添加Maven插件Maven Integration plugin。Maven的goal设置为 clean package
pom.xml中的build部分增加jar包的输出路径:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<outputDirectory>src/docker</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
Post Steps中添加Shell命令
cd ${WORKSPACE}/src/docker/
docker -H 宿主机IP build -t spring-boot-demo .
# 停止指定镜像的容器
docker -H 宿主机IP container ls| awk '$2=="spring-boot-demo"{system("docker -H 宿主机IP stop " $1)}'
# 删除指定镜像的容器
docker -H 宿主机IP container ls -a| awk '$2=="spring-boot-demo"{system("docker -H 宿主机IP rm " $1)}'
# 停止指定镜像的容器
docker -H 宿主机IP container ls|grep spring-boot-demo-container|awk '{system("docker -H 宿主机IP stop " $1)}'
# 删除指定镜像的容器
docker -H 宿主机IP container ls -a|grep spring-boot-demo-container|awk '{system("docker -H 宿主机IP rm " $1)}'
# 根据需要可以启动多个容器
docker -H 宿主机IP run -d --name spring-boot-demo-container-1 -p 9911:8080 spring-boot-demo
docker -H 宿主机IP run -d --name spring-boot-demo-container-2 -p 9912:8080 spring-boot-demo
# 总是有一个<none>的多余镜像,删掉它
docker -H 宿主机IP image ls|awk '$2=="<none>"{system("docker -H 宿主机IP image rm "$3)}'
Nginx做负载均衡
先做对应的域名解析,后端:be.demo.com, 前端:fe.demo.com,指向nginx服务器,nginx这里不用容器:
yum install nginx
systemctl start nginx
systemctl enable nginx
# 修改/etc/nginx/nginx.conf,在http节内最后添加
include /etc/nginx/vhosts/*.conf;
# 然后就可以每个站点一个conf文件
# 前端文件 /etc/nginx/vhosts/fe.conf
# 开始 fe.conf
upstream fe {
server 127.0.0.1:9901; // 启动几个容器就可以配置几个
server 127.0.0.1:9902;
}
server {
listen 80;
server_name fe.demo.com;
location / {
proxy_pass http://fe;
}
}
# 结束 fe.conf
# 后端文件 /etc/nginx/vhosts/be.conf
# 开始 be.conf
upstream be {
server 127.0.0.1:9911; // 启动几个容器就可以配置几个
server 127.0.0.1:9912;
}
server {
listen 80;
server_name be.demo.com;
location / {
proxy_pass http://be;
}
}
# 结束 be.conf
# 重新加载配置文件或者重启
systemctl reload/restart nginx
其他常用Docker容器创建
#启动一个Redis容器
sudo docker run --name myredis -d --restart=always -p 6379:6379 --privileged=true -v /data/redis/data:/data redis:alpine
#启动一个MariaDB容器
docker run -d --name mariadb --privileged=true --restart=always -v /data/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 mariadb --lower_case_table_names=1
#启动一个禅道容器
sudo docker run -d --restart=always --name zentao -p 8081:80 -v /data/zentao/www:/app/zentaopms -v /data/zentao/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d zentao:latest
#启动一个gitlab容器
GITLAB_HOME=/data/gitlab
docker run --hostname gitlab --privileged=true -p 8443:443 -p 80:80 -p 2222:22 --name gitlab --restart always -v $GITLAB_HOME/config:/etc/gitlab -v $GITLAB_HOME/logs:/var/log/gitlab -v $GITLAB_HOME/data:/var/opt/gitlab gitlab/gitlab-ce
安装RabbitMQ
docker pull rabbitmq:management-alpine
sudo docker run -d --restart=always --hostname my-rabbit -v /data/rabbitmq/data:/var/lib/rabbitmq --name rabbit -p 15672:15672 -p 4369:4369 -p 5671:5671 -p 5672:5672 -p 25672:25672 -p 61614:61614 -p 61613:61613 rabbitmq:management-alpine