Linux 提供了名稱空間(Namespace)和控制群組(Cgroup)等機制,實作更細緻的資源隔離和管理。名稱空間將系統資源劃分到不同的隔離環境,避免程式間相互幹擾;控制群組則限制和監控程式群組對系統資源的使用。這些技術在容器化技術(如 Docker)中扮演關鍵角色,確保容器間的資源隔離和系統穩定性。本文將詳細介紹 Linux 名稱空間和控制群組的使用方法,並以 Docker 為例說明其應用。
Linux 特權
Linux 中還有一種稱為特權(capabilities)的機制。特權是指程式或使用者執行特定動作的能力。Linux 中的特權可以分為多種,例如 CAP_NET_BIND_SERVICE
、CAP_SYS_BOOT
等。
特權可以用於控制程式或使用者的行為,例如限制程式或使用者對系統資源的存取。特權也可以用於提高系統安全性,例如限制程式或使用者對敏感資源的存取。
Linux 許可權與能力(Capabilities)的管理
Linux 中的許可權與能力(Capabilities)是用於控制程式或使用者能夠執行的動作。能力包括了許多特定的許可權,例如網路許可權、檔案系統許可權等。這些能力可以被指派給程式或使用者,以限制或擴大其能夠執行的動作。
檢視程式的能力
使用 getpcaps
命令可以檢視程式的能力。例如:
getpcaps 22355
這會顯示程式 22355 的能力。
設定程式的能力
使用 setcap
命令可以設定程式的能力。例如:
sudo setcap 'cap_net_raw+p'./myping
這會設定 myping
程式的 CAP_NET_RAW
能力,允許它開啟網路 socket。
許可權與能力的差異
許可權(Permissions)是用於控制檔案或目錄的存取許可權,而能力(Capabilities)是用於控制程式或使用者能夠執行的動作。兩者都是用於限制或擴大系統的安全性。
Linux 能力列表
Linux 中有許多不同的能力,包括:
cap_chown
:允許改變檔案的所有者cap_dac_override
:允許覆寫檔案的存取許可權cap_dac_read_search
:允許讀取檔案的內容cap_fowner
:允許改變檔案的所有者cap_fsetid
:允許設定檔案的 setuid 位元cap_kill
:允許終止程式cap_setgid
:允許設定程式的群組 IDcap_setuid
:允許設定程式的使用者 IDcap_setpcap
:允許設定程式的能力cap_linux_immutable
:允許設定檔案的 immutable 位元cap_net_bind_service
:允許繫結網路服務cap_net_broadcast
:允許傳送廣播封包cap_net_admin
:允許管理網路介面cap_net_raw
:允許開啟網路 socketcap_ipc_lock
:允許鎖定 IPC 物件cap_ipc_owner
:允許擁有 IPC 物件cap_sys_module
:允許載入 kernel 模組cap_sys_rawio
:允許執行 raw I/O 操作
Linux 許可權與安全性
在 Linux 中,許可權與安全性是非常重要的議題。每個使用者與程式都有其自己的許可權,決定了它們可以存取哪些資源與執行哪些動作。理解 Linux 的許可權機制對於確保系統安全性至關重要。
許可權機制
Linux 的許可權機制是根據使用者 ID(UID)與群組 ID(GID)的概念。每個使用者都有一個唯一的 UID,而每個群組也有一個唯一的 GID。檔案與目錄的許可權是根據所有者、群組與其他使用者的讀寫執行許可權設定。
特殊許可權
除了基本的讀寫執行許可權外,Linux 還有特殊許可權,如 setuid、setgid 與 sticky bit。setuid 許可權允許執行檔案的使用者暫時擁有檔案所有者的許可權,而 setgid 許可權則允許執行檔案的使用者暫時擁有檔案群組的許可權。sticky bit 許可權則用於分享目錄,確保只有檔案的所有者才能刪除或重新命名檔案。
Capability
Linux 的 capability 機制允許管理員授予程式特定的許可權,而不需要授予完整的 root 許可權。這樣可以減少程式的許可權範圍,提高系統的安全性。
控制群組(cgroups)
控制群組(cgroups)是 Linux 中的一種機制,允許管理員限制程式群組的資源使用量。控制群組可以限制 CPU、記憶體、網路等資源的使用量,確保程式不會過度佔用系統資源。
程式碼範例
以下是使用 Linux 的 capability 機制授予程式特定許可權的範例:
# 建立一個新的 capability
cap_net_raw+p
# 執行 ping 指令,並授予其 net_raw 許可權
./myping 10.0.0.1
在這個範例中,cap_net_raw+p
指令建立了一個新的 capability,並授予其 net_raw
許可權。然後,./myping
指令執行 ping 程式,並授予其 net_raw
許可權。
Mermaid 圖表
以下是 Mermaid 圖表範例,展示了 Linux 的許可權與安全性機制:
graph LR A[使用者] -->|UID|> B[檔案] B -->|許可權|> C[讀寫執行] C -->|setuid|> D[暫時擁有所有者許可權] C -->|setgid|> E[暫時擁有群組許可權] C -->|sticky bit|> F[分享目錄] D -->|capability|> G[授予特定許可權] E -->|capability|> H[授予特定許可權] F -->|控制群組|> I[限制資源使用量]
這個圖表展示了 Linux 的許可權與安全性機制,包括使用者、檔案、許可權、特殊許可權、capability 與控制群組等概念。
控制群組的管理與建立
控制群組(cgroup)是一種Linux核心提供的功能,允許使用者對系統資源進行分組管理。透過控制群組,可以限制和監控特定程式或程式群組對系統資源的使用,例如CPU、記憶體等。
控制群組的結構
控制群組的結構是一個階層式的目錄結構,每個控制群組都有一個對應的目錄。控制群組的目錄包含了多個檔案,包括引數檔案和狀態檔案。引數檔案用於設定控制群組的屬性,例如記憶體限制;狀態檔案則提供了控制群組的當前狀態資訊,例如已使用的記憶體量。
控制群組的管理
控制群組可以透過寫入特定的檔案來進行管理。例如,memory.limit_in_bytes
檔案可以用於設定控制群組的記憶體限制。透過修改這些檔案,可以實作對控制群組的管理。
控制群組的建立
建立控制群組可以透過在控制群組目錄下建立新的子目錄來實作。當建立一個新的子目錄時,Linux核心會自動填充該目錄下的各個檔案,包括引數檔案和狀態檔案。
以下是建立控制群組的範例:
root@vagrant:/sys/fs/cgroup$ mkdir memory/liz
root@vagrant:/sys/fs/cgroup$ ls memory/liz/
cgroup.clone_children memory.limit_in_bytes
cgroup.event_control memory.max_usage_in_bytes
cgroup.procs memory.move_charge_at_immigrate
在這個範例中,建立了一個名為 liz
的控制群組,該控制群組位於 memory
目錄下。建立後,Linux核心自動填充了該目錄下的各個檔案,包括 memory.limit_in_bytes
和 memory.max_usage_in_bytes
等。
記憶體限制
記憶體限制是控制群組的一個重要功能。透過設定 memory.limit_in_bytes
檔案,可以限制控制群組中程式的記憶體使用量。以下是設定記憶體限制的範例:
root@vagrant:/sys/fs/cgroup$ echo 1024M > memory/liz/memory.limit_in_bytes
在這個範例中,設定了控制群組 liz
的記憶體限制為 1024M。
控制群組(Cgroup)與記憶體管理
控制群組(Cgroup)是一種 Linux 核心功能,允許使用者對系統資源進行分組和管理。其中,記憶體控制群組(memory cgroup)是用於管理程式群組的記憶體使用情況。
記憶體控制群組檔案
記憶體控制群組中有一些重要的檔案,包括:
memory.usage_in_bytes
:顯示目前控制群組使用的記憶體量。memory.limit_in_bytes
:設定控制群組的最大記憶體限制。memory.max_usage_in_bytes
:顯示控制群組曾經使用的最大記憶體量。memory.stat
:顯示控制群組的記憶體統計資訊。memory.swappiness
:設定控制群組的交換空間使用情況。
控制群組的建立和管理
當建立一個新的容器時,會自動建立一個新的控制群組。可以使用 lscgroup
命令來檢視控制群組的資訊。
lscgroup memory:/
這個命令會顯示記憶體控制群組的資訊,包括控制群組的層次結構和相關檔案。
控制群組的層次結構
控制群組的層次結構從根控制群組開始,根控制群組通常位於 /sys/fs/cgroup/memory
。每個控制群組都有一個唯一的名稱,名稱中包含了控制群組的層次結構資訊。
memory:/user.slice/user-1000.slice/session-43.scope/sh
這個例子中,控制群組的層次結構是 user.slice
-> user-1000.slice
-> session-43.scope
-> sh
。
記憶體控制群組的使用
記憶體控制群組可以用於限制容器的記憶體使用量,避免容器佔用過多的系統資源。可以透過設定 memory.limit_in_bytes
檔案來限制控制群組的最大記憶體限制。
echo 1024M > memory.limit_in_bytes
這個命令會設定控制群組的最大記憶體限制為 1024M。
控制群組與記憶體限制
控制群組(cgroup)是一種 Linux 核心功能,允許您控制和限制系統資源的使用,例如 CPU、記憶體、I/O 等。控制群組可以用來限制程式或容器的資源使用,防止它們佔用太多系統資源。
記憶體限制
控制群組中的 memory
子系統負責管理記憶體資源。您可以使用 memory.limit_in_bytes
檔案來設定控制群組的記憶體限制。例如:
$ cat /sys/fs/cgroup/memory/user.slice/user-1000.slice/session-43.scope/sh/memory.limit_in_bytes
9223372036854771712
這個數值代表控制群組的記憶體限制,如果沒有設定限制,則會顯示一個很大的數值,代表著控制群組可以使用所有可用的記憶體。
設定記憶體限制
您可以透過修改 memory.limit_in_bytes
檔案來設定控制群組的記憶體限制。例如:
$ echo 1073741824 > /sys/fs/cgroup/memory/user.slice/user-1000.slice/session-43.scope/sh/memory.limit_in_bytes
這個命令設定控制群組的記憶體限制為 1GB。
runc 組態檔案
如果您使用 runc
來建立容器,您可以在 config.json
檔案中設定控制群組的資源限制。例如:
{
"linux": {
"resources": {
"memory": {
"limit": 1073741824
}
}
}
}
這個組態檔案設定控制群組的記憶體限制為 1GB。
Linux 控制群組(cgroup)簡介
Linux 控制群組(cgroup)是一種用於限制和監控系統資源的機制,例如 CPU、記憶體、I/O 等。它允許系統管理員將系統資源分配給不同的群組,並設定每個群組的資源限制和優先順序。
控制群組的型別
Linux 提供了多種控制群組,包括:
cpu
: 用於限制 CPU 資源cpuacct
: 用於監控 CPU 資源使用情況cpuset
: 用於限制 CPU 核心和記憶體節點memory
: 用於限制記憶體資源blkio
: 用於限制塊裝置 I/O 資源net_cls
: 用於限制網路流量
Docker 中的控制群組
Docker 自動建立自己的控制群組,用於管理容器的資源。這些控制群組可以在 /sys/fs/cgroup
目錄中找到。例如,memory
控制群組可以用於限制容器的記憶體資源。
建立控制群組
要建立一個控制群組,需要在 /sys/fs/cgroup
目錄中建立一個新目錄,並在其中建立相應的控制檔案。例如,要建立一個 memory
控制群組,需要執行以下命令:
mkdir /sys/fs/cgroup/memory/mygroup
echo 100000 > /sys/fs/cgroup/memory/mygroup/memory.limit_in_bytes
這將建立一個名為 mygroup
的 memory
控制群組,並設定其記憶體限制為 100000 bytes。
將程式新增到控制群組
要將一個程式新增到控制群組,需要將其 PID 寫入控制群組的 cgroup.procs
檔案中。例如,要將 PID 為 29903 的程式新增到 mygroup
控制群組,需要執行以下命令:
echo 29903 > /sys/fs/cgroup/memory/mygroup/cgroup.procs
Docker 容器的控制群組
Docker 容器自動建立自己的控制群組,用於管理容器的資源。這些控制群組可以在 /sys/fs/cgroup
目錄中找到。例如,memory
控制群組可以用於限制容器的記憶體資源。
要檢視 Docker 容器的控制群組,可以使用以下命令:
ls */docker | grep docker
這將顯示 Docker 容器的控制群組列表。
設定 Docker 容器的資源限制
要設定 Docker 容器的資源限制,可以使用 --memory
等選項。例如,要設定一個容器的記憶體限制為 100M,可以使用以下命令:
docker run --rm --memory 100M -d alpine sleep 10000
這將啟動一個新的容器,並設定其記憶體限制為 100M。
圖表翻譯:
graph LR A[建立控制群組] --> B[設定控制群組] B --> C[將程式新增到控制群組] C --> D[檢視控制群組] D --> E[設定 Docker 容器的資源限制] E --> F[啟動 Docker 容器]
內容解密:
以上步驟展示瞭如何建立和管理 Linux 控制群組,以及如何設定 Docker 容器的資源限制。透過使用控制群組,可以有效地限制和監控系統資源,避免資源過度使用導致系統效能下降。
Linux 控制群組與資源限制
Linux 控制群組(Control Group)是一種機制,允許使用者限制和監控系統資源的使用。控制群組可以將系統資源(如 CPU、記憶體等)劃分為不同的群組,並對每個群組進行獨立的管理和限制。
控制群組版本
Linux 控制群組有兩個版本:版本 1 和版本 2。版本 1 是較早期的實作,版本 2 是較新的實作,提供了更好的功能和效能。
控制群組的工作原理
控制群組的工作原理是將系統資源劃分為不同的群組,每個群組都有一個唯一的識別碼。當一個程式被建立時,它會被分配到一個控制群組中。控制群組可以限制程式的資源使用,例如 CPU 時間、記憶體大小等。
控制群組的型別
Linux 控制群組有多種型別,包括:
- CPU 控制群組:限制程式的 CPU 時間使用。
- 記憶體控制群組:限制程式的記憶體大小使用。
- 網路控制群組:限制程式的網路流量使用。
- 輸出入控制群組:限制程式的輸出入速度。
控制群組的優點
控制群組有以下優點:
- 可以限制程式的資源使用,防止程式佔用過多資源。
- 可以監控程式的資源使用,方便進行資源管理。
- 可以實作資源隔離,防止程式之間的資源競爭。
Linux 空間名稱(Namespaces)
Linux 空間名稱(Namespaces)是一種機制,允許使用者建立多個獨立的空間,每個空間都有一個唯一的名稱。空間名稱可以用來隔離程式之間的資源使用,例如檔案系統、網路等。
空間名稱的型別
Linux 空間名稱有多種型別,包括:
- Mount Namespace:隔離檔案系統的掛載點。
- PID Namespace:隔離程式的 ID。
- Network Namespace:隔離網路介面和路由表。
- IPC Namespace:隔離程式之間的通訊。
- UTS Namespace:隔離主機名稱和網域名稱。
空間名稱的工作原理
空間名稱的工作原理是將系統資源劃分為不同的空間,每個空間都有一個唯一的名稱。當一個程式被建立時,它會被分配到一個空間名稱中。空間名稱可以限制程式的資源使用,例如檔案系統、網路等。
空間名稱的優點
空間名稱有以下優點:
- 可以隔離程式之間的資源使用,防止程式之間的資源競爭。
- 可以建立多個獨立的空間,每個空間都有一個唯一的名稱。
- 可以監控程式的資源使用,方便進行資源管理。
chroot 命令
chroot 命令是一種 Linux 命令,允許使用者變更根目錄。chroot 命令可以用來建立一個新的根目錄,然後執行命令或啟動新的 shell。
chroot 命令的語法
chroot 命令的語法如下:
chroot [選項] 新根目錄 [命令]
其中,新根目錄是新的根目錄,命令是要執行的命令。
chroot 命令的優點
chroot 命令有以下優點:
- 可以變更根目錄,建立一個新的環境。
- 可以執行命令或啟動新的 shell。
- 可以用來進行系統維護和修復。
Docker 容器
Docker 容器是一種輕量級的虛擬化技術,允許使用者建立和管理容器。Docker 容器可以用來封裝應用程式和依賴函式庫,然後佈署到不同的環境中。
Docker 容器的優點
Docker 容器有以下優點:
- 輕量級:Docker 容器比傳統虛擬機器更輕量級。
- 易於使用:Docker 容器易於建立和管理。
- 高度可移植:Docker 容器可以佈署到不同的環境中。
Linux 名稱空間(Namespace)概覽
Linux 名稱空間(Namespace)是一種隔離應用程式的機制,允許多個獨立的應用程式在同一臺主機上執行,而不會相互幹擾。每個名稱空間都有一個唯一的識別符,稱為名稱空間 ID。
名稱空間型別
Linux 提供了七種不同型別的名稱空間:
- Mount Namespace(mnt):隔離檔案系統掛載點。
- Process Namespace(pid):隔離程式 ID 和程式樹。
- Network Namespace(net):隔離網路介面和網路堆積疊。
- Inter-Process Communication Namespace(ipc):隔離 IPC 資源,如分享記憶體和訊息佇列。
- User Namespace(user):隔離使用者 ID 和群組 ID。
- Control Group Namespace(cgroup):隔離控制群組(cgroup)資源。
- Time Namespace(time):隔離時間和時區設定。
名稱空間命令
lsns
命令用於列出系統中的名稱空間。它可以顯示每個名稱空間的型別、程式數、PID、使用者和命令。
$ lsns
使用 lsns
命令
當您以普通使用者身份執行 lsns
命令時,它只會顯示與當前使用者相關的名稱空間。若要檢視所有名稱空間,包括系統級別的名稱空間,您需要以 root 身份執行 lsns
命令。
$ sudo lsns
範例輸出
以下是 lsns
命令的範例輸出:
NS TYPE NPROCS PID USER COMMAND
4026531835 cgroup 3 28459 vagrant /lib/systemd/systemd --user
4026531836 pid 3 28459 vagrant /lib/systemd/systemd --user
4026531837 user 3 28459 vagrant /lib/systemd/systemd --user
4026531838 uts 3 28459 vagrant /lib/systemd/systemd --user
4026531839 ipc 3 28459 vagrant /lib/systemd/systemd --user
4026531840 mnt 3 28459 vagrant /lib/systemd/systemd --user
4026531992 net 3 28459 vagrant /lib/systemd/systemd --user
在這個範例中,lsns
命令顯示了七種不同型別的名稱空間,每個名稱空間都有一個唯一的 ID 和相關的程式數、PID、使用者和命令。
Linux 中的名稱空間隔離
在 Linux 中,名稱空間(namespace)是一種用於實作資源隔離的機制。它允許將系統資源(如程式、網路、檔案系統等)分配到不同的名稱空間中,從而實作不同程式或執行緒之間的隔離。
UTS 名稱空間
UTS(Unix Time Sharing)名稱空間負責管理主機名和網域名稱。透過將程式放入單獨的 UTS 名稱空間中,可以實作主機名和網域名稱的隔離。
例如,可以使用 unshare
命令建立一個新的 UTS 名稱空間,並在其中執行一個 shell 會話:
sudo unshare --uts sh
在這個新的名稱空間中,可以修改主機名和網域名稱,而不會影響父程式或其他名稱空間中的程式。
示例
可以使用以下命令建立一個新的 UTS 名稱空間,並在其中執行一個 shell 會話:
vagrant@myhost:~$ sudo unshare --uts sh
$ hostname
myhost
$ hostname experiment
$ hostname
experiment
$ exit
在這個示例中,建立了一個新的 UTS 名稱空間,並在其中執行了一個 shell 會話。然後,修改了主機名為 experiment
,並驗證了修改後的主機名。
Docker 中的 UTS 名稱空間
在 Docker 中,每個容器都有自己的 UTS 名稱空間。這意味著每個容器都有自己的主機名和網域名稱,可以獨立於宿主機或其他容器進行修改。
例如,可以使用以下命令建立一個新的 Docker 容器,並在其中執行一個 shell 會話:
vagrant@myhost:~$ docker run --rm -it --name hello ubuntu bash
root@cdf75e7a6c50:/$ hostname
cdf75e7a6c50
在這個示例中,建立了一個新的 Docker 容器,並在其中執行了一個 shell 會話。然後,驗證了容器的主機名為 cdf75e7a6c50
,這是 Docker 自動生成的主機名。
Linux 中的名稱空間隔離是一種強大的機制,可以實作系統資源的隔離。透過使用 unshare
命令,可以建立新的名稱空間,並在其中執行程式或執行緒。Docker 中的 UTS 名稱空間隔離可以實作容器之間的主機名和網域名稱隔離。
虛擬化技術與Linux名稱空間
在Linux中,名稱空間(Namespace)是一種用於隔離資源的技術,可以讓多個獨立的環境分享同一個Linux核心。這種技術被廣泛應用於容器化技術中,例如Docker。
主機名稱隔離
使用unshare
命令可以建立一個新的UTS名稱空間,從而實作主機名稱的隔離。例如:
vagrant@myhost:~$ hostname
myhost
vagrant@myhost:~$ sudo unshare --uts sh
# 新的shell環境
$ hostname
myhost
$ hostname newhost
newhost
$ exit
vagrant@myhost:~$ hostname
myhost
在上面的例子中,建立了一個新的UTS名稱空間,並將主機名稱改為newhost
。但是,這個改動只在新的名稱空間中有效,對外部環境沒有影響。
程式ID隔離
使用unshare
命令也可以建立一個新的PID名稱空間,從而實作程式ID的隔離。例如:
vagrant@myhost:~$ sudo unshare --pid sh
# 新的shell環境
$ whoami
root
$ whoami
sh: 2: Cannot fork
$ whoami
sh: 3: Cannot fork
$ ls
sh: 4: Cannot fork
$ exit
vagrant@myhost:~$
在上面的例子中,建立了一個新的PID名稱空間,但是由於沒有使用--fork
選項,新的shell環境不能建立新的程式。
程式ID隔離與fork
使用unshare
命令建立一個新的PID名稱空間時,需要使用--fork
選項,以便新的shell環境可以建立新的程式。例如:
vagrant@myhost:~$ sudo unshare --pid --fork sh
# 新的shell環境
$ whoami
root
$ ps fa
PID TTY STAT TIME COMMAND
1 pts/0 S 0:00 sh
2 pts/0 R 0:00 ps fa
在上面的例子中,建立了一個新的PID名稱空間,並使用--fork
選項,以便新的shell環境可以建立新的程式。
使用 unshare
命令進行 PID Namespace 隔離
在 Linux 中,unshare
命令可以用來建立新的 namespace,實作資源隔離。在這裡,我們關注的是 PID namespace 的隔離。
從系統資源管理的視角來看,Linux 名稱空間,尤其是 PID 名稱空間的應用,極大提升了系統安全性和資源排程靈活性。透過 unshare
命令,我們可以輕鬆建立獨立的 PID 名稱空間,實作程式之間的有效隔離,避免相互幹擾。然而,實際應用中需要注意 --fork
選項的使用,才能在新名稱空間中正常建立和管理程式。技術團隊應深入理解不同名稱空間的特性和組合應用,才能充分發揮其隔離和管理系統資源的潛力。未來,隨著容器化技術的持續發展,預計名稱空間技術將扮演更重要的角色,並與其他資源管理技術深度融合,構建更安全、高效的系統環境。 對於追求精細化資源管理和系統安全的團隊,深入理解並應用名稱空間技術將是不可或缺的一環。