天天看點

Docker容器技術-基礎指令

本文剖析Docker内的基本指令

一、基礎指令

1.運作一個鏡像

[root@bogon ~]# docker run debian echo "Hello World"
Unable to find image 'debian:latest' locally
latest: Pulling from library/debian
3e17c6eae66c: Pull complete 
Digest: sha256:2e43e863a4ab6e53caf87a37d01d8c144cdcb732ad1b944fcf45cbfd7248a02a
Status: Downloaded newer image for debian:latest
Hello World
           

提供一個容器中的shell

[root@bogon ~]# docker run -i -t debian /bin/bash
root@1bd73131a553:/# echo "Hello from Container-land!"
Hello from Container-land!
root@1bd73131a553:/# exit
exit
           

2.運作案例分析

1)docker pull

Docker Daemon從Docker Registry下載下傳指定的容器鏡像,并将鏡像儲存在本地Graph中。

流程分析:

A.Docker Client處理使用者發起的docker pull指令,解析完請求以及參數後,發送一個HTTP請求給Docker Server,HTTP請求方法為POST,請求URI為“/images/create?”+“xxx”;

B.Docker Server接收以上HTTP請求,并交給mux.Router,通過URL以及請求方式類型來确定執行該請求的具體handler;

C.mux.Router将請求路由分發至相應的handler;

D.在PostImageCreate這個handler中,建立并初始化一個名為“pull”的Job,之後觸發執行該Job;

E.這個Job在執行過程中執行pullRepository操作,即從Docker Registry中下載下傳相應的一個或多個Docker鏡像;

F.這個Job将下載下傳的Docker鏡像交給graphdriver管理;

G.graphdriver負責存儲Docker鏡像,一方面将鏡像存儲至本地檔案系統中,另一方面為鏡像建立對象,由Docker Daemon統一管理。

2)docker run

建立一個全新的Docker容器,并在容器中運作指定指令。

  • 建立Docker容器對象,并為容器準備所需的rootfs;
  • 建立容器的運作環境,運作使用者指令;

A.Docker Client處理使用者發起的docker run指令,解析完請求與參數之後,向Docker Server發送一個HTTP請求,HTTP請求方式為POST,請求URL為“/containers/create?”+“xxx”;(建立容器對象而非實際容器)

D.在PostContainersCreate這個handler中,建立并初始化一個名為“create”的Job,之後觸發執行該Job;

E.這個Job在執行過程中執行Container.Create操作,該操作需要擷取容器鏡像來為Docker容器準備rootfs,通過graphdriver完成;

F.graphdriver從Graph中擷取建立Docker容器rootfs所需要的所有鏡像;

G.graphdriver将rootfs的所有鏡像通過某種聯合檔案系統的方式加載至Docker容器指定的檔案目錄中;

H.若以上操作正常執行,沒有傳回錯誤或異常,則Docker Client收到Docker Server傳回狀态後,發起二次HTTP請求,URL為“/containers/”+container_ID+“/start”;(實作實體容器運作)

I.Docker Server接收以上HTTP請求,并交給mux.Router,通過URL以及請求方式類型來确定執行該請求的具體handler;

J.mux.Router将請求路由分發至相應的handler;

K.在PostContainersStart這個handler中,建立并初始化一個名為“start”的Job,之後觸發執行該Job;

L.這個Job執行需要完成一系列與Docker容器相關的資源配置工作;

M.networkdriver為指定的Docker容器配置設定網絡資源,防火牆規則

N.傳回名為“start”的Job,執行完一些輔助操作後,Job開始執行使用者指令,調用execdriver;

O.execdriver被調用,開始初始化Docker容器内部的運作環境,如命名空間、資源控制與隔離,以及使用者指令的執行,相應的操作轉交至libcontainer來完成;

P.libcontainer被調用,完成Docker容器内部的運作環境初始化,并最終執行使用者要求啟動的指令。

3.常用指令解析

1)啟動容器

[root@bogon ~]# docker run -h CONTAINER -i -t debian /bin/bash
root@CONTAINER:/# 
           

-h 設定新的主機名(hostname)

2)檢視容器

為了測試,我将容器搞壞了
root@CONTAINER:/# mv /bin /basket
root@CONTAINER:/# ls
bash: ls: command not found

現在檢視狀态
[root@bogon ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
8f64d43a4e26        debian              "/bin/bash"         2 minutes ago       Up 2 minutes                            competent_euclid

通過NAMES擷取容器資訊
[root@bogon ~]# docker inspect competent_euclid
[
    {
        "Id": "8f64d43a4e26dbe29626f82feb7aafc759fe805699f0f014aaf3b2be82790c82",
        "Created": "2017-10-23T13:47:20.594553293Z",
        "Path": "/bin/bash",
        "Args": [],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 2662,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2017-10-23T13:47:20.855942407Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
    ...省略部分

過濾相關内容
[root@bogon ~]# docker inspect competent_euclid |grep IPAddress
            "SecondaryIPAddresses": null,
            "IPAddress": "172.17.0.2",
                    "IPAddress": "172.17.0.2",
[root@bogon ~]# docker inspect --format {{ .NetworkSettings.IPAddress }} competent_euclid
Template parsing error: template: :1: unexpected unclosed action in command
<注意:括号内不要有空格>
[root@bogon ~]# docker inspect --format {{.NetworkSettings.IPAddress}} competent_euclid
172.17.0.2

容器内的改變
[root@bogon ~]# docker diff competent_euclid
A /basket   (A表示新增檔案)
A /basket/vdir
A /basket/chgrp
A /basket/fgrep
A /basket/mv
A /basket/pidof
A /basket/rbash
...省略部分
D /bin   (D表示被删除的檔案)

容器執行日志
[root@bogon ~]# docker logs competent_euclid
root@CONTAINER:/# mv /bin /basket
root@CONTAINER:/# ls
bash: ls: command not found
           

3)删除容器

檢視全部容器(包括已停止的)
[root@bogon ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS                         PORTS               NAMES
8f64d43a4e26        debian              "/bin/bash"            11 minutes ago      Exited (127) 23 seconds ago                        competent_euclid
1bd73131a553        debian              "/bin/bash"            About an hour ago   Exited (0) About an hour ago                       cranky_austin

重新啟動容器
docker start

删除容器
[root@bogon ~]# docker rm competent_euclid
competent_euclid

清理所有已停止的容器
[root@bogon ~]# docker ps -aq -f status=exited
1bd73131a553
69914367d6b4
74ef7227163a
5a1754f8433f
944c67e9d101
e0294c4a650a
[root@bogon ~]# docker rm -v $(docker ps -aq -f status=exited)
1bd73131a553
69914367d6b4
74ef7227163a
5a1754f8433f
944c67e9d101
e0294c4a650a

-v  當所有由Docker管理的資料卷已經沒有和任何容器關聯時,一律删除

[root@bogon ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS               NAMES
36c220e77949        busybox             "/bin/ping webapp"   3 hours ago         Created                                 destination
           

4)建立一個全新的容器流程

[root@bogon ~]# docker run -it --name cowsay --hostname cowsay debian bash
root@cowsay:/# apt-get update
...
root@cowsay:/# apt-get install -y cowsay fortune
root@cowsay:/# /usr/games/fortune | /usr/games/cowsay
root@cowsay:/# exit

把容器轉成鏡像
[root@bogon ~]# docker commit cowsay test/cowsayimage
[root@bogon ~]# docker run test/cowsayimage /usr/games/cowsay "Moo"
           

二、通過Dockerfile建立鏡像

1.Dockerfile

[root@bogon ~]# cat Dockerfile 
FROM debian:wheezy

RUN apt-get update && apt-get install -y cowsay fortune
           

2.鏡像、容器和聯合檔案系統之間的關系

聯合檔案系統(聯合挂載)—允許多個檔案系統疊加,并表現為一個單一的檔案系統;若有兩個檔案的路徑完全相同,則最後挂載的檔案覆寫之前的;

Docker支援多種不同的檔案系統,AUFS、Overlay、devicemapper、BTRFS、ZFS;

[root@bogon ~]# docker info
Containers: 2
 Running: 0
 Paused: 0
 Stopped: 2
Images: 12
Server Version: 17.09.0-ce
Storage Driver: overlay     <<<<<<<<
 Backing Filesystem: xfs
 Supports d_type: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
           

Docker鏡像由多個不同的層(layer)組成,每一層都是一個隻讀的檔案系統;

Dockerfile裡的每一個指令都會建立一個新的層,這個層位于前一個層之上;

當一個鏡像被轉化成容器時,Docker引擎會在鏡像之上添加一個處于最上層的可讀寫檔案系統。(盡量将指令寫在一行來較少層的數量)

容器可處于:已建立(created)、重新開機中(restarting)、運作中(running)、已暫停(paused)、已退出(exited)

3.ENTRYPOINT

指定一個可執行檔案,處理傳給docker run的參數。

[root@bogon ~]# cat Dockerfile 
FROM debian:wheezy

RUN apt-get update && apt-get install -y cowsay fortune
COPY entrypoint.sh /

ENTRYPOINT ["/entrypoint.sh"]

[root@bogon ~]# cat entrypoint.sh 
#!/bin/bash
if [ $# -eq 0 ];then
	/usr/games/fortune | /usr/games/cowsay
else
	/usr/games/cowsay "$0"
fi

[root@bogon ~]# docker build -t test/cowsay-dockerfile .
[root@bogon ~]# docker run test/cowsay-dockerfile "Moo"
           

4.上傳鏡像

[root@bogon ~]# cat Dockerfile 
FROM debian:wheezy

MAINTAINER hdlptz <[email protected]>
RUN apt-get update && apt-get install -y cowsay fortune
COPY entrypoint.sh /

ENTRYPOINT ["/entrypoint.sh"]

[root@bogon ~]# docker build -t hdlptz/cowsay:stable
[root@bogon ~]# docker push hdlptz/cowsay:stable
           

5.鏡像的命名空間

由鏡像名稱判斷:

  • 以字元串和“/”開頭,如hdlptz/revealjs,屬于使用者命名空間(user namespace)
  • 如debian或ubuntu的名稱,不包含字首或/,屬于根命名空間(root namespace)
  • 以主機名或IP開頭的名稱,代表該鏡像來自第三方的寄存服務,包括公司自己搭建的寄存服務

三、Redis鏡像執行個體

[root@bogon ~]# docker pull redis
Using default tag: latest
latest: Pulling from library/redis
d13d02fa248d: Pull complete 
a1846f364e39: Pull complete 
dba901efed8c: Pull complete 
b54b43b9d049: Pull complete 
b5b9e2d5e9c6: Pull complete 
7058d282fa00: Pull complete 
Digest: sha256:07e7b6cb753f8d06a894e22af30f94e04844461ab6cb002c688841873e5e5116
Status: Downloaded newer image for redis:latest

[root@bogon ~]# docker run -v /data test/webserver

[root@bogon ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hubuser/webapp      latest              cbe52807fcad        7 hours ago         362MB
redis               latest              1fb7b6c8c0d0        13 days ago         107MB
debian              latest              874e27b628fd        13 days ago         100MB
ubuntu              14.04               dea1945146b9        5 weeks ago         188MB
busybox             latest              54511612f1c4        5 weeks ago         1.13MB

[root@bogon ~]# docker run --name myredis -d redis
d07dd579ee128a9500b81507764edbcf81aef3281a22eee22fe04c74163c6986

[root@bogon ~]# docker run --rm -it --link myredis:redis redis /bin/bash

root@cbe4f668dba7:/data# redis-cli -h redis -p 6379
redis:6379> ping
PONG
redis:6379> set "docker" 1234
OK
redis:6379> get "docker"
"1234"
redis:6379> exit
root@cbe4f668dba7:/data# exit
exit

[root@bogon ~]# docker run --rm --volumes-from myredis -v $(pwd)/backup:/backup \
    debian cp /data/dump.rdb /backup/

[root@bogon ~]# docker stop myredis
[root@bogon ~]# docker rm -v myredis
[root@bogon ~]# docker rm $(docker ps -aq)
           

繼續閱讀