最佳虚拟容器LXC

和"真正的虚拟机环境"不同, "容器"(container)只能在Linux上虚拟Linux, 不能虚拟WIndows, 因为它不能虚拟硬件. 但是基于容器的虚拟机占用的资源很小--在一台中等的Linux服务器上, 创建几百个虚拟机是轻而易举的事情. 这种"容器"虚拟化技术, 又称为OS-Level虚拟化,也就是"操作系统级虚拟化".

LXC(ontainer)是Linux内核支持的技术, 这个好处就会安全性. 管理LXC容器的方式又两种:一种是使用Libvirt工具来管理,一种是使用lxc本身提供的工具管理. 两者各有优劣: 前者使用方便, 但是缺乏Apparmor保护,不安全; 后者使用性不够友好, 但是默认带了Apparmor规则,可以保证安全性.

安装LXC

使用apt命令就可以安装lxc

# sudo apt install lxc

基本用法

LXC可以创建两种不同的容器:

  • 特权模式--以root身份运行各种lxc命令,创建特权容器;
  • 普通模式--以普通用户身份运行各种lxc命令,创建非特权容器

普通容器又很多限制(比如无法创建设备节点),不过也更安全(不会危害到主机),因为这种容器的root用户,其实映射到主机上的一个普通用户

特权模式基本用法

创建容器可以使用交互式和非交互式

交互式创建容器
# sudo lxc-create -t download --name ubuntu1

下面是输出信息
Setting up the GPG keyring
Downloading the image index              <-下载所有支持的Linux发行版列表 ---
DIST RELEASE ARCH VARIANT BUILD
ubuntu xenial amd64 default 20171214_04:09
[...]
alpine 3.4 amd64 default 20171213_17:50
[...]
centos 6 amd64 default 20171214_02:16
[...]
debian buster amd64 default 20171214_04:09
[...]
--- Distribution: ubuntu <- 这里需要输入操作系统(上面列表中的),我们选择ubuntu
Release: xenial   <- 选择操作系统发行版本(上面列表中有的)
Architecture: amd64     <- 选择架构,这里选择64位 Downloading the image index
Downloading the rootfs
Downloading the metadata
The image cache is now ready
Unpacking the rootfs ---
You just created an Ubuntu container (release=xenial, arch=amd64, variant=default)
For security reason, container images ship without user accounts
and without a root password. Use lxc-attach or chroot directly into the rootfs to set a root password
or create user accounts.

上面就是交互式创建容器的方式,创建出来的容器是没有用户的,需要使用lxc-attach或者chroot命令来设置,这个后面介绍.

非交互式创建
# sudo lxc-create -t download --name ubuntu2 -- \
--dist ubuntu -release xenial --arch amd64

非交互创建其实就是一次性将操作传递给模板而已,下面我们介绍一个各个参数:

  • -t 模板: -t 选项后面跟的是模板,模式可以认为是一个原型,用来说明我们需要一个什么样的容器(比如容器里面需不需要有vim, apache等软件).模板实际上就是一个脚本文件(位于/usr/share/lxc/templates目录),我们这里指定download模板(lxc-create会调用lxc-download脚本,该脚本位于刚说的模板目录中)是说明我们目前没有自己模板,需要下载官方的模板
  • --name 容器名称: 为创建的容器命名
  • -- : --用来说明后面的参数是传递给download脚本的,告诉脚本需要下载什么样的模板
  • --dist 操作系统名称:指定操作系统
  • --release 操作系统: 指定操作系统,可以是各种Linux的变种
  • --arch 架构: 指定架构,是x86还是arm,是32位还是64位
列出现有容器
简单列出
# sudo lxc-ls 详细列出
# sudo lxc-ls --fancy
查看容器信息
# sudo lxc-info --name ubuntu1
启动和关闭容器
# sudo lxc-start --name ubuntu1

以服务的形式启动容器
# sudo lxc-start --name ubuntu1 --daemon # sudo lxc-stop --name ubuntu1
进入容器

进入容器的方式又三种:

  • lxc-attach命令
  • lxc-console命令
  • 用SSH
进入容器
# sudo lxc-attach --name ubuntu1
让容器执行某个命令(重启ssh服务)
# sudo lxc-attach --name ubuntu1 -- restart ssh 提升特权,并指定名字空间,这个命令在测试主机上软件时很有用
# sudo lxc-attach -name ubuntu1 -e -s 'NETWORK|UTSNAME'
登录容器,需要输入用户名和密码
# sodu lxc-consloe --name ubuntu1
使用SSH登录
# ssh 用户名@IP
容器的删除
先停掉容器然后进行删除
# sudo lxc-stop --name ubuntu1
# sudo lxc-destroy --name ubuntu1

非特权模式

通过非特权模式,普通用户也可以创建和管理容器,而不需要root用户权限.

用户命名空间

这种非特权模式的实现使用了一种叫做"用户命名空间(user namespace)"的特性.用户命名空间是Linux下众多命名空间(Linux namespace)之一.Linux下一个用户本来有且只有一个uid和gid(可以通过id命令查看用户的id).这个用户命名空间特性可以允许一个普通用户使用多个从属uid和gid(用户编号和组编号).拥有多个从属uid和gid的意义在于做id映射,即将容器里面的用户映射到外部的普通用户上来.可以通过查看/ect/subuid/etc/subgid来查看每个用户的可以使用的从属ID范围.

从图1可以看出用户hdy的id为1000,其从属id为图二所示,每个用户名后面就是该用户可以使用的id范围(起始id和可用id个数,中间用冒号隔开)

默认情况下,主机上的每个任务都是运行在初始用户命名空间里面的.在初始用户命名空间里,所有的id都是映射到整个id范围的(也就是没有做id映射).可以通过查看/proc/self/uid_map/proc/self/uid_map查看映射信息.

在非特权容器中,lxc会使用uidmap软件包提供的newuidmapnewgidmap程序来进行id映射.登入容器后,查看上面的两个文件可以映射情况.

创建默认的配置文件

在允许普通普通用户创建普通容器之前,需要做一些配置设置.

要让普通用户hdy能够创建容器

# mkdir -p ~/.config/lxc
# touch .config/lxc/default.conf

执行完上面命令后,需要在default.conf文件中添加以下内容

# uid映射, 填写用户hdy的从属id(/etc/subuid)
lxc.id_map = u 0 10000 65536
# gid映射, 填写用户hdy的从属id(/etc/subgid)
lxc.id_map = g 0 10000 65536
# 定义网络类型
lxc.network.type = veth
# 定义网络接口,lxcbr0是lxc包虚拟出的网卡,可以通过ifconfig查看
lxc.network.link = lxcbr0

/etc/lxc/lxc-usernet文件中添加以下内容:

# 用户名 网络类型 桥接到的网络接口 允许普通用户创建的网络接口数量
hdy vneth lxcbr0 2

该文件是lxc用来管理非特权用户网络的.当普通用户创建网络接口时,lxc使用该文件的配置进行管理和控制.

创建非特权容器

前面配置完成后可以用普通用户hdy创建容器了

创建容器
hdy@hdy-pc:~$ lxc-create -t download -name ubuntu2 -- -dist ubuntu -release xenial -arch amd64
开放权限,不然无法启动容器
hdy@hdy-pc: chmod o+x -R ~/.local

启动,进入,停止和删除容器都不需要sudo

全局配置文件

  • 对于特权容器,配置文件位于/etc/lxc
  • 对于普通容器而言,配置文件位于~/.config/lxc
  • 以root身份创建的特权容器都位于/var/lbi/lxc
  • 普通用户创建的容器在~/.local/share/lxc目录下

克隆LXC容器

在大规模部署的情况下,我们一般不会逐个去手动的创建容器,而是搞好一个后直接克隆.

拷贝和快照

"克隆"要么是其他容器的一份拷贝,要么是其他容器的一份快照

拷贝:完整的复制原来的容器,所占的空间和原来的容器一样大

快照:利用后台文件系统的快照功能,创建一个很小的新容器,在发生写操作时才进行复制

要想使快照拥有这个写时复制的特性,需要一个特殊存储系统,支持快照的存储方式有:aufs,btrfs,LVM,overlayfs,zfs等.每种存储方式各有自己特点,这里不进一步说明

创建拷贝和快照

同过lxc-clone命令可以创建拷贝和快照,在创建之前需要停止容器

$ sudo lxc-stop --name ubuntu1
创建一个名为clone_ubuntu1的克隆
$ sudo lxc-copy -n ubuntu1 -N clone_ubuntu1
创建一个名为snapshot_ubuntu1的快照
$ sudo lxc-clone -s -n ubuntu1 -N snapshot_ubuntu1

lxc专门创建快照的快捷命令lxc-snapshot

该命令创建的快照位于/var/lib/lxc/容器名(如果是为普通容器创建快照,则位于~/.local/share/lxc/容器名)目录下,快照名字为snap0,snap1...依次编号

创建快照,实际上是克隆
$ sudo lxc-snapshot -n ubuntu1 创建快照
$ sudo lxc-copy -s -n ubuntu1 -N snapshot_ubuntu1
$ sudo lxc-snapshot -n snapshot_ubuntu1

使用lxc-snapshot创建快照时需要创建aufs/overlayfs文件系统,所以先通过lxc-copy命令创建一个快照,同时会自动为该快照创建文件系统overlayfs.然后我们给新创建的快照snapshot_ubuntu1(容器)创建快照.也就是说现在有三个容器--ubuntu1,snapshot_ubuntu1,snap0.而容器snapshot_ubuntu1是ubunt1的快照,容器snap0是snapshot_ubuntu1的快照.snap0是lxc_snapshot创建的.snapshot_ubuntu1位于/var/lib/lxc目录下,snap0位于/var/lib/lxc/snapshot_ubuntu1/snaps目录下

假如我们在ubuntu1上做了一些误操作,这时想通过快照将ubuntu1恢复过来,可以这样实现.首先恢复一个容器的操作实际上是先将这个容器删除掉,然后根据快照创建一个同名的容器.但是在打快照的时候会依赖于overlayfs文件系统的,而overlayfs会依赖于原始容器(ubuntu1)的rootfs.如果将ubuntu1删除掉,那么rootfs将会被删除,进而overlayfs会被破快掉,导致无法通过快照创建创建容器.这里只能采用迂回的方式,通过快照创建一个新的容器.

通过快照创建一个新的容器ubuntu2
$ sudo lxc-snapshot -r snap0 -n ubunt1 -N ubuntu2

LXC网络

在默认的情况下,LXC会为每个容器创建一个专用的网络命名空间,包括一个二层的网络协议栈.LXC启动的时候会创建一个叫做lxcbr0的桥接设备,使用默认设置创建的容器都会有一个vethxxx虚拟网卡(每个容器都有一个虚拟网卡与之绑定),这个网卡会被桥接lxcbr0上.

使用固定IP

默认情况下,容器的IP地址是动态分配的.如果要给容器设置固定IP地址,可以修改容器的配置文件.这里以修改普通容器的配置文件为例.

编辑文件
$ vim ~/.local/share/lxc/ubuntu1/config 添加固定ip
...
lxc.network.type = veth
lxc.network.link = lxcbr0
lxc.network.ipv4 = 10.0.3.102
...

让外界可以访问容器

在默认情况下,容器只能被宿主主机访问,外界是访问不到容器的(默认NAT方式).如果想让容器像普通服务器被外界访问到,就需要使用桥接宿主主机eth0(或其他物理网卡)的设备

注意:只有特权容器才能被外界访问,普通容器是无法被外界访问的

创建桥接设备br0

在宿主主机上安装桥接工具包

$ sudo apt install bridge-utils

在宿主服务器上,修改/etc/network/interfaces,创建br0桥设备

[...]
auto enp4s0f2                物理网卡
iface enp4s0f2 inet manual auto br0
iface br0 inet dhcp
address 192.168.1.10 网桥IP地址
netmask 255.255.255.0 掩码
gateway 192.168.1.1
dns-nameserver 114.114.114.114 8.8.8.8
bridge_ports enp4s0f2 #将物理网卡添加到虚拟网桥中
bridge_stp off
bridge_maxwait 0
bridge_fd 0
[...]

上面的配置主要是创建了一个网桥,而物理网卡enp4s0f2可以看做网桥的一个端口,然后关闭网卡,启动网桥

$ sudo ifdown enp4s0f2 && sudo ifup br0

接下来停掉容器(这里以ubuntu1为列),修改其配置文件

$ sudo lxc-stop -n ubuntu1
$ vim /var/lib/lxc/ubuntu1/config 修改以下内容,容器桥接到br0上
lxc.network.link = br0

然后为容器配置固定IP

$ vim /var/lib/lxc/ubuntu1/rootfs/etc/network/interfaces
...
auto eth0
iface eth0 inet static
address 192.168.1.239
netmask 255.255.255.0
gateway 192.168.1.1
dns-nameserver 8.8.8.8 如果无法解析域名,则需要设置下

参考

https://linux.cn/article-4313-1.html

最佳虚拟容器LXC的更多相关文章

  1. [转帖]8个最佳Docker容器监控工具,收藏了

    8个最佳Docker容器监控工具,收藏了 https://www.sohu.com/a/341156793_100159565?spm=smpc.author.fd-d.9.1574127778732 ...

  2. WPF中实现自定义虚拟容器(实现VirtualizingPanel)

    WPF中实现自定义虚拟容器(实现VirtualizingPanel) 在WPF应用程序开发过程中,大数据量的数据展现通常都要考虑性能问题.有下面一种常见的情况:原始数据源数据量很大,但是某一时刻数据容 ...

  3. WPF之路——实现自定义虚拟容器(实现VirtualizingPanel)

    原文:WPF之路--实现自定义虚拟容器(实现VirtualizingPanel) 源码下载地址: http://download.csdn.net/detail/qianshen88/6618033 ...

  4. 异数OS-织梦师-异数OS虚拟容器交换机(七) 走进4Tbps网络应用时代,加速5G应用真正落地

    . 异数OS-织梦师-异数OS虚拟容器交换机(七) 走进4Tbps网络应用时代,加速5G应用真正落地 本文来自异数OS社区 github: https://github.com/yds086/Here ...

  5. docker - 容器lxc

    容器:是在用户空间进行隔离的组件叫做容器 常用的容器有lxc ----libcontainer---runc 需要隔离的资源有: Rootfs:每个容器对应的一个目录做为根目录 User: Hostn ...

  6. 【原创】Docker实战 Dockerfile最佳实践&&容器之间通信

    官方最佳实践文档 https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#from Docker实战(三十) ...

  7. 使用docker-sync解决docker for mac 启动的虚拟容器程序运行缓慢的问题

    背景: 新入职的公司有个非常OG的大项目,为了避免新同学重复造轮子,有哥们已经把项目需要的所有打好了一个镜像供我们启动docker. 初次启动docker 使用的命令如下: docker run -i ...

  8. LXC容器

    1.    LXC简述 Linux container是一种资源隔离机制而非虚拟化技术.VMM(VMM Virtual Machine Monitor)或者叫Hypervisor是标准的虚拟化技术,这 ...

  9. 虚拟化之lxc

    LXC 中文名称就是 Linux 容器工具,容器可以提供轻量级的虚拟化,以便隔离进程和资源,使用 LXC 的优点就是不需要安装太多的软件包,使用过程也不会占用太多的资源,本文循序渐进地介绍LXC的建立 ...

随机推荐

  1. ios学习--TableView详细解释

    -.建立 UITableView DataTable = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 420)]; [DataTa ...

  2. web 前端规范实例

    <!DOCTYPE html> <html> <head> <title>tmall</title> <!-- 为了被搜索引擎作为流量 ...

  3. x86 x64下调用约定浅析

    x86平台下调用约定 我们都知道x86平台下常用的有三种调用约定,__cdecl.__stdcall.__fastcall.我们分别对这三种调用约定进行分析. __cdecl __cdecl是C/C+ ...

  4. Bootstrap篇:弹出框和提示框效果以及代码展示

     前言:对于Web开发人员,弹出框和提示框的使用肯定不会陌生,比如常见的表格新增和编辑功能,一般常见的主要有两种处理方式:行内编辑和弹出框编辑.在增加用户体验方面,弹出框和提示框起着重要的作用,如果你 ...

  5. c++11——列表初始化

    1. 使用列表初始化 在c++98/03中,对象的初始化方法有很多种,例如 int ar[3] = {1,2,3}; int arr[] = {1,2,3}; //普通数组 struct A{ int ...

  6. 【PHP】通过header发送自定义数据

    发送header: 我们定义了三个参数,token.language.region,放入header发送过去 <?php $url = 'http://www.example.com'; $he ...

  7. 英语——'s和s'和s的区别

    举个例子吧,student's 是表示学生的,名词单数形式的所有格students' 是表示学生们的,名词复数形式的所有格students 是表示学生们,名词的复数形式

  8. SenchaTouch调用纯数字键盘

    items:[ { itemId:"phoneNumber", xtype: "textfield", component:{xtype:"input ...

  9. Google浏览器提示用户要允许网站允许flash!

    开发的flash播放器,在谷歌浏览器上播放不了,需要提示用户手动开启允许网站运行flash: <script type="text/javascript"> if (w ...

  10. Web界面的服务器监测工具(转载)

    企业服务器对于企业业务持续性意义重大,系统管理员需要密切关注企业服务器以确保一切正常运行.当发现问题的时候,他们需要知道问题开始出现时的状况,因此调查可以重点放在问题出现的时候,这就意味着定期记录信息 ...