はじめに
インフラ運用に従事している松谷です。2012年にOpenStackを社内に導入して以来、社内の環境は劇的に変化しました。当時ゴールにしていたハードウェアの抽象化はOpenStackを導入することで達成する事ができました。しかしながら現在はクラウドの進化やコンテナの台頭でさまざまなプラットフォーム上でサービスを迅速に稼働させる事が急務となってきていると考えます。コンテナプラットフォームを構築するとともに、今回はOpenStackを1つのアプリケーションと考えKubernetes上で稼働させる例までを数回に渡り説明いたします。
Coding Lifecycle
本プロジェクトのゴールは、1つのアプリケーションコードより必要なプラットフォームごとにイメージの作成を行い、出来上がったイメージを各プラットフォーム上へ展開する事です。
具体的にはCode registryでコードに変更が行われた場合、CI(Continuous Integration) toolsを利用してBare metal images、Docker containers、VM imagesを作成し、Image registryへpush、その後、各種インフラのプラットフォームへ展開を行います。
Productは主に下記を使用します。(Kubernetes関連のProductは後述します)
Function | Product |
---|---|
Code registry | Github Enterprise |
CI tools | Jenkins |
Image registry | Artifactory |
Bug tracking system | JIRA |
deploying Bare metal platform | OpenStack Ironic |
deploying VM platform | OpenStack |
deploying container platform | Kubernetes |
Image Creation
各種Image creationのworkflowは下記です。
VM Image Creation
- GitHubへCodeをpush
- Jenkinsのmasterへhook
- Jenkins slaveでジョブを立ち上げる
- Packer repositoryをcheckout
- Service Jobを実行
- build scriptによってPackerを実行する
- PackerはOpenStack Glance用のVMを起動する
- VMの設定と必要なアプリケーションをインストール
- snapshotを作成しglanceへ登録
- Glanceに出来上がったimageをダウンロード
- Artifactoryへ出来上がったimageをアップロード
Baremetal Image Creation
- GitHubへCodeをpush
- Jenkinsのmasterへhook
- Jenkins slaveでジョブを立ち上げる
- Packer repositoryをcheckout
- Service Jobを実行
- build scriptによってbase bare metal imageをダウンロード
- build scriptはPackerを介してdiskimage-builderを実行しbare metal imageを作成
- Glanceに出来上がったimageをアップロード
- Artifactoryへ出来上がったimageをアップロード
Container Image Creation
- GitHubへCodeをpush
- Jenkinsのmasterへhook
- Jenkins slaveでジョブを立ち上げる
- Dockerfile repositoryをcheckout
- Service Jobを実行
- Artifactoryからbase docker imageをダウンロード
- Artifactory上にdocker imageがない場合はDocker Hubからダウンロード
- docker buildを行いimageを作成する
- 出来上がったimageをArtifactoryへアップロード
Platform Architecture
3つのworkflowの中でも今回はContainerにフォーカスし、deploy先で使用されるKubernetesの説明を行います。
本Platform Architectureは下図となっております。
Function | Product |
---|---|
Infrastructure Services | OpenStack |
Container Host | CentOS |
Container Cluster Manager | Kubernetes |
Container Networking | Project Calico |
Container Engine | Docker |
Container Registry | Artifactory |
Service Registry | etcd |
Source Code Management | GitHub Enterprise |
CI tool | Jenkins |
Infrastructure Provisioning | Terraform |
Logging | Fluentd, Elasticsearch, Kibana |
Metrics | Heapster, Influxdb, Grafana |
Service Monitoring | Prometheus |
Container Host(OpenStackインスタンス)にはCentOSを使用し、Docker、Kubernetes、Calico、etcdなどをインストールします。Kubernetes上にCI toolやKubernetesのaddonなども稼働させます。もちろんKubernetes上にさまざまなContainerのアプリケーションを稼働させることが可能です。そのアプリケーションの1つとしてOpenStackも稼働させます。OpenStack on Kubernetes on OpenStackということになります。現在OpenStackのクラスタだけでも約30クラスタもあるため管理が非常に大変です。1番土台のOpenStackでは最低限の機能をKubernetesに提供し、Kubernetes上で稼働するOpenStackの管理を容易にするのが目的です。
Kubernetes Architecture
それではKubernetesのアーキテクチャをもう少し詳細に説明いたします。
下記のような構成になっています。
Product | Description |
---|---|
OpenStack Keystone | KubernetesのAuthenticationとAuthorizationで使用 |
OpenStack Cinder | Pod(複数のコンテナをグループ化したもの)が利用する外部Volumeとして使用 |
kube-apiserver | PodやService(コンテナ内サービスへアクセスするために定義するもの)といったオブジェクトの設定や検証をREST APIを通じて行う |
kube-scheduler | 各ノードに対してPodの割り当てを行う |
kube-controller-manager | 状態管理をなどを行うreplication controllerなどの管理を行う |
kubelet | Podの管理を各ノード上でagentとして起動して行う |
calico | BGPを使用してPod間の通信を可能にする |
kube-proxy | iptableのnat tableを設定してIP変更やロードバランス(ClusterIP)の設定を行う |
etcd | KubernetesやCalicoの情報を格納する分散KVS |
etcd-proxy | 各node上で稼働してclientのリクエストをetcdのクラスタへ転送する |
Tenant Isolation
OpenStackのようにマルチテナントで利用できるようにAuthenticationとAuthorizationについてOpenStack Keystoneを利用して実現しています。
Authentication
AuthenticationについてはOpenStackのKeystoneを使用することが、Kubernetesのpluginを通して利用可能です。KubernetesのAPI Serverの起動時にKeystoneのauthURLを追加してあげる事により、OpenStackのOS_USERNAMEとOS_PASSWORDを使用する事が可能です。
Authorization
Kubernetes AuthorizationのABAC(Attribute-Based Access Control) modeを使用します。OpenStack Keystoneのuserとtenant情報を、Kubernetes ABACで使用できるようにuserとnamespaceなどの情報が入ったJSON形式のpolicy fileに変換するスクリプトを作成します。このスクリプトで作成されたpolicy fileをKubernetesのAPI Server起動時に指定します。また、tenant情報から実際のnamespaceの作成もスクリプトで行っておきます。
これらの設定により、KeystoneのuserでKubernetesの認証が可能となり、認可を受けたnamespace内での操作が可能とです。
Volumes and Data Persistence
KubernetesはPodに対して永続的なストレージとしてPersistent Volumesというサブシステムを提供しています。Persistent Volumesはcloud-provider storageをサポートすることが可能となっており、cloud-providerをOpenStackにする事によってOpenStackのCinder volumeを扱うことが可能となっております。
Networking
KubernetesのネットワークはFlannelをはじめとしたさまざまなネットワークモデルが存在しますが、本プロジェクトではProject Calicoを使用して構築しました。
Yahoo! JAPANではredistribute ARPの検証、IP CLOS ネットワークの採用など、データセンタをpure L3ネットワークで組むのを推進しているため、Projcet Calicoは弊社の方向性と非常にマッチしていました。
FlannelなどOverlayモデルを採用した場合にはPodのIPにはKubernetesのクラスタ外から直接アクセスする事ができませんが、Project Calicoでは直接アクセスする事ができます。また、後述するLoad BalancingでもProject Calicoを利用しています。
Project CalicoではKubernetsの各node上にBIRD(OSSのルーティングソフトウェア)コンテナを立ち上げ、PodのIPをBGPによって広報します。デフォルトではクラスタ内にのみ広報しますが、クラスタ外のルータとpeerを張る事によりクラスタ外よりPodへ直接アクセスする事が可能です。
External Service Load Balancing
KubernetesのExternal Service Load Balancing(クラスタ外からServiceへアクセスできる仕組み)はNodePort、LoadBalancer、Ingressと複数ありますが、弊社の要件に完全に合うモデルは存在しませんでした。しかしながらInternal Service Load Balaning(クラスタ内でのみServiceへアクセスできる仕組み)で使用しているClusterIPをProject Calicoを通じてBGPにて広報する事によりクラスタ外からLayer4のExternal Load Balancingが可能となり、要件に近づけることができました。
Service Discovery
KubernetesではSkyDNSをaddonとして利用することにより、Service Discoveryを行う事ができます。クラスタ内のServiceとしてあげるため、ClusterIP同様にデフォルトではクラスタ内だけで利用可能ですが、BGPでClusterIPを広報する事によって、クラスタ外からも名前解決が可能です。
まとめ
Image creationのworkflowとKubernetesを組み合わせる事により下図のようなtool chainが出来上がり、code pushからdeployまでが簡単に行えます。
Kubernetesのもう少し詳しい説明とOpenStackを上図のtool chainに載せる説明を次回以降の記事としたいと考えております。
今回のプロジェクトではさまざま人から協力を頂戴して成し遂げる事ができました。本著が皆様の助けになれば幸いです。
次回以降の予定
- CalicoによるKubernetesピュアL3ネットワーキング
- Terraformを使ってOpenStack VMへKubernetesクラスタをデプロイする
- KubernetesとOpenStackを連携させる方法
- Kubernetes上にOpenStackのコントローラノードをデプロイする
- Kubernetesのロードバランサ
こちらの記事のご感想を聞かせください。
- 学びがある
- わかりやすい
- 新しい視点
ご感想ありがとうございました