LXC容器:概念介绍及简单上手操作指导

发布时间 2023-08-04 10:20:04作者: mini小新

LXC容器:概念介绍及简单上手操作指导

1、介绍

LXC(Linux Containers)是一种Linux端操作系统级的虚拟化技术,可以实现轻量级容器,每个容器看起来像一个独立的操作系统,它们共享同一台物理服务器,但是互相隔离。LXC容器比传统虚拟机更加轻便、高效,且启动速度快。LXC中创建的为非特权容器,相较于特权容器,其有更高的安全性,更小的攻击面,同时便于管理和升级。下面介绍一下LXC的架构和基本上手操作指导。

开源仓库:https://github.com/lxc/lxc

官网:https://linuxcontainers.org/lxc/

2、LXC架构

image

  1. 宿主机(Host OS):运行LXC命令和LXC用户空间的操作系统。
  2. LXC用户空间(Userspace):包括LXC库、配置文件和容器元数据等组件。
  3. LXC模板(Templates):用于创建容器的基础镜像
  4. LXC命令(Commands):用于管理和操作LXC容器的命令工具。
  5. LXC库(Library):提供容器相关的API和函数库。
  6. LXC配置(Configs):用于配置和定制容器的参数和选项。
  7. LXC网络脚本(Net Scripts):用于管理容器的网络连接和配置。
  8. LXC工具(Tools):提供各种辅助工具和脚本,用于管理和维护LXC容器。
  9. LXC 容器(LXC Container):相互独立运行的轻量容器。

LXC的核心功能是利用Linux内核提供的Namespace和Cgroups等机制来实现容器的隔离和虚拟化,从而使得容器可以独立运行和管理。同时,LXC还支持各种网络选项和安全特性,可以根据不同的应用场景进行定制和配置。

3、检查Linux Kernel

容器的要求如下

  • 内核版本要求:Linux kernel >= 3.12

  • 依赖包要求:

# to allow for capability drops
libcap
# to set a different apparmor profile for the container
libapparmor
# to set a different selinux context for the container
libselinux
# to set a seccomp policy for the container
libseccomp
# for various checksumming
libgnutls
# for the LUA binding
liblua
# for the python3 binding
python3-dev

检查Linux kernel配置是否达标:

# 检查非enable项
lxc-checkconfig

image

4、安装LXC

Ubuntu/Debian发行版安装:

sudo apt-get install -y lxc

CentOS/RHEL发行版安装:

sudo yum install -y epel-release
sudo yum install -y lxc

安装后检查版本号:

# 能执行成功及安装成功
lxc-info --version

image

5、容器配置

5-1、全局配置

1)全局默认配置

su切换至root权限进行配置,原始默认配置文件路径,供root用户使用:

/etc/lxc/default.conf

配置文件追加以下两行:

# 一、默认配置文件追加
# lxc.idmap = u 0 100000 65536
echo "lxc.idmap = u 0 100000 65536" >> /etc/lxc/default.conf
# lxc.idmap = g 0 100000 65536
echo "lxc.idmap = g 0 100000 65536" >> /etc/lxc/default.conf

image

注:这两个值需匹配以下两个文件的值:/etc/subuid/etc/subgid

2)全局USER默认配置

注意:在操作以下步骤时,以需要添加权限的用户角色执行,否则后续执行会提示找不到配置文件,如:给test1加权限,则su test1切换至该角色。

新增默认配置文件,供user用户使用:

# 1、创建~/.config/lxc目录
mkdir -p ~/.config/lxc
# 2、拷贝配置文件/etc/lxc/default.conf 到新路径
cp /etc/lxc/default.conf ~/.config/lxc/default.conf

配置文件中追加这两行:

# 二、新建配置文件追加
# lxc.idmap = u 0 100000 65536
echo "lxc.idmap = u 0 100000 65536" >> ~/.config/lxc/default.conf
# lxc.idmap = g 0 100000 65536
echo "lxc.idmap = g 0 100000 65536" >> ~/.config/lxc/default.conf

image

image

注:这两个值需匹配以下两个文件的值:/etc/subuid/etc/subgid

grep $USER /etc/subuid
grep $USER /etc/subgid

添加user用户相关权限:

# 允许用户创建两个设备连接到lxcbr0网桥--此操作需要root权限
echo "$USER veth lxcbr0 2" | sudo tee -a /etc/lxc/lxc-usernet

image

配置完成后直接以test1身份创建容器即可。

5-2、单容器配置

1)单个容器配置文件介绍

每创建好一个容器,会在以下默认路径生成配置文件:

# container为容器名称
# 容器文件路径
/var/lib/lxc/container
# 配置文件路径
/var/lib/lxc/container/config

相应的目录结构如下:

image

默认配置内容:

image

2)设置 UID/GID 映射

新创建的容器,若全局配置文件未修改,则默认为特权容器,不会有以下UID/GID映射限制配置。此操作会将容器内的进程限制在自己的命名空间,从而无法对宿主机上的资源进行直接访问。通过配置此步骤,将特权容器变更为非特权容器。具体操作如下:

  • 文件编辑器打开配置文件
# i编辑,wq保存
vim /var/lib/lxc/privileged-container/config
  • 查看host端UID/GID映射
cat /etc/subuid
cat /etc/subgid
  • 设置UID/GID映射
# 追加的内容与第二点查出来的区间范围保持一致
# set uid/gid
lxc.idmap = u 0 100000 65536
lxc.idmap = g 0 100000 65536

image

image

3)检查容器类型

lxc-ls -f

配置生效如下,后续容器启动为非特权容器:

image

6、创建容器

6-1、创建方式

1)指定模板创建

使用-t-template参数创建,后接<template>容器使用的模板,如ubuntucentos等;<container name>为容器名字,可以任意取名。

sudo lxc-create -t <template> -n <container name>
# 示例一:创建名称为my-container的centos镜像容器
sudo lxc-create -t centos -n my-container
# 示例二:创建名称为my-container1的Ubuntu镜像容器
sudo lxc-create -template ubuntu -n my-container1

支持以下的发行版本(填写时注意大小写!):

发行版本 发行版本 发行版本
alpine linux arch linux centos
cirros debian fedora
gentoo openmandriva opensuse leap
oracle linux ubuntu

2)不指定模板创建

不指定容器模板,可以在-t-template参数后接download参数:

# 创建名称为my-container的容器
# 选择其一
sudo lxc-create --template download --name my-container
sudo lxc-create -t download -n my-container

创建完成的容器状态为STOPPED状态,需要手动启动:

image

6-2、创建特权容器

注:未修改配置文件的情况下,默认创建的容器为特权容器

1)示例1:创建centos镜像容器

# 创建名称为privileged-container的容器
sudo lxc-create -t download -n privileged-container
sudo lxc-create -t download -n privileged-container -- --dist centos --release 7 --arch amd64
sudo lxc-create -t download -n container1 -- -d centos -r 7 -a amd64

此处-t 给定download参数,返回镜像列表,填入Distribution:centos Release:7 Architecture:amd64镜像类型:

image

image

下载创建完成如下:

image

2)示例2:创建Ubuntu镜像容器

# 创建名称为privileged-container的容器
sudo lxc-create -t download -n privileged-container
sudo lxc-create -t download -n privileged-container -- -d ubuntu -r focal -a amd64

此处-t 给定download参数,返回镜像列表,填入Distribution:ubuntu Release:focal Architecture:amd64镜像类型。"focal" 即20.04 LTS 、"amd64"即“x86-64”或“x64”,内容区分大小写。

image

下载中,等待镜像下载完成:

image

6-3、创建非特权容器

在初始的配置文件中,不对UID和GID进行限制,此时创建的容器,均为特权容器,有较高的权限。通过以下操作,修改默认的配置文件,能够在后续的容器创建中,将容器改为非特权容器。具体操作如下:

1)以user身份创建非特权容器

test1用户创建容器:

lxc-create -t download -n u1 -- -d ubuntu -r focal -a amd64

创建成功:

image

2)以root身份创建非特权容器

以root身份创建,需要修改原始的配置文件/etc/lxc/default.conf,按照1)全局默认配置修改文件,直接用lxc-create命令创建容器即可:

# 创建名称为my-container的容器
sudo lxc-create -t download -n my-container

image

6-4、容器位置

  • root用户创建容器存放位置
/var/lib/lxc

image

  • 非root用户容器创建存放位置
# user替换为实际登录的非root权限用户名称
/home/user/.local/share/lxc

image

7、检查容器状态

# 检查my-container名称的容器状态
lxc-info -n my-container
lxc-ls -f

实际查询示例如下:

image

image

LXC容器的状态可以分为以下五种:

容器状态 描述
STOPPED 容器停止状态。此时,容器进程已经被停止,并且容器的命名空间和资源控制组也已经被释放。
RUNNING 容器运行状态。此时,容器的进程正在运行,并且容器的命名空间和资源控制组也已经生效。
FREEZING 容器冻结状态。此时,容器的进程被暂停,但是容器的命名空间和资源控制组仍然在生效。
FROZEN 容器冻结状态。此时,容器的进程被暂停,同时容器的命名空间和资源控制组也被暂停。
ABORTING 容器异常退出状态。此时,容器出现了异常,需要被终止。在该状态下容器进程会被强制杀死,并且容器的命名空间和资源控制组也会被释放。

8、启动容器

# 启动名称为my-container的容器
sudo lxc-start -n my-container
sudo lxc-start -n privileged-container

启动后的容器,状态更新为RUNNING:

image

9、查看容器列表

# 结果会展示所有的容器列表
# 执行其一
sudo lxc-ls -f
lxc-ls --fancy

image

10、进入容器shell面板

# 进入名称为my-container的容器shell面板
# 执行其一
sudo lxc-attach -n my-container
lxc-attach -n my-container

进入后,shell会话中系统的名称会更改:在容器中,也为一个完整的独立的Linux环境,可以正常的执行各类指令而对host宿主机无影响。

image

若想要退出当前的容器界面,使用exit退出即可:

image

11、停止容器

# 停止名称为my-container的容器
# 执行其一
sudo lxc-stop -n my-container
lxc-stop -n my-container

停止之后,查询容器状态能发现,指定的容器会由RUNNING状态切换为STOPED状态

image

12、删除容器

# 移除为my-container的容器
# 执行其一
sudo lxc-destroy -n my-container
lxc-destroy -n my-container

移除后对应容器,从所有容器列表中删除,后续使用容器需重新创建。

image

13、输出执行日志

# 输出详细执行日志到文件:--logpriority修改日志等级
lxc-start -n u1 --logfile log.txt
lxc-start -n u1 -P /home/test1/.local/share/lxc/ --logfile=/home/test1/lxcNPr.log --logpriority DEBUG
# 非特权容器debug日志打印
lxc-start -n my-container -P /var/lib/lxc --logfile=/usr/local/src/lxclog/lxcNPr.log --logpriority DEBUG
lxc-start -n my-container -P /var/lib/lxc --logfile=/usr/local/src/lxclog/lxcNPr1.log --logpriority DEBUG
# 特权容器debug日志打印
lxc-start -n container1 -P /var/lib/lxc --logfile=/usr/local/src/lxclog/lxcPr.log --logpriority DEBUG

image

14、嵌套容器

在父容器配置文件中加入以下内容,启用嵌套功能:

lxc.mount.auto = cgroup
lxc.aa_profile = lxc-container-default-with-nesting

具体修改单个容器配置文件,参考5-2、单容器配置

15、附录

15-1、”特权容器&非特权容器“概念

特权容器&非特权容器:非特权容器和特权容器的主要区别在于它们在运行时所具有的权限不同

  • 特权容器:指在容器内部的进程拥有特权权限,例如root权限

1.特权容器在启动时会使用宿主机的命名空间;

2.容器中的进程不受限于各种 Linux Namespace 的限制;

3.通常用于需要使用底层系统资源和设备的应用程序,例如网络驱动程序、存储卷管理器和系统监视工具。

  • 非特权容器:指在容器内部的进程以普通用户权限运行,没有root权限或其他特权权限

1.非特权容器在启动时会创建一个新的命名空间来运行;

2.容器中的进程受限于各种 Linux Namespace 的限制.

具体优缺点如下表:

差异点 特权容器 非特权容器
优点 1. 可以访问宿主机上的所有资源和设备。
2. 可以进行修改和配置容器内部的操作系统设置。
3. 可以运行一些需要更高权限才能正常运行的应用程序,如内核模块。
1.更高的安全性,因为容器内进程没有特权权限,不会因为特权进程的错误而导致系统崩溃;
2. 更便于管理和升级,因为容器内进程的权限受到限制。
3. 更小的攻击面,因为容器内进程只能访问它们需要的资源。
4.隔离应用程序相互之间的影响,从而提高应用程序的稳定性和可靠性
缺点 1. 容易造成安全漏洞;
2. 对宿主机的影响比较大。
1. 无法直接访问宿主机的资源和设备;
2. 运行某些更高权限的应用程序可能会失败。

15-2、AMD64&i386架构

1)AMD64

又称“x86_64”或“x64”架构,是一种64位元的电脑处理器架构。由AMD公司所开发,兼容x86(32位)的指令集,为业界统一64位架构命名。

2)i386

即x86架构,采用IA-32指令集,纯32位指令集。由早期Intel产品命名发展而来,i386=Intel 80386,对386通常被用来作为对Intel 32位微处理器的统称,后特指x86系列架构。

16、参考文档