Linux 容器技術仰賴名稱空間與 chroot 機制,實作資源隔離和環境封裝。系統管理員可運用名稱空間,將程式的 PID、檔案系統、網路等資源隔離,避免相互幹擾。結合 chroot,更能限制程式的根目錄,建構獨立的執行環境。透過 unshare
命令,可以輕易地建立新的名稱空間,例如使用 --pid
引數隔離程式 ID,--mount
引數隔離檔案系統,--net
引數隔離網路等。在設定網路時,需使用 ip
命令組態虛擬網路介面,並設定 IP 位址和路由,確保容器網路正常運作。理解 Linux 的使用者空間概念,也有助於進一步提升容器的安全性,避免容器內的程式影響到宿主機系統。
基本使用
當你執行 sudo unshare --pid sh
時,會建立一個新的 PID namespace,並在其中執行 sh
shell。然而,這個 shell 並不是作為 unshare
的直接子程式,而是作為 sudo
的子程式。
vagrant@myhost:~$ ps fa
PID TTY STAT TIME COMMAND
...
30345 pts/0 Ss 0:00 -bash
30475 pts/0 S 0:00 \_ sudo unshare --pid sh
30476 pts/0 S 0:00 \_ sh
使用 --fork
引數
如果你新增 --fork
引數,如 sudo unshare --pid --fork sh
,則 unshare
會 fork 一個新的程式,並在新的 PID namespace 中執行 sh
shell。這樣,sh
就是 unshare
的直接子程式了。
vagrant@myhost:~$ ps fa
PID TTY STAT TIME COMMAND
...
30345 pts/0 Ss 0:00 -bash
30470 pts/0 S 0:00 \_ sudo unshare --pid --fork sh
30471 pts/0 S 0:00 \_ unshare --pid --fork sh
30472 pts/0 S 0:00 \_ sh
結果分析
使用 --fork
引數後,sh
shell 可以正常執行多條命令,而不會出現 “Cannot fork” 的錯誤。這是因為 --fork
引數使得 unshare
fork了一個新的程式,在新的 PID namespace 中執行 sh
shell。
此外,使用 ps fa
命令檢視程式樹時,你會發現 sh
shell 是 unshare
的直接子程式,這與預期相符。
處理Linux命令與系統內容
使用ps
命令檢視程式
在Linux系統中,ps
命令用於檢視程式的相關資訊。以下是使用ps
命令的範例:
$ ps
PID TTY TIME CMD
14511 pts/0 00:00:00 sudo
14512 pts/0 00:00:00 unshare
14513 pts/0 00:00:00 sh
14515 pts/0 00:00:00 ps
這個命令顯示了目前正在執行的程式,包括其PID、TTY、時間和命令。
使用ps -eaf
命令檢視所有程式
如果要檢視所有程式,包括系統程式,可以使用ps -eaf
命令:
$ ps -eaf
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 Mar27? 00:00:02 /sbin/init
root 2 0 0 Mar27? 00:00:00 [kthreadd]
root 3 2 0 Mar27? 00:00:00 [ksoftirqd/0]
root 5 2 0 Mar27? 00:00:00 [kworker/0:0H]
...
這個命令顯示了所有程式的詳細資訊,包括其UID、PID、PPID、C、STIME、TTY、TIME和CMD。
使用exit
命令離開shell
如果要離開shell,可以使用exit
命令:
$ exit
vagrant@myhost:~$
這個命令會離開目前的shell,並傳回到上一層shell。
檢視/proc目錄
在Linux系統中,/proc目錄是一個特殊的目錄,包含了系統的相關資訊。可以使用ls
命令檢視/proc目錄的內容:
vagrant@myhost:~$ ls /proc
這個命令會顯示/proc目錄的內容,包括了各種系統資訊,例如程式資訊、系統資源資訊等。
內容解密:
ps
命令用於檢視程式的相關資訊。ps -eaf
命令用於檢視所有程式的詳細資訊。exit
命令用於離開shell。- /proc目錄是一個特殊的目錄,包含了系統的相關資訊。
圖表翻譯:
graph LR A[ps命令] --> B[檢視程式資訊] B --> C[ps -eaf命令] C --> D[檢視所有程式資訊] D --> E[exit命令] E --> F[離開shell] F --> G[/proc目錄] G --> H[檢視系統資訊]
這個圖表顯示了使用ps
命令、ps -eaf
命令、exit
命令和檢視/proc目錄的流程。
Linux 系統檔案結構與內容分析
在 Linux 系統中,檔案結構和內容對於系統的運作和管理至關重要。這篇文章將深入探討 Linux 系統檔案結構,並對特設定檔案的內容進行分析。
檔案系統結構
Linux 的檔案系統結構分為多個層次,每個層次都有其特定的功能和內容。根目錄 (/
) 是檔案系統的最頂層,下面包含了多個子目錄,如 /bin
、/dev
、/etc
、/home
等。
/bin
目錄包含了基本的系統命令和工具。/dev
目錄包含了裝置檔案,代表了系統中的硬體裝置。/etc
目錄包含了系統的設定檔和組態檔。/home
目錄是使用者的家目錄,儲存了使用者的個人檔案和設定。
系統資訊檔案
在 Linux 系統中,有多個檔案提供了系統的資訊和狀態。這些檔案通常位於 /proc
目錄下,以下是其中一些重要的檔案:
cpuinfo
:提供了 CPU 的資訊,包括型號、頻率和架構。meminfo
:提供了記憶體的資訊,包括總記憶體、可用記憶體和交換空間。mounts
:提供了已經掛載的檔案系統的資訊,包括掛載點和檔案系統型別。net
:提供了網路的資訊,包括網路介面、路由表和 socket 統計。stat
:提供了系統的統計資訊,包括 CPU 使用率、記憶體使用率和磁碟使用率。
裝置檔案
Linux 系統中的裝置檔案代表了硬體裝置,通常位於 /dev
目錄下。這些檔案可以用來存取和控制硬體裝置,以下是其中一些重要的裝置檔案:
console
:代表了系統的主控臺,提供了鍵盤和螢幕的存取。dma
:代表了直接記憶體存取(DMA)通道,提供了高效的資料傳輸。fb
:代表了幀緩衝區(Frame Buffer),提供了圖形顯示的存取。mpt
:代表了多通道程式設計(MPT)介面,提供了多通道的存取。net
:代表了網路介面,提供了網路通訊的存取。
核心資訊檔案
Linux 系統中的核心資訊檔案提供了核心的資訊和狀態。這些檔案通常位於 /proc
目錄下,以下是其中一些重要的檔案:
crypto
:提供了核心的加密資訊,包括加密演算法和金鑰。devices
:提供了核心的裝置資訊,包括裝置型別和狀態。diskstats
:提供了核心的磁碟統計資訊,包括讀寫次數和錯誤次數。execdomains
:提供了核心的執行域資訊,包括執行域型別和狀態。filesystems
:提供了核心的檔案系統資訊,包括檔案系統型別和掛載點。
處理器資訊與系統管理
在 Linux 系統中,/proc
目錄是一個虛擬檔案系統,提供了大量的系統資訊,包括處理器、記憶體、網路等。每個數字目錄代表一個程式的 ID,並包含了該程式的詳細資訊。
程式資訊
每個程式的目錄中,都包含了多個檔案,提供了有關該程式的資訊。例如,/proc/<pid>/exe
是一個符號連結,指向該程式所執行的可執行檔。這些資訊對於系統管理和故障排除非常重要。
系統管理
系統管理員可以使用 /proc
目錄中的資訊來監控和管理系統。例如,可以使用 ps
命令來檢視程式列表,並使用 /proc/<pid>
目錄中的資訊來檢視程式的詳細資訊。
範例
vagrant@myhost:~$ ps
這個命令會顯示目前系統中正在執行的程式列表。然後,可以使用 /proc/<pid>
目錄中的資訊來檢視每個程式的詳細資訊。
Mermaid 圖表
graph LR A[ps 命令] --> B[顯示程式列表] B --> C[檢視程式詳細資訊] C --> D[/proc/<pid> 目錄] D --> E[符號連結到可執行檔]
圖表翻譯
這個 Mermaid 圖表顯示了使用 ps
命令來檢視程式列表,並使用 /proc/<pid>
目錄中的資訊來檢視每個程式的詳細資訊的過程。圖表中,每個節點代表了一個步驟,箭頭則代表了步驟之間的流程。
探索 Linux 處理程式的奧秘
在 Linux 系統中,/proc
檔案系統提供了一個視窗,讓我們可以窺視系統的內部運作。其中,/proc/<PID>
目錄包含了與特定處理程式相關的資訊。在這篇文章中,我們將深入探索 /proc/<PID>
目錄的內容,瞭解其結構和意義。
/proc/<PID>
目錄結構
當我們執行 ls /proc/28441
命令時,會看到以下目錄結構:
attr fdinfo numa_maps smaps
autogroup gid_map oom_adj smaps_rollup
auxv io oom_score stack
cgroup limits oom_score_adj stat
clear_refs loginuid pagemap statm
cmdline map_files patch_state status
comm maps personality syscall
coredump_filter mem projid_map task
cpuset mountinfo root timers
cwd mounts sched timerslack_ns
environ mountstats schedstat uid_map
這些目錄和檔案包含了處理程式的各種資訊,包括其屬性、記憶體對映、檔案描述符、系統呼叫等。
屬性和描述
attr
:包含了處理程式的屬性資訊,例如其實際使用者 ID 和實際組 ID。autogroup
:顯示了處理程式的自動分組資訊。auxv
:包含了處理程式的輔助向量資訊,包括其執行檔案路徑和命令列引數。cgroup
:顯示了處理程式的控制組資訊,包括其 CPU 和記憶體限制。
記憶體對映和檔案描述符
fdinfo
:包含了處理程式的檔案描述符資訊,包括其開啟的檔案和通訊端。map_files
:顯示了處理程式的記憶體對映資訊,包括其載入的分享函式庫和執行檔案。maps
:包含了處理程式的記憶體對映資訊,包括其虛擬記憶體地址空間和物理記憶體對映。
系統呼叫和計時器
syscall
:顯示了處理程式的系統呼叫資訊,包括其呼叫次數和耗時。timers
:包含了處理程式的計時器資訊,包括其設定的計時器和超時時間。timerslack_ns
:顯示了處理程式的計時器鬆弛時間,包括其計時器的鬆弛時間和超時時間。
其他資訊
cmdline
:包含了處理程式的命令列引數資訊,包括其執行檔案路徑和命令列引數。environ
:顯示了處理程式的環境變數資訊,包括其設定的環境變數和值。status
:包含了處理程式的狀態資訊,包括其執行狀態、記憶體使用量和 CPU 時間。
透過探索 /proc/<PID>
目錄的內容,我們可以更深入地瞭解 Linux 處理程式的內部運作機制和細節。這對於系統管理員、開發人員和安全分析師來說都是非常有用的資訊,可以幫助他們更好地管理和最佳化系統效能。
內容解密:
上述目錄結構和檔案描述了 Linux 處理程式的各種資訊,包括其屬性、記憶體對映、檔案描述符、系統呼叫等。透過瞭解這些資訊,我們可以更好地管理和最佳化系統效能。
圖表翻譯:
graph LR A[proc 目錄] -->|包含|> B[PID 目錄] B -->|包含|> C[屬性和描述] C -->|包含|> D[attr 和 autogroup] B -->|包含|> E[記憶體對映和檔案描述符] E -->|包含|> F[fdinfo 和 map_files] B -->|包含|> G[系統呼叫和計時器] G -->|包含|> H[syscall 和 timers] B -->|包含|> I[其他資訊] I -->|包含|> J[cmdline 和 environ]
這個圖表展示了 /proc/<PID>
目錄的結構和內容,包括其屬性、記憶體對映、檔案描述符、系統呼叫等。
Linux 中的 chroot 命令
Linux 中的 chroot
命令用於改變當前程式的根目錄。它可以使得程式看到的檔案系統與實際的檔案系統不同。這對於建立一個沙盒環境或容器化應用程式非常有用。
chroot 命令的基本用法
chroot
命令的基本用法如下:
sudo chroot 新的根目錄 [命令]
其中,新的根目錄
是要改變為根目錄的路徑,命令
是在新的根目錄下要執行的命令。如果不指定命令,則預設執行 /bin/sh
。
示例
建立一個新的目錄 new_root
,然後使用 chroot
命令改變當前程式的根目錄:
mkdir new_root
sudo chroot new_root
這將改變當前程式的根目錄為 new_root
。但是,由於 new_root
目錄下沒有 /bin
目錄,因此無法執行任何命令。
為了解決這個問題,我們可以在 new_root
目錄下建立一個 /bin
目錄,並將所需的命令(如 ls
)複製到該目錄下:
mkdir new_root/bin
cp /bin/ls new_root/bin/
sudo chroot new_root ls
這將輸出 new_root
目錄下的檔案列表。
Alpine Linux 示例
我們可以使用 chroot
命令執行 Alpine Linux。在 Alpine Linux 的官網下載一個 mini 根檔案系統,然後解壓縮:
wget http://dl-cdn.alpinelinux.org/alpine/v3.10/releases/x86_64/alpine-minirootfs-3.10.0-x86_64.tar.gz
tar xvf alpine-minirootfs-3.10.0-x86_64.tar.gz
這將建立一個 alpine
目錄,裡面包含了 Alpine Linux 的根檔案系統。然後,我們可以使用 chroot
命令改變當前程式的根目錄為 alpine
:
sudo chroot alpine ls
這將輸出 Alpine Linux 根目錄下的檔案列表。
chroot
命令是 Linux 中一個非常有用的工具,它可以幫助我們建立一個沙盒環境或容器化應用程式。透過改變當前程式的根目錄,我們可以使得程式看到的檔案系統與實際的檔案系統不同。然而,我們需要確保新的根目錄下有所需的命令和檔案,否則將無法執行任何命令。
Linux核心技術:程式隔離與根目錄變換
在Linux系統中,chroot
命令可以用來變換程式的根目錄,限制程式只能存取特定的目錄結構。這對於容器的實作非常重要,因為它允許每個容器有自己的根目錄,從而實作資源的隔離。
變換根目錄
當我們執行chroot
命令時,它會將指定的目錄作為新的根目錄。這意味著所有後續的檔案操作都將相對於這個新根目錄進行。例如,如果我們執行sudo chroot alpine sh
,則alpine目錄將成為新的根目錄,所有的檔案操作都將限制在這個目錄下。
vagrant@myhost:~$ sudo chroot alpine sh
/ $ ls
bin etc lib mnt proc run srv tmp var
dev home media opt root sbin sys usr
在這個例子中,alpine
目錄成為了新的根目錄,ls
命令只顯示了該目錄下的檔案和目錄。
空間名稱和變換根目錄的結合
Linux提供了空間名稱(namespace)的概念,允許程式執行在不同的名稱空間中。透過結合空間名稱和變換根目錄,可以實作更強大的資源隔離。
me@myhost:~$ sudo unshare --pid --fork chroot alpine sh
/ $ ls
bin etc lib mnt proc run srv tmp var
dev home media opt root sbin sys usr
在這個例子中,unshare
命令用於建立一個新的名稱空間,然後執行chroot
命令變換根目錄。這樣,程式就執行在一個完全隔離的環境中。
磁碟掛載和proc檔案系統
在容器中,需要掛載proc檔案系統以提供程式資訊。這可以透過mount
命令實作:
/ $ mount -t proc proc /proc
這樣,容器就可以透過/proc
目錄存取程式資訊,而不會受到宿主機程式的影響。
獨立環境與程式隔離
在上述範例中,我們建立了一個新的名稱空間(namespace),並在其中執行了一個 shell 程式。這使得我們可以隔離容器內的程式,讓它們只能看到自己的程式,而不是主機上的所有程式。
名稱空間隔離
名稱空間(namespace)是一種 Linux 核心提供的功能,允許我們建立多個獨立的名稱空間,每個名稱空間都有一個自己的程式樹、檔案系統樹等。這樣就可以實作程式隔離、檔案系統隔離等功能。
獨立的檔案系統樹
在上述範例中,我們建立了一個新的名稱空間,並在其中執行了一個 shell 程式。這使得我們可以建立一個獨立的檔案系統樹,讓容器內的程式只能看到自己的檔案系統,而不是主機上的檔案系統。
獨立的點掛載
點掛載(mount point)是指檔案系統中的一個特定目錄或檔案被掛載到另一個檔案系統上。上述範例中,我們建立了一個新的名稱空間,並在其中執行了一個 shell 程式。這使得我們可以建立一個獨立的點掛載,讓容器內的程式只能看到自己的點掛載,而不是主機上的點掛載。
程式碼示例
# 建立一個新的名稱空間
sudo unshare --mount sh
# 建立一個新的目錄
mkdir source
# 建立一個新的檔案
touch source/HELLO
# 檢視檔案列表
ls source
# 建立一個新的目錄
mkdir target
# 檢視檔案列表
ls target
# 將 source 目錄掛載到 target 目錄
mount --bind source target
# 檢視檔案列表
ls target
Mermaid 圖表
graph LR A[建立新的名稱空間] --> B[建立新的目錄] B --> C[建立新的檔案] C --> D[檢視檔案列表] D --> E[建立新的目錄] E --> F[將 source 目錄掛載到 target 目錄] F --> G[檢視檔案列表]
圖表翻譯:
上述 Mermaid 圖表展示了建立一個新的名稱空間、建立新的目錄和檔案、檢視檔案列表、將 source 目錄掛載到 target 目錄等步驟。這些步驟實作了容器內的程式隔離和檔案系統隔離。
Linux 中的名稱空間:進階篇
在 Linux 中,名稱空間(Namespace)是一個強大的功能,允許使用者建立多個獨立的環境,每個環境都有自己的資源和設定。這些資源包括了檔案系統、網路介面、程式 ID 等。在本文中,我們將深入探討 Linux 中的名稱空間,特別是檔案系統和網路介面的名稱空間。
檔案系統名稱空間
檔案系統名稱空間(Mount Namespace)允許使用者建立多個獨立的檔案系統環境,每個環境都有自己的檔案系統掛載點。這意味著每個環境都可以有自己的根目錄、自己的檔案系統掛載點等。
下面的例子展示瞭如何使用 unshare
命令建立一個新的檔案系統名稱空間:
vagrant@myhost:~$ sudo unshare --mount chroot alpine sh
這個命令建立了一個新的檔案系統名稱空間,並將 Alpine Linux 的根目錄掛載到新的名稱空間中。
在新的名稱空間中,我們可以使用 mount
命令掛載新的檔案系統:
/ $ mount -t proc proc proc
/ $ mount
proc on /proc type proc (rw,relatime)
這個例子展示瞭如何掛載一個新的 proc
檔案系統到新的名稱空間中。
網路介面名稱空間
網路介面名稱空間(Network Namespace)允許使用者建立多個獨立的網路環境,每個環境都有自己的網路介面和路由表。這意味著每個環境都可以有自己的網路設定、自己的 IP 位址等。
下面的例子展示瞭如何使用 unshare
命令建立一個新的網路介面名稱空間:
vagrant@myhost:~$ sudo unshare --net bash
這個命令建立了一個新的網路介面名稱空間,並啟動了一個新的 Bash shell。
在新的名稱空間中,我們可以使用 lsns
命令檢視網路介面的設定:
vagrant@myhost:~$ sudo lsns -t net
NS TYPE NPROCS PID USER NETNSID NSFS COMMAND
4026531992 net 93 1 root unassigned /sbin/init
這個例子展示瞭如何檢視網路介面的設定在新的名稱空間中。
網路隔離技術:建立虛擬網路介面
在 Linux 系統中,網路隔離是一項重要的功能,可以讓系統管理員將不同的網路介面和程式隔離,提高系統的安全性和穩定性。這篇文章將介紹如何使用 unshare
和 ip
命令建立虛擬網路介面,實作網路隔離。
建立虛擬網路介面
首先,使用 unshare
命令建立一個新的網路名稱空間:
sudo unshare --net bash
這將建立一個新的網路名稱空間,並啟動一個新的 bash
shell。
接下來,使用 ip
命令檢視當前的網路介面:
ip a
這將顯示當前的網路介面,包括 lo
(loopback) 介面。
建立虛擬 Ethernet 介面
使用 ip
命令建立一個虛擬 Ethernet 介面:
ip link add ve1 netns 28586 type veth peer name ve2 netns 1
這將建立一個虛擬 Ethernet 介面 ve1
,並將其連線到網路名稱空間 28586
。同時,建立另一個虛擬 Ethernet 介面 ve2
,並將其連線到網路名稱空間 1
。
啟用虛擬網路介面
啟用虛擬網路介面 ve1
和 ve2
:
ip link set ve1 up
ip link set ve2 up
這將啟用兩個虛擬網路介面,讓它們可以傳輸資料。
組態 IP 地址
組態 IP 地址到虛擬網路介面 ve1
和 ve2
:
ip addr add 192.168.1.100/24 dev ve1
ip addr add 192.168.1.200/24 dev ve2
這將組態 IP 地址 192.168.1.100
到虛擬網路介面 ve1
,和組態 IP 地址 192.168.1.200
到虛擬網路介面 ve2
。
測試網路連線
測試網路連線,使用 ping
命令:
ping 192.168.1.200
這將測試網路連線,確認虛擬網路介面是否可以傳輸資料。
Linux 中的使用者空間與程式隔離
Linux 中的使用者空間(User Namespace)是一種隔離機制,允許程式在不同的使用者空間中執行,從而實作使用者身份的隔離。這種機制可以將一個程式的使用者身份從宿主機的使用者身份中隔離出來,從而提高系統的安全性。
使用者空間的工作原理
當一個程式建立了一個新的使用者空間時,Linux 核心會為這個程式分配一個新的使用者身份,這個使用者身份與宿主機的使用者身份是不同的。這個新的使用者身份被稱為「對映使用者身份」(Mapped User ID)。對映使用者身份是指在使用者空間中使用的使用者身份,它與宿主機的使用者身份之間存在對映關係。
使用者空間的工作原理如下:
- 當一個程式建立了一個新的使用者空間時,Linux 核心會為這個程式分配一個新的使用者身份。
- 這個新的使用者身份被稱為對映使用者身份,它與宿主機的使用者身份是不同的。
- 當程式在新的使用者空間中執行時,它使用的是對映使用者身份,而不是宿主機的使用者身份。
- 如果程式需要存取宿主機的資源,則需要使用宿主機的使用者身份。
使用者空間的優點
使用者空間有以下優點:
- 提高安全性:使用者空間可以將程式的使用者身份從宿主機的使用者身份中隔離出來,從而提高系統的安全性。
- 簡化系統管理:使用者空間可以簡化系統管理,因為每個程式都有自己的使用者身份,不需要分享宿主機的使用者身份。
- 提高靈活性:使用者空間可以允許程式在不同的使用者空間中執行,這樣可以提高系統的靈活性。
從Linux核心技術的底層機制到使用者層面的應用,本文深入探討了程式隔離、根目錄變換、名稱空間以及虛擬網路介面等關鍵技術。藉由chroot
、unshare
、ip
等命令的實際操作範例,我們展示瞭如何在Linux系統中建立獨立的執行環境,實作資源隔離和安全性提升。分析了--fork
引數的使用,以及在不同名稱空間中操作網路介面、掛載檔案系統等技術細節,更進一步揭示了Linux系統的靈活性和強大功能。然而,構建安全可靠的隔離環境並非易事,仍需仔細考量各個名稱空間的設定及資源限制,才能避免潛在的安全風險。玄貓認為,深入理解這些核心技術,對於構建和管理複雜的Linux系統,特別是容器化環境,至關重要,值得投入時間深入研究並應用於實務操作。