Docker介绍与使用
# 服务部署方式的发展
# 物理机部署方式
一台高配置的服务器,比如32核64G,如果只部署一个应用,那就太浪费,所以一般会部署多个应用进程在服务器上。
但如果将所有服务部署到一台服务器上,就可能发生资源抢占的问题,应用程序之间对资源进行抢占,包括但不限于CPU、内存、磁盘资源等。而如果其中一个程序突发异常,抢占资源异常高,那么就会导致其他的所有进程就都无法正常运行,于是就有了虚拟机技术,它实现了进程间硬件资源隔离。
# 虚拟机部署方式
虚拟机可以通过硬件虚拟化,事先从物理机分配好CPU核数、内存、磁盘。一台物理机会部署多台虚拟机,物理机里的所有虚拟机则依靠虚拟机管理系统进行管理。同时每台虚拟机一般只部署一个应用,从而解决了进程间资源隔离的问题。
而虚拟机的问题则是版本和配置碎片化问题,在大集群部署情况下,软件的版本和配置文件容易碎片化,大应用集群的虚拟机第一次安装时,由于操作系统镜像是一样的,所以刚开始,软件的版本和库依赖是统一的。
但随着时间的推移,开源的软件需要升级,于是就需要开始批量升级集群的软件版本,但批量升级有可能会有遗漏或升级失败。所以就需要登录服务器进行手动升级,同时有些开发也会登陆机器修改软件的版本或者配置,以满足自己的需求。长此以往,一个应用的集群的软件版本和配置就会逐渐碎片化。
当线上出现问题,需要排查到基础软件层面时,由于软件版本碎片化的问题,导致排查变得很棘手,为了解决虚拟机部署的痛点,容器技术应运而生。
# 容器部署方式
容器字面上讲就是可以容纳其他物品的工具,可以部分或完全封闭,可用于容纳、存储、运输、保护内容物。它比起虚拟机,更方便移植、更节省空间、同时也做到了资源隔离。
容器技术的核心之一在于镜像文件,镜像文件通俗的理解就是程序文件加依赖文件的集装箱。容器如果要升级软件版本,那么只需要修改镜像文件,然后更新部署时集群内所有的机器重新拉取新的镜像,容器重新跑起来时,运行的就是新的版本了,软件版本混乱的问题,到容器技术这里也就得到了解决。
容器启动时,由于它使用的实际是宿主机的内核资源,因此容器对硬件资源的使用几乎没有损耗,但这也造成了容器对硬件资源的隔离能力不如虚拟机。
# Docker架构
Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。
Docker客户端
:通过命令行或者其他工具使用Docker SDK与Docker的守护进程通信Docker服务器
:用于执行Docker守护进程和容器的物理机或者虚拟机
他有三个基本概念:
# 镜像(Image)
- 镜像相当于创建容器的模板,它是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。
- Docker镜像是分层存储的,我们可以在基础镜像之上额外的添加东西,然后再将其构建成一个新的镜像,该特性提高了镜像的复用性和可定制性。另外分层特性也是我们在拉取镜像时,为什么还会拉取一些其他镜像的原因。
- Docker镜像非常的轻量级,因为即便是不同版本的Linux,其内核都是基本相同的,因此不需要安装操作系统内核,只需要在引入相应操作系统的镜像即可。
# 容器(Container)
- 容器是镜像的实例,容器基于镜像启动时,Docker会在镜像的上层创建一个可写层,在在容器中操作文件时,镜像本身是不变的,因此每一次启动容器,都会有一个基于镜像的干净环境。
- 容器的启动非常快,这是因为容器直接运行于宿主内核,启动Docker相当于启动宿主操作系统上的一个进程,无需启动完整的操作系统。同时容器也可以被创建、启动、停止、删除、暂停等。
# 仓库(Repository)
- 仓库可看成一个镜像中心,提供了庞大的镜像集合供使用。每个仓库可以包含多个标签(Tag),每个标签对应一个镜像。一般一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。
- 如果需要搭建私有仓库,可以使用官方提供给我们的registry镜像,一个镜像仓库一般包含镜像文件、权限验证、镜像索引。
# Docker安装部署
# 下载yum源
curl -o /etc/yum.repos.d/docker-ce.repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
# 安装依赖包
yum install -y yum-utils device-mapper-persistent-data lvm2
# 安装Docker
yum install -y docker-ce
# 启动docker
systemctl start docker && systemctl enable docker
2
3
4
5
6
7
8
9
10
11
12
# Docker命令
# 镜像管理
# 搜索镜像
docker search [镜像名]
# 拉取镜像
docker pull [镜像名]:[标签]
- 使用 [镜像名]:[标签] 来指定哪个镜像的哪个版本,没有标签则以latest作为默认标签。
# 查看镜像
docker images
# 删除镜像
docker rmi [镜像名/镜像ID]
- 需要先删除基于该镜像所生成的容器。
# 导出镜像
docker save [容器名/容器ID] -o [导出路径].tar
# 导入镜像
docker load -i [镜像路径]
# 镜像改名
docker image tag [原镜像名/镜像ID] [目标镜像名]
- 镜像名需要为[镜像名]:[标签]。
# 查看镜像详细信息
docker inspect [镜像名/镜像ID]
# 构建镜像
docker build [参数]
- 参数:
-m
设置内存最大值-f
指定要使用的Dockerfile路径,不指定是在当前目录下找-q
安静模式,成功后只输出镜像ID-t
指定镜像的名字及标签,格式为name:tag或者name--cpu-shares
设置CPU使用权重--squash
将Dockerfile中所有的操作压缩为一层,默认一行命令是一层--rm
构建后删除中间容器--force-rm
设置镜像过程中删除中间容器
- 例如:
docker build -t nginx:1.0 --force-rm .
# 容器管理
# 创建容器
docker run [参数] [镜像名/镜像ID] [启动命令<可选>]
- 参数:
-i
以交互模式运行容器,一般-it
这样使用-t
为容器重新分配一个伪输入终端,一般-it
这样使用-d
后台运行容器,并返回容器ID,通常单独使用-–name="[容器名]"
为容器指定一个名称-h "mars"
指定容器的主机名-m 512M
设置容器可用内存最大值--cpus=[CPU数]
限制容器可用CPU数--dns="8.8.8.8"
指定容器使用的DNS服务器,默认是和宿主一致--rm
交互式容器退出后自动删除容器-p [主机端口]:[容器端口]
指定端口进行主机与容器的端口映射-P [容器端口]
容器端口随机映射到主机的高端口(32768-60999)--net="bridge"
指定容器的网络连接类型(bridge/host/none/container)- bridge(默认) - 相当于虚拟机的NAT模式,容器访问公网时,将容器IP转换为宿主机IP再去访问公网主机,相当于把宿主机作为路由器
- none - 无网络模式,无网卡,容器无法通过网络访问公网和宿主机
- host - 共用宿主机网络,不隔离网络资源,隔离性差,可能会端口冲突等,容器的 主机名、端口和IP地址和宿主机的相同
- container - 共用其他容器网络,多个容器使用 1 个网卡、主机名、端口和IP地址,谁先用算谁的,可用于实现高可用
-v [本机目录]:[映射到容器中目录]
指定数据卷,实现持久化存储- 实现宿主机和容器的数据共享,将宿主机目录映射到容器中,映射到的容器目录如果不存在,会自动创建。如果没有指定数据卷,删除容器后数据就不存在了。
- 查看容器的数据卷位置:
docker inspect -f '{ {.Mounts} }' [容器名]
--volumes-from=[数据卷容器名]
引用数据卷容器挂载的数据卷- 在集中管理集群中,大批量的容器都需要挂载相同的多个数据卷时,可以采用数据卷容器进行统一管理。
- 先创建一个挂了数据卷的容器,然后下次需要创建挂载这些数据卷的容器时,就可以直接从数据卷容器中引用。创建的数据卷容器会作为一个数据卷通道,所以需要保持后台运行。
启动命令<可选>
如果没有指定启动命令,则是以镜像中默认的命令进行启动
- 例如:
docker run -it --rm -p 80:80 -v /html/:/html -h "docker-nginx-01" --name="nginx-01" nginx:1.0
# 删除容器
docker rm [容器名/容器ID]
# 查看容器
docker ps -a
查看所以容器--no-trunc
显示省略的信息
- 字段信息
- COMMAND:容器的启动命令
- STATUS:容器的运行状态 (Exited,Up)
# 导出容器快照
docker export [容器名/容器ID] > [文件路径]
# 导入容器快照
cat [容器文件] | docker import [容器名]
# 进入容器
docker attach [容器名/容器ID]
- 会进入到容器运行启动命令的终端中。
# 退出容器
exit
命令。
# 容器执行命令
docker exec [参数] [容器名/容器ID] [命令]
- 新启动一个终端执行命令,也可用于进入容器
docker exec -it [容器名/容器ID] /bin/bash
# 将容器转化为镜像
docker commit [参数] [容器名/容器ID] [镜像名]
- 参数:
-m
指定说明信息-a
指定用户信息
# 查看容器的详细信息
docker inspect [容器名/容器ID]
- 参数:
-f '{ {.一级.二级...} }'
指定查看某断信息
# 查看容器运行的进程
docker top [容器名/容器ID]
# 查看容器资源占用
docker stats [容器名]
# 复制主机文件到容器中
docker cp [源文件] [容器名]:[容器中路径]