文章目录
- 什么是 Docker
- Docker 理念
- 能做什么
- Docker 基本组成
- Linux 中安装
- CentOS 6.8 安装 Docker
- CentOS 7 安装 Docker
- Docker 中国官方镜像加速
- 使用 --registry-mirror 配置 Docker 守护进程
- 阿里云镜像加速
- 底层原理
- 常用命令
- 启动服务
- 帮助命令
- 镜像命令
- 列出本机上所有镜像:images
- 搜索镜像:search
- 下载镜像:pull
- 根据ID删除镜像:rmi
- 容器命令
- 新建并启动容器:run
- 列出运行的容器:ps
- 退出容器:exit
- 启动容器:start
- 重启容器:restart
- 停止容器:stop
- 强制停止容器:kill
- 删除容器:rm
- 重要命令
- 容器命令
- 启动守护式容器:run
- 查看容器日志:logs
- 查看容器内运行进程:top
- 查看容器内部细节:inspect
- 进入正在运行的容器并交互:attach/exec
- 容器与主机文件对拷:cp
- Docker 镜像
- Docker镜像加载原理
- 分层镜像
- Docker 镜像特点
- 镜像副本提交:commit
- 容器数据卷
- 作用
- 数据卷
- 直接添加数据卷:run -v
- Dockerfile 创建:build
- 数据卷容器
- 容器间传递共享:run --volumes-from
- Docker 网络相关
- Docker 的网络模式
- host 模式
- container 模式
- none 模式
- bridge 模式
- 同主机不同容器之间通信
- 连接方式
- 跨主机不同容器之间通信
- 使用 DockerCompose
- Dockerfile
- DockerFile构建过程解析
- DockerFile体系结构(保留字指令)
- 案例
- Base镜像:scratch
- 自定义镜像:mycentos
- CMD/ENTRYPOINT 镜像案例
- ONBUILD 示例
- tomcat示例:COPY/ADD
- 常用容器操作
- 安装 centos
- 安装 tomcat
- 安装 mysql
- 安装 redis
- 安装 zookeeper
- 安装 dubbo-admin
- 安装 RabbitMQ
- 安装 ElasticSearch
- 本地镜像发布到阿里云
本教程基于 Docker 尚硅谷 修改编写
什么是 Docker
解决了运行环境和配置问题软件容器,方便做持续集成并有助于整体发布的容器虚拟化技术。
环境配置如此麻烦,换一台机器,就要重来一次,费力费时。很多人想到,能不能从根本上解决问题,软件可以带环境安装?也就是说,安装的时候,把原始环境一模一样地复制过来。开发人员利用 Docker 可以消除协作编码时“在我的机器上可正常工作”的问题。
Docker 理念
Docker是基于Go语言实现的云开源项目。
Docker的主要目标是“Build,Ship and Run Any App,Anywhere”,也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的APP(可以是一个WEB应用或数据库应用等等)及其运行环境能够做到“一次封装,到处运行”。
Linux 容器技术的出现就解决了这样一个问题,而 Docker 就是在它的基础上发展过来的。将应用运行在 Docker 容器上面,而 Docker 容器在任何操作系统上都是一致的,这就实现了跨平台、跨服务器。只需要一次配置好环境,换到别的机子上就可以一键部署好,大大简化了操作
能做什么
虚拟机(virtual machine)就是带环境安装的一种解决方案。
虚拟机的缺点:资源占用多,冗余步骤多,启动慢
由于前面虚拟机存在这些缺点,Linux 发展出了另一种虚拟化技术:Linux 容器(Linux Containers,缩写为 LXC)。
Linux 容器不是模拟一个完整的操作系统,而是对进程进行隔离。有了容器,就可以将软件运行所需的所有资源打包到一个隔离的容器中。容器与虚拟机不同,不需要捆绑一整套操作系统,只需要软件工作所需的库资源和设置。系统因此而变得高效轻量并保证部署在任何环境中的软件都能始终如一地运行。
比较了 Docker 和传统虚拟化方式的不同之处:
- 传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;
- 而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。
- 每个容器之间互相隔离,每个容器有自己的文件系统 ,容器之间进程不会相互影响,能区分计算资源。
Docker 基本组成
- Docker 镜像(Image)就是一个只读的模板。镜像可以用来创建 Docker 容器,一个镜像可以创建很多容器。
- Docker 利用 容器(Container) 独立运行的一个或一组应用。容器是用镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。可以把容器看做是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。容器的定义和镜像几乎一模一样,也是一堆层的统一视角,唯一区别在于容器的最上面那一层是可读可写的。
- 仓库(Repository) 是集中存放镜像文件的场所。
仓库(Repository)和仓库注册服务器(Registry)是有区别的。仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。
仓库分为公开仓库(Public)和私有仓库(Private)两种形式。最大的公开仓库是 Docker Hub,存放了数量庞大的镜像供用户下载。国内的公开仓库包括阿里云 、网易云 等
Linux 中安装
CentOS 6.8 安装 Docker
yum install -y epel-release
Docker使用EPEL发布,RHEL系的OS首先要确保已经持有EPEL仓库,否则先检查OS的版本,然后安装相应的EPEL包。- 开始安装:
yum install -y docker-io
- 安装后的配置文件位置:
/etc/sysconfig/docker
- 启动Docker后台服务:
service docker start
- 验证Docker版本:
docker version
CentOS 7 安装 Docker
如果您不是root用户,请在命令前面加上
sudo
- 确定系统为 CentOS7及以上版本:
cat /etc/redhat-release
- 卸载旧版本:
yum remove docker \
docker-common \
docker-selinux \
docker-engine
如果 yum 报告未安装任何这些软件包,这表示情况正常。
- yum安装gcc相关:
yum -y install gcc
yum -y install gcc-c++
- 安装需要的软件包
yum install -y yum-utils device-mapper-persistent-data lvm2
(忽略)修改官方文档中提供的镜像地址。
注意,官方文档中提供的镜像地址可能依旧访问缓慢,所以需要用到阿里云的镜像
(忽略)更新 yum 软件包索引:yum makecache fast- 安装最新版本的 Docker CE:
yum install docker-ce
如果安装失败,请自行百度:docker镜像安装
- 或者安装特定版本:
- 列出可用版本:
yum list docker-ce.x86_64 --showduplicates | sort -r
- 安装特定版本,请将版本字符串附加到软件包名称,并使用连字符 (-) 分隔它们:
yum install docker-ce-<VERSION>
- 启动Docker:
systemctl start docker
- 验证Docker:docker version
- HelloWorld:
docker run hello-world
,通过运行hello-world ,Docker先检查本地是不是要此镜像,没有自动从仓库中拉取并运行。
如果加载慢,请看下面的教程,配置镜像加速器
Docker 中国官方镜像加速
通过 Docker 官方镜像加速,中国区用户能够快速访问最流行的 Docker 镜像。该镜像托管于中国大陆,本地用户现在将会享受到更快的下载速度和更强的稳定性,从而能够更敏捷地开发和交付 Docker 化应用。
Docker 中国官方镜像加速可通过 registry.docker-cn.com 访问。该镜像库只包含流行的公有镜像。私有镜像仍需要从美国镜像库中拉取。
您可以使用以下命令直接从该镜像加速地址进行拉取:
docker pull registry.docker-cn.com/myname/myrepo:mytag
例如:
docker pull registry.docker-cn.com/library/ubuntu:16.04
注: 除非您修改了 Docker 守护进程的
--registry-mirror
参数 (见下文), 否则您将需要完整地指定官方镜像的名称。例如,library/ubuntu、library/redis、library/nginx。
使用 --registry-mirror 配置 Docker 守护进程
您可以配置 Docker 守护进程默认使用 Docker 官方镜像加速。这样您可以默认通过官方镜像加速拉取镜像,而无需在每次拉取时指定 registry.docker-cn.com
。
您可以在 Docker 守护进程启动时传入 --registry-mirror
参数:
docker --registry-mirror=https://registry.docker-cn.com daemon
为了永久性保留更改,您可以修改 /etc/docker/daemon.json
文件并添加上 registry-mirrors 键值。
{
"registry-mirrors": ["https://registry.docker-cn.com"]
}
修改保存后重启 Docker 以使配置生效:systemctl restart docker
注: 您也可以使用适用于 Mac 的 Docker 和适用于 Windows 的 Docker 来进行设置。
阿里云镜像加速
鉴于国内网络问题,后续拉取 Docker 镜像十分缓慢,我们可以需要配置加速器来解决,我使用的是阿里云的本人自己账号的镜像地址(需要自己注册有一个属于你自己的加速器地址)
- 注册一个阿里云账户(可用淘宝账号):https://dev.aliyun.com/search.html
- 在管理控制台中找到【容器镜像服务】
- 创建一个获得加速器地址链接:https://cr.console.aliyun.com/cn-hangzhou/mirrors
- 配置 CentOS6.8 本机Docker运行镜像加速器
- 修改Docker配置:
vim /etc/sysconfig/docker
- 将自己的阿里云加速地址配置进
other_args="--registry-mirror=https://你自己的账号加速地址.mirror.aliyuncs.com"
- 重启Docker服务:
service docker restart
- 验证配置成功:
ps -ef | grep docker
。如果在结果中出现后面的一条加速器链接,证明配置成功。
- CentOS7 配置镜像加速器:针对Docker客户端版本大于 1.10.0 的用户您可以通过修改daemon配置文件/etc/docker/daemon.json来使用加速器
- 编辑Docker配置文件:
vi /etc/docker/daemon.json
- 添加加速器地址
- 重启Docker
systemctl daemon-reload
systemctl restart docker
完成配置!!
底层原理
- 如何工作?
Docker是一个Client-Server结构的系统,Docker守护进程运行在主机上, 然后通过Socket连接从客户端访问,守护进程从客户端接受命令并管理运行在主机上的容器。 容器,是一个运行时环境,就是我们前面说到的集装箱。
- 为什么Docker比虚拟机快?
- docker有着比虚拟机更少的抽象层。由于docker不需要Hypervisor实现硬件资源虚拟化,运行在docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在CPU、内存利用率上docker将会在效率上有明显优势。
- docker利用的是宿主机的内核,而不需要Guest OS。因此,当新建一个容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。仍而避免引寻、加载操作系统内核返个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载Guest OS,返个新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了返个过程,因此新建一个docker容器只需要几秒钟。
常用命令
启动服务
CentOS6:使用chkconfig命令即可。
开启服务:service docker start
开机自启:chkconfig docker on
禁用自启: chkconfig docker off
CentOS7:使用systemctl中的enable、disable 即可
开启服务:systemctl start docker
开机自启:systemctl enable docker
禁用自启:systemctl disable docker
帮助命令
Docker帮助命令: docker --help
Docker 详细命令:docker COMMAND --help
查看版本:docker version
Docker统计信息:docker info
镜像命令
列出本机上所有镜像:images
- 各个选项说明:
- REPOSITORY:表示镜像的仓库源
- TAG:镜像的标签
- IMAGE ID:镜像
- IDCREATED:镜像创建时间
- SIZE:镜像大小
注意:Docker命令中 IMAGE
可以指代 REPOSITORY
、 IMAGE ID
、 REPOSITORY:TAG
同一仓库源可以有多个 TAG,代表这个仓库源的不同个版本,我们使用 REPOSITORY:TAG
来定义不同的镜像。如果你不指定一个镜像的版本标签,例如你只使用 ubuntu,docker 将默认使用 ubuntu:latest
镜像
- OPTIONS说明:
-a :列出本地所有的镜像(含中间映像层)
-q :只显示镜像ID。
–digests :显示镜像的摘要信息
–no-trunc :显示完整的镜像信息
搜索镜像:search
手动从Docker镜像仓库中搜索:Docker Hub
命令:docker search [OPTIONS] 镜像名字
- OPTIONS说明:
-f, --filter filter :根据提供的条件过滤过滤输出
–format string :使用Go模板格式化字符串漂亮打印搜索
–limit int :限制搜索结果数(默认25)
–no-trunc :不要截断输出
下载镜像:pull
命令:docker pull 镜像名字[:TAG]
示例:
下载镜像:docker pull tomat
,等价于 docker pull tomat:latest
下载指定版本:docker pull tomcat:7.0
需要查询镜像的版本/TAG,转到 Docker Hub 搜索
根据ID删除镜像:rmi
命令:docker rmi [OPTIONS] IMAGE [IMAGE...]
- OPTIONS说明:
-f, --force :强制删除镜像
–no-prune : 不要删除未标记的父镜像
示例:
强制删除镜像:docker rmi -f hello-world
删除多个镜像 docker rmi hello-world nginx:latest
删除所有镜像:docker rmi -f $(docker images -qa)
,其实就是在子命令里面检索出所有的镜像ID,再执行删除
容器命令
有镜像才能创建容器,这是根本前提(下载一个CentOS镜像演示) :docker pull centos
新建并启动容器:run
命令:docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
- OPTIONS说明(常用):有些是一个减号,有些是两个减号
–name=“容器新名字” : 为容器指定一个名称
-d : 后台运行容器,并返回容器ID,也即启动守护式容器;-i
:以交互模式运行容器,通常与 -t 同时使用-t
:为容器重新分配一个伪输入终端,通常与 -i 同时使用
-P : 随机端口映射
-p : 指定端口映射,有以下四种格式
ip:hostPort:containerPort
ip::containerPort
hostPort:containerPort
containerPort
示例:
启动tomcat: docker run -it -p 8888:8080 tomcat
:表示将主机的8888端口映射到容器的8080,使得可以通过8888端口访问到容器。即可以通过链接:主机IP:8888
访问到tomcat
注意需要开放相应的端口才能其它主机访问
使用交互模式运行容器centos
docker run -it centos
ps -ef
执行命令的id与运行容器的id一致,说明就是在容器centos中
列出运行的容器:ps
命令:docker ps [OPTIONS]
- OPTIONS说明(常用):
-a :列出当前所有正在运行的容器+历史上运行过的(没有此参数表示显示正在运行)
-l :显示最近创建的容器。
-n :显示最近n个创建的容器。-q
:静默模式,只显示容器编号。
–no-trunc :不截断输出。
示例:
显示最近创建的容器:docker ps -l
显示最近3个创建的容器:docker ps -n 3
- 各个选项说明:
- CONTAINER ID:容器ID
- IMAGE:镜像名
- COMMAND:执行的命令
- CREATED:容器创建时间
- STATUS:启动状态
- PORTS:端口映射
- NAMES:容器名
注意:Docker命令中 CONTAINER
可以指代 CONTAINER ID
、 NAMES
退出容器:exit
当登录到Docker容器中时,使用命令 exit
退出并停止容器
另外一个退出方式:快捷键 ctrl+P+Q
可以使容器不停止退出
示例:与centos容器交互、退出
快捷键方式退出:
如果快捷键无效,请检查热键是否被占用
启动容器:start
命令:docker start [OPTIONS] CONTAINER [CONTAINER...]
示例:docker start 容器ID或者容器名
重启容器:restart
命令:docker restart [OPTIONS] CONTAINER [CONTAINER...]
示例:docker restart 容器ID或者容器名
停止容器:stop
命令:docker stop [OPTIONS] CONTAINER [CONTAINER...]
示例:docker stop 容器ID或者容器名
强制停止容器:kill
命令:docker kill [OPTIONS] CONTAINER [CONTAINER...]
示例:docker kill 容器ID或者容器名
删除容器:rm
命令:docker rm [OPTIONS] CONTAINER [CONTAINER...]
- OPTIONS说明:
-f :强制移除正在运行的容器
-l, --link :删除指定的链接
-v, --volumes :删除与容器关联的卷
示例:
删除单个容器:docker rm 容器ID
删除多个容器:docker rm -f $(docker ps -a -q)
删除多个容器2:docker ps -a -q | xargs docker rm
:将查询的结果赋值给xargs
重要命令
容器命令
启动守护式容器:run
继于上面的启动容器,使用它的一个参数 -d
即可设置成守护模式
命令:docker run -d 容器名
使用镜像 centos:latest
以后台模式启动一个容器
示例:docker run -d centos
【错误示例】
问题 :通过 docker ps -a
会发现容器已经退出!
很重要的一点:要想Docker容器后台运行,就必须有一个前台进程
容器运行的命令如果不是那些一直挂起的命令(比如运行top,tail),就是会自动退出。
这个是docker的机制问题,比如你的web容器,我们以nginx为例,正常情况下,我们配置启动服务只需要启动响应的service即可。例如 service nginx start
,但是这样做,nginx为后台进程模式运行,就导致docker前台没有运行的应用,这样的容器后台启动后,会立即自杀因为他觉得他没事可做了。所以最佳的解决方案是:将你要运行的程序以前台进程的形式运行:docker run -it centos
查看容器日志:logs
命令:docker logs [OPTIONS] CONTAINER
- OPTIONS说明:
–details :显示提供给日志的额外详细信息
-f, --follow :跟踪最新日志输出
–since string :显示自时间戳以来的日志(例如:2013-01-02T13:23:37)或相关日志
–tail string :从日志末尾显示的行数(默认显示全部)
-t, --timestamps :显示时间戳
–until string :在时间戳(如2013-01-02T13:23:37)之前显示日志
示例:
显示容器日志:docker logs 容器ID/名称
动态显示容器日志:
- 运行容器并执行shell脚本,使其处于非空闲状态,不至于自杀进程:
docker run -d centos /bin/sh -c "while true;do echo hello docker;sleep 2;done"
- 查看日志:要求显示最新三条日志、显示时间戳、跟踪日志输出
docker logs --tail 3 -t -f 13617502c43e
查看容器内运行进程:top
命令:docker top CONTAINER [ps OPTIONS]
示例:docker top hungry_feistel
查看容器内部细节:inspect
命令:docker inspect [OPTIONS] NAME|ID [NAME|ID...]
- OPTIONS说明:
-f, --format string :使用给定的Go模板格式化输出
-s, --size :如果类型是容器,则显示总文件大小
–type string :返回指定类型的JSON
示例:
查看与物理主机的挂载目录:docker inspect --format "{{.Mounts}}" 容器ID
- 另一种查看方式:
docker inspect 容器ID | grep Mounts -A 10
表示查找Mounts,并显示10行
进入正在运行的容器并交互:attach/exec
命令:docker attach [OPTIONS] CONTAINER
示例:
重新进入容器:docker attach 容器ID
命令:docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
- OPTIONS说明:
-d, --detach :分离模式:在后台运行命令
–detach-keys string :覆盖用于分离容器的键序列
-e, --env list :设置环境变量
-i, --interactive :即使没有连接,也要保持STDIN打开
–privileged :为命令提供扩展权限
-t, --tty :分配一个伪终端
-u, --user string : 用户名或UID (格式为: <name|uid>[:<group|gid>])
-w, --workdir string :容器内的工作目录
示例:docker exec 13617502c43e ls -l
:相当于在容器中执行了 ls -l
命令又返回到本机
那么 attach 和 exec 有什么区别呢?
- attach 直接进入容器启动命令的终端,不会启动新的进程
- exec 是在容器中打开新的终端,并且可以启动新的进程
就是说 attach命令会进入到容器中,而 exec 可以不进入容器,直接就可以执行命令并且将结果显示出来。
同时 以下两条命令都表示进入容器中
docker attach 容器ID
docker exec -t 容器ID /bin/bash
容器与主机文件对拷:cp
命令:docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
示例:docker cp 容器ID:容器内路径 目的主机路径
:docker cp d641bbb4438b:/usr/test.txt ./
docker cp 目的主机路径 容器ID:容器内路径
:docker cp ./test.txt d641bbb4438b:/
Docker 镜像
Docker镜像是一种 UnionFS(联合文件系统)
Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。
Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
Docker镜像加载原理
docker的镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
rootfs (root file system) ,在bootfs之上。包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。
平时我们安装进虚拟机的CentOS都是好几个G,为什么docker这里才200M??
对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供 rootfs 就行了。由此可见对于不同的linux发行版, bootfs基本是一致的, rootfs会有差别, 因此不同的发行版可以公用bootfs。
分层镜像
以我们的pull为例,在下载的过程中我们可以看到docker的镜像好像是在一层一层的在下载
为什么 Docker 镜像要采用这种分层结构呢?
最大的一个好处就是 共享资源
比如:有多个镜像都从相同的 base 镜像构建而来,那么宿主机只需在磁盘上保存一份base镜像,同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。
Docker 镜像特点
Docker镜像都是只读的。当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。
镜像副本提交:commit
根据容器的更改创建新映像,使用 docker commit 提交容器副本 使之成为一个新的镜像
命令:docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
- OPTIONS说明:
-a, --author string :设置作者名称
-c, --change list :将Dockerfile指令应用于创建的映像
-m, --message string :提交日志
-p, --pause :提交期间暂停容器(默认为true)
示例:
docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]
docker commit -a "theliang" -m "del tomcat docs" 155a8af163cf atguigu/tomcat01:1.2
通过命令 docker images
就可以看到刚刚自己创建的镜像
容器数据卷
先来看看Docker的理念:
- 将运用与运行的环境打包形成容器运行 ,运行可以伴随着容器,但是我们对数据的要求希望是持久化的
- 容器之间希望有可能共享数据
Docker容器产生的数据,如果不通过docker commit 成新的镜像,使得数据做为镜像的一部分保存下来,那么当容器删除后,数据自然也就没有了。为了能保存数据在docker中我们使用卷。
类似Redis里面的rdb和aof文件
作用
卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过Union File System提供一些用于持续存储或共享数据的特性:
卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷
特点:
- 数据卷可在容器之间共享或重用数据
- 卷中的更改可以直接生效
- 数据卷中的更改不会包含在镜像的更新中
- 数据卷的生命周期一直持续到没有容器使用它为止
数据卷
直接添加数据卷:run -v
命令:docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名
示例:docker run -it -v /myDataVolume:/dataVolumeContainer centos
表示:将宿主机根目录下下myDataVolume文件夹与容器内根目录下dataVolumeContainer目录相联系(运行命令后会自动创建文件夹)
- 查看数据卷是否挂载成功:
docker inspect 容器ID
- 新版查看数据卷是否挂载成功:
- 其它查看方式:
docker inspect --format "{{.Config.Volumes}}" 容器ID
此处显示的信息只有docker 容器本地数据卷的信息,与其关联的物理主机的挂载目录位置信息,要使用如下信息查看:docker inspect -f "{{.Mounts}}" 容器ID
- 也通过使用grep显示:
docker inspect 容器ID | grep Mounts -A 10
- 容器和宿主机之间数据共享:
- 容器停止退出后,主机修改后数据是否同步:是的
示例:带权限命令:
docker run -it -v /宿主机绝对路径目录:/容器内目录:ro 镜像名
这里多加了一个 :ro
即 read only ,表示容器只有只读权限,无法对文件修改。
Dockerfile 创建:build
作用:从Dockerfile构建一个映像
命令:docker build [OPTIONS] PATH | URL | -
- OPTIONS说明:
-f, --file string :指定Dockerfile,默认会使用 PATH 下的名为 Dockerfile 的文件
-t, --tag list :名称和标记(可选) ,格式:name:tag
出于可移植和分享的考虑,用 -v 主机目录:容器目录
这种方法不能够直接在 Dockerfile 中实现。
由于宿主机目录是依赖于特定宿主机的,并不能够保证在所有的宿主机上都存在这样的特定目录。
示例:根据镜像centos,添加两个数据卷(包装了一层),生成新的镜像
- 在根目录下创建文件:
/mydocker/dockerfile1
,内容如下:
# volume test
FROM centos
VOLUME ["/dataVolumeContainer1","/dataVolumeContaioner2"]
CMD ECHO "finished,----------success1"
CMD /bin/bash
- 执行命令:
docker build -f /mydocker/dockerfile1 --tag liang/centos .
注意命令中有一个点,表示当前位置
- 通过 docker images 可以看到生成的新镜像
同时你可以注意到,执行build命令后会生成一个 IMAGE ID ,它就是最终生成后的镜像ID
- 启动新镜像:可以看到在容器中已经创建好了两个数据卷
通过上述步骤,容器内的卷目录地址已经知道,但是对应的主机目录地址在哪?
解决:可以通过 inspect 查看容器细节,详细操作在 inspect示例、直接添加数据卷示例
中给出
所以打开主机默认地址后,就可以对文件进行操作了
备注:Docker挂载主机目录Docker访问出现
cannot open directory .: Permission denied
解决办法:在挂载目录后多加一个--privileged=true
参数即可docker run -it -v /myDataVolume:/dataVolumeContainer --privileged=true centos
数据卷容器
命名的容器挂载数据卷,其它容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称之为数据卷容器
换言之,活动硬盘上挂载活动硬盘,实现数据的传递依赖。
容器间传递共享:run --volumes-from
命令:dockeer run -it --name 子容器ID --volumes-from 父容器ID 容器名
示例:要创建数据卷容器
- 先创建一个父容器,我们可以用上面示例中创建出来的
liang/centos
作为模板:docker run -it --name dc01 theliang/centos
- 创建子容器(dc02 和 dc03),继承自dc01
docker run -it --name dc02 --volumes-from dc01 liang/centos
此时,dc01容器中的两个数据卷就可以被它的子容器共享了,它们之间通过数据卷可以共享数据
注意点:
- 删除了父容器dc01后,dc02修改后,dc03仍然可以访问数据卷
- 删除dc02后,dc03仍然可以访问数据卷
- 新建dc04继承dc03后再删除dc03,dc04依然可以访问数据卷
总结:容器之间配置信息的传递,数据卷的生命周期一直持续到时没有容器使用它为止。
Docker 网络相关
Docker 的网络模式
docker 目前支持以下 5 种网络模式:
docker run 创建 Docker 容器时,可以用 -net 选项指定容器的网络模式。
- host 模式 : 使用
-net=host
指定。与宿主机共享网络,此时容器没有使用网络的 namespace,宿主机的所有设备,如 Dbus 会暴露到容器中,因此存在安全隐患。 - container 模式 : 使用
-net=container:NAME_or_ID
指定。指定与某个容器实例共享网络。 - none 模式 : 使用
-net=none
指定。不设置网络,相当于容器内没有配置网卡,用户可以手动配置。 - bridge 模式 : 使用
-net=bridge
指定,默认设置。此时 docker 引擎会创建一个 veth 对,一端连接到容器实例并命名为 eth0,另一端连接到指定的网桥中(比如 docker0),因此同在一个主机的容器实例由于连接在同一个网桥中,它们能够互相通信。容器创建时还会自动创建一条 SNAT 规则,用于容器与外部通信时。如果用户使用了 -p 或者 -Pe 端口,还会创建对应的端口映射规则。 - 自定义模式 : 使用自定义网络,可以使用
docker network create
创建,并且默认支持多种网络驱动,用户可以自由创建桥接网络或者 overlay 网络。
默认是桥接模式,网络地址为 172.17.0.0/16,同一主机的容器实例能够通信,但不能跨主机通信。
host 模式
如果启动容器的时候使用 host 模式,那么这个容器将不会获得一个独立的 Network Namespace,而是和宿主机共用一个 Network Namespace。容器将不会虚拟出自己的网卡,配置自己的 IP 等,而是使用宿主机的 IP 和端口。
container 模式
这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。
none 模式
这个模式和前两个不同。在这种模式下,Docker 容器拥有自己的 Network Namespace,但是,并不为 Docker 容器进行任何网络配置。也就是说,这个 Docker 容器没有网卡、IP、路由等信息。需要我们自己为 Docker 容器添加网卡、配置 IP 等。
bridge 模式
bridge 模式是 Docker 默认的网络设置,此模式会为每一个容器分配 Network Namespace、设置 IP 等,并将一个主机上的 Docker 容器连接到一个虚拟网桥上。
当 Docker server 启动时,会在主机上创建一个名为 docker0 的虚拟网桥,此主机上启动的 Docker 容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。
接下来就要为容器分配 IP 了,Docker 会从 RFC1918 所定义的私有 IP 网段中,选择一个和宿主机不同的 IP 地址和子网分配给 docker0,连接到 docker0 的容器就从这个子网中选择一个未占用的 IP 使用。如一般 Docker 会使用 172.17.0.0/16 这个网段,并将 172.17.42.1/16 分配给 docker0 网桥(在主机上使用 ifconfig 命令是可以看到 docker0 的,可以认为它是网桥的管理接口,在宿主机上作为一块虚拟网卡使用)
当创建一个 Docker 容器的时候,同时会创建了一对 veth pair 接口(当数据包发送到一个接口时,另外一个接口也可以收到相同的数据包)。这对接口一端在容器内,即 eth0;另一端在本地并被挂载到 docker0 网桥,名称以 veth 开头(例如 vethAQI2QT)。通过这种方式,主机可以跟容器通信,容器之间也可以相互通信。Docker 就创建了在主机和所有容器之间一个虚拟共享网络。
同主机不同容器之间通信
这里同主机不同容器之间通信主要使用 Docker 桥接(Bridge)模式。该 bridge 接口在本地一个单独的 Docker 宿主机上运行,并且它是我们后面提到的所有三种连接方式的背后机制。
$ ifconfig docker0
docker0 Link encap:Ethernet HWaddr 56:84:7a:fe:97:99
inet addr:172.17.42.1 Bcast:0.0.0.0 Mask:255.255.0.0
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
连接方式
- 方式一:可以通过使用容器的 IP 地址来通信。这种方式会导致 IP 地址的硬编码,不方便迁移,并且容器重启后 IP 地址可能会改变,除非使用固定的 IP 地址。
- 方式二:可以通过宿主机的 IP 加上容器暴露出的端口号来通信。这种方式比较单一,只能依靠监听在暴露出的端口的进程来进行有限的通信。
- 方式三:可以使用容器名,通过 docker 的 link 机制通信。这种方式通过 docker 的 link 机制可以通过一个 name 来和另一个容器通信,link 机制方便了容器去发现其它的容器并且可以安全的传递一些连接信息给其它的容器。使用 name 给容器起一个别名,方便记忆和使用。即使容器重启了,地址发生了变化,不会影响两个容器之间的连接。
# 查看容器的内部IP
$ docker inspect --format='{{.NetworkSettings.IPAddress}}' $CONTAINER_ID
# Elasticsearch容器
$ docker inspect --format='{{.NetworkSettings.IPAddress}}' 4d5e7a1058de
172.17.0.2
# Kibana容器
$ docker inspect --format='{{.NetworkSettings.IPAddress}}' 4f26e64bfe82
172.17.0.4
方式一:使用容器的 IP 地址来通信
# 进入Kibana容器
$ docker exec -it 4f26e64bfe82 /bin/bash
# 在Kibana容器使用ES容器的IP地址来访问ES服务
$ curl -XGET 'http://172.17.0.2:9200/_cat/health?pretty'
1493707223 06:40:23 ben-es yellow 1 1 11 11 0 0 11 0 - 50.0%
方式二:使用宿主机的 IP 加上容器暴露出的端口号来通信
# 进入Kibana容器
$ docker exec -it 4f26e64bfe82 /bin/bash
# 在Kibana容器使用宿主机的IP地址来访问ES服务(我这里本机的IP地址是10.10.1.129)
$ curl -XGET 'http://10.10.1.129:9200/_cat/health?pretty'
1493707223 06:40:23 ben-es yellow 1 1 11 11 0 0 11 0 - 50.0%
方式三:使用 docker 的 link 机制通信
# 先启动ES容器,并且使用--name指定容器名称为:elasticsearch_2.x_yunyu
$ docker run -itd -p 9200:9200 -p 9300:9300 --name elasticsearch_2.x_yunyu birdben/elasticsearch_2.x:v2
# 启动Kibana容器,并且使用--link指定关联的容器名称为ES的容器名称:elasticsearch_2.x_yunyu
$ docker run -itd -p 5601:5601 --link elasticsearch_2.x_yunyu --name kibana_4.x_yunyu birdben/kibana_4.x:v2
# 查看运行的容器
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
4f26e64bfe82 birdben/kibana_4.x:v2 "docker-entrypoint..." 25 hours ago Up 15 minutes 0.0.0.0:5601->5601/tcp kibana_4.x_yunyu
4d5e7a1058de birdben/elasticsearch_2.x:v2 "docker-entrypoint..." 26 hours ago Up 19 hours 0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp elasticsearch_2.x_yunyu
# 在Kibana容器使用--link的容器名称来访问ES服务
$ curl -XGET 'http://elasticsearch_2.x_yunyu:9200/_cat/health?pretty'
1493707223 06:40:23 ben-es yellow 1 1 11 11 0 0 11 0 - 50.0%
实际上-link 机制就是在 Docker 容器中的 /etc/hosts 文件中添加了一个 ES 容器的名称解析。有了这个名称解析后就可以不使用 IP 来和目标容器通信了,除此之外当目标容器重启,Docker 会负责更新 /etc/hosts 文件,因此可以不用担心容器重启后 IP 地址发生了改变,解析无法生效的问题。
Kibana 容器的 /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 4d5e7a1058de
ES 容器的 /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 elasticsearch_2.x_yunyu 4d5e7a1058de
172.17.0.4 4f26e64bfe82
当 docker 引入网络新特性后,link 机制变的有些多余,但是为了兼容早期版本,-link 机制在默认网络上的功能依旧没有发生变化,docker 引入网络新特性后,内置了一个 DNS Server,但是只有用户创建了自定义网络后,这个 DNS Server 才会起作用。
跨主机不同容器之间通信
(待续)
使用 DockerCompose
(待续)
Dockerfile
Dockerfile是 用来构建Docker镜像的构建文件 ,是由一系列命令和参数构成的脚本。
构建三步骤
- 编写Dockerfile文件
- docker build
- docker run
以容器centos为例 Docker Official Images
DockerFile构建过程解析
基本规则:
- 每条保留字指令都必须为大写字母且后面要跟随至少一个参数
- 指令按照从上到下,顺序执行
- #表示注释
- 每条指令都会创建一个新的镜像层,并对镜像进行提交
Docker执行Dockerfile的大致流程
- docker从基础镜像运行一个容器
- 执行一条指令并对容器作出修改
- 执行类似
docker commit
的操作提交一个新的镜像层 - docker再基于刚提交的镜像运行一个新容器
- 执行 dockerfile 中的下一条指令直到所有指令都执行完成
从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段:
- Dockerfile是软件的原材料
- Docker镜像是软件的交付品
- Docker容器则可以认为是软件的运行态。
Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。
- Dockerfile,需要定义一个Dockerfile,Dockerfile定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等;
- Docker镜像,在用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,当运行 Docker镜像时,会真正开始提供服务;
- Docker容器,容器是直接提供服务的。
DockerFile体系结构(保留字指令)
ADD
:将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包CMD
:指定一个容器启动时要运行的命令,Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换COPY
:类似ADD,拷贝文件和目录到镜像中。 将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置
DockerFile体系结构(保留字指令)ENTRYPOINT
:指定一个容器启动时要运行的命令,ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动程序及参数ENV
:用来在构建镜像过程中设置环境变量EXPOSE
:当前容器对外暴露出的端口FROM
:基础镜像,当前新镜像是基于哪个镜像的MAINTAINER
:镜像维护者的姓名和邮箱地址ONBUILD
:当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承后父镜像的onbuild被触发RUN
:容器构建时需要运行的命令VOLUME
:容器数据卷,用于数据保存和持久化工作WORKDIR
:指定在创建容器后,终端默认登陆的进来工作目录,一个落脚点
部分示例:ENV MY_PATH /usr/mytest
:这个环境变量可以在后续的任何RUN指令中使用,这就如同在命令前面指定了环境变量前缀一样;也可以在其它指令中直接使用这些环境变量,比如:WORKDIR $MY_PATH
COPY src dest
| COPY ["src","dext"]
从构建上下文目录src复制到新的一层镜像内位置dest
CMD 启动命令:
CMD 指定的格式和 RUN 相似,也是两个格式:
- shell 格式:
CMD <命令>
- exce 格式:
CMD ["可执行文件","参数1","参数2"...]
- 参数列表格式:
CMD ["参数1","参数2"...]
。在指定了 ENTERYPOINT 指令后,用 CMD 指定具体的参数
案例
Base镜像:scratch
Docker Hub 中 99% 的镜像都是通过在 base 镜像中安装和配置需要的软件构建出来的
FROM scratch
自定义镜像:mycentos
- Hub默认CentOS镜像
所以通过自定义mycentos镜像,使其具备:登录后的默认路径、vim编辑器、查看网络配置ifconfig支持
- 创建并编辑Dockerfile文件(存放路径及文件名可以不同)
FROM centos # 基于CentOS镜像
MAINTAINER zzyy<zzyy167@163.com> # 镜像维护者姓名和邮箱
ENV MYPATH /usr/local # 设置环境变量
WORKDIR $MYPATH # 引用环境变量为默认工作目录
RUN yum -y install vim # 构建时运行的命令:安装 vim
RUN yum -y install net-tools # 构建时运行的命令:安装 net-tools,使之支持ifconfig
EXPOSE 80 # 对外暴露的端口
CMD echo $MYPATH # 输出环境变量
CMD echo "success----------------OK" # 输出提示信息
CMD /bin/bash # 执行 /bin/bash
- 构建:
docker build -f /mydocker/Dockerfile -t 新镜像名字:TAG .
。注意:命令最后有一个点,表示当前路径。如果当前路径下有名为Dockerfile的文件,可以省略-f
及它的参数
- 运行:
docker run -it 新镜像名字:TAG
可以看到,我们自己的新镜像已经支持 vim/ifconfig 命令,扩展成功了。
- 列出镜像的变更历史:
docker history 镜像名
CMD/ENTRYPOINT 镜像案例
都是指定一个容器启动时要运行的命令
- CMD:Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换。比如 tomcat 默认运行指令是:
CMD ["catalina.sh", "run"]
,如果运行时附加命令:docker run -it -p 8888:8080 tomcat ls -l
,就会使原来的指令失效导致没有启动。 - ENTRYPOINT :
docker run
之后的参数会被当做参数传递给 ENTRYPOINT,之后形成新的命令组合
示例:制作CMD版可以查询IP信息的容器
FROM centos
RUN yum install -y curl
CMD [ "curl", "-s", "https://www.ip.cn" ]
构建三步骤上面的示例已经有了,这里不做赘述
crul命令解释:
- curl命令可以用来执行下载、发送各种HTTP请求,指定HTTP头部等操作。如果系统没有 curl 可以使用
yum install curl
安装。 - curl是将下载文件输出到stdout
使用命令:curl http://www.baidu.com
执行后,www.baidu.com的html源码就会显示在屏幕上了
这是最简单的使用方法。用这个命令获得了 http://curl.haxx.se 指向的页面,同样,如果这里的URL指向的是一个文件或者一幅图都可以直接下载到本地。如果下载的是HTML文档,那么缺省的将只显示文件头部,即HTML文档的header。要全部显示,请加参数 -i
那么问题来了,如果我们希望显示 HTTP 头信息,就需要加上 -i
参数,我们可以看到可执行文件找不到的报错,executable file not found。之前我们说过,跟在镜像名后面的是 command,运行时会替换 CMD 的默认值。因此这里的 -i
替换了原来的 CMD,而不是添加在原来的 curl -s https://www.ip.cn
后面。而 -i
根本不是命令,所以自然找不到。
如果我们希望加入 -i 这参数,我们就必须重新完整的输入这个命令:docker run myip curl -s https://www.ip.cn -i
但是我们也可以使用 ENTROYPOINT 制作查询IP信息的容器
FROM centos
RUN yum install -y curl
ENTRYPOINT [ "curl", "-s", "https://www.ip.cn" ]
此时就可以直接在 docker run 附加参数了
ONBUILD 示例
当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承后父镜像的onbuild被触发
FROM centos
RUN yum install -y curl
ENTRYPOINT [ "curl", "-s", "https://www.ip.cn" ]
ONBUILD RUN echo "now,build action is ok========="
构建一个镜像myip :
构建一个子容器,继承于myip容器
FROM myip
RUN yum install -y curl
ENTRYPOINT [ "curl", "-s", "https://www.ip.cn" ]
tomcat示例:COPY/ADD
- 创建目录:
mkdir -p /zzyyuse/mydockerfile/tomcat9
- 目录下有如下文件:自行获取,不是必须
FROM centos
MAINTAINER zzyy<zzyybs@126.com>
# 把宿主机当前上下文的c.txt拷贝到容器/usr/local/路径下
COPY c.txt /usr/local/cincontainer.txt
# 把java与tomcat添加到容器中
ADD jdk-8u171-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.8.tar.gz /usr/local/
# 安装vim编辑器
RUN yum -y install vim
#设置工作访问时候的WORKDIR路径,登录落脚点
ENV MYPATH /usr/local
WORKDIR $MYPATH
# 配置java与tomcat环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_171
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.8
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.8
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
# 容器运行时监听的端口
EXPOSE 8080
# 启动时运行tomcat
# ENTRYPOINT ["/usr/local/apache-tomcat-9.0.8/bin/startup.sh" ]
# CMD ["/usr/local/apache-tomcat-9.0.8/bin/catalina.sh","run"]
CMD /usr/local/apache-tomcat-9.0.8/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.8/bin/logs/catalina.out
- 构建:此过程中注意 ADD 以及 COPY 的作用
- 运行
- 结合前述的容器卷将测试的web服务test发布:创建web.xml及jsp文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>test</display-name>
</web-app>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
-----------welcome------------
<%="i am in docker tomcat self "%>
<br>
<br>
<% System.out.println("=============docker tomcat self");%>
</body>
</html>
- 测试
常用容器操作
- 搜索镜像:
docker search NAME
- 拉取镜像:
docker pull IMAGES
- 查看镜像:
docker images
- 启动镜像:
docker run -d IMAGES
- 停止容器:
docker stop CONTAINER_ID
- 移除容器:
docker rm CONTAINER_ID
安装 centos
- 拉取镜像:
docker pull centos
- 启动容器:
docker run -itd --name CENTOS_NAME centos /bin/bash
- 进入容器:
docker exec CENTOS_NAME /bin/bash
- 退出容器:
ctrl + p + q
安装 tomcat
- 拉取镜像:
docker pull tomcat:7
- 启动容器:
docker run -d -p 8080:8080 tomcat:7
安装 mysql
- 拉取镜像:
docker pull mysql:5.6
- 启动容器:
docker run -d -p 3306:3306 mysql:5.6
使用数据卷方式启动:
docker run -d -p 3306:3306 --name mysql \
-v /root/mysql/conf:/etc/mysql/conf.d \
-v /root/mysql/logs:/logs \
-v /root/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:5.6
数据备份:
docker exec myql服务容器ID
sh -c ' exec mysqldump --all-databases -uroot -p"root" '
> /root/all-databases.sql
安装 redis
- 拉取镜像:
docker pull redis
- 启动容器:
docker run -d -p 6379:6379 redis redis-server --appendonly yes
- 运行redis客户端:
docker exec -it [运行着Rediis服务的容器ID] redis-cli
使用数据卷方式启动:
docker run -d -p 6379:6379 \
-v /root/myredis/data:/data \
-v /root/myredis/conf/redis.conf:/usr/local/etc/redis/redis.conf \
redis redis-name /usr/local/etc/redis/redis.conf \
--appendonly yes
在主机 /root/myredis/conf/redis.conf
目录下新建 redis.conf 文件
vim /root/myredis/conf/redis.conf/redis.conf
将redis.conf配置文件写入,这里就不提供配置了,启动后就完成了
安装 zookeeper
Zookeeper 是 Apacahe Hadoop 的子项目,是一个树型的目录服务,支持变更推送,适合作为 Dubbo 服务的注册中心,工业强度较高,可用于生产环境,并推荐使用。
所以这里要求安装 zookeeper 及 dubbo-admin 镜像,同时要这两个容器之间建立联系。
- 拉取镜像:
docker pull zookeeper
- 启动容器:
docker run -d \
--name zookeeper_name \
--restart always \
-p 2181:2181 \
-p 2888:2888 \
-p 3888:3888 \
zookeeper
-
--restart always
:由于 zookeeper“fails fast”,最好始终重启它。 - 此镜像包括
EXPOSE 2181 2888 3888
(zookeeper客户端端口,跟随端口,选择端口),因此标准容器链接将使其自动可用于链接的容器。
安装 dubbo-admin
为了让用户更好的管理监控众多的dubbo服务,官方提供了一个可视化的监控程序 dubbo-admin ,不过这个监控即使不装也不影响使用。
- 拉取镜像:
docker pull chenchuxin/dubbo-admin
- 启动容器:
docker run -d \
-p 8080:8080 \
-e admin.registry.address=zookeeper://192.168.222.130:2181 \
-e dubbo.admin.root.password=root \
-e dubbo.admin.guest.password=guest \
--link [name:alias] \
chenchuxin/dubbo-admin
- 测试:访问链接:http://主机IP:8080,输入账号密码root
--link list
:当使用–link方式时,作为客户端的container可以通过私有网络形式访问到这个container。同时Docker会在客户端的container中设定一些环境变量来记录绑定的IP和PORT。也就是说相当于使两个容器处于同一网络。
安装 RabbitMQ
- 拉取镜像:
docker pull rabbitmq:3-management
- 启动容器:
docker run -d \
-p 5672:5672 \
-p 15672:15672 \
--name myrabbitmq \
rabbitmq:3-management
- 带有
-management
的TAG有web界面 - 5672对应RabbitMQ端口
- 15672对应RabbitMQ管理web界面的访问端口
通过访问 :http://IP:15672 即可,用户名及密码为 guest
安装 ElasticSearch
- 拉取镜像:
docker pull elasticsearch
- 启动容器:
docker run -d \
-e ES_JAVA_OPTS="-Xms256m -Xmx256m" \
-p 9200:9200 \
-p 9300:9300 \
--name ES_name \
elasticsearch
-
-e ES_JAVA_OPTS
:表示修改JVM虚拟机的内存,防止内存溢出 - 9200:http通信端口
- 9300:创建 elasticsearch 的分布式时,各个节点之间通信的端口
6.0以上版本默认需要2G大小的内存空间,如果系统没有2G内存运行的时候就会报错:
max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
elasticsearch用户拥有的内存权限太小,至少需要262144;
解决方式:
- 运行:
sysctl -w vm.max_map_count=262144
- 查看结果:
sysctl -a|grep vm.max_map_count
,会显示vm.max_map_count = 262144
- 永久修改:在
/etc/sysctl.conf
文件最后添加一行vm.max_map_count=262144
即可永久修改
本地镜像发布到阿里云
- 镜像生成:可以使用之前的Dockerfile方式。也可以使用 commit 方式,如下
docker commit [OPTIONS] 容器ID [REPOSITORY[:TAG]]
示例:docker commit -a theliang -m "new mycentos 1.4 from 1.3 " 45e4aa594e06 mycentos:1.4
- 进入 阿里云开发平台,创建仓库镜像,绑定代码源(Github)
- 管理镜像仓库,里面包含了操作指南
- 设置登录授权密码(在操作指南中第一步时,提示用的密码就是在这里设置,注意不是用你的登录密码!)
- 登录:按照操作指南的第一步,再输入设置好的密码,即可登录成功
- 将镜像推送到Registry:[镜像版本号] 可以和 IMAGE ID 不一样
按照指南执行完成后:
在本地仓库中能看到 push 后的镜像
也可以在 公有云 上查找到:
在【控制台】-【镜像库】-【镜像搜索】也是可以的:
- 从Registry中拉取镜像:在镜像搜索中打开需要下载的镜像,选择一个镜像地址,在使用
docker pull
命令来拉取镜像