Tips:本篇已加入系列文章閱讀目錄,可點擊查看更多相關文章。html
上一篇【.Net Core微服務入門全紀錄(七)——IdentityServer4-受權認證】中使用IdentityServer4完成了鑑權中心的搭建,配合網關實現了統一的受權認證。進行到這裏,系統環境已經比較複雜了,想把整個系統運行起來會很是繁瑣:要運行Consul、業務服務、網關、鑑權中心、web客戶端,還要安裝數據庫、MQ等等。。。那麼本篇將使用Docker Compose來解決以上問題,僅需一個簡單的命令,便可啓動整個環境。git
什麼是Docker Compose?github
Compose 是用於定義和運行多容器 Docker 應用程序的工具。經過 Compose,您可使用 YML 文件來配置應用程序須要的全部服務。而後,使用一個命令,就能夠從 YML 文件配置中建立並啓動全部服務。web
簡單來理解,Compose相似一個批量工具,能夠執行一組命令,支持批量構建鏡像,批量啓動容器,批量刪除容器等等功能。docker
Windows的Docker Desktop中已經包括了Compose,Linux下Compose則須要單獨安裝一下。數據庫
yml文件是使用Compose必不可少的,在編寫yml文件以前還須要準備Dockerfile。api
以前的章節中,有些服務不是在Docker中運行的,如今所有放到Docker中。確保解決方案中每一個項目都添加Docker支持。瀏覽器
在根目錄新建docker-compose.yml文件:網絡
如下是docker-compose.yml文件內容:ide
version: '3.4' #Compose文件版本 services: #服務 auth: #定義"auth"服務 對應的是鑑權中心項目 build: #構建 context: . #構建上下文(目錄) dockerfile: ./IDS4.AuthCenter/Dockerfile #Dockerfile文件目錄 ports: #端口 - '9080:9080' #容器外部9080 容器內部9080 environment: #環境變量 - ASPNETCORE_URLS=http://+:9080 #程序在容器內部http://+:9080運行 也能夠寫成http://0.0.0.0:9080 networks: #容器網絡 - my-net #自定義網絡my-net web: #定義"web"服務 對應的web客戶端項目 build: context: . dockerfile: ./Web.MVC/Dockerfile ports: - '5000:5000' environment: - ASPNETCORE_URLS=http://+:5000 networks: - my-net depends_on: #"web"服務依賴於"auth"服務和"apigateway"服務,此服務會在依賴服務以後執行 - auth - apigateway apigateway: #定義"apigateway"服務 對應的網關項目 build: context: . dockerfile: ./Ocelot.APIGateway/Dockerfile ports: - '9070:9070' environment: - ASPNETCORE_URLS=http://+:9070 networks: - my-net depends_on: - orderapi1 - orderapi2 - orderapi3 - productapi1 - productapi2 - productapi3 productapi1: #定義"productapi1"服務 對應的產品服務項目 image: productapi #指定鏡像名稱,若是不指定 默認是:netcoremicroservicedemo_productapi1,由於下面要用到因此指定一下 build: context: . dockerfile: ./Product.API/Dockerfile ports: - '9050:9050' environment: - ASPNETCORE_URLS=http://+:9050 - ConsulSetting:ServiceIP=productapi1 #程序參數 - ConsulSetting:ServicePort=9050 #程序參數 networks: - my-net depends_on: - consul - postgres - rabbitmq productapi2: image: productapi #指定鏡像名稱爲productapi,productapi1服務中已經構建了productapi鏡像,因此不用重複構建 ports: - '9051:9051' environment: - ASPNETCORE_URLS=http://+:9051 - ConsulSetting:ServiceIP=productapi2 - ConsulSetting:ServicePort=9051 networks: - my-net depends_on: - productapi1 productapi3: image: productapi ports: - '9052:9052' environment: - ASPNETCORE_URLS=http://+:9052 - ConsulSetting:ServiceIP=productapi3 - ConsulSetting:ServicePort=9052 networks: - my-net depends_on: - productapi1 orderapi1: image: orderapi build: context: . dockerfile: ./Order.API/Dockerfile ports: - '9060:9060' environment: - ASPNETCORE_URLS=http://+:9060 - ConsulSetting:ServiceIP=orderapi1 - ConsulSetting:ServicePort=9060 networks: - my-net depends_on: - consul - postgres - rabbitmq orderapi2: image: orderapi ports: - '9061:9061' environment: - ASPNETCORE_URLS=http://+:9061 - ConsulSetting:ServiceIP=orderapi2 - ConsulSetting:ServicePort=9061 networks: - my-net depends_on: - orderapi1 orderapi3: image: orderapi ports: - '9062:9062' environment: - ASPNETCORE_URLS=http://+:9062 - ConsulSetting:ServiceIP=orderapi3 - ConsulSetting:ServicePort=9062 networks: - my-net depends_on: - orderapi1 consul: image: consul #指定鏡像名稱爲consul,本地若是沒有consul鏡像,會從docker遠程倉庫拉取 ports: - '8500:8500' networks: - my-net postgres: image: postgres environment: POSTGRES_PASSWORD: pg123456 networks: - my-net rabbitmq: image: rabbitmq networks: - my-net networks: #定義容器網絡 my-net: #my-net網絡 driver: bridge #網絡模式爲bridge
以上yml文件定義了auth,web,apigateway,productapi1,productapi2,productapi3,orderapi1,orderapi2,orderapi3,consul,postgres,rabbitmq 12個服務(容器),和一個容器網絡 my-net。這裏的productapi和orderapi至關因而基於一樣的鏡像各運行了3個容器,這其實不太合理,正常他們應該分佈在多個docker中。。。
文件的內容雖然有點多,可是應該不難理解,上面的關鍵字我都有註釋(注意,正式使用最好仍是不要加中文註釋,可能會出現編碼格式錯誤問題)。下面再簡單介紹一下文件中的networks容器網絡。
前面的章節中有提到過,默認狀況下容器之間的通信是比較麻煩的,以前是經過host.docker.internal
或者容器的IP去訪問,雖然是能夠訪問但有些不友好。更好的方式是,咱們能夠自定義一個bridge網絡,將全部服務(容器)加入這個網絡中,那麼容器之間就能夠直接經過服務名稱通訊了。bridge模式只是docker網絡模式中的一種,有興趣的話能夠自行搜索一下。
既然程序都運行在docker中,那就不能寫localhost
,host.docker.internal
之類的主機名了,統一改成docker-compose.yml文件中定義的服務名。以下:
還有多處修改就不全貼出來了,都是些相似的改動。這些配置仍是不要寫在代碼裏,改動起來比較亂。
這裏有一個特殊的就是identityserver4鑑權服務,這個服務是容器內外部都須要訪問的(容器內部ids4發現文檔等接口的調用,外部瀏覽器訪問),因此不能直接寫服務名auth,寫auth的話外部沒法訪問,寫localhost的話內部又沒法訪問。最後是參考eShopOnContainers項目,使用docker.for.win.localhost
來知足內外部的訪問需求:
理論上用host.docker.internal
或許也能夠,沒去測試。。。這個配置放到Compose的環境變量裏會比較好,這裏只是爲了方便。
eShopOnContainers項目是微軟官方出品的開源項目,對於學習微服務,docker等技術很是有幫助。
項目地址:https://github.com/dotnet-architecture/eShopOnContainers
完成以上操做後,進入項目根目錄執行docker-compose build
build完成後,執行docker-compose up -d
,-d表明在後臺運行
(第一次up,orderapi2,orderapi3,productapi2,productapi3這4個服務會起不來,是由於他們啓動時有建立數據庫的操做,同時啓動會致使後起來的4個重複的服務建立數據庫時報錯,由於orderapi1和productapi1在建立一樣的數據庫。。。這個前面說過的。這裏等up完再執行一次up就行了)
瀏覽器訪問:http://localhost:5000/
登陸後:
這樣運行系統是否是很是簡單呢?想要摧毀這個環境也很簡單,只須要一句docker-compose down
若是不習慣docker命令,推薦使用vscode,裝一下docker插件,很方便。
上文用到了Docker-Compose的3個命令:
構建:docker-compose build
啓動:docker-compose up
銷燬:docker-compose down
其實build命令也能夠省略,執行up時若是沒有build的話會自動build,不管多複雜的系統環境,只須要一個docker-compose up
命令便可啓動。不過鏡像須要從新bulid的時候,仍是要用到build命令。Compose還有一些其餘命令,須要的話能夠自行搜索。
主要的工做量在於docker-compose.yml文件的編寫。
須要代碼的點這裏:https://github.com/xiajingren/NetCoreMicroserviceDemo