diff --git a/content/ja/case-studies/nordstrom/index.html b/content/ja/case-studies/nordstrom/index.html new file mode 100644 index 0000000000000..3a9f6473bc3d1 --- /dev/null +++ b/content/ja/case-studies/nordstrom/index.html @@ -0,0 +1,106 @@ +--- +title: Nordstrom ケーススタディ +case_study_styles: true +cid: caseStudies +css: /css/style_case_studies.css +--- + +
+

ケーススタディ:
厳しい小売環境下で数百万ドルのコスト削減を実現 + + +

+ +
+ +
+ 企業名  Nordstrom     所在地  シアトル、ワシントン     業界  小売り +
+ +
+
+
+
+

課題

+ NordstromはECサイトのNordstrom.comを含む技術的な運用の効率と速度を向上させたいと考えていました。同時に、Nordstrom Technologyでは技術的な運用コストを抑える方法を模索していました。 +
+

解決策

+ 4年前にDevOpsを採用し、CI/CD(継続的インテグレーション/継続的デプロイ)プロジェクトを開始した後、同社はデプロイ時間を3か月から30分に短縮しました。ですが、環境間でさらに高速化するために、KubernetesでオーケストレーションされたDockerコンテナを採用しました。 +
+ + +
+ +
+ +

影響

+ Kubernetesを使用するNordstrom Technologyの開発者はより迅速にデプロイし、「アプリケーションを書くことだけに集中できる」と、NordstromのKubernetesエンタープライズプラットフォーム構築チームのシニアエンジニアであるDhawal Patel氏は言います。チームはOpsの効率を向上させ、ワークロードに応じてCPU使用率を5倍から12倍改善しました。「私たちは何千もの仮想マシンを実行していますが、これらのリソースをすべて効率的に使用できているわけではありません。」とPatel氏は語ります。「Kubernetes を採用することで、クラスターの効率化に挑戦することなく以前の10倍効率化できています。」 +
+
+
+
+
+ 私たちは常にテクノロジーを通じて最適化してより大きな価値を提供する方法を探しています。Kubernetesを用いて私たちは開発効率と運用効率という2つの効率を示します。これは双方にとって好都合です。 +

-Nordstrom社シニアエンジニア Dhawal Patel
+
+
+
+
+ 5年前にDhawal Patelが小売業者のウェブサイトのアプリケーション開発者としてNordstromに入社したとき、彼は開発サイクルをスピードアップする機会があることに気づきました。 +

+ DevOpsの初期の頃、Nordstrom Technologyは従来のサイロチームと機能モデルを引き続き採用していました。「開発者として、コードの記述やビジネスへの価値の追加よりも環境の修正に多くの時間を費やしました。」とPatel氏は言います。「私はそれについて情熱的だったので、修正する機会を与えられました。」 +

+ 同社はまた、より早く行動することに熱心であり、2013年に最初の継続的インテグレーション/継続的デプロイ(CI/CD)プロジェクトを開始しました。このプロジェクトはNordstromのクラウドネイティブへの旅の第一歩でした。 +

+ 開発チームと運用チームのメンバーは社内のオンプレミスサーバーを使ってCI/CDパイプラインを構築しました。チームはChefを選択し、仮想IPの作成、サーバー、および負荷分散を自動化したクックブックを作成しました。「プロジェクトの完了後、デプロイにかかる時間は3か月から30分になりました。」とPatal氏は言います。「開発環境、テスト環境、ステージング環境、本番環境という複数環境があったため、各環境でChefクックブックを流すのに30分かかりました。その時点で大きな成果でした。」 +

しかし、新しい環境はまだ立ち上がるのに時間がかかりすぎていたため、次のステップはクラウドでの作業でした。現在、Nordstrom Technologyはエンタープライズプラットフォームを構築しており、同社の1,500名の開発者はKubernetesでオーケストレーションされたDockerコンテナとして動作するアプリケーションをクラウド上にデプロイできるようになりました。 + +
+
+
+
+ 「私たちはKubernetesに人気が出ることに賭けました。コミュニティのサポートとプロジェクトの速度の初期の指標に基づいて、Kubernetesを中心にシステムを再構築しました。」 +
+
+
+
+ +「オンプレミスで仮想マシン(VM)を取得するのに数週間かかったため、クラウドはリソースへの高速なアクセスを提供しました。」とPatal氏は言います。「しかし、今ではたった5分で同じことができます。」 +

+Nordstromがクラスター上のコンテナのスケジューリングに初めて進出したのはCoreOS fleetベースの自社開発のシステムでした。彼らは、Kubernetesに切り替えるときに、Kubernetes 1.0がリリースされるまでそのシステムでいくつかのPoCプロジェクトを始めました。「コミュニティのサポートとプロジェクトの速度の初期の指標に基づき、Kubernetesの人気が出るだろうと確信したため、Kubernetesを中心にシステムを再構築しました。」とNordstromのKubernetesチームのシニアマネージャーMarius Grigoriuは述べます。 +Kubernetesは多くの場合、マイクロサービスのプラットフォームと考えられていますが、NordstromにおいてKubernetesで始動した最初の重要なプロダクションの役割を担うアプリケーションはJiraでした。「最初のアプリケーションとして期待していた理想的なマイクロサービスではありませんでした。」とPatal氏は認めます。「しかし、それに取り組んでいたチームは本当にDockerとKubernetesに情熱を傾けており、実際に使いたいと考えていました。彼らは自社運用のアプリケーションをオンプレミスで実行しており、それをKubernetesに移行したいと考えていました。」 +

+参加したチームにとってメリットはすぐに現れました。「Kubernetesクラスターを使っているチームは心配する問題が少ないという事実を気に入っていました。インフラストラクチャーやオペレーティングシステムを管理する必要はありませんでした。」とGrigoriu氏は言います。「初期の導入者は、Kubernetesの宣言的な性質を好んでいます。彼らは対処しなければならなかった領域が減少したことを好んでます。」 +
+
+
+
+ 「Kubernetesクラスターを使っているチームは心配する問題が少ないという事実を気に入っていました。インフラストラクチャーやオペレーティングシステムを管理する必要はありませんでした。」とGrigoriu氏は言います。「初期の導入者は、Kubernetesの宣言的な性質を好んでいます。彼らは対処しなければならなかった領域が減少したことを好んでます。」 +
+
+ +
+
+ これらの初期の導入者をサポートするため、Patelのチームはクラスターの成長とプロダクションレベルのサービスの構築を開始しました。「私たちは監視のためのPrometheusGrafanaフロントエンドを組み合わせました。また、Fluentdを使用してログをElasticsearchにプッシュしたため、ログの集約が可能になりました。」とPatel氏は語ります。チームはまたCNCFプロジェクトを含む多数のオープンソースコンポーネントを追加し、Kubernetes、Terraformおよびkube2iamに貢献しました。 +

+現在、Nordstrom TechnologyにはKubernetesを使っている開発チームは60以上あり、成功事例が出てくるにつれて、より多くのチームが参加するようになりました。「これを試してみようと思った最初の顧客基盤は次のユーザに勧め始めています。」Patel氏は言います。「初期の導入者の1人はDockerコンテナを使用しており、本番環境での実行方法がわかりませんでした。私たちは彼と一緒に座って、15分以内に本番環境に展開しました。彼はそれが素晴らしいと思い、彼の組織のより多くの人々が加わり始めました。」 +

+Nordstrom Technologyの場合、クラウドネイティブへの移行によって、開発と運用の効率が大幅に向上しています。Kubernetesを利用する開発者はより迅速にデプロイでき、アプリケーションの価値の構築に専念できます。こうしたノウハウを取り入れるために、1つのチームにおいてクラウド上に仮想マシンを構築し、マージからデプロイまでに25分かかるところからスタートしました。Kubernetesへの切り替えにより、プロセスが5倍高速化され、マージからデプロイまでの時間が5分に改善しました。 +
+ +
+
+ 「Kubernetesを使用することで、クラスタの効率化を図ることもなく、現在のCPU使用率は40%、つまり10倍になりました。直接クラウドに移行した場合には2600台以上のVMになるところが、同数の顧客用Podで済むようになりました。これらのPodを40台のVMで実行しているため、運用上のオーバーヘッドが大幅に削減されました。」 +
+
+ +
+ スピードは素晴らしく、簡単に実証できますが、より大きな影響はおそらくその運用効率にあります。「AWSで何千ものVMを実行する場合、全体的な平均CPU使用率は約4%です。」とPatel氏は言います。「Kubernetesを使用することで、クラスタの効率化を図ることもなく、現在のCPU使用率は40%、つまり10倍になりました。直接クラウドに移行した場合には2600台以上のVMになるところが、同数の顧客用Podで済むようになりました。これらのPodを40台のVMで実行しているため、運用上のオーバーヘッドが大幅に削減されました。」 +

+ Nordstrom TechnologyはオンプレミスのベアメタルでKubernetesを実行することも検討しています。Patel氏は言います。「オンプレミスのKubernetesクラスターを構築できれば、クラウドの力を活用してオンプレミスでリソースを迅速にプロビジョニングできます。次に、開発者にとってのインターフェースはKubernetesです。Kubernetesのみと連携しているため、自社のサービスがオンプレミスにデプロイされていることに気付かないこともあります。」 + そのため、Patel氏はKubernetesのマルチクラスター機能の開発に熱心に取り組んでいます。「クラスターフェデレーションにより、オンプレミスをプライマリクラスターとして、クラウドをセカンダリバースト可能なクラスターとして使用できます。」と彼は言います。「つまり、アニバーサリーセールやブラックフライデーセールがあり、さらにコンテナが必要な場合は、クラウドにアクセスできます。」 +

+ この種の可能性とGrigoriuとPatelのチームがKubernetesを使用してすでに提供しているという反響が、Nordstromをそもそもクラウドネイティブジャーニーに導いた理由です。「現在の小売環境は、可能な限り即応性と柔軟性を高めようとしています。」とGrigoriu氏は言います。「Kubernetesにより、開発側と運用側の両方にとってバランスよく効率化されます。これは双方にとって好都合です。」 + +
+
diff --git a/content/ja/case-studies/nordstrom/nordstrom_featured_logo.png b/content/ja/case-studies/nordstrom/nordstrom_featured_logo.png new file mode 100644 index 0000000000000..a557ffa82f12e Binary files /dev/null and b/content/ja/case-studies/nordstrom/nordstrom_featured_logo.png differ diff --git a/content/ja/case-studies/sos/index.html b/content/ja/case-studies/sos/index.html new file mode 100644 index 0000000000000..bce98342753d0 --- /dev/null +++ b/content/ja/case-studies/sos/index.html @@ -0,0 +1,110 @@ +--- +title: SOS International ケーススタディ +linkTitle: SOS International +case_study_styles: true +cid: caseStudies +css: /css/style_case_studies.css +logo: sos_featured_logo.png +--- + + +
+

ケーススタディ:
SOS International: Kubernetesを使ってコネクテッドな世界での緊急支援を提供 + +

+ +
+ +
+ 企業名  SOS International     所在地  フレゼレクスベア、デンマーク +     業界  医療および旅行支援 +
+ +
+
+
+
+

課題

+ SOS Internationalは60年にわたり、北欧諸国の顧客に信頼性の高い緊急医療および旅行支援を提供してきました。近年、同社のビジネス戦略では、デジタル分野での開発をさらに強化する必要がありましたが、ITシステムに関しては +3つの従来のモノリス(Java, .NET, およびIBMのAS/400)とウォーターフォールアプローチにおいて「SOSには非常に断片化された遺産があります。」とエンタープライズアーキテクチャー責任者のMartin Ahrentsen氏は言います。「新しいテクノロジーと新しい働き方の両方を導入することを余儀なくされているので、市場投入までの時間を短縮して効率を高めることができました。それははるかに機敏なアプローチであり、私たちにはそれをビジネスに提供するのに役立つプラットフォームが必要でした。」 + + +

+

ソリューション

+ 標準システムの模索に失敗した後、同社はプラットフォームアプローチを採用し、Kubernetesとコンテナテクノロジーを包含するソリューションを探すことにしました。RedHat OpenShiftはSOSの断片化されたシステムに最適であることが証明されました。「私たちはコード言語とその他の両方を使用する多くの異なる技術を持っていますが、それらはすべて新しいプラットフォーム上のリソースを使用できます。」とAhrentsen氏は言います。同社の3つのモノリスのうち、「この最先端のテクノロジーを2つ(.NETとJava)に提供できます。」このプラットフォームは2018年春に公開されました。現在、マイクロサービスアーキテクチャーに基づく6つの未開発プロジェクトが進行中であり、さらに、同社のJavaアプリケーションはすべて「リフト&シフト」移行を行っています。 +

+

影響

+ Kubernetesによって「市場投入までの時間、アジリティ、および変更と新しいテクノロジーに適応する能力の向上を実現しました。」とAhrentsen氏は語ります。「ソフトウェアのリリース準備ができてからリリースできるまでの時間が大幅に改善されました。」SOS Internationalの考え方も劇的に変わりました。「自動化、CI/CDパイプラインの作成を容易にするKubernetesとスクリプトへの簡単なアクセスがあるので、この完全自動化の方法に至る所で多くの内部的な関心が生まれています。旅を始めるために非常に良い気候を作り出しています。」と彼は言います。さらに、クラウドネイティブのコミュニティの一員であることは、同社が人材を引き付けるのに役立ちました。「彼らはクールで新しいテクノロジーを使いたいと思っています」とAhrentsen氏は言います。「新しいテクノロジーを提供したという理由でITプロフェッショナルが我が社を選んでいたことが新人研修の時にわかりました。」 +
+ +
+
+
+
+ 「クラウドネイティブソフトウェアとテクノロジーが現在推進している変化の速度は驚くべきものであり、それをフォローして採用することは私たちにとって非常に重要です。Kubernetesとクラウドネイティブが提供する驚くべき技術はデジタルの未来に向けてSOSに変化をもたらしました。 +

- SOS International エンタープライズアーキテクチャー責任者 Martin Ahrentsen
+
+
+
+
+

SOS Internationalは60年にわたり、北欧諸国の顧客に信頼性の高い緊急医療および旅行支援を提供してきました。

+ SOSのオペレータは年間100万件の案件を扱い、100万件以上の電話を処理しています。しかし、過去4年間で同社のビジネス戦略にデジタル空間でのますます激しい開発が必要になりました。

+ ITシステムに関していえば、会社のデータセンターで稼働する3つの伝統的なモノリスとウォーターフォールアプローチにおいて「SOSは非常に断片化された資産があります。」とエンタープライズアーキテクチャー責任者のMartin Ahrentsen氏は言います。「市場投入までの時間を短縮し、効率を高めるために新しいテクノロジーと新しい働き方の両方を導入する必要がありました。それははるかに機敏なアプローチであり、それをビジネスに提供するために役立つプラットフォームが必要でした。」 +

+ Ahrentsen氏と彼のチームは長い間SOSで機能する標準のソリューションを探していました。「私たちのような支援会社はそれほど多くないので、それにふさわしい標準システムを入手することはできません。完全に一致するものがないのです。」と彼は言います。「標準システムを採用したとしても、あまりにもひねりすぎて、もはや標準ではないものになるでしょう。そのため、新しいデジタルシステムとコアシステムを構築するために使用できるいくつかの共通コンポーネントを備えたテクノロジープラットフォームを見つけることにしました。」 + + +
+
+
+
+ 「私たちは新しいデジタルサービスを提供しなければなりませんが、古いものも移行する必要があります。そして、コアシステムをこのプラットフォーム上に構築された新しいシステムに変換する必要があります。このテクノロジーを選んだ理由の1つは古いデジタルサービスを変更しながら新しいサービスを構築できるからです。」 + +

- SOS International エンタープライズアーキテクチャー責任者 Martin Ahrentsen
+ +
+
+
+
+ Kubernetesができることを理解すると、Ahrentsen氏はすぐにビジネスニーズを満たすことができるプラットフォームに目を向けました。同社はDockerコンテナとKubernetesを組み込んだRed HatのOpenShift Container Platformを採用しました。また、RedHat Hyperconverged Infrastructureや一部のミッドウェアコンポーネントなど、すべてオープンソースコミュニティで提供されている技術スタックも利用することを決めました。

+ + テクノロジーやアジリティの適合性、法的要件、およびコンピテンシーという同社の基準に基づくと、OpenShiftソリューションはSOSの断片化されたシステムに完全に適合するように思われました。「私たちはコード言語とそれ以外の両方を使用する多くの異なる技術を持っています。それらはすべて新しいプラットフォーム上のリソースを使用できます。」とAhrentsen氏は言います。同社の3つのモノリスのうち、「この最先端のテクノロジーを2つ(.NETとJava)に提供できます。」

+ +プラットフォームは2018年春に公開されました。マイクロサービスアーキテクチャーに基づく6つの未開発のプロジェクトが最初に開始されました。さらに、同社のJavaアプリケーションはすべて「リフト&シフト」移行を行っています。最初に稼働しているKubernetesベースのプロジェクトの一つがRemote Medical Treatmentです。これは顧客が音声、チャット、ビデオを介してSOSアラームセンターに連絡できるソリューションです。「完全なCI/CDパイプラインと最新のマイクロサービスアーキテクチャーをすべて2つのOpenShiftクラスターセットアップで実行することに焦点を当てて、非常に短時間で開発できました。」とAhrentsen氏は言います。北欧諸国へのレスキュートラックの派遣に使用されるOnsite、および、レッカー車の追跡を可能にするFollow Your Truckも展開されています。 +
+
+
+
+ 「新しいテクノロジーを提供したという理由でITプロフェッショナルが我が社を選んでいたことが新人研修の時にわかりました。」 +

- SOS International エンタープライズアーキテクチャー責任者 Martin Ahrentsen
+
+
+ +
+
+ プラットフォームがまだオンプレミスで稼働しているのは、保険業界のSOSの顧客の一部は同社がデータを処理しているためまだクラウド戦略を持っていないためです。KubernetesはSOSがデータセンターで開始し、ビジネスの準備ができたらクラウドに移行できるようにします。「今後3~5年にわたって、彼らすべてが戦略を持ち、そして、データを取り出してクラウドに移行できるでしょう。」とAhrentsen氏は言います。機密データと非機密データのハイブリッドクラウド設定に移行する可能性もあります。

+ + SOSの技術は確かに過渡期にあります。「新しいデジタルサービスを提供する必要がありますが、古いものも移行する必要があり、コアシステムをこのプラットフォーム上に構築された新しいシステムに変換しなければなりません。」とAhrentsen氏は言います。「このテクノロジーを選んだ理由の1つは古いデジタルサービスを変更しながら新しいサービスを構築できるからです。」

+ + しかし、Kubernetesはすでに市場投入までの時間を短縮しており、そのことは、新興プロジェクトがいかに迅速に開発され、リリースされたかにも表れています。「ソフトウェアのリリース準備ができてからリリース可能になるまでの時間は劇的に改善されました。」とAhrentsen氏は言います。

+ + さらに、クラウドネイティブのコミュニティの一員であることは、エンジニア、オペレーター、アーキテクトの数を今年60から100に増やすという目標を追求するうえで、同社が人材を引き付けるのに役立ちました。「彼らはクールで新しいテクノロジーを使いたいと思っています。」とAhrentsenは言います。「新しいテクノロジーを提供したという理由でITプロフェッショナルが我が社を選んでいたことが新人研修の時にわかりました。」 + +
+ +
+
+ 「すべてが接続され、データを送信する未来の世界は、新しい市場機会という点で私たちにとって大きな可能性を生み出します。しかし、それはまたITプラットフォームと私たちが提供すべきものに大きな需要をもたらすでしょう。」 +

- SOS International エンタープライズアーキテクチャー責任者 Martin Ahrentsen
+
+ +
+ SOS Internationalの考え方も劇的に変わりました。「自動化、CI/CDパイプラインの作成を容易にするKubernetesとスクリプトへの簡単なアクセスがあるので、この完全自動化の方法に至る所で多くの内部的な関心が生まれています。旅を始めるために非常に良い気候を作り出しています。」

+ + SOSにおけるこの旅では、デジタル化と最適化がキーワードです。「ITがこれを実現するには改善する必要がありますが、それはKubernetesとプラットフォームの使用方法だけではありません。」とAhrentsen氏は言います。「これは自動化、そしてその後の機械学習やその他進行中の興味深い技術の準備が整ったシステムを構築する方法でもあります。」

+ + 代表例:自動車へのIoTの導入。欧州委員会は現在、すべての新車にeCallを装備することを義務づけています。eCallは重大な交通事故が発生した場合に位置やその他データを送信します。SOSはこのサービスをスマート自動支援として提供しています。「電話を受けて、緊急対応チームを派遣する必要があるかどうか、またはそれほど大きな影響がないどうかを確認します。」とAhrentsen氏は言います。「すべてが接続され、データを送信する未来の世界は、新しい市場機会という点で私たちにとって大きな可能性を生み出します。しかし、それはまたITプラットフォームと私たちが提供すべきものに大きな需要をもたらすでしょう。」

+ + Ahrentsen氏はSOSが技術の選択を行ってきたことを考えると、この課題に十分対応できると感じています。「クラウドネイティブソフトウェアとテクノロジーが現在推進している変化の速度は驚くべきものであり、それに追従して採用することは私たちにとって非常に重要です。」と彼は言います。「Kubernetesとクラウドネイティブが提供する驚くべきテクノロジーは、デジタルの未来に向けてSOSに変化をもたらし始めました。」 +
+
diff --git a/content/ja/case-studies/sos/sos_featured_logo.png b/content/ja/case-studies/sos/sos_featured_logo.png new file mode 100644 index 0000000000000..a97671af6d8f5 Binary files /dev/null and b/content/ja/case-studies/sos/sos_featured_logo.png differ diff --git a/content/ja/docs/concepts/scheduling/_index.md b/content/ja/docs/concepts/scheduling/_index.md new file mode 100644 index 0000000000000..c428c68198949 --- /dev/null +++ b/content/ja/docs/concepts/scheduling/_index.md @@ -0,0 +1,5 @@ +--- +title: "スケジューリング" +weight: 90 +--- + diff --git a/content/ja/docs/concepts/scheduling/kube-scheduler.md b/content/ja/docs/concepts/scheduling/kube-scheduler.md new file mode 100644 index 0000000000000..1b69474896f87 --- /dev/null +++ b/content/ja/docs/concepts/scheduling/kube-scheduler.md @@ -0,0 +1,118 @@ +--- +title: Kubernetesのスケジューラー +content_template: templates/concept +weight: 60 +--- + +{{% capture overview %}} + +Kubernetesにおいて、_スケジューリング_ とは、{{< glossary_tooltip term_id="kubelet" >}}が{{< glossary_tooltip text="Pod" term_id="pod" >}}を稼働させるために{{< glossary_tooltip text="Node" term_id="node" >}}に割り当てることを意味します。 + +{{% /capture %}} + +{{% capture body %}} + +## スケジューリングの概要{#scheduling} + +スケジューラーは新規に作成されたPodで、Nodeに割り当てられていないものを監視します。スケジューラーは発見した各Podのために、稼働させるべき最適なNodeを見つけ出す責務を担っています。そのスケジューラーは下記で説明するスケジューリングの原理を考慮に入れて、NodeへのPodの割り当てを行います。 + +Podが特定のNodeに割り当てられる理由を理解したい場合や、カスタムスケジューラーを自身で作ろうと考えている場合、このページはスケジューリングに関して学ぶのに役立ちます。 + +## kube-scheduler + +[kube-scheduler](https://kubernetes.io/docs/reference/command-line-tools-reference/kube-scheduler/)はKubernetesにおけるデフォルトのスケジューラーで、{{< glossary_tooltip text="コントロールプレーン" term_id="control-plane" >}}の一部分として稼働します。 +kube-schedulerは、もし希望するのであれば自分自身でスケジューリングのコンポーネントを実装でき、それを代わりに使用できるように設計されています。 + +kube-schedulerは、新規に作成された各Podや他のスケジューリングされていないPodを稼働させるために最適なNodeを選択します。 +しかし、Pod内の各コンテナにはそれぞれ異なるリソースの要件があり、各Pod自体にもそれぞれ異なる要件があります。そのため、既存のNodeは特定のスケジューリング要求によってフィルターされる必要があります。 + +クラスター内でPodに対する割り当て要求を満たしたNodeは_割り当て可能_ なNodeと呼ばれます。 +もし適切なNodeが一つもない場合、スケジューラーがNodeを割り当てることができるまで、そのPodはスケジュールされずに残ります。 + +スケジューラーはPodに対する割り当て可能なNodeをみつけ、それらの割り当て可能なNodeにスコアをつけます。その中から最も高いスコアのNodeを選択し、Podに割り当てるためのいくつかの関数を実行します。 +スケジューラーは_binding_ と呼ばれる処理中において、APIサーバーに対して割り当てが決まったNodeの情報を通知します。 + +スケジューリングを決定する上で考慮が必要な要素としては、個別または複数のリソース要求や、ハードウェア/ソフトウェアのポリシー制約、affinityやanti-affinityの設定、データの局所性や、ワークロード間での干渉などが挙げられます。 + +## kube-schedulerによるスケジューリング{#kube-scheduler-implementation} + +kube-schedulerは2ステップの操作によってPodに割り当てるNodeを選択します。 + +1. フィルタリング + +2. スコアリング + +_フィルタリング_ ステップでは、Podに割り当て可能なNodeのセットを探します。例えばPodFitsResourcesフィルターは、Podのリソース要求を満たすのに十分なリソースをもつNodeがどれかをチェックします。このステップの後、候補のNodeのリストは、要求を満たすNodeを含みます。 +たいてい、リストの要素は複数となります。もしこのリストが空の場合、そのPodはスケジュール可能な状態とはなりません。 + +_スコアリング_ ステップでは、Podを割り当てるのに最も適したNodeを選択するために、スケジューラーはリストの中のNodeをランク付けします。 +スケジューラーは、フィルタリングによって選ばれた各Nodeに対してスコアを付けます。このスコアはアクティブなスコア付けのルールに基づいています。 + +最後に、kube-schedulerは最も高いランクのNodeに対してPodを割り当てます。もし同一のスコアのNodeが複数ある場合は、kube-schedulerがランダムに1つ選択します。 + +### デフォルトのポリシーについて + +kube-schedulerは、デフォルトで用意されているスケジューリングポリシーのセットを持っています。 + +### フィルタリング + +- `PodFitsHostPorts`: Nodeに、Podが要求するポートが利用可能かどうかをチェックします。 + +- `PodFitsHost`: Podがそのホスト名において特定のNodeを指定しているかをチェックします。 + +- `PodFitsResources`: Nodeに、Podが要求するリソース(例: CPUとメモリー)が利用可能かどうかをチェックします。 + +- `PodMatchNodeSelector`: PodのNodeSelectorが、Nodeのラベルにマッチするかどうかをチェックします。 + +- `NoVolumeZoneConflict`: Podが要求するVolumeがNode上で利用可能かを、障害が発生しているゾーンを考慮して評価します。 + +- `NoDiskConflict`: NodeのVolumeがPodの要求を満たし、すでにマウントされているかどうかを評価します。 + +- `MaxCSIVolumeCount`: CSI Volumeをいくつ割り当てるべきか決定し、それが設定された上限を超えるかどうかを評価します。 + +- `CheckNodeMemoryPressure`: もしNodeがメモリーの容量が逼迫している場合、また設定された例外がない場合はそのPodはそのNodeにスケジュールされません。 + +- `CheckNodePIDPressure`: もしNodeのプロセスIDが枯渇しそうになっていた場合や、設定された例外がない場合はそのPodはそのNodeにスケジュールされません。 + +- `CheckNodeDiskPressure`: もしNodeのストレージが逼迫している場合(ファイルシステムの残り容量がほぼない場合)や、設定された例外がない場合はそのPodはそのNodeにスケジュールされません。 + +- `CheckNodeCondition`: Nodeは、ファイルシステムの空き容量が完全になくなった場合、ネットワークが利用不可な場合、kubeletがPodを稼働させる準備をできていない場合などに、その状況を通知できます。Nodeがこの状況下かつ設定された例外がない場合、Podは該当のNodeにスケジュールされません。 + +- `PodToleratesNodeTaints`: PodのTolerationがNodeのTaintを許容できるかチェックします。 + +- `CheckVolumeBinding`: Podが要求するVolumeの要求を満たすか評価します。これはPersistentVolumeClaimがバインドされているかに関わらず適用されます。 + +### スコアリング + +- `SelectorSpreadPriority`: 同一のService、StatefulSetや、ReplicaSetに属するPodを複数のホストをまたいで稼働させます。 + +- `InterPodAffinityPriority`: weightedPodAffinityTermの要素をイテレートして合計を計算したり、もし一致するPodAffinityTermがNodeに適合している場合は、"重み"を合計値に足したりします。:最も高い合計値を持つNode(複数もあり)が候補となります。 + +- `LeastRequestedPriority`: 要求されたリソースがより低いNodeを優先するものです。言い換えると、Nodeに多くのPodが稼働しているほど、Podが使用するリソースが多くなり、その要求量が低いNodeが選択されます。 + +- `MostRequestedPriority`: 要求されたリソースがより多いNodeを優先するものです。このポリシーは、ワークロードの全体セットを実行するために必要な最小数のNodeに対して、スケジュールされたPodを適合させます。  + +- `RequestedToCapacityRatioPriority`: デフォルトのリソーススコアリング関数を使用して、requestedToCapacityベースのResourceAllocationPriorityを作成します。 + +- `BalancedResourceAllocation`: バランスのとれたリソース使用量になるようにNodeを選択します。 + +- `NodePreferAvoidPodsPriority`: Nodeの`scheduler.alpha.kubernetes.io/preferAvoidPods`というアノテーションに基づいてNodeの優先順位づけをします。この設定により、2つの異なるPodが同じNode上で実行しないことを示唆できます。 + +- `NodeAffinityPriority`: "PreferredDuringSchedulingIgnoredDuringExecution"の値によって示されたNode Affinityのスケジューリング性向に基づいてNodeの優先順位づけを行います。詳細は[NodeへのPodの割り当て](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/)にて確認できます。 + +- `TaintTolerationPriority`: Node上における許容できないTaintsの数に基づいて、全てのNodeの優先順位リストを準備します。このポリシーでは優先順位リストを考慮してNodeのランクを調整します。 + +- `ImageLocalityPriority`: すでにPodに対するコンテナイメージをローカルにキャッシュしているNodeを優先します。 + +- `ServiceSpreadingPriority`: このポリシーの目的は、特定のServiceに対するバックエンドのPodが、それぞれ異なるNodeで実行されるようにすることです。このポリシーではServiceのバックエンドのPodが既に実行されていないNode上にスケジュールするように優先します。これによる結果として、Serviceは単体のNode障害に対してより耐障害性が高まります。 + +- `CalculateAntiAffinityPriorityMap`: このポリシーは[PodのAnti-Affinity](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity)の実装に役立ちます。 + +- `EqualPriorityMap`: 全てのNodeに対して等しい重みを与えます。 + +{{% /capture %}} +{{% capture whatsnext %}} +* [スケジューラーのパフォーマンスチューニング](/docs/concepts/scheduling/scheduler-perf-tuning/)を参照してください。 +* kube-schedulerの[リファレンスドキュメント](/docs/reference/command-line-tools-reference/kube-scheduler/)を参照してください。 +* [複数のスケジューラーの設定](https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/)について学んでください。 +{{% /capture %}} diff --git a/content/ja/docs/concepts/services-networking/_index.md b/content/ja/docs/concepts/services-networking/_index.md index eea2c65b33e01..3a33830f2f5d0 100755 --- a/content/ja/docs/concepts/services-networking/_index.md +++ b/content/ja/docs/concepts/services-networking/_index.md @@ -1,5 +1,4 @@ --- -title: "Services, Load Balancing, and Networking" +title: "Service、負荷分散とネットワーキング" weight: 60 --- - diff --git a/content/ja/docs/concepts/services-networking/service.md b/content/ja/docs/concepts/services-networking/service.md new file mode 100644 index 0000000000000..a7f6447d29f1a --- /dev/null +++ b/content/ja/docs/concepts/services-networking/service.md @@ -0,0 +1,909 @@ +--- +title: Service +feature: + title: サービスディスカバリーと負荷分散 + description: > + Kubernetesでは、なじみのないサービスディスカバリーの機構を使用するためにユーザーがアプリケーションの修正をする必要はありません。KubernetesはPodにそれぞれのIPアドレス割り振りや、Podのセットに対する単一のDNS名を提供したり、それらのPodのセットに対する負荷分散が可能です。 + +content_template: templates/concept +weight: 10 +--- + + +{{% capture overview %}} + +{{< glossary_definition term_id="service" length="short" >}} + +Kubernetesでは、なじみのないサービスディスカバリーの機構を使用するためにユーザーがアプリケーションの修正をする必要はありません。 +KubernetesはPodにそれぞれのIPアドレス割り振りや、Podのセットに対する単一のDNS名を提供したり、それらのPodのセットに対する負荷分散が可能です。 + +{{% /capture %}} + +{{% capture body %}} + +## Serviceを利用する動機 + +{{< glossary_tooltip term_id="pod" text="Pod" >}}は停止が想定して設計されています。 Podが作成され、もしそれらが停止する時、Podは再作成されません。 +{{< glossary_tooltip term_id="deployment" >}}をアプリケーションを稼働させるために使用すると、Podを動的に作成・削除してくれます。 + +各Podはそれ自身のIPアドレスを持ちます。しかしDeploymentでは、ある時点において同時に稼働しているPodのセットは、その後のある時点において稼働しているPodのセットとは異なる場合があります。 + +この仕組みはある問題を引き起こします。もし、あるPodのセット(ここでは"バックエンド"と呼びます)がクラスター内で他のPodのセット(ここでは"フロントエンド"と呼びます)に対して機能を提供する場合、フロントエンドのPodがワークロードにおけるバックエンドを使用するために、バックエンドのPodのIPアドレスを探し出したり、記録し続けるためにはどうすればよいでしょうか? + +ここで_Service_ について説明します。 + +## Serviceリソース {#service-resource} + +Kubernetesにおいて、ServiceはPodの論理的なセットや、そのPodのセットにアクセスするためのポリシーを定義します(このパターンはよくマイクロサービスと呼ばることがあります)。 +ServiceによってターゲットとされたPodのセットは、たいてい {{< glossary_tooltip text="セレクター" term_id="selector" >}} (セレクターなしのServiceを利用したい場合は[下記](#services-without-selectors)を参照してください)によって定義されます。 + +例えば、3つのレプリカが稼働しているステートレスな画像処理用のバックエンドを考えます。これらのレプリカは代替可能です。— フロントエンドはバックエンドが何であろうと気にしません。バックエンドのセットを構成する実際のPodのセットが変更された際、フロントエンドクライアントはその変更を気にしたり、バックエンドのPodのセットの情報を記録しておく必要はありません。 + +Serviceによる抽象化は、クライアントからバックエンドのPodの管理する責務を分離することを可能にします。 + +### クラウドネイティブのサービスディスカバリー + +アプリケーション内でサービスディスカバリーのためにKubernetes APIが使える場合、ユーザーはエンドポイントを{{< glossary_tooltip text="API Server" term_id="kube-apiserver" >}}に問い合わせることができ、またService内のPodのセットが変更された時はいつでも更新されたエンドポイントの情報を取得できます。 + +非ネイティブなアプリケーションのために、KubernetesはアプリケーションとバックエンドPodの間で、ネットワークポートやロードバランサーを配置する方法を提供します。 + +## Serviceの定義 + +KubernetesのServiceはPodと同様にRESTのオブジェクトです。他のRESTオブジェクトと同様に、ユーザーはServiceの新しいインスタンスを作成するためにAPIサーバーに対してServiceの定義を`POST`できます。 + +例えば、TCPで9376番ポートで待ち受けていて、`app=Myapp`というラベルをもつPodのセットがあるとします。 + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: my-service +spec: + selector: + app: MyApp + ports: + - protocol: TCP + port: 80 + targetPort: 9376 +``` + +この定義では、"my-service"という名前のついた新しいServiceオブジェクトを作成します。これは`app=Myapp`ラベルのついた各Pod上でTCPの9376番ポートをターゲットとします。 + +Kubernetesは、このServiceに対してIPアドレス("clusterIP"とも呼ばれます)を割り当てます。これはServiceのプロキシーによって使用されます(下記の[仮想IPとServiceプロキシー](#virtual-ips-and-service-proxies)を参照ください)。 + +Serviceセレクターのコントローラーはセレクターに一致するPodを継続的にスキャンし、“my-service”という名前のEndpointオブジェクトに対して変更をPOSTします。 + +{{< note >}} +Serviceは`port`から`targetPort`へのマッピングを行います。デフォルトでは、利便性のために`targetPort`フィールドは`port`フィールドと同じ値で設定されます。 +{{< /note >}} + +Pod内のポートの定義は名前を設定でき、Serviceの`targetPort`属性にてその名前を参照できます。これは単一の設定名をもつService内で、複数の種類のPodが混合していたとしても有効で、異なるポート番号を介することによって利用可能な、同一のネットワークプロトコルを利用します。 +この仕組みはServiceをデプロイしたり、設定を追加する場合に多くの点でフレキシブルです。例えば、バックエンドソフトウェアにおいて、次のバージョンでPodが公開するポート番号を変更するときに、クライアントの変更なしに行えます。 + +ServiceのデフォルトプロトコルはTCPです。また、他の[サポートされているプロトコル](#protocol-support)も利用可能です。 + +多くのServiceが、1つ以上のポートを公開する必要があるように、Kubernetesは1つのServiceオブジェクトに対して複数のポートの定義をサポートしています。 +各ポート定義は同一の`protocol`または異なる値を設定できます。 + +### セレクターなしのService {#services-without-selectors} + +Serviceは多くの場合、KubernetesのPodに対するアクセスを抽象化しますが、他の種類のバックエンドも抽象化できます。 +例えば: + + * プロダクション環境で外部のデータベースクラスターを利用したいが、テスト環境では、自身のクラスターが持つデータベースを利用したい場合 + * Serviceを、異なるNamespace内のServiceや他のクラスターのServiceに向ける場合 + * ワークロードをKubernetesに移行するとき、アプリケーションに対する処理をしながら、バックエンドの一部をKubernetesで実行する場合 + +このような場合において、ユーザーはPodセレクター_なしで_ Serviceを定義できます。 + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: my-service +spec: + ports: + - protocol: TCP + port: 80 + targetPort: 9376 +``` + +このServiceはセレクターがないため、対応するEndpointオブジェクトは自動的に作成されません。 +ユーザーはEndpointオブジェクトを手動で追加することにより、向き先のネットワークアドレスとポートを手動でマッピングできます。 + +```yaml +apiVersion: v1 +kind: Endpoints +metadata: + name: my-service +subsets: + - addresses: + - ip: 192.0.2.42 + ports: + - port: 9376 +``` + +{{< note >}} +Endpointのipは、loopback (127.0.0.0/8 for IPv4, ::1/128 for IPv6), や +link-local (169.254.0.0/16 and 224.0.0.0/24 for IPv4, fe80::/64 for IPv6)に設定することができません。 + +{{< glossary_tooltip term_id="kube-proxy" >}}が仮想IPを最終的な到達先に設定することをサポートしていないため、Endpointのipアドレスは他のKubernetes ServiceのClusterIPにすることができません。 +{{< /note >}} + +セレクターなしのServiceへのアクセスは、セレクターをもっているServiceと同じようにふるまいます。上記の例では、トラフィックはYAMLファイル内で`192.0.2.42:9376` (TCP)で定義された単一のエンドポイントにルーティングされます。 + +ExternalName Serviceはセレクターの代わりにDNS名を使用する特殊なケースのServiceです。さらなる情報は、このドキュメントの後で紹介する[ExternalName](#externalname)を参照ください。 + +## 仮想IPとサービスプロキシー {#virtual-ips-and-service-proxies} + +Kubernetesクラスターの各Nodeは`kube-proxy`を稼働させています。`kube-proxy`は[`ExternalName`](#externalname)タイプ以外の`Service`用に仮想IPを実装する責務があります。 + +### なぜ、DNSラウンドロビンを使わないのでしょうか。 + +ここで湧き上がる質問として、なぜKubernetesは内部のトラフィックをバックエンドへ転送するためにプロキシーに頼るのでしょうか。 +他のアプローチはどうなのでしょうか。例えば、複数のAバリュー(もしくはIPv6用にAAAAバリューなど)をもつDNSレコードを設定し、ラウンドロビン方式で名前を解決することは可能でしょうか。 + +Serviceにおいてプロキシーを使う理由はいくつかあります。 + + * DNSの実装がレコードのTTLをうまく扱わず、期限が切れた後も名前解決の結果をキャッシュするという長い歴史がある。 + * いくつかのアプリケーションではDNSルックアップを1度だけ行い、その結果を無期限にキャッシュする。 + * アプリケーションとライブラリーが適切なDNS名の再解決を行ったとしても、DNSレコード上の0もしくは低い値のTTLがDNSに負荷をかけることがあり、管理が難しい。 + +### バージョン互換性 + +Kubernetes v1.0から、[user-spaceプロキシーモード](#proxy-mode-userspace)を利用できるようになっています。 +v1.1ではiptablesモードでのプロキシーを追加し、v1.2では、kube-proxyにおいてiptablesモードがデフォルトとなりました。 +v1.8では、ipvsプロキシーモードが追加されました。 + +### user-spaceプロキシーモード {#proxy-mode-userspace} + +このモードでは、kube-proxyはServiceやEndpointオブジェクトの追加・削除をチェックするために、Kubernetes Masterを監視します。 +各Serviceは、ローカルのNode上でポート(ランダムに選ばれたもの)を公開します。この"プロキシーポート"に対するどのようなリクエストも、そのServiceのバックエンドPodのどれか1つにプロキシーされます(Endpointを介して通知されたPodに対して)。 +kube-proxyは、どのバックエンドPodを使うかを決める際にServiceの`SessionAffinity`項目の設定を考慮に入れます。 + +最後に、user-spaceプロキシーはServiceの`clusterIP`(仮想IP)と`port`に対するトラフィックをキャプチャするiptablesルールをインストールします。 +そのルールは、トラフィックをバックエンドPodにプロキシーするためのプロキシーポートにリダイレクトします。 + +デフォルトでは、user-spaceモードにおけるkube-proxyはラウンドロビンアルゴリズムによってバックエンドPodを選択します。 + +![user-spaceプロキシーのService概要ダイアグラム](/images/docs/services-userspace-overview.svg) + +### `iptables`プロキシーモード {#proxy-mode-iptables} + +このモードでは、kube-proxyはServiceやEndpointオブジェクトの追加・削除のチェックのためにKubernetesコントロールプレーンを監視します。 +各Serviceでは、そのServiceの`clusterIP`と`port`に対するトラフィックをキャプチャするiptablesルールをインストールし、そのトラフィックをServiceのあるバックエンドのセットに対してリダイレクトします。 +各Endpointオブジェクトは、バックエンドのPodを選択するiptablesルールをインストールします。 + +デフォルトでは、iptablesモードにおけるkube-proxyはバックエンドPodをランダムで選択します。 + +トラフィックのハンドリングのためにiptablesを使用すると、システムのオーバーヘッドが少なくなります。これは、トラフィックがLinuxのnetfilterによってuser-spaceとkernel-spaceを切り替える必要がないためです。 +このアプローチは、オーバーヘッドが少ないことに加えて、より信頼できる方法でもあります。 + +kube-proxyがiptablesモードで稼働し、最初に選択されたPodが応答しない場合、そのコネクションは失敗します。 +これはuser-spaceモードでの挙動と異なります: user-spaceモードにおいては、kube-proxyは最初のPodに対するコネクションが失敗したら、自動的に他のバックエンドPodに対して再接続を試みます。 + +iptablesモードのkube-proxyが正常なバックエンドPodのみをリダイレクト対象とするために、Podの[ReadinessProbe](/docs/concepts/workloads/pods/pod-lifecycle/#container-probes)を使用してバックエンドPodが正常に動作しているか確認できます。これは、ユーザーがkube-proxyを介して、コネクションに失敗したPodに対してトラフィックをリダイレクトするのを除外することを意味します。 + +![iptablesプロキシーのService概要ダイアグラム](/images/docs/services-iptables-overview.svg) + +### IPVSプロキシーモード {#proxy-mode-ipvs} + +{{< feature-state for_k8s_version="v1.11" state="stable" >}} + +`ipvs`モードにおいて、kube-proxyはServiceとEndpointオブジェクトを監視し、IPVSルールを作成するために`netlink`インターフェースを呼び出し、定期的にKubernetesのServiceとEndpointとIPVSルールを同期させます。 +このコントロールループはIPVSのステータスが理想的な状態になることを保証します。 +Serviceにアクセスするとき、IPVSはトラフィックをバックエンドのPodに向けます。 + +IPVSプロキシーモードはiptablesモードと同様に、netfilterのフック関数に基づいています。ただし、基礎となるデータ構造としてハッシュテーブルを使っているのと、kernel-spaceで動作します。 +これは、IPVSモードにおけるkube-proxyはiptablesモードに比べてより低いレイテンシーでトラフィックをリダイレクトし、プロキシーのルールを同期する際にはよりパフォーマンスがよいことを意味します。   +他のプロキシーモードと比較して、IPVSモードはより高いネットワークトラフィックのスループットをサポートしています。 + +IPVSはバックエンドPodに対するトラフィックのバランシングのために多くのオプションを下記のとおりに提供します。 + +- `rr`: ラウンドロビン +- `lc`: 最低コネクション数(オープンされているコネクション数がもっとも小さいもの) +- `dh`: 送信先IPによって割り当てられたハッシュ値をもとに割り当てる(Destination Hashing) +- `sh`: 送信元IPによって割り当てられたハッシュ値をもとに割り当てる(Source Hashing) +- `sed`: 見込み遅延が最小なもの +- `nq`: キューなしスケジューリング + +{{< note >}} +IPVSモードでkube-proxyを稼働させるためには、kube-proxyを稼働させる前にNode上でIPVSを有効にしなければなりません。 + +kube-proxyはIPVSモードで起動する場合、IPVSカーネルモジュールが利用可能かどうかを確認します。 +もしIPVSカーネルモジュールが見つからなかった場合、kube-proxyはiptablesモードで稼働するようにフォールバックされます。 +{{< /note >}} + +![IPVSプロキシーのService概要ダイアグラム](/images/docs/services-ipvs-overview.svg) + +このダイアグラムのプロキシーモデルにおいて、ServiceのIP:Portに対するトラフィックは、クライアントがKubernetesのServiceやPodについて何も知ることなく適切にバックエンドにプロキシーされています。 + +特定のクライアントからのコネクションが、毎回同一のPodにリダイレクトされるようにするためには、`service.spec.sessionAffinity`を"ClientIP"にセットすることにより、クライアントのIPアドレスに基づいたSessionAffinityを選択することができます(デフォルトは"None")。 +また、`service.spec.sessionAffinityConfig.clientIP.timeoutSeconds`を適切に設定することにより、セッションのタイムアウト時間を設定できます(デフォルトではこの値は18,000で、3時間となります)。 + +## 複数のポートを公開するService + +いくつかのServiceにおいて、ユーザーは1つ以上のポートを公開する必要があります。Kubernetesは、Serviceオブジェクト上で複数のポートを定義するように設定できます。 +Serviceで複数のポートを使用するとき、どのポートかを明確にするために、複数のポート全てに対して名前をつける必要があります。 +例えば: + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: my-service +spec: + selector: + app: MyApp + ports: + - name: http + protocol: TCP + port: 80 + targetPort: 9376 + - name: https + protocol: TCP + port: 443 + targetPort: 9377 +``` + +{{< note >}} +KubernetesのPod名と同様に、ポート名は小文字の英数字と`-`のみ含める必要があります。また、ポート名の最初と最後の文字は英数字である必要があります。 + +例えば、`123-abc`や`web`という名前は有効で、`123_abc`や`-web`は無効です。 +{{< /note >}} + +## ユーザー所有のIPアドレスを選択する + +`Service`を作成するリクエストの一部として、ユーザー所有のclusterIPアドレスを指定することができます。 +これを行うためには`.spec.clusterIP`フィールドにセットします。 +使用例として、もしすでに再利用したいDNSエントリーが存在していた場合や、特定のIPアドレスを設定されたレガシーなシステムや、IPの再設定が難しい場合です。 + +ユーザーが指定したIPアドレスは、そのAPIサーバーのために設定されている`service-cluster-ip-range`というCIDRレンジ内の有効なIPv4またはIPv6アドレスである必要があります。 +もし無効なclusterIPアドレスの値を設定してServiceを作成した場合、問題があることを示すためにAPIサーバーはHTTPステータスコード422を返します。 + +## サービスディスカバリー + +Kubernetesは、Serviceオブジェクトを見つけ出すために2つの主要なモードをサポートしています。 - それは環境変数とDNSです。 + +### 環境変数 + +PodがNode上で稼働するとき、kubeletはアクティブな各Serviceに対して、環境変数のセットを追加します。 +これは[Docker links互換性](https://docs.docker.com/userguide/dockerlinks/)のある変数( +[makeLinkVariables関数](http://releases.k8s.io/{{< param "githubbranch" >}}/pkg/kubelet/envvars/envvars.go#L72)を確認してください)や、より簡単な`{SVCNAME}_SERVICE_HOST`や、`{SVCNAME}_SERVICE_PORT`変数をサポートします。この変数名で使われるService名は大文字に変換され、`-`は`_`に変換されます。 + +例えば、TCPポート6379番を公開していて、さらにclusterIPが10.0.0.11に割り当てられている`"redis-master"`というServiceは、下記のような環境変数を生成します。 + +```shell +REDIS_MASTER_SERVICE_HOST=10.0.0.11 +REDIS_MASTER_SERVICE_PORT=6379 +REDIS_MASTER_PORT=tcp://10.0.0.11:6379 +REDIS_MASTER_PORT_6379_TCP=tcp://10.0.0.11:6379 +REDIS_MASTER_PORT_6379_TCP_PROTO=tcp +REDIS_MASTER_PORT_6379_TCP_PORT=6379 +REDIS_MASTER_PORT_6379_TCP_ADDR=10.0.0.11 +``` + +{{< note >}} +Serviceにアクセスする必要のあるPodがあり、クライアントであるそのPodに対して環境変数を使ってポートとclusterIPを公開する場合、クライアントのPodが存在する*前に* Serviceを作成しなくてはなりません。 +そうでない場合、クライアントのPodはそれらの環境変数を作成しません。 + +ServiceのclusterIPを発見するためにDNSのみを使う場合、このような問題を心配する必要はありません。 +{{< /note >}} + +### DNS + +ユーザーは[アドオン](/docs/concepts/cluster-administration/addons/)を使ってKubernetesクラスターにDNS Serviceをセットアップできます(常にセットアップすべきです)。 + +CoreDNSなどのクラスター対応のDNSサーバーは新しいServiceや、各Service用のDNSレコードのセットのためにKubernetes APIを常に監視します。 +もしクラスターを通してDNSが有効になっている場合、全てのPodはDNS名によって自動的にServiceに対する名前解決をするようにできるはずです。 + +例えば、Kubernetesの`"my-ns"`というNamespace内で`"my-service"`というServiceがある場合、KubernetesコントロールプレーンとDNS Serviceが協調して動作し、`"my-service.my-ns"`というDNSレコードを作成します。 +`"my-ns"`というNamespace内のPodは`my-service`という名前で簡単に名前解決できるはずです(`"my-service.my-ns"`でも動作します)。 + +他のNamespace内でのPodは`my-service.my-ns`といった形で指定しなくてはなりません。これらのDNS名は、そのServiceのclusterIPに名前解決されます。 + +Kubernetesは名前付きのポートに対するDNS SRV(Service)レコードもサポートしています。もし`"my-service.my-ns"`というServiceが`"http"`という名前のTCPポートを持っていた場合、IPアドレスと同様に、`"http"`のポート番号を探すために`_http._tcp.my-service.my-ns`というDNS SRVクエリを実行できます。 + +KubernetesのDNSサーバーは`ExternalName` Serviceにアクセスする唯一の方法です。 +[DNS Pods と Service](/docs/concepts/services-networking/dns-pod-service/)にて`ExternalName`による名前解決に関するさらなる情報を確認できます。 + +## Headless Service {#headless-service} + +場合によっては、負荷分散と単一のService IPは不要です。このケースにおいて、clusterIP(`.spec.clusterIP`)の値を`"None"`に設定することにより、"Headless"とよばれるServiceを作成できます。 + +ユーザーは、Kubernetesの実装と紐づくことなく、他のサービスディスカバリーのメカニズムと連携するためにHeadless Serviceを使用できます。 +例えば、ユーザーはこのAPI上でカスタム{{< glossary_tooltip term_id="operator-pattern" text="オペレーター" >}}を実装することができます。 + +この`Service`においては、clusterIPは割り当てられず、kube-proxyはこのServiceをハンドリングしないのと、プラットフォームによって行われるはずの +ロードバランシングやプロキシーとしての処理は行われません。DNSがどのように自動で設定されるかは、定義されたServiceが定義されたラベルセレクターを持っているかどうかに依存します。 + +### ラベルセレクターの利用 + +ラベルセレクターを定義したHeadless Serviceにおいて、EndpointコントローラーはAPIにおいて`Endpoints`レコードを作成し、`Service`のバックエンドにある`Pod`へのIPを直接指し示すためにDNS設定を修正します。 + +### ラベルセレクターなしの場合 + +ラベルセレクターを定義しないHeadless Serviceにおいては、Endpoint コントローラーは`Endpoint`レコードを作成しません。 +しかしDNSのシステムは下記の2つ両方を探索し、設定します。 + + * [`ExternalName`](#externalname)タイプのServiceに対するCNAMEレコード + * 他の全てのServiceタイプを含む、Service名を共有している全ての`Endpoint`レコード + +## Serviceの公開 (Serviceのタイプ) {#publishing-services-service-types} + +ユーザーのアプリケーションのいくつかの部分において(例えば、frontendsなど)、ユーザーのクラスターの外部にあるIPアドレス上でServiceを公開したい場合があります。 + +Kubernetesの`ServiceTypes`によって、ユーザーがどのような種類のServiceを使いたいかを指定することが可能です。 +デフォルトでは`ClusterIP`となります。 + +`Type`項目の値と、そのふるまいは以下のようになります。 + + * `ClusterIP`: クラスター内部のIPでServiceを公開する。このタイプではServiceはクラスター内部からのみ疎通性があります。このタイプはデフォルトの`ServiceType`です。 + * [`NodePort`](#nodeport): 各NodeのIPにて、静的なポート(`NodePort`)上でServiceを公開します。その`NodePort` のServiceが転送する先の`ClusterIP` Serviceが自動的に作成されます。`:`にアクセスすることによって`NodePort` Serviceにアクセスできるようになります。 + * [`LoadBalancer`](#loadbalancer): クラウドプロバイダーのロードバランサーを使用して、Serviceを外部に公開します。クラスター外部にあるロードバランサーが転送する先の`NodePort`と`ClusterIP` Serviceは自動的に作成されます。 + * [`ExternalName`](#externalname): `CNAME`レコードを返すことにより、`externalName`フィールドに指定したコンテンツ(例: `foo.bar.example.com`)とServiceを紐づけます。しかし、いかなる種類のプロキシーも設定されません。 + + {{< note >}} + `ExternalName`タイプのServiceを利用するためには、CoreDNSのバージョン1.7以上が必要となります。 + {{< /note >}} + +また、Serviceを公開するために[Ingress](/docs/concepts/services-networking/ingress/)も利用可能です。IngressはServiceのタイプではありませんが、クラスターに対するエントリーポイントとして動作します。 +Ingressは同一のIPアドレスにおいて、複数のServiceを公開するように、ユーザーの設定した転送ルールを1つのリソースにまとめることができます。 + +### NodePort タイプ {#nodeport} + +もし`type`フィールドの値を`NodePort`に設定すると、Kubernetesコントロールプレーンは`--service-node-port-range`フラグによって指定されたレンジのポート(デフォルト: 30000-32767)を割り当てます。 +各Nodeはそのポート(各Nodeで同じポート番号)への通信をServiceに転送します。 +作成したServiceは、`.spec.ports[*].nodePort`フィールド内に割り当てられたポートを記述します。 + +もしポートへの通信を転送する特定のIPを指定したい場合、特定のIPブロックをkube-proxyの`--nodeport-address`フラグで指定できます。これはKubernetesv1.10からサポートされています。 +このフラグは、コンマ区切りのIPブロックのリスト(例: 10.0.0./8, 192.0.2.0/25)を使用し、kube-proxyがこのNodeに対してローカルとみなすべきIPアドレスの範囲を指定します。 + +例えば、`--nodeport-addresses=127.0.0.0/8`というフラグによってkube-proxyを起動した時、kube-proxyはNodePort Serviceのためにループバックインターフェースのみ選択します。`--nodeport-addresses`のデフォルト値は空のリストになります。これはkube-proxyがNodePort Serviceに対して全てのネットワークインターフェースを利用可能とするべきということを意味します(これは以前のKubernetesのバージョンとの互換性があります)。 + +もしポート番号を指定したい場合、`nodePort`フィールドに値を指定できます。コントロールプレーンは指定したポートを割り当てるか、APIトランザクションが失敗したことを知らせるかのどちらかになります。 +これは、ユーザーが自分自身で、ポート番号の衝突に関して気をつける必要があることを意味します。 +また、ユーザーは有効なポート番号を指定する必要があり、NodePortの使用において、設定された範囲のポートを指定する必要があります。 + +NodePortの使用は、Kubernetesによって完全にサポートされていないようなユーザー独自の負荷分散を設定をするための有効な方法や、1つ以上のNodeのIPを直接公開するための方法となりえます。 + +注意点として、このServiceは`:spec.ports[*].nodePort`と、`.spec.clusterIP:spec.ports[*].port`として疎通可能です。 +(もしkube-proxyにおいて`--nodeport-addressses`が設定された場合、はフィルターされたNodeIPとなります。) + +### LoadBalancer タイプ {#loadbalancer} + +外部のロードバランサーをサポートするクラウドプロバイダー上で、`type`フィールドに`LoadBalancer`を設定すると、Service用にロードバランサーがプロビジョニングされます。 +実際のロードバランサーの作成は非同期で行われ、プロビジョンされたバランサーの情報は、Serviceの`.status.loadBalancer`フィールドに記述されます。 +例えば: + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: my-service +spec: + selector: + app: MyApp + ports: + - protocol: TCP + port: 80 + targetPort: 9376 + clusterIP: 10.0.171.239 + loadBalancerIP: 78.11.24.19 + type: LoadBalancer +status: + loadBalancer: + ingress: + - ip: 146.148.47.155 +``` + +外部のロードバランサーからのトラフィックはバックエンドのPodに直接転送されます。クラウドプロバイダーはどのようにそのリクエストをバランシングするかを決めます。 + +いくつかのクラウドプロバイダーにおいて、`loadBalancerIP`の設定をすることができます。このようなケースでは、そのロードバランサーはユーザーが指定した`loadBalancerIP`に対してロードバランサーを作成します。 +もし`loadBalancerIP`フィールドの値が指定されていない場合、そのロードバランサーはエフェメラルなIPアドレスに対して作成されます。もしユーザーが`loadBalancerIP`を指定したが、使っているクラウドプロバイダーがその機能をサポートしていない場合、その`loadBalancerIP`フィールドに設定された値は無視されます。 + +{{< note >}} +もしSCTPを使っている場合、`LoadBalancer` タイプのServiceに関する[使用上の警告](#caveat-sctp-loadbalancer-service-type)を参照してください。 +{{< /note >}} + +{{< note >}} + +**Azure** において、もしユーザーが指定する`loadBalancerIP`を使用したい場合、最初に静的なパブリックIPアドレスのリソースを作成する必要があります。 +このパブリックIPアドレスのリソースは、クラスター内で自動的に作成された他のリソースと同じグループに作られるべきです。 +例: `MC_myResourceGroup_myAKSCluster_eastus` + +割り当てられたIPアドレスをloadBalancerIPとして指定してください。クラウドプロバイダーの設定ファイルにおいてsecurityGroupNameを更新したことを確認してください。 +`CreatingLoadBalancerFailed`というパーミッションの問題に対するトラブルシューティングの情報は、[Azure Kubernetes Service(AKS)のロードバランサーで静的IPアドレスを使用する](https://docs.microsoft.com/en-us/azure/aks/static-ip) や、[高度なネットワークを使用したAKSクラスターでのCreatingLoadBalancerFailed](https://github.com/Azure/AKS/issues/357)を参照してください。 +{{< /note >}} + +#### 内部のロードバランサー +複雑な環境において、同一の(仮想)ネットワークアドレスブロック内のServiceからのトラフィックを転送する必要がでてきます。 + +Split-HorizonなDNS環境において、ユーザーは2つのServiceを外部と内部の両方からのトラフィックをエンドポイントに転送させる必要がでてきます。 + +ユーザーは、Serviceに対して下記のアノテーションを1つ追加することでこれを実現できます。 +追加するアノテーションは、ユーザーが使っているクラウドプロバイダーに依存しています。 + +{{< tabs name="service_tabs" >}} +{{% tab name="Default" %}} +タブを選択してください。 +{{% /tab %}} +{{% tab name="GCP" %}} +```yaml +[...] +metadata: + name: my-service + annotations: + cloud.google.com/load-balancer-type: "Internal" +[...] +``` + +Kubernetes1.7.0から1.7.3のMasterに対しては、`cloud.google.com/load-balancer-type: "internal"`を使用します。 +さらなる情報については、[docs](https://cloud.google.com/kubernetes-engine/docs/internal-load-balancing)を参照してください。 +{{% /tab %}} +{{% tab name="AWS" %}} +```yaml +[...] +metadata: + name: my-service + annotations: + service.beta.kubernetes.io/aws-load-balancer-internal: 0.0.0.0/0 +[...] +``` +{{% /tab %}} +{{% tab name="Azure" %}} +```yaml +[...] +metadata: + name: my-service + annotations: + service.beta.kubernetes.io/azure-load-balancer-internal: "true" +[...] +``` +{{% /tab %}} +{{% tab name="OpenStack" %}} +```yaml +[...] +metadata: + name: my-service + annotations: + service.beta.kubernetes.io/openstack-internal-load-balancer: "true" +[...] +``` +{{% /tab %}} +{{% tab name="Baidu Cloud" %}} +```yaml +[...] +metadata: + name: my-service + annotations: + service.beta.kubernetes.io/cce-load-balancer-internal-vpc: "true" +[...] +``` +{{% /tab %}} +{{< /tabs >}} + + +#### AWSにおけるTLSのサポート {#ssl-support-on-aws} + +AWS上で稼働しているクラスターにおいて、部分的なTLS/SSLのサポートをするには、`LoadBalancer` Serviceに対して3つのアノテーションを追加できます。 + +```yaml +metadata: + name: my-service + annotations: + service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012 +``` + +1つ目は、使用する証明書のARNです。これはIAMにアップロードされたサードパーティーが発行した証明書か、AWS Certificate Managerで作成された証明書になります。 + +```yaml +metadata: + name: my-service + annotations: + service.beta.kubernetes.io/aws-load-balancer-backend-protocol: (https|http|ssl|tcp) +``` + +2つ目のアノテーションはPodが利用するプロトコルを指定するものです。HTTPSとSSLの場合、ELBはそのPodが証明書を使って暗号化されたコネクションを介して自分自身のPodを認証すると推測します。 + +HTTPとHTTPSでは、レイヤー7でのプロキシーを選択します。ELBはユーザーとのコネクションを切断し、リクエストを転送するときにリクエストヘッダーをパースして、`X-Forwardef-For`ヘッダーにユーザーのIPを追加します(Podは接続相手のELBのIPアドレスのみ確認可能です)。 + +TCPとSSLでは、レイヤー4でのプロキシーを選択します。ELBはヘッダーの値を変更せずにトラフィックを転送します。 + +いくつかのポートがセキュアに保護され、他のポートではセキュアでないような混合した環境において、下記のようにアノテーションを使うことができます。 + +```yaml + metadata: + name: my-service + annotations: + service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http + service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443,8443" +``` + +上記の例では、もしServiceが`80`、`443`、`8443`と3つのポートを含んでいる場合、`443`と`8443`はSSL証明書を使いますが、`80`では単純にHTTPでのプロキシーとなります。 + +Kubernetes v1.9以降のバージョンからは、Serviceのリスナー用にHTTPSやSSLと[事前定義されたAWS SSLポリシー](http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-security-policy-table.html)を使用できます。 +どのポリシーが使用できるかを確認するために、`aws`コマンドラインツールを使用できます。 + +```bash +aws elb describe-load-balancer-policies --query 'PolicyDescriptions[].PolicyName' +``` + +ユーザーは"`service.beta.kubernetes.io/aws-load-balancer-ssl-negotiation-policy`"というアノテーションを使用することにより、複数のポリシーの中からどれか1つを指定できます。 +例えば: + +```yaml + metadata: + name: my-service + annotations: + service.beta.kubernetes.io/aws-load-balancer-ssl-negotiation-policy: "ELBSecurityPolicy-TLS-1-2-2017-01" +``` + +#### AWS上でのPROXYプロトコルのサポート + +AWS上で稼働するクラスターで[PROXY protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)のサポートを有効にするために、下記のServiceのアノテーションを使用できます。 + +```yaml + metadata: + name: my-service + annotations: + service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*" +``` + +Kubernetesバージョン1.3.0からは、このアノテーションを使用するとELBによってプロキシーされた全てのポートが対象になり、そしてそれ以外の場合は構成されません。 + +#### AWS上でのELBのアクセスログ + +AWS上でのELB Service用のアクセスログを管理するためにはいくつかのアノテーションが使用できます。 + +`service.beta.kubernetes.io/aws-load-balancer-access-log-enabled`というアノテーションはアクセスログを有効にするかを設定できます。 + +`service.beta.kubernetes.io/aws-load-balancer-access-log-emit-interval`というアノテーションはアクセスログをパブリッシュするためのインターバル(分)を設定できます。 +ユーザーはそのインターバルで5分もしくは60分で設定できます。 + +`service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-name`というアノテーションはロードバランサーのアクセスログが保存されるAmazon S3のバケット名を設定できます。 + +`service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-prefix`というアノテーションはユーザーが作成したAmazon S3バケットの論理的な階層を指定します。 + +```yaml + metadata: + name: my-service + annotations: + service.beta.kubernetes.io/aws-load-balancer-access-log-enabled: "true" + # ロードバランサーのアクセスログが有効かどうか。 + service.beta.kubernetes.io/aws-load-balancer-access-log-emit-interval: "60" + # アクセスログをパブリッシュするためのインターバル(分)。ユーザーはそのインターバルで5分もしくは60分で設定できます。 + service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-name: "my-bucket" + # ロードバランサーのアクセスログが保存されるAmazon S3のバケット名。 + service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-prefix: "my-bucket-prefix/prod" + # ユーザーが作成したAmazon S3バケットの論理的な階層。例えば: `my-bucket-prefix/prod` +``` + +#### AWSでの接続の中断 + +古いタイプのELBでの接続の中断は、`service.beta.kubernetes.io/aws-load-balancer-connection-draining-enabled`というアノテーションを`"true"`に設定することで管理できます。 +`service.beta.kubernetes.io/aws-load-balancer-connection-draining-timeout`というアノテーションで、インスタンスを登録解除するまえに既存の接続をオープンにし続けるための最大時間(秒)を指定できます。 + +```yaml + metadata: + name: my-service + annotations: + service.beta.kubernetes.io/aws-load-balancer-connection-draining-enabled: "true" + service.beta.kubernetes.io/aws-load-balancer-connection-draining-timeout: "60" +``` + +#### 他のELBアノテーション + +古いタイプのELBを管理するためのアノテーションは他にもあり、下記で紹介します。 + +```yaml + metadata: + name: my-service + annotations: + service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: "60" + # ロードバランサーによってクローズされる前にアイドル状態(コネクションでデータは送信されない)になれる秒数 + + service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true" + # ゾーンを跨いだロードバランシングが有効かどうか + + service.beta.kubernetes.io/aws-load-balancer-additional-resource-tags: "environment=prod,owner=devops" + # ELBにおいて追加タグとして保存されるキー・バリューのペアのコンマ区切りのリスト + + service.beta.kubernetes.io/aws-load-balancer-healthcheck-healthy-threshold: "" + # バックエンドへのトラフィックが正常になったと判断するために必要なヘルスチェックの連続成功数 + # デフォルトでは2 この値は2から10の間で設定可能 + + service.beta.kubernetes.io/aws-load-balancer-healthcheck-unhealthy-threshold: "3" + # バックエンドへのトラフィックが異常になったと判断するために必要なヘルスチェックの連続失敗数 + # デフォルトでは6 この値は2から10の間で設定可能 + + service.beta.kubernetes.io/aws-load-balancer-healthcheck-interval: "20" + # 各インスタンスのヘルスチェックのおよそのインターバル(秒) + # デフォルトでは10 この値は5から300の間で設定可能 + + service.beta.kubernetes.io/aws-load-balancer-healthcheck-timeout: "5" + # ヘルスチェックが失敗したと判断されるレスポンスタイムのリミット(秒) + # この値はservice.beta.kubernetes.io/aws-load-balancer-healthcheck-intervalの値以下である必要があります。 + # デフォルトでは5 この値は2から60の間で設定可能 + + service.beta.kubernetes.io/aws-load-balancer-extra-security-groups: "sg-53fae93f,sg-42efd82e" + # ELBに追加される予定のセキュリティーグループのリスト +``` + +#### AWSでのNetwork Load Balancerのサポート [α版] {#aws-nlb-support} + +{{< warning >}} +これはα版の機能で、プロダクション環境でのクラスターでの使用はまだ推奨しません。 +{{< /warning >}} + +Kubernetes v1.9.0から、ServiceとAWS Network Load Balancer(NLB)を組み合わせることができます。AWSでのネットワークロードバランサーを使用するためには、`service.beta.kubernetes.io/aws-load-balancer-type`というアノテーションの値を`nlb`に設定してください。 + +```yaml + metadata: + name: my-service + annotations: + service.beta.kubernetes.io/aws-load-balancer-type: "nlb" +``` + +{{< note >}} +NLBは特定のインスタンスクラスでのみ稼働します。サポートされているインスタンスタイプを確認するためには、ELBに関する[AWS documentation](http://docs.aws.amazon.com/elasticloadbalancing/latest/network/target-group-register-targets.html#register-deregister-targets)を参照してください。 +{{< /note >}} + +古いタイプのElastic Load Balancersとは異なり、Network Load Balancers (NLBs)はクライアントのIPアドレスをNodeに転送します。 +もしServiceの`.spec.externalTrafficPolicy`の値が`Cluster`に設定されていた場合、クライアントのIPアドレスは末端のPodに伝播しません。 + +`.spec.externalTrafficPolicy`を`Local`に設定することにより、クライアントIPアドレスは末端のPodに伝播します。しかし、これにより、トラフィックの分配が不均等になります。 +特定のLoadBalancer Serviceに紐づいたPodがないNodeでは、自動的に割り当てられた`.spec.healthCheckNodePort`に対するNLBのターゲットグループのヘルスチェックが失敗し、トラフィックを全く受信しません。 + +均等なトラフィックの分配を実現するために、DaemonSetの使用や、同一のNodeに配備しないように[Podのanti-affinity](/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity)を設定します。 + +また、[内部のロードバランサー](/docs/concepts/services-networking/service/#internal-load-balancer)のアノテーションとNLB Serviceを使用できます。 + +NLBの背後にあるインスタンスに対してクライアントのトラフィックを転送するために、Nodeのセキュリティーグループは下記のようなIPルールに従って変更されます。 + +| Rule | Protocol | Port(s) | IpRange(s) | IpRange Description | +|------|----------|---------|------------|---------------------| +| ヘルスチェック | TCP | NodePort(s) (`.spec.healthCheckNodePort` for `.spec.externalTrafficPolicy = Local`) | VPC CIDR | kubernetes.io/rule/nlb/health=\ | +| クライアントのトラフィック | TCP | NodePort(s) | `.spec.loadBalancerSourceRanges` (デフォルト: `0.0.0.0/0`) | kubernetes.io/rule/nlb/client=\ | +| MTCによるサービスディスカバリー | ICMP | 3,4 | `.spec.loadBalancerSourceRanges` (デフォルト: `0.0.0.0/0`) | kubernetes.io/rule/nlb/mtu=\ | + +どのクライアントIPがNLBにアクセス可能かを制限するためには、`loadBalancerSourceRanges`を指定してください。 + +```yaml +spec: + loadBalancerSourceRanges: + - "143.231.0.0/16" +``` + +{{< note >}} +もし`.spec.loadBalancerSourceRanges`が設定されていない場合、KubernetesはNodeのセキュリティーグループに対して`0.0.0.0/0`からのトラフィックを許可します。 +もしNodeがパブリックなIPアドレスを持っていた場合、NLBでないトラフィックも修正されたセキュリティーグループ内の全てのインスタンスにアクセス可能になってしまうので注意が必要です。 + +{{< /note >}} + +### ExternalName タイプ {#externalname} + +ExternalNameタイプのServiceは、ServiceをDNS名とマッピングし、`my-service`や`cassandra`というような従来のラベルセレクターとはマッピングしません。 +ユーザーはこれらのServiceにおいて`spec.externalName`フィールドの値を指定します。 + +このServiceの定義では、例えば`prod`というNamespace内の`my-service`というServiceを`my.database.example.com`にマッピングします。 + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: my-service + namespace: prod +spec: + type: ExternalName + externalName: my.database.example.com +``` +{{< note >}} +ExternalNameはIpv4のアドレスの文字列のみ受け付けますが、IPアドレスではなく、数字で構成されるDNS名として受け入れます。 +IPv4アドレスに似ているExternalNamesはCoreDNSもしくはIngress-Nginxによって名前解決されず、これはExternalNameは正規のDNS名を指定することを目的としているためです。 +IPアドレスをハードコードする場合、[Headless Service](#headless-service)の使用を検討してください。 +{{< /note >}} + +`my-service.prod.svc.cluster.local`というホストをルックアップするとき、クラスターのDNS Serviceは`CNAME`レコードと`my.database.example.com`という値を返します。 +`my-service`へのアクセスは、他のServiceと同じ方法ですが、再接続する際はプロキシーや転送を介して行うよりも、DNSレベルで行われることが決定的に異なる点となります。 +後にユーザーが使用しているデータベースをクラスター内に移行することになった後は、Podを起動させ、適切なラベルセレクターやEndpointを追加し、Serviceの`type`を変更します。 + +{{< note >}} +このセクションは、[Alen Komljen](https://akomljen.com/)による[Kubernetes Tips - Part1](https://akomljen.com/kubernetes-tips-part-1/)というブログポストを参考にしています。 + +{{< /note >}} + +### External IPs + +もし1つ以上のクラスターNodeに転送するexternalIPが複数ある場合、Kubernetes Serviceは`externalIPs`に指定したIPで公開されます。 +そのexternalIP(到達先のIPとして扱われます)のServiceのポートからトラフィックがクラスターに入って来る場合、ServiceのEndpointのどれか1つに対して転送されます。 +`externalIPs`はKubernetesによって管理されず、それを管理する責任はクラスターの管理者にあります。 + +Serviceのspecにおいて、`externalIPs`は他のどの`ServiceTypes`と併用して設定できます。 +下記の例では、"`my-service`"は"`80.11.12.10:80`" (`externalIP:port`)のクライアントからアクセス可能です。 + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: my-service +spec: + selector: + app: MyApp + ports: + - name: http + protocol: TCP + port: 80 + targetPort: 9376 + externalIPs: + - 80.11.12.10 +``` + +## Serviceのデメリット + +仮想IP用にuserspaceモードのプロキシーを使用すると、小規模もしくは中規模のスケールでうまく稼働できますが、1000以上のServiceがあるようなとても大きなクラスターではうまくスケールしません。 +これについては、[Serviceのデザインプロポーザル](http://issue.k8s.io/1107)にてさらなる詳細を確認できます。 + +userspaceモードのプロキシーの使用は、Serviceにアクセスするパケットの送信元IPアドレスが不明瞭になります。 +これは、いくつかの種類のネットワークフィルタリング(ファイアウォールによるフィルタリング)を不可能にします。 +iptablesプロキシーモードはクラスター内の送信元IPを不明瞭にはしませんが、依然としてロードバランサーやNodePortへ疎通するクライアントに影響があります。 + +`Type`フィールドはネストされた機能としてデザインされています。 - 各レベルの値は前のレベルに対して追加します。 +これは全てのクラウドプロバイダーにおいて厳密に要求されていません(例: Google Compute Engineは`LoadBalancer`を動作させるために`NodePort`を割り当てる必要はありませんが、AWSではその必要があります)が、現在のAPIでは要求しています。 + +## 仮想IPの実装について {#the-gory-details-of-virtual-ips} + +これより前の情報は、ただServiceを使いたいという多くのユーザーにとっては有益かもしれません。しかし、その裏側では多くのことが行われており、理解する価値があります。 + +### 衝突の回避 + +Kubernetesの主要な哲学のうちの一つは、ユーザーは、ユーザー自身のアクションによるミスでないものによって、ユーザーのアクションが失敗するような状況に晒されるべきでないことです。 +Serviceリソースの設計のでは、これはユーザーの指定したポートが衝突する可能性がある場合は、そのポートのServiceを作らないことを意味します。これは障害を分離することとなります。 + +Serviceのポート番号を選択できるようにするために、我々はどの2つのServiceでもポートが衝突しないことを保証します。 +Kubernetesは各Serviceに、それ自身のIPアドレスを割り当てることで実現しています。 + +各Serviceが固有のIPを割り当てられるのを保証するために、内部のアロケーターは、Serviceを作成する前に、etcd内のグローバルの割り当てマップをアトミックに更新します。 +そのマップオブジェクトはServiceのIPアドレスの割り当てのためにレジストリー内に存在しなくてはならず、そうでない場合は、Serviceの作成時にIPアドレスが割り当てられなかったことを示すエラーメッセージが表示されます。 + +コントロールプレーンにおいて、バックグラウンドのコントローラーはそのマップを作成する責務があります(インメモリーのロックが使われていた古いバージョンのKubernetesのマイグレーションも必要です)。 +また、Kubernetesは無効な割り当てがされているかをチェックすることと、現時点でどのServiceにも使用されていない割り当て済みIPアドレスのクリーンアップのためにコントローラーを使用します。 + +### ServiceのIPアドレス {#ips-and-vips} + +実際に固定された向き先であるPodのIPアドレスとは異なり、ServiceのIPは実際には単一のホストによって応答されません。 +その代わり、kube-proxyは必要な時に透過的にリダイレクトされる_仮想_ IPアドレスを定義するため、iptables(Linuxのパケット処理ロジック)を使用します。 +クライアントがVIPに接続する時、そのトラフィックは自動的に適切なEndpointに転送されます。 +Service用の環境変数とDNSは、Serviceの仮想IPアドレス(とポート)の面において、自動的に生成されます。 + +kube-proxyは3つの微妙に異なった動作をするプロキシーモード— userspace、iptablesとIPVS — をサポートしています。 + +#### Userspace + +例として、上記で記述されている画像処理のアプリケーションを考えます。 +バックエンドのServiceが作成されたとき、KubernetesのMasterは仮想IPを割り当てます。例えば10.0.0.1などです。 +そのServiceのポートが1234で、そのServiceはクラスター内の全てのkube-proxyインスタンスによって監視されていると仮定します。 +kube-proxyが新しいServiceを見つけた時、kube-proxyは新しいランダムポートをオープンし、その仮想IPアドレスの新しいポートにリダイレクトするようにiptablesを更新し、そのポート上で新しい接続を待ち受けを開始します。 + +クライアントがServiceの仮想IPアドレスに接続したとき、iptablesルールが有効になり、そのパケットをプロキシー自身のポートにリダイレクトします。 +その"Service プロキシー"はバックエンドPodの対象を選択し、クライアントのトラフィックをバックエンドPodに転送します。 + +これはServiceのオーナーは、衝突のリスクなしに、求めるどのようなポートも選択できることを意味します。 +クライアントは単純にそのIPとポートに対して接続すればよく、実際にどのPodにアクセスしているかを意識しません。 + +#### iptables + +また画像処理のアプリケーションについて考えます。バックエンドServiceが作成された時、そのKubernetesコントロールプレーンは仮想IPアドレスを割り当てます。例えば10.0.0.1などです。 +Serviceのポートが1234で、そのServiceがクラスター内のすべてのkube-proxyインスタンスによって監視されていると仮定します。 +kube-proxyが新しいServiceを見つけた時、kube-proxyは仮想IPから各Serviceのルールにリダイレクトされるような、iptablesルールのセットをインストールします。 +Service毎のルールは、トラフィックをバックエンドにリダイレクト(Destination NATを使用)しているEndpoint毎のルールに対してリンクしています。 + +クライアントがServiceの仮想IPアドレスに対して接続しているとき、そのiptablesルールが有効になります。 +バックエンドのPodが選択され(SessionAffinityに基づくか、もしくはランダムで選択される)、パケットはバックエンドにリダイレクトされます。 +userspaceモードのプロキシーとは異なり、パケットは決してuserspaceにコピーされず、kube-proxyは仮想IPのために稼働される必要はなく、またNodeでは変更されていないクライアントIPからトラフィックがきます。 + +このように同じ基本的なフローは、NodePortまたはLoadBalancerを介してトラフィックがきた場合に、実行され、ただクライアントIPは変更されます。 + +#### IPVS + +iptablesの処理は、大規模なクラスターの場合劇的に遅くなります。例としてはServiceが10,000ほどある場合です。 +IPVSは負荷分散のために設計され、カーネル内のハッシュテーブルに基づいています。そのためIPVSベースのkube-proxyによって、多数のServiceがある場合でも一貫して高パフォーマンスを実現できます。 +次第に、IPVSベースのkube-proxyは負荷分散のアルゴリズムはさらに洗練されています(最小接続数、位置ベース、重み付け、永続性など)。 + +## APIオブジェクト + +ServiceはKubernetesのREST APIにおいてトップレベルのリソースです。ユーザーはそのAPIオブジェクトに関して、[Service API object](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#service-v1-core)でさらなる情報を確認できます。 + +## サポートされているプロトコル {#protocol-support} + +### TCP + +{{< feature-state for_k8s_version="v1.0" state="stable" >}} + +ユーザーはどの種類のServiceにおいてもTCPを利用できます。これはデフォルトのネットワークプロトコルです。 + +### UDP + +{{< feature-state for_k8s_version="v1.0" state="stable" >}} + +ユーザーは多くのServiceにおいてUDPを利用できます。 type=LoadBalancerのServiceにおいては、UDPのサポートはこの機能を提供しているクラウドプロバイダーに依存しています。 + +### HTTP + +{{< feature-state for_k8s_version="v1.1" state="stable" >}} + +もしクラウドプロバイダーがサポートしている場合、ServiceのEndpointに転送される外部のHTTP/HTTPSでのリバースプロキシーをセットアップするために、LoadBalancerモードでServiceを作成可能です。 + +{{< note >}} +ユーザーはまた、HTTP / HTTPS Serviceを公開するために、Serviceの代わりに{{< glossary_tooltip term_id="ingress" >}}を利用することもできます。 +{{< /note >}} + +### PROXY プロトコル + +{{< feature-state for_k8s_version="v1.1" state="stable" >}} + +もしクラウドプロバイダーがサポートしている場合(例: [AWS](/docs/concepts/cluster-administration/cloud-providers/#aws))、Kubernetesクラスターの外部のロードバランサーを設定するためにLoadBalancerモードでServiceを利用できます。これは[PROXY protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)がついた接続を転送します。 + +ロードバランサーは、最初の一連のオクテットを送信します。 +下記のような例となります。 + +``` +PROXY TCP4 192.0.2.202 10.0.42.7 12345 7\r\n +``` +クライアントからのデータのあとに追加されます。 + +### SCTP + +{{< feature-state for_k8s_version="v1.12" state="alpha" >}} + +KubernetseはService、Endpoint、NetworkPolicyとPodの定義においてα版の機能として`protocol`フィールドの値でSCTPをサポートしています。この機能を有効にするために、クラスター管理者はAPI Serverにおいて`SCTPSupport`というFeature Gateを有効にする必要があります。例えば、`--feature-gates=SCTPSupport=true,…`といったように設定します。 + +そのFeature Gateが有効になった時、ユーザーはService、Endpoint、NetworkPolicyの`protocol`フィールドと、Podの`SCTP`フィールドを設定できます。 +Kubernetesは、TCP接続と同様に、SCTPアソシエーションに応じてネットワークをセットアップします。 + +#### 警告 {#caveat-sctp-overview} + +##### マルチホームSCTPアソシエーションのサポート {#caveat-sctp-multihomed} + +{{< warning >}} +マルチホームSCTPアソシエーションのサポートは、複数のインターフェースとPodのIPアドレスの割り当てをサポートできるCNIプラグインを要求します。 + +マルチホームSCTPアソシエーションにおけるNATは、対応するカーネルモジュール内で特別なロジックを要求します。 +{{< /warning >}} + +##### type=LoadBalancer Service について {#caveat-sctp-loadbalancer-service-type} + +{{< warning >}} +クラウドプロバイダーのロードバランサーの実装がプロトコルとしてSCTPをサポートしている場合は、`type` がLoadBalancerで` protocol`がSCTPの場合でのみサービスを作成できます。 +そうでない場合、Serviceの作成要求はリジェクトされます。現時点でのクラウドのロードバランサーのプロバイダー(Azure、AWS、CloudStack、GCE、OpenStack)は全てSCTPのサポートをしていません。 +{{< /warning >}} + +##### Windows {#caveat-sctp-windows-os} + +{{< warning >}} +SCTPはWindowsベースのNodeではサポートされていません。 +{{< /warning >}} + +##### Userspace kube-proxy {#caveat-sctp-kube-proxy-userspace} + +{{< warning >}} +kube-proxyはuserspaceモードにおいてSCTPアソシエーションの管理をサポートしません。 +{{< /warning >}} + +## Future work + +将来的に、Serviceのプロキシーポリシーはシンプルなラウンドロビンのバランシングだけでなく、もっと細かな設定が可能になります。例えば、Masterによって選択されるものや、水平シャーディングされたりするようになります。 +我々もまた、いくつかのServiceが"実際の"ロードバランサーを備えることを想定します。その場合、仮想IPは単純にパケットをそのロードバランサーに転送します。 + +Kubernetesプロジェクトは、L7 (HTTP) Serviceへのサポートをもっと発展させようとしています。 + +Kubernetesプロジェクトは、現在利用可能なClusterIP、NodePortやLoadBalancerタイプのServiceに対して、より柔軟なIngressのモードを追加する予定です。 + +{{% /capture %}} + +{{% capture whatsnext %}} + +* [Connecting Applications with Services](/docs/concepts/services-networking/connect-applications-service/)を参照してください。 +* [Ingress](/docs/concepts/services-networking/ingress/)を参照してください。 + +{{% /capture %}} diff --git a/content/ja/docs/reference/glossary/control-plane.md b/content/ja/docs/reference/glossary/control-plane.md new file mode 100644 index 0000000000000..1153d68db8fc3 --- /dev/null +++ b/content/ja/docs/reference/glossary/control-plane.md @@ -0,0 +1,13 @@ +--- +title: コントロールプレーン +id: control-plane +date: 2019-05-12 +full_link: +short_description: > + コンテナのライフサイクルを定義、展開、管理するためのAPIとインターフェイスを公開するコンテナオーケストレーションレイヤーです。 + +aka: +tags: +- fundamental +--- + コンテナのライフサイクルを定義、展開、管理するためのAPIとインターフェイスを公開するコンテナオーケストレーションレイヤーです。 diff --git a/content/ja/docs/reference/glossary/namespace.md b/content/ja/docs/reference/glossary/namespace.md new file mode 100755 index 0000000000000..7bc6a0c703396 --- /dev/null +++ b/content/ja/docs/reference/glossary/namespace.md @@ -0,0 +1,19 @@ +--- +title: Namespace +id: namespace +date: 2018-04-12 +full_link: /docs/concepts/overview/working-with-objects/namespaces +short_description: > + 同一の物理クラスター上で複数の仮想クラスターをサポートするために使われる抽象概念です。 + +aka: +tags: +- fundamental +--- + 同一の物理{{< glossary_tooltip text="クラスター" term_id="cluster" >}}上で複数の仮想クラスターをサポートするために使われる抽象概念です。 + + + +Namespaceはクラスター内のオブジェクトをまとめたり、クラスターのリソースを分離するための方法を提供します。 +リソース名は、Namespace内で一意である必要がありますが、Namespaceをまたいだ場合はその必要はないです。 + diff --git a/content/ja/docs/reference/glossary/node.md b/content/ja/docs/reference/glossary/node.md new file mode 100755 index 0000000000000..5cc4b3481d26c --- /dev/null +++ b/content/ja/docs/reference/glossary/node.md @@ -0,0 +1,17 @@ +--- +title: ノード +id: node +date: 2018-04-12 +full_link: /docs/concepts/architecture/nodes/ +short_description: > + ノードはKubernetesのワーカーマシンです。 + +aka: +tags: +- fundamental +--- + ノードはKubernetesのワーカーマシンです。 + + + +ワーカーノードは、クラスターに応じてVMまたは物理マシンの場合があります。{{< glossary_tooltip text="Pod" term_id="pod" >}}の実行に必要なローカルデーモンまたはサービスがあり、コントロールプレーンによって管理されます。ノード上のデーモンには、{{< glossary_tooltip text="kubelet" term_id="kubelet" >}}、{{< glossary_tooltip text="kube-proxy" term_id="kube-proxy" >}}、および{{< glossary_tooltip term_id="docker" >}}などの{{< glossary_tooltip text="CRI" term_id="cri" >}}を実装するコンテナランタイムが含まれます。