歡迎光臨
每天分享高質量文章

基於 Docker Compose 實踐 .NET Core 的現代化架構 2:在容器中整合 Skywalking APM

本章節程式碼已經上傳至 https://github.com/siegrainwong/.NET-Core-with-Docker/tree/master/Part2

系列大綱

還是先介紹一下目錄,這次我們講第二篇:

  1. 用 docker-compose 啟動 WebApi 和 SQL Server
  2. 在容器中整合 Skywalking APM
  3. 透過 nginx-proxy 對 ES、Skywalking、WebApi 實現自動反向代理和 HTTPS
  4. 透過 Azure DevOps 進行 CI/CD 和藍綠釋出

按照慣例,故障排除在最後一個章節~

Skywalking 介紹

Skywalking是一個分散式鏈路追蹤系統,在部署分散式系統時能以非常清晰和全面的方式為你展示各種各樣的監控資料,且本身接入對程式碼毫無侵入性,加上docker的部署優勢能讓你分分鐘將這個強大的 APM 整合並啟動起來。

配置監控代理

監控代理負責執行在你WebApi容器中並向收集器(Skywalking-OAP)定時傳送監控資料。

本節中的F:\path\to\your\project的路徑字串都用來指代你的專案根目錄,註意替換

開啟程式包管理控制檯,安裝SkyAPM

Install-Package SkyAPM.Agent.AspNetCore -Version 0.9.0

安裝SkyAPM.DotNet.CLI

dotnet tool install -g SkyAPM.DotNet.CLI

新增配置檔案

cd F:\path\to\your\project\Core.API
dotnet skyapm config coreapi sw-oap:11800

新增後是這樣的,並且記得設定其為始終複製

配置docker-compose

修改你的docker-compose.yml檔案成這樣:

version: "3.3"
services:
  #coreapi:
  #  container_name: coreapi
  #  image: siegrainwong/coreapi:latest
  #  ports:
  #    - 5000:5000
  #  depends_on:
  #    - sqlserver
  #  links:
  #    - sqlserver
  #  volumes:
  #    - ./Core.API/appsettings.docker.json:/app/appsettings.json:ro
  #  environment:
  #    ASPNETCORE_HOSTINGSTARTUPASSEMBLIES: SkyAPM.Agent.AspNetCore
  #    SKYWALKING__SERVICENAME: coreapi
  #  restart: always
  sqlserver:
    image: mcr.microsoft.com/mssql/server:2017-latest
    container_name: sqlserver
    restart: always
    environment:
      ACCEPT_EULA: Y
      MSSQL_PID: Developer
      SA_PASSWORD: "NetCore123!@#"
    volumes:
      - coredata:/var/opt/mssql
    ports:
      - 1433
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:6.4.3
    container_name: elasticsearch
    restart: always
    ports:
      - 9200:9200
      - 9300:9300
    environment:
      discovery.type: single-node
    ulimits:
      memlock:
        soft: -1
        hard: -1
  sw-oap:
    image: apache/skywalking-oap-server:6.1.0
    container_name: sw-oap
    depends_on:
      - elasticsearch
    links:
      - elasticsearch
    restart: always
    ports:
      - 11800:11800
      - 12800:12800
    environment:
      SW_STORAGE: elasticsearch
      SW_STORAGE_ES_CLUSTER_NODES: elasticsearch:9200
  sw-ui:
    image: apache/skywalking-ui:6.1.0
    container_name: sw-ui
    depends_on:
      - sw-oap
    links:
      - sw-oap
    restart: always
    ports:
      - 8080:8080
    environment:
      SW_OAP_ADDRESS: sw-oap:12800
volumes: coredata:

是的,我們先把這裡的coreapi註釋掉,方便本地除錯

在根目錄新增一個名為launch.ps1的指令碼:

docker-compose up -d

docker run --rm -it `
	-v F:\path\to\your\project:/app/ `
	-v F:\path\to\your\project\Core.API\appsettings.docker.json:/app/Core.API/appsettings.Development.json:ro `
	-p 5000:5000 `
	--link sw-oap `
	--link sqlserver `
	--name coreapi_dev `
	--network part2_default `
	--env ASPNETCORE_HOSTINGSTARTUPASSEMBLIES=SkyAPM.Agent.AspNetCore `
	--env SKYWALKING__SERVICENAME=coreapi `
 	-w /app/Core.API mcr.microsoft.com/dotnet/core/sdk:2.2-stretch dotnet watch run

docker run這條命令的意思是以互動樣式將當前目錄掛載到docker中執行dotnet watch run,併在執行完成後(或按 Ctrl+C 退出時)移除該容器,一般我們開發中就都是透過這種命令將應用程式快速執行在容器中。

還需要註意的是,這裡手動指定了容器的網路(--network),只有執行在同一網路內的容器才能利用容器名在容器內網互相通訊,你可以用docker network ls看看有哪些容器網路,之前我們用docker-compose建立起來的所有容器都在一個網路中,這個網路的名稱一般是當前你的專案根目錄名_default,所以我的就叫part2_default,你需要將其改為你的網路名稱。

想驗證容器之間的網路是否通暢,比如想測試從 coreapi 到 sqlserver 的連線,只需要docker exec coreapi_dev curl sqlserver:1433即可。

其他命令的意思你應該很輕鬆就能猜到的,如果不明白可以對照一下上一章中文註釋過的docker-compose.yml檔案,就不多解釋了。

我們執行這個指令碼後,訪問localhost:8080,不出意外將出現Skywalking的登入介面:

輸入 admin/admin 登入: 

然後就能看到這個酷炫的頁面了,不過此時你很有可能看不見資料,別急,我們先去http://localhost:5000/api/values頁面刷兩下,回來再將右下角的 UTC+8 改為 UTC+0,因為 ES 跟 OAP 的預設時區都是 UTC+0,這個我們後面再解決,現在掃清看是不是有資料了。

裡面具體有什麼就自己探索吧,這裡主要講部署方法,具體使用方法也有很多其他博主寫過了,就不多講了。

糾正時區為 UTC+8

糾正時區的原理非常簡單,就是靠命令修改容器虛擬機器的時區。這需要我們在 oap 跟 es 的 Dockerfile 中執行這兩條命令:

ln -sf /usr/share/zoneinfo/Asia/Shanghai  /etc/localtime
echo Asia/Shanghai > /etc/timezone

好訊息是其實這些活兒也是有人做好了的,直接拿來用就是了。

修改 ES 的容器映象為:

elasticsearch:
  image: wutang/elasticsearch-shanghai-zone:6.3.2

修改 OAP 的容器映象為:

sw-oap:
  image: siegrainwong/skywalking-oap:6.1.0

再去劃拉兩下,是不是時間就正確了?

具體的修改方式可以參考這個commit以及這個repo,其實在有官方的容器化之前一直是這位大佬在維護的,大家要感謝他,本來當時我也是跟著這個 Repo 學習的,文章也寫到一半了,結果發現官方容器化後又重新走了一遍 23333。

故障排除

  1. 透過檢視Core.API\logs\skyapm-xxx.log排錯,一般都是代理連不上 oap 等類似錯誤,重新修改下你的gRPC/Servers直到連通為止(不過這裡好像有點 bug,有時候莫名其妙日誌就不生成了~),如果有這樣的日誌,就說明代理連上 oap 了
org.apache.skywalking.oap.server.receiver.register.provider.handler.v5.grpc.InstanceDiscoveryServiceHandler -13182375 [grpc-default-executor-43] INFO [] - register service instance id=16 [UUID:23e8d5461f0049cfa708d5ec782a6a8b]
  1. 透過docker logs命令檢視sw-oap或者sw-ui的日誌,看看是不是有什麼錯誤,一般也還是連不通的錯誤,oap 連不上 es 呀,ui 連不上 oap 啊,等等

  2. 參考 skywalking-docker 官方repo

  3. 參考 SkyAPM 官方repo

  4. 如果你的 skywalking 沒有 CLR 資訊,可能是你混用的 5.x 版本的監控代理,那個程式集叫 Skywalking.xxxxx,接入時還需要修改 Startup.cs 檔案,發生這種情況用最新的 Agent 即可

原文地址:https://siegrain.wang/article/2019/07/08/deploy-skywalking-in-docker-with-netcore

已同步到看一看
贊(0)

分享創造快樂