docker
概述
整体结构
Docker Engine
- 命令行接口利用Docker命令通过REST AP直接控制Docker Daemon执行操作
- Docker Daemon负责创建并管理Docker各种对象
知识点
安装
-
centos7
-
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
-
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
-
sudo yum makecache fast
-
sudo yum -y install docker-ce
-
sudo systemctl start docker
-
ubuntu
-
阿里云帮助文档(地址已经打不开了)
-
配置加速器
- 配置Docker加速器,将会提升在国内获取Docker官方镜像的速度,否则后面下载镜像的过程会很慢,甚至有可能无法下载镜像
- 可以在阿里云申请加速器地址
- 然后 修改daemon配置文件/etc/docker/daemon.json
{ "registry-mirrors": [ "http://hub-mirror.c.163.com", "https://mirrors.tuna.tsinghua.edu.cn", "http://mirrors.sohu.com", "https://ustc-edu-cn.mirror.aliyuncs.com", "https://ccr.ccs.tencentyun.com", "https://docker.m.daocloud.io", "https://docker.awsl9527.cn" ] }
- 阿里云帮助文档(仅供参考,地址已经打不开了)
client
镜像
- docker images 或者 docker image ls
- 作用 列出本地镜像
- 命令格式:
docker images [OPTIONS][REPOSITORY[:TAG]]或者
docker image Is [OPTIONS][REPOSITORY[:TAG]]
命令参数(OPTIONS):
-a, --all 展示所有镜像(默认隐藏底层的镜像)
--no-trunc 不缩略显示
-q, --quiet 只显示镜像ID
-
docker image rm 或者 docker rmi 删除一个或多个镜像
-
docker save 保存
- 把本地一个或多个镜像打包成tar文件
- 默认是输出到stdout,可以通过重定向>到文件,或者使用 -o指定输出文件
-
docker load 导入还原
- 默认使用stdin作为输入,可以使用-i 指定输入文件
-
docker tag 重命名
-
docker image inspect 或者 docker inspect 查看详细信息
-
docker history 查看历史信息
-
docker pull 下载镜像
-
docker run
-
docker search
- 作用 搜索Docker Hub(镜像仓库)上的镜像
- 命令格式:
docker search [OPTIONS] TERM。命令参数(OPTIONS):
-f,--filter filter 根据提供的格式筛选结果
--forimat string 利用Go语言的format格式化输出结果展示最大的
--limit int 结果数,默认25个
--no-trunc 内容全部显示
容器
- docker create 创建容器
- 利用镜像创建出一个Created 状态的待启动容器。
- 命令格式:
docker create [OPTIONS] IMAGE [COMMAND] [ARG...]
命令参数(OPTIONS):
-t,--tty 分配一个伪TTY,也就是分配虚拟终端
-i, --interactive 即使没有连接,也要保持STDIN打开
--name 为容器起名,如果没有指定将会随机产生一个名称
命令参数(COMMAND\ARG):
COMMAND 表示容器启动后,需要在容器中执行的命令,如ps、Is等命令
ARG 表示执行COMMAND时需要提供的一些参数,如ps命令的aux、Is命令的-a等等
-
docker start 启动一个容器
-
docker run 创建并运营容器
- docker run 相当于 docker create + docker start -a 是前台模式
- docker run -d 相当于 docker create + docker start 是后台模式
- docker run --rm 容器停止都自动删除容器
-
停止容器
-
docker stop
- 会先发送通知,等待 -t 指定的时间后,再发送kill命令,容器内的进程可以在接收到通知后做一些特定的动作
- 会先发送通知,等待 -t 指定的时间后,再发送kill命令,容器内的进程可以在接收到通知后做一些特定的动作
-
docker kill
- 直接发送kill命令,容器内的进程不会收到任何通知
- 直接发送kill命令,容器内的进程不会收到任何通知
-
-
docker ps 查看当前存在的容器
- 不加参数。只会列出运行中的容器
- -a 列出所有容器
-
docker pause暂停 与 docker unpause恢复
-
docker restart 重启容器
-
docker container inspect 或者 docker inspect 查看一个或多个容器的详细信息
-
docker logs 查看容器的日志 容器日志中记录的是容器主进程的输出STDOUT和STDERR
-
docker rename 修改容器的name
-
docker attach 将当前终端的STDIN、STDOUT、STDERR绑定到正在运行的容器的主进程上实现连接
命令格式:
docker attach [OPTIONS] CONTAINER
命令参数(OPTIONS)
--no-stdin 不绑定STDIN
- docker exec 在容器中运行一个命令,不影响主进程
命令格式:
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]命令参数(OPTIONS)
-d,--detach 后台运行命令
-i, --interactive 即使没连接容器,也将当前的STDIN绑定上
-t,--tty 分配一个虚拟终端
-w, --workdir string 指定在容器中的工作目录
-e,--env list 设置容器中运行时的环境变量
- docker rm 删除一个或多个容器
容器与镜像
- docker commit 容器提交,生成新的镜像
命令格式:
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
命令参数(OPTIONS):
-a, --author string 作者
-c,--change list 为创建的镜像加入Dockerfile命令
-m, --message string 提交信息,类似git commit-m
-p, --pause 提交时暂停容器(default true)
-
镜像文件的分层结构
-
在容器中执行的操作,如果没有改变文件系统,执行docker commit 后生成的新镜像文件里面并不会增加层
-
如果在容器中执行了改变文件系统的操作,就算是0byte,使用docker commit生成的新镜像会增加新的层
-
docker export 将容器当前的文件系统导出成一个tar文件
命令格式:
docker export [OPTIONS] CONTAINER
命令参数(OPTIONS):
-o, --output string 指定写入的文件,默认是STDOUT
-
docker import 导入容器tar文件,生成镜像
- 通过docker commit 生成的镜像会保留历史记录
- 通过docker import 生成的是一个全新的镜像
网络
- docker network ls
- 查看已经建立的网络对象
命令格式:
docker network Is [OPTIONS]
命令参数(OPTIONS):
-f, --filter filter 过滤条件(如'driver=bridge' )
--format string 格式化打印结果
--no-trunc 不缩略显示
-q, --quiet 只显示网络对象的ID
- docker network create
- 创建新的网络对象
命令格式:
docker network create [OPTIONS] NETWORK·命令参数(OPTIONS):
-d, --driver string 指定网络的驱动(默认“bridge")
--subnet strings 指定子网网段(如192.168.0.0/16、172.88.0.0/24)
--ip-range strings 执行容器的IP范围,格式同subnet参数
--gateway strings 子网的IPv4 or IPv6网关,如(192.168.0.1)
-
docker network rm 删除一个或多个网络
-
docker network inspect 或者 docker inspect
- 查看一个或多个网络的详细信息
-
docker run/create --network network_name
- 创建或者启动容器时指定容器使用的网络
- 如果不指定网络,则默认使用名称是bridge的网络
-
docker connect / disconnect
- 将容器与指定网络进行连接或者断开连接
命令格式
docker network connect [OPTIONS] NETWORK CONTAINER
docker network disconnect [OPTIONS] NETWORK CONTAINER
命令参数(OPTIONS):
-f, --force 强制断开连接(用于disconnect)
- 端口映射
命令格式
docker run/create -P...或者
docker run/create -p...
命令参数(OPTIONS):
-P, --publish-all 将容器内部所有暴露端口进行随机映射
-p, --publish list 手动指定端口映射
注意:
-p [HOST_IP]:[HOST_PORT]:CONTAINER_PORT
如:
-p:80
将容器的80端口随机(端口)映射到宿主机任意IP
-p:8000:6379
将容器的6379端口映射到宿主机任意IP的8000端口
-p 192.168.5.1::3306 将容器的3306端口随机(端口)映射到宿主机的192.168.5.1IP上
数据卷
- docker volume create 创建数据卷对象
- docker volume inspect 查看数据卷详细信息
- docker volume Is 查看已创建的数据卷对象
- docker volume prune 删除未被使用的数据卷对象
- docker volume rm 删除一个或多个数据卷对象
Dockerfile
-
docker build
-
构建时指定Dockerfile所在目录
-
如果没有指定镜像名称和版本,则都是none
-
再次构建时,通过-t 指定名称和版本,可对已有的镜像重命名
-
或者在初次构建时就指定名称和版本
-
-
默认是用指定目录下的Dockerfile文件就行构建,如果文件名不是Dockerfile,需要使用-f指定文件具体名称
-
Dockerfile每一条命令都会生成一个对应的镜像
-
多次构建一个Dockerfile,只会从变动的命令开始构建,基于前面没有变动的命令的最后一条命令所对应的镜像
docker-compose
-
先创建Dockerfile
-
使用Dockerfile创建镜像
-
创建compose文件,compose命令默认查找的文件名是docker-compose.yaml,写入服务等配置项。注意:缩进要一致,冒号:和-等符号后面要有空格
-
编辑完之后可以使用docker-compose config验证文件是否有问题
-
使用docker-compose up 启动部署,如果Dockerfile没有预先生成镜像,docker-compose命令会主动使用Dockerfile进行构建
-
指定端口映射
-
指定容器名称和网络
-
默认的数据卷
-
docker-compose down 会删除容器,镜像,网络,默认不会删除数据卷,但是,如果没有自定义数据卷,再次通过docker-compose up启动服务后,会新建数据卷,原来的数据将会丢失。所以,慎用docker-compose down,一定是完全不用的服务才用。如果只是中途停止,可以使用pause, stop之类的命令。
-
指定数据卷
-
docker-compose log 查看日志
server
镜像image
- 镜像是一个Docker的可执行文件,其中包括运行应用程序所需的所有代码内容、依赖库、环境变量和配置文件等。
- 通过镜像可以创建一个或多个容器
- 镜像就是一个只读的联合文件系统
容器container
- 容器是一种轻量级、可移植、并将应用程序进行的打包的技术,使应用程序可以在几乎任何地方以相向的方式运行。
- Docker将镜像文件运行起来后,产生的对象就是容器。容器相当于是镜像运行起来的一个实例。
- 容器具备一定的生命周期。
- 可以借助docker ps命令查看运行的容器,如同在linux上利用ps命令查看运行着的进程那样。
与虚拟机对比
-
相同点
- 容器和虚拟机一样,都会对物理硬件资源进行共享使用。
- 容器和虚拟机的生命周期比较相似(创建、运行、暂停、关闭等等)。
- 容器中或虚拟机中都可以安装各种应用,如redis、mysql、nginx等。也就是说,在容器中的操作,如同在一个虚拟机(操作系统)中操作一样。
- 同虚拟机一样,容器创建后,会存储在宿主机上:linux上位于/var/lib/docker/containers下。
-
不同点
- 容器与虚拟机有很多相似的地方,但是容器并不是虚拟机。
- 虚拟机的创建、启动和关闭都是基于一个完整的操作系统。一个虚拟机就是一个完整的操作系统。而容器直接运行在宿主机的内核上,其本质上以一系列进程的结合。
- 容器是轻量级的,虚拟机是重量级的。首先容器不需要额外的资源来管理(不需要Hypervisor、Guest OS),虚拟机需要额外更多的性能消耗;其次创建、启动或关闭容器,如同创建、启动或者关闭进程那么轻松,而创建、启动、关闭一个操作系统就没那么方便了。
-
也因此,意味着在给定的硬件上能运行更多数量的容器,甚至可以直接把Docker运行在虚拟机上。
-
容器就是使用镜像文件创建的一个可读可写的联合文件系统
-
容器的运行,创建一个独立的进程空间,里面运行各种进程
-
容器与镜像文件关系
网络network
- 容器的网络默认与宿主机、与其他容器都是相互隔离。
- 默认情况下,docker安装完成后,会自动创建bridge、host、none三种网络驱动
- host和none模式网络只能存在一个
- docker自带的overlay 网络创建依赖于docker swarm(集群负载均衡)服务
- 192.168.0.0/16等于192.168.0.0~192.168.255.255
- 172.88.0.0/24等于 172.88.0.0~172.88.0.255
bridge network 模式(网桥)
- 默认的网络模式,类似虚拟机的nat模式
- 特点:
- 宿主机上需要单独的bridge网卡,如默认docker默认创建的docker0。
- 容器之间、容器与主机之间的网络通信,是借助为每一个容器生成的一对veth pair虚拟网络设备对,进行通信的。一个在容器上,另一个在宿主机上。
- 每创建一个基于bridge网络的容器,都会自动在宿主机上创建一个veth**虚拟网络设备。
- 外部无法直接访问容器。需要建立端口映射才能访问。
- 容器借由veth虚拟设备通过如docker0这种bridge网络设备进行通信。
- 每一容器具有单独的IP
host network 模式(主机)
-
容器与宿主机之间的网络无隔离,即容器直接使用宿主机网络
-
特点:
- 容器完全共享宿主机的网络。网络没有隔离。
宿主机的网络就是容器的网络。 - 容器、主机上的应用所使用的端口不能重复。例如:如果宿主机已经占用了8090端口,那么任何一个host模式的容器都不可以使用8090端口了;反之同理。
- 外部可以直接访问容器,不需要端口映射。
- 容器的IP就是宿主机的IP
- 容器完全共享宿主机的网络。网络没有隔离。
-
特殊host 模式:container网络模式
- container网络模式,其实就是容器共享其他容器的网络。相当于该容器,在网络层面上,将其他容器作为“主机”。它们之间的网络没有隔离。
- 这些容器之间的特性同host模式。
- 使用方法:Docker run/create --network container:CONTAINER...
None network 模式
- 容器禁用所有网络。
- 特点:
- 容器上没有网络,也无任何网络设备。
- 如果需要使用网络,需要用户自行安装与配置。
- 该模式适合需要高度定制网络的用户使用。
Overlay network 模式(覆盖网络)
- 利用VXLAN实现的bridge模式
- Overlay 网络,也称为覆盖网络。
- Overlay 网络的实现方式和方案有多种。Docker自身集成了一种,基于VXLAN隧道技术实现。
- Overlay 网络主要用于实现跨主机容器之间的通信。
- 应用场景:需要管理成百上千个跨主机的容器集群的网络时。
- IP隧道网络原理
-
标准tcp/ip
-
多加一个ip包首部
-
Macvlan network 模式
- 容器具备Mac地址,使其显示为网络上的物理设备
- macvlan网络模式,最主要的特征就是他们的通信会直接基于mac地址进行转发。
- 这时宿主机其实充当一个二层交换机。Docker会维护着一个MAC地址表,当宿主机网络收到一个数据包后,直接根据mac地址找到对应的容器,再把数据交给对应的容器。
- 容器之间可以直接通过IP互通,通过宿主机上内建的虚拟网络设备(创建macvlan网络时自动创建),但与主机无法直接利用IP互通。
- 应用场景:由于每个外来的数据包的目的mac地址就是容器的mac地址,这时每个容器对于外面网络来说就相当于一个真实的物理网络设备。因此当需要让容器来的网络看起来是一个真实的物理机时,使用macvlan模式
数据卷volume
-
数据卷存在于宿主机的文件系统中,独立于容器,和容器的生命周期是分离的。
-
数据卷可以目录也可以是文件,容器可以利用数据卷与宿主机进行数据共享,实现了容器间的数据共享和交换。
-
容器启动初始化时,如果容器使用的镜像包含了数据,这些数据会拷贝到数据卷中。
-
容器对数据卷的修改是实时进行的。
-
数据卷的变化不会影响镜像的更新。数据卷是独立于联合文件系统,镜像是基于联合文件系统。镜像与数据卷之间不会有相互影响。
-
数据卷挂载的方式
- bind mounts:将宿主机上的一个文件或目录被挂载到容器上。
利用docker run/create的参数为容器挂载数据卷
用法:
方式一:-v,--volume参数
-v 宿主机文件或文件夹路径:容器中的文件或者文件夹路径
方式二:--mount参数
--mount type=bind, src=宿主机文件或文件夹路径,dst=容器中的文件或者文件夹路
注意:src指定的文件和路径必须提前创建或存在
- volumes:由Docker创建和管理。使用docker volume命令管理
利用docker run/create的参数为容器挂载数据卷
用法:
方式一:-v,--volume参数
-v VOLUME-NAME:容器中的文件或者文件夹路径
方式二:--mount 参数
--mount type=volume, src=VOLUME-NAME,dst=容器中的文件或者文件夹路径
-
如果没有指定数据卷名称,会随机生成一个名称
-
tmpfs mounts:tmpfs是一种基于内存的临时文件系统。tmpfs mounts 数据不会存储在磁盘上。
利用docker run/create为容器挂载数据卷
用法:
--mount type=tmpfs, dst=PATH
- 共享其他容器的数据卷-数据卷容器
利用docker run/create的--volumes-from参数指定数据卷容器
用法:
docker run/create --volumes-from CONTAINER
-
Docker的数据卷更多会是使用volumes方式来进行使用。使用时需注意:
-
如果挂载一个空的数据卷到容器中的一个非空目录中,那么这个目录下的文件会被复制到数据卷中。
-
如果挂载一个非空的数据卷到容器中的一个目录中,那么容器中的目录中会显示数据卷中的数据。如果原来容器中的自录中有数据,那么这些原始数据会被隐藏掉。
-
-
这两个规则都非常重要,灵活利用第一个规则可以帮助我们初始化数据卷中的内容。掌握第二个规则可以保证挂载数据卷后的数据总是你期望的结果。
Dockerfile
- 查看官方的Dockerfile:https://github.com/docker-library/docs
- Dockerfile其实就是根据特定的语法格式撰写出来的一个普通的文本文件
- 利用docker build命令依次执行在Dockerfile中定义的一系列命令,最终生成一个新的镜像(定制镜像)
- 每条命令都是用前一个命令生成的镜像创建的容器来执行,执行完之后docker commit提交容器生成命令对应的镜像,然后删掉临时容器。重复这个步骤,直到Dockerfile文件里面的命令全部执行完。
- Dockerfile中的命令
- 官方文档 https://docs.docker.com/reference/dockerfile/#from
- RUN, CMD, ENTRYPOINT有两种格式执行命令
https://docs.docker.com/reference/dockerfile/#shell-and-exec-form- shell 在子进程使用shell执行
- exec 在主进程执行,而不是使用shell执行,参数是已标准json数组传入
- FROM:指定基础镜像
- RUN:构建镜像过程需要执行的命令。可以有多条。
- CMD:添加启动容器时需要执行的命令。多条只有最后一条生效。可以在启动容器时被覆盖修改。
- ENTRYPOINT:同CMD,但这个一定会被执行,不会被覆盖修改。
- LABEL:为镜像添加对应的数据。
- MAINTAINER:表明镜像的作者。将被遗弃,被LABEL代替。
- EXPOSE:设置对外暴露的端口。
- ENV:设置执行命令时的环境变量,并且在构建完成后,仍然生效
- ARG:设置只在构建过程中使用的环境变量,构建完成后,将消失。
- ADD:将本地文件或目录拷贝到镜像的文件系统中。能解压特定格式文件,能将URL作为要拷贝的文件
- COPY:将本地文件或且录拷贝到镜像的文件系统中
- VOLUME:添加数据卷
- USER:指定以哪个用户的名义执行RUN,CMD 和ENTRYPOINT等命令
- WORKDIR:设置工作目录
- ONBUILD:如果制作的镜像被另一个Dockerfile使用,将在那里被执行的Docekrfile命令
- STOPSIGNAL:设置容器退出时发出的关闭信号。
- HEALTHCHECK:设置容器状态检查。
- SHELL:更改执行shell命令的程序。Linux的默认shell是["/bin/sh","-c"],Windows的是
["cmd", "/S", "/C"]
docker-compose
-
docker-compose工作原理
-
docker compose file顶级配置项
- version:指定Docker Compose File版本号
- services:定义多个服务并配置启动参数
- volumes:声明或创建在多个服务中共同使用的数据卷对象
- networks:定义在多个服务中共同使用的网络对象
- configs:声明将在本服务中要使用的一些配置文件
- secrets:声明将在本服务中要使用的一些秘钥、密码文件
- x-***:自定义配置。主要用于复用相同的配置。
- 样例
registry
- Docker仓库就是存放docker镜像并用docker pull方法下载的云环境
- Docker仓库分为公有仓库和私有仓库。
- 公有仓库指Docker Hub(官方)等开放给用户使用、允许用户管理镜像。
- 私有仓库指由用户自行搭建的存放镜像的云环境。
- 搭建无认证私有仓库
- 第一步:在需要搭建仓库的服务器上安装docker。
- 第二步:在服务器上,从docker hub下载registry仓库:docker pull registry
- 第三步:在服务器上,启动仓库:
docker run -d -ti --restart always --name my-registry -p 8000:5000 -v /my-registry/registry:/var/lib/registry registry
注意:
registry内部对外开放端口是5000。默认情况下,会镜像存放于容器内的/var/lib/registry(官网Dockerfile中查看)目录下,这样如果容器被删除,则存放于容器中的镜像也会丢失。
本地利用curl 服务器IP:8000/v2/_catalog 查看当前仓库中的存放的镜像列表。(注意打开8000端口访问)
-
私有仓库--上传、下载镜像
- 第一步:利用docker tag重命名需要上传的镜像:
docker tag IMAGE 服务器IP:端口/IMAGE_NAME - 第二步:利用docker push上传刚刚重命名的镜像
docker push 服务器IP:端口/centos - 注意:
- 必须重命名为服务器IP:端口/IMAGE_NAME
- 如果push出现了类似https的错误,那么需要往配置文件/etc/docker/daemon.json里添加:"insecure-registries":["服务器IP:端口"]
- 然后重启docker。
- 第一步:利用docker tag重命名需要上传的镜像:
-
搭建带认证的私有仓库
- 在服务器上操作
- 第一步:删除先前创建的无认证的仓库容器
docker rm -f my-registry - 第二步:创建存放认证用户名和密码的文件
mkdir /my-registry/auth -p - 第三步:创建密码验证文件。注意将USERNAME和PASSWORD替换为设置的用户名和密码
docker run --entrypoint htpasswd registry -Bbn USERNAME PASSWORD > /my-registry/auth/htpasswd
第四步:重新启动仓库镜像
docker run -d -p 8000:5000 --restart=always --name docker-registry -v /my-registry/registry:/var/lib/registry -v /my-registry/auth:/auth -e "REGISTRY AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" registry
- 带认证的私有仓库-上传、下载镜像
- 在本地机器上
- 第一步:首先登录到服务器
docker login -u username -p password 47.94.153.230:8000 - 第二步:然后执行pull或者push命令
- 第三步:操作完毕后,可以退出登录
docker logout 47.94.153.230:8000 - 如果想查看仓库中已有的镜像,那么需要进行http验证才可以。可以直接借助浏览器访问
47.94.153.230:8000/v2/_catalog就可以访问了 - 注意这里:47.94.153.230指服务器IP