GCP におけるコンテナ入門 ~Kubernetes の何がすごい!?

  • Google Cloud 入門記事
  • tech系
14min

こんにちは。
クラウドエース編集部です。

Kubernetes という名前は聞いたことあるけど、実際何のために使うのか、何がすごいのかを知らないという人は多いのではないでしょうか。
本記事では、Kubernetes がどのようなサービスなのか、Google Cloud 上で Kubernetes を使うと何がすごいのかについて解説していきます。
Kubernetes 未経験の方にもわかりやすく解説するので、最後まで読んでみてください!

Kubernetes とは

https://kubernetes.io/ja/docs/concepts/overview/what-is-kubernetes/

Kubernetes は複数のコンテナを簡単にデプロイ・管理できるサービスです。
そもそも Kubertenes という名前はギリシャ語で「操舵手」を意味します。
コンテナ船を操縦・管理する人のようなイメージですね。

実際にコンテナ上にアプリケーションを構築する際は、複数のコンテナを組み合わせて一つのサービスを構築します。
コンテナのデファクトスタンダードは Docker だと言われており、Docker だけの機能では複数のコンテナを組み合わせて管理することはとても大変です。

複数のコンテナの管理で必要な観点には以下のようなものが挙げられます。

  • コンテナのスケジューリング
  • ホストの管理
  • ロードバランシング
  • オートスケーリング
  • コンテナ間のネットワーク制御など

Kubernetes を使用すれば、これらのことが簡単に管理できるようになるわけですね。

コンテナとは

https://docs.docker.com/get-started/overview/

ここまでの説明で、「コンテナ」という単語を当たり前のように使ってきましたが、コンテナについて知らない人もいると思うので簡単に解説します。

コンテナとは、ホスト OS 上に独立した領域を確保し、その中でアプリケーションを動作させる仮想化技術です。
簡単に言い換えると、一台の物理サーバーの中に軽量な別のサーバーを立ち上げるようなイメージです。
このような技術は仮想化技術と呼ばれ、ハイパーバイザーなども仮想化技術として有名です。
ただハイパーバイザーはカーネル自体も仮想化するのに比べて、コンテナはホストのカーネルを使用するので、ハイパーバイザーより軽量に動作します。

ここでコンテナができる前にどのような問題があったのかを紹介します。
コンテナができる前は、複数のアプリケーションを動作させようとすると、以下のような問題が起こっていました。

  • 依存関係(ライブラリ、ミドルウェアなど)が衝突して、動作しなくなる
  • 1つのアプリケーションがリソースを消費しすぎることで他のアプリケーションのリソースが足りなくなる。
  • デプロイに時間がかかる
  • 動作する環境ごとで、設定や構成を変える必要がある

こういった問題を解決するためにコンテナが使用されるようになりました。
コンテナ上でアプリケーションを動作させると、以下のように問題が解決します。

  • 依存関係(ライブラリや設定ファイルなど)をコンテナの中に集約できる
  • CPU やメモリなどのリソースをコンテナ単位で管理することができる
  • 高速にデプロイできる
  • どんな環境でも同じように動作させることができる

マイクロサービスやアジャイル開発といったデプロイを小さく分けて、細かくデプロイを積み重ねる運用が重視されてきている今、コンテナは必須の技術と言っても過言ではないかもしれませんね。

ここまでの内容をまとめると、コンテナはアプリケーションを独立した環境で、軽量に動作させるための仮想化技術のことで、Kubernetes は複数のコンテナの管理を自動化・簡略化してくれるツールのことでした。

ここまでの説明で、コンテナと Kubernetes についてなんとなく理解できたと思うので、ここからは Kubernetes は何がすごいのかについてもう少し細かく紹介します!

※ ここから Pod という単語が出てきます。
Kubernetes の世界では、コンテナは Pod という単位で扱われます。
Pod は一つ以上のコンテナをグループ化したものです。
細かい説明は省略しますので、Pod に馴染みのない方は Kubernetes の世界のコンテナなんだなと思って、読んでいただけると幸いです。

Kubernetes のすごいところ1

Kubernetes の基本コンセプトとして、「リソースの管理は Declarative にできる」というものがあります。
Declarative というのは「宣言的に」という意味で、対義語は「Imperative(命令的に)」です。

よく宣言的と命令的の説明として以下のように言われます。

宣言的:「何が欲しいのか」といった目的だけを記述する
命令的:「どのようにしたいのか」といった目的のものを作るための手順を記述する

Kubernetes の世界での宣言的・命令的というのはどのようなものでしょうか。
命令的にリソースを管理するというのは、希望するリソースの状態まで手順に従って構築していく手法です。
例えば、nginx イメージで動作し、`app: nginx`といったラベルを付与した Pod を構築したいとします。
命令的であれば以下のような手順で Pod を構築します。

  1. Pod を nginx イメージで作成する
  2. Pod にapp: nginxと言ったラベルをつける

この作業で以下のような Pod が出来上がります。
Kubernetes の世界ではラベルをつけることで、Pod をグループ化します。

これに対して、宣言的にリソースを管理するというのは、設定ファイルに全ての希望する設定を書いて、その設定ファイルを適用する(API サーバーに送信する)だけで、Pod が作成できるというものです。
まさに「何が欲しいのか」を書くだけですね。

例えば、上の例と同じ構成の Pod を作成しようと思ったら、このような設定ファイルを書きます。
設定ファイルが完成したら、kubectl apply コマンドを叩くだけです。

apiVersion: v1
kind: Pod
metadata:
name: sample-pod
labels:
server: nginx
container:
name: nginx
image: nginx

この設定ファイルに対して kubectl apply コマンドを叩くことで、もちろんですが以下のような Pod が出来上がります。

このように、どんなに複雑な Pod を作成したい場合でも、その全てを設定ファイルの中に書くだけで実現できるのが宣言的なリソース管理です。
命令的な管理であれば、複雑な Pod を作成しようと思ったら手順がどんどん増えていきますよね。
宣言的なリソース管理はとても便利なので、ぜひ体験していただきたいです。

Kubernetes のすごいところ2

Kubernetes にはすごい機能がたくさんあるのですが、その中でも代表的なものをいくつか紹介したいと思います。

オートスケーリング

Kubernetes 上で運用していれば、急激なトラフィックの増加にも対応できます。
水平 Pod オートスケーリングを使用すると、対象の Pod の CPU 使用率やメモリ使用率に基づいて、Pod の数を増減させることができます。
また、垂直 Pod オートスケーリングを使用すると、コンテナに割り当てられる CPU とメモリの量を自動的に増減させることができます。

さまざまなデプロイ戦略

Kubernetes を使用すると、さまざまなデプロイ戦略を取ることができます。
例えば、Blue/Green デプロイメントです。
Blue/Green デプロイメントは、既存のバージョンを残したまま、新しいバージョンを別の Pod としてデプロイし、ロードバランサを使用して一気にトラフィックを切り替える方法です。
問題が発生した場合は即座に以前のバージョンに切り替えることができます。

またローリングアップデートも可能です。
ローリングアップデートは、サービスを動かしている Pod を少しずつ順番にアップデートしていくことでダウンタイムが発生しないように、新しいバージョンのサービスをデプロイする方法です。
下の図は、app を v1 から v2 に移行している図です。
Pod が一つずつアップデートされています。
これによりダウンタイムが発生せずにアップデートできます。
ローリングアップデート中はトラフィックは v1 と v2 のどちらかに振り分けられることになります。

最後にカナリアリリースについても説明しようと思います。
カナリアリリースは一部のトラフィックを新しいバージョンにルーティングし、大部分を既存のバージョンにルーティングすることで、少数のユーザーのみが新しいバージョンを使用できるようにする手法です。
一部のユーザーで新しいバージョンをテストし、問題がないことが確認できたら全体に向けて、展開する戦略が取れます。

下の図のように新しいバージョンには、トラフィックを20%しか流さないように設定しておくことで、全体のユーザーの20%に向けて v2 をテストすることができます。

オートヒーリング

オートヒーリングとは、Pod が正常に動作しなくなった時にその Pod を削除し、新しい Pod を自動で作成してくれる機能です。
Kubernetes では、Pod をグループ化し、指定した数の Pod が正常に動作するように保ってくれる機能があります。
また、正常に Pod が動作しているという判断基準も ReadinessProbe、LivenessProbe という機能で設定することもできます。
また Node で障害が起きたことを検知すると、その Node 以外に Pod が配置されるように再作成してくれます。

Podのスケジューリング

最後に Pod のスケジューリングの機能について解説します。
「Pod をスケジュールする」とは、コントロールプレーンが Node に Pod を自動的に配置することを指します。
スケジュールを詳細に設定することで、どの Node にどの Pod を配置させるかを設定することができます。

Kubernetes では、Node Affinity という機能を使用して、どの Node で Pod を作成するかを設定することができます。
また Pod Affinity と Pod Anti-Affinity という機能を使うと、「この Pod が存在する Node に Pod を配置したい」や「この Pod が存在する Node には Pod を配置したくない」といった設定もできます。

Kubernetes のすごいところ3

Kubernetes の魅力の一つとして、機能をリッチにするための OSS が盛んに開発されていることが挙げられます。
便利な OSS として4つほど紹介したいと思います。

Istio(サービスメッシュ)

https://istio.io/latest/about/service-mesh/

Istio はサービス同士の通信を柔軟に制御するためのコンポーネントです。
今流行りのマイクロサービスでは、複数のサービスが連携することになり、Kubernetes だけでは管理が難しい部分が出来てしまいます。
サービス間の連携時に起きる問題を解決してくれるのがサービスメッシュである lstio です。
Istio を使用すると全ての Pod にプロキシが介入するようになり、Pod に出入りする通信は全てこのプロキシを経由するようになります。
このプロキシにより、各指標の収集やサービスディスカバリ、サービス同士のセキュアな通信などが実現できます。

例えばサービスディスカバリに関しては、Kubernetes 自体はカナリアリリースをネイティブにサポートしていません。
よって、複数のリソースを調整してカナリアリリースを実現する必要があります。
ですが Istio を使用すると一つの設定ファイルを書くことで、簡単にどのサービスに何%のトラフィックを流すかを指定できます。

また、Kubernetes は Pod 間の通信を暗号化しないのですが、Istio は複数の Pod 同士が通信するときの暗号化や認証なども担当します。
それにより、柔軟にサービス間のアクセス制御が行えたり、サービス同士の通信がセキュアに行えたりします。

Helm(パッケージマネージャー)

https://helm.sh/ja/docs/

Helm は Kubernetes のためのパッケージ管理ツールで、アプリケーションや使用するツールを実行するためのリソース定義が全て含まれたものです。
Homebrew や Apt をイメージしてください。
Kubernetes 上でアプリケーションを構築するときに一から構築するのは、複雑でかなりの時間を要する場合があります。
そのような場合は Helm で雛形のリソース定義セットをインストールし、変更したい部分だけを変更してデプロイすることで大幅に作業を短縮できます。
※Helm では Docker イメージ自体をカスタマイズできるわけではないので注意してください。

また、Helm 上にチャートと呼ばれるパッケージを作成してパッケージ化することができます。
これを使用して環境ごとの差異を Helm で管理することができます。
チャートは、yaml ファイルに Go 言語のテンプレートライブラリのようなものを埋め込む形で記述します。
興味がある方はドキュメントをご覧ください。

Algo CD(CI/CD)

https://argoproj.github.io/argo-cd/

ArgoCD は、Kubernetes 用の GitOps ツールです。
ArgoCD を使用することで、Github 上の通常の yaml ファイル、Helm、Kustomize などのファイルの変更を検知して、Kubernetes 上のアプリケーションに自動デプロイさせることができます。
GitOps では推奨されませんが、ローカルからファイルをアップロードさせて、デプロイさせることもできます。
Github との統合では、ブランチやタグの追跡、特定のコミットに固定するなどがサポートされています。

Sync に関する設定を柔軟に行えるのも ArgoCD の特徴で、例えば Git からリソースを定義しているファイルがなくなったとしても ArgoCD はそれを自動で削除しないように構成できます。
これにより、操作ミスによるリソースの自動削除を防ぐことができます。
また、Github を経由せずにクラスタ自体に変更が適用された時に、Git の状態にクラスタを適用させるかどうかなどの設定もあります。

また ArgoCD の構成は、UI で管理することができます。
UI 上から CI 環境を構築することができ、カスタマイズやアプリケーションの状態を確認することもできます。

Prometheus(監視ツール)

https://prometheus.io/

Prometheus はメトリクスを収集するツールです。
Kubernetes 単体では、各 Pod の CPU 使用率やリクエスト数などのメトリクスを管理することは困難です。
Prometheus を使用すると、UI ベースでメトリクスを一括管理でき、クエリを実行し、結果をグラフ化できます。
Prometheus は Helm からインストールして、設定をカスタマイズした上でデプロイできるので非常に簡単に環境を構築することができます。

例えば、次のクエリを実行してみます。

Process_resident_memory_bytes

すると、以下のようなグラフが作成されます。

このように、Prometheus の UI からクエリを書くことで様々なリソースのメトリクスを収集できます。
また、アラート機能も実現することができます。
このアラート機能は多機能で、グルーピングやミュート機能、高可用性クラスタに対応させる機能などがあります。

例えばグルーピングの機能は似たような種類のアラートを一つの通知にグルーピングして通知します。
この機能を使用することで、同じようなアラートは一つにまとめられ、どのサービスがそのアラートを受け取ったのかを確認することができます。

もう一つ、ミュート機能も紹介します。
ミュート機能では特定の時間帯は通知を送らないような設定にしたり、特定の通知が送信された後は特定の通知が送信されないように設定したりする機能があります。

Prometheus はメトリクス収集ツールなため、ログ収集の機能はありませんが、メトリクス収集に関してはかなり優秀なツールなので、ぜひお試しください。

Google Cloud で、Kubernetes を使おう

Google Cloud には、Google Kubernetes Engine(以降、GKE)と呼ばれる Kubernetes クラスタのマネージドサービスが用意されています。
GKE を使用するとクラスタの管理をしなくて良いことはもちろんのこと、クラスタをセキュアにすることや簡単に Google Cloud のサービスと Kubernetes を連携させることができるので、ご紹介したいと思います。

セキュアなクラスタを簡単に構築できる

GKE を使用すると、セキュアなクラスタを1つのコマンドの実行だけで作成することができます。
具体的には、各 Worker Node(Pod が動作する VM)にパブリック IP アドレスを持たせない構成で構築できます。
また、Control Plane(Worker Node を管理する VM)には、パブリック IP アドレスを持たせない、もしくはパブリック IP アドレスを持たせるが、承認されたネットワークからしかアクセスできないような構成で構築することができます。

また、GKE で使用するノードを保護するための GKE Sandbox という機能も用意されています。
GKE Sandbox を使用すると、コンテナで動作するアプリケーションはホストカーネルへのアクセスを通常よりも制限されます。
これにより、コンテナの内部で悪意のあるコードが実行されたとしても、ホストや他のコンテナへの影響を大幅に減少させることができます。

さらに、GKE で動作する Node はデフォルトでは Container-Optimize OS(以降、COS)と呼ばれる OS で動作します。
COS はコンテナを動かす VM 用に最適化された OS で、コンテナが動作する環境に不必要なパッケージはカットされています。
これにより、OS への攻撃範囲を最小限に抑えることができます。

参考

1) プライベートクラスタについて
https://cloud.google.com/kubernetes-engine/docs/concepts/private-cluster-concept?hl=ja

2) GKE Sandboxについて
https://cloud.google.com/kubernetes-engine/docs/concepts/sandbox-pods

3) COSのセキュリティについて
https://cloud.google.com/container-optimized-os/docs/concepts/security?hl=ja

Ingress をカスタムできる

Ingress は、Kubernetes の世界での HTTP(S)ロードバランサのことです。
Kubernetes 上でアプリケーションを公開するときによく使われる機能になります。
GKE ではこの Ingress に様々な機能を追加することができます。

例えば、Cloud CDN の機能です。
Ingress に Cloud CDN をカスタムすると、静的ファイルが Google の世界中のロケーションにキャッシュされるようになり、レスポンス速度が向上します。

また、Cloud Armor をカスタムすることで、アプリケーションにアクセスできるユーザーを IP ベースやリクエストヘッダ、リージョンコードなどで制御したり、DDoS 攻撃や XSS などの WAF を構築することができます。

参考

1)  Ingress がサポートしている機能
https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-features#feature_comparison

GKE クラスタのメトリクスを監視する

Google Cloud にはモニタリングツールが用意されていて、デフォルトでメトリクスが収集されます。
Kubernetes 単体で使用しようとすると、サードパーティツールを使用して構築する必要があるので、デフォルトで利用できるのは優れているポイントです。

Cloud Monitoring は、メトリクス収集ツールです。
Prometheus と同じようにメトリクスの一元管理やアラートの設定などが行えます。
例えば、Pod の Receive bytes という指標では、以下のようなグラフが作成できます。

個人的には、Prometheus より見やすいと思うのですが、いかがでしょうか。
他にもストレージ使用率や CPU 使用率などたくさんの指標が存在します。

また、Cloud Monitoring の指標を使用することで、アラート機能を作成することができます。
トリガーの条件には、指標の閾値を設定する方法や指標の存在を確認させる方法があります。
Cloud Monitoring のアラートポリシーはとても柔軟に設定できるので、興味がある方はドキュメントをご覧ください。

最後に、Cloud Monitering の拡張機能として、Prometheus を統合させる選択肢もあります。
この機能は Prometheus で収集される指標を Cloud Monitering 上で表示させる機能です。
Cloud Monitoring では多くの指標がサポートされていますが、Prometheus にしかない指標を監視したい時はこの機能を使用します。

1)Prometheus の指標を外部指標として使用する
https://cloud.google.com/stackdriver/docs/solutions/GKE /prometheus?hl=ja

Nodeをオートスケーリングできる

GKE を使用すると、Node をオートスケーリングできます。
Pod が増えてくると Node のリソースも枯渇していきますが、Pod を作成できる Node がなくなった時に新しい Node を作成してくれる機能です。
逆に Pod の数に対して Node が多すぎる場合には自動で削除します。
Google Cloud の VM(Node)にかかる料金は従量課金なので、必要な Node を必要な時だけ動作させることができ、最大限コストを節約することができます。

参考

1)Node のオートスケーリング
https://cloud.google.com/kubernetes-engine/docs/concepts/cluster-autoscaler?hl=ja

最後に

本記事では、Kubernetes とは何か、GKE ってなにが便利なのかについて解説しました。
GKE を使用すると簡単に様々な機能を Kubernetes にカスタマイズできるので、ぜひ一度お試しください。

これから初めてクラウド サービスの導入をご検討されている方はもちろん、「 Google Cloud を使っているがもっと有効に活用したい」という方など、ぜひクラウドエースにご相談ください。
クラウドエースでは、Google Cloud を最大限活用していただくことができるように、さまざまなサポート サービスをご用意してお待ちしております。

また、Kubernetes を利用する上で、AWS や Azure と比較したい方は、ぜひ下記の資料をご覧になってください。
AWS・GCP・Azure 3大クラウドサービス 比較表

合わせて読みたい