CNPA — クラウドネイティブプラットフォームエンジニアリングアソシエイト
ゴールデンパスを一式作る
目標
新しいサービスが1つ生まれるとき、常に一緒に付いているべきもの(標準ラベル、リソースのrequest/limit、オートスケール、中断バジェット、ネットワークポリシー)を一式にまとめ、ガードレールのかかったネームスペースに実際にデプロイします。続いて、同じサービスをHelmチャートにパッケージ化し、環境別のvaluesで分岐させて、レンダリング結果をデプロイします。
なぜ重要なのか
ゴールデンパスの価値は、「何を入れたか」よりも、「開発者が要求していないのに入っているか」にあります。スキャフォールドがリソース制限とネットワークポリシーをデフォルトで付けてくれれば、そのルールを守るための開発者の労力はゼロになります。逆に、Wikiに「必ず制限を設定してください」と書いておくだけでは、半分は忘れられます。ガードレールの位置も同じ文脈です。ResourceQuotaとLimitRangeは作成時点に即座に判定するため、事後監査レポートよりはるかに良い開発者体験を生みます。特にこの2つの組み合わせは、試験によく出ます。クォータがCPUを制限すると、requestを明示していないPodは拒否されますが、LimitRangeのデフォルト値がその穴を埋めてくれます。後半のHelmの部分は、「同じスキャフォールドを値で分岐させる」というゴールデンパスの2つ目の顔です。1つのテンプレートでdevとprodを同時に満たす方法です。
ステップ
/root/cnpa-path/manifests/deployment.yamlにDeploymentpaymentsを作成してください。spec.replicas: 2、セレクターとPodラベルにapp.kubernetes.io/name: payments、メタデータラベルにapp.kubernetes.io/name: paymentsとapp.kubernetes.io/part-of: cnpa-platform、コンテナ名はapp、イメージはghcr.io/labhub/payments:1.0.0、containerPortは8080、resources.requestsはcpu100m/ memory128Mi、resources.limitsはcpu300m/ memory256Miにします。/root/cnpa-path/manifests/service.yamlにServicepaymentsを作成してください。typeClusterIP、port80、targetPort8080、セレクターapp.kubernetes.io/name: paymentsにします。/root/cnpa-path/manifests/hpa.yamlにHorizontalPodAutoscalerpayments(apiVersionautoscaling/v2、scaleTargetRefはapps/v1のDeploymentpayments、minReplicas: 2、maxReplicas: 6、cpu Utilizationの目標70)を作成してください。/root/cnpa-path/manifests/pdb.yamlにPodDisruptionBudgetpayments(minAvailable: 1、セレクターapp.kubernetes.io/name: payments)を、/root/cnpa-path/manifests/netpol.yamlにNetworkPolicypayments(podSelectorはapp.kubernetes.io/name: payments、policyTypesの最初の項目はIngress、ingressはapp.kubernetes.io/part-of: cnpa-platformラベルを持つPodからのTCP8080のみを許可)を作成してください。- ネームスペース
cnpa-appを作成し、その中にResourceQuotacnpa-app-quota(requests.cpu: "1"、requests.memory: 1Gi、limits.cpu: "2"、limits.memory: 2Gi、pods: "8")とLimitRangecnpa-app-limits(typeContainer、defaultはcpu200m/ memory256Mi、defaultRequestはcpu100m/ memory128Mi)を作成してください。 /root/cnpa-path/manifests/の5つのマニフェストをすべて、cnpa-appネームスペースに適用してください。helm create /root/cnpa-path/paymentsでチャートを作成し、values.yamlを修正してください。replicaCount: 2、image.repository: ghcr.io/labhub/payments、image.tag: "1.0.0"にします。/root/cnpa-path/payments/values-dev.yaml(replicaCount: 1、image.tag: "1.0.0")と/root/cnpa-path/payments/values-prod.yaml(replicaCount: 3、image.tag: "1.2.0"、fullnameOverride: payments-v2)を作成してください。そのあと、helm template payments-v2 /root/cnpa-path/payments -f /root/cnpa-path/payments/values-prod.yaml -n cnpa-appの結果を/root/cnpa-path/render-prod.yamlに保存してください。/root/cnpa-path/render-prod.yamlをcnpa-appネームスペースに適用してください。適用後、payments-v2Deploymentがreplicas3、イメージghcr.io/labhub/payments:1.2.0で起動していて、ステップ3のクォータがそのまま残っている必要があります。
参考
- ディレクトリ全体の適用は、
kubectl apply -n cnpa-app -f /root/cnpa-path/manifests/です。 helm templateは、クラスターには何も作成しません。レンダリング結果だけが標準出力に出ます。fullnameOverrideを指定すると、helmが作成するリソースの名前がその値に固定されます。ステップ4でデプロイしたpaymentsと名前が重ならないようにするための仕組みです。- よくある間違い1: HPAの
scaleTargetRef.apiVersionを書き忘れることです。Deploymentはapps/v1です。 - よくある間違い2: NetworkPolicyの
policyTypesを省略することです。省略すると、ルールのある方向だけが適用され、意図と違ってしまうことがあります。
サービススキャフォールド: DeploymentとService
/root/cnpa-path/manifests/deployment.yamlにDeployment paymentsを作成してください。spec.replicas: 2、セレクターとPodラベルにapp.kubernetes.io/name: payments、メタデータラベルにapp.kubernetes.io/name: paymentsとapp.kubernetes.io/part-of: cnpa-platform、コンテナ名はapp、イメージはghcr.io/labhub/payments:1.0.0、containerPortは8080、resources.requestsはcpu 100m / memory 128Mi、resources.limitsはcpu 300m / memory 256Miにします。/root/cnpa-path/manifests/service.yamlにService paymentsを作成してください。type ClusterIP、port 80、targetPort 8080、セレクターapp.kubernetes.io/name: paymentsにします。
ゴールデンパスのデフォルト値とは、「誰も要求していないのに、常に入っているもの」です。標準ラベルとリソースのrequest/limitがその例です。
HPA・PDB・NetworkPolicy
/root/cnpa-path/manifests/hpa.yamlにHorizontalPodAutoscaler payments(apiVersion autoscaling/v2、scaleTargetRefはapps/v1のDeployment payments、minReplicas: 2、maxReplicas: 6、cpu Utilizationの目標70)を作成してください。/root/cnpa-path/manifests/pdb.yamlにPodDisruptionBudget payments(minAvailable: 1、セレクターapp.kubernetes.io/name: payments)を、/root/cnpa-path/manifests/netpol.yamlにNetworkPolicy payments(podSelectorはapp.kubernetes.io/name: payments、policyTypesの最初の項目はIngress、ingressはapp.kubernetes.io/part-of: cnpa-platformラベルを持つPodからのTCP 8080のみを許可)を作成してください。
3つのリソースはいずれも、セレクターで対象のワークロードを見つけます。HPAだけはセレクターではなく、ターゲットの参照を使います。
ガードレールのあるネームスペース
ネームスペースcnpa-appを作成し、その中にResourceQuota cnpa-app-quota(requests.cpu: "1"、requests.memory: 1Gi、limits.cpu: "2"、limits.memory: 2Gi、pods: "8")とLimitRange cnpa-app-limits(type Container、defaultはcpu 200m / memory 256Mi、defaultRequestはcpu 100m / memory 128Mi)を作成してください。
クォータがリソースを制限すると、そのネームスペースのすべてのコンテナは、requestとlimitを宣言する必要があります。宣言していないものを救済してくれるオブジェクトが、別にあります。
スキャフォールドをクラスターに適用する
/root/cnpa-path/manifests/の5つのマニフェストをすべて、cnpa-appネームスペースに適用してください。
5つのリソースをすべて同じネームスペースにデプロイします。ディレクトリ全体を一度に適用するオプションがあります。
helm createでローカルチャートを作る
helm create /root/cnpa-path/paymentsでチャートを作成し、values.yamlを修正してください。replicaCount: 2、image.repository: ghcr.io/labhub/payments、image.tag: "1.0.0"にします。
helm createは、インターネットなしでローカルにチャートの骨組みを作成します。生成されたvalues.yamlを、このサービスに合わせて修正してください。
環境別のvaluesとレンダリングの確認
/root/cnpa-path/payments/values-dev.yaml(replicaCount: 1、image.tag: "1.0.0")と/root/cnpa-path/payments/values-prod.yaml(replicaCount: 3、image.tag: "1.2.0"、fullnameOverride: payments-v2)を作成してください。そのあと、helm template payments-v2 /root/cnpa-path/payments -f /root/cnpa-path/payments/values-prod.yaml -n cnpa-appの結果を/root/cnpa-path/render-prod.yamlに保存してください。
valuesファイルは重ねて適用されます。あとから指定したファイルが優先されます。レンダリングは、クラスターに触れないコマンドで行ってください。
レンダリング結果をガードレールの中にデプロイする
/root/cnpa-path/render-prod.yamlをcnpa-appネームスペースに適用してください。適用後、payments-v2 Deploymentがreplicas 3、イメージghcr.io/labhub/payments:1.2.0で起動していて、ステップ3のクォータがそのまま残っている必要があります。
名前が衝突しないように、valuesで名前を固定したかを確認してください。レンダリングしたファイルは、そのまま適用すれば十分です。