1. 程式人生 > >第四十一課任務 Docker入門

第四十一課任務 Docker入門

1.Docker介紹

1.1 先從認識容器開始

什麼是容器?

先來看看容器較為官方的解釋:

一句話概括容器:容器就是將軟體打包成標準化單元,以用於開發、交付和部署。

  • 容器映象是輕量的、可執行的獨立軟體包 ,包含軟體執行所需的所有內容:程式碼、執行時環境、系統工具、系統庫和設定。
  • 容器化軟體適用於基於Linux和Windows的應用,在任何環境中都能夠始終如一地執行。
  • 容器賦予了軟體獨立性,使其免受外在環境差異(例如,開發和預演環境的差異)的影響,從而有助於減少團隊間在相同基礎設施上執行不同軟體時的衝突。

再來看看容器較為通俗的解釋:
如果需要通俗的描述容器的話,我覺得容器就是一個存放東西的地方,就像書包可以裝各種文具、衣櫃可以放各種衣服、鞋架可以放各種鞋子一樣。我們現在所說的容器存放的東西可能更偏向於應用比如網站、程式甚至是系統環境。

1.2 什麼是Docker

  • 官網 www.docker.com  github  https://github.com/docker/docker.github.io  開源的容器引擎,可以讓開發者打包應用以及依賴的庫,然後釋出到任何流行的linux發行版上,移植很方便
  • Docker是世界領先的軟體容器平臺。
  • Docker使用Google公司推出的Go語言進行開發實現,基於Linux核心的cgroup,namespace,以及AUFS類的UnionFS等技術,對程序進行封裝隔離,屬於作業系統層面的虛擬化技術。 由於隔離的程序獨立於宿主和其它的隔離的程序,因此也稱其為容器。Docke最初實現是基於LXC。
  • Docker能夠自動執行重複性任務,例如搭建和配置開發環境,從而解放了開發人員以便他們專注在真正重要的事情上:構建傑出的軟體。
  • 使用者可以方便地建立和使用容器,把自己的應用放入容器。容器還可以進行版本管理、複製、分享、修改,就像管理普通的程式碼一樣。
  • docker從1.13x開始,版本分為社群版ce和企業版ee,並且基於年月的時間線形式,當前最新穩定版為17.09 

1.3 Docker的優勢

  • 啟動非常快,秒級實現  資源利用率高,一臺高配置伺服器可以跑上千個docker容器  
  • 更快的交付和部署,一次建立和配置後,可以在任意地方執行  核心級別的虛擬化,不需要額外的hypevisor支援,會有更高的效能和效率  易
  • 遷移,平臺依賴性不強

1.4Docker核心概念

映象(Image)——一個特殊的檔案系統

作業系統分為核心和使用者空間。對於Linux而言,核心啟動後,會掛載root檔案系統為其提供使用者空間支援。而Docker映象(Image),就相當於是一個root檔案系統。

Docker映象是一個特殊的檔案系統,除了提供容器執行時所需的程式、庫、資源、配置等檔案外,還包含了一些為執行時準備的一些配置引數(如匿名卷、環境變數、使用者等)。 映象不包含任何動態資料,其內容在構建之後也不會被改變。

Docker設計時,就充分利用Union FS的技術,將其設計為分層儲存的架構。 映象實際是由多層檔案系統聯合組成。

映象構建時,會一層層構建,前一層是後一層的基礎。每一層構建完就不會再發生改變,後一層上的任何改變只發生在自己這一層。比如,刪除前一層檔案的操作,實際不是真的刪除前一層的檔案,而是僅在當前層標記為該檔案已刪除。在最終容器執行的時候,雖然不會看到這個檔案,但是實際上該檔案會一直跟隨映象。因此,在構建映象的時候,需要額外小心,每一層儘量只包含該層需要新增的東西,任何額外的東西應該在該層構建結束前清理掉。

分層儲存的特徵還使得映象的複用、定製變的更為容易。甚至可以用之前構建好的映象作為基礎層,然後進一步新增新的層,以定製自己所需的內容,構建新的映象。

容器(Container)——映象執行時的實體

映象(Image)和容器(Container)的關係,就像是面向物件程式設計中的類和例項一樣,映象是靜態的定義,容器是映象執行時的實體。容器可以被建立、啟動、停止、刪除、暫停等 。

容器的實質是程序,但與直接在宿主執行的程序不同,容器程序運行於屬於自己的獨立的名稱空間。前面講過映象使用的是分層儲存,容器也是如此。

容器儲存層的生存週期和容器一樣,容器消亡時,容器儲存層也隨之消亡。因此,任何保存於容器儲存層的資訊都會隨容器刪除而丟失。

按照Docker最佳實踐的要求,容器不應該向其儲存層內寫入任何資料 ,容器儲存層要保持無狀態化。所有的檔案寫入操作,都應該使用資料卷(Volume)、或者繫結宿主目錄,在這些位置的讀寫會跳過容器儲存層,直接對宿主(或網路儲存)發生讀寫,其效能和穩定性更高。資料卷的生存週期獨立於容器,容器消亡,資料卷不會消亡。因此, 使用資料卷後,容器可以隨意刪除、重新run,資料卻不會丟失。

倉庫(Repository)——集中存放映象檔案的地方

映象構建完成後,可以很容易的在當前宿主上執行,但是, 如果需要在其它伺服器上使用這個映象,我們就需要一個集中的儲存、分發映象的服務,Docker Registry就是這樣的服務。

一個Docker Registry中可以包含多個倉庫(Repository);每個倉庫可以包含多個標籤(Tag);每個標籤對應一個映象。所以說:映象倉庫是Docker用來集中存放映象檔案的地方類似於我們之前常用的程式碼倉庫。

通常,一個倉庫會包含同一個軟體不同版本的映象,而標籤就常用於對應該軟體的各個版本 。我們可以通過<倉庫名>:<標籤>的格式來指定具體是這個軟體哪個版本的映象。如果不給出標籤,將以latest作為預設標籤。

這裡補充一下Docker Registry公開服務和私有Docker Registry的概念:

Docker Registry公開服務是開放給使用者使用、允許使用者管理映象的Registry服務。一般這類公開服務允許使用者免費上傳、下載公開的映象,並可能提供收費服務供使用者管理私有映象。

最常使用的Registry公開服務是官方的Docker Hub ,這也是預設的Registry,並擁有大量的高質量的官方映象,網址為:hub.docker.com/ 。在國內訪問Docker Hub可能會比較慢國內也有一些雲服務商提供類似於Docker Hub的公開服務。

除了使用公開服務外,使用者還可以在本地搭建私有Docker Registry 。Docker官方提供了Docker Registry映象,可以直接使用做為私有Registry服務。開源的Docker Registry映象只提供了Docker Registry API的服務端實現,足以支援Docker命令,不影響使用。但不包含圖形介面,以及映象維護、使用者管理、訪問控制等高階功能。

2.Docker安裝


[[email protected] ~]# curl https://download.docker.com/linux/centos/docker-ce.repo -o  /etc/yum.repos.d/docker.repo
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  2424  100  2424    0     0   3612      0 --:--:-- --:--:-- --:--:--  3612
[[email protected] ~]# ls
anaconda-ks.cfg
[[email protected] ~]# yum install docker
Loaded plugins: fastestmirror
Determining fastest mirrors
epel/x86_64/metalink                                                   | 5.6 kB  00:00:00     
 * base: mirror.vpshosting.com.hk
 * epel: mirror.pregi.net
 * extras: mirror.vpshosting.com.hk
 * updates: mirror.vpshosting.com.hk
base                                                                   | 3.6 kB  00:00:00     
docker-ce-stable                                                       | 3.5 kB  00:00:00     
epel                                                                   | 3.2 kB  00:00:00     
extras                                                                 | 3.4 kB  00:00:00     
updates                                                                | 3.4 kB  00:00:00     
(1/6): docker-ce-stable/x86_64/updateinfo                              |   55 B  00:00:00     
epel/x86_64/primary            FAILED                                          

啟動docker

[[email protected] ~]# systemctl start docker
[[email protected] ~]# ps aux |grep docker
root       1467  1.0  2.5 563876 25376 ?        Ssl  23:43   0:00 /usr/bin/dockerd-current --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current --default-runtime=docker-runc --exec-opt native.cgroupdriver=systemd --userland-proxy-path=/usr/libexec/docker/docker-proxy-current --init-path=/usr/libexec/docker/docker-init-current --seccomp-profile=/etc/docker/seccomp.json --selinux-enabled --log-driver=journald --signature-verification=false --storage-driver overlay2
root       1471  0.0  0.7 263856  7288 ?        Ssl  23:43   0:00 /usr/bin/docker-containerd-current -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --metrics-interval=0 --start-timeout 2m --state-dir /var/run/docker/libcontainerd/containerd --shim docker-containerd-shim --runtime docker-runc --runtime-args --systemd-cgroup=true
root       1554  0.0  0.0 112704   960 pts/0    R+   23:43   0:00 grep --color=auto docker

3. Docker映象管理

//下載docker映象
[[email protected] ~]# docker pull centos
//如果下載很慢可以配置加速器
vi /etc/docker/daemon.json//加入如下內容
{
  "registry-mirrors": ["https://dhq9bx4f.mirror.aliyuncs.com"]
}

說明:這個url為加速器地址,需要同學們自行到阿里雲申請  配置完加速器,重啟docker服務,再次docker pull centos會快很多

//檢視本地的映象
[[email protected] ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
docker.io/centos    latest              75835a67d134        7 weeks ago         200 MB

docker search xxx //搜尋映象,其中xxx是關鍵詞

[[email protected] ~]# docker search ubuntun
INDEX       NAME                                       DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
docker.io   docker.io/matriphe/ubuntunginxphp          Ubuntu 14.04.1 (phusion/baseimage-docker) ...   1                    [OK]
docker.io   docker.io/adrianeguez/ubuntunode           ubuntunode                                      0                    
docker.io   docker.io/aravindgan/ubuntunodeag                                                          0                    
docker.io   docker.io/bordet/ubuntunano                                                                0                    
docker.io   docker.io/ddmsnsysu/ubuntunginx                                                   

docker tag centos knightlai //給映象打標籤

[[email protected] ~]# docker tag centos knightlia
[[email protected] ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
knightlia           latest              75835a67d134        7 weeks ago         200 MB
docker.io/centos    latest              75835a67d134        7 weeks ago         200 MB

docker run -itd centos //把映象啟動為容器,-i表示讓容器的標準輸入開啟,-t表示分配一個偽終端,-d表示後臺啟動,要把-i -t -d 放到映象名字前面

[[email protected] ~]# docker run -itd centos
b91248c025fc5268903dd6443367813324102af977acb749afa852a925e98005
[[email protected] ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
b91248c025fc        centos              "/bin/bash"         18 seconds ago      Up 16 seconds                           elated_curie

docker rmi centos //用來刪除指定映象, 其中後面的引數可以是tag,如果是tag時,實際上是刪除該tag。當後面的引數為映象ID時,則會徹底刪除整個映象,所有標籤也會一同刪除

4.Docker通過容器建立映象

docker run啟動容器後,可以通過下面命令進入容器

//其中xxxxx為容器id,這個id可以用docker ps檢視,最後面的bash為進入容器後我們要執行的命令,這樣就可以開啟一個終端

[[email protected] ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
b91248c025fc        centos              "/bin/bash"         3 minutes ago       Up 3 minutes                            elated_curie
[[email protected] ~]# docker exec -it b91248  bash
[[email protected] /]# ls
anaconda-post.log  dev  home  lib64  mnt  proc  run   srv  tmp  var
bin                etc  lib   media  opt  root  sbin  sys  usr

進入到該容器中,我們做一些變更,比如安裝一些東西,然後針對這個容器進行建立新的映象

在容器中執行 yum install -y net-tools,然後ctrl d退出容器

[[email protected] /]# yum install -y net-tools
Loaded plugins: fastestmirror, ovl
Determining fastest mirrors
 * base: mirror.vpshosting.com.hk
 * extras: mirror.vpshosting.com.hk
 * updates: mirror.vpshosting.com.hk
base                                                                   | 3.6 kB  00:00:00     
extras                                                                 | 3.4 kB  00:00:00     
updates                                                                | 3.4 kB  00:00:00
.......................................................................................

docker commit -m "change somth"  -a "somebody info" container_id new_image_name //container_id通過docker ps -a獲取,後面的new_image_name為新映象名字

[[email protected] ~]# docker commit -m "install net-tools" -a "test" b91248c025fc centos_with_nettool
sha256:d010d5769e4f0a66501f006eb5197f61f64eaed3eda86089d3606696f90be787

這個命令有點像svn的提交,-m 加一些改動資訊,-a 指定作者相關資訊  2c74d這一串為容器id,再後面為新映象的名字


//我們可以檢視剛剛提交上來的centos_with_nettool映象
[[email protected] ~]# docker images
REPOSITORY            TAG                 IMAGE ID            CREATED              SIZE
centos_with_nettool   latest              d010d5769e4f        About a minute ago   300 MB
docker.io/centos      latest              75835a67d134        7 weeks ago          200 MB
knightlia             latest              75835a67d134        7 weeks ago          200 MB

5.Docker使用模板建立映象

我們可以到這個網站下載映象:http://openvz.org/Download/templates/precreated

匯入該映象的命令為:cat centos-7-x86_64-minimal.tar.gz|docker import - centos7

[[email protected] ~]# cat centos-7-x86_64-minimal.tar.gz|docker import - centos7
sha256:0e037beb491d18db28cfa0ff20855106925a60058908aef350b6effdf90e0c1f
[[email protected] ~]# docker images
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
centos7               latest              0e037beb491d        48 seconds ago      435 MB
centos_with_nettool   latest              d010d5769e4f        17 minutes ago      300 MB
docker.io/centos      latest              75835a67d134        7 weeks ago         200 MB
knightlia             latest              75835a67d134        7 weeks ago         200 MB
  • 把現有映象,匯出為一個檔案:  docker save -o aming-centos.tar test  
  • 我們還可以用該檔案恢復本地映象:  docker load --input aming-centos.tar  或者  docker load < aming-centos.tar

6.Docker容器管理

  • docker create -it centos6   bash //這樣可以建立一個容器,但該容器並沒有啟動  
  • docker start  container_id  //啟動容器後,可以使用 docker ps 檢視到,有start 就有stop,和restart  之前
  • 我們使用的docker run 相當於先create再start
  • docker run -it centos bash  這樣進入了一個虛擬終端裡面,我們可以執行一些命令,使用命令exit或者ctrl d 退出該bash,當退出後這個容器也會停止。  
  • docker run -d 可以讓容器在後臺執行比如:docker run -d centos bash -c "while :; do echo "123"; sleep 2; done"
  • docker run --name web -itd centos bash // --name 給容器自定義名字
  •  docker run --rm -it centos bash -c "sleep 30" //--rm 可以讓容器退出後直接刪除,在這裡命令執行完容器就會退出
  • docker logs 可以獲取到容器的執行歷史資訊,
  • 用法如下  docker logs container_id  docker attach
  • 可以進入一個後臺執行的容器,比如  docker attach container_id   //但是attach命令不算好用,比如我們想要退出終端,就得exit了,這樣容器也就退出了,
  • 還有一種方法  docker exec -it container_id bash //可以臨時開啟一個虛擬終端,並且exit後,容器依然執行著  
  • docker rm container_id //container_id是ps的時候檢視到的,這樣就可以把container刪除,如果是執行的容器,可以加-f  docker export container_id > file.tar // 匯出容器,
  • 可以遷移到其他機器上,需要匯入  cat file.tar |docker import - aming_test  //這樣會生成aming_test的映象

7.Docker倉庫管理

docker pull registry  //下載registry 映象,registy為docker官方提供的一個映象,我們可以用它來建立本地的docker私有倉庫。

[[email protected] ~]# docker pull registry
Using default tag: latest
Trying to pull repository docker.io/library/registry ... 
latest: Pulling from docker.io/library/registry
d6a5679aa3cf: Pull complete 
ad0eac849f8f: Pull complete 
2261ba058a15: Pull complete 
f296fda86f10: Pull complete 
bcd4a541795b: Pull complete 
Digest: sha256:5a156ff125e5a12ac7fdec2b90b7e2ae5120fa249cf62248337b6d04abc574c8
Status: Downloaded newer image for docker.io/registry:latest

docker run -d -p 5000:5000 registry  //以registry映象啟動容器,-p會把容器的埠對映到宿主機上,:左邊為宿主機監聽埠,:右邊為容器監聽埠

[[email protected] ~]# docker run -d -p 5000:5000 registry
e161b8bb48748e2f2a8683d326e250064620dfc32c5973109533b0b1fbba5b6d

 //以registry映象啟動容器,-p會把容器的埠對映到宿主機上,:左邊為宿主機監聽埠,:右邊為容器監聽埠

 curl 127.0.0.1:5000/v2/_catalog //可以訪問本地的私有云倉庫 

[[email protected] ~]# curl 127.0.0.1:5000/v2/_catalog
{"repositories":[]}
//此時我們的倉庫沒有任何映象

 我們上傳一個映象到我們的私有云倉庫首先要docker tag 0e037beb491d  192.168.139.135:5000/centos

[[email protected] ~]# docker tag 0e037beb491d  192.168.139.135:5000/centos
[[email protected] ~]# docker images
REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
centos7                       latest              0e037beb491d        46 minutes ago      435 MB
centos                        latest              0e037beb491d        46 minutes ago      435 MB
192.168.139.135:5000/centos   latest              0e037beb491d        46 minutes ago      435 MB
centos_with_nettool           latest              d010d5769e4f        About an hour ago   300 MB
docker.io/centos              latest              75835a67d134        7 weeks ago         200 MB
knightlia                     latest              75835a67d134        7 weeks ago         200 MB
docker.io/registry            latest              2e2f252f3c88        2 months ago        33.3 MB

 

  • docker push 192.168.139.135:5000/centos  //將映象上傳到本地的私有云上
[[email protected] ~]# docker push 192.168.139.135:5000/centos
The push refers to a repository [192.168.139.135:5000/centos]
788edba9eaa8: Pushed 
latest: digest: sha256:2f788c4abc6156f1a62ac8201d6f04a0bb6be66593533ea5ccc0e3a5d8fed232 size: 529

  • curl 192.168.139.135:5000/v2/_catalog //可以檢視到推送上來的映象
[[email protected] ~]# curl 192.168.139.135:5000/v2/_catalog
{"repositories":["centos"]}

8.Docker資料管理

  • 1. 掛載本地的目錄到容器裡  docker run -tid -v /data/:/data centos bash //-v 用來指定掛載目錄,:前面的/data/為宿主機本地目錄,:後面的/data/為容器裡的目錄,會在容器中自動建立  
  • 2. 掛載資料卷  其實我們掛載目錄的時候,可以指定容器name,如果不指定就隨機定義了。比如上面我們沒有指定,它就生成了一個名字為relaxed_franklin,這個名字可以使用命令 docker ps 看最右側一列  
  • docker run -itd --volumes-from relaxed_franklin aming123 bash  這樣,我們使用aming123映象建立了新的容器,並且使用了 relaxed_franklin 容器的資料卷
  • 3. 定義資料卷容器  有時候,我們需要多個容器之間相互共享資料,類似於linux裡面的NFS,所以就可以搭建一個專門的資料卷容器,然後其他容器直接掛載該資料卷。  
  • 首先建立資料卷容器  docker run -itd -v /data/ --name testvol centos bash //注意這裡的/data/是容器的/data目錄,並非本地的/data/目錄。  
  • 然後讓其他容器掛載該資料卷  docker run -itd --volumes-from testvol aming123 bash

9.Docker資料卷的備份與恢復

  • 備份  
  • mkdir /data/backup  
  • docker run --volumes-from testvol -v /data/backup/:/backup centos tar cvf /backup/data.tar /data/  
  • 說明:首先我們需要使用testvol資料卷新開一個容器,同時我們還需要把本地的/vol_data_backup/目錄掛載到該容器的/backup下,這樣在容器中/backup目錄裡面新建的檔案,我們就可以直接在/data/backup/目錄中看到了。 然後再把/data/目錄下面的檔案打包到成data.tar檔案放到/backup目錄下面。  
  • 恢復  思路: 先新建一個數據卷容器,再建一個新的容器並掛載該資料卷容器,然後再把tar包解包。  
  • 新建資料卷容器:docker run -itd -v /data/ --name testvol2 centos bash  
  • 掛載資料卷新建容器,並解包:docker run --volumes-from testvol2 -v /data/backup/:/backup centos tar xf /backup/data.tar