docker 這麼火,我怎麼能不瞭解下?前端
從我聽到的關於 docker 的關鍵詞,諸如 容器
、go語言編寫
、虛擬化
、打包移植
等等,就以爲它是一個逼格有點高的東西。並且這玩意彷佛不是給前端準備的,畢竟咱們前端只是寫寫頁面( ̄∇ ̄),這東西太複雜了。node
最後我固然仍是去學習它,並慢慢嘗試用它。你要問緣由,那就是真香。linux
本文涉及如下內容:nginx
語言是蒼白的,但我仍是想去說些什麼。若是去搜索 docker 的定義,給出的答案就是一種容器引擎,開發者能夠打包他們的應用以及依賴包到一個可移植的鏡像中,而後發佈到任何流行的 Linux或Windows 機器上。第一次看到這個解釋時我是似懂非懂的,我把容器理解爲一個盒子,而後把代碼打包到這個盒子裏,就能夠移植到別處運行。做爲頁面仔,我也不知道理解的對不對,並且沒弄懂這麼作的具體意義,這種操做給個人感受就像是打包一個app,而後能夠下載到別人手機上用。不知道是否是隻有我這麼認爲。後來在看過不少關於 docker 的文章後,我才瞭解到 docker 的用途。git
docker 能夠解決軟件運行環境不一致所帶來的一系列問題。你是否聽過這樣一個靈魂質問:「我明明在本地運行地好好的,怎麼你線上就崩了???」github
這是由於開發環境和生產環境基本不同,代碼在哪運行,就要從新配置一套環境,這樣除了帶來時間成本外,一個大問題就是生產環境可能部署了不止一個項目,它們所依賴的環境版本不同。好比我本地用 nodejs 最新版本開發好了一個項目,想要部署到服務器,可是服務器上已經部署了一個 nodejs 項目,而且使用的是好久好久之前的一個版本,此時再直接部署新項目顯然就有很大的隱患了。雖然有其餘辦法解決,但有了 docker 後,一切變的更優雅了。redis
囉嗦了這麼多,其實 docker 的做用就是把應用代碼和所依賴的環境一塊兒打包成一個文件,運行這個文件,會生成一個虛擬容器,代碼在這個容器裏運行,就像在物理機上運行同樣,不受外界環境的影響。還有一個概念要了解一下,就是容器自己所處的環境,一般成爲「宿主機」,這能夠是一個 Linux 或 Windows 的機器。docker
總結成一句話就是:docker 是一種容器技術,主要解決代碼跨環境遷移的問題。json
安裝教程實在不少,我這裏演示的是在一臺 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 使用客戶端-服務器 (C/S) 架構模式,使用遠程API來管理和建立Docker容器,能夠用一張圖來了解:
咱們先看 Hosts
,它是 Docker 主機,用於執行 Docker 守護進程和容器。它分爲本地主機和遠程主機,主機下包含 daemon(守護程序)
,container(容器)
和 image(鏡像)
。daemon
是一個常駐在後臺的系統進程,當咱們安裝完成 Docker 後,它就存在。
Registries
是倉庫,Docker 有一個官方的鏡像倉庫Docker Hub
,與github相似,咱們能夠獲取或上傳鏡像。咱們也能夠建立本身的私有鏡像庫。
Clients
是Docker客戶端,經過命令行與守護進程通訊。
Docker 命令能夠分三部分來講,即服務命令
,鏡像命令
和容器命令
。
服務命令指的是操做 daemon 服務的命令,操控的是 docker 進程。它主要包含5個:
systemctl status docker
systemctl start docker
systemctl stop docker
systemctl restart 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。
拉取現有 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 文章還會繼續出,一來是爲了加深的印象,二來我喜歡分享學會的知識,若是對你有幫助,務必要給個贊哦~