随着微服务和容器化技术的兴起,大家或多或少的都听过docker。docker相对于虚拟机来说是一种轻量级的虚拟技术,它的隔离性和可移植性也让它有了更多的应用场景。工作闲暇之余,也曾学习过docker,所以就尝试在一台ECS上用docker搭建一台nginx + 2台tomcat的负载均衡,加深一下对docker的理解。 通常在一台机器上搭建负载均衡的时候,需要两个端口不一样的tomcat,但webapps下应用必须一致,一个应用在修改了之后需要拷贝到两个tomcat中。容器运行tomcat就不需要这样,两个容器里面的tomcat可以共享宿主机的一个tomcat目录。
对于docker,就像是一个轻量级的虚拟机,也需要自己的镜像(image)来初始化。dockerhub像托管代码的github一样,托管开发者们已构建的镜像,我们可以通过docker pull命令就可以拉取目标镜像,然后通过镜像来启动一个个容器。
docker作为一个前台进程的守护者,从启动的那一刻就为了image中预先设定的命令而存在。所以dockerhub里面的image在构建的时候已经把要运行的程序和命令集成了进去。 如果想要用基本的image来自己DIY一个属于自己的镜像,需要自己编写Dockerfile文件,dockerfile从一个基本的image来构建目标image,image构建docker容器。基本的image这里选择centos。
运行tomcat用的是java8。
编写dockerfile来构建image。这里要注意的是:文件名必须是Dockerfile。
# 第一行必须是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 runCMD就是一个容器运行的意义所在,只能存在一个,后者覆盖前者。
在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来查看启动日志。
命名还是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在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的配置,将两台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:basedocker ps查看运行的容器:
通过http://宿主机ip访问ngxin,正确访问到tomcat。 多次访问,查看nginx日志,两台tomcat都被访问到。
当修改应用时,只需要将应用放到宿主机的tomcat的webapps下,然后重启tomcat的容器即可。 重启命令:
docker stop tomcat1 docker start tomcat1