Kubernetes Kubernetes

ワークロードを健全に保つ:namespace、リソース、クォータ、probe

requests、limits、クォータでクラスターを公平に共有し、Kubernetes に不健全なコンテナを検出させます。

15 min learn.level.中級

クラスターは、CPU とメモリの共有プールです。ガードレールがなければ、1 つの貪欲なワークロードが近隣のワークロードを飢えさせたり、ハングしたアプリケーションがトラフィックを受け続けたりする可能性があります。このガイドでは、その両方に対するツールを説明します。プールを分けるための namespace とクォータ、各コンテナが必要とするものを記述するための requests と limits、そして Kubernetes がコンテナの不健全さを判断できるようにする probe です。

namespace でクラスターを分割する

namespace は、1 つのクラスターを、チーム、アプリケーション、環境ごとの別々の領域に分割します。

kubectl create namespace demo
kubectl get pods -n demo
kubectl config set-context --current --namespace=demo
kubectl get pods -A

指定しない限り、オブジェクトは default に入ります。コマンドでは -n NAME、マニフェストでは metadata.namespace を使います。クラスター自身のコンポーネントは kube-system に存在します。ほとんどのオブジェクトは namespace に属します(Pod、Service、ConfigMap、Secret)が、ノードや PersistentVolume のように、クラスター全体のものもあります。namespace は、クォータとアクセスルールが結び付けられる単位ですが、それ自体では、強力なセキュリティ境界ではなく、組織上の境界です。よくある驚きは、実際には別の namespace に作成しただけなのに、消えてしまったように見える Pod です。kubectl get pods -A で確認してください。

requests と limits を設定する

各コンテナは、必要なものと、使用できる最大量を宣言できます。

spec:
  containers:
    - name: web
      image: nginx:1.25
      resources:
        requests:
          cpu: 250m
          memory: 64Mi
        limits:
          cpu: 500m
          memory: 128Mi
  • Requests は、スケジューラーが確保するものです。Pod は、その量の未使用の容量があるノードにのみ配置され、コンテナには少なくともこれだけが保証されます。
  • Limits は、厳格な上限です。より多くの CPU を使おうとするコンテナは、スロットリングされます。メモリ制限を超えたコンテナは、強制終了され(OOMKilled)、再起動されます。

CPU はコア単位で測定され、1000m(ミリコア)が 1 コア丸ごとなので、250m は 4 分の 1 です。limit を request より低くすることはできません。どちらも Pod ごとではなく、コンテナごとに設定します。

metrics server で使用状況を観察する

kubectl top はライブの使用状況を報告しますが、多くの新しいクラスターにはない metrics server が必要です。それがないと、「Metrics API not available」と表示されます。minikube では次のとおりです。

minikube addons enable metrics-server
kubectl top nodes
kubectl top pods -A

他のクラスターでは、プロジェクトのページから metrics-server をインストールします。どの Pod が最もリソースを使っているかを見つける、手早い方法です。

ResourceQuota と LimitRange で予算を適用する

ResourceQuota は、namespace が要求または使用できる合計を制限します。

apiVersion: v1
kind: ResourceQuota
metadata:
  name: demo-quota
  namespace: demo
spec:
  hard:
    requests.cpu: "1"
    requests.memory: 1Gi
    limits.cpu: "2"
    limits.memory: 2Gi
    pods: "10"

kubectl describe resourcequota -n demo は、各制限に対する使用量を表示します。合計を超えそうになると、新しい Pod は作成時に「exceeded quota」エラーで拒否されます。クォータが CPU やメモリを対象としている場合、その namespace のすべての Pod も、それらの requests と limits を宣言する必要があり、そうでなければ拒否されます。LimitRange は、独自の値を設定しないコンテナにデフォルトを提供することで、これを避けられます。

apiVersion: v1
kind: LimitRange
metadata:
  name: container-defaults
  namespace: demo
spec:
  limits:
    - type: Container
      defaultRequest:
        cpu: 100m
        memory: 64Mi
      default:
        cpu: 250m
        memory: 128Mi

readiness probe と liveness probe を追加する

実行中のコンテナは、必ずしも動作しているコンテナではありません。probe によって、Kubernetes が確認できます。

  • readiness probe は、コンテナがトラフィックを受け取るべきかどうかを決めます。失敗すると、Pod は Service のエンドポイントから外されますが、再起動はされません。起動が遅い場合や、一時的な過負荷に使います。
  • liveness probe は、コンテナがまだ生きているかを決めます。連続して十分な回数失敗すると、kubelet がコンテナを再起動します。
  • startup probe は、遅いアプリケーションが起動している間、他の 2 つを遅らせます。
spec:
  containers:
    - name: web
      image: nginx:1.25
      readinessProbe:
        httpGet:
          path: /
          port: 80
        initialDelaySeconds: 2
        periodSeconds: 5
        timeoutSeconds: 1
        failureThreshold: 3
      livenessProbe:
        httpGet:
          path: /
          port: 80
        initialDelaySeconds: 10
        periodSeconds: 10
        failureThreshold: 3

タイミングのフィールドは、すべての probe で同じように機能します。initialDelaySeconds は、コンテナの起動後、最初のチェックまでに待つ時間、periodSeconds はチェックの頻度、timeoutSeconds は応答を待つ時間、failureThreshold は失敗とみなす連続した失敗の回数です。HTTP リクエストに加えて、probe は TCP 接続の確立(tcpSocket)、コンテナ内でのコマンドの実行(exec)、gRPC の使用もできます。

liveness のチェックは、シンプルで、プロセス自体に関するものにしてください。データベースがダウンしているために liveness probe が失敗すると、Kubernetes は健全なアプリケーションコンテナを無駄に再起動し、障害を悪化させる可能性があります。依存関係を反映するのに適した場所は、readiness probe です。readiness は、ローリングアップデートも左右します。新しい Pod は、準備完了になってはじめて、利用可能とみなされます。

probe の結果は、kubectl describe pod で確認できます。失敗はイベントに表示されます。また kubectl get pods では、readiness probe の失敗が READY 列の 0/1 として表示されます。

人気のガイド