防偽碼:博觀而約取,厚積而薄發(fā)
docker技術(shù)剖析--鏡像、容器管理
一、Docker簡介
Docker是什么?
Docker的英文本意是“搬運工”,在程序員的世界里,Docker搬運的是集裝箱(Container),集裝箱里裝的是任意類型的App,開發(fā)者通過Docker可以將App變成一種標(biāo)準(zhǔn)化的、可移植的、自管理的組件,可以在任何主流系統(tǒng)中開發(fā)、調(diào)試和運行。
說白了,docker是一種用了新穎方式實現(xiàn)的輕量級虛擬機(jī),類似于VM,但是在原理和應(yīng)用上和VM的差別還是很大的.并且docker的專業(yè)叫法是應(yīng)用容器(Application Container)。
為啥要用容器?
應(yīng)用容器是個啥樣子呢,一個做好的應(yīng)用容器長得就像一個裝好了一組特定應(yīng)用的虛擬機(jī)一樣,比如我現(xiàn)在想用mysql,那我就找個裝好了mysql的容器就可以了,然后運行起來,我就能使用mysql了。
為啥不能直接安裝一個mysql?安裝一個SQL Server也可以啊,可是有的時候根據(jù)每個人電腦的不同,在安裝的時候可能會報出各種各樣的錯誤,萬一你的機(jī)器中毒了,你的電腦掛了,你所有的服務(wù)都需要重新安裝.但是有了docker,或者說有了容器就不同了,你就相當(dāng)于有了一個可以運行起來的虛擬機(jī),只要你能運行容器,mysql的配置就省了.而且如果你想換個電腦,直接把容器”端過來”就可以使用容器里面的服務(wù).
Docker 基于 Go 語言開發(fā),代碼托管在Github上,并遵循Apache 2.0 開源協(xié)議。Docker 容器可以封裝任何有效負(fù)載,幾乎可以在任何服務(wù)器之間進(jìn)行一致性運行。換句話說,開發(fā)者構(gòu)建的應(yīng)用只需一次構(gòu)建即可多平臺運行。運營人員只需配置他們的服務(wù),即可運行所有的應(yīng)用。
若是利用容器的話,那么開發(fā)直接在容器里開發(fā),測試的時候把整個容器給測試,測好了把測試后容器再上線就好了.通過容器,整個開發(fā),測試和生產(chǎn)環(huán)境可以保持高度一致。
此外容器也VM一樣具有一定得隔離性,各個容器之間的數(shù)據(jù)和內(nèi)存空間相互隔離,可以保證一定的安全性。
Hyper-V、KVM和Xen等虛擬機(jī)管理程序都“基于虛擬化硬件仿真機(jī)制。這意味著,它們對系統(tǒng)要求很高.然而,容器卻使用共享的操作系統(tǒng)。這意味著它們在使用系統(tǒng)資源方面比虛擬機(jī)管理程序要高效得多。容器不是對硬件進(jìn)行虛擬化處理,而是駐留在一個Linux實例上。
Docker可以解決虛擬機(jī)能夠解決的問題,同時也能夠解決虛擬機(jī)由于資源要求過高而無法解決的問題。
為什么要使用docker?
1 、快速交付應(yīng)用程序
開發(fā)者使用一個標(biāo)準(zhǔn)的 image 來構(gòu)建開發(fā)容器,開發(fā)完成之后,系統(tǒng)管理員就可以使用這個容器來部署代碼
docker可以快速創(chuàng)建容器,快速迭代應(yīng)用程序,并讓整個過程可見,使團(tuán)隊中的其他成員更容易理解應(yīng)用程序是如何創(chuàng)建和工作的。
docker容器很輕!很快!容器的啟動時間是次秒級的,節(jié)約開發(fā)、測試、部署的時間
2 、更容易部署和擴(kuò)展
docker容器可以在幾乎所有的環(huán)境中運行,物理機(jī)、虛擬機(jī)、公有云、私有云、個人電腦、服務(wù)器等等。
docker容器兼容很多平臺,這樣就可以把一個應(yīng)用程序從一個平臺遷移到另外一個。
3 、效率更高
docker容器不需要 hypervisor ,他是內(nèi)核級的虛擬化。
4 、快速部署也意味著更簡單的管理
通常只需要小小的改變就可以替代以往巨型和大量的更新工作。
Docker 的常用案例包括:
自動打包和部署應(yīng)用
創(chuàng)建輕量、私有的 PaaS 環(huán)境
自動化測試和持續(xù)集成/部署
部署并擴(kuò)展 Web 應(yīng)用、數(shù)據(jù)庫和后端服務(wù)器
那么為啥不用VM?
那么既然容器和VM這么類似為啥不用VM?docker容器相對于VM還是有很多優(yōu)點的:
1.啟動速度快,容器通常在一秒內(nèi)可以啟動.而VM要很久.
2.資源利用率高,一臺普通服務(wù)器可以跑上千個容器,而跑VM就。。。。。。
3.性能開銷小,VM需要額外的CPU和內(nèi)存來完成OS的功能,這一部分占據(jù)了額外的資源.
為啥相似的功能在性能上會有如此巨大的差距呢?看一下他們的設(shè)計圖,先看VM的:
下面的圖片比較了 Docker 和傳統(tǒng)虛擬化方式的不同之處,
可見容器是在操作系統(tǒng)層面上實現(xiàn)虛擬化,直接復(fù)用本地主機(jī)的操作系統(tǒng),而傳統(tǒng)方式則是在硬件層面實現(xiàn)。
Docker優(yōu)勢和劣勢
作為一種新興的虛擬化方式,Docker 跟傳統(tǒng)的虛擬化方式相比具有眾多的優(yōu)勢。
首先,Docker 容器的啟動可以在秒級實現(xiàn),這相比傳統(tǒng)的虛擬機(jī)方式要快得多。
其次,Docker 對系統(tǒng)資源的利用率很高,一臺主機(jī)上可以同時運行數(shù)千個 Docker 容器。
容器除了運行其中應(yīng)用外,基本不消耗額外的系統(tǒng)資源,使得應(yīng)用的性能很高,同時系統(tǒng)的開銷盡量小。傳統(tǒng)虛擬機(jī)方式運行 10 個不同的應(yīng)用就要起 10 個虛擬機(jī),而 Docker 只需要啟動 10 個隔離的應(yīng)用即可。
具體說來,Docker 在如下幾個方面具有較大的優(yōu)勢。
更快速的交付和部署
對開發(fā)和運維(devop)人員來說,最希望的就是一次創(chuàng)建或配置,可以在任意地方正常運行。開發(fā)者可以使用一個標(biāo)準(zhǔn)的鏡像來構(gòu)建一套開發(fā)容器,開發(fā)完成之后,運維人員可以直接使用這個容器來部署代碼。 Docker 可以快速創(chuàng)建容器,快速迭代應(yīng)用程序,并讓整個過程全程可見,使團(tuán)隊中的其他成員更容易理解應(yīng)用程序是如何創(chuàng)建和工作的。 Docker 容器很輕很快!容器的啟動時間是秒級的,大量地節(jié)約開發(fā)、測試、部署的時間。
更高效的虛擬化
Docker 容器的運行不需要額外的 hypervisor 支持,它是內(nèi)核級的虛擬化,因此可以實現(xiàn)更高的性能和效率。
更輕松的遷移和擴(kuò)展
Docker 容器幾乎可以在任意的平臺上運行,包括物理機(jī)、虛擬機(jī)、公有云、私有云、個人電腦、服務(wù)器等。這種兼容性可以讓用戶把一個應(yīng)用程序從一個平臺直接遷移到另外一個。
更簡單的管理
使用 Docker,只需要小小的修改,就可以替代以往大量的更新工作。所有的修改都以增量的方式被分發(fā)和更新,從而實現(xiàn)自動化并且高效的管理。
對比傳統(tǒng)虛擬機(jī)總結(jié)
特性 | 容器 | 虛擬機(jī) |
啟動 | 秒級 | 分鐘級 |
硬盤使用 | 一般為MB | 一般為GB |
性能 | 接近原生 | 弱于 |
系統(tǒng)支持量 | 單機(jī)支持上千個容器 |
二、Docker 的體系結(jié)構(gòu)
docker使用C/S 架構(gòu),docker daemon 作為 server 端接受 client 的請求,并處理(創(chuàng)建、運行、分發(fā)容器),他們可以運行在一個機(jī)器上,也通過 socket或者 RESTful API 通信
Docker daemon 一般在宿主主機(jī)后臺運行。
Docker client以系統(tǒng)命令的形式存在,用戶用docker命令來跟docker daemon 交互。
Docker 守護(hù)進(jìn)程(Docker daemon)
如上圖所示,Docker 守護(hù)進(jìn)程運行在一臺主機(jī)上。用戶并不直接和守護(hù)進(jìn)程進(jìn)行交互,而是通過 Docker 客戶端間接和其通信。
Docker 客戶端(Docker client)
Docker 客戶端,實際上是docker的二進(jìn)制程序,是用戶與 Docker 交互方式。它接收用戶指令并且與背后的 Docker 守護(hù)進(jìn)程通信。
Docker 內(nèi)部:
要理解 Docker 內(nèi)部構(gòu)建,需要理解以下三種部件:
Docker 鏡像 - Docker images
Docker 倉庫 - Docker registeries
Docker 容器 - Docker containers
Docker 鏡像
Docker 鏡像是 Docker 容器運行時的只讀模板,鏡像可以用來創(chuàng)建 Docker 容器。每一個鏡像由一系列的層 (layers) 組成。Docker 使用UnionFS(聯(lián)合文件系統(tǒng))來將這些層聯(lián)合到單獨的鏡像中。UnionFS允許獨立文件系統(tǒng)中的文件和文件夾(稱之為分支)被透明覆蓋,形成一個單獨連貫的文件系統(tǒng)。正因為有了這些層的存在,Docker 是如此的輕量。當(dāng)你改變了一個 Docker 鏡像,比如升級到某個程序到新的版本,一個新的層會被創(chuàng)建。因此,不用替換整個原先的鏡像或者重新建立(在使用虛擬機(jī)的時候你可能會這么做),只是一個新的層被添加或升級了?,F(xiàn)在你不用重新發(fā)布整個鏡像,只需要升級,層使得分發(fā) Docker 鏡像變得簡單和快速。
每個docker都有很多層次構(gòu)成,docker使用 union file systems 將這些不同的層結(jié)合到一個image 中去。
例如:centos鏡像中安裝nginx,就成了nginx鏡像”,其實在此時Docker鏡像的層級概念就體現(xiàn)出來了。底層一個centos操作系統(tǒng)鏡像,上面疊加一個ngnx層,就完成了一個nginx鏡像的構(gòu)建。層級概念就不難理解,此時我們一般centos操作系統(tǒng)鏡像稱為nginx鏡像層的父鏡像。
Docker 倉庫
Docker 倉庫用來保存鏡像,可以理解為代碼控制中的代碼倉庫。同樣的,Docker 倉庫也有公有和私有的概念。公有的 Docker 倉庫名字是 Docker Hub。Docker Hub 提供了龐大的鏡像集合供使用。這些鏡像可以是自己創(chuàng)建,或者在別人的鏡像基礎(chǔ)上創(chuàng)建。
倉庫是集中存放鏡像文件的場所。有時候會把倉庫和倉庫注冊服務(wù)器(Registry)混為一談,并不嚴(yán)格區(qū)分。實際上,倉庫注冊服務(wù)器上往往存放著多個倉庫,每個倉庫中又包含了多個鏡像,每個鏡像有不同的標(biāo)簽(tag)。
倉庫分為公開倉庫(Public)和私有倉庫(Private)兩種形式。
最大的公開倉庫是 Docker Hub,存放了數(shù)量龐大的鏡像供用戶下載。國內(nèi)的公開倉庫包括 Docker Pool等,可以提供大陸用戶更穩(wěn)定快速的訪問。
當(dāng)然,用戶也可以在本地網(wǎng)絡(luò)內(nèi)創(chuàng)建一個私有倉庫。
當(dāng)用戶創(chuàng)建了自己的鏡像之后就可以使用push命令將它上傳到公有或者私有倉庫,這樣下次在另外一臺機(jī)器上使用這個鏡像時候,只需要從倉庫上pull下來就可以了。
*注:Docker 倉庫的概念跟Git類似,注冊服務(wù)器可以理解為 GitHub 這樣的托管服務(wù)。
Docker 容器
Docker 利用容器來運行應(yīng)用,一個Docker容器包含了所有的某個應(yīng)用運行所需要的環(huán)境。每一個 Docker 容器都是從 Docker 鏡像創(chuàng)建的。Docker 容器可以運行、開始、停止、移動和刪除。每一個 Docker 容器都是獨立和安全的應(yīng)用平臺。
容器是從鏡像創(chuàng)建的運行實例。它可以被啟動、開始、停止、刪除。每個容器都是相互隔離的、保證安全的平臺。
可以把容器看做是一個簡易版的 Linux 環(huán)境(包括root用戶權(quán)限、進(jìn)程空間、用戶空間和網(wǎng)絡(luò)空間等)和運行在其中的應(yīng)用程序。
*注:鏡像是只讀的,容器在啟動的時候創(chuàng)建一層可寫層作為最上層。
與虛擬機(jī)相比,容器有一個很大的差異,它們被設(shè)計用來運行"單進(jìn)程",無法很好地模擬一個完整的環(huán)境。Docker設(shè)計者極力推崇“一個容器一個進(jìn)程的方式”,如果你要選擇在一個容器中運行多個進(jìn)程,那唯一情況是:出于調(diào)試目的。
容器是設(shè)計來運行一個應(yīng)用的,而非一臺機(jī)器。你可能會把容器當(dāng)虛擬機(jī)用,但你將失去很多的靈活性,因為Docker提供了用于分離應(yīng)用與數(shù)據(jù)的工具,使得你可以快捷地更新運行中的代碼/系統(tǒng),而不影響數(shù)據(jù)。
Docker 從 0.9 版本開始使用 libcontainer 替代 lxc,libcontainer 和 Linux 系統(tǒng)的交互圖如下:
Docker 底層技術(shù)
docker底層的 2 個核心技術(shù)分別是 Namespaces 和 Control groups
Namespaces用來隔離各個容器
1)pid namespace
不同用戶的進(jìn)程就是通過pid namespace 隔離開的,且不同 namespace 中可以有相同pid。所有的LXC進(jìn)程在docker中的父進(jìn)程為docker進(jìn)程,每個lxc進(jìn)程具有不同的 namespace 。
2) net namespace
有了pid namespace, 每個 namespace 中的pid能夠相互隔離,但是網(wǎng)絡(luò)端口還是共享 host 的端口。網(wǎng)絡(luò)隔離是通過 net namespace 實現(xiàn)的,每個 net namespace 有獨立的 network devices, IP addresses, IP routing tables, /proc/net 目錄。這樣每個 container 的網(wǎng)絡(luò)就能隔離開來。docker默認(rèn)采用veth的方式將 container 中的虛擬網(wǎng)卡同 host 上的一個docker bridge: docker0 連接在一起。
3) ipc namespace
container 中進(jìn)程交互還是采用linux常見的進(jìn)程間交互方法 (interprocess communication - IPC),包括常見的信號量、消息隊列和共享內(nèi)存。container 的進(jìn)程間交互實際上還是host 上具有相同pid namespace 中的進(jìn)程間交互。
4) mnt namespace
類似chroot,將一個進(jìn)程放到一個特定的目錄執(zhí)行。mnt namespace 允許不同 namespace 的進(jìn)程看到的文件結(jié)構(gòu)不同,這樣每個 namespace 中的進(jìn)程所看到的文件目錄就被隔離開了。在container里頭,看到的文件系統(tǒng),就是一個完整的linux系統(tǒng),有/etc、/lib 等,通過chroot實現(xiàn)。
5) uts namespace
UTS("UNIX Time-sharing System") namespace 允許每個 container 擁有獨立的 hostname 和 domain name, 使其在網(wǎng)絡(luò)上可以被視作一個獨立的節(jié)點而非 Host 上的一個進(jìn)程。
6) user namespace
每個 container 可以有不同的 user 和 group id, 也就是說可以在 container 內(nèi)部用 container 內(nèi)部的用戶執(zhí)行程序而非 Host 上的用戶。
有了以上 6 種 namespace 從進(jìn)程、網(wǎng)絡(luò)、IPC、文件系統(tǒng)、UTS和用戶角度的隔離,一個 container 就可以對外展現(xiàn)出一個獨立計算機(jī)的能力,并且不同 container 從 OS 層面實現(xiàn)了隔離。然而不同 namespace 之間資源還是相互競爭的,仍然需要類似ulimit來管理每個 container 所能使用的資源 - -cgroup。
cgroups(Control groups)實現(xiàn)了對資源的配額和度量。
三、Docker 安裝
docker官網(wǎng):https://docs.docker.com
Docker值得關(guān)注的特性:
文件系統(tǒng)隔離:每個進(jìn)程容器運行在一個完全獨立的根文件系統(tǒng)里。
資源隔離:系統(tǒng)資源,像CPU和內(nèi)存等可以分配到不同的容器中,使用cgroup。
網(wǎng)絡(luò)隔離:每個進(jìn)程容器運行在自己的網(wǎng)絡(luò)空間,虛擬接口和IP地址。
日志記錄:Docker將會收集和記錄每個進(jìn)程容器的標(biāo)準(zhǔn)流(stdout/stderr/stdin),用于實時檢索或批量檢索。
變更管理:容器文件系統(tǒng)的變更可以提交到新的映像中,并可重復(fù)使用以創(chuàng)建更多的容器。無需使用模板或手動配置。
交互式shell:Docker可以分配一個虛擬終端并關(guān)聯(lián)到任何容器的標(biāo)準(zhǔn)輸入上,
CentOS 系列安裝 Docker,Docker 支持 CentOS6 及以后的版本。
CentOS6:
在RedHat/CentOS環(huán)境下安裝Docker。官方文檔要求Linux kernel至少3.8以上,且docker只能運行在64位的系統(tǒng)中。由于RHEL6和CentOS6的內(nèi)核版本為2.6,因此必須要先升級內(nèi)核。
升級內(nèi)核(記住一定要升級,要不然會出現(xiàn)很多莫名奇怪的問題,建議用yum安裝)
1、yum安裝帶aufs模塊的3.10內(nèi)核
#cd /etc/yum.repos.d
#wget http://www.hop5.in/yum/el6/hop5.repo
#yum install kernel-ml-aufs kernel-ml-aufs-devel
2、修改grub的主配置文件/etc/grub.conf,設(shè)置default=0,表示第一個title下的內(nèi)容為默認(rèn)啟動的kernel(一般新安裝的內(nèi)核在第一個位置),重啟系統(tǒng),這時候你的內(nèi)核就成功升級了。
[root@localhost ~]# uname -r
3.10.5-3.el6.x86_64
查看內(nèi)核是否支持aufs:
[root@localhost ~]# grep aufs /proc/filesystems
nodev aufs
對于 CentOS6,可以使用EPEL庫安裝 Docker,命令如下
#yum install http://mirrors.yun-idc.com/epel/6/i386/epel-release-6-8.noarch.rpm
#yum install docker-io
CentOS7:
Prerequisites(先決條件)
Docker requires a 64-bit installation regardless of your CentOS version. Also, your kernel must be 3.10 at minimum, which CentOS 7 runs.
To check your current kernel version, open a terminal and use uname -r to display your kernel version:
Docker 軟件包已經(jīng)包括在默認(rèn)的 CentOS-Extras 軟件源里。因此想要安裝docker,只需要運行下面的 yum 命令:
[root@localhost~]#yum install docker
啟動 Docker 服務(wù):
安裝完成后,使用下面的命令來啟動docker服務(wù),并將其設(shè)置為開機(jī)啟動:
[root@localhost~]#service docker start
[root@localhost~]#chkconfig docker on
(此處采用了舊式的sysv語法,如采用CentOS 7中支持的新式systemd語法,如下:
[root@localhost~]#systemctl start docker.service
[root@localhost~]#systemctl enable docker.service
查看docker版本
#docker version
查看docker版本:docker info
以上是使用centos7軟件源提供的docker安裝程序
附:也可以按照官方文檔安裝
Log into your machine as a user with sudo or root privileges.
Make sure your existing yum packages are up-to-date.
3.Add the yum repo
$ sudo tee /etc/yum.repos.d/docker.repo<<-'EOF'
[dockerrepo]
name=DockerRepositorybaseurl=https://yum.dockerproject.org/repo/main/centos/7/
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg
EOF
注:如果我們既想把輸出保存到文件中,又想在屏幕上看到輸出內(nèi)容,就可以使用tee命令了。tee命令讀取標(biāo)準(zhǔn)輸入,把這些內(nèi)容同時輸出到標(biāo)準(zhǔn)輸出和(多個)文件中
4.Install the Docker package
$ sudo yum install docker-engine
5.Start the Docker daemon.
$ sudo service dockerstart
6.Verify docker is installed correctly by running a test image in a container.
驗證docker安裝正確
$ sudo docker run hello-world
docker默認(rèn)使用的是unix socket
附:直接輸入docker命令來查看所有的Options和Commands,查看某一個command的詳細(xì)使用方法:dockerCOMMAND--help
四、Docker image詳細(xì)介紹
在之前的介紹中,我們知道docker images 是docker的三大組件之一。
docker把下載的 images 存儲到docker主機(jī)上,如果一個 image 不在主機(jī)上,docker會從一個鏡像倉庫下載,默認(rèn)的倉庫是 DOCKER HUB 公共倉庫。
接下來將介紹更多關(guān)于docker images 的內(nèi)容,包括:
使用和管理本地主機(jī)上的 images
創(chuàng)建一個基礎(chǔ)的 images
上傳 images 到docker hub (公共 images 倉庫)
列出本地主機(jī)上已經(jīng)存在的 images
1)使用docker images 顯示本機(jī)上的 images
在列出信息中,
REPOSITORY:來自于哪個倉庫,比如 docker.io/centos
TAG的標(biāo)記,比如 latest
IMAGE ID:鏡像它的 ID 號
CREATED:創(chuàng)建時間
SIZE:鏡像的 SIZE
一個倉庫可能有一個 images 的都個發(fā)行版,比如ubuntu,他們有 10.04 12.04 12.10 13.04 14.04,每個發(fā)行版的標(biāo)記都不同,可以使用 tag 命令來指定 images
注:如果你不指定具體的發(fā)行版,比如僅使用ubuntu,那么docker會使用最新的發(fā)行版ubuntu:latest
提示:建議最好指定發(fā)行版,只有這樣你才可以保證你真正使用的 image 是那個
2)獲取 images
我們?nèi)绾潍@取新的 images 呢?當(dāng)我們啟動容器使用的 image 不再本地主機(jī)上時,docker會自動下載他們。這很耗時,我們可以使用docker pull 命令來預(yù)先下載我們需要的 image 。下面的例子下載一個centos 鏡像。
這樣當(dāng)我們使用這個 image 來啟動容器的時候,它就可以馬上啟動了。
3)查找 images
docker的一個特點是很多人因為各種不同的用途創(chuàng)建了各種不同的 images 。它們都被上傳到了docker hub 共有倉庫上,我們可以在docker hub 的網(wǎng)站上來查找它們。使用docker search 命令。比如,當(dāng)我們需要 ruby 和sinatra作為 web 應(yīng)用程序的開發(fā)時,我們使用docker search 來搜索合適的image ,使用關(guān)鍵字sinatra
我們看到返回了很多包含sinatra的 images 。其中包括 image 名字、描述、星級(表示該 image 的受歡迎程度)、是否官方創(chuàng)建、是否自動創(chuàng)建。官方的 images 是stackbrew項目組創(chuàng)建和維護(hù)的,automated 資源允許你驗證 image 的來源和內(nèi)容。
到目前為止,我們看到了 2種 images 資源。比如ubuntu,被稱為基礎(chǔ)或則根鏡像。這些基礎(chǔ)鏡像是docker公司創(chuàng)建、驗證、支持、提供。他們往往使用一個單詞作為他們的名字。還有一種類型,比如我們選擇的 training/sinatra鏡像。它是由docker的用戶創(chuàng)建并維護(hù)的,你可以通過指定 image 名字的前綴來指定他們,比如 training 。
3)下載 images
現(xiàn)在我們指定了一個 image , training/sinatra,我們可以使用docker pull 命令來下載它
下載過程中,會輸出獲取鏡像的每一層信息。
該命令實際上相當(dāng)于#docker pull registry.hub.docker.com/ubuntu:12.04 命令,即從注冊服
務(wù)器 registry.hub.docker.com 中的ubuntu倉庫來下載標(biāo)記為 12.04 的鏡像。
有時候官方倉庫注冊服務(wù)器下載較慢,可以從其他倉庫下載。從其它倉庫下載時需要指定完整的倉庫注冊服務(wù)器地址。例如
#docker pull dl.dockerpool.com:5000/ubuntu:12.04
查看完整信息
當(dāng)鏡像下載成功后,你可以看到 12 位的 hash 值像 05188b417f30,這是下載完整的鏡像的精簡 ID,這些短的鏡像 ID 是完整鏡像 ID 的前 12 個字符--可以使用docker inspect 或者docker images --no-trunc來獲得完整的鏡像 ID
或
4)創(chuàng)建我們自己的 images
別人的鏡像雖然好,但不一定適合我們。我們可以對他們做一些改變,有 2 個方法:
1.第一個方法:使用docker commit 來擴(kuò)展一個 image
先使用 image 啟動容器,更新后提交結(jié)果到新的 image 。
注意:記住容器的 ID ,稍后我們還會用到
在容器中添加mariadb-server應(yīng)用。
當(dāng)結(jié)束后,我們使用 exit 來退出,現(xiàn)在我們的容器已經(jīng)被我們改變了
使用dockercommint命令來提交相應(yīng)的副本。
其中, -m 來指定提交的說明信息,跟我們使用的版本控制工具一樣; -a 可以指定更新的用戶信息;之后是用來創(chuàng)建鏡像的容器的 ID;最后指定目標(biāo)鏡像的倉庫名和 tag 信息。創(chuàng)建成功后會返回這個鏡像的 ID信息。
使用docker images 來查看新創(chuàng)建的鏡像。
之后,可以使用新的鏡像來啟動容器
2.第二個辦法:從dockerfile來創(chuàng)建 image
使用docker commit 來擴(kuò)展一個 image 比較簡單,但它不容易在一個團(tuán)隊中分享它。我們使用docker build 來創(chuàng)建一個新的 image 。為此,我們需要創(chuàng)建一個dockerfile,包含一些如何創(chuàng)建我們的image 的指令?,F(xiàn)在,我們來創(chuàng)建一個目錄和一個dockerfile
內(nèi)容如下:
Dockerfile基本的語法是
使用#來注釋
FROM指令告訴 Docker 使用哪個鏡像作為基礎(chǔ)(docker使用哪個 image 源)
MAINTAINER是維護(hù)者的信息
RUN開頭的指令會在創(chuàng)建中運行,比如安裝一個軟件包,在這里使用 yum來安裝了一些軟件
編寫完成Dockerfile后可以使用docker build 來生成鏡像。
其中 -t 標(biāo)記來添加 tag,指定新的鏡像的用戶信息。“.”是Dockerfile所在的路徑(當(dāng)前目錄),也可以替換為一個具體的Dockerfile的路徑。
可以看到 build 進(jìn)程在執(zhí)行操作。它要做的第一件事情就是上傳這個Dockerfile內(nèi)容,因為所有的操作都要依據(jù)Dockerfile來進(jìn)行。然后,Dockfile中的指令被一條一條的執(zhí)行。每一步都創(chuàng)建了一個新的容器,在容器中執(zhí)行指令并提交修改(就跟之前介紹過的docker commit 一樣)。當(dāng)所有的指令都執(zhí)行完畢之后,返回了最終的鏡像 id。所有的中間步驟所產(chǎn)生的容器都被刪除和清理了。
*注意一個鏡像不能超過 127 層
查看生成的鏡像
從我們新建的 images 開啟容器
還可以用docker tag 命令來修改鏡像的標(biāo)簽。
3.從本地文件系統(tǒng)導(dǎo)入
要從本地文件系統(tǒng)導(dǎo)入一個鏡像,可以使用openvz(容器虛擬化的先鋒技術(shù))的模板來創(chuàng)建:openvz的模板下載地址為http://openvz.org/Download/template/precreated。
先下載了一個centos-6-x86_64.tar.gz的鏡像,之后使用以下命令導(dǎo)入:
5)上傳鏡像
用戶可以通過docker push 命令,把自己創(chuàng)建的鏡像上傳到倉庫中來共享。例如,用戶在 Docker Hub 上,完成注冊后,可以推送自己的鏡像到倉庫中。
這里有兩種訪問可以創(chuàng)建和注冊一個 Docker Hub 賬戶:
1.通過網(wǎng)站,(https://hub.docker.com)
2.通過命令行
你可以通過使用命令行輸入 docker login 命令來創(chuàng)建一個 Docker Hub 賬號
#docker login
郵箱確認(rèn)
一旦你填寫完畢表格,請查看你的電子郵件,通過點擊歡迎信息中的鏈接來激活您的賬戶。
基本思路:
首先注冊docker的賬戶,然后使用docker login登錄。
使用docker push可以將自己的鏡像上傳上去了
如果有其他的倉庫,例如:
# docker push docker.sina.com.cn:5000/commit
6)用dcokerrmi移除本地 images
dockerrmi鏡像名或鏡像id
注意:在刪除 images 之前要先用dockerrm刪掉依賴于這個 images 的容器
7)存出和載入鏡像
當(dāng)需要把一臺機(jī)器上的鏡像遷移到另一臺機(jī)器的時候,需要存出鏡像與載入鏡像。
存出鏡像
如果要導(dǎo)出鏡像到本地文件,可以使用docker save 命令。
載入鏡像
可以使用docker load 從導(dǎo)出的本地文件中再導(dǎo)入到本地鏡像庫,例如
或
這將導(dǎo)入鏡像以及其相關(guān)的元數(shù)據(jù)信息(包括標(biāo)簽等)
五、Docker 容器
容器是 Docker 又一核心概念,簡單的說,容器是獨立運行的一個或一組應(yīng)用,以及它們的運行態(tài)環(huán)境。對應(yīng)的,虛擬機(jī)可以理解為模擬運行的一整套操作系統(tǒng)(提供了運行態(tài)環(huán)境和其他系統(tǒng)環(huán)境)和跑在上面的應(yīng)用。
本章將具體介紹如何來管理一個容器,包括創(chuàng)建、啟動和停止等。
啟動容器有兩種方式,一種是基于鏡像新建一個容器并啟動,另外一個是將在終止?fàn)顟B(tài)(stopped)的容器重新啟動。
新建并啟動
所需要的命令主要為docker run
下面的命令則啟動一個 bash 終端,允許用戶進(jìn)行交互。
-t 選項讓 Docker 分配一個偽終端(pseudo-tty)并綁定到容器的標(biāo)準(zhǔn)輸入上, -i則讓容器的標(biāo)準(zhǔn)輸入保持打開(即交互式),可以使用—name給容器起個形象的名稱。
在交互模式下,用戶可以通過所創(chuàng)建的終端來輸入命令,例如
容器的核心為所執(zhí)行的應(yīng)用程序,所需要的資源都是應(yīng)用程序運行所必需的。除此之外,并沒有其它的資源。可以在偽終端中利用ps或 top 來查看進(jìn)程信息。
可見,容器中僅運行了指定的 bash 應(yīng)用。這種特點使得 Docker 對資源的利用率極高,是貨真價實的輕量級虛擬化。
如果這個時候我們正常退出,logout 或者 exit 或者Ctrl+d或者Ctrl+c,dockerps–a 查看容器處于 Exit 狀態(tài)如果需要正常退出可以使用 CTRL –p + CTRL -q ----就像先按 CTRL -p 然后 CTRL –q 退出偽終端
下面的命令輸出一個“Hello World”,之后終止容器。
這跟在本地直接執(zhí)行 /bin/echo 'hello world' 幾乎感覺不出任何區(qū)別。
當(dāng)利用docker run 來創(chuàng)建容器時,Docker 在后臺運行的標(biāo)準(zhǔn)操作包括:
1.檢查本地是否存在指定的鏡像,不存在就從公有倉庫下載
2.利用鏡像創(chuàng)建并啟動一個容器
3.分配一個文件系統(tǒng),并在只讀的鏡像層外面掛載一層可讀寫層
4.從宿主主機(jī)配置的網(wǎng)橋接口中橋接一個虛擬接口到容器中去
5.從地址池配置一個ip地址給容器
6.執(zhí)行用戶指定的應(yīng)用程序
7.執(zhí)行完畢后容器被終止
查看容器dockerps
附:養(yǎng)成查看幫助的習(xí)慣
可以利用docker start 命令,直接將一個已經(jīng)終止的容器啟動運行。
# docker start [contraiID]
容器處于 Exited 狀態(tài),可以直接啟動
終止容器
# docker stop [容器 ID]
# docker kill [容器 ID]
可以使用docker stop 來終止一個運行中的容器。此外,當(dāng)Docker容器中指定的應(yīng)用終結(jié)時,容器也自動終止。例如對于前面所講中啟動了一個終端的容器,用戶通過 exit 命令或Ctrl+d來退出終端時,所創(chuàng)建的容器立刻終止
終止?fàn)顟B(tài)的容器可以用dockerps -a 命令看到
重啟容器
docker restart 命令會將一個運行態(tài)的容器終止,然后再重新啟動它。
# docker restart [容器 ID]
守護(hù)態(tài)運行
更多的時候,需要讓 Docker 容器在后臺以守護(hù)態(tài)(Daemonized)形式運行。此時,可以通過添加 -d 參數(shù)來實現(xiàn)。例如下面的命令會在后臺運行容器。
或
容器啟動后會返回一個唯一的 id,也可以通過dockerps命令來查看容器信息。
1.docker run -d 運行提個新的容器,我們通過-d 命令讓他作為一個后臺運行
2.centos:centos6 是一個我們想要在內(nèi)部運行命令的鏡像
3./bin/sh -c 是我們想要在容器內(nèi)部運行的命令
4.while true; do echo hello weibo; sleep 1; done 這是一個簡單的腳本,我們僅僅只是每秒打印一次 hello word 一直到我們結(jié)束它
用docker inspect查看容器的信息
命令格式:docker inspect 容器ID或容器名
用docker inspect查看容器的ip地址
用docker inspect查看容器執(zhí)行的程序
進(jìn)入容器
在使用 -d 參數(shù)時,容器啟動后會進(jìn)入后臺。某些時候需要進(jìn)入容器進(jìn)行操作,有很多種方法,包括使用docker attach 命令或nsenter命令。
使用docker attach進(jìn)入容器
docker attach 是Docker自帶的命令。下面示例如何使用該命令。
1.docker attach 允許我們進(jìn)入后臺進(jìn)程.
2.--sig-proxy=false 不使用容器轉(zhuǎn)發(fā)信號,允許我們使用 ctrl -c 來退出,執(zhí)行dockerps查看在后臺運行
但是使用 attach 命令有時候并不方便。當(dāng)多個窗口同時 attach 到同一個容器的時候,所有窗口都會同步顯示。當(dāng)某個窗口因命令阻塞時,其他窗口也無法執(zhí)行操作了。
也可以執(zhí)行docker exec進(jìn)入運行的容器
docker exec -it 容器ID/名稱 /bin/bash
以上命令返回一個命令界面,exec代表直接在容器中運行命令
使用nsenter進(jìn)入容器
安裝
nsenter工具在util-linux包2.23版本后包含。如果系統(tǒng)中util-linux包沒有該命令,可以按照下面的方法從源碼安裝
#wgethttps://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.tar.gz
#tar util-linux-2.24.tar.gz
#cd util-linux-2.24
# ./configure --without-ncurses&& make nsenter
#cpnsenter /usr/local/bin
nsenter可以訪問另一個進(jìn)程的名字空間。nsenter要正常工作需要有 root 權(quán)限
慶幸的是centos7使用的是util-linux-2.23,所以就直接使用系統(tǒng)提供的util-linux包了。
為了連接到容器,你還需要找到容器的第一個進(jìn)程的PID,可以通過下面的命令獲取。
PID=$(docker inspect --format "{{ .State.Pid }}" <container>)
通過這個PID,就可以連接到這個容器:
nsenter --target $PID --mount --uts --ipc --net --pid
下面給出一個完整的例子。
附:更簡單的,建議大家下載 .bashrc_docker,并將內(nèi)容放到 .bashrc中。
#wget ~ https://github.com/yeasy/docker_practice/raw/master/_local/.bashrc_docker
#echo "[ -f ~/.bashrc_docker ] &&. ~/.bashrc_docker" >> ~/.bashrc
#source ~/.bashrc
這個文件中定義了很多方便使用 Docker 的命令,例如docker-pid可以獲取某個容器的PID;而docker-enter 可以進(jìn)入容器或直接在容器內(nèi)執(zhí)行命令。
echo $(docker-pid<container>)
docker-enter <container> ls
容器導(dǎo)入和導(dǎo)出
導(dǎo)出容器
docker export [容器 id] > [導(dǎo)出文件]
如果要導(dǎo)出本地某個容器,可以使用docker export 命令。
這樣將導(dǎo)出容器快照到本地文件
導(dǎo)入容器
可以使用docker import 從容器快照文件中再導(dǎo)入為鏡像
# cat centos6.tar | docker import – centos6:test
#docker images
此外,也可以通過指定 URL 或者某個目錄來導(dǎo)入,例如
#docker import http://example.com/exampleimage.tgzexample/imagerepo
*注:用戶既可以使用docker load 來導(dǎo)入鏡像存儲文件到本地鏡像庫,也可以使用docker import 來導(dǎo)入一個容器快照到本地鏡像庫。這兩者的區(qū)別在于容器快照文件將丟棄所有的歷史記錄和元數(shù)據(jù)信息(即僅保存容器當(dāng)時的快照狀態(tài)),而鏡像存儲文件將保存完整記錄,體積也要大。此外,從容器快照文件導(dǎo)入時可以重新指定標(biāo)簽等元數(shù)據(jù)信息。
刪除容器
可以使用dockerrm來刪除一個處于終止?fàn)顟B(tài)的容器。
如果要刪除一個運行中的容器,可以添加 -f 參數(shù)。Docker 會發(fā)送SIGKILL信號給容器。
# dockerrm [容器 id/容器 name]
批量刪除多個容器
#dockerrm $(dockerps–a –q)
謝謝觀看,真心的希望能幫到您!
本文出自 “一盞燭光” 博客,謝絕轉(zhuǎn)載!
更多建議: