目录
1. docker 介绍
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口
- 特性:
- 隔离环境(系统,网络,文件系统)与应用
- 解决依赖与版本问题
- 易于分发,开箱即用
- 节点与容器快速扩容和缩容
- 镜像制作简单便捷,管理方便
-
namespace:进程隔离
-
cgroup:资源限制 它最主要的作用,就是限制一个进程
组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等等。 -
在 Linux 中,Cgroups 给用户暴露出来的操作接口是文件系统,即它以文件和目录的方式
组织在操作系统的 /sys/fs/cgroup 路径下 -
Docker和虚拟机技术比较:
- 传统虚拟机:虚拟硬件,运行一个完整的操作系统,然后在系统上安装和运行app
- docker:容器内的应用直接运行在宿主机,容器没有自己的内核,也没有虚拟硬件,容器间互相隔离,每个容器内都有一个属于自己的文件系统,互不影响
-
Docker的基本组成:
-
镜像 (image)
:镜像是一种轻量级的,可执行的独立软件包,用来打包软件运行环境和基于运行环境的开发软件,它包含运行某个软件做需要的所有的内容,包括代码,运行时,库,环境变量和配置文件 -
容器 (container)
:镜像运行起来之后,就是容器。也可以理解它就是一个服务,这个服务可以由多个服务组成,比如某个镜像提供的是一个启动服务的安装包,将其运行成容器后,它会拉起几个其他程序来提供一个完整的服务 -
仓库 (repository)
:用来存放镜像,仓库分为公有仓库Docker Hub
和私有仓库Harbor
-
2. docker 安装
# 需内核版本 3.10以上 (uname -r)
# 1. 安装依赖包
yum -y install yum-utils device-mapper-persistent-data lvm2
# 2. 添加docker的CE版(社区版)的阿里云yum源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 3. 安装docker
# 安装最新版本
yum -y install docker-ce
# 安装指定版本
# yum list docker-ce.x86_64 --showduplicates | sort -r # 从高到低列出docker版本然后选择版本安装
# 4. 配置镜像加速
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors":[
"http://hub-mirror.c.163.com",
"https://docker.mirrors.ustc.edu.cn",
"https://registry.docker-cn.com"
]
}
EOF
# 5. 启动docker并设置为开机自启动
systemctl daemon-reload
systemctl enable docker --now
3. docker 常用命令
3.1 docker信息
docker version # 查看docker容器版本
docker info # 查看docker容器信息,包括镜像和容器的数量
docker --help # 查看docker容器帮助
3.2 镜像操作
-
查看镜像
docker images # 列出本地images docker images xxx # 查看指定images # 常用可选项 -a, --all # 列出所有镜像信息 -q, --quiet # 只显示镜像ID
-
搜索镜像镜像
docker search 镜像名称 # 从镜像仓库搜索镜像 # 常用可选项 -f, --filter filter # 过滤,例如 docker search nginx --filter "STARS=3000" (搜索收藏大于3000的nginx镜像)
-
下载/上传镜像
docker pull 镜像名称[:tag] # 拉取镜像 docker push 镜像名称 # 上传镜像
-
删除镜像
docker rmi 镜像名称/镜像ID # 常用可选项 -f, --force # 强制删除
-
镜像增加tag信息
docker tag 镜像ID os/centos7:1
-
显示指定镜像的历史创建
docker history Image_name # 常用可选项 -H, --human # 以可读的格式打印镜像大小和日期 --no-trunc # 显示完整的提交记录
-
获取镜像的元信息(检查镜像或者容器的参数,默认返回 JSON 格式)
docker inspect --format '{{.RepoDigests}}' 镜像/容器 # 常用可选项 -f, --format string # 指定返回值的模板文件
3.3 容器启动和状态管理
-
创建一个容器进程但不启动
docker create Image_name
-
创建并运行一个容器
docker run -d -it 镜像名称 --name 指定容器名称 -e XXX=xxx /bin/bash # 常用可选项 -d # 后台运行 -i # 可以进行命令交互 -t # 制作一个伪终端用于登陆 -v # 挂载volume卷 -p # 映射端口 (主机端口:容器端口) -P # 映射随机端口 -e # 设置环境变量 -m # 可以使用的最大内存 --rm # 容器任务完成后自动删除,用来测试 --cpus # 可以使用的最大cpu数 --omm-kill-disable # 禁用OMM Killer --name # 容器命名 --log-opt max-size=10m # 日志文件的最大大小, 默认为-1(无限制) --log-opt max-file=3 # 可以存在的最大日志文件数。如果滚动日志会创建多余的文件,则会删除最早的文件。仅在max-size设置时有效。一个正整数。默认为1。
3.4 容器相关操作
-
启动/停止/强制停止/重启/删除/暂停/恢复容器
docker [start|stop|kill|restart|rm|pause|unpause] 容器ID或容器名称 docker rm $(docker ps -q -f status=exited) # # 删除exited状态的容器 # 常用选项 rm -f # 强制删除 rm -l 连接名 # 移除容器间的网络连接 rm -v 容器 # 删除容器,并删除容器挂载的数据卷
-
查看容器
docker ps # 常用选项 -q # 查看正在运行的容器的ID -a # 查看正在运行+历史运行过的容器 -s # 显示运行容器总文件大小 -l # 显示最近创建容器 -n 3 # 显示最近创建的3个容器
-
查看容器中的进程
docker top 容器ID或容器名称
-
查看容器日志
docker logs -f -t --tail=20 Container_ID -f 跟踪日志输出 -t 显示时间戳 --tail 仅列出最新N条容器日志
-
容器状态相关
# 实时监测容器的变化情况 docker events # 监听容器的退出状态并返回状态码 docker wait 容器ID或容器名称 # 检查容器资源使用情况 docker stats 容器ID或容器名称 # 查看容器进程与源镜像做对比,发生了改变的文件或文件夹 docker diff 容器ID或容器名称 # 查看容器与宿主机端口映射关系 docker port 容器ID或容器名称
-
获取容器的元信息
# 查看容器日志文件 docker inspect --format='{{.LogPath}}' 容器ID或容器名称 # 查看容器pid docker inspect --format '{{ .State.Pid }}' 容器ID或容器名称
-
容器终端操作
# 容器中打开新的交互模式终端 docker exec -i -t Container_ID /bin/bash # 以交互模式在容器中执行命令,结果返回到当前终端屏幕 docker exec -i -t Container_ID ls -l /tmp # 以分离模式在容器中执行命令,程序后台运行,结果不会反馈到当前终端 docker exec -d Container_ID touch cache.txt
-
容器文件复制
# 将容器中的文件copy至本地 docker cp 容器ID:路径 本地路径 # 将本地文件copy至容器 docker cp 本地路径 容器ID:路径
-
直接进入容器(不分配新终端)
docker attach 容器ID 快捷键:Ctrl + q + p # 仅退出容器,不关闭
-
修改容器名称
docker rename 容器ID或容器名称 新名称
-
调整容器资源限制
docker update -m (内存限制) -c (cpu限制) 容器ID或容器名称
4. docker 镜像
4.1 镜像加载原理
-
UnionFS联合文件系统
- UnionFS联合文件系统是一种分层、轻量级且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下
- UnionFS联合文件系统是docker镜像的基础,镜像可以通过分层来继承,基于基础镜像可以制作各种具体的应用镜像
- 一次同时加载多个文件系统,但从外面看起来只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所以底层的文件和目录
-
docker镜像加载
docker镜像
:由一层一层的文件系统组成,这种层级的文件系统就是UnionFSbootfs(boot file system)
:主要包含bootloader和kernel, bootloader 主要是引导加载kernel,当我们加载镜像的时候,会通过bootloader加载kernal,Docker镜像最底层是bootfs,当boot加载完成后整个kernal内核都在内存中了,bootfs也就可以卸载,值得注意的是,bootfs是被所有镜像共用的,许多镜像images都是在base image(rootfs)基础上叠加的。rootfs (root file system)
:在bootfs之上包含的就是典型Linux系统中的/dev, /proc, /bin, /etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu, Centos等等
对于一个精简的OS,rootfs可以很小,只需要包含最基本的命令、工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以了
Docker的镜像层都是只读的,当容器启动时,会在镜像的最上层加载一个容器层
容器层是可写的
4.2 镜像操作
4.2.1 commit
# 将一个运行中的容器的当前状态保存为一个新的镜像
docker commit -m="提交的描述信息" -a="作者" 容器ID 目标镜像名:[TAG]
4.2.2 export 和 import
# 对当前的容器状态建立快照,并持久化为tar文件
docker export 容器ID > test.tar
# 将导出的tar包文件系统生成一个新的镜像
docker import test.tar 镜像名称
4.2.3 save 和 load
# 镜像打包/镜像还原
docker save base/tomcat8 os/centos7 -o images.tar
docker load -i images.tar 或者 docker load < images.tar
5. docker 数据卷
Docker提供三种不同方式将数据从宿主机挂载到容器中:volumes
,bind mounts
和tmpfs
。
volumes
:Docker管理宿主机文件系统的一部分(/var/lib/docker/volumes)bind mounts
: 可以存储在宿主机系统的任意位置tmpfs
:挂载存储在宿主机系统的内存中,而不会写入宿主机的文件系统
5.1 volumes/bind mounts
-v
和--mount
区别:-v
没有源时自动创建并挂载,--mount
没有则报错
# 1. 创建volumes
docker volume create tomcat_volume
# 2. 查看所有volumes
docker volume ls
# 3. 删除volumes
docker volume rm 卷名
# 4. 查看volumes详细信息
docker volume inspect 卷名
# 5. 启动两个容器挂载同一个volume
mkdir /data/webapps;echo "test" > /data/webapps/test.html
# volumes方式挂载
# docker run -dit --mount src=tomcat_volume,dst=/usr/local/tomcat/webapps --name=tomcat-node01 tomcat:9.0
# bind-mount方式挂载
# docker run -dit --mount type=bind,src=/data/webapps/,dst=/usr/local/tomcat/webapps --name=tomcat-node01 tomcat:9.0
# -v方式挂载 (-v 是bind方式,可通过 docker inspect 容器 查看挂载类型)
docker run -dit -v /data/webapps/:/usr/local/tomcat/webapps --name=tomcat-node01 tomcat:9.0
# --volumes-from挂载 (挂载和指定容器相同的数据卷)
docker run -dit --volumes-from tomcat-node01 --name=tomcat-node02 tomcat:9.0
匿名挂载:
没有声明宿主机目录或卷名:
docker run -dit -v /usr/local/tomcat/webapps tomcat:9.0
Docker会默认在宿主机上创建一个临时目录
/var/lib/docker/volumes/[VOLUME_ID]/_data
,然后把它挂载到容器的/usr/local/tomcat/webapps
目录上,VOLUME_ID
和VOLUME NAME(docker volume ls)
的名字一样具名挂载:
声明卷名和容器目录:
docker run -dit -v tomcat_webapps:/usr/local/tomcat/webapps tomcat:9.0
Docker会默认在宿主机上创建一个临时目录
/var/lib/docker/volumes/tomcat_webapps/_data
,然后把它挂载到容器的/usr/local/tomcat/webapps
目录上,VOLUME_ID
和VOLUME NAME(docker volume ls)
的名字一样不创建卷挂载:
声明宿主机目录和容器目录:
docker run -dit -v /data/webapps/:/usr/local/tomcat/webapps tomcat:9.0
宿主机没有时自动创建
/data/webapps/
,然后把它挂载到容器的/usr/local/tomcat/webapps
目录上,不创建volume(docker volume ls没有显示)
挂载权限:
ro:
挂载后挂载的内容在容器内只读
docker run -dit -v tomcat_webapps:/usr/local/tomcat/webapps:ro tomcat:9.0
rw:
挂载后挂载的内容在容器内可写
docker run -dit -v tomcat_webapps:/usr/local/tomcat/webapps:rw tomcat:9.0
# mysql 持久化示例
# 1.运行myql容器并将本地目录映射到容器
docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name=mysql-node01 mysql:5.7
# 2.本机连接容器mysql并创建test库
mysql -uroot -p123456 -h 192.168.10.111 -P3310
# create database test
# 3.删除容器重新运行查看test库是否存在
5.2 tmpfs
docker run -dit --mount type=tmpfs,dst=/tmp --name=tomcat-node04 tomcat:9.0
docker exec xx df | grep -w tmp
tmpfs 932652 0 932652 0% /tmp
5.3 修改容器数据存储位置
-
方式一:修改docker启动配置文件
(/lib/systemd/system/docker.service)
ExecStart=/usr/bin/dockerd --graph=/data/docker/
-
修改docker启动配置文件
(/etc/docker/daemon.json)
{
"live-restore": true,
"graph": [ "/data/docker/" ]
}