Docker學習筆記之使用 Docker Hub 中的鏡像


0x00 概述

自己編寫 Dockerfile 能夠很好的實現我們想要的程序運行環境,不過如果裝有我們想要環境的鏡像已經由熱心的開發者構建好並共享在 Docker Hub 上,直接使用它們就會遠比自己編寫 Dockerfile 並進行構建要來的簡單的多了。事實上,在開發過程中我們用到的鏡像大部分還是直接采用 Docker Hub 中已經存在的鏡像的,即使自己編寫 Dockerfile,也只是對已有鏡像進行簡單的改動,很少會從零開始搭建鏡像。在這一節中,我們要來看看如何更好地使用 Docker Hub 上由其他開發者共享的鏡像。

 

0x01 選擇鏡像與程序版本

由於 Docker 的容器設計是程序即容器的,所以組成我們服務系統的多個程序一般會搭建在多個容器里,互相之間協作提供服務。例如一套最簡單的 Web 服務,我們可能會需要 Java 容器來運行基於 Spring Boot 的程序,需要 MySQL 容器來提供數據庫支持,需要 Redis 容器來作為高速 KV 存儲等等。裝有這些程序的鏡像我們都可以很容易的在 Docker Hub 上找到並直接使用,但在我們使用前,光選擇鏡像還是不夠的,我們還得根據需要選擇對應程序版本的鏡像。

雖然我們常把軟件的版本放在 Tag 里作為鏡像名的一部分,但對於一些復雜的應用,除了版本外,還存在很多的變量,鏡像的維護者們也喜歡將這些變量一同組合到鏡像的 Tag 里,所以我們在使用鏡像前,一定要先了解不同 Tag 對應的不同內容。

這里我們來看個例子,下面是由 Docker 官方提供的 OpenJDK 鏡像的說明頁面。

通常來說,鏡像的維護者會在鏡像介紹中展示出鏡像所有的 Tag,如果沒有,我們也能夠從頁面上的 Tags 導航里進入到鏡像標簽列表頁面。

在 OpenJDK 鏡像的 Tag 列表里,我們可以看到同樣版本號的鏡像就存在多種標簽。在這些不同的標簽上,除了定義 OpenJDK 的版本,還有操作系統,軟件提供者等信息。

鏡像維護者為我們提供這么多的標簽進行選擇,其實方便了我們在不同場景下選擇不同環境實現細節時,都能直接用到這個鏡像,而不需要再單獨編寫 Dockerfile 並構建。

但是換句話說,正是有這么多不同標簽的鏡像存在,所以我們在選擇的時候,更要仔細認真,找到我們想要的那個鏡像。

 

0x02 Alpine 鏡像

如果大家多接觸幾個鏡像,就會發現帶有 Alpine 的版本是許多鏡像中都常見的標簽。帶有 Alpine 標簽的鏡像到底是什么樣的存在呢?它與相同軟件不同標簽的鏡像又有什么樣的區別呢?

鏡像標簽中的 Alpine 其實指的是這個鏡像內的文件系統內容,是基於 Alpine Linux 這個操作系統的。Alpine Linux 是一個相當精簡的操作系統,而基於它的 Docker 鏡像可以僅有數 MB 的尺寸。如果軟件基於這樣的系統鏡像之上構建而得,可以想象新的鏡像也是十分小巧的。

在 Docker 里,Alpine 系統的鏡像到底有多小,我們不妨來與其他系統鏡像做一個比較。

 

可以看到,Alpine 系統鏡像的尺寸要遠小於其他常見的系統鏡像。讓我們再來比較同一個軟件在基於普通系統的鏡像和基於 Alpine 系統的鏡像后尺寸上的區別。

 

由於基於 Alpine 系統建立的軟件鏡像遠遠小於基於其他系統的軟件鏡像,它在網絡傳輸上的優勢尤為明顯。如果我們選擇這類的鏡像,不但可以節約網絡傳輸的時間,也能減少鏡像對硬盤空間的占用。

當然,有優點也會有缺點,Alpine 鏡像的缺點就在於它實在過於精簡,以至於麻雀雖小,也無法做到五臟俱全了。在 Alpine 中缺少很多常見的工具和類庫,以至於如果我們想基於軟件 Alpine 標簽的鏡像進行二次構建,那搭建的過程會相當煩瑣。所以如果你想要對軟件鏡像進行改造,並基於其構建新的鏡像,那么 Alpine 鏡像不是一個很好的選擇 (這時候我們更提倡基於 Ubuntu、Debian、CentOS 這類相對完整的系統鏡像來構建)。

 

0x03 對容器進行配置

除了合理選擇鏡像外,許多鏡像還為我們提供了更加方便的功能,這些細節我們通常都可以在鏡像的詳情里閱讀到。

這里我們以 MySQL 為例,看看通常我們是怎樣閱讀和使用鏡像的特殊功能的。

自己安裝過 MySQL 的朋友一定知道,搭建 MySQL 最麻煩的地方並不是安裝的過程,而是安裝后進行初始化配置的過程。就拿更改 root 賬號的密碼來說,在初始的 MySQL 里就要耗費不少工作量。

如果我們拿到一個 MySQL 鏡像,運行起來的 MySQL 也就約等於一個剛剛安裝好的程序,面臨的正好是復雜的初始化過程。

好在 MySQL 鏡像的維護者們為我們打造了一些自動化腳本,通過它們,我們只需要簡單的傳入幾個參數,就能夠快速實現對 MySQL 數據庫的初始化。

在 MySQL 鏡像的詳情里,描述了我們要如何傳入這些參數來啟動 MySQL 容器。

 

對於 MySQL 鏡像來說,進行軟件配置的方法是通過環境變量的方式來實現的 ( 在其他的鏡像里,還有通過啟動命令、掛載等方式來實現的 )。我們只需要通過這些給出的環境變量,就可以初始化 MySQL 的配置了。

例如,我們可以通過下面的命令來直接建立 MySQL 中的用戶和數據庫。

$ sudo docker run --name mysql -e MYSQL_DATABASE=webapp -e MYSQL_USER=www -e MYSQL_PASSWORD=my-secret-pw -d mysql:5.7

通過這條命令啟動的 MySQL 容器,在內部就已經完成了用戶的創建和數據庫的創建,我們通過 MySQL 客戶端就能夠直接登錄這個用戶和訪問對應的數據庫了。

如果深究 MySQL 是如何實現這樣復雜的功能的,大家可以到 MySQL 鏡像的 Dockerfile 源碼庫里,找到 docker-entrypoint.sh 這個腳本,所有的秘密正暗藏在其中。MySQL 正是利用了 ENTRYPOINT 指令進行初始化這種任務安排,對容器中的 MySQL 進行初始化的。

通過 MySQL 鏡像這樣的邏輯,大家還可以舉一反三,了解其他鏡像所特用的使用方法,甚至可以參考編寫、構建一些能夠提供這類方法的 Dockerfile 和鏡像。

 

0x04 共享自己的鏡像

如果我們希望將我們鏡像公開給網絡上的開發者們,那通過 Docker Hub 無疑是最佳的方式。

要在 Docker Hub 上共享鏡像,我們必須有一個 Docker Hub 的賬號,這自不必說了。在登錄到我們賬號的控制面板后,我們能夠找到創建的按鈕,在這里選擇 Create Automated Build ( 創建自動構建 )。

自動構建鏡像是 Docker Hub 為我們提供的一套鏡像構建服務,我們只需要提供 Dockerfile 和相關的基本文件,Docker Hub 就能夠在雲端自動將它們構建成鏡像,之后便可以讓其他開發者通過 docker pull 命令拉取到這一鏡像。

自動構建讓不需要我們再用本機進行鏡像的構建,既能節約時間,又能享受高速的雲端機器構建。

在 Docker Hub 中並不直接存放我們用於構建的 Dockerfile 和相關文件,我們必須將 Docker Hub 賬號授權到 GitHub 或是 Bitbucket 來從這些代碼庫中獲取 Dockerfile 和相關文件。

 

在連接到 GitHub 或 Bitbucket 后,我們就可以選擇我們存放 Dockerfile 和相關文件的代碼倉庫用來創建自動構建了。

 

在基本信息填寫完成,點擊創建按鈕后,Docker Hub 就會開始根據我們 Dockerfile 的內容構建鏡像了。而此時,我們也能夠訪問我們鏡像專有的詳情頁面了。

 

在 Build Details 頁面里,我們可以看到鏡像構建的進度和詳細的構建情況。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM