docker常用命令
上圖是Docker的架構
整個Docker由客戶端、服務端和倉庫構成
常用命令
docker images docker search imagename docker pull imagename:tag docker rmi id/name docker ps docker run -it -p port1:port2 image docker exec -it containername docker stop containername docker start containername docker cp file containername:dir docker cp containername:dir file docker inspect containername docker rm containername docker volume ls docker save -o image docker load xx.tar.gz
docker與虛擬機
docker出現的原因主要是解決傳統的開發和運維方面的問題
case one:開發環境和生產環境可能不一致的問題,就比如一個項目剛開發的時候使用的MySQL是5.5版本,之后經過幾輪開發,MySQL版本升級到了5.7,這個時候測試的版本還是5.5,在沒有虛擬化技術之前,測試只有兩個辦法 1.刪了重裝 2.多裝一個 就很麻煩。但虛擬化技術出現之后,直接遠程docker pull,幾分鐘之內就能構建出一個MySQL5.7的環境
case two:在不同的開發環境中構建和運行應用程序可能會遇到很多問題。Docker可以將應用程序和依賴項打包到一個可移植的容器中,從而使得開發環境的設置變得更加簡單和重復
case three:從安全性和速度上來說也比傳統運維更加簡單,可以很輕松的起成百上千個容器,并且這些容器在操作系統級別和硬件級別都存在隔離
一句話概括:通過Docker我們可以將**程序運行的環境也納入到控制中 **
docker和虛擬機有何區別
docker絕對不是輕量級的虛擬機 絕對不是
docker是一個client-server結構的應用,守護進程運行在主機上,然后通過socket連接從客戶端訪問docker守護進程
一個docker容器,是一個運行時的環境,可以簡單理解成進程運行的集裝箱
docker和kvm(linux的內核虛擬機)都是虛擬化技術,主要差別在于:
docker比虛擬機更少的抽象層,docker更加輕便和低成本
docker利用宿主機內核 kvm需要guest os(直接在Host OS上多建一個OS),docker以MB硬盤為單位,kvm以GB為單位
在啟動速度上 docker是秒級別的,而KVM是分鐘級別的,和KVM相比,docker應用的性能高,同時系統的開銷小
KVM在宿主機器的基礎上創建虛擬層、來賓操作系統、虛擬化倉庫,然后安裝應用
容器在宿主機操作系統上創建docker引擎,在引擎的基礎上安裝應用
所以虛擬機是分鐘級別 容器是秒級別
最核心的一點是:Docker和傳統的VM虛擬機作比較的話,并不需要硬件的支持,只是進行了內核級別的虛擬化,像VM虛擬機是和真正的物理機器一樣,對各種硬件都進行了虛擬化
docker技術底座
Linux命名空間 namespace 、控制組cgroup和unionFS union file system三大技術支撐了目前Docker的實現 也是Docker能夠出現的最重要原因
namespace
在linux中,namespace是在內核級別實現資源隔離的手段,不同的namespace程序可以享有一份獨立的系統資源
namespace是linux為我們提供的用于分離進程樹、網絡接口、掛載點、進程通信等資源的方法,在日常使用linux的時候,如果我們在服務器上啟動了多個服務,這些服務其實是會相互影響的,因為他們能互相可見,也可以訪問宿主機上的任意文件,但我們更希望一臺機器上的不同服務能做到完全隔離,就像運行在不同的機器上一樣。Docker通過使用namespace來實現容器的隔離,每個容器都有自己的namespace,可以訪問其內部資源而不會影響宿主機或者其他容器,這使得Docker可以輕松地創建、啟動和停止容器
在這種環境下,一旦服務器的某一個服務被入侵,那么入侵者就能夠訪問當前機器上的所有服務和文件
通過這七個選項 我們能設置新的進程在哪些資源上和宿主機進行隔離
fork:當調用fork函數時,系統會創建新的進程為其分配資源,例如存儲數據和代碼的空間,然后把原來的進程值都賦值到新的進程中,只有少量值與原來不同,相當于克隆自己fork的返回值在父進程中:fork返回子進程的ID在子進程中:fork返回0
如果錯誤:fork返回一個負值
Linux的命名空間機制提供了以下其中不同的命名空間,包括
CLONE_NEW CGROUP
CLONE_NEW IPC 提供一個獨立的進程間通信的機制,信號量、共享內存、消息隊列等只在容器內部課見
CLONE_NEW NET 為容器提供一個獨立的網絡環境,使得容器內部的網絡接口、IP地址、路由表和防火墻規則都只能在容器內部可見
CLONE_NEW NS
CLONE_NEW PID 容器的獨立進程ID空間,容器內部的進程只能看到自己的進程ID,而不會影響宿主機或者其他容器的進程
CLONE_NEW USER 容器內的獨立用戶和用戶組
CLONE_NEW UTS 容器內的獨立主機名和域名
通過這些選項,我們可以在創建新的進程時設置哪些資源與宿主機器進行隔離
Linux最特殊的兩個進程:pid為1的/sbin/init的進程,和pid為2的kthreadd進程,這兩個進程都是被Linux的上帝進程idle創建出來的,前者負責執行內核的一部分初始化工作和系統配置,后者負責管理和調度其他的內核進程
當我們運行docker run或者docker start的時候,就會啟動setNamespaces方法,設置進程、用戶、網絡和IPC相關的命名空間,然后作為Create的參數在創建新容器的時候完成設置
如果docker的容器通過Linux的命名空間完成了和宿主機進程的網絡隔離,但是又沒有辦法通過宿主機的網絡與整個互聯網相連,就會產生很多限制,所以Docker中的服務還是需要與外界連接才能發揮作用,每一個用docker run啟動的容器都具有單獨的網絡命名空間,Docker為我們提供了四種不同的網絡模式
Host
Container
None
Bridge
Docker默認的網絡設置模式:網橋模式,在這種模式下除了分配隔離的網絡命名空間之外,Docker還會為所有的容器設置IP地址,當Docker服務器啟動時,會創建新的虛擬網橋docker0,docker0會為每一個容器分配一個新的IP地址,并將docker0的IP地址設置為默認的網關,網橋docker0通過iptables中的配置與宿主機器上的網卡相連。每當有一個新的服務需要暴露給宿主機,就會給容器分配一個IP地址,同時向iptables追加一條新的規則。
Docker通過Linux的命名空間實現了網絡的隔離,又通過iptables進行數據包轉發,讓Docker容器能夠優雅的為宿主機或者其他容器提供服務
Cgroup
CGROUP解決的就是限制容器物理資源占用的問題
掛載點:Docker容器中的進程仍然能夠訪問或者修改宿主機上的其他目錄,這是我們不希望看到的。
如果一個容器需要啟動,那么它一定需要提供一個跟文件系統(rootfs),容器需要通過這個文件系統來創建一個新的進程,所有二進制的執行都必須要在這個跟文件的系統中。從而實現將容器需要的目錄掛在到容器中,同時也禁止當前的容器進程訪問宿主機器上的其他目錄,保證了不同文件系統的隔離
我們通過NAMESPACE隔離了文件、網絡和進程,但是不能提供物理資源上的隔離,比如CPU或者內存,如果一個容器正在執行CPU密集型的任務,那么就會影響其他容器的性能和效率,而CGROUPS就是能夠隔離宿主機器上的物理資源,例如CPU 內存 磁盤IO等等
每一個CGROUP都是一組被相同標準和參數限制的進程,CGROUP之間有層級關系,可以從父類進程一些標準和參數
而Cgroup的核心是一個叫做cgroupfs的文件系統,位于linux內核中的/sys/fs/cgroup目錄下。該文件系統允許用戶在一個層次結構中創建、管理和監控cgroup,具體實現如下
創建cgroup層次結構,這個層次結構由一個或者多個cgroup組成,每個cgroup都代表一組進程,并擁有一組資源限制。
將進程添加到cgroup中,這個實現其實就是把進程加到task文件中
為cgroup分配限制資源,例如可以用cgroup/cpu/相關的文件來限制cpu的使用率
監控cgroup的資源使用
Union File System
Union File System是一種文件系統技術,可以將多個文件系統(通常是只讀文件系統和可寫文件系統)合并成一個虛擬文件系統,使其像一個文件系統,但實際上是由多個文件系統組成的。
在Docker中,UFS解決了鏡像只讀不可寫的問題,同時也是Docker的基礎文件系統
UFS的實現基于三種文件系統:
只讀文件系統
是UFS的基礎,通常包含操作系統的核心組件和基本文件系統。在Docker中,只讀文件系統通常是一個Docker鏡像提供的
可寫文件系統
可寫文件系統是一個額外的文件系統層,它覆蓋在只讀文件系統之上,用于保存容器中創建、修改和刪除的文件。每個容器都有自己的可寫文件系統層,使得容器之間的文件不會相互干擾,在Docker中,可寫層是在容器運行時創建的
合并文件系統
將只讀文件系統和可寫文件系統合并而成的,使得容器可以訪問只讀文件系統和可寫文件系統層中的文件,就像它們是一個單獨的文件系統一樣。
在DOCKER中還有另一個非常重要的問題-鏡像
Docker鏡像的本質其實就是一個壓縮包 也就是一個文件
Docker鏡像是如何構建:Docker中的每一個鏡像都是由一系列只讀的層組成的,DockerFile中的每一個命令都會在已有的只讀層上創建一個新的層,類似于搭積木,鏡像的每一層其實都只是對當前鏡像進行了部分改動,當鏡像被docker run命令創建時,就會在鏡像的最上層添加一個可寫的層,也就是容器層。
容器和鏡像的區別就是 鏡像只是可讀的,而每一個容器其實等于鏡像加上一個可讀寫的層,也就是同一個鏡像可以對應多個容器。
審核編輯:劉清
-
虛擬機
+關注
關注
1文章
918瀏覽量
28263 -
LINUX內核
+關注
關注
1文章
316瀏覽量
21672 -
KVM
+關注
關注
0文章
188瀏覽量
12959 -
UFS
+關注
關注
6文章
104瀏覽量
24077 -
Docker
+關注
關注
0文章
477瀏覽量
11871
原文標題:Docker底層實現 講解
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論