1.虚拟化与容器化
随着互联网及移动互联网的快速发展,云计算技术也开始迅猛发展,云计算技术发展包括俩大方向:虚拟化与容器化。虚拟化技术是传统的云计算技术,容器化是新一代的云计算技术。
一般来说,虚拟机通过模拟硬件环境,并启动完整的操作系统为应用运行提供独占环境,因此其中需要安装Guest OS。与此相反,容器是主机操作系统上的进程虚拟化,容器镜像中并不需要OS内核,因此不需要安装Guest OS,只需要应用运行相关的库和文件就可以了。
2.Linux Container
Linux Container简称LXC,其是一种内核轻量级操作系统层的虚拟化技术。
Linux Container主要由Namespace和Cgroup两个机制保障实现。
(1)Namespace主要实现隔离,安全保护的作用。
(2)Cgroup主要实现资源的管理控制功能,通过写时复制技术(copy-on-write)实现了高效的文件操作。比如进程组使用CPU/MEM的限制,进程组的优先级控制,进程组的挂起和恢复等。
2.1 Namespaces名称空间
Namespace的六项隔离 | ||
namespace | 系统调用参数 | 隔离内容 |
UTS | CLONE_NEWUTS | 主机名与域名 |
IPS | CLONE_NEWIPC | 信号量、消息队列和共享内存 |
PID | CLONE_NEWPID | 进行编号 |
NETWORK | CLONE_NEWNET | 网络设备、网络栈、端口等 |
MOUNT | CLONE_NEWNS | 挂载点(文件系统) |
USER | CLONE_NEWUSER | 用户和用户组(3.8以后的内核才支持) |
2.2 Control Group(Cgroup)控制组
2.2.1 cgroup特点
cgroup的api以一个伪文件系统的实现方式,用户的程序可以通过文件系统实现cgroup的组件管理。
cgroup的组件管理操作单元可以细粒度到线程级别,另外用户可以创建和销毁cgroup,从而实现资源载分配和再利用。
所有资源管理的功能都以子系统的方式实现,接口统一子任务创建之初与其父任务处于同一个cgroup的控制组。
2.2.2 cgroup的四大功能
资源限制:可以对任务使用的资源总额进行限制。
优先级分配:通过分配的cpu时间片数量以及磁盘IO带宽大小,实际上相当于控制了任务运行优先级。
资源统计:可以统计系统的资源使用量,如cpu时长,内存用量等。
任务控制:cgroup可以对任务执行挂起、恢复等操作。
3.容器docker的三大概念
3.1 image镜像
docker镜像就是一个只读模板,比如,一个镜像可以包含一个完整的centos,里面仅安装apache或用户的其他应用。镜像可以用来创建docker容器,另外docker提供了一个很简单的机制来创建镜像或者更新现有的镜像,用户甚至可以直接从其他用户那里下载一个已经做好的镜像来直接使用。
3.2 container容器
docker利用容器来运行应用,容器是从镜像创建的运行实例,它可以被启动、开始、停止、删除,每个容器都是互相隔离的,可以保证安全的平台。可以把容器看做是一个简易版的linux环境(包括root用户权限、镜像空间、用户空间和网络空间等)和运行在其中的应用程序。
3.3 repostory仓库
仓库是集中存储镜像文件的仓库,registry是仓库主从服务器,实际上仓库主从服务器上存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。仓库分为两种:公有仓库和私有仓库,最大的公开仓库是docker Hub,存放了数量庞大的镜像供用户下载,国内的docker pool。这里仓库的概念与Git类似,registry可以理解为github这样的托管服务。
4.容器技术的特点
Docker本身不是容器,它是创建容器的工具,是应用容器引擎。
Docker的第一句口号:Build、Ship and Run(创建、搬运、运行)
Docker的第二句口号:Build once,Run anywhere(搭建一次,各处运行)
(1)极其轻量:只需打包必要的Bin/Lib包;
(2)秒级部署:根据镜像的不同,容器的部署只需毫秒与秒之间(比虚拟机快很多);
(3)易于移植:一次构建,随处部署;
(4)弹性伸缩:kubernetes、swam等容器管理平台有着非常强大的容器集群资源弹性管理功能。
5.容器组件结构
docker目前的组件结构图如下:
runc处于docker组件的最下层,runc下面就是容器。docker目前已经不是一个专一的容器管理组件,真正的容器管理组件是containerd,而container也不会直接与操作系统进行交互,创建、删除容器而是借助runc来对容器生命周期进行管理。因此此处也可以讲runc作为容器运行时。
6.容器运行时
传统意义上,容器运行时代表容器从拉取镜像,到启动运行,再到中止的整个生命周期,即掌握容器运行的整个生命周期。
6.1 容器运行时功能
(1)制定容器镜像格式
(2)构建容器镜像docker build
(3)管理容器镜像docker image
(4)管理容器实例docker ps
(5)运行容器docker run
(6)实现容器镜像共享docker pull/push
6.2 容器运行时工具和库
遵循OCI的实现参考,工具所拥有的功能不尽相同,有的只有运行容器(runc、lxc),有的也可以对镜像进行管理(containerd、cri-o),可将容器运行时分成low-level和high-level。
6.2.1 low-level runtime
(1)定义
关注如何与操作系统交互,创建并运行容器。
(2)常见类型
*Imctfy --- Google项目,是Borg使用的容器运行时。
*runc --- 目前最广泛的容器运行时,实现OCI规范,包含config.json文件和跟文件系统。
*rkt --- CoreOS开发的Docker/runc的一个流行替换方案。
6.2.2 high-level runtime
(1)定义
High-level相对于low-level位于堆栈的上层,负责传输和管理容器镜像,解压镜像,并传递给low-level runtime来运行镜像。
(2)常见类型
*docker
*containerd
*rkt
7.容器的标准化
容器除了有docker,还有coreos,这就需要一个标准(OCI,开放容器标准)去规范它。
标准:runtime运行时标准和image镜像标准。
7.1 容器运行时标准(runtime spec,也就是runc)
(1)creating:使用creat命令创建容器,此为创建中;
(2)created:容器创建出来了,还没有运行,容器的镜像和配置没有错误,可以运行在当前平台;
(3)running:容器的运行状态,里面的进程状态是up,正在进行用户设定的任务;
(4)stopped:容器运行完成、或者运行出错、或者stop命令之后,容器处于暂停状态。这个状态下,容器还有很多信息保存在平台上,没有被完全删除。
7.2 容器镜像标准(image spec)
(1)文件系统:以layer保存的文件系统,每个layer保存了和上层之间的变化部分,layer应该保存哪些文件,怎么表示增加、修改和删除的文件
(2)config文件:保存了文件系统的层级信息(每个层级的 hash 值,以及历史信息),以及容器运行时需要的一些信息(比如环境变量、工作目录、命令参数、mount 列表),指定了镜像在某个特定平台和系统的配置。比较接近我们使用 docker inspect <image_id> 看到的内容;
(3)manifest文件:镜像的 config 文件索引,有哪些 layer,额外的 annotation 信息,manifest 文件中保存了很多和当前平台有关的信息;
(4)index文件:可选的文件,指向不同平台的 manifest 文件,这个文件能保证一个镜像可以跨平台使用,每个平台拥有不同的 manifest 文件,使用 index 作为索引。
8.Dockerfile
9.容器命令
(1)查看运行中的容器
docker ps
(2)查看所有的容器
docker ps -a
(3)查看容器镜像
docker images
(4)从仓库下载镜像到本地仓库
docker pull 镜像名称:TAG信息
(5)从本地仓库上传镜像到仓库
(6)从本地仓库下载镜像到本地
docker save -o 镜像名称.tar 镜像名称:TAG信息
(7)从本地上传镜像到本地仓库
docker load < 容器镜像名称(一般是镜像名称.tar文件)
(8)删除某个镜像文件
docker rmi -f 镜像名称:TAG信息
(9)删除某个容器
docker rm -f 容器id
(10)批量删除所有未运行的容器(在运行的删除不了)
docker rm $(sudo docker ps -a -q)
(11)根据容器状态,删除Exited状态的容器
docker rm $(sudo docker ps -qf status=exited)
(12)查看更详细的容器container_1的描述
docker inspect container_1
(13)开启容器
docker run -itd 镜像名称
docker run -itd --privileged --runtime runc 镜像名称
docker run -itd --cap-add SYS_TIME --runtime kata-runtime 镜像名称
(14)进去容器container_1内部
docker exec -it container_1 bash #多个exec同一个docker,不同终端不会同步
docker attach 容器id #多个attach同一个docker,多个终端会同步
注:命令中 -i 确保准输入流保持开放。-t分配一个伪终端(TTY)
(15)查看容器内进程
ps -aux
(16)查看容器内文件
ls
(17)Dockerfile的生成镜像
docker build -t test:v1 .
(18)Docker容器与本地文件交互(将本地文件复制到docker里面)
docker cp 1.txt 8b3440de2d9d:/tmp
(19)基于此时修改的镜像生成新的镜像文件
10.容器应用场景
容器技术主要解决PAAS层的技术实现;
OpenStack和CloudStack主要解决的是IAAS层的问题。
11.容器构建本地仓库
12.容器安装报错
(1)从源安装docker-ce时,报错依赖包问题
依赖包有问题,执行apt --fix-broken install,然后再安装apt-get install docker-ce
(2)从源安装docekr-ce时,报错使用其他内核文件信息
查看错误报告,需要使用到内核头文件,显示还是使用的之前的内核驱动文件,发现现在正在使用的内核驱动文件build没有软连接。将源码拷贝到116机器上,建立软连接ln -s /root/kata/linux-4.19-sw-wyh build和ln -s /root/kata/linux-4.19-sw-wyh source,这样就使用了目前系统的驱动文件
(3)从源安装docker-ce时,报错aufs-dkms错误
安装aufs-dkms软件包是,依赖关系没有正确配置,执行命令
cd /var/lib/dpkg
mv info info_old
mkdir info
apt-get update
apt-get -f install
mv info/* info_old/
rm -rf info
mv info_old info
(4)重新安装docker,执行apt-get --reinstall install docker-ce报错启动docker失败
查看dockerd显示如下
A.设置/etc/docker/daemon.json文件
B.为docker添加网桥
brctl addbr docker0
ip addr add dev docker0 172.17.0.1/16
ip link set dev docker0 up
C.为docker的Debian设置nftables
Docker安装将tables用于nat,而Debian使用nftables,手动设置。
update-alternatives --set iptables /usr/sbin/iptables-legacy
update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
(5)重启报错,执行dockerd查询报错
删除/var/run/docker.pid
(6)删除docker.pid后,重启docker报错,执行dockerd查看报错
执行命令
ps axf | grep docker | grep -v grep | awk '{print "kill -9 " $1}' | sh
解决报错,重启docker,显示成功
(7)dpkg(6B平台uos830)安装docker报错
措施:
执行命令dockerd,查看报错信息
发现软件未找到4.19.90-xuelang+驱动包,内核与initrd、/lib/modules下的文件未对应上,将4.19.90-xuelang+驱动包拷贝至/lib/modules目录下,解决问题,成功安装docker。
(8)启动报错,查看journalctl -xe显示runtime报错
查询journalctl -xe显示报错信息如下: