容器简介
容器是一种基础工具。泛指任何可以用于容纳其它物品的工具,它可以是部分封闭或者完全封闭的,被用于容纳、储存、运输物品,物体可以放置在容器中,而容器则可以保护容物。容器并不是一个新鲜的概念,在历史的长河中人类早已有使用容器。
Docker也是容器的一种,它在2013年3月由dotCloud公司发布的,一开始基于LXC(LinuX Container)项目创建单个应用程序,由于Docker在业界造成的影响力实在太大,dotCloud公司后来也直接改名为Docker Inc,并专注于Docker相关技术和产品的开发。它用来供开发人员和系统管员员使用容器构建,运行和共享应用程序的平台,使用容器来部署应用程序称为容器化。容器也不是什么新事物,但用于轻松部署应用程序的容器却是新事物。在计算机系统中可以把容器理解成在隔离的环境下运行的一个进程,这个进程停止那么容器也就会被销毁。
Docker与虚拟化
虚拟化(Virtualization)技术是一个通用的概念,在不同的领域有不同的理解。而在计算机领域,一般指的是计算机虚拟化,或服务器虚拟化。虚拟化是对计算机的各种实体资源予以抽象、转换后呈现出来,它打破了实体结构间不可切割的障碍,使用户可以比原本的组态以更好的方式来应用这些资源。虚拟化的核心是对资源的抽象,它的目标往往是为了同一个主机上同时运行多个系统或应用,从而提高了系统资源的利用率,降低了成本和方便管理等好处。
Docker容器与虚拟机的比较
Docker容器作为一种轻量级的虚拟化方式,它在运行应用程序上与传统的虚拟机方式相比具有显著优势:
- Docker容器很快,启动和停止可以在秒级实现,而传统的虚拟机方式需要数分钟。
- Docker容器对系统的资源要求更少,在一台主机上同时运行的容器比传统的虚拟化方式运行的虚拟机更多。
- Docker通过类似Git设计理念的操作来方便用户获取、发布和更新应用镜像,可以存储复用、增量更新。
- Docker通过Dockerfile支持灵活的自动化创建和部署机制,提高了工作效率,使得流程标准化。
命名空间(NAMESPACE)和控制组(CGROUP)
控制组
代表单个资源,例如CPU时间或内存。linux内核提供了一系列的资源控制组,这些资源控制组由systemd自动安装。在centos7中systemd默认挂载了以下控制组:
控制组 | 描述 |
---|---|
blkio | 块设备IO |
CPU | CPU |
cpuacct | CPU资源使用报告 |
cpuset | 多处理平台上的CPU集合 |
device | 设备访问 |
freezer | 挂起或恢复任务 |
memory | 内存使用量报告 |
pref_event | 对cgroup中的任务进行统一性能测试 |
net_cls | cgroup中的任务创建的数据报文的类别标识符 |
命名空间
是linux中的一种内核功能,它提供对隔离的系统资源进行虚拟查看。通过将进程与系统资源隔离使得用户可以指定控制进程能够与之交互的对象。命名空间是控制组中的重要组成部分。linux中支持一下命名空间:
命名空间 | 描述 |
---|---|
Mount namespace | 挂载点 |
UTS namespace | 主机与域名 |
IPC namespace | 信号量、消息队列和共享内存 |
PID namespace | 进程号 |
Network namespace | 网络设备、网络栈、端口等 |
User namespace | 用户和组 |
Docker三大核心概念
- 镜像image
Docker镜像采用分层构建机制,最底层为bootfs,而bootfs之上为rootfs。
bootfs
:用于系统引导的文件系统,包括BootLoader和kernel,在容器启动完成后会被卸载以节省内存资源;
rootfs
:位于bootfs之上,表现为docker容器的根文件系统。在传统模式中,系统启动时,内核挂载rootfs是首先将其挂载为只读模式,经过完整性自检完成后将其重新挂载为读写模式;在docker中,rootfs由内核挂载为只读模式,而后通过联合挂载技术额外挂载一个可写层;
在docker镜像中,下层的称为父镜像为可写层,可写层之下的均为只读层,包括最底层,最底层称为为基础镜像
docker镜像又类似于虚拟机镜像,可以将它理解为一个只读的模板。比如:一个镜像可以包含一个基本的操作系统环境,里面只安装了Nginx应用程序(或用户需要的其它软件),可以把它称为一个Nginx镜像。
镜像是创建Docker容器的基础。通过版本管理和增量的文件系统,Docker提供了一套十分简单的机制来创建和更新现有的镜像,用户甚至可以网上下载一个已经做好的应用镜像并直接使用。
-
容器container
Docker容器类似于一个沙箱,Docker利用容器来运行和隔离应用(namespace)。容器是从镜像创建的应用运行实例。可将其启动、开始、停止、删除,这些容器都是彼此相互隔离的、互不可见的。镜像自身是只读的,容器从镜像启动的时候会在镜像的最上层创建一个可写层。 -
仓库registry
Docker仓库类似于代码仓库,它是Docker集中存放镜像的文件场所,包括镜像的层次架构和元数据。根据所存储的镜像公开分享与否,Docker仓库可以分为公开仓库(Public)和私有仓库(Private)两种形式。
安装及使用Docker
[root@localhost ~]# yum install -y docker-ce
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl restart docker
镜像基础管理
搜索镜像:
[root@localhost ~]# docker search nginx
获取镜像:
[root@localhost ~]# docker pull nginx[:TAG]
TAG是镜像的标签,如果不指定标签默认会选择latest标签,也就是最新版本的镜像
查看本地的镜像列表
[root@localhost ~]# docker image ls
在列出的信息中可以看到一下几个字段信息:
image子命令支持的选项:
-a,--all=true|false:列出所有的镜像文件,包括临时文件,默认为false
--digests=true|false:列出镜像的数字摘要值,默认为false
-f,--filter=[]:·-f,--filter=[]:过滤列出的镜像,如dangling=true只显示没有被使用的镜像;也可指定带有特定标注的镜像等
--no-trunc=true|false:对输出结果中太长的部分是否进行截断,如镜像的ID信息
-q,--quiet=true|false:仅输出ID信息,默认为false
使用inspect子命令查看详细信息
[root@localhost ~]# docker image inspect nginx
使用history子命令查看镜像历史信息
[root@localhost ~]# docker image history nginx:latest
删除镜像:
[root@localhost ~]# docker rmi nginx:latest //删除单个镜像
[root@localhost ~]#docker image rm -f `docker image ls -q` //强制删除所有镜像
当同一个镜像拥有多个标签的时候,docker rmi命令只是删除该镜像多个标签中的指定标签而已,并不影响镜像文件。
镜像详细信息查看
[root@localhost ~]# docker image inspect nginx:latest
[root@localhost ~]# docker image ls -q //只查看镜像ID
镜像的导入和导出
[root@localhost ~]# docker image save 容器ID >/opt/ngx.tar //导出镜像
[root@localhost ~]# docker load -i /opt/ngx.tar //导入镜像
手动制作镜像:
先安装一个centos的镜像,在镜像里面安装ssh服务并启动:
退出容器开始制作镜像:
运行镜像:
运行镜像之后查看发现容器并没有运行,原因是容器内的第一个进程(初始命令)必须一直处于前台运行的状态,否则这个容器就处于退出状态。
容器基础管理
运行镜像成为新容器:
[root@localhost ~]# docker container run -d [-it] --name="ngx1" nginx:1.16 [bash]
-it:分配交互式的终端
-d:像nginx这种web服务一般使用该选项做后台运行
–name:指定容器的名字
bash:覆盖容器的初始命令
容器网络访问
想除宿主机以外的机器访问容器就需要做端口映射
[root@localhost ~]# docker container run -d -p 80:80 --name="ngx2" nginx:1.16
指定映射(docker 会自动添加一条iptables规则来实现端口映射):
-p:hostPort:containerPort
-p:ip:hostPort:containerPort(多个容器共用一个端口)
-p:ip::hostPort:containerPort(随机端口32768~60999)
-p:hostPort:containerPort:UDP
-p: hostPort:containerPort -p....(可以指定多个-p选项)
-P:将容器的所有计划要暴露端口全部映射至主机端口
随机映射:
docker run -P 80 (随机端口)
容器的启动和关闭
[root@localhost ~]# docker container stop NAME
[root@localhost ~]# docker container start NAME
进入容器
[root@localhost ~]# docker container attach NAME //返回宿主机后容器就exit状态
[root@localhost ~]# docker container exec -it NAME /bin/bash //返回宿主机还是up状态,强烈推荐使用
查看nginx的日志
[root@localhost ~]# docker logs -f ngx1
[root@localhost ~]# docker logs -tf ngx1
容器的数据卷:
[root@localhost ~]# docker run -d --name="nginx_3" -p 83:80 -v /opt/html:/usr/share/nginx/html nginx //目录不存在会自动创建
[root@localhost ~]# docker run -it --name "httpd_volumes" -v /opt/Volume/a:/opt/a -v /opt/Volume/b:/opt/b centos:6.9 /bin/bash //定义httpd_volumes卷组
[root@localhost ~]# docker run -d -p 8085:80 --volumes-from nginx_volumes --name "http8085" nginx //快速调用卷组,不在需要手动一个个写-v
数据卷是一个可供容器使用的特殊目录,它将主机操作系统目录直接映射进容器,类似Linux系统的mount操作。数据卷有以下特性:
- 数据卷可以在容器之间共享和重复使用,在容器间传输数据变得高效方便;
- 对数据卷内数据的修改会立马生效,无论是容器内操作还是本地操作;
- 对数据卷的更新不会影响镜像,解耦了应用和数据;
- 卷会一直存在,直到没有容器使用可以安全地卸载它;
相关参考:
控制组CGROUP
命名空间NAMESPACE