この記事は、クラウドでのコンテナー化されたワークロードのデプロイと管理に関するウェビナーシリーズを補足するものです。 このシリーズでは、コンテナライフサイクルの管理、マルチコンテナアプリケーションのデプロイ、ワークロードのスケーリング、Kubernetesの操作など、コンテナの基本事項について説明します。 また、ステートフルアプリケーションを実行するためのベストプラクティスについても説明します。

この記事は、シリーズの4番目のセッションKubernetesの詳細を補足します。

序章

Kubernetes は、コンテナー化されたアプリケーションを管理するためのオープンソースのコンテナーオーケストレーションツールです。 このシリーズの前のチュートリアルでは、DigitalOceanでKubernetesを構成しました。 クラスターが稼働しているので、コンテナー化されたアプリケーションをクラスターにデプロイできます。

このチュートリアルでは、ポッドをKubernetesにデプロイし、サービスとして公開し、レプリケーションコントローラーを介してスケーリングするときに、これらのプリミティブがどのように連携するかを学習します。

前提条件

このチュートリアルを完了するには、最初にこのシリーズの前のチュートリアルKubernetes入門を完了する必要があります。

ステップ1-Kubernetesプリミティブを理解する

Kubernetesは、クライアントがアプリケーションの作成、スケーリング、終了に使用するAPIを公開します。 各操作は、Kubernetesが管理する1つ以上のオブジェクトを対象としています。 これらのオブジェクトは、Kubernetesの基本的な構成要素を形成します。 これらは、コンテナー化されたアプリケーションを管理するためのプリミティブです。

以下は、Kubernetesの主要なAPIオブジェクトの概要です。

  • クラスター:コンピューティング、ストレージ、およびネットワークリソースのプール。
  • ノード:クラスター内で実行されているホストマシン。
  • Namespaces :クラスターの論理パーティション。
  • ポッド:展開の単位。
  • ラベルおよびセレクター:識別とサービス検出のためのキーと値のペア。
  • Services :同じアプリケーションに属するポッドのコレクション。
  • レプリカセット:可用性とスケーラビリティを保証します。
  • 展開:アプリケーションのライフサイクルを管理します。

これらをさらに詳しく見ていきましょう。

Kubernetesクラスターを実行するNodesもオブジェクトとして扱われます。 これらは、Kubernetesの他のAPIオブジェクトと同じように管理できます。 アプリケーションの論理的な分離を可能にするために、Kubernetesは名前空間の作成をサポートしています。 たとえば、組織は、開発、テスト、ステージング、および本番環境を実行するために、Kubernetesクラスターを論理的にパーティション化する場合があります。 各環境は、独立して管理される専用の名前空間に配置できます。 Kubernetesは、マスターノードを介してAPIを公開します。

KubernetesはDockerコンテナを実行しますが、これらのコンテナを直接デプロイすることはできません。 代わりに、アプリケーションはKubernetesが理解できる形式でパッケージ化する必要があります。 この形式により、Kubernetesはコンテナ化されたアプリケーションを効率的に管理できます。 これらのアプリケーションには、連携する必要のある1つ以上のコンテナが含まれている場合があります。

Kubernetesでのパッケージ化とデプロイの基本単位は、Podと呼ばれます。 各ポッドには、一緒に管理する必要がある1つ以上のコンテナが含まれる場合があります。 たとえば、Webサーバー(Nginx)コンテナーとキャッシュ(Redis)コンテナーをポッドとして一緒にパッケージ化できます。 Kubernetesは、ポッドに属するすべてのコンテナを論理ユニットとして扱います。 新しいポッドが作成されるたびに、ポッド定義で宣言されたすべてのコンテナが作成されます。 ポッド内のすべてのコンテナは、IPアドレス、ホスト名、ストレージなどの同じコンテキストを共有します。 これらは、リモート呼び出しやREST APIではなく、プロセス間通信(IPC)を介して相互に通信します。

コンテナがパッケージ化されてKubernetesにデプロイされたら、内部および外部アクセスのためにコンテナを公開する必要があります。 データベースやキャッシュなどの特定のコンテナは、外部に公開する必要はありません。 APIとWebフロントエンドは、他のコンシューマーとエンドユーザーが直接アクセスするため、一般に公開する必要があります。 Kubernetesでは、コンテナはポリシーに基づいて内部または外部に公開されます。 このメカニズムにより、データベースなどの機密性の高いワークロードを一般に公開するリスクが軽減されます。

Kubernetesのポッドは、Servicesを通じて公開されます。 各サービスは、ポートおよびプロトコル情報とともに内部または外部エンドポイントとして宣言されます。 他のポッドを含む内部コンシューマーとAPIクライアントなどの外部コンシューマーは、基本的な対話をKubernetesサービスに依存しています。 サービスはTCPおよびUDPプロトコルをサポートします。

ポッドやサービスなどのKubernetesの各オブジェクトは、LabelsおよびSelectorsと呼ばれる追加のメタデータに関連付けられています。 ラベルは、Kubernetesオブジェクトに付加されたキーと値のペアです。 これらのラベルは、1つ以上のAPIオブジェクトを一意に識別します。 セレクターは、1つのKubernetesオブジェクトを別のオブジェクトに関連付けます。 たとえば、サービスで定義されたセレクターは、Kubernetesがセレクターの値と一致するラベルを持つすべてのポッドを見つけるのに役立ちます。 この関連付けにより、オブジェクトの動的な検出が可能になります。 同じラベルで実行時に作成された新しいオブジェクトは即座に検出され、対応するセレクターに関連付けられます。 このサービス検出メカニズムにより、スケールインおよびスケールアウト操作などの効率的な動的構成が可能になります。

コンテナに切り替える利点の1つは、迅速なスケーリングです。 コンテナは仮想マシンと比較して軽量であるため、数秒でスケーリングできます。 高可用性でスケーラブルなセットアップを行うには、アプリケーションの複数のインスタンスをデプロイし、これらのアプリケーションのインスタンスの最小数が常に実行されていることを確認する必要があります。 コンテナ化されたアプリケーションのこの構成に対処するために、Kubernetesはレプリカセットの概念を導入しました。これは、1つ以上のポッドを常に実行するように設計されています。 ポッドの複数のインスタンスをクラスターで実行する必要がある場合、それらはレプリカセットとしてパッケージ化されます。 Kubernetesは、レプリカセットで定義されたポッドの数が常に実行モードになっていることを確認します。 ハードウェアまたは構成の問題が原因でポッドが終了した場合、Kubernetesコントロールプレーンはすぐに別のポッドを起動します。

Deployment オブジェクトは、ポッドとレプリカセットの組み合わせです。 このプリミティブは、PaaSのような機能をKubernetesアプリケーションにもたらします。 これにより、最小限のダウンタイムで既存の展開のローリングアップグレードを実行できます。 展開により、カナリア展開や青/緑展開などのパターンも有効になります。 これらは、コンテナ化されたアプリケーションのアプリケーションライフサイクル管理(ALM)の重要な部分を処理します。

ステップ2–Kubernetesノードと名前空間の一覧表示

DigitalOcean でKubernetesクラスターをセットアップする手順に従ったと仮定して、次のコマンドを実行して、すべてのノードと使用可能なネームスペースを一覧表示します。

  1. kubectl get nodes
Output
NAME STATUS ROLES AGE VERSION spc3c97hei-master-1 Ready master 10m v1.8.7 spc3c97hei-worker-1 Ready <none> 4m v1.8.7 spc3c97hei-worker-2 Ready <none> 4m v1.8.7
  1. kubectl get namespaces
Output
NAME STATUS AGE default Active 11m kube-public Active 11m kube-system Active 11m stackpoint-system Active 4m

名前空間が指定されていない場合、 kubectl デフォルトの名前空間をターゲットにします。

それでは、アプリケーションを起動しましょう。

ステップ3–ポッドの作成と展開

KubernetesオブジェクトはYAMLファイルで宣言され、Kubernetesに送信されます。 kubectl CLI。 ポッドを定義してデプロイしましょう。

と呼ばれる新しいYAMLファイルを作成します Simple-Pod.yaml:

  1. nano Simple-Pod.yaml

NginxWebサーバーに基づいて1つのコンテナーでポッドを定義する次のコードを追加します。 ポートで公開されています 80 TCPプロトコルを介して。 定義にラベルが含まれていることに注意してください nameenv. これらのラベルを使用して、特定のポッドを識別および構成します。

シンプル-Pod.yaml
apiVersion: "v1"
kind: Pod
metadata:
  name: web-pod
  labels:
    name: web
    env: dev
spec:
  containers:
    - name: myweb
      image: nginx
      ports:
        - containerPort: 80
          name: http
          protocol: TCP

次のコマンドを実行して、ポッドを作成します。

  1. kubectl create -f Simple-Pod.yaml
Output
pod "web-pod" created

ポッドの作成を確認しましょう。

  1. kubectl get pods
Output
NAME READY STATUS RESTARTS AGE web-pod 1/1 Running 0 2m

次のステップでは、このポッドをパブリックインターネットにアクセスできるようにします。

ステップ4–サービスを介したポッドの公開

サービスは、ポッドのセットを内部または外部に公開します。 Nginxポッドを公開するサービスを定義しましょう。 ノードポートを介してNginxを公開します。これは、クラスターの各ノードで開かれた任意のポートを介してポッドにアクセスできるようにするスキームです。

と呼ばれる新しいファイルを作成します Simple-Service.yaml Nginxのサービスを定義する次のコードが含まれています。

Simple-Service.yaml
apiVersion: v1
kind: Service
metadata:
  name: web-svc
  labels:
    name: web
    env: dev
spec:
  selector:
    name: web
  type: NodePort
  ports:
    - port: 80
      name: http
      targetPort: 80
      protocol: TCP

サービスは、ラベルと一致する同じ名前空間内のすべてのポッドを検出します name: web. YAMLファイルのセレクターセクションは、この関連付けを明示的に定義します。

タイプ:NodePort宣言により、サービスのタイプがNodePortであることを指定します。

次に、kubectlを使用してクラスターに送信します。

  1. kubectl create -f Simple-Service.yml

サービスが正常に作成されたことを示す次の出力が表示されます。

Output
service "web-svc" created

ポッドが使用可能なポートを取得しましょう。

  1. kubectl get services
Output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.3.0.1 <none> 443/TCP 28m web-svc NodePort 10.3.0.143 <none> 80:32097/TCP 38s

この出力から、サービスがポートで利用可能であることがわかります 32097. ワーカーノードの1つに接続してみましょう。

DigitalOceanコンソールを使用して、いずれかのワーカーノードのIPアドレスを取得します。

使用 curl ポート上のノードの1つにHTTPリクエストを送信するコマンド 31930.

  1. curl http://your_worker_1_ip_address:32097

Nginxのデフォルトのホームページを含む応答が表示されます。

Output
<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> ... Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>

ポッドとサービスを定義しました。 次に、レプリカセットを使用したスケーリングを見てみましょう。

ステップ5–レプリカセットを介したポッドのスケーリング

レプリカセットは、少なくとも最小数のポッドがクラスターで実行されていることを確認します。 現在のポッドを削除し、レプリカセットを使用して3つのポッドを再作成しましょう。

まず、既存のポッドを削除します。

  1. kubectl delete pod web-pod
Output
pod "web-pod" deleted

次に、新しいレプリカセット宣言を作成します。 レプリカセットの定義はポッドと同じです。 主な違いは、実行する必要のあるポッドの数を定義するレプリカ要素が含まれていることです。 ポッドと同様に、サービス検出に役立つメタデータとしてラベルも含まれています。

ファイルを作成する Simple-RS.yml 次のコードをファイルに追加します。

シンプル-RS.yml
apiVersion: apps/v1beta2
kind: ReplicaSet
metadata:
  name: web-rs
  labels:
    name: web
    env: dev
spec:
  replicas: 3
  selector:
  	matchLabels:
  	  name: web  
  template:
	metadata:
	  labels:
		name: web
		env: dev
	spec:
	  containers:
      - name: myweb
        image: nginx
          ports:
            - containerPort: 80
              name: http
              protocol: TCP

ファイルを保存して閉じます。

次に、レプリカセットを作成します。

  1. kubectl create -f Simple-RS.yml
Output
replicaset "web-rs" created

次に、ポッドの数を確認します。

  1. kubectl get pods
Output
NAME READY STATUS RESTARTS AGE web-rs-htb58 1/1 Running 0 38s web-rs-khtld 1/1 Running 0 38s web-rs-p5lzg 1/1 Running 0 38s

NodePortを介してサービスにアクセスすると、レプリカセットによって管理されているポッドの1つにリクエストが送信されます。

ポッドの1つを削除し、何が起こるかを確認して、レプリカセットの機能をテストしてみましょう。

  1. kubectl delete pod web-rs-p5lzg
Output
pod "web-rs-p5lzg" deleted

ポッドをもう一度見てください。

  1. kubectl get pods
Output
NAME READY STATUS RESTARTS AGE web-rs-htb58 1/1 Running 0 2m web-rs-khtld 1/1 Running 0 2m web-rs-fqh2f 0/1 ContainerCreating 0 2s web-rs-p5lzg 1/1 Running 0 2m web-rs-p5lzg 0/1 Terminating 0 2m

ポッドが削除されるとすぐに、Kubernetesは別のポッドを作成して、目的のカウントが維持されるようにします。

次に、デプロイメントを見てみましょう。

ステップ6–展開への対処

コンテナをポッドおよびレプリカセットとしてデプロイできますが、デプロイにより、アプリケーションのアップグレードとパッチ適用が容易になります。 レプリカセットでは実行できない展開を使用して、ポッドをインプレースでアップグレードできます。 これにより、最小限のダウンタイムで新しいバージョンのアプリケーションを展開できます。 これらは、PaaSのような機能をアプリケーション管理にもたらします。

デプロイメントを作成する前に、既存のレプリカセットを削除してください。 これにより、関連するポッドも削除されます。

  1. kubectl delete rs web-rs
Output
replicaset "web-rs" deleted

次に、新しいデプロイメントを定義します。 ファイルを作成する Simple-Deployment.yaml 次のコードを追加します。

Simple-Deployment.yaml
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: web-dep
  labels:
    name: web
    env: dev
spec:
  replicas: 3
  selector:
    matchLabels:
      name: web
  template:
    metadata:
      labels:
        name: web
    spec:
      containers:
      - name: myweb
        image: nginx
        ports:
        - containerPort: 80

デプロイメントを作成し、作成を確認します。

  1. kubectl create -f Simple-Deployment.yml
Output
deployment "web-dep" created

展開を表示します。

  1. kubectl get deployments
Output
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE web-dep 3 3 3 3 1m

デプロイの結果ポッドが作成されるため、YAMLファイルのレプリカ宣言に従って3つのポッドが実行されます。

  1. kubectl get pods
Output
NAME READY STATUS RESTARTS AGE web-dep-8594f5c765-5wmrb 1/1 Running 0 2m web-dep-8594f5c765-6cbsr 1/1 Running 0 2m web-dep-8594f5c765-sczf8 1/1 Running 0 2m

以前に作成したサービスは、デプロイメントによって作成されたポッドにリクエストをルーティングし続けます。 これは、元のポッド定義と同じ値を含むラベルが原因です。

展開とサービスを削除して、リソースをクリーンアップします。

  1. kubectl delete deployment web-dep
Output
deployment "web-dep" deleted
  1. kubectl delete service web-svc
Output
service "web-svc" deleted

デプロイの詳細については、Kubernetesのドキュメントを参照してください。

結論

このチュートリアルでは、ポッド、サービス、レプリカセット、およびデプロイを使用してNginx Webサーバーをデプロイする際に、Kubernetesの基本的な構成要素について説明しました。

このシリーズの次のパートでは、マルチコンテナーアプリケーションをパッケージ化、デプロイ、スケーリング、および管理する方法を学習します。