docker镜像与dockerfile

docker镜像与dockerfile

docker镜像

docker镜像介绍

https://jfrog.com/knowledge-base/a-beginners-guide-to-understanding-and-building-docker-images/

​ 一个典型的linux文件系统,包含:

  • bootfs(kernel+bootloader)

  • rootfs(/bin /dev /proc等目录)

    而docker镜像不包含bootfs,只是利用宿主机的bootfs,只包含最基本的rootfs,一些常用命令等,所有docker镜像都比较小;

​ docker镜像类比文件系统上的程序文件,如/bin/ls,其动态表现为容器,特点为只读,仅在运行时会加入一个可写层,从而保证了镜像的不变性,通过同一个docker镜像启动的若干个容器,初始一定是完全一致的状态;

docker镜像特点

特点:

​ 宿主机的内核+层层叠加形成了镜像提供的rootfs,构成了容器的运行环境,镜像文件系统是一层一层往上堆,上层会覆盖下层,如每一层都由相同的文件1.txt,那么最后看到的只会是最上层的文件1.txt内容,镜像运行为容器时,会再加一层可写层,在最上面,只有该层可写,容器运行中所有的数据修改都发生在这里,可写层生命周期和容器一致,即停止容器后,所有数据修改会丢失,(数据持久化需要采用挂载卷方式)

docker的优势很大程度上依赖于:docker镜像的特性:分层构建、联合挂载、多层只读层+一层可写层

镜像包含了运行其中软件必要的文件系统结构,包含rootfs,但是没有内核,所有容器都是共用宿主机的内核;

[root@e50fe34d3cf5 /]# ls
bin  etc   lib	  lost+found  mnt  proc  run   srv  tmp  var
dev  home  lib64  media       opt  root  sbin  sys  usr
# 没有/boot目录

[root@e50fe34d3cf5 /]# uname -r
3.10.0-862.el7.x86_64
[root@e50fe34d3cf5 /]# cat /etc/redhat-release 
CentOS Linux release 8.2.2004 (Core) 
# 发行版为8.2,但内核是宿主机7版本的的3.10

image-20201028101235868

镜像构建方式

docker镜像构建的方式有2种:

  1. 基于官方的基础镜像,如各个发行版,层层叠加,构建自己的镜像
    1. 基于基础镜像运行容器,然后登陆容器,
    2. 执行想要的操作,如编译安装一个nginx
    3. 退出容器,docker commit提交为一个新的镜像
  2. 利用dockerfile编写镜像的构建构成,然后利用解析dockerfile来构建镜像;
    1. 编写dockerfile,里面指令描述了如何构建一个新的镜像,如编译安装nginx的过程
    2. docker程序解释执行dockerfile,最终生成一个新的镜像
    3. 执行dockerfile过程中,针对每个指令,都会启动一个容器进行指令操作,(制作一个镜像,会看到中间过程运行的容器,docker ps -a命令)

docker镜像管理

1、搜索官方镜像

​ 第一个往往是官方镜像,

NAME                               DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
centos                             The official build of CentOS.                   6255                [OK]                
ansible/centos7-ansible            Ansible on Centos7                              132                                     [OK]

2、下载镜像

[root@host2 ~]# docker pull busybox
Using default tag: latest
latest: Pulling from library/busybox
9758c28807f2: Pull complete 
Digest: sha256:a9286defaba7b3a519d585ba0e37d0b2cbee74ebfe590960b0b1d6a5e97d1e1d
Status: Downloaded newer image for busybox:latest

语法格式:
docker pull 仓库服务器:端口/仓库名/镜像名:标签

例如:
docker pull localdocker.com:/prodution/nginx:1.14

对于dockerhub的公共仓库
docker pull 用户名/镜像名:标签
若是官方在dockerhub上的仓库,即可省略用户名,标签默认是lateset

3、查看本地镜像

[root@host2 ~]# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
notechbb/test       v1                  945619f86ac0        16 hours ago        277MB
ubuntu              latest              d70eaf7277ea        4 days ago          72.9MB
busybox             latest              f0b02e9d092d        13 days ago         1.23MB

4、镜像导出

[root@host2 opt]# docker save busybox -o /opt/busybox.tar.gz
[root@host2 opt]# ll
total 1428
-rw------- 1 root root 1459200 Oct 28 10:37 busybox.tar.gz
[root@host2 opt]# docker save nginx > /opt/nginx.tar.gz
[root@host2 opt]# ll
total 135280
-rw------- 1 root root   1459200 Oct 28 10:37 busybox.tar.gz
-rw-r--r-- 1 root root 137064448 Oct 28 10:37 nginx.tar.gz

# docker save命令,指明镜像,用-o或> 导出为镜像文件

# 查看导出镜像内容
解压后,可以查看元数据信息
[root@host2 opt]# cat manifest.json 
[{"Config":"f0b02e9d092d905d0d87a8455a1ae3e9bb47b4aa3dc125125ca5cd10d6441c9f.json","RepoTags":["busybox:latest"],"Layers":["50670a188f4d6a8bfbe56cd21b56524e458de56637142b18933beda1acad863c/layer.tar"]}]

5、镜像删除、导入

# 当有该镜像启动的容器运行时,不能删除;

[root@host2 opt]# docker rmi busybox
Untagged: busybox:latest
Untagged: busybox@sha256:a9286defaba7b3a519d585ba0e37d0b2cbee74ebfe590960b0b1d6a5e97d1e1d
Deleted: sha256:f0b02e9d092d905d0d87a8455a1ae3e9bb47b4aa3dc125125ca5cd10d6441c9f
Deleted: sha256:d2421964bad195c959ba147ad21626ccddc73a4f2638664ad1c07bd9df48a675

[root@host2 opt]# docker load < /opt/busybox.tar.gz 
d2421964bad1: Loading layer   1.45MB/1.45MB
Loaded image: busybox:latest

或:
docker load -i 镜像压缩包

dockerfile

简介

​ dockerfile为文件文件、由一条条指令组成,由docker程序解释执行,执行过程:每个dockerfile的指令,docker都会启动一个容器,执行该指令,以此类推,由dockerfile制作镜像的过程中,会启动若干个容器,docker ps -a可以查看

语法与指令

https://docs.docker.com/engine/reference/builder/#usage

#官方介绍:
#常用指令:
run 执行命令,如yum wget等
add 将host的文件复制到镜像内部
expose 开放的端口
cmd 镜像运行为容器时,启动的命令
env 设置环境变量
maintainer 作者信息
from 基于哪个基础镜像,一般是发行版的官方镜像,centos,ubuntu等
volume 定义存储挂载卷
workdir 进入容器后的默认目录
arg 
entrypoint

#注意entrypoint、cmd、arg的区别与联系

镜像制作

手动yum版nginx镜像

​ 总结步骤:

  1. 下载一个基础镜像,如centos
  2. 将其运行为容器,并连入
  3. 配置基础仓库、nginx仓库
  4. yum安装nginx,修改配置文件,改为前台运行:daemon off;
  5. 自定义web主页
  6. ctrl p q退出容器交互窗口,docker commit提交为新镜像
  7. docker push推送镜像到docker hub或私有仓库
# 下载一个centos的基础镜像,没指定版本,默认安装latest标签的,即centos8版本
[root@host2 ~]# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              latest              d70eaf7277ea        3 days ago          72.9MB
nginx               latest              f35646e83998        2 weeks ago         133MB
centos              latest              0d120b6ccaa8        2 months ago        215MB
hello-world         latest              bf756fb1ae65        9 months ago        13.3kB

# 运行为容器
[root@host2 ~]# docker run -it --name c1 centos /bin/bash

# 修改仓库文件
[root@e50fe34d3cf5 /]# cd /etc/yum.repos.d/
[root@e50fe34d3cf5 yum.repos.d]# yum repolist
Failed to set locale, defaulting to C.UTF-8
repo id                       repo name
base                          CentOS-8 - Base - mirrors.aliyun.com
extras                        CentOS-8 - Extras - mirrors.aliyun.com
updates                       CentOS-8 - Updates - mirrors.aliyun.com


# 配置时区
[root@e50fe34d3cf5 yum.repos.d]# rm -rf /etc/localtime 
[root@e50fe34d3cf5 yum.repos.d]# ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime  
[root@e50fe34d3cf5 yum.repos.d]# echo "Asia/Shanghai" > /etc/timezone

# 下载阿里的仓库文件,nginx的仓库文件,注意是对应版本,一开始centos8下成了7的仓库,死活下不了包
[root@e50fe34d3cf5 yum.repos.d]# ls
CentOS-Base.repo  nginx.repo

# 安装nginx;
# 修改配置文件,改为前台运行,(因docker容器需要一个前台运行的容器,才可以保持运行状态)
# 定义主页文件
[root@e50fe34d3cf5 yum.repos.d]# yum install nginx
[root@e50fe34d3cf5 yum.repos.d]# vim /etc/nginx/nginx.conf 
	daemon off;
[root@e50fe34d3cf5 yum.repos.d]# echo docker yum nginx > /usr/share/nginx/html/index.html

# ctrl p q退出容器交互创建
# 采用docker commit提交,-m为注释、采用容器的id、
# 名字格式为dockerhub用户名/仓库名:标签,采用标准格式,方便直接推送到dockerhub账户
[root@host2 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
e50fe34d3cf5        centos              "/bin/bash"         28 minutes ago      Up 28 minutes                           c1
[root@host2 ~]# docker commit -m "base-centos-yum-nginx-image" e50fe34d3cf5 notechbb/test:v1sha256:945619f86ac0dd6f9ae1ef4cdada83e41970a5c63d9bdc35e883565ad31e26f0
[root@host2 ~]# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
notechbb/test       v1                  945619f86ac0        4 seconds ago       277MB

2、运行为容器,访问测试

[root@host2 opt]# docker run -d -p 80:80 --name n2 notechbb/test:v1 /usr/sbin/nginx
90b7f3ae32d72abbc01526d346c59be2e06c9b91f09230d745fd7fed5f48d18b
[root@host2 opt]# ss -lnt
State      Recv-Q Send-Q Local Address:Port                Peer Address:Port              
LISTEN     0      128                *:22                             *:*                  
LISTEN     0      100        127.0.0.1:25                             *:*                  
LISTEN     0      128               :::80                            :::*                  
LISTEN     0      128               :::22                            :::*                  
LISTEN     0      100              ::1:25                            :::*                  
[root@host2 opt]# curl 192.168.80.101
docker yum nginx

dockerfile作源码安装nginx镜像

​ dockerfile就是把运行容器,手动一步步的操作,写为了dockerfile中指令,然后由docker解释执行dockerfile,过程中,每执行一条指令,就是运行为一个容器然后做指令中操作,提交为镜像,依次类推,层层叠加,直到dockerfile最后一条指令,生成最后的镜像

步骤总结:

  1. 编写dockerfile
    1. 创建单独存放dockerfile的目录;
    2. 编写dockerfile,注意Dockerfile,的D要大写
    3. 将其中需要的文件,如源码包,配置文件等,放在dockerfile文件所在的目录
  2. 利用docker build进行构建镜像
  3. 运行构建后的镜像,测试

1、编写dockerfile如下

# 将编译安装nginx的步骤,写为dockerfile指令即可;
# Dockerfile需要D大写
# 创建目录,用于dockerfile的编写


[root@host2 nginx]# cat Dockerfile 
# dockerfile yum nginx
From centos
maintainer wang@qq.com
# 基础镜像为centos,作者信息;


run rm -rf /etc/yum.repos.d/*
run curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-8.repo
run yum install -y lrzsz gcc gcc-c++ pcre-devel openssl-devel zlib-devel
# 配置yum源,安装基础包


add nginx-1.14.2.tar.gz /usr/local/src
# run tar -xf /usr/local/src/nginx-1.14.2.tar.gz -C /usr/local/src
# 将源码包,复制到容器内的文件系统目录中,注意:不需要解压,会自动解压!


run useradd nginx
run cd /usr/local/src/nginx-1.14.2/ && ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_dav_module --with-http_stub_status_module --with-threads --with-file-aio --with-stream_realip_module --with-stream_ssl_module --with-stream --with-pcre --with-http_gzip_static_module --with-http_realip_module
# 添加用户,进入目录,configure


run yum install -y make
run cd /usr/local/src/nginx-1.14.2/ && make && make install
# 根据实验中报错,再安装make包,编译,和安装


add nginx.conf /usr/local/nginx/conf
run ln -sv /usr/local/nginx/sbin/nginx /usr/sbin/nginx
run echo "dockerfile bianyi nginx" > /usr/local/nginx/html/index.html
# 复制配置文件、做主程序软链接,自定义主页文件

expose 80
cmd ["/usr/sbin/nginx"]
# 暴露80端口,定义运行为容器时,执行的命令

2、执行过程:

# docker built -t 标签信息   dockerfile所在目录

# 执行步骤如下;每一步都是一个新容器进行操作
[root@host2 nginx]# docker build -t notechbb/test:v2 /opt/dockerfile/nginx/
Sending build context to Docker daemon  1.023MB
Step 1/15 : From centos
 ---> 0d120b6ccaa8
Step 2/15 : maintainer wang@qq.com
 ---> Using cache
 ---> 8245a3e504d2
Step 3/15 : run rm -rf /etc/yum.repos.d/*
 ---> Using cache
 ---> c83f1085fc98
Step 4/15 : run curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-8.repo
 ---> Using cache
 ---> 1016539aae88
Step 5/15 : run yum install -y lrzsz gcc gcc-c++ pcre-devel openssl-devel zlib-devel
 ---> Using cache
 ---> 6f740d6ef49a
Step 6/15 : add nginx-1.14.2.tar.gz /usr/local/src
 ---> Using cache
 ---> ef56b197b9b4
Step 7/15 : run useradd nginx
 ---> Using cache
 ---> e4892f8bcb65
Step 8/15 : run cd /usr/local/src/nginx-1.14.2/ && ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_dav_module --with-http_stub_status_module --with-threads --with-file-aio --with-stream_realip_module --with-stream_ssl_module --with-stream --with-pcre --with-http_gzip_static_module --with-http_realip_module
 ---> Using cache
 ---> 19fc0a0f4e38
Step 9/15 : run yum install -y make
 ---> Using cache
 ---> 6c663d1dd0cf
Step 10/15 : run cd /usr/local/src/nginx-1.14.2/ && make && make install
 ---> Using cache
 ---> 9e1548f2adad
Step 11/15 : add nginx.conf /usr/local/nginx/conf
 ---> Using cache
 ---> 7a28d47ccee7
Step 12/15 : run ln -sv /usr/local/nginx/sbin/nginx /usr/sbin/nginx
 ---> Using cache
 ---> b3f4eec5c2d2
Step 13/15 : run echo "dockerfile bianyi nginx" > /usr/local/nginx/html/index.html
 ---> Running in ffa27a922d14
Removing intermediate container ffa27a922d14
 ---> 424a349b646c
Step 14/15 : expose 80
 ---> Running in 861171cb77ee
Removing intermediate container 861171cb77ee
 ---> 72f0cfe401e4
Step 15/15 : cmd ["/usr/sbin/nginx"]
 ---> Running in 5021e9274d18
Removing intermediate container 5021e9274d18
 ---> ec692265596a
Successfully built ec692265596a
Successfully tagged notechbb/test:v2

# 查看构建过程中,利用的容器;
[root@host2 nginx]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                   CREATED             STATUS                           PORTS                NAMES
bc4b7a3a7692        notechbb/test:v2    "/usr/sbin/nginx"         2 minutes ago       Up 2 minutes                     0.0.0.0:80->80/tcp   ng1
8e96fd8ae793        b3f4eec5c2d2        "/bin/sh -c 'echo \"d…"   44 minutes ago      Exited (1) 44 minutes ago                             sad_easley
7002d12d0465        19fc0a0f4e38        "/bin/sh -c 'cd /usr…"    About an hour ago   Exited (127) About an hour ago                        heuristic_mcnulty
73186b8d4bc1        19fc0a0f4e38        "/bin/sh -c 'make &&…"    About an hour ago   Exited (127) About an hour ago                        mystifying_chaplygin
09d7a659b739        1ac49f6dd08b        "/bin/sh -c './confi…"    About an hour ago   Exited (127) About an hour ago                        eloquent_archimedes
16c590a6c9fe        ef56b197b9b4        "/bin/sh -c 'tar -xf…"    About an hour ago   Exited (2) About an hour ago                          silly_shaw

3、查看制作后镜像,

[root@host2 nginx]# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
notechbb/test       v2                  64784e5f6806        4 seconds ago       468MB

# 运行为容器,测试正常;
[root@host2 nginx]# docker run -d -p 80:80 --name ng1 notechbb/test:v2
bc4b7a3a7692d894b3321389b9ede0afe69fb26d3639f1a0c342bbe8459332cb
[root@host2 nginx]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                NAMES
bc4b7a3a7692        notechbb/test:v2    "/usr/sbin/nginx"   2 seconds ago       Up 2 seconds        0.0.0.0:80->80/tcp   ng1


[root@host2 nginx]# ss -nlt
State      Recv-Q Send-Q                                                 Local Address:Port                                                                Peer Address:Port              
LISTEN     0      128                                                                *:22                                                                             *:*                  
LISTEN     0      100                                                        127.0.0.1:25                                                                             *:*                  
LISTEN     0      128                                                               :::80                                                                            :::*  


[root@host2 nginx]# curl 192.168.80.101
dockerfile bianyi nginx
# 访问正常;

tomcat镜像

下载centos官方base镜像

[root@host2 nginx]# docker pull centos:centos7.2.1511

# 采用7.2 1511版本;

构建jdk镜像

1、创建dockerfile目录

[root@host2 dockerfile]# mkdir jdk
[root@host2 dockerfile]# mkdir tomcat
[root@host2 dockerfile]# ll
total 0
drwxr-xr-x 2 root root  6 Oct 28 15:57 jdk
drwxr-xr-x 2 root root  6 Oct 28 15:57 tomcat

2、编写dockerfile

[root@host2 jdk]# cat Dockerfile 
# base centos7.2 jdk image

from centos:centos7.2.1511

maintainer wang@qq.com

add  jdk-8u261-linux-x64.rpm  /root
run yum localinstall -y /root/jdk-8u261-linux-x64.rpm 
env JAVA_HOME=/usr/java/latest
env PATH=$JAVA_HOME/bin/:$PATH

# 上传jdk包
[root@host2 jdk]# ll
total 124452
-rw-r--r-- 1 root root       233 Oct 28 16:04 Dockerfile
-rw-r--r-- 1 root root 127431820 Sep  2 14:39 jdk-8u261-linux-x64.rpm

3、构建,运行,验证,查看到变量信息,都已经配置正确;

[root@host2 jdk]# docker build -t notechbb/jdk:8.261 .

[root@host2 jdk]# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
notechbb/jdk        8.261               1731b1640bee        6 seconds ago       666MB

[root@host2 jdk]# docker run -it --rm --name jdk1 notechbb/jdk:8.261 
[root@4d5b8e3c7992 /]# pwd
/
[root@4d5b8e3c7992 /]# ss -nlt
bash: ss: command not found
[root@4d5b8e3c7992 /]# echo $JAVA_HOME
/usr/java/latest
[root@4d5b8e3c7992 /]# echo $PATH     
/usr/java/latest/bin/:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

构建tomcat镜像

1、编写dockerfile

[root@host2 tomcat]# cat Dockerfile 
# tomcat image

from notechbb/jdk:8.261
maintainer wang@qq.com

add apache-tomcat-8.5.57.tar.gz /usr/local/
run ln -sv /usr/local/apache-tomcat-8.5.57/ /usr/local/tomcat


env CATALINA_HOME=/usr/local/tomcat
env PATH=$CATALINA_HOME/bin:$PATH

expose 8080

cmd /usr/local/tomcat/bin/catalina.sh run


# 注意:实验中,cmd 采用了 ["/usr/local/tomcat/bin/catalina.sh run"]
# 运行为容器时,会报错,命令路径找不到no such file ,去掉引号和括号后即可;

2、构建

[root@host2 tomcat]# ll
total 10144
-rw-r--r-- 1 root root 10379806 Sep  2 14:36 apache-tomcat-8.5.57.tar.gz
-rw-r--r-- 1 root root      269 Oct 28 16:19 Dockerfile
[root@host2 tomcat]# docker build -t notechbb/tomcat:8.5.57 .

# 准备tomcat二进制包;

3、运行、测试;

[root@host2 tomcat]# docker run  --rm -d -p 8080:8080 --name tomcat1 notechbb/tomcat:8.5.57
e2fe770a1fc3e0811272328e79473f49ef6f9ba06b34e99dfc9d5120d97cd541
[root@host2 tomcat]# docker ps -a
CONTAINER ID        IMAGE                    COMMAND                  CREATED             STATUS              PORTS                    NAMES
e2fe770a1fc3        notechbb/tomcat:8.5.57   "/usr/local/tomcat/b…"   6 seconds ago       Up 5 seconds        0.0.0.0:8080->8080/tcp   tomcat1

基于tomcat镜像构建业务镜像

1、编写dockerfile

[root@host2 app1]# cat Dockerfile 
# app1 base tomcat

from notechbb/tomcat:8.5.57
maintainer wang@qq.com

add app1/* /usr/local/tomcat/webapps/app1/


expose 8080 8009

cmd /usr/local/tomcat/bin/catalina.sh run

准备业务文件,即webapp下的文件,也可以打成war包;

[root@host2 app1]# mkdir app1
[root@host2 app1]# echo 1.html > app1/1.html
[root@host2 app1]# echo index.html > app1/index.html

[root@host2 app1]# ll
total 4
drwxr-xr-x 2 root root  38 Oct 28 16:56 app1
-rw-r--r-- 1 root root 177 Oct 28 17:00 Dockerfile

2、构建

[root@host2 app1]# docker build -t notechbb/app1:v1 .


Step 3/5 : add app1/* /usr/local/tomcat/webapps/app1
When using ADD with more than one source file, the destination must be a directory and end with a /


注意:根据提示,add添加的是目录时,目标地址要以/结尾;修改后,重新构建成功;

3、运行测试

[root@host2 app1]# docker run -d -p 8080:8080 -p 8009:8009 --name app1 notechbb/app1:v1 
4a428a12a2f52bf717cf36bad9deea0dfbc4a33dc9104deb087c708c859fd050
[root@host2 app1]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                            NAMES
4a428a12a2f5        notechbb/app1:v1    "/bin/sh -c '/usr/lo…"   3 seconds ago       Up 1 second         0.0.0.0:8009->8009/tcp, 0.0.0.0:8080->8080/tcp   app1
[root@host2 app1]# ss -nlt
State      Recv-Q Send-Q                          Local Address:Port                                         Peer Address:Port              
                                                     
LISTEN     0      128                                        :::8009                                                   :::*                  
LISTEN     0      128                                        :::8080                    

image-20201028170158976

haproxy镜像

先构建2个业务镜像

​ 根据上步业务镜像构建过程,构建2个业务应用,分别为app1,app2,就是改了不同的首页文件而已;用于稍候haproxy做负载均衡时的效果查看;

# 参考app1步骤,再构建一个app2,并都运行为容器;

[root@host2 app2]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                            NAMES
5c5a2c1cba2d        notechbb/app2:v1    "/bin/sh -c '/usr/lo…"   5 seconds ago       Up 4 seconds        8009/tcp, 0.0.0.0:8081->8080/tcp                 app2
4a428a12a2f5        notechbb/app1:v1    "/bin/sh -c '/usr/lo…"   11 minutes ago      Up 11 minutes       0.0.0.0:8009->8009/tcp, 0.0.0.0:8080->8080/tcp   app1


# 2个app的8080分别映射宿主机的8080和8081
[root@host2 app2]# ss -nlt |grep 808
LISTEN     0      128         :::8080                    :::*                  
LISTEN     0      128         :::8081                    :::*    

构建haproxy镜像

  1. 编写haproxy编译安装的dockerfile

  2. 准备haproxy的源码包,配置文件、容器入口脚本 到dockerfile同级别目录

  3. 构建镜像

  4. 编写haproxy编译安装的dockerfile

    [root@host2 haproxy]# cat Dockerfile 
    # haproxy image base centos7.2
       
    from centos:centos7.2.1511
    maintainer wang@qq.com
       
    add haproxy-1.7.12.tar.gz /usr/local/src
    run rm -rf /etc/yum.repos.d/*
    run curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
    run yum install -y gcc gcc++ pcre pcre-devel
       
    run rpm --rebuilddb && yum install -y systemd-devel zlib-devel openssl-devel
    run rpm --rebuilddb && yum install -y make
    run cd /usr/local/src/haproxy-1.7.12/ && make TARGET=linux2628 USE_PCRE=1 USE_ZLIB=1 USE_SYSTEMD=1 ARCh=x86_64 prefix=/usr/local/haproxy && make install PREFIX=/usr/local/haproxy
       
    add haproxy.cfg  /etc/haproxy/
    run mkdir /var/lib/haproxy && touch /var/lib/haproxy
    copy run_ha.sh /etc/haproxy/
    expose 80 9999
       
    cmd /etc/haproxy/run_ha.sh
       
    # dockerfile中遇到的问题:
    1、缺包,根据提示补全即可
    2、编译选项缺失问题,补全即可
    3、进入容器查看时,端口没监听问题,因配置文件中sock文件无法bind问题,添加一行即可;
     还要注意进程属主问题,改为uid 99
     run mkdir /var/lib/haproxy && touch /var/lib/haproxy
    4、容器启动时,什么作为容器的启动入口;采用了run_ha.sh脚本;
    
  5. 准备haproxy的源码包、容器启动时运行脚本、配置文件到dockerfile同级别目录

    [root@host2 haproxy]# ll
    total 1732
    -rw-r--r-- 1 root root     746 Oct 29 16:21 Dockerfile
    -rw-r--r-- 1 root root 1760527 Oct 25  2019 haproxy-1.7.12.tar.gz
    -rw-r--r-- 1 root root    1989 Oct 29 16:20 haproxy.cfg
    -rwxr-xr-x 1 root root      80 Oct 29 15:52 run_ha.sh
    
  6. 构建镜像

    [root@host2 haproxy]#  docker build -t notechbb/haproxy:v1.7.12 .
    
  7. 配置文件、和启动脚本

       
    # run_ha.sh内容
    [root@host2 haproxy]# cat run_ha.sh 
       
    /usr/local/haproxy/sbin/haproxy -f /etc/haproxy/haproxy.cfg
    tail -f /etc/hosts
       
    # 配置文件中,haproxy配置为后台运行,但是在启动脚本中,又加了个tail -f查看一个小文件,使得容器有一个占据终端的应用,保持容器的持续运行;查看的文件,不要是持久增长的日志文件,避免不必要的io消耗;
       
       
    [root@host2 haproxy]# cat haproxy.cfg 
    #---------------------------------------------------------------------
    # Global settings
    #---------------------------------------------------------------------
    global
        # to have these messages end up in /var/log/haproxy.log you will
        # need to:
        #
        # 1) configure syslog to accept network log events.  This is done
        #    by adding the '-r' option to the SYSLOGD_OPTIONS in
        #    /etc/sysconfig/syslog
        #
        # 2) configure local2 events to go to the /var/log/haproxy.log
        #   file. A line like the following can be added to
        #   /etc/sysconfig/syslog
        #
        #    local2.*                       /var/log/haproxy.log
        #
        log         127.0.0.1 local2
         
        chroot      /var/lib/haproxy
       
        pidfile     /var/run/haproxy.pid
       
        maxconn     4000
        
     uid 99
     gid 99
       
     daemon
        # turn on stats unix socket
        stats socket /var/lib/haproxy/stats
       
       
    #---------------------------------------------------------------------
    # common defaults that all the 'listen' and 'backend' sections will
    # use if not designated in their block
    #---------------------------------------------------------------------
    defaults
        mode                    http
        log                     global
        option                  httplog
        option                  dontlognull
        option http-server-close
        option forwardfor       except 127.0.0.0/8
        option                  redispatch
        retries                 3
        timeout http-request    10s
        timeout queue           1m
        timeout connect         10s
        timeout client          1m
        timeout server          1m
        timeout http-keep-alive 10s
        timeout check           10s
        maxconn                 3000
       
       
    listen stats
     mode http
     bind *:9999
     stats enable
     log global
     stats uri /ha-status
     stats auth admin:admin
       
    listen web1
     bind *:80
     mode http
     log global
     balance roundrobin
     server web1 192.168.80.101:8080 check inter 3000 fall 2 rise 5
     server web2 192.168.80.101:8081 check inter 3000 fall 2 rise 5
    

启动haproxy和2个tomcat镜像

[root@host2 haproxy]# docker run -d -p 80:80 -p 9999:9999 --name ha1 notechbb/haproxy:v1.7.12 
aa34230dabb8d598ab13d990cbf10781d5762b23029142946b905e42378c7d56
# 启动haproxy镜像,映射宿主机的80和9999端口;

[root@host2 haproxy]# docker run -d -p 8080:8080  --name app1 notechbb/app1:v1 
026a7a77e0489c558b45c6ba9e7033da51030a3942124b2e0984fa4a9a8b9e1e
[root@host2 haproxy]# docker run -d -p 8081:8080  --name app2 notechbb/app2:v1 
89ca67992c245f5c985dfc24417e256627e0e2fd882c852da7ad203b8a4229b5
# 启动2个tomcat容器


[root@host2 haproxy]# docker ps
CONTAINER ID        IMAGE                      COMMAND                  CREATED              STATUS              PORTS                                        NAMES
89ca67992c24        notechbb/app2:v1           "/bin/sh -c '/usr/lo…"   5 seconds ago        Up 4 seconds        8009/tcp, 0.0.0.0:8081->8080/tcp             app2
026a7a77e048        notechbb/app1:v1           "/bin/sh -c '/usr/lo…"   25 seconds ago       Up 24 seconds       8009/tcp, 0.0.0.0:8080->8080/tcp             app1
aa34230dabb8        notechbb/haproxy:v1.7.12   "/bin/sh -c /etc/hap…"   About a minute ago   Up About a minute   0.0.0.0:80->80/tcp, 0.0.0.0:9999->9999/tcp   ha1
[root@host2 haproxy]# ss -nlt
State      Recv-Q Send-Q                                                 Local Address:Port                                                                Peer Address:Port              
LISTEN     0      128                                                                *:22                                                                             *:*                  
LISTEN     0      100                                                        127.0.0.1:25                                                                             *:*                  
LISTEN     0      128                                                               :::9999                                                                          :::*                  
LISTEN     0      128                                                               :::8080                                                                          :::*                  
LISTEN     0      128                                                               :::80                                                                            :::*                  
LISTEN     0      128                                                               :::8081                                                                          :::* 

image-20201029162414092

image-20201029162346389

image-20201029170308647

上传镜像到docker hub

​ 本地制作的镜像,可以上传到docker官方的docker仓库保存,步骤:

  1. 注册dockerhub账户;

  2. 本地登陆

  3. 查看登陆后,本地的验证信息

  4. 给镜像打上合适的标签,上传

  5. 登陆dockerhub查看镜像

  6. 在另一台docker host下载并启动,验证

  7. 注册dockerhub账户;

    略...

  8. 本地登陆

    [root@host2 ~]# docker login
    Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
    Username: 你的用户名
    Password: 你的密码
    WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
    Configure a credential helper to remove this warning. See
    https://docs.docker.com/engine/reference/commandline/login/#credentials-store
       
    Login Succeeded
       
    
  9. 查看登陆后,本地的验证信息

    [root@host2 ~]# cat /root/.docker/config.json 
    {
    ...
    }
    
  10. 给镜像打上合适的标签,上传

    [root@host2 ~]# docker tag notechbb/test:v1 notechbb/test:good
    [root@host2 ~]# docker image ls
    notechbb/test       good                945619f86ac0        2 days ago          277MB
    notechbb/test       v1                  945619f86ac0        2 days ago          277MB
    # 一个镜像,可以具有多个标签;
       
    [root@host2 ~]# docker push notechbb/test:good
    The push refers to repository [docker.io/notechbb/test]
    58485fd67300: Pushed 
    291f6e44771a: Mounted from library/centos 
    good: digest: sha256:7ec627bf2ce412b9b0424775d530e56cf832e3c7be7d3b634cbe55d2ffa79108 size: 741
    
  11. 登陆dockerhub查看镜像

    image-20201029192631012

  12. 在另一台docker host下载并启动,验证

    [root@host3 ~]# docker pull notechbb/test:good
    good: Pulling from notechbb/test
    3c72a8ed6814: Pull complete 
    ffbfc0499962: Pull complete 
    Digest: sha256:7ec627bf2ce412b9b0424775d530e56cf832e3c7be7d3b634cbe55d2ffa79108
    Status: Downloaded newer image for notechbb/test:good
    [root@host3 ~]# docker image ls
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    notechbb/test       good                945619f86ac0        2 days ago          277MB
    
updatedupdated2020-10-292020-10-29
加载评论