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より複雑な構成を紹介してくれているので、記事を読んでみてください。