完整**
總結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的質數個...