javascript
SpringCloud + Docker
Dockerfile構建Docker 鏡像
- 注意這里說的Dockerfile是指的一個文本文件,類似txt,只不過名字是Dockerfile,里面編輯Docker的一些指令,指令作用在于描述構建鏡像的細節。如下一個簡單的案例,用上一節中下載的nginx鏡像來進行測試:
4. 訪問http:宿主機IP:92/,如下圖,nginx正常啟動。
Dockerfile常用指令
-
之前案例中用的FROM,RUN指令是Dockerfile眾多指令中的兩個,Dockerfile包含十幾個指令。一般格式: 指令名稱 參數。
-
ADD復制文件
- ADD < src> … < dest>
- ADD ["< src>" …"< desc>"]
- 從src目錄負責文件到容器dest,啟動src可以是Dockerfile所在的目錄的相對路徑,也可以是一個url,也可以是一個壓縮包
- 注意一下幾點:
- src必須在構建的上下文內,不能使用例如:ADD …/A/B這樣的命令,因為docker build命令首先會將上下文路徑和其子目錄發送到docker daemon。
- 如果src是一個URL,同時dest不以斜桿結尾,dest將被視為文件,src對應內容文件將會被下載到dest
- 如果src是一個URL,同時dest以斜桿結尾,dest將被視為目錄,src對應內容將會被下載到dest目錄
- 如果src是一個目錄,那么整個目錄下的內容將會被復制,包括文件系統元數據。
- 如果文件是可識別的壓縮包格式,則docker會自動解壓。
- 如下案例
- ARG 設置構建參數: ARG指令用于設置構建參數,類似ENV,和ARG不同的是ARG設置的是構建時候的環境變量,在容器運行時候,是不會存在這些變量的,格式如下
- 格式為:ARG < name> [=< default value>]
- CMD容器啟動命令: CMD指令用于為執行容器提供默認值,每個Dockerfile只有一個CMD命令,如果指定了多個CMD命令,你們只有最后一條會被執行,如果啟動容器時指定了運行的命令,則會覆蓋CMD指定的命令
- 支持三種格式:
- CMD [“executable”, “param1”, “param2”]
- CMD [“param1”, “param2”] (為ENTRYPOINT指令提供預設參數)
- CMD command param1 param2
- COPY 復制文件,格式如下
- COPY < src > … < dest >
- COPY [ “< src >” … “< dest >” ]
- 復制本地端的src到容器的desc。COPY指令和ADD指令類似,COPY不支持URL和壓縮包。
- ENTRYPOINT入口點,格式如下
- ENTRYPOINT [“excutable”, “param1”, “param2”]
- ENTRYPOINT command param1 param2
- ENTRYPOINT 和CMD指令的目的一樣,都是指定Docker容器啟動時執行的命令,可多次設置,但只有最后一個有效。
- ENV設置環境變量,格式如下:
- ENV < key> < value >
- ENV < key>=< value > …
- EXPOSE聲明暴露的端口:用于在運行容器的時候指定提供服務的端口號格式:EXPOSE < port> [< port>… ]
- 注意,這只是一個聲明,運行時并不會因為改聲明就打開對應的端口。改指令的作用注意是幫助鏡像使用者理解該鏡像服務的守護端口;其次是當運行時使用隨機映射時候,會自動映射EXPOSE端口。如下案例:
-
FROM 指定基礎鏡像:
- 使用FROM指令指定基礎鏡像,FROM指令有點像java的extends關鍵字。需要注意的是,FROM指令必須指定并且需要寫在其他指令之前,FROM指令后的所有指令都依賴于該指令所指定的鏡像。支持以下三種格式
- FROM < image>
- FROM < image>:< tag>
- FROM < Image>@< digest>
-
LABEL 為鏡像添加元數據,LABEL指令用于為鏡像添加元數據。格式如下:
- LABEL < key>=< value> < key>=< value> < key>=< value> …
- 使用‘ ” ’ 和 ‘ \ ’轉換命令行,案例
- MAINTAINER 指定維護者信息,用于為Dockerfile署名,如下格式
- MAINTAINER < name>
-
RUN 執行命令: 如下格式
- RUN < command> :在shell終端運行,在linux中默認 /bin/sh -c, 在win中cmd /s /c,使用這種格式,就像直接在命令行中輸入命令一樣
- RUN [ “executable”, “param1”, “param2”] : 使用exec執行,這種方式類似函數調用,指定其他終端可以通過該方式操作,例如,RUN [ “/bint/bash” , “-c”, “echo hello”],這種方式必須使用雙引號,不能用單引號,因為這種會被轉成JSON數組
-
USER設置用戶: 設置啟動鏡像時候用戶或者UID,寫在該指令后的RUN, CMD以及ENTRYPOINT指令都將使用該用戶執行命令
- 格式:USER 用戶名
- VOLUME 知道掛載點: 使容器中的一個目錄具有持久化存儲的功能,改目錄可以被容器本身使用,也可以共享給其他容器。當容器中應用有持久化數據的需求時候,可以在Dockerfile中使用該指令: VOLUME ["/data"]
- WORKDIR 指定工作目錄
- 其他參閱官網
使用Dockerfile 構建SpringCloud 項目鏡像
- 準備一個SpringCloud項目,本項目地址,到microservice-discivery-eureka項目下執行mvn clean package
構建鏡像
- 創建文件Dockerfile
- 編輯如下信息,注意命令中大小寫的區別,注意此處用到了鏡像 java:8 ,如果你本地倉庫中沒有該鏡像,將會自動先下載java:8對應的鏡像,會比較慢,可以先用使用 docker pull java:8 命令下載對應的images信息,加快構建的速度:
- 使用docker build命令構建鏡像對象,命令如下,輸出如下
- 由上可看到鏡像構建的每一個步驟的詳細輸出以及結果,我們執行docker images 可以看到新建的鏡像
- 使用docker run 命令啟動新增鏡像
- 訪問宿主機http://localhost:8761,可以正常顯示Eureka Server首頁
使用Docker Registry管理Docker鏡像
- 上一篇中我們討論過如何將我們本地的鏡像推送到我們申請的Docker Hub遠程倉庫上,此處Docker Hub就是Docker官方維護的Docker Registry,上面存放著很多優秀的鏡像,類似gitHub,Docker Hub還提供認證系統,工作結構,工作流工具,構建觸發器等工具來簡化工作。
- 使用如下方式登陸,并且將剛才的鏡像推送到遠程倉庫
使用私有倉庫管理鏡像
- 剛才體驗過從Docker Hub上下載,上傳鏡像的快感,是不是有時候慢的抓狂,因此在很多場景下,使用私有倉庫就會是一個很好的選擇,相比Docker Hub有以下優勢:
- 節省帶寬,對私有倉庫中已經有的鏡像,不需要從Docker Hub下載,只需要從私有倉庫中下載即可
- 更加安全,只有自己看到的
- 便于內部鏡像的統一管理
- 我們用Docker Registry 2.0搭建一個私有倉庫,用如下命令
- 啟動后,將剛才的鏡像文件打tag,用來對應上我我們剛才穿件的本地倉庫,如下命令
- 直接用原鏡像提交會報錯,如下,因為他默認是推送到docker.io/645121107/microservice-discovery-eureka:0.0.1
- 我刪除對提交后的images,然后通過pull命令下載,如下日志中是沒有Loading的下載過程,非常的快。
使用maven插件構建Docker鏡像
-
利用Maven的項目管理與構建工具構建Docker鏡像,使我們開發能夠更進一步的簡化開發部署流程。Maven 的Docker插件有三種,如下:
- 名稱:docker-maven-plugin, 地址:https://github.com/spotify/docker-maven-plugin
- 名稱:docker-maven-plugin, 地址:https//github.com/fabric8io/docker-maven-plugin
- 名稱:docker-maven-plugin, 地址:https://github.com/bibryam/docker-maven-plugin
-
其中熱度最高的是由Spotify公司開發的Maven插件,我們用這個來實驗,還是以上文中microservice-discovery-eureka為案例,
- 如上pom文件中build的配置,其中有兩個plugin,第一個是指定Spring cloud的使用版本,第二個是指定docker-maven-plugin,配置說明如下:
- imageName:用于指定鏡像名稱,其中645121107指定倉庫名,microservice-discovery-eureka指定鏡像名稱,0.0.1指定標簽名稱
- baseImage:用于指定基礎鏡像,類似Dockerfile中的FROM指令
- entrypoint:類似Dockerfile的Entrypoint指令
- resources.resource.directory:用于指定需要復制的根目錄,${project.build.finalName}標識target目錄
- resource.resource.include:用于指定需要復制的文件:${project.build.finalName}指的是打包后的jar文件
- 執行docker images 之后可以看到剛才構建的鏡像:
- 啟動是很快的,之后就可以直接訪問http://localhost:8761
使用Docker Compose
- 上文我們通過各種命令來操作docker 鏡像,從而達到對服務的控制,但是,一般我們微服務都是由N多個一起運行,而且每個微服務都可能部署N個,如果每個微服務都要手動啟動,那么效率之低,維護量之大可想而知。
- Compose就是用來解決這個問題,他是一個用于定義和運行多容器Docker應用程序的工具,前身是Fig,適合在開發,測試,構建CI工作流等場景。
Compose 安裝
- 官網有詳細的說明
- Compose有多重安裝方式,Shell,pip以及將Compose作為容器安裝等,我找了一個1.16.1版本,如下命令,下載會比較慢:
- 為安裝腳本添加執行權限:
- 測試安裝結果
安裝Compose命令補全工具
- Compose也有配套的命令補全工具,當輸入 docker-compose按 Tab時候,Conpose會自動補全命令,我們需要下載一個插件。
- 命令補全工具在Bash和Zsh下的安裝方式不同,可以參照官網
- 執行如下命令即可完成安裝:
Compose構建案例
- 驗證:http://localhost:8761
實戰使用Docker Compose編排Spring Cloud微服務
-
使用Compose編排之前用到的SpringCloud微服務,微服務項目地址
-
這次我用Dockerfile來對SpringCloud進行鏡像構建,之前的maven配置修改太麻煩,所以直接使用Dockerfile了。
-
第一步,修改項目中eureka對應配置,之前項目中eureka.client.serviceUrl.defaultZon的值是http://localhost:8761/eureka/。由于Docker環境默認網絡是bridge,各個容器的IP都不相同,因此使用http://localhost:8761/eureka是不通的,可以為EurekaServer所在容器配置一個主機名,例如,discover,讓各微服務使用主機名訪問EurekaServer,如下修改:
- 第二步,分別在以下Spring Cloud項目中對項目進行打包
- 第三部,編寫docker-compose.yml
- 第四步,執行啟動命令,批量啟動
簡化Compose編寫
- 咋Version 3.1file format的docker-compose.yml 中,同一個compose工程中的所有服務共享一個隔離網絡,可以使用服務名稱作為主機來發現其他服務。因此,我們可以沈略掉link相關的配置,最終簡化如下:
編排高可用的Eureka Server
- 編輯docker-compose 文件如下:
- 執行docker-compose up ,出現以下錯誤信,描述上看是循環依賴問題,eureka無法通過links實現雙向鏈接:
- 解決辦法,可以用ambassador pattern, 或者外部DNS,此處我們直接修改配置,不用links的方式。如下:
- 如上啟動成功,還有幾個解決方案如下
- 循環依賴解決資料:http://www.dockone.io/article/929
- ambassador pattern 官網:https://docs.docker.com/search/?q=ambassador
- GitHub上相關issue:https://github.com/docker/compose/issues/666
編排高可用SpringCloud 微服務集群及動態伸縮
- 上文中我們都是啟動了單個實例,這樣存在風險,生產環境肯定是不行的,以下我們利用docker-compose來編排高可用的微服務。還是用以上幾個項目
- 啟動項目,并且測試項目是否生效,如下接口已經生效,并且hystrix已經發生熔斷,因為provider項目需要訪問數據庫,沒有去關這部分配置,本次之測試高可用:
- 保證各個服務可用情況下,執行以下命令,讓除eureka以外的每一個服務都啟動三個實例,如下:
- 查看Eureka中注冊項目是否生效:
虛擬機臺TM卡了,之后在補一個圖吧,反正可以啟動就行了
上一篇:Ubuntu上安裝使用Docker
下一篇:Docker中數據管理
總結
以上是生活随笔為你收集整理的SpringCloud + Docker的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 激素冲击疗法是什么
- 下一篇: gradle idea java ssm