一、背景
最近,Docker技术真是一片火热,它的出现也弥补了虚拟机资源消耗过高的问题,直接让虚拟化技术有了质的飞跃。那么本文我们来聊一聊Docker,和大家一起认识Docker,简单入门Docker.
二、虚拟化技术简介和发展
1. 阶段一:无虚拟化技术
众所周知,在虚拟化技术出现之前,我们依靠扩展物理机的方式来扩展我们的应用,这个阶段很痛苦,也有很多的缺点,比如:
Capex费用昂贵
Go to Product速度极其慢
系统可移植行极低
资源利用率极低
2. 阶段二:基于Hypervisor的虚拟化技术
这个阶段,出现的虚拟化技术让很多人开心不已,随着时间的流逝,市面上也出现不少相关的实际应用的技术,如:VMware、KVM、AWS、Microsoft的Hyper-V等。
基于Hypervisor的虚拟化技术的优点:
资源利用率高
易于扩展、伸缩
Go to Product快速
成本降低
基于Hypervisor的虚拟化技术的缺点:
OS内核资源被重复消耗资源
应用移植性较低
3. 阶段三:基于容器的虚拟化技术
由于Hypervisor的虚拟化技术不是很完美,对内核的资源重复消耗,那随着技术的发展就出现了基于容器的虚拟化技术,最热的就是Docker Container了。它底层使用CGroup和Namespace来实现多个容器之间共享内核资源。而且它还能保证运行时相互隔离,互不影响。
基于容器虚拟化技术的优点:
资源利用率更高
非常高效
更易于扩展、伸缩
Go to Product更快速
一致性
可封装性
应用隔离性
运行时隔离,最典型的应用就是使得我们可以很方便和简单的实现在同一台机器上运行基于不同版本Java开发的应用。如下图:
基于Hypervisor的虚拟化技术 VS 基于容器的虚拟化技术
容器提供OS层的虚拟化(OS Virtualization)
容器可以避免Machine Virtualiztion启动的开销
容器主要给应用提供虚拟化的运行环境
容器只提供给应用所需的可执行文件和依赖库
虚拟机主要给操作系统提供运行环境
三、Docker架构
-
Docker daemon
处理Docker API 请求
管理Docker对象:如镜像、容器、网络等。
-
Docker client
Docker client使用Docker API 跟 Docker daemon进行通信交互
可以跟多个不同的Docker Daemon进行通信
-
Docker Registries
存储Docker镜像
公有和私有Docker Registry
-
Docker对象
镜像
容器
四、Docker术语
-
镜像
镜像是用来创建容器的只读模板
镜像是通过Docker build命令创建的
镜像由镜像层构成
镜像存储于Docker Registry
-
容器
容器是镜像的运行实例
容器是应用运行环境的封装,具有轻量级、移植性高等特点
容器由镜像创建,内部封装所有运行应用所需依赖及可执行文件
-
Registries和Repositories
Registry是存储Docker镜像的地方(可类比为Maven仓库)
可自建私有Registry和使用公用Registry,如:Docker Hub
在Registry中,镜像存储在Repository
Docker Repository是具有相同名字,不同标签的Docker镜像的集合(可类比为Maven仓库中的某个依赖所在的文件夹,可以有不同版本)
-
Docker Hub
公有:Docker Registry
私有:Docker Registry
-
官方Docker镜像
文档清晰、完整
安全,更新及时
安全性更高
五、Docker的安装
-
环境准备
Centos 7
-
Docker社区版安装步骤
-
删除已安装所有老版本docker相关(docker或者docker-engine)
yum remove -y docker docker-common docker-selinux docker-engine
-
安装devicemapper驱动和yum工具
yum install -y yum-utils device-mapper-persistent-data lvm2
-
配置repo
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
-
安装docker社区版
yum install -y docker-ce
-
启动docker
systemctl start docker
-
注:如果在没有启动docker的情况下运行[docker info]命令,则会出现:Cannot connect to the Docker daemon. Is the docker daemon running on this host? 错误。
-
Centos官方版安装步骤
yum install -y docker
-
验证安装
docker version
docker info
六、Docker常用命令
docker version 查看docker版本信息
docker info 查看docker基本信息
docker images 查看所有本地镜像
-
docker ps [-a] 查看所有正在运行的容器
-a查看所有的容器
docker search repository:tag 在远程仓库搜索指定镜像
docker pull repository:tag 从远程仓库下载指定镜像
-
docker run [-t -i -d --name containerName -p port] repository:tag cmd命令 基于一个镜像运行一个容器
-t 绑定终端
-i 交互模式
-d 后台运行
--name 指定容器的名称
-p 指定容器暴露的端口,如:8080:8080
-P 和-p互斥,当使用 -P 标记时,Docker 会随机映射一个
49000~49900
的端口到内部容器开放的网络端口
docker start containerId 启动一个已经停止的容器
docker stop containerId 停掉一个正在运行的容器
-
docker rm [-f] containerId/containerName 删除指定容器
-f 强制删除,不论容器是否正在运行
docker rmi imageId/imageName 删除指定镜像
-
docker commit [-a author] containerId repository:tag
-a author 指定作者
docker logs [-f] containerId 查看容器日志
docker history imageId/repository:tag 查看镜像的各层信息
docker inspect containerId/containerName 查看容器更底层的信息
docker save -o fileName imageId/repository:tag 将指定的镜像打包保存
docker import fileName repository:tag 使用指定文件创建镜像
docker exec [-t -i] containerId/containerName CMD 利用指定容器执行指定的cmd命令
-
docker build -t repository:tag . [--no-cache=true] 使用当前目录下的Dockerfile文件构建镜像
“.” 代表使用当前目录下Dockerfile
--no-cache=true 不使用缓存,默认是缓存
docker login 登陆到远程仓库
docker push repository[:tag] 提交镜像到远程仓库
- docker rm -f $(docker ps -qa -f status=exited) 删除所有已经停掉的容器
前台运行 VS 后台运行
-
前台运行Docker容器
默认方式
docker run 运行容器中的应用并将console和应用进程中的标准输入、输出及错误关联起来
容器启动后不能在console中执行其他命令
-
后台运行Docker容器
需要指定 -d 选项
docker run 将容器在后台启动,通常容器中的主程序退出后容器随之退出
容器启动后可以在console中继续执行其他命令
七、Docker端口映射和日志
最典型的案例是:当我们运行tomcat镜像的时候,我们需要为该容器指定向外暴露的端口以及查看容器运行时tomcat的日志信息。
-
端口暴露
运行时指定 -p或者-P选项,-p允许我们指定端口信息,-P是docker默认随机映射一个
49000~49900
的端口到内部容器开放的网络端口
-
查看日志
docker logs containerId 查看容器输出的日志信息
也可以后台运行容器,然后使用docker exec -ti containerId bash 命令进到logs目录下查看catlina.log日志信息
八、Docker 镜像
Docker镜像是容器的基础
Docker镜像是由有序文件系统层以及容器运行时所需参数组成
Docker镜像是无状态的
Docker镜像是不可更改的
运行中的容器,所有的变化被写入可写层
一旦容器被删除,可写入层随之删除,但base镜像依旧存在
多个容器共享相同的base镜像层
九、创建Docker镜像
通过docker commit命令来基于容器创建Docker镜像
通过docker build 命令配合Dockerfile文件创建Docker镜像
下面是一个简单的Dockerfile文件
FROM centos:7
LABEL maintainer "hafiz.zhang(hafiz.zhang@example.com)"
RUN yum update -y
RUN yum install -y git
Dockerfile是一个包含用户创建Docker镜像的所有命令的文本文件
Dockerfile中的命令指定在创建Docker镜像时做什么操作
Docker读取Dockerfile中的命令来创建Docker镜像
Dockerfile中的每个命令都将被Docker使用来创建一个新的Docker镜像层
Docker build 上下文
Docker客户端以当前目录为build上下文
默认读取当前目录的Dockerfile进行build
Docker客户端开始build后会将build上下文目录的文件打包成tar包并上传给Docker Daemon守护进程
十、深入Dockerfile
-
RUN指令
RUN指令在容器的可写入层执行命令,并commit容器为新的镜像
上一步RUN命令生成的镜像会被接下来的RUN指令使用,每次RUN指令生成一个新的镜像
Dockerfile中最好使用链式输入命令以减少创建镜像层的数量
-
CMD指令
CMD指令指定容器启动时执行什么命令
如果在Dockerfile中不指定CMD指令,Docker将使用基础镜像提供的默认命令
CMD指令在创建Docker镜像时不执行,只有在容器启动时才执行
-
既可以以exec形式也可以以shell形式指定要执行的命令
CMD 指令指定命令使用JSON格式,只能使用双引号,不能使用单引号
CMD ["echo", "HelloWorld"] 使用exec形式,不能获取到$HOME等环境变量信息
CMD ["sh", "-c", "echo $HOME"] 使用shell脚本形式,能获取到HOME等环境变量信息
build镜像的时候不会运行CMD指令指定的命令,只要在使用镜像启动容器时才运行CMD指令指定的命令
-
COPY指令
COPY指令从build上下文复制文件或者文件夹到容器文件系统
-
ADD指令
ADD指令不但可以复制文件到容器文件系统,而且还可以从internet上下载文件并复制到容器
ADD指令可以自动解压压缩文件
通常我们使用COPY指令,除非明确需要ADD指令
-
Docker缓存
每次Docker执行一个指令将创建新的镜像
如果下一次指令没有发生变化,Docker默认使用现有的缓存
可以通过指定 --no-cache=true 来指定不使用缓存
也可以使用链式命令来避免使用缓存
十一、上传Docker镜像到Docker Hub
首先注册Docker Hub账号
docker tag 给镜像打标签
Repository格式:ID/镜像名字
Latest标签
默认Docker使用latest作为标签
通常Repository用latest表示竟像是最新稳定版,但这只是默认传统,不是强制要求
当新版本镜像上传到Repository,latest标签的镜像不会自动更新
尽量避免使用latest标签