最佳虛擬容器LXC


最佳虛擬容器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范圍.

p1

圖1

從圖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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM