学习内容:
Docker 容器是一个轻量级、可移植、自给自足的软件环境,将应用程序及其所有依赖项(包括库、配置文件、系统工具等)封装在一个标准化的包中,使得应用能够在任何地方一致地运行
- 镜像(Image):容器的静态模板,包含了应用程序运行所需的所有依赖和文件。镜像是不可变的
- 容器(Container):镜像的一个运行实例,具有自己的文件系统、进程、网络等,且是动态的。容器从镜像启动,并在运行时保持可变
镜像是一种轻量级,可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,包含某软件运行所需的所有内容包括代码,运行时,库,环境变量和配置文件
docker 镜像加载原理:UnionFS(联合文件系统)分层,轻量级,高性能
rootfs可以很小,只需包含最基本的命令,工具和程序库
基础操作
ctrl+p+q不停止退出一个容器
docker+命令+ --help 查看指令的具体使用
docker images 查看已经获取到的镜像
- REPOSITORY:表示镜像的仓库
- TAG:镜像的标签
- IMAGE ID:镜像ID
- CREATED:镜像创建时间
- SIZE:镜像大小
docker ps -a 列出所有容器(包括已停止的容器)
docker pull+镜像 当镜像不存在时,拉取镜像
docker search+镜像名 查找镜像,或者从Docker Hub 网站查找 - NAME: 镜像源的名字
- DESCRIPTION: 镜像的描述
- OFFICIAL: 是否 docker 官方发布
- stars: 点赞、喜欢的意思
- AUTOMATED: 自动构建
docker start/restart +容器ID 启动一个已经停止的容器
–name 指定容器名
docker attach +容器ID 与容器进行标准输入,输出和错误交互
此时使用exit退出终端会使容器停止运行,因为是打开当前终端不会开启新的
docker exec +容器ID 进入容器终端
此时exit 退出容器终端,但不会使容器停止运行,因为是开启一个新的终端,在里面操作
docker container ls 查看当前正在运行的容器
docker export +容器ID +> +目录 导出本地容器到指定目录(将容器快照到本地文件)
利用管道符读取本地快照文件,导入为镜像
file|URL|-:指定要导入的文件路径、URL 或从标准输入读取(使用 -)
通过指定URL或者目录导入
docker rm -f +容器ID/容器名 删除容器,在删除时容器必须是停止状态,否则会报错
docker rm -f $(docker ps -aq) 清空所有容器
-q:选项表示“quiet”,即只输出容器的短 ID(通常是前12位),而不显示其他详细信息
docker container prune 删除所有停止状态的容器
docker rmi -f +镜像ID/镜像名:标签 删除镜像
docker rmi -f $(docker images -aq) 删除所有镜像
docker image prune -a 删除未被容器使用的镜像
docker rmi $(docker images -q) 批量删除,查找到镜像ID后进行删除
在容器中运行一个应用程序
docker run+镜像+/bin/echo+程序
/bin/echo 是一个简单的命令行工具,用于在终端输出文本内容。它的主要功能是将输入的字符串打印到标准输出(通常是终端屏幕)
- docker 二进制执行文件
- run 和docker组合运行容器
- 当镜像不存在时会在镜像仓库下载公共镜像
- bin/echo 在启动的容器中执行命令
- Docker 以 镜像创建一个新容器,然后在容器里执行 bin/echo “Hello world”,然后输出结果
运行交互式容器
提供一种灵活的方式来直接操作容器内部的环境
-i 和 -t 使容器实现对话
exit或者ctrl+d 退出容器
-i:允许在容器内标准输入进行交互
-t:在容器内指定一个伪终端或者终端
ubuntu:15.10: 指定镜像版本启动容器,不添加指定标签会使用latest镜像
/bin/bash:放在镜像名后的是命令,开启一个交互式shell
查看当前系统的版本信息和当前目录下的文件列表
后台启动容器
-d 后台运行(进程方式)容器
输出容器ID 默认不会进入容器
/bin/sh -c:在容器中启动一个 shell,并执行后面的命令
/bin/bash是/bin/sh 的扩展
docker ps 查看正在运行的容器
- CONTAINER ID: 容器 ID
- IMAGE: 使用的镜像
- COMMAND: 启动容器时运行的命令
- CREATED: 容器的创建时间
- STATUS: 容器状态
- created(已创建)
- restarting(重启中)
- running 或 Up(运行中)
- removing(迁移中)
- paused(暂停)
- exited(停止)
- dead(死亡)
- PORTS: 容器的端口信息和使用的连接类型(tcp\udp)
- NAMES: 自动分配的容器名称
docker logs +容器ID/容器名 查看容器内的标准输出
docker stop +容器ID/容器名 停止容器
docker客户端
与 Docker 守护进程(Docker Daemon)交互的命令行工具
- Docker 守护进程(类似服务端):一个后台服务进程,负责管理和维护 Docker 容器的生命周期,处理与 Docker 容器相关的各种操作,例如创建、启动、停止、删除容器,管理镜像,以及处理网络和存储卷等资源,监听来自 Docker 客户端的请求,并执行相应的操作
运行一个web应用
-P:容器内部端口随机映射到主机的端口
PORTS端口信息
通过虚拟机的静态IP+映射到主机的端口号进行访问
-p 容器内部端口绑定到指定的主机端口
指定容器绑定的网络地址,端口和端口类型(默认是tcp端口)
docker port+容器ID/容器名 查看容器确定端口映射到主机的端口号
docker logs+容器ID/容器名 查看容器内的标准输出
-f 实时更新输出
docker top+容器名 查看容器内部运行的进程
docker inspect+容器名 查看容器的底层信息,记录着配置和状态信息
docker stop+容器名 停止应用容器
docker start+容器名 重新启动停止的容器
docker ps -l 查询最后一次创建的容器,重启的容器不算是创建的
docker restart+容器名 重启正在运行的容器
从容器内拷贝文件到主机上
docker cp 容器id:容器内路径 目的主机路径
docker commit 提交容器称为新副本
docker commit -m=“提交的描述信息” -a=“作者” 容器id 目标镜像名:[TAG]
docker history + 镜像id 查看镜像的创建过程
创建
创建镜像
在已创建的容器中更新镜像,并提交这个镜像
创建已Ubuntu15.10镜像为基础的容器
更新Ubuntu系统,由于旧版Ubuntu不能再访问库,需要切换到旧版本的源来解决“404 Not Found”错误
exit退出容器
将按需求更改的容器,提交该容器副本
- -m: 描述信息
- -a: 镜像作者
- e218edb10161:容器 ID
- runoob/ubuntu:v2: 目标镜像名
通过docker images 可以查看到
docker tag +容器ID+指定镜像名:指定标签 添加一个新的镜像名和标签
Docker容器互联
docker连接系统允许将多个容器连接在一起,共享连接信息,连接会创建一个父子关系,其中父容器可以看到子容器的信息
新建网络
创建新的Docker网络 - -d:参数指定 Docker 网络类型,有 bridge、overlay
- Bridge 网络(默认网络类型)
- Host 网络
- None 网络
- Overlay 网络
- Macvlan 网络
- Custom 网络
没有设置子网和网关会默认分配
连接容器
提交安装好ping的自定义镜像
apt-get update
apt install iputils-ping
测试容器连接
配置DNS
在宿主机的 /etc/docker/daemon.json 文件中增加,设置全部容器的 DNS
"dns" : [
"114.114.114.114",
"8.8.8.8"
]
查看容器内配置
–rm:容器退出后自动删除容器,避免留下无用的容器
手动指定容器配置
容器启动时没有指定 --dns 和 --dns-search,Docker 会默认用宿主主机上的 /etc/resolv.conf 来配置容器的 DNS
- -h HOSTNAME 或者 --hostname=HOSTNAME: 设定容器的主机名,它会被写到容器内的 /etc/hostname 和 /etc/hosts
- –dns=IP_ADDRESS: 添加 DNS 服务器到容器的 /etc/resolv.conf 中,让容器用这个服务器来解析所有不在 /etc/hosts 中的主机名
- –dns-search=DOMAIN: 设定容器的搜索域,当设定搜索域为 .example.com 时,在搜索一个名为 host 的主机时,DNS 不仅搜索 host,还会搜索 host.example.com
Docker Compose
定义和运行多容器 Docker 应用程序的工具,使用 YML 文件来配置应用程序需要的所有服务
- 使用 Dockerfile 定义应用程序的环境
- 使用 docker-compose.yml 定义构成应用程序的服务,在隔离环境中一起运行
- 执行 docker-compose up 命令启动并运行整个应用程序
下载docker-compose的二进制文件
存放在/usr/local/bin目录下中,存放用户自己安装的程序,不会覆盖系统自带的命令
将该二进制文件设为可执行权限
创建软链接到/usr/bin目录下,该目录存放系统范围内用户命令和程序(系统自带工具,应用程序或第三方软件的可执行文件),会被包含在系统的环境变量PATH中
创建web文件
创建所需依赖文件
flask 是轻量级的Web应用框架
创建Dockerfile文件配置镜像
- WORKDIR : 设置工作目录
- ENV:设置环境变量
- apk add: 安装软件包
- –no-cache:不要缓存索引,减小镜像大小并加快安装速度
- pip install -r 根据文件内容下载对应的依赖项
- COPY+本地目录+镜像目录 复制到指定位置
- CMD 当生成容器后默认执行命令:flask run
创建docker-compose.yml配置文件
用于定义和管理多容器的Docker应用 - version:声明当前Docker Compose的版本
- services:定义应用中所有服务配置
- build 从指定目录查找Dockerfile根据指令构建Docker镜像
- ports:定义端口映射,将宿主机端口映射到容器端口
- image:直接使用Docker Hub 上的镜像
启动应用程序
docker-compose up -d 后台执行该服务
yml配置指令参考
Docker Machine
下载docker-machine的二进制文件,并重定向到/usr/local/bin目录下
给该文件设置可执行权限
容器数据卷
数据都在容器中,容器删除数据就会丢失
数据共享技术,容器中产生的数据同步到本地
容器持久化和同步操作,容器间数据共享
docker run -it -v 主机目录:容器内目录
当容器停止后,修改主机中对应文件,仍然可以同步到容器,删除容器后本地数据也不会丢失
具名和匿名挂载
所有容器内的卷,在没有指定目录的情况下都在/var/lib/docker/volumes/xxx
匿名卷挂载
-v 容器内路径 主机会自动生成路径
具名挂载
-v 卷名:容器内路径
通过-v 容器内路径:ro rw 改变读写权限
readonly只读 说明该路径只能通过主机操作,容器内部无法操作
readwrite可读可写
设置容器权限后,容器对挂载出的内容就有限定
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
数据卷容器
两个或多个容器同步数据
删除docker01后数据,不会丢失,备份机制
Dockerfile
构建docker镜像的构建文件
Dockerfile指令每次执行都会在docker上新建一层,所以过多无意层会造成镜像膨胀过大
指令(大写) 参数
每个命令就是镜像的一层
- FROM:定制的镜像是基于 FROM 的镜像
- RUN:用于执行后面的命令行命令
- shell格式:RUN <命令行命令>,等同于在终端操作的 shell 命令,可以使用&&连接命令创建一层镜像
- exec格式:RUN [“可执行文件”, “参数1”, “参数2”],RUN [“./test.php”, “dev”, “offline”] 等价于 RUN ./test.php dev offline
使用Dockerfile指令创建新的镜像
FROM:指定使用哪个镜像源
RUN :docker 在镜像内执行命令和安装等
- shell格式:RUN <命令行命令>,等同于在终端操作的 shell 命令,可以使用&&连接命令创建一层镜像
- -t :创建的目标镜像名
- . :Dockerfile 文件所在目录,可以是Dockerfile 的绝对路径
自定义镜像在命令行里创建了runoob用户
挂载卷
在生成镜像时挂载卷
构建镜像时没有挂载,要手动镜像挂载
匿名挂载,容器内路径是这两个目录
每个指令都会创建并提交新的镜像层
FROM #基础镜像,一切从这里开始构建
MAINTAINER #镜像作者,姓名+邮箱
RUN #镜像构建时需要运行的命令
ADD #步骤:搭建tomcat镜像,添加tomcat压缩包!添加内容
WORKDIR #镜像的工作目录
VOLUME #挂载的目录
EXPOST #暴露端口,保留端口配置
CMD #指定容器启动时要运行的命令,只有最后一个会生效且可被替代
ENTRYPOINT #指定容器启动时要运行的命令,可以追加命令
ONBUILD #当构建一个被继承Dockerfile,这个时候就会运行该指令,触发指令
COPY #类似ADD,将文件拷贝到镜像中
ENV #构建的时候设置环境变量
多数镜像都是从scratch开始,然后配置需要的软件和配置
自定义centos镜像
默认的yum源无法使用,可以将主机的yum源配置文件复制到镜像中,重新加载元数据
CMD和ENTRYPOINT
在启动容器时追加-l 目的是执行命令 ls -al,但是报错
因为在CMD情况下 -l 替换了CMD [“ls”,“-a”] 命令,但-l 不是一个命令
-l 可以直接追加到entrypoint命令的后面,组成ls -al 命令
Docker网络
docker中所有的网络接口都是虚拟的,转发效率高
192.168.0.1
192.168.0.2
两个IP在同一网段下可以相互ping通
ip addr 查看当前主机ip
lo:本机回环地址
eth0:阿里云内网地址
docker0:docker生成的网卡
注意使用tomcat镜像做测试,默认是ubuntu版本,没有ip和ping命令
需要进入容器执行
apt update
apt install -y iproute2
apt install -y iputils-ping
建议利用该容器直接创建自定义镜像
docker 处理容器网络访问
查看容器内部的网络地址 ip addr 得到一个docker分配的 eth0 ip地址
Linux可以ping通docker容器内部
每启动一个容器,docker就会分配一个ip,只要安装docker就会有一个网卡docker0 桥接模式,使用的技术是evth-pair技术
在主机再次测试ip addr
容器带来的网卡都是成对的
evth-pair 是一对虚拟设备接口,成对出现的,一端连接协议,一端彼此相连(69和70)
根据这个特性evth-pair充当桥梁,连接各种虚拟网络设备
容器间ping测试
容器之间可以ping通
所有容器在不指定网络的情况下,都是由docker0路由(网桥),docker会给容器分配一个默认可用的IP
删除容器后,对应的一对网桥会被自动删除
通过 --link 指令利用容器名与容器之间进行连接
tomcat02配置连接,但tomcat01没有,所以01不能利用容器名ping
原理:在tomcat02本地配置tomcat01的配置,在hosts中配置01的映射
查看docker网络
bridge:桥接docker(默认)
none:不配置网络
host:和宿主机共享网络
container:容器网络联通
bridge 指的是docker0
docker0不支持容器名连接访问
查看详细信息
自定义网络
自定义网络会修复docker0的缺点,自带用容器名连接
–net bridge 不写会是个默认参数
subnet 配置子网
gateway 配置网关
部署在自定义网络下
容器互联
连通后将tomcat02放到mynet网络下,一个容器两个IP