Docker学习笔记

一、简介

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

加速器地址可以在与控制台的容器与镜像服务->镜像中心->镜像加速器找到

image-20201014214547822

image-20201015193514397

二、Docker常用命令

image-20201014125954492

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

image-20201014215809201

下载镜像:

#先下载一个镜像,不指明标签默认时最新版,下在镜像时是分层下载
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 :过滤

image-20201014215313544

 docker system df # 查看镜像、容器、数据卷所占用的空间。

image-20201014220856154

删除镜像:

# 删除镜像可以是[<仓库名>:<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:   #指定镜像作者

image-20201014144304857

三、Docker仓库

仓库(Repository)是集中存放镜像的地方。

一个容易混淆的概念是注册服务器(Registry)。实际上注册服务器是管理仓库的具体服务器,每个服务器上可以有多个仓库,而每个仓库下面有多个镜像。从这方面来说,仓库可以被认为是一个具体的项目或目录。例如对于仓库地址 docker.io/ubuntu 来说,docker.io 是注册服务器地址,ubuntu 是仓库名。

  1. https://hub.docker.com 注册一个账户

  2. 在宿主机通过docker login 登录,docker logout 是退出登录

    image-20201015125622063

  3. 镜像的分类

    • 一种是类似 centos 这样的官方提供镜像,被称为基础镜像或根镜像。这些基础镜像由 Docker 公司创建、验证、支持、提供。这样的镜像往往使用单个单词作为名字。
    • 还有一种类型,比如 tianon/centos 镜像,它是由 Docker Hub 的注册用户创建并维护的,往往带有用户名称前缀。可以通过前缀 username/ 来指定使用某个用户提供的镜像,比如 tianon 用户。
  4. push镜像到自己的仓库

    docker login #回车然后输入账户密码
    # 修改镜像的标签记得加上用户前缀标签
    docker tag 0d120b6ccaa8  1769959702/mycentos:1.0
    docker push 1769959702/mycentos:1.0
    

    如果不加username/前缀推送会被拒绝,如下:

    image-20201015125743624

  5. 自动构建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

image-20201015143202798

数据卷 是被设计用来持久化数据的,它的生命周期独立于容器,Docker 不会在容器被删除后自动删除。

数据卷,并且也不存在垃圾回收这样的机制来处理没有任何容器引用的 数据卷。如果需要在删除容器的同时移除数据卷。可以在删除容器的时候使用 docker rm -v 这个命令。

无主的数据卷可能会占据很多空间,要清理请使用以下命令

docker volume prune

方式二:通过 -v 参数挂载

# 具名挂载和匿名挂载(不指定主机目录)
docker run -dit -v[宿主机路径:容器内路径]
-v 容器内路径 #匿名挂载
-v 卷名(volume):容器内路径 # 同方式一
-v 宿主机路基路径:容器内路径
# 还可以在容器路径后面跟 :ro,rw指定权限

image-20201015144338069

可以通过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

image-20201015182505610

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

image-20201015185052286

六、Dockerfile

镜像的定制实际上就是定制每一层所添加的配置、文件。Dockerfile 其实就是一个文本文件,其内包含了一条条的 指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建镜像。如何通过Dockerfile,细节看这里https://vuepress.mirror.docker-practice.com/image/dockerfile/

原文地址:https://www.cnblogs.com/myblogstart/p/13822751.html