容器云系列之容器技术相关概念介绍
容器技術的發展越來越成熟和趨于標準化,本文主要介紹容器技術的相關概念,包括Docker的一些技術點,加深對容器技術領域的理解和掌握。
1、容器技術介紹
1.1 容器定義
容器是對服務器CPU和內存等資源分割和調度的基本單位,在容器出現之前在操作系統通過進程來實現,但是計算資源的隔離和靈活調度不滿足發展需要。容器是為開發者和系統管理員設計的,用于構建、發布和運行分布式應用的平臺。
在操作系統中一個進程和操作系統構成完整環境,不同進程共享操作系統,對于容器來說一個容器和對應的主機構成完整環境。容器中提供應用程序完整的運行時環境,包括:,
- 應用程序的代碼
- 相關配置文件、庫
- 運行應用程序所需的依賴項
容器化則是一種應用程序或系統分發方法,將應用程序或系統及其依賴項與底層基礎設施隔離開來。無論底層基礎設施什么硬件,什么樣的操作系統,只要系統支持容器。容器可以看成是操作系統級虛擬化,允許用戶在容器中部署和運行分布式應用程序或系統。
1.2 容器與虛擬機區別
虛擬機和容器都是資源隔離的一種方式
- 虛擬機:通過硬件隔離技術,虛擬出物理環境進行資源的隔離,再安裝一個完整的操作系統。
- 容器:最大的區別是GuestOS在容器中不存在,通過隔離文件系統和資源使用限制獨立運行進程,共享操作系統內核
- 容器比虛擬機上更加輕量級,性能消耗更小
- 虛擬機上很難做到內存的共用,容器中可以做到不同容器之間內存的共用
1.3 當前容器技術標準
傳統意義上的容器指代docker的概念已經發生了變化,在當前的容器環境下,原來docker環境下的dockershim逐漸演變為通過CRI插件來和containered交互,再由containered管理多個container。這個也成為主流和標準的方式,整個流程上更加的簡潔。
- OCI開放容器標準(Open Container Initiative)
- CRI 是支持多種容器運行時的插件接口
- Containerd可以在宿主機中管理完整的容器生命周期
- runC是OCI的參考實現
- 第一種是docker模式,通過dockershim跟docker引擎交互,再和Containered打交道,整個鏈路較長,逐漸被廢棄
- 第二種是通過CRI-Containered直接和containered交互
- 第三種方式,是把CRI插件嵌套到Containered中
- 第四種方式,直接通過CRi-O運行
2、Docker技術
2.1 Docker組件介紹
- 守護進程daemon:運行docker的后臺進程
- 客戶端client:與用戶交互,打包,拉/推鏡像,運行/停止/刪除容器
- 鏡像images:只讀的,把環境和程序代碼打成的包
- 倉庫registries:保存鏡像的地方
- 容器containers:從鏡像創建的應用運行實例,在內存中實例化的應用
2.1.1 Docker鏡像
1)鏡像的種類
- 基本鏡像是沒有父鏡像的鏡像,通常是操作系統的鏡像,如ubuntu、alpine或debian
- 子鏡像是建立在基礎鏡像上的鏡像,增加了額外的功能
- 官方鏡像是Docker認可的鏡像
- 用戶鏡像是用戶創建和分享的鏡像。建立在基礎鏡像的基礎上,并增加了額外的功能鏡像的格式是user/image-name
2)鏡像標簽
- 使用tag為容器鏡像打標簽:和hash id相比語義清晰,latest自動用在最新的鏡像上
- 采用USERNAME/CONTAINER_NAME:TAG的命名方法
2.1.2 Docker倉庫
用戶可以創建一個本地倉庫供內部使用,可以使用官方提供的工具docker-registry,并獲取官方registry鏡像來運行。倉庫會被創建在容器的/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運行過程
$ sudo docker run -i -t ubuntu /bin/bash以上為例運行ubuntu鏡像,按照順序,Docker執行以下流程
2.2 Docker核心原理
對Docker項目來說,它最核心的原理實際上就是為待創建的用戶進程:
Rootfs保證了容器的一致性,使得容器無論是在本地、物理機、云服務器上都處于同樣的運行環境
2.2.1 隔離和權限控制
容器技術主要包括Cgroup和Namespace這兩個內核特性:Namespace用于隔離資源、Cgroup用于限制資源。參看“容器云系列之Docker數據卷管理和資源限制”部分有關資源限制介紹。
1)Namespace
- pid命名空間:使用在進程隔離(PID: Process ID)
- net命名空間:使用在管理網絡接口(NET:Networking)
- ipc命名空間:使用在管理進程間通信資源 (IPC:InterProcess Communication)
- mnt命名空間:使用在管理掛載點 (MNT: Mount)
- uts命名空間:使用在隔離內核和版本標識 (UTS:Unix Timesharing System)
- user命名空間:每個container可以有不同的user和group id
2)Cgroup:為每種可以控制的資源定義了子系統,限制進程組能夠使用cpu、內存、磁盤、帶寬等資源的上限
- 限制資源使用,各種子系統的資源限制
- 優先級控制,cpu使用、內存、磁盤io吞吐等
- 資源使用報告,可以用來計費
- 控制,掛起、恢復進程
例:查看子系統/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:內存相關的限制
- Cpu:并不能像硬件虛擬化方案一樣能夠定義 CPU 能力,但是能夠定義 CPU 輪轉的優先級
- Blkio:block IO相關的統計和限制,byte/operation 統計和限制(IOPS 等),讀寫速度限制
- Devices:設備權限限制
3)Cgroups組織
- hierarchy: cgroups提供了一種類型的文件系統,是一組虛擬的文件系統,通過配置告訴內核,如何對進程限制使用資源。父子節點構成繼承的層級關系
- task:進程在cgroups中稱為task
- subsystem:cgroup支持的所有可配置的資源稱為子系統,如:cpu、內存、網絡等都是子系統
- cgroup: 資源控制單位,任務組包含若干子系統
4)Cgroup實戰
[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卷掛載
啟動容器時掛載整個“/”根目錄
- 這個掛載在容器根目錄上、用來為容器進程提供隔離后執行環境的文件系統,就是所謂的“容器鏡像”,稱為rootfs(根文件系統)
- volumn卷機制,指定特定文件或目錄,獨立生命周期,有兩種方式:啟動容器時-v掛載;在Dockerfile中VOLUME添加
2.2.3 Docker鏡像層
Docker 在鏡像的設計中,引入了層(layer)的概念。也就是說,用戶制作鏡像的每一步操作,都會生成一個層,也就是一個增量 rootfs
參考“容器云系列之Docker鏡像和倉庫管理”關于鏡像分層結構的介紹。
2.3 Docker網絡模式
創建Docker容器時,可以用–net選項指定容器的網絡模式。Docker有以下4種網絡模式:
- host模式:使用–net=host指定,共享宿主機網絡
- bridge模式:使用–net=bridge指定,默認設置
- container模式:使用–net=container:NAME(or)ID指定,共享另一個容器的網絡
- none模式:使用–net=none指定
參看“容器云系列之Docker網絡管理及容器互聯”有關容器網絡的詳細介紹。
2.3.1 Docker端口映射
- 為了做到網絡隔離,Docker使用Linux橋接,在宿主機虛擬容器網橋
- 啟動容器時會根據docker網橋的網段分配給容器一個IP地址,稱為Container-IP。這個IP地址和宿主機IP地址不一樣
- 網橋是每個容器的默認網關
- Docker網橋是宿主機虛擬出來的,不是真實存在的網絡設備
- 外部網絡時無法尋址到的
- 外部網絡無法直接通過Container-IP訪問到容器
- 通過映射容器端口到宿主機
- 通過-p或-P參數來啟用
- docker run -p 18080:80 nginx
2.3.2 Docker虛擬網橋
當Docker進程啟動時,會創建為docker0的虛擬網橋
- Docker容器會連接到這個虛擬網橋上
- 虛擬網橋的工作方式和物理交換機類似,所有容器就通過交換機連在一起
從docker0 子網中分配一個IP給容器使用,并設置docker0的IP地址為容器的默認網關
- 在主機上創建一對虛擬網卡veth pair設備
- 組成了一個數據的通道,數據進出
Docker將veth pair設備的一端放在新創建的容器中,并命名為eth0,另一端放在主機中,以veth*這樣類似的名字命名,并將這個網絡設備加入到docker0 網橋中。通過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 實現端口轉發功能
使用docker run -p時,docker實際是在iptables 做了DNAT規則,可以使用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連接網絡和自定義網絡
- link連接容器:docker run –link:alias,推薦不再使用
- 自定義網絡:創建新的Docker,在運行容器的時候使用新的網絡
運行另外一個
[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查看該容器處于退出狀態,但是容器沒有真正銷毀
[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:備份和恢復容器文件到tar文件,但是如果有tempfs卷則無法使用,因為不能備份內存信息。
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實戰
2.5.1 Dockerfile關鍵字
2.5.2 Docker Build創建
創建Dockerfile鏡像文件:
[root@tango-01 dockerfile]# vi Dockerfile FROM alpine ADD root.txt /tmp使用docker build命令構建
[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運行docker
[root@tango-01 dockerfile]# docker run -t -i alpine:v1.0 /bin/sh / # ls /tmp root.txtDockerfile使用經驗
- 不使用多條RUN指令,防止增加不必要的鏡像
- 添加文件使用\合并成為一行
- 采用合適的根鏡像:FROM ubuntu:20.04
- 采用COPY指令而不采用ADD
- 對鏡像打標簽,確定版本
2.6 Docker Compose工具
定義和運行多容器的應用程序工具,定義若干個容器作為整體運行。通過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運行
3、Podman
Podman是Redhat公司推出的容器管理工具,開發、管理、運行OCI容器,起初是CRI-O的一部分,后來單獨分離出來叫做libpod后來改成Podman。Podman的命令幾乎同docker類似,在結構上與Docker不同,Podman不使用daemon的方式去創建容器,而是直接調用OCI runtime,比如runc。Podman由兩部分組成:Podman CLI方便用戶交互和conmon負責container runtime,主要包括監控、日志、TTY分配等,是所有容器進程的父進程。
- 在Docker中主要是Docker Daemon進程,負責生成容器、和內核交互、管理鏡像、鏡像倉庫拉取鏡像,Docker CLI和Docker Daemon進行通信
- 在Podman中有buildah鏡像構建工具和skepeo鏡像拷貝工具分別負責鏡像構建和鏡像倉庫通信
4、總結
以上是最近參加的容器技術培訓有關容器這一塊的基本概念和技術點,全文基于張建鋒老師的培訓材料整理。容器技術這幾年發展迅猛,技術迭代更新很快,逐漸也形成一套行業標準,從Docker到K8S、Rancher以及Podman,開源和商業化產品的碰撞,行業內的產品和工具不斷涌現,整個生態也是欣欣向榮。
參考資料:
轉載請注明原文地址:https://blog.csdn.net/solihawk/article/details/124288506
文章會同步在公眾號“牧羊人的方向”更新,感興趣的可以關注公眾號,謝謝!
總結
以上是生活随笔為你收集整理的容器云系列之容器技术相关概念介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Win10要是个人,也算是鬼门关走过一遭
- 下一篇: Word怎么快速插入空白页