和"真正的虚拟机环境"不一样, "容器"(container)只能在Linux上虚拟Linux, 不能虚拟WIndows, 由于它不能虚拟硬件. 可是基于容器的虚拟机占用的资源很小--在一台中等的Linux服务器上, 建立几百个虚拟机是垂手可得的事情. 这种"容器"虚拟化技术, 又称为OS-Level虚拟化,也就是"操做系统级虚拟化".html
LXC(ontainer)是Linux内核支持的技术, 这个好处就会安全性. 管理LXC容器的方式又两种:一种是使用Libvirt工具来管理,一种是使用lxc自己提供的工具管理. 二者各有优劣: 前者使用方便, 可是缺少Apparmor保护,不安全; 后者使用性不够友好, 可是默认带了Apparmor规则,能够保证安全性.linux
使用apt命令就能够安装lxcapache
# sudo apt install lxc
LXC能够建立两种不一样的容器:ubuntu
普通容器又不少限制(好比没法建立设备节点),不过也更安全(不会危害到主机),由于这种容器的root用户,其实映射到主机上的一个普通用户vim
建立容器可使用交互式和非交互式centos
# 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
非交互建立其实就是一次性将操做传递给模板而已,下面咱们介绍一个各个参数:服务器
简单列出 # 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
进入容器的方式又三种:网络
进入容器 # 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软件包提供的newuidmap和newgidmap程序来进行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
在大规模部署的状况下,咱们通常不会逐个去手动的建立容器,而是搞好一个后直接克隆.
"克隆"要么是其余容器的一份拷贝,要么是其余容器的一份快照
拷贝:完整的复制原来的容器,所占的空间和原来的容器同样大
快照:利用后台文件系统的快照功能,建立一个很小的新容器,在发生写操做时才进行复制
要想使快照拥有这个写时复制的特性,须要一个特殊存储系统,支持快照的存储方式有: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启动的时候会建立一个叫作lxcbr0的桥接设备,使用默认设置建立的容器都会有一个vethxxx虚拟网卡(每一个容器都有一个虚拟网卡与之绑定),这个网卡会被桥接lxcbr0上.
默认状况下,容器的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(或其余物理网卡)的设备
注意:只有特权容器才能被外界访问,普通容器是没法被外界访问的
在宿主主机上安装桥接工具包
$ 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