容器技術(shù)原理

何為容器?

容器,是一個(gè)視圖隔離、資源可限制、獨(dú)立文件系統(tǒng)的進(jìn)程集合

  • 鏡像?
    運(yùn)行容器所需要的所有文件集合

底層技術(shù)

  • namespaces-資源視圖隔離
  • cgroup-控制資源使用率
  • chroot-獨(dú)立的文件系統(tǒng)

chroot

簡(jiǎn)介

chroot (英文全稱:change root wiki) 命令用于改變根目錄,可以把根目錄換成指定的目的目錄,可以使其文件系統(tǒng)獨(dú)立

基本實(shí)驗(yàn)

mkdir chroottest
# 拷貝命令
cp -r /bin/ chroottest/bin
# 拷貝依賴庫(kù)
cp -r /lib/ chroottest/lib64
cp -r /lib64/ chroottest/lib64
cd chroottest/
# 將當(dāng)前目錄設(shè)為根目錄(chroot 需要root) 此時(shí)pwd輸出/
chroot .
# 推出
exit

注:chroot實(shí)驗(yàn)的要求必須有bash環(huán)境,為了方便拷貝了/lib64/lib,當(dāng)然也可以通過(guò)ldd /bin/bash拷貝指定依賴

C函數(shù)

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

void spawn_bash(void)
{
    char *newargv[] = { "/bin/bash", NULL };

    execv("/bin/bash", newargv);
    perror("exec");
    exit(EXIT_FAILURE);
}

int main() {
    int ret;
    char chroot_path[] = "/root/chroottest/";
    char *pwd;

    /*chroot 需要root權(quán)限*/
    ret = chroot(chroot_path);
    if (ret != 0) {
        perror("chroot:");
        exit(-1);
    }
    pwd = getcwd(NULL, 80);
    printf("pwd is [%s]\n",pwd);
    free(pwd);
    spawn_bash();
}

其他

為了在Linux中具有可用的chroot環(huán)境,wiki上提供了操作方法,考慮wiki訪問(wèn)不友好,將方法寫(xiě)到本博客中,方法如下:

# Mount Kernel Virtual File Systems
TARGETDIR="/mnt/chroot"
$ mount -t proc proc $TARGETDIR/proc
$ mount -t sysfs sysfs $TARGETDIR/sys
$ mount -t devtmpfs devtmpfs $TARGETDIR/dev
$ mount -t tmpfs tmpfs $TARGETDIR/dev/shm
$ mount -t devpts devpts $TARGETDIR/dev/pts

# Copy /etc/hosts
/bin/cp -f /etc/hosts $TARGETDIR/etc/

# Copy /etc/resolv.conf 
/bin/cp -f /etc/resolv.conf $TARGETDIR/etc/resolv.conf

# Link /etc/mtab
chroot $TARGETDIR rm /etc/mtab 2> /dev/null 
chroot $TARGETDIR ln -s /proc/mounts /etc/mtab

namespaces(命名空間)

簡(jiǎn)介

Linux namespaceswiki包含了大多數(shù)現(xiàn)代容器實(shí)現(xiàn)背后的一些基本技術(shù)。在較高的級(jí)別上,它們?cè)试S隔離獨(dú)立進(jìn)程之間的全局系統(tǒng)資源。例如,文件系統(tǒng)、主機(jī)名、用戶、網(wǎng)絡(luò)和進(jìn)程

基本實(shí)驗(yàn)

# 查看當(dāng)前主機(jī)名
$ hostname
# 在新UTS名稱空間中執(zhí)行shell
$ unshare -u /bin/sh
# 設(shè)置 hostname
$ hostname abcd
$ hostname
# 推出
$ exit
# 查看當(dāng)前主機(jī)名 沒(méi)有更改
$ hostname

C函數(shù)

#define _GNU_SOURCE

#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/wait.h>
#include <unistd.h>

int spawn_bash(void)
{
    char *newargv[] = { "/bin/bash", NULL };

    execv("/bin/bash", newargv);
    perror("exec");
    exit(EXIT_FAILURE);
}

int child(void *args)
{
    printf("pid as seen in the child: %lu\n", (unsigned long)getpid());
    spawn_bash();
}

int main()
{
    //需要 root 權(quán)限
    int namespaces = CLONE_NEWUTS|CLONE_NEWPID|CLONE_NEWIPC|CLONE_NEWNS|CLONE_NEWNET;
    pid_t p = clone(child, malloc(4096) + 4096, SIGCHLD|namespaces, NULL);
    if (p == -1) {
        perror("clone");
        exit(1);
    }
    printf("child pid: %lu\n", p);
    waitpid(p, NULL, 0);
    return 0;
}

cgroups

簡(jiǎn)介

cgroups,wiki,其名稱源自控制組群(英語(yǔ):control groups)的簡(jiǎn)寫(xiě),是Linux內(nèi)核的一個(gè)功能,用來(lái)限制、控制與分離一個(gè)進(jìn)程組的資源(如CPU、內(nèi)存、磁盤(pán)輸入輸出等)

基本實(shí)驗(yàn)

# 安裝cgroup ubuntu
$ apt-get install cgroup-bin
$ cd /sys/fs/cgroup
# 設(shè)置可分配最大內(nèi)存為 300 MB
$ cd /memory
$ mkdir test
$ cd test
$ echo 314572800 > memory.limit_in_bytes

創(chuàng)建一個(gè)分配內(nèi)存的程序

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define CHUNK_SIZE 1024 * 1024 * 100

void main(){
    char *p;
    int i;

    for(i = 0; i < 10; i ++)
    {
        p = malloc(sizeof(char) * CHUNK_SIZE);
        if(p == NULL){
            printf("fail to malloc!");
            return ;
        }
        memset(p, 0, CHUNK_SIZE);
        printf("malloc memory %d MB\n", (i + 1) * 100);
    }
}

執(zhí)行結(jié)果如下,當(dāng)進(jìn)程占用的內(nèi)存超過(guò)限制時(shí),將被 kill

$ cgexec -g memory:test./a.out
malloc memory 100 MB
malloc memory 200 MB
Killed

目錄說(shuō)明

├─/sys/fs/cgroup
│  ├─blkio              對(duì)塊設(shè)備的IO進(jìn)行限制
│  ├─ cpu               限制 CPU 時(shí)間片的分配,與 cpuacct 掛載在同一目錄
│  ├─ cpuacct           生成 cgroup 中的任務(wù)占用 CPU 資源的報(bào)告,與 cpu 掛載在同一目錄  
│  ├─cpuset             給 cgroup 中的任務(wù)分配獨(dú)立的 CPU(多處理器系統(tǒng)) 和內(nèi)存節(jié)點(diǎn)
│  ├─devices            允許或禁止 cgroup 中的任務(wù)訪問(wèn)設(shè)備 
│  ├─freezer            暫停/恢復(fù) cgroup 中的任務(wù)
│  ├─hugetlb            限制使用的內(nèi)存頁(yè)數(shù)量 
│  ├─memory             對(duì) cgroup 中的任務(wù)的可用內(nèi)存進(jìn)行限制,并自動(dòng)生成資源占用報(bào)告
│  ├─pids               限制任務(wù)的數(shù)量
│  └─ ...
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容