Linux Container(lxc)分析和配置使用

2023-11-20

前提

介绍

  • 最好将容器化定义为:通过操作系统中的特性启用的进程隔离机制

容器是与系统其他部分隔离的一个或多个进程的集合。

Containers != VMs

Virtual Machine Linux LXC Container
操作系统 在VM中运行隔离的客户OS 在主机OS上运行(共享内核)
网络 通过虚拟网络设备 通过虚拟网络适配器隔离的视图
隔离性 OS之间完全隔离 基于命名空间和cgroup的隔离
大小 通常是GB级别 通常是MB级别
启动时间 以秒、分钟数量级,取决于存储介质 以秒数量级

chroot

介绍

  • 默认情况下,操作系统的根目录为/,进程将其视为所有文件绝对路径的根目录。
  • 这个“视图”可以通过调用chroot()系统调用来更改,这样我们就可以创建一个独立的独立环境来运行。
  • chroot更改当前运行进程及其子进程的表面上的根目录。

缺陷

  • 但是,chroot本身并不能提供强隔离
  • 似乎阻止对父目录的访问就足够了,但是chroot只是修改进程(通过pivot_root)及其子进程的路径名查找,将新的chroot-ed目录路径放在任何绝对路径(以/开头的路径)前面。
  • 在其他原因中,如果进程能够访问chroot监狱之外的句柄,那么也允许访问chroot-ed目录的父目录——因此这本身不是强隔离。

Capabilities

介绍

  • 传统的UNIX自由访问控制分为两个部分
    • root/超级用户/特权;
    • 用户/非特权。
  • 假设一个系统用户需要生成一个需要一些root权限的服务器进程。同时,假设服务器代码具有远程代码执行漏洞。如果脆弱的服务器进程被破坏,整个系统就会被破坏(因为进程的UID是0)。有没有一种方法只给进程它需要的权限(最小权限)?
  • 为了**分割通常完全提供给root用户的特权**,Linux Capabilities从2.2版开始被引入到Linux内核中。每个Capability代表一个不同的特权单位,前缀为CAP_。一些功能包括:
    • CAP_CHOWN:更改文件的用户和组所有权的能力
    • CAP_NET_ADMIN:在系统上执行与网络相关的管理的能力
    • CAP_NET_RAW:创建RAW和PACKET套接字以及任意地址绑定的能力
    • CAP_SYS_ADMIN:能够做很多事情,以至于很多人把它当作新的根。未来肯定需要进一步的特权分片。

总共29种Capability

  • getcap和setcap命令用于获取/设置文件的Capabilities。

例子

  • 让我们看看ping实用程序,它需要创建一个RAW套接字来发送ICMP数据包:
student@6858-v20:~$ ls -al /bin/ping
-rwsr-xr-x 1 root root 64424 Jun 28  2019 /bin/ping
  • 它属于root:root,但任何用户都可读和执行。如果我们尝试ping google.com,我们可以验证UID是当前用户的(因为没有setuid位设置):
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
student    2090  0.0  0.1  21044  2476 pts/2    S+   23:17   0:00 /bin/ping google.com
  • 这里的非特权用户能够ping,因为在/bin/ping二进制文件上设置了一个功能:
student@6858-v20:~$ getcap /bin/ping
/bin/ping = cap_net_raw+ep
  • 有3个capability标志可以设置:

    • Effective:该capability是否激活
    • Inheritable:该capability是否被子进程继承
    • allowed:该capability是否被允许,与父进程capability集无关
  • 如果我们清空了ping的capability

student@6858-v20:~$ cp /bin/ping .
student@6858-v20:~$ getcap ./ping 
student@6858-v20:~$ ./ping google.com
ping: socket: Operation not permitted
student@6858-v20:~$ sudo setcap cap_net_raw=ep ./ping
student@6858-v20:~$ ./ping google.com
PING google.com (172.217.163.46) 56(84) bytes of data.

通过复制ping二进制文件到一个新的目的地,任何扩展的属性(setuid,capabilities等)都会被清除。

  • 如果没有cap_net_raw这个capability,生成的ping进程就无法打开RAW套接字。一旦我们恢复了这种capability,ping功能就会恢复正常。
  • Capabilities似乎是一个好主意,但CAP_SYS_ADMIN仍然有太多特权,这只是lxc用于加强隔离的另一种机制。

cgroup

介绍

  • Control groups (cgroups)用于根据用户定义的进程组限制系统资源的使用

  • 假设您正在运行一个非常密集的数据分析例程,它使用了大量的算力和内存,以致于您的系统没有很好的响应。cgroups是一个内核特性,它允许您定义一组进程,这些进程运行分析作业并限制、解释和隔离分配的资源,这样您就可以在资源有限的情况下执行多任务分析作业。特别地,cgroup特性包括:

    • Limits:可以在处理器使用、内存使用、设备使用等方面指定最大限制。
    • Accounting:监控资源使用情况。
    • Prioritization:资源使用可以优先于其他cgroup。
    • Control:可以控制进程的状态(如停止、重启、挂起)。
  • 一个cgroup是一个或多个进程的集合,它们被绑定到为cgroup定义的同一组限制上。cgroup还可以以分层的方式继承另一个cgroup的属性。

  • cgroups通常在大多数现代版本的Linux发行版中可用,大多数定义了大约10个子系统(也称为控制器)。

    • blkio:这个子系统设置对块设备,如物理驱动器(磁盘、固态或USB)的输入/输出访问的限制。
    • cpu:这个子系统使用调度器提供cgroup任务对cpu的访问。
    • cpuacct:该子系统自动生成cgroup中任务使用CPU资源的报告。
    • cpuset:这个子系统为cgroup中的任务分配单独的cpu(在多核系统上)和内存节点。
    • devices:这个子系统允许或拒绝cgroup中的任务访问设备。
    • freezer:这个子系统挂起或恢复cgroup中的任务。
    • memory:这个子系统对cgroup中的任务使用内存进行限制,并自动生成关于这些任务使用内存资源的报告。
    • net_cls:这个子系统用一个类标识符(classid)标记网络数据包,这个类标识符允许Linux流量控制器(tc)识别来自特定cgroup任务的数据包。
    • net_prio:这个子系统提供了一种动态设置每个网络接口的网络流量优先级的方法。
    • ns:命名空间子系统。
    • perf_event:这个子系统标识任务的cgroup成员,可以用于性能分析。
  • 管理它们需要cgroup-tools和libcgroup1包,它们可以通过以下方式安装到Ubuntu中:

sudo apt install cgroup-tools libcgroup1

例子

  • 假设我们有一个称为memes的内存密集型进程,我们希望在工作站上运行它。我们可以使用cgroups来限制内存使用,方法是在内存子系统中创建一个名为memegroup的cgroup(使用cgcreate),设置它的限制(使用cgset),并在该cgroup下执行进程(使用cgexec):
student@6858-v20:~$ sudo cgcreate -g memory:memegroup
student@6858-v20:~$ sudo cgset -r memory.limit_in_bytes=1500K memegroup
student@6858-v20:~$ cgget -r memory.limit_in_bytes memegroup 
primes: 
memory.limit_in_bytes: 1536000
student@6858-v20:~$ cat /sys/fs/cgroup/memory/memegroup/memory.limit_in_bytes
1536000
student@6858-v20:~$ sudo cgexec -g memory:memegroup ./memes 
  • cgcreate命令帮助在sysfs下创建目录(sysfs几乎总是挂载在/sys上,可以直接从命令行进行操作),并且cgset适当地设置值。注意,系统总是将其更正为最接近的4096B对齐(从1500 KB到1536 KB),这是内核页面大小。最后,我们在内存子系统下的memegroup中执行meme。

    • 过了一段时间,你会在终端上看到消息,说进程已经被终止了。
student@6858-v20:~/cgroup$ cat /sys/fs/cgroup/memory/memegroup/memory.oom_control
oom_kill_disable 0
under_oom 0
oom_kill 1

我们看到oom_kill被设置为1,这意味着"内核内存不足杀手"(OOM Killer)已经终止了memegroup中的进程。

  • memes程序源码如下;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main() {
    char *ptr;
    int cnt = 0;
    while(1) {
        ptr = (char *)malloc(4096);
        memset(ptr, 0, 4096);
        cnt += 4096;
        printf("%d bytes have been in use\n", cnt);
        sleep(1);
    }
    return 0;
}

这是一个如何通过cgroup执行限制和过程控制的例子。

大多数子系统都有计数功能,比如memory.usage_in_bytes、cpuacct.usage_sys等等。优先级的一个例子是cpu.shares(每个cgroup中每个进程可用的CPU资源份额)。

Namespaces

介绍

  • 命名空间是一个抽象对象,它封装了资源,以便资源具有限制于同一命名空间中的其他资源的视图

  • 例如,Linux进程形成了一个单进程树,根在init (PID 1)。一般情况下,特权进程可以跟踪或杀死其他进程。随着PID名称空间的引入,我们可以有多个不相交的进程树(它们不知道另一个名称空间中的进程)。如果我们创建一个新的PID名称空间并在其中运行一个进程,那么第一个进程就成为该名称空间中的PID 1创建命名空间的进程仍然位于父命名空间中,但使其子进程成为新进程树的根

  • Linux内核定义了7个命名空间

    • PID:隔离进程
    • Network:隔离网络
    • User:隔离用户/组id
    • UTS:隔离主机名和完全限定域名(FQDN)
    • Mount:隔离挂载点
    • cgroup:隔离Cgroup的sysfs根目录
    • IPC:隔离IPC/消息队列
  • 通过procfs查看系统中定义的名称空间

student@6858-v20:~/cgroup$ sudo ls /proc/1/ns
cgroup  mnt  pid               user
ipc     net  pid_for_children  uts
  • 这种级别的隔离在容器化中很有用。如果没有名称空间,在容器中运行的进程可以更改另一个容器的主机名、卸载文件系统、删除网络接口、更改限制等。

  • 通过使用名称空间来封装这些资源容器X中的进程不知道另一个容器Y中的资源

  • 随着名称空间的引入,Linux内核提供了3个新的系统调用:

    • clone():使用指定的名称空间创建一个新进程。如果传递了CLONE_NEW标志,则为每个指定的名称空间创建新的名称空间。
    • setns():允许进程加入一个现有的命名空间。命名空间由procfs中的文件描述符引用指定。
    • unshare():将调用进程移动到一个新的命名空间。
#procfs下的文件描述符
student@6858-v20:~/cgroup$ sudo ls -al /proc/1/ns
total 0
dr-x--x--x 2 root root 0 May 20 01:28 .
dr-xr-xr-x 9 root root 0 May 19 22:29 ..
lrwxrwxrwx 1 root root 0 May 20 01:28 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 root root 0 May 20 01:28 ipc -> 'ipc:[4026531839]'
lrwxrwxrwx 1 root root 0 May 20 01:28 mnt -> 'mnt:[4026531840]'
lrwxrwxrwx 1 root root 0 May 20 01:28 net -> 'net:[4026531993]'
lrwxrwxrwx 1 root root 0 May 20 01:28 pid -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 May 20 01:28 pid_for_children -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 May 20 01:28 user -> 'user:[4026531837]'
lrwxrwxrwx 1 root root 0 May 20 01:28 uts -> 'uts:[4026531838]'

例子

  • 在新的UTS名称空间中创建新的bash
student@6858-v20:~$ hostname
6858-v20
student@6858-v20:~$ sudo unshare -u /bin/bash
root@6858-v20:/home/rayden# hostname lmao
root@6858-v20:/home/rayden# hostname
lmao
root@6858-v20:/home/rayden# exit
exit
student@6858-v20:~$ hostname
6858-v20

注意:主机名在父进程中不变

  • 进程id可以做到相同的事
student@6858-v20:~/cgroup$ sudo unshare --fork --pid --mount-proc /bin/bash
root@6858-v20:~/cgroup# pidof /bin/bash
1
  • 在父进程中查看fork出来的进程id不为1
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root       4446  0.0  0.0   7912   780 pts/1    S    01:40   0:00 unshare --fork --pid --mount-proc /bin/bash

区别

  • cgroups定义了一个名称空间子系统(因此可以通过名称空间控制资源),但是注意不要混淆这两者:
    • cgroups限制资源利用率,而名称空间限制资源视图(资源在系统上可能看到的内容)。

seccomp

介绍

  • 在有些情况下,通过chroot、capabilities、cgroup和namespaces进行隔离是不够的
  • 假设某个运行在容器中的web服务器遭到破坏,攻击者生成了一个远程shell。宿主进程和容器可以调用同一组系统调用,并且可能存在一些调用序列,使容器逃逸成为可能。
  • seccomp通过限制进程允许执行的系统调用的数量来防止恶意进程通过系统调用造成的破坏。
    • 像Chrome和Firefox这样的现代浏览器使用seccomp来更严格地限制它们的应用程序。
    • 通过将系统调用接口限制为只允许容器化应用程序执行其功能所需的系统调用,可以很容易地阻止许多容器逃逸漏洞。
  • 在lxc中,可以通过容器配置文件指定seccomp过滤器
#vim ~/.local/share/lxc/<container_name>/config
lxc.seccomp = /usr/share/lxc/config/common.seccomp

/usr/share/lxc/config/common.seccomp默认拒绝的系统调用列表。

MAC

  • 假设在上一节的小型web服务器的例子中,攻击者无视chroot, capabilities, cgroups, namespaces和seccomp成功地逃出了容器。现在会发生什么?
    • 如果容器是有特权的(使用UID 0运行),它几乎是完胜。
    • 如果它是无特权的,攻击者仍然可以尝试升级特权,或者如果当前用户的特权足够大,就会造成足够大的破坏。
  • 在这种情况下,只有自由访问控制(DAC)(通过UNIX权限)站在攻击者和完全受损的系统之间。在老式的纵深防御模式中,我们使用另一种控制来降低这种风险:强制访问控制(Mandatory Access Control)。
  • MAC是一种集中的授权机制,其运作原理是信息属于组织(而不是个体成员)。安全策略被定义并保存在内核中,内核根据定义的策略授权访问。像SELinux这样的现代MAC实现是基于角色访问控制(RBAC)和两个概念的结合:

TE

  • TE将类型标记引入到每个文件系统对象中,这是MAC的先决条件
    • 对象被标记一个类型,并且在内核中定义了一个策略来指定哪些类型允许过渡到其他类型
    • 然后,每次访问带标签的文件系统对象时,内核都会检查指定的策略。如果不存在特定的类型转换,则默认拒绝访问。
    • 例如,在 Security-Enhanced Linux (SELinux)中,适用于Apache提供的web服务器内容的标准标签httpd_sys_content_t不允许访问标记为bin_t的文件,它适用于/usr/bin中的二进制文件。
  • 假设,在同一个小型web服务器示例中,攻击者设法获得了root访问权。
    • 在DAC下,任何用户都可以任意控制自己拥有的任何东西,因此攻击者拥有完全的控制权。
    • 如果TE是通过SELinux实现的,则攻击者会受到严重阻碍:web服务器exploit给了一个UID 0的进程,但exploit继承自被exploit的网页的类型标签(httpd_sys_content_t),其只允许访问相同标签的其他文件系统对象(由web服务器提供的内容应该只需要访问其他web内容,而不需要访问其他东西)。
  • 类似地,如果我们为容器主机启用了像SELinux这样的MAC机制,那么所有容器都将被标记为默认的lxc_t类型标签(由用于lxc的默认SELinux TE策略定义)。任何绕过其他隔离机制的恶意进程都将受到TE策略的限制。

MLS

MLS超纲了,此处省略。

lxc运行示例

  • 在Ubuntu上安装lxc:
sudo apt install lxc

从属UID / GID范围

  • 通过定义以下文件,我们可以确保当前用户可以拥有从属的uid和gid:
student@6858-v20:~/cgroup$ cat /etc/subuid
lxd:100000:65536
root:100000:65536
student:165536:65536
student@6858-v20:~/cgroup$ cat /etc/subgid
lxd:100000:65536
root:100000:65536
student:165536:65536
  • 这允许用户student拥有从165536开始的65536个从属uid /gid。
  • 我们还需要为lxc创建用户配置目录,如果它不存在,并创建默认配置文件:
mkdir -p ~/.config/lxc
touch ~/.config/lxc/default.conf
  • 应该修改~/.config/lxc/default.conf文件,使其看起来像这样(使用正确的id_map值):
student@6858-v20:~/cgroup$ cat ~/.config/lxc/default.conf 
lxc.idmap = u 0 165536 65536
lxc.idmap = g 0 165536 65536

Virtual network interfaces

  • 在安装lxc时,应该已经创建了一个默认网桥:lxcbr0。通过命令验证网桥是否存在
student@6858-v20:~/cgroup$ brctl show
bridge name     bridge id               STP enabled    interfaces
lxcbr0          8000.00163e000000       no
lxcbr1          8000.00163e000000       no
lxcbr2          8000.00163e000000       no
lxcbr3          8000.00163e000000       no
lxcbr4          8000.00163e000000       no
lxcbr5          8000.00163e000000       no
lxcbr6          8000.00163e000000       no
lxcbr7          8000.00163e000000       no
lxcbr8          8000.00163e000000       no
lxcbr9          8000.00163e000000       no
  • 确保/etc/lxc/lxc-usernet文件定义为:
student@6858-v20:~/cgroup$ cat /etc/lxc/lxc-usernet
# USERNAME TYPE BRIDGE COUNT
student veth lxcbr0 10
student veth lxcbr1 10
student veth lxcbr2 10
student veth lxcbr3 10
student veth lxcbr4 10
student veth lxcbr5 10
student veth lxcbr6 10
student veth lxcbr7 10
student veth lxcbr8 10
student veth lxcbr9 10

这告诉lxc它可以将多少虚拟网络接口作为用户student连接到指定的网桥(或组,每行一个)。

应用更改的最快方法是重新启动节点或注销并重新登录

  • 这将重启dbus、正确设置cgroup并打开用户名称空间(kernel.unprivileged_userns_clone=1)。
  • 验证以太网网络模块
lsmod | grep veth
  • 如果veth模块没有加载,加载它并使其在重启后持续存在:
echo veth | sudo tee -a /etc/modules

创建容器

  • 运行lxc-create来创建一个容器:
student@6858-v20:~/cgroup$ lxc-create -t download -n example
Setting up the GPG keyring
Downloading the image index

---
DIST    RELEASE ARCH    VARIANT BUILD
---
almalinux       8       amd64   default 20220519_23:08
almalinux       8       arm64   default 20220519_23:08
almalinux       8       ppc64el default 20220519_23:08
  • 这是一个交互式命令,使用download模板创建一个名为example的容器。lxc install中指定了4个默认模板,基本上都是在/usr/share/lxc/templates/目录下的脚本:

    • download:下载预构建的映像并解压缩它们
    • local:使用distrobuilder build-lxc命令构建的本地映像
    • busybox:包含在单个可执行文件中的通用UNIX实用程序
    • oci:从开放容器图像(oci)格式的图像创建应用程序容器
  • download模板提示您从给定的列表中选择发行版/发行版作为容器的基本映像,我们将使用该映像创建示例容器。

    • 我们可以直接在命令行中指定所需的映像,例如Ubuntu 19.10 (Eoan) amd64映像(注意名称后的双破折号):
lxc-create -t download -n example -- --dist ubuntu --release focalx --arch amd64
  • 将在~/.local/share/lxc/example/处创建一个容器目录,带有一个特定于容器的配置文件config,在这里你可以指定更多的过滤和控制,如MAC、seccomp拒绝列表、网络等。你会看到新创建的容器的root文件系统被解压到rootfs/中,它看起来像一个标准的Linux根文件系统:
student@6858-v20:~/.local/share/lxc/example$ ls rootfs/
bin   dev  home lib32  libx32  mnt  proc  run   srv  tmp  var
boot  etc  lib  lib64  media   opt  root  sbin  sys  usr
  • 可以通过在rootfs目录上使用chroot进行离线更改(无需启动和附加到容器)。

运行容器

  • 后台运行example容器:
lxc-start example

如果在启动容器时遇到错误,使用-F选项在前台启动容器将提供更详细的输出。

  • 验证我们的容器正在运行:
student@6858-v20:~/lab$ lxc-info example
Name:           example
State:          RUNNING
PID:            21372
  • 查看所有的容器:
student@6858-v20:~/lab$ lxc-ls --fancy
NAME    STATE   AUTOSTART GROUPS IPV4 IPV6 UNPRIVILEGED 
example RUNNING 0         -      -    -    true         
  • 连接到正在运行的容器实例:
student@6858-v20:~/lab$ lxc-attach example
root@example:/# id
uid=0(root) gid=0(root) groups=0(root)
root@example:/# passwd
New password: 
Retype new password: 
passwd: password updated successfully

一旦我们添加了用户并更改了他们的密码,我们就可以通过命令lxc-console使用交互式登录连接到容器

不同之处在于,lxc-attach的行为更像是基于密钥的ssh设置(在没有任何提示的情况下直接获得一个root会话),而lxc-console为您提供了一个虚拟控制台,它模拟了一个真实服务器上的交互式控制台,如serial、DRAC、ILO等。

  • 注意:我们是容器中的root,尽管我们创建的是一个非特权容器。
    • 此行为是UID名称空间的结果。我们可以看到,通过在容器中运行一个进程,容器中的任何进程都被映射到主机上一个无特权的UID:
root@example:/# while [ 1 ]; do sleep 5; done &
[1] 130
  • 在主机上可以看到,进程以UID 165536运行:
student@6858-v20:~$ ps aux | grep sleep
165536    22060  0.0  0.0   9832   580 pts/5    S    03:55   0:00 sleep 5
  • 如果从ps aux输出查看其他进程,可以注意到容器的init进程也是通过uid映射的:
student@6858-v20:~$ ps aux | grep init
165536    21372  0.0  0.5 103876 10656 ?        Ss   03:49   0:00 /sbin/init
  • 我们可以在里面运行大多数系统管理任务,比如安装包。
    • 安装nginx web服务器和net-tools二进制包:
root@example:/# apt update
[output truncated]
root@example:/# apt install nginx net-tools
[output truncated]
  • 验证nginx在80端口运行:
root@example:/# netstat -atunp | grep LISTEN
tcp  0 0 127.0.0.53:53 0.0.0.0:* LISTEN 88/systemd-resolved
tcp  0 0 0.0.0.0:80    0.0.0.0:* LISTEN 881/nginx: master p
tcp6 0 0 :::80         :::*      LISTEN 881/nginx: master p

网络相关

  • LXC默认情况下创建一个独立的网桥,它对所有到主接口的流量使用masquerading(伪装)
    • 网桥是凭空创建的(lxcbr0),容器连接到这个网桥。
    • 如果主接口也可以访问Internet(通过转发和伪装),则允许容器访问Internet。
    • 快速查看主机上的接口,可以看到带有Internet连接ens33的主接口、默认桥接器lxcbr0和容器示例中的虚拟接口veth1000_XXXX。

停止容器

  • 要停止创建的示例容器,只需发出以下命令:
lxc-stop example
  • 从文件系统中清除(删除)容器:
lxc-destroy example

lxc和Docker的区别

这两种解决方案适用于不同的用例

  • lxc:出现的时间更长(Docker过去使用lxc)。

    • 感觉更像是虚拟机中的一个完整的操作系统,必须以类似的方式处理:软件必须手动安装和更新,要么手工安装,要么通过配置管理工具,如Ansible
  • Docker:用于运行单个应用程序

    • 没有完整的系统进程堆栈,如lxc。一个容器的应用程序及其依赖是使用Dockerfile构建和部署的。
  • 在容器编排方面,两者都有相当新的工具:

    • lxc有lxd, Docker有Docker Swarm和Kubernetes。
    • 有一个名为lxe的新项目,旨在将lxc/lxd与Kubernetes集成。

Docker不使用lxc;Docker曾经使用lxc来运行容器,但在几年前就停止了。

Docker和lxc都使用相同的内核特性来实现容器化,但它们是独立的解决方案。

总结

  • 容器是与系统其他部分隔离的一个或多个进程的集合。

  • lxc通过使用Linux内核特性来抽象操作系统,并隔离容器来实现容器化,例如:

    • Control Groups (cgroups)

    • Capabilities

    • seccomp

    • Mandatory Access Control(通过AppArmor, SELinux)

    • Namespaces

    • chroot jails

  • lxc配置位置

    • lxc特定于容器的配置位于~/.local/share/lxc/<container name>/config
    • 针对lxc的用户特定配置位于~/.config/lxc/default.conf
    • lxc的全局配置位于/etc/lxc/default.conf
    • 容器rootfs位于~/.local/share/lxc/<container name>/rootfs
  • lxc用法

    • 使用lxc-attach创建容器
    • 使用lxc-start启动容器
    • 使用lxc-stop停止容器
    • 使用lxc-info列出容器
    • 使用lxc-destroy销毁容器
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux Container(lxc)分析和配置使用 的相关文章

  • Inotify linux 监视子目录

    是否可以以这种模式监视目录 storage data usernames Download gt storage data Download 我需要监视每个用户的下载文件夹中是否进行了更改 也许我需要创建所有路径的列表 将其放入数组中 并在
  • 如何不断刷新屏幕并实时更新[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我想在linux上写一个C程序 不断刷新屏幕并实时更新 例如类似于top终端中的命令 谁能指出我正确的方向 为了保持它跨终端类型的可移
  • 如何在Python中独立于语言安装(linux)获取用户桌面路径

    我找到了 如何找到用户桌面的路径 的几个问题和答案 但在我看来它们都已失效 至少我找到的那些 原因是 如果用户安装的 Linux 不是英语 他或她的桌面很可能位于除 Desktop 例如 对于瑞典语 我相信它是在 Skrivbord 谁知道
  • 在Linux中断上下文中运行用户线程

    我正在编写一些定制的应用程序 并允许更改 Linux 内核中的中断处理程序代码 我有一个用户线程正在等待中断发生 如果发生中断 那么我要做的第一件事就是执行该用户线程 有什么办法让它发挥作用吗 Thanks 创建一个字符设备 这就是内核所做
  • 在 Ubuntu 16.04 上找不到 printf.c

    我最近切换到Ubuntu 16 04 我在用vscode作为 Ubuntu 上的 IDE 我配置了其他语言 但我无法做到这一点C C 我创建c cpp properties json launch json tasks json 当我开始编
  • 如何让“grep”从文件中读取模式?

    假设有一个很大的文本文件 我只想打印与某些模式不匹配的行 显然 我可以使用egrep v patter1 pattern2 pattern3 现在 如果所有这些模式都在一个文本文件中怎么办 最好的制作方法是什么egrep从文件中读取模式 g
  • 从 TypeScript 运行任何 Linux 终端命令?

    有没有办法直接从 TypeScript 类中执行 Linux 终端命令 这个想法是做类似的事情 let myTerminal new LinuxTerminal let terminalResult myTerminal run sudo
  • Linux 桌面快捷方式和安装图标

    我需要添加什么到我的 spec文件来创建桌面快捷方式并在安装过程中为快捷方式分配一个图标 rpm 如果需要脚本 一个示例将非常有帮助 您在 Linux 下使用 desktop 文件作为图标 图标放置的位置取决于您使用的发行版和桌面环境 由于
  • 在 /dev/input/eventX 中写入事件需要哪些命令?

    我正在开发一个android需要将触摸事件发送到 dev input eventX 的应用程序 我知道C执行此类操作的代码结构如下 struct input event struct timeval time unsigned short
  • 如何更改 Ubuntu 14.04 上的 php-cli 版本?

    我是 Linux 新手 在篡改时破坏了一些 php 设置 如果我执行一个包含以下内容的 php 脚本 phpinfo 它显示 php 版本为 5 6 但通过命令行 如果我运行php v它返回 7 0 版本 我想让两个版本匹配 我怎样才能修复
  • Godaddy 托管上的 CakePHP 控制台

    我一直在努力让我的 CakePHP 网站在 Godaddy 网格托管 帐户上运行 我的蛋糕应用程序设置是从帐户的子目录托管的 并且可以通过子域访问 我必须调整我的 htaccess 文件才能使其正常工作 现在我需要让 CakePHP 控制台
  • 在Linux上编译C# + WPF以便在Windows上运行

    我有一个 C 应用程序 其中某些部分是使用 WPF 编写的 Mono 不支持 可以在 Linux 上编译这个应用程序吗 最终 该应用程序将在 Windows 上运行 但它是更大框架的一部分 并且我们的整个构建过程在 Linux 上运行 因此
  • Unix 命令列出包含字符串但*不*包含另一个字符串的文件

    如何递归查看包含一个字符串且不包含另一个字符串的文件列表 另外 我的意思是评估文件的文本 而不是文件名 结论 根据评论 我最终使用了 find name html exec grep lR base maps xargs grep L ba
  • 修改linux下的路径

    虽然我认为我已经接近 Linux 专业人士 但显然我仍然是一个初学者 当我登录服务器时 我需要使用最新版本的R 统计软件 R 安装在 2 个地方 当我运行以下命令时 which R I get usr bin R 进而 R version
  • 从 PL/SQL 调用 shell 脚本,但 shell 以 grid 用户而非 oracle 身份执行

    我正在尝试使用 Runtime getRuntime exec 从 Oracle 数据库内部执行 shell 脚本 在 Red Hat 5 5 上运行的 Oracle 11 2 0 4 EE CREATE OR REPLACE proced
  • awk 子串单个字符

    这是columns txt aaa bbb 3 ccc ddd 2 eee fff 1 3 3 g 3 hhh i jjj 3 kkk ll 3 mm nn oo 3 我可以找到第二列以 b 开头的行 awk if substr 2 1 1
  • 创建 jar 文件 - 保留文件权限

    我想知道如何创建一个保留其内容的文件权限的 jar 文件 我将源代码和可执行文件打包在一个 jar 文件中 该文件将在使用前提取 人们应该能够通过运行批处理 shell 脚本文件立即运行示例和演示 然后他们应该能够修改源代码并重新编译所有内
  • 使用 grep 查找包含所有搜索字符串的行

    我有一个文件 其中包含很多与此类似的行 id 2796 some model Profile message type MODEL SAVE fields account 14 address null modification times
  • 如何使用 bash 锁定文件

    我有一个任务从远程服务器同步目录 rsync av email protected cdn cgi l email protection srv data srv data 为了使其定期运行并避免脚本 reEnter 问题 我使用 rsyn
  • 从 csv 文件中删除特定列,保持输出上的相同结构[重复]

    这个问题在这里已经有答案了 我想删除第 3 列并在输出文件中保留相同的结构 输入文件 12 10 10 10 10 1 12 23 1 45 6 7 11 2 33 45 1 2 1 2 34 5 6 I tried awk F 3 fil

随机推荐

  • word2vec深入理解及实践

    以前对于word2vec的理解就是通过训练能得到词向量 对应有两种方法 skip gram和CBOW 两者差别其实不大 但关于具体的细节也不是很了解 今天来深入理解并记录一下 理论方面 word2vec是一种基于神经网络的语言模型 是goo
  • 网络协议之ARP协议解析

    ARP协议简介 ARP Address Resolution Protocol 是个地址解析协议 最直白的说法是 在IP以太网中 当一个上层协议要发包时 有了该节点的IP地址 ARP就能提供该节点的MAC地址 OSI 模式把网络工作分为七层
  • Spring项目如何部署项目到Linux

    部署前先将项目所需的数据库添加到linux的mysql中 部署jar包到linux 修改项目pom文件 将打包方式改为jar 在pom中添加springboot插件
  • 春考计算机服务器配置,考试系统的服务器配置有什么要求?

    处理器 CPU类型 Intel 至强E5 2600 CPU型号 Xeon E5 2650 CPU频率 2GHz 智能加速主频 2 8GHz 标配CPU数量 1颗 最大CPU数量 2颗 制程工艺 32nm 三级缓存 20MB 总线规格 QPI
  • Matlab运行程序_暂停方法

    pause函数 官方文档 其调用格式为 pause 延迟数秒 必须启用暂停 此调用才能生效 暂停执行matlab 并等用户按下任意键 pause on 启用暂停设置 若想省略延迟时间 则直接使用pause函数 则将程序暂停 直到用户按任意键
  • 如何在 CentOS 中下载包含所有依赖项的 RPM 包

    翻译于ostechnix com 上 Senthil Kumar的 How To Download A RPM Package With All Dependencies In CentOS 我们可以使用curl或wget命令下载任何包 对
  • 火焰识别python_基于Python的火焰识别程序

    本期介绍一下笔者在试验数据处理时写的一个用于火焰识别的小程序 该小程序的功能是对拍摄到的火焰图像进行提取 增强 降噪和识别 并输出相应处理过的火焰图像以及火焰参数 如传播距离 面积等 该程序基于Python 3语言 用到了前面提到的图像和数
  • EditText设置监听

    在开发中有的需要对编辑框进行监听如果编辑框中没有值 登录按钮就是无法点击并且颜色为灰色 当编辑框中的值满足添加的时候 按钮可以点击同时颜色发生改变 由于自己是个菜鸟 代码中也有注释 也比较简单 有什么bug希望各位大神也能指点一二 acti
  • SSRS使用MySql作为数据源遇到的问题。

    因为工作需求 SSRS需要取到MySql数据源 还好有了ODBC 谷歌了很多 都是不完整的Solution 放上完整版的供大家评价参考 下面是StepByStep 问题1 使用ODBC数据源 填入正确的MySql连接字符串 却显示 ERRO
  • Python File seek() 方法和File read()方法

    read 方法用于从文件读取指定的字节数 如果未给定或为负则读取所有 语法 read 方法语法如下 fileObject read size 参数 size 从文件中读取的字节数 默认为 1 表示读取整个文件 返回值 返回从字符串中读取的字
  • 最小花费爬楼梯(C语言)

    本周第二题 数组的每个索引做为一个阶梯 第 i个阶梯对应着一个非负数的体力花费值 索引从0开始 每当你爬上一个阶梯你都要花费对应的体力花费值 然后你可以选择继续爬一个阶梯或者爬两个阶梯 您需要找到达到楼层顶部的最低花费 在开始时 你可以选择
  • 53. 翻转字符串

    思路 首先翻转字符串整体 然后对于每个单词进行翻转 两次翻转的函数使用同一个函数 翻转函数的思路 使用队列 将String转成char 然后反过来存储 下面就是使用的这种方法 用两个指针 进行前后字符的对换 StringBuilder类中有
  • 使用Retrofit过程中碰到的一些问题(持续更新。。。。)

    1 服务端成功返回数据 但解析返回的json格式失败 解决方法 1 在使用默认推荐的JSON解析配置 GsonConverterFactory create 时 我们自己创建的json对象基类中的各个变量名称要与服务器返回的JSON中的各名
  • 深度学习RuntimeError: CUDA error: CUBLAS_STATUS_EXECUTION_FAILED when calling `cublasSgemm( handle, opa,

    错误记录 在使用GPU跑程序时 前面加载数据是没问题的 后面relu 开始报错 错误为 RuntimeError CUDA error CUBLAS STATUS EXECUTION FAILED when calling cublasSg
  • HDU - 1002 A + B Problem II

    I have a very simple problem for you Given two integers A and B your job is to calculate the Sum of A B Input The first
  • 【golang】error parsing regexp: invalid or unsupported Perl syntax (正则表达式校验密码)

    要在 Go 中编写密码校验规则 确保密码不少于8位且包含数字和字母 你可以使用正则表达式和 Go 的 regexp 包来实现 以下是一个示例代码 错误示范 package main import fmt regexp func valida
  • 一、机器学习简介

    一 机器学习简介 1 1 机器学习简介 人工智能 Artificial Intelligence 简称AI 是对人的意识 思维过程进行模拟的一门新学科 如今 人工智能从虚无缥缈的科学幻想变成了现实 计算机科学家们在 机器学习 Machine
  • sc_project

    服务计算项目 总结报告 项目介绍 工作说明 实现效果 实验心得 项目介绍 本次项目是一个文章的博客 其功能有用户的登录 查找获取文章 删除文章 编辑评论 查看评论等等 除此之外用户登录时还会获得TOKEN 而用户添加评论时需要进行TOKEN
  • c++使用继承类实现异常处理

    sales h pragma once include
  • Linux Container(lxc)分析和配置使用

    前提 本文翻译 有道翻译 自linux container lxc 根据重点摘录学习 介绍 最好将容器化定义为 通过操作系统中的特性启用的进程隔离机制 容器是与系统其他部分隔离的一个或多个进程的集合 Containers VMs lxc通过