フルスタックエンジニア目指して

エンジニアリングのことはもちろん、全然関係無い話もします。

spinnakerを使ってみたい

Spinnaker(すぴねーかー)とは

Kubernetesなどのクラスタを管理したり、デプロイを管理するためのツールで、2015年11月にNETFLIXがOSS化しました。

CIツールでのイメージのプッシュやCronなどをトリガーにして(または手動で)、以下のようなパイプラインでデプロイを管理することができるそうです。

自動デプロイのパイプライン実行

概要は公式ページMercari Engineering Blogがよくまとまってると思います。

導入する時間がなく、実際に使ったわけではないので、使い勝手の悪いところなどはわかりません。

でもできるだけ早く使ってみたい。
その気持ちを忘れないように問題点を整理しておきます。

現状の運用環境の問題点整理

現状のデプロイ方法

まず、僕は通販サイトの運用にGoogle Kubernetes Engine(GKE)を使用しています。

Kubernetesでは以下のように使用するイメージを指定しています。 eccube_web:1.0.0の部分です。

# production.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: eccube
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: eccube
        tier: frontend
        environment : production
    spec:
      containers:
      - image: gcr.io/cosme-ec/eccube_web:1.0.0
        imagePullPolicy: Always
        name: eccube
 .
 .
 .

ここで、イメージをeccube_web: 1.0.1に更新したいとしましょう。

その場合、まずyamlを書き換えます。

# production.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: eccube
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: eccube
        tier: frontend
        environment : production
    spec:
      containers:
      - image: gcr.io/cosme-ec/eccube_web:1.0.1
        imagePullPolicy: Always
        name: eccube
 .
 .
 .

次に以下のコマンドを実行します。

$ kubectl apply -f production.yaml

すると自動的に新しいイメージがpullされて、更新が行われます。
バージョン管理もできるし、これだけでも十分だとは思います。

しかし、ステージ環境なども用意して、本運用に入ると怖い点があります。

現状のデプロイ方法の問題

それはKubernetesではステージ環境と本番環境で挙動を区別できないという点です。

本番環境に影響を与えないように別のクラスタで運用されていますので、まず、ステージの構成を変更する場合は、以下のコマンドを実行し、クラスタを切り替えます。

$ gcloud container clusters get-credentials (ステージ環境クラスタ名) --project xxxx --zone xxxx

逆に本番の構成を変更する場合は、以下のコマンドを実行してクラスタを切り替えます。

$ gcloud container clusters get-credentials (本番環境クラスタ名) --project xxxx --zone xxxx

上記のように環境を切り替えてから、kubectl applyするとそのクラスタの構成が更新されます。

しかし、Kubernetes自体にはステージと本番の区別がないため、切り替え忘れた場合に警告を出したりすることができません。
本番環境にステージの構成をapplyすると普通に適用できてしまいます。

kubectl applyでイメージをデプロイするのはこのような危険性があるのです。

Spinnakerなら

メルカリの事例にあるように、以下のようなパイプラインを作成すれば問題解決できそうですね。

  • Pipeline1:開発環境のk8sクラスタへDockerイメージをDeployする
  • Pipeline2:本番へのDeployを実行するかの承認を求める
  • Pipeline3:本番環境のk8sクラスタへDockerイメージをDeployする

さらに、以下のようなメリットもあります。

  • Immutable Infrastructureを実現できる
    • 一度サーバーを構築したらその後はサーバーのソフトウェアに変更を加えないこと
    • 継ぎ足し継ぎ足しで変更を加えて、誰にも真似出来ない秘伝のタレができてしまうことを防ぐ
  • Blue/GreenデプロイメントやCanaryデプロイ、問題が起こったときのロールバックなどの戦略が簡単にハンドルできる

今はサイトオープンまで時間がなくて、検討する時間があまりないのですが、オープン後に時間ができたら考えてみようと思っています。

Spinnakerを導入したらqiitaかブログにまとめます。