-
使用Namespaces實現了系統環境的隔離,Namespaces允許一個行程以及它的子行程從共享的宿主機核心資源(網路棧、行程串列、掛載點等)裡獲得一個僅自己可見的隔離區域,讓同一個Namespace下的所有行程感知彼此變化,對外界行程一無所知,彷彿執行在一個獨佔的作業系統中;
-
使用CGroups限制這個環境的資源使用情況,比如一臺16核32GB的機器上只讓容器使用2核4GB。使用CGroups還可以為資源設定權重,計算使用量,操控任務(行程或執行緒)啟停等;
-
使用映象管理功能,利用Docker的映象分層、寫時複製、內容定址、聯合掛載技術實現了一套完整的容器檔案系統及執行環境,再結合映象倉庫,映象可以快速下載和共享,方便在多環境部署。
-
在Docker容器中執行top、free等命令,會發現看到的資源使用情況都是宿主機的資源情況,而我們需要的是這個容器被限制了多少CPU,記憶體,當前容器內的行程使用了多少;
-
在容器裡修改/etc/sysctl.conf,會收到提示”sysctl: error setting key ‘net.ipv4….’: Read-only file system”;
-
程式執行在容器裡面,呼叫API獲取系統記憶體、CPU,取到的是宿主機的資源大小;
-
對於多行程程式,一般都可以將worker數量設定成auto,自適應系統CPU核數,但在容器裡面這麼設定,取到的CPU核數是不正確的,例如Nginx,其他應用取到的可能也不正確,需要進行測試。
lynzabo@ubuntu:~$ strace free
execve("/usr/bin/free", ["free"], [/* 66 vars */]) = 0
...
statfs("/sys/fs/selinux", 0x7ffec90733a0) = -1 ENOENT (No such file or directory)
statfs("/selinux", 0x7ffec90733a0) = -1 ENOENT (No such file or directory)
open("/proc/filesystems", O_RDONLY) = 3
...
open("/sys/devices/system/cpu/online", O_RDONLY|O_CLOEXEC) = 3
...
open("/proc/meminfo", O_RDONLY) = 3
+++ exited with 0 +++
lynzabo@ubuntu:~$
const os = require('os');
const total = os.totalmem();
const free = os.freemem();
const usage = (free - total) / total * 100;
memory: usage 2047696kB, limit 2047696kB, failcnt 23543
memory+swap: usage 2047696kB, limit 9007199254740991kB, failcnt 0
......
Free swap = 0kB
Total swap = 0kB
......
Memory cgroup out of memory: Kill process 18286 (java) score 933 or sacrifice child
docker run -d -m 800M -e JAVA_OPTIONS='-Xmx300m' openjdk:8-jdk-alpine
docker run -d -m 800M -e JAVA_OPTIONS='-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=1' openjdk:8-jdk-alpine
-
/proc/self/fd->/dev/fd
-
/proc/self/fd/0->/dev/stdin
-
/proc/self/fd/1->/dev/stdout
-
/proc/self/fd/2->/dev/stderr
...
cgroup on /sys/fs/cgroup/cpuset type cgroup (ro,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/cpu type cgroup (ro,nosuid,nodev,noexec,relatime,cpu)
cgroup on /sys/fs/cgroup/cpuacct type cgroup (ro,nosuid,nodev,noexec,relatime,cpuacct)
cgroup on /sys/fs/cgroup/memory type cgroup (ro,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/devices type cgroup (ro,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/freezer type cgroup (ro,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/blkio type cgroup (ro,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/perf_event type cgroup (ro,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (ro,nosuid,nodev,noexec,relatime,hugetlb)
...
-
當為Pod指定了requests,其中 requests.cpu 會作為–cpu-shares 引數值傳遞給 docker run 命令,當一個宿主機上有多個容器發生CPU資源競爭時這個引數就會生效,引數值越大,越容易被分配到CPU,requests.memory 不會作為引數傳遞給Docker,這個引數在Kubernetes的資源QoS管理時使用;
-
當為Pod指定了limits,其中 limits.cpu 會作為 –cpu-quota 引數的值傳遞給 docker run 命令,docker run 命令中另外一個引數 –cpu-period 預設設定為100000,透過這兩個引數限制容器最多能夠使用的CPU核數,limits.memory 會作為 –memory 引數傳遞給docker run 命令,用來限制容器記憶體,目前Kubernetes不支援限制Swap大小,建議在部署Kubernetes時候禁用Swap。
# 這個值除以100000得到的就是容器核數
~ # cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us
400000
~ # cat /sys/fs/cgroup/memory/memory.usage_in_bytes
4289953792
~ # cat /sys/fs/cgroup/memory/memory.limit_in_bytes
4294967296
~ # cat /sys/fs/cgroup/memory/memory.oom_control
oom_kill_disable 0
under_oom 0
~ #
-
oom_kill_disable預設為0,表示開啟了oom killer,就是當記憶體超時會觸發kill行程。可以在使用docker run時候指定disable oom,將此值設定為1,關閉oom killer;
-
under_oom 這個值僅僅是用來看的,表示當前的CGroups的狀態是不是已經oom了,如果是,這個值將顯示為1。
~ # cat /sys/fs/cgroup/blkio/blkio.throttle.io_service_bytes
253:16 Read 20015124480
253:16 Write 24235769856
253:16 Sync 0
253:16 Async 44250894336
253:16 Total 44250894336
Total 44250894336
~ # cat /sys/class/net/eth0/statistics/rx_bytes
10167967741
~ # cat /sys/class/net/eth0/statistics/tx_bytes
15139291335
/proc/cpuinfo
/proc/diskstats
/proc/meminfo
/proc/stat
/proc/swaps
/proc/uptime