Azure Pipelinesを使ってみる ~services編~


はじめに

Azure Pipelinesの機能servicesを使おうとして、いろいろハマったことがあるので、基本的な書き方を簡単にまとめたました。

ここでは例として、nginxコンテナを外部サービスコンテナとして起動し、curlでHTTPリクエストを投げ、疎通確認をしてみます。

公式ドキュメント

ホストVMからリクエストを投げる

ホストVM → nginxコンテナ

では、localhost宛で通信できる。
ただし、nginxコンテナのポートを指定して起動する必要がある。
(optionsでポートの設定をする)

azure-pipelines.yml
resources:
  containers:
  - container: nginx
    image: nginx:latest
    options: -p 8080:80

services:
  nginx-svc: nginx

pool:
  vmImage: 'ubuntu-latest'

steps:
- script: |
    curl http://localhost:8080
  displayName: 'curl'

ちなみに、nginxのポート設定を行わなかった場合、エラーが発生する:

curl: (7) Failed to connect to localhost port 80: Connection refused

コンテナからリクエストを投げる

今度は

コンテナ → nginxコンテナ

2通りの方法でやってみる。

また、リクエスト送信元のコンテナにはcurlコマンドが必要になる。
以下では、ubuntuにcurlをインストールしたイメージkazumad/my-ubuntu(dockerhub)を使うことにする。

※ほんとはジョブのなかでインストールしたいのですが、apt-getでpermission deniedが発生して、インストールできませんでした...
(Initialize containersジョブのログを見ると、vsts_azpcontainerというユーザーを作成したうえでコマンドを実行しているようで、これが原因っぽい?)

containerを使う

Azure Pipelinesの機能(container)でコンテナを立ち上げて、nginxにリクエストを投げる。
この場合、nginxへはservicesで設定した値(例だとnginx-svc)で通信できる。

azure-pipelines.yml
resources:
  containers:
  - container: nginx
    image: nginx:latest
  - container: my-ubuntu
    image: kazumad/my-ubuntu:latest

container: my-ubuntu

services:
  nginx-svc: nginx

pool:
  vmImage: 'ubuntu-latest'

steps:
- script: |
    curl nginx-svc
  displayName: 'curl'

[補足] コンテナのアドレスの名前解決について

servicescontainerを使ってコンテナを起動すると、Azure Pipelinesはコンテナ間で名前解決できるようにDockerネットワークを作成してくれている。

実際にInitialize containersジョブのログの見てみると、以下のようにvsts_networkから始まる名前のネットワークを作成していることがわかる。

/usr/bin/docker network create --label d2053a vsts_network_{ランダムな英数字}

このネットワークは、コンテナ作成時に--networkオプションで指定されている。さらに、サービスコンテナ(nginx)のほうは、servicesで指定した値が--network-aliasオプションで設定されている。

/usr/bin/docker create --name ubuntu_kazumadmyubuntulatest_29249a --label d2053a --network vsts_network_{ランダムな英数字}  ...(省略)... kazumad/my-ubuntu:latest ...(省略)

(省略)

/usr/bin/docker create --name nginx_nginxlatest_6a890c --label d2053a --network vsts_network_{ランダムな英数字} --network-alias nginx-svc ...(省略)... nginx:latest

[補足] containerに指定できるコンテナの条件について

タイトルの通り、containerの機能で起動できるコンテナにはいくつか条件が存在する。
(条件の詳細についてはここでは記述しないので、公式ドキュメント(Container jobs > Requirements)を参照)
ドキュメントによると、Alpineベースのイメージが使えないので、当記事ではubuntuベースのイメージを使用している。

docker runを使う

リクエスト送信元コンテナ(kazumad/my-ubuntu)をdocker runコマンドから起動してcurlを実行する。
この方法だと、上記補足で述べたようなコンテナの制限はない。

azure-pipelines.yml
resources:
  containers:
  - container: nginx
    image: nginx:latest

services:
  nginx-svc: nginx

pool:
  vmImage: 'ubuntu-latest'

steps:
- script: |
    # network名を取得する
    export DOCKER_NETWORK=$(docker network ls | grep "vsts_network" | awk '{print $2}')
    # curlの実行
    docker run --net=${DOCKER_NETWORK} kazumad/my-ubuntu:latest \
    curl "nginx-svc"
  displayName: 'curl'

servicesで設定した値(nginx-svc)で通信できるようするため、Azure Pipelinesが生成するdockerネットワークを利用している。
(dockerネットワークについては上述の「コンテナのアドレスの名前解決について」を参照)

具体的には、ネットワーク名(vsts_network_{ランダムな英数字})をdocker network lsコマンドで取り出し、docker run--netオプションに指定している。