容器(Container)
Linux容器其实并不是什么新概念。最早的容器技术可以追遡到1982年Unix系列操作系统上的chroot工具(直到今天,主流的Unix、Linux操作系统仍然支持和带有该工具)。
每个容器都可以拥有自己独立的命名空间,运行其中的应用都像是在独立的操作系统中运行一样。命名空间保证了容器间彼此互不影响。
| namespaces | 系统调用参数 | 隔离内容 | 内核版本 |
|---|---|---|---|
| UTS | CLONE_NEWUTS | 主机名和域名 | 2.6.19 |
| IPC | CLONE_NEWIPC | 信号量、消息队列和共享内存 | 2.6.19 |
| PID | CLONE_NEWPID | 进程编号 | 2.6.24 |
| Network | CLONE_NEWNET | 网络设备、网络栈、端口等 | 2.6.29 |
| Mount | CLONE_NEWNS | 挂载点(文件系统) | 2.4.19 |
| User | CLONE_NEWUSER | 用户和用户组 | 3.8 |
控制组(CGroups)是Linux内核的一个特性,用来对共享资源进行隔离、限制、审计等。只有能控制分配到容器的资源,Docker才能避免多个容器同时运行时的系统资源竞争。
控制组可以提供对容器的内存、CPU、磁盘IO等资源进行限制。
CGroups能够限制的资源有:
- blkio:块设备IO
- cpu:CPU
- cpuacct:CPU资源使用报告
- cpuset:多处理器平台上的CPU集合
- devices:设备访问
- freezer:挂起或恢复任务
- memory:内存用量及报告
- perf_event:对cgroup中的任务进行统一性能测试
- net_cls:cgroup中的任务创建的数据报文的类别标识符
具体来看,控制组提供如下功能:
- 资源限制(Resource Limitting)组可以设置为不超过设定的内存限制。比如:内存子系统可以为进行组设定一个内存使用上限,一旦进程组使用的内存达到限额再申请内存,就会发出Out of Memory警告
- 优先级(Prioritization)通过优先级让一些组优先得到更多的CPU等资源
- 资源审计(Accounting)用来统计系统实际上把多少资源用到合适的目的上,可以使用cpuacct子系统记录某个进程组使用的CPU时间
- 隔离(Isolation)为组隔离命名空间,这样一个组不会看到另一个组的进程、网络连接和文件系统
- 控制(Control)挂起、恢复和重启等操作
安装Docker后,用户可以在/sys/fs/cgroup/memory/docker/目录下看到对Docker组应用的各种限制项,包括用户可以通过修改这些文件值来控制组限制Docker应用资源。
[root@localhost ~]# cd /sys/fs/cgroup/memory/ [root@localhost memory]# ls cgroup.clone_children memory.kmem.slabinfo memory.memsw.limit_in_bytes memory.swappiness cgroup.event_control memory.kmem.tcp.failcnt memory.memsw.max_usage_in_bytes memory.usage_in_bytes cgroup.procs memory.kmem.tcp.limit_in_bytes memory.memsw.usage_in_bytes memory.use_hierarchy cgroup.sane_behavior memory.kmem.tcp.max_usage_in_bytes memory.move_charge_at_immigrate notify_on_release memory.failcnt memory.kmem.tcp.usage_in_bytes memory.numa_stat release_agent memory.force_empty memory.kmem.usage_in_bytes memory.oom_control system.slice memory.kmem.failcnt memory.limit_in_bytes memory.pressure_level tasks memory.kmem.limit_in_bytes memory.max_usage_in_bytes memory.soft_limit_in_bytes user.slice memory.kmem.max_usage_in_bytes memory.memsw.failcnt memory.stat
docker工作方式
为了使容器的使用更加易于管理,docker采取一个用户空间只跑一个业务进程的方式,在一个容器内只运行一个进程,比如我们要在一台主机上安装一个nginx和一个tomcat,那么nginx就运行在nginx的容器中,tomcat运行在tomcat的容器中,二者用容器间的通信逻辑来进行通信。
LXC是把一个容器当一个用户空间使用,当虚拟机一样使用,里面可以运行N个进程,这就使得我们在容器内去管理时极为不便,而docker用这种限制性的方式,在一个容器中只运行一个进程的方式,使得容器的管理更加方便。
使用docker的优劣:
- 删除一个容器不会影响其他容器
- 调试不便,占空间(每个容器中都必须自带调试工具,比如ps命令)
- 分发容易,真正意义上一次编写到处运行,比java的跨平台更彻底
- 部署容易,无论底层系统是什么,只要有docker,直接run就可以了
- 分层构建,联合挂载
在容器中有数据称作有状态,没有数据称作无状态。在容器的使用中,我们应以有状态为耻,以无状态为荣。数据不应该放在容器中,而应放置于外部存储中,通过挂载到容器中从而进行数据的存储。
LXC
通过传统方式使用容器功能的话需要我们自己写代码去进行系统调用来实现创建内核,实际上拥有此能力的人廖廖无几。而LXC(LinuX Container)把容器技术做得更加易用,把需要用到的容器功能做成一组工具,从而极大的简化用户使用容器技术的麻烦程度。
LXC是最早一批真正把完整的容器技术用一组简易使用的工具和模板来极大的简化了容器技术使用的一个方案。
LXC虽然极大的简化了容器技术的使用,但比起直接通过内核调用来使用容器技术,其复杂程度其实并没有多大降低,因为我们必须要学会LXC的一组命令工具,且由于内核的创建都是通过命令来实现的,通过批量命令实现数据迁移并不容易。其隔离性也没有虚拟机那么强大。
后来就出现了docker,所以从一定程度上来说,docker就是LXC的增强版。
yum安装Container先把Linux Container依赖的一些软件包给装上,并启动相关的服务。其中git将在第二步中用来下载源代码。
yum -y install lxc lxc-templates bridge-utils lxc-libs libcgroup libvirt lxc #主程序包 lxc-templates #lxc的配置模板 bridge-utils #网桥管理工具 lxc-libs #lxc所需的库文件 libcgroup #cgroup是为Linux内核提供任务聚集和划分的机制,通过一组参数集合将一些任务组织成一个或多个子系统。 libvirt #管理Linux的虚拟化功能所需的服务器端守护程序。 需要针对特定驱动程序的管理程序。 ———————————————— 版权声明:本文为CSDN博主「初夏的微风」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/gzqiang08/article/details/81708656限制LXC可以使用的系统资源
在config文件内,写入限定规则。
lxc.cgroup.memory.limit_in_bytes = 512M #限定内存 lxc.cgroup.cpuset.cpus = 0 #限定可以使用的核 lxc.cgroup.blkio.throttle.read_bps_device = 8:0 100 #读取速率限定 lxc.cgroup.blkio.throttle.write_bps_device = 8:0 100 #写入速率限定 lxc.cgroup.blkio.throttle.read_iops_device = 8:0 100 #读取频率限定 lxc.cgroup.blkio.throttle.write_iops_device = 8:0 100 #写入频率限定启动服务
[root@mingzi ~]# systemctl start lxc
[root@mingzi ~]# systemctl status lxc
● lxc.service - LXC Container Initialization and Autoboot Code
Loaded: loaded (/usr/lib/systemd/system/lxc.service; disabled; vendor pre>
Active: active (exited) since Sat 2022-04-23 16:51:23 CST; 15s ago
Docs: man:lxc-autostart
man:lxc
Process: 5304 ExecStart=/usr/libexec/lxc/lxc-containers start (code=exited>
Process: 5301 ExecStartPre=/usr/libexec/lxc/lxc-apparmor-load (code=exited>
Main PID: 5304 (code=exited, status=0/SUCCESS)
Apr 23 16:51:23 mingzi systemd[1]: Starting LXC Container Initialization and>
Apr 23 16:51:23 mingzi systemd[1]: Started LXC Container Initialization and
检查配置
[root@mingzi ~]# systemctl start libvirtd [root@mingzi ~]# lxc-checkconfig Kernel configuration not found at /proc/config.gz; searching... Kernel configuration found at /boot/config-4.18.0-348.el8.x86_64 --- Namespaces --- Namespaces: enabled Utsname namespace: enabled Ipc namespace: enabled Pid namespace: enabled User namespace: enabled Warning: newuidmap is not setuid-root Warning: newgidmap is not setuid-root Network namespace: enabled --- Control groups --- Cgroups: enabled Cgroup v1 mount points: /sys/fs/cgroup/systemd /sys/fs/cgroup/cpu,cpuacct /sys/fs/cgroup/blkio /sys/fs/cgroup/devices /sys/fs/cgroup/pids /sys/fs/cgroup/hugetlb /sys/fs/cgroup/cpuset /sys/fs/cgroup/net_cls,net_prio /sys/fs/cgroup/freezer /sys/fs/cgroup/rdma /sys/fs/cgroup/perf_event /sys/fs/cgroup/memory Cgroup v2 mount points: Cgroup v1 clone_children flag: enabled Cgroup device: enabled Cgroup sched: enabled Cgroup cpu account: enabled Cgroup memory controller: enabled Cgroup cpuset: enabled --- Misc --- Veth pair device: enabled, not loaded Macvlan: enabled, not loaded Vlan: enabled, not loaded Bridges: enabled, loaded Advanced netfilter: enabled, loaded CONFIG_NF_NAT_IPV4: missing CONFIG_NF_NAT_IPV6: missing CONFIG_IP_NF_TARGET_MASQUERADE: enabled, not loaded CONFIG_IP6_NF_TARGET_MASQUERADE: enabled, not loaded CONFIG_NETFILTER_XT_TARGET_CHECKSUM: enabled, loaded CONFIG_NETFILTER_XT_MATCH_COMMENT: enabled, not loaded FUSE (for use with lxcfs): enabled, loaded --- Checkpoint/Restore --- checkpoint restore: enabled CONFIG_FHANDLE: enabled CONFIG_EVENTFD: enabled CONFIG_EPOLL: enabled CONFIG_UNIX_DIAG: enabled CONFIG_INET_DIAG: enabled CONFIG_PACKET_DIAG: enabled CONFIG_NETLINK_DIAG: enabled File capabilities: Note : Before booting a new kernel, you can check its configuration usage : CONFIG=/path/to/config /usr/bin/lxc-checkconfig创建虚拟机
查看当前系统中可用的LXC模板容器
[root@mingzi ~]# ls /usr/share/lxc/templates/ lxc-busybox lxc-download lxc-local lxc-oci
创建LXC主机
lxc-create -t centos -n myhost1 #创建LXC主机,-t 指定模板容器,-n 指定要创建的主机名
查看lxc主机的一些系统信息
[root@localhost ~]# df -h Filesystem Size Used Avail Use% Mounted on devtmpfs 874M 0 874M 0% /dev tmpfs 893M 0 893M 0% /dev/shm tmpfs 893M 8.7M 885M 1% /run tmpfs 893M 0 893M 0% /sys/fs/cgroup /dev/mapper/cs_192-root 17G 2.1G 15G 13% / /dev/sda1 1014M 210M 805M 21% /boot tmpfs 179M 0 179M 0% /run/user/0
修改root的密码和创建用户
[root@localhost ~]# passwd Changing password for user root. New password:
使用这条lxc-info命令可以查看主机的状态信息
[root@localhost ~]# lxc-info -n myhost1 myhost1 doesn't exist
停止lxc主机
lxc-stop -n myhost1
删除主机
lxc-destroy -n myhost2LXC命令详解
-n,--name #容器的主机名
-f,--config #指定配置文件以配置容器的虚拟化和隔离功能
-t template #调用模板脚本,可执行模板脚本的完整路径也可以作为参数传递。 “none”可用于强制lxc-create跳过rootfs创建。
-B backingstore #指定根文件储存路径的文件系统,可选:dir、lvm、loop、btrfs、zfs、best ,默认为dir,如果是dir可以使用--dir指定lxc主机的根在宿主机的存储路径。
-P, --lxcpath #自定义容器路径。默认值为/var/lib/lxc。
-o, --logfile #输出创建过程到一个日志文件中。
-l, --logpriority #将日志优先级设置为LEVEL,默认优先级为ERROR
-- #向template传递参数查看可选参数:lxc-create -t TEMPLATE -h,常用参数如下
-n,--name #容器标识符
-p,--path #指定容器根的创建路径,默认/var/lib/lxc/容器名/
-c,--clean #清除缓存
-R,--release #指定Centos的发行版本
--fqdn #用于DNS和系统命名的完全域名(FQDN)
--repo #指定创建容器是使用的yum源,这个是redhat系统的参数
-a,--arch #指定容器的架构,可选i686,x86_64



