LXD 2.0 系列(三):你的第一個(gè) LXD 容器
這是 LXD 2.0 系列的第三篇博客。
由于在管理 LXD 容器時(shí)涉及到大量的命令,所以這篇文章的篇幅是比較長(zhǎng)的,如果你更喜歡使用同樣的命令來(lái)快速的一步步實(shí)現(xiàn)整個(gè)過(guò)程,你可以嘗試我們的在線示例!
創(chuàng)建并啟動(dòng)一個(gè)新的容器
正如我在先前的文章中提到的一樣,LXD 命令行客戶(hù)端預(yù)配置了幾個(gè)鏡像源。Ubuntu 的所有發(fā)行版和架構(gòu)平臺(tái)全都提供了官方鏡像,但是對(duì)于其他的發(fā)行版也有大量的非官方鏡像,那些鏡像都是由社區(qū)制作并且被 LXC 上游貢獻(xiàn)者所維護(hù)。
Ubuntu
如果你想要支持最為完善的 Ubuntu 版本,你可以按照下面的去做:
- lxc launch ubuntu:
注意,這里意味著會(huì)隨著 Ubuntu LTS 的發(fā)布而變化。因此,如果用于腳本,你需要指明你具體安裝的版本(參見(jiàn)下面)。
Ubuntu14.04 LTS
得到***更新的、已經(jīng)測(cè)試過(guò)的、穩(wěn)定的 Ubuntu 14.04 LTS 鏡像,你可以簡(jiǎn)單的執(zhí)行:
- lxc launch ubuntu:14.04
在該模式下,會(huì)指定一個(gè)隨機(jī)的容器名。
如果你更喜歡指定一個(gè)你自己的名字,你可以這樣做:
- lxc launch ubuntu:14.04 c1
如果你想要指定一個(gè)特定的體系架構(gòu)(非主流平臺(tái)),比如 32 位 Intel 鏡像,你可以這樣做:
- lxc launch ubuntu:14.04/i386 c2
當(dāng)前的 Ubuntu 開(kāi)發(fā)版本
上面使用的“ubuntu:”遠(yuǎn)程倉(cāng)庫(kù)只會(huì)給你提供官方的并經(jīng)過(guò)測(cè)試的 Ubuntu 鏡像。但是如果你想要未經(jīng)測(cè)試過(guò)的日常構(gòu)建版本,開(kāi)發(fā)版可能對(duì)你來(lái)說(shuō)是合適的,你需要使用“ubuntu-daily:”遠(yuǎn)程倉(cāng)庫(kù)。
- lxc launch ubuntu-daily:devel c3
在這個(gè)例子中,將會(huì)自動(dòng)選中***的 Ubuntu 開(kāi)發(fā)版本。
你也可以更加精確,比如你可以使用代號(hào)名:
- lxc launch ubuntu-daily:xenial c4
***的Alpine Linux
Alpine 鏡像可以在“Images:”遠(yuǎn)程倉(cāng)庫(kù)中找到,通過(guò)如下命令執(zhí)行:
- lxc launch images:alpine/3.3/amd64 c5
其他
全部的 Ubuntu 鏡像列表可以這樣獲得:
- lxc image list ubuntu:
- lxc image list ubuntu-daily:
全部的非官方鏡像:
- lxc image list images:
某個(gè)給定的原程倉(cāng)庫(kù)的全部別名(易記名稱(chēng))可以這樣獲得(比如對(duì)于“ubuntu:”遠(yuǎn)程倉(cāng)庫(kù)):
- lxc image alias list ubuntu:
創(chuàng)建但不啟動(dòng)一個(gè)容器
如果你想創(chuàng)建一個(gè)容器或者一批容器,但是你不想馬上啟動(dòng)它們,你可以使用lxc init替換掉lxc launch。所有的選項(xiàng)都是相同的,唯一的不同就是它并不會(huì)在你創(chuàng)建完成之后啟動(dòng)容器。
- lxc init ubuntu:
關(guān)于你的容器的信息
列出所有的容器
要列出你的所有容器,你可以這樣這做:
- lxc list
有大量的選項(xiàng)供你選擇來(lái)改變被顯示出來(lái)的列。在一個(gè)擁有大量容器的系統(tǒng)上,默認(rèn)顯示的列可能會(huì)有點(diǎn)慢(因?yàn)楸仨毇@取容器中的網(wǎng)絡(luò)信息),你可以這樣做來(lái)避免這種情況:
- lxc list --fast
上面的命令顯示了另外一套列的組合,這個(gè)組合在服務(wù)器端需要處理的信息更少。
你也可以基于名字或者屬性來(lái)過(guò)濾掉一些東西:
- stgraber@dakara:~$ lxc list security.privileged=true
- +------+---------+---------------------+-----------------------------------------------+------------+-----------+
- | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
- +------+---------+---------------------+-----------------------------------------------+------------+-----------+
- | suse | RUNNING | 172.17.0.105 (eth0) | 2607:f2c0:f00f:2700:216:3eff:fef2:aff4 (eth0) | PERSISTENT | 0 |
- +------+---------+---------------------+-----------------------------------------------+------------+-----------+
在這個(gè)例子中,只有那些特權(quán)容器(禁用了用戶(hù)命名空間)才會(huì)被列出來(lái)。
- stgraber@dakara:~$ lxc list --fast alpine
- +-------------+---------+--------------+----------------------+----------+------------+
- | NAME | STATE | ARCHITECTURE | CREATED AT | PROFILES | TYPE |
- +-------------+---------+--------------+----------------------+----------+------------+
- | alpine | RUNNING | x86_64 | 2016/03/20 02:11 UTC | default | PERSISTENT |
- +-------------+---------+--------------+----------------------+----------+------------+
- | alpine-edge | RUNNING | x86_64 | 2016/03/20 02:19 UTC | default | PERSISTENT |
- +-------------+---------+--------------+----------------------+----------+------------+
在這個(gè)例子中,只有在名字中帶有“alpine”的容器才會(huì)被列出來(lái)(也支持復(fù)雜的正則表達(dá)式)。
獲取容器的詳細(xì)信息
由于 list 命令顯然不能以一種友好的可讀方式顯示容器的所有信息,因此你可以使用如下方式來(lái)查詢(xún)單個(gè)容器的信息:
- lxc info <container>
例如:
- stgraber@dakara:~$ lxc info zerotier
- Name: zerotier
- Architecture: x86_64
- Created: 2016/02/20 20:01 UTC
- Status: Running
- Type: persistent
- Profiles: default
- Pid: 31715
- Processes: 32
- Ips:
- eth0: inet 172.17.0.101
- eth0: inet6 2607:f2c0:f00f:2700:216:3eff:feec:65a8
- eth0: inet6 fe80::216:3eff:feec:65a8
- lo: inet 127.0.0.1
- lo: inet6 ::1
- lxcbr0: inet 10.0.3.1
- lxcbr0: inet6 fe80::c0a4:ceff:fe52:4d51
- zt0: inet 29.17.181.59
- zt0: inet6 fd80:56c2:e21c:0:199:9379:e711:b3e1
- zt0: inet6 fe80::79:e7ff:fe0d:5123
- Snapshots:
- zerotier/blah (taken at 2016/03/08 23:55 UTC) (stateless)
生命周期管理命令
這些命令對(duì)于任何容器或者虛擬機(jī)管理器或許都是最普通的命令,但是它們?nèi)匀恍枰v到。
所有的這些命令在批量操作時(shí)都能接受多個(gè)容器名。
啟動(dòng)
啟動(dòng)一個(gè)容器就向下面一樣簡(jiǎn)單:
- lxc start <container>
停止
停止一個(gè)容器可以這樣來(lái)完成:
- lxc stop <container>
如果容器不合作(即沒(méi)有對(duì)發(fā)出的 SIGPWR 信號(hào)產(chǎn)生回應(yīng)),這時(shí)候,你可以使用下面的方式強(qiáng)制執(zhí)行:
- lxc stop <container> --force
重啟
通過(guò)下面的命令來(lái)重啟一個(gè)容器:
- lxc restart <container>
如果容器不合作(即沒(méi)有對(duì)發(fā)出的 SIGINT 信號(hào)產(chǎn)生回應(yīng)),你可以使用下面的方式強(qiáng)制執(zhí)行:
- lxc restart <container> --force
暫停
你也可以“暫停”一個(gè)容器,在這種模式下,所有的容器任務(wù)將會(huì)被發(fā)送相同的 SIGSTOP 信號(hào),這也意味著它們將仍然是可見(jiàn)的,并且仍然會(huì)占用內(nèi)存,但是它們不會(huì)從調(diào)度程序中得到任何的 CPU 時(shí)間片。
如果你有一個(gè)很占用 CPU 的容器,而這個(gè)容器需要一點(diǎn)時(shí)間來(lái)啟動(dòng),但是你卻并不會(huì)經(jīng)常用到它。這時(shí)候,你可以先啟動(dòng)它,然后將它暫停,并在你需要它的時(shí)候再啟動(dòng)它。
- lxc pause <container>
刪除
***,如果你不需要這個(gè)容器了,你可以用下面的命令刪除它:
- lxc delete <container>
注意,如果容器還處于運(yùn)行狀態(tài)時(shí)你將必須使用“-force”。
容器的配置
LXD 擁有大量的容器配置設(shè)定,包括資源限制,容器啟動(dòng)控制以及對(duì)各種設(shè)備是否允許訪問(wèn)的配置選項(xiàng)。完整的清單因?yàn)樘L(zhǎng)所以并沒(méi)有在本文中列出,但是,你可以從[這里]獲取它。
就設(shè)備而言,LXD 當(dāng)前支持下面列出的這些設(shè)備類(lèi)型:
- 磁盤(pán) 既可以是一塊物理磁盤(pán),也可以只是一個(gè)被掛掛載到容器上的分區(qū),還可以是一個(gè)來(lái)自主機(jī)的綁定掛載路徑。
- 網(wǎng)絡(luò)接口卡 一塊網(wǎng)卡。它可以是一塊橋接的虛擬網(wǎng)卡,或者是一塊點(diǎn)對(duì)點(diǎn)設(shè)備,還可以是一塊以太局域網(wǎng)設(shè)備或者一塊已經(jīng)被連接到容器的真實(shí)物理接口。
- unix 塊設(shè)備 一個(gè) UNIX 塊設(shè)備,比如 /dev/sda
- unix 字符設(shè)備 一個(gè) UNIX 字符設(shè)備,比如 /dev/kvm
- none 這種特殊類(lèi)型被用來(lái)隱藏那種可以通過(guò)配置文件被繼承的設(shè)備。
配置 profile 文件
所有可用的配置文件列表可以這樣獲?。?/p>
- lxc profile list
為了看到給定配置文件的內(nèi)容,最簡(jiǎn)單的方式是這樣做:
- lxc profile show <profile>
你可能想要改變文件里面的內(nèi)容,可以這樣做:
- lxc profile edit <profile>
你可以使用如下命令來(lái)改變應(yīng)用到給定容器的配置文件列表:
- lxc profile apply <container> <profile1>,<profile2>,<profile3>,...
本地配置
有些配置是某個(gè)容器特定的,你并不想將它放到配置文件中,你可直接對(duì)容器設(shè)置它們:
- lxc config edit <container>
上面的命令做的和“profile edit”命令是一樣。
如果不想在文本編輯器中打開(kāi)整個(gè)文件的內(nèi)容,你也可以像這樣修改單獨(dú)的配置:
- lxc config set <container> <key> <value>
或者添加設(shè)備,例如:
- lxc config device add my-container kvm unix-char path=/dev/kvm
上面的命令將會(huì)為名為“my-container”的容器設(shè)置一個(gè) /dev/kvm 項(xiàng)。
對(duì)一個(gè)配置文件使用lxc profile set和lxc profile device add命令也能實(shí)現(xiàn)上面的功能。
讀取配置
你可以使用如下命令來(lái)讀取容器的本地配置:
- lxc config show <container>
或者得到已經(jīng)被展開(kāi)了的配置(包含了所有的配置值):
- lxc config show --expanded <container>
例如:
- stgraber@dakara:~$ lxc config show --expanded zerotier
- name: zerotier
- profiles:
- - default
- config:
- security.nesting: "true"
- user.a: b
- volatile.base_image: a49d26ce5808075f5175bf31f5cb90561f5023dcd408da8ac5e834096d46b2d8
- volatile.eth0.hwaddr: 00:16:3e:ec:65:a8
- volatile.last_state.idmap: '[{"Isuid":true,"Isgid":false,"Hostid":100000,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":100000,"Nsid":0,"Maprange":65536}]'
- devices:
- eth0:
- name: eth0
- nictype: macvlan
- parent: eth0
- type: nic
- limits.ingress: 10Mbit
- limits.egress: 10Mbit
- root:
- path: /
- size: 30GB
- type: disk
- tun:
- path: /dev/net/tun
- type: unix-char
- ephemeral: false
這樣做可以很方便的檢查有哪些配置屬性被應(yīng)用到了給定的容器。
實(shí)時(shí)配置更新
注意,除非在文檔中已經(jīng)被明確指出,否則所有的配置值和設(shè)備項(xiàng)的設(shè)置都會(huì)對(duì)容器實(shí)時(shí)發(fā)生影響。這意味著在不重啟正在運(yùn)行的容器的情況下,你可以添加和移除某些設(shè)備或者修改安全配置文件。
獲得一個(gè) shell
LXD 允許你直接在容器中執(zhí)行任務(wù)。最常用的做法是在容器中得到一個(gè) shell 或者執(zhí)行一些管理員任務(wù)。
和 SSH 相比,這樣做的好處是你不需要容器是網(wǎng)絡(luò)可達(dá)的,也不需要任何軟件和特定的配置。
執(zhí)行環(huán)境
與 LXD 在容器內(nèi)執(zhí)行命令的方式相比,有一點(diǎn)是不同的,那就是 shell 并不是在容器中運(yùn)行。這也意味著容器不知道使用的是什么樣的 shell,以及設(shè)置了什么樣的環(huán)境變量和你的家目錄在哪里。
通過(guò) LXD 來(lái)執(zhí)行命令總是使用最小的路徑環(huán)境變量設(shè)置,并且 HOME 環(huán)境變量必定為 /root,以容器的超級(jí)用戶(hù)身份來(lái)執(zhí)行(即 uid 為 0,gid 為 0)。
其他的環(huán)境變量可以通過(guò)命令行來(lái)設(shè)置,或者在“environment.”配置中設(shè)置成***環(huán)境變量。
執(zhí)行命令
在容器中獲得一個(gè) shell 可以簡(jiǎn)單的執(zhí)行下列命令得到:
- lxc exec <container> bash
當(dāng)然,這樣做的前提是容器內(nèi)已經(jīng)安裝了 bash。
更復(fù)雜的命令要求使用分隔符來(lái)合理分隔參數(shù)。
- lxc exec <container> -- ls -lh /
如果想要設(shè)置或者重寫(xiě)變量,你可以使用“-env”參數(shù),例如:
- stgraber@dakara:~$ lxc exec zerotier --env mykey=myvalue env | grep mykey
- mykey=myvalue
管理文件
因?yàn)?LXD 可以直接訪問(wèn)容器的文件系統(tǒng),因此,它可以直接讀取和寫(xiě)入容器中的任意文件。當(dāng)我們需要提取日志文件或者與容器傳遞文件時(shí),這個(gè)特性是很有用的。
從容器中取回一個(gè)文件
想要從容器中獲得一個(gè)文件,簡(jiǎn)單的執(zhí)行下列命令:
- lxc file pull <container>/<path> <dest>
例如:
- stgraber@dakara:~$ lxc file pull zerotier/etc/hosts hosts
或者將它讀取到標(biāo)準(zhǔn)輸出:
- stgraber@dakara:~$ lxc file pull zerotier/etc/hosts -
- 127.0.0.1 localhost
- # The following lines are desirable for IPv6 capable hosts
- ::1 ip6-localhost ip6-loopback
- fe00::0 ip6-localnet
- ff00::0 ip6-mcastprefix
- ff02::1 ip6-allnodes
- ff02::2 ip6-allrouters
- ff02::3 ip6-allhosts
向容器發(fā)送一個(gè)文件
發(fā)送以另一種簡(jiǎn)單的方式完成:
- lxc file push <source> <container>/<path>
直接編輯一個(gè)文件
編輯是一個(gè)方便的功能,其實(shí)就是簡(jiǎn)單的提取一個(gè)給定的路徑,在你的默認(rèn)文本編輯器中打開(kāi)它,在你關(guān)閉編輯器時(shí)會(huì)自動(dòng)將編輯的內(nèi)容保存到容器。
- lxc file edit <container>/<path>
快照管理
LXD 允許你對(duì)容器執(zhí)行快照功能并恢復(fù)它??煺瞻巳萜髟谀骋粫r(shí)刻的完整狀態(tài)(如果-stateful被使用的話將會(huì)包括運(yùn)行狀態(tài)),這也意味著所有的容器配置,容器設(shè)備和容器文件系統(tǒng)也會(huì)被保存。
創(chuàng)建一個(gè)快照
你可以使用下面的命令來(lái)執(zhí)行快照功能:
- lxc snapshot <container>
命令執(zhí)行完成之后將會(huì)生成名為snapX(X 為一個(gè)自動(dòng)增長(zhǎng)的數(shù))的記錄。
除此之外,你還可以使用如下命令命名你的快照:
- lxc snapshot <container> <snapshot name>
列出所有的快照
一個(gè)容器的所有快照的數(shù)量可以使用lxc list來(lái)得到,但是具體的快照列表只能執(zhí)行l(wèi)xc info命令才能看到。
- lxc info <container>
恢復(fù)快照
為了恢復(fù)快照,你可以簡(jiǎn)單的執(zhí)行下面的命令:
- lxc restore <container> <snapshot name>
給快照重命名
可以使用如下命令來(lái)給快照重命名:
- lxc move <container>/<snapshot name> <container>/<new snapshot name>
從快照中創(chuàng)建一個(gè)新的容器
你可以使用快照來(lái)創(chuàng)建一個(gè)新的容器,而這個(gè)新的容器除了一些可變的信息將會(huì)被重置之外(例如 MAC 地址)其余所有信息都將和快照完全相同。
- lxc copy <source container>/<snapshot name> <destination container>
刪除一個(gè)快照
***,你可以執(zhí)行下面的命令來(lái)刪除一個(gè)快照:
- lxc delete <container>/<snapshot name>
克隆并重命名
得到一個(gè)純凈的發(fā)行版鏡像總是讓人感到愉悅,但是,有時(shí)候你想要安裝一系列的軟件到你的容器中,這時(shí),你需要配置它然后將它分支成多個(gè)其他的容器。
復(fù)制一個(gè)容器
為了復(fù)制一個(gè)容器并有效的將它克隆到一個(gè)新的容器中,你可以執(zhí)行下面的命令:
- lxc copy <source container> <destination container>
目標(biāo)容器在所有方面將會(huì)完全和源容器等同。除了新的容器沒(méi)有任何源容器的快照以及一些可變值將會(huì)被重置之外(例如 MAC 地址)。
移動(dòng)一個(gè)快照
LXD 允許你復(fù)制容器并在主機(jī)之間移動(dòng)它。但是,關(guān)于這一點(diǎn)將在后面的文章中介紹。
現(xiàn)在,“move”命令將會(huì)被用作給容器重命名。
- lxc move <old name> <new name>
唯一的要求就是當(dāng)容器應(yīng)該被停止,容器內(nèi)的任何事情都會(huì)被保存成它本來(lái)的樣子,包括可變化的信息(類(lèi)似 MAC 地址等)。
結(jié)論
這篇如此長(zhǎng)的文章介紹了大多數(shù)你可能會(huì)在日常操作中使用到的命令。
很顯然,這些如此之多的命令都會(huì)有不少選項(xiàng),可以讓你的命令更加有效率,或者可以讓你指定你的 LXD 容器的某個(gè)具體方面。***的學(xué)習(xí)這些命令的方式就是深入學(xué)習(xí)它們的幫助文檔( -help)。
更多信息
LXD 的主要網(wǎng)站是:https://linuxcontainers.org/lxd
Github 上的開(kāi)發(fā)動(dòng)態(tài): https://github.com/lxc/lxd
郵件列表支持:https://lists.linuxcontainers.org
IRC 支持: #lxcontainers on irc.freenode.net
如果你不想或者不能在你的機(jī)器上安裝 LXD,你可以試試在線版本!