Docker学习(1)-Docker简介
Docker学习(2)-Docker基础1
Docker 镜像与制作
Docker 镜像内是否包含内核(bootfs)?
首先,从镜像的体积大小来说,一个比较小的镜像(alpine)只有几 MB,而内核文件需要一百多 MB, 因此镜像里面是没有内核的,镜像在被启动为容器后将直接使用宿主机的内核,而镜像本身则只提供相应的 rootfs,即系统正常运行所必须的用户空间的文件系统,比如/dev/,/proc,/bin,/etc 等目录,所以容器当中基本是没有/boot 目录的,而/boot 当中保存的就是与内核相关的文件和目录。
讨论论坛
Docker 镜像为什么没有提供内核?
若提供了内核,那么每个镜像的体积将至少一百 MB 以上,并且基于同一个基础镜像构建的镜像都有很大一部分冗余,容器的实质就是互相隔离的不同进程,也就是在用户空间运行的程序,而无需各自有自己的内核,共同使用主机的内
核即可。如果使用了内核,那么容器就不再是容器了,而属于虚拟机。
Docker 镜像存在的各个阶段和状态可以从下图看出:
Docker 镜像构建的过程就是一层一层新增内容的过程,其中每一层及其下面的所有层都可以构建为独立的镜像
构建镜像必须有一个引用的父镜像,一般的基础镜像(父镜像)均使用 Linux 某发行版官方提供的基础镜像,该基础镜像中包含了一个 Linux 操作用户空间所需的所有命令和资源。之后的业务镜像就可以在基础镜像上一层一层的构建。
手动构建 nginx 镜像
Docker 镜像的构建类似于虚拟机的模板制作,即按照公司的实际业务需求将需要安装的软件、相关配置等基础环境配置完成,然后将虚拟机再提交为模板,最后再批量从模板批量创建新的虚拟机,这样可以极大的简化业务中相同环境的虚拟机运行环境的部署工作。Docker的镜像构建分为手动构建和自动构建(基于DockerFile),企业通常都是基于 Dockerfile 构建镜像。
手动构建镜像实际上就是在创建并运行的基础容器中安装相应的软件和配置好相应的环境,并手动提交为新的镜像。大致过程如下:
下载镜像并初始化系统
基于某个基础镜像之上重新制作 因此需要先有一个基础镜像,本次使用 官方提供的 centos 镜像为基础:
root@Docker-1:~# docker pull centos:7.7.1908
root@Docker-1:~# docker run -it centos:7.7.1908 /bin/bash
[root@dc356876188e /]# yum install wget -y
[root@c1d6bea96f0b /]# cd /etc/yum.repos.d/
[root@c1d6bea96f0b yum.repos.d]# wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
[root@c1d6bea96f0b yum.repos.d]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
在容器中安装配置 nginx
[root@dc356876188e /]# yum install nginx -y
[root@dc356876188e /]# yum install -y vim pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop
关闭 nginx 默认的后台运行
[root@c1d6bea96f0b ~]# vim /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
daemon off; # 添加该行
......
编写测试网页
[root@c1d6bea96f0b ~]# vim /usr/share/nginx/html/index.html
[root@c1d6bea96f0b ~]# cat /usr/share/nginx/html/index.html
NGINX TEST
提交为镜像
# -a 指定镜像构建者信息,-m 指定注释信息,跟上容器ID,指定镜像仓库和标签TAG
root@Docker-1:~# docker commit -a "kaivi<likai.tech>" -m "nginx test image-1" c1d6bea96f0b nginx-1.16.1:manual-conf
sha256:5e2756b81617ad28e51f7c101ca5981594d9d865d1970e0fbca412175db89795root@Docker-1:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx-1.16.1 manual-conf 5e2756b81617 24 seconds ago 459MB
从新构建的 nginx 镜像启动容器
root@Docker-1:~# docker run -it -p 8080:80 5e2756b81617 nginx
。。。 #在后端运行root@Docker-1:~# tty
/dev/pts/1
root@Docker-1:~# ss -ntl |grep 8080
LISTEN 0 20480 *:8080 *:*
访问测试
基于 Dockerfile 构建编译版 nginx 镜像
DockerFile 是一种可以被 Docker 程序解释的规格文件,DockerFile 由一条条命令组成,每条命令对应 linux 下面的一条命令,Docker 程序将这些 Dockerfile指令再翻译成真正的 linux 命令,其有自己的书写方式和支持的命令,Docker 程序读取 DockerFile 并根据指令生成 Docker 镜像,相比手动制作镜像的方式,DockerFile 更能直观的展示镜像是怎么产生的,有了写好的各种各样 DockerFile文件,当后期某个镜像有额外的需求时,只要在之前的 DockerFile 添加或者修改相应的操作即可重新生成新的 Docke 镜像,避免了重复手动制作镜像的麻烦。使用Dockerfile 构建镜像大体分为后面涉及的步骤。
一般来说,在 Dockerfile 中能够调用的命令在普通的终端中都可以调用。
一般 Dockerfile 包括以下的指令,这些指令都是放在每行的开头:
https://docs.docker.com/engine/reference/builder/#参考文献
FROM
FROM [--platform=<platform>] <image> [AS <name>]
Or
FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
Or
FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]
# FROM 指令用于引用基础镜像(父镜像),一般该指令位于Dockerfile的第一行(#开头的注释不算),
# 但是ARG指令可以在FROM之前。ARG
ARG <name>[=<default value>]
# ARG 指令用于声明变量,在使用docker build构建镜像时可以使用--build-arg <var>=<value>
# 来指定所声明的变量RUN
# 该命令最常使用,用来运行常见的命令(在终端能用的命令其都能解析)。
# RUN 指令有两种形式来运行命令:# 1.使用shell运行命令:
RUN <command> :(默认使用/bin/sh -c运行该command,如果在windows则使用cmd /S /C运行该command)# 2. 使用可执行文件执行,该情况下不会调用shell,需要指定使用什么可执行文件来执行命令
RUN ["executable", "param1", "param2"] :(exec 形式)需要先指定一个可执行文件,再指定参数ADD
ADD [--chown=<user>:<group>] <src>... <dest>
# ADD 指令用于向镜像添加文件或者目录,如果是打包和压缩格式(.tar.gz/.tar.xz/.tar.bz2),则
# 该命令会解压,但是(.zip)文件在添加前需要先安装unzip工具。可以指定多个源,ADD 默认将这些
# 源的路径处理为在当前构建镜像的目录中,并且彼此之间是相对路径关系。COPY
COPY [--chown=<user>:<group>] <src>... <dest>
# COPY 指令用于复制文件到镜像,不会解压。ENV
ENV <key> <value>
ENV <key>=<value> ...
# ENV 指令用于设置镜像启动为容器时的环境变量。EXPOSE
EXPOSE <port> [<port>/<protocol>...]
# 该指令用于向主机暴露端口,后面直接接端口,多个用空格分隔。LABEL
LABEL <key>=<value> <key>=<value> <key>=<value> ...
# LABEL 用于指定该镜像的作者信息。
# 如:
LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates that label-values can span multiple lines."STOPSIGNAL
STOPSIGNAL signal
# 该指令用来设置使得容器退出的信号USER
USER <user>[:<group>] or
USER <UID>[:<GID>]
# 用来指定在Dockerfile中的指令随后以什么身份运行,如果没有该用户,默认使用root
# 该指令一般不用VOLUME
# 该指令用来创建一个挂载点,并标记为其挂载本地主机卷或者其它的容器卷。
VOLUME ["/data"]WORKDIR
WORKDIR /path/to/workdir
# 为其后的RUN, CMD, ENTRYPOINT, COPY and ADD等指令设置工作文件夹,不存在则创建。
Dockerfile 的格式约定:
# Comment
INSTRUCTION arguments
Dockerfile 使用#号作为注释符,在行中间的#号不视为注释,而视为参数
INSTRUCTION Dockerfile 指令,不区分大小写,约定使用大写
arguments 每个指令的参数,最常见的就是各种常用的 linux 基础命令
另外,第一行指令必须是FROM,指定该镜像时基于哪一个父镜像构建。
# test build
FROM centos:latest
RUN ...
RUN ...
除非使用ARG指令声明的变量,导致FROM指令不在第一行
ARG CODE_VERSION=latest
FROM base:${CODE_VERSION}
CMD /code/run-app
...
RUN指令在 Dockerfile 中大量使用,一般用法是直接跟命令
# test build
FROM centos:latest# 一般像下面这样使用
RUN /usr/bin/mkdir -p /usr/local/nginx/conf.d
RUN ...
但是也可以使用下面的格式,使用列表将命令和参数传给RUN指令
# test build
FROM centos:latest# 也可以像下面这样使用
RUN ["/bin/bash", "-c", "/usr/bin/mkdir -p /usr/local/nginx/conf.d"]
RUN ...
更详细的用法参考官方说明:
https://docs.docker.com/engine/reference/builder/#Dockerfile官方说明
https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#编写Dockerfile的最佳实践
下载 centos 基础镜像
~$ docker pull centos:7.5.1804
编辑 Dockerfile
root@Docker-1:~# cd /opt/
root@Docker-1:/opt# mkdir dockerfile/nginx -p
root@Docker-1:/opt# cd dockerfile/nginx/
root@Docker-1:/opt/dockerfile/nginx# vim Dockerfile #生成的镜像的时候会在执行命令的当前目录查找Dockerfile 文件,所以名称不可写错,而且D必须大写
#Dcoker image for installation of nginx
#
FROM centos:7.7.1908LABEL maintainer="kaivi <www.likai.tech>"ENV password 123456RUN rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpmRUN yum install -y vim wget tree lrzsz gcc gcc-c++ automake pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop unzipADD nginx-1.16.1.tar.gz /usr/local/srcRUN cd /usr/local/src/nginx-1.16.1 && ./configure --prefix=/usr/local/nginx --with-http_sub_module && make && make installRUN cd /usr/local/nginxADD nginx.conf /usr/local/nginx/conf/nginx.confRUN useradd nginx -s /sbin/nologinRUN ln -sv /usr/local/nginx/sbin/nginx /usr/sbin/nginx
# 用于访问验证是否成功
RUN echo "kaivi Dockerfile test ..." > /usr/local/nginx/html/index.htmlEXPOSE 80 443CMD ["/usr/local/nginx","-g","daemon off;"]
# 指定基于该镜像启动容器后容器执行的运行的命令,每个Dockerfile只能有一条,
# 如果有多条则只有最后一条被执行
如果在从该镜像启动容器的时候也指定了命令,那么指定的命令会覆盖 Dockerfile构建的镜像里面的 CMD 命令,即指定的命令优先级更高,Dockerfile 的优先级较低一些。
准备源码包和配置文件
把另外编译的nginx配置文件拷贝到当前文件夹以及nginx的二进制安装包
root@Docker-1:/opt/dockerfile/nginx# cp /etc/nginx/nginx.conf .
root@Docker-1:/opt/dockerfile/nginx# cp /usr/local/src/nginx-1.16.1.tar.gz .
root@Docker-1:/opt/dockerfile/nginx# ll
total 1028
drwxr-xr-x 2 root root 4096 Apr 18 02:04 ./
drwxr-xr-x 3 root root 4096 Apr 18 00:26 ../
-rw-r--r-- 1 root root 816 Apr 18 01:31 Dockerfile
-rw-r--r-- 1 root root 1032630 Apr 18 01:37 nginx-1.16.1.tar.gz
-rw-r--r-- 1 root root 1482 Apr 18 02:04 nginx.conf
nginx.conf文件可以先二进制编制之后把默认的配置文件拷贝过来
构建镜像
使用docker build命令构建镜像,构建镜像时该命令需要指定 Dockerfile 和构建镜像所需要的上下文(context),这里的上下文就是构建过程需要的各种文件。
构建镜像详细说明参看: Docker-builder
# -t 选项给新镜像指定仓库和标签(REPOSITORY:TAG)
# 该种用法表示dockerd会在当前目录找需要的上下文(文件)和Dockerfile
# 也可以使用-f选项指定Dockerfile文件位置
root@Docker-1:/opt/dockerfile/nginx# docker build -t nginx:v5 .
Sending build context to Docker daemon 1.038MB
Step 1/14 : FROM centos:7.7.1908---> 08d05d1d5859
Step 2/14 : LABEL maintainer="kaivi <www.likai.tech>"---> Using cache---> ece8e70c6653
Step 3/14 : ENV password 123456---> Using cache---> 9ef6fa101697
Step 4/14 : RUN rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm---> Using cache---> 71273d2c5cf9
Step 5/14 : RUN yum install -y vim wget tree lrzsz gcc gcc-c++ automake pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop unzip---> Using cache---> 6df38382d6f2
Step 6/14 : ADD nginx-1.16.1.tar.gz /usr/local/src---> Using cache---> ecf174bb26f0
Step 7/14 : RUN cd /usr/local/src/nginx-1.16.1 && ./configure --prefix=/usr/local/nginx --with-http_sub_module && make && make install---> Using cache---> 424d883a0282
Step 8/14 : RUN cd /usr/local/nginx---> Using cache---> 512ac72429ae
Step 9/14 : ADD nginx.conf /usr/local/nginx/conf/nginx.conf---> 4bbf57ca373b
Step 10/14 : RUN useradd nginx -s /sbin/nologin---> Running in a78f7495f355
Removing intermediate container a78f7495f355---> 916eacfe2ae2
Step 11/14 : RUN ln -sv /usr/local/nginx/sbin/nginx /usr/sbin/nginx---> Running in 223b65d849d9
'/usr/sbin/nginx' -> '/usr/local/nginx/sbin/nginx'
Removing intermediate container 223b65d849d9---> c4488baeef5e
Step 12/14 : RUN echo "kaivi Dockerfile test ..." > /usr/local/nginx/html/index.html---> Running in 640bbdd8905e
Removing intermediate container 640bbdd8905e---> 91d95b58c8e1
Step 13/14 : EXPOSE 80 443---> Running in 52dcea1975d1
Removing intermediate container 52dcea1975d1---> 4f488f04781a
Step 14/14 : CMD ["/usr/local/nginx","-g","daemon off;"]---> Running in 661dc57033ff
Removing intermediate container 661dc57033ff---> 217964547b78
Successfully built 217964547b78
Successfully tagged nginx:v5
# 构建完成
使用 ARG 声明变量,在构建时指定变量值
# 使用ARG声明一个叫base_version的变量
#Dcoker image for installation of nginx
#
ARG base_version# 定义变量
#FROM centos:7.5.1804
FROM ${base_version}# 使用变量
# 使用--build-arg 指定变量base_version的值为centos:7.7.1909
root@Docker-1:/opt/dockerfile/nginx#docker build --build-arg base_version=centos:7.7.1909 -t nginx:v5 .
查看已构建镜像
root@Docker-1:/opt/dockerfile/nginx# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v5 8b90ac5358a3 20 seconds ago 544MB
从构建的镜像启动容器
root@Docker-1:/opt/dockerfile/nginx# docker run -it --rm nginx:v5 /bin/bash
[root@5a536cb4b109 /]# ls
anaconda-post.log bin dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
[root@5a536cb4b109 /]# pwd
/
[root@5a536cb4b109 /]# cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2 5a536cb4b109
[root@5a536cb4b109 /]# ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
[root@5a536cb4b109 /]# /usr/local/nginx/sbin/nginx
[root@5a536cb4b109 /]# ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:80 *:*
[root@5a536cb4b109 /]# exit
后台启动容器
root@Docker-1:~# docker run -it -d -p80:80 nginx:v5 /bin/bash
b0b805d0029b35392b23fc3e7803cd72f0a492ed4af01313f2533803d5b10bc2
root@Docker-1:~# ss -ntl |grep 80
LISTEN 0 20480 *:80 *:*
#后面不加/bin/bash会出现container_linux.go:349的报错
访问测试
root@Docker-1:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b0b805d0029b nginx:v5 "/bin/bash" About a minute ago Up About a minute 443/tcp, 0.0.0.0:80->80/tcp elegant_murdockroot@Docker-1:~# docker exec -it b0b805d0029b bash
[root@b0b805d0029b /]# cd /usr/local/nginx/html/
[root@b0b805d0029b html]# vim index.html
[root@b0b805d0029b html]# cat index.html
kaivi Dockerfile test ...
[root@b0b805d0029b html]# /usr/local/nginx/sbin/nginx
[root@b0b805d0029b html]# ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:80 *:*
在构建镜像时 Docker 启动了相应的容器
Docker 在构建镜像时,实际上启动了相应的容器,每运行一个 Dockerfile 中的指令就相当于新开了一个镜像(中间层),最后一条指令运行后会将运行的容器提交为镜像。下面就记录了不同的镜像构建时间,镜像的 ID 会不同,也就是每运行一个指令,镜像ID 就变一次。
手动构建编译版 nginx 镜像
过程为在 centos 基础 镜像之上手动编译安装 nginx ,然后再提交为镜像。
下载并初始化系统
root@Docker-1:~# docker pull centos:7.7.1908
root@Docker-1:~# docker run -it docker.io/centos:7.7.1908 /bin/bash
[root@77bb67f4452e /]# yum install wget -y
[root@77bb67f4452e /]# rm /etc/yum.repos.d/*
rm: remove regular file '/etc/yum.repos.d/CentOS-Base.repo'? y
rm: remove regular file '/etc/yum.repos.d/CentOS-CR.repo'? y
rm: remove regular file '/etc/yum.repos.d/CentOS-Debuginfo.repo'? y
rm: remove regular file '/etc/yum.repos.d/CentOS-Media.repo'? y
rm: remove regular file '/etc/yum.repos.d/CentOS-Sources.repo'? y
rm: remove regular file '/etc/yum.repos.d/CentOS-Vault.repo'? y
rm: remove regular file '/etc/yum.repos.d/CentOS-fasttrack.repo'? y
[root@77bb67f4452e /]# wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
[root@77bb67f4452e /]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
在容器编译安装 nginx
[root@77bb67f4452e /]# yum install -y unzip vim gcc gcc-c++ automake lrzsz pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop
[root@77bb67f4452e /]# wget http://nginx.org/download/nginx-1.16.1.tar.gz
[root@77bb67f4452e /]# tar xvf nginx-1.16.1.tar.gz
[root@77bb67f4452e /]# cd nginx-1.16.1
[root@77bb67f4452e nginx-1.16.1]# ./configure --prefix=/apps/nginx --with-http_sub_module
[root@77bb67f4452e nginx-1.16.1]# make && make install
nginx 配置
关闭后台运行
[root@77bb67f4452e nginx-1.16.1]# cd /apps/nginx/
[root@77bb67f4452e nginx]# vim conf/nginx.conf
user nginx;
worker_processes auto;
daemon off; # 新增该行
...
[root@77bb67f4452e nginx]# ln -sv /apps/nginx/sbin/nginx /usr/sbin/nginx
'/usr/sbin/nginx' -> '/apps/nginx/sbin/nginx'
定义 html 测试界面
[root@77bb67f4452e nginx]# vim html/index.html
<DOCTYPE html />
<head><h1>Hello World Docker</h1>
</head>
<body><p>This is a test...</p>
</body>
创建用户和授权
[root@77bb67f4452e nginx]# useradd -u 2020 nginx -s /sbin/nologin [root@77bb67f4452e nginx]# chown nginx.nginx /apps/nginx/ -R
新开终端提交为镜像
root@Docker-1:~# tty
/dev/pts/1
root@Docker-1:~# docker commit -a "kaivi<www.likai.tech>" -m "nginx test images" 77bb67f4452e nginx:vv1
sha256:07f3f714d8cb065a0be0af1fa0ca9b70f356a7f23e47bed43166c9fb0033a69f
root@Docker-1:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx vv1 07f3f714d8cb 17 seconds ago 522MB
......
启动镜像
root@Docker-1:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx vv1 07f3f714d8cb 17 seconds ago 522MB
nginx v1 66c2720f919d 28 minutes ago 544MB
nginx-1.16.1 manual-conf 5e2756b81617 10 hours ago 459MB
nginx 1.16.1 16af99d71a72 40 hours ago 127MB
alpine latest a187dde48cd2 3 weeks ago 5.6MB
centos latest 470671670cac 3 months ago 237MB
centos 7.7.1908 08d05d1d5859 5 months ago 204MB
root@Docker-1:~# docker run -it -p 82:80 nginx:vv1 nginx
#最后面的 nginx 是运行的命令,即镜像里面要运行一个 nginx 命令,所以才有了前面将
#/usr/local/nginx/sbin/nginx 软连接到 /usr/sbin/nginx ,目的就是为了让系统可以执行此命令。
访问测试查看日志
root@Docker-1:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
670ec45ceb99 nginx:vv1 "nginx" About a minute ago Up About a minute 0.0.0.0:82->80/tcp affectionate_kare
77bb67f4452e centos:7.7.1908 "/bin/bash" 20 minutes ago Up 20 minutes festive_mcclintock
ea18f12e6b70 nginx:v1 "/bin/bash" 30 minutes ago Up 30 minutes 86/tcp, 0.0.0.0:80->80/tcp, 443/tcp cocky_saha
root@Docker-1:~# docker logs -f 670ec45ceb99
......
构建 Tomcat 业务镜像
在构建基于 tomcat 的业务镜像时,首先需要基于官方提供的 centos、debain、ubuntu、alpine 等基础镜像构建 JDK(Java 环境),然后再基于自定义的 JDK 镜像构建出业务需要的 tomcat 镜像。
构建 JDK 镜像
先基于官方提供的基础镜像,制作出安装了常用命令的自定义基础镜像,然后在基础镜像的基础之上,再制作 JDK 镜像、Tomcat 镜像等。业务镜像存放目录规整:
root@Docker-1:~# mkdir -pv /opt/dockerfile/{web/{nginx,tomcat,jdk,apache},system/{centos,ubuntu,redhat}}
mkdir: created directory '/opt/dockerfile/web'
mkdir: created directory '/opt/dockerfile/web/nginx'
mkdir: created directory '/opt/dockerfile/web/tomcat'
mkdir: created directory '/opt/dockerfile/web/jdk'
mkdir: created directory '/opt/dockerfile/web/apache'
mkdir: created directory '/opt/dockerfile/system'
mkdir: created directory '/opt/dockerfile/system/centos'
mkdir: created directory '/opt/dockerfile/system/ubuntu'
mkdir: created directory '/opt/dockerfile/system/redhat'
自定义 Centos 基础镜像
编写 Dockerfile 和构建脚本
root@Docker-1:~# docker pull centos:7.7.1908
root@Docker-1:~# cd /opt/dockerfile/system/centos
root@Docker-1:/opt/dockerfile/system/centos#vim Dockerfile
# CentOS base image , installed tools and created www user.ARG base_versionFROM centos:7.7.1908LABEL author="kaivi" \personal_site="www.likai.tech"RUN rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm# install epel repo from aliyun.comRUN yum install -y vim wget tree lrzsz gcc gcc-c++ automake pcre pcre-devel \zlib zlib-devel openssl openssl-devel iproute net-tools iotop# install basic tools for centosRUN groupadd www -g 2022 && useradd www -u 2022 -g www# create www user and www group
# 构建脚本
#!/bin/bashV="centos:7.7.1908"docker build -t centos-base:v1 . # 注意在当前目录构建
构建过程
root@Docker-1:/opt/dockerfile/system/centos# bash docker_build.sh
......
Complete!
Removing intermediate container bcc5cdd3ac84---> b80b6d13d6c2
Step 6/6 : RUN groupadd www -g 2022 && useradd www -u 2022 -g www---> Running in cac77aefe297
Removing intermediate container cac77aefe297---> 5fc2d6909f65
Successfully built 5fc2d6909f65
Successfully tagged centos-base:v1
查看构建的 centos 基础镜像
root@Docker-1:/opt/dockerfile/system/centos# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos-base v1 5fc2d6909f65 30 seconds ago 522MB
基于 Centos 基础镜像构建 JDK 镜像
准备 Dockerfile 文件
# JDK base image , based on centos-base:v1FROM centos-base:v1LABEL author="kaivi" \personal_site="www.likai.tech"ADD jdk-8u241-linux-x64.tar.gz /usr/local/srcRUN ln -sv /usr/local/src/jdk1.8.0_241 /usr/local/jdkADD profile /etc/profileENV JAVA_HOME /usr/local/jdk
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib:$JRE_HOME/lib
ENV PATH $PATH:$JAVA_HOME/bin# set java related env varRUN rm -rf /etc/localtime && ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \&& echo "Asia/Shanghai" > /etc/timezone# set time zone to Shanghai
~
准备 JDK 和 profile 文件
root@Docker-1:/opt/dockerfile/system/centos# cd /opt/dockerfile/web/jdk/
root@Docker-1:/opt/dockerfile/web/jdk# cp /etc/profile .
root@Docker-1:/opt/dockerfile/web/jdk# vim profile # /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
# and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).if [ "${PS1-}" ]; thenif [ "${BASH-}" ] && [ "$BASH" != "/bin/sh" ]; then# The file bash.bashrc already sets the default PS1.# PS1='\h:\w\$ 'if [ -f /etc/bash.bashrc ]; then. /etc/bash.bashrcfielseif [ "`id -u`" -eq 0 ]; thenPS1='# 'elsePS1='$ 'fifi
fiif [ -d /etc/profile.d ]; thenfor i in /etc/profile.d/*.sh; doif [ -r $i ]; then. $ifidoneunset i
fiexport JAVA_HOME="/usr/local/jdk"
export JRE_HOME="$JAVA_HOME/jre"
export CLASSPATH="$JAVA_HOME/lib:$JRE_HOME/lib"
export PATH="$PATH:$JAVA_HOME/bin"
准备构建脚本
root@Docker-1:/opt/dockerfile/web/jdk# vim docker_build.sh
\root@Docker-1:/opt/dockerfile/web/jdk# cat docker_build.sh
#!/bin/bashdocker build -t jdk-base:v8.241 .
构建
root@Docker-1:/opt/dockerfile/web/jdk# ll
total 190008
drwxr-xr-x 2 root root 4096 Apr 18 11:54 ./
drwxr-xr-x 6 root root 4096 Apr 18 10:39 ../
-rw-r--r-- 1 root root 47 Apr 18 11:36 docker_build.sh
-rw-r--r-- 1 root root 581 Apr 18 10:54 Dockerfile
-rw-r--r-- 1 root root 194545143 Apr 18 11:51 jdk-8u241-linux-x64.tar.gz
-rw-r--r-- 1 root root 732 Apr 18 11:35 profile
root@Docker-1:/opt/dockerfile/web/jdk# bash docker_build.sh
Sending build context to Docker daemon 194.6MB
Step 1/10 : FROM centos-base:v1---> 5fc2d6909f65
Step 2/10 : LABEL author="kaivi" personal_site="www.likai.tech"---> Running in 8dedfdef43ef
Removing intermediate container 8dedfdef43ef---> 7d14621a9581
Step 3/10 : ADD jdk-8u241-linux-x64.tar.gz /usr/local/src---> e492b88d17af
Step 4/10 : RUN ln -sv /usr/local/src/jdk1.8.0_241 /usr/local/jdk---> Running in d8242b5f8036
'/usr/local/jdk' -> '/usr/local/src/jdk1.8.0_241'
Removing intermediate container d8242b5f8036---> 0d3449d54998
Step 5/10 : ADD profile /etc/profile---> 8ffc5ab1f947
Step 6/10 : ENV JAVA_HOME /usr/local/jdk---> Running in b133b7663668
Removing intermediate container b133b7663668---> 53b3e7c19b91
Step 7/10 : ENV JRE_HOME $JAVA_HOME/jre---> Running in 0fbe0c83238c
Removing intermediate container 0fbe0c83238c---> cee812ece223
Step 8/10 : ENV CLASSPATH $JAVA_HOME/lib:$JRE_HOME/lib---> Running in c1685eccba5d
Removing intermediate container c1685eccba5d---> 407f7a82f638
Step 9/10 : ENV PATH $PATH:$JAVA_HOME/bin---> Running in b92f23603351
Removing intermediate container b92f23603351---> 09cb81e4162a
Step 10/10 : RUN rm -rf /etc/localtime && ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo "Asia/Shanghai" > /etc/timezone---> Running in 8f2a08bf7875
Removing intermediate container 8f2a08bf7875---> 0bb10498e7d1
Successfully built 0bb10498e7d1
Successfully tagged jdk-base:v8.241
# 构建成功
查看构建的镜像
root@Docker-1:/opt/dockerfile/web/jdk# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
jdk-base v8.241 0bb10498e7d1 2 minutes ago 926MB
centos-base v1 5fc2d6909f65 About an hour ago 522MB
启动容器进入验证 JKD 环境
root@Docker-1:~# docker run -it jdk-base:v8.241 /bin/bash
[root@1453b7367e51 /]# java -version
java version "1.8.0_241"
Java(TM) SE Runtime Environment (build 1.8.0_241-b07)
Java HotSpot(TM) 64-Bit Server VM (build 25.241-b07, mixed mode)
[root@1453b7367e51 /]# env
HOSTNAME=1453b7367e51
TERM=xterm
JRE_HOME=/usr/local/jdk/jre
。。。。。。
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/jdk/bin
PWD=/
JAVA_HOME=/usr/local/jdk
SHLVL=1
HOME=/root
CLASSPATH=/usr/local/jdk/lib:/usr/local/jdk/jre/lib
_=/usr/bin/env[root@1453b7367e51 /]# ll /etc/profile # 查看profile文件
-rw-r--r-- 1 root root 732 Apr 18 11:35 /etc/profile[root@1453b7367e51 /]# date # 验证时间是否同步
Sat Apr 18 11:59:41 CST 2020
[root@1453b7367e51 /]# root@Docker-1:~# date
Sat Apr 18 11:59:51 CST 2020
基于 JDK 镜像构建 Tomcat8 镜像
基于前面自定义的 JDK 基础镜像,构建出通用的自定义 Tomcat 基础镜像,此镜像后期会被多个业务的多个服务共同引用(这些业务的运行环境需要相同的 JDK 版本和 相同的 Tomcat 版本)。
编辑 Dockerfile
root@Docker-1:/opt/dockerfile/web/jdk# cd /opt/dockerfile/web/tomcat/
root@Docker-1:/opt/dockerfile/web/tomcat# vim Dockerfile
# tomcat image FROM jdk-base:v8.241LABEL author="kaivi" \personal_site="www.likai.tech"# set some env vars
ENV TZ "Asia/Shanghai"
ENV LANG en_US.UTF-8
ENV TOMCAT_MAJOR_VERSION 8
ENV TOMCAT_MINOR_VERSION 5.54
ENV CATALINA_HOME /apps/tomcat
ENV APP_DIR ${CATALINA_HOME}/webapps# install tomcat binary package
RUN mkdir /apps
ADD apache-tomcat-8.5.54.tar.gz /apps
RUN ln -sv /apps/apache-tomcat-8.5.54 /apps/tomcat
准备 tomcat 二进制包和构建脚本
# 上传tomcat二进制包
root@Docker-1:/opt/dockerfile/web/tomcat# rz -E
# 构建脚本
root@Docker-1:/opt/dockerfile/web/tomcat# vim docker_build.sh
#!/bin/bashdocker build -t tomcat-base:v8.5.54 .
# 加执行权限
root@Docker-1:/opt/dockerfile/web/tomcat# chmod a+x docker_build.sh
root@Docker-1:/opt/dockerfile/web/tomcat# ll
total 10088
drwxr-xr-x 2 root root 4096 Apr 18 12:11 ./
drwxr-xr-x 6 root root 4096 Apr 18 10:39 ../
-rw-r--r-- 1 root root 10312541 Apr 18 11:46 apache-tomcat-8.5.54.tar.gz
-rwxr-xr-x 1 root root 51 Apr 18 12:11 docker_build.sh*
-rw-r--r-- 1 root root 444 Apr 18 12:09 Dockerfile
构建镜像
root@Docker-1:/opt/dockerfile/web/tomcat# ./docker_build.sh
Sending build context to Docker daemon 10.32MB
Step 1/11 : FROM jdk-base:v8.241---> 0bb10498e7d1
Step 2/11 : LABEL author="kaivi" personal_site="www.likai.tech"---> Running in af58171ff0d9
Removing intermediate container af58171ff0d9---> dc4cca941fb4
Step 3/11 : ENV TZ "Asia/Shanghai"---> Running in 8b745284a1c1
Removing intermediate container 8b745284a1c1---> cd02c205bc5a
Step 4/11 : ENV LANG en_US.UTF-8---> Running in 1b8ddfb3cb76
Removing intermediate container 1b8ddfb3cb76---> 8480e037032f
Step 5/11 : ENV TOMCAT_MAJOR_VERSION 8---> Running in 9147df041bce
Removing intermediate container 9147df041bce---> 259e3c44b36c
Step 6/11 : ENV TOMCAT_MINOR_VERSION 5.54---> Running in fde56402e295
Removing intermediate container fde56402e295---> 04cde29ce6a8
Step 7/11 : ENV CATALINA_HOME /apps/tomcat---> Running in 09a5df706b38
Removing intermediate container 09a5df706b38---> 439b870c4b70
Step 8/11 : ENV APP_DIR ${CATALINA_HOME}/webapps---> Running in 6ec66e1a64ac
Removing intermediate container 6ec66e1a64ac---> 1ba75797abe6
Step 9/11 : RUN mkdir /apps---> Running in 57e980c3e2cb
Removing intermediate container 57e980c3e2cb---> 73000ce8f8fd
Step 10/11 : ADD apache-tomcat-8.5.54.tar.gz /apps---> c5f222f366ee
Step 11/11 : RUN ln -sv /apps/apache-tomcat-8.5.54 /apps/tomcat---> Running in bf3ea7a2e875
‘/apps/tomcat’ -> ‘/apps/apache-tomcat-8.5.54’
Removing intermediate container bf3ea7a2e875---> ec58914afd67
Successfully built ec58914afd67
Successfully tagged tomcat-base:v8.5.54
# 构建成功
验证
查看镜像和启动为容器
root@Docker-1:/opt/dockerfile/web/tomcat# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat-base v8.5.54 ec58914afd67 47 seconds ago 940MB
jdk-base v8.241 0bb10498e7d1 18 minutes ago 926MB
centos-base v1 5fc2d6909f65 About an hour ago 522MBroot@Docker-1:/opt/dockerfile/web/tomcat# docker run -it --rm tomcat-base:v8.5.54 /bin/bash[root@1a2873f7fc4b /]# ll /apps/tomcat/bin/catalina.sh
-rwxr-x--- 1 root root 24397 Apr 3 22:07 /apps/tomcat/bin/catalina.sh[root@1a2873f7fc4b /]# cd /apps/tomcat/bin/[root@1a2873f7fc4b bin]# ./catalina.sh start
Using CATALINA_BASE: /apps/tomcat
Using CATALINA_HOME: /apps/tomcat
Using CATALINA_TMPDIR: /apps/tomcat/temp
Using JRE_HOME: /usr/local/jdk/jre
Using CLASSPATH: /apps/tomcat/bin/bootstrap.jar:/apps/tomcat/bin/tomcat-juli.jar
Tomcat started.[root@1a2873f7fc4b bin]# ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 1 127.0.0.1:8005 *:*
LISTEN 0 100 *:8080 *:*
构建业务镜像
基于前面构建的 tomcat-base 镜像构建业务镜像。分别创建 app1 和 app2 两个目录表示不同的业务项目。
业务镜像 1
准备 Dockerfile
root@Docker-1:/opt/dockerfile/web/tomcat# mkdir tomcat-{app1,app2} -pv
mkdir: created directory 'tomcat-app1'
mkdir: created directory 'tomcat-app2'
root@Docker-1:/opt/dockerfile/web/tomcat# cd tomcat-app1/
root@Docker-1:/opt/dockerfile/web/tomcat/tomcat-app1# pwd
/opt/dockerfile/web/tomcat/tomcat-app1
root@Docker-1:/opt/dockerfile/web/tomcat/tomcat-app1# vim Dockerfile# Tomcat webapp deploy imageFROM tomcat-base:v8.5.54LABEL author="kaivi" \personal_site="www.likai.tech"# add a script to /tomcat/bin to start tomcat when container start
ADD run_tomcat.sh /apps/tomcat/bin/run_tomcat.sh# add business code to /tomcat/webapps/
ADD app1/* /apps/tomcat/webapps/app1/RUN chown www.www /apps/ -R# expose ports
EXPOSE 8080 8005 8009# run tomcat when container start
CMD ["/apps/tomcat/bin/run_tomcat.sh"]
准备容器启动时启动 tomcat 的脚本
root@Docker-1:/opt/dockerfile/web/tomcat/tomcat-app1# vim run_tomcat.sh
#!/bin/bashecho "172.20.32.101 duanxin.io" >> /etc/hosts
echo "nameserver 223.6.6.6" >> /etc/resolv.confsu - www -c "/apps/tomcat/bin/catalina.sh start"
su - www -c "tail -f /etc/hosts"root@Docker-1:/opt/dockerfile/web/tomcat/tomcat-app1# chmod a+x run_tomcat.sh
编写 app1 测试页面
root@Docker-1:/opt/dockerfile/web/tomcat/tomcat-app1# mkdir app1
root@Docker-1:/opt/dockerfile/web/tomcat/tomcat-app1# vim app1/index.html
<DOCTYPE HTML/>
<head><h1>A TEST for Tomcat app1 <h1/>
<head/>
<body><p>Tomcat app1 test...<span>NICE!<span/><p/>
<body/>
准备容器构建脚本
root@Docker-1:/opt/dockerfile/web/tomcat/tomcat-app1# vim docker_build.sh
#!/bin/bashdocker build -t tomcat:app1 .root@Docker-1:/opt/dockerfile/web/tomcat/tomcat-app1# chmod a+x docker_build.sh
构建
root@Docker-1:/opt/dockerfile/web/tomcat/tomcat-app1# ll
total 24
drwxr-xr-x 3 root root 4096 Apr 18 12:28 ./
drwxr-xr-x 4 root root 4096 Apr 18 12:17 ../
drwxr-xr-x 2 root root 4096 Apr 18 12:26 app1/
-rwxr-xr-x 1 root root 44 Apr 18 12:28 docker_build.sh*
-rw-r--r-- 1 root root 485 Apr 18 12:20 Dockerfile
-rwxr-xr-x 1 root root 281 Apr 18 12:23 run_tomcat.sh*
root@Docker-1:/opt/dockerfile/web/tomcat/tomcat-app1# ./docker_build.sh
Sending build context to Docker daemon 5.632kB
Step 1/7 : FROM tomcat-base:v8.5.54---> ec58914afd67
Step 2/7 : LABEL author="kaivi" personal_site="www.likai.tech"---> Running in 44260dc1d930
Removing intermediate container 44260dc1d930---> 8509c73764ec
Step 3/7 : ADD run_tomcat.sh /apps/tomcat/bin/run_tomcat.sh---> 7abca622da74
Step 4/7 : ADD app1/* /apps/tomcat/webapps/app1/---> d8480dca21ac
Step 5/7 : RUN chown www.www /apps/ -R---> Running in 9b07147f8ddd
Removing intermediate container 9b07147f8ddd---> 4024c3d41a24
Step 6/7 : EXPOSE 8080 8005 8009---> Running in 21f89a17a3c0
Removing intermediate container 21f89a17a3c0---> 8b0cd44d07dc
Step 7/7 : CMD ["/apps/tomcat/bin/run_tomcat.sh"]---> Running in 381e94d0d825
Removing intermediate container 381e94d0d825---> ca80466f5f71
Successfully built ca80466f5f71
Successfully tagged tomcat:app1
# 构建成功
从镜像启动容器
root@Docker-1:/opt/dockerfile/web/tomcat/tomcat-app1# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat app1 ca80466f5f71 33 seconds ago 954MB
tomcat-base v8.5.54 ec58914afd67 16 minutes ago 940MB
jdk-base v8.241 0bb10498e7d1 34 minutes ago 926MB
root@Docker-1:/opt/dockerfile/web/tomcat/tomcat-app1# docker run -it -d -p8080:8080 tomcat:app1
1d3b8cbb284dd808b183e07c4f55f5c3000f7b222005d5268e4812edc9a3e497root@Docker-1:/opt/dockerfile/web/tomcat/tomcat-app1# ss -ntl |grep 8080
LISTEN 0 20480 *:8080 *:*
访问测试
root@Docker-1:/opt/dockerfile/web/tomcat/tomcat-app1# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1d3b8cbb284d tomcat:app1 "/apps/tomcat/bin/ru…" 2 minutes ago Up 2 minutes 8005/tcp, 8009/tcp, 0.0.0.0:8080->8080/tcp trusting_ptolemy
1453b7367e51 jdk-base:v8.241 "/bin/bash" 34 minutes ago Up 34 minutes adoring_sutherland
ea18f12e6b70 nginx:v1 "/bin/bash" 3 hours ago Up 3 hours 86/tcp, 0.0.0.0:80->80/tcp, 443/tcp cocky_saha
root@Docker-1:/opt/dockerfile/web/tomcat/tomcat-app1# docker exec -it 1d3b8cbb284d /bin/bash[root@1d3b8cbb284d /]# ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 1 127.0.0.1:8005 *:*
LISTEN 0 100 *:8080 *:*
root@Docker-1:/opt/dockerfile/web/tomcat/tomcat-app2# pwd
/opt/dockerfile/web/tomcat/tomcat-app2
root@Docker-1:/opt/dockerfile/web/tomcat/tomcat-app2# vim Dockerfile
# Tomcat webapp deploy imageFROM tomcat-base:v8.5.54LABEL author="kaivi" \personal_site="www.likai.tech"# add a script to /tomcat/bin to start tomcat when container start
ADD run_tomcat.sh /apps/tomcat/bin/run_tomcat.sh# add business code to /tomcat/webapps/
ADD app2/* /apps/tomcat/webapps/app2/RUN chown www.www /apps/ -R #不修改权限 后面无法写入日志导致服务启动失败# expose ports
EXPOSE 8080 8005 8009# run tomcat when container start
CMD ["/apps/tomcat/bin/run_tomcat.sh"]
server.xml文件部署的时候注意关闭自动部署以及自动解压
准备容器启动时启动 tomcat 的脚本
root@Docker-1:/opt/dockerfile/web/tomcat/tomcat-app2# vim run_tomcat.sh
#!/bin/bashecho "172.20.32.101 duanxin.io" >> /etc/hosts
echo "nameserver 223.6.6.6" >> /etc/resolv.confsu - www -c "/apps/tomcat/bin/catalina.sh start"
su - www -c "tail -f /etc/hosts" #创建一个守护进程,监听一个变化不大的文件
编写 app2 测试页面
root@Docker-1:/opt/dockerfile/web/tomcat/tomcat-app2# mkdir app2
root@Docker-1:/opt/dockerfile/web/tomcat/tomcat-app2# vim app2/index.html
<DOCTYPE HTML/>
<head><h1>A TEST for Tomcat app2 <h1/>
<head/>
<body><p>Tomcat app2 test...<span>NICE!<span/><p/>
<body/>
主备容器构建脚本
root@Docker-1:/opt/dockerfile/web/tomcat/tomcat-app2# vim docker_build.sh
#!/bin/bashdocker build -t tomcat:app2 .
构建
root@Docker-1:/opt/dockerfile/web/tomcat/tomcat-app2# ./docker_build.sh
Sending build context to Docker daemon 6.144kB
Step 1/7 : FROM tomcat-base:v8.5.54---> ec58914afd67
Step 2/7 : LABEL author="kaivi" personal_site="www.likai.tech"---> Using cache---> 8509c73764ec
Step 3/7 : ADD run_tomcat.sh /apps/tomcat/bin/run_tomcat.sh---> b2ea0fadebfe
Step 4/7 : ADD app2/* /apps/tomcat/webapps/app2/---> 2eb6ac24beae
Step 5/7 : RUN chown www.www /apps/ -R---> Running in 7becf466e6a8
Removing intermediate container 7becf466e6a8---> 7de7462dea98
Step 6/7 : EXPOSE 8080 8005 8009---> Running in f54eeaee6b75
Removing intermediate container f54eeaee6b75---> 08e605894757
Step 7/7 : CMD ["/apps/tomcat/bin/run_tomcat.sh"]---> Running in 76ff5d601d03
Removing intermediate container 76ff5d601d03---> 6ad29a04f9a9
Successfully built 6ad29a04f9a9
Successfully tagged tomcat:app2
# 构建成功
从镜像启动
root@Docker-1:/opt/dockerfile/web/tomcat/tomcat-app2# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat app2 6ad29a04f9a9 40 seconds ago 954MB
tomcat app1 ca80466f5f71 3 hours ago 954MB
tomcat-base v8.5.54 ec58914afd67 4 hours ago 940MB
jdk-base v8.241 0bb10498e7d1 4 hours ago 926MB
centos-base v1 5fc2d6909f65 5 hours ago 522MB
......
root@Docker-1:/opt/dockerfile/web/tomcat/tomcat-app2# docker run -it -d -p 8081:8080 tomcat:app2
155eab9eafc871ece2b177a190077397f3744c8528ce3241e11022b52672d384
root@Docker-1:/opt/dockerfile/web/tomcat/tomcat-app2# ss -ntl | grep 8081
LISTEN 0 20480 *:8081 *:* root@Docker-1:/opt/dockerfile/web/tomcat/tomcat-app2# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
155eab9eafc8 tomcat:app2 "/apps/tomcat/bin/ru…" 21 seconds ago Up 20 seconds 8005/tcp, 8009/tcp, 0.0.0.0:8081->8080/tcp sleepy_cori
1d3b8cbb284d tomcat:app1 "/apps/tomcat/bin/ru…" 3 hours ago Up 3 hours root@Docker-1:/opt/dockerfile/web/tomcat/tomcat-app2# docker exec -it 155eab9eafc8 /bin/bash
[root@155eab9eafc8 /]# ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 1 127.0.0.1:8005 *:*
LISTEN 0 100 *:8080 *:*
访问测试
访问 http://172.20.32.101:8081/
访问 http://172.20.32.101:8081/app2/
基于 alpine 和 ubuntu 构建镜像
基于 alpine 构建镜像
在基于 alpine 构建镜像时,需要注意 alpine 的一些基础命令不同于 centos 或者ubuntu 系统,主要用到的是安装软件命令apk update和apk add命令,添加用户和组的adduser和addgroup命令。
构建 alpine 基础镜像
Dockerfile
root@Docker-1:~# cd /opt/dockerfile/system/
root@Docker-1:/opt/dockerfile/system# ll
total 20
drwxr-xr-x 5 root root 4096 Apr 18 10:39 ./
drwxr-xr-x 5 root root 4096 Apr 18 10:39 ../
drwxr-xr-x 2 root root 4096 Apr 18 10:47 centos/
drwxr-xr-x 2 root root 4096 Apr 18 10:39 redhat/
drwxr-xr-x 2 root root 4096 Apr 18 10:39 ubuntu/
root@Docker-1:/opt/dockerfile/system# mkdir alpine
root@Docker-1:/opt/dockerfile/system# cd alpine/
root@Docker-1:/opt/dockerfile/system/alpine# vim Dockerfile
# A alpine base image with some tools installedFROM alpine:latestLABEL author="kaivi" \personal_site="www.likai.tech"# change the pkg source to aliyun# http://mirrors.aliyun.com/alpine/v3.11/main# http://mirrors.aliyun.com/alpine/v3.11/community
COPY repositories /etc/apk/repositories# install basic tools and cmd
RUN apk update && apk add iotop gcc libgcc libc-dev libcurl \libc-utils pcre-dev zlib-dev libnfs make pcre pcre2 zip \unzip net-tools pstree wget libevent libevent-dev iproute2
root@Docker-1:/opt/dockerfile/system/alpine# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
alpine latest a187dde48cd2 3 weeks ago 5.6MB
......
root@Docker-1:/opt/dockerfile/system/alpine# docker run -it --rm alpine:latest sh
/ # cat /etc/apk/repositories
http://dl-cdn.alpinelinux.org/alpine/v3.11/main
http://dl-cdn.alpinelinux.org/alpine/v3.11/community# 替换上面的 dl-cdn.alpinelinux.org 改成 mirrors.aliyun.com/ # vi /etc/apk/repositories
/ # cat /etc/apk/repositories
#http://dl-cdn.alpinelinux.org/alpine/v3.11/main
#http://dl-cdn.alpinelinux.org/alpine/v3.11/communityhttp://mirrors.aliyun.com/alpine/v3.11/main
http://mirrors.aliyun.com/alpine/v3.11/community
构建脚本
root@Docker-1:/opt/dockerfile/system/alpine# vim docker_build.sh
#!/bin/bash
docker build -t alpine-base:v1 .
root@Docker-1:/opt/dockerfile/system/alpine# chmod u+x docker_build.sh
构建和查看
构建
root@Docker-1:/opt/dockerfile/system/alpine# ./docker_build.sh
Sending build context to Docker daemon 1.038MB
Step 1/4 : FROM alpine:latest---> a187dde48cd2
Step 2/4 : LABEL author="kaivi" personal_site="www.likai.tech"---> Using cache---> 0580a9d9e882
Step 3/4 : COPY repositories /etc/apk/repositories---> Using cache---> 9fc2e55e1e26
Step 4/4 : RUN apk update && apk add iotop gcc libgcc libc-dev libcurl libc-utils pcre-dev zlib-dev libnfs make pcre pcre2 zip unzip net-tools pstree wget libevent libevent-dev iproute2---> Running in d2b8e2724ac2
fetch http://mirrors.aliyun.com/alpine/v3.11/main/x86_64/APKINDEX.tar.gz
fetch http://mirrors.aliyun.com/alpine/v3.11/community/x86_64/APKINDEX.tar.gz
v3.11.5-56-gd94bd50429 [http://mirrors.aliyun.com/alpine/v3.11/main]
v3.11.5-54-g70c5111c08 [http://mirrors.aliyun.com/alpine/v3.11/community]
OK: 11271 distinct packages available
(1/48) Installing libgcc (9.2.0-r4)
(2/48) Installing libstdc++ (9.2.0-r4)
(3/48) Installing binutils (2.33.1-r0)
......
(47/48) Installing zip (3.0-r7)
(48/48) Installing zlib-dev (1.2.11-r3)
Executing busybox-1.31.1-r9.trigger
Executing ca-certificates-20191127-r1.trigger
OK: 183 MiB in 62 packages
Removing intermediate container d2b8e2724ac2---> 644eb1be20b8
Successfully built 644eb1be20b8
Successfully tagged alpine-base:v1
# 构建完成
root@Docker-1:/opt/dockerfile/system/alpine# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
alpine-base v1 644eb1be20b8 24 seconds ago 180MB
......root@Docker-1:/opt/dockerfile/system/alpine# docker run --rm -it alpine-base:v1 /bin/sh
/ # ping 114.114.114.114
PING 114.114.114.114 (114.114.114.114): 56 data bytes
64 bytes from 114.114.114.114: seq=0 ttl=127 time=15.745 ms
64 bytes from 114.114.114.114: seq=1 ttl=127 time=16.932 ms
^C
--- 114.114.114.114 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 15.745/16.338/16.932 ms
/ # ping www.baidu.com
PING www.baidu.com (61.135.169.121): 56 data bytes
64 bytes from 61.135.169.121: seq=0 ttl=127 time=3.724 ms
^C
--- www.baidu.com ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 3.724/3.724/3.724 ms
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:06 inet addr:172.17.0.6 Bcast:172.17.255.255 Mask:255.255.0.0UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1RX packets:18 errors:0 dropped:0 overruns:0 frame:0TX packets:19 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0 RX bytes:1708 (1.6 KiB) TX bytes:1625 (1.5 KiB)lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0UP LOOPBACK RUNNING MTU:65536 Metric:1RX packets:0 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
/ # apk update # 查看阿里云的源是否成功生效
fetch http://mirrors.aliyun.com/alpine/v3.11/main/x86_64/APKINDEX.tar.gz`在这里插入代码片`
fetch http://mirrors.aliyun.com/alpine/v3.11/community/x86_64/APKINDEX.tar.gz
v3.11.5-56-gd94bd50429 [http://mirrors.aliyun.com/alpine/v3.11/main]
v3.11.5-54-g70c5111c08 [http://mirrors.aliyun.com/alpine/v3.11/community]
OK: 11271 distinct packages available
基于 alpine 基础镜像构建 nginx 镜像
Dockerfile
root@Docker-1:/opt/dockerfile/system/alpine# mkdir nginx
root@Docker-1:/opt/dockerfile/system/alpine# vim nginx/Dockerfile
#nginx base image , based on alpine-base:v1
FROM alpine-base:v1ADD nginx-1.16.1.tar.gz /opt/RUN cd /opt/nginx-1.16.1 && ./configure --prefix=/apps/nginx && make && make install && ln -sv /apps/nginx/sbin/nginx /usr/bin/nginxRUN addgroup -g 2020 -S nginx && adduser -s /sbin/nologin -S -D -u 2020 -G nginx nginxCOPY nginx.conf /apps/nginx/conf/nginx.confADD Development_code.tar.gz /data/nginx/htmlRUN chown nginx.nginx /data/nginx/ /apps/nginx/ -REXPOSE 80 443CMD ["/apps/nginx"]
构建脚本
root@Docker-1:/opt/dockerfile/system/alpine# cd nginx/
root@Docker-1:/opt/dockerfile/system/alpine/nginx# vim docker_build.sh
#!/bin/bash
docker build -t nginx-alpine:v1 .root@Docker-1:/opt/dockerfile/system/alpine/nginx# chmod u+x docker_build.sh
构建上下文准备
root@Docker-1:/opt/dockerfile/system/alpine/nginx# rz -E #上传nginx二进制安装包
root@Docker-1:/opt/dockerfile/system/alpine/nginx# mkdir Development_code# 测试界面
root@Docker-1:/opt/dockerfile/system/alpine/nginx# vim Development_code/index.html
<DOCTYPE HTML/>
<head><h1>A TEST for alpine... <h1/>
<head/>
<body><p>Based alpine\'s nginx deployment.<span>wa...<span/><p/>
<body/>
root@Docker-1:/opt/dockerfile/system/alpine/nginx# tar -cvf Development_code.tar.gz Development_code/*
Development_code/index.htmlroot@Docker-1:/opt/dockerfile/system/alpine/nginx# cp /usr/local/src/nginx-1.16.1/conf/nginx.conf .root@Docker-1:/opt/dockerfile/system/alpine/nginx# ll
total 1048
drwxr-xr-x 3 root root 4096 Apr 18 16:47 ./
drwxr-xr-x 3 root root 4096 Apr 18 16:36 ../
drwxr-xr-x 2 root root 4096 Apr 18 16:43 Development_code/
-rw-r--r-- 1 root root 10240 Apr 18 16:46 Development_code.tar.gz
-rwxr--r-- 1 root root 46 Apr 18 16:38 docker_build.sh*
-rw-r--r-- 1 root root 504 Apr 18 16:36 Dockerfile
-rw-r--r-- 1 root root 1032630 Apr 18 01:37 nginx-1.16.1.tar.gz
-rw-r--r-- 1 root root 2656 Apr 18 16:47 nginx.conf
nginx 配置
root@Docker-1:/opt/dockerfile/system/alpine/nginx# vim nginx.conf
...
user nginx;
daemon off;
...
http {...server {listen 80;server_name localhost;access_log logs/host.access.log main;location / {root /data/nginx/html;index index.html index.htm;}...}...
}
构建
root@Docker-1:/opt/dockerfile/system/alpine/nginx# ./docker_build.sh
Sending build context to Docker daemon 1.052MB
Step 1/9 : FROM alpine-base:v1---> 644eb1be20b8
Step 2/9 : ADD nginx-1.16.1.tar.gz /opt/---> Using cache---> 02a9d885ce4a
Step 3/9 : RUN cd /opt/nginx-1.16.1 && ./configure --prefix=/apps/nginx && make && make install && ln -sv /apps/nginx/sbin/nginx /usr/bin/nginx---> Using cache---> 8d2e969ada82
Step 4/9 : RUN addgroup -g 2020 -S nginx && adduser -s /sbin/nologin -S -D -u 2020 -G nginx nginx---> Using cache---> 8f1bde17d483
Step 5/9 : COPY nginx.conf /apps/nginx/conf/nginx.conf---> Using cache---> 8ad0f6605500
Step 6/9 : ADD Development_code.tar.gz /data/nginx/html---> Using cache---> 47d4407df50c
Step 7/9 : RUN chown nginx.nginx /data/nginx/ /apps/nginx/ -R---> Using cache---> d5ec7aceeb8e
Step 8/9 : EXPOSE 80 443---> Using cache---> 51233e047af8
Step 9/9 : CMD ["/apps/nginx"]---> Using cache---> 3fc77202b016
Successfully built 3fc77202b016
Successfully tagged nginx-alpine:v1
访问测试
root@Docker-1:~# cd /opt/dockerfile/system/alpine/nginx/
root@Docker-1:/opt/dockerfile/system/alpine/nginx# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx-alpine v1 3fc77202b016 45 seconds ago 209MB
alpine-base v1 644eb1be20b8 22 minutes ago 180MBroot@Docker-1:/opt/dockerfile/system/alpine/nginx# docker run -it -p 80:80 nginx-alpine:v1 tail -f /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2 83c8c4f7ee36
root@Docker-1:/opt/dockerfile/system/alpine/nginx# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
83c8c4f7ee36 nginx-alpine:v1 "tail -f /etc/hosts" About an hour ago Up About an hour 0.0.0.0:80->80/tcp, 443/tcp practical_tereshkova
root@Docker-1:/opt/dockerfile/system/alpine/nginx# docker exec -it 83c8c4f7ee36 sh
/ # /apps/nginx/sbin/nginx #在容器中启动nginx
......
访问http://172.20.32.101/,由于根下没有 index.html 所以无法访问
访问http://172.20.32.101/Development_code/ 成功访问
基于 ubuntu 构建镜像
基于 ubuntu 构建镜像与其他系统大同小异
构建 ubuntu 基础镜像
Dockerfile
root@Docker-1:/opt/dockerfile/system/ubuntu# pwd
/opt/dockerfile/system/ubuntu
root@Docker-1:/opt/dockerfile/system/ubuntu# vim Dockerfile
# ubuntu base image with some tools installedFROM ubuntu:latestLABEL author="kaivi" \personal_site="www.likai.tech"COPY sources.list /etc/apt/sources.listRUN apt update && \apt install -y iproute2 ntpdate tcpdump telnet traceroute \nfs-kernel-server nfs-common lrzsz tree openssl libssl-dev \libpcre3 libpcre3-dev zlib1g-dev ntpdate tcpdump telnet traceroute \gcc openssh-server lrzsz tree openssl libssl-dev libpcre3 libpcre3-dev \zlib1g-dev ntpdate tcpdump telnet traceroute iotop unzip zip make && \touch /tmp/linux.txt
sources.list
root@Docker-1:/opt/dockerfile/system/ubuntu# vim sources.list deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiversedeb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiversedeb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiversedeb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiversedeb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
构建
root@Docker-1:/opt/dockerfile/system/ubuntu# vim docker_build.sh #!/bin/bash
docker build -t ubuntu-base:v1 .root@Docker-1:/opt/dockerfile/system/ubuntu# chmod u+x docker_build.sh root@Docker-1:/opt/dockerfile/system/ubuntu# ll
total 20
drwxr-xr-x 2 root root 4096 Apr 18 18:29 ./
drwxr-xr-x 6 root root 4096 Apr 18 16:11 ../
-rwxr--r-- 1 root root 45 Apr 18 18:24 docker_build.sh*
-rw-r--r-- 1 root root 573 Apr 18 18:21 Dockerfile
-rw-r--r-- 1 root root 907 Apr 18 18:23 sources.list#构建镜像
root@Docker-1:/opt/dockerfile/system/ubuntu# ./docker_build.sh
Sending build context to Docker daemon 5.12kB
Step 1/4 : FROM ubuntu:latest---> 4e5021d210f6
Step 2/4 : LABEL author="kaivi" personal_site="www.likai.tech"---> Using cache---> a127319deb66
Step 3/4 : COPY sources.list /etc/apt/sources.list---> Using cache---> e6180393cf90
Step 4/4 : RUN apt update && apt install -y iproute2 ntpdate tcpdump telnet traceroute nfs-kernel-server nfs-common lrzsz tree openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev ntpdate tcpdump telnet traceroute gcc openssh-server lrzsz tree openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev ntpdate tcpdump telnet traceroute iotop unzip zip make && touch /tmp/linux.txt---> Using cache---> 060ffdc4bf27
Successfully built 060ffdc4bf27
Successfully tagged ubuntu-base:v1
# 构建完成
注意:
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.# 该警告意思是apt的命令行接口不稳定,慎用#查看构建完成的镜像
root@Docker-1:/opt/dockerfile/system/ubuntu# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu-base v1 060ffdc4bf27 5 minutes ago 366MB
......
基于 ubuntu 基础镜像构建 nginx 镜像
Dockerfile
root@Docker-1:/opt/dockerfile/system/ubuntu# mkdir nginx
root@Docker-1:/opt/dockerfile/system/ubuntu# cd nginx/root@Docker-1:/opt/dockerfile/system/ubuntu/nginx# vim Dockerfile
# A nginx image based on ubuntuFROM ubuntu-base:v1ADD nginx-1.16.1.tar.gz /usr/local/srcRUN cd /usr/local/src/nginx-1.16.1 && \./configure --prefix=/apps/nginx && \make && make install && \ln -sv /apps/nginx/sbin/nginx /usr/bin && \rm -rf /usr/local/src/nginx-1.16.1 && \rm -rf /usr/local/src/nginx-1.16.1.tar.gzADD nginx.conf /apps/nginx/conf/nginx.confADD Development_code.tar.gz /data/nginx/htmlRUN groupadd -g 2021 nginx && \useradd -g nginx -s /usr/sbin/nologin -u 2021 nginx && \chown -R nginx.nginx /apps/nginx /data/nginxEXPOSE 80 443CMD ["/apps/nginx"]
构建
root@Docker-1:/opt/dockerfile/system/ubuntu/nginx# vim docker_build.sh
#!/bin/bash
docker build -t nginx-ubuntu:v1 .root@Docker-1:/opt/dockerfile/system/ubuntu/nginx# chmod u+x docker_build.sh
由于和之前的alpine的nginx构建基本差不多。直接复用即可
root@Docker-1:/opt/dockerfile/system/ubuntu/nginx# cp /opt/dockerfile/system/alpine/nginx/nginx.conf .
root@Docker-1:/opt/dockerfile/system/ubuntu/nginx# cp /opt/dockerfile/system/alpine/nginx/nginx-1.16.1.tar.gz .
root@Docker-1:/opt/dockerfile/system/ubuntu/nginx# cp /opt/dockerfile/system/alpine/nginx/Development_code.tar.gz .#修改测试界面```bash
root@Docker-1:/opt/dockerfile/system/ubuntu/nginx# tar xf Development_code.tar.gz
root@Docker-1:/opt/dockerfile/system/ubuntu/nginx# vim Development_code/index.html
<DOCTYPE HTML/>
<head><h1>A TEST for Ubuntu... <h1/>
<head/>
<body><p>Based ubuntu\'s nginx deployment.<span>wa o ...<span/><p/>
<body/>root@Docker-1:/opt/dockerfile/system/ubuntu/nginx# tar cvf Development_code.tar.gz Development_code/*
Development_code/index.htmlroot@Docker-1:/opt/dockerfile/system/ubuntu/nginx# rm -rf Development_code*
root@Docker-1:/opt/dockerfile/system/ubuntu/nginx# ll
total 1044
drwxr-xr-x 2 root root 4096 Apr 18 18:49 ./
drwxr-xr-x 3 root root 4096 Apr 18 18:33 ../
-rwxr--r-- 1 root root 45 Apr 18 18:37 docker_build.sh*
-rw-r--r-- 1 root root 606 Apr 18 18:36 Dockerfile
-rw-r--r-- 1 root root 1032630 Apr 18 18:40 nginx-1.16.1.tar.gz
-rw-r--r-- 1 root root 2664 Apr 18 18:39 nginx.conf
-rw-r--r-- 1 root root 10240 Apr 18 18:49 Development_code.tar.gz# 构建
root@Docker-1:/opt/dockerfile/system/ubuntu/nginx# ./docker_build.sh
Sending build context to Docker daemon 1.051MB
Step 1/8 : FROM ubuntu-base:v1---> 060ffdc4bf27
Step 2/8 : ADD nginx-1.16.1.tar.gz /usr/local/src---> Using cache---> 4fdc3572f0e4
Step 3/8 : RUN cd /usr/local/src/nginx-1.16.1 && ./configure --prefix=/apps/nginx && make && make install && ln -sv /apps/nginx/sbin/nginx /usr/bin && rm -rf /usr/local/src/nginx-1.16.1 && rm -rf /usr/local/src/nginx-1.16.1.tar.gz---> Using cache---> aa96d2e91820
Step 4/8 : ADD nginx.conf /apps/nginx/conf/nginx.conf---> Using cache---> b55a1aca5867
Step 5/8 : ADD Development_code.tar.gz /data/nginx/html---> Using cache---> 7d3df02bae55
Step 6/8 : RUN groupadd -g 2021 nginx && useradd -g nginx -s /usr/sbin/nologin -u 2021 nginx && chown -R nginx.nginx /apps/nginx /data/nginx---> Using cache---> 4c09408b97e5
Step 7/8 : EXPOSE 80 443---> Using cache---> 41c1567c685e
Step 8/8 : CMD ["/apps/nginx"]---> Using cache---> d42a1310db5e
Successfully built d42a1310db5e
Successfully tagged nginx-ubuntu:v1
# 构建完成
访问测试
root@Docker-1:/opt/dockerfile/system/ubuntu/nginx# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx-ubuntu v1 d42a1310db5e About a minute ago 382MB
ubuntu-base v1 060ffdc4bf27 26 minutes ago 366MBroot@Docker-1:/opt/dockerfile/system/ubuntu/nginx# docker run -it -d -p 80:80 nginx-ubuntu:v1 /bin/bash
c0a7a0b31bf6d50f59860ad189f8ebfc297d69bbbc1f56ed40ed476e65eb9ff3root@Docker-1:/opt/dockerfile/system/ubuntu/nginx# lsof -i:80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
docker-pr 49074 root 4u IPv6 458003 0t0 TCP *:http (LISTEN)
访问http://172.20.32.101/
访问现象和基于 alpine 时一样,由于根下没有 index.html 所以无法访问
构建 HAProxy 镜像
基于 centos-base 镜像构建 haproxy 镜像,将 haproxy 通过容器的方式运行
http://download.openpkg.org/components/cache/haproxy/#haproxy下载
准备 Dockerfile
root@Docker-1:~# cd /opt/dockerfile/system/centos/
root@Docker-1:/opt/dockerfile/system/centos# mkdir haproxy
root@Docker-1:/opt/dockerfile/system/centos# cd haproxy/root@Docker-1:/opt/dockerfile/system/centos/haproxy# vim Dockerfile
# A HAProxy image based on centos-base:v1 with some tools installed
FROM centos-base:v1 RUN yum install -y yum install gcc gcc-c++ glibc glibc-devel \pcre pcre-devel openssl openssl-devel systemd-devel net-tools \vim iotop bc zip unzip zlib-devel lrzsz tree screen lsof tcpdump \wget ntpdateADD haproxy-2.0.5.tar.gz /usr/local/src/RUN cd /usr/local/src/haproxy-2.0.5 && \make ARCH=x86_64 TARGET=linux-glibc USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 \USE_SYSTEMD=1 USE_CPU_AFFINITY=1 PREFIX=/usr/local/haproxy && \make install PREFIX=/usr/local/haproxy && \cp haproxy /usr/sbin/ && \mkdir /usr/local/haproxy/runADD haproxy.cfg /etc/haproxy/ADD run_haproxy.sh /usr/binEXPOSE 80 9999 #80用于访问 9999用于监听CMD ["/usr/bin/run_haproxy.sh"]
准备 HAProxy 源码和配置
http://www.haproxy.org/download/2.0/src/haproxy-2.0.5.tar.gz#国外下载地址 需要科学上网
root@Docker-1:/opt/dockerfile/system/centos/haproxy# rz -E# 编辑haproxy配置文件
root@Docker-1:/opt/dockerfile/system/centos/haproxy# vim haproxy.cfgglobal
chroot /usr/local/haproxy
#stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin
uid 99
gid 99
daemon
nbproc 1
pidfile /usr/local/haproxy/run/haproxy.pid
log 127.0.0.1 local3 infodefaults
option http-keep-alive
option forwardfor
mode http
timeout connect 300000ms
timeout client 300000ms
timeout server 300000mslisten statsmode httpbind 0.0.0.0:9999stats enablelog globalstats uri /haproxy-statusstats auth haadmin:123456listen docker_test_runbind 0.0.0.0:80mode httplog globalbalance roundrobinserver web1 172.20.32.101:8080 check inter 3000 fall 2 rise 5server web2 172.20.32.102:8080 check inter 3000 fall 2 rise 5
准备镜像构建脚本
root@Docker-1:/opt/dockerfile/system/centos/haproxy# vim run_haproxy.sh
#!/bin/bash
/usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg
tail -f /etc/hosts# 加执行权限
root@Docker-1:/opt/dockerfile/system/centos/haproxy# chmod u+x run_haproxy.sh # 编辑构建脚本
root@Docker-1:/opt/dockerfile/system/centos/haproxy# vim docker_build.sh
#!/bin/bash
docker build -t haproxy-ubuntu:v1 .# 加执行权限
root@Docker-1:/opt/dockerfile/system/centos/haproxy# chmod u+x docker_build.sh root@Docker-1:/opt/dockerfile/system/centos/haproxy# ll
total 2504
drwxr-xr-x 2 root root 4096 Apr 18 20:24 ./
drwxr-xr-x 3 root root 4096 Apr 18 19:19 ../
-rwxr--r-- 1 root root 48 Apr 18 20:24 docker_build.sh*
-rw-r--r-- 1 root root 760 Apr 18 20:15 Dockerfile
-rw-r--r-- 1 root root 2539226 Apr 18 20:13 haproxy-2.0.5.tar.gz
-rw-r--r-- 1 root root 680 Apr 18 20:20 haproxy.cfg
-rwxr--r-- 1 root root 77 Apr 18 20:22 run_haproxy.sh*#构建
root@Docker-1:/opt/dockerfile/system/centos/haproxy# ./docker_build.sh
Sending build context to Docker daemon 2.546MB
Step 1/8 : FROM centos-base:v1---> 5fc2d6909f65
Step 2/8 : RUN yum install -y yum install gcc gcc-c++ glibc glibc-devel pcre pcre-devel openssl openssl-devel systemd-devel net-tools vim iotop bc zip unzip zlib-devel lrzsz tree screen lsof tcpdump wget ntpdate---> Using cache---> 57ffe53d1e8c
Step 3/8 : ADD haproxy-2.0.5.tar.gz /usr/local/src/---> Using cache---> 482118c25cb7
Step 4/8 : RUN cd /usr/local/src/haproxy-2.0.5 && make ARCH=x86_64 TARGET=linux-glibc USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1 USE_CPU_AFFINITY=1 PREFIX=/usr/local/haproxy && make install PREFIX=/usr/local/haproxy && cp haproxy /usr/sbin/ && mkdir /usr/local/haproxy/run---> Using cache---> de502b965fdd
Step 5/8 : ADD haproxy.cfg /etc/haproxy/---> Using cache---> 336162d98639
Step 6/8 : ADD run_haproxy.sh /usr/bin---> Using cache---> 8c2012534b01
Step 7/8 : EXPOSE 80 9999---> Using cache---> 6c59694b7da0
Step 8/8 : CMD ["/usr/bin/run_haproxy.sh"]---> Using cache---> 47b597b9cb7c
Successfully built 47b597b9cb7c
Successfully tagged haproxy-ubuntu:v1
从镜像启动容器
root@Docker-1:/opt/dockerfile/system/centos/haproxy# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
haproxy-ubuntu v1 47b597b9cb7c 55 seconds ago 787MB
......
root@Docker-1:/opt/dockerfile/system/centos/haproxy# docker run -it -p 80:80 -p 9999:9999 haproxy-ubuntu:v1 bash
[root@e5e34e1bf06a /]# haproxy -f /etc/haproxy/haproxy.cfg
[root@e5e34e1bf06a /]#
[root@e5e34e1bf06a /]# ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:9999 *:*
LISTEN 0 128 *:80 *:*
[root@e5e34e1bf06a /]#
由于在Dockerfile配置中有ADD haproxy.cfg /etc/haproxy/ 会自动起来这个haproxy服务 所以在最后面不需要加bash也可以root@Docker-1:/opt/dockerfile/system/centos/haproxy# docker run -it -p 80:80 -p 9999:9999 haproxy-ubuntu:v1
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2 79ce10f0b3c8
启动后端服务
在后端服务器172.20.32.101机器部署(本机)
root@Docker-1:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
haproxy-ubuntu v1 47b597b9cb7c 2 hours ago 787MB
nginx-ubuntu v1 d42a1310db5e 4 hours ago 382MB
ubuntu-base v1 060ffdc4bf27 4 hours ago 366MB
tomcat app2 6ad29a04f9a9 7 hours ago 954MB
tomcat app1 ca80466f5f71 10 hours ago 954MBroot@Docker-1:~# docker run -d -it -p 8080:8080 tomcat:app1
180b61179821490e795d9300135003a73dfc87b0fa3d69ae3a638aaad7753ed8
root@Docker-1:~# ss -ntl
......
LISTEN 0 20480 *:9999 *:*
LISTEN 0 20480 *:8080 *:*
LISTEN 0 20480 *:80 *:*
......
将 tomcat:app2部署到 172.20.32.102
172.20.32.101上面导出tomcat业务镜像,拷贝到172.20.32.102使用
root@Docker-1:~# docker save tomcat:app2 > /opt/tomcat:app2.tar.gz root@Docker-1:~# scp /opt/tomcat\:app2.tar.gz 172.20.32.102:/opt/tomcat\:app2.tar.gz
#这里可能需要一些时间
在172.20.32.102导入镜像
root@Docker-2:~# docker load < /opt/tomcat\:app2.tar.gz
51505ea32d5f: Loading layer [==================================================>] 24.27MB/24.27MB
0c747fb19e38: Loading layer [==================================================>] 299.4MB/299.4MB
27853411f83c: Loading layer [==================================================>] 742.9kB/742.9kB
8ee048c0d621: Loading layer [==================================================>] 404.9MB/404.9MB
9866565c322a: Loading layer [==================================================>] 2.56kB/2.56kB
15567403b930: Loading layer [==================================================>] 3.072kB/3.072kB
4032e44635ce: Loading layer [==================================================>] 3.072kB/3.072kB
30dc82522c0e: Loading layer [==================================================>] 2.048kB/2.048kB
8eeeba765392: Loading layer [==================================================>] 15MB/15MB
3b202fd39753: Loading layer [==================================================>] 2.048kB/2.048kB
cd65936fedb7: Loading layer [==================================================>] 3.584kB/3.584kB
8e94fe36ca9f: Loading layer [==================================================>] 4.608kB/4.608kB
f7afa4a062d8: Loading layer [==================================================>] 15MB/15MB
Loaded image: tomcat:app2root@Docker-2:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat app2 6ad29a04f9a9 7 hours ago 954MB
nginx 1.16.1 16af99d71a72 2 days ago 127MB
centos 7.7.1908 08d05d1d5859 5 months ago 204MB
root@Docker-2:~# docker run -d -it -p 8080:8080 tomcat:app2
4e6ebc86b7b51d6ab8c87aaf8a669dc5f6edd2c94d2470451389ca3ed840b84a
root@Docker-2:~# ss -ntl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 511 0.0.0.0:80 0.0.0.0:*
LISTEN 0 128 127.0.0.53%lo:53 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 127.0.0.1:6010 0.0.0.0:*
LISTEN 0 128 127.0.0.1:6011 0.0.0.0:*
LISTEN 0 20480 *:8080 *:*
LISTEN 0 511 [::]:80 [::]:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 128 [::1]:6010 [::]:*
LISTEN 0 128 [::1]:6011 [::]:*
两台后端服务都启动后,控制界面 web1 和 web2 都是 UP 状态
访问:http://172.20.32.101:9999/haproxy-status
访问验证
访问web
单独访问:http://172.20.32.101:8080/app1/
单独访问:http://172.20.32.102:8080/app2/
访问 haproxy
1.访问:http://172.20.32.101/
2.访问:http://172.20.32.101/app1/
3.访问:http://172.20.32.101/app1/
4.访问:http://172.20.32.101/app2/
5.同理,刷新之后调度到另外一台tomcat上面,但是另外一台上面没有/app2/的数据
访问控制端