容器云系列之容器技术相关概念介绍
容器技術(shù)的發(fā)展越來越成熟和趨于標(biāo)準(zhǔn)化,本文主要介紹容器技術(shù)的相關(guān)概念,包括Docker的一些技術(shù)點(diǎn),加深對(duì)容器技術(shù)領(lǐng)域的理解和掌握。
1、容器技術(shù)介紹
1.1 容器定義
容器是對(duì)服務(wù)器CPU和內(nèi)存等資源分割和調(diào)度的基本單位,在容器出現(xiàn)之前在操作系統(tǒng)通過進(jìn)程來實(shí)現(xiàn),但是計(jì)算資源的隔離和靈活調(diào)度不滿足發(fā)展需要。容器是為開發(fā)者和系統(tǒng)管理員設(shè)計(jì)的,用于構(gòu)建、發(fā)布和運(yùn)行分布式應(yīng)用的平臺(tái)。
在操作系統(tǒng)中一個(gè)進(jìn)程和操作系統(tǒng)構(gòu)成完整環(huán)境,不同進(jìn)程共享操作系統(tǒng),對(duì)于容器來說一個(gè)容器和對(duì)應(yīng)的主機(jī)構(gòu)成完整環(huán)境。容器中提供應(yīng)用程序完整的運(yùn)行時(shí)環(huán)境,包括:,
- 應(yīng)用程序的代碼
- 相關(guān)配置文件、庫
- 運(yùn)行應(yīng)用程序所需的依賴項(xiàng)
容器化則是一種應(yīng)用程序或系統(tǒng)分發(fā)方法,將應(yīng)用程序或系統(tǒng)及其依賴項(xiàng)與底層基礎(chǔ)設(shè)施隔離開來。無論底層基礎(chǔ)設(shè)施什么硬件,什么樣的操作系統(tǒng),只要系統(tǒng)支持容器。容器可以看成是操作系統(tǒng)級(jí)虛擬化,允許用戶在容器中部署和運(yùn)行分布式應(yīng)用程序或系統(tǒng)。
1.2 容器與虛擬機(jī)區(qū)別
虛擬機(jī)和容器都是資源隔離的一種方式
- 虛擬機(jī):通過硬件隔離技術(shù),虛擬出物理環(huán)境進(jìn)行資源的隔離,再安裝一個(gè)完整的操作系統(tǒng)。
- 容器:最大的區(qū)別是GuestOS在容器中不存在,通過隔離文件系統(tǒng)和資源使用限制獨(dú)立運(yùn)行進(jìn)程,共享操作系統(tǒng)內(nèi)核
- 容器比虛擬機(jī)上更加輕量級(jí),性能消耗更小
- 虛擬機(jī)上很難做到內(nèi)存的共用,容器中可以做到不同容器之間內(nèi)存的共用
1.3 當(dāng)前容器技術(shù)標(biāo)準(zhǔn)
傳統(tǒng)意義上的容器指代docker的概念已經(jīng)發(fā)生了變化,在當(dāng)前的容器環(huán)境下,原來docker環(huán)境下的dockershim逐漸演變?yōu)橥ㄟ^CRI插件來和containered交互,再由containered管理多個(gè)container。這個(gè)也成為主流和標(biāo)準(zhǔn)的方式,整個(gè)流程上更加的簡(jiǎn)潔。
- OCI開放容器標(biāo)準(zhǔn)(Open Container Initiative)
- CRI 是支持多種容器運(yùn)行時(shí)的插件接口
- Containerd可以在宿主機(jī)中管理完整的容器生命周期
- runC是OCI的參考實(shí)現(xiàn)
- 第一種是docker模式,通過dockershim跟docker引擎交互,再和Containered打交道,整個(gè)鏈路較長(zhǎng),逐漸被廢棄
- 第二種是通過CRI-Containered直接和containered交互
- 第三種方式,是把CRI插件嵌套到Containered中
- 第四種方式,直接通過CRi-O運(yùn)行
2、Docker技術(shù)
2.1 Docker組件介紹
- 守護(hù)進(jìn)程daemon:運(yùn)行docker的后臺(tái)進(jìn)程
- 客戶端client:與用戶交互,打包,拉/推鏡像,運(yùn)行/停止/刪除容器
- 鏡像images:只讀的,把環(huán)境和程序代碼打成的包
- 倉庫registries:保存鏡像的地方
- 容器containers:從鏡像創(chuàng)建的應(yīng)用運(yùn)行實(shí)例,在內(nèi)存中實(shí)例化的應(yīng)用
2.1.1 Docker鏡像
1)鏡像的種類
- 基本鏡像是沒有父鏡像的鏡像,通常是操作系統(tǒng)的鏡像,如ubuntu、alpine或debian
- 子鏡像是建立在基礎(chǔ)鏡像上的鏡像,增加了額外的功能
- 官方鏡像是Docker認(rèn)可的鏡像
- 用戶鏡像是用戶創(chuàng)建和分享的鏡像。建立在基礎(chǔ)鏡像的基礎(chǔ)上,并增加了額外的功能鏡像的格式是user/image-name
2)鏡像標(biāo)簽
- 使用tag為容器鏡像打標(biāo)簽:和hash id相比語義清晰,latest自動(dòng)用在最新的鏡像上
- 采用USERNAME/CONTAINER_NAME:TAG的命名方法
2.1.2 Docker倉庫
用戶可以創(chuàng)建一個(gè)本地倉庫供內(nèi)部使用,可以使用官方提供的工具docker-registry,并獲取官方registry鏡像來運(yùn)行。倉庫會(huì)被創(chuàng)建在容器的/var/lib/registry目錄:
docker run --name registry -d -p 5000:5000 --restart=always –v /opt/data/registry:/var/lib/registry registry- 推送到本地倉庫:docker push localhost:5000/session-web:latest
- 查看私有倉庫中鏡像:curl localhost:5000/v2/_catlog
- 推薦使用倉庫軟件工具Harbor和Quay。
2.1.3 Docker運(yùn)行過程
$ sudo docker run -i -t ubuntu /bin/bash以上為例運(yùn)行ubuntu鏡像,按照順序,Docker執(zhí)行以下流程
2.2 Docker核心原理
對(duì)Docker項(xiàng)目來說,它最核心的原理實(shí)際上就是為待創(chuàng)建的用戶進(jìn)程:
Rootfs保證了容器的一致性,使得容器無論是在本地、物理機(jī)、云服務(wù)器上都處于同樣的運(yùn)行環(huán)境
2.2.1 隔離和權(quán)限控制
容器技術(shù)主要包括Cgroup和Namespace這兩個(gè)內(nèi)核特性:Namespace用于隔離資源、Cgroup用于限制資源。參看“容器云系列之Docker數(shù)據(jù)卷管理和資源限制”部分有關(guān)資源限制介紹。
1)Namespace
- pid命名空間:使用在進(jìn)程隔離(PID: Process ID)
- net命名空間:使用在管理網(wǎng)絡(luò)接口(NET:Networking)
- ipc命名空間:使用在管理進(jìn)程間通信資源 (IPC:InterProcess Communication)
- mnt命名空間:使用在管理掛載點(diǎn) (MNT: Mount)
- uts命名空間:使用在隔離內(nèi)核和版本標(biāo)識(shí) (UTS:Unix Timesharing System)
- user命名空間:每個(gè)container可以有不同的user和group id
2)Cgroup:為每種可以控制的資源定義了子系統(tǒng),限制進(jìn)程組能夠使用cpu、內(nèi)存、磁盤、帶寬等資源的上限
- 限制資源使用,各種子系統(tǒng)的資源限制
- 優(yōu)先級(jí)控制,cpu使用、內(nèi)存、磁盤io吞吐等
- 資源使用報(bào)告,可以用來計(jì)費(fèi)
- 控制,掛起、恢復(fù)進(jìn)程
例:查看子系統(tǒng)/sys/fs/cgroup/
[root@tango-01 cgroup]# cd /sys/fs/cgroup/ [root@tango-01 cgroup]# ll total 0 drwxr-xr-x 6 root root 0 Apr 16 15:38 blkio lrwxrwxrwx 1 root root 11 Apr 16 15:38 cpu -> cpu,cpuacct lrwxrwxrwx 1 root root 11 Apr 16 15:38 cpuacct -> cpu,cpuacct drwxr-xr-x 6 root root 0 Apr 16 15:38 cpu,cpuacct drwxr-xr-x 3 root root 0 Apr 16 15:38 cpuset drwxr-xr-x 6 root root 0 Apr 16 15:38 devices drwxr-xr-x 3 root root 0 Apr 16 15:38 freezer drwxr-xr-x 3 root root 0 Apr 16 15:38 hugetlb drwxr-xr-x 6 root root 0 Apr 16 15:38 memory lrwxrwxrwx 1 root root 16 Apr 16 15:38 net_cls -> net_cls,net_prio drwxr-xr-x 3 root root 0 Apr 16 15:38 net_cls,net_prio lrwxrwxrwx 1 root root 16 Apr 16 15:38 net_prio -> net_cls,net_prio drwxr-xr-x 3 root root 0 Apr 16 15:38 perf_event drwxr-xr-x 6 root root 0 Apr 16 15:38 pids drwxr-xr-x 6 root root 0 Apr 16 15:38 systemd- Memory:內(nèi)存相關(guān)的限制
- Cpu:并不能像硬件虛擬化方案一樣能夠定義 CPU 能力,但是能夠定義 CPU 輪轉(zhuǎn)的優(yōu)先級(jí)
- Blkio:block IO相關(guān)的統(tǒng)計(jì)和限制,byte/operation 統(tǒng)計(jì)和限制(IOPS 等),讀寫速度限制
- Devices:設(shè)備權(quán)限限制
3)Cgroups組織
- hierarchy: cgroups提供了一種類型的文件系統(tǒng),是一組虛擬的文件系統(tǒng),通過配置告訴內(nèi)核,如何對(duì)進(jìn)程限制使用資源。父子節(jié)點(diǎn)構(gòu)成繼承的層級(jí)關(guān)系
- task:進(jìn)程在cgroups中稱為task
- subsystem:cgroup支持的所有可配置的資源稱為子系統(tǒng),如:cpu、內(nèi)存、網(wǎng)絡(luò)等都是子系統(tǒng)
- cgroup: 資源控制單位,任務(wù)組包含若干子系統(tǒng)
4)Cgroup實(shí)戰(zhàn)
[root@tango-01 cpu]# mkdir /sys/fs/cgroup/cpu/mycgroup [root@tango-01 cpu]# ls -l mycgroup total 0 -rw-r--r-- 1 root root 0 Apr 16 16:45 cgroup.clone_children --w--w--w- 1 root root 0 Apr 16 16:45 cgroup.event_control -rw-r--r-- 1 root root 0 Apr 16 16:45 cgroup.procs -r--r--r-- 1 root root 0 Apr 16 16:45 cpuacct.stat -rw-r--r-- 1 root root 0 Apr 16 16:45 cpuacct.usage -r--r--r-- 1 root root 0 Apr 16 16:45 cpuacct.usage_percpu -rw-r--r-- 1 root root 0 Apr 16 16:45 cpu.cfs_period_us -rw-r--r-- 1 root root 0 Apr 16 16:45 cpu.cfs_quota_us -rw-r--r-- 1 root root 0 Apr 16 16:45 cpu.rt_period_us -rw-r--r-- 1 root root 0 Apr 16 16:45 cpu.rt_runtime_us -rw-r--r-- 1 root root 0 Apr 16 16:45 cpu.shares -r--r--r-- 1 root root 0 Apr 16 16:45 cpu.stat -rw-r--r-- 1 root root 0 Apr 16 16:45 notify_on_release -rw-r--r-- 1 root root 0 Apr 16 16:45 tasks模擬高CPU占用 cat /dev/urandom | gzip -9 > /dev/null
[root@tango-01 cpu]# cat /dev/urandom | gzip -9 > /dev/nullPID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 13536 root 20 0 4624 612 396 R 40.7 0.0 0:11.78 gzip限制CPU,占用率不超過20%
[root@tango-01 mycgroup]# echo 10000 > cpu.cfs_quota_us [root@tango-01 mycgroup]# echo 50000 > cpu.cfs_period_us [root@tango-01 mycgroup]# echo 13536 > tasks查看CPU使用
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 13536 root 20 0 4624 612 396 R 8.0 0.0 1:50.98 gzip2.2.2 Docker卷掛載
啟動(dòng)容器時(shí)掛載整個(gè)“/”根目錄
- 這個(gè)掛載在容器根目錄上、用來為容器進(jìn)程提供隔離后執(zhí)行環(huán)境的文件系統(tǒng),就是所謂的“容器鏡像”,稱為rootfs(根文件系統(tǒng))
- volumn卷機(jī)制,指定特定文件或目錄,獨(dú)立生命周期,有兩種方式:啟動(dòng)容器時(shí)-v掛載;在Dockerfile中VOLUME添加
2.2.3 Docker鏡像層
Docker 在鏡像的設(shè)計(jì)中,引入了層(layer)的概念。也就是說,用戶制作鏡像的每一步操作,都會(huì)生成一個(gè)層,也就是一個(gè)增量 rootfs
參考“容器云系列之Docker鏡像和倉庫管理”關(guān)于鏡像分層結(jié)構(gòu)的介紹。
2.3 Docker網(wǎng)絡(luò)模式
創(chuàng)建Docker容器時(shí),可以用–net選項(xiàng)指定容器的網(wǎng)絡(luò)模式。Docker有以下4種網(wǎng)絡(luò)模式:
- host模式:使用–net=host指定,共享宿主機(jī)網(wǎng)絡(luò)
- bridge模式:使用–net=bridge指定,默認(rèn)設(shè)置
- container模式:使用–net=container:NAME(or)ID指定,共享另一個(gè)容器的網(wǎng)絡(luò)
- none模式:使用–net=none指定
參看“容器云系列之Docker網(wǎng)絡(luò)管理及容器互聯(lián)”有關(guān)容器網(wǎng)絡(luò)的詳細(xì)介紹。
2.3.1 Docker端口映射
- 為了做到網(wǎng)絡(luò)隔離,Docker使用Linux橋接,在宿主機(jī)虛擬容器網(wǎng)橋
- 啟動(dòng)容器時(shí)會(huì)根據(jù)docker網(wǎng)橋的網(wǎng)段分配給容器一個(gè)IP地址,稱為Container-IP。這個(gè)IP地址和宿主機(jī)IP地址不一樣
- 網(wǎng)橋是每個(gè)容器的默認(rèn)網(wǎng)關(guān)
- Docker網(wǎng)橋是宿主機(jī)虛擬出來的,不是真實(shí)存在的網(wǎng)絡(luò)設(shè)備
- 外部網(wǎng)絡(luò)時(shí)無法尋址到的
- 外部網(wǎng)絡(luò)無法直接通過Container-IP訪問到容器
- 通過映射容器端口到宿主機(jī)
- 通過-p或-P參數(shù)來啟用
- docker run -p 18080:80 nginx
2.3.2 Docker虛擬網(wǎng)橋
當(dāng)Docker進(jìn)程啟動(dòng)時(shí),會(huì)創(chuàng)建為docker0的虛擬網(wǎng)橋
- Docker容器會(huì)連接到這個(gè)虛擬網(wǎng)橋上
- 虛擬網(wǎng)橋的工作方式和物理交換機(jī)類似,所有容器就通過交換機(jī)連在一起
從docker0 子網(wǎng)中分配一個(gè)IP給容器使用,并設(shè)置docker0的IP地址為容器的默認(rèn)網(wǎng)關(guān)
- 在主機(jī)上創(chuàng)建一對(duì)虛擬網(wǎng)卡veth pair設(shè)備
- 組成了一個(gè)數(shù)據(jù)的通道,數(shù)據(jù)進(jìn)出
Docker將veth pair設(shè)備的一端放在新創(chuàng)建的容器中,并命名為eth0,另一端放在主機(jī)中,以veth*這樣類似的名字命名,并將這個(gè)網(wǎng)絡(luò)設(shè)備加入到docker0 網(wǎng)橋中。通過brctl show 命令查看
[root@tango-01 ~]# brctl show bridge name bridge id STP enabled interfaces br-1d93f41271b4 8000.0242a3d69c1c no br-d9ffb1af87f2 8000.024262f9a631 no veth70da614veth78ca7c6vethb281fb7vethfb847e9 docker0 8000.02421ad85f66 no2.3.3 實(shí)現(xiàn)端口轉(zhuǎn)發(fā)功能
使用docker run -p時(shí),docker實(shí)際是在iptables 做了DNAT規(guī)則,可以使用iptables -t nat -nL查看
[root@tango-01 mycgroup]# iptables -t nat -nL DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 to:172.19.0.3:8052 DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:18080 to:172.17.0.2:802.3.4 連接容器
容器之間的連接有兩種方式:link連接網(wǎng)絡(luò)和自定義網(wǎng)絡(luò)
- link連接容器:docker run –link:alias,推薦不再使用
- 自定義網(wǎng)絡(luò):創(chuàng)建新的Docker,在運(yùn)行容器的時(shí)候使用新的網(wǎng)絡(luò)
運(yùn)行另外一個(gè)
[root@tango-01 ~]# docker run -it --rm --name busybox2 --network my-net busybox sh / # / # ifconfig eth0 Link encap:Ethernet HWaddr 02:42:AC:14:00:03 inet addr:172.20.0.3 Bcast:172.20.255.255 Mask:255.255.0.0UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1RX packets:6 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0 RX bytes:516 (516.0 B) TX bytes:0 (0.0 B)lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0UP LOOPBACK RUNNING MTU:65536 Metric:1RX packets:0 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)/ #2.4 Docker命令解析
docker ps –a查看該容器處于退出狀態(tài),但是容器沒有真正銷毀
[root@tango-01 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f88d934e7197 busybox "echo hello world" 36 seconds ago Exited (0) 14 seconds ago stoic_keplerexport/import:備份和恢復(fù)容器文件到tar文件,但是如果有tempfs卷則無法使用,因?yàn)椴荒軅浞輧?nèi)存信息。
docker rm:刪除容器
通過diff命令可以查看修改的歷史記錄
[root@tango-01 ~]# docker diff a80287c1f2da C /tmp A /tmp/root.txt C /root A /root/.ash_history [root@tango-01 ~]#2.5 Dockerfile實(shí)戰(zhàn)
2.5.1 Dockerfile關(guān)鍵字
2.5.2 Docker Build創(chuàng)建
創(chuàng)建Dockerfile鏡像文件:
[root@tango-01 dockerfile]# vi Dockerfile FROM alpine ADD root.txt /tmp使用docker build命令構(gòu)建
[root@tango-01 dockerfile]# docker build -t alpine:v1.0 . Sending build context to Docker daemon 1.06MB Step 1/2 : FROM alpine---> c059bfaa849c Step 2/2 : ADD root.txt /tmp---> d0b7c4e5849f Successfully built d0b7c4e5849f Successfully tagged alpine:v1.0運(yùn)行docker
[root@tango-01 dockerfile]# docker run -t -i alpine:v1.0 /bin/sh / # ls /tmp root.txtDockerfile使用經(jīng)驗(yàn)
- 不使用多條RUN指令,防止增加不必要的鏡像
- 添加文件使用\合并成為一行
- 采用合適的根鏡像:FROM ubuntu:20.04
- 采用COPY指令而不采用ADD
- 對(duì)鏡像打標(biāo)簽,確定版本
2.6 Docker Compose工具
定義和運(yùn)行多容器的應(yīng)用程序工具,定義若干個(gè)容器作為整體運(yùn)行。通過docker-compose.yml文件定義,包含version、services和networks三部分。
version: "3.9" services: db: image: postgres volumes: - ./tmp/db:/var/lib/postgresql/data environment: POSTGRES_PASSWORD: password web: build: . command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'" volumes: - .:/myapp ports: - "3000:3000" depends_on: - db通過命令docker-compose up運(yùn)行
3、Podman
Podman是Redhat公司推出的容器管理工具,開發(fā)、管理、運(yùn)行OCI容器,起初是CRI-O的一部分,后來單獨(dú)分離出來叫做libpod后來改成Podman。Podman的命令幾乎同docker類似,在結(jié)構(gòu)上與Docker不同,Podman不使用daemon的方式去創(chuàng)建容器,而是直接調(diào)用OCI runtime,比如runc。Podman由兩部分組成:Podman CLI方便用戶交互和conmon負(fù)責(zé)container runtime,主要包括監(jiān)控、日志、TTY分配等,是所有容器進(jìn)程的父進(jìn)程。
- 在Docker中主要是Docker Daemon進(jìn)程,負(fù)責(zé)生成容器、和內(nèi)核交互、管理鏡像、鏡像倉庫拉取鏡像,Docker CLI和Docker Daemon進(jìn)行通信
- 在Podman中有buildah鏡像構(gòu)建工具和skepeo鏡像拷貝工具分別負(fù)責(zé)鏡像構(gòu)建和鏡像倉庫通信
4、總結(jié)
以上是最近參加的容器技術(shù)培訓(xùn)有關(guān)容器這一塊的基本概念和技術(shù)點(diǎn),全文基于張建鋒老師的培訓(xùn)材料整理。容器技術(shù)這幾年發(fā)展迅猛,技術(shù)迭代更新很快,逐漸也形成一套行業(yè)標(biāo)準(zhǔn),從Docker到K8S、Rancher以及Podman,開源和商業(yè)化產(chǎn)品的碰撞,行業(yè)內(nèi)的產(chǎn)品和工具不斷涌現(xiàn),整個(gè)生態(tài)也是欣欣向榮。
參考資料:
轉(zhuǎn)載請(qǐng)注明原文地址:https://blog.csdn.net/solihawk/article/details/124288506
文章會(huì)同步在公眾號(hào)“牧羊人的方向”更新,感興趣的可以關(guān)注公眾號(hào),謝謝!
總結(jié)
以上是生活随笔為你收集整理的容器云系列之容器技术相关概念介绍的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Win10要是个人,也算是鬼门关走过一遭
- 下一篇: Word怎么快速插入空白页