クラウドネイティブ：Docker、Kubernetes、サービスメッシュの理解

このブログでは、**アリババ**のエンジニアが、**Docker**、**Kubernetes**、そして**Istio**のような**サービスメッシュ**やその他**クラウドネイティブ**のあらゆるものについての考えや理解について語っています。

*本ブログは英語版からの翻訳です。オリジナルは[こちら](https://www.alibabacloud.com/blog/cloud-native-from-docker-to-kubernetes-and-to-service-meshes_595604)からご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。*

#Dockerについての考え
ここでは、Dockerの実践ガイドを読んだ後の感想を紹介します。

[Docker](https://www.docker.com/?spm=a2c65.11461447.0.0.15d87863YiFv0v)は、分散アプリケーションの構築、出荷、実行のために設計されたLinuxコンテナツールセットです。Dockerは、アプリケーションの分離と再利用性を確保する[コンテナ化]()のプロセスや、物理マシンのセキュリティを確保するための機能的な方法である仮想化のプロセスを支援します。

多くの点で、Dockerはクラウドネイティブのパズルとなるものの最初の主流の1つでした。

下の図は、Dockerがどのように物事を効率化するために使用できるかを示したものです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/414fa3a5-ed00-35ad-28cb-72ccfdbe3d81.png)

###Dockerとは何か
以下のポイントは、Dockerとは何か、何をするのかをまとめたものです。

- Dockerは、アプリケーションのライフサイクル全体を連結する一種の契約と表現することができます。その中核的な強みは、アプリケーションの出荷を高速化し、全体的な生産性を向上させることです。
- Dockerは[仮想マシン](https://www.techopedia.com/definition/4805/virtual-machine-vm)とは根本的に異なります。Docker、つまりコンテナ化の概念自体は仮想化ではありません。マシンのハードウェアをシミュレートしているわけでもありません。むしろ、Dockerはアプリケーションを中心に構築されており、オープンな[dockerfile](https://docs.docker.com/engine/reference/builder/?spm=a2c65.11461447.0.0.15d87863YiFv0v)標準を使用して、設定や依存関係を含むアプリケーションをカプセル化しています。仮想マシンは、リソース管理に重点を置いてオペレーティングシステム層で動作します。
- また、Dockerは[Chef](https://www.chef.io/?spm=a2c65.11461447.0.0.15d87863YiFv0v)や[Jenkins](https://jenkins.io/?spm=a2c65.11461447.0.0.15d87863YiFv0v)と緊密に統合することができます。
- [Docker Hub](https://hub.docker.com/?spm=a2c65.11461447.0.0.15d87863YiFv0v)はコンテナイメージ管理の中心であり、Dockerアプリケーションの特徴を最もよく反映しています。各イメージは名前とタグ付けが可能で、固有のIDを持っています。


また、Dockerはアプリケーションのライフサイクルのすべてのステージとうまく統合されています。

- 開発：Dockerは、プロセスがその環境であることを考えると、開発環境の一貫性を確保し、Make、Chef、[Puppet](https://puppet.com/)などの従来の設定ツールと連携することができます。また、イメージが小さく、開発者に優しいのも特徴です。Dockerfilesを使用することで、ソースからイメージへの自動化を可能にします。
- DevOps：Dockerは[Git](https://git-scm.com/?spm=a2c65.11461447.0.0.15d87863YiFv0v)からDocker Hub、Jenkinsまでの自動化されたワークフローを可能にします。継続的なチェックイン、継続的なインテグレーション、継続的なデプロイ、継続的なデリバリーの包括的なワークフローを採用しています。
- 本番環境：Dockerは、[Swarm](https://docs.docker.com/engine/swarm/?spm=a2c65.11461447.0.0.15d87863YiFv0v)やKubernetesなどのPaaS（[Platform-as-a-Service](https://searchcloudcomputing.techtarget.com/definition/Platform-as-a-Service-PaaS?spm=a2c65.11461447.0.0.15d87863YiFv0v)）製品が輝く場所でもあります。


Dockerは以下のことを担当しています。

1、マルチホストコンテナのランタイムステータスと構成管理。
2、マルチホストおよびマルチコンテナのオーケストレーション環境におけるセキュリティ、ログ、トラブルシューティングの管理。

#Kubernetesについて
以前にもほのめかしたように、[Kubernetes](https://kubernetes.io/?spm=a2c65.11461447.0.0.15d87863YiFv0v)はコンテナ化されたアプリケーションやDockerが普及し、コンテナを管理するプラットフォームとして利用され始めた後に登場しました。ここでは前回同様、Kubernetesの実践ガイドを読んだ後の反省点を発表します。

###なぜKubernetesなのか
Kubernetesの人気はDockerと密接に関係しています。Dockerが広く適応したことで、Platform-as-a-Service（PaaS）が実現可能になりました。Kubernetesは、Googleで大規模なデータセンターの管理に多くの実務経験を積んだ後に生まれた偉大な成果です。また、当時起こったコンテナ化されたアプリケーションの爆発的な普及にも大きく後押しされました。[Google](https://cloud.google.com/?spm=a2c65.11461447.0.0.15d87863YiFv0v)の目標は新しい業界標準を確立することでしたが、間違いなくそれを実現することが出来ました。

Kubernetesは本当にクラウドネイティブ革命の大きな一端を担っています。

Googleは2004年にコンテナの利用を開始し、2006年にはコントロールグループ（一般的にはcgroupsと呼ばれる）をリリースしました。同時に、[Borg](https://research.google/pubs/pub43438/)や[Omega](https://research.google/pubs/pub41684/)などのクラスタ管理プラットフォームをクラウドやITインフラで内部的に利用していました。[Kubernetes](https://kubernetes.io/?spm=a2c65.11461447.0.0.15d87863YiFv0v)はBorgに触発され、Omegaを含むコンテナ管理者の経験と教訓を利用しています。

この魅力的な歴史については、[このブログ](https://blog.aquasec.com/a-brief-history-of-containers-from-1970s-chroot-to-docker-2016?spm=a2c65.11461447.0.0.15d87863YiFv0v)で詳しく読むことができます。

今後検討すべきことは、Kubernetesは[Compose](https://www.compose.com/?spm=a2c65.11461447.0.0.15d87863YiFv0v)やDocker Swarm、さらには[Mesos](http://mesos.apache.org/?spm=a2c65.11461447.0.0.15d87863YiFv0v)のような他の初期の来訪者をどうやって打ち負かしたのでしょうか？この質問に対する答えは、簡単に言えば、Kubernetesの優れた抽象化モデルにあります。Kubernetesは原理的には設計の核心部分で異なっています。Kubernetesを理解するためには、その根底にあるアーキテクチャに関わるすべての概念と用語を俯瞰する必要があります。

###Kubernetesの主な概念
以下に、多かれ少なかれKubernetes特有の概念を紹介します。Kubernetes の背後にある概念を理解することで、Kubernetes がどのように動作するかについてより一般的な理解を得ることができます。

- [Pod](https://kubernetes.io/docs/concepts/workloads/pods/?spm=a2c65.11461447.0.0.15d87863YiFv0v): Podは、Kubertnetesアプリケーションの基本的な実行ユニットです。Podはいくつかのコンテナを組み合わせたもので、すべてが同じホスト上で実行され、同じ[ネットワークネームスペース](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/?spm=a2c65.11461447.0.0.15d87863YiFv0v)、IPアドレス、ポートを使用しています。これらのコンテナは、ローカルホストを使用して、お互いに通信したり、発見したりします。さらに、これらのコンテナは同じストレージボリュームを共有することができます。コンテナではなくPodは、Kubernetesの中で最も小さなユニットで、作成、スケジュール、管理を行います。Podは、より高い抽象度と、より柔軟なデプロイと管理モデルを提供します。
- [コントローラー（Controller）](https://kubernetes.io/docs/concepts/architecture/controller/?spm=a2c65.11461447.0.0.15d87863YiFv0v)：Controllerはタスク実行のためのロジックユニットで、負荷のスケジューリングや実行はController Managerで管理されます。[ReplicationController（RC）](https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/?spm=a2c65.11461447.0.0.15d87863YiFv0v)はコントローラの特定の実装の1つで、弾力的なスケーリングとローリングアップグレードを担当します。各オブジェクトモデルには、ノード、サービス、エンドポイント、SA、PV、デプロイメント、ジョブなどの対応するコントローラがあります。また、拡張機能を使ってコントローラを実装することもできます。

- [サービス](https://kubernetes.io/docs/concepts/services-networking/service/?spm=a2c65.11461447.0.0.15d87863YiFv0v)：Kubernetesにおけるサービスとは、実際のアプリケーションサービスを抽象化したものです。Podにアクセスするための論理セットとポリシーを定義します。サービスはPodの単一アクセスポイント（またはプロキシ）として機能し、バックエンドのPodがどのように動作するかを知らなくてもアプリケーションにアクセスできるようにします。これにより、サービスのプロキシとディスカバリのメカニズムが簡素化され、拡張とメンテナンスが非常に簡単になります。サービスはPod以外にも、Kubernetesクラスタの外部サービスなど、任意のバックエンドのプロキシとして機能することができます。この場合、セレクタは必要ありませんが、サービスと同じ名前のエンドポイントを手動で定義する必要があります。
- [ラベル（Label）](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/?spm=a2c65.11461447.0.0.15d87863YiFv0v)：ラベルは、Podなどのオブジェクトに付けられるキー/値のペアです。ラベルは、Podをサービスやレプリケーションコントローラと緩く結合するために使用されます。
- [ノード](https://kubernetes.io/docs/concepts/architecture/nodes/?spm=a2c65.11461447.0.0.15d87863YiFv0v)：Kubernetes用語でのノードとは、単にホストやマシンのことです。Kubernetesでは、ノードはワーカーマシンとして定義されており、仮想マシンであっても物理マシンであっても構いません。
もっと詳しく知りたい場合は、ソース自体から入手したり、公式ドキュメントを直接読んだりすることができますが、それは[ここ](https://kubernetes.io/docs/concepts/?spm=a2c65.11461447.0.0.15d87863YiFv0v)で見つけることができます。

####Kubernetesと主流のCI/CDモデル
継続的インテグレーションとデプロイメントは、間違いなくPlatform-as-a-Service（PaaS）モデルの最も特徴的な特徴であり、同様にクラウドネイティブでもあり、ほとんどのクラウドベンダーはKubernetesをベースにしたPaaSモデルを提供しています。そのため、一般的なユーザーエクスペリエンスと、これらのモデルで使用される具体的なCI/CD（Continuous integration and continuous delivery）パイプラインが、異なるサービスを区別するものとなっています。一般的にCI/CDパイプラインは、プロジェクトが作成された時点で開始され、アプリケーションのライフサイクルの各段階に浸透します。これがCI/CDパイプラインの核心的な利点です。CI/CD パイプラインは、開発ワークフローのすべてのステップに統合することができ、オールインワンのアプリケーションサービス体験を提供します。

以下に、Kubernetesで使用できる主流のCI/CDツールをいくつか紹介します。

- [Jenkins](https://www.jenkins.io/zh/?spm=a2c65.11461447.0.0.15d87863YiFv0v)：Jenkinsはハドソンから出てきたもので、Javaで実装されています。おそらく現在最も広く使われているCI/CDツールです。
- [TeamCity](https://www.jetbrains.com/teamcity/?spm=a2c65.11461447.0.0.15d87863YiFv0v)：TeamCityは、公開されている課題追跡やフォーラム、100種類のビルド構成など、強力な機能がたくさんあります。
- [CircleCI](https://circleci.com/?spm=a2c65.11461447.0.0.15d87863YiFv0v): CircleCiは、安全な方法で大規模な開発プロセスを簡単に自動化したい場合に最適です。そのクライアントはFacebook、Kickstarter、Spotifyなどです。
- [Travis CI](https://travis-ci.org/?spm=a2c65.11461447.0.0.15d87863YiFv0v)： Travis CIは自信を持ってテストやデプロイを行うのに役立ちます。実際、Apacheのプロジェクトでは、統合テストにTravis CIを使用しています。各PRにはTCタスクがあり、ユニットテストを実行し、コードが仕様通りであることを確認します。
- [Drone CI](https://drone.io/?spm=a2c65.11461447.0.0.15d87863YiFv0v)： Droneは、忙しい開発チームに便利なセルフサービスの継続的デリバリープラットフォームです。彼らのクライアントには、Cisco、Ebay、Gannett、VMWare、Capital Oneなどがあります。

####Kubernetesで連携するAPIオブジェクトとメタデータ
さて、最後にKubernetesで重要なのは、Kubernetesと連携しているAPIオブジェクトとメタデータです。

- [kuberctl](https://kubernetes.io/docs/reference/kubectl/overview/?spm=a2c65.11461447.0.0.15d87863YiFv0v)：KuberctlはKubernetesのコマンドラインツールです。
- [KubernetesのAPI](https://kubernetes.io/docs/concepts/overview/kubernetes-api/?spm=a2c65.11461447.0.0.15d87863YiFv0v)に直接アクセス:Kubernetes API ServerはKubernetesのアクセスポイントです。RESTfulな操作をサービスし、Swaggerを統合してAPIを定義・記述します。詳しくは[こちら](https://kubernetes.io/docs/concepts/overview/kubernetes-api/?spm=a2c65.11461447.0.0.15d87863YiFv0v#openapi-and-swagger-definitions)をご覧ください。
- [Kubebuilder SDK](https://kubernetes.io/blog/2018/08/10/introducing-kubebuilder-an-sdk-for-building-kubernetes-apis-using-crds/?spm=a2c65.11461447.0.0.15d87863YiFv0v):KubebuilderはKubernetesのメインSDKです。
実際には、メタデータはAPIオブジェクトの基本情報を定義するだけです。それはメタデータフィールドで表現され、以下の属性を持っています。

- namespace： namespacフィールドは、API オブジェクトの名前空間を指定します。namespaceフィールドは、APIオブジェクトの名前空間を指定します。名前空間は、Kubernetesがサポートする同じ物理クラスタにバックアップされた複数の仮想クラスタとして定義することができます。異なるプロジェクト、チーム、ユーザーは異なる名前空間を使用して、他のポリシー以外にも管理やカスタマイズされたアクセス制御を行うことができます。ノード以外のAPIオブジェクトはすべて名前空間に属します。これは`metadata.namespace`によって定義されます。このフィールドが定義されていない場合は、defaultと呼ばれるデフォルトの名前空間が使用されます。
- name: nameフィールドはAPIオブジェクトの名前を指定します。nameフィールドは重要な属性です。これは、`metadata.name`All API オブジェクトは、Node を除くすべての API オブジェクトが名前空間に属しています。同じ名前空間内では、これらのオブジェクトは名前で識別されます。したがって、APIオブジェクトの名前は、ネームスペース内で一意でなければなりません。ノードとネームスペースはシステム内で一意でなければなりません。

- ラベル：ラベルフィールドは、APIオブジェクトのラベルを指定します。ラベルは、APIオブジェクトに添付されるキー/値のペアです。ラベルは、オブジェクトの識別属性を指定するために使用することを意図しており、ユーザーにとって意味があり、関連性がありますが、コアシステムに直接セマンティクスを意味するものではありません。ラベルは、オブジェクトのサブセットを整理したり、選択したりするために使用することができます。`ReplicationController` と `ReplicationService` は、Podに関連付けるためにラベルを使用します。Podはラベルを使ってノードを選択することもできます。
- アノテーション:アノテーションフィールドは、API オブジェクトのアノテーションを指定します。アノテーションフィールドは、オブジェクトに任意の非識別メタデータを添付するために使用されますが、オブジェクトの選択には使用できません。アノテーションは、構造化または非構造化の長いデータであることができ、キー/値のペアでもあります。

#サービスメッシュについて
ここでは、Kubernetes、Dockerに次ぐ本当に大きな存在であるService Meshについて、さっそく見ていきたいと思います。私にとって、Service Meshの核心的な強みはその制御機能であり、特にService Meshの[Istio](https://istio.io/?spm=a2c65.11461447.0.0.15d87863YiFv0v)が特に輝く場所の一つです。

実際、このままIstioのモデルが標準化されて拡大していけば、コンテナ化されたアプリケーションのデファクトPaaS製品になるのではないか、と言いたいところです。とはいえ、Apacheの[Dubbo](https://dubbo.apache.org/en-us/?spm=a2c65.11461447.0.0.15d87863YiFv0v)、[Envoy](https://www.envoyproxy.io/?spm=a2c65.11461447.0.0.15d87863YiFv0v)、[NGINX](https://www.nginx.com/?spm=a2c65.11461447.0.0.15d87863YiFv0v)、さらには[Conduit](https://conduit.io/?spm=a2c65.11461447.0.0.15d87863YiFv0v)のサービスメッシュも統合の選択肢としては有効だと思います。

Istioは本当に優れた選択肢だと思うので、まずそれに焦点を当ててみましょう。

#Istioとは？
サービスメッシュを理解するには、サービスメッシュの設計原理を理解する必要があります。Istioの設計原理とは何かを見てみましょう。一言で言えば、コンテナスケジューリングプラットフォームに実装する前に、サービスの抽象化モデルが先に来るということです。下の図を考えてみてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/ca88e2d1-0228-3b11-59b1-4ebef6772072.png)

Istioとは何かについて詳しく知りたい方は、[こちらの公式説明](https://istio.io/latest/docs/concepts/what-is-istio/)をチェックしてみてください。

一般的に言えば、Istioのサービスモデルは、サービスとそのインスタンスの抽象モデルを含んでいます。Istioは基礎となるプラットフォームから独立しており、プラットフォーム固有のアダプタを持ち、プラットフォームで見つかったメタデータから様々なフィールドをモデルオブジェクトに入力します。この中で、サービスは、他のサービスが参照するユニークな名前を持つアプリケーションのユニットであり、サービスインスタンスは、サービスを実装するPod、仮想マシン、コンテナです。サービスには複数のバージョンが存在する可能性があります。

次にサービスモデルです。各サービスは、[完全修飾ドメイン名（またはFQDN）](https://kb.iu.edu/d/aiuv?spm=a2c65.11461447.0.0.15d87863YiFv0v)と、サービスが接続をリッスンしている1つ以上のポートを持ちます。サービスは、それに関連付けられた単一のロードバランサと仮想IPアドレスを持つことができます。また、サービスモデルにはインスタンスも含まれます。各サービスは1つまたは複数のインスタンスを持ち、サービスの実際の顕在化として機能します。インスタンスはPodのようなエンティティを表し、それぞれがネットワークのエンドポイントを持っています。

Istioの設計には、サービスのバージョンも含まれており、サービスの各バージョンは、特定のバージョンに関連付けられたラベルのユニークなセットによって区別されています。もう一つの概念がラベルで、これは特定のサービス・バージョンのインスタンスに割り当てられる単純なキー値のペアです。同じバージョンのすべてのインスタンスは、同じタグを持たなければなりません。Istioは、基礎となるプラットフォームがサービス・レジストリとサービス発見メカニズムを提供することを期待しています。

#Cloud Nativeについて知っておくべきことをさらにご紹介
以上、Docker、Kubernetes、そしてIstioのようなサービスメッシュについての話をしてきた中で、一つ大きなことを省いてしまったのですが、それは「クラウドネイティブ」ということです。では、「クラウドネイティブ」とは何か？何を意味するのか、「クラウドネイティブ」になるためには何が必要なのか、様々な解釈がありますが、[Cloud Native Computing Foundation（CNCF）](https://www.cncf.io/?spm=a2c65.11461447.0.0.15d87863YiFv0v)によると、クラウドネイティブは以下のように理解できます。

クラウドネイティブの技術とソリューションは、クラウド上にスケーラブルなアプリケーションを構築して実行できる技術と定義することができます。クラウドネイティブは、DockerやKubernetesのようなコンテナ技術の開発に伴って生まれたもので、一般的にはステートレスであること、継続的なデリバリが可能であること、マイクロサービスが可能であることなどの特徴を持っています。

クラウドネイティブの技術とソリューションは、優れた耐障害性と管理の容易さを保証し、特にCI/CDパイプラインによる自動化の堅牢なシステムと組み合わせることで、あまり手間をかけずに強いインパクトを与えることができます。

今日では、CNCFによると、Kubernetesの使用を含むクラウドネイティブと "クラウドネイティブ "の概念がありますが、Kubernetesはパズルの唯一のピースではなく、むしろ始まりに過ぎません。伝統的なマイクロサービスソリューションである[Dubbo](https://dubbo.apache.org/en-us/?spm=a2c65.11461447.0.0.15d87863YiFv0v)がCNCFの景観の一部となっている現在、これらのソリューションが提供するユニークな機能や機能に惹かれて、クラウドネイティブに惹かれる人が増えています。

言い換えれば、今日のクラウドネイティブの風景では、多くの意味で、クラウドネイティブはKubernetesから始まって、最後にはIstioのようなサービスメッシュソリューションを受け入れることになるかもしれません。このブログで見てきたように、最初はDocker、次にKubernetes、そして今はService Meshがあります。

*アリババクラウドは日本に２つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
[アリババクラウドジャパン公式ページ](https://www.alibabacloud.com/ja)*