網(wǎng)站是由哪些組成電商平臺(tái)推廣怎么做
目錄
- 一、RootFs
- 1. Docker 鏡像與文件系統(tǒng)層
- 2. RootFs 與容器隔離的意義
- 二、Linux Namespace
- 1. 進(jìn)程命名空間
- 1.1 `lsns` 命令說(shuō)明
- 1.2 查看“祖先進(jìn)程”命名空間
- 1.3 查看當(dāng)前用戶進(jìn)程命名空間
- 2. 容器進(jìn)程命名空間
- 2.1 查看容器進(jìn)程命名空間列表
- 2.2 容器進(jìn)程命名空間的具體體現(xiàn)
- 三、cgroups
- 1. cpu 子系統(tǒng)
- 1.1 CFS (Completely Fair Scheduler)
- 1.2 RT (Real-time Scheduler)
- 1.3 示例
- 2. cpuset 子系統(tǒng)
- 3. cpuacct 子系統(tǒng)
- 4. memory 子系統(tǒng)
- 示例
- 5. blkio 子系統(tǒng)
- 6. devices 子系統(tǒng)
- 7. freezer 子系統(tǒng)
- 8. net_cls 子系統(tǒng)
- 9. net_prio 子系統(tǒng)
- 10. perf_event
- 11. hugetlb
- 總結(jié)
一、RootFs
在傳統(tǒng)的 Linux 系統(tǒng)中,rootfs(根文件系統(tǒng))就是系統(tǒng)的“根”目錄,一般位于 /
,其下包含 /bin
、/dev
、/etc
等常見(jiàn)目錄結(jié)構(gòu)。
在容器中,則通過(guò)鏡像(Image)+**容器層(Container Layer)**的組合來(lái)提供容器自身的根文件系統(tǒng),這個(gè)容器的根文件系統(tǒng)就是rootfs
,與宿主機(jī)的 rootfs 相對(duì)隔離。
1. Docker 鏡像與文件系統(tǒng)層
- **鏡像(Image)**由多層只讀層(read-only layers)構(gòu)成,利用了 Union FS 或 OverlayFS 等聯(lián)合文件系統(tǒng)技術(shù)。
- **容器層(Container Layer)**是該鏡像之上的可寫(xiě)層(read-write layer)。容器運(yùn)行時(shí),對(duì)文件的修改都會(huì)寫(xiě)入到這個(gè)容器層中,不會(huì)影響只讀層的內(nèi)容。
2. RootFs 與容器隔離的意義
- 當(dāng)啟動(dòng)一個(gè)容器時(shí),容器看到的“根文件系統(tǒng)”并非與宿主機(jī)相同,而是來(lái)自鏡像 + 容器層組合形成的 rootfs。
- 對(duì)于容器內(nèi)部的進(jìn)程來(lái)說(shuō),
/
就是容器自身的根目錄,與宿主機(jī)的/
相互獨(dú)立(盡管底層還是同一個(gè)內(nèi)核)。 - 這種文件系統(tǒng)級(jí)別的隔離為容器提供了和宿主機(jī)隔離的外觀,不同容器之間也不會(huì)直接污染彼此的文件系統(tǒng)。
二、Linux Namespace
Linux Namespace 是容器隔離的核心機(jī)制之一。Namespace 的主要作用是將系統(tǒng)資源進(jìn)行“分名字空間”隔離,如進(jìn)程(PID)、網(wǎng)絡(luò)(NET)、文件系統(tǒng)掛載(MOUNT)、用戶(USER)、IPC 等,從而讓容器“以為”它擁有自己獨(dú)立的環(huán)境。
1. 進(jìn)程命名空間
1.1 lsns
命令說(shuō)明
lsns
是 Linux 提供的一個(gè)查看系統(tǒng)中命名空間信息的命令??梢杂?lsns
查看當(dāng)前系統(tǒng)里所有命名空間,如lsns -t pid
可以查看 PID 命名空間,lsns -t net
查看網(wǎng)絡(luò)命名空間等。- 常見(jiàn)列示信息包含:
- NS TYPE: 命名空間類型(如
pid
、net
、mnt
、uts
、ipc
、user
等)。 - NSID: 命名空間 ID,一般可以在
/proc/pid/ns
路徑中看到相應(yīng)符號(hào)鏈接。 - PID: 對(duì)應(yīng)的進(jìn)程號(hào)。
- Command: 該命名空間對(duì)應(yīng)進(jìn)程的啟動(dòng)命令。
- NS TYPE: 命名空間類型(如
1.2 查看“祖先進(jìn)程”命名空間
在 Linux 中,每個(gè)進(jìn)程都有對(duì)應(yīng)的命名空間引用(指針)。如果想要查看某個(gè)進(jìn)程(比如 PID=1 或者宿主機(jī)上的某個(gè) PID)的命名空間,可以通過(guò):
列出系統(tǒng)所有命名空間
sudo lsns --output0all
ls -l /proc/<PID>/ns
這會(huì)展示對(duì)應(yīng)的符號(hào)鏈接,比如:
lrwxrwxrwx 1 root root 0 Jan 1 00:00 /proc/1/ns/pid -> pid:[4026531836]
這樣就能看到 pid:[4026531836]
對(duì)應(yīng)的命名空間 ID。通常 PID=1(系統(tǒng)的 init 或 systemd)會(huì)在宿主機(jī)的最初始 namespace 中。
1.3 查看當(dāng)前用戶進(jìn)程命名空間
直接對(duì)你當(dāng)前 shell 的 PID 進(jìn)行查看:
echo $$
# 假設(shè)輸出為 12345
ls -l /proc/12345/ns
就能看到你當(dāng)前 shell 進(jìn)程所使用的 namespace。
2. 容器進(jìn)程命名空間
容器之所以能夠讓其內(nèi)部進(jìn)程彼此隔離,主要原因之一是 Docker(或其他容器運(yùn)行時(shí))在啟動(dòng)容器進(jìn)程時(shí),會(huì)為該進(jìn)程創(chuàng)建或加入單獨(dú)的命名空間(PID/NET/IPC/UTS 等)。
2.1 查看容器進(jìn)程命名空間列表
假設(shè)我們有一個(gè)正在運(yùn)行的容器,可以先找到容器對(duì)應(yīng)的“容器進(jìn)程”:
docker ps
docker inspect <container_id> | grep "Pid"
然后拿到對(duì)應(yīng)的 PID,比如是 23456。接著:
ls -l /proc/23456/ns
就能看到容器進(jìn)程使用的所有 namespace 綁定信息。
2.2 容器進(jìn)程命名空間的具體體現(xiàn)
- PID Namespace
容器內(nèi)部查看到的進(jìn)程號(hào)(PID)從 1 開(kāi)始,而在宿主機(jī)上,這個(gè)容器的進(jìn)程是一個(gè)完全不同的 PID 值。容器內(nèi)部的“PID=1”通常是容器內(nèi)的 init 進(jìn)程。 - Network Namespace
容器有自己?jiǎn)为?dú)的網(wǎng)卡配置(如eth0
),與宿主機(jī)是隔離的。通過(guò)容器的 network namespace,可以將容器網(wǎng)絡(luò)與宿主機(jī)網(wǎng)絡(luò)解耦(或進(jìn)行端口映射)。 - Mount Namespace
容器有自己掛載的文件系統(tǒng)視圖,比如/
是容器自己的 rootfs。與宿主機(jī)的掛載點(diǎn)不同。 - IPC Namespace
容器之間的共享內(nèi)存、消息隊(duì)列等 IPC 機(jī)制互不影響。 - UTS Namespace
容器可以有自己獨(dú)立的 hostname。容器內(nèi)hostname
與宿主機(jī)可以不同。
借助這些命名空間,容器可以呈現(xiàn)一個(gè)與宿主機(jī)幾乎隔離的操作系統(tǒng)視圖。
三、cgroups
cgroups (control groups) 是 Linux 提供的另一項(xiàng)關(guān)鍵特性,用于對(duì)系統(tǒng)資源進(jìn)行“配額、限制、監(jiān)控、隔離”。Docker 容器通過(guò)將容器進(jìn)程加入到相應(yīng)的 cgroup,來(lái)限制其對(duì) CPU、內(nèi)存、IO 等資源的使用或進(jìn)行統(tǒng)計(jì)。
cgroups 是一個(gè)可插拔的框架,常見(jiàn)的子系統(tǒng)包括:
- cpu
- cpuset
- cpuacct
- memory
- blkio
- devices
- freezer
- net_cls
- net_prio
- perf_event
- hugetlb
等。
下面分別簡(jiǎn)要介紹這些子系統(tǒng)在容器隔離中的作用或使用示例。
1. cpu 子系統(tǒng)
cpu
子系統(tǒng)主要用于限制或分配 CPU 時(shí)間片給某個(gè) cgroup 內(nèi)進(jìn)程。讓我們來(lái)看看常見(jiàn)的調(diào)度器和示例。
1.1 CFS (Completely Fair Scheduler)
- Linux 默認(rèn)的 CPU 調(diào)度器。可通過(guò)
cpu.shares
、cpu.cfs_period_us
、cpu.cfs_quota_us
等文件對(duì) CPU 使用進(jìn)行相對(duì)或絕對(duì)限額設(shè)置。 - 例如要限制某個(gè) cgroup 的進(jìn)程只能使用“相當(dāng)于一個(gè) CPU 核心”的計(jì)算量,可以在
cpu.cfs_period_us
= 100000(默認(rèn)100ms)和cpu.cfs_quota_us
= 100000 之間做設(shè)置,這樣就大致等價(jià)于 1 core。
1.2 RT (Real-time Scheduler)
- RT 調(diào)度針對(duì)實(shí)時(shí)任務(wù),可以用來(lái)做實(shí)時(shí)優(yōu)先級(jí)的資源控制。不過(guò)容器中常見(jiàn)應(yīng)用較少直接動(dòng)用 RT 調(diào)度。
1.3 示例
在手動(dòng)配置 cgroup 時(shí),可能會(huì):
- 創(chuàng)建目錄:
mkdir /sys/fs/cgroup/cpu/test_cgroup
- 寫(xiě)入一些限制:
表示此 cgroup 一次調(diào)度周期內(nèi)(100ms),只能用 200ms CPU 時(shí)間,相當(dāng)于可以使用 2 核的 CPU 時(shí)間。echo 200000 > /sys/fs/cgroup/cpu/test_cgroup/cpu.cfs_quota_us echo 100000 > /sys/fs/cgroup/cpu/test_cgroup/cpu.cfs_period_us
- 把某個(gè)進(jìn)程寫(xiě)入 tasks:
該進(jìn)程的 CPU 使用就受限于此組的規(guī)則。echo <pid> > /sys/fs/cgroup/cpu/test_cgroup/tasks
Docker 在啟動(dòng)容器時(shí)會(huì)自動(dòng)做這些事情,如 --cpus
、--cpuset-cpus
等參數(shù)。
2. cpuset 子系統(tǒng)
cpuset
子系統(tǒng)允許指定某些 CPU 核、某些內(nèi)存節(jié)點(diǎn)給特定的 cgroup。- 比如可以指定容器只能在 CPU 0 和 1 上運(yùn)行,或者只能從 NUMA 節(jié)點(diǎn)0分配內(nèi)存。
- Docker 對(duì)應(yīng)的參數(shù)是
--cpuset-cpus="0-1"
之類。
3. cpuacct 子系統(tǒng)
cpuacct
用于統(tǒng)計(jì)某個(gè) cgroup 內(nèi)進(jìn)程的 CPU 使用情況(用戶態(tài)、內(nèi)核態(tài)占用總時(shí)長(zhǎng)),只做統(tǒng)計(jì)不做限制。- Docker 可以通過(guò)這個(gè)子系統(tǒng)查看容器的 CPU 使用狀態(tài)。
4. memory 子系統(tǒng)
memory
子系統(tǒng)用于限制和統(tǒng)計(jì)進(jìn)程的內(nèi)存使用,包括物理內(nèi)存和 swap。
- 常見(jiàn)的控制文件:
memory.limit_in_bytes
:該 cgroup 最大物理內(nèi)存限制。memory.memsw.limit_in_bytes
:物理內(nèi)存 + swap 限制(如果啟用 swap 記賬)。
- 通過(guò)設(shè)置這些值,可防止某些進(jìn)程用光系統(tǒng)所有內(nèi)存。
示例
- 創(chuàng)建 cgroup:
mkdir /sys/fs/cgroup/memory/test_mem
- 設(shè)置限制:
echo 524288000 > /sys/fs/cgroup/memory/test_mem/memory.limit_in_bytes # 500MB
- 將進(jìn)程加入:
這樣該進(jìn)程占用內(nèi)存在超過(guò) 500MB 時(shí)可能會(huì)觸發(fā) OOM(Out Of Memory)動(dòng)作。echo <pid> > /sys/fs/cgroup/memory/test_mem/tasks
5. blkio 子系統(tǒng)
blkio
(Block IO) 用于限制進(jìn)程的塊設(shè)備 IO 速率,比如磁盤(pán)讀寫(xiě)速度。- 可以設(shè)置讀取速率、寫(xiě)入速率的限制。對(duì)需要在容器層面做 IO QoS 的場(chǎng)景很有幫助。
6. devices 子系統(tǒng)
devices
子系統(tǒng)可以控制某個(gè) cgroup 中的進(jìn)程可以訪問(wèn)哪些設(shè)備、只能讀或?qū)?、或完全禁止訪問(wèn)等。- 容器通常為了安全,會(huì)只允許訪問(wèn)少數(shù)必要設(shè)備(比如
/dev/null
、/dev/random
等)。
7. freezer 子系統(tǒng)
freezer
子系統(tǒng)提供了把 cgroup 內(nèi)進(jìn)程“凍結(jié)/解凍”的功能。- 可以把某個(gè) cgroup 的狀態(tài)設(shè)置為
FROZEN
,則該組內(nèi)所有進(jìn)程都掛起,等到切回THAWED
才繼續(xù)運(yùn)行。
8. net_cls 子系統(tǒng)
net_cls
可以為網(wǎng)絡(luò)數(shù)據(jù)包打上一個(gè)分類標(biāo)識(shí)(classid),配合 tc(traffic control)做網(wǎng)絡(luò)流量整形或帶寬控制。
9. net_prio 子系統(tǒng)
net_prio
子系統(tǒng)可以為 cgroup 中的進(jìn)程設(shè)置網(wǎng)絡(luò)優(yōu)先級(jí)(priority),從而在同一臺(tái)宿主機(jī)上的容器間做網(wǎng)絡(luò)流量?jī)?yōu)先級(jí)區(qū)分。
10. perf_event
perf_event
子系統(tǒng)方便對(duì)一組進(jìn)程進(jìn)行性能計(jì)數(shù)器(performance counter)的監(jiān)控,比如 CPU cycle、cache miss 等。
11. hugetlb
hugetlb
用于管理大頁(yè)內(nèi)存(Huge Pages)??梢韵拗颇硞€(gè) cgroup 使用多少大頁(yè)內(nèi)存。
總結(jié)
通過(guò) RootFs、Linux Namespace 和 cgroups 的巧妙組合,Docker 容器能夠在同一個(gè) Linux 內(nèi)核上運(yùn)行,卻擁有與宿主機(jī)和其他容器相對(duì)獨(dú)立的文件系統(tǒng)、進(jìn)程空間、網(wǎng)絡(luò)環(huán)境、IPC、以及嚴(yán)格的資源配額/限制。這為容器提供了接近虛擬機(jī)的隔離性,同時(shí)也保留了“共享同一個(gè)內(nèi)核”的優(yōu)勢(shì)(啟動(dòng)速度快、資源開(kāi)銷小等)。
- RootFs:讓容器擁有獨(dú)立的文件系統(tǒng)視圖,與宿主機(jī)的根目錄區(qū)分開(kāi)來(lái)。
- Linux Namespace:
- PID Namespace 讓容器內(nèi)部進(jìn)程有各自的 PID 視圖。
- Network Namespace 讓容器擁有獨(dú)立的虛擬網(wǎng)卡、網(wǎng)絡(luò)棧。
- Mount Namespace 讓容器控制自己的掛載點(diǎn)。
- UTS、IPC、User Namespace 等也實(shí)現(xiàn)其他層面的隔離。
- cgroups:
- 對(duì) CPU、內(nèi)存、IO 等進(jìn)行資源限制和監(jiān)控。
- 通過(guò) Docker 參數(shù)可很方便地指定容器的資源上限、優(yōu)先級(jí)。
這些機(jī)制共同構(gòu)成了 Docker 容器環(huán)境下的核心隔離和限制手段,使得容器能夠安全、穩(wěn)定地在生產(chǎn)環(huán)境中運(yùn)行各種應(yīng)用。
參考:
0voice · GitHub