docker不是一个值得投入的领域,它解决的问题是Unix系统最初设计的一个疏忽从一个不会用docker的小白,自己一步一步的摸索,中间也踩过许多坑但任然,坚持从哪里跌倒就从哪里爬起来不求感动自己,但求人生无悔。
1 容器简介1.1 什么是 Linux 容器1.2 容器不就是虚拟化吗1.3 容器发展简史2 什么是 Docker?2.1 Docker 如何工作?2.2 Docker 技术是否与传统的 Linux 容器相同?
2.3 docker的目标3 安装Docker3.1 Docker基础命令操作3.2 启动第一个容器3.3 Docker镜像生命周期4 docker镜像相关操作4.1 搜索官方仓库镜像4.2 获取镜像4.3 导出镜像
4.4 删除镜像4.5 导入镜像4.6 查看镜像的详细信息5 容器的日常管理5.1 容器的起/停5.2 进入容器方法5.3 删除所有容器5.4 启动时进行端口映射6 Docker 数据卷的管理6.1 挂载时创建卷
6.2 创建卷后挂载6.3 手动将容器保存为镜像7 Dockerfile自动构建docker镜像7.1 Dockerfile指令集7.2 创建一个Dockerfile7.3 使用Dcokerfile安装kodexplorer
8 Docker中的镜像分层8.1 Docker 镜像为什么分层8.2 可写的容器层8.3 容器层的细节说明9 使用docker运行zabbix-server9.1 容器间的互联9.2 启动zabbix容器
9.3 关于zabbix API10 docker 仓库(registry)10.1 创建一个普通仓库10.2 带basic认证的仓库11 docker-compose编排工具11.1 安装docker-compose
11.2 编排启动镜像11.3 haproxy代理后端docker容器11.4 安装socat 直接操作socket控制haproxy12 重启docker服务,容器全部退出的解决办法12.1 在启动是指定自动重启
12.2 修改docker默认配置文件13 Docker网络类型13.1 docker的网络类型13.2 不为容器配置网络功能13.3 与其他容器共享网络配置(Container)13.4 使用宿主机网络
13.5 查看网络列表13.6 用PIPEWORK为docker容器配置独立IP13.7 Docker跨主机通信之macvlan14 docker企业级镜像仓库harbor14.1 使用容器的建议14.2 关于Docker容器的监控
15 参考文献1 容器简介1.1 什么是 Linux 容器Linux容器是与系统其他部分隔离开的一系列进程,从另一个镜像运行,并由该镜像提供支持进程所需的全部文件容器提供的镜像包含了应用的所有依赖项,因而在从开发到测试再到生产的整个过程中,它都具有可移植性和一致性。
![](http://ldjg88.com/zb_users/upload/2024/07/20240703034515171994951559331.jpeg)
更加详细地来说,请您假定您在开发一个应用您使用的是一台笔记本电脑,而且您的开发环境具有特定的配置其他开发人员身处的环境配置可能稍有不同您正在开发的应用依赖于您当前的配置,还要依赖于某些特定文件与此同时,您的企业还拥有标准化的测试和生产环境,且具有自身的配置和一系列支持文件。
您希望尽可能多在本地模拟这些环境,而不产生重新创建服务器环境的开销因此,您要如何确保应用能够在这些环境中运行和通过质量检测,并且在部署过程中不出现令人头疼的问题,也无需重新编写代码和进行故障修复?答案就是使用容器。
容器可以确保您的应用拥有必需的配置和文件,使得这些应用能够在从开发到测试、再到生产的整个流程中顺利运行,而不出现任何不良问题这样可以避免危机,做到皆大欢喜虽然这只是简化的示例,但在需要很高的可移植性、可配置性和隔离的情况下,我们可以利用 Linux 容器通过很多方式解决难题。
无论基础架构是在企业内部还是在云端,或者混合使用两者,容器都能满足您的需求1.2 容器不就是虚拟化吗是,但也不竟然我们用一种简单方式来思考一下:虚拟化使得许多操作系统可同时在单个系统上运行容器则可共享同一个操作系统内核,将应用进程与系统其他部分隔离开。
![](http://ldjg88.com/zb_users/upload/2024/07/20240703034515171994951591423.jpeg)
图-普通虚拟化技术和Docker的对比这意味着什么?首先,让多个操作系统在单个虚拟机监控程序上运行以实现虚拟化,并不能达成和使用容器同等的轻量级效果事实上,在仅拥有容量有限的有限资源时,您需要能够可以进行密集部署的轻量级应用。
Linux 容器可从单个操作系统运行,在所有容器中共享该操作系统,因此应用和服务能够保持轻量级,并行快速运行1.3 容器发展简史
![](http://ldjg88.com/zb_users/upload/2024/07/20240703034515171994951538737.jpeg)
我们现在称为容器技术的概念最初出现在 2000 年,当时称为 FreeBSD jail,这种技术可将 FreeBSD 系统分区为多个子系统(也称为 Jail)Jail 是作为安全环境而开发的,系统管理员可与企业内部或外部的多个用户共享这些 Jail。
Jail 的目的是让进程在经过修改的 chroot 环境中创建,而不会脱离和影响整个系统 — 在 chroot 环境中,对文件系统、网络和用户的访问都实现了虚拟化尽管 Jail 在实施方面存在局限性,但最终人们找到了脱离这种隔离环境的方法。
但这个概念非常有吸引力2001 年,通过 Jacques Gélinas 的 VServer 项目,隔离环境的实施进入了 Linux 领域正如 Gélinas 所说,这项工作的目的是“在高度独立且安全的单一环境中运行多个通用 Linux 服务器 [sic]。
” 在完成了这项针对 Linux 中多个受控制用户空间的基础性工作后,Linux 容器开始逐渐成形并最终发展成了现在的模样2 什么是 Docker?“Docker” 一词指代多种事物,包括开源社区项目、开源项目使用的工具、主导支持此类项目的公司 Docker Inc. 以及该公司官方支持的工具。
技术产品和公司使用同一名称,的确让人有点困惑我们来简单说明一下:IT 软件中所说的 “Docker” ,是指容器化技术,用于支持创建和使用 Linux 容器开源 Docker 社区致力于改进这类技术,并免费提供给所有用户,使之获益。
Docker Inc. 公司凭借 Docker 社区产品起家,它主要负责提升社区版本的安全性,并将改进后的版本与更广泛的技术社区分享此外,它还专门对这些技术产品进行完善和安全固化,以服务于企业客户借助 Docker ,您可将容器当做重量轻、模块化的虚拟机使用。
同时,您还将获得高度的灵活性,从而实现对容器的高效创建、部署及复制,并能将其从一个环境顺利迁移至另一个环境2.1 Docker 如何工作?Docker 技术使用 Linux 内核和内核功能(例如 Cgroups 和 namespaces)来分隔进程,以便各进程相互独立运行。
这种独立性正是采用容器的目的所在;它可以独立运行多种进程、多个应用程序,更加充分地发挥基础设施的作用,同时保持各个独立系统的安全性容器工具(包括 Docker)可提供基于镜像的部署模式这使得它能够轻松跨多种环境,与其依赖程序共享应用或服务组。
Docker 还可在这一容器环境中自动部署应用程序(或者合并多种流程,以构建单个应用程序)此外,由于这些工具基于 Linux 容器构建,使得 Docker 既易于使用,又别具一格 —— 它可为用户提供前所未有的高度应用程访问权限、快速部署以及版本控制和分发能力。
2.2 Docker 技术是否与传统的 Linux 容器相同?否Docker 技术最初是基于 LXC 技术构建(大多数人都会将这一技术与“传统的” Linux 容器联系在一起),但后来它逐渐摆脱了对这种技术的依赖。
就轻量级虚拟化这一功能来看,LXC 非常有用,但它无法提供出色的开发人员或用户体验。除了运行容器之外,Docker 技术还具备其他多项功能,包括简化用于构建容器、传输镜像以及控制镜像版本的流程。
![](http://ldjg88.com/zb_users/upload/2024/07/20240703034516171994951661220.jpeg)
传统的 Linux 容器使用 init 系统来管理多种进程这意味着,所有应用程序都作为一个整体运行与此相反,Docker 技术鼓励应用程序各自独立运行其进程,并提供相应工具以实现这一功能这种精细化运作模式自有其优势。
2.3 docker的目标docker的主要目标是"Build,Ship and Run any App,Angwhere",构建,运输,处处运行构建:做一个docker镜像运输:docker pull
运行:启动一个容器每一个容器,他都有自己的文件系统rootfs.3 安装Docker环境说明# 需要两台几点进行安装[root@docker01 ~]# cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core) [root@docker01 ~]# uname -r 3.10.0-327.el7.x86_64[root@docker01 ~]
# hostname -I10.0.0.100172.16.1.100[root@docker02 ~]# hostname -I10.0.0.101172.16.1.101在两个节点上都进行操作wget -O /etc/yum.repos.d/docker-ce.repo https:
//mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.reposed -i s#download.docker.com#mirrors.ustc.edu.cn/docker-ce#g
/etc/yum.repos.d/docker-ce.repoyum install docker-ce -y修改在docker01配置:# 修改启动文件,监听远程端口vim /usr/lib/systemd/system/docker.service
ExecStart\=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://10.0.0.100:2375 systemctl daemon\-reload
systemctl enable docker.service systemctl restart docker.service # ps -ef检查进行,是否启动在docker02测试[root@docker02 ~]
# docker -H 10.0.0.100 infoContainers: 0 Running: 0 Paused: 0 Stopped: 0Images: 0Server Version: 17.12.0
-ceStorage Driver: devicemapper···3.1 Docker基础命令操作查看docker相关信息[root@docker01 ~]# docker version Client:
Version: 17.12.0-ce API version: 1.35 Go version: go1.9.2 Git commit: c97c6d6 Built: Wed Dec
2720:10:142017 OS/Arch: linux/amd64Server: Engine: Version: 17.12.0-ce API version: 1.35 (minimum version
1.12) Go version: go1.9.2 Git commit: c97c6d6 Built: Wed Dec 2720:12:462017 OS/Arch: linux/amd64
Experimental: false配置docker镜像加速vi /etc/docker/daemon.json{ "registry-mirrors": ["https://registry.docker-cn.com"
]}3.2 启动第一个容器[root@docker01 ~]# docker run -d -p 80:80 nginxUnable to find image nginx:latest locally
latest: Pulling from library/nginxe7bb522d92ff: Pull complete 6edc05228666: Pull complete cd866a17e81f: Pull complete
Digest: sha256:285b49d42c703fdf257d1e2422765c4ba9d3e37768d6ea83d7fe2043dad6e63dStatus: Downloaded newer image
for nginx:latest8d8f81da12b5c10af6ba1a5d07f4abc041cb95b01f3d632c3d638922800b0b4d # 容器启动后,在浏览器进行访问测试参数说明
参数说明run创建并运行一个容器-d放入后台-p端口映射nginx镜像名称3.3 Docker镜像生命周期
![](http://ldjg88.com/zb_users/upload/2024/07/20240703034516171994951656906.jpeg)
4 docker镜像相关操作4.1 搜索官方仓库镜像[root@docker01 ~]# docker search centosNAME DESCRIPTION STARS OFFICIAL AUTOMATED
centos The official build of CentOS. 3992 [OK] ansible/centos7-ansible Ansible on Centos7
105列表说明参数说明NAME镜像名称DESCRIPTION镜像说明STARS点赞数量OFFICIAL是否是官方的AUTOMATED是否是自动构建的4.2 获取镜像根据镜像名称拉取镜像[root@docker01 ~]
# docker pull centosUsing default tag: latestlatest: Pulling from library/centosaf4b0a2388c6: Downloading
34.65MB/73.67MB查看当前主机镜像列表[root@docker01 ~]# docker image list REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest ff426288ea90 3 weeks ago 207MBnginx latest
3f8a4339aadd 5 weeks ago 108MB拉第三方镜像方法docker pull index.tenxcloud.com/tenxcloud/httpd4.3 导出镜像
[root@docker01 ~]# docker image list REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest ff426288ea90 3 weeks ago 207MBnginx latest
3f8a4339aadd 5 weeks ago 108MB# 导出[root@docker01 ~]# docker image save centos > docker-centos.tar.gz
4.4 删除镜像[root@docker01 ~]# docker image rm centos:latest[root@docker01 ~]# docker image list REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 3f8a4339aadd 5 weeks ago 108MB4.5 导入镜像[root@docker01 ~]
# docker image load -i docker-centos.tar.gz e15afa4858b6: Loading layer 215.8MB/215.8MBLoaded image: centos:latest
[root@docker01 ~]# docker image list REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest ff426288ea90 3 weeks ago 207MBnginx latest
3f8a4339aadd 5 weeks ago 108MB4.6 查看镜像的详细信息[root@docker01 ~]# docker image inspect centos
5 容器的日常管理5.1 容器的起/停最简单的运行一个容器[root@docker01 ~]# docker run nginx创建容器,两步走(不常用)[root@docker01 ~]# docker create centos:latest /bin/bash
bb7f32368ecf0492adb59e20032ab2e6cf6a563a0e6751e58930ee5f7aaef204[root@docker01 ~]# docker start stupefied_nobel
stupefied_nobel快速启动容器方法[root@docker01 ~]# docker run centos:latest /usr/bin/sleep 20;容器内的第一个进程必须一直处于运行的状态,否则这个容器,就会处于退出状态!
查看正在运行的容器[root@docker01 ~]# docker container ls 或[root@docker01 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8708e93fd767 nginx "nginx -g daemon of…"6 seconds ago Up 4 seconds
80/tcp keen_lewin查看你容器详细信息/ip[root@docker01 ~]# docker container inspect 容器名称/id查看你所有容器(包括未运行的)
root@docker01 ~]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8708e93fd767 nginx "nginx -g daemon of…"4minutes ago Exited(0) 59 seconds ago keen_lewin
f9f3e6af7508 nginx "nginx -g daemon of…" 5 minutes ago Exited(0) 5 minutes ago optimistic_haibt
8d8f81da12b5 nginx "nginx -g daemon of…" 3 hours ago Exited(0) 3 hours ago lucid_bohr
停止容器[root@docker01 ~]# docker stop 容器名称/id 或[root@docker01 ~]# docker container kill 容器名称/id5.2 进入容器方法
启动时进去方法[root@docker01 ~]# docker run -it #参数:-it 可交互终端[root@docker01 ~]# docker run -it nginx:latest /bin/bash
root@79241093859e:/#退出/离开容器1 | ctrl+p & ctrl+q启动后进入容器的方法启动一个docker[root@docker01 ~]# docker run -it centos:latest
[root@1bf0f43c4d2f /]# ps -ef UID PID PPID C STIME TTY TIME CMDroot 10015
:47 pts/000:00:00 /bin/bashroot 131015:47 pts/000:00:00 ps -efattach进入容器,使用pts/0 ,会让所用通过此方法进如放入用户看到同样的操作。
[root@docker01 ~]# docker attach 1bf0f43c4d2f[root@1bf0f43c4d2f /]# ps -ef UID PID PPID C STIME TTY TIME CMD
root 10015:47 pts/000:00:00 /bin/bashroot 141015:49 pts/000:00:00 ps -ef自命名启动一个容器 --name
[root@docker01 ~]# docker attach 1bf0f43c4d2f[root@1bf0f43c4d2f /]# ps -ef UID PID PPID C STIME TTY TIME CMD
root 10015:47 pts/000:00:00 /bin/bashroot 141015:49 pts/000:00:00 ps -efexrc 进入容器方法(推荐使用)
[root@docker01 ~]# docker exec -it clsn1 /bin/bash [root@b20fa75b4b40 /]# 重新分配一个终端[root@b20fa75b4b40 /]
# ps -ef UID PID PPID C STIME TTY TIME CMDroot 10016:11 pts/000:00:00 /bin/bash
root 130016:14 pts/100:00:00 /bin/bashroot 2613016:14 pts/100:00:00 ps -ef5.3 删除所有容器[root@docker01 ~]
# docker rm -f `docker ps -a -q`# -f 强制删除5.4 启动时进行端口映射-p参数端口映射[root@docker01 ~]# docker run -d -p 8888:80 nginx:latest
287bec5c60263166c03e1fc5b0b8262fe76507be3dfae4ce5cd2ee2d1e8a89a9不同指定映射方法参数说明-p hostPort:containerPort
端口映射 -p 8080:80-p ip:hostPort:containerPort 配置监听地址 -p 10.0.0.100:8080:80-p ip::containerPort
随机分配端口 -p 10.0.0.100::80-p hostPort:containerPort:udp指定协议 -p 8080:80:tcp-p 81:80 –p 443:443
指定多个随机映射docker run -P (大P)# 需要镜像支持6 Docker 数据卷的管理6.1 挂载时创建卷挂载卷[root@docker01 ~]# docker run -d -p 80:80 -v /data:/usr/share/nginx/html nginx:latest
079786c1e297b5c5031e7a841160c74e91d4ad06516505043c60dbb78a259d09容器内站点目录: /usr/share/nginx/html在宿主机写入数据,查看
[root@docker01 ~]# echo "http://www.nmtui.com" >/data/index.html[root@docker01 ~]# curl 10.0.0.100http:
//www.nmtui.com设置共享卷,使用同一个卷启动一个新的容器[root@docker01 ~]# docker run -d -p 8080:80 -v /data:/usr/share/nginx/html nginx:latest
351f0bd78d273604bd0971b186979aa0f3cbf45247274493d2490527babb4e42[root@docker01 ~]# curl 10.0.0.100:8080
http://www.nmtui.com查看卷列表[root@docker01 ~]# docker volume lsDRIVER VOLUME NAME6.2 创建卷后挂载
创建一个卷[root@docker01 ~]# docker volume create f3b95f7bd17da220e63d4e70850b8d7fb3e20f8ad02043423a39fdd072b83521
[root@docker01 ~]# docker volume ls DRIVER VOLUME NAMElocal f3b95f7bd17da220e63d4e70850b8d7fb3e20f8ad02043423a39fdd072b83521
指定卷名[root@docker01 ~]# docker volume ls DRIVER VOLUME NAMElocal clsnlocal f3b95f7bd17da220e63d4e70850b8d7fb3e20f8ad02043423a39fdd072b83521
查看卷路径[root@docker01 ~]# docker volume inspect clsn [ {"CreatedAt": "2018-02-01T00:39:25+08:00","Driver"
: "local","Labels": {},"Mountpoint": "/var/lib/docker/volumes/clsn/_data","Name": "clsn","Options": {},
"Scope": "local" }]使用卷创建[root@docker01 ~]# docker run -d -p 9000:80 -v clsn:/usr/share/nginx/html nginx:latest
1434559cff996162da7ce71820ed8f5937fb7c02113bbc84e965845c219d3503# 宿主机测试[root@docker01 ~]# echo blog.nmtui.com
>/var/lib/docker/volumes/clsn/_data/index.html [root@docker01 ~]# curl 10.0.0.100:9000blog.nmtui.com
设置卷[root@docker01 ~]# docker run -d -P --volumes-from 079786c1e297 nginx:latest b54b9c9930b417ab3257c6e4a8280b54fae57043c0b76b9dc60b4788e92369fb
查看使用的端口[root@docker01 ~]# netstat -lntup Active Internet connections(only servers)Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1400/sshd tcp 0 0 10.0.0.100:2375 0.0.0.0:* LISTEN 26218/dockerd
tcp6 0 0 :::9000 :::* LISTEN 32015/docker-proxy tcp6 0 0 :::8080 :::* LISTEN 31853/docker-proxy
tcp6 0 0 :::80 :::* LISTEN 31752/docker-proxy tcp6 0 0 :::22 :::* LISTEN 1400/sshd
tcp6 0 0 :::32769 :::* LISTEN 32300/docker-proxy [root@docker01 ~]
# curl 10.0.0.100:32769http://www.nmtui.com6.3 手动将容器保存为镜像本次是基于docker官方centos 6.8 镜像创建官方镜像列表:https://hub.docker.com/explore/
启动一个centos6.8的镜像[root@docker01 ~]# docker pull centos:6.8[root@docker01 ~]# docker run -it -p 1022:22 centos:6.8 /bin/bash
# 在容器种安装sshd服务,并修改系统密码[root@582051b2b92b ~]# yum install openssh-server -y [root@582051b2b92b ~]# echo
"root:123456" |chpasswd[root@582051b2b92b ~]# /etc/init.d/sshd start启动完成后镜像ssh连接测试将容器提交为镜像[root@docker01 ~]
# docker commit brave_mcclintock centos6-ssh使用新的镜像启动容器[root@docker01 ~]# docker run -d -p 1122:22 centos6-ssh:latest /usr/sbin/sshd -D
5b8161fda2a9f2c39c196c67e2eb9274977e7723fe51c4f08a0190217ae93094在容器安装httpd服务[root@5b8161fda2a9 /]# yum install httpd -y
编写启动脚本脚本[root@5b8161fda2a9 /]# cat init.sh #!/bin/bash /etc/init.d/httpd start /usr/sbin/sshd -D[root@
5b8161fda2a9 /]# chmod +x init.sh # 注意执行权限注意执行权限再次提交为新的镜像[root@docker01 ~]# docker commit 5b8161fda2a9 centos6-httpd
sha256:705d67a786cac040800b8485cf046fd57b1828b805c515377fc3e9cea3a481c1启动镜像,做好端口映射并在浏览器中测试访问[root@docker01 ~]。
# docker run -d -p 1222:22 -p 80:80 centos6-httpd /init.sh 46fa6a06644e31701dc019fb3a8c3b6ef008d4c2c10d46662a97664f838d8c2c
7 Dockerfile自动构建docker镜像官方构建dockerffile文件参考:https://github.com/CentOS/CentOS-Dockerfiles7.1 Dockerfile指令集
dockerfile主要组成部分: 基础镜像信息 FROM centos:6.8 制作镜像操作指令RUN yum insatll openssh-server \-y 容器启动时执行指令 CMD \["/bin/bash"\]
dockerfile常用指令: FROM 这个镜像的妈妈是谁?(指定基础镜像) MAINTAINER 告诉别人,谁负责养它?(指定维护者信息,可以没有) RUN 你想让它干啥(在命令前面加上RUN即可)
ADD 给它点创业资金(COPY文件,会自动解压) WORKDIR 我是cd,今天刚化了妆(设置当前工作目录) VOLUME 给它一个存放行李的地方(设置卷,挂载主机目录) EXPOSE 它要打开的门是啥(指定对外的端口)
CMD 奔跑吧,兄弟!(指定容器启动后的要干的事情)dockerfile其他指令:COPY 复制文件ENV 环境变量ENTRYPOINT 容器启动后执行的命令7.2 创建一个Dockerfile创建第一个Dockerfile文件
# 创建目录[root@docker01 base]# cd /opt/base# 创建Dcokerfile文件,注意大小写[root@docker01 base]# vim DockerfileFROM centos:
6.8RUN yum install openssh-server -y RUN echo "root:123456" |chpasswdRUN /etc/init.d/sshd start CMD [
"/usr/sbin/sshd","-D"]构建docker镜像[root@docker01 base]# docker image build -t centos6.8-ssh . -t 为镜像标签打标签 . 表示当前路径
使用自构建的镜像启动[root@docker01 base]# docker run -d -p 2022:22 centos6.8-ssh-b dc3027d3c15dac881e8e2aeff80724216f3ac725f142daa66484f7cb5d074e7a
7.3 使用Dcokerfile安装kodexplorerDockerfile文件内容FROM centos:6.8RUN yum install wget unzip php php-gd php-mbstring -y && yum clean all
# 设置工作目录,之后的操作都在这个目录中WORKDIR /var/www/html/RUN wget -c http://static.kodcloud.com/update/download/kodexplorer4.25.zip
RUN unzip kodexplorer4.25.zip && rm -f kodexplorer4.25.zipRUN chown -R apache.apache .CMD ["/usr/sbin/apachectl"
,"-D","FOREGROUND"]更多的Dockerfile可以参考官方方法8 Docker中的镜像分层参考文档:http://www.maiziedu.com/wiki/cloud/dockerimage。
Docker 支持通过扩展现有镜像,创建新的镜像。实际上,Docker Hub 中 99% 的镜像都是通过在 base 镜像中安装和配置需要的软件构建出来的。
从上图可以看到,新镜像是从 base 镜像一层一层叠加生成的每安装一个软件,就在现有镜像的基础上增加一层8.1 Docker 镜像为什么分层镜像分层最大的一个好处就是共享资源比如说有多个镜像都从相同的 base 镜像构建而来,那么 Docker Host 只需在磁盘上保存一份 base 镜像;同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。
而且镜像的每一层都可以被共享如果多个容器共享一份基础镜像,当某个容器修改了基础镜像的内容,比如 /etc 下的文件,这时其他容器的 /etc 是不会被修改的,修改只会被限制在单个容器内这就是容器 Copy-on-Write 特性。
8.2 可写的容器层当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。
所有对容器的改动 - 无论添加、删除、还是修改文件都只会发生在容器层中只有容器层是可写的,容器层下面的所有镜像层都是只读的8.3 容器层的细节说明镜像层数量可能会很多,所有镜像层会联合在一起组成一个统一的文件系统。
如果不同层中有一个相同路径的文件,比如 /a,上层的 /a 会覆盖下层的 /a,也就是说用户只能访问到上层中的文件 /a在容器层中,用户看到的是一个叠加之后的文件系统文件操作说明文件操作说明添加文件在容器中创建文件时,新文件被
添加到容器层中读取文件在容器中读取某个文件时,Docker 会从上往下依次在各镜像层中查找此文件一旦找到,立即将其复制到容器层,然后打开并读入内存修改文件在容器中修改已存在的文件时,Docker 会从上往下依次在各镜像层中查找
此文件一旦找到,立即将其复制到容器层,然后修改之删除文件在容器中删除文件时,Docker 也是从上往下依次在镜像层中查找此文件找到后,会在容器层中记录下此删除操作(只是记录删除操作)只有当需要修改时才复制一份数据,这种特性被称作 Copy-on-Write。
可见,容器层保存的是镜像变化的部分,不会对镜像本身进行任何修改这样就解释了我们前面提出的问题:容器层记录对镜像的修改,所有镜像层都是只读的,不会被容器修改,所以镜像可以被多个容器共享9 使用docker运行zabbix-server。
9.1 容器间的互联在运行zabbix之前务必要了解容器间互联的方法# 创建一个nginx容器docker run -d -p 80:80 nginx# 创建容器,做link,并进入容器中docker run -it --link quirky_brown:web01 centos-ssh /bin/bash
# 在容器中访问nginx容器可以ping通ping web01命令执行过程# 启动apache容器[root@docker01 ~]# docker run -d httpd:2.4 3f1f7fc554720424327286bd2b04aeab1b084a3fb011a785b0deab6a34e56955
^[[A[root@docker01 docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3f1f7fc55472 httpd:2.4"httpd-foreground"6 seconds ago Up 5 seconds 80/tcp determined_clarke
# 拉取一个busybox 镜像[root@docker01 ~]# docker pull busybox # 启动容器[root@docker01 ~]# docker run -it --link determined_clarke:web busybox:latest /bin/sh
/ # # 使用新的容器访问最初的web容器/ # ping web PING web(172.17.0.2): 56 data bytes64 bytes from 172.17.0.2: seq=0
ttl=64 time=0.058 ms^C--- web ping statistics ---1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.058/0.058/0.058 ms9.2 启动zabbix容器1、启动一个mysql的容器docker run --name mysql-server -t \
-e MYSQL_DATABASE="zabbix" \ -e MYSQL_USER="zabbix" \ -e MYSQL_PASSWORD="zabbix_pwd" \
-e MYSQL_ROOT_PASSWORD="root_pwd" \ -d mysql:5.7 \ --character-set-server=utf8 --collation-server=utf8_bin
2、启动java-gateway容器监控java服务docker run --name zabbix-java-gateway -t \ -d zabbix/zabbix-java-gateway:latest
3、启动zabbix-mysql容器使用link连接mysql与java-gatewaydocker run --name zabbix-server-mysql -t \ -e DB_SERVER_HOST=。
"mysql-server" \ -e MYSQL_DATABASE="zabbix" \ -e MYSQL_USER="zabbix" \ -e MYSQL_PASSWORD=
"zabbix_pwd" \ -e MYSQL_ROOT_PASSWORD="root_pwd" \ -e ZBX_JAVAGATEWAY="zabbix-java-gateway"
\ --link mysql-server:mysql \ --link zabbix-java-gateway:zabbix-java-gateway \ -p 10051
:10051 \ -d zabbix/zabbix-server-mysql:latest4、启动zabbix web显示,使用link连接zabbix-mysql与mysqldocker run --name zabbix-web-nginx-mysql -t \。
-e DB_SERVER_HOST="mysql-server" \ -e MYSQL_DATABASE="zabbix" \ -e MYSQL_USER="zabbix"
\ -e MYSQL_PASSWORD="zabbix_pwd" \ -e MYSQL_ROOT_PASSWORD="root_pwd" \ --link mysql-server:mysql \
--link zabbix-server-mysql:zabbix-server \ -p 80:80 \ -d zabbix/zabbix-web-nginx-mysql:latest
9.3 关于zabbix API关于zabbix API可以参考官方文档:https://www.zabbix.com/documentation/3.4/zh/manual/api获取token方法# 获取token
[root@docker02 ~]# curl -s -X POST -H Content-Type:application/json -d {"jsonrpc": "2.0","method": "user.login"
,"params": {"user": "Admin","password": "zabbix"},"id": 1} http://10.0.0.100/api_jsonrpc.php{"jsonrpc":"2.0","result":"d3be707f9e866ec5d0d1c242292cbebd","id":1}
10 docker 仓库(registry)10.1 创建一个普通仓库1、创建仓库docker run -d -p 5000:5000 --restart=always --name registry -v /opt/myregistry:/var/lib/registry registry
2、修改配置文件,使之支持http[root@docker01 ~]# cat /etc/docker/daemon.json {"registry-mirrors": ["https://registry.docker-cn.com"
],"insecure-registries": ["10.0.0.100:5000"]}重启docker让修改生效[root@docker01 ~]# systemctl restart docker.service
3、修改镜像标签[root@docker01 ~]# docker tag busybox:latest 10.0.0.100:5000/clsn/busybox:1.0[root@docker01 ~]
# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZE
centos6-ssh latest 3c2b1e57a0f5 18 hours ago 393MBhttpd
2.42e202f453940 6 days ago 179MB10.0.0.100:5000/clsn/busybox 1.05b0d59026729
8 days ago 1.15MB4、将新打标签的镜像上传镜像到仓库[root@docker01 ~]# docker push 10.0.0.100:5000/clsn/busybox
10.2 带basic认证的仓库1、安装加密工具[root@docker01 clsn]# yum install httpd-tools -y2、设置认证密码mkdir /opt/registry-var/auth/ -p
htpasswd \-Bbn clsn 123456 > /opt/registry-var/auth/htpasswd3、启动容器,在启动时传入认证参数docker run -d -p 5000:5000
-v /opt/registry-var/auth/:/auth/ -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm"
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd registry4、使用验证用户测试# 登陆用户[root@docker01 ~]# docker login 10.0.0.100:5000
Username: clsn Password: 123456Login Succeeded# 推送镜像到仓库[root@docker01 ~]# docker push 10.0.0.100:5000/clsn/busybox
The push refers to repository [10.0.0.100:5000/clsn/busybox]4febd3792a1f: Pushed 1.0: digest: sha256:
4cee1979ba0bf7db9fc5d28fb7b798ca69ae95a47c5fecf46327720df4ff352d size: 527#认证文件的保存位置[root@docker01 ~]
# cat .docker/config.json {"auths": {"10.0.0.100:5000": {"auth": "Y2xzbjoxMjM0NTY=" },"https://index.docker.io/v1/"
: {"auth": "Y2xzbjpIenNAMTk5Ng==" } },"HttpHeaders": {"User-Agent": "Docker-Client/17.12.0-ce (linux)"
}}至此,一个简单的docker镜像仓库搭建完成11 docker-compose编排工具11.1 安装docker-compose安装docker-compose# 下载pip软件yum install -y python2-pip
# 下载 docker-composepip install docker-compose国内开启pip 下载加速:http://mirrors.aliyun.com/help/pypimkdir ~/.pip/
cat > ~/.pip/pip.conf <
EOF11.2 编排启动镜像1、创建文件目录[root@docker01 ~]# mkdir /opt/my_wordpress/[root@docker01 ~]# cd /opt/my_wordpress/
2、编写编排文件[root@docker01 my_wordpress]# vim docker-compose.ymlversion: 3services: db: image: mysql:
5.7 volumes: - /data/db_data:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress wordpress:
depends_on: - db image: wordpress:latest volumes: - /data/web_data:/var/www/html
ports: - "8000:80" restart: always environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress3、启动[root@docker01 my_wordpress]# docker-compose up #启动方法:docker-compose up
#后台启动方法:docker-compose up -d4、浏览器上访问http://10.0.0.100:8000进行wordpress的安装即可11.3 haproxy代理后端docker容器1、修改编排脚本
[root@docker01 my_wordpress]# cat docker-compose.yml version: 3services: db: image: mysql:5.7 volumes:
- /data/db_data:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress wordpress:
depends_on: - db image: wordpress:latest volumes: - /data/web_data:/var/www/html
ports: - "80" restart: always environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress2、同时启动两台wordpress[root@docker01 my_wordpress]# docker-compose scale wordpress=2
WARNING: The scale command is deprecated. Use the up command with the --scale flag instead.Starting mywordpress_wordpress_1 ... done
Creating mywordpress_wordpress_2 ... done3、安装haproxy[root@docker01 ~]# yum install haproxy -y4、修改haproxy配置文件
关于配置文件的详细说明,参考:https://www.cnblogs.com/MacoLee/p/5853413.html[root@docker01 ~]#cp /etc/haproxy/haproxy.cfg{,.bak}
[root@docker01 ~]# vim /etc/haproxy/haproxy.cfggloballog127.0.0.1 local2 chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid maxconn 4000 user haproxy group haproxy
daemon stats socket /var/lib/haproxy/stats level admin #支持命令行控制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 queue1m timeout connect
10s timeout client 1m timeout server 1m timeout http-keep-alive 10s timeout check
10s maxconn 3000listen stats mode http bind 0.0.0.0:8888 stats enable stats uri /haproxy-status
stats auth admin:123456frontend frontend_www_example_com bind 10.0.0.100:8000 mode http option httplog
log global default_backend backend_www_example_combackend backend_www_example_com option forwardfor header X-REAL-IP
option httpchk HEAD / HTTP/1.0 balance roundrobin server web-node1 10.0.0.100:32768 check inter
2000 rise 30 fall 15 server web-node2 10.0.0.100:32769 check inter 2000 rise 30 fall 155、启动haproxy
systemctl start haproxysystemctl enable haproxy6、使用浏览器访问hapeoxy监听的8000端口可以看到负载的情况
7、使用浏览器访问 http://10.0.0.100:8888/haproxy-status可以看到后端节点的监控状况,
11.4 安装socat 直接操作socket控制haproxy1、安装软件yum install socat.x86\_64 -y2、查看帮助[root@docker01 web_data]# echo
"help"|socat stdio /var/lib/haproxy/stats3、下线后端节点echo "disable server backend_www_example_com/web-node2"
|socat stdio /var/lib/haproxy/stats4、上线后端节点echo "enable server backend_www_example_com/web-node3"|socat stdio /var/lib/haproxy/stats
5、编写php测试页,放到/data/web_data下,在浏览器中访问可以查看当前的节点[root@docker01 web_data]# vim check.php PHP测试
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。