Kustomizeを使用してKubernetes構成を管理する方法

提供:Dev Guides
移動先:案内検索

著者は、 Diversity in Tech Fund を選択して、 Write forDOnationsプログラムの一環として寄付を受け取りました。

序章

アプリケーションをKubernetesにデプロイするのは、面倒な場合があります。 サービスでアクセシビリティが定義された、展開に裏打ちされたいくつかのポッドを展開します。 これらのリソースはすべて、適切な定義と構成のためにYAMLファイルを必要とします。

さらに、アプリケーションはデータベースとの通信、Webコンテンツの管理、またはログの詳細度の設定が必要になる場合があります。 さらに、これらのパラメーターは、デプロイ先の環境によって異なる場合があります。 これらすべてにより、YAML定義のコードベースが広大になり、それぞれに1行または2行の変更が加えられ、特定が困難になる可能性があります。

Kustomize は、これらの懸念に対処するために開発されたオープンソースの構成管理ツールです。 Kubernetes 1.14以降、kubectlはKustomizeおよびkustomizationファイルを完全にサポートしています。

このガイドでは、小さなWebアプリケーションを構築してから、Kustomizeを使用して構成の無秩序な増加を管理します。 さまざまな構成の開発環境と本番環境にアプリをデプロイします。 また、 Kustomizeのベースとオーバーレイを使用してこれらの可変構成を階層化し、コードを読みやすく、保守しやすくします。

前提条件

このチュートリアルでは、次のものが必要になります。

ステップ1—Kustomizeを使用せずにアプリケーションをデプロイする

Kustomizeを使用してアプリをデプロイする前に、まず従来の方法でアプリをデプロイします。 この場合、sammy-appの開発バージョン( Nginx でホストされる静的Webアプリケーション)をデプロイします。 WebコンテンツをデータとしてConfigMapに保存します。これは、デプロイメントのポッドにマウントします。 これらのそれぞれに個別のYAMLファイルが必要であり、これを作成します。

まず、アプリケーションとそのすべての構成ファイル用のフォルダーを作成します。 ここで、このチュートリアルのすべてのコマンドを実行します。

ホームディレクトリに新しいフォルダを作成し、内部を移動します。

mkdir ~/sammy-app && cd ~/sammy-app

次に、お好みのテキストエディタを使用して、configmap.ymlというファイルを作成して開きます。

nano configmap.yml

次のコンテンツを追加します。

〜/ sammy-app / configmap.yml

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: sammy-app
  namespace: default
data:
  body: >
    <html>
      <style>
        body {
          background-color: #222;
        }
        p {
          font-family:"Courier New";
          font-size:xx-large;
          color:#f22;
          text-align:center;
        }
      </style>
      <body>
        <p>DEVELOPMENT</p>
      </body>
    </html>

この仕様により、新しいConfigMapオブジェクトが作成されます。 sammy-appという名前を付け、data:内にいくつかのHTMLWebコンテンツを保存しています。

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

次に、deployment.ymlという名前の2番目のファイルを作成して開きます。

nano deployment.yml

次のコンテンツを追加します。

〜/ sammy-app / deployment.yml

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sammy-app
  namespace: default
  labels:
    app: sammy-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sammy-app
  template:
    metadata:
      labels:
        app: sammy-app
    spec:
      containers:
      - name: server
        image: nginx:1.17
        volumeMounts:
          - name: sammy-app
            mountPath: /usr/share/nginx/html
        ports:
        - containerPort: 80
          protocol: TCP
        resources:
          requests:
            cpu: 100m
            memory: "128M"
          limits:
            cpu: 100m
            memory: "256M"
        env:
        - name: LOG_LEVEL
          value: "DEBUG"
      volumes:
      - name: sammy-app
        configMap:
          name: sammy-app
          items:
          - key: body
            path: index.html

この仕様は、新しいDeploymentオブジェクトを作成します。 sammy-appの名前とラベルを追加し、レプリカの数を1に設定し、Nginxバージョン1.17コンテナイメージを使用するオブジェクトを指定します。 また、コンテナのポートを80に設定し、CPUとメモリの要求と制限を定義し、ログレベルをDEBUGに設定しています。

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

次に、これら2つのファイルをKubernetesクラスターにデプロイします。 stdinから複数のオブジェクトを作成するには、catコマンドをkubectlにパイプします。

cat configmap.yml deployment.yml | kubectl apply -f -

しばらく待ってから、kubectlを使用してアプリケーションのステータスを確認してください。

kubectl get pods -l app=sammy-app

最終的に、アプリケーションが実行されている1つのポッドと、READY列に1/1コンテナーが表示されます。

OutputNAME                         READY   STATUS    RESTARTS   AGE
sammy-app-56bbd86cc9-chs75   1/1     Running   0          8s

ポッドは実行されており、Deploymentによってサポートされていますが、それでもアプリケーションにアクセスできません。 まず、サービスを追加する必要があります。

service.ymlという3番目のYAMLファイルを作成して開きます。

nano service.yml

次のコンテンツを追加します。

〜/ sammy-app / service.yml

---
apiVersion: v1
kind: Service
metadata:
  name: sammy-app
  labels:
    app: sammy-app
spec:
  type: LoadBalancer
  ports:
  - name: sammy-app-http
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: sammy-app

この仕様は、sammy-appと呼ばれる新しいサービスオブジェクトを作成します。 ほとんどのクラウドプロバイダーでは、spec.typeをLoadBalancerに設定すると、ロードバランサーがプロビジョニングされます。 たとえば、 DigitalOcean Managed Kubernetes(DOKS)は、 DigitalOcean LoadBalancer をプロビジョニングして、アプリケーションをインターネットで利用できるようにします。 spec.portsは、sammy-appラベルの付いたポッドのTCPポート80をターゲットにします。

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

次に、サービスをKubernetesクラスターにデプロイします。

kubectl apply -f service.yml

しばらく待ってから、kubectlを使用してアプリケーションのステータスを確認してください。

kubectl get services -w

最終的に、パブリックIPがEXTERNAL-IP列の下に表示されます。 your_external_ipの代わりに一意のIPが表示されます。

OutputNAME         TYPE           CLUSTER-IP       EXTERNAL-IP         PORT(S)        AGE
kubernetes   ClusterIP      10.245.0.1       <none>              443/TCP        7h26m
sammy-app    LoadBalancer   10.245.186.235   <pending>           80:30303/TCP   65s
sammy-app    LoadBalancer   10.245.186.235   your_external_ip   80:30303/TCP   2m29s

表示されたIPアドレスをコピーして、Webブラウザに入力します。 アプリケーションのDEVELOPMENTバージョンが表示されます。

端末からCTRL + Cと入力して、サービスの視聴を停止します。

このステップでは、開発バージョンのsammy-appをKubernetesにデプロイしました。 手順2と3では、Kustomizeを使用してsammy-appの開発バージョンを再デプロイしてから、構成が少し異なる本番バージョンをデプロイします。 この新しいワークフローを使用すると、Kustomizeが構成の変更をどの程度適切に管理し、開発ワークフローを簡素化できるかがわかります。

ステップ2—Kustomizeを使用してアプリケーションをデプロイする

このステップでは、まったく同じアプリケーションをデプロイしますが、デフォルトのKubernetes方式ではなく、Kustomizeが期待する形式でデプロイします。

現在、ファイルシステムは次のようになっています。

sammy-app/
├── configmap.yml
├── deployment.yml
└── service.yml

このアプリケーションをKustomizeでデプロイ可能にするには、kustomization.ymlという1つのファイルを追加する必要があります。 今すぐそうしてください:

nano kustomization.yml

少なくとも、このファイルは、kubectl-kオプションで実行するときに管理するリソースを指定する必要があります。これにより、kubectlはkustomizationファイルを処理するように指示されます。

次のコンテンツを追加します。

〜/ sammy-app / kustomization.yml

---
resources:
- configmap.yml
- deployment.yml
- service.yml

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

ここで、再度デプロイする前に、ステップ1から既存のKubernetesリソースを削除します。

kubectl delete deployment/sammy-app service/sammy-app configmap/sammy-app

そして、それらを再度デプロイしますが、今回はKustomizeを使用します。

kubectl apply -k .

-fオプションをkubectlに提供して、Kubernetesにファイルからリソースを作成するように指示する代わりに、-kとディレクトリ(この場合は.)を提供します現在のディレクトリを示します)。 これは、kubectlにKustomizeを使用し、そのディレクトリのkustomization.ymlを検査するように指示します。

これにより、ConfigMap、Deployment、およびServiceの3つのリソースすべてが作成されます。 get podsコマンドを使用して、展開を確認します。

kubectl get pods -l app=sammy-app

アプリケーションが実行されているポッドが1つ表示され、READY列に1/1コンテナーが表示されます。

次に、get servicesコマンドを再実行します。 また、公的にアクセス可能なEXTERNAL-IPでサービスが表示されます。

kubectl get services -l app=sammy-app

これで、Kustomizeを使用してKubernetes構成を正常に管理できます。 次のステップでは、sammy-appをわずかに異なる構成で本番環境にデプロイします。 また、Kustomizeを使用してこれらの差異を管理します。

ステップ3—Kustomizeを使用したアプリケーションの差異の管理

Kubernetesリソースの構成ファイルは、複数のリソースタイプの処理を開始すると、特に環境間にわずかな違いがある場合(たとえば、開発と本番環境など)に、実際に無秩序に広がり始める可能性があります。 deployment.ymlの代わりに、deployment-development.ymldeployment-production.ymlがある場合があります。 他のすべてのリソースでも状況は似ている可能性があります。

Nginx Dockerイメージの新しいバージョンがリリースされ、それを使い始めたいと思ったときに何が起こるか想像してみてください。 deployment-development.ymlで新しいバージョンをテストして続行したいのに、deployment-production.ymlを新しいバージョンに更新するのを忘れた可能性があります。 突然、本番環境とは異なるバージョンのNginxを開発中に実行していることになります。 このような小さな構成エラーは、アプリケーションをすぐに壊す可能性があります。

Kustomizeは、これらの管理の問題を大幅に簡素化できます。 これで、Kubernetes構成ファイルとkustomization.ymlを含むファイルシステムができたことを思い出してください。

sammy-app/
├── configmap.yml
├── deployment.yml
├── kustomization.yml
└── service.yml

これで、sammy-appを本番環境にデプロイする準備ができたと想像してください。 また、アプリケーションの製品版は、次の点で開発版とは異なることを決定しました。

  • replicas1から3に増加します。
  • コンテナリソースrequestsは、100mCPUおよび128Mメモリから250mCPUおよび256Mメモリに増加します。
  • コンテナリソースlimitsは、100mCPUおよび256Mメモリから1CPUおよび1Gメモリに増加します。
  • LOG_LEVEL環境変数がDEBUGからINFOに変更されます。
  • ConfigMapデータは、わずかに異なるWebコンテンツを表示するように変更されます。

まず、Kustomize固有の方法で物事を整理するために、いくつかの新しいディレクトリを作成します。

mkdir base

これにより、「デフォルト」構成、つまりベースが保持されます。 あなたの例では、これはsammy-appの開発バージョンです。

次に、sammy-app/の現在の構成を次のディレクトリに移動します。

mv configmap.yml deployment.yml service.yml kustomization.yml base/

次に、実稼働構成用の新しいディレクトリーを作成します。 Kustomizeはこれをオーバーレイと呼びます。 オーバーレイは、ベースの上にあるレイヤーと考えてください。機能するには、常にベースが必要です。

mkdir -p overlays/production

別のkustomization.ymlファイルを作成して、本番オーバーレイを定義します。

nano overlays/production/kustomization.yml

次のコンテンツを追加します。

〜/ sammy-app / overlays / product / kustomization.yml

---
bases:
- ../../base
patchesStrategicMerge:
- configmap.yml
- deployment.yml

このファイルは、オーバーレイのbaseと、Kubernetesがリソースにパッチを適用するために使用する戦略を指定します。 この例では、strategic-merge-styleパッチを指定してConfigMapおよびDeploymentリソースを更新します。

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

最後に、新しいdeployment.ymlおよびconfigmap.ymlファイルをoverlays/production/ディレクトリに追加します。

最初に新しいdeployment.ymlファイルを作成します。

nano overlays/production/deployment.yml

以下をファイルに追加します。 強調表示されたセクションは、開発構成からの変更を示しています。

〜/ sammy-app / overlays / Production / deployment.yml

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sammy-app
  namespace: default
spec:
  replicas: 3
  template:
    spec:
      containers:
      - name: server
        resources:
          requests:
            cpu: 250m
            memory: "256M"
          limits:
            cpu: 1
            memory: "1G"
        env:
        - name: LOG_LEVEL
          value: "INFO"

この新しいdeployment.ymlの内容に注意してください。 これには、変更されたリソース(この場合はアプリケーションのデプロイメント)を識別するために使用されるTypeMetaフィールドと、ネストされた構造にステップインして新しいフィールド値を指定するのに十分な残りのフィールドのみが含まれます。コンテナリソースのリクエストと制限。

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

次に、プロダクションオーバーレイ用の新しいconfigmap.ymlを作成します。

nano /overlays/production/configmap.yml

次のコンテンツを追加します。

〜/ sammy-app / overlays / product / configmap.yml

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: sammy-app
  namespace: default
data:
  body: >
    <html>
      <style>
        body {
          background-color: #222;
        }
        p {
          font-family:"Courier New";
          font-size:xx-large;
          color:#22f;
          text-align:center;
        }
      </style>
      <body>
        <p>PRODUCTION</p>
      </body>
    </html>

ここでは、DEVELOPMENTではなくPRODUCTIONを表示するようにテキストを変更しました。 また、テキストの色を赤の色相#f22から青の色相#22fに変更したことに注意してください。 Kustomizeのような構成管理ツールを使用していなかった場合、そのような小さな変更を見つけて追跡することがどれほど難しいかを考えてみてください。

ディレクトリ構造は次のようになります。

sammy-app/
├── base
│   ├── configmap.yml
│   ├── deployment.yml
│   ├── kustomization.yml
│   └── service.yml
└── overlays
    └── production
        ├── configmap.yml
        ├── deployment.yml
        └── kustomization.yml

基本構成を使用してデプロイする準備ができました。 まず、既存のリソースを削除します。

kubectl delete deployment/sammy-app service/sammy-app configmap/sammy-app

基本構成をKubernetesにデプロイします。

kubectl apply -k base/

デプロイメントを検査します。

kubectl get pods,services -l app=sammy-app

サービスのEXTERNAL-IPに開発バージョンが表示された、予想される基本構成が表示されます。

OutputNAME                             READY   STATUS    RESTARTS   AGE
pod/sammy-app-5668b6dc75-rwbtq   1/1     Running   0          21s

NAME                TYPE           CLUSTER-IP       EXTERNAL-IP            PORT(S)        AGE
service/sammy-app   LoadBalancer   10.245.110.172   your_external_ip   80:31764/TCP   7m43s

次に、本番構成をデプロイします。

kubectl apply -k overlays/production/

デプロイメントを再度検査します。

kubectl get pods,services -l app=sammy-app

予想されるproduction構成が表示され、製品版はサービスのEXTERNAL-IPに表示されます。

OutputNAME                             READY   STATUS    RESTARTS   AGE
pod/sammy-app-86759677b4-h5ndw   1/1     Running   0          15s
pod/sammy-app-86759677b4-t2dml   1/1     Running   0          17s
pod/sammy-app-86759677b4-z56f8   1/1     Running   0          13s

NAME                TYPE           CLUSTER-IP       EXTERNAL-IP            PORT(S)        AGE
service/sammy-app   LoadBalancer   10.245.110.172   your_external_ip   80:31764/TCP   8m59s

実稼働構成では、ポッドが1つではなく合計3つあることに注意してください。 展開リソースを表示して、あまり目立たない変更が有効になったことを確認することもできます。

kubectl get deployments -l app=sammy-app -o yaml

ブラウザでyour_external_ipにアクセスして、サイトの製品版を表示します。

現在、Kustomizeを使用してアプリケーションの差異を管理しています。 元の問題の1つを振り返ると、Nginxイメージのバージョンを変更したい場合は、ベースのdeployment.ymlを変更するだけで済み、そのベースを使用するオーバーレイもKustomizeを介してその変更を受け取ります。 。 これにより、開発ワークフローが大幅に簡素化され、読みやすさが向上し、エラーの可能性が減少します。

結論

このチュートリアルでは、小さなWebアプリケーションを構築し、それをKubernetesにデプロイしました。 次に、Kustomizeを使用して、さまざまな環境でのアプリケーションの構成の管理を簡素化しました。 ほぼ重複しているYAMLファイルのセットを階層化されたモデルに再編成しました。 これにより、エラーが減り、手動設定が減り、作業がより認識されやすくなり、保守しやすくなります。

ただし、これはKustomizeが提供するもののほんの一部にすぎません。 詳細については、数十の公式例詳細な技術文書が豊富に用意されています。