原文地址:github.com/rccoder/blo…前端
或許 XX 震驚部應該這樣起名:《瞭解 Docker,看完這篇就行!》node
Docker 自開源以來受到了各大公司的普遍關注,或許如今互聯網公司的運維體系不承載在 Docker(或 Pouch 等)之上都很差意思說本身的互聯網公司。git
本文會簡單介紹下 Docker 的基礎概念,入門級使用方式和一些使用 Docker 能大大提高效率的場景。github
對 Docker 最簡單而且帶有必定錯誤的認知就是 「Docker 是一種性能很是好的虛擬機」。docker
正如上面所說,這是有必定錯誤的說法。Docker 相比於傳統虛擬機的技術來講先進了很多,具體表如今 Docker 不是在宿主機上虛擬出一套硬件後再虛擬出一個操做系統,而是讓 Docker 容器裏面的進程直接運行在宿主機上(Docker 會作文件、網絡等的隔離),這樣一來 Docker 會 「體積更輕、跑的更快、同宿主機下可建立的個數更多」。shell
Docker 中有三個核心概念:Image、Container、Repository。npm
Image: 有領「好人卡」傾向的廣大程序猿必定對 鏡像 的概念不會陌生。但和 windows 的那種 iso 鏡像相比,Docker 中的鏡像是分層的,可複用的,而非簡單的一堆文件迭在一塊兒(相似於一個壓縮包的源碼和一個 git 倉庫的區別)。ubuntu
Container: 容器的存在離不開鏡像的支持,他是鏡像運行時的一個載體(相似於實例和類的關係)。依託 Docker 的虛擬化技術,給容器建立了獨立的端口、進程、文件等「空間」,Container 就是一個與宿機隔離 「容器」。容器可宿主機之間能夠進行 port、volumes、network 等的通訊。windows
Repository: Docker 的倉庫和 git 的倉庫比較類似,擁有倉庫名、tag。在本地構建完鏡像以後,便可經過倉庫進行鏡像的分發。經常使用的 Docker hub 有 https://hub.docker.com/ 、 https://cr.console.aliyun.com/ 等。安全
Docker 的安裝是很是便捷的,在 macOS、ubuntu 等下面都有一鍵式安裝工具或者腳本。更多能夠參考 Docker 官方教程。
安裝後 Terminal 中敲下 docker
,有使用說明出來的話大多狀況下說明已經安裝成功了。
DockerHub 等網站都提供了衆多鏡像,通常狀況下咱們都會從它那找個鏡像做爲基礎鏡像,而後再進行咱們的後續操做。
這裏咱們以 ubuntu 基礎鏡像爲例,配置一個 node 環境。
由於 「鏈路太長」 的緣由,國內訪問 Docker Hub 可能會比較慢,可使用國內衆多廠商提供的鏡像加速器
利用 docker pull 命令便可從相關 hub 網站上拉取鏡像到本地。同時在拉的過程當中就能看到是按照多個 「層」 去拉鏡像的。
> docker pull ubuntu:18.04
18.04: Pulling from library/ubuntu
c448d9b1e62f: Pull complete
0277fe36251d: Pull complete
6591defe1cd9: Pull complete
2c321da2a3ae: Pull complete
08d8a7c0ac3c: Pull complete
Digest: sha256:2152a8e6c0d13634c14aef08b6cc74cbc0ad10e4293e53d2118550a52f3064d1
Status: Downloaded newer image for ubuntu:18.04
複製代碼
執行 docker images 便可看到本地全部的鏡像
> docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 18.04 58c12a55082a 44 hours ago 79MB
複製代碼
docker create 命令經過鏡像去建立一個容器,同時吐出容器 id。
> docker create --name ubuntuContainer ubuntu:18.04
0da83bc6515ea1df100c32cccaddc070199b72263663437b8fe424aadccf4778
複製代碼
用 docker start 便可運行改容器。
> docker start ubuntuContainer
複製代碼
用 docker ps 便可查看運行中的 container
> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9298a27262da ubuntu:18.04 "/bin/bash" 4 minutes ago Up About a minute ubuntuContainer
複製代碼
用 docker exec 便可進入該 container。
> docker exec -it 9298
root@9298a27262da:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@9298a27262da:/# exit
複製代碼
用 docker run 能夠一步到位建立並運行一個容器,而後進入該容器。
> docker run -it --name runUbuntuContainer ubuntu:18.04 /bin/bash
root@57cdd61d4383:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@57cdd61d4383:/#
# docker ps 能夠查到已經成功運行了 runUbuntuContainer
> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
57cdd61d4383 ubuntu:18.04 "/bin/bash" 9 seconds ago Up 8 seconds runUbuntuContainer
9298a27262da ubuntu:18.04 "/bin/bash" 9 minutes ago Up 6 minutes ubuntuContainer
複製代碼
進入容器以後一切操做和普通環境一致,咱們安裝個簡單的 node 環境
> apt-get update
> apt-get install wget
> wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash
# 安裝完以後可能當前 session 讀不到 nvm 命令,能夠 exit 以後再進入中終端環境
> nvm install 8.0.0
> node -v
複製代碼
和 Ghost 裝 windows 同樣,不少時候,咱們指望能定製本身的鏡像,在裏面安裝一些基礎環境(好比上文中的 node),而後製做出本身要的基礎鏡像。這個時候 docker commit 就派上用場了。
> docker commit --author "rccoder" --message "curl+node" 9298 rccoder/myworkspace:v1
sha256:68e83119eefa0bfdc8e523ab4d16c8cf76770dbb08bad1e32af1c872735e6f71
# 經過 docker images 就能看到新制做的 rccoder/myworkspace 就躺在這裏了
>docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
rccoder/myworkspace v1 e0d73563fae8 20 seconds ago 196MB
複製代碼
接着,試一下咱們新建立的鏡像?
> docker run -it --name newWorkSpace rccoder/myworkspace:v1 /bin/bash
root@9109f6985735:/# node -v
8.0.0
複製代碼
看起來沒問題。
鏡像製做好了,怎麼共享出去讓別人使用呢?這裏以 push 到 docker hub 爲例。
第一步是先去 docker hub 註冊一個帳號,而後在終端上登陸帳號,進行 push。
> docker login
> docker push rccoder/myworkspace:v1
The push refers to repository [docker.io/rccoder/myworkspace]
c0913fec0e19: Pushing [=> ] 2.783MB/116.7MB
bb1eed35aacf: Mounted from library/ubuntu
5fc1dce434ba: Mounted from library/ubuntu
c4f90a44515b: Mounted from library/ubuntu
a792400561d8: Mounted from library/ubuntu
6a4e481d02df: Waiting
複製代碼
用 Docker 進行持續集成?相比在瞭解 Docker 以前確定聽過這個事情,那就意外着須要從某個地方拷貝代碼,而後執行(對,聽上去有點 travis-ci 的那種感受)。
是時候該 Dockerfile 出場了!
Dockerfile 是一個由一堆命令+參數構成的腳本,使用 docker build 便可執行腳本構建鏡像,自動的去作一些事(同相似於travis-ci 中的 .travis.yml
)。
Dockerfile 的格式通通爲:
# Comment
INSTRUCTION arguments
複製代碼
必須以 FROM BASE_IMAGE
開頭指定基礎鏡像。
更詳細的規範與說明請參考 Dockerfile reference。這裏咱們以基於上面的 rccoder/myworkspace:v1 做爲基礎鏡像,而後在根目錄建立 a 目錄爲例
Dockerfile 以下:
FROM rccoder/myworkspace:v1
RUN mkdir a
複製代碼
而後執行:
> docker build -t newfiledocker:v1 .
Sending build context to Docker daemon 3.584kB
Step 1/2 : FROM rccoder/myworkspace:v1
---> 68e83119eefa
Step 2/2 : RUN mkdir a
---> Running in 1127aff5fbd3
Removing intermediate container 1127aff5fbd3
---> 25a8a5418af0
Successfully built 25a8a5418af0
Successfully tagged newfiledocker:v1
# 新建基於 newfiledocker 的容器並在終端中打開,發現裏面已經有 a 文件夾了。
> docker docker run -it newfiledocker:v1 /bin/bash
root@e3bd8ca19ffc:/# ls
a bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
複製代碼
藉助 Dockerfile 的能力,Docker 留下了無限的可能。
說了這麼一堆,那實際生產環境中 Docker 能作什麼呢?經常使用的可能有下面這些(歡迎在評論中補充)
業務開發中每每須要區分開發環境與線上環境,利用 Docker 能原封不動的將開發環境中的 代碼與環境原封不動無污染的 遷移到線上環境,配合必定的自動化流程便可實現自動的發佈。
由於 node_modules
的蛋疼問題,同一個倉庫下不一樣人開發每每會遇到不一樣的人使用不一樣的 包版本 且本身根本不知道與別人不同,最終致使發佈以後產生線上問題。利用 Docker 能夠在雲端新建容器,遠程 無污染、低成本 構建代碼,實現 不一樣人用的必定是同一個版本。
某些場景下可能會配一些超級複雜的環境(好比:大一同窗配 Java 環境),這個時候能夠利用 Docker 對環境配置作封裝,直接生成鏡像,讓你們低成本使用。
相似於 travis-ci 這種
好比這個項目依賴 node6,那個項目依賴 node 8(只是舉例子,硬盤夠大的話仍是建議經過 nodeinstall 解決);同一臺服務器上跑了 100 個 wordpress 程序(能夠用 Docker 創建隔離開,防止互相污染)。
嗯,低成本安全超售(大霧)