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は、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が提供するもののほんの一部にすぎません。 詳細については、数十の公式例と詳細な技術文書が豊富に用意されています。