和"真正的虛擬機環境"不一樣, "容器"(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