From 58521d2cb043f8ad8bb86728e30c56829a33db6c Mon Sep 17 00:00:00 2001 From: zoetrope Date: Thu, 6 Jul 2023 16:34:15 +0900 Subject: [PATCH] Add helm chart --- .github/workflows/ci.yaml | 1 - .github/workflows/release.yaml | 56 ++++++++++++- .gitignore | 1 - .goreleaser.yml | 3 - Makefile | 5 -- charts/pod-security-admission/.helmignore | 23 ++++++ charts/pod-security-admission/Chart.yaml | 21 +++++ .../templates/_helpers.tpl | 62 +++++++++++++++ .../templates/controller-manager.yaml | 11 +++ .../templates/deployment.yaml | 76 ++++++++++++++++++ .../mutating-webhook-configuration.yaml | 79 +++++++++++++++++++ .../pod-security-admission-config.yaml | 9 +++ .../templates/selfsigned-issuer.yaml | 8 ++ .../templates/serving-cert.yaml | 16 ++++ .../validating-webhook-configuration.yaml | 77 ++++++++++++++++++ .../templates/webhook-service.yaml | 13 +++ charts/pod-security-admission/values.yaml | 32 ++++++++ config/manager/controller_manager_config.yaml | 11 --- config/manager/kustomization.yaml | 3 - docs/getting-started.md | 6 +- 20 files changed, 481 insertions(+), 32 deletions(-) create mode 100644 charts/pod-security-admission/.helmignore create mode 100644 charts/pod-security-admission/Chart.yaml create mode 100644 charts/pod-security-admission/templates/_helpers.tpl create mode 100644 charts/pod-security-admission/templates/controller-manager.yaml create mode 100644 charts/pod-security-admission/templates/deployment.yaml create mode 100644 charts/pod-security-admission/templates/mutating-webhook-configuration.yaml create mode 100644 charts/pod-security-admission/templates/pod-security-admission-config.yaml create mode 100644 charts/pod-security-admission/templates/selfsigned-issuer.yaml create mode 100644 charts/pod-security-admission/templates/serving-cert.yaml create mode 100644 charts/pod-security-admission/templates/validating-webhook-configuration.yaml create mode 100644 charts/pod-security-admission/templates/webhook-service.yaml create mode 100644 charts/pod-security-admission/values.yaml delete mode 100644 config/manager/controller_manager_config.yaml diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 79afca2..46beef4 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -36,7 +36,6 @@ jobs: - uses: ./.github/actions/aqua with: github_token: ${{ secrets.GITHUB_TOKEN }} - - run: make install.yaml - name: GoReleaser uses: goreleaser/goreleaser-action@f82d6c1c344bcacabba2c841718984797f664a6b # v4.2.0 with: diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 0228f6c..959f141 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -32,11 +32,10 @@ jobs: - uses: ./.github/actions/aqua with: github_token: ${{ secrets.GITHUB_TOKEN }} - - name: Set Tag + - name: Set previous release tag for GoReleaser run: | - TAG=${GITHUB_REF#refs/tags/v} - sed -i "s/newTag: .*/newTag: $TAG/g" config/manager/kustomization.yaml - make install.yaml + export TAG=$(curl -s "https://api.github.com/repos/cybozu-go/pod-security-admission/releases/latest" | jq -r .tag_name) + echo "GORELEASER_PREVIOUS_TAG=${TAG}" >> $GITHUB_ENV - name: GoReleaser uses: goreleaser/goreleaser-action@f82d6c1c344bcacabba2c841718984797f664a6b # v4.2.0 with: @@ -44,3 +43,52 @@ jobs: args: release --clean env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + chart-release: + runs-on: ubuntu-22.04 + needs: release + if: contains(needs.release.result, 'success') + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Install Helm + uses: azure/setup-helm@5119fcb9089d432beecbf79bb2c7915207344b78 # v3.5 + - name: Set chart version + run: | + helm repo add pod-security-admission https://cybozu-go.github.io/pod-security-admission + helm repo update + + # get the release tag version + tag_version=${GITHUB_REF##*/v} + + # get the latest chart version + chart_version=$(helm search repo pod-security-admission -o json | jq -r 'sort_by(.version) | .[-1].version') + chart_patch_version=${chart_version##*.} + new_patch_version=$(($chart_patch_version+1)) + + # if minor or major version changed, reset new patch version + local_version=$(cat charts/pod-security-admission/Chart.yaml | yq .version | sed "s/0-chart-patch-version-placeholder/$chart_patch_version/g") + [ "$local_version" != "$chart_version" ] && new_patch_version=0 + + # replace placeholder with new version + sed --in-place "s/app-version-placeholder/$tag_version/g" charts/pod-security-admission/Chart.yaml + sed --in-place "s/0-chart-patch-version-placeholder/$new_patch_version/g" charts/pod-security-admission/Chart.yaml + sed --in-place "s/app-version-placeholder/$tag_version/g" charts/pod-security-admission/values.yaml + - name: Create release notes + run: | + tag_version=${GITHUB_REF##*/} + cat < ./charts/pod-security-admission/RELEASE.md + Helm chart for pod-security-admission [$tag_version](https://github.com/cybozu-go/pod-security-admission/releases/tag/$tag_version) + + EOF + - name: Configure Git + run: | + git config user.name "$GITHUB_ACTOR" + git config user.email "$GITHUB_ACTOR@users.noreply.github.com" + - name: Run chart-releaser + uses: helm/chart-releaser-action@be16258da8010256c6e82849661221415f031968 # v1.5.0 + with: + config: cr.yaml + env: + CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.gitignore b/.gitignore index 850a69f..e4bcb02 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,3 @@ /.idea cover.out /build -install.yaml diff --git a/.goreleaser.yml b/.goreleaser.yml index 3921b23..72bbde5 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -11,9 +11,6 @@ builds: - amd64 ldflags: - -X github.com/cybozu-go/pod-security-admission.Version={{.Version}} -archives: - - files: - - install.yaml dockers: - image_templates: - "quay.io/cybozu/{{.ProjectName}}:{{ .Version }}-amd64" diff --git a/Makefile b/Makefile index dfcb96e..bddcc4c 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,6 @@ ENVTEST_K8S_VERSION = 1.27.1 SHELL = /bin/bash .SHELLFLAGS = -e -o pipefail -c BIN_DIR := $(shell pwd)/bin -INSTALL_YAML = install.yaml STATICCHECK = $(BIN_DIR)/staticcheck @@ -67,10 +66,6 @@ test: setup-envtest manifests generate ## Run tests. build: ## Build binary. CGO_ENABLED=0 go build -o bin/pod-security-admission -ldflags="-w -s" ./cmd -$(INSTALL_YAML): setup - mkdir -p build - kustomize build ./config/default > $@ - $(STATICCHECK): $(call go-install-tool,$(STATICCHECK),honnef.co/go/tools/cmd/staticcheck@latest) diff --git a/charts/pod-security-admission/.helmignore b/charts/pod-security-admission/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/charts/pod-security-admission/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/pod-security-admission/Chart.yaml b/charts/pod-security-admission/Chart.yaml new file mode 100644 index 0000000..47d6d02 --- /dev/null +++ b/charts/pod-security-admission/Chart.yaml @@ -0,0 +1,21 @@ +apiVersion: v2 +name: pod-security-admission +description: A Helm chart for Kubernetes +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0-chart-patch-version-placeholder +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: app-version-placeholder diff --git a/charts/pod-security-admission/templates/_helpers.tpl b/charts/pod-security-admission/templates/_helpers.tpl new file mode 100644 index 0000000..596337f --- /dev/null +++ b/charts/pod-security-admission/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "pod-security-admission.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "pod-security-admission.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "pod-security-admission.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "pod-security-admission.labels" -}} +helm.sh/chart: {{ include "pod-security-admission.chart" . }} +{{ include "pod-security-admission.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "pod-security-admission.selectorLabels" -}} +app.kubernetes.io/name: {{ include "pod-security-admission.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "pod-security-admission.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "pod-security-admission.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/charts/pod-security-admission/templates/controller-manager.yaml b/charts/pod-security-admission/templates/controller-manager.yaml new file mode 100644 index 0000000..e56bd13 --- /dev/null +++ b/charts/pod-security-admission/templates/controller-manager.yaml @@ -0,0 +1,11 @@ +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "pod-security-admission.fullname" . }}-controller-manager + labels: + {{- include "pod-security-admission.labels" . | nindent 4 }} +spec: + maxUnavailable: 1 + selector: + matchLabels: + control-plane: controller-manager \ No newline at end of file diff --git a/charts/pod-security-admission/templates/deployment.yaml b/charts/pod-security-admission/templates/deployment.yaml new file mode 100644 index 0000000..e8e4eae --- /dev/null +++ b/charts/pod-security-admission/templates/deployment.yaml @@ -0,0 +1,76 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "pod-security-admission.fullname" . }}-controller-manager + labels: + control-plane: controller-manager + {{- include "pod-security-admission.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.controllerManager.replicas }} + selector: + matchLabels: + control-plane: controller-manager + {{- include "pod-security-admission.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + control-plane: controller-manager + {{- include "pod-security-admission.selectorLabels" . | nindent 8 }} + spec: + containers: + - args: {{- toYaml .Values.controllerManager.manager.args | nindent 8 }} + command: + - /pod-security-admission + env: + - name: KUBERNETES_CLUSTER_DOMAIN + value: {{ quote .Values.kubernetesClusterDomain }} + image: {{ .Values.controllerManager.manager.image.repository }}:{{ .Values.controllerManager.manager.image.tag + | default .Chart.AppVersion }} + imagePullPolicy: {{ .Values.controllerManager.manager.imagePullPolicy }} + lifecycle: + preStop: + exec: + command: + - sleep + - "5" + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + name: manager + ports: + - containerPort: 8080 + name: metrics + - containerPort: 8081 + name: health + - containerPort: 9443 + name: webhook + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: {{- toYaml .Values.controllerManager.manager.resources | nindent 10 + }} + securityContext: {{- toYaml .Values.controllerManager.manager.containerSecurityContext + | nindent 10 }} + volumeMounts: + - mountPath: /certs + name: cert + readOnly: true + - mountPath: /etc/pod-security-admission + name: config + securityContext: + runAsNonRoot: true + terminationGracePeriodSeconds: 10 + volumes: + - name: cert + secret: + defaultMode: 420 + secretName: webhook-server-cert + - configMap: + name: {{ include "pod-security-admission.fullname" . }}-pod-security-admission-config + name: config \ No newline at end of file diff --git a/charts/pod-security-admission/templates/mutating-webhook-configuration.yaml b/charts/pod-security-admission/templates/mutating-webhook-configuration.yaml new file mode 100644 index 0000000..32437de --- /dev/null +++ b/charts/pod-security-admission/templates/mutating-webhook-configuration.yaml @@ -0,0 +1,79 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: {{ include "pod-security-admission.fullname" . }}-mutating-webhook-configuration + annotations: + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ include "pod-security-admission.fullname" . }}-serving-cert + labels: + {{- include "pod-security-admission.labels" . | nindent 4 }} +webhooks: +- admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: '{{ include "pod-security-admission.fullname" . }}-webhook-service' + namespace: '{{ .Release.Namespace }}' + path: /mutate-baseline + failurePolicy: Fail + name: baseline.mpod.kb.io + namespaceSelector: + matchExpressions: + - key: pod-security.cybozu.com/policy + operator: NotIn + values: + - privileged + reinvocationPolicy: IfNeeded + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + resources: + - pods + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - UPDATE + resources: + - pods/ephemeralcontainers + sideEffects: None +- admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: '{{ include "pod-security-admission.fullname" . }}-webhook-service' + namespace: '{{ .Release.Namespace }}' + path: /mutate-restricted + failurePolicy: Fail + name: restricted.mpod.kb.io + namespaceSelector: + matchExpressions: + - key: pod-security.cybozu.com/policy + operator: In + values: + - restricted + reinvocationPolicy: IfNeeded + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + resources: + - pods + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - UPDATE + resources: + - pods/ephemeralcontainers + sideEffects: None \ No newline at end of file diff --git a/charts/pod-security-admission/templates/pod-security-admission-config.yaml b/charts/pod-security-admission/templates/pod-security-admission-config.yaml new file mode 100644 index 0000000..f08fc36 --- /dev/null +++ b/charts/pod-security-admission/templates/pod-security-admission-config.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "pod-security-admission.fullname" . }}-pod-security-admission-config + labels: + {{- include "pod-security-admission.labels" . | nindent 4 }} +data: + config.yaml: {{ .Values.podSecurityAdmissionConfig.configYaml | toYaml | indent + 1 }} \ No newline at end of file diff --git a/charts/pod-security-admission/templates/selfsigned-issuer.yaml b/charts/pod-security-admission/templates/selfsigned-issuer.yaml new file mode 100644 index 0000000..92c9a99 --- /dev/null +++ b/charts/pod-security-admission/templates/selfsigned-issuer.yaml @@ -0,0 +1,8 @@ +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: {{ include "pod-security-admission.fullname" . }}-selfsigned-issuer + labels: + {{- include "pod-security-admission.labels" . | nindent 4 }} +spec: + selfSigned: {} \ No newline at end of file diff --git a/charts/pod-security-admission/templates/serving-cert.yaml b/charts/pod-security-admission/templates/serving-cert.yaml new file mode 100644 index 0000000..c210874 --- /dev/null +++ b/charts/pod-security-admission/templates/serving-cert.yaml @@ -0,0 +1,16 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: {{ include "pod-security-admission.fullname" . }}-serving-cert + labels: + {{- include "pod-security-admission.labels" . | nindent 4 }} +spec: + dnsNames: + - '{{ include "pod-security-admission.fullname" . }}-webhook-service.{{ .Release.Namespace + }}.svc' + - '{{ include "pod-security-admission.fullname" . }}-webhook-service.{{ .Release.Namespace + }}.svc.{{ .Values.kubernetesClusterDomain }}' + issuerRef: + kind: Issuer + name: '{{ include "pod-security-admission.fullname" . }}-selfsigned-issuer' + secretName: webhook-server-cert \ No newline at end of file diff --git a/charts/pod-security-admission/templates/validating-webhook-configuration.yaml b/charts/pod-security-admission/templates/validating-webhook-configuration.yaml new file mode 100644 index 0000000..40a7e15 --- /dev/null +++ b/charts/pod-security-admission/templates/validating-webhook-configuration.yaml @@ -0,0 +1,77 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: {{ include "pod-security-admission.fullname" . }}-validating-webhook-configuration + annotations: + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ include "pod-security-admission.fullname" . }}-serving-cert + labels: + {{- include "pod-security-admission.labels" . | nindent 4 }} +webhooks: +- admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: '{{ include "pod-security-admission.fullname" . }}-webhook-service' + namespace: '{{ .Release.Namespace }}' + path: /validate-baseline + failurePolicy: Fail + name: baseline.vpod.kb.io + namespaceSelector: + matchExpressions: + - key: pod-security.cybozu.com/policy + operator: NotIn + values: + - privileged + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + resources: + - pods + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - UPDATE + resources: + - pods/ephemeralcontainers + sideEffects: None +- admissionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: '{{ include "pod-security-admission.fullname" . }}-webhook-service' + namespace: '{{ .Release.Namespace }}' + path: /validate-restricted + failurePolicy: Fail + name: restricted.vpod.kb.io + namespaceSelector: + matchExpressions: + - key: pod-security.cybozu.com/policy + operator: In + values: + - restricted + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + resources: + - pods + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - UPDATE + resources: + - pods/ephemeralcontainers + sideEffects: None \ No newline at end of file diff --git a/charts/pod-security-admission/templates/webhook-service.yaml b/charts/pod-security-admission/templates/webhook-service.yaml new file mode 100644 index 0000000..6374f28 --- /dev/null +++ b/charts/pod-security-admission/templates/webhook-service.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "pod-security-admission.fullname" . }}-webhook-service + labels: + {{- include "pod-security-admission.labels" . | nindent 4 }} +spec: + type: {{ .Values.webhookService.type }} + selector: + control-plane: controller-manager + {{- include "pod-security-admission.selectorLabels" . | nindent 4 }} + ports: + {{- .Values.webhookService.ports | toYaml | nindent 2 -}} \ No newline at end of file diff --git a/charts/pod-security-admission/values.yaml b/charts/pod-security-admission/values.yaml new file mode 100644 index 0000000..dcce039 --- /dev/null +++ b/charts/pod-security-admission/values.yaml @@ -0,0 +1,32 @@ +controllerManager: + manager: + args: + - --cert-dir=/certs + - --config-path=/etc/pod-security-admission/config.yaml + containerSecurityContext: + allowPrivilegeEscalation: false + image: + repository: quay.io/cybozu/pod-security-admission + tag: app-version-placeholder + imagePullPolicy: IfNotPresent + resources: + requests: + cpu: 100m + memory: 20Mi + replicas: 2 +kubernetesClusterDomain: cluster.local +podSecurityAdmissionConfig: + configYaml: |- + - name: baseline + nonCoreVolumeTypes: true + allowPrivilegeEscalation: true + runAsRoot: true + rootGroups: true + seccomp: true + - name: restricted + forceRunAsNonRoot: true +webhookService: + ports: + - port: 443 + targetPort: 9443 + type: ClusterIP diff --git a/config/manager/controller_manager_config.yaml b/config/manager/controller_manager_config.yaml deleted file mode 100644 index 7c6e616..0000000 --- a/config/manager/controller_manager_config.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 -kind: ControllerManagerConfig -health: - healthProbeBindAddress: :8081 -metrics: - bindAddress: 127.0.0.1:8080 -webhook: - port: 9443 -leaderElection: - leaderElect: true - resourceName: a3c75b0a.cybozu.com diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index 0d3f58e..0780def 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -10,9 +10,6 @@ generatorOptions: disableNameSuffixHash: true configMapGenerator: - - name: manager-config - files: - - controller_manager_config.yaml - name: pod-security-admission-config files: - config.yaml diff --git a/docs/getting-started.md b/docs/getting-started.md index fc40fde..c979e8a 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -32,10 +32,8 @@ $ kubectl label namespace/cert-manager pod-security.cybozu.com/policy=privileged Deploy pod-security-admission: ```console -$ wget https://github.com/cybozu-go/pod-security-admission/releases/download/vx.y.z/pod-security-admission_x.y.z_linux_amd64.tar.gz -$ tar xvzf pod-security-admission_x.y.z_linux_amd64.tar.gz -$ cd pod-security-admission_x.y.z_linux_amd64 -$ kubectl apply -f install.yaml +$ helm repo add pod-security-admission https://cybozu-go.github.io/pod-security-admission +$ helm template pod-security-admission pod-security-admission/pod-security-admission ``` Verification