「継続的デリバリ」(CD)を実現できるコンテナクラスタ管理ツール「Spinnaker」
実運用されるソフトウェアのリリースは、かつては入念な準備のうえで行う一大イベントだった。しかし昨今ではソフトウェアの更新サイクルの高速化により、頻繁にソフトウェアのリリースを行うケースが増えている。特にソフトウェアの開発・デバッグサイクルにリリースも組み込んだ手法は「継続的デリバリ(CD)」と呼ばれており、Facebookなど大規模なシステムを運営する企業も採用している。今回はこのCDを支援するツール「Spinnaker」を紹介する。
継続的デリバリとは
最近、特にWebサービス関連業界においては、素早いソフトウェアの改善・改良や新機能追加が求められるようになっている。そのため、開発と並行して自動的にビルドやテストを実行するような「継続的インテグレーション」が普及しつつある。そして昨今ではこれをさらに拡張し、開発と並行してソフトウェアのリリースも自動的に行おうという考え方が出てきた。これが継続的デリバリである。
継続的デリバリでは、対象とするソフトウェアにおいて常時リリース可能なバージョンとそれをビルドしてインストール可能にしたもの、そしてそれを自動的に運用環境にデプロイする手段を用意しておく。この3つが常時存在することで、迅速に成果物を実運用環境に投入できるようになる。
常時リリース可能なバージョンを用意するというのは、バージョン管理システムの運用によって実現できる。たとえば新規機能開発や修正はすべて別のブランチで行い、作業が完了してテスト済みのものだけをメインブランチ(リリースブランチ)にマージするようにすれば良い。また、ビルドについてはTravis CIやJenkinsなどの継続的インテグレーションツールを利用することで実現できる。
いっぽうで、自動的に運用環境にデプロイする手段については運用環境に依存することもあり、決定的な支援ツールはなかなか出てこなかった。
たとえば以前「カスタムRPMや独自yumリポジトリではじめるソフトウェア管理術」や「独自Debパッケージやaptリポジトリを使ったサーバー管理術」といった記事で紹介したように、ソフトウェアをRPMやDEB形式のパッケージにしてデプロイするという手法もあるが、これらは信頼性は高いものの「クリック1つでデプロイ」とはいかない。
しかし、最近では特に大規模なシステムを運用するような事業者ではクラウド環境を利用してサービスをデプロイするケースが増えてきた。このような環境ではクラウド環境のAPIを利用することで、スクリプトやツールを使ってデプロイを行える。これを発展させたデプロイ管理するツールも登場した。今回紹介する「Spinnaker」もその1つである。
大規模なインフラを活用するNetflixが開発した「Spinnaker」
Spinnakerは、動画配信サービスを手がける米Netflixが2015年に公開したツールだ。Webブラウザ経由で操作するフロントエンド(Web UI)と、さまざまなクラウドインフラに対応するバックエンドの組み合わせで構築されている。GUIでデプロイを実行できるだけでなく、特定の処理の完了をトリガーに処理を実行するパイプライン機能が提供されているのが特徴だ(図1)。
SpinnakerはAmazon Web Services(AWS)やGoogle Cloud Platform(GCP)といったパブリッククラウドで利用できるほか、KubernetesやOpenStackといったプライベートクラウド構築で使われている技術についてもサポートされている。今回は、このSpinnakerをKubernetesクラスタで利用するためのインストール・設定方法や、利用できる機能について紹介する。
なお、今回はさくらのクラウドを使用し、CentOS 7.4およびKubernetes 1.52を使用してマスターサーバー1台とクラスタノード4台からなるKubernetesクラスタを構築したものを検証環境として使用した。Spinnakerのインストールおよび動作にはクラスタ内でDNS(kube-dns)が動いている必要があるので、この設定も行っている。
Spinnakerのインストール
Spinnakerは表1のような複数のコンポーネントから構成されており、これらをすべて適切に設定・インストールする必要がある。
名称 | 説明 |
---|---|
Deck | Web UIを提供する |
Gate | 各種操作を実行するAPIのエンドポイントを提供する |
Orca | オーケストレーションを行う |
Clouddriver | デプロイなどのクラウド環境の操作を行う |
Front50 | メタデータやパイプライン、プロジェクト、通知の管理などを行う |
Rosco | 仮想マシンイメージの管理を行う |
Igor | 継続的インテグレーション経由で処理を行うためのトリガーを管理する |
Echo | イベントや通知の管理を行う |
Fiat | 認証機能を提供する |
そのため、Spinnaker 1.0からはインストールや設定を行うための専用ツール「halyard」が導入された。Spinnakerをインストールするにはまずこのhalyardをインストールし、続いてhalyardが提供する「hal」コマンドを使ってコンポーネントの設定やインストールを行うことになる。
halyardのインストール方法については公式ドキュメントでも解説されているが、直接作業用のマシンにインストールする方法と、halyardがインストールされたコンテナを利用する方法がある。Spinnakerが提供しているインストールスクリプトはUbuntu 14.04/16.04向けとなっていることもあり、今回はコンテナをDocker経由で実行する方法を選択した。
また、Spinnakerの各コンポーネントのインストールについても、これらを直接ホストにインストールする方法(Local Debian)と、クラウド上に分散インストールする方法(Distributed)が用意されている。対応するクラウドは次のとおりだ。
- App Engine
- Amazon Web Services
- Azure
- DC/OS
- Google Compute Engine
- Kubernetes (legacy)
- Kubernetes V2 (manifest based)
- Openstack
- Oracle
今回はKubernetesを利用するので後者(Distributed)を選択し、Kubernetes上にSpinnakerの各コンポーネントをインストールする。
そのほか、Spinnakerの各種設定を保存する永続的ストレージサービスや、使用するイメージを格納するリポジトリ(Docker Registry)も必要になる。今回はこれらについてもコンテナを利用して稼動させることとした。
ストレージサービスの準備
Spinnakerでは各種設定を保存するストレージとして、次のものが利用できる。
- Azure Storage
- Google Cloud Storage
- Minio
- S3
なお、ドキュメントではRedisも利用できるとされているが、プロダクション環境での利用は推奨されていない。そのため今回はS3互換のストレージサービスであるMinioを利用する。
Minioはコンテナイメージの形でも提供されており、Kubernetesの管理下で実行させることで冗長化や管理が容易になるが、今回はDockerを利用してKubernetesのマスターノード上で稼動させることとした。作業手順としては次のようになる。
まず、Minioコンテナ内にマウントさせるデータや設定保存用のディレクトリを作成する。今回は/var/minio以下に「data」および「config」の2つのディレクトリを用意した。
# mkdir -p /var/minio/{data,config}
続いてこのディレクトリをマウントするように設定して「minio/minio」イメージからコンテナを作成する。
# docker run -d -p 9001:9000 --name minio -v /var/minio/data:/data -v /var/minio/config:/root/.minio minio/minio server /data
これで、「minio」という名称でコンテナが作成される。なお、デフォルトでminioは9000番ポートで待ち受けを行うが、このポートはSpinnakerも使用するため、念のため異なるポート(9001番ポート)で待ち受けするよう設定している。
コンテナの作成後、「docker logs」でこのコンテナの出力を確認すると、MinioのストレージにアクセスするためのAccessKeyおよびSecretKeyが表示される。これはあとでSpinnakerの設定で利用するので、適宜コピーしておこう。
$ docker logs minio Created minio configuration file successfully at /root/.minio Drive Capacity: 12 GiB Free, 15 GiB Total Endpoint: http://172.17.69.2:9000 http://127.0.0.1:9000 AccessKey: YYNO7REGTXUGDW8L5KZW SecretKey: mvuhy4qtdqt6lgnTTpXSsGDM3m86yQWnrvu8HjOh Browser Access: http://172.17.69.2:9000 http://127.0.0.1:9000 Command-line Access: https://docs.minio.io/docs/minio-client-quickstart-guide $ mc config host add myminio http://172.17.69.2:9000 YYNO7REGTXUGDW8L5KZW mvuhy4qtdqt6lgnTTpXSsGDM3m86yQWnrvu8HjOh Object API (Amazon S3 compatible): Go: https://docs.minio.io/docs/golang-client-quickstart-guide Java: https://docs.minio.io/docs/java-client-quickstart-guide Python: https://docs.minio.io/docs/python-client-quickstart-guide JavaScript: https://docs.minio.io/docs/javascript-client-quickstart-guide .NET: https://docs.minio.io/docs/dotnet-client-quickstart-guide
Docker Registryの設定
続いて、使用するイメージを保存するプライベートリポジトリの準備を行う。
プライベートリポジトリを利用するための設定についてはKubernetesによるDockerコンテナ管理入門記事で以前紹介しているので基本的にはこれに従えば良いのだが、注意点としてDockerではリポジトリへの接続にSSL/TLSを利用するのがデフォルトとなっており、SSL/TLSに非対応、もしくはSSL/TLSに対応していてもいわゆる自己署名証明書を利用するリポジトリの場合、設定が煩雑になってしまう。そのため、今回は適切なSSL/TLS証明書を用意したうえで、SSL/TLS対応のプライベートリポジトリを実行させることとした。
この場合、Kubernetesクラスタ内から証明書に対応したホスト名でプライベートリポジトリにアクセスできなければならない。そのため適切なDNS設定などを事前に行っておく必要がある。
さて、CentOSの「docker-distribution」パッケージを使ってプライベートリポジトリを運用する場合、次のように設定ファイル(/etc/docker-distribution/registry/config.yml)に記述を追加することで、SSL/TLS接続を利用できるようになる。
version: 0.1 log: fields: service: registry storage: cache: layerinfo: inmemory filesystem: rootdirectory: /var/lib/registry http: addr: <待ち受けに使用するIPアドレスもしくはホスト名>:5000 tls: certificate: <証明書ファイルのパス名> key: <秘密鍵ファイルのパス名> auth: htpasswd: realm: "docker registry" path: *[<htpasswdファイルのパス名>]
また、ここではhtpasswdファイルを利用してユーザー管理を行うよう設定している。これにより、リポジトリへのアクセスにあらかじめ用意しておいたユーザー名およびパスワードでの認証を必要とするよう設定できる。たとえば「admin」というユーザーを作成したい場合、次のようにしてこのユーザーを含むhtpasswdファイルを作成できる。
$ htpasswd -cB htpasswd admin New password: ←パスワードを入力 Re-type new password: ←同じパスワードを再度入力 Adding password for user admin
これらに加えて、docker-distributionサービスはデフォルトでは5000番ポートで待ち受けを行うので、このポートにクラスタ内からアクセスできるようファイアウォールの設定を行っておこう。
正しく設定が行えているかどうかは、次のように「docker login」コマンドでログインを試みることで確認できる。
$ docker login <設定したドメイン名>:5000 Username: admin Password: ←設定したパスワードを入力 Login Succeeded
このように「Login Succeeded」と表示されれば成功だ。
halyardコンテナの実行
永続的ストレージおよびプライベートリポジトリを用意したら、続いてhalyard環境を含むコンテナを実行し、そこでSpinnakerの設定およびデプロイ作業を行っていく。halyard環境を含むコンテナは、次のようにして実行できる。
# mkdir ~/hal # docker run -d --name halyard -v ~/hal:/root/.hal -v <使用するKubernetesの設定ファイル>:/root/.kube/config gcr.io/spinnaker-marketplace/halyard:stable
なお、ここでは~/halというディレクトリを作成し、これをコンテナ内の/root/.halにマウントしている。このディレクトリにはhalyardの設定ファイルなどが保存される。また、Kubernetesの設定が保存された設定ファイルも同様にコンテナ内にマウントしている。この設定ファイルは通常はユーザーのホームディレクトリ以下の.kubeディレクトリ内に「config」というファイル名で保存されている。このファイルの作成方法については「KubernetesによるDockerコンテナ管理入門」記事の『「kubectl」コマンドを利用するための設定』項目で解説しているので、こちらを参照して欲しい。このファイル内にはKubernetesへのアクセスに使用する情報などが含まれており、これがないと適切にKubernetesへのデプロイが行えないので注意したい。
コンテナが起動したら、次のようにしてコンテナ内のシェルにアクセスする。
$ docker exec -ti halyard bash
使用するSpinnakerバージョンとプライベートリポジトリ設定
続いて、コンテナ内のシェルから「hal」コマンドを実行してデプロイのための各種設定を行っていく。
まず、デプロイするSpinnakerのバージョンを指定する。今回は記事作成時点の最新版であるバージョン1.6.0を使用することとした。
# hal config version edit --version 1.6.0 + Get current deployment Success + Edit Spinnaker version Success + Spinnaker has been configured to update/install version "1.6.0". Deploy this version of Spinnaker with `hal deploy apply`.
次に、Dockerプライベートリポジトリにアクセスするための情報(docker-registry account)を登録する。ここでは「test-repo」という名称を指定し、さらにアクセスに使用するユーザー名として「admin」を指定しているが、これらは適宜適切な名前に変更してほしい。
# hal config provider docker-registry account add test-repo --address <リポジトリのホスト名>:5000 --username admin --password Your docker registry password: ←パスワードを入力 + Get current deployment Success + Add the test-repo account Success Problems in default.provider.dockerRegistry.test-repo: - WARNING Your docker registry has no repositories specified, and the registry's catalog is empty. Spinnaker will not be able to deploy any images until some are pushed to this registry. ? Manually specify some repositories for this docker registry to index. + Successfully added account test-repo for provider dockerRegistry.
続いてDocker Registry機能のサポートを有効にする。
# hal config provider docker-registry enable + Get current deployment Success + Edit the dockerRegistry provider Success Problems in default.provider.dockerRegistry.test-hylom-net: - WARNING Your docker registry has no repositories specified, and the registry's catalog is empty. Spinnaker will not be able to deploy any images until some are pushed to this registry. ? Manually specify some repositories for this docker registry to index. + Successfully enabled dockerRegistry
Kubernetesプロバイダの設定
Spinnakerの機能は「プロバイダ」という形で提供されており、利用するクラウドインフラストラクチャに対応するプロバイダを有効にする必要がある。今回はKubernetesを利用するので、「kubernetes」プロバイダを有効にすれば良い。
まず、kuberneteで使用するアカウントを追加する。ここでは「admin」という名前とした。また、先に登録したdocker-registry accountを「--docker-registries」オプションで指定しておく。
# hal config provider kubernetes account add admin --docker-registries test-repo + Get current deployment Success + Add the admin account Success + Successfully added account admin for provider kubernetes.
続いてkubernetesプロバイダを有効にするよう設定する。
# hal config provider kubernetes enable + Get current deployment Success + Edit the kubernetes provider Success Problems in default.provider.kubernetes.admin: - WARNING You have not specified a Kubernetes context in your halconfig, Spinnaker will use "default-context" instead. ? We recommend explicitly setting a context in your halconfig, to ensure changes to your kubeconfig won't break your deployment. ? Options include: - default-context + Successfully enabled kubernetes
永続的ストレージ設定
今回は永続的ストレージとしてS3互換のminioを使用するので、その情報を登録する。このとき、minioが待ち受けを行っているホストおよびポート番号と、前述したAccessKey、SecretKeyの情報が必要となる。
# hal config storage s3 edit --endpoint http://<minioの待ち受けホスト>:<ポート> --access-key-id <AccessKey> --secret-access-key Your AWS Secret Key.: ←minioのSecretKeyを入力 + Get current deployment Success + Get persistent store Success Generated bucket name: spin-89567809-7f6b-418f-bef8-a9ece00fd822 + Edit persistent store Success Problems in default.persistentStorage: - WARNING Your deployment will most likely fail until you configure and enable a persistent store. + Successfully edited persistent store "s3".
続いてストレージとしてS3を使用するよう指定する。
# hal config storage edit --type s3 + Get current deployment Success + Get persistent storage settings Success + Edit persistent storage settings Success + Successfully edited persistent storage.
デプロイ設定
今回はKubernetes上に分散デプロイを行うので、次のようにしてその設定を行う。
# hal config deploy edit --type distributed --account-name admin + Get current deployment Success + Get the deployment environment Success + Edit the deployment environment Success + Successfully updated your deployment environment.
Web UIのURL設定
Spinnakerでは各種操作をWebブラウザ経由で行うが、デフォルト設定ではこのWeb UIのURLのホスト名が「localhost」になっている。そのため、これを適切なホスト名に変更しておこう。詳しくは後述するが、今回はKubernetesのNodePort機能を使ってマスターノードへのアクセスをDeckおよびGateコンテナに転送する構成を取るので、次のように設定を行った。
# hal config security ui edit --override-base-url http://<マスターノードのIPアドレス>:30009 + Get current deployment Success + Get UI security settings Success + Edit UI security settings Success Problems in default.security: - WARNING Your UI or API domain does not have override base URLs set even though your Spinnaker deployment is a Distributed deployment on a remote cloud provider. As a result, you will need to open SSH tunnels against that deployment to access Spinnaker. ? We recommend that you instead configure an authentication mechanism (OAuth2, SAML2, or x509) to make it easier to access Spinnaker securely, and then register the intended Domain and IP addresses that your publicly facing services will be using. # hal config security api edit --override-base-url http://<マスターノードのIPアドレス>:30008 + Get current deployment Success + Get API security settings Success + Edit API security settings Success
なお、この設定によってKubernetesクラスタを構成する各ノードからSpinnakerにアクセスできるようになるため、ファイアウォールなどを適切に設定してアクセスを制限しておく必要がある。
デプロイの実行
以上で設定は完了だ。この状態で「hal deploy apply」コマンドを実行するとSpinnakerの構成コンポーネントがKubernetesにデプロイされる。
# hal deploy apply
なお、デプロイに失敗した場合はその旨が表示され、作業が中断される。Spinnakerの各コンポーネントは「spinnaker」というネームスペース上に展開されるので、次のように稼動しているPodを確認し、トラブルシューティングを行うとよいだろう。
$ kubectl -n spinnaker get pod NAME READY STATUS RESTARTS AGE spin-clouddriver-bootstrap-v000-qjn05 0/1 Running 0 1d spin-clouddriver-v000-jbndd 0/1 Running 0 1d spin-deck-v000-7960f 1/1 Running 0 1d spin-echo-v000-v3h9s 1/1 Running 0 1d spin-gate-v000-9dx0j 1/1 Running 0 1d spin-igor-v000-m4zw2 1/1 Running 0 1d spin-orca-bootstrap-v000-rf3rl 1/1 Running 0 1d spin-orca-v000-62j22 1/1 Running 0 1d spin-redis-bootstrap-v000-cpbjh 1/1 Running 0 1d spin-redis-v000-b7cjw 1/1 Running 0 1d spin-rosco-v000-bp4hz 1/1 Running 0 1d
また、「hal deploy clean」コマンドを実行すればデプロイされたコンポーネントがすべて削除される。
ポートの転送設定
Spinnakerをデプロイすると、次のように多数のサービスが作成される。このうち、「spin-deck」サービスがWeb UIを、「spin-gate」サービスがSpinnakerをコントロールするためのAPIを提供するものだ。
$ kubectl -n spinnaker get svc NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE spin-clouddriver 10.254.102.221 <none> 7002/TCP,8008/TCP 1d spin-clouddriver-bootstrap 10.254.162.60 <none> 7002/TCP,8008/TCP 1d spin-deck 10.254.132.106 <none> 9000/TCP,8008/TCP 1d spin-echo 10.254.28.49 <none> 8089/TCP,8008/TCP 1d spin-front50 10.254.121.107 <none> 8080/TCP,8008/TCP 1d spin-gate 10.254.98.155 <none> 8084/TCP,8008/TCP 1d spin-igor 10.254.82.125 <none> 8088/TCP,8008/TCP 1d spin-orca 10.254.116.148 <none> 8083/TCP,8008/TCP 1d spin-orca-bootstrap 10.254.89.221 <none> 8083/TCP,8008/TCP 1d spin-redis 10.254.178.149 <none> 6379/TCP,8008/TCP 1d spin-redis-bootstrap 10.254.27.173 <none> 6379/TCP,8008/TCP 1d spin-rosco 10.254.54.33 <none> 8087/TCP,8008/TCP 1d
SpinnakerのWeb UIにアクセスするにはこのspin-deckサービスにWebブラウザでアクセスすれば良いのだが、今回のように独自に構築したKubernetesクラスタではデフォルトでは外部からクラスタ内のサービスに直接アクセスできない。そのため、KubernetesのNodePort機能を利用してこれらのサービスに個別のポートを割り当て、さらにプロクシを用意することで外部からアクセスできるように設定する。
まず、「kubectl edit」コマンドでspin-deckおよびspin-gateサービスの設定を編集し、NodePort機能を利用してポートを割り当てる。
$ kubectl -n spinnaker edit svc spin-deck : : spec: clusterIP: 10.254.132.106 ports: - name: http port: 9000 protocol: TCP targetPort: 9000 nodePort: 30009 ←nodePort設定を追加 - name: monitoring port: 8008 protocol: TCP targetPort: 8008 selector: load-balancer-spin-deck: "true" sessionAffinity: None type: NodePort ←type:をNodePortに変更 status: loadBalancer: {}
$ kubectl -n spinnaker edit svc spin-gate : : spec: clusterIP: 10.254.98.155 ports: - name: http port: 8084 protocol: TCP targetPort: 8084 nodePort: 30008 ←nodePort設定を追加 - name: monitoring port: 8008 protocol: TCP targetPort: 8008 selector: load-balancer-spin-gate: "true" sessionAffinity: None type: NodePort ←type:をNodePortに変更 status: loadBalancer: {}
これで、spin-deckの9000番ポートに30009番ポートから、spin-gateの8084番ポートに30008番ポートからアクセスできるようになる。
$ kubectl -n spinnaker get svc NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE spin-clouddriver 10.254.102.221 <none> 7002/TCP,8008/TCP 1d spin-clouddriver-bootstrap 10.254.162.60 <none> 7002/TCP,8008/TCP 1d spin-deck 10.254.132.106 <nodes> 9000:30009/TCP,8008:32545/TCP 1d spin-echo 10.254.28.49 <none> 8089/TCP,8008/TCP 1d spin-front50 10.254.121.107 <none> 8080/TCP,8008/TCP 1d spin-gate 10.254.98.155 <nodes> 8084:30008/TCP,8008:32468/TCP 1d spin-igor 10.254.82.125 <none> 8088/TCP,8008/TCP 1d spin-orca 10.254.116.148 <none> 8083/TCP,8008/TCP 1d spin-orca-bootstrap 10.254.89.221 <none> 8083/TCP,8008/TCP 1d spin-redis 10.254.178.149 <none> 6379/TCP,8008/TCP 1d spin-redis-bootstrap 10.254.27.173 <none> 6379/TCP,8008/TCP 1d spin-rosco 10.254.54.33 <none> 8087/TCP,8008/TCP 1d
以上で設定は完了だ。Kubernetesクラスタを構成するノードの30009番ポートにブラウザでアクセスすれば、Spinnakerの管理画面が表示される。
Spinnakerでのデプロイ管理
続いては、Spinnakerを使ってクラスタ上にアプリケーションをデプロイする流れについて紹介していこう。
「application」を作成する
Spinnakerでは「application(アプリケーション)」という単位でアプリケーションを管理する。applicationに関する操作は、はWeb UIの「Application」タブで行える(図2)。
それでは、まずは実際にapplicationを作成してみよう。画面右上の「Actions」をクリックし、続いて表示される「create Application」メニュー項目をクリックする。すると「New Application」というダイアログが表示されるので、必要事項を入力して「Create」をクリックする(図3)
ここで必須なのは「Name」(名前)と「Owner Email」(所有者のメールアドレス)だけで、残りは後からでも設定可能だ。これらを入力して「Create」をクリックするとapplicationが作成され、詳細画面が表示される。この画面では表2のようなタブが用意されており、たとえば「Clusters」ではapplicationに関連したコンテナの情報を確認できる(図4)。
タブ名 | 行える設定や表示される情報 |
---|---|
Pipeline | パイプラインを利用したデプロイ管理 |
Clusters | applicationに関連するコンテナ |
Tasks | 実行した/実行するタスク |
Load Balancers | ロードバランサ管理 |
Security Groups | ネットワークトラフィックに関するアクセス管理 |
Config | applicationに対する各種設定 |
サーバーの作成
「Clusters」タブからは、手動でKubernetesクラスタ上にPodを作成する操作を行える。なお、SpinnakerはKubernetes以外のクラスタ環境にも対応しているため、KubernetesにおけるPodを「Server」と呼んでいる。以下でもこれに準じてPodを「サーバー」と呼ぶことにする。
画面上に表示されている「+」ボタンをクリックすると作成するサーバーに関する情報を入力するダイアログが表示されるので、ここに必要事項を入力して「Create」をクリックする(図5)。
すると作業の進捗を表示する画面が表示され、作業が完了するとその旨が表示される(図6)。
その後「Clusters」画面に戻ると、作成されたサーバーが表示される(図7)。
なお、ここで作成されたサーバーはKubernetesのReplicaSet機能を使って作成される。そのため、レプリカ数の指定なども可能だ。さらにコマンドや環境変数、使用するポートやリソースなどのオプションを指定することもできる(図8)。
作成したサーバーに対する各種操作は「Server Group Actions」ドロップダウンメニューから行える(図9)。
ちなみにここから実行できる「Destroy(削除)」と「Disable(無効化)」の違いだが、Destroyではサーバーが削除されるのに対し、Disableでは削除は行われず、ロードバランサに対しそのサーバーへのルーティングを行わないよう設定するという違いがある。
パイプラインの作成
継続的インテグレーションや継続的デリバリでは、なんらかの通知をトリガーとして処理を実行し、その処理が完了した際にそれを受けて続く処理を実行する、という流れを「パイプライン」と呼ぶ。Spinnakerではあらかじめパイプラインを設定しておくことで、自動的にクラスタ内にコンテナをデプロイできる仕組みとなっている。
パイプラインを作成するには、application画面の「PIPELINE」タブを開き、「Configure a new pipeline」をクリックする(図10)。
「Create New Pipeline」ダイアログが表示されるので、ここでパイプライン名(「Pipeline Name」)を入力して「Create」をクリックする(図11)。
すると新たなパイプラインが作成され、パイプラインの内容を設定する画面が表示される(図12)。
ここで、まずはパイプラインを起動するトリガーの設定などの設定(Configuration)を行うこととなる。たとえば「Add Trigger」をクリックすると、パイプラインを起動するトリガーを指定できる。トリガーには定期的に実行する「CRON」やGitリポジトリへのプッシュを検知して実行する「Git」、Jenkinsと連携する「Jenkins」などさまざまなものが利用できるが、今回はDocker Registryを監視し、指定されたイメージの新たなバージョンがプッシュされたら実行を開始する「Docker Registry」を利用する(図13)。なお、ここで選択できるのはSpinnakerのデプロイ時に登録しておいたDocker Registryのみなので注意したい。
続いて「Add Stage」をクリックし、パイプラインで実行する処理を追加していく(図14)。
ここではまず「Type」で実行する処理の内容を指定する。ここでは表3のような処理を選択可能だ。
名称 | 説明 |
---|---|
Check Preconditions | 事前に実行された処理の進行状況を確認する |
Delete (Manifest) | Kubernetesオブジェクトを削除する |
Deploy | イメージをデプロイする |
Deploy (Manifest) | YAML/JSON形式のKubernetes設定ファイルからデプロイを行う |
Destroy Server Group | サーバーを削除する |
Disable Server Group | サーバーを無効にする |
Enable Server Group | サーバーを有効にする |
Find Image from Cluster | クラスタ内に存在するイメージを検索する |
Jenkins | Jenkinsのジョブを実行する |
Manual Judgment | 手動で管理者の判断を待つ |
Pipeline | パイプラインを実行する |
Resize Server Group | サーバーのレプリカ数を変更する |
Run Job | コンテナを実行する |
Scale (Manifest) | Kubernetesオブジェクトをスケールさせる |
Scale Down Cluster | クラスタをスケールダウンさせる |
Script | スクリプトを実行する |
Shrink Cluster | クラスタを縮小する |
Undo Rollout (Manifest) | ロールバックを実行する |
Wait | 指定した時間待機する |
Webhook | Webhookを使ってジョブを実行する |
今回はイメージをデプロイする「Deploy」を指定した。この場合、「Deploy Configuration」という項目が表示され、ここでデプロイするサーバーの設定を行える。デプロイ設定ではサーバーの作成時と同様にコンテナイメージや各種オプションの設定などが行えるのだが、それに加えてデプロイ完了後に既存のサーバーを無効化/削除するための「Strategy」指定も可能だ(表4)。
名称 | 説明 |
---|---|
Red/Black | デプロイ完了後に既存のサーバーを無効にする |
Highlander | デプロイ完了後に既存のサーバーを削除する |
Custom | あらかじめ用意しておいた任意の処理を実行する |
None | デプロイのみを実行し既存のサーバーはそのまま放置する |
ここで「Red/Black」や「Highlander」を指定すれば、デプロイの完了後に古いイメージで動いているコンテナを無効化/削除する処理を自動で実行できる。今回は「Highlander」を指定し、デプロイ完了後に古いコンテナを削除するよう設定した。
設定が完了したら、画面右下の「Save Changes」をクリックすることで設定を保存できる。続いてPiplelines画面に戻り、作成したパイプラインの「Start Manual Execution」をクリックすることで手動でパイプラインを起動してテストできる(図15)。
これで、「コンテナイメージがプッシュされたらそのイメージから新たなコンテナを作成し、古いコンテナを削除する」という操作を自動化できるようになった。ただ、筆者の環境では既存のタグと同名のタグでイメージをプッシュした場合はパイプラインが起動せず、新しいタグ名を指定しないと正常に動作しなかった。
また、パイプラインの実行結果はPipelines画面で確認できる(図16)。
さまざまな処理を自動化可能、ただし独自に構築したクラウドで利用するには注意が必要か
今回はコンテナイメージのプッシュをトリガーにしてそこから自動的にコンテナを作成する、というシンプルなデプロイ方法を紹介したが、Spinnakerではこれ以外にもJenkinsと連動させたり、独自にビルド処理を実行するといったさまざまな処理を実現できる。ユーザーインターフェイスの完成度も高く、うまく活用することでデプロイ作業を効率化できる。
ただ、注意したいのが作成したコンテナを外部に公開する(外部からコンテナに通信をルーティングする)処理についてはロードバランサの実装に依存する点だ。Google Cloud PlatformやMicrosoft Azureといったクラウド環境ではKubernetesと統合されたロードバランサが提供されているが、独自に構築したKubernetesクラスタの場合、Kubernetesと連携して動作するロードバランサを用意するのは簡単ではない。そのため、KubernetesのNodePort機能を使うような設定と組み合わせるといった工夫が必要だろう。