Docker通过linux的namespace实现资源隔离、cgroups实现资源控制,通过写时复制机制(copy-on-write)实现了高效的文件操作,在实际开发中可用于提供一次性的环境、微服务架构的搭建、统一环境的部署。
虽然Docker已经是风靡全球的容器技术了,统一环境避免环境问题上是Docker的主要吸引点之一,但使用时详细还是会遇到不少问题的,比如个人搭建时曾思考过这些问题:
在实际搭建部署中也找到了与上相对应的答案:
当探索到自我提问的答案时,便确定了各组件的主要职责:
搭建环境流程:
安装JDK
安装Maven
安装git
安装Jenkins(该步骤之前的可参考Jenkins安装并部署Java项目完整流程)
如有权限问题可将/etc/sysconfig/jenkins文件JENKINS_USER
修改为root或手动赋权
Centos安装Docker(Install Docker Engine - Community)
安装DockerCompose
sudo curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
docker-compose --version
使用DockerCompose可省去容器增多时需多次执行docker run的麻烦
1. SpringBoot项目Dockerfile
FROM java:8
MAINTAINER Wilson
# 统一容器与服务器时间
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
#复制target/docker-spring-boot.jar到容器app目录下
COPY ./target/docker-spring-boot.jar app/docker-spring-boot.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","app/docker-spring-boot.jar"]
# docker build -t docker-spring-boot/latest .
2. 配置docker-compose.yml
version: '3.7'
services:
app:
restart: always
build: ./
hostname: docker-spring-boot
container_name: docker-spring-boot
image: docker-spring-boot/latest
# 端口不对外开放
# ports:
# - 8080:8080
volumes:
- ./volumes/app:/app
nginx:
depends_on:
- app
container_name: docker-nginx
hostname: docker-nginx
image: nginx:1.17.6
environment:
TZ: Asia/Shanghai
restart: always
expose:
- 80
ports:
- 80:80
links:
- app
volumes:
- ./volumes/nginx/nginx.conf:/etc/nginx/nginx.conf
- ./volumes/nginx/conf.d:/etc/nginx/conf.d
- ./volumes/nginx/logs:/var/log/nginx
3. Nginx
./volumes/nginx/nginx.conf
user nginx;
worker_processes 2; #设置值和CPU核心数一致
error_log /etc/nginx/error.log crit; #日志位置和日志级别
pid /etc/nginx/nginx.pid;
events
{
use epoll;
worker_connections 65535;
}
http{
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" "$http_cookie"';
access_log /var/log/nginx/access.log main;
#charset utf8;
server_names_hash_bucket_size 128;
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
client_max_body_size 8m;
sendfile on;
tcp_nopush on;
keepalive_timeout 60;
tcp_nodelay on;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml;
gzip_vary on;
#limit_zone crawler $binary_remote_addr 10m;
#server虚拟主机的配置
include /etc/nginx/conf.d/*.conf;
}
./volumes/nginx/conf.d目录下的default.conf
upstream application {
server docker-spring-boot:8080;
}
server{
listen 80;#监听端口
server_name localhost;#域名
access_log /var/log/nginx/nginx-spring-boot.log;
location / {
proxy_pass http://application;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Jenkins脚本(如果Nginx配置更改较多也可添加Nginx容器重启指令):
cd /var/lib/jenkins/workspace/docker-spring-boot/spring-boot-nginx-docker-demo
mvn clean package
if [ -e "./volumes/app/docker-spring-boot.jar" ]
then rm -f ./volumes/app/docker-spring-boot.jar \
&& cp ./target/docker-spring-boot.jar ./volumes/app/docker-spring-boot.jar \
&& docker restart docker-spring-boot \
&& echo "update restart success"
else mkdir volumes/app -p \
&& cp ./target/docker-spring-boot.jar ./volumes/app/docker-spring-boot.jar \
&& docker-compose -p docker-spring-boot up -d \
&& echo "first start"
fi
docker-compose up指令可以进行镜像的安装,所以也省去了只用docker指令时需要提前准备好镜像相关指令的麻烦。
docker ps
如需将SpringBoot通过容器集群搭建,只需进行以下更改:
docker-compose.yml添加SpringBoot项目冗余,更改冗余容器名,区分日志挂载路径,冗余项目更改容器名
version: '3.7'
services:
app:
restart: always
build: ./
hostname: docker-spring-boot
container_name: docker-spring-boot
image: docker-spring-boot/latest
volumes:
- ./volumes/app/docker-spring-boot.jar:/app/docker-spring-boot.jar
- ./volumes/app/logs:/app/logs
app-bak:
restart: always
build: ./
hostname: docker-spring-boot
container_name: docker-spring-boot-bak
image: docker-spring-boot/latest
volumes:
- ./volumes/app/docker-spring-boot.jar:/app/docker-spring-boot.jar
- ./volumes/app/logs-bak:/app/logs
nginx:
depends_on:
- app
container_name: docker-nginx
hostname: docker-nginx
image: nginx:1.17.6
environment:
TZ: Asia/Shanghai
restart: always
expose:
- 80
ports:
- 80:80
links:
- app
- app-bak
volumes:
- ./volumes/nginx/nginx.conf:/etc/nginx/nginx.conf
- ./volumes/nginx/conf.d:/etc/nginx/conf.d
- ./volumes/nginx/logs:/var/log/nginx
nginx更改default.conf的upstream,添加冗余容器配置
upstream application {
server docker-spring-boot:8080 fail_timeout=2s max_fails=2 weight=1;
server docker-spring-boot-bak:8080 fail_timeout=2s max_fails=2 weight=1;
}
server{
listen 80;#监听端口
server_name localhost;#域名
access_log /var/log/nginx/nginx-spring-boot.log;
location / {
proxy_pass http://application;
proxy_connect_timeout 2s;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Jenkins添加冗余容器重启脚本
BUILD_ID=DONTKILLME
cd /var/lib/jenkins/workspace/docker-spring-boot/spring-boot-nginx-docker-demo
mvn clean package
if [ -e "./volumes/app/docker-spring-boot.jar" ]
then rm -f ./volumes/app/docker-spring-boot.jar \
&& cp ./target/docker-spring-boot.jar ./volumes/app/docker-spring-boot.jar \
&& docker-compose -p docker-spring-boot up -d \
&& docker restart docker-spring-boot \
&& docker restart docker-spring-boot-bak \
&& docker restart docker-nginx \
&& echo "update restart success"
else mkdir volumes/app -p \
&& cp ./target/docker-spring-boot.jar ./volumes/app/docker-spring-boot.jar \
&& docker-compose -p docker-spring-boot up -d \
&& echo "first start"
fi
测试集群效果:
docker stop docker-spring-boot
,仍可通过url/api通过Nginx访问可以看出容器配置集群的以下优点:
spring-boot-nginx-docker-demo