ORNEW

CoreOSが大規模クラスタを構築するのに向いている理由

Facebook にシェア
Pocket

なぜCoreOSか?

  1. 他のLinuxディストリビューションに比べ堅牢なデフォルトのセキュリティの高さ
  2. 設定ファイル1つで環境が完成する、移植性とスケーラビリティの高さ
  3. Dockerやrktのようなコンテナエンジンは問わず、また既存のサービスやその他ツールと共存させやすい汎用性

1. セキュリティの高さ

もちろん、他のディストリビューションでもセキュアに運用することは出来ます。CoreOSに目新しいセキュリティ技術が搭載されている訳ではありません。しかし、CoreOSはデフォルトのセキュリティ設計が非常に堅牢に設計されており、初期設定や環境構築のコストが抑えられる上、設定ミスなどのリスクを負う必要がありません。

具体的にCoreOSのセキュリティが高い理由は以下のとおりです。

デフォルトのユーザはrootではなくcore

些細なことですが、とても重要なセキュリティ項目です。CoreOSには後述するIgnitionというステップがあり、OSが初回ブートした直後、sshdなどが起動するよりも前にcoreユーザを始めとした非rootユーザを作成する事ができます。よって、一度もrootにログインすることなく環境を構築することが可能です。

初期状態でパスワード認証ができない

初期パスワードは、rootユーザはもちろんcoreユーザも意図的に設定しない限り存在しません(するべきではありません)。認証には鍵を用いる必要があります。もちろん他のディストリビューションでも、rootの初期パスワードがrootで、それを変更し忘れるなんていう事はまさかないでしょうが(意味深)、CoreOSでは全てのユーザに一度もパスワードを設定することなく構築できるため、そのようなリスクは根本的に排除することが可能です。

OSの自動アップデート

何も設定しなくても標準でOSの自動アップデートのサービスが動作します。OSのアップデートはセキュリティ維持に不可欠です。

今までのOSだと、自動アップデートによってアプリケーションのOSへの依存関係が破壊されるなどしてサービスが継続できなくなる場合が稀にあり、自動アップデートをしたくない場合もありました。しかし、CoreOSではそのような懸念はありません。CoreOSはあくまでもコンテナを運用するためのOSです。システムへの依存関係はコンテナの中で完結するため、CoreOS自体はコンテナの中のサービスへ直接影響をあたえることはないのです。ホストマシンのセキュリティは保ちつつ、コンテナのサービスを維持することが容易になります。

2. 移植性とスケーラビリティ

CoreOSは1つの「汎用的な設定ファイル」でマシンを構築することが可能です。1つの同じ設定ファイルで様々なプラットフォーム(クラウド、ベアメタル、VM、etc…)へ展開可能で、起動すると同時に複数台のマシンをクラスタリングできます。移植性に優れているのはもちろん、クラウドのようにインスタンス単位でマシンを増やせる環境であれば容易にクラスタ構成をスケールすることが可能です。もう少し詳しくご紹介しましょう。

Container Linux Config

CoreOSにおける設定ファイルは、「Container Linux Config」と「Ignition」というものです。(※以前はCloud Configが用いられていましたが、非推奨になりました。日本語の情報は古いCloud Configを用いたものが多いため混乱しないように気をつけてください。似て非なるものです。

Container Linux ConfigはYAMLライク、IgnitionはJSONライクのファイルです。基本的に、Ignitionを直接書くことはなく、Container Linux ConfigをIgnitionにトランスパイアします。Ignition設定ファイルはOSの初回ブート時にのみ点火(Ignition)されます。

トランスパイアのタイミングで、設定ファイルのバリデーションや特定のプラットフォーム用に設定を変換します。トランスパイアが環境への依存性を吸収するため、Container Linux Configは移植性に優れた記述が可能となっています。

例えば、Container Linux Configでマシンの設定を書き、AWS EC2向けにトランスパイアしたIgnitionファイルを生成します。EC2の場合、CoreOSのEC2インスタンスを起動する時にユーザデータとしてIgnitionを渡すことで設定通りのCoreOSインスタンスが起動できます。同様に、同じContainer Linux ConfigをMicrosoft Azure向けにトランスパイアしAzure上で起動する事もできます。

具体的に、Container Linux Configの例を載せます。僕が普段使っているものから、基本的な設定を抜粋して簡易化したものです。一部の値は伏せています。

passwd:
  users:
    - name: core
      ssh_authorized_keys:
      - ssh-rsa ...
    - name: hoge
      ssh_authorized_keys:
      - ssh-rsa ...
      create:
        groups:
          - docker
        home_dir: /home/hoge
        shell: /bin/bash
storage:
  files:
    - path: /etc/ssh/sshd_config
      filesystem: root
      mode: 0600
      contents:
        inline: |
          PermitRootLogin no
          # ...
systemd:
  units:
    - name: sshd.socket
      dropins:
      - name: 10-sshd-port.conf
        contents: |
          [Socket]
          ListenStream=
          ListenStream=<port number>
etcd:
  advertise_client_urls:       "http://{PRIVATE_IPV4}:2379"
  initial_advertise_peer_urls: "http://{PRIVATE_IPV4}:2380"
  listen_client_urls:          "http://0.0.0.0:2379"
  listen_peer_urls:            "http://{PRIVATE_IPV4}:2380"
  discovery:                   "https://discovery.etcd.io/<token>"

この例ではユーザとsshd、etcdに関するを行っています。

まず、passwd以下でcoreとhogeというユーザを作成し、認証鍵を設定しています。Ignitionは初回ブート直後、sshd起動よりも前に行われるため、安全にユーザを作成できます。hogeは一般ユーザですがdockerの操作を許可しています。

storageではファイルの作成やボリュームマウントなどの操作ができます。ここではsshd_configを書き換えています。基本的に、ブート後はrootファイルシステムへの干渉を極力すべきではないというのがCoreOSのポリシーですので、Ignitionの時点で必要なものは書き換えます。

systemdでsystemdに関する設定が可能です。パブリックIPを持つような環境ではほぼ確実に攻撃やアクセス試行が来ます。ログが流れる上に、万が一突破される可能性も0ではありません。ポートを変えるだけでもかなり効果があるので、ドロップインでポートを変更してしまいましょう。なお、クラウドのセキュリティグループを設定している場合は別途そちらでもポートを開放する必要があることに気をつけてください。基本的に、systemdに関する設定は全てこの設定ファイルに書くことが出来ます。

etcdは、分散型のキーバリューストア(KVS)です。etcdについては解説しませんが、例のように設定するだけで簡単にストアを共有するクラスタが組めます。注目すべきはPRIVATE_IPV4で、Ignitionにトランスパイアする時に、プラットフォームを指定すると、そのプラットフォームに応じて適切な値に置き換わるように自動変換されます。新しくクラスタに参加したり、排除したりといった操作をシンプルに扱えます。

また、設定内容に誤りがある場合はトランスパイアの段階でエラーや警告が出ます。トランスパイアという手順が増えることで、間違った設定をデプロイするリスクを軽減できます。

これらの設定は通常のLinuxと同様に起動後に行うことも可能ですが、明確な違いがあります。改めてまとめると以下のとおりです。

このファイル1つで、マシンの構築を完了することができるため、スケールのコストが軽減されます。

汎用性

CoreOSを構成するのは、systemd、etcd、fleetの3つのシステムツールです。

systemd、etcdは決してコンテナ専用のツールではありませんが、コンテナをサービス化してクラスタで管理するコストを大きく軽減してくれます。また、コンテナではなく直接実行したいサービスなども共存することが出来ます。

簡単にそれぞれの役割をまとめると、

※systemdとetcdは汎用的なツールなので上記以外の使い方も十分考えられます。

基本的に、この3つでクラスタ管理をする場合は、サービスがDockerコンテナであっても、rktコンテナであっても、或いはバイナリを直接実行するものでも同じように扱えます。もちろんバイナリを実行するのはおすすめしません。コンテナでサービスを構築することでマシン環境への依存を解消し、fleetが適切なノード上で実行します。

RancherOSなど、他のコンテナ特化OSはDockerへの依存が非常に強い傾向があります。CoreOSはコンテナ特化でありながら、Dockerやrktといった特定のコンテナエンジンに依存していません。もしも新しいコンテナエンジンが登場しても、同じように包括できるだけのキャパシティがあります。

更に、これらのシステムツールではなく、他のコンテナオーケストレーションツールを扱うこともできます。CoreOSはGoogleのKubernetesとの連携を強めており、KubernetesでクラスタリングしたCoreOSを管理する商用サービス(tectonic)も提供しています。