《云原生入门级开发者认证》学习笔记之云原生基础设施之容器技术
寫在前面
- 嗯,報了考試,整理課堂筆記記憶
- 學習的原因:
- 雖然考了CKA,了解了一些K8s相關的知識
- 但是對云原生整個體系一直都很模糊
- 希望對云原生有一個基本的認識
- 通過學習實現云原生相關入門
- 博文主要內容涉及:
- 關于Docker知識體系的簡述,適合溫習
- 講的很淺,都是理論,沒有實戰
傍晚時分,你坐在屋檐下,看著天慢慢地黑下去,心里寂寞而凄涼,感到自己的生命被剝奪了。當時我是個年輕人,但我害怕這樣生活下去,衰老下去。在我看來,這是比死亡更可怕的事。--------王小波
云原生基礎設施之容器技術
容器發展背景
企業IT業務云化路徑
傳統業務云化
業務云化創新
容器是什么?
容器是一種輕量級、可移植、自包含的軟件打包技術,使應用程序可以在幾乎任何地方以相同的方式運行。
開發人員在自己開發環境創建并測試好的容器,無需任何修改就能夠在生產系統的虛擬機、物理服務器或公有云主機上運行
容器核心思想
將集裝箱的思想應用到了軟件的打包和部署上,為各類不同的代碼提供了一個基于容器的標準化運輸系統。
容器與虛擬機
容器和虛擬機 之間的主要區別在于虛擬化層的位置和操作系統資源的使用方式。
用戶運行在容器里的應用進程,跟宿主機上的其他進程一樣,都由宿主機操作系統統一管理,只不過這些被隔離的進程擁有額外設置過的Namespace參數。而Docker項目在這里扮演的角色,更,多的是旁路式的輔助和管理工作
Docker項目介紹
2013年, dotCloud公司將Docker項目開源。
Docker項目:GitHub上開發的Moby開源項目的一部分,遵循Apache License 2.0許可證協議,Go語言編寫Docker是一個開源的引擎,可以輕松的為任何應用創建一個輕量級的、可移植的、自給自足的容器。
Docker公司目前推出兩個版本:
- Docker CE (社區版),
- Docker EE (企業版)
容器關鍵技術介紹
容器規范
容器不光是Docker,還有其他容器,比如CoreOS的rkt,紅帽的podman,以及之后的K8s之后的containerd。為了保證容器生態的健康發展,保證不同容器之間能夠兼容,包含Docker-CoreOS-Google在內的若干公司共同成立了一個叫Open Container Initiative(OCI)的組織,其目是制定開放的容器規范。
容器runtime
runtime與操作系統kernel緊密協作,為容器提供運行環境。常見的容器runtime:
- runC是Docker公司2015年發布的容器runtime工具,符合OCI規范。 runC Libcontainer演變而來。
- rkt,是CoreOS公司開發的Docker/runc的一個流行替代方案,符合OCI規范。
- Kata, 2017年整合Clear ContainerNrunV項目,基于虛擬化技術的容器實現,符合OCI規范。
- gVisor ,2018 年Google公司發布 gVisor的項目,基于虛擬化技術的容器實現,符合OCI規范
Docker 引擎
Docker主要指容器引擎,即Docker engine。Docker Engine是-個Client/Server應用程序。Docker engine主要組件有3部分:
- 服務器:是一個長期運行的程序,稱為daemon進程:Docker daemon用于創建和管理docker對象,如容器鏡像、容器、網絡、卷。
- 命令行界面客戶端(docker CLI):CLI使用Docker REST API通過腳本或直接的CLI命令與Docker daemon交互。
- 一個REST API:Client可以用它來與daemon進程通信交互。
Docker 架構
- Docker Client: Docker是個采用的C/S架構的應用程序。Docker Client一般通過Docker command來發起請求。在用戶界面,支持用戶與Docker Daemon之間通信
- Docker daemon :簡單地說, Docker daemon實現的功能就是接收客戶端發來的請求,并實現請求所要求的功能,同時針對請求返回相應的結果。Docker daemon是驅動整個Docker功能的核心引擎。在功能的實現上,Docker daemon涉及了容器、鏡像、存儲等多方面的內容,涉及多個模塊的實現和交互。
- Containers :容器以鏡像為基礎,同時又為鏡像提供了一個標準和隔離的運行環境。Docker的容器就是“軟件界的集裝箱”,可以安裝任意的軟件和庫文件,做任意的運行環境配置。開發及運維人員在轉移和部署應用的時候,不需關心容器里裝了什么軟件,也不需了解它們是如何配置的。
- Docker Image :與容器相對應,如果說容器提供了一個完整的、隔離的運行環境,那么鏡像則是這個運行環境的靜態體現
- Registry : Registry是一個存放鏡像的倉庫。Registry本身也是一個單獨的開源項目企業可使用Registry鏡像搭建私有倉庫。
Docker容器實現原理
Docker容器通過namespace技術實現進程隔離,通過cgroup技術實現容器進程可用資源的限制。Docker啟動一個容器時,實際是創建了包含多個namespace參數的進程。
Namespace
Namespace :命名空間作用:資源隔離。 namespace將內核的全局資源進行封裝,使得每個namespace都有一份獨立的資源。因此不同進程在各自namespace內對同一種資源的使用不會相互干擾。
Namespace實際上是Linux系統上創建新進程時的一個可選參數。實際上在創建Docker容器時,指定了這個進程所需要啟用的一組namespace參數。通過namespace機制的隔離,容器只能見到當前Namespace中所限定的資源、文件、設備、狀態或配置。以此實現應用運行環境的隔離。
PID namespace隔離示例
以交互模式啟動一個centos容器,并在其中運行/bin/bash程序。執行ps命令查看到"/bin/bash"是PID=1的進程,即Docker將其隔離于宿主機中的其他進程之外。
Cgroups
Cgroups : Linux Control Groups作用:限制一個進程組對系統資源的使用上限,包括CPU、內存、Block I/O等。
┌──[root@vms81.liruilongs.github.io]-[~] └─$cd /sys/fs/cgroup ┌──[root@vms81.liruilongs.github.io]-[/sys/fs/cgroup] └─$ls blkio cpuacct cpuset freezer memory net_cls,net_prio perf_event systemd cpu cpu,cpuacct devices hugetlb net_cls net_prio pids ┌──[root@vms81.liruilongs.github.io]-[/sys/fs/cgroup] └─$Cgroups還可以設置進程優先級,對進程進行掛起和恢復等操作。
原理 :將一組進程放在一個Cgroup中,通過給這個Cgroup分配指定的可用資源,達到控制這一組進程可用資源的目的
實現 :在Linux中,Cgroups以文件和目錄的方式組織在操作系統的/sys/fs/cgroup路徑下。該路徑中所有的資源種類均可被Cgroup限制。
┌──[root@vms81.liruilongs.github.io]-[/sys/fs/cgroup] └─$mount -t cgroup cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd) cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset) cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct,cpu) cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices) cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event) cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids) cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb) cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer) cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory) cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_prio,net_cls) cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio) ┌──[root@vms81.liruilongs.github.io]-[/sys/fs/cgroup] └─$容器鏡像
對軟件開發而言,容器鏡像打通了“開發 - 測試 - 部署”的流程。
鏡像是容器的模板,容器是鏡像的運行實例,runtime根據鏡像創建容器
容器鏡像掛載在容器根目錄下,為容器中的應用提供執行環境的文件系:容器鏡像打包了整個操作系統的文件和目錄(rootfs),也包括應用本身,即應用及其運行所需的所有依賴都被封裝在容器鏡像中。
容器鏡像采用分層結構:所有容器共享宿主機Kernel,并且不能修改宿主機Kernel ·即容器運行過程中使用容器鏡像中的文件,使用宿主機OS上的Kermel
- Build any Application:根據image format spec標準,任何應用都可以被制作成容器鏡像,
- Ship any Anywhere:根據runtime spec標準,容器鏡像可以傳送到任何環境中運行。
容器鏡像只是提供了一套鏡像文件系統中的各種文件,而各種內核相關的模塊或者特性支持,完全依賴于宿主機。
UnionFS聯合文件系統
Docker鏡像分層結構的實現,借助于UnionFS聯合文件系統的能力.
Union File System聯合文件系統,是實現Docker鏡像的技術基礎。它是一種輕量級的高性能分層文件系統,支持將文件系統中的修改進行提交和層層疊加。這個特性使得鏡像可通過分層實現和繼承。同時支持將不同目錄掛載到同一個虛擬文件系統下。
以Overlay2為例: Overlay2是一種堆疊文件系統,它依賴并建立在其它的文件系統之上(如ext4fs、xfs等),并不直接參與磁盤空間結構的劃分,僅將原來底層文件系統中不同的目錄進行“合并”,然后向用戶呈現,這也就是聯合掛載技術。
嗯,這里不太理解,感覺整理類似是linux中的LVM,局部類似寫時復制技術,基礎的鏡像文件不會被修改,只是對修改進行記錄,在寫入的時候,對鏡像文件寫入部分進行復制,然后修改后記錄。看到的是基礎鏡像文件 + 寫時復制的記錄的疊加。
容器數據卷
卷就是目錄或文件,存在于一個或多個容器中,由docker掛載到容器,但不屬于聯合文件系統,因此能夠繞過Union File System提供一些用于持續存儲或共享數據的特性。
將運用與運行的環境打包形成容器運行,對數據的要求希望是持久化的。
容器之間希望有可能共享數據。
卷的設計目的就是數據的持久化,完全獨立于容器的生存周期,因此Docker不會在容器刪除時刪除其掛載的數據卷。
- 啟動容器的時候直接使用-v命令就可以進行數據卷的掛載。
- 還可以在Dockerfile中使用VOLUME指令來給鏡像添加一個或多個數據卷,
容器copy-on-write特性
對容器的增刪改查:
- 創建文件:新文件只能被添加在容器層中。
- 刪除文件:依據容器分層結構由上往下依次查找。找到后,在容器層中記錄該刪除操作。具體刪除文件實現是:UnionFS會在容器層創建一個"whiteout"文件,將被刪除的文件“遮擋”起來。
- 修改文件:依據容器分層結構由上往下依次查找。找到后,將鏡像層中的數據復制到容器層進行修改,修改后的數據保存在容器層中(copy-on-write)。
- 讀取文件:依據容器分層結構由上往下依次查找,
所有storage driver都支持鏡像分層結構和寫時復制(CoW)策略。
Registry
Registry是存放容器鏡像的倉庫,用戶可進行鏡像下載和訪問,分為公有和私有兩類Registry。
公有鏡像倉庫:
- Docker Hub是Docker公司為公眾提供的托管Registry。
- Quay.io現為Red Hat下的公共托管Registryo
私有鏡像倉庫:
- 企業可以用Docker Registry構建私有的Registry。Registry本身是一個開源項目,可以用于搭建私有Registry
Docker Hub中可查看到Registry鏡像的Dockerfile。
Docker Hub
Docker Hub是目前世界上最大的容器鏡像倉庫,由Docker公司維護,并提供官方鏡像及大量用戶上傳的鏡像。
如何使用Dockerfile構建鏡像
Dockerfile是一個文本文件,其內包含了一條條的指令,每一條指令構建一層,因此每一條指令的內容,就是描述該層應當如何構建。所以為了減少存儲占用,一般盡可能把run指令寫到一行。
Docker提供了兩種構建鏡像的方法:docker commit命令與dockerfile構建文件。
Dockerfile
Dockerfile :文件指令集,描述如何自動創建Docker鏡像。
- Dockerfile是包含若干指令的文本文件,可以通過這些指令創建出docker image。
- Dockerfile文件中的指令執行后,會創建一個個新的鏡像層。
- Dockerfile文件中的注釋以"#"開始。
- Dockerfile一般由4部分組成:
- 基礎鏡像信息.
- 維護者信息
- 鏡像操作指令
- 容器啟動指令
- build context :為鏡像構建提供所需的文件或目錄。
| 指定base鏡像 | FROM |
| 注明鏡像的作者 | MAINTAINED |
| 運行指定的命令 | RUN |
| 將文件從build context復制到鏡像中 | ADD |
| 將文件從build context復制到鏡像中(自動解壓) | COPY |
| 設置環境變量 | ENV |
| 指定容器中的應用監聽的端口 | EXPOSE |
| 設置后動容器的用戶 | USER |
| 設置在容器啟動時運行指定的腳本或命令 | CMD |
| 指定的是一個可執行的腳本或者程序的路徑 | ENTRYPONT |
| 將文件或目錄聲明為volume,掛載到容器中 | VOLUME |
| 設置鏡像的當前工作目錄 | WORKDIR |
Dockerfile的指令根據作用可以分為兩種:
- 構建指令:構建指令用于構建image,其指定的操作不會在運行image的容器上
執行。 - 設置指令:設置指令用于設置image的屬性,其指定的操作將在運行image的容器中執行。
Dockerfile指令使用注意事項:
- RUN等指令后運行的必須是基礎image支持的命令。如基礎image選擇了centos,那么軟件管理部分只能使用centos的命令。
- ADD指令與COPY指令的不同在于,在ADD指令中,若src是壓縮文件,則會自動解壓到dest。
- Dockerfile中若有多條CMD命令,則只執行最后一條。
- Dockerfile中若有多條ENTRYPOINT命令,則只執行最后一條。
- CMD與ENTRYPOINT的不同在于:當Docker run command的命令匹配到CMD command時,會替換CMD執行的命令。ENTRYPOINT指令提供的命令則不容易在啟動容器時被覆蓋。實際上, docker run命令行中指定的任何參數都會被當做參數再次傳遞給ENTRYPOINT指令中指定的命令。
使用ENTYRPOINT
#ENTRYPOINT [ "/usr/sbin/nginx", "-g" , "daemon off;" ] ENTRYPOINT [ "usr/sbin/nginx" ] sudo docker run -it nginx -g "daemon off;"同時使用ENTRYPOINT和CMD
ENTRYPOINT [ "/usr/sbin/nginx" ] CMD [ "-h" ] # /usr/sbin/nginx -h 顯示幫助信息如果確實需要,用戶也可以在運行時通過docker run的--entrypoint標志覆蓋ENTRYPOINT指令
一個簡單的Dockerfile
#基于centos鏡像 FROM centos #維護人的信息 MAINTAINER docker_user docker_user@email.com #安裝httpd軟件包 RUN yum-y update && RUN yum-y install httpd #開后80端口 EXPOSE 80 #復制網站首頁文件至鏡像中web站點下 ADD index.html /var/www/html/index.html #復制該腳本至鏡像中·并修改其權限 ADD run.sh /run.sh RUN chmod 775 /run.sh #當后動容器時執行的腳本文件 CMD[/run.sh"]容器生命周期管理
查看Docker服務狀態
┌──[root@vms81.liruilongs.github.io]-[/] └─$systemctl status docker ● docker.service - Docker Application Container EngineLoaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)Active: active (running) since 日 2022-04-03 18:43:45 CST; 18h agoDocs: https://docs.docker.comMain PID: 1120 (dockerd)Memory: 157.7MCGroup: /system.slice/docker.service└─1120 /usr/bin/dockerd --insecure-registry 192.168.26.56 -H fd:// --containerd=/run/containerd/containerd...4月 03 18:44:51 vms81.liruilongs.github.io dockerd[1120]: time="2022-04-03T18:44:51.153876648+08:00" level=info ...ete" 4月 04 08:07:05 vms81.liruilongs.github.io dockerd[1120]: time="2022-04-04T08:07:05.336006734+08:00" level=error...ifo" 4月 04 08:07:05 vms81.liruilongs.github.io dockerd[1120]: time="2022-04-04T08:07:05.396998780+08:00" level=error...ifo" 4月 04 08:07:05 vms81.liruilongs.github.io dockerd[1120]: time="2022-04-04T08:07:05.406139699+08:00" level=error...own" 4月 04 08:07:06 vms81.liruilongs.github.io dockerd[1120]: time="2022-04-04T08:07:06.332774038+08:00" level=info ...ete" 4月 04 08:07:06 vms81.liruilongs.github.io dockerd[1120]: time="2022-04-04T08:07:06.336614138+08:00" level=error...ifo" 4月 04 08:07:06 vms81.liruilongs.github.io dockerd[1120]: time="2022-04-04T08:07:06.353399388+08:00" level=error...ifo" 4月 04 08:07:06 vms81.liruilongs.github.io dockerd[1120]: time="2022-04-04T08:07:06.384605677+08:00" level=info ...rce" 4月 04 08:07:06 vms81.liruilongs.github.io dockerd[1120]: time="2022-04-04T08:07:06.600509732+08:00" level=error...own" 4月 04 08:07:07 vms81.liruilongs.github.io dockerd[1120]: time="2022-04-04T08:07:07.067233807+08:00" level=info ...ete" Hint: Some lines were ellipsized, use -l to show in full. ┌──[root@vms81.liruilongs.github.io]-[/] └─$容器生命周期管理
容器生命周期管理命令:
- docker create:創建一個容器;
- docker start:啟動一個容器;
- docker run:創建并運行一個容器;
- docker pause:暫停一個容器;
- docker unpause:恢復一個容器;
- docker restart:重啟一個容器;
- docker stop:停止一個運行的容器;
- docker rm:刪除一個處于終止狀態的容器;
- docker kill:殺死容器進程
進入一個容器
docker attach命令:
- docker attach命令直接進入已啟動容器的命令終端,不會啟動新的進程。
- Usage:docker attach [OPTIONS] CONTAINER
docker exec命令:
- docker exec命令是在容器中打開新的終端。
- Usage:docker exec [OPTIONS] CONTAINER COMMAND [ARG…]
其他常見命令
- 使用docker inspect獲取容器/鏡像元數據。
- 使用docker tovp命令查看容器中運行的進程信息。
- 使用docker events從服務器獲取實時事件。
- 使用docker port列出指定的容器的端口映射。
總結
以上是生活随笔為你收集整理的《云原生入门级开发者认证》学习笔记之云原生基础设施之容器技术的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 图片素材17
- 下一篇: Web端 Html5 直接播放 .ts