這周分享的內容是關于 Docker 的基礎,大概的內容分為下面的兩個部分,另外還做了個視頻,其實這個視頻僅僅用來娛樂娛樂而已。
前言
第一趴---Docker容器圈簡介
Docker容器圈簡介
第二趴---Docker基本操作
Docker基本操作
容器圈
容器這個新生事物,現在還可以說是新生事物嗎?對于我們學生而言,我覺得沒毛病,你說呢?
容器技術可說重塑了整個云計算市場的形態,帶動了一批年輕有為的容器技術兒,不過「容器」這個概念是Docker公司發明的么,不是,它只是眾多Paas項目中的最底層,沒人關注的那一部分而已。
什么是Pass項目?
Paas項目之所會被很多公司所接受,自然是因為解放了部分開發人員的勞動力,盡快干玩活兒早點下班。其依賴的就是「應用托管」的能力,在電腦上斗過地主的應該知道,托管了以后就會自動出牌,同樣的道理,為了盡量的彌補本地和云上的環境差異,就出現了Paas開源項目。
舉個例子來說,運維人員小仙云上部署一個Cloud Foundry項目,開發人員只需要簡單的一行代碼就可以實現將本地的應用部署到云上
就這樣一行代碼就實現了將本地應用上傳到云上,屬實很輕松。
那么這個命令執行的基本原理是怎樣的?
實際上,我們可以將其最核心的組件理解為一套應用的打包和分發機制。云上部署的Cloud Foundry會為大部分編程語言定義一種打包的格式,當開發人員執行命令的時候,實際上是將可執行文件和啟動腳本打包上傳到云上的Coulud Foudry中,然后Cloud Foundry通過相應的調度器選擇一個虛擬機的Agent將壓縮包下載后啟動
那如何區分虛擬機中的不同應用呢?
虛擬機一般不可能只跑一個應用,因為這樣確實也太浪費資源了,我們可以想想,現在手上的電腦,可以用Vmvare導入幾個虛擬機,所以諸如Cloud Foundry通過引入操作系統的Cgroups和Namespace等機制,從而來為每個應用單獨創建一個叫做「沙盒」的隔離環境,然后在這些「沙盒」中啟動應用,通過這樣的方法就讓虛擬機中應用各自互不干擾,讓其自由翱翔,至于Cgroups和 Namespace 的實現原理,后續我們再共同的探討
這里所謂的隔離環境就是「容器」。
那 Docker 和這 Pass 項目的 Cloud Foundry 的容器有啥不一樣?
自然不一樣,不然現在我們一旦提到容器,想到的不會是Docker,而是Cloud Foundry了吧。Cloud Foundry的首席產品經理就覺得沒什么,畢竟自己放的屁都是香的!
不一樣,而且當時還發了一份報告,報告中還寫到:“Docker不就是使用了 Cgroups和 Namespace實現的「沙盒」而已,不用過于關注”。
沒想到的是,隨后短短的幾個月,Docker項目迅速起飛以至于其他所有 Paas社區都還沒來及反應過來,就已經宣告出局
什么魔力讓 Docker 一發不可收拾?
就是提出了鏡像的概念。上面我們說過,Paas提供的一套應用打包的功能,看起很輕松省事,但是一旦使用了Paas,你就要終身服務于它,畢竟他是提供商,是「爸爸」,用戶需要為每個版本,每種語言去維護一個包,這個打包的過程是需要多次的嘗試,多次試錯后,才能摸清本地應用和遠端Paas的脾氣,從而順利部署。
而Docker 鏡像恰恰就是解決了打包這一根本問題。
什么是Docker鏡像?
Docker鏡像也是一個壓縮包,只是這個壓縮包不只是可執行文件,環境部署腳本,它還包含了完整的操作系統。因為大部分的鏡像都是基于某個操作系統來構建,所以很輕松的就可以構建本地和遠端一樣的環境。
這就很牛皮了,如果我們的應用是在Centos7上部署,我們只需要將項目環境部署在基于Centos7的環境中,然后無論在哪里去解壓這個壓縮包,都可以保證環境的一致性。在整個過程中,我們根本不需要進行任何的配置,因為這個壓縮包可以保證:本地的環境和云端是一致的,這也是Docker鏡像的精髓
開發者體驗到了Docker的便利,從而很快宣布Paas時代的結束,不過對于大規模應用的部署,Docker能否實現在當時還是個問號
就在 2014 年的DockerCon上,緊接著發布了自研的「Docker swarm」,Docker就這樣 一度奔向高潮,即將就到達了自己夢想之巔。
為什么會推出Docker Swarm?
雖然Docker通過「容器」完成了對Paas的「降維打擊」,但是Docker的目的是:如何讓更多的開發者將項目部署在自己的項目上,從技術,商業,市場多方位的爭取開發者的群體,為此形成自家的 Paas平臺做鋪墊
Docker項目雖然很受歡迎,就目前看來只是一個創建和啟動容器的小工具。需要應該清楚的一點是,用戶最終部署的還是他們的網站,服務甚至云計算業務。所以推出一個完整的整體對外提供集群管理功能的Swarm勢在必行,這個項目中的最大亮點即直接使用了Docker原生的API來完成對集群的管理。
對于單機項目,只需要執行下面一條語句即可實現容器
對于多機的項目,只需要執行
你看,從單機切換到多機,使用的方法也就參數不同而已,所以這樣一個原生的「Docker容器集群管理」一發布就受到大家的青睞。隨著自身生態的逐漸完善,借助這一波浪潮并通過各種并購來強大自己的平層能力
要說最成功的案例,非Fig項目莫屬。之所以這么屌,是因為作者提出了「容器編排」的概念。
什么是容器編排?
其實這也不是什么新鮮內容,比如在Linux中的Makefile和常見的SHELL腳本,它是一種通過工具或者配置來完成一組虛擬機或者關聯資源的定義、配置、創建等工具。
容器的編排是怎么樣的呢
我們先以 Fig 為例,假設開發人員小黑,現在要部署一個項目,其中包含了應用容器A,數據庫容器B,負載容器C,這個時候Fig只需要將三個容器定義在一個配置文件,然后指定他們的關聯關系,執行下面的命令即可
當然也可以在Fig的配置文件中配置各種容器的副本,然后加上Swarm的集群管理功能,這樣不就是Paas了么。只是這個項目被收購以后,修改名字為compose了,后續也會的compose進行詳細的闡述
就這樣一個以「鯨魚」為商標的Docker,火遍全球,因為它秉持將「開發者」群體放在食物鏈的頂端。一分鐘實現網站的部署,三分鐘搭建集群,這么多年以來,很多后端開發者很少將眼光放在Linux技術上,開發者們為了深入的了解Docker的技術原理,終于將眼光放入諸如Cgroups和Namespace技術中。
就在這一時之間,后端及云計算領域的大佬都匯聚于這個「小鯨魚」的身邊。隨后到了考慮集群的方案,論集群的管理調度能力,還不得不提Berkeley的Mesos,專注于大數據領域,更加關注的是計算密集型的業務。憑借著它天生的兩層調度機制,讓它很快發布了一個叫做Marathon的項目,這個項目隨即成為了Swarm的有力競爭對手。
這還沒完,說了這么久,還沒有提到在基礎設施領域翹楚的Google公司,是的,同在這一年,宣告了一個叫做Kubernetes項目的誕生。
隨著 Docker生態的建立,Docker swarm,Docker compose,Machine形成了三件套,此時大量圍繞Docker項目的網絡,存儲,監控都涌現。在令人興奮的背后,是對它更多的擔憂,這主要來源于對Docker商業化戰略的顧慮,Docker公司對于Docker著絕對的權威并在多個場合直接和谷歌,微軟對干
其實在Docker興起的時候,谷歌也開源了一個Linux容器:Imctfy,在當時這個項目在Docker面前真是弟弟,所以向Docker公司表示想合作的意愿,Docker顯然不同意,且在之后的不久自己發布了一個容器運行時的庫Libcontainer,可能由于太急躁,其代碼可讀性極差,不穩定和頻繁的變更,讓社區叫苦不迭
為了切割Docker項目的話語權,決定成立一個中立的基金會。所以于 2015 年將這個Libcontainer捐出,并修改名稱為Runc,然后依據RunC項目,制定了一套容器和鏡像的標準和規范----OCI
什么是OCI
為了讓Docker不能太囂張,其他玩家構建自身平臺的時候不依賴于Docker項目,提出一個標準和規范----OCI。這一標準并沒有改變 Docker 在容器領域一家獨大的現狀。Google 坐不住了,必須得搞點大招
**Google **給RedHat等伙伴打了電話,說咱們共同牽頭發起一個基金會-----CNCF。目的很簡單,以kubernetes為基礎,建立一個以由開源基礎設置主導,按照獨立基金會方式運營的平臺級社區,來對抗Docker公司為核心的容器商業生態
為了做好這個事兒,CNCF 必須完成兩件事兒
必須在編排領取足夠的優勢
CNCF 必須以 kubernetes 為核心,覆蓋更多的場景
CNCF 如何解決第一個問題----編排能力
Swarm的無縫集成以及Mesos的大規模集群的調度管理能力,很明顯,如果繼續往這兩個方向發展,后面的路不一定好走。所以,kubernetes選擇的方式是Borg,其基礎特性是 Google 在容器化基礎設施多年來實踐的經驗,這也正是項目從一開始就避免了和Swarm,mesos 社區同質化的重要手段
看似很有技巧,怎么落地?
RedHat正好擅長這玩意呀,它能真正的理解開源社區運作和項目研發真諦的合作伙伴。作為Docker一方,主要不管的強調「Docker native」,但是由于kubernetes沒有跟Swarm展開同質化的競爭,所以這個「Docker Native」的說法并沒有什么殺傷力。反而其獨特的設計理念和號召力,讓其構建了一個完全與眾不同的容器編排管理生態。
就這樣很快就把Swarm甩在了身后。隨機開始探討第二個問題,CNCF 添加了一系列容器工具和項目,面對這樣的壓迫,Docker在2016年決定放棄現有的Swarm項目,而是將容器編排等全部內置到Docker項目中。
而kubunetes的應對方案也蠻有意思,開啟「民主化架構」,kubernetes為開發者暴露可以擴展的插件機制,讓用戶可以隨意的通過植入代碼的方式介入到kubernetes的每一個階段,很快,整個容器圈出現了優秀的作品:火熱的微服務治理項目lstio等
面對kubernetes的 強力攻擊,Docker公司不得不面對失敗的事實,只好放棄開源社區專注于商業化轉型,所以于2017年將容器運行時部分containerd捐贈給了CNCF,從而將Docker項目改名為Moby,然后交給社區維護,于 2017 年,**Docker **公司宣布將在企業版內置kubernetes項目,這也標志了kubernetes「編排之爭」的結束
Docker能做什么
Docker是一個用于開發,發布,運行應用的程序于一體的開放平臺。如果我們需要將貨物整齊的擺放在船上且互不影響,那么一種可行的方案即通過集裝箱進行標準化,我們將各種貨品通過集裝箱打包,然后統一的放在船上進行運輸,Docker其實就是這樣一個將各種軟件進行打包成集裝箱,然后分發。
Docker的安裝
Docker是一個跨平臺的解決方案,支持各大平臺比如Centos,Ubuntu等Linux發行版。下面講述的是在Centos中的使用,安裝
卸載當前已經存在的舊版Docker,執行下面的命令
添加Docker安裝源
安裝最新版本
如果需要安裝指定版本,可以通過下面命令查看版本并選擇需要的版本
安裝完成,啟動Docker
按照國際案例,先跑一個 helloworld
運行上述命令,Docker首先會檢查本地是否有hello-world這個鏡像,如果發現本地沒有這個鏡像,Docker就會去Docker Hub官方倉庫下載此鏡像,然后運行它。最后我們看到該鏡像輸出 "Hello from Docker!" 并退出。
Docker核心概念
Docker的操作主要圍繞鏡像,容器,倉庫三大核心概念
什么是鏡像?
一句話說即鏡像是Docker容器啟動的先決條件,因為鏡像會提供容器運行的一些基礎文件和配置文件,是容器啟動的基礎。說白了,要啟動容器,需要鏡像來提供一些基礎環境。
使用的鏡像的方式有哪些?
自定義創建鏡像。首先找一個基礎鏡像,比如此鏡像是Centos,然后在此鏡像基礎上自定義需要的內容。舉個例子,基礎鏡像為Centos,先安裝Nginx服務,然后部署咱們的應用程序,最后做一些自定義的配置,這樣一個鏡像就完成了,此鏡像的操作系統是Centos,其中包含了Nginx服務
從倉庫尋找別人已經做好的鏡像。直接去 **Docker hub **或者其他公開倉庫 下載即可
什么是容器?
容器是鏡像的運行實體。鏡像是靜態的只讀文件,可是容器是要運行的,需要可寫文件層。所以容器運行著真正的應用進程,所以自然會有創建,運行,停止,暫停和刪除五種狀態
既然容器是直接運行的運行程序,那它是有自己的命名空間嘛?
容器有自己獨立的命名空間和資源限制,意味著在容器內部,你無法看到主機上面的進程,環境變量等信息,這就是容器和物理機上的進程本質區別
什么是倉庫?
鏡像倉庫類似于代碼倉庫,用來分發和存儲鏡像,分為公共鏡像和私有鏡像。Docker hub是Docker的官方公開鏡像倉庫,很多的官方鏡像都可以在上面找到,但是訪問很慢,所以可以找國內的鏡像源,當然后面我們也會自己搭建一個私有鏡像倉庫
三者的關系是怎么樣的?
上圖清晰的展現了鏡像是容器的基石,容器是在鏡像的基礎上創建的。一個鏡像可以創建多個容器,倉庫用來存放和分發鏡像
Docker架構
容器技術的發展可說突飛猛進了,市面上除了Docker容器還有coreos的 rkt,lxc 等,這么多種容器,是不是需要一個標準呢,不然就太容易亂套了
你可能會說直接把Docker作為標準不就好了,但是有這么多相關的容器技術,誰不想吃個好瓜,除此之外,當時的編排的技術也競爭火爆,當時的三主力分別是Docker Swarm,kubernetes以及mesos。作為原生的Docker Swarm自然優勢明顯,但是kubernetes不同意啊,它們覺得調度形式太單一了
因此爆發了容器大戰,OCI也就在此出現。
OCI是開放的容器標準,輕量級開放的治理結構,目前主要有兩個標準,分別是容器運行時標準和容器鏡像標準
在如此競爭激烈下面,Docker的架構成為了下面這個樣子
Docker的整體架構為CS架構,客戶端和服務端兩部分組成,客戶端發送命令,服務端接受處理指令,其通信的方式有多種,即可以通過Unix套接字通信,也可以網絡鏈接遠程通信
Docker客戶端
我們平時通常使用Docker命令行的方式和服務端打交道,其實還可以通過 **REST API **的方式和Docker服務端交互,甚至使用各種預言的sdk和Docker的服務端交互,美滋滋
Docker服務端
Docker服務端是 Docker 后臺服務的總稱。其中Dockerd是一個非常重要的后臺進程,它負責響應并處理Docker客戶端的請求,然后轉化為Docker的具體操作
Docker 重要的組件
我們去 Docker 默認安裝路徑先看看有哪些組件
這里主要說明下runc和contained組件
runc:是一個用來運行容器的輕量級工具
contained:是容器標準化后的產物,從Dockerd剝離出來,contained通過contained-shim啟動并管理runc,可以說contained是真正管理容器的生命周期
通過上圖,可以看到,dockerd通過gRPC與containerd通信,由于dockerd與真正的容器運行時,runC中間有了containerd這一 OCI標準層,使得dockerd可以確保接口向下兼容。
gRPC是一種遠程服務調用。containerd-shim的意思是墊片,類似于擰螺絲時夾在螺絲和螺母之間的墊片。containerd-shim的主要作用是將containerd和真正的容器進程解耦,使用containerd-shim作為容器進程的父進程,從而實現重啟dockerd不影響已經啟動的容器進程。
docker 各個組件之間的關系
啟動一個容器
啟動完成,通過下面命令查看 docker 的 pid
此時發現其 pid 為 4428,隨后我們查看進程之間的關系
通過 pstree 查看進程之間的關系
注意,docker19 就看不到兩者是父子關系了
可以先使用 ps aux | grep contained ,然后使用pstree查看 contained 的 pid ,實際上,Docker 啟動的時候,contained 就啟動了,dockerd 和 contained 一直就存在。當執行了docker run以后,contained 就會創建 contained-shim 充當墊片進程,然后啟動容器的真正進程 sleep 3600,這和架構圖一致
075528566666
Docker相關組件
docker
對于我們最直觀的即Docker命令,作為Docker客戶端的完整實現,通過Docker命令來實現所有的Docker客戶與服務端的通信
Docker 客戶端于服務端的交互過程是怎么樣的呢
Docker組件向服務端發送請求后,服務端根據請求執行具體的動作并將結果返回給Docker,Docker解析服務端的返回結果,并將結果通過命令行標準輸出展示給用戶。這樣一次完整的客戶端服務端請求就完成了
dockerd
dockerd 為Docker服務端后臺的常駐進程,負責接收客戶端的請求,處理具體的任務并將結果返回客戶端
那么 Docke r客戶端采用哪幾種方式發送請求
第一種方式:通過unix套接字與服務端通信,配置的格式為:unix://socket_path。默認的dockerd生成的 socket文件存放在 /var/run/docker.sock,此文件只能是root用戶才能訪問,這也是為什么剛安裝完Docker后只能root 來進行訪問操作
第二種方式:采用TCP的方式與服務端通信,配置格式為:tcp://host:por,為了保證安全,通常還需要使用TLS認證
第三種方式:通過fd文件描述符的方式,配置格式為:fd://這種格式一般用于systemd管理的系統中。
docker-init
在Linux中,有一個叫做init的進程,是所有進程的父進程,用來回收那些沒有回收的進程,同樣的道理,在容器內部,可以通過加上參數 --init 的方式,讓 1 號進程管理所有的子進程,例如回收僵尸進程
舉個例子示范,以鏡像 busybox 為例
此時的 1 號進程為為 sh 進程,如果加上 --init
你會發現,此時的 1 號進程為docker-init,而不是sh了
docker-proxy
docker-proxy 用來將容器啟動的端口映射到主機,方便主機的訪問。
假設目前啟動一個nginx容器并將容器的80端口映射到主機的8080端口
查看容器 IP
此時使用 ps 查看主機是否有 docker-proxy 進程
可以發現當進行端口映射的時候,docker為我們創建了一個docker-proxy進程,并且通過參數將容器的IP和端口傳遞給docker-proxy,然后proxy通過iptables完成nat的轉發
從最后一句可以看出,當我們主機訪問 8080 端口的時候,iptable將流量會轉發給 172.17.0.2 的 80 ,從而實現主機上直接訪問容器的業務
使用curl訪問一下nginx容器
contained組件
containerd
contained主要負責容器的生命周期管理,同時還會負責一些其他的功能
主要負責那些功能?
鏡像的管理
接收dockerd的請求
管理存儲相關資源
管理網絡資源
containerd-shim
containerd-shim 的意思是墊片,類似于擰螺絲時夾在螺絲和螺母之間的墊片。containerd-shim 的主要作用是將 containerd 和真正的容器進程解耦,使用 containerd-shim 作為容器進程的父進程,從而實現重啟 containerd 不影響已經啟動的容器進程。
ctr
ctr 實際上是 containerd-ctr,它是 containerd 的客戶端,主要用來開發和調試,在沒有 dockerd 的環境中,ctr 可以充當 docker 客戶端的部分角色,直接向 containerd 守護進程發送操作容器的請求。
Docker鏡像使用
來,繼續,我們看看鏡像是什么。鏡像是一個只讀的鏡像模版且包含了啟動容器所需要的文件結構內容。鏡像不包含動態數據,構建完成將不會改變
對于鏡像都有哪些操作?
對于鏡像的操作分為:
拉取鏡像:通過docker pull拉取遠程倉庫的鏡像
重命名鏡像:通過docker tag重命名鏡像
查看鏡像:通過docker image ls查看本地已經存在的鏡像
刪除鏡像:通過docekr rmi刪除沒有用的鏡像
構建鏡像
第一種是通過docker build命令基于dockerfile構建鏡像,推薦
第二種是通過docker commit基于運行的容器提交為鏡像
拉取鏡像
拉取鏡像直接使用 docker pull 命令即可,命令的格式如下
registry為注冊的服務器,docker 默認會從官網docker.io上拉取鏡像,當然可以將registry注冊為自己的服務器
repository為鏡像倉庫,library為默認的鏡像倉庫
image為鏡像的名稱
tag為給鏡像打的標簽
現在舉個例子,這里有個鏡像叫做busybox,這個鏡像集成了上百個常用的Linux命令,可以通過這個鏡像方便快捷的查找生產環境中的問題,下面我們一起操作一波
docker pull busybox
首先會在本地鏡像庫查找,如果不存在本地庫則直接去官網拉取鏡像。拉取完鏡像后隨即查看鏡像
查看鏡像---docker images
如果要查看指定的鏡像,則使用docker image ls命令進一步查詢
重命名鏡像采用打標簽的方式重命名,格式如下
我們仔細觀察這兩個鏡像,就會發現這兩個鏡像的 IMAGE ID其實是一樣的,這是什么原因呢
實際上他們都是指向的同一個鏡像文件,只不過其別名不一樣而已,如果此時不想要mybox鏡像,想刪除這個鏡像
使用 docker rmi 刪除鏡像
此時再次使用 docker images 查看確實刪除了
如何自己構建自己鏡像呢
之前說過,有兩種方式,一種是通過docker commit的方式,一種是docker build的方式。首先看看使用容器提交鏡像的方式
此時啟動了一個busybox容器并進入到容器,并在容器中創建一個文件,并寫入內容
此時就在當前目錄下創建了一個hello.txt文件并寫入了內容?,F在新建另外一個窗口,然后提交為一個鏡像
然后使用 docker image ls 查看發現確實生成了鏡像
然后我們再看看使用 dockerfile 的方式
dockerfile的每一行的命令都會生成獨立的鏡像層并擁有唯一的id
dockerfile命令是完全透明的,通過查看dockerfile的內容,就可以知道鏡像是怎么一步步構建的
dockerfile為純文本,方便做版本控制
先看看都有哪些命令
這么多,不存在的,我們先看一個dockerfile就知道如何用了
首先第一行表示基于什么鏡像構建
第二行是拷貝文件nginx。repo 到容器內的 /etc/yum.repos.d
第三行為容器中運行 yum install 命令,安裝 nginx 命令到容器
第四行為生命容器使用 80 端口對外開放
第五行定義容器啟動時的環境變量HOST=mynginx,容器啟動后可以獲取到環境變量 HOST 的值為 mynginx。
第六行定義容器的啟動命令,命令格式為json 數組。這里設置了容器的啟動命令為 nginx ,并且添加了 nginx 的啟動參數 -g 'daemon off;' ,使得 nginx 以前臺的方式啟動。
基本操作已經會了,現在我們看看鏡像的實現原理
第一行:創建一個 busybox 鏡像層
第二行:拷貝本機 test 文件到鏡像內
第三行 在tmp 文件夾創建一個目錄 testdir
為了清楚的看見鏡像的存儲結構,通過 docker build 構建鏡像
因為我的 docker 使用的是 overlay2 文件驅動,所以進入到/var/lib/docker/overlay2 ,使用 tree 查看
可以清楚的看到,dockerfile 的每一行命令都會生成一個鏡像層
Docker容器操作
我們通過一個鏡像可以輕松的創建一個容器,一個鏡像可以有多個容器,在運行容器的時候,實際上是在容器內部創建了這個文件系統的讀寫副本,如下圖所示
容器的生命周期是怎么樣的?
容器的生命周期一共有五個狀態分別為
created 初建狀態
running 運行狀態
stopped 停止狀態
opaused 暫停狀態
deleted 刪除狀態
通過docker cretate進入容器的初建狀態,然后通過docker start進入運行狀態,通過docker stop進入停止狀態,運行狀態的容器可以通過docker pause讓其變為暫停狀態,為了詳細的查看這些過程,我們實操一下
創建并啟動容器
通過docker create創建的容器處于停止的狀態,使用docker start busybox進入啟動狀態
當使用docker run創建并啟動容器的時候,docker后臺的執行邏輯為
首先檢查本地是否有busybox鏡像,不存在則取dockerhub中拉取
使用busybox鏡像啟動一個容器
分配文件系統,并在鏡像的只讀層外創建一個讀寫層
從docker ip池分配個ip給容器
運行鏡像
可以進入交互模式么
同時使用-it 參數可以讓我們進入交互模式,容器內部和主機是完全隔離的。另外由于此時的 sh 為 1 號進程,所以如果通過 exit 退出 sh,那么容器也就退出,所以對于容器而言,殺死容器中的主進程,那么容器也就會被殺死
通過docker stop停止容器,其原理是給運行中的容器給 sigterm 信號,如果容器為 1 號進程接受并處理sigterm,則等待 1 號進程處理完畢后就退出,如果等待一段時間后還是沒有處理,則會通過發送sigkill命令強制終止容器
如何進入容器?
想要進入容器,有三種方案,分別是 docker attach,docker exec,nsenter 等
使用 docker attach 方式進入容器
通過 docker ps -a 查看當前的進程信息
可是當我們在進行窗口進行docker attach的時候,這個命令就不好用了,所以使用docker exec的方式
使用 docker exec進入容器
奇怪的發現居然是兩個sh 進程,主要是因為,當我們使用 docker exec方式進入容器的時候,會單獨啟動一個 sh 進程,此時的多個窗口都是獨立且不受干擾,也是非常常用的方式
刪除容器
現在基本上知道了如何創建,啟動容器,那么怎么刪除容器呢
使用docker rm的方式刪除容器
如果此時,容器正在運行,那么需要添加-f的方式停止正在運行的容器
如果想要導出容器怎么操作呢
這簡單,不過在導出之前先進入容器創建一個文件
然后導出為文件
此時會在當前目錄生成一個 busybox.tar 文件,此時就可以將其拷貝到其他的機器上使用
那如何導入容器呢
通過 docker import的方式導入,然后使用docker run啟動就完成了容器的遷移
此時容器名稱為 busybox:test,然后我們使用 docker run 啟動并進入容器
此時發現之前在/tmp創建的目錄也被遷移了過來
倉庫
容器的基本操作應該都會了,那么我們應該如何去存儲和分發這些鏡像,這就需要介紹下倉庫;
我們可以使用共有鏡像倉庫分發,也可以搭建私有的倉庫
倉庫是啥玩意
錢錢倉庫放錢,這個倉庫放鏡像。Github 放代碼,我們理解鏡像的倉庫可以聯想 Github 倉庫。
在學習的過程中,不太能區分注冊服務器和倉庫的關系。注冊服務器其實是用來存放倉庫的實際機器,而倉庫我們可以將其理解為具體的項目或者目錄。一個注冊服務器可以存放多個倉庫,每個倉庫可以存放多個鏡像
公有倉庫
Docker hub 是當前全球最大的鏡像市場,差不多超過 10w 個容器鏡像,大部分操作系統鏡像都來自于此。
如何使用公共鏡像倉庫和存儲鏡像
注冊 Docker hub
創建倉庫
實戰鏡像推送到倉庫
此時假設我的賬戶是 xiaolantest,創建一個 busybox 的倉庫,隨后將鏡像推送到倉庫中。
第一步:拉取 busybox 鏡像
第二步:推送鏡像之前先登錄鏡像服務器(注意用戶名密碼哦),出現 login Succeeded表示登錄成功
第三步:推送之前還要做一件事,重新對鏡像命名,這樣測能正確的推動到自己創建的倉庫中
第四步:docker push 到倉庫中
私有倉庫
Docker 官方提供了開源的鏡像倉庫 Distribution,鏡像存放于 Docker hub 的 Registry中
啟動本地鏡像倉庫
使用 docker ps查看啟動的容器
重命名鏡像
此時 Docker 為busybox鏡像創建了一個別名localhost:5000/busybox,localhost:5000為主機名和端口,Docker 將會把鏡像推送到這個地址。
推送鏡像到本地倉庫
刪除之前存在的鏡像
此時,我們驗證一下從本地鏡像倉庫拉取鏡像。首先,我們刪除本地的busybox和localhost:5000/busybox鏡像。
查看當前本地鏡像
可以看到此時本地已經沒有busybox這個鏡像了。下面,我們從本地鏡像倉庫拉取busybox鏡像:
隨后再使用 docker image ls busybox 命令,這時可以看到我們已經成功從私有鏡像倉庫拉取 busybox 鏡像到本地了
總結
本篇文章從 Docker 容器圈到基本使用,寫的應該蠻清楚了。另外說明一下,由于直接使用代碼很可能導致格式排版混亂,所以全部采用截圖的方式,更加直觀和清晰,當然如有不妥之處也望大家指正。
責任編輯:lq
-
操作系統
+關注
關注
37文章
7152瀏覽量
125633 -
編程語言
+關注
關注
10文章
1956瀏覽量
36692 -
Docker
+關注
關注
0文章
515瀏覽量
12975
發布評論請先 登錄
docker無法啟用怎么解決?
如何使用Docker部署大模型
Docker Compose的常用命令
Docker常用命令大全
【技術案例】Android in Docker

基于Docker鏡像逆向生成Dockerfile

云服務器 Flexus X 實例,Docker 集成搭建 NGINX

docker通過中間鏡像加速部署
在 Huawei Cloud EulerOS 系統中安裝 Docker 的詳細步驟與常見問題解決

docker-compose配置文件內容詳解以及常用命令介紹

評論