lxc exec 介紹
最近,我對 lxc exec
進行了幾個改進。如果你不知道它的話我介紹一下,lxc exec
是 LXD 的客戶端工具,使用 LXD 客戶端 api 與 LXD 守護程序通信,並執行用戶想要執行的各種程序,以下是你可以使用的一個例子:
我們的主要目標之一就是使 lxc exec
與 ssh
類似,因為它是互動式或非互動式遠程運行命令的標準。這使得 把 lxc exec
做得很好變得有點棘手。
1、 處理後台任務
一個長期存在的問題當然是如何正確處理後台任務。這是一個關於 LXD 2.7 實例的問題的例子:
你可以看到,在後台執行任務將導致 lxc exec
無法退出。許多命令可以觸發此問題:
chb@conventiont|~
> lxc exec zest1 bash
root@zest1:~# yes &
y
y
y
.
.
.
現在沒有什麼能救你了。yes
將會永遠直接寫入stdout
。
問題的根源在於 stdout
是一直打開著的,但這是必要的,因為它用以確保用戶所啟動的進程寫入的任何數據實際上都是通過我們建立的 websocket 連接讀取並發回的。
假如你想這樣,運行一個 shell 會話,然後在後台運行一個進程,並馬上退出 shell。對不起,它並不能如預期那樣。
第一種並且原始的方法是一旦你檢測到前台程序(例如 shell)已經退出就直接關閉 stdout
。但這不像想得那麼好,當你運行快速執行程序時,這個問題會變得明顯,比如:
lxc exec -- ls -al /usr/lib
這裡 lxc exec
進程(和相關的 forkexec
進程。但現在不要考慮它,只要記住 Go
+ setns()
不相往來就行了……)會在 stdout
中所有的緩衝數據被讀取之前退出。這種情況下將會導致截斷輸出,沒有人想要這樣。在嘗試使用幾個方法來解決問題之後,包括禁用 pty 緩衝(我告訴你,這不太漂亮,也沒有如預期工作。)和其他奇怪的思路,我設法通過幾個 poll()
「技巧」(在某種意義上說一個「技巧」)解決了這個問題。現在你終於可以運行後台任務,並且可以完全退出了。如圖:
2、 報告由信號引起的退出碼
ssh
是一個很棒的工具。但有一件事,我一直以來不喜歡當 ssh 運行的命令接收到一個信號時, ssh
總是會報告 -1
,也就是退出碼 255
。當你想要了解導致程序終止的信號時,這很煩人。這就是為什麼我最近實施標準 shell 所使用的慣例 128 + n
來報告任何由信號導致的退出,其中 n
被定義為導致執行程序退出的信號量。例如,在 SIGKILL
信號上,你會看到 128 + SIGKILL = 137
(計算其他致命信號的退出碼作為讀者的練習)。所以你可以這麼做:
chb@conventiont|~
> lxc exec zest1 sleep 100
現在,將 SIGKILL
發送到執行程序(不是 lxc exec
本身,因為 SIGKILL
不可轉發)。
kill -KILL $(pidof sleep 100)
最後檢查你程序的退出碼:
chb@conventiont|~
> echo $?
137
瞧。這顯然只有當 a) 退出碼沒有超過 8
位計算壁壘,b)當執行程序不使用 137
來表示成功(這可真……有趣?!)。這兩個論點似乎對我來說都不太有說服力。前者因為致命信號量不應該超過這個範圍。後者因為(i)這是用戶問題,(ii)這些退出代碼實際上是保留的(我是這樣認為。),(iii)你在本地或其他上面運行程序時會遇到同樣的問題。
我看到的主要優點是這能夠回報執行程序細粒度的退出狀態。注意,我們不會報告所有被信號殺死的程序實例。比如說,當你的程序能夠處理 SIGTERM
並且完全退出時,LXD 沒有簡單的方法來檢測到這個情況並報告說這個程序被信號殺死了。你只會簡單地收到退出碼 0
。
3、 轉發信號
這可能不太有趣(或者也許不是,誰知道呢),但我發現它非常有用。正如你在 SIGKILL
案例中看到的那樣,我明確地指出,必須將 SIGKILL
發送到執行程序,而不是 lxc exec
命令本身。這是因為 SIGKILL
在程序中無法處理。程序可以做的唯一的事情就是去死,像現在這樣……像這個例子……馬上(你明白了了吧……)。但是程序可以處理很多其他信號 SIGTERM
、SIGHUP',當然也可以處理
SIGUSR1和
SIGUSR2。因此,當你發送可以被
lxc exec` 處理而不是被執行程序處理的信號時,較新版本的 LXD 會將信號轉發到執行進程。這在腳本中非常方便。
無論如何,我希望你覺得這篇小小的 lxc exec
文章/胡言亂語有用。享受 LXD 吧,這是與一隻瘋狂的美麗的野獸玩耍。請試試在線實驗:https://linuxcontainers.org/lxd/try-it/,對於開發人員看看這裡:https://github.com/lxc/lxd 並給我們補丁。
我們不要求籤署任何 CLA,我們遵循內核風格,只要其中有 「Signed-off-by」 這行就好。
via: https://cbrauner.wordpress.com/2017/01/20/lxc-exec-vs-ssh/
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive