From b620832663fc6ee8708a84138a728db802c975c5 Mon Sep 17 00:00:00 2001 From: Keita Akutsu Date: Thu, 12 Sep 2019 02:06:03 +0900 Subject: [PATCH] ja-trans:Translate concepts/services-networking/service/ into Japanese (#14917) --- .../concepts/services-networking/_index.md | 4 + .../concepts/services-networking/service.md | 917 ++++++++++++++++++ .../ja/docs/reference/glossary/namespace.md | 19 + content/ja/docs/reference/glossary/pod.md | 19 + content/ja/docs/reference/glossary/service.md | 19 + 5 files changed, 978 insertions(+) create mode 100644 content/ja/docs/concepts/services-networking/_index.md create mode 100644 content/ja/docs/concepts/services-networking/service.md create mode 100755 content/ja/docs/reference/glossary/namespace.md create mode 100755 content/ja/docs/reference/glossary/pod.md create mode 100755 content/ja/docs/reference/glossary/service.md diff --git a/content/ja/docs/concepts/services-networking/_index.md b/content/ja/docs/concepts/services-networking/_index.md new file mode 100644 index 0000000000000..e22401c476a61 --- /dev/null +++ b/content/ja/docs/concepts/services-networking/_index.md @@ -0,0 +1,4 @@ +--- +title: "Services, Load Balancing, and Networking" +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..ea98a03bcfe36 --- /dev/null +++ b/content/ja/docs/concepts/services-networking/service.md @@ -0,0 +1,917 @@ +--- +reviewers: +title: Service +feature: + title: サービスディスカバリーとロードバランシング + description: > + No need to modify your application to use an unfamiliar service discovery mechanism. Kubernetes gives Pods their own IP addresses and a single DNS name for a set of Pods, and can load-balance across them. + +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" >}}をアプリケーションを稼働させるために使用する時、DeploymentはPodを動的に作成・削除します。 + + +各Podはそれ自身のIPアドレスを持ちます。しかしDeploymentでは、ある時点において同時に稼働しているPodのセットは、その後のある時点において稼働しているPodのセットとは異なる場合があります。 + +この仕組みはある問題を引き起こします。もしあるPodのセット(ここでは"backends"と呼びます)がクラスター内で他のPodのセット(ここでは"frontends"と呼びます)に対して機能を提供する場合、frontendsのPodがワークロードにおけるbackendsを使用するために、どのようにbackendsのPodのIPアドレスを探し出したり、記録し続けるでしょうか? + +ここで_Service_ について説明します。 + +## Service リソース {#service-resource} + +Kubernetesにおいて、ServiceはPodの論理的なセットや、そのPodのセットにアクセスするためのポリシーを定義します(このパターンはよくマイクロサービスと呼ばることがあります)。 +ServiceによってターゲットとされたPodのセットは、たいてい {{< glossary_tooltip text="セレクター" term_id="selector" >}} (セレクターなしのServiceを利用したい場合は[下記](#services-without-selectors)の記事を参照してください)によって定義されます。 + +例えば、3つのレプリカが稼働しているステートレスな画像処理用のバックエンドを考えます。このレプリカは代替可能なfrontendのPodです。— backendに何を使うかに関しては意識しません。backendのセットを構成する実際のPodのセットが変更された際、frontendクライアントはその変更を気にしたり、backendのPodのセットの情報を記録しておく必要はありません。 + +Serviceによる抽象化は、クライアントから、バックエンドのPodの管理する責務を分離することを可能にします。 + +### クラウドネイティブのサービスディスカバリー + +もしアプリケーション内でサービスディスカバリーのためにKubernetes APIを使うことができる場合、ユーザーは{{< glossary_tooltip text="API Server" term_id="kube-apiserver" >}}に対してのエンドポイントのためのクエリを実行でき、またService内のPodのセットが変更された時はいつでも更新された情報を取得できます。 + +非ネイティブなアプリケーションのために、Kubernetesは、アプリケーションとbackend 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が、iptableモードにおいて稼働し、その最初に選択された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 - Part +1](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アドレスに対して接続しているとkい、その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/namespace.md b/content/ja/docs/reference/glossary/namespace.md new file mode 100755 index 0000000000000..10423897ee733 --- /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: > + An abstraction used by Kubernetes to support multiple virtual clusters on the same physical cluster. + +aka: +tags: +- fundamental +--- + 同一の物理{{< glossary_tooltip text="クラスター" term_id="cluster" >}}上で複数の仮想クラスターをサポートするための機能を抽象化したものです。 + + + +Namespaceはクラスター内のオブジェクトをまとめたり、クラスターのリソースを分離するための方法を提供します。 +リソース名は、Namespace内で一意である必要がありますが、Namespaceをまたいだ場合はその必要はないです。 + diff --git a/content/ja/docs/reference/glossary/pod.md b/content/ja/docs/reference/glossary/pod.md new file mode 100755 index 0000000000000..1a893463d64fd --- /dev/null +++ b/content/ja/docs/reference/glossary/pod.md @@ -0,0 +1,19 @@ +--- +title: Pod +id: pod +date: 2018-04-12 +full_link: /docs/concepts/workloads/pods/pod-overview/ +short_description: > + The smallest and simplest Kubernetes object. A Pod represents a set of running containers on your cluster. + +aka: +tags: +- core-object +- fundamental +--- + Kubernetesオブジェクトの最小単位です。Podはクラスター上で稼働している{{< glossary_tooltip text="コンテナー" term_id="container" >}}のセットを表します。 + + + +Podは典型的に、単一の主要なコンテナーを稼働させるためにセットアップされます。また、オプションとして、ロギングなどの機能を提供するためのサイドカーコンテナーも稼働させることができます。Podは通常、{{< glossary_tooltip term_id="deployment" >}}によって管理されます。 + diff --git a/content/ja/docs/reference/glossary/service.md b/content/ja/docs/reference/glossary/service.md new file mode 100755 index 0000000000000..009bb7adce5cb --- /dev/null +++ b/content/ja/docs/reference/glossary/service.md @@ -0,0 +1,19 @@ +--- +title: Service +id: service +date: 2018-04-12 +full_link: /docs/concepts/services-networking/service/ +short_description: > + A way to expose an application running on a set of Pods as a network service. + +aka: +tags: +- fundamental +- core-object +--- + +Serviceとは、ネットワークサービスとして{{< glossary_tooltip text="Pod" term_id="pod" >}}のセット上で稼働するアプリケーションを公開するための、抽象化された方法です。 + + + + ServiceによってターゲットされたPodのセットは、たいてい{{< glossary_tooltip text="selector" term_id="selector" >}}によって定義されます。もしさらに多くのPodが追加または削除された時、そのセレクターに一致するPodのセットが変更されます。Serviceは、ネットワークトラフィックが現在稼働しているワークロード用のPodのセットに向けられることを保証します。