🙌

kubernetesのServiceタイプをまとめた

2021/02/26に公開

はじめに

くーばねてすを倒すために今回はkubernetesのサービスタイプをまとめた!(^^)!。

概要

■サービスを設定することでポッドはどうなるのか
■ClusterIP
■NodePort
■LoadBalancer
■ExternalName
■serviceで使用するコマンド

をまとめた(^_-)-☆

■サービスを設定することでポッドはどうなるのか

サービスは永続的な IPアドレスをもたないポッドにクライアントがアクセスするためのオブジェクトだ。
サービスには4タイプがあり、サービスの設定により様々なアクセスやアクセス範囲を指定したりすることができる。
|サービスタイプ|意味|
| --- | --- | --- |
|ClusterIP|デフォルト設定値であり、内部ネットワークのポッドから内部DNSに登録された名前でアクセスできる|
|NodePort|ClusterIPのアクセス範囲に加え、ノードのIPアドレスとポート番号を指定することで外部クラスタからもアクセスできる|
|LoadBalancer|NodePortのアクセス範囲に加えクラスタ外からも代表IPアドレスとプロトコルのデフォルトポート番号でアクセスできる|
|ExternalName|クラスタ内から外部のIPアドレスを名前でアクセスできる|
KubernetesのServiceはPodと同様にオブジェクトとして扱う。
他のオブジェクトと同様に、ユーザーはServiceを作成するためにAPIサーバーに対してServiceの定義を指定することができる。Serviceオブジェクトの名前は、有効なDNSラベル名である必要がある。

■ClusterIP

ClusterIPでは、内部ネットワークのポッドから内部DNSに登録された名前でClusterIP(代表IPアドレス)にリクエストを送信し、ClusterIPがリクエストを負荷分散をする。
「ClusterIP:None」でセットすると代表IPアドレスを取得せず、ヘッドレスにポッドを運用できる。

■NodePort

NodePortではClusterIPに加え、ノードのIPアドレスに公開用ポートを開くことによりkubernetesクラスタ外のネットワークからポッドにリクエストを送信することができる。
公開ポートはデフォルトでは30000から32767である。クライアントがノードのIPアドレスと公開用ポートに送った番号はポッドのポートの番号に変換されてポッドにリクエストが送信される。

記述例                   
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: NodePort
  selector:
    app: MyApp
  ports:
      # デフォルトでは利便性のため、 `targetPort` は `port` と同じ値にセットされる。
    - port: 80
      targetPort: 80
      # 省略可能なフィールド
      # デフォルトでは利便性のため、自動的にある範囲から1つポートを割り当てる(デフォルト値の範囲:30000-32767)
      nodePort: 30007

NodePortタイプのサービスを作成すると全ノードに公開用ポートが開設される。
各ノードで受けたリクエストは全てのノード上のポッドに対して負荷分散を行い、転送する。
ただし、一度ノードをシャットダウンするとポッドが使用できなくなってしまうのと、再度公開用ポートで起動しようとすると既に使用中なのでエラーとなってしまう。
マニュフェストではspec/ports/nodePortに記述する。
NodePortは外部のネットワークへポッドを公開できるが可用性が十分ではないため本番環境には適さない。

■LoadBalancer

LoadBalancerをサービスタイプとして設定することでロードバランサーが作成され、ポッドのアプリケーションを外部ネットワークからアクセスできるようになる。
LoadBalancerはNodePort上に作成されるのでClusterIPも自動的に作成される。
マニュフェストではstatus/loadBalancerで記述する。
LoadBalancerは可用性があり、HTTPやHTTPSのデフォルトportが利用できるので本番環境に適している。

記述例
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9376
  clusterIP: 10.0.171.239
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
    - ip: 192.0.2.127

■ExternalName

ExternalNameは、ポッドからクラスタ外のエンドポイント(ネットワークへ繋がっているところ)へアクセスするための名前解決をする。
my-serviceやcassandraというような従来のラベルセレクターとはマッピングしない。
ExternalNameでは名前解決をするためにサービス名、外部DNS名を設定する必要がある。
また外部IPアドレスからポッドにアクセスできるように設定しなければならない。
ExternalNameではプロキシは設定されないのでポート番号の設定はできない。
ExternalNameではマニフェストspec/externalNameでは外部DNS設定のためにIPアドレスを設定できないのでマニフェストにIPアドレスを設定したいときは※Headless Serviceを利用する。

記述例
apiVersion: v1
kind: Service
metadata:
  name: my-service
  namespace: prod
spec:
  type: ExternalName
  externalName: my.database.example.com

※Headless Serviceについて
https://kubernetes.io/ja/docs/concepts/services-networking/service/

Headless Service
場合によっては、負荷分散と単一のService IPは不要です。このケースにおいて、clusterIP(.spec.clusterIP)の値を"None"に設定することにより、"Headless"とよばれるServiceを作成できます。
ユーザーは、Kubernetesの実装と紐づくことなく、他のサービスディスカバリーのメカニズムと連携するためにHeadless Serviceを使用できます。 例えば、ユーザーはこのAPI上でカスタムオペレーターを実装することができます。
このServiceにおいては、clusterIPは割り当てられず、kube-proxyはこのServiceをハンドリングしないのと、プラットフォームによって行われるはずの ロードバランシングやプロキシーとしての処理は行われません。DNSがどのように自動で設定されるかは、定義されたServiceが定義されたラベルセレクターを持っているかどうかに依存します。
ラベルセレクターの利用
ラベルセレクターを定義したHeadless Serviceにおいて、EndpointsコントローラーはAPIにおいてEndpointsレコードを作成し、ServiceのバックエンドにあるPodへのIPを直接指し示すためにDNS設定を修正します。
ラベルセレクターなしの場合
ラベルセレクターを定義しないHeadless Serviceにおいては、EndpointsコントローラーはEndpointsレコードを作成しません。 しかしDNSのシステムは下記の2つ両方を探索し、設定します。
・ExternalNameタイプのServiceに対するCNAMEレコード
・他の全てのServiceタイプを含む、Service名を共有している全てのEndpointsレコード

■serviceで使用するコマンド

実行中のservice一覧表示

$ kubectl get scv

serviceの詳細を表示する

$ kubectl discribe scv

まとめ

つぎはサービスのマニフェストの書き方を勉強する!(>_<)

Discussion