Docker概述
简介
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。
Docker是一个用于开发,发布和运行应用程序的开放平台。Docker使您能够将应用程序与基础架构分开,从而可以快速交付软件。借助Docker,您可以以与管理应用程序相同的方式来管理基础架构。通过利用Docker的方法来快速交付,测试和部署代码。
历史
Docker 公司起初是一家名为 dotCloud 的平台即服务(Platform-as-a-Service, PaaS)提供商。
底层技术上,dotCloud 平台利用了 Linux 容器技术。为了方便创建和管理这些容器,dotCloud 开发了一套内部工具,之后被命名为“Docker”。Docker就是这样诞生的!
2013年3月,dotCloud公司公布了其开源项目Docker。
2013年10月,dotCloud公司正式转换业务核心并将自身重新定名为Docker。
2014年6月,Docker 1.0版本正式发布。
2014年12月,Docker方面陆续发布了Swarm、Machine与Compose。
2015年6月,Docker公司发布了Docker Network。
2015年年末,Docker公司推出Docker Hub。一个基于云的存储库。
Docker容器和虚拟机
其结构对比图如下,Docker减少Guest OS这一层级,所以更轻量和更高性能。
![img](https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=416472420,4072848564&fm=26&gp=0.jpg)
特性 | 虚拟机 | 容器 |
---|---|---|
隔离级别 | 操作系统级 | 进程级 |
隔离策略 | Hypervisor | CGroups |
系统资源 | 5~15% | 0~5% |
启动时间 | 分钟级 | 秒级 |
镜像存储 | GB-TB | KB-MB |
系统支持量 | 几十 | 上千 |
Docker架构
Docker使用客户端-服务器架构。Docker客户端与Docker守护程序进行对话,该守护程序完成了构建,运行和分发Docker容器的繁重工作。Docker客户端和守护程序可以 在同一系统上运行,也可以将Docker客户端连接到远程Docker守护程序。Docker客户端和守护程序在UNIX套接字或网络接口上使用REST API进行通信。
Docker 包括三个基本概念:
- 镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统。
- 容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
- 仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像。
Docker安装
以Centos为例:
- 确保 yum 包更新到最新。
yum update
- 卸载旧版本(如果安装过旧版本的话)
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
- 安装需要的软件包,yum-util 提供yum-config-manager功能,另外两个是devicemapper驱动依赖的
yum install -y yum-utils device-mapper-persistent-data lvm2
- 设置yum源地址(使用阿里云地址)
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
- 查看仓库中docker版本,并选择特定版本安装
yum list docker-ce --showduplicates | sort -r
- 安装docker
# 命令:
yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io
# 根据上一步选择一个版本安装,此处选择 18.03.1.ce
yum install docker-ce-18.03.1 docker-ce-cli-18.03.1
# 也可直接安装最新版本
yum install docker-ce docker-ce-cli containerd.io
- 启动并加入开机启动
# 启动:
systemctl start docker
# 停止:
systemctl stop docker
# 重启:
systemctl restart docker
# 开机自启:
systemctl enable docker
# 查看版本:
docker version
# 查看信息:
docker info
# 查看状态:
systemctl status docker
设置镜像源
Docker镜像服务器在国外,国内访问比较慢,所以需要先设置国内镜像源,如下。
# 修改文件
vi /etc/docker/daemon.json
# 增加如下配置
{
"registry-mirrors": ["https://mltfzuzk.mirror.aliyuncs.com"]
}
# 重启daemon
systemctl daemon-reload
# 重启docker
systemctl restart docker.service
上面使用的是我的阿里云的镜像加速器地址。
获取地址:https://cr.console.aliyun.com/cn-shanghai/instances/mirrors
常用命令
# 帮助命令
docker --help
docker [commond] --help
# 查看容器
docker ps [-a/-f/-n/-l/-q/-s]
# # 过滤容器名查看容器
docker ps -f name= my
# 搜索镜像
docker search keyword
# 查看镜像
docker iamges
# 过滤镜像名查看镜像
docker images -f reference=myn*
# 启动容器
docker start [容器名/容器ID]
# 停止容器
docker stop/kill [容器名/容器ID]
# 停止所有容器
docker stop/kill $(docker ps -aq)
# 重启容器
docker restart [容器名/容器ID]
# 删除已停止的容器
docker rm [容器名/容器ID]
# 强制删除容器
docker rm -f [容器名/容器ID]
# 删除镜像
docker rmi 镜像id
# 查看容器日志
docker logs [容器名/容器ID]
# 查看容器运行状态信息
docker stats [容器名/容器ID]
# 获取容器/镜像的元数据
docker inspect [OPTIONS] NAME|ID [NAME|ID...]
# 查看容器中运行的进程信息,支持 ps 命令参数
docker top [OPTIONS] CONTAINER [ps OPTIONS]
# 将宿主机目录拷贝到容器目录
docker cp [path1] [容器ID]:[path2]
# 将容器目录拷贝到宿主机目录
docker cp [容器ID]:[path2] [path1]
拉取镜像
一般安装前需要先拉取镜像
# 命令:
docker pull [softName]:[version]
# softName -- 下载的软件名,如:mysql、redis等
# version -- 下载软件的版本
# 例:
docker pull mysql:5.7
启动容器
# 创建并运行容器命令:
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
# 常用OPTIONS说明:
-d: 后台运行容器,并返回容器ID;
-p: 指定端口映射,格式为:主机(宿主)端口:容器端口;
-i: 以交互模式运行容器,通常与 -t 同时使用;
-t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
-e: 设置环境变量,例:-e TZ="Asia/Shanghai" 设置时区;
--env-file=[]: 从指定文件读入环境变量;
-m : 设置容器使用内存最大值;
--cpus : 设置容器使用的cpu核数
--dns: 设置dns
--volume,-v: 绑定一个卷;
--name: 为容器指定一个名称;
--privileged=true 获取宿主机root权限
--restart=always 容器自动重启
例:
docker run -p 3306:3306 --restart=always -e TZ="Asia/Shanghai" --name mymysql \
-v /usr/local/gourd/docker/mysql/conf:/etc/mysql/conf.d \
-v /usr/local/gourd/docker/mysql/logs:/logs \
-e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
进入容器
可以使用docker attach
命令或 docker exec
命令,推荐使用 docker exec
命令。
docker exec -it [容器ID] bash
docker exec -it [容器ID] /bin/bash
# 退出容器,直接输入 exit回车即可
exit
监控工具-weavescope
WeaveScope是一款开源项目,项目地址:https://github.com/weaveworks/scope。Weave Scope会自动生成容器之间的关系图,方便理解容器之间的关系,也方便监控容器化和微服务化的应用。
安装:
# 下载
curl -L git.io/scope -o /usr/local/bin/scope
# 赋予可执行权限
chmod a+x /usr/local/bin/scope
# 启动scope,默认端口为 4040
scope launch
# 如果监控多台,空格分隔即可
scope launch [ip1] [ip2]
访问
启动成功后,访问 你的IP+port访问:http://ip:4040/
点击相应容器,可以查看具体详细信息,也可直接对容器镜像操作。
DockerFile
什么是 Dockerfile?
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
命令详解
- FROM
FROM image:tag
设置基础镜像, 可出现多次,以便于创建混合的images。
如果没有指定 tag ,latest 将会被指定为要使用的基础镜像版本。
- RUN
RUN指令在构建时将会生成一个新的镜像层并且执行RUN指令后面的内容。比如安装一些软件、配置一些基础环境
使用RUN指令时应该尽量遵循以下原则:
当RUN指令后面跟的内容比较复杂时,建议使用反斜杠(\) 结尾并且换行;
RUN指令后面的内容尽量按照字母顺序排序,提高可读性。
格式:
RUN [“executable”, “param1”, “param2”] (推荐)
RUN
- CMD 和 ENTRYPOINT
CMD和ENTRYPOINT指令都是容器运行的命令入口,这两个指令使用中有很多相似的地方,但是也有一些区别
区别:
Dockerfile 中如果使用了ENTRYPOINT指令,启动 Docker 容器时需要使用 --entrypoint 参数才能覆盖 Dockerfile 中的ENTRYPOINT指令 ,而使用CMD设置的命令则可以被docker run后面的参数直接覆盖。
ENTRYPOINT指令可以结合CMD指令使用,也可以单独使用,而CMD指令只能单独使用。存在多个 CMD 指令,仅最后一个生效
格式:
- CMD/ENTRYPOINT [“executable”,“param1”,“param2”] (推荐)
- CMD/ENTRYPOINT command param1 param2
- ADD 和 COPY
ADD和COPY指令功能类似,都是从外部往容器内添加文件。
但是COPY指令只支持基本的文件和文件夹拷贝功能,ADD则支持更多文件来源类型,比如自动提取 tar 包,并且可以支持源文件为 URL 格式。
- WORKDIR
指定容器的工作路径
格式:WORKDIR <工作目录路径>
- LABEL
LABEL = = = …
给构建的镜像打标签。
LABEL version=“1.0”
LABEL description=“This text illustrates”
- ENV
设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。
格式:ENV = =…
- EXPOSE
仅仅只是声明端口
作用:
帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。
在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口
示例:
# 基础镜像
FROM nginx
# 工作目录
WORKDIR /usr/share/nginx
# 声明端口
EXPOSE 80
# 复制指令,复制文件或者目录到容器里指定路径。
COPY gourdIndex*.txt /usr/share/nginx/
# 设置时区
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo '这是一个本地构建的nginx镜像' > /usr/share/nginx/html/index.html
构建镜像:
docker build -t imagename:tag .
底层技术
Docker用Go编程语言编写,并利用Linux内核的多个功能来交付其功能。
命名空间
Docker 是使用 Linux 的 Namespace 技术实现各种资源隔离的。运行容器时,Docker会为该容器创建一组 名称空间。
这些名称空间提供了一层隔离。容器的每个方面都在单独的名称空间中运行,并且对其的访问仅限于该名称空间。
Docker Engine在Linux上使用以下名称空间:
- **
pid
命名空间:**进程隔离(PID:进程ID)。 - **
net
命名空间:**管理网络接口(NET:网络)。 - **
ipc
命名空间:**管理访问IPC资源(IPC:进程间通信)。 - **
mnt
命名空间:**管理文件系统挂载点(MNT:挂载)。 - **
uts
命名空间:**隔离内核和版本标识符。(UTS:Unix时间共享系统)。
控制组
cgroups(全称:control groups)是 Linux 内核的一个功能,它可以实现限制进程或者进程组的资源(如 CPU、内存、磁盘 IO 等)。
cgroup将应用程序限制为一组特定的资源。控制组允许Docker Engine将可用的硬件资源共享给容器,并有选择地实施限制和约束。例如,您可以限制特定容器可用的内存。
联合文件系统
联合文件系统或UnionFS是通过创建图层进行操作的文件系统,使其非常轻便且快速。Docker Engine使用UnionFS为容器提供构建模块。Docker 目前支持的联合文件系统包括 OverlayFS
, AUFS
, Btrfs
, VFS
, ZFS
和 Device Mapper
。
overlay2
是目前 Docker 默认的存储驱动。你也可以通过配置来使用以上提到的其他类型的存储驱动。
如下是文件联合系统的结构图:
网络
当 Docker 启动时,会自动在主机上创建一个
docker0
虚拟网桥,实际上是 Linux 的一个 bridge,可以理解为一个软件交换机。它会在挂载到它的网口之间进行转发。
当创建一个 Docker 容器的时候,同时会创建了一对
veth pair
接口(当数据包发送到一个接口时,另外一个接口也可以收到相同的数据包)。这对接口一端在容器内,即eth0
;另一端在本地并被挂载到docker0
网桥(默认),名称以veth
开头(例如vethAQI2QT
)。通过这种方式,主机可以跟容器通信,容器之间也可以相互通信。Docker 就创建了在主机和所有容器之间一个虚拟共享网络。
![img](https://gblobscdn.gitbook.com/assets%2F-M5xTVjmK7ax94c8ZQcm%2F-M5xT_hHX2g5ldlyp9nm%2F-M5xTloJ8V-9G0aacJWQ%2Fnetwork.png?alt=media)
容器互联 --link
创建容器通过 --link [容器id/容器名] 来关联容器
docker run -itd --name tomcat04 --link tomcat03 tomcat
自定义网络
相关命令
命令 | 说明 |
---|---|
docker network create [network] | 创建一个网络 |
docker network inspect [network] | 显示一个或多个网络的详细信息 |
docker network ls | 列出网络 |
docker network rm [network] | 删除一个或多个网络 |
docker network connect [network] [container] | 将容器连接到网络 |
docker network disconnect [network] [container] | 断开容器的网络 |
网络模式:
bridge: 桥接(docker默认)
host: 和主机共享网络
none: 不配置网络
创建自定义网络
启动容器并设置自定义网络
docker run -itd --name tomcat01 --network mynet tomcat
将已启动的容器加入自定义网络
docker network connect mynet tomcat01