この記事は Cloud Foundry Advent Calendar 22日目の記事です。
はじめに
この記事では Cloud Foundry Container Runtime (CFCR) を Microsoft Azure にデプロイする試みを紹介します。
そもそもの話として「CFCR とは何か」「今までの Cloud Foundry (CFAR) はどうなるのか」といった説明が必要かとは思いますが、非常に丁寧な解説記事があるのでここでは割愛させて頂きます。
2017年12月22日時点において、CFCR がサポートしているクラウドプロバイダは、GCP, vSphere, AWS, OpenStack の 4 つです。
私の職場では Azure を利用することが多いのですが、 残念ながら CFCR の Azure サポートの予定は直近ではない ようです。
ならば、自分でどうにか動かしてみよう、というのが本記事の趣旨になります。
ニッチな話題であり、どのくらい興味をお持ちの方がいるかわかりませんが、お付き合い頂けますと幸いです。
【2018/03/28 更新】 Azure サポートの最初のプルリクエストが発行されました。
https://github.com/cloudfoundry-incubator/kubo-release/pull/191https://github.com/cloudfoundry-incubator/kubo-deployment/pull/285
【2018/05/03 更新】
上記のプルリクエストは スパイク に利用され、一旦クローズされました。
CFCR チームが正式に Azure サポートに着手する際には改めて活用されるかもしれないようです。
【2018/7/6 更新】
最初のプルリクエストをベースにした新しいプルリクエストが発行されました。
- https://github.com/cloudfoundry-incubator/kubo-release/pull/223
- https://github.com/cloudfoundry-incubator/kubo-deployment/pull/320
このプルリクエストは bosh-agent のプルリクエスト に依存しており、こちらがマージされるまではペンディングのようです。
⇒ 2018/10/12 マージされました。
⇒ 2018/10/16 experimental の扱いで Azure 対応された、CFCR v0.23.0 がリリース されました。
⇒ 2018/11/9 CFCR v0.24.0 がリリース され、Azure 対応はアルファ扱いからベータ扱いになりました。
正式に Azure サポートが完了したら、この記事も書き直そうかと思います。
※ CFCR は本記事執筆時点において開発段階にあり、今後実装が大きく変わる可能性もあります(⇒ 【2018/10/1 更新】: BOSH Director のデプロイ方法などが変わりました)。したがって、本記事に記載した手順を実行した結果について、筆者は一切の責任を負いかねます。ただし、誤りの指摘等につきましては歓迎致しますのでよろしくお願いします。
0. 前提条件
今回の検証では、kubo-deployment (7bbf17aef5) をベースに、Azure 用のカスタマイズを加えた kubo-deployment を利用します。
また、事前に
を済ませておく必要があります。
1. IaaS リソースの準備
CFCR のデプロイに必要な Azure リソースを用意します。
GCP のデプロイ等では、 Terraform が利用されていますが、ここでは Azure Resource Manager Template (AWS の CloudFormation のようなもの) を利用します。
上記のテンプレートを利用すると、 Azure 上に以下のリソースを用意します。
- リソースグループ
- ストレージアカウント
- 仮想ネットワーク
- ネットワークセキュリティグループ ✕ 2
- パブリック IP アドレス ✕ 2
- ロードバランサー
- 仮想 NIC
- 仮想マシン
以下のリンクから Azure Portal にログインすると、テンプレートに設定するパラメータを入力するフォーム画面が現れます。
パラメータ名 | 必須項目 | デフォルト値 | 説明 |
---|---|---|---|
vmName | YES | azure-vm | CFCR のデプロイ作業をおこなう踏み台 VM の名前 |
ubuntuOSVersion | NO | 16.04.0-LTS | VM の OS バージョン (Ubuntu のみ対応) |
adminUsername | YES | VM のログインユーザ名 | |
sshKeyData | YES | VM の SSH ログインに使う RSA 公開鍵 | |
tenantID | YES | サービスプリンシパルのテナント ID | |
clientID | YES | サービスプリンシパルのクライアント ID | |
clientSecret | YES | サービスプリンシパルのクライアントシークレット | |
_artifactsLocation | NO | https://raw.githubusercontent.com/a09-capf/kubo-deployment/azure/docs/user-guide/platforms/azure/ | このテンプレートのロケーションのベース URL |
上記のパラメータを入力し、Azure Marketplace の使用条件に同意して、「購入」ボタンをクリックすると、リソースのプロビジョニングが始まります。
10 分程でプロビジョニングは完了します。
2. BOSH Director のデプロイ
プロビジョニングされた 仮想マシンに SSH でログインします。ログインに必要な情報は、Azure Portal で当該の仮想マシンを選択して、「概要」 → 「接続」 と進むと確認できます。
仮想マシンにログインしたら、今回の検証で使う kubo-deployment を clone します。
$ git clone -b azure https://github.com/a09-capf/kubo-deployment.git
$ cd kubo-deployment
デプロイに使ういくつかの環境変数を設定します。
$ export kubo_env=~/kubo-env
$ export kubo_env_name=kubo
$ export kubo_env_path="${kubo_env}/${kubo_env_name}"
$ export BOSH_ENV=$kubo_env_path
$ export BOSH_NAME=$kubo_env_name
デプロイメントの情報を格納するディレクトリを作成します。
$ mkdir -p "${kubo_env}"
BOSH と CFCR のデプロイ時に埋め込むパラメータのテンプレートファイルを生成します。
./bin/generate_env_config "${kubo_env}" ${kubo_env_name} azure
上記のスクリプト は、 IaaS 非依存の共通パラメータ一覧 と IaaS ごとに異なるパラメータ一覧 を結合して、${kubo_env_path}/director.yml
と ${kubo_env_path}/director-secrets.yml
という 2 つのテンプレートファイルを生成します。後者は機密情報を記載するファイルなので、間違って git push などしないように十分に注意してください。
生成されたテンプレートファイルをそれぞれ編集します。
基本的に以下の例と同じで構わないので、xxx
になっている部分のみご自身の環境に合わせて記載してください。
internal_ip: 10.0.1.252 # Internal ip address of the BOSH director. Please select an available ip address in the network you wish to deploy into.
internal_cidr: 10.0.1.0/24 # CIDR range that BOSH will deploy to
internal_gw: 10.0.1.1 # internal gateway
director_name: bosh # user friendly Director name
dns_recursor_ip: 168.63.129.16 # Azure が提供する DNS リゾルバ
kubo_release_url: https://storage.googleapis.com/kubo-public/kubo-release-latest.tgz
worker_count: 1 # リソース節約のため 3 → 1 に変更
routing_mode: iaas
kubernetes_master_host: xx.xx.xx.xx # ロードバランサー (cfcr-lb) のパブリック IP アドレスを記載する
# master_target_pool: # コメントアウトする
authorization_mode: rbac # なぜか abac だと CFCR デプロイ時に権限エラーが発生したので rbac にする
vnet_name: boshvnet-crp # Azure Virtual Network Name
subnet_name: CFCR # Azure Subnet Name
subscription_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx # Azure Subscription ID
resource_group_name: xxx # Azure Resource Group Name
storage_account_name: cfcrsa # Azure Storage Account Name
default_security_group: nsg-cfcr # Azure Network Security Group
iaas: azure
tenant_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx # Azure Service Principal TENANT_ID
client_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx # Azure Service Principal CLIENT_ID
client_secret: xxxxxxxxxxxxxxxxxxxxxx # Service Principal CLIENT_SECRET
なお、CFCR は CFAR と ルーティング機能を共用する こともできますが、今回は CFCR を単体でデプロイするので、 Azure のロードバランサーを使用する設定にしています。
テンプレートを編集したら、 BOSH Director をデプロイします。
$ ./bin/deploy_bosh "${kubo_env_path}"
上記のスクリプト は、内部的には以下のように Operations Files を組み合わせてマニフェストを生成して Azure 用の Director をデプロイしています。
(以下の擬似コードは、わかりやすさのために実際の処理を簡略化しています。)
$ bosh_manifest=$(bosh-cli int ./bosh-deployment/bosh.yml --ops-file ./bosh-deployment/uaa.yml --ops-file ./bosh-deployment/local-dns.yml --ops-file ./configurations/generic/dns-addresses.yml --ops-file ./bosh-deployment/credhub.yml --ops-file ./configurations/generic/bosh-admin-client.yml --vars-file ../kubo-env/kubo/director.yml --vars-file ../kubo-env/kubo/director-secrets.yml --ops-file ./bosh-deployment/azure/cpi.yml)
$ bosh-cli create-env $bosh_manifest --vars-store ../kubo-env/kubo/creds.yml --state ../kubo-env/kubo/state.json
10 分程で Director のデプロイは完了します。
3. CFCR のデプロイ
ここまで来ると、公式ドキュメントの手順 に従って CFCR をデプロイするだけです。
$ ./bin/deploy_k8s ~/kubo-env/kubo my-cluster public
上記のスクリプト は、内部では以下の擬似コードのようにマニフェストを生成しているようです。
$ bosh-cli int ./manifest/cfcr.yml --ops-file=./manifests/ops-files/misc/dev.yml --ops-file=./manifests/ops-files/misc/bootstrap.yml --ops-file=./manifests/ops-files/use-runtime-config-bosh-dns.yml --vars-file=../kubo-env/kubo/director.yml --var deployment_name=my-kubo --var director_uuid=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx --vars-file=../kubo-env/kubo/creds.yml --vars-file=../kubo-env/kubo/director-secrets.yml
20 分程で CFCR のデプロイは完了します。
bosh-cli をセットアップして、正常に BOSH VM が稼働しているか確認します。
$ source bin/set_bosh_environment
$ ./bin/set_bosh_alias $kubo_env_path
$ bosh-cli -e $kubo_env_name -d my-cluster vms
以下のような画面が出力されれば、デプロイは成功です。
Deployment 'my-cluster'
Instance Process State AZ IPs VM CID VM Type
master/36d8a40f-7c17-4130-8822-3acfc377b17e running z1 10.0.1.4 agent_id:d6a793ea-b46b-459d-aec3-3b3f28b898a3;resource_group_name:cfcr;storage_account_name:cfcrsa master
worker/133e0146-0003-4f21-8e1c-214f5aa55041 running z1 10.0.1.5 agent_id:09dbe3d8-df10-47a9-b232-837de005cd67;resource_group_name:cfcr;storage_account_name:cfcrsa worker
2 vms
Succeeded
デプロイが成功したら、 Azure ロードバランサーから Kuberenetes Master へのルーティングを設定します。
Azure Portal から cfcr-lb
を選択して、「バックエンド プール」 → 「BackendPool」 と進み、関連付け先に「可用性セット」を選択します。可用性セットに「master」を選択し、ターゲットネットワーク IP 構成に進みます。「ターゲット仮想マシン」と「ネットワーク IP 構成」をそれぞれ選択します(いずれも選択肢は一つしかないはずなので、それを選択する)。
最後に「保存」ボタンを押せばすべてのデプロイ作業が完了です!
4. 動作確認
簡単な動作確認をおこないます。
はじめに kubectl の設定をおこないます。
$ ./bin/set_kubeconfig $kubo-env_path my-cluster
kube-system
namespace の Pods を確認します。
$ kubectl get pods --namespace=kube-system
以下のような画面が出力されていれば正常な状態です。
NAME READY STATUS RESTARTS AGE
heapster-776fb9d89b-bw8wh 1/1 Running 0 27m
kube-dns-9dc479d4f-8n68q 3/3 Running 0 27m
kubernetes-dashboard-789b8cfdb7-zrdws 1/1 Running 0 27m
monitoring-influxdb-c577bbf7-r7kjq 1/1 Running 0 27m
Nginx の Deployment を作成してみます。
$ kubectl run nginx --image=nginx:1.11.3
Service を NodePort で公開します。
$ kubectl expose deployment nginx --port 80 --type=NodePort
Node の IP アドレスと Service の Port をそれぞれ確認して、疎通確認をおこないます。
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
10.0.1.5 Ready <none> 35m v1.8.4
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.100.200.1 <none> 443/TCP 38m
nginx NodePort 10.100.200.177 <none> 80:31901/TCP 1m
$ curl 10.0.1.5:31901
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
(以下略)
アクセスできました!
動作確認が終わったら、 CFCR と BOSH Director を削除します。
$ bosh-cli -e $kubo_env_name -d my-cluster delete-deployment
$ ./bin/destroy_bosh $kubo_env_path
最後に Azure Portal からリソースグループを削除して、終了です。
おわりに
もう少し突っ込んだ解説をしたかったのですが、時間切れになってしまいました。
ひとまず Azure 上で CFCR が動くというところまでなんとか漕ぎ着けました。ただし、実際にはこれで Azure 対応ができたとは言えません。
例えば、Pod がマウントする Volume として Azure Storage Account を利用したい場合など、Azure リソースを Kuberenetes の オブジェクトとして使うためには、IaaS の API とのやり取りを仲介する Cloud Provider という機構を用意する必要があります(BOSH の CPI と似てますね! このあたりの起源も Borg から来ているのでしょうか?)。
この Cloud Provider の Azure 対応をするには、CFCR 本体 の方に手を入れる必要がありそうなので、まとまった時間ができたら、腰を据えて挑戦してみたいと思っています。
長くなりましたが、最後までお付き合い頂きありがとうございます。
それでは良い新年をお迎えください!!