LXD 2.0 系列(三):你的第一個 LXD 容器
這是 LXD 2.0 系列的第三篇博客。
由于在管理 LXD 容器時涉及到大量的命令,所以這篇文章的篇幅是比較長的,如果你更喜歡使用同樣的命令來快速的一步步實現(xiàn)整個過程,你可以嘗試我們的在線示例!
創(chuàng)建并啟動一個新的容器
正如我在先前的文章中提到的一樣,LXD 命令行客戶端預配置了幾個鏡像源。Ubuntu 的所有發(fā)行版和架構平臺全都提供了官方鏡像,但是對于其他的發(fā)行版也有大量的非官方鏡像,那些鏡像都是由社區(qū)制作并且被 LXC 上游貢獻者所維護。
Ubuntu
如果你想要支持最為完善的 Ubuntu 版本,你可以按照下面的去做:
- lxc launch ubuntu:
注意,這里意味著會隨著 Ubuntu LTS 的發(fā)布而變化。因此,如果用于腳本,你需要指明你具體安裝的版本(參見下面)。
Ubuntu14.04 LTS
得到***更新的、已經(jīng)測試過的、穩(wěn)定的 Ubuntu 14.04 LTS 鏡像,你可以簡單的執(zhí)行:
- lxc launch ubuntu:14.04
在該模式下,會指定一個隨機的容器名。
如果你更喜歡指定一個你自己的名字,你可以這樣做:
- lxc launch ubuntu:14.04 c1
如果你想要指定一個特定的體系架構(非主流平臺),比如 32 位 Intel 鏡像,你可以這樣做:
- lxc launch ubuntu:14.04/i386 c2
當前的 Ubuntu 開發(fā)版本
上面使用的“ubuntu:”遠程倉庫只會給你提供官方的并經(jīng)過測試的 Ubuntu 鏡像。但是如果你想要未經(jīng)測試過的日常構建版本,開發(fā)版可能對你來說是合適的,你需要使用“ubuntu-daily:”遠程倉庫。
- lxc launch ubuntu-daily:devel c3
在這個例子中,將會自動選中***的 Ubuntu 開發(fā)版本。
你也可以更加精確,比如你可以使用代號名:
- lxc launch ubuntu-daily:xenial c4
***的Alpine Linux
Alpine 鏡像可以在“Images:”遠程倉庫中找到,通過如下命令執(zhí)行:
- lxc launch images:alpine/3.3/amd64 c5
其他
全部的 Ubuntu 鏡像列表可以這樣獲得:
- lxc image list ubuntu:
- lxc image list ubuntu-daily:
全部的非官方鏡像:
- lxc image list images:
某個給定的原程倉庫的全部別名(易記名稱)可以這樣獲得(比如對于“ubuntu:”遠程倉庫):
- lxc image alias list ubuntu:
創(chuàng)建但不啟動一個容器
如果你想創(chuàng)建一個容器或者一批容器,但是你不想馬上啟動它們,你可以使用lxc init替換掉lxc launch。所有的選項都是相同的,唯一的不同就是它并不會在你創(chuàng)建完成之后啟動容器。
- lxc init ubuntu:
關于你的容器的信息
列出所有的容器
要列出你的所有容器,你可以這樣這做:
- lxc list
有大量的選項供你選擇來改變被顯示出來的列。在一個擁有大量容器的系統(tǒng)上,默認顯示的列可能會有點慢(因為必須獲取容器中的網(wǎng)絡信息),你可以這樣做來避免這種情況:
- lxc list --fast
上面的命令顯示了另外一套列的組合,這個組合在服務器端需要處理的信息更少。
你也可以基于名字或者屬性來過濾掉一些東西:
- 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 |
- +------+---------+---------------------+-----------------------------------------------+------------+-----------+
在這個例子中,只有那些特權容器(禁用了用戶命名空間)才會被列出來。
- 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 |
- +-------------+---------+--------------+----------------------+----------+------------+
在這個例子中,只有在名字中帶有“alpine”的容器才會被列出來(也支持復雜的正則表達式)。
獲取容器的詳細信息
由于 list 命令顯然不能以一種友好的可讀方式顯示容器的所有信息,因此你可以使用如下方式來查詢單個容器的信息:
- 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)
生命周期管理命令
這些命令對于任何容器或者虛擬機管理器或許都是最普通的命令,但是它們仍然需要講到。
所有的這些命令在批量操作時都能接受多個容器名。
啟動
啟動一個容器就向下面一樣簡單:
- lxc start <container>
停止
停止一個容器可以這樣來完成:
- lxc stop <container>
如果容器不合作(即沒有對發(fā)出的 SIGPWR 信號產(chǎn)生回應),這時候,你可以使用下面的方式強制執(zhí)行:
- lxc stop <container> --force
重啟
通過下面的命令來重啟一個容器:
- lxc restart <container>
如果容器不合作(即沒有對發(fā)出的 SIGINT 信號產(chǎn)生回應),你可以使用下面的方式強制執(zhí)行:
- lxc restart <container> --force
暫停
你也可以“暫停”一個容器,在這種模式下,所有的容器任務將會被發(fā)送相同的 SIGSTOP 信號,這也意味著它們將仍然是可見的,并且仍然會占用內存,但是它們不會從調度程序中得到任何的 CPU 時間片。
如果你有一個很占用 CPU 的容器,而這個容器需要一點時間來啟動,但是你卻并不會經(jīng)常用到它。這時候,你可以先啟動它,然后將它暫停,并在你需要它的時候再啟動它。
- lxc pause <container>
刪除
***,如果你不需要這個容器了,你可以用下面的命令刪除它:
- lxc delete <container>
注意,如果容器還處于運行狀態(tài)時你將必須使用“-force”。
容器的配置
LXD 擁有大量的容器配置設定,包括資源限制,容器啟動控制以及對各種設備是否允許訪問的配置選項。完整的清單因為太長所以并沒有在本文中列出,但是,你可以從[這里]獲取它。
就設備而言,LXD 當前支持下面列出的這些設備類型:
- 磁盤 既可以是一塊物理磁盤,也可以只是一個被掛掛載到容器上的分區(qū),還可以是一個來自主機的綁定掛載路徑。
- 網(wǎng)絡接口卡 一塊網(wǎng)卡。它可以是一塊橋接的虛擬網(wǎng)卡,或者是一塊點對點設備,還可以是一塊以太局域網(wǎng)設備或者一塊已經(jīng)被連接到容器的真實物理接口。
- unix 塊設備 一個 UNIX 塊設備,比如 /dev/sda
- unix 字符設備 一個 UNIX 字符設備,比如 /dev/kvm
- none 這種特殊類型被用來隱藏那種可以通過配置文件被繼承的設備。
配置 profile 文件
所有可用的配置文件列表可以這樣獲取:
- lxc profile list
為了看到給定配置文件的內容,最簡單的方式是這樣做:
- lxc profile show <profile>
你可能想要改變文件里面的內容,可以這樣做:
- lxc profile edit <profile>
你可以使用如下命令來改變應用到給定容器的配置文件列表:
- lxc profile apply <container> <profile1>,<profile2>,<profile3>,...
本地配置
有些配置是某個容器特定的,你并不想將它放到配置文件中,你可直接對容器設置它們:
- lxc config edit <container>
上面的命令做的和“profile edit”命令是一樣。
如果不想在文本編輯器中打開整個文件的內容,你也可以像這樣修改單獨的配置:
- lxc config set <container> <key> <value>
或者添加設備,例如:
- lxc config device add my-container kvm unix-char path=/dev/kvm
上面的命令將會為名為“my-container”的容器設置一個 /dev/kvm 項。
對一個配置文件使用lxc profile set和lxc profile device add命令也能實現(xiàn)上面的功能。
讀取配置
你可以使用如下命令來讀取容器的本地配置:
- lxc config show <container>
或者得到已經(jīng)被展開了的配置(包含了所有的配置值):
- 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
這樣做可以很方便的檢查有哪些配置屬性被應用到了給定的容器。
實時配置更新
注意,除非在文檔中已經(jīng)被明確指出,否則所有的配置值和設備項的設置都會對容器實時發(fā)生影響。這意味著在不重啟正在運行的容器的情況下,你可以添加和移除某些設備或者修改安全配置文件。
獲得一個 shell
LXD 允許你直接在容器中執(zhí)行任務。最常用的做法是在容器中得到一個 shell 或者執(zhí)行一些管理員任務。
和 SSH 相比,這樣做的好處是你不需要容器是網(wǎng)絡可達的,也不需要任何軟件和特定的配置。
執(zhí)行環(huán)境
與 LXD 在容器內執(zhí)行命令的方式相比,有一點是不同的,那就是 shell 并不是在容器中運行。這也意味著容器不知道使用的是什么樣的 shell,以及設置了什么樣的環(huán)境變量和你的家目錄在哪里。
通過 LXD 來執(zhí)行命令總是使用最小的路徑環(huán)境變量設置,并且 HOME 環(huán)境變量必定為 /root,以容器的超級用戶身份來執(zhí)行(即 uid 為 0,gid 為 0)。
其他的環(huán)境變量可以通過命令行來設置,或者在“environment.”配置中設置成***環(huán)境變量。
執(zhí)行命令
在容器中獲得一個 shell 可以簡單的執(zhí)行下列命令得到:
- lxc exec <container> bash
當然,這樣做的前提是容器內已經(jīng)安裝了 bash。
更復雜的命令要求使用分隔符來合理分隔參數(shù)。
- lxc exec <container> -- ls -lh /
如果想要設置或者重寫變量,你可以使用“-env”參數(shù),例如:
- stgraber@dakara:~$ lxc exec zerotier --env mykey=myvalue env | grep mykey
- mykey=myvalue
管理文件
因為 LXD 可以直接訪問容器的文件系統(tǒng),因此,它可以直接讀取和寫入容器中的任意文件。當我們需要提取日志文件或者與容器傳遞文件時,這個特性是很有用的。
從容器中取回一個文件
想要從容器中獲得一個文件,簡單的執(zhí)行下列命令:
- lxc file pull <container>/<path> <dest>
例如:
- stgraber@dakara:~$ lxc file pull zerotier/etc/hosts hosts
或者將它讀取到標準輸出:
- 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ā)送一個文件
發(fā)送以另一種簡單的方式完成:
- lxc file push <source> <container>/<path>
直接編輯一個文件
編輯是一個方便的功能,其實就是簡單的提取一個給定的路徑,在你的默認文本編輯器中打開它,在你關閉編輯器時會自動將編輯的內容保存到容器。
- lxc file edit <container>/<path>
快照管理
LXD 允許你對容器執(zhí)行快照功能并恢復它。快照包括了容器在某一時刻的完整狀態(tài)(如果-stateful被使用的話將會包括運行狀態(tài)),這也意味著所有的容器配置,容器設備和容器文件系統(tǒng)也會被保存。
創(chuàng)建一個快照
你可以使用下面的命令來執(zhí)行快照功能:
- lxc snapshot <container>
命令執(zhí)行完成之后將會生成名為snapX(X 為一個自動增長的數(shù))的記錄。
除此之外,你還可以使用如下命令命名你的快照:
- lxc snapshot <container> <snapshot name>
列出所有的快照
一個容器的所有快照的數(shù)量可以使用lxc list來得到,但是具體的快照列表只能執(zhí)行l(wèi)xc info命令才能看到。
- lxc info <container>
恢復快照
為了恢復快照,你可以簡單的執(zhí)行下面的命令:
- lxc restore <container> <snapshot name>
給快照重命名
可以使用如下命令來給快照重命名:
- lxc move <container>/<snapshot name> <container>/<new snapshot name>
從快照中創(chuàng)建一個新的容器
你可以使用快照來創(chuàng)建一個新的容器,而這個新的容器除了一些可變的信息將會被重置之外(例如 MAC 地址)其余所有信息都將和快照完全相同。
- lxc copy <source container>/<snapshot name> <destination container>
刪除一個快照
***,你可以執(zhí)行下面的命令來刪除一個快照:
- lxc delete <container>/<snapshot name>
克隆并重命名
得到一個純凈的發(fā)行版鏡像總是讓人感到愉悅,但是,有時候你想要安裝一系列的軟件到你的容器中,這時,你需要配置它然后將它分支成多個其他的容器。
復制一個容器
為了復制一個容器并有效的將它克隆到一個新的容器中,你可以執(zhí)行下面的命令:
- lxc copy <source container> <destination container>
目標容器在所有方面將會完全和源容器等同。除了新的容器沒有任何源容器的快照以及一些可變值將會被重置之外(例如 MAC 地址)。
移動一個快照
LXD 允許你復制容器并在主機之間移動它。但是,關于這一點將在后面的文章中介紹。
現(xiàn)在,“move”命令將會被用作給容器重命名。
- lxc move <old name> <new name>
唯一的要求就是當容器應該被停止,容器內的任何事情都會被保存成它本來的樣子,包括可變化的信息(類似 MAC 地址等)。
結論
這篇如此長的文章介紹了大多數(shù)你可能會在日常操作中使用到的命令。
很顯然,這些如此之多的命令都會有不少選項,可以讓你的命令更加有效率,或者可以讓你指定你的 LXD 容器的某個具體方面。***的學習這些命令的方式就是深入學習它們的幫助文檔( -help)。
更多信息
LXD 的主要網(wǎng)站是:https://linuxcontainers.org/lxd
Github 上的開發(fā)動態(tài): https://github.com/lxc/lxd
郵件列表支持:https://lists.linuxcontainers.org
IRC 支持: #lxcontainers on irc.freenode.net
如果你不想或者不能在你的機器上安裝 LXD,你可以試試在線版本!