この記事では、アリババの技術者の目を通してKubernetesを紹介し、トラブルシューティングなどのヒントを紹介しています。
1、Kubernetesとは?
まず最初に、Kubernetesの定義を説明します。ここでは、Kubernetesを4つの視点から説明します。
1.1 未来へのツール、Kubernetes
前述の図は、将来的に多くの企業が採用すると予想されるバックエンドITインフラのアーキテクチャを示しています。将来的には、すべての企業がITインフラをクラウド上に展開すると考えています。Kubernetesを使えば、基盤となるクラウドのリソースを、ビジネスごとに特定のクラスタに分割することができます。マイクロサービスアーキテクチャが一般的になるにつれ、サービスメッシュのサービスガバナンスロジックは、2つの基礎的なレイヤーを反映するように変化し、インフラの一部となります。
現在、アリババのほとんどの事業はクラウド上で運営されています。これらのビジネスのうち、ほぼ半数がカスタムKubernetesクラスタに移行しています。私の理解では、アリババは今年中にすべての事業をKubernetesクラスター上に展開する予定です。
Ant FinancialのようなAlibabaの一部の部門では、サービスメッシュがすでにオンラインビジネスで使用されています。
誇張していると思われるかもしれませんが、Kubernetesへの流れは私にとって非常に明白です。今後数年のうちに、KubernetesはLinuxと同じくらい普及し、あらゆる場所でクラスターのOSとして機能するようになるでしょう。
1.2 KubernetesとOS
前述の図では、従来のOSとKubernetesを比較しています。LinuxやWindowsのような従来型のOSは、その下にあるハードウェアを抽象化する役割を果たします。メモリやCPUなど、その下にあるコンピュータのハードウェア資源を管理するように設計されています。そして、その下にあるハードウェアリソースを使いやすいインターフェースに抽象化し、その上にあるアプリケーションレイヤーをサポートします。
同様に、KubernetesをOSと見なすことができます。簡単に言えば、OSとは抽象化されたレイヤーのことです。Kubernetesの場合、管理対象となる下位層のハードウェアは、メモリやCPUリソースではなく、複数のコンピュータで構成されるクラスタとなります。これらのコンピュータは、それぞれのOSやハードウェアを持った普通のスタンドアロンのシステムです。Kubernetesはこれらのコンピュータをリソースプールとして管理し、上位層のアプリケーションをサポートします。
Kubernetes上で動作するアプリケーションは、コンテナ化されたアプリケーションです。コンテナに馴染みのない方は、アプリケーションのインストーラーと考えるとよいでしょう。インストーラは、libcファイルなど、必要なアプリケーションの依存関係をすべてパッケージ化します。Kubernetesでは、アプリケーションは基盤となるOSのライブラリファイルに依存しません。
1.3 KubernetesとGoogle O&M
前述の図では、左にKubernetesクラスタ、右に有名な書籍「Site Reliability Engineering」が示されています。How Google Runs Production Systems』という有名な本が右に示されています。この本を読んだことのある方は多いと思いますし、この本に書かれている障害管理やO&Mのスケジューリングなどの手法を現在実践している企業も多いと思います。
Kubernetesとこの本の関係は、剣術と中国の武術である気功の関係に似ています。皆さんの中で『The Smiling, Proud Wanderer』を読んだことがある人は少ないと思いますが、これは伝説の剣士の本です。この本の中では、武士の学校が2つに分かれていて、1つは武術の気功を実践し、もう1つは剣術を実践しています。気功は、身体、呼吸、心を調和させるための哲学的なアプローチであり、剣術は剣の技術を重視しています。この本の中で、武士の学校が2つに分かれているのは、2人の弟子が秘密の書物から学んだが、それぞれの弟子は書物の一部分しか学んでいなかったからです。
Kubernetesは、Googleのクラスタ自動化管理・スケジューリングシステム「Borg」から派生したものです。このシステムは、書籍「Site Reliability Engineering」の題材にもなっています。「How Google Runs Production Systems」という本もあります。Borgシステムと、この本で紹介されている様々なO&M手法は、同じものの両面と捉えることができます。SREポストの設置などのO&M手法だけを学んでも、その手法で管理されているシステムを理解していなければ、システム全体の一部分しか学んでいないのと同じです。
BorgはGoogleの内部システムであり、一般には公開されていません。比較的、Kubernetesは自動クラスタ管理における重要な手法の一部を継承しています。したがって、本書を読んですごいと思ったり、説明されている手法を実践したいと思ったりする場合は、まずKubernetesを深く理解する必要があります。
1.4 Kubernetes技術の進化
初期の頃は、Webサイトのバックエンドを構築して、すべてのモジュールを1つの実行ファイルにまとめることができました。先ほどの図のように、3つのモジュールを用意しました。UI、データ、そしてビジネスです。これらのモジュールは実行ファイルにまとめられ、サーバー上で実行されます。
しかし、業務量が大幅に増加した場合、サーバーの構成を変更してもアプリケーションの容量を拡張することはできません。そのためには、アプリケーションをマイクロサービスに分割する必要があります。
マイクロサービスとは、1つのアプリケーションを、より小さな、疎結合のアプリケーションに分割することです。これらの小さなアプリケーションは、それぞれがビジネスを担当します。各アプリケーションには専用のサーバーがあり、ネットワーク接続でお互いを呼び出します。
このアーキテクチャの主な利点は、インスタンスの数を増やすことで小規模なアプリケーションをスケールアウトできることです。これにより、個々のサーバーを拡張することができないという問題を解決することができます。
マイクロサービスでは、1つのインスタンスが1つのサーバーを占有するという新たな問題が発生します。この展開パターンは多くのリソースを浪費します。解決策としては、複数のインスタンスを基礎となるサーバーにまとめてデプロイすることが考えられます。
しかし、このようなハイブリッド・デプロイメントでは、さらに2つの問題が発生します。まず、依存ライブラリの互換性の問題があります。これらのアプリケーションが依存しているライブラリファイルのバージョンが全く異なる場合があり、同じOSにインストールされた場合にエラーが発生します。もう1つの問題は、アプリケーションのスケジューリングとクラスターのリソース管理に関するものです。
例えば、新しいアプリケーションを作成する際には、そのアプリケーションをホストする対象となるサーバーを検討し、そのサーバーにアプリケーションをスケジューリングした後に、そのサーバーのリソースが十分であるかどうかを検討する必要があります。
依存関係にあるライブラリの互換性は、アプリケーションをコンテナ化することで解決できます。これは、各アプリケーションが独自の依存ライブラリを持ち、同じサーバー上の他のアプリケーションとのみカーネルを共有することを意味します。Kubernetesは、スケジューリングやリソース管理の問題を解決するために部分的に設計されています。
ちなみに、クラスター内に配置されたアプリケーションの数が多すぎて、その関係が複雑になると、リクエストに対するレスポンスが遅いなどの問題を解決できなくなります。そのため、サービスメッシュのようなサービスガバナンス技術が今後のトレンドとなるでしょう。
2. Kubernetesの学習方法
2.1 Kubernetes学習の難しさ
一般的にKubernetesは、カーネル、仮想化、コンテナ、SDN(Software-Defined Networking)、ストレージ、セキュリティ、トラステッドコンピューティングなど、深い技術スタックを持っているため、習得が難しいと言われています。フルスタックの技術とも言えるでしょう。
同時に、クラウド環境にKubernetesを導入するには、多くのクラウド製品が必要になります。例えばAlibaba Cloudでは、Kubernetesクラスターには、ECS(Elastic Compute Service)、VPC(Virtual Private Cloud)、SLB(Server Load Balancer)、セキュリティグループ、Log Service、CloudMonitor、ミドルウェア製品であるAHAS(Application High Availability Service)、ARMS(Application Real-Time Monitoring Service)、ASM(Alibaba Cloud Service Mesh)、Auto Scalingなど、さまざまなクラウド製品が使われています。
最後に、Kubernetesは汎用的なコンピューティングプラットフォームなので、データベースなどの様々なビジネスシーンで利用されています。私が知る限りでは、当社のデータベースアプライアンス「PolarDB Box」もKubernetesをベースに構築する予定です。また、Kubernetesはエッジコンピューティングや機械学習、ストリームコンピューティングなどにも利用されています。
2.2 背景と実践、そして概念の整理
私の個人的な経験では、Kubernetesを学ぶためには、「背景」「実践」「概念」の3つのアプローチで理解する必要があります。
背景知識はとても重要です。特に、この技術の進化と現在の状況を理解することが重要です。
具体的には、chrootコマンドからコンテナ技術がどのように発展したのかなど、Kubernetesを構成するさまざまな技術がどのように進化してきたのかを知る必要があります。また、技術の進化を促した問題点についても知っておく必要があります。技術の進化とその原動力を理解して初めて、今後の技術進化の方向性を判断することができます。
加えて、技術のランドスケープを理解する必要があります。Kubernetesの場合は、コンテナ、CI/CD(Continuous Integration and Continuous Delivery)、マイクロサービス、サービスメッシュなど、クラウドネイティブな技術スタック全体を理解する必要があります。そうすることで、テクノロジースタック全体の中でのKubernetesの位置づけが見えてきます。
こうした基本的な背景知識に加えて、Kubernetesの技術を学び、実践することが非常に重要です。
大勢のエンジニアと問題を解決してきた経験から言うと、技術的な内容を丁寧に勉強している人はほとんどいません。よく冗談で「エンジニアには2種類あって、1つは検索エンジニア、もう1つは研究エンジニアだ」と言うことがあります。多くのエンジニアは何か問題が発生すると、まずGoogleで検索します。それがうまくいかなければ、すぐにチケットを提出します。これでは、技術を深く理解することはできません。
最後に、技術について考え、頭の中で概念化する必要があります。私自身の経験では、技術的な内容を理解した後、その奥にもっと本質的なものがあるのではないかと、常に自問自答する必要があると感じています。言い換えれば、複雑な細部に潜り込んで、それらを結びつけるパターンを発見する必要があるということです。
ここでは、2つの例を使ってこのアプローチを説明します。
2.3 冷蔵庫から見たクラスタコントローラの理解
最初の例では、クラスタコントローラを扱います。Kubernetesを学んでいると、宣言型API、演算子、望ましい状態指向のデザインなどの用語をよく耳にします。本質的には、これらの概念はすべてKubernetesのコントローラを指しています。
では、Kubernetesコントローラとは何でしょうか。前述の図は、クラスター制御ノードとワーカーノードを含む、古典的なKubernetesのアーキテクチャを示しています。コントロールノードには、セントラルデータベース、APIサーバ、スケジューラ、そしていくつかのコントローラがあります。
中央データベースはクラスタの中核となるストレージシステムであり、APIサーバはクラスタの制御ポータルであり、スケジューラは十分なリソースを持つノードにアプリケーションをスケジューリングする役割を担っています。ここでは、コントローラに注目してみましょう。コントローラーの機能を文章で表現すると、"夢を実現するため "に使うものと言えるでしょう。その意味で、私はコントローラーの役割を果たすことが多いのです。娘が「パパ、アイス食べたい」と言ったとしたら、娘はクラスターのユーザーであり、私はその願いを実現する責任者、つまりコントローラーです。
Kubernetesクラスターには、制御ノードのほかに多くのワーカーノードがあり、そのすべてに2つのプロキシがあります。KubeletとProxyです。Kubeletは、ノード上のアプリケーションの起動や停止など、ワーカーノードの管理を行います。Proxyは、サービス定義を具体的なiptablesやIPVSのルールとして実装する役割を担います。ここでいうサービスの概念とは、iptablesやIPVSを使って負荷分散を行うことを意味しています。
コントローラの視点から1枚目の写真を見ると、2枚目の写真のようになります。クラスタには、データベース、クラスタエントリ、および複数のコントローラが含まれます。スケジューラ、Kubelet、Proxyなどのこれらのコンポーネントは、クラスタ内のさまざまなリソースの定義を継続的に観測し、コンテナの起動やiptablesの設定など、具体的な設定として実装していきます。
コントローラという観点からKubernetesを考えると、Kubernetesの最も基本的な原理である「コントローラの使用」が見えてきます。
このようなコントローラーは、私たちの日常生活の中にあふれています。冷蔵庫がその良い例です。冷蔵庫を制御するといっても、冷蔵庫の中の冷蔵システムや照明を直接制御するのではなく、冷蔵庫を開けると中の照明が点灯するようになっています。また、希望の温度を設定しておけば、留守中でも冷蔵庫はその温度を保ってくれます。このように、コントローラーが働いているのです。
2.4 永続的な名前空間の理由
2つ目の例では、実際の問題のトラブルシューティングを見てみましょう。問題は、削除できない名前空間です。トラブルシューティングの手順は少し複雑なので、順を追って説明します。
名前空間とは、前出の図の1枚目の写真のように、Kubernetesクラスター内のストレージボックスのようなものです。この箱が名前空間で、消しゴムや鉛筆が入っています。
ネームスペースは作成したり削除したりすることができます。しかし、「名前空間を削除できない」という問題がよく発生します。この問題を解決する方法がわからない場合、どうすればよいのでしょうか。まず、クラスターの管理ポータルであるAPIサーバーが、この削除操作をどのように処理しているかを調べてみるとよいでしょう。
APIサーバーはアプリケーションです。このアプリケーションがどのように動作するかを理解するために、このアプリケーションのログレベルを上げることができます。この問題では、APIサーバーが削除コマンドを受信するが、その他の情報はないことがわかります。
ここで、名前空間の削除プロセスを理解する必要があります。名前空間を削除しても、その名前空間はすぐには削除されません。代わりに、まず「削除中」の状態になります。その後、ネームスペースコントローラがこの状態を検出します。
ネームスペースコントローラの動作を理解するために、コントローラのログレベルを上げて詳細なログを見ることができます。すると、コントローラがすべてのAPIグループを取得しようとしていることがわかります。
ここで、2つのことを理解する必要があります。1つ目は、なぜ名前空間を削除する際にコントローラがAPIグループを取得しようとするのか、次に、APIグループとは何かです。
まず、2つ目の質問から始めましょう。APIグループは、クラスターのAPIを分類する仕組みです。例えば、ネットワーク関連のAPIはネットワーキンググループに置かれます。また、ネットワーキングAPIグループで作成されたリソースもこのグループに属します。
次に、ネームスペースコントローラがAPIグループをフェッチする理由を理解する必要があります。これは、コントローラが名前空間を削除すると、その名前空間内のすべてのリソースも削除されるためです。この操作は、フォルダを削除したときに、そのフォルダに含まれるすべてのファイルが削除されるのとは異なります。
名前空間にはリソースが含まれており、リソースはインデックスのような仕組みでこの名前空間を指しています。クラスタは、すべてのAPIグループをトラバースして、削除するネームスペースを指し示すすべてのリソースを見つけ、これらのリソースを1つずつ削除する必要があります。
APIグループをトラバースすると、クラスターのAPI Serverがそのエクステンションと通信します。これは、API Serverのエクステンションが一部のAPIグループも実装できるためです。そのため、API Serverは、削除する名前空間にこの拡張機能で定義されたリソースが含まれているかどうかを確認するために、その拡張機能と通信する必要があります。
ここで、この問題は、APIサーバーとその拡張機能の間の通信問題であることがわかります。したがって、リソース削除の問題は、ネットワークの問題です。
Alibaba Cloudでは、KubernetesクラスタはVPCインスタンス(仮想ローカルエリアネットワーク(VLAN))で作成されます。デフォルトでは、VPCインスタンスは自身のCIDRブロックしか知らず、クラスタ内のコンテナは一般的にVPCインスタンスとは異なるCIDRブロックを使用します。例えば、VPCインスタンスがCIDRブロック172を使用している場合、コンテナはCIDRブロック192を使用することがあります。
コンテナのCIDRブロックのルートエントリをVPCインスタンスのルートテーブルに追加することで、コンテナがVPCネットワーク上で通信することを許可することができます。
図の右下では、2つのクラスタノードがCIDRブロック172に位置しているため、CIDRブロック192のルートエントリをルートテーブルに追加する必要があります。そうすると、VPCインスタンスはコンテナに送信されたデータを正しいノードに転送することができ、ノードはデータを特定のコンテナに送信することができます。
ここでは、ノードがクラスタに追加されると、ルートコントローラによってルートエントリが追加されます。ルーティングコントローラは、新しいノードがクラスタに追加されたことを検出した直後に、ルートテーブルにルートエントリを追加します。
ルートエントリの追加は、VPCの操作です。この操作は、ローカルマシンからクラウドのリソースにアクセスするのと似ているため、実行には必ず承認が必要になります。
ルーティングコントローラーが実行する認証は、ルーティングコントローラーをRAMロールの常駐クラスタノードにバインドすることです。RAMロールには、一般的に一連の認証ルールがあります。
最後に、RAMロールを確認すると、あるユーザーが認証ルールを変更したことで問題が発生していることがわかります。
Alibaba CloudにおけるKubernetesの詳細については、https://www.alibabacloud.com/product/kubernetes
ここに記載されている見解は参考情報であり、必ずしもAlibaba Cloudの公式見解を示すものではありません。
本ブログは英語版からの翻訳です。オリジナルはこちらからご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。
アリババクラウドは日本に2つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ