From d1c10ca6d734686a2c029bc92b392731c1ef974c Mon Sep 17 00:00:00 2001 From: system Date: Thu, 7 Aug 2025 08:38:03 +0000 Subject: [PATCH] Update values --- kubeflow/CUSTOM-README.md | 59 + kubeflow/LICENSE | 201 + kubeflow/OWNERS | 11 + kubeflow/README.md | 708 + .../upstream/base/cluster-role-binding.yaml | 11 + .../upstream/base/cluster-role.yaml | 65 + .../admission-webhook/upstream/base/crd.yaml | 2066 + .../upstream/base/deployment.yaml | 25 + .../upstream/base/kustomization.yaml | 52 + .../base/mutating-webhook-configuration.yaml | 28 + .../upstream/base/params.yaml | 19 + .../upstream/base/service-account.yaml | 4 + .../upstream/base/service.yaml | 9 + .../overlays/cert-manager/certificate.yaml | 23 + .../overlays/cert-manager/deployment.yaml | 12 + .../overlays/cert-manager/kustomization.yaml | 47 + .../mutating-webhook-configuration.yaml | 7 + .../overlays/cert-manager/params.yaml | 16 + .../overlays/oauth2-proxy/kustomization.yaml | 9 + .../upstream/base/clusterrole-binding.yaml | 14 + .../upstream/base/clusterrole.yaml | 17 + .../upstream/base/configmap.yaml | 120 + .../upstream/base/deployment.yaml | 50 + .../upstream/base/kustomization.yaml | 83 + .../centraldashboard/upstream/base/params.env | 5 + .../upstream/base/role-binding.yaml | 14 + .../centraldashboard/upstream/base/role.yaml | 26 + .../upstream/base/service-account.yaml | 4 + .../upstream/base/service.yaml | 15 + .../overlays/istio/authorizationpolicy.yaml | 14 + .../overlays/istio/kustomization.yaml | 49 + .../upstream/overlays/istio/params.yaml | 3 + .../overlays/istio/virtual-service.yaml | 20 + .../overlays/kserve/kustomization.yaml | 13 + .../overlays/kserve/patches/configmap.yaml | 132 + .../upstream/base/cluster-role-binding.yaml | 11 + .../upstream/base/cluster-role.yaml | 114 + .../base/configs/logos-configmap.yaml | 191 + .../base/configs/spawner_ui_config.yaml | 309 + .../upstream/base/deployment.yaml | 39 + .../upstream/base/kustomization.yaml | 92 + .../jupyter-web-app/upstream/base/params.env | 7 + .../upstream/base/role-binding.yaml | 11 + .../jupyter-web-app/upstream/base/role.yaml | 48 + .../upstream/base/service-account.yaml | 4 + .../upstream/base/service.yaml | 13 + .../overlays/istio/authorization-policy.yaml | 14 + .../overlays/istio/destination-rule.yaml | 9 + .../overlays/istio/kustomization.yaml | 13 + .../upstream/overlays/istio/params.yaml | 3 + .../overlays/istio/virtual-service.yaml | 24 + .../notebook-controller/upstream/README.md | 30 + .../upstream/base/kustomization.yaml | 8 + .../crd/bases/kubeflow.org_notebooks.yaml | 9410 +++ .../upstream/crd/kustomization.yaml | 32 + .../upstream/crd/kustomizeconfig.yaml | 17 + .../crd/patches/cainjection_in_notebooks.yaml | 8 + .../crd/patches/trivial_conversion_patch.yaml | 9 + .../crd/patches/validation_patches.yaml | 29 + .../crd/patches/webhook_in_notebooks.yaml | 17 + .../upstream/default/kustomization.yaml | 75 + .../default/manager_auth_proxy_patch.yaml | 25 + .../upstream/default/manager_image_patch.yaml | 12 + .../manager_prometheus_metrics_patch.yaml | 19 + .../default/manager_webhook_patch.yaml | 23 + .../default/webhookcainjection_patch.yaml | 15 + .../upstream/manager/kustomization.yaml | 8 + .../upstream/manager/manager.yaml | 73 + .../upstream/manager/params.env | 7 + .../upstream/manager/service-account.yaml | 4 + .../upstream/manager/service.yaml | 13 + .../overlays/kubeflow/kustomization.yaml | 13 + .../kubeflow/patches/remove-namespace.yaml | 5 + .../overlays/standalone/kustomization.yaml | 10 + .../upstream/rbac/auth_proxy_role.yaml | 13 + .../rbac/auth_proxy_role_binding.yaml | 11 + .../upstream/rbac/auth_proxy_service.yaml | 18 + .../upstream/rbac/kustomization.yaml | 12 + .../upstream/rbac/leader_election_role.yaml | 32 + .../rbac/leader_election_role_binding.yaml | 11 + .../upstream/rbac/role.yaml | 51 + .../upstream/rbac/role_binding.yaml | 11 + .../upstream/rbac/user_cluster_roles.yaml | 55 + .../upstream/samples/_v1_notebook.yaml | 11 + .../upstream/samples/_v1alpha1_notebook.yaml | 11 + .../upstream/samples/_v1beta1_notebook.yaml | 11 + .../components/controller/controller.yaml | 68 + .../components/controller/kustomization.yaml | 9 + .../upstream/components/controller/rbac.yaml | 149 + .../components/controller/service.yaml | 26 + .../controller/trial-templates.yaml | 77 + .../upstream/components/crd/experiment.yaml | 36 + .../components/crd/kustomization.yaml | 8 + .../upstream/components/crd/suggestion.yaml | 42 + .../katib/upstream/components/crd/trial.yaml | 36 + .../components/db-manager/db-manager.yaml | 41 + .../components/db-manager/kustomization.yaml | 7 + .../components/db-manager/service.yaml | 16 + .../components/mysql/kustomization.yaml | 9 + .../upstream/components/mysql/mysql.yaml | 73 + .../katib/upstream/components/mysql/pvc.yaml | 12 + .../upstream/components/mysql/secret.yaml | 8 + .../upstream/components/mysql/service.yaml | 16 + .../components/namespace/kustomization.yaml | 7 + .../components/namespace/namespace.yaml | 7 + .../components/postgres/kustomization.yaml | 9 + .../components/postgres/postgres.yaml | 42 + .../upstream/components/postgres/pvc.yaml | 12 + .../upstream/components/postgres/secret.yaml | 10 + .../upstream/components/postgres/service.yaml | 16 + .../upstream/components/ui/kustomization.yaml | 8 + .../katib/upstream/components/ui/rbac.yaml | 52 + .../katib/upstream/components/ui/service.yaml | 17 + .../apps/katib/upstream/components/ui/ui.yaml | 35 + .../components/webhook/kustomization.yaml | 6 + .../upstream/components/webhook/webhooks.yaml | 74 + .../katib-cert-manager/certificate.yaml | 22 + .../katib-cert-manager/katib-config.yaml | 58 + .../katib-cert-manager/kustomization.yaml | 69 + .../installs/katib-cert-manager/params.yaml | 19 + .../patches/katib-cert-injection.yaml | 14 + .../katib-external-db/katib-config.yaml | 60 + .../katib-external-db/kustomization.yaml | 45 + .../katib-external-db/patches/db-manager.yaml | 39 + .../installs/katib-external-db/secrets.env | 5 + .../katib-leader-election/katib-config.yaml | 61 + .../katib-leader-election/kustomization.yaml | 18 + .../leader-election-rbac.yaml | 27 + .../katib-openshift/katib-config.yaml | 58 + .../katib-openshift/kustomization.yaml | 72 + .../patches/service-serving-cert.yaml | 4 + .../patches/webhook-inject-cabundle.yaml | 5 + .../katib-config.yaml | 60 + .../kustomization.yaml | 48 + .../patches/db-manager.yaml | 8 + .../katib-standalone/katib-config.yaml | 59 + .../katib-standalone/kustomization.yaml | 41 + .../istio-authorizationpolicy.yaml | 15 + .../kubeflow-katib-roles.yaml | 66 + .../katib-with-kubeflow/kustomization.yaml | 56 + .../installs/katib-with-kubeflow/params.yaml | 4 + .../patches/enable-ui-authz-checks.yaml | 6 + .../patches/istio-sidecar-injection.yaml | 10 + .../patches/remove-namespace.yaml | 6 + .../katib-with-kubeflow/patches/ui-rbac.yaml | 7 + .../ui-virtual-service.yaml | 21 + kubeflow/apps/kserve/Makefile | 56 + kubeflow/apps/kserve/OWNERS | 2 + kubeflow/apps/kserve/README.md | 120 + kubeflow/apps/kserve/UPGRADE.md | 68 + kubeflow/apps/kserve/assets/kserve.png | Bin 0 -> 472792 bytes kubeflow/apps/kserve/assets/kserve_new.png | Bin 0 -> 101325 bytes .../apps/kserve/kserve/aggregated-roles.yaml | 89 + .../kserve/kserve-cluster-resources.yaml | 651 + kubeflow/apps/kserve/kserve/kserve.yaml | 33452 +++++++++ .../apps/kserve/kserve/kserve_kubeflow.yaml | 33329 +++++++++ .../apps/kserve/kserve/kustomization.yaml | 42 + kubeflow/apps/kserve/kserve/params.env | 1 + .../models-web-app/base/deployment.yaml | 54 + .../kserve/models-web-app/base/istio.yaml | 21 + .../models-web-app/base/kustomization.yaml | 24 + .../apps/kserve/models-web-app/base/rbac.yaml | 68 + .../kserve/models-web-app/base/service.yaml | 14 + .../overlays/kubeflow/kustomization.yaml | 43 + .../overlays/kubeflow/params.yaml | 4 + .../kubeflow/patches/web-app-sidecar.yaml | 10 + .../kubeflow/patches/web-app-vsvc.yaml | 14 + .../web-app-authorization-policy.yaml | 18 + kubeflow/apps/model-registry/upstream/OWNERS | 8 + .../apps/model-registry/upstream/README.md | 128 + .../upstream/base/kustomization.yaml | 11 + .../base/model-registry-configmap.yaml | 12 + .../base/model-registry-deployment.yaml | 121 + .../upstream/base/model-registry-sa.yaml | 4 + .../upstream/base/model-registry-service.yaml | 27 + .../controller/default/kustomization.yaml | 177 + .../default/manager_metrics_patch.yaml | 4 + .../controller/default/metrics_service.yaml | 17 + .../controller/manager/kustomization.yaml | 2 + .../options/controller/manager/manager.yaml | 103 + .../network-policy/allow-metrics-traffic.yaml | 26 + .../network-policy/kustomization.yaml | 2 + .../overlays/base/kustomization.yaml | 14 + .../controller/overlays/base/params.env | 11 + .../overlays/base/replacements.yaml | 110 + .../controller/prometheus/kustomization.yaml | 2 + .../controller/prometheus/monitor.yaml | 30 + .../controller/rbac/kustomization.yaml | 20 + .../controller/rbac/leader_election_role.yaml | 40 + .../rbac/leader_election_role_binding.yaml | 15 + .../controller/rbac/metrics_auth_role.yaml | 17 + .../rbac/metrics_auth_role_binding.yaml | 12 + .../controller/rbac/metrics_reader_role.yaml | 9 + .../options/controller/rbac/role.yaml | 36 + .../options/controller/rbac/role_binding.yaml | 15 + .../controller/rbac/service_account.yaml | 8 + .../options/csi/clusterstoragecontainer.yaml | 19 + .../upstream/options/csi/kustomization.yaml | 10 + .../options/istio/destination-rule.yaml | 9 + .../istio/istio-authorization-policy.yaml | 11 + .../upstream/options/istio/kustomization.yaml | 8 + .../options/istio/virtual-service.yaml | 29 + .../options/ui/base/kustomization.yaml | 13 + .../ui/base/model-registry-ui-deployment.yaml | 60 + .../ui/base/model-registry-ui-role.yaml | 76 + .../model-registry-ui-service-account.yaml | 5 + .../ui/base/model-registry-ui-service.yaml | 16 + .../ui/overlays/integrated/kustomization.yaml | 13 + .../model-registry-ui-deployment.yaml | 5 + .../istio/authorization-policy-ui.yaml | 16 + .../overlays/istio/destination-rule-ui.yaml | 11 + .../ui/overlays/istio/kustomization.yaml | 17 + .../istio/model-registry-ui-service.yaml | 3 + .../ui/overlays/istio/virtual-service.yaml | 26 + .../standalone/kubeflow-dashboard-rbac.yaml | 39 + .../ui/overlays/standalone/kustomization.yaml | 14 + .../model-registry-ui-deployment.yaml | 5 + .../upstream/overlays/db/kustomization.yaml | 45 + .../db/model-registry-db-deployment.yaml | 62 + .../overlays/db/model-registry-db-pvc.yaml | 10 + .../db/model-registry-db-service.yaml | 14 + .../upstream/overlays/db/params.env | 3 + .../db/patches/model-registry-deployment.yaml | 42 + .../upstream/overlays/db/secrets.env | 2 + .../overlays/postgres/kustomization.yaml | 45 + .../model-registry-db-deployment.yaml | 52 + .../postgres/model-registry-db-pvc.yaml | 10 + .../postgres/model-registry-db-service.yaml | 14 + .../upstream/overlays/postgres/params.env | 2 + .../patches/model-registry-deployment.yaml | 32 + .../upstream/overlays/postgres/secrets.env | 2 + kubeflow/apps/pipeline/upstream/Makefile | 23 + kubeflow/apps/pipeline/upstream/OWNERS | 6 + kubeflow/apps/pipeline/upstream/README.md | 103 + .../base/application/application.yaml | 49 + .../base/application/kustomization.yaml | 4 + .../cache-deployer-deployment.yaml | 29 + .../cache-deployer/cache-deployer-role.yaml | 17 + .../cache-deployer-rolebinding.yaml | 11 + .../cache-deployer-clusterrole.yaml | 35 + .../cache-deployer-clusterrolebinding.yaml | 12 + .../cluster-scoped/cache-deployer-sa.yaml | 4 + .../cluster-scoped/kustomization.yaml | 11 + .../base/cache-deployer/kustomization.yaml | 13 + .../upstream/base/cache/cache-deployment.yaml | 108 + .../upstream/base/cache/cache-role.yaml | 33 + .../base/cache/cache-rolebinding.yaml | 11 + .../upstream/base/cache/cache-sa.yaml | 4 + .../upstream/base/cache/cache-service.yaml | 10 + .../upstream/base/cache/kustomization.yaml | 15 + .../upstream/base/crds/kustomization.yaml | 5 + .../pipelines.kubeflow.org_pipelines.yaml | 49 + ...pelines.kubeflow.org_pipelineversions.yaml | 89 + .../base/installs/generic/kustomization.yaml | 47 + .../base/installs/generic/mysql-secret.yaml | 7 + .../base/installs/generic/params.yaml | 10 + .../generic/pipeline-install-config.yaml | 96 + .../generic/postgres/kustomization.yaml | 47 + .../installs/generic/postgres/params.yaml | 10 + .../postgres/pipeline-install-config.yaml | 95 + .../postgres/postgres-secret-extended.yaml | 7 + .../api-service/cluster-role-binding.yaml | 11 + .../multi-user/api-service/cluster-role.yaml | 63 + .../api-service/deployment-patch.yaml | 17 + .../multi-user/api-service/kustomization.yaml | 9 + .../multi-user/api-service/params.env | 4 + .../cache/cluster-role-binding.yaml | 11 + .../multi-user/cache/cluster-role.yaml | 31 + .../multi-user/cache/deployment-patch.yaml | 13 + .../multi-user/cache/kustomization.yaml | 9 + .../istio-authorization-config.yaml | 113 + .../installs/multi-user/kustomization.yaml | 35 + .../metadata-writer/cluster-role-binding.yaml | 11 + .../metadata-writer/cluster-role.yaml | 31 + .../metadata-writer/deployment-patch.yaml | 13 + .../metadata-writer/kustomization.yaml | 5 + .../base/installs/multi-user/params.yaml | 4 + .../cluster-role-binding.yaml | 11 + .../persistence-agent/cluster-role.yaml | 35 + .../persistence-agent/deployment-patch.yaml | 13 + .../persistence-agent/kustomization.yaml | 5 + .../decorator-controller.yaml | 41 + .../deployment.yaml | 59 + .../kustomization.yaml | 18 + .../pipelines-profile-controller/params.env | 1 + .../requirements-dev.txt | 3 + .../pipelines-profile-controller/run_tests.sh | 9 + .../pipelines-profile-controller/service.yaml | 10 + .../pipelines-profile-controller/sync.py | 395 + .../pipelines-profile-controller/test_sync.py | 286 + .../pipelines-ui/cluster-role-binding.yaml | 11 + .../multi-user/pipelines-ui/cluster-role.yaml | 42 + .../pipelines-ui/configmap-patch.yaml | 13 + .../pipelines-ui/deployment-patch.yaml | 34 + .../pipelines-ui/kustomization.yaml | 10 + .../cluster-role-binding.yaml | 11 + .../scheduled-workflow/cluster-role.yaml | 43 + .../scheduled-workflow/deployment-patch.yaml | 13 + .../scheduled-workflow/kustomization.yaml | 6 + .../multi-user/view-edit-cluster-roles.yaml | 142 + .../cluster-role-binding.yaml | 11 + .../viewer-controller/cluster-role.yaml | 31 + .../viewer-controller/deployment-patch.yaml | 13 + .../viewer-controller/kustomization.yaml | 5 + .../installs/multi-user/virtual-service.yaml | 21 + .../base/metadata/base/kustomization.yaml | 13 + .../base/metadata-envoy-deployment.yaml | 35 + .../metadata/base/metadata-envoy-service.yaml | 14 + .../base/metadata-grpc-configmap.yaml | 9 + .../base/metadata-grpc-deployment.yaml | 90 + .../base/metadata/base/metadata-grpc-sa.yaml | 4 + .../metadata/base/metadata-grpc-service.yaml | 14 + .../options/istio/destination-rule.yaml | 9 + .../istio/istio-authorization-policy.yaml | 11 + .../metadata/options/istio/kustomization.yaml | 7 + .../options/istio/virtual-service.yaml | 21 + .../metadata/overlays/db/kustomization.yaml | 38 + .../overlays/db/metadata-db-deployment.yaml | 50 + .../metadata/overlays/db/metadata-db-pvc.yaml | 10 + .../overlays/db/metadata-db-service.yaml | 14 + .../base/metadata/overlays/db/params.env | 3 + .../db/patches/metadata-grpc-deployment.yaml | 25 + .../base/metadata/overlays/db/secrets.env | 2 + .../overlays/postgres/kustomization.yaml | 37 + .../postgres/metadata-db-deployment.yaml | 41 + .../overlays/postgres/metadata-db-pvc.yaml | 10 + .../postgres/metadata-db-service.yaml | 14 + .../metadata/overlays/postgres/params.env | 2 + .../patches/metadata-grpc-deployment.yaml | 28 + .../metadata/overlays/postgres/secrets.env | 2 + .../cluster-scoped/kustomization.yaml | 5 + .../scheduled-workflow-crd.yaml | 39 + .../pipeline/cluster-scoped/viewer-crd.yaml | 34 + .../base/pipeline/container-builder-sa.yaml | 4 + .../base/pipeline/kfp-launcher-configmap.yaml | 6 + .../upstream/base/pipeline/kustomization.yaml | 49 + .../metadata-writer/kustomization.yaml | 10 + .../metadata-writer-deployment.yaml | 37 + .../metadata-writer/metadata-writer-role.yaml | 33 + .../metadata-writer-rolebinding.yaml | 11 + .../metadata-writer/metadata-writer-sa.yaml | 4 + .../ml-pipeline-apiserver-deployment.yaml | 184 + .../pipeline/ml-pipeline-apiserver-role.yaml | 65 + .../ml-pipeline-apiserver-rolebinding.yaml | 13 + .../pipeline/ml-pipeline-apiserver-sa.yaml | 4 + .../ml-pipeline-apiserver-service.yaml | 20 + ...-pipeline-persistenceagent-deployment.yaml | 59 + .../ml-pipeline-persistenceagent-role.yaml | 35 + ...pipeline-persistenceagent-rolebinding.yaml | 11 + .../ml-pipeline-persistenceagent-sa.yaml | 4 + ...pipeline-scheduledworkflow-deployment.yaml | 56 + .../ml-pipeline-scheduledworkflow-role.yaml | 45 + ...ipeline-scheduledworkflow-rolebinding.yaml | 11 + .../ml-pipeline-scheduledworkflow-sa.yaml | 4 + .../pipeline/ml-pipeline-ui-configmap.yaml | 11 + .../pipeline/ml-pipeline-ui-deployment.yaml | 98 + .../base/pipeline/ml-pipeline-ui-role.yaml | 45 + .../pipeline/ml-pipeline-ui-rolebinding.yaml | 13 + .../base/pipeline/ml-pipeline-ui-sa.yaml | 4 + .../base/pipeline/ml-pipeline-ui-service.yaml | 14 + .../ml-pipeline-viewer-crd-deployment.yaml | 40 + .../pipeline/ml-pipeline-viewer-crd-role.yaml | 31 + .../ml-pipeline-viewer-crd-rolebinding.yaml | 11 + .../pipeline/ml-pipeline-viewer-crd-sa.yaml | 4 + .../ml-pipeline-visualization-deployment.yaml | 64 + .../ml-pipeline-visualization-sa.yaml | 4 + .../ml-pipeline-visualization-service.yaml | 12 + .../base/pipeline/pipeline-runner-role.yaml | 80 + .../pipeline/pipeline-runner-rolebinding.yaml | 11 + .../base/pipeline/pipeline-runner-sa.yaml | 4 + .../upstream/base/pipeline/viewer-sa.yaml | 4 + .../cache/cache-deployment-patch.yaml | 75 + .../base/postgresql/cache/kustomization.yaml | 6 + .../postgresql/pipeline/kustomization.yaml | 6 + ...l-pipeline-apiserver-deployment-patch.yaml | 74 + .../upstream/base/webhook/kustomization.yaml | 10 + .../upstream/base/webhook/params.yaml | 13 + ...pelineversion-mutating-webhook-config.yaml | 27 + ...lineversion-validating-webhook-config.yaml | 27 + .../kustomization.yaml | 26 + .../cluster-scoped-resources/namespace.yaml | 4 + .../cluster-scoped-resources/params.yaml | 4 + .../apps/pipeline/upstream/env/aws/OWNERS | 3 + .../apps/pipeline/upstream/env/aws/README.md | 56 + .../aws/aws-configuration-pipeline-patch.yaml | 32 + .../aws-configuration-pipeline-ui-patch.yaml | 27 + .../apps/pipeline/upstream/env/aws/config | 20 + .../upstream/env/aws/kustomization.yaml | 39 + .../env/aws/minio-artifact-secret-patch.env | 2 + .../apps/pipeline/upstream/env/aws/params.env | 5 + .../apps/pipeline/upstream/env/aws/secret.env | 2 + .../upstream/env/aws/viewer-pod-template.json | 37 + .../apps/pipeline/upstream/env/azure/OWNERS | 4 + .../upstream/env/azure/kustomization.yaml | 29 + .../minio-azure-gateway/kustomization.yaml | 14 + .../minio-artifact-secret.env | 2 + .../minio-azure-gateway-deployment.yaml | 40 + .../minio-azure-gateway-service.yaml | 11 + .../upstream/env/azure/mysql-secret.env | 2 + .../pipeline/upstream/env/azure/params.env | 1 + .../pipeline/upstream/env/azure/readme.md | 15 + .../kfp-api-cert-issuer.yaml | 6 + .../base-webhook-certs/kfp-api-cert.yaml | 15 + .../base-webhook-certs/kustomization.yaml | 13 + .../base-webhook-certs/params.yaml | 7 + .../cert-manager/base/cache-cert-issuer.yaml | 6 + .../env/cert-manager/base/cache-cert.yaml | 15 + .../base/cache-webhook-config.yaml | 25 + .../env/cert-manager/base/kustomization.yaml | 15 + .../env/cert-manager/base/params.yaml | 13 + .../kustomization.yaml | 7 + .../dev/delete-cache-deployer.yaml | 18 + .../env/cert-manager/dev/kustomization.yaml | 44 + .../env/cert-manager/dev/namespace.yaml | 4 + .../upstream/env/cert-manager/dev/params.yaml | 4 + .../kustomization.yaml | 30 + .../patches/deployment.yaml | 29 + .../patches/mutating-webhook.yaml | 6 + .../patches/service.yaml | 10 + .../patches/validating-webhook.yaml | 6 + .../kustomization.yaml | 30 + .../patches/deployment.yaml | 30 + .../patches/mutating-webhook.yaml | 6 + .../patches/service.yaml | 10 + .../patches/validating-webhook.yaml | 6 + .../kustomization.yaml | 31 + .../delete.clusterrole.cache-deployer.yaml | 6 + .../patches/delete.crb.cache-deployer.yaml | 6 + .../delete.deployment.cache-deployer.yaml | 6 + .../patches/delete.role.cache-deployer.yaml | 6 + .../delete.rolebinding.cache-deployer.yaml | 6 + .../patches/delete.sa.cache-deployer.yaml | 6 + .../dev-kind/forward-local-api-endpoint.yaml | 21 + .../upstream/env/dev-kind/kustomization.yaml | 166 + .../upstream/env/dev/kustomization.yaml | 20 + .../env/dev/postgresql/kustomization.yaml | 21 + .../cloudsql-proxy-deployment.yaml | 89 + .../gcp/cloudsql-proxy/cloudsql-proxy-sa.yaml | 4 + .../env/gcp/cloudsql-proxy/kustomization.yaml | 7 + .../env/gcp/cloudsql-proxy/mysql-service.yaml | 9 + .../env/gcp/gcp-configurations-patch.yaml | 36 + .../env/gcp/inverse-proxy/kustomization.yaml | 11 + .../gcp/inverse-proxy/proxy-configmap.yaml | 4 + .../gcp/inverse-proxy/proxy-deployment.yaml | 21 + .../env/gcp/inverse-proxy/proxy-role.yaml | 13 + .../gcp/inverse-proxy/proxy-rolebinding.yaml | 13 + .../env/gcp/inverse-proxy/proxy-sa.yaml | 4 + .../upstream/env/gcp/kustomization.yaml | 36 + .../gcp/minio-gcs-gateway/kustomization.yaml | 15 + .../minio-artifact-secret.env | 2 + .../minio-gcs-gateway-deployment.yaml | 47 + .../minio-gcs-gateway-sa.yaml | 4 + .../minio-gcs-gateway-service.yaml | 11 + .../apps/pipeline/upstream/env/gcp/params.env | 6 + .../env/plain-multi-user/kustomization.yaml | 25 + .../upstream/env/plain/kustomization.yaml | 20 + .../kustomization.yaml | 4 + .../kustomization.yaml | 4 + .../kustomization.yaml | 26 + .../kustomization.yaml | 26 + .../kustomization.yaml | 22 + .../env/platform-agnostic/kustomization.yaml | 21 + .../upstream/gcp-workload-identity-setup.sh | 202 + .../apps/pipeline/upstream/hack/format.sh | 39 + .../apps/pipeline/upstream/hack/presubmit.sh | 57 + .../apps/pipeline/upstream/hack/release.sh | 53 + kubeflow/apps/pipeline/upstream/hack/test.sh | 57 + .../apps/pipeline/upstream/sample/README.md | 77 + .../kustomization.yaml | 10 + .../upstream/sample/kustomization.yaml | 38 + .../upstream/sample/params-db-secret.env | 2 + .../apps/pipeline/upstream/sample/params.env | 4 + .../application-controller-deployment.yaml | 38 + .../application-controller-role.yaml | 21 + .../application-controller-rolebinding.yaml | 11 + .../application-controller-sa.yaml | 4 + .../application-controller-service.yaml | 13 + .../cluster-scoped/application-crd.yaml | 531 + .../cluster-scoped/kustomization.yaml | 9 + .../application/kustomization.yaml | 9 + .../upstream/third-party/argo/.krmignore | 1 + .../upstream/third-party/argo/Kptfile | 6 + .../upstream/third-party/argo/Makefile | 12 + .../upstream/third-party/argo/README.md | 35 + .../third-party/argo/base/kustomization.yaml | 14 + .../third-party/argo/base/params.yaml | 3 + .../workflow-controller-configmap-patch.yaml | 38 + .../workflow-controller-deployment-patch.yaml | 23 + .../argo/installs/cluster/kustomization.yaml | 18 + ...w-controller-clusterrolebinding-patch.json | 7 + .../cluster-scoped/kustomization.yaml | 5 + .../installs/namespace/kustomization.yaml | 18 + .../workflow-controller-deployment-patch.json | 7 + .../argo/upstream/manifests/Kptfile | 18 + .../argo/upstream/manifests/LICENSE | 202 + .../argo-server/argo-server-deployment.yaml | 48 + .../base/argo-server/argo-server-sa.yaml | 6 + .../base/argo-server/argo-server-service.yaml | 13 + .../base/argo-server/kustomization.yaml | 6 + .../manifests/base/crds/full/README.md | 3 + .../argoproj.io_clusterworkflowtemplates.yaml | 19154 ++++++ .../crds/full/argoproj.io_cronworkflows.yaml | 19219 ++++++ .../argoproj.io_workflowartifactgctasks.yaml | 1014 + .../argoproj.io_workfloweventbindings.yaml | 619 + .../base/crds/full/argoproj.io_workflows.yaml | 49299 ++++++++++++++ .../full/argoproj.io_workflowtaskresults.yaml | 600 + .../full/argoproj.io_workflowtasksets.yaml | 8803 +++ .../full/argoproj.io_workflowtemplates.yaml | 19153 ++++++ .../base/crds/full/kustomization.yaml | 11 + .../manifests/base/crds/kustomization.yaml | 4 + .../manifests/base/crds/minimal/README.md | 3 + .../argoproj.io_clusterworkflowtemplates.yaml | 38 + .../minimal/argoproj.io_cronworkflows.yaml | 42 + .../argoproj.io_workflowartifactgctasks.yaml | 43 + .../argoproj.io_workfloweventbindings.yaml | 37 + .../crds/minimal/argoproj.io_workflows.yaml | 56 + .../argoproj.io_workflowtaskresults.yaml | 599 + .../minimal/argoproj.io_workflowtasksets.yaml | 43 + .../argoproj.io_workflowtemplates.yaml | 37 + .../base/crds/minimal/kustomization.yaml | 11 + .../manifests/base/kustomization.yaml | 6 + .../workflow-controller/kustomization.yaml | 7 + .../workflow-controller-configmap.yaml | 6 + .../workflow-controller-deployment.yaml | 53 + .../workflow-controller-priorityclass.yaml | 7 + .../workflow-controller-sa.yaml | 6 + .../argo-server-clusterole.yaml | 67 + .../argo-server-clusterolebinding.yaml | 13 + .../argo-server-rbac/kustomization.yaml | 5 + .../cluster-install/kustomization.yaml | 7 + .../kustomization.yaml | 8 + .../workflow-aggregate-roles.yaml | 98 + .../workflow-controller-clusterrole.yaml | 115 + ...orkflow-controller-clusterrolebinding.yaml | 13 + .../workflow-controller-role.yaml | 21 + .../workflow-controller-rolebinding.yaml | 13 + .../argo-server-rbac/argo-server-role.yaml | 67 + .../argo-server-rolebinding.yaml | 13 + .../argo-server-rbac/kustomization.yaml | 5 + .../namespace-install/kustomization.yaml | 19 + .../overlays/argo-server-deployment.yaml | 3 + .../workflow-controller-deployment.yaml | 3 + .../kustomization.yaml | 5 + .../workflow-controller-role.yaml | 119 + .../workflow-controller-rolebinding.yaml | 13 + .../base/agent-default-rolebinding.yaml | 13 + .../quick-start/base/agent-role.yaml | 25 + .../base/argo-server-sso-secret.yaml | 9 + .../base/artifact-repositories-configmap.yaml | 35 + .../base/artifactgc-default-rolebinding.yaml | 13 + .../quick-start/base/artifactgc-role.yaml | 23 + .../base/cluster-workflow-template-rbac.yaml | 66 + .../default.service-account-token-secret.yaml | 8 + .../base/executor-default-rolebinding.yaml | 13 + .../base/executor/docker/executor-role.yaml | 19 + .../base/executor/emissary/executor-role.yaml | 16 + .../base/executor/k8sapi/executor-role.yaml | 38 + .../base/executor/kubelet/executor-role.yaml | 19 + .../kubelet/kubelet-executor-clusterrole.yaml | 15 + ...t-executor-default-clusterrolebinding.yaml | 15 + .../base/executor/pns/executor-role.yaml | 29 + .../base/httpbin/httpbin-deploy.yaml | 36 + .../base/httpbin/httpbin-service.yaml | 16 + .../base/httpbin/kustomization.yaml | 6 + .../base/httpbin/my-httpbin-cred-secret.yaml | 99 + .../quick-start/base/kustomization.yaml | 24 + .../base/memoizer-default-rolebinding.yaml | 13 + .../quick-start/base/memoizer-role.yaml | 17 + .../quick-start/base/minio/kustomization.yaml | 6 + .../quick-start/base/minio/minio-deploy.yaml | 48 + .../quick-start/base/minio/minio-service.yaml | 20 + .../base/minio/my-minio-cred-secret.yaml | 12 + .../base/overlays/argo-server-deployment.yaml | 17 + .../workflow-controller-configmap.yaml | 54 + .../base/pod-manager-default-rolebinding.yaml | 13 + .../quick-start/base/pod-manager-role.yaml | 18 + .../base/prometheus/kustomization.yaml | 6 + .../prometheus/prometheus-config-cluster.yaml | 14 + .../prometheus/prometheus-deployment.yaml | 37 + .../base/prometheus/prometheus-service.yaml | 12 + ...argo-workflows-webhook-clients-secret.yaml | 24 + .../base/webhooks/github.com-rolebinding.yaml | 14 + .../base/webhooks/github.com-sa.yaml | 6 + .../base/webhooks/github.com-secret.yaml | 8 + .../base/webhooks/kustomization.yaml | 8 + .../submit-workflow-template-role.yaml | 27 + .../base/workflow-default-rolebinding.yaml | 13 + .../workflow-manager-default-rolebinding.yaml | 13 + .../base/workflow-manager-role.yaml | 17 + .../quick-start/minimal/kustomization.yaml | 6 + .../workflow-controller-configmap.yaml | 11 + .../mysql/argo-mysql-config-secret.yaml | 12 + .../quick-start/mysql/kustomization.yaml | 9 + .../quick-start/mysql/mysql-deployment.yaml | 40 + .../quick-start/mysql/mysql-service.yaml | 15 + .../workflow-controller-configmap.yaml | 30 + .../postgres/argo-postgres-config-secret.yaml | 12 + .../quick-start/postgres/kustomization.yaml | 9 + .../workflow-controller-configmap.yaml | 30 + .../postgres/postgres-deployment.yaml | 33 + .../postgres/postgres-service.yaml | 15 + .../quick-start/sso/dex/dev-svc.yaml | 12 + .../manifests/quick-start/sso/dex/dex-cm.yaml | 36 + .../quick-start/sso/dex/dex-deploy.yaml | 35 + .../manifests/quick-start/sso/dex/dex-rb.yaml | 13 + .../quick-start/sso/dex/dex-role.yaml | 16 + .../manifests/quick-start/sso/dex/dex-sa.yaml | 6 + .../quick-start/sso/dex/kustomization.yaml | 13 + .../quick-start/sso/kustomization.yaml | 8 + .../sso/overlays/argo-server-sa.yaml | 8 + .../workflow-controller-configmap.yaml | 23 + .../grafana/grafana-deployment.yaml | 60 + .../third-party/grafana/grafana-role.yaml | 19 + .../grafana/grafana-rolebinding.yaml | 13 + .../third-party/grafana/grafana-sa.yaml | 4 + .../third-party/grafana/grafana-service.yaml | 14 + .../third-party/grafana/kustomization.yaml | 11 + .../base/cluster-role-binding.yaml | 11 + .../metacontroller/base/cluster-role.yaml | 32 + .../third-party/metacontroller/base/crd.yaml | 827 + .../metacontroller/base/kustomization.yaml | 17 + .../metacontroller/base/service-account.yaml | 4 + .../metacontroller/base/stateful-set.yaml | 54 + .../third-party/minio/base/kustomization.yaml | 9 + .../minio/base/minio-deployment.yaml | 63 + .../third-party/minio/base/minio-pvc.yaml | 10 + .../third-party/minio/base/minio-service.yaml | 12 + .../mlpipeline-minio-artifact-secret.yaml | 7 + .../istio/istio-authorization-policy.yaml | 30 + .../minio/options/istio/kustomization.yaml | 5 + .../third-party/mysql/base/kustomization.yaml | 9 + .../mysql/base/mysql-deployment.yaml | 79 + .../mysql/base/mysql-pv-claim.yaml | 10 + .../third-party/mysql/base/mysql-service.yaml | 12 + .../mysql/base/mysql-serviceaccount.yaml | 5 + .../istio/istio-authorization-policy.yaml | 32 + .../mysql/options/istio/kustomization.yaml | 5 + .../upstream/third-party/postgresql/README.md | 15 + .../postgresql/base/kustomization.yaml | 8 + .../postgresql/base/pg-deployment.yaml | 48 + .../third-party/postgresql/base/pg-pvc.yaml | 12 + .../postgresql/base/pg-secret.yaml | 7 + .../postgresql/base/pg-service.yaml | 13 + .../postgresql/base/pg-serviceaccount.yaml | 4 + .../third-party/prometheus/kustomization.yaml | 11 + .../prometheus/prometheus-configmap.yaml | 31 + .../prometheus/prometheus-deployment.yaml | 34 + .../prometheus/prometheus-role.yaml | 19 + .../prometheus/prometheus-rolebinding.yaml | 13 + .../third-party/prometheus/prometheus-sa.yaml | 4 + .../prometheus/prometheus-service.yaml | 14 + kubeflow/apps/pipeline/upstream/wi-utils.sh | 85 + kubeflow/apps/profiles/upstream/README.md | 33 + .../profiles/upstream/base/kustomization.yaml | 20 + .../upstream/base/namespace-labels.yaml | 18 + .../upstream/base/patches/manager.yaml | 27 + .../crd/bases/kubeflow.org_profiles.yaml | 323 + .../profiles/upstream/crd/kustomization.yaml | 22 + .../upstream/crd/kustomizeconfig.yaml | 19 + .../crd/patches/cainjection_in_profiles.yaml | 7 + .../crd/patches/trivial_conversion_patch.yaml | 8 + .../crd/patches/webhook_in_profiles.yaml | 16 + .../upstream/default/kustomization.yaml | 76 + .../default/manager_auth_proxy_patch.yaml | 34 + .../manager_prometheus_metrics_patch.yaml | 18 + .../default/manager_webhook_patch.yaml | 22 + .../default/webhookcainjection_patch.yaml | 15 + .../upstream/manager/kustomization.yaml | 14 + .../profiles/upstream/manager/manager.yaml | 48 + .../upstream/manager/service-account.yaml | 4 + .../kubeflow/authorizationpolicy.yaml | 14 + .../overlays/kubeflow/kustomization.yaml | 32 + .../upstream/overlays/kubeflow/params.yaml | 3 + .../overlays/kubeflow/patches/kfam.yaml | 44 + .../kubeflow/patches/remove-namespace.yaml | 5 + .../upstream/overlays/kubeflow/service.yaml | 7 + .../overlays/kubeflow/virtual-service.yaml | 24 + .../overlays/standalone/kustomization.yaml | 5 + .../upstream/prometheus/kustomization.yaml | 2 + .../profiles/upstream/prometheus/monitor.yaml | 20 + .../rbac/auth_proxy_client_clusterrole.yaml | 9 + .../upstream/rbac/auth_proxy_role.yaml | 17 + .../rbac/auth_proxy_role_binding.yaml | 11 + .../upstream/rbac/auth_proxy_service.yaml | 15 + .../profiles/upstream/rbac/kustomization.yaml | 18 + .../upstream/rbac/leader_election_role.yaml | 32 + .../rbac/leader_election_role_binding.yaml | 11 + .../upstream/rbac/profile_editor_role.yaml | 24 + .../upstream/rbac/profile_viewer_role.yaml | 20 + .../apps/profiles/upstream/rbac/role.yaml | 39 + .../profiles/upstream/rbac/role_binding.yaml | 11 + .../upstream/rbac/service_account.yaml | 5 + .../upstream/samples/_v1_profile.yaml | 8 + .../upstream/samples/_v1_profile_aws_iam.yaml | 12 + .../upstream/samples/_v1beta1_profile.yaml | 15 + .../upstream/base/kustomization.yaml | 9 + .../upstream/certmanager/certificate.yaml | 39 + .../upstream/certmanager/kustomization.yaml | 5 + .../upstream/certmanager/kustomizeconfig.yaml | 8 + .../crd/bases/kubeflow.org_pvcviewers.yaml | 3428 + .../upstream/crd/kustomization.yaml | 17 + .../upstream/crd/kustomizeconfig.yaml | 19 + .../patches/cainjection_in_pvcviewers.yaml | 7 + .../crd/patches/webhook_in_pvcviewers.yaml | 16 + .../upstream/default/cainjection_patch.yaml | 36 + .../upstream/default/dnsnames_patch.yaml | 9 + .../upstream/default/kustomization.yaml | 170 + .../upstream/default/kustomizeconfig.yaml | 4 + .../default/manager_auth_proxy_patch.yaml | 55 + .../default/manager_webhook_patch.yaml | 28 + .../upstream/default/remove_namespace.yaml | 5 + .../upstream/manager/kustomization.yaml | 2 + .../upstream/manager/manager.yaml | 77 + .../upstream/prometheus/kustomization.yaml | 2 + .../upstream/prometheus/monitor.yaml | 26 + .../rbac/auth_proxy_client_clusterrole.yaml | 16 + .../upstream/rbac/auth_proxy_role.yaml | 24 + .../rbac/auth_proxy_role_binding.yaml | 19 + .../upstream/rbac/auth_proxy_service.yaml | 21 + .../upstream/rbac/kustomization.yaml | 10 + .../upstream/rbac/leader_election_role.yaml | 44 + .../rbac/leader_election_role_binding.yaml | 19 + .../upstream/rbac/role.yaml | 78 + .../upstream/rbac/role_binding.yaml | 19 + .../upstream/rbac/service_account.yaml | 12 + .../rbac/volumesviewer_editor_role.yaml | 31 + .../rbac/volumesviewer_viewer_role.yaml | 27 + .../upstream/samples/_v1alpha1_pvcviewer.yaml | 42 + .../upstream/samples/kustomization.yaml | 4 + .../upstream/webhook/kustomization.yaml | 6 + .../upstream/webhook/kustomizeconfig.yaml | 22 + .../upstream/webhook/manifests.yaml | 52 + .../upstream/webhook/service.yaml | 20 + kubeflow/apps/spark/OWNERS | 5 + kubeflow/apps/spark/README.md | 13 + .../spark-operator/base/aggregated-roles.yaml | 69 + .../spark-operator/base/kustomization.yaml | 65 + .../spark/spark-operator/base/resources.yaml | 25533 +++++++ .../overlays/kubeflow/kustomization.yaml | 3 + .../overlays/standalone/kustomization.yaml | 3 + .../apps/spark/sparkapplication_example.yaml | 46 + .../upstream/base/kustomization.yaml | 17 + .../base/patches/add_controller_config.yaml | 12 + .../base/patches/add_service_account.yaml | 8 + .../upstream/base/service_account.yaml | 4 + .../upstream/certmanager/certificate.yaml | 24 + .../upstream/certmanager/kustomization.yaml | 5 + .../upstream/certmanager/kustomizeconfig.yaml | 16 + ...tensorboard.kubeflow.org_tensorboards.yaml | 86 + .../upstream/crd/kustomization.yaml | 21 + .../upstream/crd/kustomizeconfig.yaml | 19 + .../patches/cainjection_in_tensorboards.yaml | 7 + .../crd/patches/webhook_in_tensorboards.yaml | 16 + .../upstream/default/kustomization.yaml | 75 + .../default/manager_auth_proxy_patch.yaml | 32 + .../manager_prometheus_metrics_patch.yaml | 18 + .../default/manager_webhook_patch.yaml | 22 + .../default/webhookcainjection_patch.yaml | 15 + .../manager/controller_manager_config.yaml | 11 + .../upstream/manager/kustomization.yaml | 2 + .../upstream/manager/manager.yaml | 56 + .../overlays/kubeflow/kustomization.yaml | 7 + .../kubeflow/patches/remove-namespace.yaml | 5 + .../overlays/standalone/kustomization.yaml | 5 + .../upstream/prometheus/kustomization.yaml | 2 + .../upstream/prometheus/monitor.yaml | 20 + .../rbac/auth_proxy_client_clusterrole.yaml | 9 + .../upstream/rbac/auth_proxy_role.yaml | 17 + .../rbac/auth_proxy_role_binding.yaml | 12 + .../upstream/rbac/auth_proxy_service.yaml | 15 + .../upstream/rbac/kustomization.yaml | 18 + .../upstream/rbac/leader_election_role.yaml | 37 + .../rbac/leader_election_role_binding.yaml | 12 + .../upstream/rbac/role.yaml | 79 + .../upstream/rbac/role_binding.yaml | 12 + .../upstream/rbac/service_account.yaml | 5 + .../tensorboard_v1alpha1_tensorboard.yaml | 8 + .../upstream/webhook/kustomization.yaml | 6 + .../upstream/webhook/kustomizeconfig.yaml | 25 + .../upstream/webhook/manifests.yaml | 0 .../upstream/webhook/service.yaml | 12 + .../upstream/base/cluster-role-binding.yaml | 11 + .../upstream/base/cluster-role.yaml | 119 + .../upstream/base/deployment.yaml | 25 + .../upstream/base/kustomization.yaml | 73 + .../upstream/base/params.env | 6 + .../upstream/base/service-account.yaml | 4 + .../upstream/base/service.yaml | 13 + .../overlays/istio/authorization-policy.yaml | 14 + .../overlays/istio/destination-rule.yaml | 9 + .../overlays/istio/kustomization.yaml | 13 + .../upstream/overlays/istio/params.yaml | 3 + .../overlays/istio/virtual-service.yaml | 24 + .../base/crds/kubeflow.org_jaxjobs.yaml | 7901 +++ .../base/crds/kubeflow.org_mpijobs.yaml | 7907 +++ .../base/crds/kubeflow.org_paddlejobs.yaml | 8394 +++ .../base/crds/kubeflow.org_pytorchjobs.yaml | 8431 +++ .../base/crds/kubeflow.org_tfjobs.yaml | 7907 +++ .../base/crds/kubeflow.org_xgboostjobs.yaml | 7889 +++ .../upstream/base/crds/kustomization.yaml | 9 + .../upstream/base/deployment.yaml | 63 + .../upstream/base/kustomization.yaml | 10 + .../base/rbac/cluster-role-binding.yaml | 14 + .../upstream/base/rbac/role.yaml | 292 + .../upstream/base/rbac/service-account.yaml | 6 + .../upstream/base/service.yaml | 22 + .../upstream/base/webhook/kustomization.yaml | 17 + .../base/webhook/kustomizeconfig.yaml | 10 + .../upstream/base/webhook/manifests.yaml | 106 + .../upstream/base/webhook/patch.yaml | 18 + .../kubeflow/kubeflow-training-roles.yaml | 100 + .../overlays/kubeflow/kustomization.yaml | 15 + .../overlays/standalone/kustomization.yaml | 13 + .../overlays/standalone/namespace.yaml | 4 + .../kubeflow.org_clustertrainingruntimes.yaml | 9760 +++ .../crds/kubeflow.org_trainingruntimes.yaml | 9760 +++ .../v2/base/crds/kubeflow.org_trainjobs.yaml | 3322 + .../upstream/v2/base/crds/kustomization.yaml | 6 + .../v2/base/manager/kustomization.yaml | 4 + .../upstream/v2/base/manager/manager.yaml | 70 + .../upstream/v2/base/rbac/kustomization.yaml | 6 + .../upstream/v2/base/rbac/role.yaml | 72 + .../upstream/v2/base/rbac/role_binding.yaml | 12 + .../v2/base/rbac/service_account.yaml | 5 + .../runtimes/pre-training/kustomization.yaml | 4 + .../pre-training/torch-distributed.yaml | 33 + .../v2/base/webhook/kustomization.yaml | 14 + .../v2/base/webhook/kustomizeconfig.yaml | 10 + .../upstream/v2/base/webhook/manifests.yaml | 66 + .../upstream/v2/base/webhook/patch.yaml | 12 + .../overlays/only-manager/kustomization.yaml | 18 + .../v2/overlays/only-manager/namespace.yaml | 4 + .../overlays/only-runtimes/kustomization.yaml | 4 + .../v2/overlays/standalone/kustomization.yaml | 19 + .../v2/overlays/standalone/namespace.yaml | 4 + .../upstream/base/cluster-role-binding.yaml | 11 + .../upstream/base/cluster-role.yaml | 128 + .../upstream/base/deployment.yaml | 35 + .../upstream/base/kustomization.yaml | 76 + .../volumes-web-app/upstream/base/params.env | 6 + .../upstream/base/service-account.yaml | 4 + .../upstream/base/service.yaml | 13 + .../upstream/base/viewer-spec.yaml | 46 + .../overlays/istio/authorization-policy.yaml | 14 + .../overlays/istio/destination-rule.yaml | 9 + .../overlays/istio/kustomization.yaml | 13 + .../upstream/overlays/istio/params.yaml | 3 + .../overlays/istio/virtual-service.yaml | 24 + kubeflow/common/cert-manager/OWNERS | 2 + kubeflow/common/cert-manager/README.md | 9 + .../cert-manager/base/kustomization.yaml | 9 + .../base/upstream/cert-manager.yaml | 13263 ++++ .../kubeflow-issuer/base/cluster-issuer.yaml | 6 + .../kubeflow-issuer/base/kustomization.yaml | 11 + kubeflow/common/dex/OWNERS | 3 + kubeflow/common/dex/README.md | 191 + kubeflow/common/dex/base/config-map.yaml | 30 + kubeflow/common/dex/base/crds.yaml | 52 + kubeflow/common/dex/base/deployment.yaml | 57 + kubeflow/common/dex/base/dex-passwords.yaml | 6 + kubeflow/common/dex/base/kustomization.yaml | 20 + kubeflow/common/dex/base/namespace.yaml | 4 + kubeflow/common/dex/base/secret_params.env | 2 + kubeflow/common/dex/base/service.yaml | 13 + .../dex/overlays/istio/kustomization.yaml | 40 + .../dex/overlays/istio/virtual-service.yaml | 18 + .../dex/overlays/oauth2-proxy/config-map.yaml | 30 + .../overlays/oauth2-proxy/kustomization.yaml | 14 + kubeflow/common/istio-1-24/README.md | 77 + .../base/cluster-local-gateway.yaml | 391 + .../base/gateway-authorizationpolicy.yaml | 14 + .../cluster-local-gateway/base/gateway.yaml | 17 + .../base/kustomization.yaml | 12 + .../base/patches/remove-pdb.yaml | 6 + .../istio-1-24/istio-crds/base/crd.yaml | 17061 +++++ .../istio-crds/base/kustomization.yaml | 5 + .../base/deny_all_authorizationpolicy.yaml | 9 + .../istio-install/base/gateway.yaml | 17 + .../base/gateway_authorizationpolicy.yaml | 15 + .../istio-install/base/install.yaml | 3444 + .../istio-install/base/kustomization.yaml | 23 + .../base/patches/disable-debugging.yaml | 18 + .../istio-configmap-disable-tracing.yaml | 20 + .../istio-ingressgateway-remove-pdb.yaml | 6 + .../base/patches/istiod-remove-pdb.yaml | 6 + .../patches/seccomp-istio-ingressgateway.yaml | 16 + .../base/patches/seccomp-istiod.yaml | 16 + .../istio-install/base/patches/service.yaml | 7 + .../overlays/oauth2-proxy/kustomization.yaml | 8 + .../istio-namespace/base/kustomization.yaml | 6 + .../istio-namespace/base/namespace.yaml | 7 + .../base/cluster-roles.yaml | 56 + .../base/kf-istio-resources.yaml | 14 + .../base/kustomization.yaml | 6 + .../common/istio-1-24/profile-overlay.yaml | 58 + kubeflow/common/istio-1-24/profile.yaml | 31 + .../common/istio-1-24/split-istio-packages | 72 + kubeflow/common/istio-cni-1-24/README.md | 87 + .../base/cluster-local-gateway.yaml | 391 + .../base/gateway-authorizationpolicy.yaml | 14 + .../cluster-local-gateway/base/gateway.yaml | 17 + .../base/kustomization.yaml | 12 + .../base/patches/remove-pdb.yaml | 6 + .../istio-cni-1-24/istio-crds/base/crd.yaml | 17061 +++++ .../istio-crds/base/kustomization.yaml | 5 + .../base/deny_all_authorizationpolicy.yaml | 9 + .../istio-install/base/gateway.yaml | 17 + .../base/gateway_authorizationpolicy.yaml | 15 + .../istio-install/base/install.yaml | 3756 + .../istio-install/base/kustomization.yaml | 21 + .../base/patches/disable-debugging.yaml | 18 + .../istio-configmap-disable-tracing.yaml | 20 + .../istio-ingressgateway-remove-pdb.yaml | 6 + .../base/patches/istiod-remove-pdb.yaml | 6 + .../patches/seccomp-istio-ingressgateway.yaml | 16 + .../base/patches/seccomp-istiod.yaml | 16 + .../istio-install/base/patches/service.yaml | 7 + .../overlays/oauth2-proxy/kustomization.yaml | 8 + .../istio-namespace/base/kustomization.yaml | 10 + .../istio-namespace/base/namespace.yaml | 7 + .../base/cluster-roles.yaml | 56 + .../base/kf-istio-resources.yaml | 14 + .../base/kustomization.yaml | 6 + .../istio-cni-1-24/profile-overlay.yaml | 58 + kubeflow/common/istio-cni-1-24/profile.yaml | 31 + .../istio-cni-1-24/split-istio-packages | 72 + kubeflow/common/knative/OWNERS | 2 + kubeflow/common/knative/README.md | 27 + .../base/eventing-post-install.yaml | 53 + .../base/kustomization.yaml | 4 + .../knative-eventing/base/kustomization.yaml | 17 + .../base/patches/clusterrole-patch.yaml | 60 + .../base/upstream/eventing-core.yaml | 5834 ++ .../base/upstream/in-memory-channel.yaml | 1041 + .../base/upstream/mt-channel-broker.yaml | 633 + .../base/kustomization.yaml | 14 + .../base/serving-post-install-jobs.yaml | 50 + .../base/istio-authorization-policy.yaml | 78 + .../knative-serving/base/kustomization.yaml | 23 + .../base/patches/config-deployment.yaml | 8 + .../base/patches/config-istio.yaml | 7 + .../knative-serving-namespaced-admin.yaml | 6 + .../knative-serving-namespaced-edit.yaml | 6 + .../knative-serving-namespaced-view.yaml | 6 + .../base/patches/namespace-injection.yaml | 6 + .../base/patches/remove-gateway.yaml | 6 + .../knative-serving/base/patches/seccomp.yaml | 11 + .../base/patches/service-labels.yaml | 7 + .../base/patches/sidecar-injection.yaml | 10 + .../base/upstream/net-istio.yaml | 465 + .../base/upstream/serving-core.yaml | 8887 +++ .../overlays/gateways/kustomization.yaml | 13 + .../gateways/patches/config-domain.yaml | 7 + .../gateway-selector-in-istio-system.yaml | 9 + .../gateway-selector-in-knative-serving.yaml | 9 + .../base/kustomization.yaml | 4 + .../kubeflow-namespace/base/namespace.yaml | 7 + kubeflow/common/kubeflow-roles/OWNERS | 2 + kubeflow/common/kubeflow-roles/README.md | 70 + .../kubeflow-roles/base/cluster-roles.yaml | 335 + .../kubeflow-roles/base/kustomization.yaml | 4 + kubeflow/common/networkpolicies/OWNERS | 6 + kubeflow/common/networkpolicies/README.md | 8 + .../networkpolicies/base/cache-server.yaml | 20 + .../base/centraldashboard.yaml | 23 + .../base/default-allow-same-namespace.yaml | 12 + .../networkpolicies/base/jupyter-web-app.yaml | 23 + .../base/katib-controller.yaml | 23 + .../base/katib-db-manager.yaml | 23 + .../common/networkpolicies/base/katib-ui.yaml | 22 + .../base/kserve-models-web-app.yaml | 22 + .../common/networkpolicies/base/kserve.yaml | 20 + .../networkpolicies/base/kustomization.yaml | 26 + .../networkpolicies/base/metadata-envoy.yaml | 23 + .../base/metadata-grpc-server.yaml | 23 + .../common/networkpolicies/base/minio.yaml | 29 + .../networkpolicies/base/ml-pipeline-ui.yaml | 22 + .../networkpolicies/base/ml-pipeline.yaml | 28 + .../base/model-registry-ui.yaml | 23 + .../networkpolicies/base/model-registry.yaml | 33 + .../networkpolicies/base/poddefaults.yaml | 20 + .../base/pvcviewer-webhook.yaml | 20 + .../base/spark-operator-webhook.yaml | 24 + .../base/tensorboards-web-app.yaml | 25 + .../base/training-operator-webhook.yaml | 20 + .../networkpolicies/base/volumes-web-app.yaml | 23 + kubeflow/common/oauth2-proxy/OWNERS | 3 + kubeflow/common/oauth2-proxy/README.md | 308 + kubeflow/common/oauth2-proxy/base/README.md | 24 + .../common/oauth2-proxy/base/deployment.yaml | 100 + .../oauth2-proxy/base/kubeflow-logo.svg | 15 + .../oauth2-proxy/base/kustomization.yaml | 95 + .../common/oauth2-proxy/base/namespace.yaml | 4 + .../common/oauth2-proxy/base/oauth2_proxy.cfg | 79 + .../common/oauth2-proxy/base/service.yaml | 13 + .../oauth2-proxy/base/serviceaccount.yaml | 4 + .../oauth2-proxy/base/virtualservice.yaml | 18 + .../common/oauth2-proxy/components/README.md | 216 + .../README.md | 43 + ...lebinding.unauthenticated-oidc-viewer.yaml | 12 + .../kustomization.yaml | 5 + .../central-dashboard/kustomization.yaml | 5 + .../patches/deployment.logout-url.yaml | 17 + .../components/cluster-jwks-proxy/README.md | 0 .../cluster-jwks-proxy.yaml | 88 + .../cluster-jwks-proxy/kustomization.yaml | 10 + .../istio-external-auth-patches/README.md | 0 .../kustomization.yaml | 6 + .../patches/cm.enable-oauth2-proxy.yaml | 36 + .../deployment.jwt-refresh-interval.yaml | 18 + .../components/istio-external-auth/README.md | 0 ...ngressgateway-oauth2-proxy.cloudflare.yaml | 34 + ...icy.istio-ingressgateway-oauth2-proxy.yaml | 25 + ...ingressgateway-require-jwt.cloudflare.yaml | 33 + ...licy.istio-ingressgateway-require-jwt.yaml | 24 + .../istio-external-auth/kustomization.yaml | 12 + .../requestauthentication.dex-jwt.yaml | 44 + .../components/istio-m2m/README.md | 13 + .../components/istio-m2m/kustomization.yaml | 5 + .../istio-m2m/requestauthentication.yaml | 42 + .../components/kubeflow_auth_diagram.svg | 1 + .../oauth2-proxy/components/oauth2-flow.svg | 13 + .../m2m-dex-and-eks/kustomization.yaml | 31 + .../m2m-dex-and-kind/kustomization.yaml | 57 + .../overlays/m2m-dex-only/kustomization.yaml | 15 + ...icy.istio-ingressgateway-oauth2-proxy.yaml | 28 + ...licy.istio-ingressgateway-require-jwt.yaml | 27 + .../istio-keycloak-auth/kustomization.yaml | 12 + .../requestauthentication.keycloak-jwt.yaml | 25 + .../overlays/m2m-keycloak/kustomization.yaml | 63 + .../overlays/m2m-keycloak/m2m.env | 2 + .../patch-oauth2-proxy-config.yaml | 56 + .../overlays/m2m-keycloak/secrets.env | 3 + .../user-namespace/base/kustomization.yaml | 41 + .../common/user-namespace/base/params.env | 2 + .../common/user-namespace/base/params.yaml | 5 + .../user-namespace/base/profile-instance.yaml | 8 + kubeflow/dip/README.md | 75 + .../kubeflow-applicationset.yaml | 59 + kubeflow/dip/istio-system/kustomization.yaml | 31 + .../dip/kubeflow-core/cluster-policy.yaml | 140 + kubeflow/dip/kubeflow-core/cluster-role.yaml | 17 + .../kubeflow-core/cluster-rolebinding.yaml | 15 + kubeflow/dip/kubeflow-core/ingress.yaml | 24 + kubeflow/dip/kubeflow-core/kustomization.yaml | 42 + .../knative-serving/README.md | 88 + .../knative-serving/kustomization.yaml | 14 + .../patches/config-deployment.yaml | 8 + .../patches/config-domain.yaml | 7 + .../patches/config-feature.yaml | 7 + .../patches/config-network.yaml | 7 + .../gateway-selector-in-istio-system.yaml | 9 + .../gateway-selector-in-knative-serving.yaml | 9 + .../kubeflow-dependencies/kustomization.yaml | 19 + kubeflow/example/kustomization.yaml | 110 + kubeflow/experimental/OWNERS | 5 + kubeflow/experimental/README.md | 4 + kubeflow/experimental/ray/Makefile | 11 + kubeflow/experimental/ray/OWNERS | 5 + kubeflow/experimental/ray/README.md | 150 + kubeflow/experimental/ray/UPGRADE.md | 6 + .../experimental/ray/assets/architecture.svg | 1 + .../experimental/ray/assets/map-of-ray.png | Bin 0 -> 71412 bytes .../base/aggregated-roles.yaml | 52 + .../kuberay-operator/base/kustomization.yaml | 9 + .../ray/kuberay-operator/base/resources.yaml | 56838 ++++++++++++++++ .../overlays/kubeflow/disable-injection.yaml | 13 + .../overlays/kubeflow/kustomization.yaml | 6 + .../overlays/standalone/kustomization.yaml | 3 + .../experimental/ray/raycluster_example.yaml | 167 + kubeflow/experimental/ray/test.sh | 90 + kubeflow/experimental/seaweedfs/OWNERS | 6 + kubeflow/experimental/seaweedfs/README.md | 51 + kubeflow/experimental/seaweedfs/UPDGRADE.md | 3 + .../seaweedfs/base/kustomization.yaml | 29 + .../seaweedfs/base/minio-service-patch.yaml | 13 + .../deployment.yaml | 42 + .../base/pipeline-profile-controller/sync.py | 243 + .../base/seaweedfs/kustomization.yaml | 11 + .../seaweedfs-create-admin-user-job.yaml | 67 + .../base/seaweedfs/seaweedfs-deployment.yaml | 72 + .../seaweedfs/seaweedfs-networkpolicy.yaml | 43 + .../base/seaweedfs/seaweedfs-pvc.yaml | 11 + .../seaweedfs/seaweedfs-service-account.yaml | 4 + .../base/seaweedfs/seaweedfs-service.yaml | 33 + .../istio/istio-authorization-policy.yaml | 32 + .../seaweedfs/istio/kustomization.yaml | 7 + kubeflow/experimental/seaweedfs/test.sh | 20 + .../PSS/dynamic/baseline/kustomization.yaml | 9 + .../dynamic/baseline/namespace-labels.yaml | 23 + .../PSS/dynamic/restricted/kustomization.yaml | 9 + .../dynamic/restricted/namespace-labels.yaml | 23 + .../PSS/static/baseline/kustomization.yaml | 10 + .../static/baseline/patches/auth-labels.yaml | 6 + .../baseline/patches/cert-manager-labels.yaml | 6 + .../baseline/patches/istio-system-labels.yaml | 6 + .../patches/knative-serving-labels.yaml | 6 + .../baseline/patches/kubeflow-labels.yaml | 6 + .../baseline/patches/oauth2-proxy-labels.yaml | 6 + .../PSS/static/restricted/kustomization.yaml | 10 + .../restricted/patches/auth-labels.yaml | 7 + .../patches/cert-manager-labels.yaml | 6 + .../patches/istio-system-labels.yaml | 6 + .../patches/knative-serving-labels.yaml | 6 + .../restricted/patches/kubeflow-labels.yaml | 6 + .../patches/oauth2-proxy-labels.yaml | 6 + .../proposals/20200913-rootlessKubeflow.md | 50 + .../20220926-contrib-component-guidelines.md | 71 + .../proposals/20230323-end-to-end-testing.md | 395 + kubeflow/proposals/20240606-jwt-handling.md | 136 + kubeflow/proposals/README.md | 6 + kubeflow/scripts/library.sh | 101 + .../synchronize-istio-cni-manifests.sh | 61 + .../scripts/synchronize-istio-manifests.sh | 61 + .../scripts/synchronize-katib-manifests.sh | 38 + .../scripts/synchronize-knative-manifests.sh | 110 + .../synchronize-kserve-kserve-manifests.sh | 46 + ...ronize-kserve-web-application-manifests.sh | 39 + .../scripts/synchronize-kubeflow-manifests.sh | 99 + .../synchronize-model-registry-manifests.sh | 47 + .../synchronize-pipelines-manifests.sh | 39 + .../synchronize-spark-operator-manifests.sh | 58 + ...synchronize-training-operator-manifests.sh | 38 + kubeflow/scripts/template.sh | 39 + kubeflow/scripts/trivy_scan.py | 412 + kubeflow/tests/README.md | 20 + .../tests/gh-actions/enable_baseline_PSS.sh | 15 + .../tests/gh-actions/enable_restricted_PSS.sh | 14 + ...D_create_KinD_cluster_install_kustomize.sh | 67 + kubeflow/tests/gh-actions/install_argo_cli.sh | 14 + .../gh-actions/install_central_dashboard.sh | 5 + .../tests/gh-actions/install_cert_manager.sh | 13 + kubeflow/tests/gh-actions/install_dex.sh | 5 + .../tests/gh-actions/install_istio-cni.sh | 10 + kubeflow/tests/gh-actions/install_katib.sh | 14 + .../tests/gh-actions/install_knative-cni.sh | 21 + kubeflow/tests/gh-actions/install_kserve.sh | 28 + kubeflow/tests/gh-actions/install_kubectl.sh | 7 + .../gh-actions/install_kubeflow_profile.sh | 8 + .../tests/gh-actions/install_kustomize.sh | 7 + .../tests/gh-actions/install_multi_tenancy.sh | 12 + .../tests/gh-actions/install_oauth2-proxy.sh | 13 + .../tests/gh-actions/install_pipelines.sh | 23 + .../gh-actions/install_pipelines_swfs.sh | 21 + kubeflow/tests/gh-actions/install_spark.sh | 16 + .../gh-actions/install_training_operator.sh | 14 + kubeflow/tests/gh-actions/install_trivy.sh | 4 + .../install_volumes_web_application.sh | 8 + .../gh-actions/kf-objects/katib_test.yaml | 59 + .../gh-actions/kf-objects/kserve_test.yaml | 16 + ...tebook.test.kubeflow-user-example.com.yaml | 27 + ...ml-pipeline.kubeflow-user-example-com.yaml | 25 + .../gh-actions/kf-objects/test_pipeline.py | 29 + .../kf-objects/training_operator_job.yaml | 40 + .../gh-actions/kserve/data/iris_input.json | 6 + .../tests/gh-actions/kserve/requirements.txt | 4 + .../tests/gh-actions/kserve/test_sklearn.py | 60 + kubeflow/tests/gh-actions/kserve/utils.py | 125 + .../gh-actions/oauth2_dex_credentials.sh | 104 + .../tests/gh-actions/port_forward_gateway.sh | 6 + .../run_and_wait_kubeflow_pipeline.py | 108 + kubeflow/tests/gh-actions/runasnonroot.sh | 101 + kubeflow/tests/gh-actions/test_dex_login.py | 193 + kubeflow/tests/gh-actions/test_kserve.sh | 70 + kubeflow/tests/gh-actions/test_pipeline_v1.py | 49 + kubeflow/tests/gh-actions/test_pipeline_v2.py | 96 + kubeflow/tests/gh-actions/test_spark.sh | 46 + .../gh-actions/test_training_operator.sh | 15 + .../test_volumes_web_application.sh | 98 + kubeflow/tests/gh-actions/trivy_scan.py | 401 + 1170 files changed, 461741 insertions(+) create mode 100644 kubeflow/CUSTOM-README.md create mode 100644 kubeflow/LICENSE create mode 100644 kubeflow/OWNERS create mode 100644 kubeflow/README.md create mode 100644 kubeflow/apps/admission-webhook/upstream/base/cluster-role-binding.yaml create mode 100644 kubeflow/apps/admission-webhook/upstream/base/cluster-role.yaml create mode 100644 kubeflow/apps/admission-webhook/upstream/base/crd.yaml create mode 100644 kubeflow/apps/admission-webhook/upstream/base/deployment.yaml create mode 100644 kubeflow/apps/admission-webhook/upstream/base/kustomization.yaml create mode 100644 kubeflow/apps/admission-webhook/upstream/base/mutating-webhook-configuration.yaml create mode 100644 kubeflow/apps/admission-webhook/upstream/base/params.yaml create mode 100644 kubeflow/apps/admission-webhook/upstream/base/service-account.yaml create mode 100644 kubeflow/apps/admission-webhook/upstream/base/service.yaml create mode 100644 kubeflow/apps/admission-webhook/upstream/overlays/cert-manager/certificate.yaml create mode 100644 kubeflow/apps/admission-webhook/upstream/overlays/cert-manager/deployment.yaml create mode 100644 kubeflow/apps/admission-webhook/upstream/overlays/cert-manager/kustomization.yaml create mode 100644 kubeflow/apps/admission-webhook/upstream/overlays/cert-manager/mutating-webhook-configuration.yaml create mode 100644 kubeflow/apps/admission-webhook/upstream/overlays/cert-manager/params.yaml create mode 100644 kubeflow/apps/centraldashboard/overlays/oauth2-proxy/kustomization.yaml create mode 100644 kubeflow/apps/centraldashboard/upstream/base/clusterrole-binding.yaml create mode 100644 kubeflow/apps/centraldashboard/upstream/base/clusterrole.yaml create mode 100644 kubeflow/apps/centraldashboard/upstream/base/configmap.yaml create mode 100644 kubeflow/apps/centraldashboard/upstream/base/deployment.yaml create mode 100644 kubeflow/apps/centraldashboard/upstream/base/kustomization.yaml create mode 100644 kubeflow/apps/centraldashboard/upstream/base/params.env create mode 100644 kubeflow/apps/centraldashboard/upstream/base/role-binding.yaml create mode 100644 kubeflow/apps/centraldashboard/upstream/base/role.yaml create mode 100644 kubeflow/apps/centraldashboard/upstream/base/service-account.yaml create mode 100644 kubeflow/apps/centraldashboard/upstream/base/service.yaml create mode 100644 kubeflow/apps/centraldashboard/upstream/overlays/istio/authorizationpolicy.yaml create mode 100644 kubeflow/apps/centraldashboard/upstream/overlays/istio/kustomization.yaml create mode 100644 kubeflow/apps/centraldashboard/upstream/overlays/istio/params.yaml create mode 100644 kubeflow/apps/centraldashboard/upstream/overlays/istio/virtual-service.yaml create mode 100644 kubeflow/apps/centraldashboard/upstream/overlays/kserve/kustomization.yaml create mode 100644 kubeflow/apps/centraldashboard/upstream/overlays/kserve/patches/configmap.yaml create mode 100644 kubeflow/apps/jupyter/jupyter-web-app/upstream/base/cluster-role-binding.yaml create mode 100644 kubeflow/apps/jupyter/jupyter-web-app/upstream/base/cluster-role.yaml create mode 100644 kubeflow/apps/jupyter/jupyter-web-app/upstream/base/configs/logos-configmap.yaml create mode 100644 kubeflow/apps/jupyter/jupyter-web-app/upstream/base/configs/spawner_ui_config.yaml create mode 100644 kubeflow/apps/jupyter/jupyter-web-app/upstream/base/deployment.yaml create mode 100644 kubeflow/apps/jupyter/jupyter-web-app/upstream/base/kustomization.yaml create mode 100644 kubeflow/apps/jupyter/jupyter-web-app/upstream/base/params.env create mode 100644 kubeflow/apps/jupyter/jupyter-web-app/upstream/base/role-binding.yaml create mode 100644 kubeflow/apps/jupyter/jupyter-web-app/upstream/base/role.yaml create mode 100644 kubeflow/apps/jupyter/jupyter-web-app/upstream/base/service-account.yaml create mode 100644 kubeflow/apps/jupyter/jupyter-web-app/upstream/base/service.yaml create mode 100644 kubeflow/apps/jupyter/jupyter-web-app/upstream/overlays/istio/authorization-policy.yaml create mode 100644 kubeflow/apps/jupyter/jupyter-web-app/upstream/overlays/istio/destination-rule.yaml create mode 100644 kubeflow/apps/jupyter/jupyter-web-app/upstream/overlays/istio/kustomization.yaml create mode 100644 kubeflow/apps/jupyter/jupyter-web-app/upstream/overlays/istio/params.yaml create mode 100644 kubeflow/apps/jupyter/jupyter-web-app/upstream/overlays/istio/virtual-service.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/README.md create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/base/kustomization.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/crd/bases/kubeflow.org_notebooks.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/crd/kustomization.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/crd/kustomizeconfig.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/crd/patches/cainjection_in_notebooks.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/crd/patches/trivial_conversion_patch.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/crd/patches/validation_patches.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/crd/patches/webhook_in_notebooks.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/default/kustomization.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/default/manager_auth_proxy_patch.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/default/manager_image_patch.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/default/manager_prometheus_metrics_patch.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/default/manager_webhook_patch.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/default/webhookcainjection_patch.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/manager/kustomization.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/manager/manager.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/manager/params.env create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/manager/service-account.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/manager/service.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/overlays/kubeflow/kustomization.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/overlays/kubeflow/patches/remove-namespace.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/overlays/standalone/kustomization.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/rbac/auth_proxy_role.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/rbac/auth_proxy_role_binding.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/rbac/auth_proxy_service.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/rbac/kustomization.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/rbac/leader_election_role.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/rbac/leader_election_role_binding.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/rbac/role.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/rbac/role_binding.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/rbac/user_cluster_roles.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/samples/_v1_notebook.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/samples/_v1alpha1_notebook.yaml create mode 100644 kubeflow/apps/jupyter/notebook-controller/upstream/samples/_v1beta1_notebook.yaml create mode 100644 kubeflow/apps/katib/upstream/components/controller/controller.yaml create mode 100644 kubeflow/apps/katib/upstream/components/controller/kustomization.yaml create mode 100644 kubeflow/apps/katib/upstream/components/controller/rbac.yaml create mode 100644 kubeflow/apps/katib/upstream/components/controller/service.yaml create mode 100644 kubeflow/apps/katib/upstream/components/controller/trial-templates.yaml create mode 100644 kubeflow/apps/katib/upstream/components/crd/experiment.yaml create mode 100644 kubeflow/apps/katib/upstream/components/crd/kustomization.yaml create mode 100644 kubeflow/apps/katib/upstream/components/crd/suggestion.yaml create mode 100644 kubeflow/apps/katib/upstream/components/crd/trial.yaml create mode 100644 kubeflow/apps/katib/upstream/components/db-manager/db-manager.yaml create mode 100644 kubeflow/apps/katib/upstream/components/db-manager/kustomization.yaml create mode 100644 kubeflow/apps/katib/upstream/components/db-manager/service.yaml create mode 100644 kubeflow/apps/katib/upstream/components/mysql/kustomization.yaml create mode 100644 kubeflow/apps/katib/upstream/components/mysql/mysql.yaml create mode 100644 kubeflow/apps/katib/upstream/components/mysql/pvc.yaml create mode 100644 kubeflow/apps/katib/upstream/components/mysql/secret.yaml create mode 100644 kubeflow/apps/katib/upstream/components/mysql/service.yaml create mode 100644 kubeflow/apps/katib/upstream/components/namespace/kustomization.yaml create mode 100644 kubeflow/apps/katib/upstream/components/namespace/namespace.yaml create mode 100644 kubeflow/apps/katib/upstream/components/postgres/kustomization.yaml create mode 100644 kubeflow/apps/katib/upstream/components/postgres/postgres.yaml create mode 100644 kubeflow/apps/katib/upstream/components/postgres/pvc.yaml create mode 100644 kubeflow/apps/katib/upstream/components/postgres/secret.yaml create mode 100644 kubeflow/apps/katib/upstream/components/postgres/service.yaml create mode 100644 kubeflow/apps/katib/upstream/components/ui/kustomization.yaml create mode 100644 kubeflow/apps/katib/upstream/components/ui/rbac.yaml create mode 100644 kubeflow/apps/katib/upstream/components/ui/service.yaml create mode 100644 kubeflow/apps/katib/upstream/components/ui/ui.yaml create mode 100644 kubeflow/apps/katib/upstream/components/webhook/kustomization.yaml create mode 100644 kubeflow/apps/katib/upstream/components/webhook/webhooks.yaml create mode 100644 kubeflow/apps/katib/upstream/installs/katib-cert-manager/certificate.yaml create mode 100644 kubeflow/apps/katib/upstream/installs/katib-cert-manager/katib-config.yaml create mode 100644 kubeflow/apps/katib/upstream/installs/katib-cert-manager/kustomization.yaml create mode 100644 kubeflow/apps/katib/upstream/installs/katib-cert-manager/params.yaml create mode 100644 kubeflow/apps/katib/upstream/installs/katib-cert-manager/patches/katib-cert-injection.yaml create mode 100644 kubeflow/apps/katib/upstream/installs/katib-external-db/katib-config.yaml create mode 100644 kubeflow/apps/katib/upstream/installs/katib-external-db/kustomization.yaml create mode 100644 kubeflow/apps/katib/upstream/installs/katib-external-db/patches/db-manager.yaml create mode 100644 kubeflow/apps/katib/upstream/installs/katib-external-db/secrets.env create mode 100644 kubeflow/apps/katib/upstream/installs/katib-leader-election/katib-config.yaml create mode 100644 kubeflow/apps/katib/upstream/installs/katib-leader-election/kustomization.yaml create mode 100644 kubeflow/apps/katib/upstream/installs/katib-leader-election/leader-election-rbac.yaml create mode 100644 kubeflow/apps/katib/upstream/installs/katib-openshift/katib-config.yaml create mode 100644 kubeflow/apps/katib/upstream/installs/katib-openshift/kustomization.yaml create mode 100644 kubeflow/apps/katib/upstream/installs/katib-openshift/patches/service-serving-cert.yaml create mode 100644 kubeflow/apps/katib/upstream/installs/katib-openshift/patches/webhook-inject-cabundle.yaml create mode 100644 kubeflow/apps/katib/upstream/installs/katib-standalone-postgres/katib-config.yaml create mode 100644 kubeflow/apps/katib/upstream/installs/katib-standalone-postgres/kustomization.yaml create mode 100644 kubeflow/apps/katib/upstream/installs/katib-standalone-postgres/patches/db-manager.yaml create mode 100644 kubeflow/apps/katib/upstream/installs/katib-standalone/katib-config.yaml create mode 100644 kubeflow/apps/katib/upstream/installs/katib-standalone/kustomization.yaml create mode 100644 kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/istio-authorizationpolicy.yaml create mode 100644 kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/kubeflow-katib-roles.yaml create mode 100644 kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/kustomization.yaml create mode 100644 kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/params.yaml create mode 100644 kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/patches/enable-ui-authz-checks.yaml create mode 100644 kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/patches/istio-sidecar-injection.yaml create mode 100644 kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/patches/remove-namespace.yaml create mode 100644 kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/patches/ui-rbac.yaml create mode 100644 kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/ui-virtual-service.yaml create mode 100644 kubeflow/apps/kserve/Makefile create mode 100644 kubeflow/apps/kserve/OWNERS create mode 100644 kubeflow/apps/kserve/README.md create mode 100644 kubeflow/apps/kserve/UPGRADE.md create mode 100644 kubeflow/apps/kserve/assets/kserve.png create mode 100644 kubeflow/apps/kserve/assets/kserve_new.png create mode 100644 kubeflow/apps/kserve/kserve/aggregated-roles.yaml create mode 100644 kubeflow/apps/kserve/kserve/kserve-cluster-resources.yaml create mode 100644 kubeflow/apps/kserve/kserve/kserve.yaml create mode 100644 kubeflow/apps/kserve/kserve/kserve_kubeflow.yaml create mode 100644 kubeflow/apps/kserve/kserve/kustomization.yaml create mode 100644 kubeflow/apps/kserve/kserve/params.env create mode 100644 kubeflow/apps/kserve/models-web-app/base/deployment.yaml create mode 100644 kubeflow/apps/kserve/models-web-app/base/istio.yaml create mode 100644 kubeflow/apps/kserve/models-web-app/base/kustomization.yaml create mode 100644 kubeflow/apps/kserve/models-web-app/base/rbac.yaml create mode 100644 kubeflow/apps/kserve/models-web-app/base/service.yaml create mode 100644 kubeflow/apps/kserve/models-web-app/overlays/kubeflow/kustomization.yaml create mode 100644 kubeflow/apps/kserve/models-web-app/overlays/kubeflow/params.yaml create mode 100644 kubeflow/apps/kserve/models-web-app/overlays/kubeflow/patches/web-app-sidecar.yaml create mode 100644 kubeflow/apps/kserve/models-web-app/overlays/kubeflow/patches/web-app-vsvc.yaml create mode 100644 kubeflow/apps/kserve/models-web-app/overlays/kubeflow/web-app-authorization-policy.yaml create mode 100644 kubeflow/apps/model-registry/upstream/OWNERS create mode 100644 kubeflow/apps/model-registry/upstream/README.md create mode 100644 kubeflow/apps/model-registry/upstream/base/kustomization.yaml create mode 100644 kubeflow/apps/model-registry/upstream/base/model-registry-configmap.yaml create mode 100644 kubeflow/apps/model-registry/upstream/base/model-registry-deployment.yaml create mode 100644 kubeflow/apps/model-registry/upstream/base/model-registry-sa.yaml create mode 100644 kubeflow/apps/model-registry/upstream/base/model-registry-service.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/controller/default/kustomization.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/controller/default/manager_metrics_patch.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/controller/default/metrics_service.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/controller/manager/kustomization.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/controller/manager/manager.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/controller/network-policy/allow-metrics-traffic.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/controller/network-policy/kustomization.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/controller/overlays/base/kustomization.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/controller/overlays/base/params.env create mode 100644 kubeflow/apps/model-registry/upstream/options/controller/overlays/base/replacements.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/controller/prometheus/kustomization.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/controller/prometheus/monitor.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/controller/rbac/kustomization.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/controller/rbac/leader_election_role.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/controller/rbac/leader_election_role_binding.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/controller/rbac/metrics_auth_role.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/controller/rbac/metrics_auth_role_binding.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/controller/rbac/metrics_reader_role.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/controller/rbac/role.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/controller/rbac/role_binding.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/controller/rbac/service_account.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/csi/clusterstoragecontainer.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/csi/kustomization.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/istio/destination-rule.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/istio/istio-authorization-policy.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/istio/kustomization.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/istio/virtual-service.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/ui/base/kustomization.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/ui/base/model-registry-ui-deployment.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/ui/base/model-registry-ui-role.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/ui/base/model-registry-ui-service-account.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/ui/base/model-registry-ui-service.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/ui/overlays/integrated/kustomization.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/ui/overlays/integrated/model-registry-ui-deployment.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/ui/overlays/istio/authorization-policy-ui.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/ui/overlays/istio/destination-rule-ui.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/ui/overlays/istio/kustomization.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/ui/overlays/istio/model-registry-ui-service.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/ui/overlays/istio/virtual-service.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/ui/overlays/standalone/kubeflow-dashboard-rbac.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/ui/overlays/standalone/kustomization.yaml create mode 100644 kubeflow/apps/model-registry/upstream/options/ui/overlays/standalone/model-registry-ui-deployment.yaml create mode 100644 kubeflow/apps/model-registry/upstream/overlays/db/kustomization.yaml create mode 100644 kubeflow/apps/model-registry/upstream/overlays/db/model-registry-db-deployment.yaml create mode 100644 kubeflow/apps/model-registry/upstream/overlays/db/model-registry-db-pvc.yaml create mode 100644 kubeflow/apps/model-registry/upstream/overlays/db/model-registry-db-service.yaml create mode 100644 kubeflow/apps/model-registry/upstream/overlays/db/params.env create mode 100644 kubeflow/apps/model-registry/upstream/overlays/db/patches/model-registry-deployment.yaml create mode 100644 kubeflow/apps/model-registry/upstream/overlays/db/secrets.env create mode 100644 kubeflow/apps/model-registry/upstream/overlays/postgres/kustomization.yaml create mode 100644 kubeflow/apps/model-registry/upstream/overlays/postgres/model-registry-db-deployment.yaml create mode 100644 kubeflow/apps/model-registry/upstream/overlays/postgres/model-registry-db-pvc.yaml create mode 100644 kubeflow/apps/model-registry/upstream/overlays/postgres/model-registry-db-service.yaml create mode 100644 kubeflow/apps/model-registry/upstream/overlays/postgres/params.env create mode 100644 kubeflow/apps/model-registry/upstream/overlays/postgres/patches/model-registry-deployment.yaml create mode 100644 kubeflow/apps/model-registry/upstream/overlays/postgres/secrets.env create mode 100644 kubeflow/apps/pipeline/upstream/Makefile create mode 100644 kubeflow/apps/pipeline/upstream/OWNERS create mode 100644 kubeflow/apps/pipeline/upstream/README.md create mode 100644 kubeflow/apps/pipeline/upstream/base/application/application.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/application/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/cache-deployer/cache-deployer-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/cache-deployer/cache-deployer-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/cache-deployer/cache-deployer-rolebinding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/cache-deployer/cluster-scoped/cache-deployer-clusterrole.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/cache-deployer/cluster-scoped/cache-deployer-clusterrolebinding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/cache-deployer/cluster-scoped/cache-deployer-sa.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/cache-deployer/cluster-scoped/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/cache-deployer/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/cache/cache-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/cache/cache-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/cache/cache-rolebinding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/cache/cache-sa.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/cache/cache-service.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/cache/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/crds/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/crds/pipelines.kubeflow.org_pipelines.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/crds/pipelines.kubeflow.org_pipelineversions.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/generic/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/generic/mysql-secret.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/generic/params.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/generic/pipeline-install-config.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/generic/postgres/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/generic/postgres/params.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/generic/postgres/pipeline-install-config.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/generic/postgres/postgres-secret-extended.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/api-service/cluster-role-binding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/api-service/cluster-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/api-service/deployment-patch.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/api-service/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/api-service/params.env create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/cache/cluster-role-binding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/cache/cluster-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/cache/deployment-patch.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/cache/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/istio-authorization-config.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/metadata-writer/cluster-role-binding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/metadata-writer/cluster-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/metadata-writer/deployment-patch.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/metadata-writer/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/params.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/persistence-agent/cluster-role-binding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/persistence-agent/cluster-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/persistence-agent/deployment-patch.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/persistence-agent/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/pipelines-profile-controller/decorator-controller.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/pipelines-profile-controller/deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/pipelines-profile-controller/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/pipelines-profile-controller/params.env create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/pipelines-profile-controller/requirements-dev.txt create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/pipelines-profile-controller/run_tests.sh create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/pipelines-profile-controller/service.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/pipelines-profile-controller/sync.py create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/pipelines-profile-controller/test_sync.py create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/pipelines-ui/cluster-role-binding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/pipelines-ui/cluster-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/pipelines-ui/configmap-patch.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/pipelines-ui/deployment-patch.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/pipelines-ui/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/scheduled-workflow/cluster-role-binding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/scheduled-workflow/cluster-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/scheduled-workflow/deployment-patch.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/scheduled-workflow/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/view-edit-cluster-roles.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/viewer-controller/cluster-role-binding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/viewer-controller/cluster-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/viewer-controller/deployment-patch.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/viewer-controller/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/installs/multi-user/virtual-service.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/metadata/base/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/metadata/base/metadata-envoy-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/metadata/base/metadata-envoy-service.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/metadata/base/metadata-grpc-configmap.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/metadata/base/metadata-grpc-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/metadata/base/metadata-grpc-sa.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/metadata/base/metadata-grpc-service.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/metadata/options/istio/destination-rule.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/metadata/options/istio/istio-authorization-policy.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/metadata/options/istio/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/metadata/options/istio/virtual-service.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/metadata/overlays/db/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/metadata/overlays/db/metadata-db-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/metadata/overlays/db/metadata-db-pvc.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/metadata/overlays/db/metadata-db-service.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/metadata/overlays/db/params.env create mode 100644 kubeflow/apps/pipeline/upstream/base/metadata/overlays/db/patches/metadata-grpc-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/metadata/overlays/db/secrets.env create mode 100644 kubeflow/apps/pipeline/upstream/base/metadata/overlays/postgres/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/metadata/overlays/postgres/metadata-db-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/metadata/overlays/postgres/metadata-db-pvc.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/metadata/overlays/postgres/metadata-db-service.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/metadata/overlays/postgres/params.env create mode 100644 kubeflow/apps/pipeline/upstream/base/metadata/overlays/postgres/patches/metadata-grpc-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/metadata/overlays/postgres/secrets.env create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/cluster-scoped/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/cluster-scoped/scheduled-workflow-crd.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/cluster-scoped/viewer-crd.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/container-builder-sa.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/kfp-launcher-configmap.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/metadata-writer/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/metadata-writer/metadata-writer-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/metadata-writer/metadata-writer-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/metadata-writer/metadata-writer-rolebinding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/metadata-writer/metadata-writer-sa.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/ml-pipeline-apiserver-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/ml-pipeline-apiserver-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/ml-pipeline-apiserver-rolebinding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/ml-pipeline-apiserver-sa.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/ml-pipeline-apiserver-service.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/ml-pipeline-persistenceagent-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/ml-pipeline-persistenceagent-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/ml-pipeline-persistenceagent-rolebinding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/ml-pipeline-persistenceagent-sa.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/ml-pipeline-scheduledworkflow-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/ml-pipeline-scheduledworkflow-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/ml-pipeline-scheduledworkflow-rolebinding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/ml-pipeline-scheduledworkflow-sa.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/ml-pipeline-ui-configmap.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/ml-pipeline-ui-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/ml-pipeline-ui-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/ml-pipeline-ui-rolebinding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/ml-pipeline-ui-sa.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/ml-pipeline-ui-service.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/ml-pipeline-viewer-crd-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/ml-pipeline-viewer-crd-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/ml-pipeline-viewer-crd-rolebinding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/ml-pipeline-viewer-crd-sa.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/ml-pipeline-visualization-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/ml-pipeline-visualization-sa.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/ml-pipeline-visualization-service.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/pipeline-runner-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/pipeline-runner-rolebinding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/pipeline-runner-sa.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/pipeline/viewer-sa.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/postgresql/cache/cache-deployment-patch.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/postgresql/cache/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/postgresql/pipeline/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/postgresql/pipeline/ml-pipeline-apiserver-deployment-patch.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/webhook/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/webhook/params.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/webhook/pipelineversion-mutating-webhook-config.yaml create mode 100644 kubeflow/apps/pipeline/upstream/base/webhook/pipelineversion-validating-webhook-config.yaml create mode 100644 kubeflow/apps/pipeline/upstream/cluster-scoped-resources/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/cluster-scoped-resources/namespace.yaml create mode 100644 kubeflow/apps/pipeline/upstream/cluster-scoped-resources/params.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/aws/OWNERS create mode 100644 kubeflow/apps/pipeline/upstream/env/aws/README.md create mode 100644 kubeflow/apps/pipeline/upstream/env/aws/aws-configuration-pipeline-patch.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/aws/aws-configuration-pipeline-ui-patch.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/aws/config create mode 100644 kubeflow/apps/pipeline/upstream/env/aws/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/aws/minio-artifact-secret-patch.env create mode 100644 kubeflow/apps/pipeline/upstream/env/aws/params.env create mode 100644 kubeflow/apps/pipeline/upstream/env/aws/secret.env create mode 100644 kubeflow/apps/pipeline/upstream/env/aws/viewer-pod-template.json create mode 100644 kubeflow/apps/pipeline/upstream/env/azure/OWNERS create mode 100644 kubeflow/apps/pipeline/upstream/env/azure/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/azure/minio-azure-gateway/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/azure/minio-azure-gateway/minio-artifact-secret.env create mode 100644 kubeflow/apps/pipeline/upstream/env/azure/minio-azure-gateway/minio-azure-gateway-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/azure/minio-azure-gateway/minio-azure-gateway-service.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/azure/mysql-secret.env create mode 100644 kubeflow/apps/pipeline/upstream/env/azure/params.env create mode 100644 kubeflow/apps/pipeline/upstream/env/azure/readme.md create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/base-webhook-certs/kfp-api-cert-issuer.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/base-webhook-certs/kfp-api-cert.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/base-webhook-certs/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/base-webhook-certs/params.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/base/cache-cert-issuer.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/base/cache-cert.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/base/cache-webhook-config.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/base/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/base/params.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/cluster-scoped-resources/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/dev/delete-cache-deployer.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/dev/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/dev/namespace.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/dev/params.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/platform-agnostic-k8s-native/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/platform-agnostic-k8s-native/patches/deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/platform-agnostic-k8s-native/patches/mutating-webhook.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/platform-agnostic-k8s-native/patches/service.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/platform-agnostic-k8s-native/patches/validating-webhook.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/platform-agnostic-multi-user-k8s-native/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/platform-agnostic-multi-user-k8s-native/patches/deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/platform-agnostic-multi-user-k8s-native/patches/mutating-webhook.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/platform-agnostic-multi-user-k8s-native/patches/service.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/platform-agnostic-multi-user-k8s-native/patches/validating-webhook.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/platform-agnostic-multi-user/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/platform-agnostic-multi-user/patches/delete.clusterrole.cache-deployer.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/platform-agnostic-multi-user/patches/delete.crb.cache-deployer.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/platform-agnostic-multi-user/patches/delete.deployment.cache-deployer.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/platform-agnostic-multi-user/patches/delete.role.cache-deployer.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/platform-agnostic-multi-user/patches/delete.rolebinding.cache-deployer.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/cert-manager/platform-agnostic-multi-user/patches/delete.sa.cache-deployer.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/dev-kind/forward-local-api-endpoint.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/dev-kind/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/dev/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/dev/postgresql/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/gcp/cloudsql-proxy/cloudsql-proxy-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/gcp/cloudsql-proxy/cloudsql-proxy-sa.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/gcp/cloudsql-proxy/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/gcp/cloudsql-proxy/mysql-service.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/gcp/gcp-configurations-patch.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/gcp/inverse-proxy/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/gcp/inverse-proxy/proxy-configmap.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/gcp/inverse-proxy/proxy-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/gcp/inverse-proxy/proxy-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/gcp/inverse-proxy/proxy-rolebinding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/gcp/inverse-proxy/proxy-sa.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/gcp/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/gcp/minio-gcs-gateway/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/gcp/minio-gcs-gateway/minio-artifact-secret.env create mode 100644 kubeflow/apps/pipeline/upstream/env/gcp/minio-gcs-gateway/minio-gcs-gateway-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/gcp/minio-gcs-gateway/minio-gcs-gateway-sa.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/gcp/minio-gcs-gateway/minio-gcs-gateway-service.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/gcp/params.env create mode 100644 kubeflow/apps/pipeline/upstream/env/plain-multi-user/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/plain/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/platform-agnostic-emissary/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/platform-agnostic-multi-user-emissary/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/platform-agnostic-multi-user-legacy/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/platform-agnostic-multi-user/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/platform-agnostic-postgresql/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/env/platform-agnostic/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/gcp-workload-identity-setup.sh create mode 100644 kubeflow/apps/pipeline/upstream/hack/format.sh create mode 100644 kubeflow/apps/pipeline/upstream/hack/presubmit.sh create mode 100644 kubeflow/apps/pipeline/upstream/hack/release.sh create mode 100644 kubeflow/apps/pipeline/upstream/hack/test.sh create mode 100644 kubeflow/apps/pipeline/upstream/sample/README.md create mode 100644 kubeflow/apps/pipeline/upstream/sample/cluster-scoped-resources/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/sample/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/sample/params-db-secret.env create mode 100644 kubeflow/apps/pipeline/upstream/sample/params.env create mode 100644 kubeflow/apps/pipeline/upstream/third-party/application/application-controller-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/application/application-controller-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/application/application-controller-rolebinding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/application/application-controller-sa.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/application/application-controller-service.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/application/cluster-scoped/application-crd.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/application/cluster-scoped/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/application/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/.krmignore create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/Kptfile create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/Makefile create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/README.md create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/base/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/base/params.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/base/workflow-controller-configmap-patch.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/base/workflow-controller-deployment-patch.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/installs/cluster/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/installs/cluster/workflow-controller-clusterrolebinding-patch.json create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/installs/namespace/cluster-scoped/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/installs/namespace/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/installs/namespace/workflow-controller-deployment-patch.json create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/Kptfile create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/LICENSE create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/argo-server/argo-server-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/argo-server/argo-server-sa.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/argo-server/argo-server-service.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/argo-server/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/crds/full/README.md create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/crds/full/argoproj.io_cronworkflows.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/crds/full/argoproj.io_workflowartifactgctasks.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/crds/full/argoproj.io_workfloweventbindings.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/crds/full/argoproj.io_workflows.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/crds/full/argoproj.io_workflowtaskresults.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/crds/full/argoproj.io_workflowtasksets.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/crds/full/argoproj.io_workflowtemplates.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/crds/full/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/crds/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/crds/minimal/README.md create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/crds/minimal/argoproj.io_clusterworkflowtemplates.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/crds/minimal/argoproj.io_cronworkflows.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/crds/minimal/argoproj.io_workflowartifactgctasks.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/crds/minimal/argoproj.io_workfloweventbindings.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/crds/minimal/argoproj.io_workflows.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/crds/minimal/argoproj.io_workflowtaskresults.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/crds/minimal/argoproj.io_workflowtasksets.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/crds/minimal/argoproj.io_workflowtemplates.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/crds/minimal/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/workflow-controller/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/workflow-controller/workflow-controller-configmap.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/workflow-controller/workflow-controller-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/workflow-controller/workflow-controller-priorityclass.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/base/workflow-controller/workflow-controller-sa.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/cluster-install/argo-server-rbac/argo-server-clusterole.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/cluster-install/argo-server-rbac/argo-server-clusterolebinding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/cluster-install/argo-server-rbac/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/cluster-install/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/cluster-install/workflow-controller-rbac/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/cluster-install/workflow-controller-rbac/workflow-aggregate-roles.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/cluster-install/workflow-controller-rbac/workflow-controller-clusterrole.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/cluster-install/workflow-controller-rbac/workflow-controller-clusterrolebinding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/cluster-install/workflow-controller-rbac/workflow-controller-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/cluster-install/workflow-controller-rbac/workflow-controller-rolebinding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/namespace-install/argo-server-rbac/argo-server-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/namespace-install/argo-server-rbac/argo-server-rolebinding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/namespace-install/argo-server-rbac/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/namespace-install/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/namespace-install/overlays/argo-server-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/namespace-install/overlays/workflow-controller-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/namespace-install/workflow-controller-rbac/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/namespace-install/workflow-controller-rbac/workflow-controller-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/namespace-install/workflow-controller-rbac/workflow-controller-rolebinding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/agent-default-rolebinding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/agent-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/argo-server-sso-secret.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/artifact-repositories-configmap.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/artifactgc-default-rolebinding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/artifactgc-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/cluster-workflow-template-rbac.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/default.service-account-token-secret.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/executor-default-rolebinding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/executor/docker/executor-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/executor/emissary/executor-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/executor/k8sapi/executor-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/executor/kubelet/executor-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/executor/kubelet/kubelet-executor-clusterrole.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/executor/kubelet/kubelet-executor-default-clusterrolebinding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/executor/pns/executor-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/httpbin/httpbin-deploy.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/httpbin/httpbin-service.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/httpbin/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/httpbin/my-httpbin-cred-secret.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/memoizer-default-rolebinding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/memoizer-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/minio/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/minio/minio-deploy.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/minio/minio-service.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/minio/my-minio-cred-secret.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/overlays/argo-server-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/overlays/workflow-controller-configmap.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/pod-manager-default-rolebinding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/pod-manager-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/prometheus/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/prometheus/prometheus-config-cluster.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/prometheus/prometheus-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/prometheus/prometheus-service.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/webhooks/argo-workflows-webhook-clients-secret.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/webhooks/github.com-rolebinding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/webhooks/github.com-sa.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/webhooks/github.com-secret.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/webhooks/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/webhooks/submit-workflow-template-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/workflow-default-rolebinding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/workflow-manager-default-rolebinding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/base/workflow-manager-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/minimal/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/minimal/overlays/workflow-controller-configmap.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/mysql/argo-mysql-config-secret.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/mysql/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/mysql/mysql-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/mysql/mysql-service.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/mysql/overlays/workflow-controller-configmap.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/postgres/argo-postgres-config-secret.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/postgres/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/postgres/overlays/workflow-controller-configmap.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/postgres/postgres-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/postgres/postgres-service.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/sso/dex/dev-svc.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/sso/dex/dex-cm.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/sso/dex/dex-deploy.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/sso/dex/dex-rb.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/sso/dex/dex-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/sso/dex/dex-sa.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/sso/dex/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/sso/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/sso/overlays/argo-server-sa.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/argo/upstream/manifests/quick-start/sso/overlays/workflow-controller-configmap.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/grafana/grafana-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/grafana/grafana-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/grafana/grafana-rolebinding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/grafana/grafana-sa.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/grafana/grafana-service.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/grafana/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/metacontroller/base/cluster-role-binding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/metacontroller/base/cluster-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/metacontroller/base/crd.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/metacontroller/base/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/metacontroller/base/service-account.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/metacontroller/base/stateful-set.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/minio/base/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/minio/base/minio-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/minio/base/minio-pvc.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/minio/base/minio-service.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/minio/base/mlpipeline-minio-artifact-secret.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/minio/options/istio/istio-authorization-policy.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/minio/options/istio/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/mysql/base/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/mysql/base/mysql-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/mysql/base/mysql-pv-claim.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/mysql/base/mysql-service.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/mysql/base/mysql-serviceaccount.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/mysql/options/istio/istio-authorization-policy.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/mysql/options/istio/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/postgresql/README.md create mode 100644 kubeflow/apps/pipeline/upstream/third-party/postgresql/base/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/postgresql/base/pg-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/postgresql/base/pg-pvc.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/postgresql/base/pg-secret.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/postgresql/base/pg-service.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/postgresql/base/pg-serviceaccount.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/prometheus/kustomization.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/prometheus/prometheus-configmap.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/prometheus/prometheus-deployment.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/prometheus/prometheus-role.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/prometheus/prometheus-rolebinding.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/prometheus/prometheus-sa.yaml create mode 100644 kubeflow/apps/pipeline/upstream/third-party/prometheus/prometheus-service.yaml create mode 100644 kubeflow/apps/pipeline/upstream/wi-utils.sh create mode 100644 kubeflow/apps/profiles/upstream/README.md create mode 100644 kubeflow/apps/profiles/upstream/base/kustomization.yaml create mode 100644 kubeflow/apps/profiles/upstream/base/namespace-labels.yaml create mode 100644 kubeflow/apps/profiles/upstream/base/patches/manager.yaml create mode 100644 kubeflow/apps/profiles/upstream/crd/bases/kubeflow.org_profiles.yaml create mode 100644 kubeflow/apps/profiles/upstream/crd/kustomization.yaml create mode 100644 kubeflow/apps/profiles/upstream/crd/kustomizeconfig.yaml create mode 100644 kubeflow/apps/profiles/upstream/crd/patches/cainjection_in_profiles.yaml create mode 100644 kubeflow/apps/profiles/upstream/crd/patches/trivial_conversion_patch.yaml create mode 100644 kubeflow/apps/profiles/upstream/crd/patches/webhook_in_profiles.yaml create mode 100644 kubeflow/apps/profiles/upstream/default/kustomization.yaml create mode 100644 kubeflow/apps/profiles/upstream/default/manager_auth_proxy_patch.yaml create mode 100644 kubeflow/apps/profiles/upstream/default/manager_prometheus_metrics_patch.yaml create mode 100644 kubeflow/apps/profiles/upstream/default/manager_webhook_patch.yaml create mode 100644 kubeflow/apps/profiles/upstream/default/webhookcainjection_patch.yaml create mode 100644 kubeflow/apps/profiles/upstream/manager/kustomization.yaml create mode 100644 kubeflow/apps/profiles/upstream/manager/manager.yaml create mode 100644 kubeflow/apps/profiles/upstream/manager/service-account.yaml create mode 100644 kubeflow/apps/profiles/upstream/overlays/kubeflow/authorizationpolicy.yaml create mode 100644 kubeflow/apps/profiles/upstream/overlays/kubeflow/kustomization.yaml create mode 100644 kubeflow/apps/profiles/upstream/overlays/kubeflow/params.yaml create mode 100644 kubeflow/apps/profiles/upstream/overlays/kubeflow/patches/kfam.yaml create mode 100644 kubeflow/apps/profiles/upstream/overlays/kubeflow/patches/remove-namespace.yaml create mode 100644 kubeflow/apps/profiles/upstream/overlays/kubeflow/service.yaml create mode 100644 kubeflow/apps/profiles/upstream/overlays/kubeflow/virtual-service.yaml create mode 100644 kubeflow/apps/profiles/upstream/overlays/standalone/kustomization.yaml create mode 100644 kubeflow/apps/profiles/upstream/prometheus/kustomization.yaml create mode 100644 kubeflow/apps/profiles/upstream/prometheus/monitor.yaml create mode 100644 kubeflow/apps/profiles/upstream/rbac/auth_proxy_client_clusterrole.yaml create mode 100644 kubeflow/apps/profiles/upstream/rbac/auth_proxy_role.yaml create mode 100644 kubeflow/apps/profiles/upstream/rbac/auth_proxy_role_binding.yaml create mode 100644 kubeflow/apps/profiles/upstream/rbac/auth_proxy_service.yaml create mode 100644 kubeflow/apps/profiles/upstream/rbac/kustomization.yaml create mode 100644 kubeflow/apps/profiles/upstream/rbac/leader_election_role.yaml create mode 100644 kubeflow/apps/profiles/upstream/rbac/leader_election_role_binding.yaml create mode 100644 kubeflow/apps/profiles/upstream/rbac/profile_editor_role.yaml create mode 100644 kubeflow/apps/profiles/upstream/rbac/profile_viewer_role.yaml create mode 100644 kubeflow/apps/profiles/upstream/rbac/role.yaml create mode 100644 kubeflow/apps/profiles/upstream/rbac/role_binding.yaml create mode 100644 kubeflow/apps/profiles/upstream/rbac/service_account.yaml create mode 100644 kubeflow/apps/profiles/upstream/samples/_v1_profile.yaml create mode 100644 kubeflow/apps/profiles/upstream/samples/_v1_profile_aws_iam.yaml create mode 100644 kubeflow/apps/profiles/upstream/samples/_v1beta1_profile.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/base/kustomization.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/certmanager/certificate.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/certmanager/kustomization.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/certmanager/kustomizeconfig.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/crd/bases/kubeflow.org_pvcviewers.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/crd/kustomization.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/crd/kustomizeconfig.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/crd/patches/cainjection_in_pvcviewers.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/crd/patches/webhook_in_pvcviewers.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/default/cainjection_patch.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/default/dnsnames_patch.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/default/kustomization.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/default/kustomizeconfig.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/default/manager_auth_proxy_patch.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/default/manager_webhook_patch.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/default/remove_namespace.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/manager/kustomization.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/manager/manager.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/prometheus/kustomization.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/prometheus/monitor.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/rbac/auth_proxy_client_clusterrole.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/rbac/auth_proxy_role.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/rbac/auth_proxy_role_binding.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/rbac/auth_proxy_service.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/rbac/kustomization.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/rbac/leader_election_role.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/rbac/leader_election_role_binding.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/rbac/role.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/rbac/role_binding.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/rbac/service_account.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/rbac/volumesviewer_editor_role.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/rbac/volumesviewer_viewer_role.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/samples/_v1alpha1_pvcviewer.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/samples/kustomization.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/webhook/kustomization.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/webhook/kustomizeconfig.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/webhook/manifests.yaml create mode 100644 kubeflow/apps/pvcviewer-controller/upstream/webhook/service.yaml create mode 100644 kubeflow/apps/spark/OWNERS create mode 100644 kubeflow/apps/spark/README.md create mode 100644 kubeflow/apps/spark/spark-operator/base/aggregated-roles.yaml create mode 100644 kubeflow/apps/spark/spark-operator/base/kustomization.yaml create mode 100644 kubeflow/apps/spark/spark-operator/base/resources.yaml create mode 100644 kubeflow/apps/spark/spark-operator/overlays/kubeflow/kustomization.yaml create mode 100644 kubeflow/apps/spark/spark-operator/overlays/standalone/kustomization.yaml create mode 100644 kubeflow/apps/spark/sparkapplication_example.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/base/kustomization.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/base/patches/add_controller_config.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/base/patches/add_service_account.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/base/service_account.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/certmanager/certificate.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/certmanager/kustomization.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/certmanager/kustomizeconfig.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/crd/bases/tensorboard.kubeflow.org_tensorboards.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/crd/kustomization.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/crd/kustomizeconfig.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/crd/patches/cainjection_in_tensorboards.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/crd/patches/webhook_in_tensorboards.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/default/kustomization.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/default/manager_auth_proxy_patch.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/default/manager_prometheus_metrics_patch.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/default/manager_webhook_patch.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/default/webhookcainjection_patch.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/manager/controller_manager_config.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/manager/kustomization.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/manager/manager.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/overlays/kubeflow/kustomization.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/overlays/kubeflow/patches/remove-namespace.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/overlays/standalone/kustomization.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/prometheus/kustomization.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/prometheus/monitor.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/rbac/auth_proxy_client_clusterrole.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/rbac/auth_proxy_role.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/rbac/auth_proxy_role_binding.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/rbac/auth_proxy_service.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/rbac/kustomization.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/rbac/leader_election_role.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/rbac/leader_election_role_binding.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/rbac/role.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/rbac/role_binding.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/rbac/service_account.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/samples/tensorboard_v1alpha1_tensorboard.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/webhook/kustomization.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/webhook/kustomizeconfig.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/webhook/manifests.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboard-controller/upstream/webhook/service.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboards-web-app/upstream/base/cluster-role-binding.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboards-web-app/upstream/base/cluster-role.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboards-web-app/upstream/base/deployment.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboards-web-app/upstream/base/kustomization.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboards-web-app/upstream/base/params.env create mode 100644 kubeflow/apps/tensorboard/tensorboards-web-app/upstream/base/service-account.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboards-web-app/upstream/base/service.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboards-web-app/upstream/overlays/istio/authorization-policy.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboards-web-app/upstream/overlays/istio/destination-rule.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboards-web-app/upstream/overlays/istio/kustomization.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboards-web-app/upstream/overlays/istio/params.yaml create mode 100644 kubeflow/apps/tensorboard/tensorboards-web-app/upstream/overlays/istio/virtual-service.yaml create mode 100644 kubeflow/apps/training-operator/upstream/base/crds/kubeflow.org_jaxjobs.yaml create mode 100644 kubeflow/apps/training-operator/upstream/base/crds/kubeflow.org_mpijobs.yaml create mode 100644 kubeflow/apps/training-operator/upstream/base/crds/kubeflow.org_paddlejobs.yaml create mode 100644 kubeflow/apps/training-operator/upstream/base/crds/kubeflow.org_pytorchjobs.yaml create mode 100644 kubeflow/apps/training-operator/upstream/base/crds/kubeflow.org_tfjobs.yaml create mode 100644 kubeflow/apps/training-operator/upstream/base/crds/kubeflow.org_xgboostjobs.yaml create mode 100644 kubeflow/apps/training-operator/upstream/base/crds/kustomization.yaml create mode 100644 kubeflow/apps/training-operator/upstream/base/deployment.yaml create mode 100644 kubeflow/apps/training-operator/upstream/base/kustomization.yaml create mode 100644 kubeflow/apps/training-operator/upstream/base/rbac/cluster-role-binding.yaml create mode 100644 kubeflow/apps/training-operator/upstream/base/rbac/role.yaml create mode 100644 kubeflow/apps/training-operator/upstream/base/rbac/service-account.yaml create mode 100644 kubeflow/apps/training-operator/upstream/base/service.yaml create mode 100644 kubeflow/apps/training-operator/upstream/base/webhook/kustomization.yaml create mode 100644 kubeflow/apps/training-operator/upstream/base/webhook/kustomizeconfig.yaml create mode 100644 kubeflow/apps/training-operator/upstream/base/webhook/manifests.yaml create mode 100644 kubeflow/apps/training-operator/upstream/base/webhook/patch.yaml create mode 100644 kubeflow/apps/training-operator/upstream/overlays/kubeflow/kubeflow-training-roles.yaml create mode 100644 kubeflow/apps/training-operator/upstream/overlays/kubeflow/kustomization.yaml create mode 100644 kubeflow/apps/training-operator/upstream/overlays/standalone/kustomization.yaml create mode 100644 kubeflow/apps/training-operator/upstream/overlays/standalone/namespace.yaml create mode 100644 kubeflow/apps/training-operator/upstream/v2/base/crds/kubeflow.org_clustertrainingruntimes.yaml create mode 100644 kubeflow/apps/training-operator/upstream/v2/base/crds/kubeflow.org_trainingruntimes.yaml create mode 100644 kubeflow/apps/training-operator/upstream/v2/base/crds/kubeflow.org_trainjobs.yaml create mode 100644 kubeflow/apps/training-operator/upstream/v2/base/crds/kustomization.yaml create mode 100644 kubeflow/apps/training-operator/upstream/v2/base/manager/kustomization.yaml create mode 100644 kubeflow/apps/training-operator/upstream/v2/base/manager/manager.yaml create mode 100644 kubeflow/apps/training-operator/upstream/v2/base/rbac/kustomization.yaml create mode 100644 kubeflow/apps/training-operator/upstream/v2/base/rbac/role.yaml create mode 100644 kubeflow/apps/training-operator/upstream/v2/base/rbac/role_binding.yaml create mode 100644 kubeflow/apps/training-operator/upstream/v2/base/rbac/service_account.yaml create mode 100644 kubeflow/apps/training-operator/upstream/v2/base/runtimes/pre-training/kustomization.yaml create mode 100644 kubeflow/apps/training-operator/upstream/v2/base/runtimes/pre-training/torch-distributed.yaml create mode 100644 kubeflow/apps/training-operator/upstream/v2/base/webhook/kustomization.yaml create mode 100644 kubeflow/apps/training-operator/upstream/v2/base/webhook/kustomizeconfig.yaml create mode 100644 kubeflow/apps/training-operator/upstream/v2/base/webhook/manifests.yaml create mode 100644 kubeflow/apps/training-operator/upstream/v2/base/webhook/patch.yaml create mode 100644 kubeflow/apps/training-operator/upstream/v2/overlays/only-manager/kustomization.yaml create mode 100644 kubeflow/apps/training-operator/upstream/v2/overlays/only-manager/namespace.yaml create mode 100644 kubeflow/apps/training-operator/upstream/v2/overlays/only-runtimes/kustomization.yaml create mode 100644 kubeflow/apps/training-operator/upstream/v2/overlays/standalone/kustomization.yaml create mode 100644 kubeflow/apps/training-operator/upstream/v2/overlays/standalone/namespace.yaml create mode 100644 kubeflow/apps/volumes-web-app/upstream/base/cluster-role-binding.yaml create mode 100644 kubeflow/apps/volumes-web-app/upstream/base/cluster-role.yaml create mode 100644 kubeflow/apps/volumes-web-app/upstream/base/deployment.yaml create mode 100644 kubeflow/apps/volumes-web-app/upstream/base/kustomization.yaml create mode 100644 kubeflow/apps/volumes-web-app/upstream/base/params.env create mode 100644 kubeflow/apps/volumes-web-app/upstream/base/service-account.yaml create mode 100644 kubeflow/apps/volumes-web-app/upstream/base/service.yaml create mode 100644 kubeflow/apps/volumes-web-app/upstream/base/viewer-spec.yaml create mode 100644 kubeflow/apps/volumes-web-app/upstream/overlays/istio/authorization-policy.yaml create mode 100644 kubeflow/apps/volumes-web-app/upstream/overlays/istio/destination-rule.yaml create mode 100644 kubeflow/apps/volumes-web-app/upstream/overlays/istio/kustomization.yaml create mode 100644 kubeflow/apps/volumes-web-app/upstream/overlays/istio/params.yaml create mode 100644 kubeflow/apps/volumes-web-app/upstream/overlays/istio/virtual-service.yaml create mode 100644 kubeflow/common/cert-manager/OWNERS create mode 100644 kubeflow/common/cert-manager/README.md create mode 100644 kubeflow/common/cert-manager/base/kustomization.yaml create mode 100644 kubeflow/common/cert-manager/base/upstream/cert-manager.yaml create mode 100644 kubeflow/common/cert-manager/kubeflow-issuer/base/cluster-issuer.yaml create mode 100644 kubeflow/common/cert-manager/kubeflow-issuer/base/kustomization.yaml create mode 100644 kubeflow/common/dex/OWNERS create mode 100644 kubeflow/common/dex/README.md create mode 100644 kubeflow/common/dex/base/config-map.yaml create mode 100644 kubeflow/common/dex/base/crds.yaml create mode 100644 kubeflow/common/dex/base/deployment.yaml create mode 100644 kubeflow/common/dex/base/dex-passwords.yaml create mode 100644 kubeflow/common/dex/base/kustomization.yaml create mode 100644 kubeflow/common/dex/base/namespace.yaml create mode 100644 kubeflow/common/dex/base/secret_params.env create mode 100644 kubeflow/common/dex/base/service.yaml create mode 100644 kubeflow/common/dex/overlays/istio/kustomization.yaml create mode 100644 kubeflow/common/dex/overlays/istio/virtual-service.yaml create mode 100644 kubeflow/common/dex/overlays/oauth2-proxy/config-map.yaml create mode 100644 kubeflow/common/dex/overlays/oauth2-proxy/kustomization.yaml create mode 100644 kubeflow/common/istio-1-24/README.md create mode 100644 kubeflow/common/istio-1-24/cluster-local-gateway/base/cluster-local-gateway.yaml create mode 100644 kubeflow/common/istio-1-24/cluster-local-gateway/base/gateway-authorizationpolicy.yaml create mode 100644 kubeflow/common/istio-1-24/cluster-local-gateway/base/gateway.yaml create mode 100644 kubeflow/common/istio-1-24/cluster-local-gateway/base/kustomization.yaml create mode 100644 kubeflow/common/istio-1-24/cluster-local-gateway/base/patches/remove-pdb.yaml create mode 100644 kubeflow/common/istio-1-24/istio-crds/base/crd.yaml create mode 100644 kubeflow/common/istio-1-24/istio-crds/base/kustomization.yaml create mode 100644 kubeflow/common/istio-1-24/istio-install/base/deny_all_authorizationpolicy.yaml create mode 100644 kubeflow/common/istio-1-24/istio-install/base/gateway.yaml create mode 100644 kubeflow/common/istio-1-24/istio-install/base/gateway_authorizationpolicy.yaml create mode 100644 kubeflow/common/istio-1-24/istio-install/base/install.yaml create mode 100644 kubeflow/common/istio-1-24/istio-install/base/kustomization.yaml create mode 100644 kubeflow/common/istio-1-24/istio-install/base/patches/disable-debugging.yaml create mode 100644 kubeflow/common/istio-1-24/istio-install/base/patches/istio-configmap-disable-tracing.yaml create mode 100644 kubeflow/common/istio-1-24/istio-install/base/patches/istio-ingressgateway-remove-pdb.yaml create mode 100644 kubeflow/common/istio-1-24/istio-install/base/patches/istiod-remove-pdb.yaml create mode 100644 kubeflow/common/istio-1-24/istio-install/base/patches/seccomp-istio-ingressgateway.yaml create mode 100644 kubeflow/common/istio-1-24/istio-install/base/patches/seccomp-istiod.yaml create mode 100644 kubeflow/common/istio-1-24/istio-install/base/patches/service.yaml create mode 100644 kubeflow/common/istio-1-24/istio-install/overlays/oauth2-proxy/kustomization.yaml create mode 100644 kubeflow/common/istio-1-24/istio-namespace/base/kustomization.yaml create mode 100644 kubeflow/common/istio-1-24/istio-namespace/base/namespace.yaml create mode 100644 kubeflow/common/istio-1-24/kubeflow-istio-resources/base/cluster-roles.yaml create mode 100644 kubeflow/common/istio-1-24/kubeflow-istio-resources/base/kf-istio-resources.yaml create mode 100644 kubeflow/common/istio-1-24/kubeflow-istio-resources/base/kustomization.yaml create mode 100644 kubeflow/common/istio-1-24/profile-overlay.yaml create mode 100644 kubeflow/common/istio-1-24/profile.yaml create mode 100644 kubeflow/common/istio-1-24/split-istio-packages create mode 100644 kubeflow/common/istio-cni-1-24/README.md create mode 100644 kubeflow/common/istio-cni-1-24/cluster-local-gateway/base/cluster-local-gateway.yaml create mode 100644 kubeflow/common/istio-cni-1-24/cluster-local-gateway/base/gateway-authorizationpolicy.yaml create mode 100644 kubeflow/common/istio-cni-1-24/cluster-local-gateway/base/gateway.yaml create mode 100644 kubeflow/common/istio-cni-1-24/cluster-local-gateway/base/kustomization.yaml create mode 100644 kubeflow/common/istio-cni-1-24/cluster-local-gateway/base/patches/remove-pdb.yaml create mode 100644 kubeflow/common/istio-cni-1-24/istio-crds/base/crd.yaml create mode 100644 kubeflow/common/istio-cni-1-24/istio-crds/base/kustomization.yaml create mode 100644 kubeflow/common/istio-cni-1-24/istio-install/base/deny_all_authorizationpolicy.yaml create mode 100644 kubeflow/common/istio-cni-1-24/istio-install/base/gateway.yaml create mode 100644 kubeflow/common/istio-cni-1-24/istio-install/base/gateway_authorizationpolicy.yaml create mode 100644 kubeflow/common/istio-cni-1-24/istio-install/base/install.yaml create mode 100644 kubeflow/common/istio-cni-1-24/istio-install/base/kustomization.yaml create mode 100644 kubeflow/common/istio-cni-1-24/istio-install/base/patches/disable-debugging.yaml create mode 100644 kubeflow/common/istio-cni-1-24/istio-install/base/patches/istio-configmap-disable-tracing.yaml create mode 100644 kubeflow/common/istio-cni-1-24/istio-install/base/patches/istio-ingressgateway-remove-pdb.yaml create mode 100644 kubeflow/common/istio-cni-1-24/istio-install/base/patches/istiod-remove-pdb.yaml create mode 100644 kubeflow/common/istio-cni-1-24/istio-install/base/patches/seccomp-istio-ingressgateway.yaml create mode 100644 kubeflow/common/istio-cni-1-24/istio-install/base/patches/seccomp-istiod.yaml create mode 100644 kubeflow/common/istio-cni-1-24/istio-install/base/patches/service.yaml create mode 100644 kubeflow/common/istio-cni-1-24/istio-install/overlays/oauth2-proxy/kustomization.yaml create mode 100644 kubeflow/common/istio-cni-1-24/istio-namespace/base/kustomization.yaml create mode 100644 kubeflow/common/istio-cni-1-24/istio-namespace/base/namespace.yaml create mode 100644 kubeflow/common/istio-cni-1-24/kubeflow-istio-resources/base/cluster-roles.yaml create mode 100644 kubeflow/common/istio-cni-1-24/kubeflow-istio-resources/base/kf-istio-resources.yaml create mode 100644 kubeflow/common/istio-cni-1-24/kubeflow-istio-resources/base/kustomization.yaml create mode 100644 kubeflow/common/istio-cni-1-24/profile-overlay.yaml create mode 100644 kubeflow/common/istio-cni-1-24/profile.yaml create mode 100644 kubeflow/common/istio-cni-1-24/split-istio-packages create mode 100644 kubeflow/common/knative/OWNERS create mode 100644 kubeflow/common/knative/README.md create mode 100644 kubeflow/common/knative/knative-eventing-post-install-jobs/base/eventing-post-install.yaml create mode 100644 kubeflow/common/knative/knative-eventing-post-install-jobs/base/kustomization.yaml create mode 100644 kubeflow/common/knative/knative-eventing/base/kustomization.yaml create mode 100644 kubeflow/common/knative/knative-eventing/base/patches/clusterrole-patch.yaml create mode 100644 kubeflow/common/knative/knative-eventing/base/upstream/eventing-core.yaml create mode 100644 kubeflow/common/knative/knative-eventing/base/upstream/in-memory-channel.yaml create mode 100644 kubeflow/common/knative/knative-eventing/base/upstream/mt-channel-broker.yaml create mode 100644 kubeflow/common/knative/knative-serving-post-install-jobs/base/kustomization.yaml create mode 100644 kubeflow/common/knative/knative-serving-post-install-jobs/base/serving-post-install-jobs.yaml create mode 100644 kubeflow/common/knative/knative-serving/base/istio-authorization-policy.yaml create mode 100644 kubeflow/common/knative/knative-serving/base/kustomization.yaml create mode 100644 kubeflow/common/knative/knative-serving/base/patches/config-deployment.yaml create mode 100644 kubeflow/common/knative/knative-serving/base/patches/config-istio.yaml create mode 100644 kubeflow/common/knative/knative-serving/base/patches/knative-serving-namespaced-admin.yaml create mode 100644 kubeflow/common/knative/knative-serving/base/patches/knative-serving-namespaced-edit.yaml create mode 100644 kubeflow/common/knative/knative-serving/base/patches/knative-serving-namespaced-view.yaml create mode 100644 kubeflow/common/knative/knative-serving/base/patches/namespace-injection.yaml create mode 100644 kubeflow/common/knative/knative-serving/base/patches/remove-gateway.yaml create mode 100644 kubeflow/common/knative/knative-serving/base/patches/seccomp.yaml create mode 100644 kubeflow/common/knative/knative-serving/base/patches/service-labels.yaml create mode 100644 kubeflow/common/knative/knative-serving/base/patches/sidecar-injection.yaml create mode 100644 kubeflow/common/knative/knative-serving/base/upstream/net-istio.yaml create mode 100644 kubeflow/common/knative/knative-serving/base/upstream/serving-core.yaml create mode 100644 kubeflow/common/knative/knative-serving/overlays/gateways/kustomization.yaml create mode 100644 kubeflow/common/knative/knative-serving/overlays/gateways/patches/config-domain.yaml create mode 100644 kubeflow/common/knative/knative-serving/overlays/gateways/patches/gateway-selector-in-istio-system.yaml create mode 100644 kubeflow/common/knative/knative-serving/overlays/gateways/patches/gateway-selector-in-knative-serving.yaml create mode 100644 kubeflow/common/kubeflow-namespace/base/kustomization.yaml create mode 100644 kubeflow/common/kubeflow-namespace/base/namespace.yaml create mode 100644 kubeflow/common/kubeflow-roles/OWNERS create mode 100644 kubeflow/common/kubeflow-roles/README.md create mode 100644 kubeflow/common/kubeflow-roles/base/cluster-roles.yaml create mode 100644 kubeflow/common/kubeflow-roles/base/kustomization.yaml create mode 100644 kubeflow/common/networkpolicies/OWNERS create mode 100644 kubeflow/common/networkpolicies/README.md create mode 100644 kubeflow/common/networkpolicies/base/cache-server.yaml create mode 100644 kubeflow/common/networkpolicies/base/centraldashboard.yaml create mode 100644 kubeflow/common/networkpolicies/base/default-allow-same-namespace.yaml create mode 100644 kubeflow/common/networkpolicies/base/jupyter-web-app.yaml create mode 100644 kubeflow/common/networkpolicies/base/katib-controller.yaml create mode 100644 kubeflow/common/networkpolicies/base/katib-db-manager.yaml create mode 100644 kubeflow/common/networkpolicies/base/katib-ui.yaml create mode 100644 kubeflow/common/networkpolicies/base/kserve-models-web-app.yaml create mode 100644 kubeflow/common/networkpolicies/base/kserve.yaml create mode 100644 kubeflow/common/networkpolicies/base/kustomization.yaml create mode 100644 kubeflow/common/networkpolicies/base/metadata-envoy.yaml create mode 100644 kubeflow/common/networkpolicies/base/metadata-grpc-server.yaml create mode 100644 kubeflow/common/networkpolicies/base/minio.yaml create mode 100644 kubeflow/common/networkpolicies/base/ml-pipeline-ui.yaml create mode 100644 kubeflow/common/networkpolicies/base/ml-pipeline.yaml create mode 100644 kubeflow/common/networkpolicies/base/model-registry-ui.yaml create mode 100644 kubeflow/common/networkpolicies/base/model-registry.yaml create mode 100644 kubeflow/common/networkpolicies/base/poddefaults.yaml create mode 100644 kubeflow/common/networkpolicies/base/pvcviewer-webhook.yaml create mode 100644 kubeflow/common/networkpolicies/base/spark-operator-webhook.yaml create mode 100644 kubeflow/common/networkpolicies/base/tensorboards-web-app.yaml create mode 100644 kubeflow/common/networkpolicies/base/training-operator-webhook.yaml create mode 100644 kubeflow/common/networkpolicies/base/volumes-web-app.yaml create mode 100644 kubeflow/common/oauth2-proxy/OWNERS create mode 100644 kubeflow/common/oauth2-proxy/README.md create mode 100644 kubeflow/common/oauth2-proxy/base/README.md create mode 100644 kubeflow/common/oauth2-proxy/base/deployment.yaml create mode 100644 kubeflow/common/oauth2-proxy/base/kubeflow-logo.svg create mode 100644 kubeflow/common/oauth2-proxy/base/kustomization.yaml create mode 100644 kubeflow/common/oauth2-proxy/base/namespace.yaml create mode 100644 kubeflow/common/oauth2-proxy/base/oauth2_proxy.cfg create mode 100644 kubeflow/common/oauth2-proxy/base/service.yaml create mode 100644 kubeflow/common/oauth2-proxy/base/serviceaccount.yaml create mode 100644 kubeflow/common/oauth2-proxy/base/virtualservice.yaml create mode 100644 kubeflow/common/oauth2-proxy/components/README.md create mode 100644 kubeflow/common/oauth2-proxy/components/allow-unauthenticated-issuer-discovery/README.md create mode 100644 kubeflow/common/oauth2-proxy/components/allow-unauthenticated-issuer-discovery/clusterrolebinding.unauthenticated-oidc-viewer.yaml create mode 100644 kubeflow/common/oauth2-proxy/components/allow-unauthenticated-issuer-discovery/kustomization.yaml create mode 100644 kubeflow/common/oauth2-proxy/components/central-dashboard/kustomization.yaml create mode 100644 kubeflow/common/oauth2-proxy/components/central-dashboard/patches/deployment.logout-url.yaml create mode 100644 kubeflow/common/oauth2-proxy/components/cluster-jwks-proxy/README.md create mode 100644 kubeflow/common/oauth2-proxy/components/cluster-jwks-proxy/cluster-jwks-proxy.yaml create mode 100644 kubeflow/common/oauth2-proxy/components/cluster-jwks-proxy/kustomization.yaml create mode 100644 kubeflow/common/oauth2-proxy/components/istio-external-auth-patches/README.md create mode 100644 kubeflow/common/oauth2-proxy/components/istio-external-auth-patches/kustomization.yaml create mode 100644 kubeflow/common/oauth2-proxy/components/istio-external-auth-patches/patches/cm.enable-oauth2-proxy.yaml create mode 100644 kubeflow/common/oauth2-proxy/components/istio-external-auth-patches/patches/deployment.jwt-refresh-interval.yaml create mode 100644 kubeflow/common/oauth2-proxy/components/istio-external-auth/README.md create mode 100644 kubeflow/common/oauth2-proxy/components/istio-external-auth/authorizationpolicy.istio-ingressgateway-oauth2-proxy.cloudflare.yaml create mode 100644 kubeflow/common/oauth2-proxy/components/istio-external-auth/authorizationpolicy.istio-ingressgateway-oauth2-proxy.yaml create mode 100644 kubeflow/common/oauth2-proxy/components/istio-external-auth/authorizationpolicy.istio-ingressgateway-require-jwt.cloudflare.yaml create mode 100644 kubeflow/common/oauth2-proxy/components/istio-external-auth/authorizationpolicy.istio-ingressgateway-require-jwt.yaml create mode 100644 kubeflow/common/oauth2-proxy/components/istio-external-auth/kustomization.yaml create mode 100644 kubeflow/common/oauth2-proxy/components/istio-external-auth/requestauthentication.dex-jwt.yaml create mode 100644 kubeflow/common/oauth2-proxy/components/istio-m2m/README.md create mode 100644 kubeflow/common/oauth2-proxy/components/istio-m2m/kustomization.yaml create mode 100644 kubeflow/common/oauth2-proxy/components/istio-m2m/requestauthentication.yaml create mode 100644 kubeflow/common/oauth2-proxy/components/kubeflow_auth_diagram.svg create mode 100644 kubeflow/common/oauth2-proxy/components/oauth2-flow.svg create mode 100644 kubeflow/common/oauth2-proxy/overlays/m2m-dex-and-eks/kustomization.yaml create mode 100644 kubeflow/common/oauth2-proxy/overlays/m2m-dex-and-kind/kustomization.yaml create mode 100644 kubeflow/common/oauth2-proxy/overlays/m2m-dex-only/kustomization.yaml create mode 100644 kubeflow/common/oauth2-proxy/overlays/m2m-keycloak/istio-keycloak-auth/authorizationpolicy.istio-ingressgateway-oauth2-proxy.yaml create mode 100644 kubeflow/common/oauth2-proxy/overlays/m2m-keycloak/istio-keycloak-auth/authorizationpolicy.istio-ingressgateway-require-jwt.yaml create mode 100644 kubeflow/common/oauth2-proxy/overlays/m2m-keycloak/istio-keycloak-auth/kustomization.yaml create mode 100644 kubeflow/common/oauth2-proxy/overlays/m2m-keycloak/istio-keycloak-auth/requestauthentication.keycloak-jwt.yaml create mode 100644 kubeflow/common/oauth2-proxy/overlays/m2m-keycloak/kustomization.yaml create mode 100644 kubeflow/common/oauth2-proxy/overlays/m2m-keycloak/m2m.env create mode 100644 kubeflow/common/oauth2-proxy/overlays/m2m-keycloak/patch-oauth2-proxy-config.yaml create mode 100644 kubeflow/common/oauth2-proxy/overlays/m2m-keycloak/secrets.env create mode 100644 kubeflow/common/user-namespace/base/kustomization.yaml create mode 100644 kubeflow/common/user-namespace/base/params.env create mode 100644 kubeflow/common/user-namespace/base/params.yaml create mode 100644 kubeflow/common/user-namespace/base/profile-instance.yaml create mode 100644 kubeflow/dip/README.md create mode 100644 kubeflow/dip/applicationset/kubeflow-applicationset.yaml create mode 100644 kubeflow/dip/istio-system/kustomization.yaml create mode 100644 kubeflow/dip/kubeflow-core/cluster-policy.yaml create mode 100644 kubeflow/dip/kubeflow-core/cluster-role.yaml create mode 100644 kubeflow/dip/kubeflow-core/cluster-rolebinding.yaml create mode 100644 kubeflow/dip/kubeflow-core/ingress.yaml create mode 100644 kubeflow/dip/kubeflow-core/kustomization.yaml create mode 100644 kubeflow/dip/kubeflow-dependencies/knative-serving/README.md create mode 100644 kubeflow/dip/kubeflow-dependencies/knative-serving/kustomization.yaml create mode 100644 kubeflow/dip/kubeflow-dependencies/knative-serving/patches/config-deployment.yaml create mode 100644 kubeflow/dip/kubeflow-dependencies/knative-serving/patches/config-domain.yaml create mode 100644 kubeflow/dip/kubeflow-dependencies/knative-serving/patches/config-feature.yaml create mode 100644 kubeflow/dip/kubeflow-dependencies/knative-serving/patches/config-network.yaml create mode 100644 kubeflow/dip/kubeflow-dependencies/knative-serving/patches/gateway-selector-in-istio-system.yaml create mode 100644 kubeflow/dip/kubeflow-dependencies/knative-serving/patches/gateway-selector-in-knative-serving.yaml create mode 100644 kubeflow/dip/kubeflow-dependencies/kustomization.yaml create mode 100644 kubeflow/example/kustomization.yaml create mode 100644 kubeflow/experimental/OWNERS create mode 100644 kubeflow/experimental/README.md create mode 100644 kubeflow/experimental/ray/Makefile create mode 100644 kubeflow/experimental/ray/OWNERS create mode 100644 kubeflow/experimental/ray/README.md create mode 100644 kubeflow/experimental/ray/UPGRADE.md create mode 100644 kubeflow/experimental/ray/assets/architecture.svg create mode 100644 kubeflow/experimental/ray/assets/map-of-ray.png create mode 100644 kubeflow/experimental/ray/kuberay-operator/base/aggregated-roles.yaml create mode 100644 kubeflow/experimental/ray/kuberay-operator/base/kustomization.yaml create mode 100644 kubeflow/experimental/ray/kuberay-operator/base/resources.yaml create mode 100644 kubeflow/experimental/ray/kuberay-operator/overlays/kubeflow/disable-injection.yaml create mode 100644 kubeflow/experimental/ray/kuberay-operator/overlays/kubeflow/kustomization.yaml create mode 100644 kubeflow/experimental/ray/kuberay-operator/overlays/standalone/kustomization.yaml create mode 100644 kubeflow/experimental/ray/raycluster_example.yaml create mode 100644 kubeflow/experimental/ray/test.sh create mode 100644 kubeflow/experimental/seaweedfs/OWNERS create mode 100644 kubeflow/experimental/seaweedfs/README.md create mode 100644 kubeflow/experimental/seaweedfs/UPDGRADE.md create mode 100644 kubeflow/experimental/seaweedfs/base/kustomization.yaml create mode 100644 kubeflow/experimental/seaweedfs/base/minio-service-patch.yaml create mode 100644 kubeflow/experimental/seaweedfs/base/pipeline-profile-controller/deployment.yaml create mode 100644 kubeflow/experimental/seaweedfs/base/pipeline-profile-controller/sync.py create mode 100644 kubeflow/experimental/seaweedfs/base/seaweedfs/kustomization.yaml create mode 100644 kubeflow/experimental/seaweedfs/base/seaweedfs/seaweedfs-create-admin-user-job.yaml create mode 100644 kubeflow/experimental/seaweedfs/base/seaweedfs/seaweedfs-deployment.yaml create mode 100644 kubeflow/experimental/seaweedfs/base/seaweedfs/seaweedfs-networkpolicy.yaml create mode 100644 kubeflow/experimental/seaweedfs/base/seaweedfs/seaweedfs-pvc.yaml create mode 100644 kubeflow/experimental/seaweedfs/base/seaweedfs/seaweedfs-service-account.yaml create mode 100644 kubeflow/experimental/seaweedfs/base/seaweedfs/seaweedfs-service.yaml create mode 100644 kubeflow/experimental/seaweedfs/istio/istio-authorization-policy.yaml create mode 100644 kubeflow/experimental/seaweedfs/istio/kustomization.yaml create mode 100644 kubeflow/experimental/seaweedfs/test.sh create mode 100644 kubeflow/experimental/security/PSS/dynamic/baseline/kustomization.yaml create mode 100644 kubeflow/experimental/security/PSS/dynamic/baseline/namespace-labels.yaml create mode 100644 kubeflow/experimental/security/PSS/dynamic/restricted/kustomization.yaml create mode 100644 kubeflow/experimental/security/PSS/dynamic/restricted/namespace-labels.yaml create mode 100644 kubeflow/experimental/security/PSS/static/baseline/kustomization.yaml create mode 100644 kubeflow/experimental/security/PSS/static/baseline/patches/auth-labels.yaml create mode 100644 kubeflow/experimental/security/PSS/static/baseline/patches/cert-manager-labels.yaml create mode 100644 kubeflow/experimental/security/PSS/static/baseline/patches/istio-system-labels.yaml create mode 100644 kubeflow/experimental/security/PSS/static/baseline/patches/knative-serving-labels.yaml create mode 100644 kubeflow/experimental/security/PSS/static/baseline/patches/kubeflow-labels.yaml create mode 100644 kubeflow/experimental/security/PSS/static/baseline/patches/oauth2-proxy-labels.yaml create mode 100644 kubeflow/experimental/security/PSS/static/restricted/kustomization.yaml create mode 100644 kubeflow/experimental/security/PSS/static/restricted/patches/auth-labels.yaml create mode 100644 kubeflow/experimental/security/PSS/static/restricted/patches/cert-manager-labels.yaml create mode 100644 kubeflow/experimental/security/PSS/static/restricted/patches/istio-system-labels.yaml create mode 100644 kubeflow/experimental/security/PSS/static/restricted/patches/knative-serving-labels.yaml create mode 100644 kubeflow/experimental/security/PSS/static/restricted/patches/kubeflow-labels.yaml create mode 100644 kubeflow/experimental/security/PSS/static/restricted/patches/oauth2-proxy-labels.yaml create mode 100644 kubeflow/proposals/20200913-rootlessKubeflow.md create mode 100644 kubeflow/proposals/20220926-contrib-component-guidelines.md create mode 100644 kubeflow/proposals/20230323-end-to-end-testing.md create mode 100644 kubeflow/proposals/20240606-jwt-handling.md create mode 100644 kubeflow/proposals/README.md create mode 100644 kubeflow/scripts/library.sh create mode 100644 kubeflow/scripts/synchronize-istio-cni-manifests.sh create mode 100644 kubeflow/scripts/synchronize-istio-manifests.sh create mode 100644 kubeflow/scripts/synchronize-katib-manifests.sh create mode 100644 kubeflow/scripts/synchronize-knative-manifests.sh create mode 100644 kubeflow/scripts/synchronize-kserve-kserve-manifests.sh create mode 100644 kubeflow/scripts/synchronize-kserve-web-application-manifests.sh create mode 100644 kubeflow/scripts/synchronize-kubeflow-manifests.sh create mode 100644 kubeflow/scripts/synchronize-model-registry-manifests.sh create mode 100644 kubeflow/scripts/synchronize-pipelines-manifests.sh create mode 100644 kubeflow/scripts/synchronize-spark-operator-manifests.sh create mode 100644 kubeflow/scripts/synchronize-training-operator-manifests.sh create mode 100644 kubeflow/scripts/template.sh create mode 100644 kubeflow/scripts/trivy_scan.py create mode 100644 kubeflow/tests/README.md create mode 100644 kubeflow/tests/gh-actions/enable_baseline_PSS.sh create mode 100644 kubeflow/tests/gh-actions/enable_restricted_PSS.sh create mode 100644 kubeflow/tests/gh-actions/install_KinD_create_KinD_cluster_install_kustomize.sh create mode 100644 kubeflow/tests/gh-actions/install_argo_cli.sh create mode 100644 kubeflow/tests/gh-actions/install_central_dashboard.sh create mode 100644 kubeflow/tests/gh-actions/install_cert_manager.sh create mode 100644 kubeflow/tests/gh-actions/install_dex.sh create mode 100644 kubeflow/tests/gh-actions/install_istio-cni.sh create mode 100644 kubeflow/tests/gh-actions/install_katib.sh create mode 100644 kubeflow/tests/gh-actions/install_knative-cni.sh create mode 100644 kubeflow/tests/gh-actions/install_kserve.sh create mode 100644 kubeflow/tests/gh-actions/install_kubectl.sh create mode 100644 kubeflow/tests/gh-actions/install_kubeflow_profile.sh create mode 100644 kubeflow/tests/gh-actions/install_kustomize.sh create mode 100644 kubeflow/tests/gh-actions/install_multi_tenancy.sh create mode 100644 kubeflow/tests/gh-actions/install_oauth2-proxy.sh create mode 100644 kubeflow/tests/gh-actions/install_pipelines.sh create mode 100644 kubeflow/tests/gh-actions/install_pipelines_swfs.sh create mode 100644 kubeflow/tests/gh-actions/install_spark.sh create mode 100644 kubeflow/tests/gh-actions/install_training_operator.sh create mode 100644 kubeflow/tests/gh-actions/install_trivy.sh create mode 100644 kubeflow/tests/gh-actions/install_volumes_web_application.sh create mode 100644 kubeflow/tests/gh-actions/kf-objects/katib_test.yaml create mode 100644 kubeflow/tests/gh-actions/kf-objects/kserve_test.yaml create mode 100644 kubeflow/tests/gh-actions/kf-objects/notebook.test.kubeflow-user-example.com.yaml create mode 100644 kubeflow/tests/gh-actions/kf-objects/poddefaults.access-ml-pipeline.kubeflow-user-example-com.yaml create mode 100644 kubeflow/tests/gh-actions/kf-objects/test_pipeline.py create mode 100644 kubeflow/tests/gh-actions/kf-objects/training_operator_job.yaml create mode 100644 kubeflow/tests/gh-actions/kserve/data/iris_input.json create mode 100644 kubeflow/tests/gh-actions/kserve/requirements.txt create mode 100644 kubeflow/tests/gh-actions/kserve/test_sklearn.py create mode 100644 kubeflow/tests/gh-actions/kserve/utils.py create mode 100644 kubeflow/tests/gh-actions/oauth2_dex_credentials.sh create mode 100644 kubeflow/tests/gh-actions/port_forward_gateway.sh create mode 100644 kubeflow/tests/gh-actions/run_and_wait_kubeflow_pipeline.py create mode 100644 kubeflow/tests/gh-actions/runasnonroot.sh create mode 100644 kubeflow/tests/gh-actions/test_dex_login.py create mode 100644 kubeflow/tests/gh-actions/test_kserve.sh create mode 100644 kubeflow/tests/gh-actions/test_pipeline_v1.py create mode 100644 kubeflow/tests/gh-actions/test_pipeline_v2.py create mode 100644 kubeflow/tests/gh-actions/test_spark.sh create mode 100644 kubeflow/tests/gh-actions/test_training_operator.sh create mode 100644 kubeflow/tests/gh-actions/test_volumes_web_application.sh create mode 100644 kubeflow/tests/gh-actions/trivy_scan.py diff --git a/kubeflow/CUSTOM-README.md b/kubeflow/CUSTOM-README.md new file mode 100644 index 0000000..ff1f122 --- /dev/null +++ b/kubeflow/CUSTOM-README.md @@ -0,0 +1,59 @@ +# Kubeflow 배포 + +## 배포 절차 +### 1) 변수 수정 +- 대상 파일 +``` +- common/oauth2-proxy/overlays/m2m-keycloak/m2m.env +- common/oauth2-proxy/overlays/m2m-keycloak/patch-oauth2-proxy-config.yaml +- common/oauth2-proxy/overlays/m2m-keycloak/secrets.env +- dip/kubeflow-core/ingress.yaml +- dip/applicationset/kubeflow-applicationset.yaml +``` +- 변수 예시 +``` yaml +HOST='kubeflow.example.org' +DOMAIN='example.org' +OIDC_ISSUER_URL='https://keycloak.example.org/realms/paasup' +OIDC_JWKS_URL='http://kubeflow.platform.svc.cluster.local/realms/paasup/protocol/openid-connect/certs' +REDIRECT_URL='https://kubeflow.example.org/oauth2/callback' +CLIENT_ID='kubeflow' +CLIENT_SECRET='NOARm1WehZbWIHt9Aheau9kDrefBrZy8' +COOKIE_SECRET='094f9651100c4ee4a3a7337e405d8650' +GIT_REPO_URL=https://gitea.example.org/dip/tenant-catalog +TAG=kubeflow/1.10.0 +``` + +- 수정 위치 +``` +# 변수 처리된 파일에 값 수정 +## 1. dip/kubeflow-core/ingress.yaml +## 파일 내 $HOST 수정 + +## 2. dip/kubeflow-dependencies/knative-serving/patches/config-domain.yaml +## $DOMAIN 수정 + +## 3. common/oauth2-proxy/overlays/m2m-keycloak/m2m.env +## $OIDC_ISSUER_URL와 $OIDC_JWKS_URL 수정 + +## 4. common/oauth2-proxy/overlays/m2m-keycloak/patch-oauth2-proxy-config.yaml +## $OIDC_ISSUER_URL와 $REDIRECT_URL 수정 + +## 5. common/oauth2-proxy/overlays/m2m-keycloak/secrets.env +## $CLIENT_ID / $CLIENT-SECRET / $COOKIE-SECRET 수정 + +## 6. dip/applicationset/kubeflow-applicationset.yaml +## $GIT_REPO_URL / $TAG 수정 +``` + + +### 2. 배포 방법 +- 배포 전 검토 사항 + - keycloak 내 oicd 설정 확인 + - gitea repogitory 구성 확인 + - argocd 배포 확인 + - argocd 내 repository 등록 확인 +- 배포 +``` sh +kubectl apply -f dip/applicationset/kubeflow-applicationset.yaml +``` \ No newline at end of file diff --git a/kubeflow/LICENSE b/kubeflow/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/kubeflow/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/kubeflow/OWNERS b/kubeflow/OWNERS new file mode 100644 index 0000000..55bb5a0 --- /dev/null +++ b/kubeflow/OWNERS @@ -0,0 +1,11 @@ +approvers: + - juliusvonkohout + - kimwnasptd +reviewers: + - juliusvonkohout + - kimwnasptd +emeritus_approvers: + - elikatsis + - PatrickXYS + - StefanoFioravanzo + - yanniszark diff --git a/kubeflow/README.md b/kubeflow/README.md new file mode 100644 index 0000000..f2ccacd --- /dev/null +++ b/kubeflow/README.md @@ -0,0 +1,708 @@ +# Kubeflow Manifests + +The **Kubeflow Manifests** are a collection of community-maintained manifests for installing Kubeflow in popular Kubernetes clusters such as Kind, Minikube, Rancher, EKS, AKS, and GKE. The manifests include all Kubeflow components (Pipelines, Kserve, etc.), the **Kubeflow Central Dashboard**, and other applications that comprise the **Kubeflow Platform**. This installation is beneficial for users wanting to explore the end-to-end capabilities of the Kubeflow Platform. + +For a stable and conservative experience, we recommend using the [latest stable release](https://github.com/kubeflow/manifests/releases). However, please consult the more up-to-date documentation in the master branch. + +- **Kubeflow 1.10:** + - [`v1.10.0`](https://github.com/kubeflow/manifests/tree/v1.10-branch) + +You can also install the master branch of [`kubeflow/manifests`](https://github.com/kubeflow/manifests) by following the instructions [here](https://github.com/kubeflow/manifests?tab=readme-ov-file#installation) and providing us with feedback. + +## Table of Contents + + + +- [Overview of the Kubeflow Platform](#overview-of-the-kubeflow-platform) +- [Kubeflow Components Versions](#kubeflow-components-versions) +- [Installation](#installation) + - [Prerequisites](#prerequisites) + - [Install with a Single Command](#install-with-a-single-command) + - [Install Individual Components](#install-individual-components) + - [Connect to Your Kubeflow Cluster](#connect-to-your-kubeflow-cluster) + - [Change Default User Name](#change-default-user-name) + - [Change Default User Password](#change-default-user-password) +- [Upgrading and Extending](#upgrading-and-extending) +- [Release Process](#release-process) +- [CVE Scanning](#cve-scanning) +- [Pre-commit Hooks](#pre-commit-hooks) +- [Frequently Asked Questions](#frequently-asked-questions) + + + +## Overview of the Kubeflow Platform + +This repository is owned by the [Platform/Manifests Working Group](https://github.com/kubeflow/community/blob/master/wg-manifests/charter.md). If you are a contributor authoring or editing the packages, please see [Best Practices](https://kubectl.docs.kubernetes.io/references/kustomize/). You can join the CNCF Slack and access our meetings at the [Kubeflow Community](https://www.kubeflow.org/docs/about/community/) website. Our channel on the CNCF Slack is [**#kubeflow-platform**](https://app.slack.com/client/T08PSQ7BQ/C073W572LA2). You can also find our [biweekly meetings](https://bit.ly/kf-wg-manifests-meet), including the commentable [Agenda](https://bit.ly/kf-wg-manifests-notes). + +The Kubeflow Manifests repository is organized under three main directories, which include manifests for installing: + +| Directory | Purpose | +| - | - | +| `applications` | Kubeflow's official components, maintained by the respective Kubeflow WGs | +| `common` | Common services, maintained by the Manifests WG | +| `experimental` | Third-party integrations and platform experiments (e.g., Ray, SeaweedFS, or security improvements) | + +All components are deployable with `kustomize`. You can choose to deploy the entire Kubeflow platform or individual components. + +## Kubeflow Components Versions + +### Kubeflow Version: Master + +This repository periodically synchronizes all official Kubeflow components from the respective upstream repositories. The following matrix shows the git version included for each component: + +| Component | Local Manifests Path | Upstream Revision | +| - | - | - | +| Training Operator | apps/training-operator/upstream | [v1.9.2](https://github.com/kubeflow/training-operator/tree/v1.9.2/manifests) | +| Notebook Controller | apps/jupyter/notebook-controller/upstream | [v1.10.0](https://github.com/kubeflow/kubeflow/tree/v1.10.0/components/notebook-controller/config) | +| PVC Viewer Controller | apps/pvcviewer-controller/upstream | [v1.10.0](https://github.com/kubeflow/kubeflow/tree/v1.10.0/components/pvcviewer-controller/config) | +| Tensorboard Controller | apps/tensorboard/tensorboard-controller/upstream | [v1.10.0](https://github.com/kubeflow/kubeflow/tree/v1.10.0/components/tensorboard-controller/config) | +| Central Dashboard | apps/centraldashboard/upstream | [v1.10.0](https://github.com/kubeflow/kubeflow/tree/v1.10.0/components/centraldashboard/manifests) | +| Profiles + KFAM | apps/profiles/upstream | [v1.10.0](https://github.com/kubeflow/kubeflow/tree/v1.10.0/components/profile-controller/config) | +| PodDefaults Webhook | apps/admission-webhook/upstream | [v1.10.0](https://github.com/kubeflow/kubeflow/tree/v1.10.0/components/admission-webhook/manifests) | +| Jupyter Web Application | apps/jupyter/jupyter-web-app/upstream | [v1.10.0](https://github.com/kubeflow/kubeflow/tree/v1.10.0/components/crud-web-apps/jupyter/manifests) | +| Tensorboards Web Application | apps/tensorboard/tensorboards-web-app/upstream | [v1.10.0](https://github.com/kubeflow/kubeflow/tree/v1.10.0/components/crud-web-apps/tensorboards/manifests) | +| Volumes Web Application | apps/volumes-web-app/upstream | [v1.10.0](https://github.com/kubeflow/kubeflow/tree/v1.10.0/components/crud-web-apps/volumes/manifests) | +| Katib | apps/katib/upstream | [v0.18.0](https://github.com/kubeflow/katib/tree/v0.18.0/manifests/v1beta1) | +| KServe | apps/kserve/kserve | [v0.15.0](https://github.com/kserve/kserve/releases/tag/v0.15.0/install/v0.15.0) | +| KServe Models Web Application | apps/kserve/models-web-app | [v0.14.0](https://github.com/kserve/models-web-app/tree/v0.14.0/config) | +| Kubeflow Pipelines | apps/pipeline/upstream | [2.5.0](https://github.com/kubeflow/pipelines/tree/2.5.0/manifests/kustomize) | +| Kubeflow Model Registry | apps/model-registry/upstream | [v0.2.17](https://github.com/kubeflow/model-registry/tree/v0.2.17/manifests/kustomize) | +| Spark Operator | apps/spark/spark-operator | [2.1.1](https://github.com/kubeflow/spark-operator/tree/v2.1.1) | + +The following matrix shows the versions of common components used across different Kubeflow projects: + +| Component | Local Manifests Path | Upstream Revision | +| - | - | - | +| Istio | common/istio-1-24 | [1.24.3](https://github.com/istio/istio/releases/tag/1.24.3) | +| Knative | common/knative/knative-serving
common/knative/knative-eventing | [v1.16.2](https://github.com/knative/serving/releases/tag/knative-v1.16.2)
[v1.16.4](https://github.com/knative/eventing/releases/tag/knative-v1.16.4) | +| Cert Manager | common/cert-manager | [1.16.1](https://github.com/cert-manager/cert-manager/releases/tag/v1.16.1) | + +## Installation + +This section covers the installation from scratch. For the in-place upgrade guide, please jump to the [Upgrading and Extending](#upgrading-and-extending) section. + +Although our master branch has extended automated tests and is already quite stable, please consider using a stable [release tag/branch](https://github.com/kubeflow/manifests/releases) for a more conservative experience. + +We provide two options for installing the official Kubeflow components and common services with Kustomize. The aim is to help users install easily and building distributions of Kubeflow by deriving / deviating from the Kubeflow manifests: + +1. Single-command installation of all components under `apps` and `common` +2. Multi-command, individual component installation for `apps` and `common` + +Option 1 targets ease of deployment for end users. \ +Option 2 targets customization, allowing users to pick and choose individual components. + +The `example` directory contains an example kustomization for the single command to be able to run. + +:warning: In both options, we use a default email (`user@example.com`) and password (`12341234`). For any production Kubeflow deployment, you should change the default password by following [the relevant section](#change-default-user-password). + +### Prerequisites +- This is the master branch, which targets Kubernetes version 1.32. +- For the specific Kubernetes version per release, consult the [release notes](https://github.com/kubeflow/manifests/releases). +- Either our local Kind (installed below) or your own Kubernetes cluster with a default [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/). +- Kustomize version [5.4.3+](https://github.com/kubernetes-sigs/kustomize/releases/tag/kustomize%2Fv5.4.3). +- Kubectl version compatible with your Kubernetes cluster ([Version Skew Policy](https://kubernetes.io/releases/version-skew-policy/#kubectl)). + +--- +**NOTE** + +`kubectl apply` commands may fail on the first try. This is inherent in how Kubernetes and `kubectl` work (e.g., CR must be created after CRD becomes ready). The solution is to simply re-run the command until it succeeds. For the single-line command, we have included a bash one-liner to retry the command. + +--- + +### Install with a Single Command + +#### Prerequisites +- 16 GB of RAM recommended. +- 8 CPU cores recommended. +- `kind` version 0.27+. +- `docker` or a more modern tool such as `podman` to run the OCI images for the Kind cluster. +- Linux kernel subsystem changes to support many pods: + - `sudo sysctl fs.inotify.max_user_instances=2280` + - `sudo sysctl fs.inotify.max_user_watches=1255360` +- You can exclude components from the `example/kustomization.yaml` to fit Kubeflow into 4-8 GB of memory and 2-4 CPU cores. + +#### Create Kind Cluster +```sh +cat < /tmp/kubeflow-config +export KUBECONFIG=/tmp/kubeflow-config +``` + +#### Create a Secret Based on Existing Credentials to Pull the Images +```sh +docker login + +kubectl create secret generic regcred \ + --from-file=.dockerconfigjson=$HOME/.docker/config.json \ + --type=kubernetes.io/dockerconfigjson +``` + +You can install all Kubeflow official components (residing under `apps`) and all common services (residing under `common`) using the following command: + +```sh +while ! kustomize build example | kubectl apply --server-side --force-conflicts -f -; do echo "Retrying to apply resources"; sleep 20; done +``` + +Once everything is installed successfully, you can access the Kubeflow Central Dashboard [by logging in to your cluster](#connect-to-your-kubeflow-cluster). + +Congratulations! You can now start experimenting and running your end-to-end ML workflows with Kubeflow. + +### Install Individual Components + +In this section, we will install each Kubeflow official component (under `apps`) and each common service (under `common`) separately, using just `kubectl` and `kustomize`. + +If all the following commands are executed, the result is the same as in the above section of the single command installation. The purpose of this section is to: + +- Provide a description of each component and insight on how it gets installed. +- Enable the user or distribution owner to pick and choose only the components they need. + +--- +**Troubleshooting Note** + +We've seen errors like the following when applying the kustomizations of different components: +``` +error: resource mapping not found for name: "" namespace: "" from "STDIN": no matches for kind "" in version "" +ensure CRDs are installed first +``` + +This is because a kustomization applies both a CRD and a CR very quickly, and the CRD has not yet become [`Established`](https://github.com/kubernetes/apiextensions-apiserver/blob/a7ee7f91a2d0805f729998b85680a20cfba208d2/pkg/apis/apiextensions/types.go#L276-L279) yet. You can learn more about this in and . + +If you encounter this error, we advise re-applying the manifests of the component. + +--- + +#### cert-manager + +Cert-manager is used by many Kubeflow components to provide certificates for admission webhooks. + +Install cert-manager: + +```sh +kustomize build common/cert-manager/base | kubectl apply -f - +kustomize build common/cert-manager/kubeflow-issuer/base | kubectl apply -f - +echo "Waiting for cert-manager to be ready ..." +kubectl wait --for=condition=Ready pod -l 'app in (cert-manager,webhook)' --timeout=180s -n cert-manager +kubectl wait --for=jsonpath='{.subsets[0].addresses[0].targetRef.kind}'=Pod endpoints -l 'app in (cert-manager,webhook)' --timeout=180s -n cert-manager +``` + +In case you encounter this error: +``` +Error from server (InternalError): error when creating "STDIN": Internal error occurred: failed calling webhook "webhook.cert-manager.io": failed to call webhook: Post "https://cert-manager-webhook.cert-manager.svc:443/mutate?timeout=10s": dial tcp 10.96.202.64:443: connect: connection refused +``` +This is because the webhook is not yet ready to receive requests. Wait a couple of seconds and retry applying the manifests. + +For more troubleshooting info, also check out . + +#### Istio + +Istio is used by most Kubeflow components to secure their traffic, enforce network authorization, and implement routing policies. If you use Cilium CNI on your cluster, you must configure it properly for Istio as shown [here](https://docs.cilium.io/en/latest/network/servicemesh/istio/); otherwise, you will encounter RBAC access denied on the central dashboard. + +Install Istio: + +```sh +echo "Installing Istio configured with external authorization..." +kustomize build common/istio-1-24/istio-crds/base | kubectl apply -f - +kustomize build common/istio-1-24/istio-namespace/base | kubectl apply -f - +kustomize build common/istio-1-24/istio-install/overlays/oauth2-proxy | kubectl apply -f - + +echo "Waiting for all Istio Pods to become ready..." +kubectl wait --for=condition=Ready pods --all -n istio-system --timeout 300s +``` + +#### Oauth2-proxy + +The oauth2-proxy extends your Istio Ingress-Gateway capabilities to function as an OIDC client. It supports user sessions as well as proper token-based machine-to-machine authentication. + +```sh +echo "Installing oauth2-proxy..." + +# Only uncomment ONE of the following overlays, as they are mutually exclusive. +# See `common/oauth2-proxy/overlays/` for more options. + +# OPTION 1: works on most clusters, does NOT allow K8s service account +# tokens to be used from outside the cluster via the Istio ingress-gateway. +# +kustomize build common/oauth2-proxy/overlays/m2m-dex-only/ | kubectl apply -f - +kubectl wait --for=condition=Ready pod -l 'app.kubernetes.io/name=oauth2-proxy' --timeout=180s -n oauth2-proxy + +# Option 2: works on Kind, K3D, Rancher, GKE, and many other clusters with the proper configuration, and allows K8s service account tokens to be used +# from outside the cluster via the Istio ingress-gateway. For example, for automation with GitHub Actions. +# In the end, you need to patch the issuer and jwksUri fields in the request authentication resource in the istio-system namespace +# as done in /common/oauth2-proxy/overlays/m2m-dex-and-kind/kustomization.yaml. +# Please follow the guidelines in the section Upgrading and Extending below for patching. +# curl --insecure -H "Authorization: Bearer `cat /var/run/secrets/kubernetes.io/serviceaccount/token`" https://kubernetes.default/.well-known/openid-configuration +# from a pod in the cluster should provide you with the issuer of your cluster. +# +#kustomize build common/oauth2-proxy/overlays/m2m-dex-and-kind/ | kubectl apply -f - +#kubectl wait --for=condition=Ready pod -l 'app.kubernetes.io/name=oauth2-proxy' --timeout=180s -n oauth2-proxy +#kubectl wait --for=condition=Ready pod -l 'app.kubernetes.io/name=cluster-jwks-proxy' --timeout=180s -n istio-system + +# OPTION 3: works on most EKS clusters with K8s service account +# tokens to be used from outside the cluster via the Istio ingress-gateway. +# You have to adjust AWS_REGION and CLUSTER_ID in common/oauth2-proxy/overlays/m2m-dex-and-eks/ first. +# +#kustomize build common/oauth2-proxy/overlays/m2m-dex-and-eks/ | kubectl apply -f - +#kubectl wait --for=condition=Ready pod -l 'app.kubernetes.io/name=oauth2-proxy' --timeout=180s -n oauth2-proxy +``` + +If and after you finish the installation with Kubernetes service account token support, you should be able to create and use the tokens: +```sh +kubectl port-forward svc/istio-ingressgateway -n istio-system 8080:80 +TOKEN="$(kubectl -n $KF_PROFILE_NAMESPACE create token default-editor)" +client = kfp.Client(host="http://localhost:8080/pipeline", existing_token=token) +curl -v "localhost:8080/jupyter/api/namespaces/${$KF_PROFILE_NAMESPACE}/notebooks" -H "Authorization: Bearer ${TOKEN}" +``` + +If you want to use OAuth2 Proxy without Dex and connect it directly to your own IDP, you can refer to this [document](common/oauth2-proxy/README.md#change-default-authentication-from-dex--oauth2-proxy-to-oauth2-proxy-only). However, you can also keep Dex and extend it with connectors to your own IDP as explained in the Dex section below. + +#### Dex + +Dex is an OpenID Connect (OIDC) identity provider with multiple authentication backends. In this default installation, it includes a static user with the email `user@example.com`. By default, the user's password is `12341234`. For any production Kubeflow deployment, you should change the default password by following [the relevant section](#change-default-user-password). + +Install Dex: + +```sh +echo "Installing Dex..." +kustomize build common/dex/overlays/oauth2-proxy | kubectl apply -f - +kubectl wait --for=condition=Ready pods --all --timeout=180s -n auth +``` + +To connect to your desired identity providers (LDAP, GitHub, Google, Microsoft, OIDC, SAML, GitLab), please take a look at . We recommend using OIDC in general since it is compatible with most providers. For example, Azure in the following example. You need to modify and add some environment variables in by adding a patch section in your main Kustomization file. For guidance, please check out [Upgrading and Extending](#upgrading-and-extending). + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: dex +data: + config.yaml: | + issuer: http://dex.auth.svc.cluster.local:5556/dex + storage: + type: kubernetes + config: + inCluster: true + web: + http: 0.0.0.0:5556 + logger: + level: "debug" + format: text + oauth2: + skipApprovalScreen: true + enablePasswordDB: true + #### WARNING: YOU SHOULD NOT USE THE DEFAULT STATIC PASSWORDS + #### and patch /common/dex/base/dex-passwords.yaml in a Kustomize overlay or remove it + staticPasswords: + - email: user@example.com + hashFromEnv: DEX_USER_PASSWORD + username: user + userID: "15841185641784" + staticClients: + # https://github.com/dexidp/dex/pull/1664 + - idEnv: OIDC_CLIENT_ID + redirectURIs: ["/oauth2/callback"] + name: 'Dex Login Application' + secretEnv: OIDC_CLIENT_SECRET + #### Here come the connectors to OIDC providers such as Azure, GCP, GitHub, GitLab, etc. + #### Connector config values starting with a "$" will read from the environment. + connectors: + - type: oidc + id: azure + name: azure + config: + issuer: https://login.microsoftonline.com/$TENANT_ID/v2.0 + redirectURI: https://$KUBEFLOW_INGRESS_URL/dex/callback + clientID: $AZURE_CLIENT_ID + clientSecret: $AZURE_CLIENT_SECRET + insecureSkipEmailVerified: true + scopes: + - openid + - profile + - email + #- groups # groups might be used in the future +``` + +For Keycloak, we have rough guidelines in . + +#### Knative + +Knative is used by the KServe official Kubeflow component. + +Install Knative Serving: + +```sh +kustomize build common/knative/knative-serving/overlays/gateways | kubectl apply -f - +kustomize build common/istio-1-24/cluster-local-gateway/base | kubectl apply -f - +``` + +Optionally, you can install Knative Eventing, which can be used for inference request logging: + +```sh +kustomize build common/knative/knative-eventing/base | kubectl apply -f - +``` + +#### Kubeflow Namespace + +Create the namespace where the Kubeflow components will reside. This namespace is named `kubeflow`. + +Install the Kubeflow namespace: + +```sh +kustomize build common/kubeflow-namespace/base | kubectl apply -f - +``` + +#### Network Policies + +Install network policies: +```sh +kustomize build common/networkpolicies/base | kubectl apply -f - +``` + +#### Kubeflow Roles + +Create the Kubeflow ClusterRoles: `kubeflow-view`, `kubeflow-edit`, and `kubeflow-admin`. Kubeflow components aggregate permissions to these ClusterRoles. + +Install Kubeflow roles: + +```sh +kustomize build common/kubeflow-roles/base | kubectl apply -f - +``` + +#### Kubeflow Istio Resources + +Create the Kubeflow Gateway `kubeflow-gateway` and ClusterRole `kubeflow-istio-admin`. + +Install Kubeflow Istio resources: + +```sh +kustomize build common/istio-1-24/kubeflow-istio-resources/base | kubectl apply -f - +``` + +#### Kubeflow Pipelines + +Install the [Multi-User Kubeflow Pipelines](https://www.kubeflow.org/docs/components/pipelines/multi-user/) official Kubeflow component: + +```sh +kustomize build apps/pipeline/upstream/env/cert-manager/platform-agnostic-multi-user | kubectl apply -f - +``` +This installs Argo with the runasnonroot emissary executor. Please note that you are still responsible for analyzing the security issues that arise when containers are run with root access and for deciding if the Kubeflow pipeline main containers are run as runasnonroot. It is generally strongly recommended that all user-accessible OCI containers run with Pod Security Standards [restricted](https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted). + +#### KServe + +KFServing was rebranded to KServe. + +Install the KServe component: + +```sh +kustomize build apps/kserve/kserve | kubectl apply --server-side --force-conflicts -f - +``` + +Install the Models web application: + +```sh +kustomize build apps/kserve/models-web-app/overlays/kubeflow | kubectl apply -f - +``` + +#### Katib + +Install the Katib official Kubeflow component: + +```sh +kustomize build apps/katib/upstream/installs/katib-with-kubeflow | kubectl apply -f - +``` + +#### Central Dashboard + +Install the Central Dashboard official Kubeflow component: + +```sh +kustomize build apps/centraldashboard/overlays/oauth2-proxy | kubectl apply -f - +``` + +#### Admission Webhook + +Install the Admission Webhook for PodDefaults: + +```sh +kustomize build apps/admission-webhook/upstream/overlays/cert-manager | kubectl apply -f - +``` + +#### Notebooks 1.0 + +Install the Notebook Controller official Kubeflow component: + +```sh +kustomize build apps/jupyter/notebook-controller/upstream/overlays/kubeflow | kubectl apply -f - +``` + +Install the Jupyter Web Application official Kubeflow component: + +```sh +kustomize build apps/jupyter/jupyter-web-app/upstream/overlays/istio | kubectl apply -f - +``` + +#### Workspaces (Notebooks 2.0) + +This feature is still in development. + +#### PVC Viewer Controller + +Install the PVC Viewer Controller official Kubeflow component: + +```sh +kustomize build apps/pvcviewer-controller/upstream/base | kubectl apply -f - +``` + +#### Profiles + KFAM + +Install the Profile Controller and the Kubeflow Access-Management (KFAM) official Kubeflow components: + +```sh +kustomize build apps/profiles/upstream/overlays/kubeflow | kubectl apply -f - +``` + +#### Volumes Web Application + +Install the Volumes Web Application official Kubeflow component: + +```sh +kustomize build apps/volumes-web-app/upstream/overlays/istio | kubectl apply -f - +``` + +#### Tensorboard + +Install the Tensorboards Web Application official Kubeflow component: + +```sh +kustomize build apps/tensorboard/tensorboards-web-app/upstream/overlays/istio | kubectl apply -f - +``` + +Install the Tensorboard Controller official Kubeflow component: + +```sh +kustomize build apps/tensorboard/tensorboard-controller/upstream/overlays/kubeflow | kubectl apply -f - +``` + +#### Training Operator + +Install the Training Operator official Kubeflow component: + +```sh +kustomize build apps/training-operator/upstream/overlays/kubeflow | kubectl apply --server-side --force-conflicts -f - +``` + +#### Spark Operator + +Install the Spark Operator: + +```sh +kustomize build apps/spark/spark-operator/overlays/kubeflow | kubectl apply -f - +``` + +#### User Namespaces + +Finally, create a new namespace for the default user (named `kubeflow-user-example-com`). + +```sh +kustomize build common/user-namespace/base | kubectl apply -f - +``` + +### Connect to Your Kubeflow Cluster + +After installation, it will take some time for all Pods to become ready. Ensure all Pods are ready before trying to connect; otherwise, you might encounter unexpected errors. To check that all Kubeflow-related Pods are ready, use the following commands: + +```sh +kubectl get pods -n cert-manager +kubectl get pods -n istio-system +kubectl get pods -n auth +kubectl get pods -n oauth2-proxy +kubectl get pods -n knative-serving +kubectl get pods -n kubeflow +kubectl get pods -n kubeflow-user-example-com +``` + +#### Port-Forward + +The default way of accessing Kubeflow is via port-forwarding. This enables you to get started quickly without imposing any requirements on your environment. Run the following to port-forward Istio's Ingress-Gateway to local port `8080`: + +```sh +kubectl port-forward svc/istio-ingressgateway -n istio-system 8080:80 +``` + +After running the command, you can access the Kubeflow Central Dashboard by doing the following: + +1. Open your browser and visit `http://localhost:8080`. You should see the Dex login screen. +2. Log in with the default user's credentials. The default email address is `user@example.com`, and the default password is `12341234`. + +#### NodePort / LoadBalancer / Ingress + +To connect to Kubeflow using NodePort / LoadBalancer / Ingress, you need to set up HTTPS. The reason is that many of our web applications (e.g., Tensorboard Web Application, Jupyter Web Application, Katib UI) use [Secure Cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies), so accessing Kubeflow with HTTP over a non-localhost domain does not work. + +Exposing your Kubeflow cluster with proper HTTPS is a straightforward process but depends on your environment. You can expose the `istio-ingressgateway` service in the `istio-system` namespace via nginx-ingress or any other ingress provider. For security reasons, only use `ClusterIP` on the service, not NodePort or something similarly dangerous. There is third-party [commercial support](https://www.kubeflow.org/docs/started/support/) available. + +--- +**NOTE** + +If you absolutely need to expose Kubeflow over HTTP, you can disable the `Secure Cookies` feature by setting the `APP_SECURE_COOKIES` environment variable to `false` in every relevant web app. This is not recommended, as it poses security risks. + +--- + +### Change Default User Name + +For security reasons, we don't want to use the default username and email for the default Kubeflow user when installing in security-sensitive environments. Instead, you should define your own username and email before deploying. To define it for the default user: + +1. Edit `common/dex/overlays/oauth2-proxy/config-map.yaml` and fill the relevant field with your email and preferred username: + + ```yaml + ... + staticPasswords: + - email: + username: + ``` + +### Change Default User Password + +If you have an identity provider (LDAP, GitHub, Google, Microsoft, OIDC, SAML, GitLab) available, you should use that instead of static passwords and connect it to oauth2-proxy or Dex as explained in the sections above. This is best practice instead of using static passwords. + +For security reasons, we don't want to use the default static password for the default Kubeflow user when installing in security-sensitive environments. Instead, you should define your own password and apply it either **before creating the cluster** or **after creating the cluster**. + +Pick a password for the default user, with email `user@example.com`, and hash it using `bcrypt`: + + ```sh + python3 -c 'from passlib.hash import bcrypt; import getpass; print(bcrypt.using(rounds=12, ident="2y").hash(getpass.getpass()))' + ``` + +For example, running the above command locally with required packages like _passlib_ would look as follows: + ```sh + python3 -c 'from passlib.hash import bcrypt; import getpass; print(bcrypt.using(rounds=12, ident="2y").hash(getpass.getpass()))' + Password: <--- Enter the password here + $2y$12$vIm8CANhuWui0J1p3jYeGeuM28Qcn76IFMaFWvZCG5ZkKZ4MjTF4u <--- GENERATED_HASH_FOR_ENTERED_PASSWORD + ``` + +#### Before Creating the Cluster: + +1. Edit `common/dex/base/dex-passwords.yaml` and fill the relevant field with the hash of the password you chose: + + ```yaml + ... + stringData: + DEX_USER_PASSWORD: + ``` + +#### After Creating the Cluster: + +1. Delete the existing secret _dex-passwords_ in the auth namespace using the following command: + + ```sh + kubectl delete secret dex-passwords -n auth + ``` + +2. Create the secret dex-passwords with the new hash using the following command: + + ```sh + kubectl create secret generic dex-passwords --from-literal=DEX_USER_PASSWORD='REPLACE_WITH_HASH' -n auth + ``` + +3. Recreate the _dex_ pod in the auth namespace using the following command: + + ```sh + kubectl delete pods --all -n auth + ``` + +4. Try to log in using the new Dex password. + +## Upgrading and Extending + +For modifications and in-place upgrades of the Kubeflow platform, we provide a rough description for advanced users: + +- Never edit the manifests directly; use Kustomize overlays and [components](https://github.com/kubernetes-sigs/kustomize/blob/master/examples/components.md) on top of the [example.yaml](https://github.com/kubeflow/manifests/blob/master/example/kustomization.yaml). +- This allows you to upgrade by just referencing the new manifests, building with Kustomize, and running `kubectl apply` again. +- You might have to adjust your overlays and components if needed. +- You might need to prune old resources. For that, you would add [labels](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/labels/) to all your resources from the start. +- With labels, you can use `kubectl apply` with `--prune` and `--dry-run` to list prunable resources. +- Sometimes there are major changes; for example, in the 1.9 release, we switched to oauth2-proxy, which needs additional attention (cleanup istio-system once); or 1.9.1 -> 1.10 `kubectl delete clusterrolebinding meta-controller-cluster-role-binding` +- Nevertheless, with a bit of Kubernetes knowledge, one should be able to upgrade. + +### Kubernetes upgrade fails due to `PodDisruptionBudget` + +To work around this remove these `PodDisruptionBudget`s for the time of the upgrade. +You can most easily find them via the `k9s` pdb overview of this resource, alternatively with this command: + +``` +$ kubectl get --all-namespaces PodDisruptionBudget +``` + +As of now the following `PodDisruptionBudget`s are problematic in the upgrade +context, all due to the `minAvailable` attribute: + +- **eventing-webhook** from _knative-eventing_ +- **activator-pdb** from _knative-serving_ +- **webhook-pdb** from _knative-serving_ + +## Release Process + +The Manifest Working Group releases Kubeflow based on the [release timeline](https://github.com/kubeflow/community/blob/master/releases/handbook.md#timeline). The community and the release team work closely with the Manifest Working Group to define the specific dates at the start of the [release cycle](https://github.com/kubeflow/community/blob/master/releases/handbook.md#releasing) and follow the [release versioning policy](https://github.com/kubeflow/community/blob/master/releases/handbook.md#versioning-policy), as defined in the [Kubeflow release handbook](https://github.com/kubeflow/community/blob/master/releases/handbook.md). + +## CVE Scanning + +To view all past security scans, head to the [Image Extracting and Security Scanning GitHub Action workflow](https://github.com/kubeflow/manifests/actions/workflows/trivy.yaml). In the logs of the workflow, you can expand the `Run image extracting and security scanning script` step to view the CVE logs. You will find a per-image CVE scan and a JSON dump of per-WorkingGroup aggregated metrics. You can run the Python script from the workflow file locally on your machine to obtain the detailed JSON files for any git commit. + +The Kubeflow security working group follows a responsible disclosure policy for CVE results: + +- **Internal Review**: All CVE findings are initially reviewed internally by the security working group. +- **Severity Assessment**: Each CVE is assessed for severity and potential impact on the Kubeflow project. +- **Disclosure**: For high and critical severity CVEs, the security working group will: + - Notify the maintainers and contributors. + - Try to provide a fix or mitigation strategy. + - Publicly disclose the CVE details. + +## Pre-commit Hooks + +This repository uses pre-commit hooks to ensure code quality and consistency. The following hooks are configured: + +1. **Black** - Python code formatter. +2. **Yamllint** - YAML file linter. +3. **Shellcheck** - Shell script static analysis. + +To use these hooks: + +1. Install pre-commit: + + ```bash + pip install pre-commit + ``` + +2. Install the git hooks: + + ```bash + pre-commit install + ``` + +The hooks will run automatically on `git commit`. You can also run them manually: + +```bash +pre-commit run +``` + +## Frequently Asked Questions + +- **Q:** What versions of Istio, Knative, Cert-Manager, Argo, ... are compatible with Kubeflow? + **A:** Please refer to each individual component's documentation for a dependency compatibility range. For Istio, Knative, Dex, Cert-Manager, and OAuth2 Proxy, the versions in `common` are the ones we have validated. +- **Q:** Can I use Kubeflow in an air-gapped environment? + **A:** Yes you can. You just need to to get the list of images from our [trivy CVE scanning script](https://github.com/kubeflow/manifests/blob/master/tests/gh-actions/trivy_scan.py), mirror them and replace the references in the manifests with kustomize components and overlays, see [Upgrading and Extending](#upgrading-and-extending). You could also use a simple kyverno policy to replace the images at runtime, which could be easier to maintain. diff --git a/kubeflow/apps/admission-webhook/upstream/base/cluster-role-binding.yaml b/kubeflow/apps/admission-webhook/upstream/base/cluster-role-binding.yaml new file mode 100644 index 0000000..f7fe51d --- /dev/null +++ b/kubeflow/apps/admission-webhook/upstream/base/cluster-role-binding.yaml @@ -0,0 +1,11 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: cluster-role-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cluster-role +subjects: +- kind: ServiceAccount + name: service-account diff --git a/kubeflow/apps/admission-webhook/upstream/base/cluster-role.yaml b/kubeflow/apps/admission-webhook/upstream/base/cluster-role.yaml new file mode 100644 index 0000000..df74fde --- /dev/null +++ b/kubeflow/apps/admission-webhook/upstream/base/cluster-role.yaml @@ -0,0 +1,65 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: cluster-role +rules: +- apiGroups: + - kubeflow.org + resources: + - poddefaults + verbs: + - get + - watch + - list + - update + - create + - patch + - delete + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: kubeflow-poddefaults-admin + labels: + rbac.authorization.kubeflow.org/aggregate-to-kubeflow-admin: "true" +aggregationRule: + clusterRoleSelectors: + - matchLabels: + rbac.authorization.kubeflow.org/aggregate-to-kubeflow-poddefaults-admin: "true" +rules: [] + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: kubeflow-poddefaults-edit + labels: + rbac.authorization.kubeflow.org/aggregate-to-kubeflow-edit: "true" +aggregationRule: + clusterRoleSelectors: + - matchLabels: + rbac.authorization.kubeflow.org/aggregate-to-kubeflow-poddefaults-edit: "true" +rules: [] + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: kubeflow-poddefaults-view + labels: + rbac.authorization.kubeflow.org/aggregate-to-kubeflow-poddefaults-admin: "true" + rbac.authorization.kubeflow.org/aggregate-to-kubeflow-poddefaults-edit: "true" + rbac.authorization.kubeflow.org/aggregate-to-kubeflow-view: "true" +rules: +- apiGroups: + - kubeflow.org + resources: + - poddefaults + verbs: + - get + - list + - watch diff --git a/kubeflow/apps/admission-webhook/upstream/base/crd.yaml b/kubeflow/apps/admission-webhook/upstream/base/crd.yaml new file mode 100644 index 0000000..b719b5d --- /dev/null +++ b/kubeflow/apps/admission-webhook/upstream/base/crd.yaml @@ -0,0 +1,2066 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null + name: poddefaults.kubeflow.org +spec: + group: kubeflow.org + names: + kind: PodDefault + listKind: PodDefaultList + plural: poddefaults + singular: poddefault + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + annotations: + additionalProperties: + type: string + type: object + args: + items: + type: string + type: array + automountServiceAccountToken: + type: boolean + command: + items: + type: string + type: array + desc: + type: string + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + initContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + labels: + additionalProperties: + type: string + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + serviceAccountName: + type: string + sidecars: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + storageClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - selector + type: object + status: + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/kubeflow/apps/admission-webhook/upstream/base/deployment.yaml b/kubeflow/apps/admission-webhook/upstream/base/deployment.yaml new file mode 100644 index 0000000..f01da0f --- /dev/null +++ b/kubeflow/apps/admission-webhook/upstream/base/deployment.yaml @@ -0,0 +1,25 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: deployment +spec: + template: + metadata: + labels: + sidecar.istio.io/inject: "false" + spec: + containers: + - image: ghcr.io/kubeflow/kubeflow/poddefaults-webhook + name: admission-webhook + volumeMounts: + - mountPath: /etc/webhook/certs + name: webhook-cert + readOnly: true + ports: + - name: https-webhook + containerPort: 4443 + volumes: + - name: webhook-cert + secret: + secretName: webhook-certs + serviceAccountName: service-account diff --git a/kubeflow/apps/admission-webhook/upstream/base/kustomization.yaml b/kubeflow/apps/admission-webhook/upstream/base/kustomization.yaml new file mode 100644 index 0000000..c070110 --- /dev/null +++ b/kubeflow/apps/admission-webhook/upstream/base/kustomization.yaml @@ -0,0 +1,52 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- cluster-role-binding.yaml +- cluster-role.yaml +- deployment.yaml +- mutating-webhook-configuration.yaml +- service-account.yaml +- service.yaml +- crd.yaml +commonLabels: + app: poddefaults + kustomize.component: poddefaults + app.kubernetes.io/component: poddefaults + app.kubernetes.io/name: poddefaults +images: +- name: ghcr.io/kubeflow/kubeflow/poddefaults-webhook + newName: ghcr.io/kubeflow/kubeflow/poddefaults-webhook + newTag: v1.10.0 +namespace: kubeflow +generatorOptions: + disableNameSuffixHash: true +vars: +# These vars are used to substitute in the namespace, service name and +# deployment name into the mutating WebHookConfiguration. +# Since its a CR kustomize isn't aware of those fields and won't +# transform them. +# We need the var names to be relatively unique so that when we +# compose with other applications they won't conflict. +- fieldref: + fieldPath: metadata.namespace + name: podDefaultsNamespace + objref: + apiVersion: v1 + kind: Service + name: service +- fieldref: + fieldPath: metadata.name + name: podDefaultsServiceName + objref: + apiVersion: v1 + kind: Service + name: service +- fieldref: + fieldPath: metadata.name + name: podDefaultsDeploymentName + objref: + apiVersion: apps/v1 + kind: Deployment + name: deployment +configurations: +- params.yaml diff --git a/kubeflow/apps/admission-webhook/upstream/base/mutating-webhook-configuration.yaml b/kubeflow/apps/admission-webhook/upstream/base/mutating-webhook-configuration.yaml new file mode 100644 index 0000000..2875482 --- /dev/null +++ b/kubeflow/apps/admission-webhook/upstream/base/mutating-webhook-configuration.yaml @@ -0,0 +1,28 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: mutating-webhook-configuration +webhooks: +- admissionReviewVersions: + - v1beta1 + - v1 + clientConfig: + caBundle: "" + service: + name: service + path: /apply-poddefault + sideEffects: None + failurePolicy: Fail + name: $(podDefaultsDeploymentName).kubeflow.org + namespaceSelector: + matchLabels: + app.kubernetes.io/part-of: kubeflow-profile + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + resources: + - pods diff --git a/kubeflow/apps/admission-webhook/upstream/base/params.yaml b/kubeflow/apps/admission-webhook/upstream/base/params.yaml new file mode 100644 index 0000000..3ad20da --- /dev/null +++ b/kubeflow/apps/admission-webhook/upstream/base/params.yaml @@ -0,0 +1,19 @@ +varReference: +- path: webhooks/clientConfig/service/namespace + kind: MutatingWebhookConfiguration +- path: webhooks/clientConfig/service/name + kind: MutatingWebhookConfiguration +- path: webhooks/name + kind: MutatingWebhookConfiguration +nameReference: +- kind: Service + version: v1 + fieldSpecs: + - kind: MutatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/name +namespace: +- kind: MutatingWebhookConfiguration + group: admissionregistration.k8s.io + path: webhooks/clientConfig/service/namespace + create: true diff --git a/kubeflow/apps/admission-webhook/upstream/base/service-account.yaml b/kubeflow/apps/admission-webhook/upstream/base/service-account.yaml new file mode 100644 index 0000000..a36cbd8 --- /dev/null +++ b/kubeflow/apps/admission-webhook/upstream/base/service-account.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: service-account diff --git a/kubeflow/apps/admission-webhook/upstream/base/service.yaml b/kubeflow/apps/admission-webhook/upstream/base/service.yaml new file mode 100644 index 0000000..07d6d77 --- /dev/null +++ b/kubeflow/apps/admission-webhook/upstream/base/service.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Service +metadata: + name: service +spec: + ports: + - name: https-webhook + port: 443 + targetPort: https-webhook diff --git a/kubeflow/apps/admission-webhook/upstream/overlays/cert-manager/certificate.yaml b/kubeflow/apps/admission-webhook/upstream/overlays/cert-manager/certificate.yaml new file mode 100644 index 0000000..9858344 --- /dev/null +++ b/kubeflow/apps/admission-webhook/upstream/overlays/cert-manager/certificate.yaml @@ -0,0 +1,23 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: cert +spec: + isCA: true + commonName: $(podDefaultsServiceName).$(podDefaultsNamespace).svc + dnsNames: + - $(podDefaultsServiceName).$(podDefaultsNamespace).svc + - $(podDefaultsServiceName).$(podDefaultsNamespace).svc.cluster.local + issuerRef: + kind: Issuer + name: selfsigned-issuer + secretName: webhook-certs + +--- + +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: selfsigned-issuer +spec: + selfSigned: {} diff --git a/kubeflow/apps/admission-webhook/upstream/overlays/cert-manager/deployment.yaml b/kubeflow/apps/admission-webhook/upstream/overlays/cert-manager/deployment.yaml new file mode 100644 index 0000000..af4c7b6 --- /dev/null +++ b/kubeflow/apps/admission-webhook/upstream/overlays/cert-manager/deployment.yaml @@ -0,0 +1,12 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: deployment +spec: + template: + spec: + containers: + - name: admission-webhook + args: + - --tlsCertFile=/etc/webhook/certs/tls.crt + - --tlsKeyFile=/etc/webhook/certs/tls.key diff --git a/kubeflow/apps/admission-webhook/upstream/overlays/cert-manager/kustomization.yaml b/kubeflow/apps/admission-webhook/upstream/overlays/cert-manager/kustomization.yaml new file mode 100644 index 0000000..36542dd --- /dev/null +++ b/kubeflow/apps/admission-webhook/upstream/overlays/cert-manager/kustomization.yaml @@ -0,0 +1,47 @@ +# This overlay uses CertManager to provision a certificate for the +# PodDefaults admission controller. This is preferred over the old +# way of using "bootstrap" which was running a shell script to create +# the certificate. +# TODO(jlewi): We should eventually refactor the manifests to delete +# bootstrap and use certmanager by default. +bases: +- ../../base + +resources: +- certificate.yaml + +namespace: kubeflow + +namePrefix: admission-webhook- + +commonLabels: + app: poddefaults + kustomize.component: poddefaults + app.kubernetes.io/component: poddefaults + app.kubernetes.io/name: poddefaults + +patchesStrategicMerge: +- mutating-webhook-configuration.yaml +- deployment.yaml + +generatorOptions: + disableNameSuffixHash: true + +vars: +# These vars are used to substitute in the namespace, service name and +# deployment name into the mutating WebHookConfiguration. +# Since its a CR kustomize isn't aware of those fields and won't +# transform them. +# We need the var names to be relatively unique so that when we +# compose with other applications they won't conflict. +- name: podDefaultsCertName + objref: + kind: Certificate + group: cert-manager.io + version: v1 + name: cert + fieldref: + fieldpath: metadata.name + +configurations: +- params.yaml diff --git a/kubeflow/apps/admission-webhook/upstream/overlays/cert-manager/mutating-webhook-configuration.yaml b/kubeflow/apps/admission-webhook/upstream/overlays/cert-manager/mutating-webhook-configuration.yaml new file mode 100644 index 0000000..734cd90 --- /dev/null +++ b/kubeflow/apps/admission-webhook/upstream/overlays/cert-manager/mutating-webhook-configuration.yaml @@ -0,0 +1,7 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: mutating-webhook-configuration + annotations: + cert-manager.io/inject-ca-from: $(podDefaultsNamespace)/$(podDefaultsCertName) + \ No newline at end of file diff --git a/kubeflow/apps/admission-webhook/upstream/overlays/cert-manager/params.yaml b/kubeflow/apps/admission-webhook/upstream/overlays/cert-manager/params.yaml new file mode 100644 index 0000000..f5033fb --- /dev/null +++ b/kubeflow/apps/admission-webhook/upstream/overlays/cert-manager/params.yaml @@ -0,0 +1,16 @@ +varReference: +- path: spec/commonName + kind: Certificate +- path: spec/dnsNames + kind: Certificate +- path: spec/issuerRef/name + kind: Certificate +- path: metadata/annotations + kind: MutatingWebhookConfiguration +nameReference: +- kind: Issuer + group: cert-manager.io + fieldSpecs: + - kind: Certificate + group: cert-manager.io + path: spec/issuerRef/name diff --git a/kubeflow/apps/centraldashboard/overlays/oauth2-proxy/kustomization.yaml b/kubeflow/apps/centraldashboard/overlays/oauth2-proxy/kustomization.yaml new file mode 100644 index 0000000..bdd73a2 --- /dev/null +++ b/kubeflow/apps/centraldashboard/overlays/oauth2-proxy/kustomization.yaml @@ -0,0 +1,9 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +# Using kserve overlay because it's also used in example installation. +- ../../upstream/overlays/kserve + +components: +- ../../../../common/oauth2-proxy/components/central-dashboard diff --git a/kubeflow/apps/centraldashboard/upstream/base/clusterrole-binding.yaml b/kubeflow/apps/centraldashboard/upstream/base/clusterrole-binding.yaml new file mode 100644 index 0000000..07224e8 --- /dev/null +++ b/kubeflow/apps/centraldashboard/upstream/base/clusterrole-binding.yaml @@ -0,0 +1,14 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app: centraldashboard + name: centraldashboard +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: centraldashboard +subjects: +- kind: ServiceAccount + name: centraldashboard + namespace: kubeflow diff --git a/kubeflow/apps/centraldashboard/upstream/base/clusterrole.yaml b/kubeflow/apps/centraldashboard/upstream/base/clusterrole.yaml new file mode 100644 index 0000000..aa251d2 --- /dev/null +++ b/kubeflow/apps/centraldashboard/upstream/base/clusterrole.yaml @@ -0,0 +1,17 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app: centraldashboard + name: centraldashboard +rules: +- apiGroups: + - "" + resources: + - events + - namespaces + - nodes + verbs: + - get + - list + - watch diff --git a/kubeflow/apps/centraldashboard/upstream/base/configmap.yaml b/kubeflow/apps/centraldashboard/upstream/base/configmap.yaml new file mode 100644 index 0000000..387be4e --- /dev/null +++ b/kubeflow/apps/centraldashboard/upstream/base/configmap.yaml @@ -0,0 +1,120 @@ +apiVersion: v1 +data: + settings: |- + { + "DASHBOARD_FORCE_IFRAME": true + } + links: |- + { + "menuLinks": [ + { + "icon": "book", + "link": "/jupyter/", + "text": "Notebooks", + "type": "item" + }, + { + "icon": "assessment", + "link": "/tensorboards/", + "text": "TensorBoards", + "type": "item" + }, + { + "icon": "device:storage", + "link": "/volumes/", + "text": "Volumes", + "type": "item" + }, + { + "icon": "kubeflow:katib", + "link": "/katib/", + "text": "Katib Experiments", + "type": "item" + }, + { + "icon": "kubeflow:pipeline-centered", + "items": [ + { + "link": "/pipeline/#/pipelines", + "text": "Pipelines", + "type": "item" + }, + { + "link": "/pipeline/#/experiments", + "text": "Experiments", + "type": "item" + }, + { + "link": "/pipeline/#/runs", + "text": "Runs", + "type": "item" + }, + { + "link": "/pipeline/#/recurringruns", + "text": "Recurring Runs", + "type": "item" + }, + { + "link": "/pipeline/#/artifacts", + "text": "Artifacts", + "type": "item" + }, + { + "link": "/pipeline/#/executions", + "text": "Executions", + "type": "item" + } + ], + "text": "Pipelines", + "type": "section" + } + ], + "externalLinks": [], + "documentationItems": [ + { + "desc": "The Kubeflow website", + "link": "https://www.kubeflow.org/", + "text": "Kubeflow Website" + }, + { + "desc": "Documentation for Kubeflow Pipelines", + "link": "https://www.kubeflow.org/docs/components/pipelines/", + "text": "Kubeflow Pipelines Documentation" + }, + { + "desc": "Documentation for Kubeflow Notebooks", + "link": "https://www.kubeflow.org/docs/components/notebooks/", + "text": "Kubeflow Notebooks Documentation" + }, + { + "desc": "Documentation for Kubeflow Training Operator", + "link": "https://www.kubeflow.org/docs/components/training/", + "text": "Kubeflow Training Operator Documentation" + }, + { + "desc": "Documentation for Katib", + "link": "https://www.kubeflow.org/docs/components/katib/", + "text": "Katib Documentation" + } + ], + "quickLinks": [ + { + "desc": "Kubeflow Notebooks", + "link": "/jupyter/new", + "text": "Create a new Notebook" + }, + { + "desc": "Kubeflow Pipelines", + "link": "/pipeline/#/pipelines", + "text": "Upload a Pipeline" + }, + { + "desc": "Pipelines", + "link": "/pipeline/#/runs", + "text": "View Pipeline Runs" + } + ] + } +kind: ConfigMap +metadata: + name: centraldashboard-config diff --git a/kubeflow/apps/centraldashboard/upstream/base/deployment.yaml b/kubeflow/apps/centraldashboard/upstream/base/deployment.yaml new file mode 100644 index 0000000..5956cba --- /dev/null +++ b/kubeflow/apps/centraldashboard/upstream/base/deployment.yaml @@ -0,0 +1,50 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: centraldashboard + name: centraldashboard +spec: + replicas: 1 + selector: + matchLabels: + app: centraldashboard + template: + metadata: + labels: + app: centraldashboard + sidecar.istio.io/inject: "true" + spec: + containers: + - name: centraldashboard + image: ghcr.io/kubeflow/kubeflow/central-dashboard + imagePullPolicy: IfNotPresent + livenessProbe: + httpGet: + path: /healthz + port: 8082 + initialDelaySeconds: 30 + periodSeconds: 30 + ports: + - containerPort: 8082 + protocol: TCP + env: + - name: USERID_HEADER + value: CD_USERID_HEADER_PLACEHOLDER + - name: USERID_PREFIX + value: CD_USERID_PREFIX_PLACEHOLDER + - name: PROFILES_KFAM_SERVICE_HOST + value: profiles-kfam.kubeflow + - name: REGISTRATION_FLOW + value: CD_REGISTRATION_FLOW_PLACEHOLDER + - name: DASHBOARD_CONFIGMAP + value: CD_CONFIGMAP_NAME_PLACEHOLDER + - name: LOGOUT_URL + value: '/oauth2/sign_out' + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: COLLECT_METRICS + value: CD_COLLECT_METRICS + serviceAccountName: centraldashboard diff --git a/kubeflow/apps/centraldashboard/upstream/base/kustomization.yaml b/kubeflow/apps/centraldashboard/upstream/base/kustomization.yaml new file mode 100644 index 0000000..9744c17 --- /dev/null +++ b/kubeflow/apps/centraldashboard/upstream/base/kustomization.yaml @@ -0,0 +1,83 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: kubeflow +resources: +- clusterrole-binding.yaml +- clusterrole.yaml +- deployment.yaml +- role-binding.yaml +- role.yaml +- service-account.yaml +- service.yaml +- configmap.yaml +images: +- name: ghcr.io/kubeflow/kubeflow/central-dashboard + newName: ghcr.io/kubeflow/kubeflow/central-dashboard + newTag: v1.10.0 +configMapGenerator: +- envs: + - params.env + name: centraldashboard-parameters +generatorOptions: + disableNameSuffixHash: true +labels: +- includeSelectors: true + pairs: + app: centraldashboard + app.kubernetes.io/component: centraldashboard + app.kubernetes.io/name: centraldashboard + kustomize.component: centraldashboard + +replacements: +- source: + fieldPath: data.CD_USERID_HEADER + kind: ConfigMap + name: centraldashboard-parameters + version: v1 + targets: + - fieldPaths: + - spec.template.spec.containers.0.env.0.value + select: + group: apps + kind: Deployment + name: centraldashboard + version: v1 +- source: + fieldPath: data.CD_USERID_PREFIX + kind: ConfigMap + name: centraldashboard-parameters + version: v1 + targets: + - fieldPaths: + - spec.template.spec.containers.0.env.1.value + select: + group: apps + kind: Deployment + name: centraldashboard + version: v1 +- source: + fieldPath: data.CD_REGISTRATION_FLOW + kind: ConfigMap + name: centraldashboard-parameters + version: v1 + targets: + - fieldPaths: + - spec.template.spec.containers.0.env.3.value + select: + group: apps + kind: Deployment + name: centraldashboard + version: v1 +- source: + fieldPath: metadata.name + kind: ConfigMap + name: centraldashboard-config + version: v1 + targets: + - fieldPaths: + - spec.template.spec.containers.0.env.4.value + select: + group: apps + kind: Deployment + name: centraldashboard + version: v1 diff --git a/kubeflow/apps/centraldashboard/upstream/base/params.env b/kubeflow/apps/centraldashboard/upstream/base/params.env new file mode 100644 index 0000000..213567f --- /dev/null +++ b/kubeflow/apps/centraldashboard/upstream/base/params.env @@ -0,0 +1,5 @@ +CD_CLUSTER_DOMAIN=cluster.local +CD_USERID_HEADER=kubeflow-userid +CD_USERID_PREFIX= +CD_REGISTRATION_FLOW=false +CD_COLLECT_METRICS=true diff --git a/kubeflow/apps/centraldashboard/upstream/base/role-binding.yaml b/kubeflow/apps/centraldashboard/upstream/base/role-binding.yaml new file mode 100644 index 0000000..87ab83e --- /dev/null +++ b/kubeflow/apps/centraldashboard/upstream/base/role-binding.yaml @@ -0,0 +1,14 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app: centraldashboard + name: centraldashboard +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: centraldashboard +subjects: +- kind: ServiceAccount + name: centraldashboard + namespace: kubeflow diff --git a/kubeflow/apps/centraldashboard/upstream/base/role.yaml b/kubeflow/apps/centraldashboard/upstream/base/role.yaml new file mode 100644 index 0000000..9f68b4c --- /dev/null +++ b/kubeflow/apps/centraldashboard/upstream/base/role.yaml @@ -0,0 +1,26 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app: centraldashboard + name: centraldashboard +rules: +- apiGroups: + - "" + - "app.k8s.io" + resources: + - applications + - pods + - pods/exec + - pods/log + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - secrets + - configmaps + verbs: + - get diff --git a/kubeflow/apps/centraldashboard/upstream/base/service-account.yaml b/kubeflow/apps/centraldashboard/upstream/base/service-account.yaml new file mode 100644 index 0000000..b5a417a --- /dev/null +++ b/kubeflow/apps/centraldashboard/upstream/base/service-account.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: centraldashboard diff --git a/kubeflow/apps/centraldashboard/upstream/base/service.yaml b/kubeflow/apps/centraldashboard/upstream/base/service.yaml new file mode 100644 index 0000000..a5dc3e9 --- /dev/null +++ b/kubeflow/apps/centraldashboard/upstream/base/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: centraldashboard + name: centraldashboard +spec: + ports: + - port: 80 + protocol: TCP + targetPort: 8082 + selector: + app: centraldashboard + sessionAffinity: None + type: ClusterIP diff --git a/kubeflow/apps/centraldashboard/upstream/overlays/istio/authorizationpolicy.yaml b/kubeflow/apps/centraldashboard/upstream/overlays/istio/authorizationpolicy.yaml new file mode 100644 index 0000000..ea4be12 --- /dev/null +++ b/kubeflow/apps/centraldashboard/upstream/overlays/istio/authorizationpolicy.yaml @@ -0,0 +1,14 @@ +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: central-dashboard +spec: + action: ALLOW + rules: + - from: + - source: + principals: + - cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account + selector: + matchLabels: + app: centraldashboard diff --git a/kubeflow/apps/centraldashboard/upstream/overlays/istio/kustomization.yaml b/kubeflow/apps/centraldashboard/upstream/overlays/istio/kustomization.yaml new file mode 100644 index 0000000..c2d2eb6 --- /dev/null +++ b/kubeflow/apps/centraldashboard/upstream/overlays/istio/kustomization.yaml @@ -0,0 +1,49 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- ../../base +- virtual-service.yaml +- authorizationpolicy.yaml +namespace: kubeflow +replacements: +- source: + fieldPath: metadata.namespace + kind: Service + name: centraldashboard + version: v1 + targets: + - fieldPaths: + - spec.http.0.route.0.destination.host + options: + delimiter: . + index: 1 + select: + group: networking.istio.io + kind: VirtualService + name: centraldashboard + version: v1alpha3 +- source: + fieldPath: data.CD_CLUSTER_DOMAIN + kind: ConfigMap + name: centraldashboard-parameters + version: v1 + targets: + - fieldPaths: + - spec.http.0.route.0.destination.host + options: + delimiter: . + index: 3 + select: + group: networking.istio.io + kind: VirtualService + name: centraldashboard + version: v1alpha3 +configurations: +- params.yaml +labels: +- includeSelectors: true + pairs: + app: centraldashboard + app.kubernetes.io/component: centraldashboard + app.kubernetes.io/name: centraldashboard + kustomize.component: centraldashboard diff --git a/kubeflow/apps/centraldashboard/upstream/overlays/istio/params.yaml b/kubeflow/apps/centraldashboard/upstream/overlays/istio/params.yaml new file mode 100644 index 0000000..eea869e --- /dev/null +++ b/kubeflow/apps/centraldashboard/upstream/overlays/istio/params.yaml @@ -0,0 +1,3 @@ +varReference: +- path: spec/http/route/destination/host + kind: VirtualService diff --git a/kubeflow/apps/centraldashboard/upstream/overlays/istio/virtual-service.yaml b/kubeflow/apps/centraldashboard/upstream/overlays/istio/virtual-service.yaml new file mode 100644 index 0000000..30f9801 --- /dev/null +++ b/kubeflow/apps/centraldashboard/upstream/overlays/istio/virtual-service.yaml @@ -0,0 +1,20 @@ +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: centraldashboard +spec: + gateways: + - kubeflow-gateway + hosts: + - '*' + http: + - match: + - uri: + prefix: / + rewrite: + uri: / + route: + - destination: + host: centraldashboard.CD_NAMESPACE_PLACEHOLDER.svc.CD_CLUSTER_DOMAIN_PLACEHOLDER + port: + number: 80 diff --git a/kubeflow/apps/centraldashboard/upstream/overlays/kserve/kustomization.yaml b/kubeflow/apps/centraldashboard/upstream/overlays/kserve/kustomization.yaml new file mode 100644 index 0000000..821bd92 --- /dev/null +++ b/kubeflow/apps/centraldashboard/upstream/overlays/kserve/kustomization.yaml @@ -0,0 +1,13 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- ../istio +labels: +- includeSelectors: true + pairs: + app: centraldashboard + app.kubernetes.io/component: centraldashboard + app.kubernetes.io/name: centraldashboard + kustomize.component: centraldashboard +patches: +- path: patches/configmap.yaml diff --git a/kubeflow/apps/centraldashboard/upstream/overlays/kserve/patches/configmap.yaml b/kubeflow/apps/centraldashboard/upstream/overlays/kserve/patches/configmap.yaml new file mode 100644 index 0000000..89f76a6 --- /dev/null +++ b/kubeflow/apps/centraldashboard/upstream/overlays/kserve/patches/configmap.yaml @@ -0,0 +1,132 @@ +apiVersion: v1 +data: + settings: |- + { + "DASHBOARD_FORCE_IFRAME": true + } + links: |- + { + "menuLinks": [ + { + "icon": "book", + "link": "/jupyter/", + "text": "Notebooks", + "type": "item" + }, + { + "icon": "assessment", + "link": "/tensorboards/", + "text": "TensorBoards", + "type": "item" + }, + { + "icon": "device:storage", + "link": "/volumes/", + "text": "Volumes", + "type": "item" + }, + { + "icon": "kubeflow:katib", + "link": "/katib/", + "text": "Katib Experiments", + "type": "item" + }, + { + "type": "item", + "link": "/kserve-endpoints/", + "text": "KServe Endpoints", + "icon": "kubeflow:models" + }, + { + "icon": "kubeflow:pipeline-centered", + "items": [ + { + "link": "/pipeline/#/pipelines", + "text": "Pipelines", + "type": "item" + }, + { + "link": "/pipeline/#/experiments", + "text": "Experiments", + "type": "item" + }, + { + "link": "/pipeline/#/runs", + "text": "Runs", + "type": "item" + }, + { + "link": "/pipeline/#/recurringruns", + "text": "Recurring Runs", + "type": "item" + }, + { + "link": "/pipeline/#/artifacts", + "text": "Artifacts", + "type": "item" + }, + { + "link": "/pipeline/#/executions", + "text": "Executions", + "type": "item" + } + ], + "text": "Pipelines", + "type": "section" + }, + { + "icon": "assignment", + "link": "/model-registry/", + "text": "Model Registry", + "type": "item" + } + ], + "externalLinks": [], + "documentationItems": [ + { + "desc": "The Kubeflow website", + "link": "https://www.kubeflow.org/", + "text": "Kubeflow Website" + }, + { + "desc": "Documentation for Kubeflow Pipelines", + "link": "https://www.kubeflow.org/docs/components/pipelines/", + "text": "Kubeflow Pipelines Documentation" + }, + { + "desc": "Documentation for Kubeflow Notebooks", + "link": "https://www.kubeflow.org/docs/components/notebooks/", + "text": "Kubeflow Notebooks Documentation" + }, + { + "desc": "Documentation for Kubeflow Training Operator", + "link": "https://www.kubeflow.org/docs/components/training/", + "text": "Kubeflow Training Operator Documentation" + }, + { + "desc": "Documentation for Katib", + "link": "https://www.kubeflow.org/docs/components/katib/", + "text": "Katib Documentation" + } + ], + "quickLinks": [ + { + "desc": "Kubeflow Notebooks", + "link": "/jupyter/new", + "text": "Create a new Notebook" + }, + { + "desc": "Kubeflow Pipelines", + "link": "/pipeline/#/pipelines", + "text": "Upload a Pipeline" + }, + { + "desc": "Pipelines", + "link": "/pipeline/#/runs", + "text": "View Pipeline Runs" + } + ] + } +kind: ConfigMap +metadata: + name: centraldashboard-config diff --git a/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/cluster-role-binding.yaml b/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/cluster-role-binding.yaml new file mode 100644 index 0000000..f7fe51d --- /dev/null +++ b/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/cluster-role-binding.yaml @@ -0,0 +1,11 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: cluster-role-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cluster-role +subjects: +- kind: ServiceAccount + name: service-account diff --git a/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/cluster-role.yaml b/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/cluster-role.yaml new file mode 100644 index 0000000..b9eb15e --- /dev/null +++ b/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/cluster-role.yaml @@ -0,0 +1,114 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: cluster-role +rules: +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +- apiGroups: + - kubeflow.org + resources: + - notebooks + - notebooks/finalizers + - poddefaults + verbs: + - get + - list + - create + - delete + - patch + - update +- apiGroups: + - "" + resources: + - persistentvolumeclaims + verbs: + - create + - delete + - get + - list +- apiGroups: + - "" + resources: + - events + - nodes + verbs: + - list +- apiGroups: + - storage.k8s.io + resources: + - storageclasses + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - pods + - pods/log + verbs: + - list + - get + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: kubeflow-notebook-ui-admin + labels: + rbac.authorization.kubeflow.org/aggregate-to-kubeflow-admin: "true" +rules: [] + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: kubeflow-notebook-ui-edit + labels: + rbac.authorization.kubeflow.org/aggregate-to-kubeflow-edit: "true" +rules: +- apiGroups: + - kubeflow.org + resources: + - notebooks + - notebooks/finalizers + - poddefaults + verbs: + - get + - list + - create + - delete + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: kubeflow-notebook-ui-view + labels: + rbac.authorization.kubeflow.org/aggregate-to-kubeflow-view: "true" +rules: +- apiGroups: + - kubeflow.org + resources: + - notebooks + - notebooks/finalizers + - poddefaults + verbs: + - get + - list +- apiGroups: + - storage.k8s.io + resources: + - storageclasses + verbs: + - get + - list + - watch diff --git a/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/configs/logos-configmap.yaml b/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/configs/logos-configmap.yaml new file mode 100644 index 0000000..2e32fc8 --- /dev/null +++ b/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/configs/logos-configmap.yaml @@ -0,0 +1,191 @@ +apiVersion: v1 +data: + jupyter-icon.svg: | + + Created using Figma 0.90 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jupyterlab-logo.svg: | + + + + + + group-two-icon.svg: |- + + + + + + + + + group-two-logo.svg: |- + + + + + + + + + group-one-icon.svg: |- + + + + + + + + + group-one-logo.svg: |- + + + + + + + + +kind: ConfigMap +metadata: + name: logos diff --git a/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/configs/spawner_ui_config.yaml b/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/configs/spawner_ui_config.yaml new file mode 100644 index 0000000..d1a5c41 --- /dev/null +++ b/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/configs/spawner_ui_config.yaml @@ -0,0 +1,309 @@ +# -------------------------------------------------------------- +# Configuration file for the Kubeflow Notebooks UI. +# +# About the `readOnly` configs: +# - when `readOnly` is set to "true", the respective option +# will be disabled for users and only set by the admin +# - when 'readOnly' is missing, it defaults to 'false' +# -------------------------------------------------------------- + +spawnerFormDefaults: + ################################################################ + # Container Images + ################################################################ + # if users can input custom images, or only select from dropdowns + allowCustomImage: true + + # if the registry of the container image is hidden from display + hideRegistry: true + + # if the tag of the container image is hidden from display + hideTag: false + + # configs for the ImagePullPolicy + imagePullPolicy: + readOnly: false + + # the default ImagePullPolicy + # (possible values: "Always", "IfNotPresent", "Never") + value: IfNotPresent + + ################################################################ + # Jupyter-like Container Images + # + # NOTES: + # - the `image` section is used for "Jupyter-like" apps whose + # HTTP path is configured by the "NB_PREFIX" environment variable + ################################################################ + image: + # the default container image + value: ghcr.io/kubeflow/kubeflow/notebook-servers/jupyter-scipy:v1.10.0 + + # the list of available container images in the dropdown + options: + - ghcr.io/kubeflow/kubeflow/notebook-servers/jupyter-scipy:v1.10.0 + - ghcr.io/kubeflow/kubeflow/notebook-servers/jupyter-pytorch-full:v1.10.0 + - ghcr.io/kubeflow/kubeflow/notebook-servers/jupyter-pytorch-cuda-full:v1.10.0 + - ghcr.io/kubeflow/kubeflow/notebook-servers/jupyter-pytorch-gaudi-full:v1.10.0 + - ghcr.io/kubeflow/kubeflow/notebook-servers/jupyter-tensorflow-full:v1.10.0 + - ghcr.io/kubeflow/kubeflow/notebook-servers/jupyter-tensorflow-cuda-full:v1.10.0 + + ################################################################ + # VSCode-like Container Images (Group 1) + # + # NOTES: + # - the `imageGroupOne` section is used for "VSCode-like" apps that + # expose themselves under the HTTP root path "/" and support path + # rewriting without breaking + # - the annotation `notebooks.kubeflow.org/http-rewrite-uri: "/"` is + # set on Notebooks spawned by this group, to make Istio rewrite + # the path of HTTP requests to the HTTP root + ################################################################ + imageGroupOne: + # the default container image + value: ghcr.io/kubeflow/kubeflow/notebook-servers/codeserver-python:v1.10.0 + + # the list of available container images in the dropdown + options: + - ghcr.io/kubeflow/kubeflow/notebook-servers/codeserver-python:v1.10.0 + + ################################################################ + # RStudio-like Container Images (Group 2) + # + # NOTES: + # - the `imageGroupTwo` section is used for "RStudio-like" apps whose + # HTTP path is configured by the "X-RStudio-Root-Path" header + # - the annotation `notebooks.kubeflow.org/http-rewrite-uri: "/"` is + # set on Notebooks spawned by this group, to make Istio rewrite + # the path of HTTP requests to the HTTP root + # - the annotation `notebooks.kubeflow.org/http-headers-request-set` is + # set on Notebooks spawned by this group, such that Istio injects the + # "X-RStudio-Root-Path" header to all request + ################################################################ + imageGroupTwo: + # the default container image + value: ghcr.io/kubeflow/kubeflow/notebook-servers/rstudio-tidyverse:v1.10.0 + + # the list of available container images in the dropdown + options: + - ghcr.io/kubeflow/kubeflow/notebook-servers/rstudio-tidyverse:v1.10.0 + + ################################################################ + # CPU Resources + ################################################################ + cpu: + readOnly: false + + # the default cpu request for the container + value: "0.5" + + # a factor by which to multiply the CPU request calculate the cpu limit + # (to disable cpu limits, set as "none") + limitFactor: "1.2" + + ################################################################ + # Memory Resources + ################################################################ + memory: + readOnly: false + + # the default memory request for the container + value: "1.0Gi" + + # a factor by which to multiply the memory request calculate the memory limit + # (to disable memory limits, set as "none") + limitFactor: "1.2" + + ################################################################ + # GPU/Device-Plugin Resources + ################################################################ + gpus: + readOnly: false + + # configs for gpu/device-plugin limits of the container + # https://kubernetes.io/docs/tasks/manage-gpus/scheduling-gpus/#using-device-plugins + value: + # the `limitKey` of the default vendor + # (to have no default, set as "") + vendor: "" + + # the list of available vendors in the dropdown + # `limitsKey` - what will be set as the actual limit + # `uiName` - what will be displayed in the dropdown UI + vendors: + - limitsKey: "nvidia.com/gpu" + uiName: "NVIDIA" + - limitsKey: "amd.com/gpu" + uiName: "AMD" + - limitsKey: "habana.ai/gaudi" + uiName: "Intel Gaudi" + + # the default value of the limit + # (possible values: "none", "1", "2", "4", "8") + num: "none" + + ################################################################ + # Workspace Volumes + ################################################################ + workspaceVolume: + readOnly: false + + # the default workspace volume to be created and mounted + # (to have no default, set `value: null`) + value: + mount: /home/jovyan + + # pvc configs for creating new workspace volumes + # https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/#persistentvolumeclaim-v1-core + newPvc: + metadata: + # "{notebook-name}" is replaced with the Notebook name + name: "{notebook-name}-workspace" + spec: + #storageClassName: my-storage-class + resources: + requests: + storage: 5Gi + accessModes: + - ReadWriteOnce + + ################################################################ + # Data Volumes + ################################################################ + dataVolumes: + readOnly: false + + # a list of additional data volumes to be created and/or mounted + value: [] + #value: + # - mount: /home/jovyan/datavol-1 + # newPvc: + # metadata: + # name: "{notebook-name}-datavol-1" + # spec: + # resources: + # requests: + # storage: 5Gi + # accessModes: + # - ReadWriteOnce + # + # - mount: /home/jovyan/datavol-1 + # existingSource: + # persistentVolumeClaim: + # claimName: "test-pvc" + + ################################################################ + # Affinity + ################################################################ + affinityConfig: + readOnly: false + + # the `configKey` of the default affinity config + # (to have no default, set as "") + # (if `readOnly`, the default `value` will be the only accessible option) + value: "" + + # the list of available affinity configs in the dropdown + options: [] + #options: + # - configKey: "dedicated_node_per_notebook" + # displayName: "Dedicated Node Per Notebook" + # affinity: + # # Require a Node with label `lifecycle=kubeflow-notebook` + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: "lifecycle" + # operator: "In" + # values: + # - "kubeflow-notebook" + # + # # Require a Node WITHOUT an existing Pod having `notebook-name` label + # podAntiAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # - labelSelector: + # matchExpressions: + # - key: "notebook-name" + # operator: "Exists" + # topologyKey: "kubernetes.io/hostname" + # # WARNING: `namespaceSelector` is Beta in 1.22 and Stable in 1.24, + # # setting to {} is required for affinity to work across Namespaces + # namespaceSelector: {} + + ################################################################ + # Tolerations + ################################################################ + tolerationGroup: + readOnly: false + + # the `groupKey` of the default toleration group + # (to have no default, set as "") + # (if `readOnly`, the default `value` will be the only accessible option) + value: "" + + # the list of available toleration groups in the dropdown + options: [] + #options: + # - groupKey: "group_1" + # displayName: "4 CPU 8Gb Mem at ~$X.XXX USD per day" + # tolerations: + # - key: "dedicated" + # operator: "Equal" + # value: "kubeflow-c5.xlarge" + # effect: "NoSchedule" + # + # - groupKey: "group_2" + # displayName: "8 CPU 16Gb Mem at ~$X.XXX USD per day" + # tolerations: + # - key: "dedicated" + # operator: "Equal" + # value: "kubeflow-c5.2xlarge" + # effect: "NoSchedule" + # + # - groupKey: "group_3" + # displayName: "16 CPU 32Gb Mem at ~$X.XXX USD per day" + # tolerations: + # - key: "dedicated" + # operator: "Equal" + # value: "kubeflow-c5.4xlarge" + # effect: "NoSchedule" + # + # - groupKey: "group_4" + # displayName: "32 CPU 256Gb Mem at ~$X.XXX USD per day" + # tolerations: + # - key: "dedicated" + # operator: "Equal" + # value: "kubeflow-r5.8xlarge" + # effect: "NoSchedule" + + ################################################################ + # Shared Memory + ################################################################ + shm: + readOnly: false + + # the default state of the "Enable Shared Memory" toggle + value: true + + ################################################################ + # PodDefaults + ################################################################ + configurations: + readOnly: false + + # the list of PodDefault names that are selected by default + # (take care to ensure these PodDefaults exist in Profile Namespaces) + value: [] + #value: + # - my-pod-default + + ################################################################ + # Environment + # + # NOTE: + # - these configs are only used by the ROK "flavor" of the UI + ################################################################ + environment: + readOnly: false + value: {} diff --git a/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/deployment.yaml b/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/deployment.yaml new file mode 100644 index 0000000..f9d34b3 --- /dev/null +++ b/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/deployment.yaml @@ -0,0 +1,39 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: deployment +spec: + replicas: 1 + template: + spec: + containers: + - name: jupyter-web-app + image: ghcr.io/kubeflow/kubeflow/jupyter-web-app + ports: + - containerPort: 5000 + volumeMounts: + - mountPath: /etc/config + name: config-volume + - mountPath: /src/apps/default/static/assets/logos + name: logos-volume + env: + - name: APP_PREFIX + value: $(JWA_PREFIX) + - name: UI + value: $(JWA_UI) + - name: USERID_HEADER + value: $(JWA_USERID_HEADER) + - name: USERID_PREFIX + value: $(JWA_USERID_PREFIX) + - name: APP_SECURE_COOKIES + value: $(JWA_APP_SECURE_COOKIES) + - name: METRICS + value: $(JWA_APP_ENABLE_METRICS) + serviceAccountName: service-account + volumes: + - configMap: + name: config + name: config-volume + - configMap: + name: jupyter-web-app-logos + name: logos-volume diff --git a/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/kustomization.yaml b/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/kustomization.yaml new file mode 100644 index 0000000..7698904 --- /dev/null +++ b/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/kustomization.yaml @@ -0,0 +1,92 @@ +# TODO(https://github.com/kubeflow/manifests/issues/774): +# This is a legacy package. Hopefully we can get rid of it once +# 774 is complete. +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +# TODO(jlewi): We can't depend on base because of the deployment_patch. +# but maybe if we changed that to use ConfigMapRef then the patch would correctly +# override the patch applied in base_v3 +resources: +- cluster-role-binding.yaml +- cluster-role.yaml +- deployment.yaml +- role-binding.yaml +- role.yaml +- service-account.yaml +- service.yaml +- configs/logos-configmap.yaml +namePrefix: jupyter-web-app- +namespace: kubeflow +commonLabels: + app: jupyter-web-app + kustomize.component: jupyter-web-app +images: +- name: ghcr.io/kubeflow/kubeflow/jupyter-web-app + newName: ghcr.io/kubeflow/kubeflow/jupyter-web-app + newTag: v1.10.0 +# We need the name to be unique without the suffix because the original name is what +# gets used with patches +configMapGenerator: +- envs: + - params.env + name: parameters +- files: + - configs/spawner_ui_config.yaml + name: config +vars: +- fieldref: + fieldPath: data.JWA_CLUSTER_DOMAIN + name: JWA_CLUSTER_DOMAIN + objref: + apiVersion: v1 + kind: ConfigMap + name: parameters +- fieldref: + fieldPath: metadata.namespace + name: JWA_NAMESPACE + objref: + apiVersion: v1 + kind: Service + name: service +- fieldref: + fieldPath: data.JWA_USERID_HEADER + name: JWA_USERID_HEADER + objref: + apiVersion: v1 + kind: ConfigMap + name: parameters +- fieldref: + fieldPath: data.JWA_USERID_PREFIX + name: JWA_USERID_PREFIX + objref: + apiVersion: v1 + kind: ConfigMap + name: parameters +- fieldref: + fieldPath: data.JWA_UI + name: JWA_UI + objref: + apiVersion: v1 + kind: ConfigMap + name: parameters +- fieldref: + fieldPath: data.JWA_PREFIX + name: JWA_PREFIX + objref: + apiVersion: v1 + kind: ConfigMap + name: parameters +- name: JWA_APP_SECURE_COOKIES + fieldref: + fieldPath: data.JWA_APP_SECURE_COOKIES + objref: + apiVersion: v1 + kind: ConfigMap + name: parameters +- name: JWA_APP_ENABLE_METRICS + fieldref: + fieldPath: data.JWA_APP_ENABLE_METRICS + objref: + apiVersion: v1 + kind: ConfigMap + name: parameters diff --git a/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/params.env b/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/params.env new file mode 100644 index 0000000..6a0e9a5 --- /dev/null +++ b/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/params.env @@ -0,0 +1,7 @@ +JWA_UI=default +JWA_PREFIX=/jupyter +JWA_CLUSTER_DOMAIN=cluster.local +JWA_USERID_HEADER=kubeflow-userid +JWA_USERID_PREFIX= +JWA_APP_SECURE_COOKIES=true +JWA_APP_ENABLE_METRICS=1 diff --git a/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/role-binding.yaml b/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/role-binding.yaml new file mode 100644 index 0000000..20c82c1 --- /dev/null +++ b/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/role-binding.yaml @@ -0,0 +1,11 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: jupyter-notebook-role-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: jupyter-notebook-role +subjects: +- kind: ServiceAccount + name: jupyter-notebook diff --git a/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/role.yaml b/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/role.yaml new file mode 100644 index 0000000..50ea08a --- /dev/null +++ b/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/role.yaml @@ -0,0 +1,48 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: jupyter-notebook-role +rules: +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +- apiGroups: + - kubeflow.org + resources: + - notebooks + - notebooks/finalizers + - poddefaults + verbs: + - get + - list + - create + - delete + - patch + - update +- apiGroups: + - "" + resources: + - persistentvolumeclaims + verbs: + - create + - delete + - get + - list +- apiGroups: + - "" + resources: + - events + - nodes + verbs: + - list +- apiGroups: + - storage.k8s.io + resources: + - storageclasses + verbs: + - get + - list + - watch diff --git a/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/service-account.yaml b/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/service-account.yaml new file mode 100644 index 0000000..a36cbd8 --- /dev/null +++ b/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/service-account.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: service-account diff --git a/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/service.yaml b/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/service.yaml new file mode 100644 index 0000000..e8f70f4 --- /dev/null +++ b/kubeflow/apps/jupyter/jupyter-web-app/upstream/base/service.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + run: jupyter-web-app + name: service +spec: + ports: + - name: http + port: 80 + protocol: TCP + targetPort: 5000 + type: ClusterIP diff --git a/kubeflow/apps/jupyter/jupyter-web-app/upstream/overlays/istio/authorization-policy.yaml b/kubeflow/apps/jupyter/jupyter-web-app/upstream/overlays/istio/authorization-policy.yaml new file mode 100644 index 0000000..b81b95e --- /dev/null +++ b/kubeflow/apps/jupyter/jupyter-web-app/upstream/overlays/istio/authorization-policy.yaml @@ -0,0 +1,14 @@ +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: jupyter-web-app +spec: + action: ALLOW + rules: + - from: + - source: + principals: + - cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account + selector: + matchLabels: + app: jupyter-web-app diff --git a/kubeflow/apps/jupyter/jupyter-web-app/upstream/overlays/istio/destination-rule.yaml b/kubeflow/apps/jupyter/jupyter-web-app/upstream/overlays/istio/destination-rule.yaml new file mode 100644 index 0000000..bd651c5 --- /dev/null +++ b/kubeflow/apps/jupyter/jupyter-web-app/upstream/overlays/istio/destination-rule.yaml @@ -0,0 +1,9 @@ +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: jupyter-web-app +spec: + host: jupyter-web-app-service.kubeflow.svc.cluster.local + trafficPolicy: + tls: + mode: ISTIO_MUTUAL diff --git a/kubeflow/apps/jupyter/jupyter-web-app/upstream/overlays/istio/kustomization.yaml b/kubeflow/apps/jupyter/jupyter-web-app/upstream/overlays/istio/kustomization.yaml new file mode 100644 index 0000000..a647f10 --- /dev/null +++ b/kubeflow/apps/jupyter/jupyter-web-app/upstream/overlays/istio/kustomization.yaml @@ -0,0 +1,13 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- ../../base +- virtual-service.yaml +- authorization-policy.yaml +- destination-rule.yaml +namespace: kubeflow +commonLabels: + app: jupyter-web-app + kustomize.component: jupyter-web-app +configurations: +- params.yaml diff --git a/kubeflow/apps/jupyter/jupyter-web-app/upstream/overlays/istio/params.yaml b/kubeflow/apps/jupyter/jupyter-web-app/upstream/overlays/istio/params.yaml new file mode 100644 index 0000000..eea869e --- /dev/null +++ b/kubeflow/apps/jupyter/jupyter-web-app/upstream/overlays/istio/params.yaml @@ -0,0 +1,3 @@ +varReference: +- path: spec/http/route/destination/host + kind: VirtualService diff --git a/kubeflow/apps/jupyter/jupyter-web-app/upstream/overlays/istio/virtual-service.yaml b/kubeflow/apps/jupyter/jupyter-web-app/upstream/overlays/istio/virtual-service.yaml new file mode 100644 index 0000000..4934c1c --- /dev/null +++ b/kubeflow/apps/jupyter/jupyter-web-app/upstream/overlays/istio/virtual-service.yaml @@ -0,0 +1,24 @@ +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: jupyter-web-app-jupyter-web-app +spec: + gateways: + - kubeflow-gateway + hosts: + - '*' + http: + - headers: + request: + add: + x-forwarded-prefix: /jupyter + match: + - uri: + prefix: /jupyter/ + rewrite: + uri: / + route: + - destination: + host: jupyter-web-app-service.$(JWA_NAMESPACE).svc.$(JWA_CLUSTER_DOMAIN) + port: + number: 80 diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/README.md b/kubeflow/apps/jupyter/notebook-controller/upstream/README.md new file mode 100644 index 0000000..8a3af90 --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/README.md @@ -0,0 +1,30 @@ +### Manifests + +This folder contains manifests for installing `notebook-controller`. The structure is the following: + +``` +. +├── crd +├── default +├── manager +├── rbac +├── samples +├── base +├── overlays +│ ├── kubeflow +│ └── standalone +``` + +The breakdown is the following: +- `crd`, `default`, `manager`, `rbac`, `samples`: Kubebuilder-generated structure. We keep this in order to be compatible with kubebuilder workflows. This is not meant for the consumer of the manifests. +- `base`, `overlays`: Kustomizations meant for consumption by the user: + - `overlays/kubeflow`: Installs `notebook-controller` as part of Kubeflow. The resulting manifests should be the same as the result of the [deprecated `base_v3` from kubeflow/manifests](https://github.com/kubeflow/manifests/tree/306d02979124bc29e48152272ddd60a59be9306c/profiles/base_v3). At a glance, it makes the following changes: + - Use namespace `kubeflow`. + - Remove namespace resource. + - Add KFAM container. + - Add KFAM Service and VirtualService. + - `overlays/standalone`: Install `notebook-controller` in its own namespace. Useful for testing or for users that prefer to install just the controller. + +### CRD Issue + +We patch the kubebuilder-generated CRD with an older version. That's because the validation was more relaxed in a previous version and now we ended up with some clients and resources in a state that fails more detailed validation, but works correctly. For more information, see: https://github.com/kubeflow/kubeflow/issues/5722 \ No newline at end of file diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/base/kustomization.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/base/kustomization.yaml new file mode 100644 index 0000000..ccd0e8c --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/base/kustomization.yaml @@ -0,0 +1,8 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- ../default +images: +- name: ghcr.io/kubeflow/kubeflow/notebook-controller + newName: ghcr.io/kubeflow/kubeflow/notebook-controller + newTag: v1.10.0 diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/crd/bases/kubeflow.org_notebooks.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/crd/bases/kubeflow.org_notebooks.yaml new file mode 100644 index 0000000..1ca9aac --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/crd/bases/kubeflow.org_notebooks.yaml @@ -0,0 +1,9410 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null + name: notebooks.kubeflow.org +spec: + group: kubeflow.org + names: + kind: Notebook + listKind: NotebookList + plural: notebooks + singular: notebook + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + template: + properties: + spec: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + automountServiceAccountToken: + type: boolean + containers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + dnsPolicy: + type: string + enableServiceLinks: + type: boolean + ephemeralContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + targetContainerName: + type: string + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + hostAliases: + items: + properties: + hostnames: + items: + type: string + type: array + ip: + type: string + type: object + type: array + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + hostname: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + initContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + nodeName: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + os: + properties: + name: + type: string + required: + - name + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + preemptionPolicy: + type: string + priority: + format: int32 + type: integer + priorityClassName: + type: string + readinessGates: + items: + properties: + conditionType: + type: string + required: + - conditionType + type: object + type: array + restartPolicy: + type: string + runtimeClassName: + type: string + schedulerName: + type: string + securityContext: + properties: + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + serviceAccountName: + type: string + setHostnameAsFQDN: + type: boolean + shareProcessNamespace: + type: boolean + subdomain: + type: string + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + maxSkew: + format: int32 + type: integer + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + storageClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - containers + type: object + type: object + type: object + status: + properties: + conditions: + items: + properties: + lastProbeTime: + format: date-time + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + containerState: + properties: + running: + properties: + startedAt: + format: date-time + type: string + type: object + terminated: + properties: + containerID: + type: string + exitCode: + format: int32 + type: integer + finishedAt: + format: date-time + type: string + message: + type: string + reason: + type: string + signal: + format: int32 + type: integer + startedAt: + format: date-time + type: string + required: + - exitCode + type: object + waiting: + properties: + message: + type: string + reason: + type: string + type: object + type: object + readyReplicas: + format: int32 + type: integer + required: + - conditions + - containerState + - readyReplicas + type: object + type: object + served: true + storage: true + subresources: + status: {} + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + template: + properties: + spec: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + automountServiceAccountToken: + type: boolean + containers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + dnsPolicy: + type: string + enableServiceLinks: + type: boolean + ephemeralContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + targetContainerName: + type: string + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + hostAliases: + items: + properties: + hostnames: + items: + type: string + type: array + ip: + type: string + type: object + type: array + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + hostname: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + initContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + nodeName: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + os: + properties: + name: + type: string + required: + - name + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + preemptionPolicy: + type: string + priority: + format: int32 + type: integer + priorityClassName: + type: string + readinessGates: + items: + properties: + conditionType: + type: string + required: + - conditionType + type: object + type: array + restartPolicy: + type: string + runtimeClassName: + type: string + schedulerName: + type: string + securityContext: + properties: + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + serviceAccountName: + type: string + setHostnameAsFQDN: + type: boolean + shareProcessNamespace: + type: boolean + subdomain: + type: string + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + maxSkew: + format: int32 + type: integer + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + storageClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - containers + type: object + type: object + type: object + status: + properties: + conditions: + items: + properties: + lastProbeTime: + format: date-time + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + containerState: + properties: + running: + properties: + startedAt: + format: date-time + type: string + type: object + terminated: + properties: + containerID: + type: string + exitCode: + format: int32 + type: integer + finishedAt: + format: date-time + type: string + message: + type: string + reason: + type: string + signal: + format: int32 + type: integer + startedAt: + format: date-time + type: string + required: + - exitCode + type: object + waiting: + properties: + message: + type: string + reason: + type: string + type: object + type: object + readyReplicas: + format: int32 + type: integer + required: + - conditions + - containerState + - readyReplicas + type: object + type: object + served: true + storage: false + subresources: + status: {} + - name: v1beta1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + template: + properties: + spec: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + automountServiceAccountToken: + type: boolean + containers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + dnsPolicy: + type: string + enableServiceLinks: + type: boolean + ephemeralContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + targetContainerName: + type: string + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + hostAliases: + items: + properties: + hostnames: + items: + type: string + type: array + ip: + type: string + type: object + type: array + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + hostname: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + initContainers: + items: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + type: string + required: + - name + type: object + type: array + nodeName: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + os: + properties: + name: + type: string + required: + - name + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + preemptionPolicy: + type: string + priority: + format: int32 + type: integer + priorityClassName: + type: string + readinessGates: + items: + properties: + conditionType: + type: string + required: + - conditionType + type: object + type: array + restartPolicy: + type: string + runtimeClassName: + type: string + schedulerName: + type: string + securityContext: + properties: + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + serviceAccountName: + type: string + setHostnameAsFQDN: + type: boolean + shareProcessNamespace: + type: boolean + subdomain: + type: string + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + maxSkew: + format: int32 + type: integer + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + storageClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - containers + type: object + type: object + type: object + status: + properties: + conditions: + items: + properties: + lastProbeTime: + format: date-time + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - status + - type + type: object + type: array + containerState: + properties: + running: + properties: + startedAt: + format: date-time + type: string + type: object + terminated: + properties: + containerID: + type: string + exitCode: + format: int32 + type: integer + finishedAt: + format: date-time + type: string + message: + type: string + reason: + type: string + signal: + format: int32 + type: integer + startedAt: + format: date-time + type: string + required: + - exitCode + type: object + waiting: + properties: + message: + type: string + reason: + type: string + type: object + type: object + readyReplicas: + format: int32 + type: integer + required: + - conditions + - containerState + - readyReplicas + type: object + type: object + served: true + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/crd/kustomization.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/crd/kustomization.yaml new file mode 100644 index 0000000..8dac3f0 --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/crd/kustomization.yaml @@ -0,0 +1,32 @@ +# This kustomization.yaml is not intended to be run by itself, +# since it depends on service name and namespace that are out of this kustomize package. +# It should be run by config/default +resources: +- bases/kubeflow.org_notebooks.yaml +# +kubebuilder:scaffold:crdkustomizeresource + +patchesStrategicMerge: +- patches/trivial_conversion_patch.yaml + +# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. +# patches here are for enabling the conversion webhook for each CRD +#- patches/webhook_in_notebooks.yaml +# +kubebuilder:scaffold:crdkustomizewebhookpatch + +# [CERTMANAGER] To enable webhook, uncomment all the sections with [CERTMANAGER] prefix. +# patches here are for enabling the CA injection for each CRD +#- patches/cainjection_in_notebooks.yaml +# +kubebuilder:scaffold:crdkustomizecainjectionpatch + +# the following config is for teaching kustomize how to do kustomization for CRDs. +configurations: +- kustomizeconfig.yaml + +patchesJson6902: + - target: + group: apiextensions.k8s.io + version: v1 + kind: CustomResourceDefinition + name: notebooks.kubeflow.org + path: patches/validation_patches.yaml + diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/crd/kustomizeconfig.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/crd/kustomizeconfig.yaml new file mode 100644 index 0000000..6f83d9a --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/crd/kustomizeconfig.yaml @@ -0,0 +1,17 @@ +# This file is for teaching kustomize how to substitute name and namespace reference in CRD +nameReference: +- kind: Service + version: v1 + fieldSpecs: + - kind: CustomResourceDefinition + group: apiextensions.k8s.io + path: spec/conversion/webhookClientConfig/service/name + +namespace: +- kind: CustomResourceDefinition + group: apiextensions.k8s.io + path: spec/conversion/webhookClientConfig/service/namespace + create: false + +varReference: +- path: metadata/annotations diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/crd/patches/cainjection_in_notebooks.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/crd/patches/cainjection_in_notebooks.yaml new file mode 100644 index 0000000..f99acf3 --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/crd/patches/cainjection_in_notebooks.yaml @@ -0,0 +1,8 @@ +# The following patch adds a directive for certmanager to inject CA into the CRD +# CRD conversion requires k8s 1.13 or later. +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + certmanager.k8s.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + name: notebooks.kubeflow.org diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/crd/patches/trivial_conversion_patch.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/crd/patches/trivial_conversion_patch.yaml new file mode 100644 index 0000000..3ed80e6 --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/crd/patches/trivial_conversion_patch.yaml @@ -0,0 +1,9 @@ + +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: notebooks.kubeflow.org +spec: + preserveUnknownFields: false # TODO: Remove in Kubeflow 1.7 release + conversion: + strategy: None diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/crd/patches/validation_patches.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/crd/patches/validation_patches.yaml new file mode 100644 index 0000000..7bb93c2 --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/crd/patches/validation_patches.yaml @@ -0,0 +1,29 @@ +- op: replace + path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/template/properties/spec/properties/containers/items/required + value: + - name + - image + +- op: replace + path: /spec/versions/1/schema/openAPIV3Schema/properties/spec/properties/template/properties/spec/properties/containers/items/required + value: + - name + - image + +- op: replace + path: /spec/versions/2/schema/openAPIV3Schema/properties/spec/properties/template/properties/spec/properties/containers/items/required + value: + - name + - image + +- op: add + path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/template/properties/spec/properties/containers/minItems + value: 1 + +- op: add + path: /spec/versions/1/schema/openAPIV3Schema/properties/spec/properties/template/properties/spec/properties/containers/minItems + value: 1 + +- op: add + path: /spec/versions/2/schema/openAPIV3Schema/properties/spec/properties/template/properties/spec/properties/containers/minItems + value: 1 diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/crd/patches/webhook_in_notebooks.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/crd/patches/webhook_in_notebooks.yaml new file mode 100644 index 0000000..b980a96 --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/crd/patches/webhook_in_notebooks.yaml @@ -0,0 +1,17 @@ +# The following patch enables conversion webhook for CRD +# CRD conversion requires k8s 1.13 or later. +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: notebooks.kubeflow.org +spec: + conversion: + strategy: Webhook + webhookClientConfig: + # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, + # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) + caBundle: Cg== + service: + namespace: system + name: webhook-service + path: /convert diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/default/kustomization.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/default/kustomization.yaml new file mode 100644 index 0000000..393aaa5 --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/default/kustomization.yaml @@ -0,0 +1,75 @@ +# Adds namespace to all resources. +namespace: notebook-controller-system + +# Value of this field is prepended to the +# names of all resources, e.g. a deployment named +# "wordpress" becomes "alices-wordpress". +# Note that it should also match with the prefix (text before '-') of the namespace +# field above. +namePrefix: notebook-controller- + +# Labels to add to all resources and selectors. +commonLabels: + app: notebook-controller + kustomize.component: notebook-controller + + +bases: +- ../rbac +- ../manager +- ../crd +# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in crd/kustomization.yaml +#- ../webhook +# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. +#- ../certmanager + +#patchesStrategicMerge: +#- manager_image_patch.yaml + # Protect the /metrics endpoint by putting it behind auth. + # Only one of manager_auth_proxy_patch.yaml and + # manager_prometheus_metrics_patch.yaml should be enabled. +#- manager_auth_proxy_patch.yaml + # If you want your controller-manager to expose the /metrics + # endpoint w/o any authn/z, uncomment the following line and + # comment manager_auth_proxy_patch.yaml. + # Only one of manager_auth_proxy_patch.yaml and + # manager_prometheus_metrics_patch.yaml should be enabled. +#- manager_prometheus_metrics_patch.yaml + +# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in crd/kustomization.yaml +#- manager_webhook_patch.yaml + +# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. +# Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks. +# 'CERTMANAGER' needs to be enabled to use ca injection +#- webhookcainjection_patch.yaml + +# the following config is for teaching kustomize how to do var substitution +vars: +# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. +# - name: CERTIFICATE_NAMESPACE # namespace of the certificate CR +# objref: +# kind: Certificate +# group: certmanager.k8s.io +# version: v1alpha1 +# name: serving-cert # this name should match the one in certificate.yaml +# fieldref: +# fieldpath: metadata.namespace +# - name: CERTIFICATE_NAME +# objref: +# kind: Certificate +# group: certmanager.k8s.io +# version: v1alpha1 +# name: serving-cert # this name should match the one in certificate.yaml +# - name: SERVICE_NAMESPACE # namespace of the service +# objref: +# kind: Service +# version: v1 +# name: webhook-service +# fieldref: +# fieldpath: metadata.namespace +# - name: SERVICE_NAME +# objref: +# kind: Service +# version: v1 +# name: webhook-service diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/default/manager_auth_proxy_patch.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/default/manager_auth_proxy_patch.yaml new file mode 100644 index 0000000..c9ae058 --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/default/manager_auth_proxy_patch.yaml @@ -0,0 +1,25 @@ +# This patch inject a sidecar container which is a HTTP proxy for the controller manager, +# it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews. +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + - name: kube-rbac-proxy + image: quay.io/brancz/kube-rbac-proxy:v0.4.0 + args: + - "--secure-listen-address=0.0.0.0:8443" + - "--upstream=http://127.0.0.1:8080/" + - "--logtostderr=true" + - "--v=10" + ports: + - containerPort: 8443 + name: https + - name: manager + args: + - "--metrics-addr=127.0.0.1:8080" + - "--enable-leader-election" diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/default/manager_image_patch.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/default/manager_image_patch.yaml new file mode 100644 index 0000000..eb90957 --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/default/manager_image_patch.yaml @@ -0,0 +1,12 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + # Change the value of image field below to your controller image URL + - image: IMAGE_URL + name: manager diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/default/manager_prometheus_metrics_patch.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/default/manager_prometheus_metrics_patch.yaml new file mode 100644 index 0000000..0b96c68 --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/default/manager_prometheus_metrics_patch.yaml @@ -0,0 +1,19 @@ +# This patch enables Prometheus scraping for the manager pod. +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + metadata: + annotations: + prometheus.io/scrape: 'true' + spec: + containers: + # Expose the prometheus metrics on default port + - name: manager + ports: + - containerPort: 8080 + name: metrics + protocol: TCP diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/default/manager_webhook_patch.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/default/manager_webhook_patch.yaml new file mode 100644 index 0000000..f2f7157 --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/default/manager_webhook_patch.yaml @@ -0,0 +1,23 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + - name: manager + ports: + - containerPort: 443 + name: webhook-server + protocol: TCP + volumeMounts: + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: cert + readOnly: true + volumes: + - name: cert + secret: + defaultMode: 420 + secretName: webhook-server-cert diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/default/webhookcainjection_patch.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/default/webhookcainjection_patch.yaml new file mode 100644 index 0000000..5e3e077 --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/default/webhookcainjection_patch.yaml @@ -0,0 +1,15 @@ +# This patch add annotation to admission webhook config and +# the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize. +apiVersion: admissionregistration.k8s.io/v1beta1 +kind: MutatingWebhookConfiguration +metadata: + name: mutating-webhook-configuration + annotations: + certmanager.k8s.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) +--- +apiVersion: admissionregistration.k8s.io/v1beta1 +kind: ValidatingWebhookConfiguration +metadata: + name: validating-webhook-configuration + annotations: + certmanager.k8s.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/manager/kustomization.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/manager/kustomization.yaml new file mode 100644 index 0000000..4cc3f30 --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/manager/kustomization.yaml @@ -0,0 +1,8 @@ +resources: +- manager.yaml +- service-account.yaml +- service.yaml +configMapGenerator: +- name: config + envs: + - params.env diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/manager/manager.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/manager/manager.yaml new file mode 100644 index 0000000..88cc068 --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/manager/manager.yaml @@ -0,0 +1,73 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: + control-plane: controller-manager + name: system +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: deployment +spec: + template: + metadata: + labels: + app: notebook-controller + kustomize.component: notebook-controller + spec: + containers: + - name: manager + image: ghcr.io/kubeflow/kubeflow/notebook-controller + command: + - /manager + env: + - name: USE_ISTIO + valueFrom: + configMapKeyRef: + name: config + key: USE_ISTIO + - name: ISTIO_GATEWAY + valueFrom: + configMapKeyRef: + name: config + key: ISTIO_GATEWAY + - name: ISTIO_HOST + valueFrom: + configMapKeyRef: + name: config + key: ISTIO_HOST + - name: CLUSTER_DOMAIN + valueFrom: + configMapKeyRef: + name: config + key: CLUSTER_DOMAIN + - name: ENABLE_CULLING + valueFrom: + configMapKeyRef: + name: config + key: ENABLE_CULLING + - name: CULL_IDLE_TIME + valueFrom: + configMapKeyRef: + name: config + key: CULL_IDLE_TIME + - name: IDLENESS_CHECK_PERIOD + valueFrom: + configMapKeyRef: + name: config + key: IDLENESS_CHECK_PERIOD + imagePullPolicy: IfNotPresent + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + serviceAccountName: service-account diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/manager/params.env b/kubeflow/apps/jupyter/notebook-controller/upstream/manager/params.env new file mode 100644 index 0000000..232af1d --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/manager/params.env @@ -0,0 +1,7 @@ +USE_ISTIO=true +ISTIO_GATEWAY=kubeflow/kubeflow-gateway +ISTIO_HOST=* +CLUSTER_DOMAIN=cluster.local +ENABLE_CULLING=false +CULL_IDLE_TIME=1440 +IDLENESS_CHECK_PERIOD=1 diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/manager/service-account.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/manager/service-account.yaml new file mode 100644 index 0000000..a36cbd8 --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/manager/service-account.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: service-account diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/manager/service.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/manager/service.yaml new file mode 100644 index 0000000..d828b8e --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/manager/service.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: notebook-controller + kustomize.component: notebook-controller + name: service +spec: + ports: + - port: 443 + selector: + app: notebook-controller + kustomize.component: notebook-controller diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/overlays/kubeflow/kustomization.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/overlays/kubeflow/kustomization.yaml new file mode 100644 index 0000000..6a9b11b --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/overlays/kubeflow/kustomization.yaml @@ -0,0 +1,13 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- ../../base +namespace: kubeflow +patchesStrategicMerge: +- patches/remove-namespace.yaml +configMapGenerator: +- name: config + behavior: merge + literals: + - USE_ISTIO=true + - ISTIO_GATEWAY=kubeflow/kubeflow-gateway diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/overlays/kubeflow/patches/remove-namespace.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/overlays/kubeflow/patches/remove-namespace.yaml new file mode 100644 index 0000000..4b0795f --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/overlays/kubeflow/patches/remove-namespace.yaml @@ -0,0 +1,5 @@ +$patch: delete +apiVersion: v1 +kind: Namespace +metadata: + name: notebook-controller-system diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/overlays/standalone/kustomization.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/overlays/standalone/kustomization.yaml new file mode 100644 index 0000000..c1d881c --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/overlays/standalone/kustomization.yaml @@ -0,0 +1,10 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- ../../base +namespace: notebook-controller-system +configMapGenerator: +- name: config + behavior: merge + literals: + - USE_ISTIO=false diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/rbac/auth_proxy_role.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/rbac/auth_proxy_role.yaml new file mode 100644 index 0000000..618f5e4 --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/rbac/auth_proxy_role.yaml @@ -0,0 +1,13 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: proxy-role +rules: +- apiGroups: ["authentication.k8s.io"] + resources: + - tokenreviews + verbs: ["create"] +- apiGroups: ["authorization.k8s.io"] + resources: + - subjectaccessreviews + verbs: ["create"] diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/rbac/auth_proxy_role_binding.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/rbac/auth_proxy_role_binding.yaml new file mode 100644 index 0000000..9a800c8 --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/rbac/auth_proxy_role_binding.yaml @@ -0,0 +1,11 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: proxy-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: proxy-role +subjects: +- kind: ServiceAccount + name: service-account diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/rbac/auth_proxy_service.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/rbac/auth_proxy_service.yaml new file mode 100644 index 0000000..d61e546 --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/rbac/auth_proxy_service.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Service +metadata: + annotations: + prometheus.io/port: "8443" + prometheus.io/scheme: https + prometheus.io/scrape: "true" + labels: + control-plane: controller-manager + name: controller-manager-metrics-service + namespace: system +spec: + ports: + - name: https + port: 8443 + targetPort: https + selector: + control-plane: controller-manager diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/rbac/kustomization.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/rbac/kustomization.yaml new file mode 100644 index 0000000..40a4b9a --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/rbac/kustomization.yaml @@ -0,0 +1,12 @@ +resources: +- role.yaml +- role_binding.yaml +- leader_election_role.yaml +- leader_election_role_binding.yaml +- user_cluster_roles.yaml +# Comment the following 3 lines if you want to disable +# the auth proxy (https://github.com/brancz/kube-rbac-proxy) +# which protects your /metrics endpoint. +# - auth_proxy_service.yaml +# - auth_proxy_role.yaml +# - auth_proxy_role_binding.yaml diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/rbac/leader_election_role.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/rbac/leader_election_role.yaml new file mode 100644 index 0000000..eaa7915 --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/rbac/leader_election_role.yaml @@ -0,0 +1,32 @@ +# permissions to do leader election. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: leader-election-role +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - configmaps/status + verbs: + - get + - update + - patch +- apiGroups: + - "" + resources: + - events + verbs: + - create diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/rbac/leader_election_role_binding.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/rbac/leader_election_role_binding.yaml new file mode 100644 index 0000000..365e2fe --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/rbac/leader_election_role_binding.yaml @@ -0,0 +1,11 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: leader-election-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: leader-election-role +subjects: +- kind: ServiceAccount + name: service-account diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/rbac/role.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/rbac/role.yaml new file mode 100644 index 0000000..7273f3a --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/rbac/role.yaml @@ -0,0 +1,51 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: role +rules: +- apiGroups: + - apps + resources: + - statefulsets + verbs: + - '*' +- apiGroups: + - "" + resources: + - events + verbs: + - create + - get + - list + - patch + - watch +- apiGroups: + - "" + resources: + - pods + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - services + verbs: + - '*' +- apiGroups: + - kubeflow.org + resources: + - notebooks + - notebooks/finalizers + - notebooks/status + verbs: + - '*' +- apiGroups: + - networking.istio.io + resources: + - virtualservices + verbs: + - '*' diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/rbac/role_binding.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/rbac/role_binding.yaml new file mode 100644 index 0000000..a1a3945 --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/rbac/role_binding.yaml @@ -0,0 +1,11 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: role-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: role +subjects: +- kind: ServiceAccount + name: service-account diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/rbac/user_cluster_roles.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/rbac/user_cluster_roles.yaml new file mode 100644 index 0000000..566e576 --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/rbac/user_cluster_roles.yaml @@ -0,0 +1,55 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: kubeflow-notebooks-admin + labels: + rbac.authorization.kubeflow.org/aggregate-to-kubeflow-admin: "true" +aggregationRule: + clusterRoleSelectors: + - matchLabels: + rbac.authorization.kubeflow.org/aggregate-to-kubeflow-notebooks-admin: "true" +rules: [] + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: kubeflow-notebooks-edit + labels: + rbac.authorization.kubeflow.org/aggregate-to-kubeflow-edit: "true" + rbac.authorization.kubeflow.org/aggregate-to-kubeflow-notebooks-admin: "true" +rules: +- apiGroups: + - kubeflow.org + resources: + - notebooks + - notebooks/status + verbs: + - get + - list + - watch + - create + - delete + - deletecollection + - patch + - update + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: kubeflow-notebooks-view + labels: + rbac.authorization.kubeflow.org/aggregate-to-kubeflow-view: "true" +rules: +- apiGroups: + - kubeflow.org + resources: + - notebooks + - notebooks/status + verbs: + - get + - list + - watch diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/samples/_v1_notebook.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/samples/_v1_notebook.yaml new file mode 100644 index 0000000..5490c33 --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/samples/_v1_notebook.yaml @@ -0,0 +1,11 @@ +--- +apiVersion: kubeflow.org/v1 +kind: Notebook +metadata: + name: notebook-sample-v1 +spec: + template: + spec: + containers: + - name: notebook-sample-v1 + image: ghcr.io/kubeflow/kubeflow/notebook-servers/jupyter:latest diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/samples/_v1alpha1_notebook.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/samples/_v1alpha1_notebook.yaml new file mode 100644 index 0000000..266ab8f --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/samples/_v1alpha1_notebook.yaml @@ -0,0 +1,11 @@ +--- +apiVersion: kubeflow.org/v1alpha1 +kind: Notebook +metadata: + name: notebook-sample-v1alpha1 +spec: + template: + spec: + containers: + - name: notebook-sample-v1 + image: ghcr.io/kubeflow/kubeflow/notebook-servers/jupyter:latest diff --git a/kubeflow/apps/jupyter/notebook-controller/upstream/samples/_v1beta1_notebook.yaml b/kubeflow/apps/jupyter/notebook-controller/upstream/samples/_v1beta1_notebook.yaml new file mode 100644 index 0000000..9c8cde1 --- /dev/null +++ b/kubeflow/apps/jupyter/notebook-controller/upstream/samples/_v1beta1_notebook.yaml @@ -0,0 +1,11 @@ +--- +apiVersion: kubeflow.org/v1beta1 +kind: Notebook +metadata: + name: notebook-sample-v1beta1 +spec: + template: + spec: + containers: + - name: notebook-sample-v1 + image: ghcr.io/kubeflow/kubeflow/notebook-servers/jupyter:latest diff --git a/kubeflow/apps/katib/upstream/components/controller/controller.yaml b/kubeflow/apps/katib/upstream/components/controller/controller.yaml new file mode 100644 index 0000000..4f9a3c6 --- /dev/null +++ b/kubeflow/apps/katib/upstream/components/controller/controller.yaml @@ -0,0 +1,68 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: katib-controller + namespace: kubeflow + labels: + katib.kubeflow.org/component: controller +spec: + replicas: 1 + selector: + matchLabels: + katib.kubeflow.org/component: controller + template: + metadata: + labels: + katib.kubeflow.org/component: controller + sidecar.istio.io/inject: "false" + annotations: + prometheus.io/scrape: "true" + prometheus.io/port: "8080" + spec: + serviceAccountName: katib-controller + containers: + - name: katib-controller + image: ghcr.io/kubeflow/katib/katib-controller + command: ["./katib-controller"] + args: + - --katib-config=/katib-config.yaml + ports: + - containerPort: 8443 + name: webhook + protocol: TCP + - containerPort: 8080 + name: metrics + protocol: TCP + - containerPort: 18080 + name: healthz + protocol: TCP + readinessProbe: + httpGet: + path: /readyz + port: healthz + livenessProbe: + httpGet: + path: /healthz + port: healthz + env: + - name: KATIB_CORE_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + volumeMounts: + - mountPath: /tmp/cert + name: cert + readOnly: true + - mountPath: /katib-config.yaml + name: katib-config + subPath: katib-config.yaml + readOnly: true + volumes: + - name: cert + secret: + defaultMode: 420 + secretName: katib-webhook-cert + - name: katib-config + configMap: + name: katib-config diff --git a/kubeflow/apps/katib/upstream/components/controller/kustomization.yaml b/kubeflow/apps/katib/upstream/components/controller/kustomization.yaml new file mode 100644 index 0000000..18979dd --- /dev/null +++ b/kubeflow/apps/katib/upstream/components/controller/kustomization.yaml @@ -0,0 +1,9 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - controller.yaml + - rbac.yaml + - service.yaml + - trial-templates.yaml diff --git a/kubeflow/apps/katib/upstream/components/controller/rbac.yaml b/kubeflow/apps/katib/upstream/components/controller/rbac.yaml new file mode 100644 index 0000000..9eec022 --- /dev/null +++ b/kubeflow/apps/katib/upstream/components/controller/rbac.yaml @@ -0,0 +1,149 @@ +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: katib-controller +rules: + - apiGroups: + - "" + resources: + - services + verbs: + - "get" + - "list" + - "watch" + - "create" + - "delete" + - apiGroups: + - "" + resources: + - events + verbs: + - "create" + - "patch" + - "update" + - apiGroups: + - "" + resources: + - serviceaccounts + - persistentvolumes + - persistentvolumeclaims + verbs: + - "get" + - "list" + - "watch" + - "create" + - apiGroups: + - "" + resources: + - namespaces + - configmaps + verbs: + - "get" + - "list" + - "watch" + - apiGroups: + - "" + resources: + - pods + - pods/status + verbs: + - "get" + - apiGroups: + - "" + resources: + - secrets + verbs: + - "get" + - "list" + - "watch" + - "patch" + - "update" + - apiGroups: + - apps + resources: + - deployments + verbs: + - "get" + - "list" + - "watch" + - "create" + - "delete" + - apiGroups: + - rbac.authorization.k8s.io + resources: + - roles + - rolebindings + verbs: + - "get" + - "create" + - "list" + - "watch" + - apiGroups: + - batch + resources: + - jobs + - cronjobs + verbs: + - "get" + - "list" + - "watch" + - "create" + - "delete" + - apiGroups: + - kubeflow.org + resources: + - tfjobs + - pytorchjobs + - mpijobs + - xgboostjobs + verbs: + - "get" + - "list" + - "watch" + - "create" + - "delete" + - apiGroups: + - kubeflow.org + resources: + - experiments + - experiments/status + - experiments/finalizers + - trials + - trials/status + - trials/finalizers + - suggestions + - suggestions/status + - suggestions/finalizers + verbs: + - "*" + - apiGroups: + - admissionregistration.k8s.io + resources: + - validatingwebhookconfigurations + - mutatingwebhookconfigurations + verbs: + - "get" + - "watch" + - "list" + - "patch" + - "update" +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: katib-controller + namespace: kubeflow +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: katib-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: katib-controller +subjects: + - kind: ServiceAccount + name: katib-controller + namespace: kubeflow diff --git a/kubeflow/apps/katib/upstream/components/controller/service.yaml b/kubeflow/apps/katib/upstream/components/controller/service.yaml new file mode 100644 index 0000000..f783747 --- /dev/null +++ b/kubeflow/apps/katib/upstream/components/controller/service.yaml @@ -0,0 +1,26 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: katib-controller + namespace: kubeflow + labels: + katib.kubeflow.org/component: controller + annotations: + prometheus.io/port: "8080" + prometheus.io/scheme: http + prometheus.io/scrape: "true" +spec: + ports: + - port: 443 + protocol: TCP + targetPort: 8443 + name: webhook + - name: metrics + port: 8080 + targetPort: 8080 + - name: healthz + port: 18080 + targetPort: 18080 + selector: + katib.kubeflow.org/component: controller diff --git a/kubeflow/apps/katib/upstream/components/controller/trial-templates.yaml b/kubeflow/apps/katib/upstream/components/controller/trial-templates.yaml new file mode 100644 index 0000000..1b0f3bb --- /dev/null +++ b/kubeflow/apps/katib/upstream/components/controller/trial-templates.yaml @@ -0,0 +1,77 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: trial-templates + namespace: kubeflow + labels: + katib.kubeflow.org/component: trial-templates +data: + defaultTrialTemplate.yaml: |- + apiVersion: batch/v1 + kind: Job + spec: + template: + spec: + containers: + - name: training-container + image: ghcr.io/kubeflow/katib/pytorch-mnist-cpu:v0.18.0 + command: + - "python3" + - "/opt/pytorch-mnist/mnist.py" + - "--epochs=1" + - "--batch-size=16" + - "--lr=${trialParameters.learningRate}" + - "--momentum=${trialParameters.momentum}" + restartPolicy: Never + # For ConfigMap templates double quotes must set in commands to correct parse JSON parameters in Trial Template (e.g nn_config, architecture) + enasCPUTemplate: |- + apiVersion: batch/v1 + kind: Job + spec: + template: + spec: + containers: + - name: training-container + image: ghcr.io/kubeflow/katib/enas-cnn-cifar10-cpu:v0.18.0 + command: + - python3 + - -u + - RunTrial.py + - --num_epochs=1 + - "--architecture=\"${trialParameters.neuralNetworkArchitecture}\"" + - "--nn_config=\"${trialParameters.neuralNetworkConfig}\"" + restartPolicy: Never + pytorchJobTemplate: |- + apiVersion: kubeflow.org/v1 + kind: PyTorchJob + spec: + pytorchReplicaSpecs: + Master: + replicas: 1 + restartPolicy: OnFailure + template: + spec: + containers: + - name: pytorch + image: ghcr.io/kubeflow/katib/pytorch-mnist-cpu:v0.18.0 + command: + - "python3" + - "/opt/pytorch-mnist/mnist.py" + - "--epochs=1" + - "--lr=${trialParameters.learningRate}" + - "--momentum=${trialParameters.momentum}" + Worker: + replicas: 2 + restartPolicy: OnFailure + template: + spec: + containers: + - name: pytorch + image: ghcr.io/kubeflow/katib/pytorch-mnist-cpu:v0.18.0 + command: + - "python3" + - "/opt/pytorch-mnist/mnist.py" + - "--epochs=1" + - "--lr=${trialParameters.learningRate}" + - "--momentum=${trialParameters.momentum}" diff --git a/kubeflow/apps/katib/upstream/components/crd/experiment.yaml b/kubeflow/apps/katib/upstream/components/crd/experiment.yaml new file mode 100644 index 0000000..8b07270 --- /dev/null +++ b/kubeflow/apps/katib/upstream/components/crd/experiment.yaml @@ -0,0 +1,36 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: experiments.kubeflow.org +spec: + group: kubeflow.org + scope: Namespaced + versions: + - name: v1beta1 + served: true + storage: true + additionalPrinterColumns: + - name: Type + type: string + jsonPath: .status.conditions[-1:].type + - name: Status + type: string + jsonPath: .status.conditions[-1:].status + - name: Age + type: date + jsonPath: .metadata.creationTimestamp + subresources: + status: {} + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + names: + kind: Experiment + singular: experiment + plural: experiments + categories: + - all + - kubeflow + - katib diff --git a/kubeflow/apps/katib/upstream/components/crd/kustomization.yaml b/kubeflow/apps/katib/upstream/components/crd/kustomization.yaml new file mode 100644 index 0000000..9c2e6b1 --- /dev/null +++ b/kubeflow/apps/katib/upstream/components/crd/kustomization.yaml @@ -0,0 +1,8 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - experiment.yaml + - suggestion.yaml + - trial.yaml diff --git a/kubeflow/apps/katib/upstream/components/crd/suggestion.yaml b/kubeflow/apps/katib/upstream/components/crd/suggestion.yaml new file mode 100644 index 0000000..b6eaa3f --- /dev/null +++ b/kubeflow/apps/katib/upstream/components/crd/suggestion.yaml @@ -0,0 +1,42 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: suggestions.kubeflow.org +spec: + group: kubeflow.org + scope: Namespaced + versions: + - name: v1beta1 + served: true + storage: true + additionalPrinterColumns: + - name: Type + type: string + jsonPath: .status.conditions[-1:].type + - name: Status + type: string + jsonPath: .status.conditions[-1:].status + - name: Requested + type: string + jsonPath: .spec.requests + - name: Assigned + type: string + jsonPath: .status.suggestionCount + - name: Age + type: date + jsonPath: .metadata.creationTimestamp + subresources: + status: {} + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + names: + kind: Suggestion + singular: suggestion + plural: suggestions + categories: + - all + - kubeflow + - katib diff --git a/kubeflow/apps/katib/upstream/components/crd/trial.yaml b/kubeflow/apps/katib/upstream/components/crd/trial.yaml new file mode 100644 index 0000000..765314b --- /dev/null +++ b/kubeflow/apps/katib/upstream/components/crd/trial.yaml @@ -0,0 +1,36 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: trials.kubeflow.org +spec: + group: kubeflow.org + scope: Namespaced + versions: + - name: v1beta1 + served: true + storage: true + additionalPrinterColumns: + - name: Type + type: string + jsonPath: .status.conditions[-1:].type + - name: Status + type: string + jsonPath: .status.conditions[-1:].status + - name: Age + type: date + jsonPath: .metadata.creationTimestamp + subresources: + status: {} + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + names: + kind: Trial + singular: trial + plural: trials + categories: + - all + - kubeflow + - katib diff --git a/kubeflow/apps/katib/upstream/components/db-manager/db-manager.yaml b/kubeflow/apps/katib/upstream/components/db-manager/db-manager.yaml new file mode 100644 index 0000000..a328873 --- /dev/null +++ b/kubeflow/apps/katib/upstream/components/db-manager/db-manager.yaml @@ -0,0 +1,41 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: katib-db-manager + namespace: kubeflow + labels: + katib.kubeflow.org/component: db-manager +spec: + replicas: 1 + selector: + matchLabels: + katib.kubeflow.org/component: db-manager + template: + metadata: + labels: + katib.kubeflow.org/component: db-manager + sidecar.istio.io/inject: "false" + spec: + containers: + - name: katib-db-manager + image: ghcr.io/kubeflow/katib/katib-db-manager + env: + - name: DB_NAME + value: "mysql" + - name: DB_PASSWORD + valueFrom: + secretKeyRef: + name: katib-mysql-secrets + key: MYSQL_ROOT_PASSWORD + command: + - "./katib-db-manager" + ports: + - name: api + containerPort: 6789 + livenessProbe: + grpc: + port: 6789 + initialDelaySeconds: 10 + periodSeconds: 60 + failureThreshold: 5 diff --git a/kubeflow/apps/katib/upstream/components/db-manager/kustomization.yaml b/kubeflow/apps/katib/upstream/components/db-manager/kustomization.yaml new file mode 100644 index 0000000..2d9e91e --- /dev/null +++ b/kubeflow/apps/katib/upstream/components/db-manager/kustomization.yaml @@ -0,0 +1,7 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - db-manager.yaml + - service.yaml diff --git a/kubeflow/apps/katib/upstream/components/db-manager/service.yaml b/kubeflow/apps/katib/upstream/components/db-manager/service.yaml new file mode 100644 index 0000000..4c1c733 --- /dev/null +++ b/kubeflow/apps/katib/upstream/components/db-manager/service.yaml @@ -0,0 +1,16 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: katib-db-manager + namespace: kubeflow + labels: + katib.kubeflow.org/component: db-manager +spec: + type: ClusterIP + ports: + - port: 6789 + protocol: TCP + name: api + selector: + katib.kubeflow.org/component: db-manager diff --git a/kubeflow/apps/katib/upstream/components/mysql/kustomization.yaml b/kubeflow/apps/katib/upstream/components/mysql/kustomization.yaml new file mode 100644 index 0000000..3843f3b --- /dev/null +++ b/kubeflow/apps/katib/upstream/components/mysql/kustomization.yaml @@ -0,0 +1,9 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - mysql.yaml + - pvc.yaml + - secret.yaml + - service.yaml diff --git a/kubeflow/apps/katib/upstream/components/mysql/mysql.yaml b/kubeflow/apps/katib/upstream/components/mysql/mysql.yaml new file mode 100644 index 0000000..a5eb054 --- /dev/null +++ b/kubeflow/apps/katib/upstream/components/mysql/mysql.yaml @@ -0,0 +1,73 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: katib-mysql + namespace: kubeflow + labels: + katib.kubeflow.org/component: mysql +spec: + replicas: 1 + selector: + matchLabels: + katib.kubeflow.org/component: mysql + strategy: + type: Recreate + template: + metadata: + labels: + katib.kubeflow.org/component: mysql + sidecar.istio.io/inject: "false" + spec: + containers: + - name: katib-mysql + image: mysql:8.0.29 + args: + - --datadir + - /var/lib/mysql/datadir + env: + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: katib-mysql-secrets + key: MYSQL_ROOT_PASSWORD + - name: MYSQL_ALLOW_EMPTY_PASSWORD + value: "true" + - name: MYSQL_DATABASE + value: "katib" + ports: + - name: dbapi + containerPort: 3306 + readinessProbe: + exec: + command: + - "/bin/bash" + - "-c" + - "mysql -D ${MYSQL_DATABASE} -u root -p${MYSQL_ROOT_PASSWORD} -e 'SELECT 1'" + initialDelaySeconds: 10 + periodSeconds: 5 + failureThreshold: 10 + livenessProbe: + exec: + command: + - "/bin/bash" + - "-c" + - "mysqladmin ping -u root -p${MYSQL_ROOT_PASSWORD}" + initialDelaySeconds: 10 + periodSeconds: 5 + failureThreshold: 10 + startupProbe: + exec: + command: + - "/bin/bash" + - "-c" + - "mysqladmin ping -u root -p${MYSQL_ROOT_PASSWORD}" + periodSeconds: 15 + failureThreshold: 60 + volumeMounts: + - name: katib-mysql + mountPath: /var/lib/mysql + volumes: + - name: katib-mysql + persistentVolumeClaim: + claimName: katib-mysql diff --git a/kubeflow/apps/katib/upstream/components/mysql/pvc.yaml b/kubeflow/apps/katib/upstream/components/mysql/pvc.yaml new file mode 100644 index 0000000..9249d8c --- /dev/null +++ b/kubeflow/apps/katib/upstream/components/mysql/pvc.yaml @@ -0,0 +1,12 @@ +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: katib-mysql + namespace: kubeflow +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi diff --git a/kubeflow/apps/katib/upstream/components/mysql/secret.yaml b/kubeflow/apps/katib/upstream/components/mysql/secret.yaml new file mode 100644 index 0000000..c0e32fa --- /dev/null +++ b/kubeflow/apps/katib/upstream/components/mysql/secret.yaml @@ -0,0 +1,8 @@ +--- +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: katib-mysql-secrets +data: + MYSQL_ROOT_PASSWORD: dGVzdA== # "test" diff --git a/kubeflow/apps/katib/upstream/components/mysql/service.yaml b/kubeflow/apps/katib/upstream/components/mysql/service.yaml new file mode 100644 index 0000000..234d87f --- /dev/null +++ b/kubeflow/apps/katib/upstream/components/mysql/service.yaml @@ -0,0 +1,16 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: katib-mysql + namespace: kubeflow + labels: + katib.kubeflow.org/component: mysql +spec: + type: ClusterIP + ports: + - port: 3306 + protocol: TCP + name: dbapi + selector: + katib.kubeflow.org/component: mysql diff --git a/kubeflow/apps/katib/upstream/components/namespace/kustomization.yaml b/kubeflow/apps/katib/upstream/components/namespace/kustomization.yaml new file mode 100644 index 0000000..ba51550 --- /dev/null +++ b/kubeflow/apps/katib/upstream/components/namespace/kustomization.yaml @@ -0,0 +1,7 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: kubeflow +resources: + # Namespace. + - namespace.yaml diff --git a/kubeflow/apps/katib/upstream/components/namespace/namespace.yaml b/kubeflow/apps/katib/upstream/components/namespace/namespace.yaml new file mode 100644 index 0000000..443752f --- /dev/null +++ b/kubeflow/apps/katib/upstream/components/namespace/namespace.yaml @@ -0,0 +1,7 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: kubeflow + labels: + katib.kubeflow.org/metrics-collector-injection: enabled diff --git a/kubeflow/apps/katib/upstream/components/postgres/kustomization.yaml b/kubeflow/apps/katib/upstream/components/postgres/kustomization.yaml new file mode 100644 index 0000000..0d18841 --- /dev/null +++ b/kubeflow/apps/katib/upstream/components/postgres/kustomization.yaml @@ -0,0 +1,9 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - postgres.yaml + - pvc.yaml + - secret.yaml + - service.yaml diff --git a/kubeflow/apps/katib/upstream/components/postgres/postgres.yaml b/kubeflow/apps/katib/upstream/components/postgres/postgres.yaml new file mode 100644 index 0000000..f4d243f --- /dev/null +++ b/kubeflow/apps/katib/upstream/components/postgres/postgres.yaml @@ -0,0 +1,42 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: katib-postgres + namespace: kubeflow + labels: + katib.kubeflow.org/component: postgres +spec: + replicas: 1 + selector: + matchLabels: + katib.kubeflow.org/component: postgres + strategy: + type: Recreate + template: + metadata: + labels: + katib.kubeflow.org/component: postgres + sidecar.istio.io/inject: "false" + annotations: + spec: + containers: + - name: katib-postgres + image: postgres:14.5-alpine + envFrom: + - secretRef: + name: katib-postgres-secrets + env: + - name: PGDATA + value: /var/lib/postgresql/data/pgdata + ports: + - name: postgres + containerPort: 5432 + protocol: TCP + volumeMounts: + - name: katib-postgres + mountPath: /var/lib/postgresql/data + volumes: + - name: katib-postgres + persistentVolumeClaim: + claimName: katib-postgres diff --git a/kubeflow/apps/katib/upstream/components/postgres/pvc.yaml b/kubeflow/apps/katib/upstream/components/postgres/pvc.yaml new file mode 100644 index 0000000..d3e45a7 --- /dev/null +++ b/kubeflow/apps/katib/upstream/components/postgres/pvc.yaml @@ -0,0 +1,12 @@ +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: katib-postgres + namespace: kubeflow +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 3Gi diff --git a/kubeflow/apps/katib/upstream/components/postgres/secret.yaml b/kubeflow/apps/katib/upstream/components/postgres/secret.yaml new file mode 100644 index 0000000..184df5a --- /dev/null +++ b/kubeflow/apps/katib/upstream/components/postgres/secret.yaml @@ -0,0 +1,10 @@ +--- +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: katib-postgres-secrets +data: + POSTGRES_USER: a2F0aWI= # katib + POSTGRES_PASSWORD: a2F0aWI= # katib + POSTGRES_DB: a2F0aWI= # katib diff --git a/kubeflow/apps/katib/upstream/components/postgres/service.yaml b/kubeflow/apps/katib/upstream/components/postgres/service.yaml new file mode 100644 index 0000000..b95d5fc --- /dev/null +++ b/kubeflow/apps/katib/upstream/components/postgres/service.yaml @@ -0,0 +1,16 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: katib-postgres + namespace: kubeflow + labels: + katib.kubeflow.org/component: postgres +spec: + type: ClusterIP + ports: + - port: 5432 + protocol: TCP + name: dbapi + selector: + katib.kubeflow.org/component: postgres diff --git a/kubeflow/apps/katib/upstream/components/ui/kustomization.yaml b/kubeflow/apps/katib/upstream/components/ui/kustomization.yaml new file mode 100644 index 0000000..2682158 --- /dev/null +++ b/kubeflow/apps/katib/upstream/components/ui/kustomization.yaml @@ -0,0 +1,8 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - rbac.yaml + - service.yaml + - ui.yaml diff --git a/kubeflow/apps/katib/upstream/components/ui/rbac.yaml b/kubeflow/apps/katib/upstream/components/ui/rbac.yaml new file mode 100644 index 0000000..85798dc --- /dev/null +++ b/kubeflow/apps/katib/upstream/components/ui/rbac.yaml @@ -0,0 +1,52 @@ +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: katib-ui +rules: + - apiGroups: + - "" + resources: + - configmaps + - namespaces + verbs: + - "*" + - apiGroups: + - kubeflow.org + resources: + - experiments + - trials + - suggestions + verbs: + - "*" + - apiGroups: + - "" + resources: + - pods + verbs: + - list + - apiGroups: + - "" + resources: + - pods/log + verbs: + - get +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: katib-ui + namespace: kubeflow +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: katib-ui +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: katib-ui +subjects: + - kind: ServiceAccount + name: katib-ui + namespace: kubeflow diff --git a/kubeflow/apps/katib/upstream/components/ui/service.yaml b/kubeflow/apps/katib/upstream/components/ui/service.yaml new file mode 100644 index 0000000..387eca3 --- /dev/null +++ b/kubeflow/apps/katib/upstream/components/ui/service.yaml @@ -0,0 +1,17 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: katib-ui + namespace: kubeflow + labels: + katib.kubeflow.org/component: ui +spec: + type: ClusterIP + ports: + - port: 80 + protocol: TCP + name: ui + targetPort: 8080 + selector: + katib.kubeflow.org/component: ui diff --git a/kubeflow/apps/katib/upstream/components/ui/ui.yaml b/kubeflow/apps/katib/upstream/components/ui/ui.yaml new file mode 100644 index 0000000..cdf00ae --- /dev/null +++ b/kubeflow/apps/katib/upstream/components/ui/ui.yaml @@ -0,0 +1,35 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: katib-ui + namespace: kubeflow + labels: + katib.kubeflow.org/component: ui +spec: + replicas: 1 + selector: + matchLabels: + katib.kubeflow.org/component: ui + template: + metadata: + labels: + katib.kubeflow.org/component: ui + sidecar.istio.io/inject: "false" + spec: + containers: + - name: katib-ui + image: ghcr.io/kubeflow/katib/katib-ui + command: + - "./katib-ui" + args: + - "--port=8080" + env: + - name: KATIB_CORE_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + ports: + - name: ui + containerPort: 8080 + serviceAccountName: katib-ui diff --git a/kubeflow/apps/katib/upstream/components/webhook/kustomization.yaml b/kubeflow/apps/katib/upstream/components/webhook/kustomization.yaml new file mode 100644 index 0000000..36d137d --- /dev/null +++ b/kubeflow/apps/katib/upstream/components/webhook/kustomization.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - webhooks.yaml diff --git a/kubeflow/apps/katib/upstream/components/webhook/webhooks.yaml b/kubeflow/apps/katib/upstream/components/webhook/webhooks.yaml new file mode 100644 index 0000000..fb8d93b --- /dev/null +++ b/kubeflow/apps/katib/upstream/components/webhook/webhooks.yaml @@ -0,0 +1,74 @@ +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: katib.kubeflow.org +webhooks: + - name: validator.experiment.katib.kubeflow.org + sideEffects: None + admissionReviewVersions: + - v1 + clientConfig: + service: + name: katib-controller + namespace: kubeflow + path: /validate-experiment + rules: + - apiGroups: + - kubeflow.org + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - experiments +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: katib.kubeflow.org +webhooks: + - name: defaulter.experiment.katib.kubeflow.org + sideEffects: None + admissionReviewVersions: + - v1 + clientConfig: + service: + name: katib-controller + namespace: kubeflow + path: /mutate-experiment + rules: + - apiGroups: + - kubeflow.org + apiVersions: + - v1beta1 + operations: + - CREATE + - UPDATE + resources: + - experiments + - name: mutator.pod.katib.kubeflow.org + sideEffects: None + admissionReviewVersions: + - v1 + clientConfig: + service: + name: katib-controller + namespace: kubeflow + path: /mutate-pod + namespaceSelector: + matchLabels: + katib.kubeflow.org/metrics-collector-injection: enabled + matchConditions: + - name: 'exclude-katib-controller' + expression: 'request.userInfo.username != "system:serviceaccount:kubeflow:katib-controller"' + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + resources: + - pods diff --git a/kubeflow/apps/katib/upstream/installs/katib-cert-manager/certificate.yaml b/kubeflow/apps/katib/upstream/installs/katib-cert-manager/certificate.yaml new file mode 100644 index 0000000..cdd7b41 --- /dev/null +++ b/kubeflow/apps/katib/upstream/installs/katib-cert-manager/certificate.yaml @@ -0,0 +1,22 @@ +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: katib-webhook-cert +spec: + isCA: true + commonName: $(KATIB_SERVICE_NAME).$(KATIB_NAMESPACE).svc + dnsNames: + - $(KATIB_SERVICE_NAME).$(KATIB_NAMESPACE).svc + - $(KATIB_SERVICE_NAME).$(KATIB_NAMESPACE).svc.cluster.local + issuerRef: + kind: Issuer + name: katib-selfsigned-issuer + secretName: katib-webhook-cert +--- +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: katib-selfsigned-issuer +spec: + selfSigned: {} diff --git a/kubeflow/apps/katib/upstream/installs/katib-cert-manager/katib-config.yaml b/kubeflow/apps/katib/upstream/installs/katib-cert-manager/katib-config.yaml new file mode 100644 index 0000000..a97d288 --- /dev/null +++ b/kubeflow/apps/katib/upstream/installs/katib-cert-manager/katib-config.yaml @@ -0,0 +1,58 @@ +--- +apiVersion: config.kubeflow.org/v1beta1 +kind: KatibConfig +init: + controller: + webhookPort: 8443 + trialResources: + - Job.v1.batch + - TFJob.v1.kubeflow.org + - PyTorchJob.v1.kubeflow.org + - MPIJob.v1.kubeflow.org + - XGBoostJob.v1.kubeflow.org +runtime: + metricsCollectors: + - kind: StdOut + image: ghcr.io/kubeflow/katib/file-metrics-collector:v0.18.0 + - kind: File + image: ghcr.io/kubeflow/katib/file-metrics-collector:v0.18.0 + - kind: TensorFlowEvent + image: ghcr.io/kubeflow/katib/tfevent-metrics-collector:v0.18.0 + resources: + limits: + memory: 1Gi + suggestions: + - algorithmName: random + image: ghcr.io/kubeflow/katib/suggestion-hyperopt:v0.18.0 + - algorithmName: tpe + image: ghcr.io/kubeflow/katib/suggestion-hyperopt:v0.18.0 + - algorithmName: grid + image: ghcr.io/kubeflow/katib/suggestion-optuna:v0.18.0 + - algorithmName: hyperband + image: ghcr.io/kubeflow/katib/suggestion-hyperband:v0.18.0 + - algorithmName: bayesianoptimization + image: ghcr.io/kubeflow/katib/suggestion-skopt:v0.18.0 + - algorithmName: cmaes + image: ghcr.io/kubeflow/katib/suggestion-goptuna:v0.18.0 + - algorithmName: sobol + image: ghcr.io/kubeflow/katib/suggestion-goptuna:v0.18.0 + - algorithmName: multivariate-tpe + image: ghcr.io/kubeflow/katib/suggestion-optuna:v0.18.0 + - algorithmName: enas + image: ghcr.io/kubeflow/katib/suggestion-enas:v0.18.0 + resources: + limits: + memory: 400Mi + - algorithmName: darts + image: ghcr.io/kubeflow/katib/suggestion-darts:v0.18.0 + - algorithmName: pbt + image: ghcr.io/kubeflow/katib/suggestion-pbt:v0.18.0 + persistentVolumeClaimSpec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 5Gi + earlyStoppings: + - algorithmName: medianstop + image: ghcr.io/kubeflow/katib/earlystopping-medianstop:v0.18.0 diff --git a/kubeflow/apps/katib/upstream/installs/katib-cert-manager/kustomization.yaml b/kubeflow/apps/katib/upstream/installs/katib-cert-manager/kustomization.yaml new file mode 100644 index 0000000..d4296a1 --- /dev/null +++ b/kubeflow/apps/katib/upstream/installs/katib-cert-manager/kustomization.yaml @@ -0,0 +1,69 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: kubeflow +resources: + # Namespace. + - ../../components/namespace + # Katib controller. + - ../../components/controller/ + # Katib CRDs. + - ../../components/crd/ + # Katib DB manager. + - ../../components/db-manager/ + # Katib DB mysql. + - ../../components/mysql/ + # Katib UI. + - ../../components/ui/ + # Katib webhooks. + - ../../components/webhook/ + # Cert-manager certificate for webhooks + - certificate.yaml +images: + - name: ghcr.io/kubeflow/katib/katib-controller + newName: ghcr.io/kubeflow/katib/katib-controller + newTag: v0.18.0 + - name: ghcr.io/kubeflow/katib/katib-db-manager + newName: ghcr.io/kubeflow/katib/katib-db-manager + newTag: v0.18.0 + - name: ghcr.io/kubeflow/katib/katib-ui + newName: ghcr.io/kubeflow/katib/katib-ui + newTag: v0.18.0 + +patchesStrategicMerge: + - patches/katib-cert-injection.yaml + +vars: + - fieldref: + fieldPath: metadata.namespace + name: KATIB_NAMESPACE + objref: + apiVersion: v1 + kind: Service + name: katib-controller + - fieldref: + fieldPath: metadata.name + name: KATIB_SERVICE_NAME + objref: + apiVersion: v1 + kind: Service + name: katib-controller + - name: KATIB_CERT_NAME + objref: + kind: Certificate + group: cert-manager.io + version: v1 + name: katib-webhook-cert + fieldref: + fieldpath: metadata.name + +configurations: + - params.yaml + +configMapGenerator: + - name: katib-config + behavior: create + files: + - katib-config.yaml + options: + disableNameSuffixHash: true diff --git a/kubeflow/apps/katib/upstream/installs/katib-cert-manager/params.yaml b/kubeflow/apps/katib/upstream/installs/katib-cert-manager/params.yaml new file mode 100644 index 0000000..246d79a --- /dev/null +++ b/kubeflow/apps/katib/upstream/installs/katib-cert-manager/params.yaml @@ -0,0 +1,19 @@ +--- +varReference: + - path: spec/commonName + kind: Certificate + - path: spec/dnsNames + kind: Certificate + - path: spec/issuerRef/name + kind: Certificate + - path: metadata/annotations + kind: MutatingWebhookConfiguration + - path: metadata/annotations + kind: ValidatingWebhookConfiguration +nameReference: + - kind: Issuer + group: cert-manager.io + fieldSpecs: + - kind: Certificate + group: cert-manager.io + path: spec/issuerRef/name diff --git a/kubeflow/apps/katib/upstream/installs/katib-cert-manager/patches/katib-cert-injection.yaml b/kubeflow/apps/katib/upstream/installs/katib-cert-manager/patches/katib-cert-injection.yaml new file mode 100644 index 0000000..ec25919 --- /dev/null +++ b/kubeflow/apps/katib/upstream/installs/katib-cert-manager/patches/katib-cert-injection.yaml @@ -0,0 +1,14 @@ +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: katib.kubeflow.org + annotations: + cert-manager.io/inject-ca-from: $(KATIB_NAMESPACE)/$(KATIB_CERT_NAME) +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: katib.kubeflow.org + annotations: + cert-manager.io/inject-ca-from: $(KATIB_NAMESPACE)/$(KATIB_CERT_NAME) diff --git a/kubeflow/apps/katib/upstream/installs/katib-external-db/katib-config.yaml b/kubeflow/apps/katib/upstream/installs/katib-external-db/katib-config.yaml new file mode 100644 index 0000000..f4d5226 --- /dev/null +++ b/kubeflow/apps/katib/upstream/installs/katib-external-db/katib-config.yaml @@ -0,0 +1,60 @@ +--- +apiVersion: config.kubeflow.org/v1beta1 +kind: KatibConfig +init: + certGenerator: + enable: true + controller: + webhookPort: 8443 + trialResources: + - Job.v1.batch + - TFJob.v1.kubeflow.org + - PyTorchJob.v1.kubeflow.org + - MPIJob.v1.kubeflow.org + - XGBoostJob.v1.kubeflow.org +runtime: + metricsCollectors: + - kind: StdOut + image: ghcr.io/kubeflow/katib/file-metrics-collector:v0.18.0 + - kind: File + image: ghcr.io/kubeflow/katib/file-metrics-collector:v0.18.0 + - kind: TensorFlowEvent + image: ghcr.io/kubeflow/katib/tfevent-metrics-collector:v0.18.0 + resources: + limits: + memory: 1Gi + suggestions: + - algorithmName: random + image: ghcr.io/kubeflow/katib/suggestion-hyperopt:v0.18.0 + - algorithmName: tpe + image: ghcr.io/kubeflow/katib/suggestion-hyperopt:v0.18.0 + - algorithmName: grid + image: ghcr.io/kubeflow/katib/suggestion-optuna:v0.18.0 + - algorithmName: hyperband + image: ghcr.io/kubeflow/katib/suggestion-hyperband:v0.18.0 + - algorithmName: bayesianoptimization + image: ghcr.io/kubeflow/katib/suggestion-skopt:v0.18.0 + - algorithmName: cmaes + image: ghcr.io/kubeflow/katib/suggestion-goptuna:v0.18.0 + - algorithmName: sobol + image: ghcr.io/kubeflow/katib/suggestion-goptuna:v0.18.0 + - algorithmName: multivariate-tpe + image: ghcr.io/kubeflow/katib/suggestion-optuna:v0.18.0 + - algorithmName: enas + image: ghcr.io/kubeflow/katib/suggestion-enas:v0.18.0 + resources: + limits: + memory: 400Mi + - algorithmName: darts + image: ghcr.io/kubeflow/katib/suggestion-darts:v0.18.0 + - algorithmName: pbt + image: ghcr.io/kubeflow/katib/suggestion-pbt:v0.18.0 + persistentVolumeClaimSpec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 5Gi + earlyStoppings: + - algorithmName: medianstop + image: ghcr.io/kubeflow/katib/earlystopping-medianstop:v0.18.0 diff --git a/kubeflow/apps/katib/upstream/installs/katib-external-db/kustomization.yaml b/kubeflow/apps/katib/upstream/installs/katib-external-db/kustomization.yaml new file mode 100644 index 0000000..3e96671 --- /dev/null +++ b/kubeflow/apps/katib/upstream/installs/katib-external-db/kustomization.yaml @@ -0,0 +1,45 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: kubeflow +resources: + # Namespace. + - ../../components/namespace/ + # Katib controller. + - ../../components/controller/ + # Katib CRDs. + - ../../components/crd/ + # Katib DB manager. + - ../../components/db-manager/ + # Katib UI. + - ../../components/ui/ + # Katib webhooks. + - ../../components/webhook/ +images: + - name: ghcr.io/kubeflow/katib/katib-controller + newName: ghcr.io/kubeflow/katib/katib-controller + newTag: v0.18.0 + - name: ghcr.io/kubeflow/katib/katib-db-manager + newName: ghcr.io/kubeflow/katib/katib-db-manager + newTag: v0.18.0 + - name: ghcr.io/kubeflow/katib/katib-ui + newName: ghcr.io/kubeflow/katib/katib-ui + newTag: v0.18.0 +patchesStrategicMerge: + - patches/db-manager.yaml +# Modify katib-mysql-secrets with parameters for the DB. +secretGenerator: + - name: katib-mysql-secrets + envs: + - secrets.env + # Secret for webhooks certs. + - name: katib-webhook-cert + options: + disableNameSuffixHash: true +configMapGenerator: + - name: katib-config + behavior: create + files: + - katib-config.yaml + options: + disableNameSuffixHash: true diff --git a/kubeflow/apps/katib/upstream/installs/katib-external-db/patches/db-manager.yaml b/kubeflow/apps/katib/upstream/installs/katib-external-db/patches/db-manager.yaml new file mode 100644 index 0000000..54da0d4 --- /dev/null +++ b/kubeflow/apps/katib/upstream/installs/katib-external-db/patches/db-manager.yaml @@ -0,0 +1,39 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: katib-db-manager + namespace: kubeflow +spec: + template: + spec: + containers: + - name: katib-db-manager + env: + - name: DB_NAME + value: mysql + - name: DB_USER + valueFrom: + secretKeyRef: + name: katib-mysql-secrets + key: DB_USER + - name: DB_PASSWORD + valueFrom: + secretKeyRef: + name: katib-mysql-secrets + key: DB_PASSWORD + - name: KATIB_MYSQL_DB_DATABASE + valueFrom: + secretKeyRef: + name: katib-mysql-secrets + key: KATIB_MYSQL_DB_DATABASE + - name: KATIB_MYSQL_DB_HOST + valueFrom: + secretKeyRef: + name: katib-mysql-secrets + key: KATIB_MYSQL_DB_HOST + - name: KATIB_MYSQL_DB_PORT + valueFrom: + secretKeyRef: + name: katib-mysql-secrets + key: KATIB_MYSQL_DB_PORT diff --git a/kubeflow/apps/katib/upstream/installs/katib-external-db/secrets.env b/kubeflow/apps/katib/upstream/installs/katib-external-db/secrets.env new file mode 100644 index 0000000..d9b31a9 --- /dev/null +++ b/kubeflow/apps/katib/upstream/installs/katib-external-db/secrets.env @@ -0,0 +1,5 @@ +KATIB_MYSQL_DB_DATABASE= +KATIB_MYSQL_DB_HOST= +KATIB_MYSQL_DB_PORT= +DB_USER= +DB_PASSWORD= diff --git a/kubeflow/apps/katib/upstream/installs/katib-leader-election/katib-config.yaml b/kubeflow/apps/katib/upstream/installs/katib-leader-election/katib-config.yaml new file mode 100644 index 0000000..5e4bcfa --- /dev/null +++ b/kubeflow/apps/katib/upstream/installs/katib-leader-election/katib-config.yaml @@ -0,0 +1,61 @@ +--- +apiVersion: config.kubeflow.org/v1beta1 +kind: KatibConfig +init: + certGenerator: + enable: true + controller: + webhookPort: 8443 + enableLeaderElection: true + trialResources: + - Job.v1.batch + - TFJob.v1.kubeflow.org + - PyTorchJob.v1.kubeflow.org + - MPIJob.v1.kubeflow.org + - XGBoostJob.v1.kubeflow.org +runtime: + metricsCollectors: + - kind: StdOut + image: ghcr.io/kubeflow/katib/file-metrics-collector:v0.18.0 + - kind: File + image: ghcr.io/kubeflow/katib/file-metrics-collector:v0.18.0 + - kind: TensorFlowEvent + image: ghcr.io/kubeflow/katib/tfevent-metrics-collector:v0.18.0 + resources: + limits: + memory: 1Gi + suggestions: + - algorithmName: random + image: ghcr.io/kubeflow/katib/suggestion-hyperopt:v0.18.0 + - algorithmName: tpe + image: ghcr.io/kubeflow/katib/suggestion-hyperopt:v0.18.0 + - algorithmName: grid + image: ghcr.io/kubeflow/katib/suggestion-optuna:v0.18.0 + - algorithmName: hyperband + image: ghcr.io/kubeflow/katib/suggestion-hyperband:v0.18.0 + - algorithmName: bayesianoptimization + image: ghcr.io/kubeflow/katib/suggestion-skopt:v0.18.0 + - algorithmName: cmaes + image: ghcr.io/kubeflow/katib/suggestion-goptuna:v0.18.0 + - algorithmName: sobol + image: ghcr.io/kubeflow/katib/suggestion-goptuna:v0.18.0 + - algorithmName: multivariate-tpe + image: ghcr.io/kubeflow/katib/suggestion-optuna:v0.18.0 + - algorithmName: enas + image: ghcr.io/kubeflow/katib/suggestion-enas:v0.18.0 + resources: + limits: + memory: 400Mi + - algorithmName: darts + image: ghcr.io/kubeflow/katib/suggestion-darts:v0.18.0 + - algorithmName: pbt + image: ghcr.io/kubeflow/katib/suggestion-pbt:v0.18.0 + persistentVolumeClaimSpec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 5Gi + earlyStoppings: + - algorithmName: medianstop + image: ghcr.io/kubeflow/katib/earlystopping-medianstop:v0.18.0 diff --git a/kubeflow/apps/katib/upstream/installs/katib-leader-election/kustomization.yaml b/kubeflow/apps/katib/upstream/installs/katib-leader-election/kustomization.yaml new file mode 100644 index 0000000..64b8a15 --- /dev/null +++ b/kubeflow/apps/katib/upstream/installs/katib-leader-election/kustomization.yaml @@ -0,0 +1,18 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: kubeflow +resources: + - ../katib-standalone + # rbac for leader-election + - leader-election-rbac.yaml +replicas: + - name: katib-controller + count: 2 +configMapGenerator: + - name: katib-config + behavior: replace + files: + - katib-config.yaml + options: + disableNameSuffixHash: true diff --git a/kubeflow/apps/katib/upstream/installs/katib-leader-election/leader-election-rbac.yaml b/kubeflow/apps/katib/upstream/installs/katib-leader-election/leader-election-rbac.yaml new file mode 100644 index 0000000..645187b --- /dev/null +++ b/kubeflow/apps/katib/upstream/installs/katib-leader-election/leader-election-rbac.yaml @@ -0,0 +1,27 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: leader-election + namespace: kubeflow +rules: + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - "*" +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: leader-election + namespace: kubeflow +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: leader-election +subjects: + - kind: ServiceAccount + name: katib-controller + namespace: kubeflow diff --git a/kubeflow/apps/katib/upstream/installs/katib-openshift/katib-config.yaml b/kubeflow/apps/katib/upstream/installs/katib-openshift/katib-config.yaml new file mode 100644 index 0000000..a97d288 --- /dev/null +++ b/kubeflow/apps/katib/upstream/installs/katib-openshift/katib-config.yaml @@ -0,0 +1,58 @@ +--- +apiVersion: config.kubeflow.org/v1beta1 +kind: KatibConfig +init: + controller: + webhookPort: 8443 + trialResources: + - Job.v1.batch + - TFJob.v1.kubeflow.org + - PyTorchJob.v1.kubeflow.org + - MPIJob.v1.kubeflow.org + - XGBoostJob.v1.kubeflow.org +runtime: + metricsCollectors: + - kind: StdOut + image: ghcr.io/kubeflow/katib/file-metrics-collector:v0.18.0 + - kind: File + image: ghcr.io/kubeflow/katib/file-metrics-collector:v0.18.0 + - kind: TensorFlowEvent + image: ghcr.io/kubeflow/katib/tfevent-metrics-collector:v0.18.0 + resources: + limits: + memory: 1Gi + suggestions: + - algorithmName: random + image: ghcr.io/kubeflow/katib/suggestion-hyperopt:v0.18.0 + - algorithmName: tpe + image: ghcr.io/kubeflow/katib/suggestion-hyperopt:v0.18.0 + - algorithmName: grid + image: ghcr.io/kubeflow/katib/suggestion-optuna:v0.18.0 + - algorithmName: hyperband + image: ghcr.io/kubeflow/katib/suggestion-hyperband:v0.18.0 + - algorithmName: bayesianoptimization + image: ghcr.io/kubeflow/katib/suggestion-skopt:v0.18.0 + - algorithmName: cmaes + image: ghcr.io/kubeflow/katib/suggestion-goptuna:v0.18.0 + - algorithmName: sobol + image: ghcr.io/kubeflow/katib/suggestion-goptuna:v0.18.0 + - algorithmName: multivariate-tpe + image: ghcr.io/kubeflow/katib/suggestion-optuna:v0.18.0 + - algorithmName: enas + image: ghcr.io/kubeflow/katib/suggestion-enas:v0.18.0 + resources: + limits: + memory: 400Mi + - algorithmName: darts + image: ghcr.io/kubeflow/katib/suggestion-darts:v0.18.0 + - algorithmName: pbt + image: ghcr.io/kubeflow/katib/suggestion-pbt:v0.18.0 + persistentVolumeClaimSpec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 5Gi + earlyStoppings: + - algorithmName: medianstop + image: ghcr.io/kubeflow/katib/earlystopping-medianstop:v0.18.0 diff --git a/kubeflow/apps/katib/upstream/installs/katib-openshift/kustomization.yaml b/kubeflow/apps/katib/upstream/installs/katib-openshift/kustomization.yaml new file mode 100644 index 0000000..f384b55 --- /dev/null +++ b/kubeflow/apps/katib/upstream/installs/katib-openshift/kustomization.yaml @@ -0,0 +1,72 @@ +# This kustomization copies the `katib-standalone` one with following exclusions: +# - No Job is spawned to generate TLS key for `katib-controller` Service +# - Instead, the Service and WebhookConfigurations linked to it are annotated +# for OpenShift service controller to handle TLS certification. +# +# Requires OpenShift version: 4.4+ +# +# To achieve this, run: +# +# `kustomize build ./manifests/v1beta1/installs/katib-openshift | oc apply -f - -l type!=local` +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: kubeflow +resources: + # Namespace. + - ../../components/namespace/ + # Katib controller. + - ../../components/controller/ + # Katib CRDs. + - ../../components/crd/ + # Katib DB manager. + - ../../components/db-manager/ + # Katib DB mysql. + - ../../components/mysql/ + # Katib UI. + - ../../components/ui/ + # Katib webhooks. + - ../../components/webhook/ +images: + - name: ghcr.io/kubeflow/katib/katib-controller + newName: ghcr.io/kubeflow/katib/katib-controller + newTag: v0.18.0 + - name: ghcr.io/kubeflow/katib/katib-db-manager + newName: ghcr.io/kubeflow/katib/katib-db-manager + newTag: v0.18.0 + - name: ghcr.io/kubeflow/katib/katib-ui + newName: ghcr.io/kubeflow/katib/katib-ui + newTag: v0.18.0 + +patchesJson6902: + # Annotate Service to delegate TLS-secret generation to OpenShift service controller + # https://docs.openshift.com/container-platform/4.6/security/certificates/service-serving-certificate.html#add-service-certificate_service-serving-certificate + - target: + group: "" + version: v1 + kind: Service + name: katib-controller + namespace: kubeflow + path: patches/service-serving-cert.yaml + # Annotate WebhookConfigurations to delegate `caBundle` population to OpenShift service controller + # https://docs.openshift.com/container-platform/4.6/security/certificates/service-serving-certificate.html#add-service-certificate-mutating-webhook_service-serving-certificate + - target: + group: admissionregistration.k8s.io + version: v1 + kind: ValidatingWebhookConfiguration + name: katib.kubeflow.org + path: patches/webhook-inject-cabundle.yaml + - target: + group: admissionregistration.k8s.io + version: v1 + kind: MutatingWebhookConfiguration + name: katib.kubeflow.org + path: patches/webhook-inject-cabundle.yaml + +configMapGenerator: + - name: katib-config + behavior: create + files: + - katib-config.yaml + options: + disableNameSuffixHash: true diff --git a/kubeflow/apps/katib/upstream/installs/katib-openshift/patches/service-serving-cert.yaml b/kubeflow/apps/katib/upstream/installs/katib-openshift/patches/service-serving-cert.yaml new file mode 100644 index 0000000..2b6c88b --- /dev/null +++ b/kubeflow/apps/katib/upstream/installs/katib-openshift/patches/service-serving-cert.yaml @@ -0,0 +1,4 @@ +--- +- op: "add" + path: "/metadata/annotations/service.beta.openshift.io~1serving-cert-secret-name" + value: katib-webhook-cert diff --git a/kubeflow/apps/katib/upstream/installs/katib-openshift/patches/webhook-inject-cabundle.yaml b/kubeflow/apps/katib/upstream/installs/katib-openshift/patches/webhook-inject-cabundle.yaml new file mode 100644 index 0000000..8f3833a --- /dev/null +++ b/kubeflow/apps/katib/upstream/installs/katib-openshift/patches/webhook-inject-cabundle.yaml @@ -0,0 +1,5 @@ +--- +- op: "add" + path: "/metadata/annotations" + value: + service.beta.openshift.io/inject-cabundle: "true" diff --git a/kubeflow/apps/katib/upstream/installs/katib-standalone-postgres/katib-config.yaml b/kubeflow/apps/katib/upstream/installs/katib-standalone-postgres/katib-config.yaml new file mode 100644 index 0000000..f4d5226 --- /dev/null +++ b/kubeflow/apps/katib/upstream/installs/katib-standalone-postgres/katib-config.yaml @@ -0,0 +1,60 @@ +--- +apiVersion: config.kubeflow.org/v1beta1 +kind: KatibConfig +init: + certGenerator: + enable: true + controller: + webhookPort: 8443 + trialResources: + - Job.v1.batch + - TFJob.v1.kubeflow.org + - PyTorchJob.v1.kubeflow.org + - MPIJob.v1.kubeflow.org + - XGBoostJob.v1.kubeflow.org +runtime: + metricsCollectors: + - kind: StdOut + image: ghcr.io/kubeflow/katib/file-metrics-collector:v0.18.0 + - kind: File + image: ghcr.io/kubeflow/katib/file-metrics-collector:v0.18.0 + - kind: TensorFlowEvent + image: ghcr.io/kubeflow/katib/tfevent-metrics-collector:v0.18.0 + resources: + limits: + memory: 1Gi + suggestions: + - algorithmName: random + image: ghcr.io/kubeflow/katib/suggestion-hyperopt:v0.18.0 + - algorithmName: tpe + image: ghcr.io/kubeflow/katib/suggestion-hyperopt:v0.18.0 + - algorithmName: grid + image: ghcr.io/kubeflow/katib/suggestion-optuna:v0.18.0 + - algorithmName: hyperband + image: ghcr.io/kubeflow/katib/suggestion-hyperband:v0.18.0 + - algorithmName: bayesianoptimization + image: ghcr.io/kubeflow/katib/suggestion-skopt:v0.18.0 + - algorithmName: cmaes + image: ghcr.io/kubeflow/katib/suggestion-goptuna:v0.18.0 + - algorithmName: sobol + image: ghcr.io/kubeflow/katib/suggestion-goptuna:v0.18.0 + - algorithmName: multivariate-tpe + image: ghcr.io/kubeflow/katib/suggestion-optuna:v0.18.0 + - algorithmName: enas + image: ghcr.io/kubeflow/katib/suggestion-enas:v0.18.0 + resources: + limits: + memory: 400Mi + - algorithmName: darts + image: ghcr.io/kubeflow/katib/suggestion-darts:v0.18.0 + - algorithmName: pbt + image: ghcr.io/kubeflow/katib/suggestion-pbt:v0.18.0 + persistentVolumeClaimSpec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 5Gi + earlyStoppings: + - algorithmName: medianstop + image: ghcr.io/kubeflow/katib/earlystopping-medianstop:v0.18.0 diff --git a/kubeflow/apps/katib/upstream/installs/katib-standalone-postgres/kustomization.yaml b/kubeflow/apps/katib/upstream/installs/katib-standalone-postgres/kustomization.yaml new file mode 100644 index 0000000..7e7a105 --- /dev/null +++ b/kubeflow/apps/katib/upstream/installs/katib-standalone-postgres/kustomization.yaml @@ -0,0 +1,48 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: kubeflow +resources: + # Namespace. + - ../../components/namespace/ + # Katib controller. + - ../../components/controller/ + # Katib CRDs. + - ../../components/crd/ + # Katib DB manager. + - ../../components/db-manager/ + # Katib DB postgres. + - ../../components/postgres/ + # Katib UI. + - ../../components/ui/ + # Katib webhooks. + - ../../components/webhook/ +images: + - name: ghcr.io/kubeflow/katib/katib-controller + newName: ghcr.io/kubeflow/katib/katib-controller + newTag: v0.18.0 + - name: ghcr.io/kubeflow/katib/katib-db-manager + newName: ghcr.io/kubeflow/katib/katib-db-manager + newTag: v0.18.0 + - name: ghcr.io/kubeflow/katib/katib-ui + newName: ghcr.io/kubeflow/katib/katib-ui + newTag: v0.18.0 +patchesJson6902: + - target: + group: apps + version: v1 + kind: Deployment + name: katib-db-manager + path: ./patches/db-manager.yaml +configMapGenerator: + - name: katib-config + behavior: create + files: + - katib-config.yaml + options: + disableNameSuffixHash: true +# Secret for webhooks certs. +secretGenerator: + - name: katib-webhook-cert + options: + disableNameSuffixHash: true diff --git a/kubeflow/apps/katib/upstream/installs/katib-standalone-postgres/patches/db-manager.yaml b/kubeflow/apps/katib/upstream/installs/katib-standalone-postgres/patches/db-manager.yaml new file mode 100644 index 0000000..1077f91 --- /dev/null +++ b/kubeflow/apps/katib/upstream/installs/katib-standalone-postgres/patches/db-manager.yaml @@ -0,0 +1,8 @@ +--- +- op: replace + path: /spec/template/spec/containers/0/env + value: + - name: DB_NAME + value: "postgres" + - name: DB_PASSWORD + value: "katib" diff --git a/kubeflow/apps/katib/upstream/installs/katib-standalone/katib-config.yaml b/kubeflow/apps/katib/upstream/installs/katib-standalone/katib-config.yaml new file mode 100644 index 0000000..da9736f --- /dev/null +++ b/kubeflow/apps/katib/upstream/installs/katib-standalone/katib-config.yaml @@ -0,0 +1,59 @@ +apiVersion: config.kubeflow.org/v1beta1 +kind: KatibConfig +init: + certGenerator: + enable: true + controller: + webhookPort: 8443 + trialResources: + - Job.v1.batch + - TFJob.v1.kubeflow.org + - PyTorchJob.v1.kubeflow.org + - MPIJob.v1.kubeflow.org + - XGBoostJob.v1.kubeflow.org +runtime: + metricsCollectors: + - kind: StdOut + image: ghcr.io/kubeflow/katib/file-metrics-collector:v0.18.0 + - kind: File + image: ghcr.io/kubeflow/katib/file-metrics-collector:v0.18.0 + - kind: TensorFlowEvent + image: ghcr.io/kubeflow/katib/tfevent-metrics-collector:v0.18.0 + resources: + limits: + memory: 1Gi + suggestions: + - algorithmName: random + image: ghcr.io/kubeflow/katib/suggestion-hyperopt:v0.18.0 + - algorithmName: tpe + image: ghcr.io/kubeflow/katib/suggestion-hyperopt:v0.18.0 + - algorithmName: grid + image: ghcr.io/kubeflow/katib/suggestion-optuna:v0.18.0 + - algorithmName: hyperband + image: ghcr.io/kubeflow/katib/suggestion-hyperband:v0.18.0 + - algorithmName: bayesianoptimization + image: ghcr.io/kubeflow/katib/suggestion-skopt:v0.18.0 + - algorithmName: cmaes + image: ghcr.io/kubeflow/katib/suggestion-goptuna:v0.18.0 + - algorithmName: sobol + image: ghcr.io/kubeflow/katib/suggestion-goptuna:v0.18.0 + - algorithmName: multivariate-tpe + image: ghcr.io/kubeflow/katib/suggestion-optuna:v0.18.0 + - algorithmName: enas + image: ghcr.io/kubeflow/katib/suggestion-enas:v0.18.0 + resources: + limits: + memory: 400Mi + - algorithmName: darts + image: ghcr.io/kubeflow/katib/suggestion-darts:v0.18.0 + - algorithmName: pbt + image: ghcr.io/kubeflow/katib/suggestion-pbt:v0.18.0 + persistentVolumeClaimSpec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 5Gi + earlyStoppings: + - algorithmName: medianstop + image: ghcr.io/kubeflow/katib/earlystopping-medianstop:v0.18.0 diff --git a/kubeflow/apps/katib/upstream/installs/katib-standalone/kustomization.yaml b/kubeflow/apps/katib/upstream/installs/katib-standalone/kustomization.yaml new file mode 100644 index 0000000..9882be6 --- /dev/null +++ b/kubeflow/apps/katib/upstream/installs/katib-standalone/kustomization.yaml @@ -0,0 +1,41 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: kubeflow +resources: + # Namespace. + - ../../components/namespace/ + # Katib controller. + - ../../components/controller/ + # Katib CRDs. + - ../../components/crd/ + # Katib DB manager. + - ../../components/db-manager/ + # Katib DB mysql. + - ../../components/mysql/ + # Katib UI. + - ../../components/ui/ + # Katib webhooks. + - ../../components/webhook/ +images: + - name: ghcr.io/kubeflow/katib/katib-controller + newName: ghcr.io/kubeflow/katib/katib-controller + newTag: v0.18.0 + - name: ghcr.io/kubeflow/katib/katib-db-manager + newName: ghcr.io/kubeflow/katib/katib-db-manager + newTag: v0.18.0 + - name: ghcr.io/kubeflow/katib/katib-ui + newName: ghcr.io/kubeflow/katib/katib-ui + newTag: v0.18.0 +configMapGenerator: + - name: katib-config + behavior: create + files: + - katib-config.yaml + options: + disableNameSuffixHash: true +# Secret for webhooks certs. +secretGenerator: + - name: katib-webhook-cert + options: + disableNameSuffixHash: true diff --git a/kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/istio-authorizationpolicy.yaml b/kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/istio-authorizationpolicy.yaml new file mode 100644 index 0000000..dd3dbea --- /dev/null +++ b/kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/istio-authorizationpolicy.yaml @@ -0,0 +1,15 @@ +--- +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: katib-ui + namespace: kubeflow +spec: + action: ALLOW + selector: + matchLabels: + katib.kubeflow.org/component: ui + rules: + - from: + - source: + principals: ["cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account"] diff --git a/kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/kubeflow-katib-roles.yaml b/kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/kubeflow-katib-roles.yaml new file mode 100644 index 0000000..57b0fba --- /dev/null +++ b/kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/kubeflow-katib-roles.yaml @@ -0,0 +1,66 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: kubeflow-katib-admin + labels: + rbac.authorization.kubeflow.org/aggregate-to-kubeflow-admin: "true" +aggregationRule: + clusterRoleSelectors: + - matchLabels: + rbac.authorization.kubeflow.org/aggregate-to-kubeflow-katib-admin: "true" +rules: [] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: kubeflow-katib-edit + labels: + rbac.authorization.kubeflow.org/aggregate-to-kubeflow-edit: "true" + rbac.authorization.kubeflow.org/aggregate-to-kubeflow-katib-admin: "true" +rules: + - apiGroups: + - kubeflow.org + resources: + - experiments + - trials + - suggestions + verbs: + - get + - list + - watch + - create + - delete + - deletecollection + - patch + - update + - apiGroups: + - "" + resources: + - pods + verbs: + - list + - apiGroups: + - "" + resources: + - pods/log + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: kubeflow-katib-view + labels: + rbac.authorization.kubeflow.org/aggregate-to-kubeflow-view: "true" +rules: + - apiGroups: + - kubeflow.org + resources: + - experiments + - trials + - suggestions + verbs: + - get + - list + - watch diff --git a/kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/kustomization.yaml b/kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/kustomization.yaml new file mode 100644 index 0000000..a1ab26a --- /dev/null +++ b/kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/kustomization.yaml @@ -0,0 +1,56 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: kubeflow +resources: + - ../katib-cert-manager + # Kubeflow Katib components. + - kubeflow-katib-roles.yaml + - ui-virtual-service.yaml + - istio-authorizationpolicy.yaml +images: + - name: ghcr.io/kubeflow/katib/katib-controller + newName: ghcr.io/kubeflow/katib/katib-controller + newTag: v0.18.0 + - name: ghcr.io/kubeflow/katib/katib-db-manager + newName: ghcr.io/kubeflow/katib/katib-db-manager + newTag: v0.18.0 + - name: ghcr.io/kubeflow/katib/katib-ui + newName: ghcr.io/kubeflow/katib/katib-ui + newTag: v0.18.0 + +patchesStrategicMerge: + - patches/remove-namespace.yaml + +patches: + # Extend RBAC permission list of katib-ui so it can + # create SubjectAccessReview resources. + - target: + kind: ClusterRole + name: katib-ui + group: rbac.authorization.k8s.io + version: v1 + path: patches/ui-rbac.yaml + # Enable RBAC authz checks in UI's backend. + - target: + version: v1 + kind: Deployment + name: katib-ui + path: patches/enable-ui-authz-checks.yaml + # Allow istio sidecar injection in katib-UI Pod. + - target: + kind: Deployment + name: katib-ui + path: patches/istio-sidecar-injection.yaml + +vars: + - fieldref: + fieldPath: metadata.namespace + name: KATIB_UI_NAMESPACE + objref: + apiVersion: apps/v1 + kind: Deployment + name: katib-ui + +configurations: + - params.yaml diff --git a/kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/params.yaml b/kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/params.yaml new file mode 100644 index 0000000..360f60f --- /dev/null +++ b/kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/params.yaml @@ -0,0 +1,4 @@ +--- +varReference: + - path: spec/http/route/destination/host + kind: VirtualService diff --git a/kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/patches/enable-ui-authz-checks.yaml b/kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/patches/enable-ui-authz-checks.yaml new file mode 100644 index 0000000..70fa139 --- /dev/null +++ b/kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/patches/enable-ui-authz-checks.yaml @@ -0,0 +1,6 @@ +--- +- op: add + path: /spec/template/spec/containers/0/env/- + value: + name: APP_DISABLE_AUTH + value: "false" diff --git a/kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/patches/istio-sidecar-injection.yaml b/kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/patches/istio-sidecar-injection.yaml new file mode 100644 index 0000000..3164977 --- /dev/null +++ b/kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/patches/istio-sidecar-injection.yaml @@ -0,0 +1,10 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: "katib-ui" +spec: + template: + metadata: + labels: + sidecar.istio.io/inject: "true" diff --git a/kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/patches/remove-namespace.yaml b/kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/patches/remove-namespace.yaml new file mode 100644 index 0000000..9ea2958 --- /dev/null +++ b/kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/patches/remove-namespace.yaml @@ -0,0 +1,6 @@ +--- +$patch: delete +apiVersion: v1 +kind: Namespace +metadata: + name: kubeflow diff --git a/kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/patches/ui-rbac.yaml b/kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/patches/ui-rbac.yaml new file mode 100644 index 0000000..9ef1378 --- /dev/null +++ b/kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/patches/ui-rbac.yaml @@ -0,0 +1,7 @@ +--- +- op: add + path: /rules/- + value: + apiGroups: [authorization.k8s.io] + resources: [subjectaccessreviews] + verbs: [create] diff --git a/kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/ui-virtual-service.yaml b/kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/ui-virtual-service.yaml new file mode 100644 index 0000000..4ed0f3d --- /dev/null +++ b/kubeflow/apps/katib/upstream/installs/katib-with-kubeflow/ui-virtual-service.yaml @@ -0,0 +1,21 @@ +--- +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: katib-ui +spec: + gateways: + - kubeflow-gateway + hosts: + - "*" + http: + - match: + - uri: + prefix: /katib/ + rewrite: + uri: /katib/ + route: + - destination: + host: katib-ui.$(KATIB_UI_NAMESPACE).svc.cluster.local + port: + number: 80 diff --git a/kubeflow/apps/kserve/Makefile b/kubeflow/apps/kserve/Makefile new file mode 100644 index 0000000..d99ce48 --- /dev/null +++ b/kubeflow/apps/kserve/Makefile @@ -0,0 +1,56 @@ +KSERVE_VERSION ?= 0.12.1 +MODELS_WEBAPP_VERSION ?= 0.8.1 +MODELS_WEBAPP_RELEASE_VERSION := $(shell echo ${MODELS_WEBAPP_VERSION} | cut -d "." -f1-2) + +.PHONY: upgrade-kserve-manifests +upgrade-kserve-manifests: clean-kserve-manifests + curl -sSL 'https://github.com/kserve/kserve/releases/download/v$(KSERVE_VERSION)/kserve_kubeflow.yaml' -o 'kserve/kserve_kubeflow.yaml' + curl -sSL 'https://github.com/kserve/kserve/releases/download/v$(KSERVE_VERSION)/kserve-cluster-resources.yaml' -o 'kserve/kserve-cluster-resources.yaml' + curl -sSL 'https://github.com/kserve/kserve/releases/download/v$(KSERVE_VERSION)/kserve.yaml' -o 'kserve/kserve.yaml' + +.PHONY: clean-kserve-manifests +clean-kserve-manifests: + cd kserve && rm -f kserve.yaml kserve-cluster-resources.yaml kserve_kubeflow.yaml + +.PHONY: install-kserve +install-kserve: + # Create kubeflow namespace if not exists + kubectl create namespace kubeflow || echo "kubeflow namespace exists" + kubectl apply -k kserve + +.PHONY: uninstall-kserve +uninstall-kserve: + kubectl delete -k kserve + +.PHONY: test-kserve +test-kserve: + cd tests && pytest . + +.PHONY: clean-models-webapp-manifests +clean-models-webapp-manifests: + rm -rf models-web-app + +.PHONY: upgrade-models-webapp-manifests +upgrade-models-webapp-manifests: clean-models-webapp-manifests + git clone https://github.com/kserve/models-web-app.git kserve-models-web-app-src + cd kserve-models-web-app-src && git checkout release-${MODELS_WEBAPP_RELEASE_VERSION} + cp -r kserve-models-web-app-src/config ./models-web-app + # cleanup + rm -rf kserve-models-web-app-src + +.PHONY: install-models-web-app +install-models-webapp: + # Create kubeflow namespace if not exists + kubectl create namespace kubeflow || echo "kubeflow namespace exists" + kubectl apply -k models-web-app/overlays/kubeflow + +.PHONY: uninstall-models-web-app +uninstall-models-webapp: + kubectl delete -k models-web-app/overlays/kubeflow + +.PHONY: test-models-webapp +test-models-webapp: install-models-webapp + kubectl wait --for=condition=Available --timeout=300s -n kubeflow deployment/kserve-models-web-app + @echo "Test Passed" + @echo "cleaning up ..." + kubectl delete -k models-web-app/overlays/kubeflow diff --git a/kubeflow/apps/kserve/OWNERS b/kubeflow/apps/kserve/OWNERS new file mode 100644 index 0000000..e1e978e --- /dev/null +++ b/kubeflow/apps/kserve/OWNERS @@ -0,0 +1,2 @@ +approvers: + - yuzisun diff --git a/kubeflow/apps/kserve/README.md b/kubeflow/apps/kserve/README.md new file mode 100644 index 0000000..3afe5f6 --- /dev/null +++ b/kubeflow/apps/kserve/README.md @@ -0,0 +1,120 @@ +# KServe +[![Go Report Card](https://goreportcard.com/badge/github.com/kserve/kserve)](https://goreportcard.com/report/github.com/kserve/kserve) +[![OpenSSF Best Practices](https://bestpractices.coreinfrastructure.org/projects/6643/badge)](https://bestpractices.coreinfrastructure.org/projects/6643) +[![Releases](https://img.shields.io/github/release-pre/kserve/kserve.svg?sort=semver)](https://github.com/kserve/kserve/releases) +[![LICENSE](https://img.shields.io/github/license/kserve/kserve.svg)](https://github.com/kserve/kserve/blob/master/LICENSE) + +KServe provides a Kubernetes [Custom Resource Definition](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) for serving predictive and generative machine learning (ML) models. It aims to solve production model serving use cases by providing high abstraction interfaces for Tensorflow, XGBoost, ScikitLearn, PyTorch, Huggingface Transformer/LLM models using standardized data plane protocols. + +It encapsulates the complexity of autoscaling, networking, health checking, and server configuration to bring cutting edge serving features like GPU Autoscaling, Scale to Zero, and Canary Rollouts to your ML deployments. It enables a simple, pluggable, and complete story for Production ML Serving including prediction, pre-processing, post-processing and explainability. KServe is being [used across various organizations.](https://kserve.github.io/website/master/community/adopters/) + +For more details, visit the [KServe website](https://kserve.github.io/website/). + +![KServe](assets/kserve_new.png) + +*[KFServing has been rebranded to KServe since v0.7](https://blog.kubeflow.org/release/official/2021/09/27/kfserving-transition.html).* + +## Why KServe? +- KServe is a standard, cloud agnostic **Model Inference Platform** for serving predictive and generative AI models on Kubernetes, built for highly scalable use cases. +- Provides performant, **standardized inference protocol** across ML frameworks including OpenAI specification for generative models. +- Support modern **serverless inference workload** with **request based autoscaling including scale-to-zero** on **CPU and GPU**. +- Provides **high scalability, density packing and intelligent routing** using **ModelMesh**. +- **Simple and pluggable production serving** for **inference**, **pre/post processing**, **monitoring** and **explainability**. +- Advanced deployments for **canary rollout**, **pipeline**, **ensembles** with **InferenceGraph**. + + +## :hammer_and_wrench: Installation + +### Standalone Installation +- **[Serverless Installation](https://kserve.github.io/website/master/admin/serverless/serverless/)**: KServe by default installs Knative for **serverless deployment** for InferenceService. +- **[Raw Deployment Installation](https://kserve.github.io/website/master/admin/kubernetes_deployment)**: Compared to Serverless Installation, this is a more **lightweight** installation. However, this option does not support canary deployment and request based autoscaling with scale-to-zero. +- **[ModelMesh Installation](https://kserve.github.io/website/master/admin/modelmesh/)**: You can optionally install ModelMesh to enable **high-scale**, **high-density** and **frequently-changing model serving** use cases. +- **[Quick Installation](https://kserve.github.io/website/master/get_started/)**: Install KServe on your local machine. + +### Kubeflow Installation +KServe is an important addon component of Kubeflow, please learn more from the [Kubeflow KServe documentation](https://www.kubeflow.org/docs/external-add-ons/kserve/kserve) and follow [KServe with Kubeflow on AWS](https://awslabs.github.io/kubeflow-manifests/main/docs/component-guides/kserve) to learn how to use KServe on AWS. + +## :hammer_and_pick: Models Web App +The Models web app is responsible for allowing the user to manipulate the Model Servers in their Kubeflow cluster. To achieve this it provides a user friendly way to handle the lifecycle of InferenceService CRs. +Please follow the [Kserve Models UI documentation](https://www.kubeflow.org/docs/external-add-ons/kserve/webapp/) for more information. + +## :rocket: Upgrading +For upgrading see [UPGRADE.md](UPGRADE.md) + +## :microscope: Testing +### Testing Kserve +#### Prerequisite + +1. Install Python >= 3.8 +2. Install requirements + ```sh + pip install -r tests/requirements.txt + ``` +3. Create kubeflow namespace + ```sh + kubectl apply -k ../../common/kubeflow-namespace/base + ``` +4. Install cert manager + ```sh + kubectl apply -k ../../common/cert-manager/base + kubectl apply -k ../../common/cert-manager/kubeflow-issuer/base + ``` +5. Install Istio + ```sh + kubectl apply -k ../../common/istio-1-24/istio-crds/base + kubectl apply -k ../../common/istio-1-24/istio-namespace/base + kubectl apply -k ../../common/istio-1-24/istio-install/base + ``` +6. Install knative + ```sh + kubectl apply -k ../../common/knative/knative-serving/overlays/gateways + kubectl apply -k ../../common/istio-1-24/cluster-local-gateway/base + kubectl apply -k ../../common/istio-1-24/kubeflow-istio-resources/base + ``` +7. Install kserve + ```sh + make install-kserve + ``` +> **_NOTE:_** If resource/crd installation fails please re-run the commands. + +#### Steps +1. Create test namespace + ```sh + kubectl create ns kserve-test + ``` +2. Configure domain name + ```sh + kubectl patch cm config-domain --patch '{"data":{"example.com":""}}' -n knative-serving + ``` + +3. Port forward + ```sh + # start a new terminal and run + INGRESS_GATEWAY_SERVICE=$(kubectl get svc --namespace istio-system --selector="app=istio-ingressgateway" --output jsonpath='{.items[0].metadata.name}') + kubectl port-forward --namespace istio-system svc/${INGRESS_GATEWAY_SERVICE} 8080:80 + ``` +4. Run test + ```sh + export KSERVE_INGRESS_HOST_PORT='localhost:8080' + make test-kserve + +### Testing Models WebApp +#### Prerequisite +1. Running kubernetes cluster +2. `kubectl` configured to talk to the desired cluster. + +#### Steps +1. Run the test + ```sh + make test-models-webapp + ``` +## :flight_departure: [Create your first InferenceService](https://kserve.github.io/website/master/get_started/first_isvc) + +## :blue_book: [InferenceService API Reference](https://kserve.github.io/website/master/reference/api/) + +## :handshake: [Adopters](https://kserve.github.io/website/master/community/adopters/) + +## :books: Learn More +To learn more about KServe, how to use various supported features, and how to participate in the KServe community, +please follow the [KServe website documentation](https://kserve.github.io/website). +Additionally, we have compiled a list of [presentations and demos](https://kserve.github.io/website/master/community/presentations/) to dive through various details. diff --git a/kubeflow/apps/kserve/UPGRADE.md b/kubeflow/apps/kserve/UPGRADE.md new file mode 100644 index 0000000..d0c4226 --- /dev/null +++ b/kubeflow/apps/kserve/UPGRADE.md @@ -0,0 +1,68 @@ +# Upgrade Documentation + +## Upgrade Kserve + +### Prerequisites + +- Running Kubernetes cluster with kubeflow installed. +- `kubectl` configured to talk to the desired cluster. +- `curl` + +> **_NOTE:_** This documentation assumes that you are running the commands in linux. + If you are using another OS, please make sure to update the Makefile commands. + +### To update the kserve manifests to specific version follow the below instructions. + +1. Set the desired version to upgrade. + + ```sh + export KSERVE_VERSION=0.12.1 + ``` + +2. Rebuild the manifests. + + ```sh + make upgrade-kserve-manifests + ``` + +3. Install the updated manifests. + ```sh + make install-kserve + ``` +> **_NOTE:_** If resource/crd installation fails please re-run the commands. + +### Testing +For testing refer [kserve readme](README.md#testing-kserve). + +## Upgrade Models Webapp +### Prerequisites + +- Running Kubernetes cluster with kubeflow installed. +- `kubectl` configured to talk to the desired cluster. +- `git` + +> **_NOTE:_** This documentation assumes that you are running the commands in linux. +If you are using another OS, please make sure to update the Makefile commands. + +### To update the kserve manifests to specific version follow the below instructions. + +1. Set the desired version to upgrade. + + ```sh + export MODELS_WEBAPP_VERSION=0.8.1 + ``` + +2. Rebuild the manifests. + + ```sh + make upgrade-models-webapp-manifests + ``` + +3. Install the updated manifests. + ```sh + make install-models-webapp + ``` +> **_NOTE:_** If resource/crd installation fails please re-run the commands. + +### Testing +For testing refer [kserve readme](README.md#testing-models-webapp). diff --git a/kubeflow/apps/kserve/assets/kserve.png b/kubeflow/apps/kserve/assets/kserve.png new file mode 100644 index 0000000000000000000000000000000000000000..8639fcfb2c46c901a227736a3c2cbca7cbd24431 GIT binary patch literal 472792 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