前言
随着微服务和容器化技术的兴起,大家或多或少的都听过 docker。docker 相对于虚拟机来说是一种轻量级的虚拟技术,它的隔离性和可移植性也让它有了更多的应用场景。工作闲暇之余,也曾学习过 docker,所以就尝试在一台 ECS 上用 docker 搭建一台 nginx + 2 台 tomcat 的负载均衡,加深一下对 docker 的理解。
通常在一台机器上搭建负载均衡的时候,需要两个端口不一样的 tomcat,但 webapps 下应用必须一致,一个应用在修改了之后需要拷贝到两个 tomcat 中。容器运行 tomcat 就不需要这样,两个容器里面的 tomcat 可以共享宿主机的一个 tomcat 目录。
Docker
对于 docker,就像是一个轻量级的虚拟机,也需要自己的镜像(image)来初始化。dockerhub 像托管代码的 github 一样,托管开发者们已构建的镜像,我们可以通过 docker pull 命令就可以拉取目标镜像,然后通过镜像来启动一个个容器。
docker 作为一个前台进程的守护者,从启动的那一刻就为了 image 中预先设定的命令而存在。所以 dockerhub 里面的 image 在构建的时候已经把要运行的程序和命令集成了进去。
如果想要用基本的 image 来自己 DIY 一个属于自己的镜像,需要自己编写 Dockerfile 文件,dockerfile 从一个基本的 image 来构建目标 image,image 构建 docker 容器。基本的 image 这里选择 centos。
安装 docker
yum -y install docker
# 启动docker守护进程
systemctl start docker.service
# 拉取最基础的image镜像
docker pull centos
复制代码
Tomcat
运行 tomcat 用的是 java8。
下载 tomcat
wget https://mirrors.bfsu.edu.cn/apache/tomcat/tomcat-8/v8.5.57/bin/apache-tomcat-8.5.57.tar.gz
tar zxvf apache-tomcat-8.5.57.tar.gz
复制代码
dockerfile
编写 dockerfile 来构建 image。这里要注意的是:<font color=#cc0000>文件名必须是 Dockerfile</font>。
# 第一行必须是FROM,指定基础镜像
FROM centos
# 在容器中指定jdk和tomcat的挂载点
VOLUME /usr/local/jdk
VOLUME /usr/local/tomcat
# 设置java和tomcat环境变量,需要将宿主机中的jdk和tomcat目录挂载到对应目录上
ENV JAVA_HOME /usr/local/jdk
ENV CATALINA_HOME /usr/local/tomcat
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/bin
# 指定开放端口,在运行容器时指定宿主机端口与其映射
EXPOSE 8080
# docker要运行的命令,这个是tomcat的前台运行方式,不能使用后台运行
CMD catalina.sh run
复制代码
CMD 就是一个容器运行的意义所在,只能存在一个,后者覆盖前者。
构建 image
在 Dockerfile 所在目录使用 docker build 命令来构建 image。命令和执行步骤如下:
[root@ tomcat]# docker build -t tomcat:base .
Sending build context to Docker daemon 2.048 kB
Step 1/8 : FROM centos
---> 0d120b6ccaa8
Step 2/8 : VOLUME /usr/local/jdk
---> Running in 358380feb38c
---> 3861d1ad84ae
Removing intermediate container 358380feb38c
Step 3/8 : VOLUME /usr/local/tomcat
---> Running in 530d504561ed
---> d31fe0243b5c
Removing intermediate container 530d504561ed
Step 4/8 : ENV JAVA_HOME /usr/local/jdk
---> Running in e135bbe0e419
---> 82c1725ef317
Removing intermediate container e135bbe0e419
Step 5/8 : ENV CATALINA_HOME /usr/local/tomcat
---> Running in 241108146f13
---> a16468b916c8
Removing intermediate container 241108146f13
Step 6/8 : ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/bin
---> Running in 2b6ca6c98b05
---> 59c63f6dd4d7
Removing intermediate container 2b6ca6c98b05
Step 7/8 : EXPOSE 8080
---> Running in 91375d4ee543
---> 213c08fc99da
Removing intermediate container 91375d4ee543
Step 8/8 : CMD catalina.sh run
---> Running in a7bc2b3bad54
---> a1d156c4ad18
Removing intermediate container a7bc2b3bad54
Successfully built a1d156c4ad18
复制代码
使用 docker images 查看新构建的镜像 tomcat:
运行容器
使用新建的 image 来构建并启动第一个容器:
docker run -d --name tomcat1 \
-p 8081:8080 \
-v /usr/java/jdk1.8.0_131:/usr/local/jdk \
-v /usr/local/apache-tomcat-8.5.57:/usr/local/tomcat \
tomcat:base
复制代码
构建并启动第二个容器:
docker run -d --name tomcat2 \
-p 8082:8080 \
-v /usr/java/jdk1.8.0_131:/usr/local/jdk \
-v /usr/local/apache-tomcat-8.5.57:/usr/local/tomcat \
tomcat:base
复制代码
两个容器在构建时,-d 代表后台运行,--name 用来来指定各自的名字,-p 来指定宿主机端口和容器 8080 端口的映射,这样才能通过宿主机端口来访问容器内的 tomcat,-v 将主机的 jdk 和 tomcat 目录挂载到容器中。通过 docker ps 查看容器的启动情况:
如果容器启动失败,可以通过 docker logs tomcat1 来查看启动日志。
Nginx
安装 nginx
wget http://nginx.org/download/nginx-1.18.0.tar.gz
tar zxvf nginx-1.18.0.tar.gz
cd nginx-1.18.0
# 检测安装环境并指定安装目录
./configure --prefix=/usr/local/nginx
# 编译并安装
make && make install
复制代码
dockerfile
命名还是 Dockerfile,设置 nginx 的挂载点并开放 80 端口。
FROM centos
VOLUME /usr/local/nginx
ENV NGINX_HOME /usr/local/nginx
ENV PATH $PATH:$NGINX_HOME/sbin
EXPOSE 80
CMD nginx
复制代码
构建 image
在 Dockerfile 的目录下 build 镜像。
[root@iZuf6hmbw6l1tj3u3tzjsdZ nginx]# docker build -t nginx:base .
Sending build context to Docker daemon 2.048 kB
Step 1/6 : FROM centos
---> 0d120b6ccaa8
Step 2/6 : VOLUME /usr/local/nginx
---> Running in e55653915b1f
---> 65e96f9c4d30
Removing intermediate container e55653915b1f
Step 3/6 : ENV NGINX_HOME /usr/local/nginx
---> Running in 6dccb09a2d84
---> 32f2e7563ffe
Removing intermediate container 6dccb09a2d84
Step 4/6 : ENV PATH $PATH:$NGINX_HOME/sbin
---> Running in e5b588d688b0
---> 9c23baa48124
Removing intermediate container e5b588d688b0
Step 5/6 : EXPOSE 80
---> Running in 362a6cbbffc9
---> 6f8ba20a1e48
Removing intermediate container 362a6cbbffc9
Step 6/6 : CMD nginx
---> Running in f0b96ed930d3
---> 64ee43ce3106
Removing intermediate container f0b96ed930d3
Successfully built 64ee43ce3106
复制代码
查看构建的 nginx image:
nginx.conf
修改 nginx 的配置,将两台 tomcat 添加到 upstream 中,作为一组服务。
# 关闭nginx的后台启动,docker只能守护前台进程
daemon off;
http {
upstream docker {
server 宿主机ip:8081;
server 宿主机ip:8082;
}
server {
listen 80;
server_name 宿主机ip;
location / {
root html;
index index.html index.htm;
# 添加反向代理
proxy_pass http://docker;
}
}
}
复制代码
运行容器
将宿主机的 80 端口与容器 80 端口进行映射,并将宿主机的 nginx 挂载到了容器中。
docker run -d \
--name nginx \
-p 80:80 \
-v /usr/local/nginx:/usr/local/nginx \
nginx:base
复制代码
docker ps 查看运行的容器:
测试
通过 http://宿主机 ip 访问 ngxin,正确访问到 tomcat。
多次访问,查看 nginx 日志,两台 tomcat 都被访问到。
总结
当修改应用时,只需要将应用放到宿主机的 tomcat 的 webapps 下,然后重启 tomcat 的容器即可。重启命令:
docker stop tomcat1
docker start tomcat1
复制代码
评论