docker 与 虚拟机
docker 原理
命名空间(namespace)
提供了一种资源隔离的解决方案, 使得处于不同namespace的进程拥有独立的全局系统资源,改变一个namespace中的系统资源只会影响当前namespace里的进程,对其他namespace中的进程没有影响。
Linux支持的Namespace类型
名称 | 作用 |
---|---|
IPC | 用于隔离进程间通讯所需的资源( System V IPC, POSIX message queues),PID命名空间和IPC命名空间可以组合起来用,同一个IPC名字空间内的进程可以彼此看见,允许进行交互,不同空间进程无法交互 |
Network | Network Namespace为进程提供了一个完全独立的网络协议栈的视图。包括网络设备接口,IPv4和IPv6协议栈,IP路由表,防火墙规则,sockets等等。一个Network Namespace提供了一份独立的网络环境,就跟一个独立的系统一样。 |
Mount | 每个进程都存在于一个mount Namespace里面,mount Namespace为进程提供了一个文件层次视图。如果不设定这个flag,子进程和父进程将共享一个mount Namespace,其后子进程调用mount或umount将会影响到所有该Namespace内的进程。如果子进程在一个独立的mount Namespace里面,就可以调用mount或umount建立一份新的文件层次视图。 |
PID | linux通过命名空间管理进程号,同一个进程,在不同的命名空间进程号不同!进程命名空间是一个父子结构,子空间对于父空间可见。 |
User | 用于隔离用户 |
UTS | 用于隔离主机名 |
虚拟机的原理
种类
裸机型,直接运行在物理设备之上,是一种基于内核的虚拟机(其中包括VMware ESX Server、Microsoft Hyper-V)。这种类型的虚拟机监视器所扮演的角色是一种抽象概念的OS。
宿主机型,运行在宿主机器的操作系统上(VMware Workstation, VirtualBox) 创建硬件全仿真实例。虚拟机监视器构建出一整套虚拟硬件平台(CPU/Memory/Storage/Adapter),这样底层和上层的OS就可以完全无关化。
性能
裸机型 > 宿主机型
docker与虚拟机对比
特性 | docker | 虚拟机 |
---|---|---|
运行形态 | 共享宿主机内核 | 运行与虚拟机监视器上 |
性能 | 接近宿主机 | 低于宿主机 |
资源利用率 | 高 | 低 |
隔离性 | 安全隔离 | 完全隔离 |
并发性 | 一台宿主机可以启动成百上千个容器 | 最多几十个虚拟机 |
启动速度 | 快, 几秒钟 | 慢,几分钟 |
占用磁盘空间 | 小,甚至只有几十 KB | 非常大,可达GB |
docker安装
sudo usermod -aG docker your-user
- 设置镜像加速(Ubuntu)
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://wmndjzem.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
docker 使用
docker 开发中的使用
- 一键搭建开发环境
apt-get install docker
docker run -d --name rabbitmq -p 5671:5671 -p 5672:5672 -p 15671:15671 -p 15672:15672 rabbitmq:3.7.14-management-alpine
docker run -d --name redis -p 6379:6379 redis:5.0.4-alpine
docker run -d --name zookeeper -p 2181:2181 zookeeper:3.4.14
- 便于测试一些技术, 比如说利用binlog在2个mysql中实现表同步, 各种集群测试, 各种版本新特性测试等等
- 提升技术深度
docker的基本概念
镜像
类似于虚拟机镜像, 可以将它理解为一个只读的模板. 镜像是创建docker容器的基础, 通过版本管理和增量的文件系统, docker提供了一套非常简单的机智来创建和更新现有的镜像, 甚至可以从网上下载一个已经做好的应用镜像并且直接使用.
镜像分为很多层(layer), 每个层都会有个id.
容器
容器类似与一个轻量级的沙箱, docekr利用容器来运行和隔离应用. 容器是从镜像创建的应用实例. 可以将其启动/开始/停止/删除.
可以把容器看做是一个简易版的linux系统环境以及运行在其中的应用程序打包而成的盒子
仓库
docker仓库类似于代码仓库. 它是docker集中存放镜像文件的场所. 根据所存储的镜像公开与否, docker仓库可以分为公开仓库和私有仓库.
使用docker镜像
下载镜像
docker [image] pull NAME[:TAG]
NAME是镜像名称, TAG是镜像的标签
例如:
[root@localhost ~]# docker image pull mysql:5.7
5.7: Pulling from library/mysql
fc7181108d40: Already exists
787a24c80112: Already exists
a08cb039d3cd: Already exists
4f7d35eb5394: Already exists
5aa21f895d95: Already exists
a742e211b7a2: Already exists
0163805ad937: Already exists
62d0ebcbfc71: Pull complete
559856d01c93: Pull complete
c849d5f46e83: Pull complete
f114c210789a: Pull complete
Digest: sha256:c3594c6528b31c6222ba426d836600abd45f554d078ef661d3c882604c70ad0a
Status: Downloaded newer image for mysql:5.7
查看镜像信息
docker images可以查看已经下载的镜像
例如:
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql latest c7109f74d339 3 weeks ago 443MB
redis 5.0.4-alpine c8eda26fcdab 2 months ago 50.9MB
hello-world latest fce289e99eb9 6 months ago 1.84kB
canal/otter-all latest e4ea8e200811 7 months ago 1.06GB
删除镜像
docker rmi 或 docker image rm 命令可以删除镜像
命令格式为 docker rmi IMAGE [IMAGE...], 其中IMAGE可以为标签或者ID
例如:
[root@localhost ~]# docker rmi mysql:5.7
Untagged: mysql:5.7
Untagged: mysql@sha256:c3594c6528b31c6222ba426d836600abd45f554d078ef661d3c882604c70ad0a
Deleted: sha256:a1aa4f76fab910095dfcf4011f32fbe7acdb84c46bb685a8cf0a75e7d0da8f6b
Deleted: sha256:1e469e8670a36fe95b3d93fa42cfb8af28fa008eefc8f54c959b25ee2c0aede9
Deleted: sha256:dfc8a50c616d3fe82f9a73916f5177b3b45d9e8c9a66fadd75050c732703f37c
Deleted: sha256:03f1d8adf4a4d0a5b5921c20692e68144c00c7e4afdfb321d2db90a4953675ce
Deleted: sha256:f299ef3d6713adeb2f1df6f1bbf4d4a2373fb4d1f8ba840363b2714cb7316fa1
清理镜像
使用Docker一段时间后, 系统中可能会遗留一些临时的镜像文件, 以及一些没有被使 用的镜像, 可以通过docker image prune命令来进行清理。
例如:
[root@localhost ~]# docker image prune
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] y
Total reclaimed space: 0B
创建容器并启动
创建容器
docker [container] create
选 项 | 说 明 |
---|---|
-d --detach=true|false | 是否在后台运行容器, 默认为否 |
--net= "bridge" | 指定容器网络模式,包括 bridge、none、其他容器内网络、 host 的 网络或某个现有网络等 |
-p, --publish=[] | 指定如何|决射到本地主机端口 |
-v | --volume[=[[HOST-DIR:] CONTAINER-DIR [:OPTIONS]]] | 挂载主机上的文件卷到容器内 |
-e, --env=[] | 指定容器内环境变量 |
--name="" | 指定容器的别名 |
--restart | 容器退出时使用的重启策略, 默认"no", "always"时容器自动重启 |
例如:
[root@localhost ~]# docker create --name mysql -p 5688:3306 -v /root/mysqldata:/data -e MYSQL_ROOT_PASSWORD=123456 --net=bridge mysql:5.7
e5f3fdf2d16c8d55bb62f270075e0b3a8fc38fe719e20dbd7327aaa2f41db170
启动容器
docker [container] start NAME | ID
例如:
[root@localhost ~]# docker start mysql
mysql
创建并启动容器
docker [container]run,等价于先执行 docker [container] create 命令,再执行 docker [container] start 命令, 但是守护态运行需要加-d参数
例如之前创建mysql:
docker run -d --name mysql -p 5688:3306 -v /root/mysqldata:/data -e MYSQL_ROOT_PASSWORD=123456 --net=bridge mysql:5.7
例如:
[root@localhost ~]# docker run --rm -it --net=host mysql:5.7 mysql -h127.0.0.1 -P5688 -uroot -p
停止容器
docker [container] stop NAME | ID
例如:
[root@localhost ~]# docker stop mysql
mysql
进入容器
docker exec -it NAME | ID /bin/sh
例如:
[root@localhost ~]# docker exec -it mysql /bin/sh
删除容器
docker [container] rm [-f] NAME | ID
例如:
[root@localhost ~]# docker rm mysql
mysql
docker的网络类型
host
直接使用宿主机网络
container
新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等
none
Docker容器没有网卡、IP、路由等信息, 需要自己为Docker容器添加网卡、配置IP等
bridge
虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。