2.3.2 从 JDK 镜像构建 tomcat 8 Base 镜像
2.1 手动制作 yum 版 nginx 镜像
Docker 制作类似于虚拟机的模板制作,即按照公司的实际业务务求将需要安装的软件、相关配置等基础环境配置完成,然后将虚拟机再提交为模板,最后再批量从模板批量创建新的虚拟机,这样可以极大的简化业务中相同环境的虚拟机运行环境的部署工作,Docker的镜像制作分为手动制作和自动制作(基于DockerFile),企业通常都是基于 Dockerfile 制作镜像,其中手动制作镜像步骤具体如下:
2.1.1 下载镜像并初始化系统
#基于某个基础镜像之上重新制作,因此需要先有一个基础镜像,本次使用官方提供的 centos 镜像为基础:
[root@localhost ~]# docker pull centos:7
[root@localhost ~]# docker run -it --name centos7 centos:7
[root@865e00f81237 /]# yum -y install epel-release
#安装nginx
[root@865e00f81237 /]# yum -y install nginx
[root@865e00f81237 /]# vi /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
#关闭后台运行
daemon off;
[root@865e00f81237 /]# nginx -t #测试配置文件
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
#准备自定义的web页面
[root@865e00f81237 /]# rm -f /usr/share/nginx/html/index.html
[root@865e00f81237 /]# echo "666" > /usr/share/nginx/html/index.html
[root@865e00f81237 /]# yum clean all #清空yum缓存,精简镜像体积
2.1.2 提交为镜像
在宿主机基于容器名称或 ID 提交为镜像
[root@localhost ~]# docker commit -m "ngixn image" centos7 web/centos7-nginx
sha256:76efd9f0111e4ae06f589d87dc520fcd0907e63e85706fd2c59571c058c53935
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
web/centos7-nginx latest 76efd9f0111e 12 seconds ago 262MB
busybox latest 9d5226e6ce3f 13 days ago 1.24MB
nginx latest 605c77e624dd 11 months ago 141MB
centos 7 eeb6ee3f44bd 14 months ago 204MB
centos 8 5d0da3dc9764 14 months ago 231MB
centos latest 5d0da3dc9764 14 months ago 231MB
#提交为带版本的镜像
[root@localhost ~]# docker commit -m "ngixn image" centos7 web/centos7-nginx:v1
sha256:d2ed0598866aae8eee375ec38db16ea7587461655a8d6cb60ff78e44a2d22f20
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
web/centos7-nginx v1 d2ed0598866a 2 seconds ago 262MB
web/centos7-nginx latest 76efd9f0111e 51 seconds ago 262MB
busybox latest 9d5226e6ce3f 13 days ago 1.24MB
nginx latest 605c77e624dd 11 months ago 141MB
centos 7 eeb6ee3f44bd 14 months ago 204MB
centos 8 5d0da3dc9764 14 months ago 231MB
centos latest 5d0da3dc9764 14 months ago 231MB
2.1.2.1 docker commit 命令
[root@localhost ~]# docker commit --help
Usage: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
Create a new image from a container's changes
Options:
-a, --author string Author (e.g., "John Hannibal Smith <hannibal@a-team.com>")
-c, --change list Apply Dockerfile instruction to the created image
-m, --message string Commit message
-p, --pause Pause container during commit (default true)
2.1.3 从自己镜像启动容器
[root@localhost ~]# docker run -d -p 80:80 --name web1 web/centos7-nginx:v1 /usr/sbin/nginx
e2a2479235c34482edd0e440bc2fa726fc044f284730da179c8f99d55af03137
[root@localhost ~]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:111 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 *:9090 *:*
LISTEN 0 128 [::]:111 [::]:*
LISTEN 0 512 *:80 *:*
LISTEN 0 128 [::]:22 [::]:*
[root@localhost ~]# curl 192.168.11.11
666
2.2 DockerFile 制作编译版 nginx 镜像
DockerFile 可以说是一种可以被 Docker 程序解释的脚本,DockerFile 是由一 条条的命令组成的,每条命令对应 linux 下面的一条命令,Docker 程序将这些 DockerFile 指令再翻译成真正的linux 命令,其有自己的书写方式和支持的命令, Docker 程序读取DockerFile 并根据指令生成 Docker 镜像,相比手动制作镜像的方式,DockerFile 更能直观的展示镜像是怎么产生的,有了写好的各种各样 DockerFile 文件,当后期某个镜像有额外的需求时,只要在之前的 DockerFile 添加或者修改相应的操作即可重新生成新的Docke 镜像,避免了重复手动制作镜像的麻烦,具体如下:
https://docs.docker.com/engine/reference/builder/
FROM #在整个dockfile文件中,除了注释之外的第一行,要是from,用于指定父镜像
ADD #用于添加宿主机本地的文件、目录、压缩等资源到镜像里面去,会自动解压tar.gz格式的压缩包,不会自动解压zip
MAINTAINER #(镜像的作者信息)
LABEL #设置镜像的属性标签
COPY #用于添加宿主机本地的文件、目录、压缩等资源到镜像里面去,不会解压任何压缩包
ENV #设置容器环境变量
EXPOSE #声明要把容器的某些端口映射到宿主机
STOPSIGNAL #设置信号
USER #指定运行操作的用户
VOLUME #定义volume,也就是创建目录
WORKDIR #用于定义工作目录
RUN #执行shell命令,但是一定要以非交互式的方式执行
CMD #镜像启动为一个容器时候的默认命令或脚本, CMD ["/bin/bash"]
ENTRYPOINT #也可以用于定义容器在启动时候默认执行的命令或者脚本,如果是和CMD命令混合使用的时候,会将CMD的命令当做参数传递给ENTRYPOINT后面的脚本,可以在脚本中对参数做判断并相应的容器初始化操作。
2.2.1 下载镜像并初始化系统
nginx-1.18.0.tar.gz下载链接
链接:https://pan.baidu.com/s/1w45jM0vd-pGyPtkbcyJyrA
提取码:1111
[root@localhost ~]# cd /opt/
[root@localhost opt]# mkdir -pv dockerfile/{web/{nginx,tomcat,apache},system/{centos,ubuntu,redhat}}
[root@localhost ~]# cd /opt/dockerfile/web/nginx/
[root@localhost nginx]# vim Dockerfile
#生成的镜像的时候会在执行命令的当前目录查找 Dockerfile
#生成的镜像的时候会在执行命令的当前目录查找 Dockerfile文件,所以名称不可写错,而且D必须大写
#My Dockerfile
#'#'为注释,等于shell脚本中#
#除了注释行以外的第一行,必须是From开始
#第一行先定义基础镜像,后面的本地有效的镜像名,如果本地没有会从远程仓库下载,第一行很重要
FROM centos:7
#镜像维护者的信息
MAINTAINER kylin kylin@kylin.com
RUN rm -f /etc/yum.repos.d/* \
&& curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo \
&& yum install -y gcc gcc-c++ make openssl-devel pcre-devel gd-devel iproute net-tools telnet wget zlib zlib-devel \
&& yum clean all
ADD nginx-1.18.0.tar.gz /
RUN useradd nginx -s /sbin/nologin \
&& cd /nginx-1.18.0 \
&& ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream \
&& make && make install \
&& ln -sv /usr/local/nginx/sbin/nginx /usr/sbin/nginx
RUN rm -rf /nginx*
ADD nginx.conf /usr/local/nginx/conf/nginx.conf
ADD index.html /usr/local/nginx/html/index.html
RUN chmod 755 /usr/local/nginx && chmod 755 /usr/local/nginx/html
#向外开放的端口,多个端口用空格做间隔,启动容器时候-p需要使用此端向外映射,如: -p 8081:80,则 80 就是这里的 80
EXPOSE 80 443
#运行的命令,每个 Dockerfile 只能有一条,如果有多条则只有最后一条被执行
CMD ["/usr/local/nginx/sbin/nginx"]
如果在从该镜像启动容器的时候也指定了命令,那么指定的命令会覆盖Dockerfile 构建的镜像里面的 CMD 命令,即指定的命令优先级更高,Dockerfile的优先级较低一些,重新指定的指令优先级要高一些。
2.2.3 准备源码包与配置文件
[root@localhost nginx]# echo It Works > index.html
[root@localhost nginx]# cat index.html
It Works
[root@localhost nginx]# ls
Dockerfile index.html nginx-1.18.0.tar.gz
[root@localhost nginx]# tar xf nginx-1.18.0.tar.gz
[root@localhost nginx]# ls
Dockerfile index.html nginx-1.18.0 nginx-1.18.0.tar.gz
[root@localhost nginx]# cd nginx-1.18.0/
[root@localhost nginx-1.18.0]# find . -name nginx.conf
./conf/nginx.conf
[root@localhost nginx-1.18.0]# cp ./conf/nginx.conf ../
[root@localhost nginx-1.18.0]# cd ..
[root@localhost nginx]# ls
Dockerfile index.html nginx-1.18.0 nginx-1.18.0.tar.gz nginx.conf
[root@localhost nginx]# rm -rf nginx-1.18.0
#修改nginx配置,关闭守护运行
[root@localhost nginx]# vim nginx.conf
...
daemon off;
...
2.2.4 执行镜像构建
[root@localhost nginx]# docker build -t nginx:v1 .
Successfully built 04ae6ed3c9d2
Successfully tagged nginx:v1
#在构建的过程中使用docker ps 查看构建的过程,会生成一个容器,当构建完成的时候,生成的容器会删除
2.2.5 查看是否生成本地镜像
[root@localhost nginx]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v1 04ae6ed3c9d2 4 minutes ago 404MB
2.2.6 从镜像启动容器
[root@localhost nginx]# docker run -d --rm --name nginx1 -p 80:80 nginx:v1
8a8eba67b2decd7a300943f775a6f444d41d68e8c30aa40916fad1bbb60fde38
#测试访问
[root@localhost nginx]# curl 192.168.11.11
666
2.2.7 镜像编译制作程中
制作镜像过程中,需要启动一个临时的容器进行相应的指令操作,操作完成后再把此容器转换为 image。
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
640bbb57f782 6e02db74c062 "/bin/sh -c 'yum ins…" 4 seconds ago Up 3 seconds kind_greider
2.3 自定义 Tomcat 业务镜像
基于官方提供的 centos、debain、ubuntu、alpine 等基础镜像构建JDK (Java 环境),然后再基于自定义的 JDK 镜像构建出业务需要的tomcat 镜像
2.3.1 构建 JDK 镜像
先基于官方提供的基础镜像,制作出安装了常用命令的自定义基础镜像,然后在基础镜像的基础之上,再制作 JDK 镜像、Tomcat 镜像等。
2.3.1.1 自定义 Centos 基础镜像
[root@localhost ~]# cd /opt/dockerfile/system/centos/
[root@localhost centos]# vim Dockerfile
FROM centos:7
RUN yum install -y epel-release vim wget tree lrzsz gcc gcc-c++ auto make pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop && yum clean all
RUN groupadd www -g 2020 && useradd www -u 2020 -g www #添加系统账户
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime #设置时区
[root@localhost centos]# docker build -t centos-base:v1 .
[root@localhost ~]# mkdir -pv /opt/dockerfile/web/jdk
[root@localhost ~]# cd /opt/dockerfile/web/jdk
[root@localhost ~]# mkdir jdk-8u171
[root@localhost ~]# cd jdk-8u171
jdk-8u171-linux-x64.tar.gz #上传jdk
[root@localhost jdk-8u171]# vim java.sh #准备环境变量
export JAVA_HOME=/usr/local/jdk
export PATH=$PATH:$JAVA_HOME/bin
export JRE_HOME=$JAVA_HOME/jre
export CLASSPATH=$JAVA_HOME/lib/:$JRE_HOME/lib/
[root@localhost jdk-8u171]# vim Dockerfile vim Dockerfile #准备Dockerfile文件
FROM centos-base:v1
MAINTAINER KKK "xxx@xx.com"
ADD jdk-8u171-linux-x64.tar.gz /usr/local/src/
RUN ln -s /usr/local/src/jdk1.8.0_171 /usr/local/jdk
ADD java.sh /etc/profile.d/
#ENV用来给刚启动容器的root用户使用
ENV JAVA_HOME=/usr/local/jdk
ENV PATH=$PATH:$JAVA_HOME/bin
ENV JRE_HOME=$JAVA_HOME/jre
ENV CLASSPATH=$JAVA_HOME/lib/:$JRE_HOME/lib/
[root@localhost jdk-8u171]# docker build -t jdk-8u171:v1 .
[root@localhost jdk-8u171]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
jdk-8u171 v1 ffb57035cac9 6 minutes ago 785MB
centos-base v1 94b4af17162e 7 minutes ago 397MB
centos 7 eeb6ee3f44bd 14 months ago 204MB
[root@localhost jdk-8u171]# docker run --rm jdk-8u171:v1 java -version
java version "1.8.0_171"
Java(TM) SE Runtime Environment (build 1.8.0_171-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)
2.3.2 从 JDK 镜像构建 tomcat 8 Base 镜像
基于自定义的 JDK 基础镜像,构建出通用的自定义 Tomcat 基础镜像,此镜像后期会被多个业务的多个服务共同引用(相同的 JDK 版本和 Tomcat 版本)。
2.3.2.1 编辑 Dockerfile
[root@localhost ~]# cd /opt/dockerfile/web/tomcat/
[root@localhost tomcat]# vim Dockerfile
FROM jdk-8u171:v1
ADD apache-tomcat-8.5.66.tar.gz /apps/
RUN ln -s /apps/apache-tomcat-8.5.66 /apps/tomcat
#上传tomcat压缩包
[root@localhost tomcat]# ls
apache-tomcat-8.5.66.tar.gz Dockerfile
#执行构建
[root@localhost tomcat]# docker build -t tomcat-base:v8.5.66 .
[root@localhost tomcat]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat-base v8.5.66 dec5807b7450 5 seconds ago 799MB
jdk-8u171 v1 ffb57035cac9 30 minutes ago 785MB
centos-base v1 94b4af17162e 31 minutes ago 397MB
centos 7 eeb6ee3f44bd 14 months ago 204MB
2.3.3 构建业务镜像
创建 app1 和 app2 两个目录,表示基于 tomcat 自定义基础镜像构建出不同业务的 tomcat app 镜像
2.3.3.1 准备 Dockerfile
[root@localhost ~]# mkdir /opt/dockerfile/web/app{1,2}
[root@localhost ~]# cd /opt/dockerfile/web/app1
[root@localhost app1]# vim Dockerfile
FROM tomcat-base:v8.5.66
ADD run_tomcat.sh /apps/tomcat/bin/run_tomcat.sh
COPY myapp /apps/apache-tomcat-8.5.66/webapps/myapp
RUN chown -R www.www /apps
EXPOSE 8080
CMD ["/apps/tomcat/bin/run_tomcat.sh"]
#准备测试代码
[root@localhost app1]# mkdir myapp
[root@localhost app1]# echo tomcat8 >> myapp/index.html
#准备容器启动执行脚本
[root@localhost app1]# vim run_tomcat.sh
#!/bin/bash
su - www -c "/apps/tomcat/bin/catalina.sh start"
su - www -c "tail -f /etc/hosts"
[root@localhost app1]# chmod +x run_tomcat.sh
[root@localhost app1]# docker build -t tomcat-web:app1 .
#启动
[root@localhost app1]# docker run -itd -p 8080:8080 --rm tomcat-web:app1
#测试
[root@localhost app1]# curl 192.168.11.11:8080/myapp/ -I
HTTP/1.1 200
Accept-Ranges: bytes
[root@localhost app1]# curl 192.168.11.11:8080/myapp/
tomcat8
2.4 构建 haproxy 镜像
构建出 haproxy 镜像,将 haproxy 通过容器的方式运行
2.4.1 准备 Dockerfile
[root@localhost ~]# mkdir /opt/dockerfile/web/haproxy
[root@localhost ~]# cd /opt/dockerfile/web/haproxy
[root@localhost haproxy]# vim Dockerfile
FROM centos-base:v1
MAINTAINER KKK "xxx@xx.com"
RUN yum install -y libtermcap-devel ncurses-devel libevent-devel readline-devel gcc gcc-c++ glibc glibc-devel pcre pcre-devel openssl openssl-devel systemd-devel net-tools vim iotop bc zip unzip zlib-devel && yum clean all
ADD lua-5.4.3.tar.gz /usr/local/src/
RUN cd /usr/local/src/lua-5.4.3 \
&& make linux \
&& ln -s /usr/local/src/lua-5.4.3 /usr/local/lua \
&& ln -s /usr/local/lua/src/lua /sbin/
ADD haproxy-2.0.21.tar /usr/local/src/
RUN cd /usr/local/src/haproxy-2.0.21 \
&& make ARCH=x86_64 TARGET=linux-glibc USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1 SE_CPU_AFFINITY=1 USE_LUA=1 LUA_INC=/usr/local/lua/src/ LUA_LIB=/usr/local/lua/src/ PREFIX=/usr/local/haproxy \
&& make install PREFIX=/usr/local/haproxy
RUN rm -rf /usr/local/src/haproxy-2.0.21
[root@localhost haproxy]# ls
Dockerfile haproxy-2.0.21.tar lua-5.4.3.tar.gz
[root@localhost haproxy]# docker build -t haproxy-base:v1 .
[root@localhost haproxy]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
haproxy-base v1 3a0259ace422 6 minutes ago 531MB
tomcat-web app1 678f1108dbf4 About an hour ago 814MB
tomcat-base v8.5.66 dec5807b7450 2 hours ago 799MB
jdk-8u171 v1 ffb57035cac9 2 hours ago 785MB
centos-base v1 94b4af17162e 2 hours ago 397MB
centos 7 eeb6ee3f44bd 14 months ago 204MB
2.4.2 准备部署 haproxy-web:v1
[root@localhost ~]# mkdir /opt/dockerfile/web/haproxy-web1
[root@localhost ~]# cd /opt/dockerfile/web/haproxy-web1
#先启动两个web服务
[root@localhost haproxy-web1]# docker run -d -v /data1:/www --rm --name web01 busybox httpd -f -h /www
[root@localhost haproxy-web1]# docker run -d -v /data2:/www --rm --name web02 busybox httpd -f -h /www
[root@localhost haproxy-web1]# echo web011111111111 > /data1/index.html
[root@localhost haproxy-web1]# echo web0222222 > /data2/index.html
#获取容器的ip地址
[root@localhost haproxy-web1]# docker inspect web01 | grep IPaddress | tail -1
[root@localhost haproxy-web1]# docker inspect web01 | grep IPAddress | tail -1
"IPAddress": "172.17.0.3",
[root@localhost haproxy-web1]# docker inspect web02 | grep IPAddress | tail -1
"IPAddress": "172.17.0.4",
#测试网页
[root@localhost haproxy-web1]# curl 172.17.0.3
web011111111111
[root@localhost haproxy-web1]# curl 172.17.0.4
web0222222
#准备haproxy配置文件
[root@localhost haproxy-web1]# vim haproxy.cfg
global
maxconn 100000
chroot /usr/local/haproxy
stats socket /run/haproxy.sock
uid 99
gid 99
daemon
pidfile /run/haproxy.pid
log 127.0.0.1 local3 info
defaults
option http-keep-alive
option forwardfor
maxconn 100000
mode http
timeout connect 300000ms
timeout client 300000ms
timeout server 300000ms
#haproxy状态页
listen stats
mode http
bind 0.0.0.0:9999
stats enable
log global
stats hide-version
stats uri /haproxy-status
stats auth haadmin:123456
stats refresh 5s
stats admin if TRUE
listen web_host
bind 0.0.0.0:80
mode http
log global
balance static-rr
option forwardfor
server web1 172.17.0.3:80 weight 1 check inter 3000 fall 3 rise 5
server web2 172.17.0.4:80 weight 1 check inter 3000 fall 3 rise 5
#准备启动脚本
[root@localhost haproxy-web1]# vim run_haproxy.sh
#!/bin/bash
/usr/local/haproxy/sbin/haproxy -f /etc/haproxy/haproxy.cfg
tail -f /etc/hosts
[root@localhost haproxy-web1]# chmod +x run_haproxy.sh
[root@localhost haproxy-web1]# vim Dockerfile
FROM haproxy-base:v1
COPY haproxy.cfg /etc/haproxy/
COPY run_haproxy.sh /
EXPOSE 80 9999
CMD ["./run_haproxy.sh"]
#构建
[root@localhost haproxy-web1]# docker build -t haproxy-web1:v1 .
[root@localhost haproxy-web1]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
haproxy-web1 v1 fd11b90661a7 8 minutes ago 531MB
haproxy-base v1 3a0259ace422 18 hours ago 531MB
tomcat-web app1 678f1108dbf4 19 hours ago 814MB
tomcat-base v8.5.66 dec5807b7450 20 hours ago 799MB
jdk-8u171 v1 ffb57035cac9 20 hours ago 785MB
centos-base v1 94b4af17162e 20 hours ago 397MB
busybox latest 334e4a014c81 26 hours ago 4.86MB
centos 7 eeb6ee3f44bd 14 months ago 204MB
#运行
[root@localhost haproxy-web1]# docker run -d --rm --name testhaproxy -p 80:80 -p 9999:9999 haproxy-web1:v1
[root@localhost haproxy-web1]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dd5953b7e127 haproxy-web1:v1 "./run_haproxy.sh" 4 seconds ago Up 4 seconds 0.0.0.0:80->80/tcp, 0.0.0.0:9999->9999/tcp testhaproxy
60209110b401 busybox "httpd -f -h /www" 18 hours ago Up 18 hours web02
051bf18842cd busybox "httpd -f -h /www" 18 hours ago Up 18 hours web01
e7afd79f861c tomcat-web:app1 "/apps/tomcat/bin/ru…" 19 hours ago Up 19 hours 0.0.0.0:8080->8080/tcp lucid_golick
#测试
[root@localhost haproxy-web1]# curl 192.168.11.11
web011111111111
[root@localhost haproxy-web1]# curl 192.168.11.11
web0222222
[root@localhost haproxy-web1]# curl 192.168.11.11
web011111111111
[root@localhost haproxy-web1]# curl 192.168.11.11
web0222222
2.4.3 访问 haproxy 控制端
http://192.168.11.11:9999/haproxy-status
账号:haadmin
密码:123456