1 docker 基本命令 1 2 3 4 5 6 7 8 9 docker run -it -d -p -e -v --network container_name docker ps -a docker rm container_name docker rmi image_name docker inpect container_name docker log container_name docker pull <image_name> docker images docker stop container_name
关于docker run 命令
应当把run命令当做运行一个任务或者进程,完成了一个任务就会自动结束(保留下来算是任务执行过程的痕迹)
直接执行的时候,docker 运行的容器其实没有attach 到当前的命令行窗口中,无法读取 input 并且利用 Terminal 输出 需要加入 it 选项进行交互(否则只会输出一个最终结果?)
detach 完全进入后台运行
我希望将docker host 的一个端口映射给容器的某个端口,完成网络访问,可以使用 p 选项, 一定是外 对 内(内就是 container)
有的时候,不想总是改容器镜像中的脚本(其实是拷贝出来一份)所以把容易变化的当做环境变量,在脚本里面读取,在运行的时候设置,使用 -e
不希望容器内的数据随着容器的销毁而消失,所以会想要把数据卷挂载到容器某个路径下,这样容器写这个路径,就相当于向着外部数据卷进行写入,使用 -v volume(不过这是老式的写法)
新版的挂载数据卷的方式:docker run –mount type=bind,source=/data/mysql,target=/var/ilb/mysql container_name
指定所在的网络就用 –network 具体在网络部分展开
想要查看所有正在运行或者停止运行的所有容器:使用 -a 选项 ,docker ps
删除容器用 rm 表示remove, 删除镜像使用 rmi 表示 remove image
已经停止运行的容器可以 探测其中的配置和相关改动,用 inspect ?
正在运行的容器使用 log 探查日志输出
想要拉取镜像?使用 pull 就好(当然像私有库推送镜像使用 push)但是记者这个每次只能写入一个镜像名,否则会报错
想要停止容器运行就使用 stop 吧
2 docker 制作镜像 Dockerfile 基本命令 1 2 3 4 5 6 RUN CMD ENTRYPOINT COPY WORKDIR FROM
ENTRYPOINT 和 CMD 是配合使用的
如果 没有 ENTRYPOINT 并且没有命令行指定命令,那么默认CMD是启动时要执行的命令
此时可采用JSON 格式或者直接写空格分隔的命令两种形式
如果命令行里有指定命令,那么使用命令行中的命令
如果ENTRYPOINT 有指定(就是确定了要执行哪个程序)
CMD只能使用 JSON 格式,表示默认的这个程序执行时的参数
命令行可以覆盖CMD中的默认参数
如果命令行参数不够,默认会使用 JSON 格式指明的 CMD 中的参数append ?
FROM 基础镜像
RUN 执行一系列命令来构成镜像新的一层
COPY 拷贝外部文件到镜像的一层内
WORKDIR 指定容器运行的工作目录 ?
构建镜像 1 docker build Dockerfile -t image_name
3 docker-compose 使用
把需要成组运行的服务写到一个yaml 文件。
直接使用 docker-compose up 运行
文件结构
1 2 3 4 5 6 7 8 version: 3 services: web: image: port: database: image: port:
分了不同的版本,目前最新版本是版本3
可以指定网络,直接用服务名可以解析出 IP 地址(默认是绑定到网络 docker0)
可以指定数据卷、端口等
4 docker 底层原理
使用分层文件系统 路径在 /var/lib/docker
aufs(表示的是这个文件系, 常见系统还有 ZFS, BTRFS等)
container
image
volumes 默认的数据卷都在这个路径下
相关的文件都存储在对应的文件夹下面
镜像
都是分层的文件,利用Dockerfile 文件各个命令作为一层进行制作
制作完成之后内容只读
容器
在镜像的基础上,加上一层可读可写层,如果要修改镜像中的内容,会拷贝一份进行修改 (由分层文件系统完成)
但是这一层只在容器存在的时候存在
docker 运行结构
分为三层
Docker CLI 与用户命令交互的命令行终端
REST API Server 程序与守护进程交互的一系列接口
Docker Daemon 后台守护者进程,管理所有镜像、容器等对象
在各个部分区分了命令空间,使得各个容器运行互相不干扰
进程ID
Network
InterProcess communication
Mount
Unix Time Sharing
使用 cgroups 可以进行资源控制 【control groups】
5 docker 网络
补充知识: 私有 IP 如: 192.168.x.x、 10.x.x.x、 172.16.x.x ~ 172.31.x.x 不可被互联网直接访问 默认网关指的是:当前网络中,负责转发不在本地子网内的数据包的下一跳 IP 地址,它不一定能访问公网,但必须能连接到“外面”; 基本上发送到默认网关 MAC 地址的数据包,都是“要发到外部网络”的 关于网桥(只能看到MAC,看不到 IP ): 会学习每个 MAC 是从哪个接口来的(MAC 学习表); 如果它知道目标 MAC → 只发到对应接口; 如果它不知道目标 MAC → 广播到所有接口(Flood)。
如果是网桥模式:
每个容器将分配一个子网 IP ,如 172.17.0.2/16 ,如果它想要发送请求到 公网 ip 8.8.8.8 ,首先,它得找到本子网段的网关对应的mac 地址,以便于它知道自己的下一跳是哪里。于是它广播了一个 ARP 请求,询问网关的MAC
内核网关 docker0 以 172.16.0.1 的身份接收到请求后,发送了自己的MAC地址,于是该容器记录了这个MAC地址,发送了目的IP 是 8.8.8.8 的请求。
网关 docker0 接收到请求后,将请求发送到网络 “外部”,这个请求将注入宿主机协议栈,宿主机物理网卡就是中间的一跳,如果发现目标 ip 不在当前子网中,就会发送给当前网段的默认网关,即路由器,路由器将请求发送出去。
使用 host 模式后:
容器就像是“宿主机的一个进程”一样参与网络;
它直接在宿主机所在局域网中;
也直接使用宿主机的默认网关;
但也失去了容器间网络隔离的优势。
container 模式:
none 模式:
自定义网络模式:
相比于直接的桥接模式,自定义网络本身就建立了主机名和ip 的映射关系,不管是ping 主机名还是 ping IP 都能 ping 通
docker0 网络内部存在DNS服务器 172.12.0.11 , 可以把容器名解析到对应的局域网IP
自定义网络 1 docker network create --driver bridge --subnet 182.18.0.0/16 custom_network_name
如果直接inspect 能发现网关、IPAddress、MacAddress 等网络字段
6 Docker 集群
可以使用 Docker Swarm
但是使用 Kubernets 更方便