【Kubernetes初めの一歩】リソースざっくりまとめ
はじめに
Kubernetesを勉強していて、Kubernetesのリソースが多くどれがなんだかわからなくなるので、ざっくりまとめてみました。
unknown linkアルファベット順に並べています。
ConfigMap
機密性のない設定ファイルを定義して、Podへ提供します。
環境変数やコマンドライン引数などをコンテナから分離できます。
unknown linkCronJob
Cron形式で指定したスケジュールで実行されるJobです。
unknown linkDeployment
ReplicaSetを管理します。
DeploymentはReplicaSetを管理することでPodを制御します。
![Deployment](/images/kubernetes-horizontal-color.png)
Deployment
Deployment はPodとReplicaSetの宣言的なアップデート機能を提供します。 Deploymentにおいて 理想的な状態 を記述すると、Deploymentコントローラーは指定された頻度で現在の状態を理想的な状態に変更します。Deploymentを定義することによって、新しいReplicaSetを作成したり、既存のDeploymentを削除して新しいDeploymentで全てのリソースを適用できます。 備考:Deploymentによって作成されたReplicaSetを管理しないでください。ご自身のユースケースが以下の項目に含まれない場合、メインのKubernetesリポジトリーにIssueを作成することを検討してください。 ユースケース 以下の項目はDeploymentの典型的なユースケースです。 ReplicaSetをロールアウトするためにDeploymentの作成を行う: ReplicaSetはバックグラウンドでPodを作成します。Podの作成が完了したかどうかは、ロールアウトのステータスを確認してください。 DeploymentのPodTemplateSpecを更新することによりPodの新しい状態を宣言する: 新しいReplicaSetが作成され、Deploymentは指定された頻度で古いReplicaSetから新しいReplicaSetへのPodの移行を管理します。新しいReplicaSetはDeploymentのリビジョンを更新します。 Deploymentの現在の状態が不安定な場合、Deploymentのロールバックをする: ロールバックによる各更新作業は、Deploymentのリビジョンを更新します。 より多くの負荷をさばけるように、Deploymentをスケールアップする。 PodTemplateSpecに対する複数の修正を適用するためにDeploymentを停止(Pause)し、それを再開して新しいロールアウトを開始します。 Deploymentのステータス をロールアウトが失敗したサインとして利用する。 今後必要としない古いReplicaSetのクリーンアップ Deploymentの作成 以下はDeploymentの例です。これはnginxPodのレプリカを3つ持つReplicaSetを作成します。 controllers/nginx-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 この例では、 .metadata.nameフィールドで指定されたnginx-deploymentという名前のDeploymentが作成されます。 このDeploymentは.spec.replicasフィールドで指定された通り、3つのレプリカPodを作成します。 .spec.selectorフィールドは、Deploymentが管理するPodのラベルを定義します。ここでは、Podテンプレートにて定義されたラベル(app: nginx)を選択しています。しかし、PodTemplate自体がそのルールを満たす限り、さらに洗練された方法でセレクターを指定することができます。 備考:`.spec.selector.matchLabels`フィールドはキーバリューペアのマップです。 `matchLabels`マップにおいて、{key, value}というペアは、keyというフィールドの値が"key"で、その演算子が"In"で、値の配列が"value"のみ含むような`matchExpressions`の要素と等しくなります。 `matchLabels`と`matchExpressions`の両方が設定された場合、条件に一致するには両方とも満たす必要があります。 templateフィールドは、以下のサブフィールドを持ちます。: Podは.metadata.labelsフィールドによって指定されたapp: nginxというラベルがつけられます。 PodTemplate、または.template.specフィールドは、Podがnginxという名前でDocker Hubにあるnginxのバージョン1.14.2が動くコンテナを1つ動かすことを示します。 1つのコンテナを作成し、.
Ingress
Serviceに対する外部からのアクセスを制御します。
![Ingress](/images/kubernetes-horizontal-color.png)
Ingress
FEATURE STATE: Kubernetes v1.19 [stable] クラスター内のServiceに対する外部からのアクセス(主にHTTP)を管理するAPIオブジェクトです。 Ingressは負荷分散、SSL終端、名前ベースの仮想ホスティングの機能を提供します。 用語 簡単のために、このガイドでは次の用語を定義します。 ノード: Kubernetes内のワーカーマシンで、クラスターの一部です。 クラスター: Kubernetesによって管理されているコンテナ化されたアプリケーションを実行させるノードの集合です。この例や、多くのKubernetesによるデプロイでは、クラスター内のノードはインターネットに公開されていません。 エッジルーター: クラスターでファイアウォールのポリシーを強制するルーターです。クラウドプロバイダーが管理するゲートウェイや、物理的なハードウェアの一部である場合もあります。 クラスターネットワーク: 物理的または論理的な繋がりの集合で、Kubernetesのネットワークモデルによって、クラスター内でのコミュニケーションを司るものです。 Service: ラベルセレクターを使ったPodの集合を特定するKubernetes Serviceです。特に指定がない限り、Serviceはクラスターネットワーク内でのみ疎通可能な仮想IPを持つものとして扱われます。 Ingressとは何か Ingressはクラスター外からクラスター内ServiceへのHTTPとHTTPSのルートを公開します。トラフィックのルーティングはIngressリソース上で定義されるルールによって制御されます。 全てのトラフィックを単一のServiceに送る単純なIngressの例を示します。 図. Ingress IngressはServiceに対して、外部疎通できるURL、負荷分散トラフィック、SSL/TLS終端の機能や、名前ベースの仮想ホスティングを提供するように設定できます。Ingressコントローラーは通常はロードバランサーを使用してIngressの機能を実現しますが、エッジルーターや、追加のフロントエンドを構成してトラフィックの処理を支援することもできます。 Ingressは任意のポートやプロトコルを公開しません。HTTPやHTTPS以外のServiceをインターネットに公開する場合、Service.Type=NodePortやService.Type=LoadBalancerのServiceタイプを一般的には使用します。 Ingressを使用する上での前提条件 Ingressを提供するためにはIngressコントローラーが必要です。Ingressリソースを作成するのみでは何の効果もありません。 ingress-nginxのようなIngressコントローラーのデプロイが必要な場合があります。いくつかのIngressコントローラーの中から選択してください。 理想的には、全てのIngressコントローラーはリファレンスの仕様を満たすはずです。しかし実際には、各Ingressコントローラーは微妙に異なる動作をします。 備考:Ingressコントローラーのドキュメントを確認して、選択する際の注意点について理解してください。 Ingressリソース Ingressリソースの最小構成の例は以下のとおりです。 service/networking/minimal-ingress.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: minimal-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: ingressClassName: nginx-example rules: - http: paths: - path: /testpath pathType: Prefix backend: service: name: test port: number: 80 IngressにはapiVersion、kind、metadataやspecフィールドが必要です。Ingressオブジェクトの名前は、有効なDNSサブドメイン名である必要があります。設定ファイルに関する一般的な情報は、アプリケーションのデプロイ、コンテナの設定、リソースの管理を参照してください。Ingressでは、Ingressコントローラーに依存しているいくつかのオプションの設定をするためにアノテーションを一般的に使用します。例としては、rewrite-targetアノテーションなどがあります。Ingressコントローラーの種類が異なれば、サポートするアノテーションも異なります。サポートされているアノテーションについて学ぶためには、使用するIngressコントローラーのドキュメントを確認してください。 Ingress Specは、ロードバランサーやプロキシサーバーを設定するために必要な全ての情報を持っています。最も重要なものとして、外部からくる全てのリクエストに対して一致したルールのリストを含みます。IngressリソースはHTTP(S)トラフィックに対してのルールのみサポートしています。 ingressClassNameが省略された場合、デフォルトのIngressClassを定義する必要があります。 デフォルトのIngressClassを定義しなくても動作するIngressコントローラーがいくつかあります。例えば、Ingress-NGINXコントローラーはフラグ --watch-ingress-without-classで設定できます。ただし、下記のようにデフォルトのIngressClassを指定することを推奨します。
Job
常駐ではない、正常終了することが保証しているPodの集合です。
unknown linkNamespace
Kubernetesクラスターで作成される仮想的なクラスターです。
![Namespace(名前空間)](/images/kubernetes-horizontal-color.png)
Namespace(名前空間)
Kubernetesは、同一の物理クラスター上で複数の仮想クラスターの動作をサポートします。 この仮想クラスターをNamespaceと呼びます。 複数のNamespaceを使う時 Namespaceは、複数のチーム・プロジェクトにまたがる多くのユーザーがいる環境での使用を目的としています。 数人から数十人しかユーザーのいないクラスターに対して、あなたはNamespaceを作成したり、考える必要は全くありません。 Kubernetesが提供するNamespaceの機能が必要となった時に、Namespaceの使用を始めてください。 Namespaceは名前空間のスコープを提供します。リソース名は単一のNamespace内ではユニークである必要がありますが、Namespace全体ではその必要はありません。Namespaceは相互にネストすることはできず、各Kubernetesリソースは1つのNamespaceにのみ存在できます。 Namespaceは、複数のユーザーの間でクラスターリソースを分割する方法です。(これはリソースクォータを介して分割します。) 同じアプリケーションの異なるバージョンなど、少し違うリソースをただ分割するだけに、複数のNamespaceを使う必要はありません。 同一のNamespace内でリソースを区別するためにはラベルを使用してください。 Namespaceを利用する Namespaceの作成と削除方法はNamespaceの管理ガイドドキュメントに記載されています。 備考:プレフィックスkube-を持つNamespaceは、KubernetesシステムのNamespaceとして予約されているため利用は避けてください。 Namespaceの表示 ユーザーは、以下の方法で単一クラスター内の現在のNamespaceの一覧を表示できます。 kubectl get namespace NAME STATUS AGE default Active 1d kube-node-lease Active 1d kube-system Active 1d kube-public Active 1d Kubernetesの起動時には4つの初期Namespaceが作成されています。 default 他にNamespaceを持っていないオブジェクトのためのデフォルトNamespace kube-system Kubernetesシステムによって作成されたオブジェクトのためのNamespace kube-public このNamespaceは自動的に作成され、全てのユーザーから読み取り可能です。(認証されていないユーザーも含みます。) このNamespaceは、リソースをクラスター全体を通じてパブリックに表示・読み取り可能にするため、ほとんどクラスターによって使用される用途で予約されます。 このNamespaceのパブリックな側面は単なる慣例であり、要件ではありません。 kube-node-lease クラスターのスケールに応じたノードハートビートのパフォーマンスを向上させる各ノードに関連したLeaseオブジェクトのためのNamespace。 Namespaceの設定 現在のリクエストのNamespaceを設定するには、--namespaceフラグを使用します。 例: kubectl run nginx --image=nginx --namespace=<insert-namespace-name-here> kubectl get pods --namespace=<insert-namespace-name-here> Namespace設定の永続化 ユーザーはあるコンテキストのその後のコマンドで使うために、コンテキスト内で永続的にNamespaceを保存できます。 kubectl config set-context --current --namespace=<insert-namespace-name-here> # Validate it kubectl config view --minify | grep namespace: NamespaceとDNS ユーザーがServiceを作成するとき、Serviceは対応するDNSエントリを作成します。 このエントリは<service-name>.
Node
コンテナを配置するためのPodを実行する1つのVMまたは物理マシンです。
unknown linkPersistentVolume
永続ボリュームそのものを定義します。
unknown linkPersistentVolumeClaim
実際に使うボリュームを要求します。
unknown linkPod
コンテナの集合体で、コンテナを実行する方法を定義します。
unknown linkReplicaSet
同じ仕様のPodを複数生成、管理します。
unknown linkSecret
認証情報などの機密情報を定義し、Podから参照できるようにします。
unknown linkService
アプリケーションとして実行されているPodの集合にアクセスする経路を定義します。
![Service](/images/kubernetes-horizontal-color.png)
Service
KubernetesにおけるServiceとは、 クラスター内で1つ以上のPodとして実行されているネットワークアプリケーションを公開する方法です。 Kubernetesでは、なじみのないサービスディスカバリーのメカニズムを使用するためにユーザーがアプリケーションの修正をする必要はありません。 KubernetesはPodにそれぞれのIPアドレス割り振りや、Podのセットに対する単一のDNS名を提供したり、それらのPodのセットに対する負荷分散が可能です。 Serviceを利用する動機 Kubernetes Podはクラスターの状態に合わせて作成され削除されます。Podは揮発的なリソースです。 Deploymentをアプリケーションを稼働させるために使用すると、Podを動的に作成・削除してくれます。 各Podはそれ自身のIPアドレスを持ちます。しかしDeploymentでは、ある時点において同時に稼働しているPodのセットは、その後のある時点において稼働しているPodのセットとは異なる場合があります。 この仕組みはある問題を引き起こします。もし、あるPodのセット(ここでは"バックエンド"と呼びます)がクラスター内で他のPodのセット(ここでは"フロントエンド"と呼びます)に対して機能を提供する場合、フロントエンドのPodがワークロードにおけるバックエンドを使用するために、バックエンドのPodのIPアドレスを探し出したり、記録し続けるためにはどうすればよいでしょうか? ここで Service について説明します。 Serviceリソース Kubernetesにおいて、ServiceはPodの論理的なセットや、そのPodのセットにアクセスするためのポリシーを定義します(このパターンはよくマイクロサービスと呼ばることがあります)。 ServiceによってターゲットとされたPodのセットは、たいてい セレクターによって定義されます。 その他の方法について知りたい場合はセレクターなしのServiceを参照してください。 例えば、3つのレプリカが稼働しているステートレスな画像処理用のバックエンドを考えます。これらのレプリカは代替可能です。— フロントエンドはバックエンドが何であろうと気にしません。バックエンドのセットを構成する実際のPodのセットが変更された際、フロントエンドクライアントはその変更を気にしたり、バックエンドのPodのセットの情報を記録しておく必要はありません。 Serviceによる抽象化は、クライアントからバックエンドのPodの管理する責務を分離することを可能にします。 クラウドネイティブのサービスディスカバリー アプリケーション内でサービスディスカバリーのためにKubernetes APIが使える場合、ユーザーはエンドポイントをAPI Serverに問い合わせることができ、またService内のPodのセットが変更された時はいつでも更新されたエンドポイントの情報を取得できます。 非ネイティブなアプリケーションのために、KubernetesはアプリケーションとバックエンドPodの間で、ネットワークポートやロードバランサーを配置する方法を提供します。 Serviceの定義 KubernetesのServiceはPodと同様にRESTのオブジェクトです。他のRESTオブジェクトと同様に、ユーザーはServiceの新しいインスタンスを作成するためにAPIサーバーに対してServiceの定義をPOSTできます。Serviceオブジェクトの名前は、有効なDNSラベル名である必要があります。 例えば、TCPで9376番ポートで待ち受けていて、app=MyappというラベルをもつPodのセットがあるとします。 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プロキシを参照ください)。 Serviceセレクターのコントローラーはセレクターに一致するPodを継続的にスキャンし、“my-service”という名前のEndpointsオブジェクトに対して変更をPOSTします。 備考:ServiceはportからtargetPortへのマッピングを行います。デフォルトでは、利便性のためにtargetPortフィールドはportフィールドと同じ値で設定されます。 Pod内のポートの定義は名前を設定でき、ServiceのtargetPort属性にてその名前を参照できます。これは単一の設定名をもつService内で、複数の種類のPodが混合していたとしても有効で、異なるポート番号を介することによって利用可能な、同一のネットワークプロトコルを利用します。 この仕組みはServiceをデプロイしたり、設定を追加する場合に多くの点でフレキシブルです。例えば、バックエンドソフトウェアにおいて、次のバージョンでPodが公開するポート番号を変更するときに、クライアントの変更なしに行えます。 ServiceのデフォルトプロトコルはTCPです。また、他のサポートされているプロトコルも利用可能です。 多くのServiceが、1つ以上のポートを公開する必要があるように、Kubernetesは1つのServiceオブジェクトに対して複数のポートの定義をサポートしています。 各ポート定義は同一のprotocolまたは異なる値を設定できます。 セレクターなしのService Serviceは多くの場合、KubernetesのPodに対するアクセスを抽象化しますが、他の種類のバックエンドも抽象化できます。 例えば: プロダクション環境で外部のデータベースクラスターを利用したいが、テスト環境では、自身のクラスターが持つデータベースを利用したい場合 Serviceを、異なるNamespaceのServiceや他のクラスターのServiceに向ける場合 ワークロードをKubernetesに移行するとき、アプリケーションに対する処理をしながら、バックエンドの一部をKubernetesで実行する場合 このような場合において、ユーザーはPodセレクターなしでServiceを定義できます。 apiVersion: v1 kind: Service metadata: name: my-service spec: ports: - protocol: TCP port: 80 targetPort: 9376 このServiceはセレクターがないため、対応するEndpointsオブジェクトは自動的に作成されません。 ユーザーはEndpointsオブジェクトを手動で追加することにより、向き先のネットワークアドレスとポートを手動でマッピングできます。
StatefulSet
データストアのような状態を保持する(ステートフルな)Podを複数生成、管理します。
unknown link