后端系統會部署很多服務,包括我們自己開發的服務,還有 mysql、redis 等中間件的服務,部署它們需要一系列依賴的安裝、環境變量的設置等等。
如果你要部署多臺機器的話,同樣的操作要重復多次,萬一哪一步漏掉了,服務就跑不起來了。
就很麻煩。
而 Docker 就能完美解決這個問題:
它把系統的所有文件封裝成一個鏡像,鏡像跑起來作為容器,它可以在一臺機器上跑多個容器,每個容器都有獨立的操作系統環境,比如文件系統、網絡端口等,在容器內跑各種服務。
這樣整個環境都保存在這個鏡像里,部署多個實例只要通過這個鏡像跑多個容器就行。
這也是為什么它的 logo 是這樣的:
Docker 提供了 Docker Hub 鏡像倉庫,可以把本地鏡像 push 到倉庫或者從倉庫 pull 鏡像到本地。
我們 pull 個鏡像下來試試看:
首先需要安裝 Docker,直接從官網下載 docker desktop 就行:
它內置了 docker 命令。
把它安裝到系統之后,可以在命令行看下 docker 命令是否可用:
如果不可用,那要設置下這個:
點擊 Settings > Advanced,里面有兩種安裝路徑,如果是 /user/local/bin,那 docker 命令就是直接可用的,因為這個路徑在 PATH 變量里。
如果是第二種,那就需要手動把 $HOME/.docker/bin 加到 PATH 環境變量里。
然后我們來看看 docker desktop 的界面:
images 是本地的所有鏡像,containers 是鏡像跑起來的容器。
docker desktop 可以可視化的管理它們,很方便。
我們 pull 一個鏡像試試看。
搜索 nginx 鏡像,點擊 pull(搜索這步需要科學上網,不然搜不到)。
pull 下來之后,就可以在本地 images 看到了:
點擊 run 會讓你填一些參數:
首先是名字,如果不填,docker desktop 會給你生成隨機的容器名字。
就是這種:
然后是端口,容器內跑的 nginx 服務是在 80 端口,你要把宿主機的某個端口映射到容器的 80 端口才可以訪問。
接下來是數據卷 volume,這個是把宿主機某個目錄掛到容器內。
因為容器是鏡像跑起來的,下次再用這個鏡像跑的還是同樣的容器,那你在容器內保存的數據就會消失。
所以我們都是把某個宿主機目錄,掛載到容器內的某個保存數據的目錄,這樣數據是保存在宿主機的,下次再用鏡像跑一個新容器,只要把這個目錄掛載上去就行。
至于環境變量,這個就很容易理解了。
我們分別設置一下:
掛載本地的 /tmp/aaa 到容器內的 /user/share/nginx/html 目錄。
點擊 run:
可以看到容器內的 nginx 服務跑起來了。
我們在 /tmp/aaa 目錄下添加一個 index.html:
瀏覽器訪問 http://localhost 就可以訪問到:
這就說明數據卷掛載成功了。
點擊 files 標簽就可以看到容器內的文件。
可以看到 /usr/share/nginx/html 被標識為 mounted,就是掛載目錄的意思:
我們再在本地添加一個文件:
你會發現容器內這個目錄內容也變了:
這就是 volume 掛載的作用。
如果你掛載某些目錄報錯,是因為 docker desktop 掛載的目錄是需要配置的,在 Settings > Resources > File Sharing 里加一下就行:
至于掛載到的目錄,在鏡像搜索結果頁有寫:
通過命令行 docker run 來跑鏡像, -v 是指定掛載的數據卷,后面的 :ro 代表 readonly,也就是容器內這個目錄只讀,:rw 表示容器內可以讀寫這個目錄。
這就是數據卷的作用。
此外,你還可以進入到容器內執行各種命令:
是不是感覺 docker 學起來還挺簡單的?
docker 常用的就是這些東西。
當然,在服務器上沒有 Docker Desktop 這種東西,還是要敲命令的。
比如我們點擊 pull 按鈕,就相當于執行了 docker pull:
dockerpullnginx:latest
latest 是標簽,也就是這個:
然后我們點擊 run 按鈕,填了個表單,就相當于執行了 docker run:
dockerrun--namenginx-test2-p80:80-v/tmp/aaa:/usr/share/nginx/html-eKEY1=VALUE1-dnginx:latest
-p 是端口映射
-v 是指定數據卷掛載目錄
-e 是指定環境變量
-d 是后臺運行
對照下前面可視化界面,是不是瞬間就懂了:
docker run 會返回一個容器的 hash:
就是這里的 id:
這個界面可以用 docker ps 來獲取:
它是顯示容器列表的,默認是運行中的。
想顯示全部的,可以加個 -a
除了 container 列表,image 鏡像列表也可以通過 docker images 命令獲取:
我們在容器的 terminal 里執行命令,對應的是 docker exec 命令:
-i 是 terminal 交互的方式運行
-t 是 tty 終端類型
然后指定容器 id 和 shell 類型,就可以交互的方式在容器內執行命令了。
查看日志,對應 docker logs 命令:
輸入 exit 退出:
docker inspect 可以查看容器的詳情
對應 desktop 里的 inspect 的 tab:
docker volume 可以管理數據卷:
對應 desktop 的這部分:
此外,還有這些常用命令:
docker start:啟動一個已經停止的容器
docker rm:刪除一個容器
docker stop:停止一個容器
都可以通過 docker desktop 很方便的操作。
那如果我們要自己制作一個這樣的鏡像,怎么做呢?
docker 容器內就是一個獨立的系統環境,想想如果在這樣一個系統上,要安裝 nginx 服務,怎么做呢?
需要執行一些命令、復制一些文件進來,然后啟動服務。
制作鏡像自然也要進行這樣的過程,不過可以自動化。
只要在 dockerfile 里聲明要做哪些事情,docker build 的時候就會根據這個 dockerfile 來自動化構建出一個鏡像來。
比如這樣:
FROMnode:latest WORKDIR/app COPY.. RUNnpminstall-ghttp-server EXPOSE8080 CMD["http-server","-p","8080"]
這些指令的含義如下:
FROM:基于一個基礎鏡像來修改
WORKDIR:指定當前工作目錄
COPY:把容器外的內容復制到容器內
EXPOSE:聲明當前容器要訪問的網絡端口,比如這里起服務會用到 8080
RUN:在容器內執行命令
CMD:容器啟動的時候執行的命令
我們先通過 FROM 繼承了 node 基礎鏡像,里面就有 npm、node 這些命令了。
通過 WORKDIR 指定當前目錄。
然后通過 COPY 把 Dockerfile 同級目錄下的內容復制到容器內,這里的 . 也就是 /app 目錄
之后通過 RUN 執行 npm install,全局安裝 http-server
通過 EXPOSE 指定要暴露的端口
CMD 指定容器跑起來之后執行的命令,這里就是執行 http-server 把服務跑起來。
把這個文件保存為 Dockerfile,然后在同級添加一個 index.html
然后通過 docker build 就可以根據這個 dockerfile 來生成鏡像。
dockerbuild-taaa:ccc.
aaa 是鏡像名,ccc 是鏡像的標簽
FROM 是繼承一個基礎鏡像,看輸出也可以看出來,前面都是 node 鏡像的內容,會一層層下載下來。
最后才是本地的我們添加的那些。
這時你在 desktop 的 images 列表里就可以看到這個鏡像了:
然后執行 docker run 把這個鏡像跑起來,用 desktop 我們就直接點擊 run 按鈕了:
會讓你輸入這些內容:
是不是前面用 nginx 鏡像的感覺回來了?這次是我們自己 build 的鏡像。
指定容器名、映射的端口、點擊 run:
然后可以看到容器內的日志,服務啟動成功了:
當然,容器內打印的是 8080 端口,但在容器外要用映射的 8888 端口訪問:
訪問 http://localhost:8888 就可以看到我們在 html 寫的內容了:
在容器內頁打印了一條訪問日志:
至此,我們寫的第一個 dockerfile 和 build 出的第一個鏡像就跑成功了!
我們在 files 里看看 /app 下是啥內容:
雙擊 index.html,可以看到這就是我們 build 鏡像的時候 COPY 進去的文件。
但是我們想修改靜態文件怎么辦呢?
進入容器內改太麻煩,不如把這個 /app 目錄設置為掛載點吧。
這樣改下 Dockerfile:
然后重新 build 出一個鏡像來:
docker build -t aaa:ddd -f 2.Dockerfile
因為現在不是默認的 Dockerfile 了,需要用 -f 指定下 dockefile 的文件名。
構建完之后再 run 一下這個新鏡像:
這次把桌面目錄作為數據卷掛載到 /app 目錄了:
容器跑起來后可以看到確實掛載上去了,也標識為了 mount:
瀏覽器訪問下:
在 inspect 這里也可以看到掛載的目錄:
有同學說,就算不在 dockerfile 里指定 VOLUME,還是可以 docker run 的時候通過 -v 掛載數據卷呀。
那為啥還要指定 VOLUME?
在 dockerfile 里指定 VOLUME 之后,如果你 docker run 的時候沒有帶 -v,那會放在一個臨時的目錄里。
比如直接點擊 run,不設置參數:
docker 會隨機給他生成一個名字。
還會隨機生成一個目錄作為數據卷掛載上去:
inspect 可以看到這時候的路徑是一個臨時的目錄:
這樣就算你刪了容器,數據也可以在這里找回。
設想下,如果你跑了個 mysql 容器,存了很多數據,但是跑容器的時候沒指定數據卷。有一天,你把容器刪了,所有數據都沒了,可不可怕?
為了避免這種情況,mysql 的 dockerfile 里是必須聲明 volume 的,這樣就算你沒通過 -v 指定數據卷,將來也可以找回數據。
在鏡像詳情可以看到 mysql 的 dockerfile,確實聲明了 volume
這樣就能保證數據不丟失。
總結
Docker 可以把環境封裝成鏡像,鏡像跑起來是一個獨立的容器。通過這種方式可以快速部署多個相同的實例。
docker 提供了一個 desktop 工具,可以可視化的操作 docker,包括容器、鏡像、volume 等
我們 pull 了一個 nginx 鏡像下來,指定端口映射、掛載的數據卷,并把它跑起來了。
這就是 docker 的基本用法。
當然,這些可視化的操作都有對應的命令,當服務器上沒有桌面的時候,就需要用命令行操作了。
docker 鏡像是通過 dockerfile 構建出來的。
我們寫了第一個 dockerfile,通過 FROM、WORKDIR、COPY、RUN、EXPOSE、CMD 等指令聲明了一個 http-server 提供靜態服務的鏡像。
docker run 這個鏡像就可以生成容器,指定映射的端口、掛載的數據卷、環境變量等。
VOLUME 指令看起來沒啥用,但能保證你容器內某個目錄下的數據一定會被持久化,能保證沒掛載數據卷的時候,數據不丟失。
寫完這個 dockerfile,相信你會對 docker 鏡像、容器有更具體的理解了。
不得不說,用 desktop 來學 docker 真是太簡單了。
-
變量
+關注
關注
0文章
613瀏覽量
28451 -
鏡像
+關注
關注
0文章
170瀏覽量
10786 -
Docker
+關注
關注
0文章
492瀏覽量
11925
原文標題:通過 Desktop 學 Docker 也太簡單了
文章出處:【微信號:良許Linux,微信公眾號:良許Linux】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論