Categories
程式開發

使用Docker Application Package實現跨團隊交付應用


本文要點

  • 目前,尚沒有解決方案能夠定義和打包在任意主機上運行的多服務、多格式的分佈式應用。
  • 雲原生應用bundle(Cloud-Native Application Bundle,CNAB)是一個開源、雲中立的規範,致力於打包和運行分佈式應用。
  • CNAB包格式包括一個定義應用的bundle定義文件(bundle.json),以及安裝應用的調用(invocation)鏡像。
  • 最新的Docker App發布版本實現了當前的CNAB規範。通過實現該CNAB規範,Docker App可以用來構建適用於Compose的CNAB bundle,同時還能安裝、更新和卸載任意其他的CNAB bundle。

雲原生應用通常會使用不同的技術,每種技術都有自己的打包格式。舉例來說,如果你使用Microsoft Azure的話,那麼格式將會是ARM模板,如果使用Kubernetes的話,那就是Helm charts,如果使用AWS的話,那麼可能就是CloudFormation等等。

分佈式應用通常由可執行單元(executable unit)基於API的支撐服務所組成。可執行單元可能會跨多種環境,比如IaaS(如OpenStack或Azure)、容器編排器(如Kubernetes或Nomad)、容器運行時(如本地Docker或ACI)、雲平台服務(如對象存儲或數據庫即服務)和功能即服務(FaaS,Functions-as-a-Service),同時還有高層級的PaaS服務。除了這些組件外,許多託管雲服務,例如負載均衡器、數據庫的路由器,都以REST API進行提供和互連。

在我們的行業中,目前還沒有解決方案能夠定義和打包多服務、多格式的分佈式應用。

在本文中,我們將會看一下CNAB打包格式如何為應用供應商和開發人員提供一種將多組件應用安裝到分佈式計算環境的方式,該格式支持上述的所有類型,使得跨團隊、組織和市場交付應用變得更加容易。

雲原生應用Bundle(CNAB)簡介

雲原生應用Bundle(Cloud Native Application Bundle,CNAB)是一個開源、雲中立的規範,致力於打包和運行分佈式應用。該規範是由微軟、Docker、HashiCorp、Bitnami、Pivo​​tal和很多其他公司創立的。它將跨不同工具鏈的多服務、分佈式應用進行統一管理,將其放到一個一站式的打包格式中。

收益 描述
簡化複雜的部署 借助CNAB,我們可以打包多服務、多格式的分佈式應用。所以,部署很容易就能得到簡化。
開源、雲中立 CNAB bundle可以適應我們所需的各種基礎設施組件或服務。對於多雲策略來講,CNAB是正確的選擇。
可分享的應用 能夠讓開發人員/應用提供商跨團隊、組織和市場共享/交付應用。

CNAB的主要收益

按照CNAB規範,CNAB打包格式能夠帶來如下功能:

  1. 支持面向不同運行時和架構的包。
  2. 內部使用容器來封裝安裝邏輯,所以能夠獨立於底層的雲環境。
  3. 有一個bundle定義文件bundle.json)和一個調用鏡像(invocation image)組成,前者用來定義應用,後者用來安裝應用。調用鏡像的任務是安裝所需的組件到宿主環境中。
  4. CNAB_bundle定義_文件包含瞭如下的信息:
    • 關於bundle的信息,如名稱、bundle版本、描述和關鍵字
    • 關於調用鏡像的信息(installer程序)
    • 本bundle將要安裝的可執行鏡像的列表
    • 本bundle運行所需的憑證路徑或環境變量列表
  5. CNAB調用鏡像包含了一個標準化的文件系統佈局,其中存儲了元數據和安裝數據。
    • 文件系統的層級結構在規範中進行了聲明
    • 主入口(run tool):可執行文件,用來將動作請求(如安裝/更新)轉換成任務序列
    • 運行時元數據(比如Helm charts、Terraform模板等)
    • 用來構建鏡像的文件(如Dockerfile)

基於Docker compose構建的容器應用不易於跨團隊和在不同的環境之間共享和管理。

為了克服這一點,最新版本的Docker App實現了目前的CNAB規範。通過實現CNAB規範,Docker App既可以用來為Compose構建bundle,也可以安裝、升級和卸載任意其他的CNAB bundle。同樣的CNAB bundle可以在任何兼容CNAB的客戶端中使用。

在下一部分的內容中,我們看一下如何將已有的Docker compose應用轉換成新的Docker Application Package。

安裝Docker App

我們有兩種方式來安裝Docker App,要么獨立安裝,要么作為CLI插件。針對Windows、Linux和macOS的預構建靜態二進製文件可以在GitHub發布頁面獲取。在這裡,我使用Linux版本,並將Docker app安裝成一個獨立的工具。

使用Docker Application Package實現跨團隊交付應用 1

圖:Docker App安裝

使用Docker Application Package實現跨團隊交付應用 2

圖:Docker App安裝成功

在下面的樣例中,我們將會看到如何將已有的Compose應用轉換為Docker App項目。

創建新的Helloworld Docker App

Docker App搭建完成之後,我們可以使用已有的Docker compose文件(如下所示),它會啟動一個HTTP echo服務器,當訪問配置好的端口時,服務器會打印指定的文本。

version: '3.2'
services:
  hello:
    image: hashicorp/http-echo
    command: ("-text", "hello world")
    ports:
      - 5678:5678

使用Docker Application Package實現跨團隊交付應用 3

圖:Hello World Docker compose文件

在compose文件所在的目錄中運行docker-app init命令,這樣就能創建一個新的Application Package:

docker app init --single-file hello

使用Docker Application Package實現跨團隊交付應用 4

圖:Hello World Docker App已創建

如果你查看一下Docker Application Package的 hello.dockerapp,會發現它包含了三個YAML文檔:

  • 第一部分包含了元數據,如名稱、版本、描述和維護者。
  • 第二部分描述了應用,實際上就是我們的Compose文件
  • 第三部分是應用的參數

如果你希望將這三個核心文檔放到單獨的YAML文件中的話,那麼可以移除docker app init command命令上的*–single-file*選項。這樣的話,會創建一個新的目錄,而不是單個文件。

使用Docker Application Package實現跨團隊交付應用 5

圖:Docker Application Package文件

編輯元數據

接下來,我們編輯helloworld.dockerapp中的Compose文件部分,引入$text和$port變量。

version: '3.2'
services:
  hello:
    image: hashicorp/http-echo
    command: ("-text", "${text}")
    ports:
      - ${port}:5678

使用Docker Application Package實現跨團隊交付應用 6

圖:修改後的Docker Application Package文件

探查Docker App

在啟動修改後的Docker Application Package之前,我們檢查一下是否一切正常。

使用Docker Application Package實現跨團隊交付應用 7

圖:探查Docker App

Docker App還提供了一個validate命令,能夠用來檢查語法和配置的其他方面。我們跳過這一步,直接渲染應用。

渲染Docker App

render命令將會使用默認值展示compose文件。

使用Docker Application Package實現跨團隊交付應用 8

圖:渲染Docker App

下一步就是部署Docker App項目。在這裡,我們有兩個可選方案,要么將其啟動為Docker原生app應用,要么將其啟動為Compose app應用。

我們採用Compose app方案,隨後將應用推送至DockerHub註冊中心。

啟動Docker App

使用Docker Application Package實現跨團隊交付應用 9

圖:啟動Docker App

使用Docker Application Package實現跨團隊交付應用 10

圖:Docker App的輸出

使用不同的配置來啟動Docker App

儘管Docker Compose配置有默認的端口和文本值,但是我們可以在運行時設置這些值並部署它們。

下面,我們嘗試為端口和文本設置不同的值。

使用Docker Application Package實現跨團隊交付應用 11

圖:通過不同的配置來啟動Docker App

使用Docker Application Package實現跨團隊交付應用 12

圖:Docker App的輸出

我們可以通過docker app status 命令檢查應用的狀態。

在DockerHub上共享Docker App

新的Docker應用打包好之後,帶有默認值的compose配置可以推送至DockerHub,在開發者/團隊之間共享。

使用Docker Application Package實現跨團隊交付應用 13

圖:在DockerHub上共享Docker App

安裝為Docker原生App

應用可以通過運行docker app deploy進行安裝,或者使用渲染後的版本並運行docker stack deploy render/docker-compose.ymldocker-compose –f up。

使用Docker Application Package實現跨團隊交付應用 14

圖:安裝Docker App

升級Docker App

Application Package推送至DockerHub或其他註冊中心之後,我們就可以使用像install、upgrade、uninstall這樣的命令了。

使用Docker Application Package實現跨團隊交付應用 15

圖:升級Docker App

卸載Docker App

使用Docker Application Package實現跨團隊交付應用 16

圖:卸載Docker App

在接下來的章節中,我們會看另外一個例子,它使用了Angular、SpringBoot和PostgreSQL技術棧,我們看一下如何為它創建Docker Application Package。

為Angular、SpringBoot和PostgreSQL應用創建Docker App

如下展示了我們將要使用的Angular、SpringBoot和PostgreSQL應用的compose文件。

version: '3'
services:
   ui:
    build:
      context: .
      dockerfile: UIDockerfile
    ports:
      - '4200:4200'
    networks:
      - samplenet
    links:
      - 'api:api'
  api:
   build:
     context: .
     dockerfile: AppDockerfile
   ports:
     - '8080:8080'
   depends_on:
    - db
   networks:
    - samplenet
   links:
    - 'db:db'
  db:
   build:
    context: .
    dockerfile: DBDockerfile
  volumes:
   - 'postgresdb:/var/lib/postgresql/data'
  environment:
   POSTGRES_USER: postgres
   POSTGRES_PASSWORD: postgres
   POSTGRES_DB: testdb
  ports:
   - '5432:5432'
  healthcheck:
   test:
     - CMD-SHELL
     - 'pg_isready -U postgres'
   interval: 10s
   timeout: 5s
   retries: 5
  networks:
   - samplenet
networks:
samplenet: null
volumes:
postgresdb: {}

上面的compose文件定義瞭如下服務:

  • ui:運行在4200端口上,服務於Angular應用。
  • api:運行在8080端口上,服務於Spring Boot應用。
  • db:運行在5432端口上,服務於postgresdb應用。
  • 上述的服務都使用了samplenet network
  • 持久化卷postgresdb定義是用於db服務的。
  • db服務添加了額外的健康檢查部分,以便於跟踪數據庫的健康狀況。
  • depends_on闡明了服務的依賴關係。當啟動服務的時候,compose將會同時啟動依賴的服務。

在compose文件所在的目錄下,運行docker-app init命令,創建一個新的Application Package:

使用Docker Application Package實現跨團隊交付應用 17

圖:創建新的Application Package

使用Docker Application Package實現跨團隊交付應用 18

圖:生成的Application Package

接下來,我們探查一下,看是否一切正常。

使用Docker Application Package實現跨團隊交付應用 19

圖:探查Application Package

接下來,使用Docker Compose up命令並附加render選項來啟動應用。

使用Docker Application Package實現跨團隊交付應用 20

圖:渲染Application Package

將其推送至DockerHub之後,我們就可以和團隊共享它了,團隊成員能夠執行像install、upgrade和uninstall這樣的任務。

使用Docker Application Package實現跨團隊交付應用 21

圖:推送Application Package到DockerHub

現在,可以通過運行docker app deploy安裝應用,或者使用渲染後的版本並運行docker stack deploy render/docker-compose.ymldocker-compose –f up

使用Docker Application Package實現跨團隊交付應用 22

圖:安裝Application Package

結論

Compose文件難以在不同的環境或跨團隊共享,Docker Application Packages解決了這些問題,使得Compose應用能夠跨不同環境(開發/QA/Staging/生產)實現重用。 Docker App目前還處於體驗模式階段,不能在生產環境中使用。

參考資料

  1. Cloud Native Application Bundle (CNAB)規範
  2. CNAB bundle樣例
  3. Docker App Github

作者介紹:

Karthikeyan Shanmugam(Karthik)**是一位經驗豐富的解決方案架構師,在銀行、金融服務、醫療保健和航空領域的企業應用程序設計和開發方面擁有超過18年以上的經驗。目前,他主要從事技術諮詢,為應用轉換(Application Transformation)領域提供解決方案。

原文鏈接:

Using Docker Application Packages to Deliver Apps Across Teams