概述:docker
docker
1.docker&VM
传统虚拟化
Docker
docker 架构
![image-20210126190803002](/Users/junmingguo/Library/Application Support/typora-user-images/image-20210126190803002.png)
docker镜像由文件+元数据组成,元数据包括:环境变量、端口映射、卷等其它细节
Container = cgroup + namespace + rootfs + Container Engine
cgroup即ControlGroup,LInux操作系统通过cgroup设置进程使用CPU 内存 IO资源的限额
docker运行命令配置:–cpu-shares, –memory, –device-write-bps实际在配置cgroup
namespace实现了容器间资源的隔离,Linux使用了六种namespace,分别是:
Mount
UTS namespace
IPC namespace
PID namespace
Network namespace
User namespace
2.基本概念
2.1 镜像
Docker 镜像(Image),就相当于是一个 root
文件系统。比如官方镜像 ubuntu:18.04
就包含了完整的一套 Ubuntu 18.04 最小系统的 root
文件系统。
2.2 容器
容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
2.3 仓库
一个 Docker Registry 中可以包含多个 仓库(Repository
);每个仓库可以包含多个 标签(Tag
);每个标签对应一个镜像。
通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签>
的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest
作为默认标签。
3.目标及使用场景
3.1 目标
提供简单轻量的建模方式
职责的逻辑分离
快速高效的开发生命周期
鼓励使用面向服务的架构
3.2 使用场景
(1)使用docker容器开发、测试、部署服务
(2)创建隔离的运行环境
(3)搭建测试环境
(4)构建多用户的平台即服务(PaaS)基础设施
(5)提供软件即服务(SaaS)应用程序
(6)高性能、超大规模的宿主机部署
3.3 能力
(1)文件系统隔离:每一个容器都有自己的root文件系统
(2)进程隔离:每一个容器都运行在自己的进程环境中
(3)网络隔离:容器间的虚拟网络接口和IP地址是分开的
(4)资源隔离和分组:使用cgroup将cpu和内存之类的资源独立分配给每一个docker容器
4.常见命令
1.基础
1.1 安装docker(mac OS)
1 | brew cask install docker |
1.2 查看docker版本
1 | docker --version |
1.3 测试docker是否成功安装
1 | docker run hello-world |
1.5 登录远程 login
1 | docker login -u <用户名> -p <密码> <URL> |
1.6 查看容器网络列表 ls
1 | docker network ls |
—————————
2. 容器
2.1 进入容器 exec
1 | docker exec -it CONTAINER_ID/NAME bash |
2.2 查看容器 ps
1 | # 查看正在运行的容器 |
2.3 删除容器 rm
1 | docker rm CONTAINER_ID |
2.4 运行容器 run
1 | docker run -it python |
守护态运行容器:让 Docker 容器在后台以守护态(Daemonized)形式运行
1 | docker run -d ubuntu:18.04 |
容器对资源的使用限制
1 | docker run -d -it -c 1024 --memory 200M --memory-swap 300M --blkio-weight 600 ubuntu bash |
2.5 启动和终止容器 start/stop
启动时针对已经终止的容器启动运行
1 | docker container start |
2.6 重新启动/停止容器
1 | docker start CONTAINER-ID |
2.7 导出容器 export
导出容器快照到本地文件
1 | docker export 7691a814370e > ubuntu.tar |
2.8 导入容器 import
1 | docker import - test/ubuntu:v1.0 |
—————————
3. 镜像
3.1 拉取镜像 pull
从 Docker 镜像仓库获取镜像的命令是 docker pull
。其命令格式为:
1 | docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签] |
具体的选项可以通过 docker pull --help
命令看到,这里我们说一下镜像名称的格式。
- Docker 镜像仓库地址:地址的格式一般是
<域名/IP>[:端口号]
。默认地址是 Docker Hub(docker.io)。 - 仓库名:如之前所说,这里的仓库名是两段式名称,即
<用户名>/<软件名>
。对于 Docker Hub,如果不给出用户名,则默认为library
,也就是官方镜像。
比如:
1 | docker pull ubuntu:18.04 |
从Docker Hub拉取镜像
1 | docker search centos # 搜索centos相关的镜像 |
3.2 运行指定镜像 run
1 | docker run -it --rm ubuntu:18.04 bash |
参数说明:
-it
:这是两个参数,一个是 -i
:交互式操作,一个是 -t
终端。我们这里打算进入 bash
执行一些命令并查看返回结果,因此我们需要交互式终端。
--rm
:这个参数是说容器退出后随之将其删除。默认情况下,为了排障需求,退出的容器并不会立即删除,除非手动 docker rm
。我们这里只是随便执行个命令,看看结果,不需要排障和保留结果,因此使用 --rm
可以避免浪费空间。
ubuntu:18.04
:这是指用 ubuntu:18.04
镜像为基础来启动容器。
bash
:放在镜像名后的是 命令,这里我们希望有个交互式 Shell,因此用的是 bash
。
启动容器并运行nginx
1 | docker run --name webserver -d -p 80:80 nginx |
启动定制的镜像
1 | docker run --name mywebserver -d -p 81:80 nginx:v2 |
3.3 查看本地镜像列表 images
1 | docker image ls [CONTAINER_NAME] |
列表包含了 仓库名
、标签
、镜像 ID
、创建时间
以及 所占用的空间
。
其中镜像ID是镜像的唯一标识,而一个镜像可以对应多个标签,其中你可能发现存在
![image-20201021195826724](/Users/junmingguo/Library/Application Support/typora-user-images/image-20201021195826724.png)
查看虚悬镜像
1 | docker image ls -f dangling=true |
删除虚悬镜像
1 | docker image prune |
查看镜像、容器、数据卷所占用的空间
1 | docker system df |
3.4 删除本地镜像 rmi
1 | docker image rm IMAGE_ID |
若镜像所在的容器正在运行,会出现删除镜像失败的情况。
批量删除镜像 -> 包含none文字的所有镜像
1 | docker rmi $(docker images | grep "none" | awk '{print $3}') |
3.5 保存容器成镜像 commit
1 | docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]] |
3.6 创建镜像 build
使用Dockerfile创建镜像,其中Dockerfile示例:
1 | FROM python:3.7 |
将Dockerfile打包成tar
1 | docker build . -f Dockerfile -t IMAGE_NAME --network host |
3.7 推送镜像至指定位置 push
1 | docker push URL+路径:tag |
3.8 镜像重命名 tag
1 | docker tag IMAGE_ID IMAGE_NAME |
3.9 保存镜像 save
1 | # 将镜像导出为tar文件 |
3.13 载入镜像 load
1 | # 导入自定义镜像 |
—————————
4. 数据卷
数据卷是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性:
- 数据卷可以在容器之间共享和重用
- 对数据卷的修改会立马生效
- 对数据卷的更新,不会影响镜像
- 卷会一直存在,直到没有容器使用
*数据卷的使用,类似于 Linux 下对目录或文件进行 mount。
4.1 创建数据卷
在用 docker run
命令的时候,使用 -v
标记来创建一个数据卷并挂载到容器里。在一次 run 中多次使用可以挂载多个数据卷。
下面创建一个 web 容器,并加载一个数据卷到容器的 /webapp
目录。
1 | docker run -d -P --name web -v /webapp training/webapp python app.py |
4.2 挂载一个本地主机文件作为数据卷
-v
标记也可以从主机挂载单个文件到容器中
1 | $ sudo docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash |
4.3 数据卷容器
如果你有一些持续更新的数据需要在容器之间共享,最好创建数据卷容器。
数据卷容器,其实就是一个正常的容器,专门用来提供数据卷供其它容器挂载的。
创建一个命名的数据卷容器 dbdata:
1 | docker run -d -v /dbdata --name dbdata training/postgres echo Data-only container for postgres |
其他容器中使用 --volumes-from
来挂载 dbdata 容器中的数据卷。
1 | docker run -d --volumes-from dbdata --name db1 training/postgres |
可以使用多个 --volumes-from
参数来从多个容器挂载多个数据卷
注意:使用 --volumes-from
参数所挂载数据卷的容器自己并不需要保持在运行状态。
4.4 利用数据卷容器来备份、恢复、迁移数据卷
备份
首先使用 --volumes-from
标记来创建一个加载 dbdata 容器卷的容器,并从本地主机挂载当前到容器的 /backup 目录。命令如下:
1 | docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata |
容器启动后,使用了 tar
命令来将 dbdata 卷备份为本地的 /backup/backup.tar
。
恢复
如果要恢复数据到一个容器,首先创建一个带有数据卷的容器 dbdata2。
1 | docker run -v /dbdata --name dbdata2 ubuntu /bin/bash |
然后创建另一个容器,挂载 dbdata2 的容器,并使用 untar
解压备份文件到挂载的容器卷中。
1 | docker run --volumes-from dbdata2 -v $(pwd):/backup busybox tar xvf |
—————————
5.网络
5.1外部访问容器
容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P
或 -p
参数来指定端口映射。
当使用 -P 标记时,Docker 会随机映射一个 49000~49900
的端口到内部容器开放的网络端口。
使用 docker ps
可以看到,本地主机的 49155 被映射到了容器的 5000 端口。此时访问本机的 49155 端口即可访问容器内 web 应用提供的界面。
eg.
1 | docker run -d -P training/webapp python app.py |
-p(小写的)则可以指定要映射的端口,并且,在一个指定端口上只可以绑定一个容器。支持的格式有```
1 | ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort |
5.2 映射所有接口地址
使用 hostPort:containerPort
格式本地的 5000 端口映射到容器的 5000 端口,可以执行
1 | $ sudo docker run -d -p 5000:5000 training/webapp python app.py |
此时默认会绑定本地所有接口上的所有地址。
5.3 映射到指定地址的指定端口
可以使用 ip:hostPort:containerPort
格式指定映射使用一个特定地址,比如 localhost 地址 127.0.0.1
1 | $ sudo docker run -d -p 127.0.0.1:5000:5000 training/webapp python app.py |
5.4 映射到指定地址的任意端口
使用 ip::containerPort
绑定 localhost 的任意端口到容器的 5000 端口,本地主机会自动分配一个端口。
1 | $ sudo docker run -d -p 127.0.0.1::5000 training/webapp python app.py |
还可以使用 udp 标记来指定 udp 端口
1 | $ sudo docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py |
5.5 查看映射端口配置
使用 docker port
来查看当前映射的端口配置,也可以查看到绑定的地址
1 | $ docker port nostalgic_morse 5000 |
注意:
- 容器有自己的内部网络和 ip 地址(使用
docker inspect
可以获取所有的变量,Docker 还可以有一个可变的网络配置。) - -p 标记可以多次使用来绑定多个端口
例如
1 | $ sudo docker run -d -p 5000:5000 -p 3000:80 training/webapp python app.py |
5.6 容器互联
容器的连接(linking)系统是除了端口映射外,另一种跟容器中应用交互的方式。
该系统会在源和接收容器之间创建一个隧道,接收容器可以看到源容器指定的信息。
🔗链接:http://www.dockerinfo.net/%e4%bd%bf%e7%94%a8%e7%bd%91%e7%bb%9c