2016年7月25日

基盤技術

OpenStackとKubernetesを利用したマルチプラットフォームへのCI環境

  • このエントリーをはてなブックマークに追加

はじめに

インフラ運用に従事している松谷です。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

  1. GitHubへCodeをpush
  2. Jenkinsのmasterへhook
  3. Jenkins slaveでジョブを立ち上げる
  4. Packer repositoryをcheckout
  5. Service Jobを実行
  6. build scriptによってPackerを実行する
  7. PackerはOpenStack Glance用のVMを起動する
  8. VMの設定と必要なアプリケーションをインストール
  9. snapshotを作成しglanceへ登録
  10. Glanceに出来上がったimageをダウンロード
  11. Artifactoryへ出来上がったimageをアップロード

Baremetal Image Creation

  1. GitHubへCodeをpush
  2. Jenkinsのmasterへhook
  3. Jenkins slaveでジョブを立ち上げる
  4. Packer repositoryをcheckout
  5. Service Jobを実行
  6. build scriptによってbase bare metal imageをダウンロード
  7. build scriptはPackerを介してdiskimage-builderを実行しbare metal imageを作成
  8. Glanceに出来上がったimageをアップロード
  9. Artifactoryへ出来上がったimageをアップロード

Container Image Creation

  1. GitHubへCodeをpush
  2. Jenkinsのmasterへhook
  3. Jenkins slaveでジョブを立ち上げる
  4. Dockerfile repositoryをcheckout
  5. Service Jobを実行
  6. Artifactoryからbase docker imageをダウンロード
  7. Artifactory上にdocker imageがない場合はDocker Hubからダウンロード
  8. docker buildを行いimageを作成する
  9. 出来上がった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のロードバランサ

Yahoo! JAPANでは情報技術を駆使して人々や社会の課題を一緒に解決していける方を募集しています。詳しくは採用情報をご覧ください。

  • このエントリーをはてなブックマークに追加