Linux Namespace 超簡單容器構建

2021-09-27 03:45:02 字數 3851 閱讀 7094

完整**

總結namespace隔離了程序、網路、使用者等系統資源,本文將講述如何通過namespace建立乙個超簡單容器,並在容器內部執行簡單的busybox程式。本文內容參考了linuxnamespace系列(09),雖然目的相同,但本文採用c語言系統呼叫的方式實現,因此更加實用。

p.s:本文全部**都在ubuntu18.04server下編譯執行通過

準備busybox二進位制檔案

作者使用的是busybox_1.31.0,構建容器後會在容器內安裝busybox,並執行busybox中的shell。

編寫程式

建立所需目錄,包括/bin, /proc, /old_root等

複製可執行檔案

呼叫unshare建立namespace

呼叫pivot_root設定root檔案系統的路徑

掛載/proc等檔案系統

執行busybox --install ./bin,執行./bin/sh

執行程式,busybox中執行ls等命令

本文首先展示最終的執行結果,之後分模組講述程式的構建過程。

eric@ubuntu:~/coding/linux_learn/******_container$ ./simp_container.out

running......

preparing root...

preparing dirs...

copying file...

doing unshare...

setting hostname...

chdir to new root...

pivot root...

doing mount and umount...

set env and exec busybox sh...

/ $ ls

bin data old_root proc

/ $ ps -ef

pid user time command

1 65534 0:00 sh

5 65534 0:00 ps -ef

/ $

上述執行結果中,以...結尾的為日誌輸出。容器建立後,執行了busybox中的shell程式,ps -ef命令的輸出表明當前容器隔離了pid,即容器內程序無法看到外部程序。由於沒有對映使用者和組id,因此user為預設的65534。程式執行後的目錄結構如下所示,bin目錄存放了busybox安裝後的可執行檔案:

simp_container_root/

└── new_root

├── bin

├── data

├── old_root

└── proc

目錄準備主要使用mkdir函式實現,該函式建立指定目錄,並授予指定許可權,函式原型為int mkdir(const char *pathname, mode_t mode)。如下為**:

#define md(a) mkdir(a, s_irwxu | s_irwxg)

void

prepare_dirs()

由於沒有找到複製檔案的庫函式,因此這裡直接使用標準庫的file物件實現,複製後呼叫chmod新增執行許可權:

void

cpy_file

(const

char old_path,

const

char new_path)

;int n =

fread

(buf,

1, buf_size, oldfp)

;fwrite

(buf,

1, n, newfp);}

fclose

(oldfp)

;fflush

(newfp)

;fclose

(newfp)

;chmod

(new_path, s_irwxu | s_irwxg)

;}

通過呼叫unshare建立新的namespace,這裡指定pid,uts,user,network,mount,ipc,cgroup所有七個namespace。之後呼叫fork在子程序中執行接下來的操作。關於pivot_root系統呼叫,作者未作深入研究,感興趣的可以參考linuxnamespace系列(09)。

void

do_unshare()

else

if(ret >0)

}

安裝程式通過呼叫execl實現即可,安裝之後以同樣的方式啟動/bin下的sh程式即可:

void

exec_cmd()

if(ret ==0)

errexit

("fork");

}

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define logger(a) \

do while (0)

#define md(a) mkdir(a, s_irwxu | s_irwxg)

const

void

errexit

(const

char

*fmt,..

.)void

cpy_file

(const

char old_path,

const

char new_path)

;int n =

fread

(buf,

1, buf_size, oldfp)

;fwrite

(buf,

1, n, newfp);}

fclose

(oldfp)

;fflush

(newfp)

;fclose

(newfp)

;chmod

(new_path, s_irwxu | s_irwxg);}

void

prepare_dirs()

void

exec_cmd()

if(ret ==0)

errexit

("fork");

}void

do_unshare()

if(ret >0)

}void

create_container()

intmain

(int argc,

char

const

*ar**)

超網 超網各類說明

超網的劃分 示例 某企業有乙個網段,該網段有200臺主機,使用192.168.0.0 255.255.255.0網段。後來計算機數量增加到400臺,為後來增加的200臺主機使用192.168.1.0 255.255.255.0網段,如下圖 在路由器配置了192.168.0.1的ip位址介面,再新增1...

HTML標籤學習 超基礎 超easy

文字標籤 和文字有關的標籤 b 字型加粗 i 字型斜體 font 標籤列表標籤無序列表 鏈結標籤 div和span 語義化標籤 html5中為了提高程式的可讀性,提供了一些標籤 標籤 tr 定義行 背景色,對齊方式 td 定義單元格 th 定義表頭單元格 caption 標題 thead 的頭部分 ...

問題 F 超超的自閉意思

時間限制 1 sec 記憶體限制 128 mb 提交 80 解決 10 提交 狀態 命題人 jsu admin 題目描述 質數定義為在大於1的自然數中,除了1和它本身以外不再有其他因數。回文數定義為在正整數中,從左到右,從右到左讀都相同的數字。沒有前導零的十進位制 現在 z n 表示不大於n的質數個...