一、简介
1.1 、什么是Docker
Docker是基于Go语言实现的云开源项目。Docker的主要目标是“Build,Ship and Run Any App,Anywhere”,也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的APP(可以是一个WEB应用或数据库应用等等)及其运行环境能够做到“一次封装,到处运行”。只需要一次配置好环境,换到别的机子上就可以一键部署好,大大简化了操作。 在Docker 设计时,充分利用 了Union FS 的技术,将其设计为分层存储的架构,镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。
1.2、 docker的三个概念
-
镜像(image):Docker 镜像(Image)就是一个只读的模板,采用的时分层存储。镜像可以用来创建 Docker 容器,一个镜像可以创建很多容器。Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。分层存储的特征还使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。
-
容器(container):利用容器技术可以运行一个或者一组应用,容器是用镜像创建的运行实例。像(
Image
)和容器(Container
)的关系,就像是面向对象程序设计中的类
和实例
一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层为 容器存储层。 -
仓库(repository):存放镜像的地方类似github,仓库(Repository)和仓库注册服务器(Registry)是有区别的。仓库注册服务器上往往存放着多个仓库,每个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过
<仓库名>:<标签>
的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以latest
作为默认标签。最常使用的 Registry 公开服务是官方的 Docker Hub,国内也有一些云服务商提供类似于 Docker Hub 的公开服务。比如 网易云镜像服务、DaoCloud 镜像市场、阿里云镜像库 等。
1.3、为什么使用Docker
- 更高效的利用系统资源:由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,
Docker
对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。 - 更快速的启动时间:传统的虚拟机技术启动应用服务往往需要数分钟,而
Docker
容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。 - 一致的运行环境:
Docker
的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 「这段代码在我机器上没问题啊」 这类问题。 - 持续交付和部署:使用
Docker
可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过 Dockerfile 来进行镜像构建,并结合 持续集成(Continuous Integration) 系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合 持续部署(Continuous Delivery/Deployment) 系统进行自动部署。 - 更轻松的迁移:由于
Docker
确保了执行环境的一致性,使得应用的迁移更加容易。户可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。 - 更轻松的维护和扩展:
Docker
使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker
团队同各个开源项目团队一起维护了一大批高质量的 官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。
1.4、Docker对比传统虚拟机
特性 | 容器 | 虚拟机 |
---|---|---|
启动 | 秒级 | 分钟级 |
硬盘使用 | 一般为 MB |
一般为 GB |
性能 | 接近原生 | 弱于 |
系统支持量 | 单机支持上千个容器 | 一般几十个 |
二、安装Docker
1.查看系统版本
cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
2.卸载Docker
# 卸载依赖
$ sudo yum remove docker-ce docker-ce-cli containerd.io
# 删除资源 /var/lib/docke docker默认的工作路径
$ sudo rm -rf /var/lib/doker
$ sudo yum remove docker
docker-client
docker-client-latest
docker-common
docker-latest
docker-latest-logrotate
docker-logrotate
docker-selinux
docker-engine-selinux
docker-engine
3.安装docker
$ sudo yum install -y yum-utils #安装工具包
# 设置仓库这里设置阿里云的仓库
$ sudo yum-config-manager
--add-repo
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 安装最新版docker社区版 -ce -ee企业版
$ sudo yum install docker-ce docker-ce-cli containerd.io
# 也可以安装特定版的docker
# 查看docker版本,并选择安装
#$ yum list docker-ce --showduplicates | sort -r
#$ sudo yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io
#启动docker
$ sudo systemctl start docker
# 测试docker是否安装成功,但是缺少镜像docker会自动pull镜像并启动容器
$ sudo docker run hello-world
#还可以通过docker version 查看docker版本
4. 配置阿里云镜像加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["加速器地址"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
加速器地址可以在与控制台的容器与镜像服务->镜像中心->镜像加速器找到
二、Docker常用命令
2.1 帮助命令
docker version # docker版本信息
dicker info #显示docker的详细信息,包括系统信息,镜像信息
docker --help #查看docker帮助命令
docker command -- help # 产看docker所有命令的帮助
2.2 镜像命令
搜索镜像:
# 搜索mysql镜像,可以通过过-f过滤,建议在https://hub.docker.com/上查找
docker search mysql
NAME: #镜像仓库源的名称
DESCRIPTION: #镜像的描述
OFFICIAL: #是否 docker 官方发布
stars: #类似 Github 里面的 star,表示点赞、喜欢的意思。
AUTOMATED: #自动构建
#搜索starts>3000的镜像
docker search mysql -f=stars=3000
下载镜像:
#先下载一个镜像,不指明标签默认时最新版,下在镜像时是分层下载
docker pull [选项] 仓库名[:标签]
docker pull centos:7.5 #下载centos7.5版本
#下载mysql,并且制定版本为5.7(mysql:5.7),如果不指定就是最新版
[root@iZwz9c9w0i9d0wy4233h5xZ ~]# docker pull mysql:5.7
5.7: Pulling from library/mysql
bf5952930446: Pull complete # 分层下载
8254623a9871: Pull complete
938e3e06dac4: Pull complete
ea28ebf28884: Pull complete
f3cef38785c2: Pull complete
894f9792565a: Pull complete
1d8a57523420: Pull complete
5f09bf1d31c1: Pull complete
1b6ff254abe7: Pull complete
74310a0bf42d: Pull complete
d398726627fd: Pull complete
Digest: sha256:da58f943b94721d46e87d5de208dc07302a8b13e638cd1d24285d222376d6d84 #这是防伪签名
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7 # 真实地址
列出镜像:
docker images --help # 查看帮助人可一个命令都可以通过--help查看帮助
docker image ls [选项] #查看本地所有镜像
docker images [选项] #查看本地主机上的所有镜像
docker image ls ubuntu [选项] #根据仓库查询镜像
REPOSITORY: #表示镜像的仓库源
TAG: #镜像的标签
IMAGE ID: #镜像ID
CREATED: #镜像创建时间
SIZE: #镜像大小
#可以追加参数
-a :列出所有镜像
-q :只显示id
-f :过滤
docker system df # 查看镜像、容器、数据卷所占用的空间。
删除镜像:
# 删除镜像可以是[<仓库名>:<tag>] 或者镜像id删除,id可以不写完整,只要能区分就行
docker rmi [选项] [镜像] [镜像]
选项
-f # 强制删除
#批量删除$()里面的参数是全部的镜像id
docker rmi -f $(docker images -a -q)
导入导出镜像:
# 导出镜像
docker save -o <保存路径> <镜像名称:标签>
#导入镜像
docker load --input <文件>
给镜像增加新的标签:
# 给镜像增加一个新的标签
docker tag [镜像id] [Repository]:[tag]
2.3 容器命令
启动容器:
#新建容器并启动当运行容器时,使用的镜像如果在本地中不存在,docker 就会自动从 docker 镜像仓库中下载,启动容器
#不指定版本默认使用最新版
docker run [参数列表] image:tag /bin/bash
## 参数说明
--rm #关闭容器就删除容器
--name=容器名字 # 用来区分不同的容器
-d #后台方式运行,注意:容器使用后台运行必须要有一个前台进程,如果没有则这个后台启动的应用就会停止
-it # 这是两个参数,一个是 -i:交互式操作,一个是 -t 终端。我们这里打算进入 bash 执行一些命令并查看返回结果,因此我们需要交互式终端。
-P #是容器内部端口随机映射到主机的端口。
-p # 指定容器端口,-p 标记可以多次使用来绑定多个端口
-p ip:主机端口:容器端口/[tcp|udp]
-p 主机端口:容器端口/[tcp|udp]
# 常见格式:ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort
-e #指定环境
#/bin/bash:放在镜像名后的是命令,这里我们希望启动容器后有个交互式 Shell,因此用的是 /bin/bash
#启动已经终止的容器,而run会新建一个容器并启动
docker start [镜像]
# 重启容器
docker restart 容器Id #重启容器
当利用 docker run
来创建容器时,Docker 在后台运行的标准操作包括:
- 当利用 docker run 来创建容器时,Docker 在后台运行的标准操作包括:
- 检查本地是否存在指定的镜像,不存在就从公有仓库下载
- 利用镜像创建并启动一个容器
- 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层(原来的镜像的每一层都是不可变的)
- 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
- 从地址池配置一个 ip 地址给容器
- 执行用户指定的应用程序
- 执行完毕后容器被终止
进入正在运行的容器:
#进入正在运行的容器
docker attach 容器Id #进入容器正在执行的终端
docker exec -it 容器Id /bin/bash #进入容器后开启一个新的终端 推荐大家使用 docker exec 命令,因为此退出容器终端,不会导致容器的停止。
查看容器:
# 查看正在运行的容器
docker ps [选项]
-l # 产看最近运行的一个容器
-a # 查看所有的容器包括没有运行的
-n=? # 查看指定数量的容器
-q # 只查看容器id
docker container ls # 查看正在运行的容器
# 查看容器端口映射(需用用-p指定)
docker port <容器名称或者容器id>
#查看容器进程
docker top <容器名称或者 容器id>
# 查看容器元数据
docker inspect 容器Id
#查看容器日志
docker logs -f -t --tail 10 [容器id]
-f :更新显示
-t :显示时间戳
--tail :显示条数
终止容器:
#退出容器
exit # 停止容器并退出ctrl+d
Ctrl+P+Q #退出容器但不停止
docker stop 容器ID
docker kill 容器ID #杀死容器
删除容器:
#删除容器,也可以批量删除
docker rm 容器ID #不能删除正在运行的容器除非加上-f
docker ps -a -q|xargs docker rm #通过管道符删除所有容器
docker rm $(docker ps -qa) #删除所有容器
docker container prune #删除已经终止的容器
导入和导出容器:
#从容器内拷贝文件到主机
docker cp 容器ID:文件目录 主机目录
# 导出容器(需要停止)
docker export <容器id> > <保存路径>
#可以使用 docker import 从容器快照文件中再导入为镜像,例如
cat <文件> | docker import - <容器名称>:<标签>
# 方式2
docker import <url或者目录> <容器名称>
通过容器创建镜像:
#创建镜像
#当我们从 docker 镜像仓库中下载的镜像不能满足我们的需求时,我们可以通过以下两种方式对镜像进行更改。
1、从已经创建的容器中更新镜像,并且提交这个镜像
更新镜像之前,我们需要使用镜像来创建一个容器
apt-get update 命令进行更新。
exit 命令来退出这个容器。
docker commit -m="描述" -a="作者" [容器id] [Repository]:[tag]
-m: #提交的描述信息
-a: #指定镜像作者
三、Docker仓库
仓库(Repository
)是集中存放镜像的地方。
一个容易混淆的概念是注册服务器(Registry
)。实际上注册服务器是管理仓库的具体服务器,每个服务器上可以有多个仓库,而每个仓库下面有多个镜像。从这方面来说,仓库可以被认为是一个具体的项目或目录。例如对于仓库地址 docker.io/ubuntu
来说,docker.io
是注册服务器地址,ubuntu
是仓库名。
-
在https://hub.docker.com 注册一个账户
-
在宿主机通过
docker login
登录,docker logout
是退出登录 -
镜像的分类
- 一种是类似
centos
这样的官方提供镜像,被称为基础镜像或根镜像。这些基础镜像由 Docker 公司创建、验证、支持、提供。这样的镜像往往使用单个单词作为名字。 - 还有一种类型,比如
tianon/centos
镜像,它是由 Docker Hub 的注册用户创建并维护的,往往带有用户名称前缀。可以通过前缀username/
来指定使用某个用户提供的镜像,比如 tianon 用户。
- 一种是类似
-
push镜像到自己的仓库
docker login #回车然后输入账户密码 # 修改镜像的标签记得加上用户前缀标签 docker tag 0d120b6ccaa8 1769959702/mycentos:1.0 docker push 1769959702/mycentos:1.0
如果不加username/前缀推送会被拒绝,如下:
-
自动构建https://vuepress.mirror.docker-practice.com/repository/dockerhub/#自动构建
四、容器数据卷
4.1、什么是卷
Docker默认的数据是存储在容器内部不能共享的,当容器被删除之后,数据也就没了,为了能够保存数据,在docker容器中使用卷,将容器内的目录挂载到宿主机上。数据卷
是一个可供一个或多个容器使用的特殊目录,但是不属于联合文件系统,因此能够绕过Union File System提供一些用于持久化数据或共享数据的特点。
4.2、卷的特点
- 数据卷可以在容器之间共享和重用。
- 对数据卷的修改会立马生效。
- 容器删除不会删除数据卷。
注意:
数据卷
的使用,类似于 Linux 下对目录或文件进行 mount,镜像中的被指定为挂载点的目录中的文件会复制到数据卷中(仅数据卷为空时会复制)。
4.3、使用数据卷
查看帮助:
docker volume --help # 查看帮助
create Create a volume
inspect Display detailed information on one or more volumes
ls List volumes
prune Remove all unused local volumes
rm Remove one or more volumes
创建数据卷:
docker volume create my-volume1
查看数据卷:
[root@iZwz9a8vgb7qexsr6cc65pZ ceshi]# docker volume ls
DRIVER VOLUME NAME
local my-volume1
查看数据卷信息:
[root@iZwz9a8vgb7qexsr6cc65pZ ceshi]# docker volume inspect my-volume1
[
{
"CreatedAt": "2020-10-15T14:13:46+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/my-volume1/_data",
"Name": "my-volume1",
"Options": {},
"Scope": "local"
}
]
挂载数据卷:
方式一:通过--mount挂载
# 在用 docker run 命令的时候,使用 --mount 标记来将 数据卷 挂载到容器里。在一次 docker run 中可以挂载多个 数据卷。此时数据卷的内容就和容器内被挂载目录的内容同步
# 创建一个volume(数据卷)
docker volume create my-volume1
#将target目录与volume关联,volumn如果不存在,则会自动创建
docker run -dit --mount source=[volume],target=[容器内目录]
#例如:
# my-volume1使我们创建的volume,
docker run -dit --name=centos3 --mount source=my-volume1,target=/home/ centos /bin/bash
容器启动并挂载数据卷后可以通过docker inspect [容器id]查看容器的源信息,多了一个Mounts
数据卷
是被设计用来持久化数据的,它的生命周期独立于容器,Docker 不会在容器被删除后自动删除。
数据卷
,并且也不存在垃圾回收这样的机制来处理没有任何容器引用的数据卷
。如果需要在删除容器的同时移除数据卷。可以在删除容器的时候使用docker rm -v
这个命令。无主的数据卷可能会占据很多空间,要清理请使用以下命令
docker volume prune
方式二:通过 -v 参数挂载
# 具名挂载和匿名挂载(不指定主机目录)
docker run -dit -v[宿主机路径:容器内路径]
-v 容器内路径 #匿名挂载
-v 卷名(volume):容器内路径 # 同方式一
-v 宿主机路基路径:容器内路径
# 还可以在容器路径后面跟 :ro,rw指定权限
可以通过docker run -dit --name centos4 --volumes-from [容器] [镜像]的方式使多个容器之间共享数据
# centos就是centos共享数据 docker run -dit --name centos4 --volumes-from centos3 centos
注意:数据卷的默认目录是/var/lib/docker/volumes/volume_name/_data,如果挂载到主机目录的方式就是自己指定
五、Docker网络
5.1、Docker的网络功能介绍
Docker 允许通过外部访问容器或容器互联的方式来提供网络服务。
5.2、外部访问容器
容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P
或 -p
参数来指定端口映射。当使用 -P
标记时,Docker 会随机映射一个端口到内部容器开放的网络端口。
容器有自己的内部网络和 ip 地址(使用
docker inspect
查看,Docker 还可以有一个可变的网络配置。
# 启动一个nginx
docker run -d --name nginx -p 5767:8081 nginx:late
# 查看容器信息
docker inspect nginx
[
{
"Id": "edcfc134e07c186b3ab0c8cdc8864f027d157594b331f8bdf289ad9efeb7e853",
"Created": "2020-10-15T07:46:01.391640644Z",
"Path": "/docker-entrypoint.sh",
"Args": [
"nginx",
"-g",
"daemon off;"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 27691,
"ExitCode": 0,
"Error": "",
"StartedAt": "2020-10-15T07:46:01.696140695Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:f35646e83998b844c3f067e5a2cff84cdf0967627031aeda3042d78996b68d35",
"ResolvConfPath": "/var/lib/docker/containers/edcfc134e07c186b3ab0c8cdc8864f027d157594b331f8bdf289ad9efeb7e853/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/edcfc134e07c186b3ab0c8cdc8864f027d157594b331f8bdf289ad9efeb7e853/hostname",
"HostsPath": "/var/lib/docker/containers/edcfc134e07c186b3ab0c8cdc8864f027d157594b331f8bdf289ad9efeb7e853/hosts",
"LogPath": "/var/lib/docker/containers/edcfc134e07c186b3ab0c8cdc8864f027d157594b331f8bdf289ad9efeb7e853/edcfc134e07c186b3ab0c8cdc8864f027d157594b331f8bdf289ad9efeb7e853-json.log",
"Name": "/nginx",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {
"8081/tcp": [
{
"HostIp": "",
"HostPort": "5767"
}
]
},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"Capabilities": null,
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"KernelMemory": 0,
"KernelMemoryTCP": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": null,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/7aa2bd5a31d9282766a160a013722ca06a83e76042f5f09423ebf7919ccfd102-init/diff:/var/lib/docker/overlay2/3d2d4b61980a217c587890fc042d14a76a3e5bd544308d6e3e50e32cc3e61fec/diff:/var/lib/docker/overlay2/91d46d606db7a93ff595e019770f9cba8d36be594ffa2bd202aa6023abd5381b/diff:/var/lib/docker/overlay2/b0a13670752494a6ec0501e64536499a3a727e42407936c4e7f8b4f2d7a35353/diff:/var/lib/docker/overlay2/777d902b90e3a97af59b6e45bcae64dc2b5ad92c3c1661a4ecefc69488988cc9/diff:/var/lib/docker/overlay2/82aa931fd060ec9cae7db273ed24c79e092b42bcbd5144d7793d605acdd6d59e/diff",
"MergedDir": "/var/lib/docker/overlay2/7aa2bd5a31d9282766a160a013722ca06a83e76042f5f09423ebf7919ccfd102/merged",
"UpperDir": "/var/lib/docker/overlay2/7aa2bd5a31d9282766a160a013722ca06a83e76042f5f09423ebf7919ccfd102/diff",
"WorkDir": "/var/lib/docker/overlay2/7aa2bd5a31d9282766a160a013722ca06a83e76042f5f09423ebf7919ccfd102/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "edcfc134e07c",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"80/tcp": {},
"8081/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"NGINX_VERSION=1.19.3",
"NJS_VERSION=0.4.4",
"PKG_RELEASE=1~buster"
],
"Cmd": [
"nginx",
"-g",
"daemon off;"
],
"Image": "nginx:latest",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": {
"maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
},
"StopSignal": "SIGTERM"
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "9d4b862b2f19c7733a5e9c41e611d3d2e5206e1da5198c4e9013e62d83d6cbdd",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"80/tcp": null,
"8081/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "5767"
}
]
},
"SandboxKey": "/var/run/docker/netns/9d4b862b2f19",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "9ac19e2103b80905cbdbea3295cd2bb3fdddb1aa5eb808e45fb5f881646daeba",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:02",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "8141a15ce6f7b2644431fe46025ae59b6e0f7f4f978a7411bb29a52476445931",
"EndpointID": "9ac19e2103b80905cbdbea3295cd2bb3fdddb1aa5eb808e45fb5f881646daeba",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2", # 容器的IP地址
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02",
"DriverOpts": null
}
}
}
}
]
5.3、容器互联
#docker 有一个连接系统允许将多个容器连接在一起,共享连接信息。
#新建Docker网络,bridge使用桥接模式
docker network create -d bridge my-net
-d:参数指定 Docker 网络类型,有 bridge、overlay。
# 启动一个centos容器加入到 my-net
docker run -dit --rm --name centos1 --network my-net centos /bin/bash
#在启动一个centos容器加入到my-net
docker run -dit --rm --name centos2 --network my-net centos /bin/bash
# 进入到容器centos2不仅可以通过ipping通centos1还可以直接通过容器名称ping通centos1
[root@iZwz9a8vgb7qexsr6cc65pZ ~]# docker exec -it centos2 /bin/bash
[root@bcaced3d42d3 /]# ping 172.19.0.2
PING 172.19.0.2 (172.19.0.2) 56(84) bytes of data.
64 bytes from 172.19.0.2: icmp_seq=1 ttl=64 time=0.096 ms
64 bytes from 172.19.0.2: icmp_seq=2 ttl=64 time=0.067 ms
64 bytes from 172.19.0.2: icmp_seq=3 ttl=64 time=0.076 ms
# 也可以使用 --link的方式连接两个容器
docker run -dit --name centos1 --link centos2 centos
5.4、配置DNS
方式一:
如何自定义配置容器的主机名和 DNS 呢?秘诀就是 Docker 利用虚拟文件来挂载容器的 3 个相关配置文件。这种机制可以让宿主主机 DNS 信息发生更新后,所有 Docker 容器的 DNS 配置通过
/etc/resolv.conf
文件立刻得到更新。
方式二:配置全部容器的 DNS ,也可以在 /etc/docker/daemon.json
文件中增加以下内容来设置。如果之前已经有其它配置要用逗号","隔开。
{
"dns" : ["114.114.114.114","8.8.8.8"]
}
方式二: 在启动时手动指定dns
docker run -it --rm --dns 114.114.114.114 centos cat /etc/resolv.conf
六、Dockerfile
镜像的定制实际上就是定制每一层所添加的配置、文件。Dockerfile 其实就是一个文本文件,其内包含了一条条的 指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建镜像。如何通过Dockerfile,细节看这里https://vuepress.mirror.docker-practice.com/image/dockerfile/