KubernetesYAMLのベストプラクティスと戦略

Kubernetesワークロードは、最も一般的にYAML形式のファイルで定義されます。

YAMLの問題の1つは、マニフェストファイル間の制約または関係を説明することが難しいことです。
クラスタにデプロイされたすべてのイメージが信頼できるレジストリから抽出されているかどうかを確認したい場合はどうなりますか?
ポッドセキュリティポリシーのないワークロードがクラスタに送信されないようにするにはどうすればよいですか?
統合された静的チェックにより、開発ライフサイクルに近いエラーやポリシー違反を検出できます。
また、リソース定義の有効性とセキュリティが向上しているため、本番ワークロードがベストプラクティスに従っていることを信頼できます。

Kubernetes YAMLファイルの静的検査エコシステムは、次のカテゴリに分類できます。

  • APIベリファイア:このタイプのツールは、指定されたYAMLリストをKubernetesAPIサーバーに対して検証します。
  • 組み込みチェッカー:このタイプのツールには、セキュリティ、ベストプラクティスなどの意識的なチェックがバンドルされています。
  • カスタムバリデーター:これらのツールを使用すると、カスタムチェックを複数の言語(pythonやJavascriptなど)で作成できます。

この記事では、6つの異なるツールについて学習します。

Kubeval
Kube-score
Config-lint
Copper
Conftest
Polaris

行きましょう~~~

ベンチマークサービス

後でテストおよび比較するために、最初にベンチマークサービスを展開します

apiVersion: apps/v1
kind: Deployment
metadata:
  name: http-echo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: http-echo
  template:
    metadata:
      labels:
        app: http-echo
    spec:
      containers:
      - name: http-echo
        image: hashicorp/http-echo
        args: ["-text", "hello-world"]
        ports:
        - containerPort: 5678
---
apiVersion: v1
kind: Service
metadata:
  name: http-echo
spec:
  ports:
  - port: 5678
    protocol: TCP
    targetPort: 5678
  selector:
    app: http-echo

展開が完了し、次のように検証されます。

[root@k8s-node001 Test]# kubectl  get po
NAME                            READY   STATUS    RESTARTS   AGE
http-echo-57dd74545-rtxzm       1/1     Running   0          65s
http-echo-57dd74545-trst7       1/1     Running   0          65s

[root@k8s-node001 Test]# kubectl  get svc
NAME             TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
http-echo        ClusterIP   10.102.221.64   <none>        5678/TCP         70s

[root@k8s-node001 Test]# curl  10.102.221.64:5678
hello-world

上記のYAMLファイルは正常にデプロイできますが、ベストプラクティスに従っていますか?

はじめましょう。

kubeval

kubevalの前提は、Kubernetesとの対話がRESTAPIを介して行われることです。
したがって、APIパターンを使用して、特定のYAML入力がパターンに準拠しているかどうかを確認できます。

kubevalをインストールします

wget https://github.com/instrumenta/kubeval/releases/latest/download/kubeval-linux-amd64.tar.gz
tar xf kubeval-linux-amd64.tar.gz
cp kubeval /usr/local/bin

それでは、base.yamlを変更して削除しましょう

  selector:
    matchLabels:
      app: http-echo

次に、kubevalを使用してbase.yamlを確認します

[root@k8s-node001 Test]# kubeval  base.yaml
WARN - base.yaml contains an invalid Deployment (http-echo) - selector: selector is required
PASS - base.yaml contains a valid Service (http-echo)

出力には、セレクターが必須フィールドであることを示すWARNが表示され、セレクター
を復元して、再度確認します。

[root@k8s-node001 Test]# kubeval  base.yaml 
PASS - base.yaml contains a valid Deployment (http-echo)
PASS - base.yaml contains a valid Service (http-echo)

PASSを確認してください

kubevalのようなツールの利点は、展開サイクルの早い段階でそのようなエラーを検出できることです。
さらに、チェックを実行するためにクラスターにアクセスする必要はありません。チェックはオフラインで実行できます。
デフォルトでは、kubevalは最新の未公開のKubernetesAPIパターンに基づいてリソースを検証します。
使用方法の詳細については、公式サイトをご覧ください。

スコアになる

kube-scoreは、提供されたYAMLリストを分析し、クラスターの組み込みチェックに対してスコアを付けます。
kube-scoreはオンラインバージョンオフラインバージョンを提供します
怠惰な場合は、オンラインバージョンを使用して
ください最初にhttps://kube-score.com/を開き、入力ボックスに書き込まれたYAMLリストを貼り付けます。ここで、上記のテキストbase.yamlが分析します。

KubernetesYAMLのベストプラクティスと戦略
分析結果は以下のとおりです。

KubernetesYAMLのベストプラクティスと戦略

上記から、リソース制限、ミラーリングTAG、ポッドネットワーク戦略など、このファイルに与えられた提案を確認できます。悪くない、非常に便利なツール。

もちろん、kube-scoreはスケーラブルではなく、戦略を追加または調整することはできません。
組織のポリシーに準拠するカスタムチェックを作成する場合は、config-lint、copper、conftest、またはPolarisの4つのツールのいずれかを使用できます。

Config-lint

Config-lintは、YAML、JSON、Terraform、CSV、およびKubernetesマニフェストで記述された構成ファイルを検証するためのツールです。

Config-lintをインストールします

wget https://github.com/stelligent/config-lint/releases/download/v1.6.0/config-lint_Linux_x86_64.tar.gz
tar -zxf config-lint_Linux_x86_64.tar.gz
mv config-lint /usr/local/bin/

Config-lintは、Kubernetesマニフェストに対して組み込みのチェックを実行しません。検証を実行するには、独自のルールを作成する必要があります。
ルールは、ルールセットと呼ばれるYAMLファイルとして記述され、次の構造を持っています。

version: 1
description: Rules for Kubernetes spec files
type: Kubernetes
files:
  - "*.yaml"
rules:
   # list of rules

デプロイメント内のイメージが常に信頼できるリポジトリ(たとえば、kubeops.net / app:1.0)から抽出されているかどうかを確認するとします。
このようなチェックを実装するためのconfig-lintルールは次のとおりです。

- id: MY_DEPLOYMENT_IMAGE_TAG
  severity: FAILURE
  message: Deployment must use a valid image tag
  resource: Deployment
  assertions:
    - every:
        key: spec.template.spec.containers
        expressions:
          - key: image
            op: starts-with
            value: "kubeops.net/"

完全なルールセットは次のとおりです。

version: 1
description: Rules for Kubernetes spec files
type: Kubernetes
files:
  - "*.yaml"
rules:
  - id: DEPLOYMENT_IMAGE_REPOSITORY
    severity: FAILURE
    message: Deployment must use a valid image repository
    resource: Deployment
    assertions:
      - every:
          key: spec.template.spec.containers
          expressions:
            - key: image
              op: starts-with
              value: "kubeops.net/"

検査をテストする場合は、ルールセットをcheck_image_repo.yamlとして保存できます。
次に、config-lintを使用してチェックを実行します

[root@k8s-node001 Test]# config-lint -rules check_image_repo.yaml base.yaml
[
  {
    "AssertionMessage": "Every expression fails: And expression fails: image does not start with kubeops.net/",
    "Category": "",
    "CreatedAt": "2020-11-02T08:28:43Z",
    "Filename": "base.yaml",
    "LineNumber": 0,
    "ResourceID": "http-echo",
    "ResourceType": "Deployment",
    "RuleID": "DEPLOYMENT_IMAGE_REPOSITORY",
    "RuleMessage": "Deployment must use a valid image repository",
    "Status": "FAILURE"
  }
]

すべての式が失敗し、テストが失敗したことがわかります。
次に、画像のアドレスをに変更して、image: kubeops.net/http-echoもう一度確認します。

[root@k8s-node001 Test]# config-lint -rules check_image_repo.yaml base.yaml
[]

出力がエラーを報告しない場合、それは成功を意味します。

Config-lintは、YAMLDSLを使用してKubernetesYAMLリストのカスタムチェックを作成できる有望なフレームワークです。
しかし、より複雑なロジックと検査を表現したい場合はどうでしょうか。
YAMLにはこれに関する制限がありますか?
これらのチェックを実際のプログラミング言語で表現できるとしたらどうでしょうか。次に銅を見てください

Copper V2は、config-lintと同様に、カスタムチェックを使用してリストを検証するフレームワークです。
ただし、CopperはYAML定義チェックを使用しません。
代わりに、テストはJavaScriptで記述されており、Copperは、Kubernetesオブジェクトの読み取りとエラーの報告に役立ついくつかの基本的なヘルパーを含むライブラリを提供します。

銅をインストールする

https://github.com/cloud66-oss/copper/releases/download/2.0.1/linux_amd64_2.0.1
mv linux_amd64_2.0.1 copper
chmod + x copper
mv copper /usr/local/bin/

config-lintと同様に、Copperは組み込みのチェックを提供しません。
チェックをカスタマイズして、デプロイメントイメージタグが最新でないことを確認しましょう。
check_image_repo.js

$$.forEach(function($){
    if ($.kind === 'Deployment') {
        $.spec.template.spec.containers.forEach(function(container) {
            var image = new DockerImage(container.image);
            if (image.tag === 'latest') {
                errors.add_error('no_latest',"latest is used in " + $.metadata.name, 1)
            }
        });
    }
});

検査を行う

[root@k8s-node001 Test]# copper validate --in=base.yaml --validator=check_image_tag.js
Check no_latest failed with severity 1 due to latest is used in http-echo
Validation failed

今修正されたimage: kubeops.net/http-echo:v1.0.0

[root@k8s-node001 Test]# copper validate --in=base.yaml --validator=check_image_tag.js
Validation successful

その他の使用法については、を参照してください。

コンテスト

Conftestは、Kubernetesインベントリをチェックおよび検証するために使用できる構成データのテストフレームワークです。
テストは、専用のクエリ言語Regoを使用して記述されています。

Conftestをインストールする

wget https://github.com/open-policy-agent/conftest/releases/download/v0.21.0/conftest_0.21.0_Linux_x86_64.tar.gz
tar -xzf conftest_0.21.0_Linux_x86_64.tar.gz
mv conftest /usr/local/bin

config-lintやcopperと同様に、conftestには組み込みのチェックがありません。

まず、新しいディレクトリconftest-checksと、次の内容のcheck_image_registry.regoという名前のファイルを作成します。

package main

deny[msg] {

  input.kind == "Deployment"
  image := input.spec.template.spec.containers[_].image
  not startswith(image, "kubeops.net/")
  msg := sprintf("image '%v' doesn't come from kubeops.net repository", [image])
}

最初にbase.yamlを変更し、conftestをimage: docker.io/http-echo
使用して検出を実行します

[root@k8s-node001 Test]# conftest test --policy ./conftest-checks base.yaml 
FAIL - base.yaml - image 'docker.io/http-echo:v1.0.0' doesn't come from kubeops.net repository

2 tests, 1 passed, 0 warnings, 1 failure, 0 exceptions

もう一度base.yamlに変更します。image: kubeops.net/http-echo

[root@k8s-node001 Test]# conftest test --policy ./conftest-checks base.yaml 

2 tests, 2 passed, 0 warnings, 0 failures, 0 exceptions

その他の使用法については、を参照してください。

ポラリス

最後のツールはPolarisです。Polarisはクラスター内にインストールするか、Kubernetesリストを静的に分析するためのコマンドラインツールとして使用できます。
コマンドラインツールとして実行すると、kube-scoreと同様に、セキュリティやベストプラクティスなどの側面をカバーする複数の組み込みチェックが含まれます。
さらに、これを使用して、config-lint、copper、conftestと同様のカスタムチェックを作成できます。
言い換えると、Polarisは、組み込みチェッカーとカスタムチェッカーの2つのカテゴリの利点を兼ね備えています。

Polarisをインストールします。ここではコマンドラインモードのみをインストールします

wget https://github.com/FairwindsOps/polaris/releases/download/1.2.1/polaris_1.2.1_linux_amd64.tar.gz
tar -zxf polaris_1.2.1_linux_amd64.tar.gz
 mv polaris /usr/local/bin/

インストールが完了したら、Polarisを使用してbase.yaml
[root @ k8s-node001テスト]を確認
できます。分析の結果を見てください。

  "PolarisOutputVersion": "1.0",
  "AuditTime": "0001-01-01T00:00:00Z",
  "SourceType": "Path",
  "SourceName": "base.yaml",
  "DisplayName": "base.yaml",
  "ClusterInfo": {
    "Version": "unknown",
    "Nodes": 0,
    "Pods": 1,
    "Namespaces": 0,
    "Controllers": 1
  },
  "Results": [
    {
      "Name": "http-echo",
      "Namespace": "",
      "Kind": "Deployment",
      "Results": {},
      "PodResult": {
        "Name": "",
        "Results": {
          "hostIPCSet": {
            "ID": "hostIPCSet",
            "Message": "Host IPC is not configured",
            "Success": true,
            "Severity": "danger",
            "Category": "Security"
..............
              "tagNotSpecified": {
                "ID": "tagNotSpecified",
                "Message": "Image tag is specified",
                "Success": true,
                "Severity": "danger",
                "Category": "Images"
              }
            }
          }
        ]
      },
      "CreatedTime": "0001-01-01T00:00:00Z"
    }
  ]
}

また、スコアのみ出力できます

[root@k8s-node001 Test]# polaris audit --audit-path base.yaml --format score
66

次のYAMLコードスニペットは、checkImageRepoと呼ばれる新しいチェックを定義します
。config_with_custom_check.yaml

checks:
  checkImageRepo: danger

customChecks:
  checkImageRepo:
    successMessage: Image registry is valid
    failureMessage: Image registry is not valid
    category: Images
    target: Container
    schema:
      '$schema': http://json-schema.org/draft-07/schema
      type: object
      properties:
        image:
          type: string
          pattern: ^kubeops.net/.+$

base.yamlのイメージは次のとおりです。image: docker.io/http-echo:v1.0.0
カスタムルールを使用してチェックを実行しましょう

[root@k8s-node001 Test]# polaris audit --config config_with_custom_check.yaml --audit-path base.yaml
{
  "PolarisOutputVersion": "1.0",
  "AuditTime": "0001-01-01T00:00:00Z",
  "SourceType": "Path",
  "SourceName": "base.yaml",
  "DisplayName": "base.yaml",
  "ClusterInfo": {
    "Version": "unknown",
    "Nodes": 0,
    "Pods": 1,
    "Namespaces": 0,
    "Controllers": 1
  },
  "Results": [
    {
      "Name": "http-echo",
      "Namespace": "",
      "Kind": "Deployment",
      "Results": {},
      "PodResult": {
        "Name": "",
        "Results": {},
        "ContainerResults": [
          {
            "Name": "http-echo",
            "Results": {
              "checkImageRepo": {
                "ID": "checkImageRepo",
                "Message": "Image registry is not valid",
                "Success": false,
                "Severity": "danger",
                "Category": "Images"
              }
            }
          }
        ]
      },
      "CreatedTime": "0001-01-01T00:00:00Z"
    }
  ]
}

結果は「メッセージ」を示しています:「画像レジストリが無効です」、「成功」:false、
次にbase.yamlの画像を次のように変更します:image: kubeops.net/http-echo:v1.0.0
チェックを再度実行します

[root@k8s-node001 Test]# polaris audit --config config_with_custom_check.yaml --audit-path base.yaml 
{
  "PolarisOutputVersion": "1.0",
  "AuditTime": "0001-01-01T00:00:00Z",
  "SourceType": "Path",
  "SourceName": "base.yaml",
  "DisplayName": "base.yaml",
  "ClusterInfo": {
    "Version": "unknown",
    "Nodes": 0,
    "Pods": 1,
    "Namespaces": 0,
    "Controllers": 1
  },
  "Results": [
    {
      "Name": "http-echo",
      "Namespace": "",
      "Kind": "Deployment",
      "Results": {},
      "PodResult": {
        "Name": "",
        "Results": {},
        "ContainerResults": [
          {
            "Name": "http-echo",
            "Results": {
              "checkImageRepo": {
                "ID": "checkImageRepo",
                "Message": "Image registry is valid",
                "Success": true,
                "Severity": "danger",
                "Category": "Images"
              }
            }
          }
        ]
      },
      "CreatedTime": "0001-01-01T00:00:00Z"
    }
  ]
}

出力から、「メッセージ」:「画像レジストリが有効です」、「成功」:trueが表示され、チェックに合格しました。
その他の使用法については、を参照してください。

総括する

Kubernetes YAMLファイルを検証、スコアリング、および整理するためのツールは多数ありますが、チェックを設計および実行するための健全なモデルを用意することが重要です。
たとえば、パイプラインを介してKubernetesマニフェストを検討する場合、オブジェクト定義がKubernetes APIパターンに準拠していることを確認できるため、kubevalがパイプラインの最初のステップになることがあります。このチェックが成功すると、標準のベストプラクティスやカスタム戦略など、より詳細なテストに進むことができます。
Kube-scoreとPolarisがより良い選択です。
複雑な要件があり、検査の詳細をカスタマイズしたい場合は、copper、config-lint、およびconftestの使用を検討する必要があります。
conftestとconfig-lintはどちらもカス​​タム検証ルールを定義するためにより多くのYAMLを使用しますが、Copperは真のプログラミング言語へのアクセスを許可するため、非常に魅力的です。
しかし、それらの1つを使用して、すべてのチェックを最初から作成する必要がありますか?または、Polarisを使用して、他のカスタムチェックを作成する必要がありますか?
それはすべてあなた次第であり、あなたに合ったものが最高です。

おすすめ

転載: blog.51cto.com/1648324/2546488