天天看點

Docker 容器學習筆記

該Linux運維筆記純手打,所有指令都是在學習Linux時總結出來的,包括排版,摒棄用不到的指令,其主要目的是在生産環境中能夠快速的定位并查詢需要指令的參數,能夠高效工作。

1.配置YUM源,此處我們使用阿裡源,并安裝EPEL源,和Docker相應的依賴.

[root@localhost ~]# rm -fr /etc/yum.repos.d/*
[root@localhost ~]# wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
[root@localhost ~]# yum makecache
[root@localhost ~]# yum -y install epel-release
[root@localhost ~]# yum install -y yum-utils device-mapper-persistent-data lvm2      

2.開始安裝Docker,并設定開機自啟動.

[root@localhost ~]# yum install -y docker-ce
[root@localhost ~]# systemctl start docker
[root@localhost ~]# systemctl enable docker
[root@localhost ~]# docker run hello-world      

3.接着配置好阿裡雲Docker加速器位址.

[root@localhost ~]# vim /etc/docker/daemon.json

{
 "registry-mirrors": ["https://h8o9al0n.mirror.aliyuncs.com"]
}

[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl restart docker
[root@localhost ~]# docker version      

管理Docker鏡像

鏡像是Docker三大核心概念中最為重要的,自Docker誕生之日起,鏡像就是相關社群最為熱門的關鍵詞,Docker運作容器前需要本地存在對應的鏡像,如果鏡像沒儲存在本地,Docker會嘗試先從預設Docker Hub倉庫下載下傳,使用者也可以通過配置,使用自定義的鏡像倉庫.

下面例子将圍繞鏡像這一核心概念的具體操作,包括如何使用pull指令從Docker Hub倉庫中下載下傳鏡像到本地,如何檢視本地已有的鏡像資訊和管理鏡像标簽,如何在遠端倉庫使用search指令進行搜尋和過濾,如何删除鏡像标簽和鏡像檔案,如何建立使用者定制的鏡像并且儲存為外部檔案.最後,還介紹如何往Docker Hub倉庫中推送自己的鏡像.

查詢本地鏡像

使用docker images指令可以列出本地主機上已有鏡像的基本資訊,還可以使用條件過濾出你想要看得到的相關鏡像檔案的資訊.

[root@localhost ~]# docker images

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              4ab4c602aa5e        3 months ago        1.84kB      
上面資訊的參數解釋,在列出的資訊中可以看到以下幾個字段資訊:

REPOSITORY=來自于哪個倉庫,比如hello-world倉庫.

TAG=鏡像标簽資訊,latest表示不同版本資訊.

IMAGE ID=鏡像唯一ID号,此處唯一.

CREATED=建立時間資訊,鏡像最後的更新時間.

SIZE=鏡像大小,優秀的鏡像往往體積都較小,hello-world很優秀.

其中鏡像的ID資訊十分重要,它唯一辨別了鏡像.在使用鏡像ID的時候,一般可以使用該ID的前若幹個字元組成的可區分串來替代完整的ID,比如後期我們要删除一個鏡像時無需寫出全部鏡像ID.

TAG資訊用來标記來自同一個倉庫的不同鏡像,例如ubuntu倉庫中有多個鏡像,通過TAG資訊來區分發行版本,包括13.04、14.04、16.04等标簽.

鏡像大小資訊隻是表示該鏡像的邏輯體積大小,實際上由于相同的鏡像層本地隻會存儲一份,實體上占用的存儲空間會小于各鏡像的邏輯體積之和.

執行個體1: 通過使用​

​-a --all=true|false​

​參數,列出所有的鏡像檔案(包括臨時檔案),預設為否.因為我這裡隻有一個鏡像是以隻有這一個啦.

[root@localhost ~]# docker images --all=true

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              4ab4c602aa5e        3 months ago        1.84kB      

執行個體2: 通過使用​

​--digests=true|false​

​,列出鏡像的數字摘要值,預設為否.

[root@localhost ~]# docker images --digests=true

REPOSITORY          TAG                 DIGEST                                                                    IMAGE ID            CREATED             SIZE
hello-world         latest              sha256:0add3ace90ecb4adbf7777e9a   4ab4c602aa5e        3 months ago        1.84kB      

執行個體3: 通過使用​

​--quiet=true|false​

​,僅輸出ID資訊,預設為否.

[root@localhost ~]# docker images -q
4ab4c602aa5e

[root@localhost ~]# docker images --quiet=false

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              4ab4c602aa5e        3 months ago        1.84kB      

查詢網絡鏡像

使用docker search指令可以搜尋遠端倉庫中共享的鏡像,預設搜尋官方倉庫中的鏡像.用法為docker search TERM.

執行個體1: 使用​

​search​

​搜尋一個Centos鏡像檔案.

[root@localhost ~]# docker search centos

NAME                               DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
centos                             The official build of CentOS.                   5048                [OK]            
ansible/centos7-ansible            Ansible on Centos7                              119                                     [OK]
jdeathe/centos-ssh                 CentOS-6 6.10 x86_64 / CentOS-7 7.5.1804 x86…   102                
......      

執行個體2: 僅顯示自動建立的鏡像,預設為否.

[root@localhost ~]# docker search --automated=true centos
Flag --automated has been deprecated, use --filter=is-automated=true instead
NAME                              DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
ansible/centos7-ansible           Ansible on Centos7                              119                                     [OK]
jdeathe/centos-ssh                CentOS-6 6.10 x86_64 / CentOS-7 7.5.1804 x86…   102                                     [OK]
consol/centos-xfce-vnc            Centos container with "headless" VNC session…   73                                      [OK]
imagine10255/centos6-lnmp-php56   centos6-lnmp-php56                              48                                      [OK]      

執行個體3: 搜尋所有自動建立的評價為1+的帶nginx關鍵字的鏡像.

[root@localhost ~]# docker search --automated -s 3 nginx

Flag --automated has been deprecated, use --filter=is-automated=true instead
Flag --stars has been deprecated, use --filter=stars=3 instead
NAME                                                   DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
jwilder/nginx-proxy                                    Automated Nginx reverse proxy for docker con…   1488                                    [OK]
richarvey/nginx-php-fpm                                Container running Nginx + PHP-FPM capable of…   663      

拉鏡像到本地

可以使用docker pull指令直接從Docker Hub鏡像源來下載下傳鏡像,該指令的格式為docker pull NAME[:TAG].其中NAME是鏡像倉庫的名稱,TAG是鏡像的标簽,通常情況下,描述一個鏡像需要包括"名稱+标簽".

執行個體: 通過​

​pull​

​指令擷取一個Centos系統鏡像.

[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              4ab4c602aa5e        3 months ago        1.84kB

[root@localhost ~]# docker pull centos

[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              1e1148e4cc2c        8 days ago          202MB
hello-world         latest              4ab4c602aa5e        3 months ago        1.84kB      

給鏡像加标簽

為了友善在後續工作中使用特定鏡像,還可以使用docker tag指令來為本地鏡像任意添加新的标簽.

執行個體: 為Centos鏡像添加一個新的mycentos:latest鏡像标簽.

[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              1e1148e4cc2c        8 days ago          202MB
hello-world         latest              4ab4c602aa5e        3 months ago        1.84kB

[root@localhost ~]# docker tag centos:latest mycentos:latest

[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              1e1148e4cc2c        8 days ago          202MB
mycentos            latest              1e1148e4cc2c        8 days ago          202MB
hello-world         latest              4ab4c602aa5e        3 months ago        1.84kB      

上圖可看到,當再次使用docker images列出本地主機上鏡像資訊,可以看到多了一個擁有mycentos:latest标簽的鏡像,細心的你可能注意到,這些mycentos:latest鏡像的ID跟centos:latest完全一緻,它們實際上指向同一個鏡像檔案,隻是别名不同而已.docker tag指令添加的标簽實際上起到了類似連結的作用.

查詢鏡像詳情

使用docker inspect指令可以擷取該鏡像的詳細資訊,包括制作者、适應架構、各層的數字摘要等.

[root@localhost ~]# docker inspect hello-world

[
    {
        "Id": "sha256:4ab4c602aa5eed5528a6620ff18a1dc4faef0e1ab3a5eddeddb410714478c67f",
        "RepoTags": [
            "hello-world:latest"
        ],
        "RepoDigests": [
            "hello-world@sha256:0add3ace90ecb4adbf7777e9aacf18357296e799f81cabc9fde470971e499788"
        ],
.....      

上面的輸出有很多,隻不過我這裡簡單顯示了,如果我們隻要其中一項内容時,可以使用參數​

​-f​

​來指定你要列印的資料,例如下面我們來示範一下擷取目前鏡像的Id這個字段的資料.

[root@localhost ~]# docker inspect -f {{".Id"}} hello-world

sha256:4ab4c602aa5eed5528a6620ff18a1dc4faef0e1ab3a5eddeddb410714478c67f      

查詢鏡像分層

既然鏡像檔案由多個層組成,那麼怎麼知道各個層的内容具體是什麼呢?這時候可以使用history子指令,該指令将列出各層的建立資訊.注意過長的指令被自動截斷了,可以使用前面提到的​

​--no-trunc​

​選項來輸出完整指令.

[root@localhost ~]# docker history centos:latest

IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
1e1148e4cc2c        8 days ago          /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B
<missing>           8 days ago          /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B
<missing>           8 days ago          /bin/sh -c #(nop) ADD file:6f877549795f4798a…   202MB      

删除指定鏡像

使用docker rmi指令可以删除鏡像,其中IMAGE可以為标簽或ID,如果要強制删除可加​

​-f​

​這個選項.

删除鏡像: 通過​

​rmi​

​指令删除mycentos這個标簽.

[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              1e1148e4cc2c        8 days ago          202MB
mycentos            latest              1e1148e4cc2c        8 days ago          202MB
hello-world         latest              4ab4c602aa5e        3 months ago        1.84kB

[root@localhost ~]# docker rmi mycentos:latest
Untagged: mycentos:latest

[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              1e1148e4cc2c        8 days ago          202MB
hello-world         latest              4ab4c602aa5e        3 months ago        1.84kB      

強制删除: 強制删除系統全部鏡像.

[root@localhost ~]# docker rmi -f $(docker images -q)

Deleted: sha256:1e1148e4cc2c148c6890a18e3b2d2dde41a6745ceb4e5fe94a923d811bf82ddb
Deleted: sha256:071d8bd765171080d01682844524be57ac9883e53079b6ac66707e192ea25956
Untagged: hello-world:latest
Untagged: hello-world@sha256:0add3ace90ecb4adbf7777e9aacf18357296e799f81cabc9fde470971e499788
Deleted: sha256:4ab4c602aa5eed5528a6620ff18a1dc4faef0e1ab3a5eddeddb410714478c67f      

鏡像導入導出

導出操作: 通過​

​save 鏡像ID >​

​導出centos鏡像.

[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              1e1148e4cc2c        8 days ago          202MB
hello-world         latest              4ab4c602aa5e        3 months ago        1.84kB

[root@localhost ~]# docker save 1e1148e4cc2c > /root/centos.tar

[root@localhost ~]# ls
centos.tar      

導入操作: 通過​

​load < 檔案名​

​導入centos鏡像.

[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              4ab4c602aa5e        3 months ago        1.84kB

[root@localhost ~]# docker load < centos.tar

[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
<none>              <none>              1e1148e4cc2c        8 days ago          202MB
hello-world         latest              4ab4c602aa5e        3 months ago        1.84kB      

鏡像指令速查

[root@localhost ~]# docker info                       #查詢守護程序的系統資源設定
[root@localhost ~]# docker search                     #倉庫鏡像的查詢
[root@localhost ~]# docker pull                       #倉庫鏡像的下載下傳
[root@localhost ~]# docker images                     #本地鏡像的查詢
[root@localhost ~]# docker rmi                        #本地鏡像的删除
[root@localhost ~]# docker rmi -f $(docker images -q) #強制删除全部鏡像(Image)
[root@localhost ~]# docker rmi -f <image id>          #強制删除指定鏡像(Image)
[root@localhost ~]# docker history 鏡像名              #查詢鏡像的分層
[root@localhost ~]# docker save 鏡像ID > /root/*.tar  #鏡像的導出
[root@localhost ~]# docker load < /root/*.tar         #鏡像的導入      

管理Docker容器

下面的例子将具體介紹圍繞容器的重要操作,包括建立一個容器、啟動容器、終止一個容器、進入容器内執行操作、删除容器和通過導入導出容器來實作容器遷移等.

建立容器

從現在開始,忘掉臃腫的虛拟機吧,對容器進行操作就跟直接操作應用一樣簡單、快速.Docker容器實在太輕量級了,使用者可以随時建立或删除容器.

建立容器: 可以使用docker create指令建立一個容器,使用docker create指令建立的容器處于停止狀态,可以使用docker start指令來啟動它.

[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              1e1148e4cc2c        9 days ago          202MB
hello-world         latest              4ab4c602aa5e        3 months ago        1.84kB

[root@localhost ~]# docker create -it centos:latest
23c881ac33c526e60811978a418be92c6a022c106e6d59d989fb7b932dc3473a

[root@localhost ~]# docker start 23c881ac33c5
23c881ac33c5      

建立并啟動: 除了建立容器後通過start指令來啟動,也可以直接建立并啟動容器.所需要的指令主要為docker run,等價于先執行docker create指令,再執行docker start指令.

[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              1e1148e4cc2c        9 days ago          202MB
hello-world         latest              4ab4c602aa5e        3 months ago        1.84kB

[root@localhost ~]# docker run centos:latest      

守護态運作: 更多的時候,需要讓Docker容器在背景以守護态Daemonized形式運作.此時,可以通過添加​

​-d​

​參數來實作.

[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              1e1148e4cc2c        9 days ago          202MB
hello-world         latest              4ab4c602aa5e        3 months ago        1.84kB

[root@localhost ~]# docker run -itd ubuntu:latest
540fd59ee8899a38c4302d83549bd113ad159064ec41c9475a773cbc0fd2dfb8

[root@localhost ~]# docker run -d centos:latest /bin/sh
505a728a2bed9e96b3e4615c4e528bd55285a856dc201bb50d4ed5c9e0a52566

[root@localhost ~]# docker run -d centos:latest /bin/sh -c "echo hello"
6c8fc14a6637928442b768bee0b2d3af800464192e7fce295f39ccdd91b73572      

終止容器

可以使用docker stop來終止一個運作中的容器,也可以使用docker kill指令幹掉一個容器.

stop終止容器: 指定通過stop終止一個容器.

[root@localhost ~]# docker stop 540fd59ee889
[root@localhost ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
540fd59ee889        ubuntu:latest       "/bin/bash"         6 minutes ago       Up 6 minutes                            festive_liskov

[root@localhost ~]# docker stop 540fd59ee889
540fd59ee889      

kill終止容器:docker kill指令會直接發送SIGKILL信号來強行終止容器.

[root@localhost ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
84da1ad9f06c        centos:latest       "/bin/bash"         33 seconds ago      Up 32 seconds                           hungry_bhabha

[root@localhost ~]# docker kill 84da1ad9f06c
84da1ad9f06c      

進入容器

在使用-d參數時,容器啟動後會進入背景,使用者無法看到容器中的資訊,也無法進行操作.

這個時候如果需要進入容器進行操作,有多種方法,包括使用官方的attach或exec指令,以及第三方的nsenter工具等.下面分别介紹一下.

attach進入容器: attach是Docker自帶的指令,下面我們使用它來進入容器的内部吧.

[root@localhost ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
540fd59ee889        ubuntu:latest       "/bin/bash"         About a minute ago   Up About a minute                       festive_liskov
300560ca1c88        centos:latest       "/bin/bash"         3 minutes ago        Up 3 minutes                            ecstatic_raman

[root@localhost ~]# docker attach 300560ca1c88
[root@300560ca1c88 /]#      

但是使用attach指令有時候并不友善,當多個視窗同時用attach指令連到同一個容器的時候,所有視窗都會同步顯示.當某個視窗因指令阻塞時,其他視窗也無法執行操作了,接着下面的指令就更好一些了.

exec進入容器: Docker從1.3.0版本起提供了一個更加友善的exec指令,可以在容器内直接執行任意指令.

[root@localhost ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
540fd59ee889        ubuntu:latest       "/bin/bash"         3 minutes ago       Up 3 minutes                            festive_liskov

[root@localhost ~]# docker exec -it 540fd59ee889 /bin/bash
root@540fd59ee889:/#      

可以看到,一個bash終端打開了,在不影響容器内其他應用的前提下,使用者可以很容易與容器進行互動,通過指定​

​-it​

​參數來保持标準輸入打開,并且配置設定一個僞終端.通過exec指令對容器執行操作是最為推薦的方式.

删除容器

可以使用docker rm指令來删除處于終止或退出狀态的容器.

rm 删除容器: 通過​

​rm -f​

​指令強制删除一個容器.

[root@localhost ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
fa6110bdb3df        centos:latest       "/bin/bash"         3 seconds ago       Up 2 seconds                            eager_mirzakhani

[root@localhost ~]# docker rm -f fa6110bdb3df
fa6110bdb3df      

指令速查

[root@localhost ~]# docker run                      #容器的建立或啟動
[root@localhost ~]# docker run --restart=always     #設定容器的自啟動

[root@localhost ~]# docker ps                       #運作中的容器的查詢
[root@localhost ~]# docker ps --no-trunc            #檢視容器狀态
[root@localhost ~]# docker start/stop               #容器啟動/關閉
[root@localhost ~]# docker stop $(docker ps -a -q)  #停止所有運作中的容器(Container)
[root@localhost ~]# docker rm $(docker ps -a -q)    #删除全部容器(Container)

[root@localhost ~]# docker start/stop 鏡像名         #通過容器别名啟動/停止
[root@localhost ~]# docker inspect 鏡像名            #檢視容器所有基本資訊
[root@localhost ~]# docker logs 鏡像名               #檢視容器日志
[root@localhost ~]# docker stats 鏡像名              #檢視容器所占用的系統資源

[root@localhost ~]# docker exec 容器名 容器内執行的指令#容器執行指令
[root@localhost ~]# docker exec -it 容器名 /bin/bash  #登入容器的bash
[root@localhost ~]# docker run -it 容器名 /bin/bash   #進入一個鏡像      

Docker 持久存儲

生産環境中使用Docker的過程中,往往需要對資料進行持久化,或者需要在多個容器之間進行資料共享,這必然涉及容器的資料管理操作,容器管理中主要有兩種方式,​

​資料卷(Data Volumes)​

​​,​

​資料卷容器(Data Volume Containers)​

​,本小結将首先介紹如何在容器内建立資料卷,并且把本地的目錄或檔案挂載到容器内的資料卷中.接下來,會介紹如何使用資料卷容器在容器和主機、容器和容器之間共享資料,并實作資料的備份和恢複.

資料卷

資料卷是一個可供容器使用的特殊目錄,它将主機作業系統目錄直接映射進容器,類似于Linux中的mount操作.

資料卷可以提供很多有用的特性,如下所示:

● 資料卷可以在容器之間共享和重用,容器間傳遞資料将變得高效友善.

● 對資料卷内資料的修改會立馬生效,無論是容器内操作還是本地操作.

● 對資料卷的更新不會影響鏡像,解耦了應用和資料.

● 卷會一直存在,直到沒有容器使用,可以安全地解除安裝它.

挂載一個本地目錄作為資料卷:

1.在本地主機建立一個目錄,并寫入一些資料,來模拟本地資料.

[root@localhost ~]# mkdir /data
[root@localhost ~]# echo "hello mkdirs.com" > /data/index.html      

2.開啟容器,并讓容器讀取本地的​

​/data​

​目錄.

[root@localhost ~]# docker run -d -p 8080:80 --name MyWeb -v /data:/usr/local/apache2/htdocs httpd:latest
2882b3edda42fe153a897d3dc21f73835eb57c14019b5e810066c34e0eda4c0c

[參數解釋]

  -d     #以守護程序運作
  -p     #将容器中的80口,映射到本地主機的8080
  --name #指定一個容器名稱
  -v     #上面指的是,将本地/data目錄挂載得到容器中的/usr/local目錄中.
  -P     #是将容器服務暴露的端口,是自動映射到本地主機的臨時端口.


[root@localhost ~]# curl 127.0.0.1:8080
hello mkdirs.com      

資料卷容器

如果使用者需要在多個容器之間共享一些持續更新的資料,最簡單的方式是使用資料卷容器.資料卷容器也是一個容器,但是它的目的是專門用來提供資料卷供其他容器挂載.

1.首先,建立一個資料卷容器dbdata,并在容器中建立一個資料卷/dbdata的目錄.

[root@localhost ~]# docker run -itd -v /usr/local/apache2/htdocs --name dbdata centos:latest
1bc16a7978db7db83a4a107bf2fe1c4c42c4c7fffa7dd92372a6aacb68ccfdd0

[root@localhost ~]# docker exec -it dbdata /bin/bash
[root@1bc16a7978db /]# echo "hello mkdirs.com" > /usr/local/apache2/htdocs/index.html
[root@1bc16a7978db /]# ls -lh /usr/local/apache2/htdocs/index.html
total 4.0K
-rw-r--r-- 1 root root 17 Dec 15 11:37 index.html

[root@1bc16a7978db /]# exit      

2.然後,可以在其他容器中使用​

​--volumes-from​

​來挂載dbdata容器中的資料卷,例如建立db1和db2兩個容器,并從dbdata容器挂載資料卷.

[root@localhost ~]# docker run -d -p 801:80 --volumes-from dbdata --name db1 httpd:latest
123e75f38947f3294ac77a08bf4380f311d09cc176b576c61499139d75b35db3

[root@localhost ~]# docker run -d -p 802:80 --volumes-from dbdata --name db2 httpd:latest
a4e0f8016af6b89e31a637b1482b0849dcea26e4004298def4abce44c84d6dd6      

3.分别通路兩個不同的端口,會發現網頁展現效果是一樣的,也就是說,db1和db2共享了dbdata容器裡指定檔案的内容.

[root@localhost ~]# netstat -antp |grep 801
tcp6       0      0 :::801                  :::*                    LISTEN      3998/docker-proxy
[root@localhost ~]# netstat -antp |grep 802
tcp6       0      0 :::802                  :::*                    LISTEN      4157/docker-proxy

[root@localhost ~]# curl 127.0.0.1:801
hello mkdirs.com
[root@localhost ~]# curl 127.0.0.1:802
hello mkdirs.com      

使用​

​--volumes-from​

​​參數所挂載資料卷的容器自身并不需要保持在運作狀态,如果删除了挂載的容器(包括dbdata、db1和db2),資料卷并不會被自動删除.如果要删除一個資料卷,必須在删除最後一個還挂載着它的容器時顯式使用​

​docker rm -v​

​指令來指定同時删除關聯的容器.

容器備份恢複

資料備份: 使用下面的指令來備份dbdata資料卷容器内的資料卷,并把它備份到目前目錄下.

[root@localhost ~]# docker run --volumes-from dbdata -v $(pwd):/backup --name workers centos:latest tar -czvf /backup/backup.tar /usr/local/apache2/htdocs

tar: Removing leading `/' from member names
/usr/local/apache2/htdocs/
/usr/local/apache2/htdocs/index.html
[root@localhost ~]# ls
backup.tar      

這個指令稍微有點複雜,具體分析一下,首先利用centos鏡像建立了一個容器workers.使用​

​--volumes-from dbdata​

​​參數來讓workers容器挂載dbdata容器的資料卷(即dbdata資料卷),使用​

​-v $(pwd):/backup​

​​參數來挂載本地的目前目錄到workers容器的/backup目錄.workers容器啟動後,使用了​

​tar -czvf/backup/backup.tar /usr/local/apache2/htdocs​

​​指令來将​

​/usr/local/apache2/htdocs​

​​下内容備份為容器内的​

​/backup/backup.tar​

​,即宿主主機目前目錄下的backup.tar.

資料恢複: 如果要将資料恢複到一個容器,可以按照下面的步驟操作.

1.首先建立一個帶有資料卷的容器dbdata_backup.

[root@localhost ~]# docker run -itd -v /usr/local/apache2/htdocs --name dbdata_backup centos:latest /bin/bash
a207d887bfa07cc0e1737efb197950cac3b2c5647391348b1b8fa8b873c58667      

2.然後建立另一個新的容器,挂載dbdata2的容器,并使用untar解壓備份檔案到所挂載的容器卷中.

[root@localhost ~]# docker run --volumes-from dbdata_backup -v $(pwd):/backup busybox tar -xzvf /backup/backup.tar

usr/local/apache2/htdocs/
usr/local/apache2/htdocs/index.html      

本章介紹了通過資料卷和資料卷容器對容器内資料進行共享、備份和恢複等操作,通過這些機制,即使容器在運作中出現故障,使用者也不必擔心資料發生丢失,隻需要快速地重新建立容器即可.

Docker 端口映射

在實踐中,經常會碰到需要多個服務元件容器共同協作的情況,這往往需要多個容器之間有能夠互相通路到對方的服務,Docker提供了兩個很友善的功能來滿足服務通路的基本需求:一個是允許映射容器内應用的服務端口到本地宿主主機,另一個是互聯機制實作多個容器間通過容器名來快速通路,下面我們來分别介紹一下吧.

從外部通路容器應用

随機配置設定端口: 當容器中運作一些網絡應用,要讓外部通路這些應用時,可以通過​

​-P​

​​或​

​-p​

​​參數來指定端口映射.當使用-P(大寫的)标記時,Docker會随機映射一個​

​49000~49900​

​的端口到内部容器開放的網絡端口.

[root@localhost ~]# docker run -d -P --name myweb httpd:latest
afb211e832c16c80822632fe0864838781cee2132993f93cde8c915e242f9df5

[root@localhost ~]# docker ps
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS                   NAMES
afb211e832c1        httpd:latest        "httpd-foreground"   3 seconds ago       Up 2 seconds        0.0.0.0:32768->80/tcp   myweb      

指定配置設定端口: 當我們使用​

​-p(小寫的)​

​可以指定要映射的端口,并且,在一個指定端口上隻可以綁定一個容器.

[root@localhost ~]# docker run -d -p 8080:80 --name myweb1 httpd:latest
b47f6131dea02c8cd22a75049e97c28cc4bb25bc6bf5cd36645c1ccb4210554e

#上面說明,将容器的80端口,映射到本地的8080

[root@localhost ~]# curl 127.0.0.1.8080
<html><body><h1>It works!</h1></body></html>      

映射所有接口位址

映射指定端口: 格式将容器的80端口映射到本機的80端口.

[root@localhost ~]# docker run -d -p 80:80 --name myweb2 httpd:latest
9c3d0f8ad0bbfa75cc6534f93f959192316125a2776a2c909c71dc9dfb5a8b79

[root@localhost ~]# curl 127.0.0.1
<html><body><h1>It works!</h1></body></html>      

映射多個端口: 多次使用​

​-p​

​标記可以綁定多個端口.

[root@localhost ~]# docker run -d -p 8080:80 -p 1000:21 --name myweb3 httpd:latest
097ceb68128b58195c990dff720e39ca1717809cc2019d3f31466dee6fd32aec

[root@localhost ~]# netstat -antp |grep "8080"
tcp6       0      0 :::8080                 :::*                    LISTEN      2306/docker-proxy
[root@localhost ~]# netstat -antp |grep "1000"
tcp6       0      0 :::1000                 :::*                    LISTEN      2317/docker-proxy      

映射到指定位址

映射到指定位址的指定端口: 将容器中的80端口映射到本地指定IP位址上去.

[root@localhost ~]# ifconfig ens32:0 192.168.1.10 netmask 255.255.255.0
[root@localhost ~]# ifconfig ens32:0
ens32:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.10  netmask 255.255.255.0  broadcast 192.168.1.255
        ether 00:0c:29:1e:14:e2  txqueuelen 1000  (Ethernet)

[root@localhost ~]# docker run -d -p 192.168.1.10:8080:80 --name myweb_port httpd:latest
7385faa5d476cb37dd7d201cd0ec939501c9bdb23ec1c8239245c30d2be9abe7

[root@localhost ~]# netstat -antp |grep "8080"
tcp        0      0 192.168.1.10:8080       0.0.0.0:*               LISTEN      2585/docker-proxy

[root@localhost ~]# curl 192.168.1.10:8080
<html><body><h1>It works!</h1></body></html>      

映射到指定位址的任意端口: :本地主機會自動配置設定一個端口,綁定到容器的80口.

[root@localhost ~]# docker run -d -p 192.168.1.10::80 --name myweb_port1 httpd:latest
7a5a105ae0827aaff68864a28b5f9b8a9592af3551f7deca564ea2d6d5a249b3

[root@localhost ~]# netstat -antp |grep "80"
tcp        0      0 192.168.1.10:8080       0.0.0.0:*               LISTEN      2585/docker-proxy

#還可以使用udp标記來指定udp端口
[root@localhost ~]# docker run -d -p 192.168.1.10:5000:5000/udp --name myweb_udp httpd:latest
b9cc6333a63109a70a1d2e645b1ff5046988b472dea3bb4f4d010f1478951adf

[root@localhost ~]# netstat -an |grep "5000"
udp        0      0 192.168.1.10:5000       0.0.0.0:*      

讓容器支援SSH連接配接

1.首先建立子網

[root@localhost ~]# docker network create --subnet=172.1.0.0/16 mynetwork
[root@localhost ~]# docker network ls      

2.為容器配置設定ip

[root@localhost ~]# docker run -itd --name lyshark --net mynetwork --ip 172.1.0.2 centos:latest /bin/bash
[root@localhost ~]# docker exec -it lyshark /bin/bash      

3.安裝各種軟體

[root@localhost ~]# yum -y install net-tools  passwd openssh-server openssh-clients
[root@localhost ~]# passwd root      

4.執行ssh生成

[root@localhost ~]# ssh-keygen -q -t rsa -b 2048 -f /etc/ssh/ssh_host_rsa_key -N ''  
[root@localhost ~]# ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N ''
[root@localhost ~]# ssh-keygen -t dsa -f /etc/ssh/ssh_host_ed25519_key -N ''      

5.接着修改sshd_config檔案配置資訊

[root@localhost ~]# vi /etc/ssh/sshd_config

開啟 Port 22 注釋
将  PermitRootLogin  的 no  改為 yes

啟動ssh服務  /usr/sbin/sshd -D &      

6.退出這個鏡像,然後打包成新的。

[root@localhost ~]# docker commit lyshark mycentos   制作新的鏡像      

5.直接建立新的容器即可。

[root@localhost ~]# docker rm $(docker ps -a -q)
[root@localhost ~]# docker run -itd --name centos1 --net mynetwork --ip 172.1.0.2 mycentos  /usr/sbin/init
[root@localhost ~]# docker exec -it lyshark /bin/bash      

6.外網連結配置,将外網的5423端口映射到内網主機的 172.1.0.2:22口上,即可外部連接配接該容器

[root@localhost ~]# firewall-cmd --add-forward-port=port=5423:proto=tcp:toaddr=172.1.0.2:toport=22
success
[root@localhost ~]# firewall-cmd --add-port=5423/tcp
success      

Docker 容器互聯

容器的互聯(linking)是一種讓多個容器中應用進行快速互動的方式,它會在源和接收容器之間建立連接配接關系,接收容器可以通過容器名快速通路到源容器,而不用指定具體的IP位址.

1.使用​

​--link​

​參數可以讓容器之間安全地進行互動,下面先建立一個新的MySQL資料庫容器.

[root@localhost ~]# docker run -d --name mysqldb mysql:latest
c1770a69ed29944466ce013c42ac2a0391651c88381e41be05308eab80458390      

2.然後建立一個新的web容器,并将它連接配接到MySQL容器,使之能夠通信.

[root@localhost ~]# docker run -d -P --name web --link mysqldb:mysqldb httpd:latest
8b2bfcbbe00f6966c511fdbbbc16e40736ab8d6aa89d229e224f38d12c4643df      

此時,mysqldb容器和web容器建立互聯關系,​

​--link​

​​參數的格式為​

​--link name:alias​

​,其中name是要連接配接的容器名稱,alias是這個連接配接的别名.

Docker相當于在兩個互聯的容器之間建立了一個虛機通道,而且不用映射它們的端口到宿主主機上.在啟動mysqldb容器的時候并沒有使用-p和-P标記,進而避免了暴露資料庫服務端口到外部網絡上.

環境變量傳遞參數

FROM centos:latest
USER root
MAINTAINER [email protected]

ENV USER none
ENV PASD none      

在docker run 指令中通過 -e标記來傳遞環境變量,這樣容器運作時就可以使用該變量:

docker run -it --env "USER=root" \
               --env "PASD=1233" df434s4s /bin/bash      

檢視環境變量

[root@localhost ~]# docker inspect centos:v3
[root@localhost ~]# docker exec -it b2f327865a98 env      

Apache

Apache是世界使用排名第一的Web伺服器軟體,它可以運作在幾乎所有廣泛使用的計算機平台上,由于其跨平台和安全性被廣泛使用,是最流行的Web伺服器端軟體之一.它快速、可靠并且可通過簡單的API擴充,将Perl/Python等解釋器編譯到伺服器中.

1.拉取鏡像,并在本地建立一個測試頁.

[root@localhost ~]# docker pull httpd:latest
[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
httpd               latest              2a51bb06dc8b        4 weeks ago         132MB

[root@localhost ~]# mkdir /web
[root@localhost ~]# echo "hello world" > /web/index.html      

2.運作http容器,并通路測試.

[root@localhost ~]# docker run -d -p 8080:80 --name MyWeb -v /web:/usr/local/apache2/htdocs httpd:latest
[root@localhost ~]# curl 127.0.0.1:8080
hello world      

GitLab

Gitlab是一款非常強大的開源源碼管理系統.它支援基于Git的源碼管理、代碼評審、issue跟蹤、活動管理、wiki頁面,持續內建和測試等功能.基于Gitlab,使用者可以自己搭建一套類似Github的開發協同平台.

1.安裝并啟動postgresql.

[root@localhost ~]# docker pull sameersbn/postgresql:latest
[root@localhost ~]# docker images
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
sameersbn/postgresql   latest              3c0142eb3992        5 months ago        204MB

[root@localhost ~]# docker run --name gitlab_postgresql -d \
--env 'DB_NAME=gitlab' \
--env 'DB_USER=gitlab' --env 'DB_PASS=gitlab' \
sameersbn/postgresql:latest      

2.安裝redis.

[root@localhost ~]# docker pull sameersbn/redis:latest
[root@localhost ~]# docker images
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
sameersbn/redis        latest              ad607f019b8c        4 months ago        84.8MB
sameersbn/postgresql   latest              3c0142eb3992        5 months ago        204MB

[root@localhost ~]# docker run --name gitlab_redis -itd sameersbn/redis:latest      

3.安裝GitLab.

[root@localhost ~]# docker pull sameersbn/gitlab:latest
[root@localhost ~]# docker images
REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
sameersbn/gitlab       latest              336fe9c19d92        6 days ago          1.96GB
sameersbn/redis        latest              ad607f019b8c        4 months ago        84.8MB
sameersbn/postgresql   latest              3c0142eb3992        5 months ago        204MB

[root@localhost ~]# docker run --name gitlab -d sameersbn/gitlab \
--link gitlab_postgresql:postgresql --link gitlab_redis:redis \
--publish 10022:22 --publish 10080:80 \
--env 'GITLAB_PORT=10080' --env 'GITLAB_SSH_PORT=10022' \
--env 'GITLAB_SECRETS_DB_KEY_BASE=long-and-random-alpha-numeric-string' \
sameersbn/gitlab:latest      

WordPress

WordPress是使用PHP語言開發的部落格平台,使用者可以在支援PHP和MySQL資料庫的伺服器上架設屬于自己的網站.也可以把WordPress當作一個内容管理系統(CMS)來使用,WordPress逐漸演化成一款内容管理系統軟體,它是使用PHP語言和MySQL資料庫開發的.使用者可以在支援PHP和MySQL資料庫的伺服器上使用自己的部落格.

1.首先安裝一個MariaDB資料庫,并配置好初始密碼.

[root@localhost ~]# docker pull mariadb:latest
[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
mariadb             latest              b468922dbbd7        3 weeks ago         366MB

[root@localhost ~]# docker run --name MyDataBase --env MYSQL_ROOT_PASSWORD=example -d mariadb:latest      

2.拉取WordPress鏡像,并運作,将容器内的80口映射到主控端的8080口上.

[root@localhost ~]# docker pull wordpress:latest
[root@localhost ~]# docker run --name MyWordPress --link MyDataBase:MariaDB -p 8080:80 -d wordpress:latest      

Docker 制作鏡像

手動制作鏡像

1.拉centos:latest 鏡像為基礎鏡像

[root@localhost ~]# docker pull centos:latest      

2.啟動并進入容器内部

[root@localhost ~]# docker run -itd --name lamp --net=host centos:latest
[root@localhost ~]# docker exec -it lamp /bin/bash      

3.安裝lamp環境

yum install -y httpd httpd-devel \
               mariadb mariadb-server mysql-devel \
               php php-mysql php-common php-gd \
               php-mbstring php-mcrypt php-devel php-xml      

4.寫入一下内容.

echo "hello lyshark" > /var/www/html/index.html
echo "/usr/sbin/apachectl" >> /etc/bashrc      

5.儲存鏡像,将所退出的容器用commit指令儲存為一個新的my_ssh:centos鏡像.

[root@localhost ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS             
ebfae6bcd308        centos:latest       "/bin/bash"         2 minutes ago       Up 2 minutes      

[root@localhost ~]# docker commit ebfae6bcd308 httpd:latest
[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
httpd               latest              89cb7bb995ba        4 seconds ago       329 MB
docker.io/centos    latest              9f38484d220f        2 months ago        202 MB      

6.啟動容器,并添加端口映射10000-->22.其中10000是宿主主機的端口,22是容器的SSH服務監聽端口.

[root@localhost ~]# docker run -itd -p 8080:80 httpd:latest
[root@localhost ~]# docker run -p 10000:22 -itd my_ssh:centos      

編譯制作鏡像

1.首先我們要解決Docker容器内不得網絡問題.修改DockerDNS,預設沒有檔案自行建立即可.

[root@localhost ~]# vim /etc/default/docker
docker_OPTS="--dns 8.8.8.8 --dns 114.114.114.114"

[root@localhost ~]# systemctl restart docker      

2.接着在目前目錄建立一個Dockerfile檔案,和一個index.html檔案,檔案内容如下.

vim Dockerfile

FROM centos:latest                          // 指定基礎鏡像
USER root                                   // 以root身份運作
MAINTAINER [email protected]                  // 個人描述資訊
ENV PATH $PATH:/usr/local/nginx/sbin/       // 指定環境變量

RUN yum install -y gcc wget pcre pcre-devel zlib zlib-devel openssl openssl-devel
WORKDIR /tmp/
RUN wget http://nginx.org/download/nginx-1.15.12.tar.gz
RUN tar -xzf nginx-1.15.12.tar.gz           // 解壓檔案
WORKDIR /tmp/nginx-1.15.12                  // 切換預設目錄

RUN useradd -s /sbin/nologin -M nginx \     // 編譯安裝過程
&& ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx \
&& make \
&& make install

RUN echo "hello docker" > /usr/local/nginx/html/index.html
# COPY ./index.html /usr/local/nginx/html/      // 拷貝檔案
EXPOSE 80                                       // 内部偵聽端口
ENTRYPOINT  /usr/local/nginx/sbin/nginx && tail -f /usr/local/nginx/logs/access.log  // 鏡像入口
#CMD ["/usr/local/nginx/sbin/nginx"]            // 作用同上      

3.編譯鏡像檔案,并運作鏡像

docker build -t nginx:latest .
docker run -d -p80:80 nginx:latest      

Registry 倉庫搭建

Docker Registry工具是Docker内置的私有倉庫解決方案,新版本的Registry基于Golang進行了重構,提供更好的性能和擴充性,并且支援Docker 1.6+的API,非常适合用來建構私有的鏡像注冊伺服器.官方倉庫中也提供了Registry的鏡像,是以使用者可以通過容器運作和源碼安裝兩種方

式來使用Registry.

實驗規劃​

​Docker伺服器:192.168.1.5​

​​,​

​Docker用戶端:192.168.1.25​

​,請在服務端配置好網橋服務.

服務端配置

1.将本機配置成網橋,使之能夠互相通信.

[root@localhost ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens32
[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens32
DEVICE=eno16777728
TYPE=Ethernet
BOOTPROTO=static
BRIDGE=br0
NM_CONTROLLED=yes
ONBOOT=yes

[root@localhost ~]# vim /etc/sysconfig/network-scripts/ifcfg-br0
[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-br0
TYPE=Bridge
DEVICE=br0
BOOTPROTO=static
IPADDR=192.168.1.15
NETMASK=255.255.255.0
GATEWAY=192.168.1.1
DNS1=8.8.8.8
DNS2=114.114.114.114
ONBOOT=yes

[root@localhost ~]# reboot      

2.在服務端​

​192.168.1.5​

​上拉取registry鏡像包.

[root@localhost ~]# docker pull registry:latest
[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
registry            latest              2e2f252f3c88        3 months ago        33.3MB      

3.在服務端192.168.1.5運作docker私有倉庫成功執行,則我們的docker私有倉庫搭建成功.

[root@localhost ~]# docker run -itd -p 5000:5000 -v /registry:/var/lib/registry --restart=always --privileged=true --name my_registry registry:latest      

用戶端上傳

1.此處我們以​

​hello-world​

​為例,首先要先把它拉取下來.

[root@localhost ~]# docker pull hello-world:latest
[root@localhost ~]# docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
docker.io/hello-world   latest              4ab4c602aa5e        3 months ago        1.84 kB      

2.其次給​

​hello-world​

​鏡像打個tag表示新的版本,過程中指定伺服器IP位址.

[root@localhost ~]# docker tag hello-world 192.168.1.5:5000/hello-world:latest
[root@localhost ~]# docker images
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
192.168.1.5:5000/hello-world   latest              4ab4c602aa5e        3 months ago        1.84 kB
docker.io/hello-world          latest              4ab4c602aa5e        3 months ago        1.84 kB      

3.由于docker私有倉庫伺服器,預設是基于https傳輸的,是以我們需要在用戶端​

​192.168.1.25​

​做相關設定,禁止使用https傳輸.

[root@localhost ~]# vim /etc/docker/daemon.json
{
        "registry-mirrors": ["https://njrds9qc.mirror.aliyuncs.com"],
        "insecure-registries":["192.168.1.5:5000"]
}      

4.依次執行下面兩條指令,重新啟動docker讓其加載我們的配置檔案.

[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl restart docker
[root@localhost ~]# systemctl enable docker      

5.執行推送指令,将我們的​

​hello-world​

​推送到伺服器上.

[root@localhost ~]# docker images
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
192.168.1.5:5000/hello-world   latest              4ab4c602aa5e        3 months ago        1.84 kB
docker.io/hello-world          latest              4ab4c602aa5e        3 months ago        1.84 kB

[root@localhost ~]# docker push 192.168.1.5:5000/hello-world:latest
The push refers to a repository [192.168.1.5:5000/hello-world]
428c97da766c: Pushed
latest: digest: sha256:1a6fd470b9ce10849be79e99529a88371dff60c60aab424c077007f6979b4812 size: 524      

6.在伺服器端檢視剛剛送出的一個請求.

[root@localhost ~]# ls -l /registry/docker/registry/v2/repositories
total 0
drwxr-xr-x 5 root root 55 Dec 17 20:23 hello-world

[root@localhost ~]# curl http://192.168.1.5:5000/v2/_catalog
{"repositories":["hello-world"]}      

用戶端拉取

1.用戶端修改一下配置檔案,指定以下伺服器位址.

[root@localhost ~]# cat /etc/docker/daemon.json
{
        "registry-mirrors": ["https://njrds9qc.mirror.aliyuncs.com"],
        "insecure-registries":["192.168.1.5:5000"]
}      

2.修改Docker配置檔案,開啟區域網路模式.

在/etc/default/docker添加一行:

DOCKER_OPTS="--insecure-registry 192.168.1.5:5000"

或在/etc/sysconfig/docker檔案中添加

OPTIONS='--selinux-enabled --insecure-registry 192.168.1.5:5000'      

3.重新啟動Docker,加載配置檔案.

[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl restart docker
[root@localhost ~]# systemctl enable docker      

4.通過指令下載下傳測試鏡像.

[root@localhost ~]# docker pull 192.168.1.5:5000/hello-world:latest      

版權聲明:本部落格文章與代碼均為學習時整理的筆記,文章 [均為原創] 作品,轉載請 [添加出處] ,您添加出處是我創作的動力!

繼續閱讀