Kustomizeを使用してKubernetes構成を管理する方法
著者は、 Diversity in Tech Fund を選択して、 Write forDOnationsプログラムの一環として寄付を受け取りました。
序章
アプリケーションをKubernetesにデプロイするのは、面倒な場合があります。 サービスでアクセシビリティが定義された、展開に裏打ちされたいくつかのポッドを展開します。 これらのリソースはすべて、適切な定義と構成のためにYAMLファイルを必要とします。
さらに、アプリケーションはデータベースとの通信、Webコンテンツの管理、またはログの詳細度の設定が必要になる場合があります。 さらに、これらのパラメーターは、デプロイ先の環境によって異なる場合があります。 これらすべてにより、YAML定義のコードベースが広大になり、それぞれに1行または2行の変更が加えられ、特定が困難になる可能性があります。
Kustomize は、これらの懸念に対処するために開発されたオープンソースの構成管理ツールです。 Kubernetes 1.14以降、kubectlはKustomizeおよびkustomizationファイルを完全にサポートしています。
このガイドでは、小さなWebアプリケーションを構築してから、Kustomizeを使用して構成の無秩序な増加を管理します。 さまざまな構成の開発環境と本番環境にアプリをデプロイします。 また、 Kustomizeのベースとオーバーレイを使用してこれらの可変構成を階層化し、コードを読みやすく、保守しやすくします。
前提条件
このチュートリアルでは、次のものが必要になります。
- 接続構成が
kubectl
デフォルトとして設定されているKubernetes1.14+クラスター。 DigitalOceanでKubernetesクラスタを作成するには、Kubernetesクイックスタートをお読みください。 クラスタに接続するには、DigitalOceanKubernetesクラスタに接続する方法をお読みください。 kubectl
がローカルマシンにインストールされています。 Kubernetesの使用を開始するためのこのチュートリアル:kubectl CheatSheetに従ってインストールしてください。
ステップ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.yml
とdeployment-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
を本番環境にデプロイする準備ができたと想像してください。 また、アプリケーションの製品版は、次の点で開発版とは異なることを決定しました。
replicas
は1
から3
に増加します。- コンテナリソース
requests
は、100m
CPUおよび128M
メモリから250m
CPUおよび256M
メモリに増加します。 - コンテナリソース
limits
は、100m
CPUおよび256M
メモリから1
CPUおよび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が提供するもののほんの一部にすぎません。 詳細については、数十の公式例と詳細な技術文書が豊富に用意されています。