天天看點

Docker入門

Docker入門

Docker指令官方示例

[toc]

1. Docker架構

1.1 Docker鏡像與Docker容器的關系

父與子的關系,用Docker鏡像來建立Docker視窗;也類似于面向對象中類(鏡像)與對象(容器)的關系。

Docker 面向對象
容器 對象
鏡像
Docker入門

image.png

名字 解釋
Docker鏡像(Images) Docker鏡像是用于建立Docker容器的模闆
Docker容器(Container) 容器是獨立運作的一個或一組應用。
Docker用戶端(Client) Docker用戶端通過指令行或者其他工具使用 Docker API 與Docker守護程序通信。
Docker主機(Host) 一個實體或者虛拟的機器用于執行Docker守護程序和容器。
Docker倉庫(Registry) Docker倉庫用來儲存鏡像,可以了解為代碼控制中的代碼倉庫。 Docker Hub 提供了龐大的鏡像集合供使用。
Docker Machine Docker Machine是一個簡化Docker安裝的指令行工具,通過一個簡單的指令行即可在相應的平台上安裝Docker,比如VirtualBox、Digital Ocean、Microsoft Azure

1.2 Docker改變了什麼?

  • 面向産品:産品傳遞
  • 面向開發:簡化環境配置
  • 面向測試:多版本測試
  • 面向運維:環境一緻性
  • 面向架構:自動化擴容(微服務)

2. 安裝Docker

安裝Docker請查另一篇部落格:

https://www.jianshu.com/p/87e7f6ada205

啟動docker

$ sudo systemctl start docker
           

3. Docker鏡像

3.1 Docker拉取鏡像加速

需要先登入DaoCloud網站

http://www.daocloud.io/mirror

Docker入門

點選立即使用,然後登入,然後選擇你的系統:

Docker入門

Linux執行如下指令。

[root@linux-host2 ~]# curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://4a1df5ef.m.daocloud.io
docker version >= 1.12
{"registry-mirrors": ["http://4a1df5ef.m.daocloud.io"]}
Success.

           

這條指令實際上是在

/etc/docker/daemon.json

檔案中加一行配置:

{"registry-mirrors": ["http://4a1df5ef.m.daocloud.io"]}
           

3.2 鏡像相關的指令

docker search <鏡像名關鍵字>      # 搜尋鏡像
docker pull <鏡像名稱>          # 拉取鏡像
docker images                   # 列出本地鏡像
docker rmi <鏡像名稱>           # 删除鏡像
           

3.3 導出/導入鏡像

# 先檢視已有的鏡像
[root@linux-host2 ~]# docker images
REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
hub.c.163.com/public/centos   7.2                 2ce04a284fa8        21 months ago       288 MB
docker.io/training/webapp     latest              6fae60ef3446        2 years ago         349 MB


# 導出鏡像
# docker save hub.c.163.com/public/centos:7.2 > centos-7.2.tar.gz


# 導入鏡像
# docker load < /root/centos-7.2.tar.gz
           

4. Docker應用

使用

docker run

指令來在容器内運作一個應用程式,輸出Hello World

[root@openstack-control2 ~]# docker run ubuntu:15.10 /bin/echo "Hello world"
           

參數解析:

  • run

    :運作一個容器;
  • ubuntu:15.10

    :指定要運作的鏡像,Docker首先從本地主機上查找鏡像是否存在,如果不存在,Docker就會從鏡像倉庫Docker Hub下載下傳公共鏡像;
  • /bin/echo "Hello World"

    :在啟動的容器裡執行的指令。

以上指令完整的意思可以解釋為:Docker 以 ubuntu15.10 鏡像建立一個新容器,然後在容器裡執行 bin/echo "Hello world",然後輸出結果。

Centos7 的Docker 鏡像位址修改

4.1 運作容器

4.1.1 運作互動式的容器
[root@openstack-control2 docker]# docker run -i -t ubuntu:15.10 /bin/bash
           
  • -i

    :允許你對容器的标準輸入(STDIN)進行互動;
  • -t

    :在新容器内指定一個僞終端或終端。
4.1.2 啟動容器(背景模式)
[root@openstack-control2 docker]# docker run -d ubuntu:15.10 /bin/sh -c "while true;do echo hello-world;sleep 1;done"
02c285ff03bbf167796be5e1b4ce7b2a835d8d795e68b4375e1ec61b892ed42b
           
  • -d

    :背景模式運作docker容器;
  • 還可以用

    --name xxx

    指定容器名稱叫xxx。
  • --rm

    ,當容器停止運作後自動删除,一般用在測試時。
  • --restart always

    : 如果加上此選項,表示這個容器會在docker程序啟動後,立即自己啟動。
那一長串字元串是容器ID,對每個容器來說是唯一的;

4.2 --entrypoint的作用

有些容器啟動後會直接在前台運作指令,導緻你進入容器後不能做其他的事情。這時你可以使用run指令下的參數

--entrypoint

,它的作用是覆寫鏡像的預設入口點,示例如下:

啟動一個以python3.6為基礎鏡像的容器:

[root@docker ~]# docker run -it --name python3.6 python:3.6
Python 3.6.5 (default, Mar 31 2018, 01:15:58) 
[GCC 4.9.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 
>>> 
>>>
           
容器啟動後,直接進入python的互動終端了,不能做其它操作,而exit後,就直接退出容器了。這裡加入

--entrypoint bash

參數,用bash覆寫它預設的入口點。
[root@docker ~]# docker run -it --entrypoint /bin/bash --name python3.6 python:3.6
root@430e3c9c09ac:/# 
root@430e3c9c09ac:/# 
           
這樣進入容器後,就是bash互動了。

4.3 列出容器

列出正在運作的容器

[root@openstack-control2 docker]# docker ps
           
注意:預設隻顯示正在運作的容器,加

-a(或 --all)

參數,可以顯示出所有容器。

**

-l

**:查詢最後一次建立的容器

列出所有容器

[root@openstack-control2 docker]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                        PORTS               NAMES
02c285ff03bb        ubuntu:15.10        "/bin/sh -c 'while..."   12 minutes ago      Exited (137) 11 minutes ago                       practical_hopper
7f1ee35531a8        ubuntu:15.10        "/bin/bash"              19 minutes ago      Exited (0) 18 minutes ago                         upbeat_wiles
           

解釋:

  • CONTAINER ID:容器ID,可以通過容器ID來操作此容器,也可以用容器名稱;
  • IMAGE:此容器是由哪個鏡像建立的;
  • COMMAND:容器中運作的指令;
  • CREATED:建立時間;
  • STATUS:容器狀态,

    Exited

    表示退出;
  • NAMES:是啟動容器時,随機為容器配置設定的一個名稱,也可以用來操作容器。

檢視所有容器的ID

$ docker ps -a -q    # 這條指令會将所有容器的ID顯示(隻顯示容器ID)
           

4.4 檢視容器内的标準輸出

[root@openstack-control2 docker]# docker logs 2b1b7a428627
           
可以用容器ID或容器名稱(用

docker ps

檢視)

4.5 停止容器

[root@openstack-control2 docker]# docker stop 7f1ee35531a8
           

4.6 殺死正在運作的容器

[root@linux-host2 ~]# docker kill 000ed90ec053
           

4.7 檢視容器對硬體資源的占用情況

[root@openstack-control2 docker]# docker stats 7f1ee35531a8
           
如果不指定容器ID或名稱,則預設顯示所有正在運作的容器的資源占用情況;加

-a(或--all)

,則顯示所有的容器;

4.8 檢視容器的程序

[root@linux-host2 ~]# docker top adoring_noether
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                9127                9115                0                   00:05               ?                   00:00:00            python app.p
           

4.9 檢視容器的配置和狀态資訊

[root@linux-host2 ~]# docker inspect adoring_noether
[
    {
        "Id": "251a6cacd10d5117025bda929ec1fb12f18b49cd2596c54d626c0c0e99491f48",
        "Created": "2018-04-13T16:05:01.028216802Z",
        "Path": "python",
        "Args": [
            "app.py"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 9127,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2018-04-13T16:05:01.186294688Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
省略...
           

可以通過

--format

參數檢視容器的指定參數

# 檢視容器的狀态
[root@linux-host2 ~]# docker inspect --format '{{.State.Status}}' mycentos-2
running

# 檢視容器的PID
[root@linux-host2 ~]# docker inspect --format '{{.State.Pid}}' mycentos-2
36897
           
點選檢視官方inspect資料擷取的方法

4.10 進入容器

方式一:

# docker attach mycentos-2   # 進入名為mycentos-2的容器
           
這種方式進入容器容易卡死,而且

exit

退出後,容器也随即停止,如果想讓容器在背景運作,可以用快捷鍵

Ctrl+p+q

方式二:

# docker exec -it 容器ID /bin/bash
           
直接

exit

退出容器而不會中斷容器運作。

方式三:

先擷取容器的PID

[root@linux-host2 ~]# docker inspect --format '{{.State.Pid}}' mycentos-2
36897
           

然後利用

nsenter

指令進入到容器中

[root@linux-host2 ~]# nsenter -t 36897 -u -i -n -p
[root@000ed90ec053 ~]#
           
這樣即使退出容器了,容器也不會停止運作。

nsenter

指令可以進入到指定PID程序的名稱空間。如果系統沒有

nsenter

指令,則需要安裝

yum install util-linux

寫成腳本,更友善:

[root@linux-host2 ~]# cat in_container.sh 
#!/bin/bash
CID=$1
PID=$(docker inspect --format "{{.State.Pid}}" $CID) 
nsenter -t $PID -u -i -n -p
           

調用:

# ./in_container.sh mycentos-2
           

4.11 檢視WEB應用程式日志

[root@linux-host2 ~]# docker logs -f 251a6cacd10
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
192.168.10.1 - - [13/Apr/2018 16:05:10] "GET / HTTP/1.1" 200 -
192.168.10.1 - - [13/Apr/2018 16:07:45] "GET / HTTP/1.1" 200 -
           

-f

:讓容器中運作的web日志像使用

tail -f

一樣來輸出容器内部的标準輸出。

4.12 移除容器

# 需要先停止容器
[root@linux-host2 ~]# docker stop adoring_noether

# 然後再删除指定的容器
[root@linux-host2 ~]# docker rm adoring_noether
           

4.13 導出容器

[root@linux-host6 ~]# docker export -o mytomcat.tar mytomcat
           
  • mytomcat.tar

    是将容器導出後儲存為mytomcat.tar檔案名;
  • mytomcat

    是容器名稱,這裡也可以寫容器ID。

5. 端口映射

5.1 用

-P

随機端口映射

# 拉取鏡像
[root@openstack-control2 docker]# docker pull training/webapp

# 運作容器
[root@openstack-control2 docker]# docker run -d -P training/webapp python app.py
80f795a76ac1ef52b8f3a47cca2ae670cdbcd6fc42d01e702fbdbd53d6a41f51
           

-d

:讓容器在背景運作;

-P

:将容器内部使用的端口映射主控端上一個随機端口。

通過

docker ps

檢視正在運作的容器:

Docker入門

多了端口資訊:

PORTS
0.0.0.0:32768->5000/tcp
           
左邊是主控端端口,右邊是容器内開啟的端口;就是做了一個端口映射;

5.2 用

-p

來指定端口映射

[root@linux-host2 ~]# docker run -d -p 8000:5000 training/webapp python app.py
5959c85fae98e363cf2d339847fd3039f0de4b107fed2b362e905f74f176e55a
[root@linux-host2 ~]# 
[root@linux-host2 ~]# 
[root@linux-host2 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
5959c85fae98        training/webapp     "python app.py"     5 seconds ago       Up 4 seconds        0.0.0.0:8000->5000/tcp   pensive_payne
           

指定IP:PORT映射

[root@linux-host2 ~]# docker run -d --name myweb -p 192.168.10.202:8000:5000 training/webapp python app.py
bf73ccb767a52a1f14a2c11a913a0d7d77263edc612380514e3ec0de489bb46f

PORTS
192.168.10.202:8000->5000/tcp
           

5.3 檢視容器端口的映射情況

[root@linux-host2 ~]# docker port 251a6cacd10d
5000/tcp -> 0.0.0.0:8000
           

6. Docker資料管理

6.1 資料卷

将主控端下的某個目錄挂載至指定的容器目錄。

如果不指定将哪個主控端目錄挂載至容器目錄,則預設會将

/var/lib/docker/vloumes/容器ID/_data

挂載至容器。

# docker run -it --name centos7.2 -v /data public/centos:7.2 /bin/bash
           

直接使用

-v /data

會将主控端的某個目錄挂載至容器的/data目錄。

這個目錄可以通過下面這條指令檢視到;

[root@linux-host2 ~]# docker inspect --format "{{(index .Mounts 0).Source}}" centos7.2
/var/lib/docker/volumes/2a97b4ef3be22d590edf90089ee9fb32cf5a5848faa15076fff8f522bcbf406d/_data
           

指定主控端目錄挂載至容器

# docker run -it --name test1 -v /opt/data/:/data:ro public/centos:7.2 /bin/bash
           

-v src:dst:ro

, src 是主機目錄,dst是容器目錄,ro是隻讀權限。

6.2 資料卷容器

資料卷容器就是專門啟動一個容器挂載一個目錄,以後其他的容器直接從資料卷容器來挂載目錄,即使資料卷容器停止了,也不影響這些容器通路挂載的目錄。使用

--volumes-from

# 先啟動一個容器test1用來提供數卷
$ docker run -it --rm --name test1 -v /data public/centos:7.2 /bin/bash


# 再啟動一個容器test2,從test1容器挂載/data目錄至test2的/data目錄。 
$ docker run -it --name test2 --volumes-from test1 public/centos:7.2 /bin/bash
           

7. 手動建構一個鏡像

我們以建構一個Nginx容器為例。

7.1 先拉取一個基礎鏡像

$ docker pull centos
           

7.2 利用基礎鏡像啟動一個容器

$ docker run -it --name mynginx public/centos /bin/bash
           

7.3 在容器内安裝nginx,并修改配置為使nginx為前台運作

$ yum -y install nginx

$ echo "daemon off;" >> /etc/nginx/nginx.conf
           

7.4 送出鏡像

$ docker commit -m "My nginx" mynginx oldboyedu/mynginx:v1  
           

commit

送出鏡像至本地倉庫,用

docker images

檢視鏡像是否生成。
  • 指令格式:

    docker commit -m "描述資訊" CID new_image

    CID

    :是将要以哪個容器生成新的鏡像的容器ID或名稱;

    new_image

    :是新鏡像的名稱及版本,(鏡像名稱與版本号用冒号

    :

    分隔。)

7.5 生成新容器

$ docker run -d --name nginx -p 81:80 -v /wwwroot:/data oldboyedu/mynginx:v1 nginx
           
最後跟着的nginx是nginx啟動指令。

8. Dockerfile建構鏡像

Dockerfile需要包含以下資訊:

  • 基礎鏡像資訊
  • 維護者資訊
  • 鏡像操作指令
  • 容器啟動時執行的指令

8.1 Dockerfile中的關鍵字指令

Dockerfile通常包含以下關鍵字指令:

  • FROM

    :它的媽媽是誰(基礎鏡像)
  • MAINTAINER

    :告訴别人,你創造了它(維護者資訊)
  • RUN

    :你想讓它幹啥(把shell指令前面加上RUN)
  • ADD

    :往它肚子裡放點檔案(copy檔案,會自動解壓)
  • WORKDIR

    :我是cd,今天化了妝(目前工作目錄)
  • VOLUME

    :給我一個存放行李的地方(目錄挂載)
  • EXPOSE

    :我要打開哪扇門(開啟的端口)
  • CMD

    :最後啟動容器要執行的指令,如:

    CMD ["apachetcl -D FOREGROUND"]

8.2 Dockerfile示例

一個建構Nginx容器的Dockerfile示例:

[root@linux-host2 data]# vim Dockerfile

# This Dockerfile is build nginx container

# 基礎鏡像
FROM public/centos:7.2

# 維護者
MAINTAINER caigy [email protected]

# 執行的操作
RUN curl http://mirrors.aliyun.com/repo/epel-7.repo -o /etc/yum.repos.d/epel.repo 
RUN yum install -y nginx

# 添加檔案至容器中
ADD index.html /usr/share/nginx/html/index.html

# 修改nginx配置檔案
RUN echo "daemon off;" >> /etc/nginx/nginx.conf

# 開啟端口
EXPOSE 80

# 啟動容器時要執行的指令
CMD ["nginx"]
           

開始建構:

$ docker build -t caigy/nginx:1.0 /opt/data/

注意:基于Dockerfile建構鏡像時,需要指定Dockerfile父目錄(上述指令中的/opt/data/),或者用

.

指代目前目錄,表示Dockerfile就在目前目錄下。
  • -t

    :為鏡像打一個标簽。

以下是建構過程中的輸出:

Sending build context to Docker daemon 6.144 kB
Step 1/8 : FROM public/centos:7.2
 ---> 2ce04a284fa8
Step 2/8 : MAINTAINER caigy [email protected]
 ---> Using cache
 ---> b7e06003d244
Step 3/8 : RUN curl http://mirrors.aliyun.com/repo/epel-7.repo -o /etc/yum.repos.d/epel.repo
 ---> Running in 31b2f1dafe05

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1084  100  1084    0     0  14137      0 --:--:-- --:--:-- --:--:-- 14263
 ---> c4b667b90187
Removing intermediate container 31b2f1dafe05
Step 4/8 : RUN yum install -y nginx
 ---> Running in 10ec5f05491e

省略部分輸出......

Step 7/8 : EXPOSE 80
 ---> Running in 027863d66b45
 ---> 8cc1cdc2c890
Removing intermediate container 027863d66b45
Step 8/8 : CMD nginx
 ---> Running in 9d62c62bd97c
 ---> 2f8bea7e3937
Removing intermediate container 9d62c62bd97c
Successfully built 2f8bea7e3937
           

檢視本地鏡像是否有剛才建構的鏡像:

[root@linux-host2 data]# docker images
REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
caigy/nginx                   1.0                 2f8bea7e3937        7 minutes ago       477 MB
           

8.3 啟動容器

利用剛剛建構的鏡像啟動一個容器:

[root@linux-host2 data]# docker run -d --name mynginx -p 8800:80 caigy/nginx:1.0 nginx
e799d2abe242657477d356378981c801d0c5b49115a7b82965148d082fdbb74f
           

檢視容器:

[root@linux-host2 data]# docker ps
CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS              PORTS                          NAMES
e799d2abe242        caigy/nginx:1.0        "nginx"                  4 seconds ago       Up 4 seconds        22/tcp, 0.0.0.0:8800->80/tcp   mynginx
           

假設主控端ip是:x.x.x.x,那麼浏覽器輸入:

http://x.x.x.x:8800

驗證容器是否啟動成功。

9. CentOS 7.x 下Docker橋接網絡配置

docker預設提供了一個隔離的内網環境,啟動時會建立一個docker0的虛拟網卡,每個容器都是連接配接到docker0網卡上的。而docker0的ip段為172.17.0.1,如果想讓容器與主控端同一網段的其他機器通路,就必須在啟動docker的時候将某個端口映射到主控端的端口。這樣如果大家會發現很麻煩,而且在企業裡面也沒這麼使用的,比較弱。

大家應該知道KVM的橋接網絡非常友善,其實docker也比較友善,至少不是自帶的橋接而已,接下來講解centos7下如何快速實作docker容器橋接網絡,并為容器配置設定外網IP。

實體機的IP:192.168.1.7 網關:192.168.1.1

  1. 停止docker服務;

    systemctl stop docker

  2. 建立橋接網卡br0;

    brctl addbr br0

    ip link set dev br0 up

  3. 為br0配置設定實體網絡中的IP位址;

    這裡可直接用主控端的IP,接下來會清空主控端的IP。

    ip addr add 192.168.1.7/24 dev br0

  4. 将主控端網卡的IP清空,并将主控端網卡挂至br0上;

    ip addr del 192.168.1.7/24 dev eth0

    brctl addif br0 eth0

    # 将主控端eth0網卡挂到br0上
  5. 删除原路由,并為br0設定路由

    ip route del default

    ip route add default via 192.168.1.1 dev br0

  6. 設定docker服務啟動參數

    vim /etc/sysconfig/docker-network

    ,其他系統可能在

    /etc/sysconfig/docker

    下。

    改成如下行即可:

    DOCKER_NETWORK_OPTIONS="-b=br0"
               
  1. 啟動docker服務

    systemctl docker start

  2. 删除docker0網卡
    $ ip link set dev docker0 down  #先關閉docker0網卡
    $ brctl delbr docker0           #再删除
               
  3. 安裝pipework

    git clone https://github.com/jpetazzo/pipework

    cp ./pipework/pipework /usr/local/bin/

  4. 啟動容器并設定網絡

    docker run -itd --net=none --name=mycentos cgy/mycentos:v1 /bin/bash

  5. 為mycentos容器設定一個與橋接實體網絡同位址段的

    ip/掩碼@網關

    pipework br0 mycentos 192.168.1.10/[email protected]

  6. 進入容器檢視IP

    docker exec -it mycentos /bin/bash

    如下圖:
    Docker入門

以上2~5步通過指令行建立的橋接網卡br0,在伺服器重新開機後就會失效,要想永久生效,就需要建立網卡配置檔案了。如下 :

  1. 建立br0的網卡配置檔案;

    vim /etc/sysconfig/network-scripts/ifcfg-br0

TYPE=Bridge
DEVICE=br0
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.1.7
GATEWAY=192.168.1.1
PREFIX=24
NM_CONTROLLED=no
DNS1=8.8.8.8
           
  1. 修改eth0網卡配置檔案:

    vim /etc/sysconfig/network-scripts/ifcfg-eth0

TYPE="Ethernet"
BOOTPROTO="static"
NAME="eth0"
UUID="5c013315-95d6-4f08-a61d-1b8340a9cb94"
DEVICE="eth0"
ONBOOT="yes"
BRIDGE=br0      # 表示橋接至br0網卡上
           
  1. 重新開機網卡

    systemctl restart network

10. Docker磁盤熱擴容

預設情況下,docker容器的空間是10G。在實際生産環境下,對docker容器進行熱擴容(動态擴容)是非常重要的一個需求。

Docker容器動态擴充的優點:

1)不需要修改docker配置,不需要重新開機docker服務;

2)可以直接對運作中的容器進行動态擴充(隻能增,無法縮);

Docker容器動态擴充的條件:

1)docker存儲引擎必須是

devicemapper

。可通過

docker info

檢視:

Storage Driver: devicemapper

10.1 操作環境

主控端系統版本:

[root@linux-host2 ~]# cat /etc/redhat-release 
CentOS Linux release 7.2.1511 (Core)
           

Docker版本:

[root@linux-host2 ~]# docker version
Client:
 Version:   18.04.0-ce
 API version:   1.37
 Go version:    go1.9.4
 Git commit:    3d479c0
 Built: Tue Apr 10 18:21:36 2018
 OS/Arch:   linux/amd64
 Experimental:  false
 Orchestrator:  swarm

Server:
 Engine:
  Version:  18.04.0-ce
  API version:  1.37 (minimum version 1.12)
  Go version:   go1.9.4
  Git commit:   3d479c0
  Built:    Tue Apr 10 18:25:25 2018
  OS/Arch:  linux/amd64
  Experimental: false
           

10.2 啟動一個容器

# 啟動容器
[root@linux-host2 ~]# docker run -itd --name mycentos cgy/mycentos:v1 /bin/bash
56b03239e57c99802bba279d20f1437621269b74eb15d8d6a712c3f56f740541

# 進入容器檢視分區大小
[root@linux-host2 ~]# docker attach mycentos
[root@ebec89c0ee40 /]# df -HT
Filesystem                                                                                        Type   Size  Used Avail Use% Mounted on
/dev/mapper/docker-253:0-67921092-b65077731c946204e67b376e591d0e6290a5c4572ee2568c275b4afbf5b32486 xfs     10G  375M   9.7G   4% /
tmpfs                                                                                             tmpfs   68M     0   68M   0% /dev
tmpfs                                                                                             tmpfs  2.0G     0  2.0G   0% /sys/fs/cgroup
/dev/mapper/docker-root                                                                           ext4    32G  462M   29G   2% /etc/hosts
shm                                                                                               tmpfs   68M     0   68M   0% /dev/shm
tmpfs                                                                                             tmpfs  2.0G     0  2.0G   0% /proc/scsi
tmpfs                                                                                             tmpfs  2.0G     0  2.0G   0% /sys/firmware
           

ctrl+p+q

退出容器而不使其中斷。

注意:容器mycentos的磁盤空間預設為10G左右,

/dev/mapper/docker-253:0-67921092-b65077731c946204e67b376e591d0e6290a5c4572ee2568c275b4afbf5b32486

就是容器mycentos的儲存設備檔案名。

接下來就開始進行容器存儲空間的動态擴容

10.3 開始容器存儲空間動态擴容

dmsetup

檢視該檔案扇區資訊.下面指令結果中的第二個數字(即20971520)是裝置的大小,表示有20971520個 512-bytes 的扇區. 這個值(

20971520*512bytes

)略高于 10GB 的大小。

[root@linux-host2 ~]# dmsetup table /dev/mapper/docker-253:0-67921092-b65077731c946204e67b376e591d0e6290a5c4572ee2568c275b4afbf5b32486
0 20971520 thin 253:2 9
           

計算20G所需扇區數目

[root@linux-host2 ~]# echo $((20*1024*1024*1024/512))
41943040
           

将新的扇區大小寫入,注意隻是改變舊表中的第二個數字20971520的數字,其他數字不變!

[root@linux-host2 ~]# echo 0 41943040 thin 253:2 9 | dmsetup load /dev/mapper/docker-253:0-67921092-b65077731c946204e67b376e591d0e6290a5c4572ee2568c275b4afbf5b32486
           

将修改後的容器存儲檔案激活

[root@linux-host2 ~]# dmsetup resume /dev/mapper/docker-253:0-67921092-b65077731c946204e67b376e591d0e6290a5c4572ee2568c275b4afbf5b32486
           

重新檢視檔案資訊

[root@linux-host2 ~]# dmsetup table /dev/mapper/docker-253:0-67921092-b65077731c946204e67b376e591d0e6290a5c4572ee2568c275b4afbf5b32486
0 41943040 thin 253:2 9
           

更改檔案系統大小,使變更生。

[root@linux-host2 ~]# xfs_growfs /dev/mapper/docker-253:0-67921092-b65077731c946204e67b376e591d0e6290a5c4572ee2568c275b4afbf5b32486
meta-data=/dev/mapper/docker-253:0-67921092-b65077731c946204e67b376e591d0e6290a5c4572ee2568c275b4afbf5b32486 isize=256    agcount=16, agsize=163824 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=0        finobt=0
data     =                       bsize=4096   blocks=2621184, imaxpct=25
         =                       sunit=16     swidth=16 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=0
log      =internal               bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=16 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
data blocks changed from 2621184 to 5242880
           
如果檔案系統是ext2、ext3、ext4格式的,則要用

resize2fs <裝置檔案>

指令,使之變更。

如果是xfs檔案系統,用

resize2fs

指令去操作則會報如下錯誤:

[root@linux-host2 ~]# resize2fs /dev/mapper/docker-253:0-67921092-b65077731c946204e67b376e591d0e6290a5c4572ee2568c275b4afbf5b32486
resize2fs 1.42.9 (28-Dec-2013)
resize2fs: Bad magic number in super-block while trying to open /dev/mapper/docker-253:0-67921092-b65077731c946204e67b376e591d0e6290a5c4572ee2568c275b4afbf5b32486
Couldn't find valid filesystem superblock.
           

再次登入mycentos容器,發現容器大小已經更新為20G左右!

[root@linux-host2 ~]# docker attach mycentos
[root@56b03239e57c /]# 
[root@56b03239e57c /]# 
[root@56b03239e57c /]# df -HT
Filesystem                                                                                         Type   Size  Used Avail Use% Mounted on
/dev/mapper/docker-253:0-67921092-b65077731c946204e67b376e591d0e6290a5c4572ee2568c275b4afbf5b32486 xfs     22G  394M   22G   2% /
tmpfs                                                                                              tmpfs   68M     0   68M   0% /dev
tmpfs                                                                                              tmpfs  2.0G     0  2.0G   0% /sys/fs/cgroup
/dev/mapper/centos-root                                                                            xfs     54G  5.2G   48G  10% /etc/hosts
shm                                                                                                tmpfs   68M     0   68M   0% /dev/shm
tmpfs                                                                                              tmpfs  2.0G     0  2.0G   0% /proc/scsi
tmpfs                                                                                              tmpfs  2.0G     0  2.0G   0% /sys/firmware
           

擴容後可能出現的問題:停止該容器後,無法重新啟動-

當容器擴容之後,由于dm認為裝置塊大小仍然為之前設定的初始大小,是以會發生無法起啟動的情況,這時隻要重新操作即可。

1)必須要先啟動一下,讓其生成dm檔案才能修改
[root@linux-host2 ~]# docker start mycentos
    //此時報錯不必理會,執行以下操作即可

[root@linux-host2 ~]# echo 0 41943040 thin 253:2 9 | dmsetup load /dev/mapper/docker-253:0-67921092-b65077731c946204e67b376e591d0e6290a5c4572ee2568c275b4afbf5b32486
[root@linux-host2 ~]# 
[root@linux-host2 ~]# dmsetup resume /dev/mapper/docker-253:0-67921092-b65077731c946204e67b376e591d0e6290a5c4572ee2568c275b4afbf5b32486
[root@linux-host2 ~]# 
[root@linux-host2 ~]# docker start mycentos
mycentos
           

為了友善後續容器動态擴容,可以采用下面的Dynamic_Modify_Docker_Disk.sh腳本(經測試可以使用)

#!/usr/bin/env bash
# This script is dynamic modify docker container disk
# Author Deng Lei
# 參數:
#       $1 : 容器名稱或容器ID
#       $2 : 擴容後的大小,預設機關是GB,隻寫數字即可


if [ -z $1 ] || [ -z $2 ]; then
    echo "Usage: container_name increase_capacity"
    echo "\tsh `basename $0` <container_name> <size>"
    echo "Example: I want increase 11G to test"
    echo "The command is:   sh `basename $0` test 11"
    exit 1
                                                                                                                                                        fi
if [ `docker inspect $1 &>>/dev/null &&  echo 0 || echo 1` -eq 1 ];then
    echo "ERROR: The container $1 is no exist!"
    exit 1
fi

# 如果$2輸入的不是純數字,例如:20G,則$?為0,可以以此判斷$2輸入的是否為純數字
echo $2 | grep [^0-9] &>/dev/null && echo "ERROR: Size is a Pure digital" && exit 1

device_name=`docker inspect -f "{{.GraphDriver.Data.DeviceName}}" $1`
device_file=/dev/mapper/$device_name

now_disk=`dmsetup table $device_file | awk '{print $2}'`
disk=$(($2*1024*1024*1024/512))
if [ $disk -lt $now_disk ];then
    echo "ERROR: I can't shink container $1 from $(($now_disk*512/1024/1024/1024))G to ${2}G!I only modify contanier increase disk!"
    exit 1
fi
dmsetup table $device_file | sed "s/0 [0-9]* thin/0 $disk thin/" | dmsetup load $device_file
dmsetup resume $device_file

# 如果是ext2|ext3|ext4 請将如下xfs_growfs指令替換成resize2fs指令
xfs_growfs $device_file &>/dev/null

if [ $? -eq 0 ];then
    echo -e "\033[1;32mDynamic expansion container $1 disk to ${2}G is success!\033[0m"
else
    echo "Dynamic expansion container $1 disk to ${2}G is failed!"
fi
           

利用上述腳本給mycenos1容器動态擴容至25G

[root@docker ~]# chmod 755 dynamic_expansion_docker_disk.sh
[root@docker ~]# ./dynamic_expansion_docker_disk.sh mycentos1 25
dynamic container mycentos1 disk to 25G is success!
           
動态擴容後,對容器進行重新開機,會發生報錯,此時再運作一次該腳本進行重新擴容(空間大小要等于或大于之前的設定,出現報錯不用管),再啟動容器即可(注意:docker容器目前是無法進行動态縮減的,僅能進行增加操作)。

延伸:

點選檢視根分區擴充容量:

LVM根分區擴容

容器硬碟熱擴容和Docker鏡像和容器存放目錄修改方法:

https://www.cnblogs.com/kevingrace/p/6667063.html

使用 Device Mapper來改變Docker 容器的大小:

https://blog.csdn.net/feiskyer/article/details/41248123

11. Docker倉庫

11.1 将本地鏡像推送到公有倉庫

先檢視一下本地的鏡像:

[root@linux-host2 ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
cgy/mycentos        v1                  32f504582f68        33 hours ago        347MB
           

将本地

cgy/mycentos:v1

這個鏡像打個标簽

[root@linux-host2 ~]# docker tag mycentos:1.0 cgy/mycentos:v1
           

因為docker預設是将鏡像推送到官方鏡像倉庫,是以你得先去hub.docker.com注冊一個賬号,然後再回來

docker login

登入,才能推送成功。

[root@linux-host2 ~]# docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: cgy0903        # 輸入使用者名
Password:                # 輸入密碼
           

推送鏡像至公共倉庫:

[root@linux-host2 ~]# docker push mycentos:1.0
           

11.2 搭建私有鏡像倉庫

  1. 先pull一下官方的registry鏡像
[root@linux-host2 ~]# docker pull registry
           
  1. 運作容器
[root@linux-host2 ~]# docker run -d -p 5000:5000 --restart always --name registry registry:latest
d8532caa38586f40769c0c0e0c30d26227329270648b6d51c9cb3df5a0443f38
           

--restart always

:表示容器會在docker程序重新開機後,立即跟着自己啟動,無須手動操作。
  1. 打标簽

    Usage: docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]

[root@linux-host2 ~]# docker tag mycentos:1.0 localhost:5000/mycentos:1.0
           
  1. 推送鏡像
[root@linux-host2 ~]# docker push localhost:5000/mycentos:1.0
The push refers to repository [localhost:5000/mycentos]
907467dd33d7: Pushed 
43e653f84b79: Pushed 
1.0: digest: sha256:57ab246be805bb5758d09cbcf874e5e4f94550428c7f365195fc254aebc9afc4 size: 741
           
速度快多了。
注意:雖然自建的私有倉庫速度快多了,但是還是感覺不好用,它沒用友好的互動界面。這就需要用到

harbor

了。

11.3 搭建harbor

harbor是VMWare開源的一個存儲和分發Docker鏡像的企業級注冊伺服器,github位址:

https://github.com/vmware/harbor

。Harbour提供更好的性能和安全性。此外,Harbor還提供進階安全功能,例如使用者管理,通路控制和活動審計。

  1. 下載下傳
$ wget https://github.com/vmware/harbor/archive/v1.4.0.tar.gz
           
  1. 解壓
[root@docker src]# tar xvf harbor-offline-installer-v1.4.0.tgz

# 進入安裝目錄下
[root@docker src]# cd harbor
           
  1. 修改配置
[root@docker harbor]# pwd
/usr/src/harbor
[root@docker harbor]# vim harbor.cfg
hostname = 192.168.1.7      # 主機名或IP,不可以是localhost或127.0.0.1
harbor_admin_password = Harbor12345     # web界面登入密碼
           
我們隻配置上述兩項即可,此外harbor.cfg中還有郵件發送、LDAP、以及資料庫相關配置,根據需要再進行配置即可。
  1. 安裝
[root@docker harbor]# ./install.sh 

[Step 0]: checking installation environment ...

Note: docker version: 18.04.0
 Need to install docker-compose(1.7.1+) by yourself first and run this script again.
           
報錯:提示需要安裝docker-compose 1.7.1以上版本。

安裝docker-compose 1.9

[root@docker harbor]# yum list | grep docker-compose
docker-compose.noarch                    1.9.0-5.el7                   epel     
[root@docker harbor]# 
[root@docker harbor]# yum install -y docker-compose
           

再次安裝

[root@docker harbor]# ./install.sh

[Step 0]: checking installation environment ...

Note: docker version: 18.04.0

Note: docker-compose version: 1.9.0

[Step 1]: loading Harbor images ...
...
...
 ----Harbor has been installed and started successfully.----

Now you should be able to visit the admin portal at http://hub.cgy.com. 
For more details, please visit https://github.com/vmware/harbor .
           

最後會提示安裝成功并成功啟動,

通路htp://192.168.1.7

Docker入門

harbor登入頁面

使用者名:admin (預設),密碼是harbor.cfg中

harbor_admin_password

配置的值。

使用很簡單,這裡就不寫教程了。

繼續閱讀