"你真的,自由了~"
容器虚拟化基础之Cgroups:
(1) 什么是cgroups
cgroups是 linux 内核提供的一种机制, 这种机制可以根据需求把一系列系统任务及其子任务整合(或分隔)到按资源划分等级的不同组内,从而为系统资源管理提供一个统一的框架。简单说, cgroups 就是可以控制、记录任务组所使用的物理资源。
本质上来说: " cgroups 是内核附加在程序上的一系列钩子(hook) ,通过程序运行时对资源的调度触发相应的钩子以达到资源追踪和限制的目的 "。
Hook原理
Hook其本质就是劫持函数调用。但是由于处于Linux用户态,每个进程都有自己独立的进程空间,所以必须先注入到所要Hook的进程空间,修改其内存中的进程代码,替换其过程表的符号地址。
(2) 为什么使用cgroups?
cgroups可以做到对CPU、内存等等系统资源进行精细化管控!目前,很风靡的轻量级容器Docker及 k8s 中的 pod 就使用了 cgroups 提供的资源限制能力来完成 cpu、内存等部分资源的管控。
例如,如果你想在一台8核服务器上部署一个服务,其中你可以通过 cgroups 限制业务处理仅仅用掉完全够用的6个核,其余剩下的也可以另作他用。
(3) cgroups的用途作用
● Resource limitation: 限制资源使用.例:内存使用上限/cpu 的使用限制。
● Prioritization: 优先级控制. 例:CPU 利用/磁盘 IO 吞吐。
● Accounting: 一些审计或一些统计。
● Control: 挂起进程/恢复执行进程。
使用cgroups控制的子系统:
blkio | 对块设备的IO进行限制 |
cpu | 限制cpu时间片分配 |
cpuacct | 生成cgroup中的任务占用cpu资源的报告,与cpu挂载到同一目录 |
cpuset | 给cgroup中的任务分配独立的cpu(多核)和内存节点。 |
devices | 限制设备文件创建和对设备文件的读写 |
freezer | 暂停、恢复cgroup中的任务 |
memory | 对cgroup中的任务的可用内存进行限制,并自动生成占用资源报告 |
perf_event | 允许perf观测cgroup中的task |
net_cls | cgroup中的任务创建数据报文的类别标识符,让Linux流量控制器可以识别来自特定cgroup任务的数据包,并进行网络限制 |
hugetlb | 限制使用内存页的数量 |
pids | 限制任务数量 |
rdma | 限制远程直接数据存取 |
(4) cgroups资源控制实战
cgroups的基本信息有哪些?cgroups是如何进行资源管理、控制的呢?作为真正的资源控制层——OS,它同cgroups是怎样运作的?
基础知识:
pidstat:
pidstat 是 sysstat(Linux系统性能监控工具) 的一个命令,用于监控全部或指定进程的 CPU、内存、线程、设备、IO等系统资源的占用情况。
语法:
pidstat [option] [ <时间间隔>] [次数]
注:
用户可以通过指定统计的次数和时间来获得所需的统计信息.
参数:
参数 | 作用 |
-u | 默认参数,显示各进程的 CPU 使用统计. |
-r | 显示各进程的内存使用统计. |
-d | 显示各进程的 IO 使用情况. |
-p: ALL | 指定进程号,ALL 表示所有进程. |
-C | 指定命令,这个字符串可以是正则表达式. |
-l | 显示命令名和所有参数. |
示例: 我们可以查看Linux下的Mysql服务资源使用情况
安装\卸载(Centos7)
yum install(remove) sysstat -y
stress:
stress 是 Linux 的一个压力测试工具,可以对 CPU、 Memory、 IO、磁盘进行压力测
试。
语法:
stress [ option ] [ARG] ]
参数:
-c, --cpu N | 产生 N 个进程,每个进程都循环调用 sqrt 函数产生 CPU 压力. |
-i, --io N | 产生 N 个进程,每个进程循环调用 sync 将内存缓冲区内容写到磁盘上,产生 IO 压力. |
-m, --vm | 产生 N 个进程,每个进程循环调用 malloc/free 函数分配和释放内存。 --vm-bytes B: 指定分配内存的大小。 |
-d, --hdd N | 产生 N 个不断执行 write 和 unlink 函数的进程(创建文件,写入内容,删除文件) --hdd-bytes B:指定文件大小 |
-t, --timeout N | 在 N 秒后结束程序 |
-q, --quiet: | 程序在运行的过程中不输出信息 |
安装\卸载(Centos7):
yum install(remove) stress -y
实操一: cgroups 信息查看
● cgroups 版本查看
cat /proc/filesystems | grep cgroup
● cgroups 子系统查看
cat /proc/cgroups
● cgroups 挂载信息查看
mount |grep cgroup
可以看到默认存储位置为 /sys/fs/cgroup。
● 查看一个进程上的cgroups的信息
① 以当前 shell 进程为例,查看进程的 cgroup
cat /proc/$$/cgroup
注: "$$"当前shell脚本 —> 命令行解释器进程
② 比如 cpu 在 user.slice,我们可以找到这个目录,里面有对 init 进程的详细限制信息
ll /sys/fs/cgroup/cpu/user.slice/
实操二:使用 cgroups 对内存进行控制
① 创建内存的 cgroup,很简单我们进入到 cgroup 的内存控制目录: “/sys/fs/cgroup/memory”,我们创建目录 test_memory。
这里只要在这个目录里创建新目录,内存限制文件就会自动在其中进行创建了。cgroups 文件系统会在创建文件目录的时候自动创建相应的配置文件。
② 配置 cgroup 的策略为最大使用 20M 内存
echo "20971520" > ./memory.limit_in_bytes
③ 启动 1 个消耗内存的进程,每个进程占用 50M 内存
stress -m 1 --vm-bytes 50M
我们打开一个新窗口监控该内存使用情况:
另启与一个窗口,并且将进程 id 移动到我们的 cgroup 策略(test_memory):
/sys/fs/cgroup/memory/test_memory/tasks
echo pro_pid >> tasks
可以看到进程无法申请到足够内存退出,进程消失。
实操三:使用 cgroups 对 cpu 进行控制
① 创建内存的 cgroup,很简单我们进入到 cgroup 的内存控制目录“/sys/fs/cgroup/cpu”,并且继续执行像在memory目录之中的动作,创建test_cpu目录。
② 我们设置 cproup 的 cpu 使用率为 30%, cpu 使用率为:"cfs_quota_us/cfs_period_us "
● cfs_period_us: 表示一个 cpu 带宽,单位为“us”。系统总 CPU 带宽 ,默认值 10,0000。
● cfs_quota_us: 表示 Cgroup 可以使用的 cpu 的带宽,单位为“us”。cfs_quota_us 为-1,表示使用的 CPU 不受 cgroup 限制。 cfs_quota_us 的最小值为1"ms"(1000us),最大值为 1s。
因此,我们将 cfs_quota_us设置为 30000us 从理论上讲就可以限制 test_cpu 控制的进程的 cpu 利用率最多是 30%。
echo 30000 > cpu.cfs_quota_us
③ 新建一个窗口,并使用 stress 模拟一个任务, 并查看该cpu使用率
stress -c 1
使用率接近100%。
④ 我们将该进程放到 tasks 文件进行控制,并观察cpu的使用情况
我们监控的 cpu 的使用率由 100%降低为 30%左右。
小结:
至此我们成功的模拟了对 "内存" 和 "cpu" 的使用控制,而 docker 本质也是调用这些的 API来完成对资源的管理,只不过 docker 的易用性和镜像的设计更加人性化,所以 docker才能风靡全球。
容器虚拟化基础之LXC:
(1) LXC是什么?
LXC(LinuX Containers)Linux容器,一种操作系统层虚拟化技术,是‘’Linux 内核容器”功能的一个用户接口。可以提供轻量级的虚拟化,以便隔离进程(namespace)和资源管理(cgroups)。
LXC 是最早一批真正把完整的容器技术用一组简易使用的工具和模板来极大的简化了容器技术使用的一个方案。
(2) LXC用什么用处?
它将应用软件系统打包成一个软件容器(Container),内含应用软件本身的代码,以及所需要的操作系统核心和库。透过统一的名字空间和共享 API 来分配不同软件容器的可用硬件资源,创造出应用程序的独立沙箱运行环境,使得 Linux 用户可以容易的创建和管理系统或应用容器。
(3) LXC vs Docker
LXC 虽然极大的简化了容器技术的使用,但比起直接 "通过内核调用来使用容器" 技术,其复杂程度其实并没有多大降低:
①我们必须要学会 LXC 的一组命令工具.
②由于内核的创建都是通过命令来实现的,通过批量命令实现数据迁移并不容易.
③ 其隔离性也没有虚拟机那么强大.
后来就出现了 docker,所以从一定程度上来说, docker 就是 LXC 的增强版。
(4) LXC容器实战
通过 lxc 来完成容器的创建,体会容器。LXC虽然比docker逊色,但也可以作为理解容器、理解docker的基础。
基础知识:
LXC常用命令如下:
命令 | 格式要求\作用 |
lxc-checkconfig | 检查系统环境是否满足容器使用要求 |
lxc-create | 创建 lxc 容器; 格式: lxc-create -n [NAME] -t [TEMPLATE_NAME] [-- template-options] |
lxc-start | 启动容器; 格式: lxc-start -n NAME -d |
lxc-ls | 列出所有容器,-f 表示打印常用的信息 格式: lxc-ls -f |
lxc-info | 查看容器相关的信息 格式: lxc-info -n NAME |
lxc-attach | 进入容器执行命令; 格式: lxc-attach --name=[NAME] [-- COMMAND] |
lxc-stop | 停止容器; 格式: lxc-stop -n [NAME] |
lxc-destroy | 删除处于停机状态的容器; 格式: lxc-destory -n [NAME] |
CentOS 安装:
● 检查是否安装。清理资源
systemctl status lxc # 检查安装
lxc-stop -n [name] # 停止正在使用的容器
lxc-destory -n [name] # 删除对应容器
● 安装软件
# lxc 程序包
# lxc-templates lxc的配置模板
# bridge-utils 网桥管理工具 lxc-libs lxc 所需的库文件
# libcgroup cgroup 安装包
# libvirt 管理 Linux 的虚拟化功能所需的服务器端守护程序。 需要针对特定驱动程序的管理程序。
# debootstrap debootstrap 是 Debian 引导程序,它允许您将 Debian 基本系统(例如 Debian 或 Ubuntu)安装到当前正在运行的系统的目录中。# 配置源
yum -y install epel-release#安装程序
yum -y install lxc lxc-templates bridge-utils lxc-libs libcgroup libvirt lxc-extra debootstrap
● 启动\检查
# 输入以下命令完成启动(停止)
systemctl start(stop) lxc #启动 lxc 服务
systemctl start(stop) libvirtd #启动虚拟机监控服务
systemctl status lxc
systemctl status libvirtd
● 卸载软件
yum remove lxc lxc-templates lxc-libs lxc-extra libvirt debootstrap
操作实战:
① 检查 lxc 的功能支持情况
在lxc运行的情况下,检查lxc版本。
lxc-checkconfig (连起的)
② 查看 lxc 提供的容器模板
ls /usr/share/lxc/templates/
④ 建一个 lxc 虚拟主机,这个命令就会下载安装指定环境下的软件包,创建新容器。整个过程需要时间较长,与容器的类型有关。
#创建 LXC 主机, -t 指定模板容器, -n 指定要创建的主机名
# 下面是创建Centos7的命令行
lxc-create -t centos --name centos1 -- --release 7 --arch x86_64
⑤ 容器位置信息
下载安装完所有软件包后, LXC 容器镜像就创建完成了。容器被放到 /var/lib/lxc/<容器名> 这个目录下,容器的根文件系统放在/var/lib/lxc/<容器名>/rootfs 目录下。创建过程中下载的软件包保存在 /var/cache/lxc 目录下面,当你想另外建一个一样的容器时,可以省去很多下载时间。
⑥ 查看容器信息、启动容器为运行
lxc-start -n centos1
⑦ 使用ssh进入容器,查看 ip 地址,磁盘挂载信息,目录信息和宿主机都不一样
容器ip为 [ 192.168.122.118 ]: " ssh 用户名@ip地址 "
⑧ 在容器外面,进入容器执行命令
lxc-attach -n centos1 --clear-env
⑨ 停止容器、删除容器
lxc-stop -n [name]
lxc-destroy -n [name]
本篇到此结束,感谢你的阅读。
祝你好运,向阳而生~