docker 入門上篇

docker 這麼火,我怎麼能不瞭解下?前端

從我聽到的關於 docker 的關鍵詞,諸如 容器go語言編寫虛擬化打包移植等等,就以爲它是一個逼格有點高的東西。並且這玩意彷佛不是給前端準備的,畢竟咱們前端只是寫寫頁面( ̄∇ ̄),這東西太複雜了。node

最後我固然仍是去學習它,並慢慢嘗試用它。你要問緣由,那就是真香。linux

本文涉及如下內容:nginx

  • Docker 用途理解
  • Docker 安裝及加速器配置
  • Docker 相關概念理解,以及學習相關命令,如鏡像命令和容器命令
  • Docker 數據卷和數據卷容器
  • Docker 安裝 nginx 實踐

理解 Docker 的用途

語言是蒼白的,但我仍是想去說些什麼。若是去搜索 docker 的定義,給出的答案就是一種容器引擎,開發者能夠打包他們的應用以及依賴包到一個可移植的鏡像中,而後發佈到任何流行的 Linux或Windows 機器上。第一次看到這個解釋時我是似懂非懂的,我把容器理解爲一個盒子,而後把代碼打包到這個盒子裏,就能夠移植到別處運行。做爲頁面仔,我也不知道理解的對不對,並且沒弄懂這麼作的具體意義,這種操做給個人感受就像是打包一個app,而後能夠下載到別人手機上用。不知道是否是隻有我這麼認爲。後來在看過不少關於 docker 的文章後,我才瞭解到 docker 的用途。git

docker 能夠解決軟件運行環境不一致所帶來的一系列問題。你是否聽過這樣一個靈魂質問:「我明明在本地運行地好好的,怎麼你線上就崩了???」github

這是由於開發環境和生產環境基本不同,代碼在哪運行,就要從新配置一套環境,這樣除了帶來時間成本外,一個大問題就是生產環境可能部署了不止一個項目,它們所依賴的環境版本不同。好比我本地用 nodejs 最新版本開發好了一個項目,想要部署到服務器,可是服務器上已經部署了一個 nodejs 項目,而且使用的是好久好久之前的一個版本,此時再直接部署新項目顯然就有很大的隱患了。雖然有其餘辦法解決,但有了 docker 後,一切變的更優雅了。redis

囉嗦了這麼多,其實 docker 的做用就是把應用代碼和所依賴的環境一塊兒打包成一個文件,運行這個文件,會生成一個虛擬容器,代碼在這個容器裏運行,就像在物理機上運行同樣,不受外界環境的影響。還有一個概念要了解一下,就是容器自己所處的環境,一般成爲「宿主機」,這能夠是一個 Linux 或 Windows 的機器。docker

總結成一句話就是:docker 是一種容器技術,主要解決代碼跨環境遷移的問題json

安裝 Docker

安裝教程實在不少,我這裏演示的是在一臺 CentOS 7.5 64位 服務器上的安裝,參考的 菜鳥教程。別的系統的安裝也能夠自行查看。ubuntu

首先安裝所需的軟件包:

sudo yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2
複製代碼

使用如下命令來設置穩定的倉庫:

sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
複製代碼

安裝最新版本的 Docker Engine-Community 和 containerd:

sudo yum install docker-ce docker-ce-cli containerd.io
複製代碼

安裝完成後輸入 docker version 驗證是否安裝成功。

配置鏡像加速器

跟 github 相似,docker也有一個鏡像存儲庫 DockerHub(關於鏡像,後面會說),因爲國內網絡緣由,咱們在拉取一些已有鏡像時會遇到困難,因此須要配置加速器。加速器有不少種,這裏推薦使用阿里雲的加速器,它是免費的,不須要購買任何東西。

登陸阿里雲後搜索關鍵詞 鏡像服務,選擇容器鏡像服務:

第一次使用時,會讓你設置登陸密碼,設置一下便可:

而後在左側菜單點擊鏡像加速器,右邊能夠看到給你提供了一個加速地址,這個地址每一個人的都不同。阿里雲很貼心地在下方給出直接運行的命令代碼,選擇你的平臺,複製粘貼全部代碼,直接運行在終端便可:

運行結束後,可使用命令 cat /etc/docker/daemon.json 查看是否設置成功,結果以下:

{
  "registry-mirrors": ["https://55zqg9lk.mirror.aliyuncs.com"]
}
複製代碼

若是你想替換別的加速地址,直接修改後面的地址便可,修改完不要忘記運行:

sudo systemctl daemon-reload
sudo systemctl restart docker
複製代碼

瞭解 Docker 的基礎概念

docker 有三個基本概念:

  • 鏡像(Image):Docker 鏡像(Image),就至關因而一個 root 文件系統。好比官方鏡像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系統的 root 文件系統。
  • 容器(Container):鏡像(Image)和容器(Container)的關係,就像是面向對象程序設計中的類和實例同樣,鏡像是靜態的定義,容器是鏡像運行時的實體。容器能夠被建立、啓動、中止、刪除、暫停等。
  • 倉庫(Repository):倉庫可看着一個代碼控制中心,用來保存鏡像。

再說一下,鏡像 其實就是打包出來的包含代碼和依賴環境的文件,咱們可使用別人製做好的鏡像,也能夠本身製做鏡像。而 容器 就是根據鏡像建立的,同一個鏡像能夠建立不少容器,就像對象的關係。

另外,Docker 使用客戶端-服務器 (C/S) 架構模式,使用遠程API來管理和建立Docker容器,能夠用一張圖來了解:

咱們先看 Hosts,它是 Docker 主機,用於執行 Docker 守護進程和容器。它分爲本地主機和遠程主機,主機下包含 daemon(守護程序)container(容器)image(鏡像)daemon是一個常駐在後臺的系統進程,當咱們安裝完成 Docker 後,它就存在。

Registries 是倉庫,Docker 有一個官方的鏡像倉庫Docker Hub,與github相似,咱們能夠獲取或上傳鏡像。咱們也能夠建立本身的私有鏡像庫。

Clients 是Docker客戶端,經過命令行與守護進程通訊。

Docker 相關命令

Docker 命令能夠分三部分來講,即服務命令鏡像命令容器命令

服務命令

服務命令指的是操做 daemon 服務的命令,操控的是 docker 進程。它主要包含5個:

  • 查看 docker 狀態:systemctl status docker
  • 啓動 docker 服務:systemctl start docker
  • 中止 docker 服務:systemctl stop docker
  • 重啓 docker 服務:systemctl restart docker
  • 開機啓動 docker 服務:systemctl enable docker

首先咱們能夠查看一下當前 docker 服務狀態,使用 systemctl status docker

綠色部分的 active (running) 就表示 docker 正在運行,咱們再來中止一次服務,並查看狀態:

如圖,inactive (dead) 就表示 docker 服務已中止。再試下重啓服務:

開機啓動命令這裏就不演示了。

鏡像命令

鏡像命令用於操做鏡像(images)相關。

查看鏡像

查看本地全部鏡像,可以使用命令:

docker images
複製代碼

能夠看到個人本地有一個 redis 的鏡像,這是由於我提早安裝了,若是沒安裝就是空的。顯示結果的第一行是表頭,分別表示爲 鏡像名稱版本號鏡像 id建立時間鏡像大小

查看全部鏡像的 id,可使用命令:

docker images -q
複製代碼

我這裏只有一個鏡像,因此只顯示了一個 id,若是有多個鏡像的話會顯示全部的鏡像 id。

搜索鏡像

有時候咱們並不知道庫裏是否有咱們須要的鏡像,這時候就須要先搜索,使用命令:

docker search 鏡像名稱
複製代碼

好比咱們來搜索 redis

如圖所示,會將全部 redis 相關源信息打印出來,第一行依舊是頭,依次表示爲:名稱描述star 數是不是官方出的自動構建

拉取鏡像

拉取鏡像即從 docker 倉庫下載鏡像到本地,使用命令:

docker pull 鏡像名稱
複製代碼

或者下載指定版本:

docker pull 鏡像名稱:版本號
複製代碼

注意,當不指定版本號時,默認下載最新版本(latest版)。另外要指定下載某個版本時,能夠去 DockerHub 查看鏡像對應的一些版本號,不要隨便自定義版本號。下載就不演示了。

刪除鏡像

刪除指定鏡像,使用命令:

docker rmi 鏡像id
複製代碼

注意這裏是要指定鏡像的 id ,而不是名稱。咱們能夠先使用 docker images 來查看鏡像的id,而後再來刪除。刪除 redis 測試:

第一步查看全部鏡像時,顯示有兩個鏡像,刪除 redis 後再查看時只有一個了,說明刪除成功。

另外,當一次刪除多個鏡像時,能夠將鏡像id依次輸入進去,這樣:

docker rmi id1 id2 id3...
複製代碼

當要刪除全部的鏡像時,可使用這樣一個組合命令:

docker rmi `docker images -q`
複製代碼

這句命令的意思很明顯,就是將 docker images -q 查詢到的全部鏡像 id 傳給刪除命令,以達到刪除全部鏡像的效果。

容器命令

容器命令用於操控容器相關,是比較重要的部分,咱們最終直接用於生產的也就是容器。

查看容器

查看本地全部正在運行中的容器,使用命令:

docker ps
複製代碼

查看本地全部的容器(無論是否運行),使用命令:

docker ps -a
複製代碼

因爲我本地暫未有容器,因此兩個命令結果都爲空。結果中的表頭含義依次爲:容器 ID使用的鏡像啓動容器時運行的命令容器的建立時間容器狀態容器的端口信息和使用的鏈接類型容器名稱

建立並啓動容器

容器是根據鏡像建立的,若是本地有鏡像,能夠直接使用,若是沒有,會自動下載鏡像,而後再建立容器。建立容器使用命令:

docker run [OPTIONS] IMAGE [COMMAND]
複製代碼

[OPTIONS] 是可選參數,IMAGE 是建立容器要根據的鏡像,[COMMAND] 是啓動容器後執行的命令,可選。

這裏說一下 OPTIONS 參數,官方提供了不少可選參數,咱們不須要一開始就去認識全部的參數,後面遇到的會再說,這裏先只列舉幾個經常使用的瞭解一下:

  • -i:以交互模式運行容器,保持容器運行狀態,一般與 -t 同時使用;
  • -t:爲容器從新分配一個僞終端,一般與 -i 同時使用;
  • -d:之後臺模式運行容器,建立一個容器在後臺運行,須要使用 docker exec 進入容器,退出後容器不會關閉;
  • --name:爲建立的容器命名(注意這裏是長參數)。

如今舉例來建立一個容器,選取鏡像 centos,使用如下命令:

docker run -it --name=c1 centos /bin/bash
複製代碼

來分析下這句命令的含義:

首先參數 -it-i -t 的合併寫法,linux 的基礎知識就很少說了,這兩個參數同時使用表示建立的是一個交互式容器,建立完成後會自動進入容器,退出容器後,容器會關閉。開始這裏可能不太明白什麼意思,日後看。

--name=c1 表示給這個容器取名爲 c1,也能夠不加等號 --name c1,另外若是不主動取名,會自動生成一個名字。

centos 是鏡像名稱,在使用一個鏡像前最好先搜索是否有這個鏡像,同時咱們也能夠指定鏡像的版本,即 centos:7

/bin/bash 是一個命令,他會在建立容器完成並進入容器時執行,非必須。

如今咱們在終端執行這句命令:

首先看圖中紅框裏,由於本地沒有 centos 這個鏡像,因此會自動在遠程倉庫拉取這個鏡像,而且由於沒指定版本,因此下載的是最新版的,以後就根據這個鏡像建立完成了容器。

建立完成後會自動進入容器裏,此時注意綠框中的命令提示符,顯然已經不是在宿主機的終端了,而是容器內部的終端(由於 -t 參數),因此此時再執行的命令只對容器內部有效。退出容器,可執行 exit 命令:

退出後能夠看到命令提示符中顯示的又是宿主機了。須要知道的是,此時退出容器後,容器是關閉了的,再次強調一下使用 -it 參數建立的容器是交互式容器,退出即關閉,不信的話能夠執行 docker ps 命令查看執行中的容器,它並不在列。

上面這種交互式容器意味着咱們不能退出,否則就關閉了,因此不少時候咱們須要另一種方式建立容器,讓它在後臺一直運行。

咱們使用另一種方式建立容器,使用命令:

docker run -id --name=c2 centos
複製代碼

這條命令,使用 -d 參數替換掉了 -t,表示建立的是一個後臺運行的容器,同時去除掉了 /bin/bash命令,由於建立後不會進入容器,不須要執行命令。須要注意的是使用的仍是同一個鏡像,同一個鏡像能夠建立不少容器。

運行結果:

能夠看到,建立完成後只返回了容器id,並無進入容器內部,命令提示符顯示仍是在宿主機終端上。但此時這個容器是在運行的,使用 docker ps 來驗證:

咱們能夠進入容器來操做它,進入容器的命令是 docker exec,咱們先執行 docker exec --help 看看它有什麼要求:

能夠看到它必需要跟上容器名和一個命令,因此咱們能夠執行:

docker exec c2 /bin/bash
複製代碼

可是這樣執行,咱們就拿不到一個能夠在容器內部執行的終端,因此還須要加上 -it 參數,以下:

docker exec -it c2 /bin/bash
複製代碼

仍是根據命令提示符,咱們已經進入到容器內部,此時一樣可使用 exit 命令退出容器,可是此時退出並不會關閉容器,始終在後臺運行,只能手動關閉(關閉容器命令後面說)。

須要注意的是, docker exec 進入容器操做不是僅針對 -id 形式建立的容器,使用 -it 形式建立的容器退出後,也是要用這個命令從新進入,而且進入以前須要手動啓動容器。

小結:此小節咱們知道建立容器有兩種方式,使用 -it 參數建立的是交互式容器,建立完自動進入容器,退出時自動關閉容器。使用 -id 參數建立的是守護式容器,即建立完運行在後臺,須要使用 docker exec 進入容器,使用 exit 退出,而且退出時不會關閉容器。

啓動/中止容器

啓動容器,使用命令:

docker start 容器ID或者容器名
複製代碼

中止容器,使用命令:

docker stop 容器ID或者容器名
複製代碼

在使用以前能夠先用 docker ps -a 來查看容器的相關信息。

刪除容器

刪除容器使用命令:

docker rm 容器ID或者容器名
複製代碼

注意不能刪除正在運行的容器,須要先關閉容器,才能刪除。

若是要一次刪除全部容器,可使用這個命令:

docker rm `docker ps -aq`
複製代碼

docker ps -aq 表示查詢全部容器的id,而後將結果傳給 docker rm,以完成刪除全部。須要注意這裏刪除全部的前提是全部的容器都處於關閉狀態。

查看某容器信息

要查看某一個容器的信息,可使用命令:

docker inspect 容器ID或者容器名
複製代碼

數據卷

數據卷是什麼?

數據卷簡單來講,就是宿主機中的一個特殊目錄,它會與容器內目錄造成映射關係。用一張圖來表示層級關係以下:

數據卷有什麼用?

有這樣一個問題是否想過,就是當容器刪除後,它產生的數據是否會銷燬?答案是確定的,由於容器是隔離運行的,數據也是產生在容器內部而不是在宿主機上,當容器被銷燬時,所產生的數據也會被銷燬。這顯然是不安全的,咱們須要對容器數據進行備份。而數據卷的做用就是用來作數據持久化的,它徹底獨立與容器的生命週期,容器刪除時也不會刪除其掛載的數據卷。

配置數據卷的方式其實就是在建立容器的同時,使用 -v 參數來配置,方式以下:

docker run ... -v 宿主機文件夾:容器內文件夾 ...
複製代碼

注意事項:

  • 文件夾路徑要是絕對路徑
  • 若是文件夾不存在,會自動建立
  • 能夠掛載多個數據卷,幾屢次使用 -v 參數

來舉個例子:

docker run -it --name=c1 -v ~/data:/root/data_container centos /bin/bash
複製代碼

建立完成後,能夠在容器的 /root 中看到 data_container 這個文件夾。同時宿主機的 ~/data 文件夾也確定存在了,它就是數據卷。

怎麼使用數據卷呢?其實當配置好了數據卷後,無論是在宿主機上的操做仍是在容器中的操做,都會自動同步。來舉個例子,咱們在容器 /root/data_container 目錄中建立一個文件 test.txt

接下來,在新窗口查看宿主機的 ~/data 目錄下是否有 test.txt 文件:

顯然,文件是被同步的。反過來在宿主機上的操做,也是同步到容器中的,這裏就很少演示了。

正是由於數據卷的這種同步功能,因此能夠用來進行兩個容器之間的間接通訊,原理無非就是兩個容器同時掛載到一個數據卷中,誰修改了,另外一個也會收到更新。

另外,你也能夠掛載多個數據卷,像這樣:

docker run -it --name=c2 -v ~/data1:/root/data1 -v ~/data2:/root/data2 centos /bin/bash
複製代碼

數據卷容器

數據卷容器首先是一個容器,它掛載數據卷,而後其餘容器經過掛載這個容器實現數據共享。一樣用一張圖表示:

數據卷容器至關於起了一個橋樑做用,它掛載數據卷,而後其餘容器間要通訊時就不須要一一再與數據卷掛載,直接掛載到數據卷容器上便可,簡化了操做。

首先咱們來建立數據卷容器 c3,(注意我每次舉例前都清空了現有容器,因此一直能用重複的名稱,容器名你們隨意~)

docker run -it --name=c3 -v /volume centos /bin/bash
複製代碼

與以前配置數據卷不一樣,這裏的 -v 參數後面只接了一個目錄,這個目錄是咱們自定義的,它是屬於容器內的。強調一下,這個目錄是屬於容器內的,不是宿主機上的。此時建立後,宿主機上會自動生成一個目錄來映射(圖中的數據卷是自動生成的,不是手動配置的)。

當運行命令後,容器內部已經生成了 volume 目錄,如今咱們回到宿主機環境,使用 docker inspect c3 命令來查看此容器的一些信息:

Mounts 數組中,「Source」 後面的就是宿主機上的數據卷,它是建立數據卷容器時自動建立的,「Destination」 表示目標地址,就是咱們建立數據卷容器的自定義的 volume 目錄。

而後咱們在建立兩個容器:

docker run -it --name=c1 --volumes-from c3 centos /bin/bash

docker run -it --name=c2 --volumes-from c3 centos /bin/bash
複製代碼

使用到了 --volumes-from 參數,使得新建立的容器能夠訪問 c3數據卷容器 的數據卷,說白了就是受權 c1,c2 能夠訪問 c3 的數據卷,實現數據共享。

當咱們按照上面建立 c1 後,會發現目錄下存在 volume 這個目錄,說明綁定 c3 成功了,建立 c2 也是同理。

那麼如今就來驗證一下數據共享。咱們在 c2 的 volume 目錄下建立一個 hello.txt 文件,而後去查看 c1,c3 以及宿主機上的目錄是否同步。

如圖所示,一切沒毛病。

使用 docker 安裝 nginx

這裏簡單演示一下使用 docker 來安裝 nginx。

拉取現有 nginx 鏡像,正常狀況下載一個鏡像前應該去先搜索,這裏略過,默認安裝最新版本:

docker pull nginx
複製代碼

根據鏡像建立 nginx 的容器:

docker run -id --name=nginx_c -p 8080:80 nginx
複製代碼

這裏又出現了一個新的參數 -p ,它的做用是端口映射,8080:80 的意思是將容器的 80 端口映射到宿主機的 8080 端口。

爲何要端口映射?這是由於外部機器是不能直接訪問到容器,可是外部機器與宿主機是能夠鏈接的,同時容器也能夠與宿主機鏈接,因此爲了在外部機器上能夠遠程訪問到容器,咱們須要把容器的服務端口映射到宿主機上。

執行命令以後,使用服務器的 ip 加 8080 端口訪問測試,以下:

能夠看到使用 docker 部署 nginx 是如此便捷。固然用於實際生產還須要一些配置,這裏先很少講了,之後慢慢來。

結尾

因爲本人也是剛剛入門 docker ,因此文中有不對的地方仍是但願各位童鞋們指出,先謝謝了。

docker 文章還會繼續出,一來是爲了加深的印象,二來我喜歡分享學會的知識,若是對你有幫助,務必要給個贊哦~

相關文章
相關標籤/搜索