Docker 快速上手指南

如下記錄 Docker 中的經常使用操做、指令,使得你們可以快速地使用 Docker。php

爲什使用 Docker?

爲何要使用 Docker?就我的而言,Docker 能提供的最大便利在於這種技術面對程序環境遷移時所表現的卓越性。html

這種性能使得咱們沒必要在分享代碼或項目合做、交接時附帶一長串的環境配置指南進行版本限制和擴展描述;也沒必要再特地記錄本身對現有環境的配置改變,以避免下次系統遷移時手足無措;更爲重要的是,Docker 在提供以上解決方案的同時沒有把解法變得複雜,相反的,它提供了一種更快、更容易的方式。nginx

Docker 獨到的對增量和文件層的應用,使得鏡像下載、共享 & 隔離、版本控制等問題的解決方法變得格外優雅。有興趣的讀者能夠參考「按部就班學 Docker」這本書。c++

下載 & 安裝

下載

訪問下面的網址,從菜單的 Get Docker 中選擇適合的版本進行下載。web

https://www.docker.com/

安裝

Mac 和 Windows 中均可以使用桌面版傻瓜式安裝。docker

在 Centos 中,安裝步驟分爲 安裝 Docker安裝 Docker Compose。注意,Docker 的安裝受限於系統內核版本,可查看 參考連接shell

安裝完成後,能夠經過如下方式查看 Docker 版本:json

docker --version

更改鏡像源

國內訪問官方鏡像的速度較慢,能夠選用國內的鏡像源,這裏給出 DaoCloud 和阿里雲的鏡像源,鏡像源更換方法在如下網址中都有說明:ubuntu

DaoCloud: https://www.daocloud.io/mirror
AliCloud: https://cr.console.aliyun.com/#/accelerator

鏡像市場

能夠從如下網址中搜索須要的鏡像:segmentfault

// 官方:
https://store.docker.com/

// DaoCloud: 
http://hub.daocloud.io/

// AliCloud
https://dev.aliyun.com/

名詞解釋

  1. 鏡像:從鏡像市場中下載的即爲鏡像,能夠理解爲容器的模板。

  2. 容器:應用程序運行的環境,容器的建立依賴於某一鏡像。注意,容器不是鏡像的拷貝,容器只是在鏡像之上創建了一層讀寫層,用以覆蓋容器內對鏡像配置、文件的修改。採用這一方式能夠避免因頻繁的鏡像複製而致使的資源浪費。具體能夠參考相關書籍或博客。

鏡像與容器

鏡像的搜索與獲取

搜索鏡像

能夠在安裝了 Docker 的機器上使用如下指令搜索鏡像,不過仍是建議經過訪問鏡像商店的方式搜索。注意,$mirror-name 須要替換爲想要搜索的鏡像名。

docker search $mirror-name

獲取鏡像

可使用如下指令拉取鏡像到本地,其中冒號後的 $tag 爲鏡像的版本標籤,若是省略冒號及以後的內容,則爲下載最新版本即 :latest。版本標籤信息能夠在鏡像市場中查找到。

docker pull $mirror-name:$tag

注意,若下載的鏡像攜帶有版本標籤,則以後對這一鏡像的使用都須要攜帶版本標籤,不然會由於版本不一樣而再次下載。

鏡像的查看與刪除

查看鏡像

查看全部鏡像可使用:

docker images

也可經過如下方式查看單個鏡像:

docker images $mirror-name

刪除鏡像

咱們能夠經過如下方式刪除鏡像,但此時須要保證沒有容器使用這一鏡像:

docker rmi $mirror-name

查看容器

查看已啓動的容器

docker ps

查看所有容器

docker ps -a

查看容器日誌

採用如下方法能夠查看容器的操做歷史和輸出:

docker logs $container-name

啓動容器

生成容器

能夠經過如下方式生成一個基於某一鏡像的容器,注意,若是宿主機中沒有該鏡像則會先進行下載。務必注意鏡像標籤是否正確。

docker run $mirror-name:$tag

使用這一命令會使得容器在建立後自動啓動。

給容器添加自定義名字

經過 docker ps -a 能夠看到容器的 ID 和 name,這二者均可以做爲後續對容器刪除、啓動、關閉及設置等操做的標識。使用 ID 時,只需輸入 ID 的前幾位便可(能與其餘容器區分)。

Docker 會爲其隨機生成 64 位長度的字符串做爲 ID,固然,咱們也能夠經過以下方式手動指定容器的名字,其中 $container-name 即爲指定的容器名。

docker run --name $container-name $mirror-name

啓動容器

docker start $container-name

關閉容器

docker stop $container-name

以交互方式建立容器

能夠經過如下方式,以交互的方式建立容器,固然也能夠在 $mirror-name 的前面加上 --name xxx 來指定容器的名字,在交互模式中,能夠輸入 exit 退出:

docker run -it $mirror-name

之後臺運行方式建立容器

咱們可使用 -d 操做使容器在後臺運行:

docker run -d $mirror-name

容器狀態問題

容器在啓動後,若是沒有活動的前臺進程,容器會自動關閉。若要保持容器啓動狀態,能夠強制其執行一個前臺進程。具體可查看 參考連接 I參考連接 II

能夠用如下方式建立一個不自動關閉的 centos 鏡像:

docker run -it --name mycentos centos
docker start mycentos

// 此時能夠看到該容器沒有自動關閉
docker ps

容器執行操做

咱們能夠經過如下方式對已經啓動的容器執行一些操做,其中 $container-name 能夠是容器的名字,也能夠是容器的 ID:

docker exec $container-name echo "hello" && echo "world"

也能夠經過如下方式進入交互模式:

docekr exec -it $container-name bash

其中,&& 是起到操做間鏈接的做用,詳細能夠查看 參考連接。此外,咱們也能夠在建立的容器的時候就使其執行一些操做:

docker run $mirror-name echo "hello world"

查看容器詳情

經過如下方式能夠查看容器的詳細信息,這些信息是採用 JSON 的格式展示的:

docker inspect $container-name

刪除容器

能夠在 rm 以後加入一個或多個容器名或容器 ID 進行批量刪除。

docker rm $container-name-1 $container-name-2 ...

可使用如下方法刪除所有容器:

docker rm $(docker ps -aq)

Docker 網絡

網絡類別

查看網絡類別

網絡的類別爲 nonehostbridge 三種,能夠經過如下方式查看:

docker network ls

none 型網絡

顧名思義,此類網絡表示容器爲獨立個體,不與外部通訊。

host 型網絡

此類網絡表示該容器與宿主機(安裝 Docker 的機器)共享網絡。

bridge 型網絡

這是容器的默認網絡類型,網橋模式意味着容器間能夠互相通訊,而對外的通訊須要藉助宿主機,這一形式一般表現爲端口號的映射。

查看網絡類別詳情

docker network inspect $network-name

經過這種方式能夠查看 JSON 格式的網絡類別,在 Containers 條目中能夠看到使用當前網絡類型的容器列表,注意 Containers 中只會顯示那些已經啓動的容器。

建立網絡

能夠經過如下方式建立一個網絡,其中,$network-driver 表示網絡類別,即 nonebridgehost,而 $network-name 爲自定義的網絡名:

docker network create --driver $network-driver $network-name

若是省略 --driver $network-driver 則默認建立 bridge 類型的網絡。

爲容器指定網絡

咱們能夠建立自定義的網絡環境,並將一些容器放入這一網絡內,以此管理容器間的網絡連通狀況。這種局域網網段的模擬實際是由內部 DNS 實現的。如下羅列將容器添加或移除到某一網絡中的方法。

將容器添加進某一網絡

能夠經過如下方式將容器 $container-name 加入 $network-name 網絡中。注意,一個容器能夠屬於多個網絡。

docker network connect $network-name $container-name

以後,當容器啓動時,咱們就能夠在 docker network inspect $network-nameContainers 中看到這一容器了。

將容器從某一網絡中移除

docker network disconnect $network-name $container-name

在容器生成時指定網絡

咱們也能夠在容器生成時指定網絡,使用以下方法:

docker run --network $network-name $mirror-name

測試網絡連通狀況

咱們能夠經過如下方式查詢到容器的 IP 地址:

  1. 在容器交互模式中使用 ip addr

  2. 使用 docker inspect $container-name

  3. 使用 docker inspect $container-name | grep IPAddress

以後可使用 ping 指令測試容期間的網絡連通狀況。沒有 ping 命令的容器須要安裝 iputils

刪除網絡

docker network rm $network-name

Docker 存儲

有時,咱們須要將容器的部分存儲映射到宿主機器件中,以便對配置文件、日誌文件、數據文件等進行備份或統一管理。

指定數據卷

咱們能夠在建立時,將系統的某一目錄指定爲容器某一目錄的數據卷,其中 --volume 可使用 -v 縮寫:

docker run --volume /my/mac/dir:/container/dir $mirror-name

此時,容器內部的 /container/dir 將與宿主機的 /my/mac/dir 造成映射。

固然,咱們也能夠將文件與文件映射起來。

docker run --volume /my/mac/file:/container/file $mirror-name

在指定數據卷時,能夠省略宿主主機目錄,此時 Docker 會自動指定一個主機空間用以映射:

docker run --volume /container/dir $mirror-name

此外,還能夠選擇只讀方式,這樣文件或目錄的修改就只能在宿主機中進行了。只需添加 :ro 便可:

docker run --volume /my/mac/dir:/container/dir:ro $mirror-name

咱們能夠經過 docker inspect $container-name,並在 Mounts 中看到數據卷的詳細狀況。

查看數據卷

咱們能夠經過如下指令查看數據卷的狀況:

docker volume ls

當容器被刪除時,主機上的數據卷並不會被刪除,此時能夠經過如下指令查看那些沒有容器使用的數據卷,注意,這裏只會顯示那些由 Docker 自動指定的數據卷,即沒有手動指定主機映射目錄的數據卷:

docker volume ls -f dangling=true

順便,若是須要在刪除容器時一併刪除數據卷,可使用如下指令:

docker rm -v $container-name

數據卷的繼承

有時咱們可能須要在建立容器時,選擇該容器的數據卷與以前的某容器相同,好比在面對多容器共享項目目錄空間這一需求時。此時咱們能夠經過如下方式實現:

docker run --volumes-from $container-name $mirror-name

數據卷的刪除

可使用以下方式刪除數據卷,其中 $volume-id 能夠經過 docker volume ls 查看:

docker volume rm $volume-id

給已建立時的容器添加數據卷

容器一旦建立後,再添加數據卷映射會比較麻煩,能夠查看 參考連接

並且,這裏並不建議這麼作,建議的作法是將容器提交爲鏡像後,以此鏡像再次建立容器。

Docker 端口

綁定端口

咱們能夠將容器的端口綁定到主機的某一端口上,已完成某些應用的需求,如將主機的 12345 端口綁定到容器的 80 端口上,這樣咱們對 localhost:12345 的訪問就至關於對容器 80 端口的訪問。

經過如下方式能夠實現端口綁定,其中 $host-port 爲宿主主機的端口,而 $container-port 爲容器的端口,如 12345:80

docker run -p $host-port:$container-port nginx

咱們也能夠只指定容器的端口號,此時 Docker 會自動分配一個主機上的端口號。

docker run -p $container-port nginx

對於 Nginx,官方鏡像在製做時指定暴露 80443 端口用於 httphttps 請求,對於這種在鏡像中暴露的端口,能夠在建立時使用如下方式所有指定:

docker run -P nginx

此時,Docker 會自動分配主機上的兩個端口分別映射容器的 80443 端口。自動分配的數量與鏡像中暴露的端口數量對應。

查看端口

咱們能夠在 docker ps -a 中的 PORTS 欄看到端口映射狀況。注意只有處於運行中的容器纔會有實際的端口映射。

此外,咱們還可使用如下指令查看某一容器的端口映射:

docker port $container-name

docker-compose

建立一個容器時,可能須要對多項參數進行限制,好比指定網絡、指定數據卷、指定端口等等。並且,有時咱們可能須要同時使用多個容器共同支撐應用,好比 Nginx 容器、php & php-fpm 容器、MySQL 容器、Redis 容器等。

若是每次都使用各類參數,按某種順序依次啓動容器(容器之間可能存在前後順序,好比要先啓動 PHP 而後再啓動 Nginx 容器)的話,會形成不少繁瑣的操做。爲了解決這個問題,咱們可使用 docker-compose。

執行如下指令查看 docker-compose 能夠執行的指令:

docker-compose --help

YAML

docker-compose 依賴一個 docker-compose.yml 文件,用以指定容器數據卷、網絡等。

.yml 文件遵循 YAML 語法,這是一種使用縮進的語法。詳細可見 YAML 語言教程

樣例

下面給出一個簡單的樣例,用以說明 docker-compose 的用法

version: '2.0'
services: 
  # 啓用一個鏡像爲 nginx 的容器並命名爲 web1
  web1:
    image: nginx
    # 開啓 80 和 443 端口,實際映射端口由 Docker 指定
    ports:
      - "80"
      - "443"
    # 將該容器加入 mynetwork 中
    networks:
      - "mynetwork"
    # 指定該容器要在 web2 容器啓動以後啓動,且在其中止前中止
    depends_on:
      - web2
  web2:
    image: nginx
    ports:
      - "33333:80"
    networks:
      - "mynetwork"
      - "bridge"
    volumes:
      - "/mnt"
networks:
  # 建立一個驅動爲 bridge 的網絡,命名爲 mynetwork
  mynetwork:
    driver: bridge

其中,容器的實際名字爲 .yml 文件所在目錄名_.yml 文件中指定的名字_序號,如 mydir_web1_1。可是,在容器內部,可使用 mydir_web1_1 也可使用 web1 做爲域名訪問另外一主機,這對於以後多容器共同支撐 web 服務是相當重要的。

更多的 .yml 文件的寫法能夠參考 [YAML 模板文件][9]

docker-compose 的使用

生成容器

首先,咱們須要有一個名爲 docker-compose.ymldocker-compose.yaml 的文件,並進入該文件所在目錄下,經過如下命令生成並啓動:

docker-compose up

Docker 會根據 docker-compose.yml 中的內容建立網絡、數據卷和容器。

固然也能夠加入參數 -d 使其生成後在後臺運行:

docker-compose up -d

中止

中止容器可使用:

docker-compose stop

運行

再次運行容器可使用

docker-compose start

查看日誌

docker-compose logs

刪除

經過如下命令能夠刪除容器,但不會刪除以前建立的網絡

docker-compose rm

若想既刪除容器,又刪除網絡,可使用:

docker-compose down

注意,數據卷的刪除仍要使用以前刪除數據卷的方法。

生成 & 提交鏡像

生成鏡像

咱們對使用某一鏡像的容器作了修改,好比在使用 centos 這一鏡像建立的容器中安裝了 nginx,此時咱們能夠將這一容器生成爲一個新的鏡像,這以後就能夠經過這個新鏡像建立其餘容器,而這些容器也一樣已經安裝了 nginx。

生成鏡像可使用以下方式:

docker commit -m $commit-msg -a $author $container-id $namespace/$mirror-name:$tag

如:

docker commit -m 'install nginx' -a 'dailybird' abcd1234 dailybird/nginx:test

以後即可以經過 docker images 查看已經建立的鏡像了。

提交鏡像

咱們能夠將鏡像提交到官方倉庫中,這樣就能夠像最初獲取鏡像的方式同樣得到本身製做的鏡像了。

首先,咱們須要在 Docker Hub 上註冊帳戶:

https://hub.docker.com/

而後使用如下命令登陸:

docker login

以後會提示輸入用戶名和密碼,顯示登陸成功後,用如下方式推送:

docker push $namespace/$mirror-name:$tag

因爲國內訪問 Docker Hub 的速度較慢,咱們也可使用 DaoCloud 或阿里雲的 Docker 服務,具體的推送方法能夠訪問以前給出的網址,參照其中的方法便可。

Dockerfile

使用已有容器建立鏡像的方式當然可行,可當咱們須要再次對鏡像修改時,就須要再次生成容器、進行配置修改或軟件安裝、提交鏡像。此外,不斷在原有提交鏡像的基礎上修改提交會存在兩個問題:

  1. 累積的修改條目不夠直觀,可能以後本身也不知道對原有鏡像作了什麼修改;

  2. 不斷修改的過程在 Docker 看來是增量更新的過程。這一次的修改至關於在上一次的基礎上增長了一個只讀層用於記錄本次的修改狀況。而只讀層的數量是有限的,也就意味着這種修改和提交的方式的操做次數是受限的。

那麼,有沒有一種更好的方式能夠實現鏡像的生成呢?類比 docker-compose.yml,咱們可使用另外一種相似配置文件的方式來指導鏡像的生成,這就是 Dockerfile

Dockerfile 能夠指定新鏡像的原鏡像來源、對原鏡像的操做、環境變量,以及以此建立容器時執行的指令等。

樣例

# 新鏡像基於的原鏡像
FROM centos:centos6.8

# 指明維護者
MAINTAINER dailybird <dailybird@mail.com>

# 設置一些環境變量,使用 \ 表示鏈接多個設置
ENV NGINX_VERSION 1.11.11 \
    TEST_ENV hello

# 指定暴露的端口號,
EXPOSE 80 443

# 在原鏡像基礎上進行的修改
RUN yum install -y wget iputils \
    && wget http://nginx.org/download/nginx-1.11.11.tar.gz

# 以此鏡像建立並啓動時,容器執行的指令,一般用於啓動服務
CMD ["echo", "hello world"]

好比使用如下配置能夠在 centos 中安裝 nginx

FROM centos:centos6.8

MAINTAINER dailybird <dailybird@mail.com>

EXPOSE 80 443

RUN cd / \
    && mkdir data \
    && cd data \
    && mkdir nmp \
    && cd nmp \
    && yum install -y wget pcre-devel gcc gcc-c++ \
       ncurses-devel perl make zlib zlib-devel \
       openssl openssl--devel iputils \
    && wget http://nginx.org/download/nginx-1.11.11.tar.gz \
    && tar zxf nginx-1.11.11.tar.gz \
    && cd nginx-1.11.11 \
    && ./configure --prefix=/usr/local/nginx \
    && make && make install && make clean \

更多的 Dockerfile 指令能夠參考 Dockerfile 指令

Dockerfile 的使用

使用 Dockerfile 建立鏡像

首先,咱們須要新建一個名爲 Dockerfile 的文件(沒有後綴),並寫入一些配置內容。而後在該文件的目錄中,經過如下指令建立鏡像:

docker build --tag $namespace/$mirror-name:$tag $dockerfile-dir

其中,$dockerfile-dirDockerfile 所在目錄,好比執行:

docker build --tag dailybird/nginx-demo:demo ./

等待一段時間以後,即可經過 docker images 看到新建立的鏡像了。

docker-compose 中使用 Dockerfile

當咱們須要啓動一個新鏡像時,能夠先將此鏡像建立出來,而後在 docker-compose.yml 文件中經過 image 指定新鏡像;也能夠直接經過如下方式將這兩個步驟合併:

version: '2.0'
services: 
  web1:
    # build 後的參數爲 Dockerfile 文件所在的目錄位置,替換原先的 image
    build: ./
    ports:
      - "80"
    networks:
      - "mynetwork"
      
# ...
# 其餘配置

此後,能夠經過如下指令建立容器:

docker-compose build
docker-compose up

或者,直接執行:

docker-compose up --build

這時,Docker 會自動建立一個鏡像,並以此建立容器。

後記

關於 Docker 還有不少內容,好比備份、集羣、插件等。不過這些就留到進一步研究以後再撰文吧。

問題備忘

權限問題

有時可能遇到以下 Docker 報錯:

WARNING: Error loading config file:/home/user/.docker/config.json - stat /home/user/.docker/config.json: permission denied

此時,能夠經過如下方法解決:

sudo chmod -R g+rwx /your/path/to/.docker/

參考

  1. Docker 中文社區站

  2. 阿里雲ECS部署Docker服務 - CSDN

  3. 爲何docker容器啓動不了? - Segmentfault

  4. Docker爲何剛運行就退出了? - CSDN

  5. &&,&,:的區別

  6. 給一個正在運行的Docker容器動態添加Volume

  7. YAML 語言教程 - 阮一峯

  8. YAML 模版文件 - 極客學院

  9. Docker:尋找一些docker-compose.yml文件的示例 - segmentfault

  10. Docker Compose—簡化複雜容器應用的利器 - 推酷

  11. 一些 Docker 的技巧與祕訣 - segmentfault

  12. Dockerfile 指令 - 極客學院

  13. Docker permission denied - askubuntu

  14. DOCKER 教程 - 寧皓網

  15. CenOS Linux安裝nginx - 博客園

  16. docker-compose.yml 語法說明

  17. Docker學習筆記(2)--Docker經常使用命令 - CSDN

  18. Dockerfile文件格式的簡單介紹 - 博客園

相關文章
相關標籤/搜索