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
镜像构建方式
docker镜像构建的方式有2种:
- 基于官方的基础镜像,如各个发行版,层层叠加,构建自己的镜像
- 基于基础镜像运行容器,然后登陆容器,
- 执行想要的操作,如编译安装一个nginx
- 退出容器,docker commit提交为一个新的镜像
- 利用dockerfile编写镜像的构建构成,然后利用解析dockerfile来构建镜像;
- 编写dockerfile,里面指令描述了如何构建一个新的镜像,如编译安装nginx的过程
- docker程序解释执行dockerfile,最终生成一个新的镜像
- 执行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镜像
总结步骤:
- 下载一个基础镜像,如centos
- 将其运行为容器,并连入
- 配置基础仓库、nginx仓库
- yum安装nginx,修改配置文件,改为前台运行:daemon off;
- 自定义web主页
- ctrl p q退出容器交互窗口,docker commit提交为新镜像
- 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最后一条指令,生成最后的镜像
步骤总结:
- 编写dockerfile
- 创建单独存放dockerfile的目录;
- 编写dockerfile,注意Dockerfile,的D要大写
- 将其中需要的文件,如源码包,配置文件等,放在dockerfile文件所在的目录
- 利用docker build进行构建镜像
- 运行构建后的镜像,测试
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
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镜像
-
编写haproxy编译安装的dockerfile
-
准备haproxy的源码包,配置文件、容器入口脚本 到dockerfile同级别目录
-
构建镜像
-
编写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脚本;
-
准备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
-
构建镜像
[root@host2 haproxy]# docker build -t notechbb/haproxy:v1.7.12 .
-
配置文件、和启动脚本
# 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 :::*
上传镜像到docker hub
本地制作的镜像,可以上传到docker官方的docker仓库保存,步骤:
-
注册dockerhub账户;
-
本地登陆
-
查看登陆后,本地的验证信息
-
给镜像打上合适的标签,上传
-
登陆dockerhub查看镜像
-
在另一台docker host下载并启动,验证
-
注册dockerhub账户;
略...
-
本地登陆
[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
-
查看登陆后,本地的验证信息
[root@host2 ~]# cat /root/.docker/config.json { ... }
-
给镜像打上合适的标签,上传
[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
-
登陆dockerhub查看镜像
-
在另一台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