Kubenews #30
2021-09-10
Managing Kubernetes seccomp profiles with security profiles operator (click here to source)
seccompプロファイルの作成と管理は煩雑であり、エラーが発生しやすくなるのを緩和する目的で作成された。
セキュリティプロファイルオペレータの機能
- SeccompプロファイルCRD
- seccompプロファイルをポッドにバインドするためのCRD
- 実行中のポッドからseccompプロファイルを作成するためのCRD
- Seccompプロファイルの同期とノードサポートの検証
- メトリックス
- ログエンリッチャー
インストール
cert-managerをインストールする必要があります。
$ kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.4.2/cert-manager.yaml
次にservice profile operatorのインストール
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/security-profiles-operator/master/deploy/operator.yaml
seccomp profileの作成
以下のプロファイルは、SCMP_ACT_LOGのデフォルトアクションのみを設定します。
profile1.yaml
という名前でファイルを作成します。
apiVersion: security-profiles-operator.x-k8s.io/v1alpha1 kind: SeccompProfile metadata: namespace: default name: profile1 spec: defaultAction: SCMP_ACT_LOG
では、作成していきます。
$ kubectl apply -f profile1.yaml seccompprofile.security-profiles-operator.x-k8s.io/profile1 created $ kubectl get seccompprofile profile1 --output wide NAME STATUS AGE LOCALHOSTPROFILE profile1 Installed 7m21s operator/default/profile1.json
作成されたプロファイルは、
/var/lib/kubelet/seccomp/operator/<namespace>/<profile name>.json
に格納されます。
$ ssh k8s-pool1-18290975-vmss000000 sudo cat /var/lib/kubelet/seccomp/operator/default/profile1.json {"defaultAction":"SCMP_ACT_LOG"}
seccomp profileの利用
作成したprofileをPodに適用してきます。
apiVersion: v1 kind: Pod metadata: name: nginx spec: securityContext: seccompProfile: type: Localhost localhostProfile: operator/default/profile1.json containers: - name: nginx image: nginx
プロファイルの継承
1つのprofileをベースとして使用して新しいカスタムプロファイルを作成することもできます。
apiVersion: security-profiles-operator.x-k8s.io/v1alpha1 kind: SeccompProfile metadata: namespace: default name: inheritance-profile1 spec: defaultAction: SCMP_ACT_ERRNO baseProfileName: base-profile1 syscalls: - action: SCMP_ACT_ALLOW names: - mkdir
profile bindings
PodのSpecを直接いじりたくない場合に、ProfileBinding
が有用である。
今回は、nginx:1.21.1
のimageを使用するPodに対して、最初に作成した profile1
を適用させる例を紹介します。
apiVersion: security-profiles-operator.x-k8s.io/v1alpha1 kind: ProfileBinding metadata: name: nginx-binding spec: profileRef: kind: SeccompProfile name: profile1 image: nginx:1.21.1
適用します。
$ kubectl apply -f nginx-binding.yaml profilebinding.security-profiles-operator.x-k8s.io/nginx-binding created
以下のprofileを指定していないPodを作成すると挙動が確認できます。
$ cat <<EOF kubectl create -f - apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx:1.21.1 EOF pod/nginx created $ kubectl get pod nginx -o jsonpath='{.spec.containers[*].securityContext.seccompProfile}' {"localhostProfile":"operator/default/profile1.json","type":"Localhost"}
profileの記録
以下のmanifestを適用した場合、app: nginx
というラベルを持ったPodが作成された際に記録が開始されます。
そして、そのポッドが削除されると、seccompプロファイルリソース(ポッドごと)が作成され、使用できるようになります。
apiVersion: security-profiles-operator.x-k8s.io/v1alpha1 kind: ProfileRecording metadata: name: recording spec: kind: SeccompProfile recorder: hook podSelector: matchLabels: app: nginx
Shipwright - Building Container Images In Kubernetes (click here to source)
Shipwrightとという、Kubernetes上でコンテナイメージを作成するツールが紹介されています。
リソースとしては、
- BuildStrategy or ClusterBuildStrategy
- Build
- BuildRun
BuildStrategy or ClusterBuildStrategy
BuildのManifestで指定する、コンテナイメージをビルドする際に使用するツールについてです。
現在は、以下の選択肢があるみたいです。
- Available ClusterBuildStrategies
Name | Supported platforms |
---|---|
buildah | linux/amd64 only |
BuildKit | all |
buildpacks-v3-heroku | linux/amd64 only |
buildpacks-v3 | linux/amd64 only |
kaniko | all |
ko | all |
source-to-image | linux/amd64 only |
- Available BuildStrategies
Name | Supported platforms |
---|---|
buildpacks-v3-heroku | linux/amd64 only |
buildpacks-v3 | linux/amd64 only |
Build
ここで、実際にどうビルドするのかを定義します。
spec.source.url
: アプリケーションのソースコードのあるレポジトリを指定spec.strategy
: ビルドツールを指定spec.output
: 作成したimageをプッシュするregistryを指定output.credentials.name
: registryにアクセスする際に使用する既存のsecretを指定
apiVersion: shipwright.io/v1alpha1 kind: Build metadata: name: s2i-nodejs-build spec: source: url: https://github.com/shipwright-io/sample-nodejs strategy: name: kaniko kind: ClusterBuildStrategy output: image: us.icr.io/source-to-image-build/nodejs-ex credentials: name: icr-knbuild
例えば、
- レポジトリのrootディレクトリにソースコードがない場合は、
spec.source.contextDir
にて指定 - 独自のビルドツールを積んでいるimageを使う場合、
spec.strategy.name
をsource-to-image
にし、spec.builder.image
にてそのimageを指定する
など、柔軟性がありそう。
apiVersion: shipwright.io/v1alpha1 kind: Build metadata: name: s2i-nodejs-build spec: source: url: https://github.com/shipwright-io/sample-nodejs contextDir: source-build/ strategy: name: source-to-image kind: ClusterBuildStrategy builder: image: docker.io/centos/nodejs-10-centos7 output: image: us.icr.io/source-to-image-build/nodejs-ex credentials: name: icr-knbuild
BuildRun
Kubernetes上でBuildを実行するリソース。
apiVersion: shipwright.io/v1alpha1 kind: BuildRun metadata: name: buildpack-nodejs-buildrun-namespaced spec: buildRef: name: s2i-nodejs-build serviceAccount: name: pipeline
Buildで定義したプッシュ先を上書きしたい場合、このリソースでも定義ができる。
apiVersion: shipwright.io/v1alpha1 kind: BuildRun metadata: name: buildpack-nodejs-buildrun-namespaced spec: buildRef: name: s2i-nodejs-build serviceAccount: name: pipeline output: image: us.icr.io/source-to-image-build/nodejs-ex credentials: name: icr-knbuild
Distributed tracing with Knative, OpenTelemetry and Jaeger (click here to source)
Knative、OpenTelemetry、Jaegerを使った分散トレーシングについて書かれています。
Setup
既にKnative Serving and Eventingがデプロイされてていることを前提としています。
まず、クラスターにOpenTelemetryオペレーターを追加します。 こちらは、cert-managerに依存しているため、そちらもデプロイします。
$ kubectl apply -f https://github.com/jetstack/cert-manager/releases/latest/download/cert-manager.yaml $ kubectl apply -f https://github.com/open-telemetry/opentelemetry-operator/releases/latest/download/opentelemetry-operator.yaml
次に、イェーガーオペレーターをデプロイします。
$ kubectl create namespace observability $ kubectl create -n observability \ -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/crds/jaegertracing.io_jaegers_crd.yaml \ -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/service_account.yaml \ -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/role.yaml \ -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/role_binding.yaml \ -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/operator.yaml
起動したら、次のコマンドを実行してJaegerインスタンスを作成できます。
$ kubectl apply -n observability -f - <<EOF apiVersion: jaegertracing.io/v1 kind: Jaeger metadata: name: simplest EOF
次に、OpenTelemetryコレクターを作成します。
$ kubectl apply -f - <<EOF apiVersion: opentelemetry.io/v1alpha1 kind: OpenTelemetryCollector metadata: name: otel namespace: observability spec: config: | receivers: zipkin: exporters: logging: jaeger: endpoint: "simplest-collector.observability:14250" insecure: true service: pipelines: traces: receivers: [zipkin] processors: [] exporters: [logging, jaeger] EOF
最後に、すべてのトレースがコレクターを指すようにEventing andServingを構成します。
$ for ns in knative-eventing knative-serving; do kubectl patch --namespace "$ns" configmap/config-tracing \ --type merge \ --patch '{"data":{"backend":"zipkin","zipkin-endpoint":"http://otel-collector.observability:9411/api/v2/spans", "debug": "true"}}' done
Hello World
トレースインフラストラクチャがすべてデプロイおよび構成されたので、ハートビートイメージ をContainerSourceとして デプロイして、 すべてが正しく接続されていることをテストおよび確認できます。
$ kubectl apply -f - <<EOF apiVersion: sources.knative.dev/v1 kind: ContainerSource metadata: name: heartbeats spec: template: spec: containers: - image: gcr.io/knative-nightly/knative.dev/eventing/cmd/heartbeats:latest name: heartbeats args: - --period=1 env: - name: POD_NAME value: "heartbeats" - name: POD_NAMESPACE value: "default" - name: K_CONFIG_TRACING value: '{"backend":"zipkin","debug":"true","sample-rate":"1","zipkin-endpoint":"http://otel-collector.observability:9411/api/v2/spans"}' sink: uri: http://dev.null EOF
今のところ、このコンテナは存在しないドメインhttp://dev.null
にハートビートを送信しているだけなので、このポッドのログを見ると、一連のDNS解決エラーが表示されますが、otel-collectorポッドのログを調べると、サービスからトレースを正常に受信していることがわかります。
ハートビートを受信するためにKnativeサービスを追加し、ハートビートサービスを更新します。
$ kubectl apply -f - <<EOF apiVersion: serving.knative.dev/v1 kind: Service metadata: name: event-display spec: template: spec: containers: - image: gcr.io/knative-nightly/knative.dev/eventing/cmd/event_display:latest env: - name: K_CONFIG_TRACING value: '{"backend":"zipkin","debug":"true","zipkin-endpoint":"http://otel-collector.observability:9411/api/v2/spans"}' EOF $ kubectl apply -f - <<EOF apiVersion: sources.knative.dev/v1 kind: ContainerSource metadata: name: heartbeats spec: template: spec: containers: - image: gcr.io/knative-nightly/knative.dev/eventing/cmd/heartbeats:latest name: heartbeats args: - --period=1 env: - name: POD_NAME value: "heartbeats" - name: POD_NAMESPACE value: "default" - name: K_CONFIG_TRACING value: '{"backend":"zipkin","debug":"true","zipkin-endpoint":"http://otel-collector.observability:9411/api/v2/spans"}' sink: ref: apiVersion: serving.knative.dev/v1 kind: Service name: event-display EOF
これらのサービスがデプロイされたら、Jaegerダッシュボードでもう一度確認することで、おもしろいとレースが表示されます。
Getting fancy
Hello Worldより複雑な構成を紹介してくれているので、記事を読んでみてください。
Kubenews #extra-001
2021-09-**
配信なし
monday.com’s Multi-Regional Architecture: A Deep Dive (click here to source)
マルチリージョンに移行することを決定するときは、パフォーマンス優先、復元力優先、プライバシー優先等の優先事項に対する設計間で作業が大きく異なるため、主な動機を理解する必要があります。
プラットフォームを複数の地域で実行するに至る3つの主な動機
パフォーマンス
- サーバーを顧客の近くで実行すると、待ち時間が短くなり、接続品質が向上し(特にモバイルで)、一般的にエンドユーザーのエクスペリエンスが向上します。
-
- 任意のリージョンにおいて任意の時点でユーザーにサービスを提供できる場合、複数のリージョンでシステムを同時に実行することは、システムの全体的なフォールトトレランスの向上、ダウンタイムの短縮につながる。
プライバシーとコンプライアンス
- 顧客が世界のどこにデータを保存するかを選択できるようにすることで、明確な競争上の優位性が生まれ、PIIや機密情報を処理するヘルスケア、銀行、企業などの厳しく規制された業界との連携への扉が開かれます。
2番目のリージョンを追加する際の課題
【課題1】 サブドメインは基本的にスラッグであるが、完全ではない。
ユニークなサブドメインを使えるものもあれば、すべての顧客が使用する共有サブドメインがも存在してしまう。
【課題2】ユーザーが誰であるかさえわからない場合がある。
ログインフローにおいて、匿名の訪問者がプラットフォームに到着し、電子メールとパスワードを入力して、最終的にアカウントにルーティングされる際に、すべてのユーザーが同じサブドメインにアクセスします。
この時、どのリージョンがログインフローを処理するのか。
【課題3】可能な限りベンダーに中立を保つ
アーキテクチャを単一のネットワークサービスプロバイダーにチェーンした場合、いざ大規模な停止が起こった際に、インフラストラクチャ全体を再構築せずに回復することが難しい。
【課題4】再現性
簡単に複製できる方法で新しいリージョンを構築したかった。
monday.comのマルチリージョンデザイン
設計の重要なポイントとして以下を上げている。
- 各リージョンの独立
- ユーザーは各リージョンに直接アクセス可能
- 認証はグローバル
- ベンダー中立性
そのほか、処理の流れの説明が書かれています。
マルチリージョンをサポートするためのアンバサダーの構成
前で説明したことを基に、マルチリージョンネットワーク、認証サービス、API構造を結び付ける構成について、深く掘り下げて説明がされています。
マルチリージョンでのアプリケーションの展開
次の3つのデプロイトポロジをサポートしているようです。
Regional
地域ごとに分けて展開されるアプリケーションは、独立したコンポーネントとしてあらゆるリージョンに展開されます。
各デプロイメントは、地域ごとに独立していて、データを共有せず、互いを認識しないようになっています。
Global
- グローバルなアプリケーションは米国で一度展開され、すべての地域から内部ネットワークを介してアクセスできるようになっている。
Replicated
- レプリケートされたアプリケーションはすべてのリージョンに独立してデプロイされますが、データベースに関しては単一のレプリケートされたものを共有し、それらの状態はすべてのリージョンで同じものになっている。
ロギングとモニタリング
Kubernetes Supply Chain Policy Management with Cosign and Kyverno (click here to source)
以前は、connaseiurというツールを紹介しました。
今回はみんな大好きkyverno!
Image Signing with Cosign
cosign (github)
Generate a keypair
$ cosign generate-key-pair Enter password for private key: Enter again: Private key written to cosign.key Public key written to cosign.pub
- Sign a container and store the signature in the registry
$ cosign sign -key cosign.key dlorenc/demo Enter password for private key: Pushing signature to: index.docker.io/dlorenc/demo:sha256-87ef60f558bad79beea6425a3b28989f01dd417164150ab3baab98dcbf04def8.sig
- Verify a container against a public key
$ cosign verify -key cosign.pub dlorenc/demo The following checks were performed on these signatures: - The cosign claims were validated - The signatures were verified against the specified public key {"Critical":{"Identity":{"docker-reference":""},"Image":{"Docker-manifest-digest":"sha256:87ef60f558bad79beea6425a3b28989f01dd417164150ab3baab98dcbf04def8"},"Type":"cosign container image signature"},"Optional":null}
Cosign Image Signature Verification with Kyverno
「ghcr.io/kyverno/」リポジトリの「test-verify-image」という名前で始まるのすべてのイメージを対象として、cosignの共通鍵で複合化できるのかを確認してくれる。
apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: check-image spec: validationFailureAction: enforce background: false rules: - name: check-image match: resources: kinds: - Pod verifyImages: - image: "ghcr.io/kyverno/test-verify-image:*" key: |- – ---BEGIN PUBLIC KEY----- MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8nXRh950IZbRj8Ra/N9sbqOPZrfM 5/KAQN0/KjHcorm/J5yctVd7iEcnessRQjU917hmKO6JWVGHpDguIyakZA== – ---END PUBLIC KEY--- –
署名されたimageを使ってdeployすると通ります。
kubectl create deployment signed \ --image=ghcr.io/kyverno/test-verify-image:signed
署名されてないimageを使った場合、kyvernoによって弾かれる。
kubectl create deployment unsigned \ --image=ghcr.io/kyverno/test-verify-image:unsigned error: failed to create deployment: admission webhook "mutate.kyverno.svc" denied the request: resource Deployment/default/unsigned was blocked due to the following policies verify-image: autogen-verify-image: 'image verification failed for ghcr.io/kyverno/test-verify-image:unsigned: signature not found'
別のキーペアにおける鍵で署名されたimageも通りません。
kubectl create deployment signed-other \ --image=ghcr.io/kyverno/test-verify-image:signed-by-someone-else error: failed to create deployment: admission webhook "mutate.kyverno.svc" denied the request: resource Deployment/default/signed-other was blocked due to the following policies verify-image: autogen-verify-image: 'image verification failed for ghcr.io/kyverno/test-verify-image:signed-by-someone-else: invalid signature'
Audit Logging in Clusters (click here to source)
Falcoを使用した監査ログの検索について書かれています。
監査ポリシー
監査ポリシーは、監査ログの構成を定義します。どのイベントが監査の対象に入るのかを制御します。
パラメータ「omitStages」を使用して、リクエストがログに記録されないようにする対象を定義できます。
監査ポリシーのYAMLファイル
apiVersion: audit.k8s.io/v1 # This is required. kind: Policy # Don't generate audit events for all requests in RequestReceived stage. omitStages: - "RequestReceived" rules: # Log pod changes at RequestResponse level - level: RequestResponse resources: - group: "" # Resource "pods" doesn't match requests to any subresource of pods, # which is consistent with the RBAC policy. resources: ["pods"] # Log "pods/log", "pods/status" at Metadata level - level: Metadata resources: - group: "" resources: ["pods/log", "pods/status"] # Don't log requests to a configmap called "controller-leader" - level: None resources: - group: "" resources: ["configmaps"] resourceNames: ["controller-leader"]
リクエストのステージ
リクエストをログに記録できる4つの段階は、次のように定義されています。
RequestReceived
- サーバーが応答の発行を開始する前の段階。
ResponseStarted
- リクエストのヘッダーの作成は完了したが、レスポンスの本文は送信されていない段階。
ResponseComplete
- リクエストに対するレスポンスボディが完了した段階。
Panic
- パニックが発生した段階。
イベントのレベル
None
- このルールに一致するイベントはログに記録されません。
Metadata
Request
RequestResponse
パラメータ「rules」は、監査ポリシーYAMLファイルで必要な唯一のパラメータです。
ここで、どのリクエストをどのレベルでログに記録するかを定義できます。
たとえば、先ほどの例の最初のruleは、Podのすべての変更がRequestResponseレベルでログに記録されることを示しています。
監査のバックエンド
監査ログを外部ストレージに書き込むことに関して、2つの方法があります。
ログバックエンド
- JSONlines形式を使用して、ログをファイルシステムに書き込みます
webhookバックエンド
- イベントを外部HTTPAPIに送信します
kubescape (click here to source)
Kubernetes Hardening Guidance by NSA and CISAに基づいて、Cluster内のリソースをチェックしてくれます。
$ kubescape scan framework nsa --exclude-namespaces kube-system,kube-public ARMO security scanner starting [progress] Downloading framework definitions [success] Downloaded framework [progress] Accessing Kubernetes objects W0831 18:12:29.875935 241 warnings.go:70] batch/v1beta1 CronJob is deprecated in v1.21+, unavailable in v1.25+; use batch/v1 CronJob [success] Accessed successfully to Kubernetes objects, let’s start!!! [progress] Scanning cluster ◑ [success] Done scanning cluster [control: Allow privilege escalation] passed 👍 Description: Attackers may gain access to a container and uplift its privilege to enable excessive capabilities. Summary - Passed:1 Failed:0 Total:1 ・・・ [control: Control plane hardening] passed 👍 Description: Kubernetes control plane API is running with non-secure port enabled which allows attackers to gain unprotected access to the cluster. Summary - Passed:1 Failed:0 Total:1 [control: Dangerous capabilities] passed 👍 Description: Giving dangerous and unnecessary capabilities for a container can increase the impact of a container compromise. Summary - Passed:1 Failed:0 Total:1 ・・・ [control: Privileged container] failed 😥 Description: Potential attackers may gain access to privileged containers and inherit access to the host resources. Therefore, it is not recommended to deploy privileged containers unless it is absolutely necessary. Namespace kube-image DaemonSet - builder Summary - Passed:0 Failed:1 Total:1 Remediation: Change the deployment and/or pod definition to unprivileged. The securityContext.privileged should be false. ・・・ +-------------------------------------------------+------------------+---------------+-----------+ | CONTROL NAME | FAILED RESOURCES | ALL RESOURCES | % SUCCESS | +-------------------------------------------------+------------------+---------------+-----------+ | Allow privilege escalation | 0 | 1 | 100% | | Allowed hostPath | 1 | 1 | 0% | | Anonymous requests | 0 | 0 | NaN | | Applications credentials in configuration files | 3 | 4 | 25% | | Automatic mapping of service account | 3 | 3 | 0% | | Cluster-admin binding | 4 | 122 | 96% | | Container hostPort | 1 | 1 | 0% | | Control plane hardening | 0 | 1 | 100% | | Dangerous capabilities | 0 | 1 | 100% | | Exec into container | 4 | 122 | 96% | | Exposed dashboard | 0 | 2 | 100% | | Host PID/IPC privileges | 1 | 1 | 0% | | Immutable container filesystem | 1 | 1 | 0% | | Ingress and Egress blocked | 1 | 1 | 0% | | Insecure capabilities | 0 | 1 | 100% | | Linux hardening | 1 | 1 | 0% | | Non-root containers | 0 | 1 | 100% | | Privileged container | 1 | 1 | 0% | | Resource policies | 1 | 1 | 0% | | hostNetwork access | 1 | 1 | 0% | +-------------------------------------------------+------------------+---------------+-----------+ | 20 | 23 | 267 | 91% | +-------------------------------------------------+------------------+---------------+-----------+
Writing a Kubernetes Validating Webhook using Python (click here to source)
Validating Webhookを実行するコンテナをPythonを用いて作成する方法について書かれています。
How to Secure Containers with Cosign and Distroless Images (click here to source)
Distroless Container Imagesとは何か。
Distroless Container Imagesは、「言語に焦点を合わせたDockerイメージからオペレーティングシステムを除いたもの」です。つまり、アプリケーションとそのランタイム依存関係のみが含まれ、他の通常のOSパッケージマネージャー、Linuxシェル、または標準のLinuxディストリビューションで通常期待されるようなプログラムは含まれません。
ディストロレスコンテナイメージと一緒にCosignが必要な理由
Cosignの必要性は、ディストロレスイメージを使用しても、タイポスクワッティング攻撃や悪意のあるイメージの受信などのセキュリティ上の脅威に直面する可能性があるためです。
Cosign検証を使用した、ディストロレスコンテナのベースイメージの検証。
こちらでは、実際にディストロレスコンテナイメージとcosignを使用したDemoを紹介してくれています。
Easy, Secure Kubernetes Authentication With Pinniped (click here to source)
Pinnipedについて、Demoを交えて説明してくれています。
Kubenews #29
2021-08-20
Encrypt your Kubernetes Secrets with Mozilla SOPS (click here to source)
Kubernetes Secretsは、base64で暗号化されていて、簡単に複合化できてしまう。 そのソリューションとして、Mozilla SOPSがある。
・特徴
以下のようなSolutionと連携が可能
この記事では、Azureに関しての例が書かれており、Azure Service Principal (SP) を使うことを推奨しています。
- Provision an Azure Service Principal (SP)
# create a service principal az ad sp create-for-rbac -n sp-sops-keyvault -o json # { # "appId": "00000000-0000-0000-000000000000", # "displayName": "http://sp-sops-keyvault", # "name": "http://sp-sops-keyvault", # "password": "00000000-0000-0000-000000000000", # "tenant": "<your_tenant_identifier> # } export AZURE_CLIENT_ID=<appId> export AZURE_CLIENT_SECRET=<password> export AZURE_TENANT_ID=<tenant>
- Provisioning an Azure Key Vault instance
# create a new Resource Group az group create -n rg-sops-sample -l germanywestcentral # create a Key Vault instance az keyvault create -n kv-sops-sample \ -g rg-sops-sample \ -l germanywestcentral # create an access policy for the SP az keyvault set-policy -n kv-sops-sample \ -g rg-sops-sample \ --spn $AZURE_CLIENT_ID \ --key-permissions encrypt decrypt
- Create a key in Azure Key Vault for encryption & decryption
# create an key for encryption / decryption az keyvault key create -n sops-sample-key \ --vault-name kv-sops-sample \ --ops encrypt decrypt \ --protection software # read and store key identifier export KEY_ID=$(az keyvault key show -n sops-sample-key \ --vault-name kv-sops-sample \ --query key.kid -o tsv)
- Install Mozilla SOPS
# download sops cli for macOS curl -O -L -C - https://github.com/mozilla/sops/releases/download/v3.7.1/sops-v3.7.1.darwin # move and rename the cli to /usr/bin sudo mv sops-v3.7.1.darwin /usr/bin/sops # make it executable sudo chmod +x /usr/bin/sops
- Encrypt Kubernetes Secrets
まず、Sercretを作成します。
# create the Kubernetes secret kubectl create secret generic demo \ --from-literal mysecret=secret_value \ -o yaml \ --dry-run=client > secret.encoded.yml # print the contents of secret.encoded.yml cat secret.encoded.yml # apiVersion: v1 # data: # mysecret: c2VjcmV0X3ZhbHVl # kind: Secret # metadata: # creationTimestamp: null # name: demo
sopsコマンドを用いて、暗号化します。
# encrypt secret.encoded.yml using SOPS sops --encrypt --encrypted-regex '^(data|stringData)$' \ --azure-kv $KEY_ID secret.encoded.yml > secret.encrypted.yml # print the contents of secret.encrypted.yml cat secret.encrypted.yml # apiVersion: v1 # data: # mysecret: ENC[AES256_GCM,data:gz/WAjWte3bCnNm6e+G4ow==,iv:VB4pAv833tDdD4n76h4CqEZNpGdwA3V1QGWp7PK/Jfc=,tag:CcUy3rti4XcWArmHANVS8Q==,type:str] # kind: Secret # metadata: # creationTimestamp: null # name: demo # sops: # kms: [] # gcp_kms: [] # azure_kv: # - vault_url: https://kv-sops-sample.vault.azure.net # name: sops-sample-key # version: ee44c0c0cc9e4620aa4f4c86c4942047 # created_at: "2021-08-02T20:55:40Z" # enc: EjszDACgiDP8rW3wzs-7fAmFzlAhCq0-R9YlA9cuPcq78EXEeNTC8OnlSdXQAGdGrgE9oylu1HKZa4RB9GxzzVDav8uNVPp67NPmC4-teeA5iRE4jqlp1An6sG6CpkZGcAmKWpfj_DEWecqrNGWSLTA2hI_HKwG5xNkFh9Myik6732W-XL65IFqgepcFrNIzeHetznO0j1iISNXqMeJjeCnZ6Qq0jcXUMIfQnXjAllKfjSukiT3A3GlWxP0j50Z328t-JHi5RowYHT-hC8FDOdR_U95sqnFd27RgEXmbDIU6IGvP3vmCiZJz4YQCPXaGhySvFY6qCEoCbCSC4RaoWw # hc_vault: [] # age: [] # lastmodified: "2021-08-02T20:55:41Z" # mac: ENC[AES256_GCM,data:AmKRnzoImfIzPa3JBcuxUKRrse5uZwJGukpLj1wxed3R7lsUN+QAV1+WkfNyeMoW5C3ek7j20Xpbvzi+MgP8zcQOwWSwA79Svgz3hKMn9eTRTfgU+4jYezIIHCwkv61MTN8RGW5AhOInYP8oRPW3zKD+SbBO/Jeu7SC+/oVn07I=,iv:S4Th+0quL84lhJtA/lugEv+iLc+WhWEYPSlXGWKhd/M=,tag:CUGg8+UM7gNSzfjJx1Ua1w==,type:str] # pgp: [] # encrypted_regex: ^(data|stringData)$ # version: 3.7.1 # delete encoded version of the secret rm secret.encoded.yml # add encrypted secret to source control and commit it git add secret.encrypted.yml git commit -m 'chore: add encrypted secret'
- Decrypt Kubernetes Secrets for deployment
sopsコマンドを用いて複合化ができます。
# decrypt and deploy the secret sops --decrypt secret.encrypted.yml | kubectl apply -f -
- Deploy an echo server to Kubernetes
いつものSecret同様、Pod等から参照が可能です。
apiVersion: v1 kind: Pod metadata: name: echo labels: app: echo spec: containers: - image: thorstenhans/env-via-http:0.0.1 name: main ports: - containerPort: 5000 protocol: TCP envFrom: - secretRef: name: demo optional: true resources: requests: cpu: 50m memory: 32Mi limits: cpu: 100m memory: 48Mi
Implementing traffic policies in Kubernetes (click here to source)
Kumaを使用したKubernetesのトラフィックポリシーの設計について
2つのバックエンドサービスは外部ネットワークから分離した状態で、ある1つのサービスからの通信を許可したい場合、以下のようなポリシーを適用できる。
cat <<EOF | kumactl apply -f - type: TrafficPermission name: api-to-backends mesh: default sources: - match: service: 'publicAPI' destinations: - match: service: 'backend1' - match: service: 'backend2' EOF
How to Run HAProxy with Docker (click here to source)
Dockerの実行によるパフォーマンスへの影響
Dockerを使用すると、ホストへのブリッジネットワークを作成することで、コンテナー内で実行されているサービスにアクセスできます。
よって、コンテナのローカルネットワークとホストのブリッジネットワーク間でネットワークアドレス変換(NAT)をするため、遅延が発生します。
前に引用した同じIBMの調査では、DockerのNATによって、クライアントからの100バイトの要求とアプリケーションからの200バイトの応答のレイテンシーが約35 µsから70 µsに倍増されたらしい。
非常に低いレイテンシが必要な場合は、Dockerのホストネットワーク機能の使用に切り替えることで、コンテナはホストと同じネットワークを共有できるため、NATの必要性がなくなります。
Dockerを実行する際のセキュリティに関する考慮事項
HAProxyは、80や443などの制限されたTCPポートにバインドする必要があるため、rootアクセスが必要です。
ただし、起動が完了すると、root権限が削除され、非特権ユーザーとして実行されます。
DockerでHAProxyを実行する
3つのアプリケーションを動かします。
$ sudo docker network create --driver=bridge mynetwork $ sudo docker run -d \ --name web1 --net mynetwork jmalloc/echo-server:latest $ sudo docker run -d \ --name web2 --net mynetwork jmalloc/echo-server:latest $ sudo docker run -d \ --name web3 --net mynetwork jmalloc/echo-server:latest $ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 98216bb8c5ff jmalloc/echo-server:latest "/bin/echo-server" About a minute ago Up About a minute 8080/tcp web3 ae6accc111d9 jmalloc/echo-server:latest "/bin/echo-server" About a minute ago Up About a minute 8080/tcp web2 554fafbc2b3b jmalloc/echo-server:latest "/bin/echo-server" About a minute ago Up About a minute 8080/tcp web1
HAProxyロードバランサーを介してこれらのコンテナーにトラフィックを中継できるよう、現在のディレクトリにhaproxy.cfgという名前のファイルを作成し、それに以下を追加します。
global stats socket /var/run/api.sock user haproxy group haproxy mode 660 level admin expose-fd listeners log stdout format raw local0 info defaults mode http timeout client 10s timeout connect 5s timeout server 10s timeout http-request 10s log global frontend stats bind *:8404 stats enable stats uri / stats refresh 10s frontend myfrontend bind :80 default_backend webservers backend webservers server s1 web1:8080 check server s2 web2:8080 check server s3 web3:8080 check
最初のフロントエンドはポート8404でリッスンし、HAProxy Statsダッシュボードを有効にします。このダッシュボードには、ロードバランサーに関するライブ統計が表示されます。
もう一方のフロントエンドはポート80でリッスンし、Webサーバーのバックエンドにリストされている3つのWebアプリケーションの1つに要求をディスパッチします。
以下のコマンドで、HAProxyを作成します。
$ sudo docker run -d \ --name haproxy \ --net mynetwork \ -v $(pwd):/usr/local/etc/haproxy:ro \ -p 80:80 \ -p 8404:8404 \ haproxytech/haproxy-alpine:2.4
Kubernetes CI/CD with Tekton and ArgoCD (click here to source)
TektonとArgoCDを使用してKubernetesでCI / CDプロセスを構成する方法が書かれています。
AWS App MeshとIstioの比較 (click here to source)
AWSが提供するサービスメッシュのマネージドサービスであるApp MeshとIstioの比較について書かれています。
比較項目としてはいかがあります。
OPA GatekeeperによるKubernetesセキュリティの歩き方 (click here to source)
以下のような、運用をしていく中でこういったことに注意したなどの事例を基に説明されている。
ConstraintとConstraintTemplateを何も考えずにクラスタに適用してしまうと、意図していないリソースまでも影響を受ける可能性があります。 enforcementAction: dryrunを使用し、一定期間様子を見ながら適用することをおすすめします
入門 Rancher Desktop
Rancher Desktopとは
Rancher Desktopとは、インストールして起動するだけで、Windows 10やmacOS上に簡単にKubernetes環境を展開することができるオープンソースのアプリケーションです。
Control Planeにk3s, CRIにcontainerdを用いたClusterを、
上に展開します。
Installation
では、さっそくインストールをしていきたいと思います。
踏むのは何と1stepだけです! 以下のlink先からアプリケーションをダウンロードして起動してください。
今回、windowsを使って確認をしていきます。
起動
起動をすると、以下のようにアプリケーションが動きます。
「Kubernetes Settings」というtabを押していただき、以下のようにゲージが止まり「Reset Kubernetes」が押せる状態になると、Kubernetes Clusterの展開が完了しています。
Mac版では、リソースの指定もできます。
使い方
Kubernetes Clusterの立ち上げが完了すると、WindowsではUserディレクトリの直下にconfigファイルが生成されています。
では、Nodeの情報を見ていきます。
$ kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME w10dyh79c3 Ready builder,master 17m v1.19.10+k3s1 <Internal IP> <none> Unknown 5.4.72-microsoft-standard-WSL2 containerd://1.4.4-k3s1
初期で動いているNamespace、及びPodは以下のようになっています。
$ kubectl get ns NAME STATUS AGE default Active 18m kube-system Active 18m kube-public Active 18m kube-node-lease Active 18m kube-image Active 18m $ kubectl get pods -A NAMESPACE NAME READY STATUS RESTARTS AGE kube-system coredns-66c464876b-zt485 1/1 Running 0 18m kube-system local-path-provisioner-7ff9579c6-dzvg2 1/1 Running 0 18m kube-system metrics-server-7b4f8b595-lmsh2 1/1 Running 0 18m kube-system helm-install-traefik-zzbcw 0/1 Completed 0 18m kube-system svclb-traefik-wcg8k 2/2 Running 0 17m kube-system traefik-5dd496474-sbb4b 1/1 Running 0 17m kube-image builder-xzrlf 2/2 Running 0 17m
StorageClassに関しても、以下のように作成されます。
$ kubectl get sc NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 18m
以下のようなmanifestを適用してみます。
$ cat pvc.yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: demo-pvc namespace: default spec: storageClassName: local-path accessModes: - ReadWriteOnce volumeMode: Filesystem resources: requests: storage: 5Gi
この時点では、StorageClassのvolumeBindingModeが WaitForFirstConsumer
であるため、
PodからPVCを指定されるまで、容量の確保がされないようになっています。
$ kubectl apply -f pvc.yaml persistentvolumeclaim/demo-pvc created $ kubectl get pvc -n default NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE demo-pvc Pending local-path 61s
では、このpvcを使うPodを立ち上げてみます。
apiVersion: v1 kind: Pod metadata: name: mypod spec: containers: - name: myfrontend image: nginx volumeMounts: - mountPath: "/var/www/html" name: mypd volumes: - name: mypd persistentVolumeClaim: claimName:
nginxが問題なく動きました。
$ kubectl apply -f nginx.yaml pod/demo-pod created $ kubectl get pods NAME READY STATUS RESTARTS AGE demo-pod 1/1 Running 0 4m22s $ kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE demo-pvc Bound pvc-1222f2ff-7afd-4254-b352-640c906b5804 5Gi RWO local-path 8m28s
Appendix
k3sのバイナリは以下に配置されています。
# /mnt/c/Users/uwatsr/AppData/Local/xdg.cache/rancher-desktop/k3s /v1.19.10+k3s1/k3s -h NAME: k3s - Kubernetes, but small and simple USAGE: k3s [global options] command [command options] [arguments...] VERSION: v1.19.10+k3s1 (72e8196c) COMMANDS: server Run management server agent Run node agent kubectl Run kubectl crictl Run crictl ctr Run ctr check-config Run config check etcd-snapshot Trigger an immediate etcd snapshot help, h Shows a list of commands or help for one command GLOBAL OPTIONS: --debug (logging) Turn on debug logs [$K3S_DEBUG] --help, -h show help --version, -v print the version
Kubenews #27
2021-08-06
各タイトルを押していただくことで、実際の記事に飛びます。
Prometheus HA with Thanos Sidecar Or Receiver?
- Thanosは、次の2つの方法でPrometheusとの統合をサポートしています。
- サイドカー
- レシーバー
- Thanos Stackは以下のコンポーネントを持ちます。
- Querier
- Store
- Compactor
- Ruler
Thanos Sidecar
- 複数のプロメテウスサーバーポッドでサイドカーとして実行されます。
- このコンポーネントは、(Prometheus TSDBからの)オブジェクトストレージへのデータ配信を担当します。
- Sidecarは、Prometheusのremote read APIの上にThanosのStore APIを実装し、ThanosQuerierという名前の集中コンポーネントからPrometheusサーバーの時系列データをクエリできるようにします。
- さらに、サイドカーは、TSDBブロックを2時間間隔でオブジェクトストレージにアップロードするように構成することもできます。 この場合、バケットに保存されているデータは、Thanos Storeコンポーネントを使用してクエリできます。これは、同じStore APIを実装しており、ThanosQuerierが検出する必要があります。
Thanos Receiver
サイドカーとレシーバーの比較
- 高可用性
- プロメテウスとの統合
- ストレージ
- サイドカー
- SidecarはPrometheusのローカルストレージから読み取るため、TSDBに追加のローカルストレージ(PV)は必要ありません。
- レシーバー
- StatefulSetであるReceiverは、PVでプロビジョニングする必要があります。
- ここで必要なローカルストレージの量は、--receive.replication-factor、--tsdb.retentionというフラグに依存しています。
- このセットアップには、Sidecarと比較してより多くのローカルストレージが必要です。
- サイドカー
- データ収集
What Is Workload Security? On-Premises, Cloud, Kubernetes, and More
Announcing Vitess Arewefastyet
- Vitess arewefastyet
Scheduled-Scaling with Kubernetes HPA External Metrics
- HPA + Datadogの連携について
Verify Container Image Signatures in Kubernetes using Notary or Cosign or both
-
- コンテナイメージの署名検証とtrust pinningをKubernetesクラスタに統合するためのアドミッションコントローラ
- Connaisseurは展開前のイメージ署名の確認することを目指しています。
- Mutating アドミッションコントローラーとして実装され、Kubernetesクラスターに送信されたリソースの作成または更新リクエストをインターセプトし、すべてのコンテナーイメージを識別たうえで、事前構成された公開鍵に対してそれらの署名を検証します。 その結果に基づいて、それらの要求を受け入れるか拒否します。
demo
レポジトリをクローンしてきます。
% git clone https://github.com/sse-secure-systems/connaisseur.git Cloning into 'connaisseur'... remote: Enumerating objects: 3682, done. remote: Counting objects: 100% (764/764), done. remote: Compressing objects: 100% (285/285), done. remote: Total 3682 (delta 613), reused 478 (delta 478), pack-reused 2918 Receiving objects: 100% (3682/3682), 10.01 MiB | 3.98 MiB/s, done. Resolving deltas: 100% (2198/2198), done. % cd connaisseur
Connaisseurをデプロイします。
% helm install connaisseur helm --atomic --create-namespace --namespace connaisseur NAME: connaisseur LAST DEPLOYED: Wed Aug 4 11:45:35 2021 NAMESPACE: connaisseur STATUS: deployed REVISION: 1 TEST SUITE: None % kubectl get pods -n connaisseur NAME READY STATUS RESTARTS AGE connaisseur-deployment-7d6bd95d48-bmjxw 1/1 Running 0 93s connaisseur-deployment-7d6bd95d48-ghbkf 1/1 Running 0 94s connaisseur-deployment-7d6bd95d48-m9zjh 1/1 Running 0 93s
Official Docker imagesを使ってPodを作成します。
% kubectl run hello-world --image=docker.io/hello-world pod/hello-world created
作成されたこと確認できました。
では、署名されていないimageはどうでしょう。
% kubectl run demo --image=docker.io/securesystemsengineering/testimage:unsigned Error from server: admission webhook "connaisseur-svc.connaisseur.svc" denied the request: Unable to find signed digest for image docker.io/securesystemsengineering/testimage:unsigned.
しっかり弾かれることがわかりました。
Bad Pods
- こんなものがあったので紹介です。
Kubenews #26
2021-07-09
配信URL
各タイトルを押していただくことで、実際の記事に飛びます。
Kubernetes Essential Tools: 2021
Kubernetesを使っていく上で、様々なケースに対応するためのツールを紹介してくれています。
Run the HAProxy Kubernetes Ingress Controller Outside of Your Kubernetes Cluster
(要約)
Podへ外部から到達する際に、NodePortもしくはLoad BalancerのServiceを公開する必要があり、クラウド環境では、LoadBalancerオプションは各クラウドプロバイダーが用意しているロードバランサーがありそれを利用できるが、オンプレミス環境では、通常 NodePortを使用し、ロードバランサーを手作業で前面に配置する必要があります。
従来のレイアウトでは、外部ロードバランサーがワーカーノードの 1 つにトラフィックを送信し、次に Kubernetes がIngressコントローラーポッドを実行しているノードにトラフィックを中継します。
HAProxy Kubernetes Ingressコントローラのバージョン 1.5 以降では、Kubernetes クラスターの外部で実行するオプションがあり、前にロードバランサーを追加する必要がなくなります。
注意すべき点として、IngressコントローラがPodとして実行されておらず、Kubernetes クラスタ内に存在しない場合、Pod レベルのネットワークに何らかの方法でアクセスする必要があります。
Project Calicoを Kubernetes のネットワーク プラグインとしてインストールし、次に Calico が BGP ピアリングを介してIngressコントローラ サーバーとネットワーク ルートを共有できるようにすることで、この問題を解決することができます。
Handling Auth in EKS Clusters: Setting Up Kubernetes User Access Using AWS IAM
EKSクラスターでの認証の処理について
kubenews #25
2021-07-02
配信URL
各タイトルを押していただくことで、実際の記事に飛びます。
Monitoring Kyverno with Prometheus
ついに、keyvernoがmonitoringされている例がでました。 keyvernoがに関しては、以下を参照ください。
cAdvisor and Kubernetes Monitoring Guide
Since cAdvisor is already integrated with the kubelet binary, ~~
とあり、kubeletに統合されています。
この記事では、cpu, memory, diskなどの項目に関するmetric名やGrafanaから確認する方法についてが書かれているので、とても参考になる資料となっています。
Avoiding Kubernetes Cluster Outages with Synthetic Monitoring
- Kuberhealthy
- khcheck / khjob(Kuberhealthy check / Kuberhealthy job)と呼ばれるカスタムリソースによって作成されたテストコンテナーを用いる
- khjobが1回実行されるのに対し、khcheckは定期的に実行されることを除いて、両方のカスタムリソースの機能はほぼ同じ
- Kuberhealthy合成チェックのユースケース
demo
kuberhealthyをデプロイしていきます。
% kubectl create namespace kuberhealthy % helm repo add kuberhealthy https://kuberhealthy.github.io/kuberhealthy/helm-repos "kuberhealthy" has been added to your repositories % helm install kuberhealthy kuberhealthy/kuberhealthy NAME: kuberhealthy LAST DEPLOYED: Fri Jul 2 22:06:02 2021 NAMESPACE: kuberhealthy STATUS: deployed REVISION: 1 TEST SUITE: None
デプロイされたか見ていきます。
% kubectl get pods -n kuberhealthy NAME READY STATUS RESTARTS AGE kuberhealthy-8575448769-r8npz 1/1 Running 0 3d19h kuberhealthy-8575448769-zslkx 1/1 Running 0 3d19h
なんかAgeがおかしい気もしますが、一旦進みます。
次に、サンプルのアプリを入れます。
% kubectl create deploy nginx --replicas 2 --image nginx:latest deployment.apps/nginx created % kubectl expose deployment nginx --type=NodePort --name=example-service --port 80 service/example-service exposed
では、アプリが見えるか確認していきます。
% curl 192.168.64.2:30795 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
今回、使うServiceは以下です。
% kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE example-service NodePort 10.105.7.80 <none> 80:30795/TCP 42m
では、以下のような2つのチェック用manifestを用意していきます。
今回、違いがわかるように、Service名ではなくIPで書いています。
- URLが正しいもの
% cat kuberhealthy.yaml apiVersion: comcast.github.io/v1 kind: KuberhealthyCheck metadata: name: nginx-reachable namespace: kuberhealthy spec: runInterval: 2m timeout: 2m podSpec: containers: - name: nginx-reachable-check image: kuberhealthy/http-check:v1.5.0 imagePullPolicy: IfNotPresent env: - name: CHECK_URL value: "http://10.105.7.80:80" - name: COUNT #### default: "0" value: "5" - name: SECONDS #### default: "0" value: "1" - name: PASSING_PERCENT #### default: "100" value: "100" - name: REQUEST_TYPE #### default: "GET" value: "GET" - name: EXPECTED_STATUS_CODE #### default: "200" value: "200" resources: requests: cpu: 15m memory: 15Mi limits: cpu: 25m restartPolicy: Always terminationGracePeriodSeconds: 5
- URLがおかしいもの
apiVersion: comcast.github.io/v1 kind: KuberhealthyCheck metadata: name: nginx-unreachable namespace: kuberhealthy spec: runInterval: 2m timeout: 2m podSpec: containers: - name: nginx-unreachable-check image: kuberhealthy/http-check:v1.5.0 imagePullPolicy: IfNotPresent env: - name: CHECK_URL value: "http://10.105.7.180:80" - name: COUNT #### default: "0" value: "5" - name: SECONDS #### default: "0" value: "1" - name: PASSING_PERCENT #### default: "100" value: "100" - name: REQUEST_TYPE #### default: "GET" value: "GET" - name: EXPECTED_STATUS_CODE #### default: "200" value: "200" resources: requests: cpu: 15m memory: 15Mi limits: cpu: 25m restartPolicy: Always terminationGracePeriodSeconds: 5
Applyすると以下のように確認ができます。
% kubectl get khcheck -n kuberhealthy NAME AGE nginx-reachable 20m nginx-unreachable 18m
以下のような形でPodは作成されています。
% kubectl get pod -n kuberhealthy NAME READY STATUS RESTARTS AGE kuberhealthy-8575448769-r8npz 1/1 Running 5 3d23h kuberhealthy-8575448769-zslkx 1/1 Running 0 3d23h nginx-reachable-1625242353 0/1 Completed 0 7m56s nginx-reachable-1625242473 0/1 Completed 0 5m56s nginx-reachable-1625242593 0/1 Completed 0 3m56s nginx-reachable-1625242713 0/1 Completed 0 116s nginx-unreachable-1625242725 1/1 Running 0 104s
では、実行結果を見ていきましょう。 以下のServiceに対してport-forwardしていきます。
% kubectl get svc -n kuberhealthy NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kuberhealthy ClusterIP 10.107.202.150 <none> 80/TCP 3d20h % kubectl port-forward svc/kuberhealthy 8080:80 -n kuberhealthy
では、アクセスしてみます。
localhost:8080
以下のように、チェック結果を確認することができます。
{ "OK": false, "Errors": [ "Check execution error: kuberhealthy/nginx-unreachable: timed out waiting for checker pod to report in" ], "CheckDetails": { "kuberhealthy/nginx-reachable": { "OK": true, "Errors": [], "RunDuration": "17.206972822s", "Namespace": "kuberhealthy", "LastRun": "2021-07-02T14:23:13.09344293Z", "AuthoritativePod": "kuberhealthy-8575448769-r8npz", "uuid": "7401e1f7-330a-467d-9ad3-d0ea5e8a799f" }, "kuberhealthy/nginx-unreachable": { "OK": false, "Errors": [ "Check execution error: kuberhealthy/nginx-unreachable: timed out waiting for checker pod to report in" ], "RunDuration": "", "Namespace": "kuberhealthy", "LastRun": "2021-07-02T14:22:46.962592884Z", "AuthoritativePod": "kuberhealthy-8575448769-r8npz", "uuid": "9adf2caa-0a1d-42bb-9f45-a83ad94aedfa" } }, "JobDetails": {}, "CurrentMaster": "kuberhealthy-8575448769-r8npz" }
What end-users want out of Prometheus remote storage: A comparison of M3 and Thanos
- prometheusのリモートストレージソリューションとして、以下が人気
- Thanos
- M3
- Cortex
- 以下の観点でThanosとM3を比較
- 信頼性と可用性
- Thanos
- クエリアによって取得されたデータに加えてルール(アラートルールやPrometheusレコーディングルールなど)を適用できるネイティブクエリサービスがある。
- Thanosの分散読み取りまたはクエリパスが原因で失敗率が高くなることがある。
- M3
- Thanos
- スケーラビリティとシンプルさ
- Thanos
- Thanosは、PrometheusのProxyの役割としてサイドカーで構成される。
- ???
- M3
- 分散時系列データベース(M3DB)、取り込みおよびダウンサンプリング層(M3コーディネーター)、およびクエリエンジン(M3クエリ)の3つのコアコンポーネントで構成されている。
- アーキテクチャ上、M3は簡単にスケールアップまたはスケールダウンできる。
- M3DBは1つのユニットとして水平方向にスケールできるが、クラスター内のM3DBノードの数のサイズを変更する際、M3DBはステートフルであり、ノードメンバーシップの変更時にピアにデータをストリーミングするため、大規模な管理が困難になる可能性がある。
- こちらは、Operatorによって自動的にスケールアップおよびスケールダウンできるようになっている。
- Thanos
- 効率とスピード
- Thanos
- M3
- すべてのダウンサンプリングおよびアグリゲーションはM3・コーディネーターによってローカルに行われる。
- この設定では、集計はリアルタイムで行われ、各解決間隔の終わりに、集計されたメトリックがすぐにクエリに使用できます(つまり、5分の解像度でデータを集計する場合は5分ごと)。
- M3コーディネーターサイドカーにダウンタイムがあると、集約されたデータが失われる可能性がある。
- アフォーダビリティ
- 信頼性と可用性