云计算是什么
云计算的本质是计算资源的虚拟化。
与磁盘逻辑卷的分配类似,云计算是在负载波动时动态调整服务器计算资源,避免资源浪费的做法,生产环境中,厂商一般将服务器组成一个池,实现逻辑管理计算资源,对不同的部署项目动态调整算力,
比如电商在618、双十一需要应对极大的数据量,而平时并不需要这么多的计算资源,所以只需要在个别情景下增加计算资源即可。
docker是什么
docker是云计算的实现形式之一,该程序2013年开源,基于go语言实现。
核心组成是:镜像、容器和仓库。
镜像和容器对应程序和进程,仓库则是镜像的集合。
核心技术是Namespace
命名空间隔离、Control Group
控制组资源限制、Union Filesystem
联合文件系统。
docker核心技术
核心技术都在Linux内核层实现:
Namespace
对全局系统资源的一种封装隔离,用于解决多个容器命名等可能产生冲突的问题,每个命名空间内的资源彼此独立互不干扰。
该技术本质是Linux中chroot
的派生版,早先的chroot
用于限制文件访问本身以外的内容。
Namespace
的具体空间划分如下:
隔离类型 | 功能 | 系统调用参数 | 说明 |
---|---|---|---|
MNT Namespace(mount) | 提供磁盘挂载点和文件系统的隔离能力 | CLONE_NEWNS | 保证容器使用空间独立 |
IPC Namespace(Inter-Process Communication) | 提供进程间通信的隔离能力 | CLONE_NEWIPC | 允许容器内进程通信,阻止容器间进程通信 |
UTS Namespace(UNIX Timesharing System) | 提供主机名隔离能力 | CLONE_NEWUTS | 通过主机名和域名隔离 |
PID Namespace(Process Identification) | 提供进程隔离能力 | CLONE_NEWPID | 管理容器内进程 |
Net Namespace(network) | 提供网络隔离能力 | CLONE_NEWNET | 不同容器网络独立,有自己的网卡docker0 |
User Namespace(user) | 提供用户隔离能力 | CLONE_NEWUSER | 允许不同容器用户名相同,实现用户隔离 |
Control Group
资源控制是为了防止容器无限申请资源的情况发生,通过将进程按组管理的形式实现,作为使用者了解到这应该就行了,更多信息可以看看其他文章。
Union Filesystem
联合文件系统用于将多个物理位置不同的文件挂载到同一个目录,从而达到从逻辑上看是一个整体文件系统的效果。
该技术可以使得制作镜像更为方便,新的镜像可以从基础镜像开始,构造新的功能作为新的层添加到文件联合系统中,大大提高了存储效率和开发效率,共享时也只需要传输新加的层,而无需更新整个镜像,同时将文件系统分层便于维护和回滚,不同的文件层相当于快照可以随时恢复。
云计算和虚拟机的区别
如果说逻辑管理计算资源,我们用虚拟机也能实现,docker云计算的实现手段高明在哪呢?
首先虚拟机的确可以实现计算资源的管理,并且还很方便,但因为其原理,虚拟机是真实操作系统之上又建立起的虚拟操作系统,指令从硬件到程序需要穿透两层操作系统,其中还有复杂的Hypervisor
虚拟机监视器,性能损失很大,并且再小的程序也需要完整的操作系统,造成很大的存储资源浪费,docker正是弥补了这些不足才得以广泛应用。
但虚拟机也有docker不具备的有点,因为虚拟机允许独立的操作系统,所以其隔离性高于docker,安全性更高。
从应用来说都是二者都是虚拟化计算资源,但虚拟机是虚拟完整的运行环境,docker只虚拟容器所需的资源,二者的结构区别见下图:
虚拟化实现的是物理资源的隔离,docker实现的是应用层面的隔离。
docker快速开始
安装docker
yum install wget # 安装网络下载工具,通过HTTP、HTTPS、FTP三个最常见的TCP/IP协议下载,并可以使用HTTP代理
# yum则是红帽系列Linux的系统安装方式
rm -rf /etc/yum.repos.d/* # 清除原有源文件
wget -O /etc/yum.repos.d/Centos-7.repo http://mirrors.aliyun.com/repo/Centos-7.repo
wget -O /etc/yum.repos.d/epel-7.repo http://mirrors.aliyun.com/repo/epel-7.repo
wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 将各种源切换为阿里云
yum install -y docker-ce # 安装新版的docker-ce
systemctl start docker # 启动docker服务
切换仓库
此时我们如果要直接拉取镜像会出现如下场景:
因为网络等原因,我们有时无法连接到dockers仓库,所以需要手动配置镜像,先前我们更改的源只是保证我们能正确获取到docker软件,切换仓库的方法如下:
vim /etc/docker/daemon.json
创建或修改docker的配置文件,添加如下内容:
{
"registry-mirrors" : ["https://docker.mirrors.ustc.edu.cn" ] # 中国科技大学
}
切换完成后重启容器服务systemctl daemon-reload
和systemctl restart docker
,此时再通过docker pull nginx
命令就可以拉取到nginx
镜像,通过docker images
可以查看已有镜像,如下图:
再使用docker run -d -p 80:80 nginx
运行服务,出现下图说明运行成功
RUN的一些参数
-d, --detach: 以守护进程方式运行容器
-p, --publish: 映射容器端口到宿主机端口
格式: -p [hostPort]:[containerPort]
-v, --volume: 挂载数据卷
格式: -v [hostPath]:[containerPath]
-e, --env: 设置环境变量
--name: 为容器指定名称
--network: 指定容器所属网络
--restart: 容器退出时的重启策略
可选值: no, on-failure, unless-stopped, always
-i, --interactive: 保持标准输入打开
-t, --tty: 分配一个伪终端
-u, --user: 指定运行容器的用户
--entrypoint: 覆盖容器的默认入口点
--rm: 容器退出后自动删除
--hostname: 设置容器主机名
--add-host: 添加自定义主机名到 IP 的映射
--link: 添加到另一个容器的链接
--expose: 暴露容器端口
--volume-driver: 指定数据卷驱动程序
--cpu-shares: 设置 CPU 权重
--memory: 设置容器内存限制
docker方法
镜像管理
直接展示管理方法:
目的 | 方法 |
---|---|
搜索 | docker search 名称 |
下载 | docker pull 名称:标签(默认为latest) |
删除 | docker rmi ID或名称 |
查看 | docker images |
修改标签 | docker tag 名称:原标签 新名称:新标签 |
显示详细信息 | docker inspect 名称 |
查看历史/各层 | docker history 名称 |
导出 | docker save 名称 -o或> 文件名称 |
导入 | load -i或< 名称 |
容器管理
容器是运行着的镜像,同样直接展示管理方法:
目的 | 方法 |
---|---|
创建容器 | docker create |
启动容器 | docker start |
创建并启动 | docker run |
显示容器 | docker ps -a |
端口映射 | -P随机映射 -p 指定端口:容器目的端口 |
查看映射端口 | docker port |
暂停 | docker pause |
停止 | docker stop |
删除 | docker rm -f 查询结果 |
进入容器内部 | docker exec |
后台启动 | docker run -d |
容器要保证运行状态,必须依赖前台进程
镜像制作
手动方法为:
1,拉取基础操作系统环境
2,装载需要的应用
3,关闭后台运行
4,commit提交容器为镜像
但在企业生产环境中,一般使用专门的镜像制作工具Dockerfile
,该工具本质上类似于一个解释器,将内容解释为Linux命令,工具生成的文件名必须为dockerfile
,新建该文件后即可写入镜像的构建步骤,一些常用指令如下:
FROM 指定基础镜像,用于后续的指令构建。
MAINTAINER 指定Dockerfile的作者/维护者。(已弃用,推荐使用LABEL指令)
LABEL 添加镜像的元数据,使用键值对的形式。
RUN 在构建过程中在镜像中执行命令。
CMD 指定容器创建时的默认命令。(可以被覆盖)
ENTRYPOINT 设置容器创建时的主要命令。(不可被覆盖)
EXPOSE 声明容器运行时监听的特定网络端口。
ENV 在容器内部设置环境变量。
ADD 将文件、目录或远程URL复制到镜像中。
COPY 将文件或目录复制到镜像中。
VOLUME 为容器创建挂载点或声明卷。
WORKDIR 设置后续指令的工作目录。
USER 指定后续指令的用户上下文。
ARG 定义在构建过程中传递给构建器的变量,可使用 "docker build" 命令设置。
ONBUILD 当该镜像被用作另一个构建过程的基础时,添加触发器。
STOPSIGNAL 设置发送给容器以退出的系统调用信号。
HEALTHCHECK 定义周期性检查容器健康状态的命令。
SHELL 覆盖Docker中默认的shell,用于RUN、CMD和ENTRYPOINT指令。
详细步骤可见该文章
数据管理
容器运行过程中数据独立,如果我们部署的容器发生损坏,数据也同样存储在容器内部,如何将容器内部的数据持久化到外部主机呢?这是生产环境中常面临的问题,解决方法之一是数据卷:
即用本机的文件代替容器文件,将宿主机的目录挂载到容器目录上,通过docker run -v 宿主机目录:容器目录
将目录映射到容器内部,该方法可以实现文件的复用,也可以避免容器损坏而影响本地数据,容器程序损坏只需要重新拉取然后挂载即可。
另一个方法是使用数据卷容器,即单独用一个容器作为存储介质,供其他容器交换信息,容器本身的隔离机制并不允许这么做,所以我们需要通过--volume-from 数据卷容器
来告知容器可以从数据卷容器中获取信息,就可以实现容器的通信和数据持久化操作。
网络管理
容器间要进行网络通信,可以通过宿主机同一个端口映射或docker0的网桥来实现,命令可以使用--link 名称或别名
方法实现网络互通。
docker本质也是一个虚拟机,只是其更侧重于应用的虚拟机,所以其网络连接方式也有很多种,分别对应不同的网络策略,说明如下:
网络模式 | 配置方法 | 说明 |
---|---|---|
host模式 | --net=host | 容器和宿主机共享Network namespace |
container模式 | --net=container:NAME或ID | 容器和另外一个容器共享Network namespace。 kubernetes中的pod就是多个容器共享一个Network |
none模式 | --net=none | 容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配veth pair 和网桥连接,配置IP等 |
bridge模式 | --net=bridge | 默认为该模式,容器与虚拟网桥通信,虚拟网桥作为在网络中作为交换机 |
总结
其实学多了,我们大多数也只是拉现成的镜像下来使用,知道pull
和run
基本就算会docker了。