docker鏡像、容器管理

1、Docker簡介

Docker是什麼?

Docker的英文本意是「搬運工」,在程序員的世界裏,Docker搬運的是集裝箱(Container),集裝箱裏裝的是任意類型的App,開發者經過Docker能夠將App變成一種標準化的、可移植的、自管理的組件,能夠在任何主流系統中開發、調試和運行。mysql

說白了,docker是一種用了新穎方式實現的輕量級虛擬機,相似於VM,可是在原理和應用上和VM的差異仍是很大的.而且docker的專業叫法是應用容器(Application Container)。linux

爲啥要用容器?
應用容器是個啥樣子呢,一個作好的應用容器長得就像一個裝好了一組特定應用的虛擬機同樣,好比我如今想用mysql,那我就找個裝好了mysql的容器就能夠了,而後運行起來,我就能使用mysql了。nginx

爲啥不能直接安裝一個mysql?安裝一個SQL Server也能夠啊,但是有的時候根據每一個人電腦的不一樣,在安裝的時候可能會報出各類各樣的錯誤,萬一你的機器中毒了,你的電腦掛了,你全部的服務都須要從新安裝.可是有了docker,或者說有了容器就不一樣了,你就至關於有了一個能夠運行起來的虛擬機,只要你能運行容器,mysql的配置就省了.並且若是你想換個電腦,直接把容器」端過來」就可使用容器裏面的服務.git

Docker 基於 Go 語言開發,代碼託管在Github上,並遵循Apache 2.0 開源協議。Docker 容器能夠封裝任何有效負載,幾乎能夠在任何服務器之間進行一致性運行。換句話說,開發者構建的應用只需一次構建便可多平臺運行。運營人員只需配置他們的服務,便可運行全部的應用。程序員

如果利用容器的話,那麼開發直接在容器裏開發,測試的時候把整個容器給測試,測好了把測試後容器再上線就行了.經過容器,整個開發,測試和生產環境能夠保持高度一致。github

此外容器也VM同樣具備必定得隔離性,各個容器之間的數據和內存空間相互隔離,能夠保證必定的安全性。web

Hyper-V、KVM和Xen等虛擬機管理程序都「基於虛擬化硬件仿真機制。這意味着,它們對系統要求很高.然而,容器卻使用共享的操做系統。這意味着它們在使用系統資源方面比虛擬機管理程序要高效得多。容器不是對硬件進行虛擬化處理,而是駐留在一個Linux實例上。
Docker能夠解決虛擬機可以解決的問題,同時也可以解決虛擬機因爲資源要求太高而沒法解決的問題。sql

爲何要使用docker?
1 、快速交付應用程序

•開發者使用一個標準的 image 來構建開發容器,開發完成以後,系統管理員就可使用這個容器來部署代碼
•docker能夠快速建立容器,快速迭代應用程序,並讓整個過程可見,使團隊中的其餘成員更容易理解應用程序是如何建立和工做的。
•docker容器很輕!很快!容器的啓動時間是次秒級的,節約開發、測試、部署的時間docker

2 、更容易部署和擴展

•docker容器能夠在幾乎全部的環境中運行,物理機、虛擬機、公有云、私有云、我的電腦、服務器等等。
•docker容器兼容不少平臺,這樣就能夠把一個應用程序從一個平臺遷移到另一個。shell

3 、效率更高

•docker容器不須要 hypervisor ,他是內核級的虛擬化。

4 、快速部署也意味着更簡單的管理

•一般只須要小小的改變就能夠替代以往巨型和大量的更新工做。

  • Docker 的經常使用案例包括:
     自動打包和部署應用
     建立輕量、私有的 PaaS 環境
     自動化測試和持續集成/部署
     部署並擴展 Web 應用、數據庫和後端服務器
那麼爲啥不用VM?

那麼既然容器和VM這麼相似爲啥不用VM?docker容器相對於VM仍是有不少優勢的:
1.啓動速度快,容器一般在一秒內能夠啓動.而VM要好久.
2.資源利用率高,一臺普通服務器能夠跑上千個容器,而跑VM就。。。。。。
3.性能開銷小,VM須要額外的CPU和內存來完成OS的功能,這一部分佔據了額外的資源.

爲啥類似的功能在性能上會有如此巨大的差距呢?看一下他們的設計圖,先看VM的:

下面的圖片比較了 Docker 和傳統虛擬化方式的不一樣之處,

可見容器是在操做系統層面上實現虛擬化,直接複用本地主機的操做系統,而傳統方式則是在硬件層面實現。

Docker優點和劣勢
做爲一種新興的虛擬化方式,Docker 跟傳統的虛擬化方式相比具備衆多的優點。
首先,Docker 容器的啓動能夠在秒級實現,這相比傳統的虛擬機方式要快得多。
其次,Docker 對系統資源的利用率很高,一臺主機上能夠同時運行數千個 Docker 容器。
容器除了運行其中應用外,基本不消耗額外的系統資源,使得應用的性能很高,同時系統的開銷儘可能小。傳統虛擬機方式運行 10 個不一樣的應用就要起 10 個虛擬機,而 Docker 只須要啓動 10 個隔離的應用便可。

具體說來,Docker 在以下幾個方面具備較大的優點。
更快速的交付和部署
對開發和運維(devop)人員來講,最但願的就是一次建立或配置,能夠在任意地方正常運行。開發者可使用一個標準的鏡像來構建一套開發容器,開發完成以後,運維人員能夠直接使用這個容器來部署代碼。 Docker 能夠快速建立容器,快速迭代應用程序,並讓整個過程全程可見,使團隊中的其餘成員更容易理解應用程序是如何建立和工做的。 Docker 容器很輕很快!容器的啓動時間是秒級的,大量地節約開發、測試、部署的時間。
更高效的虛擬化
Docker 容器的運行不須要額外的 hypervisor 支持,它是內核級的虛擬化,所以能夠實現更高的性能和效率。
更輕鬆的遷移和擴展
Docker 容器幾乎能夠在任意的平臺上運行,包括物理機、虛擬機、公有云、私有云、我的電腦、服務器等。這種兼容性可讓用戶把一個應用程序從一個平臺直接遷移到另一個。
更簡單的管理
使用 Docker,只須要小小的修改,就能夠替代以往大量的更新工做。全部的修改都以增量的方式被分發和更新,從而實現自動化而且高效的管理。

對比傳統虛擬機總結
| 特性 | 容器 | 虛擬機 |
| ---------- | ------------------ | -------------- |
| 啓動 | 秒級 | 分鐘級 |
| 硬盤使用 | 通常爲MB | 通常爲GB |
| 性能 | 接近原生 | 弱於 |
| 系統支持量 | 單機支持上千個容器 | 單機最多幾十個 |

2、Docker 的體系結構

docker使用C/S 架構,docker daemon 做爲 server 端接受 client 的請求,並處理(建立、運行、分發容器),他們能夠運行在一個機器上,也經過 socket或者 RESTful API 通訊

Docker daemon 通常在宿主主機後臺運行。
Docker client以系統命令的形式存在,用戶用docker命令來跟docker daemon 交互。

Docker 守護進程(Docker daemon)
如上圖所示,Docker 守護進程運行在一臺主機上。用戶並不直接和守護進程進行交互,而是經過 Docker 客戶端間接和其通訊。
Docker 客戶端(Docker client)
Docker 客戶端,其實是docker的二進制程序,是用戶與 Docker 交互方式。它接收用戶指令而且與背後的 Docker 守護進程通訊。

Docker 內部:

要理解 Docker 內部構建,須要理解如下三種部件:
1)Docker 鏡像 - Docker images
2)Docker 倉庫 - Docker registeries
3)Docker 容器 - Docker containers

一、Docker 鏡像 :

Docker 鏡像是 Docker 容器運行時的只讀模板,鏡像能夠用來建立 Docker 容器。每個鏡像由一系列的層 (layers) 組成。Docker 使用UnionFS(聯合文件系統)來將這些層聯合到單獨的鏡像中。UnionFS容許獨立文件系統中的文件和文件夾(稱之爲分支)被透明覆蓋,造成一個單獨連貫的文件系統。正由於有了這些層的存在,Docker 是如此的輕量。當你改變了一個 Docker 鏡像,好比升級到某個程序到新的版本,一個新的層會被建立。所以,不用替換整個原先的鏡像或者從新創建(在使用虛擬機的時候你可能會這麼作),只是一個新的層被添加或升級了。如今你不用從新發布整個鏡像,只須要升級,層使得分發 Docker 鏡像變得簡單和快速。
每一個docker都有不少層次構成,docker使用 union file systems 將這些不一樣的層結合到一個image 中去。
例如:centos鏡像中安裝nginx,就成了nginx鏡像」,其實在此時Docker鏡像的層級概念就體現出來了。底層一個centos操做系統鏡像,上面疊加一個ngnx層,就完成了一個nginx鏡像的構建。層級概念就不難理解,此時咱們通常centos操做系統鏡像稱爲nginx鏡像層的父鏡像。

二、Docker 倉庫 :

Docker 倉庫用來保存鏡像,能夠理解爲代碼控制中的代碼倉庫。一樣的,Docker 倉庫也有公有和私有的概念。公有的 Docker 倉庫名字是 Docker Hub。Docker Hub 提供了龐大的鏡像集合供使用。這些鏡像能夠是本身建立,或者在別人的鏡像基礎上建立。
倉庫是集中存放鏡像文件的場所。有時候會把倉庫和倉庫註冊服務器(Registry)混爲一談,並不嚴格區分。實際上,倉庫註冊服務器上每每存放着多個倉庫,每一個倉庫中又包含了多個鏡像,每一個鏡像有不一樣的標籤(tag)。

倉庫分爲公開倉庫(Public)和私有倉庫(Private)兩種形式,最大的公開倉庫是 Docker Hub,存放了數量龐大的鏡像供用戶下載。國內的公開倉庫包括 Docker Pool等,能夠提供大陸用戶更穩定快速的訪問。

固然,用戶也能夠在本地網絡內建立一個私有倉庫。當用戶建立了本身的鏡像以後就可使用push命令將它上傳到公有或者私有倉庫,這樣下次在另一臺機器上使用這個鏡像時候,只須要從倉庫上pull下來就能夠了。
*注:Docker 倉庫的概念跟Git相似,註冊服務器能夠理解爲 GitHub 這樣的託管服務。

三、Docker 容器 :

Docker 容器用來運行應用,一個Docker容器包含了全部的某個應用運行所須要的環境。每個 Docker 容器都是從 Docker 鏡像建立的。Docker 容器能夠運行、開始、中止、移動和刪除。每個 Docker 容器都是獨立和安全的應用平臺。
容器是從鏡像建立的運行實例。它能夠被啓動、開始、中止、刪除。每一個容器都是相互隔離的、保證安全的平臺。
能夠把容器看作是一個簡易版的 Linux 環境(包括root用戶權限、進程空間、用戶空間和網絡空間等)和運行在其中的應用程序。
*注:鏡像是隻讀的,容器在啓動的時候建立一層可寫層做爲最上層。

與虛擬機相比,容器有一個很大的差別,它們被設計用來運行"單進程",沒法很好地模擬一個完整的環境。Docker設計者極力推崇「一個容器一個進程的方式」,若是你要選擇在一個容器中運行多個進程,那惟一狀況是:出於調試目的。
容器是設計來運行一個應用的,而非一臺機器。你可能會把容器當虛擬機用,但你將失去不少的靈活性,由於Docker提供了用於分離應用與數據的工具,使得你能夠快捷地更新運行中的代碼/系統,而不影響數據。
Docker 從 0.9 版本開始使用 libcontainer 替代 lxc,libcontainer 和 Linux 系統的交互圖以下:

Docker 底層技術
docker底層的 2 個核心技術分別是 Namespaces 和 Control groups
Namespaces用來隔離各個容器

1)pid namespace

不一樣用戶的進程就是經過pid namespace 隔離開的,且不一樣 namespace 中能夠有相同pid。全部的LXC進程在docker中的父進程爲docker進程,每一個lxc進程具備不一樣的 namespace 。

2) net namespace

有了pid namespace, 每一個 namespace 中的pid可以相互隔離,可是網絡端口仍是共享 host 的端口。網絡隔離是經過 net namespace 實現的,每一個 net namespace 有獨立的 network devices, IP addresses, IP routing tables, /proc/net 目錄。這樣每一個 container 的網絡就能隔離開來。docker默認採用veth的方式將 container 中的虛擬網卡同 host 上的一個docker bridge: docker0 鏈接在一塊兒。

3) ipc namespace

container 中進程交互仍是採用linux常見的進程間交互方法 (interprocess communication - IPC),包括常見的信號量、消息隊列和共享內存。container 的進程間交互實際上仍是host 上具備相同pid namespace 中的進程間交互。

4) mnt namespace

相似chroot,將一個進程放到一個特定的目錄執行。mnt namespace 容許不一樣 namespace 的進程看到的文件結構不一樣,這樣每一個 namespace 中的進程所看到的文件目錄就被隔離開了。在container裏頭,看到的文件系統,就是一個完整的linux系統,有/etc、/lib 等,經過chroot實現。

5) uts namespace

UTS("UNIX Time-sharing System") namespace 容許每一個 container 擁有獨立的 hostname 和 domain name, 使其在網絡上能夠被視做一個獨立的節點而非 Host 上的一個進程。

6) user namespace

每一個 container 能夠有不一樣的 user 和 group id, 也就是說能夠在 container 內部用 container 內部的用戶執行程序而非 Host 上的用戶。

有了以上 6 種 namespace 從進程、網絡、IPC、文件系統、UTS和用戶角度的隔離,一個 container 就能夠對外展示出一個獨立計算機的能力,而且不一樣 container 從 OS 層面實現了隔離。然而不一樣 namespace 之間資源仍是相互競爭的,仍然須要相似ulimit來管理每一個 container 所能使用的資源 - -cgroup。

資源配額「cgroups」
cgroups 實現了對資源的配額和度量。 cgroups 的使用很是簡單,提供相似文件的接口,在 /cgroup 目錄下新建一個文件夾便可新建一個 group,在此文件夾中新建 task 文件,並將 pid 寫入該文件,便可實現對該進程的資源控制。具體的資源配置選項能夠在該文件夾中新建子 subsystem ,{子系統前綴}.{資源項} 是典型的配置方法, 如 memory.usageinbytes 就定義了該 group 在 subsystem memory 中的一個內存限制選項。 另外,cgroups 中的 subsystem 能夠隨意組合,一個 subsystem 能夠在不一樣的 group 中,也能夠一個 group 包含多個 subsystem - 也就是說一個 subsystem。
memory
內存相關的限制
cpu
在 cgroup 中,並不能像硬件虛擬化方案同樣可以定義 CPU 能力,可是可以定義 CPU 輪轉的優先級,所以具備較高 CPU 優先級的進程會更可能獲得 CPU 運算。 經過將參數寫入 cpu.shares ,便可定義改 cgroup 的 CPU 優先級 - 這裏是一個相對權重,而非絕對值
blkio
block IO 相關的統計和限制,byte/operation 統計和限制 (IOPS 等),讀寫速度限制等,可是這裏主要統計的都是同步 IO
devices
設備權限限制

3、Docker 安裝

docker官網:https://docs.docker.com
Docker值得關注的特性:
o文件系統隔離:每一個進程容器運行在一個徹底獨立的根文件系統裏。
o資源隔離:系統資源,像CPU和內存等能夠分配到不一樣的容器中,使用cgroup。
o網絡隔離:每一個進程容器運行在本身的網絡空間,虛擬接口和IP地址。
o日誌記錄:Docker將會收集和記錄每一個進程容器的標準流(stdout/stderr/stdin),用於實時檢索或批量檢索。
o變動管理:容器文件系統的變動能夠提交到新的映像中,並可重複使用以建立更多的容器。無需使用模板或手動配置。
o交互式shell:Docker能夠分配一個虛擬終端並關聯到任何容器的標準輸入上,

CentOS 系列安裝 Docker,Docker 支持 CentOS6 及之後的版本。
CentOS6:
在RedHat/CentOS環境下安裝Docker。官方文檔要求Linux kernel至少3.8以上,且docker只能運行在64位的系統中。因爲RHEL6和CentOS6的內核版本爲2.6,所以必需要先升級內核。

升級內核(記住必定要升級,要否則會出現不少莫名奇怪的問題,建議用yum安裝)

一、Centos6系統安裝docker:

1-1)yum安裝帶aufs模塊的3.10內核

[root@server4 ~]# cd /etc/yum.repos.d/
[root@server4 yum.repos.d]# wget http://www.hop5.in/yum/el6/hop5.repo
[root@server4 yum.repos.d]# ls
hop5.repo
[root@server4 yum.repos.d]# yum -y install kernel-ml-aufs kernel-ml-aufs-devel

1-2)修改grub的主配置文件/etc/grub.conf,設置default=0,表示第一個title下的內容爲默認啓動的kernel(通常新安裝的內核在第一個位置),

1-3)重啓系統,這時候你的內核就成功升級了。

[root@server4 ~]# uname -r
3.10.0-327.el7.x86_64

1-4)可使用EPEL庫安裝 Docker,命令以下:

#yum install http://mirrors.yun-idc.com/epel/6/i386/epel-release-6-8.noarch.rpm
#yum install docker-io

1-5)啓動docker服務

#service docker start
二、CentOS7安裝docker:

2-1)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:
[root@server4 yum.repos.d]# uname -r
3.10.0-327.el7.x86_64

2-2)Docker 軟件包已經包括在默認的 CentOS-Extras 軟件源裏。所以想要安裝docker,只須要運行下面的 yum 命令:
[root@server4 yum.repos.d]# yum -y install docker
注:如出現如下報錯
[root@server4 yum.repos.d]# yum -y install docker
Loaded plugins: plugins: fastestmirror, langpacks
Existing lock /var/run/yum.pid: another copy is running as pid 13120.
Another app is currently holding the yum lock; waiting for it to exit...
The other application is: PackageKit
Memory : 26 M RSS (429 MB VSZ)
Started: Fri Nov 11 10:27:44 2016 - 00:12 ago
State : Sleeping, pid: 13120
解決方法:
[root@server4 yum.repos.d]# rm -rf /var/run/yum.pid

2-3)啓動 Docker 服務:
安裝完成後,使用下面的命令來啓動docker服務,並將其設置爲開機啓動:

[root@server4 ~]# systemctl enable docker 
[root@server4 ~]# systemctl start docker

2-4)查看docker版本

[root@server4 ~]# docker version
Client:
 Version:         1.10.3
 API version:     1.22
 Package version: docker-common-1.10.3-46.el7.centos.14.x86_64
 Go version:      go1.6.3
 Git commit:      cb079f6-unsupported
 Built:           Fri Sep 16 13:24:25 2016
 OS/Arch:         linux/amd64

Server:
 Version:         1.10.3
 API version:     1.22
 Package version: docker-common-1.10.3-46.el7.centos.14.x86_64
 Go version:      go1.6.3
 Git commit:      cb079f6-unsupported
 Built:           Fri Sep 16 13:24:25 2016
 OS/Arch:         linux/amd64

2-5)查看docker版本:docker info

[root@server4 ~]# docker info
Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 0
Server Version: 1.10.3
Storage Driver: devicemapper
 Pool Name: docker-253:0-1785801-pool
 Pool Blocksize: 65.54 kB
 Base Device Size: 10.74 GB
 Backing Filesystem: xfs
 Data file: /dev/loop0
 Metadata file: /dev/loop1
 Data Space Used: 11.8 MB
 Data Space Total: 107.4 GB
 Data Space Available: 40.74 GB
 Metadata Space Used: 581.6 kB
 Metadata Space Total: 2.147 GB
 Metadata Space Available: 2.147 GB
 Udev Sync Supported: true
 Deferred Removal Enabled: false
 Deferred Deletion Enabled: false
 Deferred Deleted Device Count: 0
 Data loop file: /var/lib/docker/devicemapper/devicemapper/data

以上是使用centos7軟件源提供的docker安裝程序
附:也能夠按照官方文檔安裝
1.Log into your machine as a user with sudo or root privileges.
2.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
注:若是咱們既想把輸出保存到文件中,又想在屏幕上看到輸出內容,就可使用tee命令了。tee命令讀取標準輸入,把這些內容同時輸出到標準輸出和(多個)文件中
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安裝正確

以上是使用centos7軟件源提供的docker安裝程序
附:也能夠按照官方文檔安裝
1.Log into your machine as a user with sudo or root privileges.
2.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
注:若是咱們既想把輸出保存到文件中,又想在屏幕上看到輸出內容,就可使用tee命令了。tee命令讀取標準輸入,把這些內容同時輸出到標準輸出和(多個)文件中
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

7.docker默認使用的是unix socket

[root@server4 ~]# ss -ax | grep docker
u_str  LISTEN     0      128    /var/lib/docker/network/files/8269c2bdc34721cabf2d2fa89b52bafd7fd1cd3f7d0c7456518c74b5cb704bdf.sock 53403                 * 0                    
u_str  LISTEN     0      128    /var/run/docker.sock 53301                 * 0                    
u_str  ESTAB      0      0      /var/run/docker.sock 55511                 * 48920


附:直接輸入docker命令來查看全部的Options和Commands,查看某一個command的詳細使用方法:dockerCOMMAND--help

4、Docker image詳細介紹

在以前的介紹中,咱們知道docker images 是docker的三大組件之一。
docker把下載的 images 存儲到docker主機上,若是一個 image 不在主機上,docker會從一個鏡像倉庫下載,默認的倉庫是 DOCKER HUB 公共倉庫。
接下來將介紹更多關於docker images 的內容,包括:
•使用和管理本地主機上的 images
•建立一個基礎的 images
•上傳 images 到docker hub (公共 images 倉庫)
•列出本地主機上已經存在的 images

1)使用docker images 顯示本機上的 images
[root@localhost ~]# docker images 
REPOSITORY     TAG          IMAGE ID         CREATED         SIZE
docker.io/centos  latest        50dae1ee8677     3 months ago     196.7 MB

在列出信息中,
•REPOSITORY:來自於哪一個倉庫,好比 docker.io/centos
•TAG的標記,好比 latest
•IMAGE ID:鏡像它的 ID 號
•CREATED:建立時間
•SIZE:鏡像的 SIZE
一個倉庫可能有一個 images 的都個發行版,好比ubuntu,他們有 10.04 12.04 12.10 13.04 14.04,每一個發行版的標記都不一樣,可使用 tag 命令來指定 images
注:若是你不指定具體的發行版,好比僅使用ubuntu,那麼docker會使用最新的發行版ubuntu:latest
提示:建議最好指定發行版,只有這樣你才能夠保證你真正使用的 image 是那個

2)獲取 images (網絡)

咱們如何獲取新的 images 呢?當咱們啓動容器使用的 image 再也不本地主機上時,docker會自動下載他們。這很耗時,咱們可使用docker pull 命令來預先下載咱們須要的 image 。下面的例子下載一個centos 鏡像。

[root@localhost ~]# docker pull docker.io/centos
Using default tag: latest
Trying to pull repository docker.io/library/centos ... 
latest: Pulling from docker.io/library/centos
08d48e6f1cff: Downloading [>                                   ] 1.081 MB/70.48 MB

這樣當咱們使用這個 image 來啓動容器的時候,它就能夠立刻啓動了。

這樣當咱們使用這個 image 來啓動容器的時候,它就能夠立刻啓動了。

3)查找 images (網絡)

docker的一個特色是不少人由於各類不一樣的用途建立了各類不一樣的 images 。它們都被上傳到了docker hub 共有倉庫上,咱們能夠在docker hub 的網站上來查找它們。使用docker search 命令。好比,當咱們須要 ruby 和sinatra做爲 web 應用程序的開發時,咱們使用docker search 來搜索合適的image ,使用關鍵字sinatra

[root@localhost ~]# docker search sinatra

咱們看到返回了不少包含sinatra的 images 。其中包括 image 名字、描述、星級(表示該 image 的受歡迎程度)、是否官方建立、是否自動建立。官方的 images 是stackbrew項目組建立和維護的,automated 資源容許你驗證 image 的來源和內容。

到目前爲止,咱們看到了 2種 images 資源。好比ubuntu,被稱爲基礎或則根鏡像。這些基礎鏡像是docker公司建立、驗證、支持、提供。他們每每使用一個單詞做爲他們的名字。還有一種類型,好比咱們選擇的 training/sinatra鏡像。它是由docker的用戶建立並維護的,你能夠經過指定 image 名字的前綴來指定他們,好比 training 。

4)下載 images

如今咱們指定了一個 image , training/sinatra,咱們可使用docker pull 命令來下載它

[root@localhost ~]# docker pull  docker.io/jdeathe/centos-ssh

下載過程當中,會輸出獲取鏡像的每一層信息。
該命令實際上至關於#docker pull registry.hub.docker.com/ubuntu:12.04 命令,即從註冊服
務器 registry.hub.docker.com 中的ubuntu倉庫來下載標記爲 12.04 的鏡像。
有時候官方倉庫註冊服務器下載較慢,能夠從其餘倉庫下載。從其它倉庫下載時須要指定完整的倉庫註冊服務器地址。例如

#docker pull dl.dockerpool.com:5000/ubuntu:12.04
5) 查看鏡像文件docker images
[root@localhost ~]# docker images 
REPOSITORY      TAG             IMAGE ID          CREATED          SIZE
docker.io/centos   latest           50dae1ee8677      3 months ago      196.7 MB
docker.io/centos   centos6         cf2c3ece5e41       4 months ago      194.6 MB
6) 查看完整信息

當鏡像下載成功後,你能夠看到 12 位的 hash 值像 05188b417f30,這是下載完整的鏡像的精簡 ID,這些短的鏡像 ID 是完整鏡像 ID 的前 12 個字符--可使用docker inspect 或者docker images --no-trunc來得到完整的鏡像 ID

[root@localhost ~]# docker inspect docker.io/centos

或: --no-trunc來得到完整的鏡像 ID

[root@localhost ~]# docker images --no-trunc
7)建立咱們本身的 images

別人的鏡像雖然好,但不必定適合咱們。咱們能夠對他們作一些改變,有 2 個方法:
1.第一個方法:使用docker commit 來擴展一個 image
1-1先使用 image 啓動容器,更新後提交結果到新的 image 。

[root@localhost ~]# docker run -it docker.io/centos /bin/bash
[root@cfd9c030875b /]#

注意:記住容器的 ID ,稍後咱們還會用到

注意:記住容器的 ID ,稍後咱們還會用到

1-2在容器中添加mariadb-server應用。

[root@cfd9c030875b /]# yum -y install httpd
[root@cfd9c030875b /]# exit

exit
當結束後,咱們使用 exit 來退出,如今咱們的容器已經被咱們改變了

exit
當結束後,咱們使用 exit 來退出,如今咱們的容器已經被咱們改變了

1-3使用docker commint命令來提交相應的副本。

[root@localhost ~]# docker commit -m "added httpd app" -a "docker chen" cfd9c030875b centos:httpd
sha256:05653ceb4e74275edfbc16edaa1976410e0fd6a35b910d4d04d83f8e92353669

其中:
-m 來指定提交的說明信息,跟咱們使用的版本控制工具同樣;
-a 能夠指定更新的用戶信息;以後是用來建立鏡像的容器的 ID;
最後指定目標鏡像的倉庫名和 tag 信息。建立成功後會返回這個鏡像的 ID信息。

其中:
-m 來指定提交的說明信息,跟咱們使用的版本控制工具同樣;
-a 能夠指定更新的用戶信息;以後是用來建立鏡像的容器的 ID;
最後指定目標鏡像的倉庫名和 tag 信息。建立成功後會返回這個鏡像的 ID信息。

1-4)使用docker images 來查看新建立的鏡像。

[root@localhost ~]# docker images 
REPOSITORY       TAG             IMAGE ID         CREATED            SIZE
centos           httpd            05653ceb4e74     About a minute ago   295.3 MB
docker.io/centos   latest            50dae1ee8677     3 months ago        196.7 MB
docker.io/centos  centos6          cf2c3ece5e41       4 months ago         194.6 MB

以後,可使用新的鏡像來啓動容器

以後,可使用新的鏡像來啓動容器

[root@localhost ~]# docker run  -it centos:httpd /bin/bash
[root@392e3fa371b7 /]# uname -r
3.10.0-327.el7.x86_64

2.第二個辦法:從dockerfile來建立 image
使用docker commit 來擴展一個 image 比較簡單,但它不容易在一個團隊中分享它。咱們使用docker build 來建立一個新的 image 。爲此,咱們須要建立一個dockerfile,包含一些如何建立咱們的image 的指令。
2-1)建立一個目錄和一個dockerfile

[root@localhost ~]# mkdir -p /docker/httpd
[root@localhost ~]# cd /docker/httpd
[root@localhost httpd]# vim dockerfile
#This is a comment
FROM docker.io/centos
MAINTAINER chen <chen@mail.com>
RUN yum -y -q install httpd

Dockerfile基本的語法是
使用#來註釋
FROM指令告訴 Docker 使用哪一個鏡像做爲基礎(docker使用哪一個 image 源)
MAINTAINER是維護者的信息
RUN開頭的指令會在建立中運行,好比安裝一個軟件包,在這裏使用 yum來安裝了一些軟件

Dockerfile基本的語法是
使用#來註釋
FROM指令告訴 Docker 使用哪一個鏡像做爲基礎(docker使用哪一個 image 源)
MAINTAINER是維護者的信息
RUN開頭的指令會在建立中運行,好比安裝一個軟件包,在這裏使用 yum來安裝了一些軟件

2-2)編寫完成Dockerfile後可使用docker build 來生成鏡像。

[root@localhost httpd]# docker build -t="centos:httpd-1" .

其中:
-t 標記來添加 tag,指定新的鏡像的用戶信息。
「.」是Dockerfile所在的路徑(當前目錄),也能夠替換爲一個具體的Dockerfile的路徑。
能夠看到 build 進程在執行操做。它要作的第一件事情就是上傳這個Dockerfile內容,由於全部的操做都要依據Dockerfile來進行。而後,Dockfile中的指令被一條一條的執行。每一步都建立了一個新的容器,在容器中執行指令並提交修改(就跟以前介紹過的docker commit 同樣)。當全部的指令都執行完畢以後,返回了最終的鏡像 id。全部的中間步驟所產生的容器都被刪除和清理了。
*注意一個鏡像不能超過 127 層

2-3)查看生成的鏡像

[root@localhost httpd]# docker images 
REPOSITORY        TAG              IMAGE ID          CREATED           SIZE
centos            httpd-1           a7e5b7ebdc89      8 minutes ago      338.5 MB
centos            httpd            f8cadf4f19b7       13 minutes ago      338.5 MB
docker.io/centos    latest            50dae1ee8677      3 months ago       196.7 MB
docker.io/centos   centos6           cf2c3ece5e41       4 months ago       194.6 MB

2-4)從咱們新建的 images 開啓容器

[root@localhost httpd]# docker run -it centos:httod-1 /bin/bash
[root@dafdc2b34c56 /]#

2-5)還能夠用docker tag 命令來修改鏡像的標籤。

[root@localhost httpd]# docker tag centos:httpd-1 centos:httod-1
[root@localhost httpd]# docker images 
REPOSITORY        TAG             IMAGE ID         CREATED            SIZE
centos            httod-1           a7e5b7ebdc89      12 minutes ago     338.5 MB
centos            httpd-1           a7e5b7ebdc89      12 minutes ago     338.5 MB
centos            httpd            f8cadf4f19b7       17 minutes ago      338.5 MB
docker.io/centos   latest             50dae1ee8677      3 months ago       196.7 MB
docker.io/centos   centos6           cf2c3ece5e41       4 months ago       194.6 MB

3.從本地文件系統導入
要從本地文件系統導入一個鏡像,可使用openvz(容器虛擬化的先鋒技術)的模板來建立:openvz的模板下載地址爲http://openvz.org/Download/template/precreated。
先下載了一個centos-6-x86_64.tar.gz的鏡像,以後使用如下命令導入:

8)上傳鏡像

用戶能夠經過docker push 命令,把本身建立的鏡像上傳到倉庫中來共享。例如,用戶在 Docker Hub 上,完成註冊後,能夠推送本身的鏡像到倉庫中。
這裏有兩種訪問能夠建立和註冊一個 Docker Hub 帳戶:
1.經過網站,(https://hub.docker.com)
2.經過命令行
你能夠經過使用命令行輸入 docker login 命令來建立一個 Docker Hub 帳號

#docker login

郵箱確認
一旦你填寫完畢表格,請查看你的電子郵件,經過點擊歡迎信息中的連接來激活您的帳戶。

郵箱確認
一旦你填寫完畢表格,請查看你的電子郵件,經過點擊歡迎信息中的連接來激活您的帳戶。

基本思路:
首先註冊docker的帳戶,而後使用docker login登陸。
使用docker push能夠將本身的鏡像上傳上去了

若是有其餘的倉庫,例如:

docker push docker.sina.com.cn:5000/commit
9)用dcokerrmi移除本地 images

dockerrmi鏡像名或鏡像id

[root@localhost httpd]# docker rmi centos:httod-1

注意:在刪除 images 以前要先用dockerrm刪掉依賴於這個 images 的容器

注意:在刪除 images 以前要先用dockerrm刪掉依賴於這個 images 的容器

10)存出和載入鏡像

當須要把一臺機器上的鏡像遷移到另外一臺機器的時候,須要存出鏡像與載入鏡像。
10-1)存出鏡像
若是要導出鏡像到本地文件,可使用docker save 命令。

[root@localhost ~]# docker save -o centos-6-httpd.tar centos:httpd-1
[root@localhost ~]# ls centos-6-httpd.tar 
centos-6-httpd.tar

10-2)載入鏡像
可使用docker load 從導出的本地文件中再導入到本地鏡像庫,例如

這將導入鏡像以及其相關的元數據信息(包括標籤等)

5、Docker 容器

容器是 Docker 又一核心概念,簡單的說,容器是獨立運行的一個或一組應用,以及它們的運行態環境。對應的,虛擬機能夠理解爲模擬運行的一整套操做系統(提供了運行態環境和其餘系統環境)和跑在上面的應用。
本章將具體介紹如何來管理一個容器,包括建立、啓動和中止等。
啓動容器有兩種方式,一種是基於鏡像新建一個容器並啓動,另一個是將在終止狀態(stopped)的容器從新啓動。

一、新建並啓動

所須要的命令主要爲docker run
下面的命令則啓動一個 bash 終端,容許用戶進行交互。

[root@localhost ~]# docker run -it docker.io/centos:centos6
[root@c88f4fefd1ff /]#

-t 選項讓 Docker 分配一個僞終端(pseudo-tty)並綁定到容器的標準輸入上,
-i則讓容器的標準輸入保持打開(即交互式),可使用—name給容器起個形象的名稱。
在交互模式下,用戶能夠經過所建立的終端來輸入命令,例如

-t 選項讓 Docker 分配一個僞終端(pseudo-tty)並綁定到容器的標準輸入上,
-i則讓容器的標準輸入保持打開(即交互式),可使用—name給容器起個形象的名稱。
在交互模式下,用戶能夠經過所建立的終端來輸入命令,例如

[root@c88f4fefd1ff /]# pwd
/
[root@c88f4fefd1ff /]# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 08:18 ?        00:00:00 /bin/bash
root        12     1  0 08:20 ?        00:00:00 ps -ef

容器的核心爲所執行的應用程序,所須要的資源都是應用程序運行所必需的。除此以外,並無其它的資源。能夠在僞終端中利用ps或 top 來查看進程信息。

容器的核心爲所執行的應用程序,所須要的資源都是應用程序運行所必需的。除此以外,並無其它的資源。能夠在僞終端中利用ps或 top 來查看進程信息。

[root@c88f4fefd1ff /]# ps
  PID TTY          TIME CMD
    1 ?        00:00:00 bash
   13 ?        00:00:00 ps

可見,容器中僅運行了指定的 bash 應用。這種特色使得 Docker 對資源的利用率極高,是貨真價實的輕量級虛擬化。

可見,容器中僅運行了指定的 bash 應用。這種特色使得 Docker 對資源的利用率極高,是貨真價實的輕量級虛擬化。

若是這個時候咱們正常退出,logout 或者 exit 或者Ctrl+d或者Ctrl+c,dockerps–a 查看容器處於 Exit 狀態若是須要正常退出可使用 CTRL –p + CTRL -q ----就像先按 CTRL -p 而後 CTRL –q 退出僞終端
下面的命令輸出一個「Hello World」,以後終止容器。

[root@localhost ~]# docker run docker.io/centos:latest /bin/echo 'hello world'
htool world

這跟在本地直接執行 /bin/echo 'hello world' 幾乎感受不出任何區別。

這跟在本地直接執行 /bin/echo 'hello world' 幾乎感受不出任何區別。

當利用docker run 來建立容器時,Docker 在後臺運行的標準操做包括:
1.檢查本地是否存在指定的鏡像,不存在就從公有倉庫下載
2.利用鏡像建立並啓動一個容器
3.分配一個文件系統,並在只讀的鏡像層外面掛載一層可讀寫層
4.從宿主主機配置的網橋接口中橋接一個虛擬接口到容器中去
5.從地址池配置一個ip地址給容器
6.執行用戶指定的應用程序
7.執行完畢後容器被終止

二、查看容器dockerps
[root@localhost ~]# docker ps -a
![](https://img2018.cnblogs.com/blog/1829796/201910/1829796-20191022110725324-901966730.png)

附:養成查看幫助的習慣

[root@localhost ~]# docker ps -h

Usage:  docker ps [OPTIONS]

List containers

  -a, --all          Show all containers (default shows just running)
  -f, --filter=[]    Filter output based on conditions provided
  --format           Pretty-print containers using a Go template
  --help             Print usage
  -l, --latest       Show the latest created container (includes all states)
  -n=-1              Show n last created containers (includes all states)
  --no-trunc         Don't truncate output
  -q, --quiet        Only display numeric IDs
  -s, --size         Display total file sizes
三、能夠利用docker start 命令,直接將一個已經終止的容器啓動運行。
docker start [contraiID]

容器處於 Exited 狀態,能夠直接啓動

四、終止容器
docker stop [容器 ID]

docker kill [容器 ID]

可使用docker stop 來終止一個運行中的容器。此外,當Docker容器中指定的應用終結時,容器也自動終止。例如對於前面所講中啓動了一個終端的容器,用戶經過 exit 命令或Ctrl+d來退出終端時,所建立的容器馬上終止
終止狀態的容器能夠用docker ps -a 命令看到。例如

狀態由 Up -> Exit
處於終止狀態的容器,能夠經過docker start 命令來從新啓動。

五、重啓容器
docker restart  命令會將一個運行態的容器終止,而後再從新啓動它。

docker restart [容器 ID]

六、守護狀態運行

更多的時候,須要讓 Docker 容器在後臺以守護狀態(Daemonized)形式運行。此時,能夠經過添加 -d 參數來實現。例以下面的命令會在後臺運行容器。

[root@localhost ~]# docker run -d docker.io/centos /bin/bash -c "while true ; do echo hello world ; sleep 1 ; done"
![](https://img2018.cnblogs.com/blog/1829796/201910/1829796-20191022110819599-2000970667.png)

[root@localhost ~]# docker run -dt docker.io/centos /bin/bash
56c3adf740ba870818af856ab76fe43fa7f44d7a0f2fc26fc4b4558788585e3a
[root@localhost ~]#

容器啓動後會返回一個惟一的 id,也能夠經過docker ps命令來查看容器信息。
1.docker run -d 運行提個新的容器,咱們經過-d 命令讓他做爲一個後臺運行
2.centos:centos6 是一個咱們想要在內部運行命令的鏡像
3./bin/sh -c 是咱們想要在容器內部運行的命令
4.while true; do echo hello weibo; sleep 1; done 這是一個簡單的腳本,咱們僅僅只是每秒打印一次 hello word 一直到咱們結束它

容器啓動後會返回一個惟一的 id,也能夠經過docker ps命令來查看容器信息。
1.docker run -d 運行提個新的容器,咱們經過-d 命令讓他做爲一個後臺運行
2.centos:centos6 是一個咱們想要在內部運行命令的鏡像
3./bin/sh -c 是咱們想要在容器內部運行的命令
4.while true; do echo hello weibo; sleep 1; done 這是一個簡單的腳本,咱們僅僅只是每秒打印一次 hello word 一直到咱們結束它

七、用docker inspect查看容器的信息

命令格式:docker inspect 容器ID或容器名

[root@localhost ~]# docker inspect 56c3adf740ba
 [
    {
        "Id": "56c3adf740ba870818af856ab76fe43fa7f44d7a0f2fc26fc4b4558788585e3a",
        "Created": "2016-11-15T10:50:58.658378757Z",
        "Path": "/bin/bash",
        "Args": [],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 42710,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2016-11-15T10:50:59.092432423Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },

用docker inspect查看容器的ip地址

用docker inspect查看容器的ip地址

[root@localhost ~]# docker inspect -f '{{.NetworkSettings.IPAddress}}' 56c3adf740ba
172.17.0.4

用docker inspect查看容器執行的程序

用docker inspect查看容器執行的程序

[root@localhost ~]# docker inspect  -f '{{.Config.Cmd}}' 56c3adf740ba 
{[/bin/bash]}
八、進入容器

在使用 -d 參數時,容器啓動後會進入後臺。某些時候須要進入容器進行操做,有不少種方法,包括使用docker attach 命令或nsenter命令。
使用docker attach進入容器
docker attach 是Docker自帶的命令。下面示例如何使用該命令。

[root@localhost ~]# docker attach 56c3adf740ba 
[root@56c3adf740ba /]#

或:

或:

[root@localhost ~]# docker attach --sig-proxy=false 56c3adf740ba 
[root@56c3adf740ba /]#

1.docker attach 容許咱們進入後臺進程.
2.--sig-proxy=false 不使用容器轉發信號,容許咱們使用 ctrl -c 來退出,執行dockerps查看在後臺運行
可是使用 attach命令有時候並不方便。當多個窗口同時 attach 到同一個容器的時候,全部窗口都會同步顯示。當某個窗口因命令阻塞時,其餘窗口也沒法執行操做了。

1.docker attach 容許咱們進入後臺進程.
2.--sig-proxy=false 不使用容器轉發信號,容許咱們使用 ctrl -c 來退出,執行dockerps查看在後臺運行
可是使用 attach命令有時候並不方便。當多個窗口同時 attach 到同一個容器的時候,全部窗口都會同步顯示。當某個窗口因命令阻塞時,其餘窗口也沒法執行操做了。

也能夠執行docker exec進入運行的容器

docker  exec  -it  容器ID/名稱 /bin/bash

以上命令返回一個命令界面,exec表明直接在容器中運行命令

以上命令返回一個命令界面,exec表明直接在容器中運行命令

[root@localhost ~]# docker exec -it 56c3adf740ba
[root@56c3adf740ba /]#
九、使用nsenter進入容器

安裝
nsenter工具在util-linux包2.23版本後包含。若是系統中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能夠訪問另外一個進程的名字空間。nsenter要正常工做須要有 root 權限
慶幸的是centos7使用的是util-linux-2.23,因此就直接使用系統提供的util-linux包了。

nsenter能夠訪問另外一個進程的名字空間。nsenter要正常工做須要有 root 權限
慶幸的是centos7使用的是util-linux-2.23,因此就直接使用系統提供的util-linux包了。

[root@localhost ~]# rpm -q util-linux
util-linux-2.23.2-26.el7.x86_64

爲了鏈接到容器,你還須要找到容器的第一個進程的PID,能夠經過下面的命令獲取。

爲了鏈接到容器,你還須要找到容器的第一個進程的PID,能夠經過下面的命令獲取。

PID=$(docker inspect --format "{{ .State.Pid }}" <container>)

經過這個PID,就能夠鏈接到這個容器:

nsenter --target $PID --mount --uts --ipc --net --pid

下面給出一個完整的例子。

下面給出一個完整的例子。

經過這個PID,就能夠鏈接到這個容器:

nsenter --target $PID --mount --uts --ipc --net --pid

下面給出一個完整的例子。

下面給出一個完整的例子。

附:更簡單的,建議你們下載 .bashrc_docker,並將內容放到 .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 能夠進入容器或直接在容器內執行命令。

這個文件中定義了不少方便使用 Docker 的命令,例如docker-pid能夠獲取某個容器的PID;而docker-enter 能夠進入容器或直接在容器內執行命令。

echo $(docker-pid<container>)
docker-enter <container> ls

容器導入和導出
導出容器:
docker export [容器 id] > [導出文件]
若是要導出本地某個容器,可使用docker export 命令。

[root@localhost ~]# docker export 56c3adf740ba > centos_web.tar
[root@localhost ~]# ls
anaconda-ks.cfg
centos6.tar
centos7.tar
centos_web.tar

這樣將導出容器快照到本地文件

這樣將導出容器快照到本地文件

導入容器:
可使用docker import 從容器快照文件中再導入爲鏡像

cat centos6.tar | docker import – centos6:test

docker images

[root@localhost ~]# cat centos_web.tar | docker import - centos:web
sha256:4429751684b5529cb70ddd080ada1462b3dfe2f48651c02a42c8ebd794a11c7d
[root@localhost ~]# docker images 
REPOSITORY       TAG               IMAGE ID          CREATED           SIZE
centos            web              4429751684b5      4 seconds ago     196.7 MB

此外,也能夠經過指定 URL 或者某個目錄來導入,例如
docker import http://example.com/exampleimage.tgzexample/imagerepo
*注:用戶既可使用docker load 來導入鏡像存儲文件到本地鏡像庫,也可使用docker import 來導入一個容器快照到本地鏡像庫。這二者的區別在於容器快照文件將丟棄全部的歷史記錄和元數據信息(即僅保存容器當時的快照狀態),而鏡像存儲文件將保存完整記錄,體積也要大。此外,從容器快照文件導入時能夠從新指定標籤等元數據信息。

此外,也能夠經過指定 URL 或者某個目錄來導入,例如
docker import http://example.com/exampleimage.tgzexample/imagerepo
*注:用戶既可使用docker load 來導入鏡像存儲文件到本地鏡像庫,也可使用docker import 來導入一個容器快照到本地鏡像庫。這二者的區別在於容器快照文件將丟棄全部的歷史記錄和元數據信息(即僅保存容器當時的快照狀態),而鏡像存儲文件將保存完整記錄,體積也要大。此外,從容器快照文件導入時能夠從新指定標籤等元數據信息。

刪除容器
可使用dockerrm來刪除一個處於終止狀態的容器。
若是要刪除一個運行中的容器,能夠添加 -f 參數。Docker 會發送SIGKILL信號給容器。

docker rm [容器 id/容器 name]

[root@localhost ~]# docker rm -f 3db07fa904c9
3db07fa904c9

批量刪除多個容器
docker rm $(docker ps –a –q)

[root@localhost ~]# docker rm -f $(docker ps -a)
56c3adf740ba
e674da52f432
acb16411ba25
eea3221f0dac
相關文章
相關標籤/搜索