diff --git a/deployment/eks/flyte_generated.yaml b/deployment/eks/flyte_generated.yaml index dce796fcae..66576a38a3 100644 --- a/deployment/eks/flyte_generated.yaml +++ b/deployment/eks/flyte_generated.yaml @@ -7610,6 +7610,12 @@ metadata: --- apiVersion: v1 kind: ServiceAccount +metadata: + name: flyte-pod-webhook + namespace: flyte +--- +apiVersion: v1 +kind: ServiceAccount metadata: annotations: eks.amazonaws.com/role-arn: arn:aws:iam::111222333456:role/flyte-operator @@ -7641,6 +7647,24 @@ metadata: --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole +metadata: + name: flyte-pod-webhook + namespace: flyte +rules: +- apiGroups: + - '*' + resources: + - mutatingwebhookconfigurations + - secrets + - pods + verbs: + - get + - create + - update + - patch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole metadata: name: flyteadmin namespace: flyte @@ -7892,6 +7916,20 @@ rules: verbs: - '*' --- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: flyte-pod-webhook + namespace: flyte +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: flyte-pod-webhook +subjects: +- kind: ServiceAccount + name: flyte-pod-webhook + namespace: flyte +--- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: @@ -8391,6 +8429,22 @@ spec: --- apiVersion: v1 kind: Service +metadata: + annotations: + projectcontour.io/upstream-protocol.h2c: grpc + name: flyte-pod-webhook + namespace: flyte +spec: + ports: + - name: https + port: 443 + protocol: TCP + targetPort: 9443 + selector: + app: flyte-pod-webhook +--- +apiVersion: v1 +kind: Service metadata: annotations: external-dns.alpha.kubernetes.io/hostname: flyteadmin.subdomain.mydomain.com @@ -8577,6 +8631,63 @@ spec: --- apiVersion: apps/v1 kind: Deployment +metadata: + labels: + app: flyte-pod-webhook + name: flyte-pod-webhook + namespace: flyte +spec: + selector: + matchLabels: + app: flyte-pod-webhook + template: + metadata: + annotations: + prometheus.io/path: /metrics + prometheus.io/port: "10254" + prometheus.io/scrape: "true" + labels: + app: flyte-pod-webhook + app.kubernetes.io/name: flyte-pod-webhook + app.kubernetes.io/version: 0.5.13 + spec: + containers: + - args: + - webhook + - --config + - /etc/flyte/config/*.yaml + command: + - flytepropeller + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + image: ghcr.io/flyteorg/flytepropeller:v0.7.8 + imagePullPolicy: IfNotPresent + name: webhook + volumeMounts: + - mountPath: /etc/flyte/config + name: config-volume + readOnly: true + - mountPath: /etc/webhook/certs + name: webhook-certs + readOnly: true + serviceAccountName: flyte-pod-webhook + volumes: + - configMap: + name: flyte-propeller-config-ct29cf4cch + name: config-volume + - name: webhook-certs + secret: + secretName: flyte-pod-webhook +--- +apiVersion: apps/v1 +kind: Deployment metadata: labels: app: flyteadmin @@ -8604,7 +8715,7 @@ spec: - --config - /etc/flyte/config/*.yaml - serve - image: ghcr.io/flyteorg/flyteadmin:v0.3.38 + image: ghcr.io/flyteorg/flyteadmin:v0.4.0 imagePullPolicy: IfNotPresent name: flyteadmin ports: @@ -8649,7 +8760,7 @@ spec: - /etc/flyte/config/*.yaml - migrate - run - image: ghcr.io/flyteorg/flyteadmin:v0.3.38 + image: ghcr.io/flyteorg/flyteadmin:v0.4.0 imagePullPolicy: IfNotPresent name: run-migrations volumeMounts: @@ -8666,7 +8777,7 @@ spec: - flytesnacks - flytetester - flyteexamples - image: ghcr.io/flyteorg/flyteadmin:v0.3.38 + image: ghcr.io/flyteorg/flyteadmin:v0.4.0 imagePullPolicy: IfNotPresent name: seed-projects volumeMounts: @@ -8680,7 +8791,7 @@ spec: - /etc/flyte/config/*.yaml - clusterresource - sync - image: ghcr.io/flyteorg/flyteadmin:v0.3.38 + image: ghcr.io/flyteorg/flyteadmin:v0.4.0 imagePullPolicy: IfNotPresent name: sync-cluster-resources volumeMounts: @@ -8771,7 +8882,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.name - image: ghcr.io/flyteorg/flytepropeller:v0.7.1 + image: ghcr.io/flyteorg/flytepropeller:v0.7.8 imagePullPolicy: IfNotPresent name: flytepropeller ports: @@ -8958,7 +9069,7 @@ spec: - /etc/flyte/config/*.yaml - clusterresource - sync - image: ghcr.io/flyteorg/flyteadmin:v0.3.38 + image: ghcr.io/flyteorg/flyteadmin:v0.4.0 imagePullPolicy: IfNotPresent name: sync-cluster-resources volumeMounts: @@ -8984,6 +9095,46 @@ spec: --- apiVersion: batch/v1 kind: Job +metadata: + name: flyte-pod-webhook-secret + namespace: flyte +spec: + backoffLimit: 3 + template: + spec: + containers: + - args: + - webhook + - init-certs + - --config + - /etc/flyte/config/*.yaml + command: + - flytepropeller + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + image: ghcr.io/flyteorg/flytepropeller:v0.7.8 + imagePullPolicy: IfNotPresent + name: webhook + volumeMounts: + - mountPath: /etc/flyte/config + name: config-volume + restartPolicy: Never + serviceAccountName: flyte-pod-webhook + volumes: + - configMap: + name: flyte-propeller-config-ct29cf4cch + name: config-volume + ttlSecondsAfterFinished: 0 +--- +apiVersion: batch/v1 +kind: Job metadata: labels: app.kubernetes.io/name: sparkoperator diff --git a/deployment/gcp/flyte_generated.yaml b/deployment/gcp/flyte_generated.yaml index 2faab6b203..2480b3640d 100644 --- a/deployment/gcp/flyte_generated.yaml +++ b/deployment/gcp/flyte_generated.yaml @@ -7610,6 +7610,12 @@ metadata: --- apiVersion: v1 kind: ServiceAccount +metadata: + name: flyte-pod-webhook + namespace: flyte +--- +apiVersion: v1 +kind: ServiceAccount metadata: name: flyteadmin namespace: flyte @@ -7637,6 +7643,24 @@ metadata: --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole +metadata: + name: flyte-pod-webhook + namespace: flyte +rules: +- apiGroups: + - '*' + resources: + - mutatingwebhookconfigurations + - secrets + - pods + verbs: + - get + - create + - update + - patch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole metadata: name: flyteadmin namespace: flyte @@ -7888,6 +7912,20 @@ rules: verbs: - '*' --- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: flyte-pod-webhook + namespace: flyte +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: flyte-pod-webhook +subjects: +- kind: ServiceAccount + name: flyte-pod-webhook + namespace: flyte +--- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: @@ -8391,6 +8429,22 @@ spec: --- apiVersion: v1 kind: Service +metadata: + annotations: + projectcontour.io/upstream-protocol.h2c: grpc + name: flyte-pod-webhook + namespace: flyte +spec: + ports: + - name: https + port: 443 + protocol: TCP + targetPort: 9443 + selector: + app: flyte-pod-webhook +--- +apiVersion: v1 +kind: Service metadata: annotations: cloud.google.com/load-balancer-type: Internal @@ -8609,6 +8663,63 @@ spec: --- apiVersion: apps/v1 kind: Deployment +metadata: + labels: + app: flyte-pod-webhook + name: flyte-pod-webhook + namespace: flyte +spec: + selector: + matchLabels: + app: flyte-pod-webhook + template: + metadata: + annotations: + prometheus.io/path: /metrics + prometheus.io/port: "10254" + prometheus.io/scrape: "true" + labels: + app: flyte-pod-webhook + app.kubernetes.io/name: flyte-pod-webhook + app.kubernetes.io/version: 0.5.13 + spec: + containers: + - args: + - webhook + - --config + - /etc/flyte/config/*.yaml + command: + - flytepropeller + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + image: ghcr.io/flyteorg/flytepropeller:v0.7.8 + imagePullPolicy: IfNotPresent + name: webhook + volumeMounts: + - mountPath: /etc/flyte/config + name: config-volume + readOnly: true + - mountPath: /etc/webhook/certs + name: webhook-certs + readOnly: true + serviceAccountName: flyte-pod-webhook + volumes: + - configMap: + name: flyte-propeller-config-7288ccf2f8 + name: config-volume + - name: webhook-certs + secret: + secretName: flyte-pod-webhook +--- +apiVersion: apps/v1 +kind: Deployment metadata: labels: app: flyteadmin @@ -8636,7 +8747,7 @@ spec: - --config - /etc/flyte/config/*.yaml - serve - image: ghcr.io/flyteorg/flyteadmin:v0.3.38 + image: ghcr.io/flyteorg/flyteadmin:v0.4.0 imagePullPolicy: IfNotPresent name: flyteadmin ports: @@ -8681,7 +8792,7 @@ spec: - /etc/flyte/config/*.yaml - migrate - run - image: ghcr.io/flyteorg/flyteadmin:v0.3.38 + image: ghcr.io/flyteorg/flyteadmin:v0.4.0 imagePullPolicy: IfNotPresent name: run-migrations volumeMounts: @@ -8698,7 +8809,7 @@ spec: - flytesnacks - flytetester - flyteexamples - image: ghcr.io/flyteorg/flyteadmin:v0.3.38 + image: ghcr.io/flyteorg/flyteadmin:v0.4.0 imagePullPolicy: IfNotPresent name: seed-projects volumeMounts: @@ -8712,7 +8823,7 @@ spec: - /etc/flyte/config/*.yaml - clusterresource - sync - image: ghcr.io/flyteorg/flyteadmin:v0.3.38 + image: ghcr.io/flyteorg/flyteadmin:v0.4.0 imagePullPolicy: IfNotPresent name: sync-cluster-resources volumeMounts: @@ -8803,7 +8914,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.name - image: ghcr.io/flyteorg/flytepropeller:v0.7.1 + image: ghcr.io/flyteorg/flytepropeller:v0.7.8 imagePullPolicy: IfNotPresent name: flytepropeller ports: @@ -8990,7 +9101,7 @@ spec: - /etc/flyte/config/*.yaml - clusterresource - sync - image: ghcr.io/flyteorg/flyteadmin:v0.3.38 + image: ghcr.io/flyteorg/flyteadmin:v0.4.0 imagePullPolicy: IfNotPresent name: sync-cluster-resources volumeMounts: @@ -9016,6 +9127,46 @@ spec: --- apiVersion: batch/v1 kind: Job +metadata: + name: flyte-pod-webhook-secret + namespace: flyte +spec: + backoffLimit: 3 + template: + spec: + containers: + - args: + - webhook + - init-certs + - --config + - /etc/flyte/config/*.yaml + command: + - flytepropeller + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + image: ghcr.io/flyteorg/flytepropeller:v0.7.8 + imagePullPolicy: IfNotPresent + name: webhook + volumeMounts: + - mountPath: /etc/flyte/config + name: config-volume + restartPolicy: Never + serviceAccountName: flyte-pod-webhook + volumes: + - configMap: + name: flyte-propeller-config-7288ccf2f8 + name: config-volume + ttlSecondsAfterFinished: 0 +--- +apiVersion: batch/v1 +kind: Job metadata: labels: app.kubernetes.io/name: sparkoperator diff --git a/deployment/sandbox/flyte_generated.yaml b/deployment/sandbox/flyte_generated.yaml index f0dde874e2..24c6f4928e 100644 --- a/deployment/sandbox/flyte_generated.yaml +++ b/deployment/sandbox/flyte_generated.yaml @@ -1588,6 +1588,12 @@ metadata: --- apiVersion: v1 kind: ServiceAccount +metadata: + name: flyte-pod-webhook + namespace: flyte +--- +apiVersion: v1 +kind: ServiceAccount metadata: name: flyteadmin namespace: flyte @@ -1691,6 +1697,24 @@ rules: --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole +metadata: + name: flyte-pod-webhook + namespace: flyte +rules: +- apiGroups: + - '*' + resources: + - mutatingwebhookconfigurations + - secrets + - pods + verbs: + - get + - create + - update + - patch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole metadata: name: flyteadmin namespace: flyte @@ -1936,6 +1960,20 @@ subjects: --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding +metadata: + name: flyte-pod-webhook + namespace: flyte +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: flyte-pod-webhook +subjects: +- kind: ServiceAccount + name: flyte-pod-webhook + namespace: flyte +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding metadata: name: contour roleRef: @@ -2236,6 +2274,9 @@ data: type: bucket rate: 10 capacity: 100 + webhook: + certDir: /etc/webhook/certs + serviceName: flyte-pod-webhook enabled_plugins.yaml: | tasks: task-plugins: @@ -2283,7 +2324,7 @@ data: kubernetes-template-uri: "http://localhost:30082/#/log/{{ .namespace }}/{{ .podName }}/pod?namespace={{ .namespace }}" kind: ConfigMap metadata: - name: flyte-propeller-config-492gkfhbgk + name: flyte-propeller-config-c8kkg4fth7 namespace: flyte --- apiVersion: v1 @@ -2426,6 +2467,17 @@ metadata: type: Opaque --- apiVersion: v1 +data: + password: bXl1c2Vy + user_secret: bXlzZWNyZXQ= + username: bXl1c2Vy +kind: Secret +metadata: + name: user-info + namespace: flyte +type: Opaque +--- +apiVersion: v1 data: csrf: "" kind: Secret @@ -2467,6 +2519,22 @@ spec: --- apiVersion: v1 kind: Service +metadata: + annotations: + projectcontour.io/upstream-protocol.h2c: grpc + name: flyte-pod-webhook + namespace: flyte +spec: + ports: + - name: https + port: 443 + protocol: TCP + targetPort: 9443 + selector: + app: flyte-pod-webhook +--- +apiVersion: v1 +kind: Service metadata: annotations: projectcontour.io/upstream-protocol.h2c: grpc @@ -2693,6 +2761,69 @@ spec: --- apiVersion: apps/v1 kind: Deployment +metadata: + labels: + app: flyte-pod-webhook + name: flyte-pod-webhook + namespace: flyte +spec: + selector: + matchLabels: + app: flyte-pod-webhook + template: + metadata: + annotations: + prometheus.io/path: /metrics + prometheus.io/port: "10254" + prometheus.io/scrape: "true" + labels: + app: flyte-pod-webhook + app.kubernetes.io/name: flyte-pod-webhook + app.kubernetes.io/version: 0.5.13 + spec: + containers: + - args: + - webhook + - --config + - /etc/flyte/config/*.yaml + command: + - flytepropeller + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + image: ghcr.io/flyteorg/flytepropeller:v0.7.8 + imagePullPolicy: IfNotPresent + name: webhook + volumeMounts: + - mountPath: /etc/secrets/user-info + name: sample-secrets + readOnly: true + - mountPath: /etc/flyte/config + name: config-volume + readOnly: true + - mountPath: /etc/webhook/certs + name: webhook-certs + readOnly: true + serviceAccountName: flyte-pod-webhook + volumes: + - name: sample-secrets + secret: + secretName: user-info + - configMap: + name: flyte-propeller-config-c8kkg4fth7 + name: config-volume + - name: webhook-certs + secret: + secretName: flyte-pod-webhook +--- +apiVersion: apps/v1 +kind: Deployment metadata: labels: app: flyteadmin @@ -2720,7 +2851,7 @@ spec: - --config - /etc/flyte/config/*.yaml - serve - image: ghcr.io/flyteorg/flyteadmin:v0.3.38 + image: ghcr.io/flyteorg/flyteadmin:v0.4.0 imagePullPolicy: IfNotPresent name: flyteadmin ports: @@ -2771,7 +2902,7 @@ spec: - /etc/flyte/config/*.yaml - migrate - run - image: ghcr.io/flyteorg/flyteadmin:v0.3.38 + image: ghcr.io/flyteorg/flyteadmin:v0.4.0 imagePullPolicy: IfNotPresent name: run-migrations volumeMounts: @@ -2787,7 +2918,7 @@ spec: - seed-projects - flytesnacks - flyteexamples - image: ghcr.io/flyteorg/flyteadmin:v0.3.38 + image: ghcr.io/flyteorg/flyteadmin:v0.4.0 imagePullPolicy: IfNotPresent name: seed-projects volumeMounts: @@ -2801,7 +2932,7 @@ spec: - /etc/flyte/config/*.yaml - clusterresource - sync - image: ghcr.io/flyteorg/flyteadmin:v0.3.38 + image: ghcr.io/flyteorg/flyteadmin:v0.4.0 imagePullPolicy: IfNotPresent name: sync-cluster-resources volumeMounts: @@ -2892,7 +3023,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.name - image: ghcr.io/flyteorg/flytepropeller:v0.7.1 + image: ghcr.io/flyteorg/flytepropeller:v0.7.8 imagePullPolicy: IfNotPresent name: flytepropeller ports: @@ -2903,7 +3034,7 @@ spec: serviceAccountName: flytepropeller volumes: - configMap: - name: flyte-propeller-config-492gkfhbgk + name: flyte-propeller-config-c8kkg4fth7 name: config-volume --- apiVersion: apps/v1 @@ -3197,7 +3328,7 @@ spec: - /etc/flyte/config/*.yaml - clusterresource - sync - image: ghcr.io/flyteorg/flyteadmin:v0.3.38 + image: ghcr.io/flyteorg/flyteadmin:v0.4.0 imagePullPolicy: IfNotPresent name: sync-cluster-resources volumeMounts: @@ -3357,6 +3488,46 @@ spec: --- apiVersion: batch/v1 kind: Job +metadata: + name: flyte-pod-webhook-secret + namespace: flyte +spec: + backoffLimit: 3 + template: + spec: + containers: + - args: + - webhook + - init-certs + - --config + - /etc/flyte/config/*.yaml + command: + - flytepropeller + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + image: ghcr.io/flyteorg/flytepropeller:v0.7.8 + imagePullPolicy: IfNotPresent + name: webhook + volumeMounts: + - mountPath: /etc/flyte/config + name: config-volume + restartPolicy: Never + serviceAccountName: flyte-pod-webhook + volumes: + - configMap: + name: flyte-propeller-config-c8kkg4fth7 + name: config-volume + ttlSecondsAfterFinished: 0 +--- +apiVersion: batch/v1 +kind: Job metadata: name: contour-certgen-v1.13.1 namespace: projectcontour diff --git a/deployment/test/flyte_generated.yaml b/deployment/test/flyte_generated.yaml index 2028979b20..59d5e1a0d5 100644 --- a/deployment/test/flyte_generated.yaml +++ b/deployment/test/flyte_generated.yaml @@ -26,6 +26,12 @@ metadata: --- apiVersion: v1 kind: ServiceAccount +metadata: + name: flyte-pod-webhook + namespace: flyte +--- +apiVersion: v1 +kind: ServiceAccount metadata: name: flyteadmin namespace: flyte @@ -38,6 +44,24 @@ metadata: --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole +metadata: + name: flyte-pod-webhook + namespace: flyte +rules: +- apiGroups: + - '*' + resources: + - mutatingwebhookconfigurations + - secrets + - pods + verbs: + - get + - create + - update + - patch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole metadata: name: flyteadmin namespace: flyte @@ -121,6 +145,20 @@ rules: - post - deletecollection --- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: flyte-pod-webhook + namespace: flyte +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: flyte-pod-webhook +subjects: +- kind: ServiceAccount + name: flyte-pod-webhook + namespace: flyte +--- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: @@ -375,6 +413,9 @@ data: type: bucket rate: 10 capacity: 100 + webhook: + certDir: /etc/webhook/certs + serviceName: flyte-pod-webhook enabled_plugins.yaml: | tasks: task-plugins: @@ -417,7 +458,7 @@ data: kind: ConfigMap metadata: - name: flyte-propeller-config-ttk5h2hkmg + name: flyte-propeller-config-cbbhf652h4 namespace: flyte --- apiVersion: v1 @@ -451,6 +492,22 @@ spec: --- apiVersion: v1 kind: Service +metadata: + annotations: + projectcontour.io/upstream-protocol.h2c: grpc + name: flyte-pod-webhook + namespace: flyte +spec: + ports: + - name: https + port: 443 + protocol: TCP + targetPort: 9443 + selector: + app: flyte-pod-webhook +--- +apiVersion: v1 +kind: Service metadata: annotations: projectcontour.io/upstream-protocol.h2c: grpc @@ -564,6 +621,63 @@ spec: --- apiVersion: apps/v1 kind: Deployment +metadata: + labels: + app: flyte-pod-webhook + name: flyte-pod-webhook + namespace: flyte +spec: + selector: + matchLabels: + app: flyte-pod-webhook + template: + metadata: + annotations: + prometheus.io/path: /metrics + prometheus.io/port: "10254" + prometheus.io/scrape: "true" + labels: + app: flyte-pod-webhook + app.kubernetes.io/name: flyte-pod-webhook + app.kubernetes.io/version: 0.5.13 + spec: + containers: + - args: + - webhook + - --config + - /etc/flyte/config/*.yaml + command: + - flytepropeller + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + image: ghcr.io/flyteorg/flytepropeller:v0.7.8 + imagePullPolicy: IfNotPresent + name: webhook + volumeMounts: + - mountPath: /etc/flyte/config + name: config-volume + readOnly: true + - mountPath: /etc/webhook/certs + name: webhook-certs + readOnly: true + serviceAccountName: flyte-pod-webhook + volumes: + - configMap: + name: flyte-propeller-config-cbbhf652h4 + name: config-volume + - name: webhook-certs + secret: + secretName: flyte-pod-webhook +--- +apiVersion: apps/v1 +kind: Deployment metadata: labels: app: flyteadmin @@ -591,7 +705,7 @@ spec: - --config - /etc/flyte/config/*.yaml - serve - image: ghcr.io/flyteorg/flyteadmin:v0.3.38 + image: ghcr.io/flyteorg/flyteadmin:v0.4.0 imagePullPolicy: IfNotPresent name: flyteadmin ports: @@ -642,7 +756,7 @@ spec: - /etc/flyte/config/*.yaml - migrate - run - image: ghcr.io/flyteorg/flyteadmin:v0.3.38 + image: ghcr.io/flyteorg/flyteadmin:v0.4.0 imagePullPolicy: IfNotPresent name: run-migrations volumeMounts: @@ -658,7 +772,7 @@ spec: - seed-projects - flytetester - flytesnacks - image: ghcr.io/flyteorg/flyteadmin:v0.3.38 + image: ghcr.io/flyteorg/flyteadmin:v0.4.0 imagePullPolicy: IfNotPresent name: seed-projects volumeMounts: @@ -672,7 +786,7 @@ spec: - /etc/flyte/config/*.yaml - clusterresource - sync - image: ghcr.io/flyteorg/flyteadmin:v0.3.38 + image: ghcr.io/flyteorg/flyteadmin:v0.4.0 imagePullPolicy: IfNotPresent name: sync-cluster-resources volumeMounts: @@ -729,7 +843,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.name - image: ghcr.io/flyteorg/flytepropeller:v0.7.1 + image: ghcr.io/flyteorg/flytepropeller:v0.7.8 imagePullPolicy: IfNotPresent name: flytepropeller ports: @@ -740,7 +854,7 @@ spec: serviceAccountName: flytepropeller volumes: - configMap: - name: flyte-propeller-config-ttk5h2hkmg + name: flyte-propeller-config-cbbhf652h4 name: config-volume --- apiVersion: apps/v1 @@ -808,6 +922,46 @@ spec: - emptyDir: {} name: postgres-storage --- +apiVersion: batch/v1 +kind: Job +metadata: + name: flyte-pod-webhook-secret + namespace: flyte +spec: + backoffLimit: 3 + template: + spec: + containers: + - args: + - webhook + - init-certs + - --config + - /etc/flyte/config/*.yaml + command: + - flytepropeller + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + image: ghcr.io/flyteorg/flytepropeller:v0.7.8 + imagePullPolicy: IfNotPresent + name: webhook + volumeMounts: + - mountPath: /etc/flyte/config + name: config-volume + restartPolicy: Never + serviceAccountName: flyte-pod-webhook + volumes: + - configMap: + name: flyte-propeller-config-cbbhf652h4 + name: config-volume + ttlSecondsAfterFinished: 0 +--- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: diff --git a/kustomize/base/admindeployment/deployment.yaml b/kustomize/base/admindeployment/deployment.yaml index 1c455774ab..b77ea096a1 100644 --- a/kustomize/base/admindeployment/deployment.yaml +++ b/kustomize/base/admindeployment/deployment.yaml @@ -37,7 +37,7 @@ spec: secretName: db-pass initContainers: - name: run-migrations - image: flyteadmin:v0.3.38 + image: flyteadmin:v0.4.0 imagePullPolicy: IfNotPresent command: ["flyteadmin", "--config", "/etc/flyte/config/*.yaml", "migrate", "run"] volumeMounts: @@ -47,7 +47,7 @@ spec: mountPath: /etc/db # Optional, These just seed the project - TODO move them to only - name: seed-projects - image: flyteadmin:v0.3.38 + image: flyteadmin:v0.4.0 imagePullPolicy: IfNotPresent command: ["flyteadmin", "--config", "/etc/flyte/config/*.yaml", "migrate", "seed-projects", "flytesnacks", "flytetester", "flyteexamples"] @@ -57,7 +57,7 @@ spec: - name: db-pass mountPath: /etc/db - name: sync-cluster-resources - image: flyteadmin:v0.3.38 + image: flyteadmin:v0.4.0 imagePullPolicy: IfNotPresent command: ["flyteadmin", "--config", "/etc/flyte/config/*.yaml", "clusterresource", "sync"] volumeMounts: @@ -69,7 +69,7 @@ spec: mountPath: /etc/db containers: - name: flyteadmin - image: flyteadmin:v0.3.38 + image: flyteadmin:v0.4.0 imagePullPolicy: IfNotPresent command: ["flyteadmin", "--config", "/etc/flyte/config/*.yaml", "serve"] ports: diff --git a/kustomize/base/propeller/kustomization.yaml b/kustomize/base/propeller/kustomization.yaml index 3f090bdf48..408244dcaf 100644 --- a/kustomize/base/propeller/kustomization.yaml +++ b/kustomize/base/propeller/kustomization.yaml @@ -1,3 +1,4 @@ resources: -- deployment.yaml -- rbac.yaml + - deployment.yaml + - rbac.yaml + - webhook.yaml diff --git a/kustomize/base/propeller/webhook.yaml b/kustomize/base/propeller/webhook.yaml new file mode 100644 index 0000000000..23efff56d2 --- /dev/null +++ b/kustomize/base/propeller/webhook.yaml @@ -0,0 +1,161 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: flyte-pod-webhook-secret + namespace: flyte +spec: + backoffLimit: 3 + ttlSecondsAfterFinished: 0 + template: + spec: + serviceAccountName: flyte-pod-webhook + restartPolicy: Never + containers: + - name: webhook + image: flytepropeller:v0.5.13 + imagePullPolicy: IfNotPresent + command: + - flytepropeller + args: + - webhook + - init-certs + - --config + - /etc/flyte/config/*.yaml + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + volumeMounts: + - name: config-volume + mountPath: /etc/flyte/config + volumes: + - name: config-volume + configMap: + name: flyte-propeller-config +--- +# Create the actual deployment +apiVersion: apps/v1 +kind: Deployment +metadata: + name: flyte-pod-webhook + namespace: flyte + labels: + app: flyte-pod-webhook +spec: + selector: + matchLabels: + app: flyte-pod-webhook + template: + metadata: + labels: + app: flyte-pod-webhook + app.kubernetes.io/name: flyte-pod-webhook + app.kubernetes.io/version: 0.5.13 + annotations: + prometheus.io/scrape: "true" + prometheus.io/port: "10254" + prometheus.io/path: "/metrics" + spec: + serviceAccountName: flyte-pod-webhook + containers: + - name: webhook + image: flytepropeller:v0.5.13 + imagePullPolicy: IfNotPresent + command: + - flytepropeller + args: + - webhook + - --config + - /etc/flyte/config/*.yaml + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + volumeMounts: + - name: config-volume + mountPath: /etc/flyte/config + readOnly: true + - name: webhook-certs + mountPath: /etc/webhook/certs + readOnly: true + volumes: + - name: config-volume + configMap: + name: flyte-propeller-config + - name: webhook-certs + secret: + secretName: flyte-pod-webhook +--- +# Service +apiVersion: v1 +kind: Service +metadata: + name: flyte-pod-webhook + namespace: flyte + annotations: + # This tells contour to use a H2 connection for the port associated + # with the name 'grpc' under spec/ports. + # For more information, refer to + # https://github.com/heptio/contour/blob/master/docs/annotations.md#contour-specific-service-annotations + # # Following this issue - the annotation was updated https://github.com/projectcontour/contour/issues/2092 + projectcontour.io/upstream-protocol.h2c: "grpc" +spec: + selector: + app: flyte-pod-webhook + ports: + - name: https + protocol: TCP + port: 443 + targetPort: 9443 +--- +# Create a ClusterRole for the webhook +# https://kubernetes.io/docs/admin/authorization/rbac/ +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: flyte-pod-webhook + namespace: flyte +rules: + - apiGroups: + - "*" + resources: + - mutatingwebhookconfigurations + - secrets + - pods + verbs: + - get + - create + - update + - patch +--- +# Create a Service Account for webhook +apiVersion: v1 +kind: ServiceAccount +metadata: + name: flyte-pod-webhook + namespace: flyte +--- +# Create a binding from Role -> ServiceAccount +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: flyte-pod-webhook + namespace: flyte +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: flyte-pod-webhook +subjects: + - kind: ServiceAccount + name: flyte-pod-webhook + namespace: flyte diff --git a/kustomize/base/single_cluster/headless/config/propeller/core.yaml b/kustomize/base/single_cluster/headless/config/propeller/core.yaml index e1fce27b72..055e7a8840 100644 --- a/kustomize/base/single_cluster/headless/config/propeller/core.yaml +++ b/kustomize/base/single_cluster/headless/config/propeller/core.yaml @@ -31,3 +31,6 @@ propeller: type: bucket rate: 10 capacity: 100 +webhook: + certDir: /etc/webhook/certs + serviceName: flyte-pod-webhook diff --git a/kustomize/overlays/eks/kustomization.yaml b/kustomize/overlays/eks/kustomization.yaml index e0ab501cdd..21b3f2ef07 100644 --- a/kustomize/overlays/eks/kustomization.yaml +++ b/kustomize/overlays/eks/kustomization.yaml @@ -21,7 +21,7 @@ bases: images: # FlyteAdmin - name: flyteadmin # match images with this name - newTag: v0.3.38 # override the tag + newTag: v0.4.0 # override the tag newName: ghcr.io/flyteorg/flyteadmin # override the name # FlyteConsole - name: flyteconsole # match images with this name @@ -33,5 +33,9 @@ images: newName: ghcr.io/flyteorg/datacatalog # override the name # FlytePropeller - name: flytepropeller # match images with this name - newTag: v0.7.1 # override the tag + newTag: v0.7.8 # override the tag + newName: ghcr.io/flyteorg/flytepropeller # override the name + # Webhook + - name: webhook # match images with this name + newTag: v0.7.8 # override the tag newName: ghcr.io/flyteorg/flytepropeller # override the name diff --git a/kustomize/overlays/gcp/kustomization.yaml b/kustomize/overlays/gcp/kustomization.yaml index acfcec1508..a209c3bf86 100644 --- a/kustomize/overlays/gcp/kustomization.yaml +++ b/kustomize/overlays/gcp/kustomization.yaml @@ -23,7 +23,7 @@ bases: images: # FlyteAdmin - name: flyteadmin # match images with this name - newTag: v0.3.38 # override the tag + newTag: v0.4.0 # override the tag newName: ghcr.io/flyteorg/flyteadmin # override the name # FlyteConsole - name: flyteconsole # match images with this name @@ -35,5 +35,9 @@ images: newName: ghcr.io/flyteorg/datacatalog # override the name # FlytePropeller - name: flytepropeller # match images with this name - newTag: v0.7.1 # override the tag + newTag: v0.7.8 # override the tag + newName: ghcr.io/flyteorg/flytepropeller # override the name + # Webhook + - name: webhook # match images with this name + newTag: v0.7.8 # override the tag newName: ghcr.io/flyteorg/flytepropeller # override the name diff --git a/kustomize/overlays/sandbox/flyte/admin/deployment.yaml b/kustomize/overlays/sandbox/flyte/admin/deployment.yaml index 33f39ab46b..f3a7c1ef20 100644 --- a/kustomize/overlays/sandbox/flyte/admin/deployment.yaml +++ b/kustomize/overlays/sandbox/flyte/admin/deployment.yaml @@ -20,7 +20,7 @@ spec: do echo waiting for database; sleep 2; done;", ] - name: run-migrations - image: flyteadmin:v0.3.38 + image: flyteadmin:v0.4.0 imagePullPolicy: IfNotPresent command: [ @@ -34,7 +34,7 @@ spec: - name: config-volume mountPath: /etc/flyte/config - name: seed-projects - image: flyteadmin:v0.3.38 + image: flyteadmin:v0.4.0 imagePullPolicy: IfNotPresent command: [ @@ -50,7 +50,7 @@ spec: - name: config-volume mountPath: /etc/flyte/config - name: sync-cluster-resources - image: flyteadmin:v0.3.38 + image: flyteadmin:v0.4.0 imagePullPolicy: IfNotPresent command: [ diff --git a/kustomize/overlays/sandbox/flyte/kustomization.yaml b/kustomize/overlays/sandbox/flyte/kustomization.yaml index d3485ba7b7..c0ad168558 100644 --- a/kustomize/overlays/sandbox/flyte/kustomization.yaml +++ b/kustomize/overlays/sandbox/flyte/kustomization.yaml @@ -5,38 +5,42 @@ kind: Kustomization namespace: flyte bases: -- ../../../base/single_cluster/complete + - ../../../base/single_cluster/complete + +resources: + - propeller/webhook-secret.yaml patchesStrategicMerge: -- admin/deployment.yaml + - admin/deployment.yaml + - propeller/webhook.yaml configMapGenerator: -- behavior: merge - files: - - ./config/admin/db.yaml - - ./config/admin/task_resource_defaults.yaml - - ./config/common/storage.yaml - - ./config/common/logger.yaml - name: flyte-admin-config - -- behavior: merge - files: - - ./config/clusterresource-templates/ac_project-copilot-dataconfig.yaml - name: clusterresource-template - -- behavior: merge - files: - - ./config/propeller/enabled_plugins.yaml - - ./config/propeller/resource_manager.yaml - - ./config/propeller/plugins/k8s.yaml - - ./config/propeller/plugins/task_logs.yaml - - ./config/common/storage.yaml - - ./config/common/logger.yaml - name: flyte-propeller-config - -- behavior: merge - files: - - ./config/common/storage.yaml - - ./config/common/logger.yaml - - ./config/datacatalog/db.yaml - name: datacatalog-config + - behavior: merge + files: + - ./config/admin/db.yaml + - ./config/admin/task_resource_defaults.yaml + - ./config/common/storage.yaml + - ./config/common/logger.yaml + name: flyte-admin-config + + - behavior: merge + files: + - ./config/clusterresource-templates/ac_project-copilot-dataconfig.yaml + name: clusterresource-template + + - behavior: merge + files: + - ./config/propeller/enabled_plugins.yaml + - ./config/propeller/resource_manager.yaml + - ./config/propeller/plugins/k8s.yaml + - ./config/propeller/plugins/task_logs.yaml + - ./config/common/storage.yaml + - ./config/common/logger.yaml + name: flyte-propeller-config + + - behavior: merge + files: + - ./config/common/storage.yaml + - ./config/common/logger.yaml + - ./config/datacatalog/db.yaml + name: datacatalog-config diff --git a/kustomize/overlays/sandbox/flyte/propeller/webhook-secret.yaml b/kustomize/overlays/sandbox/flyte/propeller/webhook-secret.yaml new file mode 100644 index 0000000000..4029be3716 --- /dev/null +++ b/kustomize/overlays/sandbox/flyte/propeller/webhook-secret.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +data: + password: bXl1c2Vy + user_secret: bXlzZWNyZXQ= + username: bXl1c2Vy +kind: Secret +metadata: + name: user-info + namespace: flyte +type: Opaque diff --git a/kustomize/overlays/sandbox/flyte/propeller/webhook.yaml b/kustomize/overlays/sandbox/flyte/propeller/webhook.yaml new file mode 100644 index 0000000000..a659e88141 --- /dev/null +++ b/kustomize/overlays/sandbox/flyte/propeller/webhook.yaml @@ -0,0 +1,18 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: flyte-pod-webhook + namespace: flyte +spec: + template: + spec: + containers: + - name: webhook + volumeMounts: + - name: sample-secrets + mountPath: /etc/secrets/user-info + readOnly: true + volumes: + - name: sample-secrets + secret: + secretName: user-info diff --git a/kustomize/overlays/sandbox/kustomization.yaml b/kustomize/overlays/sandbox/kustomization.yaml index 59f2f9e5ca..50d2f74c61 100644 --- a/kustomize/overlays/sandbox/kustomization.yaml +++ b/kustomize/overlays/sandbox/kustomization.yaml @@ -25,7 +25,7 @@ resources: images: # FlyteAdmin - name: flyteadmin # match images with this name - newTag: v0.3.38 # override the tag + newTag: v0.4.0 # override the tag newName: ghcr.io/flyteorg/flyteadmin # override the name # FlyteConsole - name: flyteconsole # match images with this name @@ -37,7 +37,11 @@ images: newName: ghcr.io/flyteorg/datacatalog # override the name # FlytePropeller - name: flytepropeller # match images with this name - newTag: v0.7.1 # override the tag + newTag: v0.7.8 # override the tag + newName: ghcr.io/flyteorg/flytepropeller # override the name + # Webhook + - name: webhook # match images with this name + newTag: v0.7.8 # override the tag newName: ghcr.io/flyteorg/flytepropeller # override the name # Override postgres image to use alpine based (rather smaller) docker image - name: postgres diff --git a/kustomize/overlays/test/kustomization.yaml b/kustomize/overlays/test/kustomization.yaml index 313dffa35e..6bb67c1098 100644 --- a/kustomize/overlays/test/kustomization.yaml +++ b/kustomize/overlays/test/kustomization.yaml @@ -19,7 +19,7 @@ bases: images: # FlyteAdmin - name: flyteadmin # match images with this name - newTag: v0.3.38 # override the tag + newTag: v0.4.0 # override the tag newName: ghcr.io/flyteorg/flyteadmin # override the name # FlyteConsole - name: flyteconsole # match images with this name @@ -31,7 +31,11 @@ images: newName: ghcr.io/flyteorg/datacatalog # override the name # FlytePropeller - name: flytepropeller # match images with this name - newTag: v0.7.1 # override the tag + newTag: v0.7.8 # override the tag + newName: ghcr.io/flyteorg/flytepropeller # override the name + # Webhook + - name: webhook # match images with this name + newTag: v0.7.8 # override the tag newName: ghcr.io/flyteorg/flytepropeller # override the name # Override postgres image to use alpine based (rather smaller) docker image - name: postgres diff --git a/rsts/howto/index.rst b/rsts/howto/index.rst index 77e85c719a..1c0bbe5e1c 100644 --- a/rsts/howto/index.rst +++ b/rsts/howto/index.rst @@ -32,6 +32,7 @@ Frequently Asked Questions notifications serviceaccount gcp + secrets .. _howto_extend: diff --git a/rsts/howto/secrets.rst b/rsts/howto/secrets.rst new file mode 100644 index 0000000000..939c00f5d6 --- /dev/null +++ b/rsts/howto/secrets.rst @@ -0,0 +1,62 @@ +.. _howto-secrets: + +################################ +How to Inject Secrets Into Tasks +################################ + + +************************** +What Is Secrets Injection? +************************** + +Flyte supports running a wide variety of tasks; from containers to sql queries and service calls. In order for flyte-run +containers to request and access secrets, flyte now natively supports a Secret construct. + +For a simple task that launches a Pod, the flow will look something like this: + +.. image:: https://mermaid.ink/img/eyJjb2RlIjoic2VxdWVuY2VEaWFncmFtXG4gICAgUHJvcGVsbGVyLT4-K1BsdWdpbnM6IENyZWF0ZSBLOHMgUmVzb3VyY2VcbiAgICBQbHVnaW5zLT4-LVByb3BlbGxlcjogUmVzb3VyY2UgT2JqZWN0XG4gICAgUHJvcGVsbGVyLT4-K1Byb3BlbGxlcjogU2V0IExhYmVscyAmIEFubm90YXRpb25zXG4gICAgUHJvcGVsbGVyLT4-K0FwaVNlcnZlcjogQ3JlYXRlIE9iamVjdCAoZS5nLiBQb2QpXG4gICAgQXBpU2VydmVyLT4-K1BvZCBXZWJob29rOiAvbXV0YXRlXG4gICAgUG9kIFdlYmhvb2stPj4rUG9kIFdlYmhvb2s6IExvb2t1cCBnbG9iYWxzXG4gICAgUG9kIFdlYmhvb2stPj4rUG9kIFdlYmhvb2s6IEluamVjdCBTZWNyZXQgQW5ub3RhdGlvbnMgKGUuZy4gSzhzLCBWYXVsdC4uLiBldGMuKVxuICAgIFBvZCBXZWJob29rLT4-LUFwaVNlcnZlcjogTXV0YXRlZCBQb2RcbiAgICBcbiAgICAgICAgICAgICIsIm1lcm1haWQiOnt9LCJ1cGRhdGVFZGl0b3IiOmZhbHNlfQ + :target: https://mermaid.ink/img/eyJjb2RlIjoic2VxdWVuY2VEaWFncmFtXG4gICAgUHJvcGVsbGVyLT4-K1BsdWdpbnM6IENyZWF0ZSBLOHMgUmVzb3VyY2VcbiAgICBQbHVnaW5zLT4-LVByb3BlbGxlcjogUmVzb3VyY2UgT2JqZWN0XG4gICAgUHJvcGVsbGVyLT4-K1Byb3BlbGxlcjogU2V0IExhYmVscyAmIEFubm90YXRpb25zXG4gICAgUHJvcGVsbGVyLT4-K0FwaVNlcnZlcjogQ3JlYXRlIE9iamVjdCAoZS5nLiBQb2QpXG4gICAgQXBpU2VydmVyLT4-K1BvZCBXZWJob29rOiAvbXV0YXRlXG4gICAgUG9kIFdlYmhvb2stPj4rUG9kIFdlYmhvb2s6IExvb2t1cCBnbG9iYWxzXG4gICAgUG9kIFdlYmhvb2stPj4rUG9kIFdlYmhvb2s6IEluamVjdCBTZWNyZXQgQW5ub3RhdGlvbnMgKGUuZy4gSzhzLCBWYXVsdC4uLiBldGMuKVxuICAgIFBvZCBXZWJob29rLT4-LUFwaVNlcnZlcjogTXV0YXRlZCBQb2RcbiAgICBcbiAgICAgICAgICAgICIsIm1lcm1haWQiOnt9LCJ1cGRhdGVFZGl0b3IiOmZhbHNlfQ + +Where: + +1. Flyte invokes a plugin to create the K8s object. This can be a Pod or a more complex CRD (e.g. Spark, PyTorch, etc.) + + .. tip:: The plugin will ensure that labels and annotations are passed through to any Pod that will be spawned due to the creation of the CRD. + +3. Flyte will apply labels and annotations that are referenced to all secrets the task is requesting access to. +4. Flyte will send a POST request to ApiServer to create the object. +5. Before persisting the Pod, ApiServer will invoke all registered Pod Webhooks. Flyte's Pod Webhook will be called. +6. Flyte Pod Webhook will then lookup globally mounted secrets for each of the requested secrets. +7. If found, Pod Webhook will mount them directly in the Pod. If not found, it will inject the appropriate annotations to load the secrets for K8s (or Vault or Confidant or any other secret management system plugin configured) into the Pod. + +****************************** +How to Enable Secret Injection +****************************** + +This feature is available in Flytekit v0.17.0+. Here is an example of an annotated task: + +The webhook is included in all overlays in this repo. The deployment file creates (mainly) two things; a Job and a Deployment. + +1) flyte-pod-webhook-secrets Job: This job runs ``flytepropeller webhook init-certs`` command that issues self-signed + CA Certificate as well as a derived TLS certificate and its private key. It stores them into a new secret ``flyte-pod-webhook-secret``. +2) flyte-pod-webhook Deployment: This deployment creates the Webhook pod which creates a MutatingWebhookConfiguration + on startup. This serves as the registration contract with the ApiServer to know about the Webhook before it starts serving + traffic. + +******************* +Scaling the Webhook +******************* + +Vertical Scaling +================= + +To scale the Webhook to be able to process the number/rate of pods you need, you may need to configure a vertical `pod +autoscaler `_. + +Horizontal Scaling +================== + +The Webhook does not make any external API Requests in response to Pod mutation requests. It should be able to handle traffic +quickly, but a benchmark is needed. For horizontal scaling, adding additional replicas for the Pod in the +deployment should be sufficient. A single MutatingWebhookConfiguration object will be used, the same TLS certificate +will be shared across the pods and the Service created will automatically load balance traffic across the available pods.